summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2013-08-12 18:18:08 -0400
committerSpencer T Brody <spencer@10gen.com>2013-08-19 17:03:51 -0400
commite8a98c47fcf80829adae349c09efa1f6e2e1d9af (patch)
treed84947d9f8dd2acc90fbf3a819b39d84e8921916 /src/mongo
parent4140e3743026af40d83b29f10cfbc6d7cd8505fa (diff)
downloadmongo-e8a98c47fcf80829adae349c09efa1f6e2e1d9af.tar.gz
SERVER-9518 Reload User if User has been invalidated
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp16
-rw-r--r--src/mongo/db/auth/authorization_manager.h5
-rw-r--r--src/mongo/db/auth/authorization_session.cpp16
-rw-r--r--src/mongo/db/auth/authorization_session_test.cpp27
4 files changed, 63 insertions, 1 deletions
diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp
index b4903730b45..102ac60bed6 100644
--- a/src/mongo/db/auth/authorization_manager.cpp
+++ b/src/mongo/db/auth/authorization_manager.cpp
@@ -731,6 +731,22 @@ namespace {
}
}
+ void AuthorizationManager::invalidateUser(User* user) {
+ boost::lock_guard<boost::mutex> lk(_lock);
+ if (!user->isValid()) {
+ return;
+ }
+
+ unordered_map<UserName, User*>::iterator it = _userCache.find(user->getName());
+ massert(17052,
+ mongoutils::str::stream() <<
+ "Invalidating cache for user " << user->getName().toString() <<
+ " failed as it is not present in the user cache",
+ it != _userCache.end() && it->second == user);
+ _userCache.erase(it);
+ user->invalidate();
+ }
+
void AuthorizationManager::addInternalUser(User* user) {
boost::lock_guard<boost::mutex> lk(_lock);
_userCache.insert(make_pair(user->getName(), user));
diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h
index c206f0299e0..7f00c0d902d 100644
--- a/src/mongo/db/auth/authorization_manager.h
+++ b/src/mongo/db/auth/authorization_manager.h
@@ -146,6 +146,11 @@ namespace mongo {
void releaseUser(User* user);
/**
+ * Marks the given user as invalid and removes it from the user cache.
+ */
+ void invalidateUser(User* user);
+
+ /**
* Inserts the given user directly into the _userCache. Used to add the internalSecurity
* user into the cache at process startup.
*/
diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp
index 6c89fbbef84..5358d5c90f0 100644
--- a/src/mongo/db/auth/authorization_session.cpp
+++ b/src/mongo/db/auth/authorization_session.cpp
@@ -356,7 +356,21 @@ namespace {
it != _authenticatedUsers.end(); ++it) {
User* user = *it;
- // TODO(spencer): Handle if the user has been invalidated.
+ if (!user->isValid()) {
+ // Need to release and re-acquire user if it's been invalidated.
+ UserName name = user->getName();
+
+ _authenticatedUsers.removeByDBName(name.getDB());
+ getAuthorizationManager().releaseUser(user);
+
+ Status status = getAuthorizationManager().acquireUser(name, &user);
+ if (!status.isOK()) {
+ return Status(ErrorCodes::Unauthorized,
+ mongoutils::str::stream() << "Re-acquiring invalidated user "
+ "failed due to: " << status.reason());
+ }
+ _authenticatedUsers.add(user);
+ }
for (int i = 0; i < static_cast<int>(boost::size(resourceSearchList)); ++i) {
ActionSet userActions = user->getActionsForResource(resourceSearchList[i]);
diff --git a/src/mongo/db/auth/authorization_session_test.cpp b/src/mongo/db/auth/authorization_session_test.cpp
index 6a473091729..6000e616368 100644
--- a/src/mongo/db/auth/authorization_session_test.cpp
+++ b/src/mongo/db/auth/authorization_session_test.cpp
@@ -101,6 +101,33 @@ namespace {
ASSERT_FALSE(authzSession->checkAuthorization("test.foo", ActionType::collMod));
}
+ TEST_F(AuthorizationSessionTest, InvalidateUser) {
+ // Add a readWrite user
+ ASSERT_OK(managerState->insertPrivilegeDocument("test",
+ BSON("user" << "spencer" <<
+ "pwd" << "a" <<
+ "roles" << BSON_ARRAY("readWrite"))));
+ ASSERT_OK(authzSession->addAndAuthorizeUser(UserName("spencer", "test")));
+
+ ASSERT_TRUE(authzSession->checkAuthorization("test", ActionType::find));
+ ASSERT_TRUE(authzSession->checkAuthorization("test", ActionType::insert));
+
+ User* user = authzSession->lookupUser(UserName("spencer", "test"));
+ ASSERT(user->isValid());
+
+ // Change the user to be read-only
+ managerState->clearPrivilegeDocuments();
+ ASSERT_OK(managerState->insertPrivilegeDocument("test",
+ BSON("user" << "spencer" <<
+ "pwd" << "a" <<
+ "roles" << BSON_ARRAY("read"))));
+
+ // Make sure that invalidating the user causes the session to reload its privileges.
+ authzManager->invalidateUser(user);
+ ASSERT_TRUE(authzSession->checkAuthorization("test", ActionType::find));
+ ASSERT_FALSE(authzSession->checkAuthorization("test", ActionType::insert));
+ }
+
TEST_F(AuthorizationSessionTest, ImplicitAcquireFromSomeDatabasesWithV1Users) {
managerState->insertPrivilegeDocument("test",