From 8ac4553c3d5c7509ea708c31a7f0232b2b3d4f4f Mon Sep 17 00:00:00 2001 From: "sergey.galtsev" Date: Mon, 1 Nov 2021 20:11:09 +0000 Subject: SERVER-45717 Allow changes to clusterIpSourceAllowlist without restart --- src/mongo/db/auth/authorization_manager_impl.cpp | 68 +++++++++++++++++------- 1 file changed, 50 insertions(+), 18 deletions(-) (limited to 'src/mongo/db/auth/authorization_manager_impl.cpp') diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp index 3a24e2d8165..0b29680b2af 100644 --- a/src/mongo/db/auth/authorization_manager_impl.cpp +++ b/src/mongo/db/auth/authorization_manager_impl.cpp @@ -65,36 +65,67 @@ namespace mongo { namespace { -MONGO_INITIALIZER_GENERAL(SetupInternalSecurityUser, - ("EndStartupOptionStorage"), - ("CreateAuthorizationManager")) -(InitializerContext* const context) try { - UserHandle user(User(UserName("__system", "local"))); +std::shared_ptr createSystemUserHandle() { + auto user = std::make_shared(User(UserName("__system", "local"))); ActionSet allActions; allActions.addAllActions(); PrivilegeVector privileges; auth::generateUniversalPrivileges(&privileges); - user->addPrivileges(privileges); + (*user)->addPrivileges(privileges); - if (mongodGlobalParams.allowlistedClusterNetwork) { - const auto& allowlist = *mongodGlobalParams.allowlistedClusterNetwork; + if (internalSecurity.credentials) { + (*user)->setCredentials(internalSecurity.credentials.value()); + } - auto restriction = std::make_unique(allowlist); - auto restrictionSet = std::make_unique>(std::move(restriction)); - auto restrictionDocument = - std::make_unique>(std::move(restrictionSet)); + return user; +} - RestrictionDocuments clusterAllowList(std::move(restrictionDocument)); +class ClusterNetworkRestrictionManagerImpl : public ClusterNetworkRestrictionManager { +public: + static void configureClusterNetworkRestrictions(std::shared_ptr user) { + const auto allowlistedClusterNetwork = + std::atomic_load(&mongodGlobalParams.allowlistedClusterNetwork); // NOLINT + if (allowlistedClusterNetwork) { + auto restriction = + std::make_unique(*allowlistedClusterNetwork); + auto restrictionSet = std::make_unique>(std::move(restriction)); + auto restrictionDocument = + std::make_unique>(std::move(restrictionSet)); + + RestrictionDocuments clusterAllowList(std::move(restrictionDocument)); + (*user)->setRestrictions(clusterAllowList); + } + } + + void updateClusterNetworkRestrictions() override { + auto user = createSystemUserHandle(); + configureClusterNetworkRestrictions(user); + auto originalUser = internalSecurity.setUser(user); - user->setRestrictions(std::move(clusterAllowList)); + // TODO: Invalidate __system sessions falling under restrictions (SERVER-61038) + boost::ignore_unused_variable_warning(originalUser); } +}; - internalSecurity.user = user; +MONGO_INITIALIZER_GENERAL(SetupInternalSecurityUser, + ("EndStartupOptionStorage"), + ("CreateAuthorizationManager")) +(InitializerContext* const context) try { + auto user = createSystemUserHandle(); + ClusterNetworkRestrictionManagerImpl::configureClusterNetworkRestrictions(user); + internalSecurity.setUser(user); } catch (...) { uassertStatusOK(exceptionToStatus()); } +ServiceContext::ConstructorActionRegisterer setClusterNetworkRestrictionManager{ + "SetClusterNetworkRestrictionManager", [](ServiceContext* service) { + std::unique_ptr manager = + std::make_unique(); + ClusterNetworkRestrictionManager::set(service, std::move(manager)); + }}; + class PinnedUserSetParameter { public: void append(BSONObjBuilder& b, const std::string& name) const { @@ -175,7 +206,7 @@ public: private: Status _checkForSystemUser(const std::vector& names) { if (std::any_of(names.begin(), names.end(), [&](const UserName& userName) { - return (userName == internalSecurity.user->getName()); + return (userName == (*internalSecurity.getUser())->getName()); })) { return {ErrorCodes::BadValue, "Cannot set __system as a pinned user, it is always pinned"}; @@ -461,8 +492,9 @@ MONGO_FAIL_POINT_DEFINE(authUserCacheSleep); StatusWith AuthorizationManagerImpl::acquireUser(OperationContext* opCtx, const UserName& userName) try { - if (userName == internalSecurity.user->getName()) { - return internalSecurity.user; + auto systemUser = internalSecurity.getUser(); + if (userName == (*systemUser)->getName()) { + return *systemUser; } UserRequest request(userName, boost::none); -- cgit v1.2.1