summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorauto-revert-processor <dev-prod-dag@mongodb.com>2022-11-14 10:04:23 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-11-14 10:35:57 +0000
commit16bf50d195697115e1ccf5dcb9c87a826643c613 (patch)
treec520affe5b7f8572c413f5633472e0bd0b7981dc
parent2bfdf69af4ab1b08b07e757a61668cf9fe620fb4 (diff)
downloadmongo-16bf50d195697115e1ccf5dcb9c87a826643c613.tar.gz
Revert "SERVER-70700 Use UserRequest to in authorization workflow"
This reverts commit 8728459da343c79cc2f8157856a5b8e03c1bfdf1.
-rw-r--r--src/mongo/db/auth/authorization_manager.h6
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.cpp73
-rw-r--r--src/mongo/db/auth/authorization_manager_impl.h3
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp53
-rw-r--r--src/mongo/db/auth/authorization_session.h2
-rw-r--r--src/mongo/db/auth/authorization_session_for_test.cpp3
-rw-r--r--src/mongo/db/auth/authorization_session_impl.cpp6
-rw-r--r--src/mongo/db/auth/authorization_session_impl.h2
-rw-r--r--src/mongo/db/auth/authorization_session_test.cpp129
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_local.cpp2
-rw-r--r--src/mongo/db/auth/authz_manager_external_state_s.cpp2
-rw-r--r--src/mongo/db/auth/sasl_commands.cpp4
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry.cpp2
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry.h4
-rw-r--r--src/mongo/db/auth/sasl_mechanism_registry_test.cpp3
-rw-r--r--src/mongo/db/auth/sasl_plain_server_conversation.cpp3
-rw-r--r--src/mongo/db/auth/sasl_scram_server_conversation.cpp2
-rw-r--r--src/mongo/db/auth/security_key_test.cpp3
-rw-r--r--src/mongo/db/auth/security_token_authentication_guard.cpp4
-rw-r--r--src/mongo/db/auth/user.cpp10
-rw-r--r--src/mongo/db/auth/user.h72
-rw-r--r--src/mongo/db/auth/user_document_parser_test.cpp4
-rw-r--r--src/mongo/db/auth/validated_tenancy_scope_test.cpp2
-rw-r--r--src/mongo/db/commands/SConscript1
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp25
-rw-r--r--src/mongo/db/commands/user_management_commands.cpp5
-rw-r--r--src/mongo/db/session/SConscript1
-rw-r--r--src/mongo/db/session/kill_sessions.cpp8
-rw-r--r--src/mongo/db/session/logical_session_id_test.cpp4
-rw-r--r--src/mongo/embedded/embedded_auth_manager.cpp2
-rw-r--r--src/mongo/embedded/embedded_auth_session.cpp2
-rw-r--r--src/mongo/rpc/op_msg_test.cpp2
-rw-r--r--src/mongo/util/net/network_interface_ssl_test.cpp3
33 files changed, 205 insertions, 242 deletions
diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h
index 0f4f89e24dc..69077aebe6a 100644
--- a/src/mongo/db/auth/authorization_manager.h
+++ b/src/mongo/db/auth/authorization_manager.h
@@ -305,14 +305,14 @@ public:
std::vector<BSONObj>* result) = 0;
/**
- * Returns a Status or UserHandle for the given userRequest. If the user cache already has a
+ * Returns a Status or UserHandle for the given userName. If the user cache already has a
* user object for this user, it returns a handle from the cache, otherwise it reads the
- * user document from the AuthzManagerExternalState - this may block for a long time.
+ * user document from disk or LDAP - this may block for a long time.
*
* The returned user may be invalid by the time the caller gets access to it.
*/
virtual StatusWith<UserHandle> acquireUser(OperationContext* opCtx,
- const UserRequest& userRequest) = 0;
+ const UserName& userName) = 0;
/**
* Validate the ID associated with a known user while refreshing session cache.
diff --git a/src/mongo/db/auth/authorization_manager_impl.cpp b/src/mongo/db/auth/authorization_manager_impl.cpp
index 9a50ec921ab..db1081b8bf3 100644
--- a/src/mongo/db/auth/authorization_manager_impl.cpp
+++ b/src/mongo/db/auth/authorization_manager_impl.cpp
@@ -68,8 +68,7 @@ namespace mongo {
namespace {
std::shared_ptr<UserHandle> createSystemUserHandle() {
- UserRequest request(UserName("__system", "local"), boost::none);
- auto user = std::make_shared<UserHandle>(User(std::move(request)));
+ auto user = std::make_shared<UserHandle>(User(UserName("__system", "local")));
ActionSet allActions;
allActions.addAllActions();
@@ -285,6 +284,29 @@ 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,
@@ -472,17 +494,29 @@ MONGO_FAIL_POINT_DEFINE(authUserCacheSleep);
} // namespace
StatusWith<UserHandle> AuthorizationManagerImpl::acquireUser(OperationContext* opCtx,
- const UserRequest& request) try {
- const auto& userName = request.name;
-
+ const UserName& userName) try {
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));
@@ -525,7 +559,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, user->getUserRequest());
+ auto swUserHandle = acquireUser(opCtx, userName);
if (!swUserHandle.isOK()) {
return swUserHandle.getStatus();
}
@@ -611,18 +645,6 @@ 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;
@@ -630,14 +652,7 @@ void AuthorizationManagerImpl::_pinnedUsersThreadRoutine() noexcept try {
continue;
}
- 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);
+ auto swUser = acquireUser(opCtx.get(), userName);
if (swUser.isOK()) {
LOGV2_DEBUG(20232, 2, "Pinned user", "user"_attr = userName);
diff --git a/src/mongo/db/auth/authorization_manager_impl.h b/src/mongo/db/auth/authorization_manager_impl.h
index 17502fd0067..fcec7b97e32 100644
--- a/src/mongo/db/auth/authorization_manager_impl.h
+++ b/src/mongo/db/auth/authorization_manager_impl.h
@@ -97,8 +97,7 @@ public:
bool showBuiltinRoles,
std::vector<BSONObj>* result) override;
- StatusWith<UserHandle> acquireUser(OperationContext* opCtx,
- const UserRequest& userRequest) override;
+ StatusWith<UserHandle> acquireUser(OperationContext* opCtx, const UserName& userName) override;
StatusWith<UserHandle> reacquireUser(OperationContext* opCtx, const UserHandle& user) override;
/**
diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp
index 3363aead426..f91f3f0a329 100644
--- a/src/mongo/db/auth/authorization_manager_test.cpp
+++ b/src/mongo/db/auth/authorization_manager_test.cpp
@@ -140,7 +140,7 @@ TEST_F(AuthorizationManagerTest, testAcquireV2User) {
<< "admin"))),
BSONObj()));
- auto swu = authzManager->acquireUser(opCtx.get(), {{"v2read", "test"}, boost::none});
+ auto swu = authzManager->acquireUser(opCtx.get(), UserName("v2read", "test"));
ASSERT_OK(swu.getStatus());
auto v2read = std::move(swu.getValue());
ASSERT_EQUALS(UserName("v2read", "test"), v2read->getName());
@@ -153,7 +153,7 @@ TEST_F(AuthorizationManagerTest, testAcquireV2User) {
ASSERT(testDBPrivilege.getActions().contains(ActionType::find));
// Make sure user's refCount is 0 at the end of the test to avoid an assertion failure
- swu = authzManager->acquireUser(opCtx.get(), {{"v2cluster", "admin"}, boost::none});
+ swu = authzManager->acquireUser(opCtx.get(), UserName("v2cluster", "admin"));
ASSERT_OK(swu.getStatus());
auto v2cluster = std::move(swu.getValue());
ASSERT_EQUALS(UserName("v2cluster", "admin"), v2cluster->getName());
@@ -169,19 +169,24 @@ TEST_F(AuthorizationManagerTest, testAcquireV2User) {
#ifdef MONGO_CONFIG_SSL
TEST_F(AuthorizationManagerTest, testLocalX509Authorization) {
- std::set<RoleName> roles({{"read", "test"}, {"readWrite", "test"}});
- UserRequest request(UserName("CN=mongodb.com", "$external"), roles);
+ setX509PeerInfo(session,
+ SSLPeerInfo(buildX509Name(),
+ boost::none,
+ {RoleName("read", "test"), RoleName("readWrite", "test")}));
- auto swu = authzManager->acquireUser(opCtx.get(), request);
+ auto swu = authzManager->acquireUser(opCtx.get(), UserName("CN=mongodb.com", "$external"));
ASSERT_OK(swu.getStatus());
auto x509User = std::move(swu.getValue());
ASSERT(x509User.isValid());
- std::set<RoleName> gotRoles;
- for (auto it = x509User->getRoles(); it.more();) {
- gotRoles.emplace(it.next());
+ stdx::unordered_set<RoleName> expectedRoles{RoleName("read", "test"),
+ RoleName("readWrite", "test")};
+ RoleNameIterator roles = x509User->getRoles();
+ stdx::unordered_set<RoleName> acquiredRoles;
+ while (roles.more()) {
+ acquiredRoles.insert(roles.next());
}
- ASSERT_TRUE(roles == gotRoles);
+ ASSERT_TRUE(expectedRoles == acquiredRoles);
const User::ResourcePrivilegeMap& privileges = x509User->getPrivileges();
ASSERT_FALSE(privileges.empty());
@@ -197,16 +202,14 @@ TEST_F(AuthorizationManagerTest, testLocalX509AuthorizationInvalidUser) {
{RoleName("read", "test"), RoleName("write", "test")}));
ASSERT_NOT_OK(
- authzManager->acquireUser(opCtx.get(), {{"CN=10gen.com", "$external"}, boost::none})
- .getStatus());
+ authzManager->acquireUser(opCtx.get(), UserName("CN=10gen.com", "$external")).getStatus());
}
TEST_F(AuthorizationManagerTest, testLocalX509AuthenticationNoAuthorization) {
setX509PeerInfo(session, {});
- ASSERT_NOT_OK(
- authzManager->acquireUser(opCtx.get(), {{"CN=mongodb.com", "$external"}, boost::none})
- .getStatus());
+ ASSERT_NOT_OK(authzManager->acquireUser(opCtx.get(), UserName("CN=mongodb.com", "$external"))
+ .getStatus());
}
#endif
@@ -237,7 +240,7 @@ TEST_F(AuthorizationManagerTest, testAcquireV2UserWithUnrecognizedActions) {
<< "insert")))),
BSONObj()));
- auto swu = authzManager->acquireUser(opCtx.get(), {{"myUser", "test"}, boost::none});
+ auto swu = authzManager->acquireUser(opCtx.get(), UserName("myUser", "test"));
ASSERT_OK(swu.getStatus());
auto myUser = std::move(swu.getValue());
ASSERT_EQUALS(UserName("myUser", "test"), myUser->getName());
@@ -314,12 +317,14 @@ TEST_F(AuthorizationManagerTest, testRefreshExternalV2User) {
std::vector<UserHandle> checkedOutUsers;
checkedOutUsers.reserve(userDocs.size());
for (const auto& userDoc : userDocs) {
- const UserName userName(userDoc.getStringField(kUserFieldName),
- userDoc.getStringField(kDbFieldName));
- auto swUser = authzManager->acquireUser(opCtx.get(), {userName, boost::none});
+ auto swUser = authzManager->acquireUser(
+ opCtx.get(),
+ UserName(userDoc.getStringField(kUserFieldName), userDoc.getStringField(kDbFieldName)));
ASSERT_OK(swUser.getStatus());
auto user = std::move(swUser.getValue());
- ASSERT_EQUALS(userName, user->getName());
+ ASSERT_EQUALS(
+ UserName(userDoc.getStringField(kUserFieldName), userDoc.getStringField(kDbFieldName)),
+ user->getName());
ASSERT(user.isValid());
RoleNameIterator cachedUserRoles = user->getRoles();
@@ -359,12 +364,14 @@ TEST_F(AuthorizationManagerTest, testRefreshExternalV2User) {
// Retrieve all users from the cache and verify that only the external ones contain the newly
// added role.
for (const auto& userDoc : userDocs) {
- const UserName userName(userDoc.getStringField(kUserFieldName),
- userDoc.getStringField(kDbFieldName));
- auto swUser = authzManager->acquireUser(opCtx.get(), {userName, boost::none});
+ auto swUser = authzManager->acquireUser(
+ opCtx.get(),
+ UserName(userDoc.getStringField(kUserFieldName), userDoc.getStringField(kDbFieldName)));
ASSERT_OK(swUser.getStatus());
auto user = std::move(swUser.getValue());
- ASSERT_EQUALS(userName, user->getName());
+ ASSERT_EQUALS(
+ UserName(userDoc.getStringField(kUserFieldName), userDoc.getStringField(kDbFieldName)),
+ user->getName());
ASSERT(user.isValid());
RoleNameIterator cachedUserRolesIt = user->getRoles();
diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h
index 6bca9cd0192..777da1ad56d 100644
--- a/src/mongo/db/auth/authorization_session.h
+++ b/src/mongo/db/auth/authorization_session.h
@@ -144,7 +144,7 @@ public:
* Adds the User identified by "UserName" to the authorization session, acquiring privileges
* for it in the process.
*/
- virtual Status addAndAuthorizeUser(OperationContext* opCtx, const UserRequest& userRequest) = 0;
+ virtual Status addAndAuthorizeUser(OperationContext* opCtx, const UserName& userName) = 0;
// Returns the authenticated user with the given name. Returns NULL
// if no such user is found.
diff --git a/src/mongo/db/auth/authorization_session_for_test.cpp b/src/mongo/db/auth/authorization_session_for_test.cpp
index e88dd65ebc4..620716c5e4f 100644
--- a/src/mongo/db/auth/authorization_session_for_test.cpp
+++ b/src/mongo/db/auth/authorization_session_for_test.cpp
@@ -48,8 +48,7 @@ void AuthorizationSessionForTest::assumePrivilegesForDB(Privilege privilege, Str
void AuthorizationSessionForTest::assumePrivilegesForDB(PrivilegeVector privileges,
StringData dbName) {
- UserRequest request(UserName("authorizationSessionForTestUser"_sd, dbName), boost::none);
- _authenticatedUser = UserHandle(User(request));
+ _authenticatedUser = UserHandle(User(UserName("authorizationSessionForTestUser", dbName)));
_authenticatedUser.value()->addPrivileges(privileges);
_authenticationMode = AuthorizationSession::AuthenticationMode::kConnection;
_updateInternalAuthorizationState();
diff --git a/src/mongo/db/auth/authorization_session_impl.cpp b/src/mongo/db/auth/authorization_session_impl.cpp
index 85b8bcc0c6e..90083b297ba 100644
--- a/src/mongo/db/auth/authorization_session_impl.cpp
+++ b/src/mongo/db/auth/authorization_session_impl.cpp
@@ -200,9 +200,7 @@ void AuthorizationSessionImpl::startContractTracking() {
}
Status AuthorizationSessionImpl::addAndAuthorizeUser(OperationContext* opCtx,
- const UserRequest& userRequest) try {
- const auto& userName = userRequest.name;
-
+ const UserName& userName) try {
// Check before we start to reveal as little as possible. Note that we do not need the lock
// because only the Client thread can mutate _authenticatedUser.
if (_authenticatedUser) {
@@ -234,7 +232,7 @@ Status AuthorizationSessionImpl::addAndAuthorizeUser(OperationContext* opCtx,
}
AuthorizationManager* authzManager = AuthorizationManager::get(opCtx->getServiceContext());
- auto user = uassertStatusOK(authzManager->acquireUser(opCtx, userRequest));
+ auto user = uassertStatusOK(authzManager->acquireUser(opCtx, userName));
auto restrictionStatus = user->validateRestrictions(opCtx);
if (!restrictionStatus.isOK()) {
diff --git a/src/mongo/db/auth/authorization_session_impl.h b/src/mongo/db/auth/authorization_session_impl.h
index e9e19c63bb7..94a13c59249 100644
--- a/src/mongo/db/auth/authorization_session_impl.h
+++ b/src/mongo/db/auth/authorization_session_impl.h
@@ -76,7 +76,7 @@ public:
void startContractTracking() override;
- Status addAndAuthorizeUser(OperationContext* opCtx, const UserRequest& userRequest) override;
+ Status addAndAuthorizeUser(OperationContext* opCtx, const UserName& userName) override;
User* lookupUser(const UserName& name) override;
diff --git a/src/mongo/db/auth/authorization_session_test.cpp b/src/mongo/db/auth/authorization_session_test.cpp
index b1a980f5396..1336554897a 100644
--- a/src/mongo/db/auth/authorization_session_test.cpp
+++ b/src/mongo/db/auth/authorization_session_test.cpp
@@ -172,53 +172,37 @@ const ResourcePattern otherProfileCollResource(
const ResourcePattern thirdProfileCollResource(
ResourcePattern::forExactNamespace(NamespaceString("third.system.profile")));
-const UserName kUser1Test("user1"_sd, "test"_sd);
-const UserRequest kUser1TestRequest(kUser1Test, boost::none);
-const UserName kUser2Test("user2"_sd, "test"_sd);
-const UserRequest kUser2TestRequest(kUser2Test, boost::none);
-
TEST_F(AuthorizationSessionTest, MultiAuthSameUserAllowed) {
authzSession->startContractTracking();
- ASSERT_OK(createUser(kUser1Test, {}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUser1TestRequest));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUser1TestRequest));
+ ASSERT_OK(createUser({"user1", "test"}, {}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {"user1", "test"}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {"user1", "test"}));
authzSession->logoutAllDatabases(_client.get(), "Test finished");
}
TEST_F(AuthorizationSessionTest, MultiAuthSameDBDisallowed) {
authzSession->startContractTracking();
- ASSERT_OK(createUser(kUser1Test, {}));
- ASSERT_OK(createUser(kUser2Test, {}));
+ ASSERT_OK(createUser({"user1", "test"}, {}));
+ ASSERT_OK(createUser({"user2", "test"}, {}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUser1TestRequest));
- ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUser2TestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {"user1", "test"}));
+ ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {"user2", "test"}));
authzSession->logoutAllDatabases(_client.get(), "Test finished");
}
-const UserName kUserTest1("user"_sd, "test1"_sd);
-const UserRequest kUserTest1Request(kUserTest1, boost::none);
-const UserName kUserTest2("user"_sd, "test2"_sd);
-const UserRequest kUserTest2Request(kUserTest2, boost::none);
-
TEST_F(AuthorizationSessionTest, MultiAuthMultiDBDisallowed) {
authzSession->startContractTracking();
- ASSERT_OK(createUser(kUserTest1, {}));
- ASSERT_OK(createUser(kUserTest2, {}));
+ ASSERT_OK(createUser({"user", "test1"}, {}));
+ ASSERT_OK(createUser({"user", "test2"}, {}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUserTest1Request));
- ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUserTest2Request));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {"user", "test1"}));
+ ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {"user", "test2"}));
authzSession->logoutAllDatabases(_client.get(), "Test finished");
}
-const UserName kSpencerTest("spencer"_sd, "test"_sd);
-const UserRequest kSpencerTestRequest(kSpencerTest, boost::none);
-
-const UserName kAdminAdmin("admin"_sd, "admin"_sd);
-const UserRequest kAdminAdminRequest(kAdminAdmin, boost::none);
-
TEST_F(AuthorizationSessionTest, AddUserAndCheckAuthorization) {
authzSession->startContractTracking();
@@ -234,11 +218,11 @@ TEST_F(AuthorizationSessionTest, AddUserAndCheckAuthorization) {
// Check that you can't authorize a user that doesn't exist.
ASSERT_EQUALS(ErrorCodes::UserNotFound,
- authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
// Add a user with readWrite and dbAdmin on the test DB
- ASSERT_OK(createUser(kSpencerTest, {{"readWrite", "test"}, {"dbAdmin", "test"}}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_OK(createUser({"spencer", "test"}, {{"readWrite", "test"}, {"dbAdmin", "test"}}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
ASSERT_TRUE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::insert));
@@ -249,8 +233,8 @@ TEST_F(AuthorizationSessionTest, AddUserAndCheckAuthorization) {
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
// Add an admin user with readWriteAnyDatabase
- ASSERT_OK(createUser(kAdminAdmin, {{"readWriteAnyDatabase", "admin"}}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kAdminAdminRequest));
+ ASSERT_OK(createUser({"admin", "admin"}, {{"readWriteAnyDatabase", "admin"}}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("admin", "admin")));
ASSERT_TRUE(authzSession->isAuthorizedForActionsOnResource(
ResourcePattern::forExactNamespace(NamespaceString("anydb.somecollection")),
@@ -302,9 +286,9 @@ TEST_F(AuthorizationSessionTest, AddUserAndCheckAuthorization) {
TEST_F(AuthorizationSessionTest, DuplicateRolesOK) {
// Add a user with doubled-up readWrite and single dbAdmin on the test DB
- ASSERT_OK(createUser(kSpencerTest,
+ ASSERT_OK(createUser({"spencer", "test"},
{{"readWrite", "test"}, {"dbAdmin", "test"}, {"readWrite", "test"}}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
ASSERT_TRUE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::insert));
@@ -315,24 +299,14 @@ TEST_F(AuthorizationSessionTest, DuplicateRolesOK) {
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
}
-const UserName kRWTest("rw"_sd, "test"_sd);
-const UserName kUserAdminTest("useradmin"_sd, "test"_sd);
-const UserName kRWAnyTest("rwany"_sd, "test"_sd);
-const UserName kUserAdminAnyTest("useradminany"_sd, "test"_sd);
-
-const UserRequest kRWTestRequest(kRWTest, boost::none);
-const UserRequest kUserAdminTestRequest(kUserAdminTest, boost::none);
-const UserRequest kRWAnyTestRequest(kRWAnyTest, boost::none);
-const UserRequest kUserAdminAnyTestRequest(kUserAdminAnyTest, boost::none);
-
TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) {
- ASSERT_OK(createUser(kRWTest, {{"readWrite", "test"}, {"dbAdmin", "test"}}));
- ASSERT_OK(createUser(kUserAdminTest, {{"userAdmin", "test"}}));
- ASSERT_OK(createUser(kRWAnyTest,
+ ASSERT_OK(createUser({"rw", "test"}, {{"readWrite", "test"}, {"dbAdmin", "test"}}));
+ ASSERT_OK(createUser({"useradmin", "test"}, {{"userAdmin", "test"}}));
+ ASSERT_OK(createUser({"rwany", "test"},
{{"readWriteAnyDatabase", "admin"}, {"dbAdminAnyDatabase", "admin"}}));
- ASSERT_OK(createUser(kUserAdminAnyTest, {{"userAdminAnyDatabase", "admin"}}));
+ ASSERT_OK(createUser({"useradminany", "test"}, {{"userAdminAnyDatabase", "admin"}}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kRWAnyTestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("rwany", "test")));
ASSERT_FALSE(
authzSession->isAuthorizedForActionsOnResource(testUsersCollResource, ActionType::insert));
@@ -348,7 +322,7 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) {
authzSession->isAuthorizedForActionsOnResource(otherProfileCollResource, ActionType::find));
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUserAdminAnyTestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("useradminany", "test")));
ASSERT_FALSE(
authzSession->isAuthorizedForActionsOnResource(testUsersCollResource, ActionType::insert));
ASSERT_TRUE(
@@ -363,7 +337,7 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) {
authzSession->isAuthorizedForActionsOnResource(otherProfileCollResource, ActionType::find));
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kRWTestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("rw", "test")));
ASSERT_FALSE(
authzSession->isAuthorizedForActionsOnResource(testUsersCollResource, ActionType::insert));
@@ -379,7 +353,7 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) {
authzSession->isAuthorizedForActionsOnResource(otherProfileCollResource, ActionType::find));
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kUserAdminTestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("useradmin", "test")));
ASSERT_FALSE(
authzSession->isAuthorizedForActionsOnResource(testUsersCollResource, ActionType::insert));
ASSERT_FALSE(
@@ -397,15 +371,15 @@ TEST_F(AuthorizationSessionTest, SystemCollectionsAccessControl) {
TEST_F(AuthorizationSessionTest, InvalidateUser) {
// Add a readWrite user
- ASSERT_OK(createUser(kSpencerTest, {{"readWrite", "test"}}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_OK(createUser({"spencer", "test"}, {{"readWrite", "test"}}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
ASSERT_TRUE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::find));
ASSERT_TRUE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::insert));
- User* user = authzSession->lookupUser(kSpencerTest);
+ User* user = authzSession->lookupUser(UserName("spencer", "test"));
// Change the user to be read-only
int ignored;
@@ -414,7 +388,7 @@ TEST_F(AuthorizationSessionTest, InvalidateUser) {
BSONObj(),
BSONObj(),
&ignored));
- ASSERT_OK(createUser(kSpencerTest, {{"read", "test"}}));
+ ASSERT_OK(createUser({"spencer", "test"}, {{"read", "test"}}));
// Make sure that invalidating the user causes the session to reload its privileges.
authzManager->invalidateUserByName(_opCtx.get(), user->getName());
@@ -424,7 +398,7 @@ TEST_F(AuthorizationSessionTest, InvalidateUser) {
ASSERT_FALSE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::insert));
- user = authzSession->lookupUser(kSpencerTest);
+ user = authzSession->lookupUser(UserName("spencer", "test"));
// Delete the user.
ASSERT_OK(managerState->remove(_opCtx.get(),
@@ -439,21 +413,21 @@ TEST_F(AuthorizationSessionTest, InvalidateUser) {
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::find));
ASSERT_FALSE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::insert));
- ASSERT_FALSE(authzSession->lookupUser(kSpencerTest));
+ ASSERT_FALSE(authzSession->lookupUser(UserName("spencer", "test")));
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
}
TEST_F(AuthorizationSessionTest, UseOldUserInfoInFaceOfConnectivityProblems) {
// Add a readWrite user
- ASSERT_OK(createUser(kSpencerTest, {{"readWrite", "test"}}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_OK(createUser({"spencer", "test"}, {{"readWrite", "test"}}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
ASSERT_TRUE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::find));
ASSERT_TRUE(
authzSession->isAuthorizedForActionsOnResource(testFooCollResource, ActionType::insert));
- User* user = authzSession->lookupUser(kSpencerTest);
+ User* user = authzSession->lookupUser(UserName("spencer", "test"));
// Change the user to be read-only
int ignored;
@@ -463,7 +437,7 @@ TEST_F(AuthorizationSessionTest, UseOldUserInfoInFaceOfConnectivityProblems) {
BSONObj(),
BSONObj(),
&ignored));
- ASSERT_OK(createUser(kSpencerTest, {{"read", "test"}}));
+ ASSERT_OK(createUser({"spencer", "test"}, {{"read", "test"}}));
// Even though the user's privileges have been reduced, since we've configured user
// document lookup to fail, the authz session should continue to use its known out-of-date
@@ -517,7 +491,7 @@ TEST_F(AuthorizationSessionTest, AcquireUserObtainsAndValidatesAuthenticationRes
std::make_unique<RestrictionEnvironment>(
SockAddr::create(clientSource, 5555, AF_UNSPEC),
SockAddr::create(serverAddress, 27017, AF_UNSPEC)));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
};
@@ -526,11 +500,11 @@ TEST_F(AuthorizationSessionTest, AcquireUserObtainsAndValidatesAuthenticationRes
std::make_unique<RestrictionEnvironment>(
SockAddr::create(clientSource, 5555, AF_UNSPEC),
SockAddr::create(serverAddress, 27017, AF_UNSPEC)));
- ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
};
// The empty RestrictionEnvironment will cause addAndAuthorizeUser to fail.
- ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_NOT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
// A clientSource from the 192.168.0.0/24 block will succeed in connecting to a server
// listening on 192.168.0.2.
@@ -1085,26 +1059,28 @@ TEST_F(AuthorizationSessionTest, UnauthorizedSessionIsCoauthorizedWithNobody) {
}
TEST_F(AuthorizationSessionTest, UnauthorizedSessionIsNotCoauthorizedWithAnybody) {
- ASSERT_FALSE(authzSession->isCoauthorizedWith(kSpencerTest));
+ ASSERT_FALSE(authzSession->isCoauthorizedWith(UserName("spencer", "test")));
}
TEST_F(AuthorizationSessionTest, UnauthorizedSessionIsCoauthorizedWithAnybodyWhenAuthIsDisabled) {
authzManager->setAuthEnabled(false);
- ASSERT_TRUE(authzSession->isCoauthorizedWith(kSpencerTest));
+ ASSERT_TRUE(authzSession->isCoauthorizedWith(UserName("spencer", "test")));
}
TEST_F(AuthorizationSessionTest, AuthorizedSessionIsNotCoauthorizedNobody) {
- ASSERT_OK(createUser(kSpencerTest, {}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ UserName user("spencer", "test");
+ ASSERT_OK(createUser(user, {}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), user));
ASSERT_FALSE(authzSession->isCoauthorizedWith(boost::none));
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
}
TEST_F(AuthorizationSessionTest, AuthorizedSessionIsCoauthorizedNobodyWhenAuthIsDisabled) {
+ UserName user("spencer", "test");
authzManager->setAuthEnabled(false);
- ASSERT_OK(createUser(kSpencerTest, {}));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
- ASSERT_TRUE(authzSession->isCoauthorizedWith(kSpencerTest));
+ ASSERT_OK(createUser(user, {}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), user));
+ ASSERT_TRUE(authzSession->isCoauthorizedWith(user));
authzSession->logoutDatabase(_client.get(), "test", "Kill the test!");
}
@@ -1472,9 +1448,6 @@ TEST_F(SystemBucketsTest, CanCheckIfHasAnyPrivilegeInResourceDBForSystemBuckets)
ASSERT_TRUE(authzSession->isAuthorizedForAnyActionOnAnyResourceInDB(sb_db_other));
}
-const UserName kGMarksAdmin("gmarks"_sd, "admin"_sd);
-const UserRequest kGMarksAdminRequest(kGMarksAdmin, boost::none);
-
TEST_F(AuthorizationSessionTest, MayBypassWriteBlockingModeIsSetCorrectly) {
ASSERT_FALSE(authzSession->mayBypassWriteBlockingMode());
@@ -1490,7 +1463,7 @@ TEST_F(AuthorizationSessionTest, MayBypassWriteBlockingModeIsSetCorrectly) {
<< "db"
<< "test"))),
BSONObj()));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kSpencerTestRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("spencer", "test")));
ASSERT_FALSE(authzSession->mayBypassWriteBlockingMode());
// Add a user with restore role on admin db and ensure we can bypass
@@ -1507,7 +1480,7 @@ TEST_F(AuthorizationSessionTest, MayBypassWriteBlockingModeIsSetCorrectly) {
BSONObj()));
authzSession->logoutDatabase(_client.get(), "test", "End of test");
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kGMarksAdminRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("gmarks", "admin")));
ASSERT_TRUE(authzSession->mayBypassWriteBlockingMode());
// Remove that user by logging out of the admin db and ensure we can't bypass anymore
@@ -1529,7 +1502,7 @@ TEST_F(AuthorizationSessionTest, MayBypassWriteBlockingModeIsSetCorrectly) {
BSONObj()));
authzSession->logoutDatabase(_client.get(), "admin", "");
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), kAdminAdminRequest));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), UserName("admin", "admin")));
ASSERT_TRUE(authzSession->mayBypassWriteBlockingMode());
// Remove non-privileged user by logging out of test db and ensure we can still bypass
diff --git a/src/mongo/db/auth/authz_manager_external_state_local.cpp b/src/mongo/db/auth/authz_manager_external_state_local.cpp
index bf2b0238eac..9f98e5f7032 100644
--- a/src/mongo/db/auth/authz_manager_external_state_local.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_local.cpp
@@ -293,7 +293,7 @@ StatusWith<User> AuthzManagerExternalStateLocal::getUserObject(OperationContext*
const UserRequest& userReq) try {
const UserName& userName = userReq.name;
std::vector<RoleName> directRoles;
- User user(userReq);
+ User user(userReq.name);
auto rolesLock = _lockRoles(opCtx, userName.getTenant());
diff --git a/src/mongo/db/auth/authz_manager_external_state_s.cpp b/src/mongo/db/auth/authz_manager_external_state_s.cpp
index 4f415fd7247..61705c9c9b9 100644
--- a/src/mongo/db/auth/authz_manager_external_state_s.cpp
+++ b/src/mongo/db/auth/authz_manager_external_state_s.cpp
@@ -118,7 +118,7 @@ StatusWith<User> AuthzManagerExternalStateMongos::getUserObject(OperationContext
return status;
}
- User user(userReq);
+ User user(userReq.name);
V2UserDocumentParser dp;
dp.setTenantId(getActiveTenant(opCtx));
status = dp.initializeUserFromUserDocument(userDoc, &user);
diff --git a/src/mongo/db/auth/sasl_commands.cpp b/src/mongo/db/auth/sasl_commands.cpp
index 4d5755c5d95..5c00f9c23c9 100644
--- a/src/mongo/db/auth/sasl_commands.cpp
+++ b/src/mongo/db/auth/sasl_commands.cpp
@@ -184,9 +184,9 @@ SaslReply doSaslStep(OperationContext* opCtx,
}
if (mechanism.isSuccess()) {
- auto request = mechanism.getUserRequest();
+ UserName userName(mechanism.getPrincipalName(), mechanism.getAuthenticationDatabase());
uassertStatusOK(
- AuthorizationSession::get(opCtx->getClient())->addAndAuthorizeUser(opCtx, request));
+ AuthorizationSession::get(opCtx->getClient())->addAndAuthorizeUser(opCtx, userName));
if (!serverGlobalParams.quiet.load()) {
auto attrs = makeLogAttributes();
diff --git a/src/mongo/db/auth/sasl_mechanism_registry.cpp b/src/mongo/db/auth/sasl_mechanism_registry.cpp
index e49a1c07185..4ba33279435 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry.cpp
+++ b/src/mongo/db/auth/sasl_mechanism_registry.cpp
@@ -103,7 +103,7 @@ void SASLServerMechanismRegistry::advertiseMechanismNamesForUser(OperationContex
AuthorizationManager* authManager = AuthorizationManager::get(opCtx->getServiceContext());
UserHandle user;
- const auto swUser = authManager->acquireUser(opCtx, UserRequest(userName, boost::none));
+ const auto swUser = authManager->acquireUser(opCtx, userName);
if (!swUser.isOK()) {
auto& status = swUser.getStatus();
if (status.code() == ErrorCodes::UserNotFound) {
diff --git a/src/mongo/db/auth/sasl_mechanism_registry.h b/src/mongo/db/auth/sasl_mechanism_registry.h
index 2fe16292b80..06b0850125b 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry.h
+++ b/src/mongo/db/auth/sasl_mechanism_registry.h
@@ -206,10 +206,6 @@ public:
return Status::OK();
}
- virtual UserRequest getUserRequest() const {
- return UserRequest(UserName(getPrincipalName(), getAuthenticationDatabase()), boost::none);
- }
-
protected:
/**
* Mechanism provided step implementation.
diff --git a/src/mongo/db/auth/sasl_mechanism_registry_test.cpp b/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
index a7bb4d75440..2f39ddea4f0 100644
--- a/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
+++ b/src/mongo/db/auth/sasl_mechanism_registry_test.cpp
@@ -225,8 +225,7 @@ public:
<< "roles" << BSONArray()),
BSONObj()));
- UserRequest systemLocal(UserName("__system"_sd, "local"_sd), boost::none);
- internalSecurity.setUser(std::make_shared<UserHandle>(User(systemLocal)));
+ internalSecurity.setUser(std::make_shared<UserHandle>(User(UserName("__system", "local"))));
}
BSONObj getMechsFor(const UserName user) {
diff --git a/src/mongo/db/auth/sasl_plain_server_conversation.cpp b/src/mongo/db/auth/sasl_plain_server_conversation.cpp
index 8ec01b8f0c7..08401c59835 100644
--- a/src/mongo/db/auth/sasl_plain_server_conversation.cpp
+++ b/src/mongo/db/auth/sasl_plain_server_conversation.cpp
@@ -126,8 +126,7 @@ StatusWith<std::tuple<bool, std::string>> SASLPlainServerMechanism::stepImpl(
// The authentication database is also the source database for the user.
auto swUser = authManager->acquireUser(
- opCtx,
- UserRequest({ServerMechanismBase::_principalName, _authenticationDatabase}, boost::none));
+ opCtx, UserName(ServerMechanismBase::_principalName, _authenticationDatabase));
if (!swUser.isOK()) {
return swUser.getStatus();
diff --git a/src/mongo/db/auth/sasl_scram_server_conversation.cpp b/src/mongo/db/auth/sasl_scram_server_conversation.cpp
index 3271626aaf7..87ff7a789db 100644
--- a/src/mongo/db/auth/sasl_scram_server_conversation.cpp
+++ b/src/mongo/db/auth/sasl_scram_server_conversation.cpp
@@ -203,7 +203,7 @@ StatusWith<std::tuple<bool, std::string>> SaslSCRAMServerMechanism<Policy>::_fir
// The authentication database is also the source database for the user.
auto authManager = AuthorizationManager::get(opCtx->getServiceContext());
- auto swUser = authManager->acquireUser(opCtx, UserRequest(user, boost::none));
+ auto swUser = authManager->acquireUser(opCtx, user);
if (!swUser.isOK()) {
return swUser.getStatus();
}
diff --git a/src/mongo/db/auth/security_key_test.cpp b/src/mongo/db/auth/security_key_test.cpp
index 7a33cfbbad7..e64aded89f6 100644
--- a/src/mongo/db/auth/security_key_test.cpp
+++ b/src/mongo/db/auth/security_key_test.cpp
@@ -160,8 +160,7 @@ TEST(SecurityFile, Test) {
}
TEST(SecurityKey, Test) {
- UserRequest systemLocal(UserName("__system"_sd, "local"_sd), boost::none);
- internalSecurity.setUser(std::make_shared<UserHandle>(User(systemLocal)));
+ internalSecurity.setUser(std::make_shared<UserHandle>(User(UserName("__system", "local"))));
for (const auto& testCase : testCases) {
TestFile file(testCase.fileContents, testCase.mode != TestCase::FailureMode::Permissions);
diff --git a/src/mongo/db/auth/security_token_authentication_guard.cpp b/src/mongo/db/auth/security_token_authentication_guard.cpp
index a8f86fa240d..5be6de3dc75 100644
--- a/src/mongo/db/auth/security_token_authentication_guard.cpp
+++ b/src/mongo/db/auth/security_token_authentication_guard.cpp
@@ -41,9 +41,9 @@ namespace auth {
SecurityTokenAuthenticationGuard::SecurityTokenAuthenticationGuard(
OperationContext* opCtx, const ValidatedTenancyScope& token) {
if (token.hasAuthenticatedUser()) {
- UserRequest request(token.authenticatedUser(), boost::none);
+ const auto& userName = token.authenticatedUser();
auto* client = opCtx->getClient();
- uassertStatusOK(AuthorizationSession::get(client)->addAndAuthorizeUser(opCtx, request));
+ uassertStatusOK(AuthorizationSession::get(client)->addAndAuthorizeUser(opCtx, userName));
_client = client;
LOGV2_DEBUG(5838100,
diff --git a/src/mongo/db/auth/user.cpp b/src/mongo/db/auth/user.cpp
index c50de72a546..a80e833c9e7 100644
--- a/src/mongo/db/auth/user.cpp
+++ b/src/mongo/db/auth/user.cpp
@@ -66,8 +66,8 @@ SHA256Block computeDigest(const UserName& name) {
} // namespace
-User::User(UserRequest request)
- : _request(std::move(request)), _isInvalidated(false), _digest(computeDigest(_request.name)) {}
+User::User(const UserName& name)
+ : _name(name), _isInvalidated(false), _digest(computeDigest(_name)) {}
template <>
User::SCRAMCredentials<SHA1Block>& User::CredentialData::scram<SHA1Block>() {
@@ -201,10 +201,10 @@ void User::reportForUsersInfo(BSONObjBuilder* builder,
bool showCredentials,
bool showPrivileges,
bool showAuthenticationRestrictions) const {
- builder->append(kIdFieldName, getName().getUnambiguousName());
+ builder->append(kIdFieldName, _name.getUnambiguousName());
UUID::fromCDR(ConstDataRange(_id)).appendToBuilder(builder, kUserIdFieldName);
- builder->append(kUserFieldName, getName().getUser());
- builder->append(kDbFieldName, getName().getDB());
+ builder->append(kUserFieldName, _name.getUser());
+ builder->append(kDbFieldName, _name.getDB());
BSONArrayBuilder mechanismNamesBuilder(builder->subarrayStart(kMechanismsFieldName));
for (const StringData& mechanism : _credentials.toMechanismsVector()) {
diff --git a/src/mongo/db/auth/user.h b/src/mongo/db/auth/user.h
index 83dcc398775..52b9e4e38d9 100644
--- a/src/mongo/db/auth/user.h
+++ b/src/mongo/db/auth/user.h
@@ -47,36 +47,6 @@
namespace mongo {
/**
- * Represents the properties required to request a UserHandle.
- * This type is hashable and may be used as a key describing requests
- */
-struct UserRequest {
- UserRequest(UserName name, boost::optional<std::set<RoleName>> roles)
- : name(std::move(name)), roles(std::move(roles)) {}
-
-
- template <typename H>
- friend H AbslHashValue(H h, const UserRequest& key) {
- auto state = H::combine(std::move(h), key.name);
- if (key.roles) {
- for (const auto& role : *key.roles) {
- state = H::combine(std::move(state), role);
- }
- }
- return state;
- }
-
- bool operator==(const UserRequest& key) const {
- return name == key.name && roles == key.roles;
- }
-
- // The name of the requested user
- UserName name;
- // Any authorization grants which should override and be used in favor of roles acquisition.
- boost::optional<std::set<RoleName>> roles;
-};
-
-/**
* Represents a MongoDB user. Stores information about the user necessary for access control
* checks and authentications, such as what privileges this user has, as well as what roles
* the user belongs to.
@@ -188,7 +158,7 @@ public:
using ResourcePrivilegeMap = stdx::unordered_map<ResourcePattern, Privilege>;
- explicit User(UserRequest request);
+ explicit User(const UserName& name);
User(User&&) = default;
User& operator=(User&&) = default;
@@ -200,15 +170,11 @@ public:
_id = std::move(id);
}
- const UserRequest& getUserRequest() const {
- return _request;
- }
-
/**
* Returns the user name for this user.
*/
const UserName& getName() const {
- return _request.name;
+ return _name;
}
/**
@@ -360,8 +326,8 @@ private:
// Unique ID (often UUID) for this user. May be empty for legacy users.
UserId _id;
- // The original UserRequest which resolved into this user
- UserRequest _request;
+ // The full user name (as specified by the administrator)
+ UserName _name;
// User was explicitly invalidated
bool _isInvalidated;
@@ -388,6 +354,36 @@ private:
RestrictionDocuments _indirectRestrictions;
};
+/**
+ * Represents the properties required to request a UserHandle.
+ * This type is hashable and may be used as a key describing requests
+ */
+struct UserRequest {
+ UserRequest(const UserName& name, boost::optional<std::set<RoleName>> roles)
+ : name(name), roles(std::move(roles)) {}
+
+
+ template <typename H>
+ friend H AbslHashValue(H h, const UserRequest& key) {
+ auto state = H::combine(std::move(h), key.name);
+ if (key.roles) {
+ for (const auto& role : *key.roles) {
+ state = H::combine(std::move(state), role);
+ }
+ }
+ return state;
+ }
+
+ bool operator==(const UserRequest& key) const {
+ return name == key.name && roles == key.roles;
+ }
+
+ // The name of the requested user
+ UserName name;
+ // Any authorization grants which should override and be used in favor of roles acquisition.
+ boost::optional<std::set<RoleName>> roles;
+};
+
using UserCache = ReadThroughCache<UserRequest, User>;
using UserHandle = UserCache::ValueHandle;
diff --git a/src/mongo/db/auth/user_document_parser_test.cpp b/src/mongo/db/auth/user_document_parser_test.cpp
index 9773927ad50..00ff394a222 100644
--- a/src/mongo/db/auth/user_document_parser_test.cpp
+++ b/src/mongo/db/auth/user_document_parser_test.cpp
@@ -63,8 +63,8 @@ public:
BSONObj sha1_creds, sha256_creds;
void setUp() {
- user.reset(new User(UserRequest(UserName("spencer", "test"), boost::none)));
- adminUser.reset(new User(UserRequest(UserName("admin", "admin"), boost::none)));
+ user.reset(new User(UserName("spencer", "test")));
+ adminUser.reset(new User(UserName("admin", "admin")));
sha1_creds = scram::Secrets<SHA1Block>::generateCredentials(
"a", saslGlobalParams.scramSHA1IterationCount.load());
diff --git a/src/mongo/db/auth/validated_tenancy_scope_test.cpp b/src/mongo/db/auth/validated_tenancy_scope_test.cpp
index 66c48653916..94b35e9626b 100644
--- a/src/mongo/db/auth/validated_tenancy_scope_test.cpp
+++ b/src/mongo/db/auth/validated_tenancy_scope_test.cpp
@@ -48,7 +48,7 @@ public:
* Synthesize a user with the useTenant privilege and add them to the authorization session.
*/
static void grantUseTenant(Client& client) {
- User user(UserRequest(UserName("useTenant"_sd, "admin"_sd), boost::none));
+ User user(UserName("useTenant", "admin"));
user.setPrivileges(
{Privilege(ResourcePattern::forClusterResource(), ActionType::useTenant)});
auto* as = dynamic_cast<AuthorizationSessionImpl*>(AuthorizationSession::get(client));
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index 143fdd94491..052dfba1186 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -176,7 +176,6 @@ env.Library(
'$BUILD_DIR/mongo/db/auth/auth',
'$BUILD_DIR/mongo/db/auth/auth_options',
'$BUILD_DIR/mongo/db/auth/authentication_session',
- '$BUILD_DIR/mongo/db/auth/authorization_manager_global',
'$BUILD_DIR/mongo/db/auth/cluster_auth_mode',
'$BUILD_DIR/mongo/db/commands',
'$BUILD_DIR/mongo/db/server_base',
diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp
index 8feb2d6320c..7c2c5d231a9 100644
--- a/src/mongo/db/commands/authentication_commands.cpp
+++ b/src/mongo/db/commands/authentication_commands.cpp
@@ -44,7 +44,6 @@
#include "mongo/config.h"
#include "mongo/db/auth/auth_options_gen.h"
#include "mongo/db/auth/authentication_session.h"
-#include "mongo/db/auth/authorization_manager_global_parameters_gen.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/cluster_auth_mode.h"
#include "mongo/db/auth/privilege.h"
@@ -243,7 +242,7 @@ void _authenticateX509(OperationContext* opCtx, AuthenticationSession* session)
"No verified subject name available from client",
!clientName.empty());
- UserName userName = ([&] {
+ auto user = [&] {
if (session->getUserName().empty()) {
auto user = UserName(clientName.toString(), session->getDatabase().toString());
session->updateUserName(user);
@@ -254,7 +253,7 @@ void _authenticateX509(OperationContext* opCtx, AuthenticationSession* session)
session->getUserName() == clientName.toString());
return UserName(session->getUserName().toString(), session->getDatabase().toString());
}
- })();
+ }();
uassert(ErrorCodes::ProtocolError,
"SSL support is required for the MONGODB-X509 mechanism.",
@@ -270,7 +269,7 @@ void _authenticateX509(OperationContext* opCtx, AuthenticationSession* session)
uassert(ErrorCodes::ProtocolError,
"X.509 authentication must always use the $external database.",
- userName.getDB() == kExternalDB);
+ user.getDB() == kExternalDB);
auto isInternalClient = [&]() -> bool {
return opCtx->getClient()->session()->getTags() & transport::Session::kInternalClient;
@@ -278,27 +277,11 @@ void _authenticateX509(OperationContext* opCtx, AuthenticationSession* session)
const auto clusterAuthMode = ClusterAuthMode::get(opCtx->getServiceContext());
- boost::optional<std::set<RoleName>> roles;
- if (allowRolesFromX509Certificates) {
- auto& sslPeerInfo = SSLPeerInfo::forSession(opCtx->getClient()->session());
- if (!sslPeerInfo.roles.empty() &&
- (sslPeerInfo.subjectName.toString() == userName.getUser())) {
- 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(*roles, roles->begin()));
- }
- }
- UserRequest request(std::move(userName), std::move(roles));
-
auto authorizeExternalUser = [&] {
uassert(ErrorCodes::BadValue,
kX509AuthenticationDisabledMessage,
!isX509AuthDisabled(opCtx->getServiceContext()));
- uassertStatusOK(authorizationSession->addAndAuthorizeUser(opCtx, request));
+ uassertStatusOK(authorizationSession->addAndAuthorizeUser(opCtx, user));
};
if (sslConfiguration->isClusterMember(clientName)) {
diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp
index 409a2883fd3..328b214ae5e 100644
--- a/src/mongo/db/commands/user_management_commands.cpp
+++ b/src/mongo/db/commands/user_management_commands.cpp
@@ -139,7 +139,7 @@ Status getCurrentUserRoles(OperationContext* opCtx,
AuthorizationManager* authzManager,
const UserName& userName,
stdx::unordered_set<RoleName>* roles) {
- auto swUser = authzManager->acquireUser(opCtx, UserRequest(userName, boost::none));
+ auto swUser = authzManager->acquireUser(opCtx, userName);
if (!swUser.isOK()) {
return swUser.getStatus();
}
@@ -1385,8 +1385,7 @@ UsersInfoReply CmdUMCTyped<UsersInfoCommand, UMCInfoParams>::Invocation::typedRu
} else {
// Custom data is not required in the output, so it can be generated from a cached
// user object.
- auto swUserHandle =
- authzManager->acquireUser(opCtx, UserRequest(userName, boost::none));
+ auto swUserHandle = authzManager->acquireUser(opCtx, userName);
if (swUserHandle.getStatus().code() == ErrorCodes::UserNotFound) {
continue;
}
diff --git a/src/mongo/db/session/SConscript b/src/mongo/db/session/SConscript
index a0021e3ac81..9862c8a660b 100644
--- a/src/mongo/db/session/SConscript
+++ b/src/mongo/db/session/SConscript
@@ -155,7 +155,6 @@ env.Library(
'$BUILD_DIR/mongo/db/api_parameters',
'$BUILD_DIR/mongo/db/auth/auth',
'$BUILD_DIR/mongo/db/auth/authprivilege',
- '$BUILD_DIR/mongo/db/auth/user',
'$BUILD_DIR/mongo/idl/idl_parser',
'$BUILD_DIR/mongo/rpc/client_metadata',
'logical_session_id_helpers',
diff --git a/src/mongo/db/session/kill_sessions.cpp b/src/mongo/db/session/kill_sessions.cpp
index 99d8fd5122a..7626afa111b 100644
--- a/src/mongo/db/session/kill_sessions.cpp
+++ b/src/mongo/db/session/kill_sessions.cpp
@@ -109,8 +109,12 @@ KillAllSessionsByPatternItem makeKillAllSessionsByPattern(OperationContext* opCt
const KillAllSessionsUser& kasu) {
KillAllSessionsByPatternItem item = makeKillAllSessionsByPattern(opCtx);
- User user(UserRequest(UserName(kasu.getUser(), kasu.getDb()), boost::none));
- item.pattern.setUid(user.getDigest());
+ auto authMgr = AuthorizationManager::get(opCtx->getServiceContext());
+
+ UserName un(kasu.getUser(), kasu.getDb());
+
+ auto user = uassertStatusOK(authMgr->acquireUser(opCtx, un));
+ item.pattern.setUid(user->getDigest());
return item;
}
diff --git a/src/mongo/db/session/logical_session_id_test.cpp b/src/mongo/db/session/logical_session_id_test.cpp
index 1142e4335ef..736525ecf0f 100644
--- a/src/mongo/db/session/logical_session_id_test.cpp
+++ b/src/mongo/db/session/logical_session_id_test.cpp
@@ -111,7 +111,7 @@ public:
<< "db"
<< "test"))),
BSONObj()));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {un, boost::none}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), un));
return authzSession->lookupUser(un);
}
@@ -126,7 +126,7 @@ public:
<< "db"
<< "admin"))),
BSONObj()));
- ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), {un, boost::none}));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(_opCtx.get(), un));
return authzSession->lookupUser(un);
}
};
diff --git a/src/mongo/embedded/embedded_auth_manager.cpp b/src/mongo/embedded/embedded_auth_manager.cpp
index 255fc535210..ec2c7dc9184 100644
--- a/src/mongo/embedded/embedded_auth_manager.cpp
+++ b/src/mongo/embedded/embedded_auth_manager.cpp
@@ -108,7 +108,7 @@ public:
UASSERT_NOT_IMPLEMENTED;
}
- StatusWith<UserHandle> acquireUser(OperationContext*, const UserRequest&) override {
+ StatusWith<UserHandle> acquireUser(OperationContext*, const UserName&) override {
UASSERT_NOT_IMPLEMENTED;
}
diff --git a/src/mongo/embedded/embedded_auth_session.cpp b/src/mongo/embedded/embedded_auth_session.cpp
index cae0689cb44..d086a0a3309 100644
--- a/src/mongo/embedded/embedded_auth_session.cpp
+++ b/src/mongo/embedded/embedded_auth_session.cpp
@@ -70,7 +70,7 @@ public:
void startContractTracking() override {}
- Status addAndAuthorizeUser(OperationContext*, const UserRequest&) override {
+ Status addAndAuthorizeUser(OperationContext*, const UserName&) override {
UASSERT_NOT_IMPLEMENTED;
}
diff --git a/src/mongo/rpc/op_msg_test.cpp b/src/mongo/rpc/op_msg_test.cpp
index df6aa2e04a3..d5287b18144 100644
--- a/src/mongo/rpc/op_msg_test.cpp
+++ b/src/mongo/rpc/op_msg_test.cpp
@@ -61,7 +61,7 @@ public:
* Synthesize a user with the useTenant privilege and add them to the authorization session.
*/
static void grantUseTenant(Client& client) {
- User user(UserRequest(UserName("useTenant", "admin"), boost::none));
+ User user(UserName("useTenant", "admin"));
user.setPrivileges(
{Privilege(ResourcePattern::forClusterResource(), ActionType::useTenant)});
auto* as = dynamic_cast<AuthorizationSessionImpl*>(AuthorizationSession::get(client));
diff --git a/src/mongo/util/net/network_interface_ssl_test.cpp b/src/mongo/util/net/network_interface_ssl_test.cpp
index cc4fae14287..fadbb694257 100644
--- a/src/mongo/util/net/network_interface_ssl_test.cpp
+++ b/src/mongo/util/net/network_interface_ssl_test.cpp
@@ -60,8 +60,7 @@ public:
NetworkInterfaceIntegrationFixture::setUp();
// Setup an internal user so that we can use it for external auth
- UserRequest systemLocal(UserName("__system"_sd, "local"_sd), boost::none);
- auto user = std::make_shared<UserHandle>(User(systemLocal));
+ auto user = std::make_shared<UserHandle>(User(UserName("__system", "local")));
internalSecurity.setUser(user);