diff options
author | Sara Golemon <sara.golemon@mongodb.com> | 2022-10-31 12:50:44 -0500 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-11-13 02:58:52 +0000 |
commit | 8728459da343c79cc2f8157856a5b8e03c1bfdf1 (patch) | |
tree | f3aa3dc9df15652bc5b8acb31c21d621ffb7c752 /src/mongo/db/auth/authorization_manager_impl.cpp | |
parent | 9298a0edec45d9e902cb0e9ef9875c3a06a76098 (diff) | |
download | mongo-8728459da343c79cc2f8157856a5b8e03c1bfdf1.tar.gz |
SERVER-70700 Use UserRequest to in authorization workflow
Diffstat (limited to 'src/mongo/db/auth/authorization_manager_impl.cpp')
-rw-r--r-- | src/mongo/db/auth/authorization_manager_impl.cpp | 73 |
1 files changed, 29 insertions, 44 deletions
diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp index db1081b8bf3..9a50ec921ab 100644 --- a/src/mongo/db/auth/authorization_manager_impl.cpp +++ b/src/mongo/db/auth/authorization_manager_impl.cpp @@ -68,7 +68,8 @@ namespace mongo { namespace { std::shared_ptr<UserHandle> createSystemUserHandle() { - auto user = std::make_shared<UserHandle>(User(UserName("__system", "local"))); + UserRequest request(UserName("__system", "local"), boost::none); + auto user = std::make_shared<UserHandle>(User(std::move(request))); ActionSet allActions; allActions.addAllActions(); @@ -284,29 +285,6 @@ bool appliesToAuthzData(StringData op, const NamespaceString& nss, const BSONObj } } -/** - * Returns true if roles for this user were provided by the client, and can be obtained from - * the connection. - */ -bool shouldUseRolesFromConnection(OperationContext* opCtx, const UserName& userName) { -#ifdef MONGO_CONFIG_SSL - if (!opCtx || !opCtx->getClient() || !opCtx->getClient()->session()) { - return false; - } - - if (!allowRolesFromX509Certificates) { - return false; - } - - auto& sslPeerInfo = SSLPeerInfo::forSession(opCtx->getClient()->session()); - return sslPeerInfo.subjectName.toString() == userName.getUser() && - userName.getDB() == "$external"_sd && !sslPeerInfo.roles.empty(); -#else - return false; -#endif -} - - std::unique_ptr<AuthorizationManager> authorizationManagerCreateImpl( ServiceContext* serviceContext) { return std::make_unique<AuthorizationManagerImpl>(serviceContext, @@ -494,29 +472,17 @@ MONGO_FAIL_POINT_DEFINE(authUserCacheSleep); } // namespace StatusWith<UserHandle> AuthorizationManagerImpl::acquireUser(OperationContext* opCtx, - const UserName& userName) try { + const UserRequest& request) try { + const auto& userName = request.name; + auto systemUser = internalSecurity.getUser(); if (userName == (*systemUser)->getName()) { + uassert(ErrorCodes::OperationFailed, + "Attempted to acquire system user with predefined roles", + request.roles == boost::none); return *systemUser; } - UserRequest request(userName, boost::none); - -#ifdef MONGO_CONFIG_SSL - // Clients connected via TLS may present an X.509 certificate which contains an authorization - // grant. If this is the case, the roles must be provided to the external state, for expansion - // into privileges. - if (shouldUseRolesFromConnection(opCtx, userName)) { - auto& sslPeerInfo = SSLPeerInfo::forSession(opCtx->getClient()->session()); - request.roles = std::set<RoleName>(); - - // In order to be hashable, the role names must be converted from unordered_set to a set. - std::copy(sslPeerInfo.roles.begin(), - sslPeerInfo.roles.end(), - std::inserter(*request.roles, request.roles->begin())); - } -#endif - if (authUserCacheBypass.shouldFail()) { // Bypass cache and force a fresh load of the user. auto loadedUser = uassertStatusOK(_externalState->getUserObject(opCtx, request)); @@ -559,7 +525,7 @@ StatusWith<UserHandle> AuthorizationManagerImpl::reacquireUser(OperationContext* // Make a good faith effort to acquire an up-to-date user object, since the one // we've cached is marked "out-of-date." - auto swUserHandle = acquireUser(opCtx, userName); + auto swUserHandle = acquireUser(opCtx, user->getUserRequest()); if (!swUserHandle.isOK()) { return swUserHandle.getStatus(); } @@ -645,6 +611,18 @@ void AuthorizationManagerImpl::_pinnedUsersThreadRoutine() noexcept try { } } + // Find UserRequests for UserNames we need to pin if they exist in the cache. + std::map<UserName, UserRequest> pinNow; + _userCache.peekLatestCachedIf([&](const UserRequest& request, const User& user) { + if (std::any_of(usersToPin.begin(), usersToPin.end(), [&](const auto& userName) { + return user.getName() == userName; + })) { + pinNow.emplace(request.name, request); + } + // Don't need any output vector. + return false; + }); + for (const auto& userName : usersToPin) { if (std::any_of(pinnedUsers.begin(), pinnedUsers.end(), [&](const auto& user) { return user->getName() == userName; @@ -652,7 +630,14 @@ void AuthorizationManagerImpl::_pinnedUsersThreadRoutine() noexcept try { continue; } - auto swUser = acquireUser(opCtx.get(), userName); + auto request = ([&] { + if (auto it = pinNow.find(userName); it != pinNow.end()) { + return it->second; + } + return UserRequest(userName, boost::none); + })(); + + auto swUser = acquireUser(opCtx.get(), request); if (swUser.isOK()) { LOGV2_DEBUG(20232, 2, "Pinned user", "user"_attr = userName); |