summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mongo/db/auth/SConscript5
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp176
-rw-r--r--src/mongo/db/auth/authorization_manager.h33
-rw-r--r--src/mongo/db/auth/authorization_manager_test.cpp428
-rw-r--r--src/mongo/db/auth/authorization_session.cpp107
-rw-r--r--src/mongo/db/auth/authorization_session.h35
-rw-r--r--src/mongo/db/auth/authz_session_external_state.h2
-rw-r--r--src/mongo/db/auth/authz_session_external_state_d.cpp2
-rw-r--r--src/mongo/db/auth/authz_session_external_state_d.h2
-rw-r--r--src/mongo/db/auth/authz_session_external_state_mock.h2
-rw-r--r--src/mongo/db/auth/authz_session_external_state_s.cpp2
-rw-r--r--src/mongo/db/auth/authz_session_external_state_s.h2
-rw-r--r--src/mongo/db/auth/principal.cpp44
-rw-r--r--src/mongo/db/auth/principal.h65
-rw-r--r--src/mongo/db/auth/principal_set.cpp82
-rw-r--r--src/mongo/db/auth/principal_set.h106
-rw-r--r--src/mongo/db/auth/principal_set_test.cpp97
-rw-r--r--src/mongo/db/auth/privilege.cpp1
-rw-r--r--src/mongo/db/auth/privilege.h1
-rw-r--r--src/mongo/db/auth/privilege_set.cpp143
-rw-r--r--src/mongo/db/auth/privilege_set.h137
-rw-r--r--src/mongo/db/auth/privilege_set_test.cpp211
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp2
-rw-r--r--src/mongo/db/dbeval.cpp1
-rw-r--r--src/mongo/db/dbwebserver.cpp1
-rw-r--r--src/mongo/db/repl/rs.cpp1
26 files changed, 234 insertions, 1454 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript
index 39ede94e793..26748a9e8b3 100644
--- a/src/mongo/db/auth/SConscript
+++ b/src/mongo/db/auth/SConscript
@@ -14,10 +14,7 @@ env.StaticLibrary('authcore', ['action_set.cpp',
'authorization_session.cpp',
'authz_manager_external_state.cpp',
'authz_session_external_state.cpp',
- 'principal.cpp',
- 'principal_set.cpp',
'privilege.cpp',
- 'privilege_set.cpp',
'role_graph.cpp',
'role_name.cpp',
'user.cpp',
@@ -50,8 +47,6 @@ env.StaticLibrary('authmocks',
LIBDEPS=['$BUILD_DIR/mongo/expressions'])
env.CppUnitTest('action_set_test', 'action_set_test.cpp', LIBDEPS=['authcore'])
-env.CppUnitTest('principal_set_test', 'principal_set_test.cpp', LIBDEPS=['authcore'])
-env.CppUnitTest('privilege_set_test', 'privilege_set_test.cpp', LIBDEPS=['authcore'])
env.CppUnitTest('role_graph_test', 'role_graph_test.cpp', LIBDEPS=['authcore'])
env.CppUnitTest('user_set_test', 'user_set_test.cpp', LIBDEPS=['authcore'])
env.CppUnitTest('authorization_manager_test', 'authorization_manager_test.cpp',
diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp
index 21722d2fcf9..3ef9d841c2b 100644
--- a/src/mongo/db/auth/authorization_manager.cpp
+++ b/src/mongo/db/auth/authorization_manager.cpp
@@ -27,7 +27,6 @@
#include "mongo/base/status.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/auth/privilege_set.h"
#include "mongo/db/auth/user.h"
#include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user_name_hash.h"
@@ -471,63 +470,6 @@ namespace {
return Status::OK();
}
- Status AuthorizationManager::buildPrivilegeSet(const std::string& dbname,
- const UserName& user,
- const BSONObj& privilegeDocument,
- PrivilegeSet* result) const {
- if (!privilegeDocument.hasField(ROLES_FIELD_NAME)) {
- // Old-style (v2.2 and prior) privilege document
- if (AuthorizationManager::getSupportOldStylePrivilegeDocuments()) {
- return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname,
- user,
- privilegeDocument,
- result);
- }
- else {
- return _oldPrivilegeFormatNotSupported();
- }
- }
- else {
- return _buildPrivilegeSetFromExtendedPrivilegeDocument(
- dbname, user, privilegeDocument, result);
- }
- }
-
- Status AuthorizationManager::_buildPrivilegeSetFromOldStylePrivilegeDocument(
- const std::string& dbname,
- const UserName& user,
- const BSONObj& privilegeDocument,
- PrivilegeSet* result) const {
- if (!(privilegeDocument.hasField(AuthorizationManager::USER_NAME_FIELD_NAME) &&
- privilegeDocument.hasField(AuthorizationManager::PASSWORD_FIELD_NAME))) {
-
- return Status(ErrorCodes::UnsupportedFormat,
- mongoutils::str::stream() << "Invalid old-style privilege document "
- "received when trying to extract privileges: "
- << privilegeDocument,
- 0);
- }
- std::string userName = privilegeDocument[AuthorizationManager::USER_NAME_FIELD_NAME].str();
- if (userName != user.getUser()) {
- return Status(ErrorCodes::BadValue,
- mongoutils::str::stream() << "Principal name from privilege document \""
- << userName
- << "\" doesn't match name of provided Principal \""
- << user.getUser()
- << "\"",
- 0);
- }
-
- bool readOnly = privilegeDocument[READONLY_FIELD_NAME].trueValue();
- ActionSet actions = getActionsForOldStyleUser(dbname, readOnly);
- std::string resourceName = (dbname == ADMIN_DBNAME || dbname == LOCAL_DBNAME) ?
- AuthorizationManager::WILDCARD_RESOURCE_NAME : dbname;
- result->grantPrivilege(Privilege(resourceName, actions), user);
-
- return Status::OK();
- }
-
-
/**
* Adds to "outPrivileges" the privileges associated with having the named "role" on "dbname".
*
@@ -593,90 +535,6 @@ namespace {
}
}
- /**
- * Given a database name and a BSONElement representing an array of roles, populates
- * "outPrivileges" with the privileges associated with the given roles on the named database.
- *
- * Returns Status::OK() on success.
- */
- Status _getPrivilegesFromRoles(const std::string& dbname,
- const BSONElement& rolesElement,
- std::vector<Privilege>* outPrivileges) {
-
- static const char privilegesTypeMismatchMessage[] =
- "Roles must be enumerated in an array of strings.";
-
- if (dbname == AuthorizationManager::WILDCARD_RESOURCE_NAME) {
- return Status(ErrorCodes::BadValue,
- AuthorizationManager::WILDCARD_RESOURCE_NAME +
- " is an invalid database name.");
- }
-
- if (rolesElement.type() != Array)
- return Status(ErrorCodes::TypeMismatch, privilegesTypeMismatchMessage);
-
- for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) {
- BSONElement roleElement = *iter;
- if (roleElement.type() != String)
- return Status(ErrorCodes::TypeMismatch, privilegesTypeMismatchMessage);
- _addPrivilegesForSystemRole(dbname, roleElement.str(), outPrivileges);
- }
- return Status::OK();
- }
-
- Status AuthorizationManager::_buildPrivilegeSetFromExtendedPrivilegeDocument(
- const std::string& dbname,
- const UserName& user,
- const BSONObj& privilegeDocument,
- PrivilegeSet* result) const {
-
- if (!privilegeDocument[READONLY_FIELD_NAME].eoo()) {
- return Status(ErrorCodes::UnsupportedFormat,
- "Privilege documents may not contain both \"readonly\" and "
- "\"roles\" fields");
- }
-
- std::vector<Privilege> acquiredPrivileges;
-
- // Acquire privileges on "dbname".
- Status status = _getPrivilegesFromRoles(
- dbname, privilegeDocument[ROLES_FIELD_NAME], &acquiredPrivileges);
- if (!status.isOK())
- return status;
-
- // If "dbname" is the admin database, handle the otherDBPrivileges field, which
- // grants privileges on databases other than "dbname".
- BSONElement otherDbPrivileges = privilegeDocument[OTHER_DB_ROLES_FIELD_NAME];
- if (dbname == ADMIN_DBNAME) {
- switch (otherDbPrivileges.type()) {
- case EOO:
- break;
- case Object: {
- for (BSONObjIterator iter(otherDbPrivileges.embeddedObject());
- iter.more(); iter.next()) {
-
- BSONElement rolesElement = *iter;
- status = _getPrivilegesFromRoles(
- rolesElement.fieldName(), rolesElement, &acquiredPrivileges);
- if (!status.isOK())
- return status;
- }
- break;
- }
- default:
- return Status(ErrorCodes::TypeMismatch,
- "Field \"otherDBRoles\" must be an object, if present.");
- }
- }
- else if (!otherDbPrivileges.eoo()) {
- return Status(ErrorCodes::BadValue, "Only the admin database may contain a field "
- "called \"otherDBRoles\"");
- }
-
- result->grantPrivileges(acquiredPrivileges, user);
- return Status::OK();
- }
-
Status AuthorizationManager::acquireUser(const UserName& userName, User** acquiredUser) {
boost::lock_guard<boost::mutex> lk(_lock);
unordered_map<UserName, User*>::iterator it = _userCache.find(userName);
@@ -764,21 +622,21 @@ namespace {
*/
Status _initializeUserCredentialsFromPrivilegeDocument(User* user, const BSONObj& privDoc) {
User::CredentialData credentials;
- if (privDoc.hasField("pwd")) {
- credentials.password = privDoc["pwd"].String();
+ if (privDoc.hasField(AuthorizationManager::PASSWORD_FIELD_NAME)) {
+ credentials.password = privDoc[AuthorizationManager::PASSWORD_FIELD_NAME].String();
credentials.isExternal = false;
}
- else if (privDoc.hasField("userSource")) {
- std::string userSource = privDoc["userSource"].String();
+ else if (privDoc.hasField(AuthorizationManager::USER_SOURCE_FIELD_NAME)) {
+ std::string userSource = privDoc[AuthorizationManager::USER_SOURCE_FIELD_NAME].String();
if (userSource != "$external") {
- return Status(ErrorCodes::FailedToParse,
+ return Status(ErrorCodes::UnsupportedFormat,
"Cannot extract credentials from user documents without a password "
"and with userSource != \"$external\"");
} else {
credentials.isExternal = true;
}
} else {
- return Status(ErrorCodes::FailedToParse,
+ return Status(ErrorCodes::UnsupportedFormat,
"Invalid user document: must have one of \"pwd\" and \"userSource\"");
}
@@ -831,6 +689,13 @@ namespace {
Status _initializeUserRolesFromV1PrivilegeDocument(
User* user, const BSONObj& privDoc, const StringData& dbname) {
+
+ if (!privDoc[READONLY_FIELD_NAME].eoo()) {
+ return Status(ErrorCodes::UnsupportedFormat,
+ "Privilege documents may not contain both \"readonly\" and "
+ "\"roles\" fields");
+ }
+
Status status = _initializeUserRolesFromV1RolesArray(user,
privDoc[ROLES_FIELD_NAME],
dbname);
@@ -864,8 +729,8 @@ namespace {
}
}
else if (!otherDbPrivileges.eoo()) {
- return Status(ErrorCodes::BadValue, "Only the admin database may contain a field "
- "called \"otherDBRoles\"");
+ return Status(ErrorCodes::UnsupportedFormat,
+ "Only the admin database may contain a field called \"otherDBRoles\"");
}
return Status::OK();
@@ -906,6 +771,17 @@ namespace {
Status AuthorizationManager::_initializeUserFromPrivilegeDocument(
User* user, const BSONObj& privDoc) const {
+ std::string userName = privDoc[AuthorizationManager::USER_NAME_FIELD_NAME].str();
+ if (userName != user->getName().getUser()) {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream() << "User name from privilege document \""
+ << userName
+ << "\" doesn't match name of provided User \""
+ << user->getName().getUser()
+ << "\"",
+ 0);
+ }
+
Status status = _initializeUserCredentialsFromPrivilegeDocument(user, privDoc);
if (!status.isOK()) {
return status;
diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h
index 8f1de7a9474..fa169ca473d 100644
--- a/src/mongo/db/auth/authorization_manager.h
+++ b/src/mongo/db/auth/authorization_manager.h
@@ -24,7 +24,6 @@
#include "mongo/base/status.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/authz_manager_external_state.h"
-#include "mongo/db/auth/privilege_set.h"
#include "mongo/db/auth/user.h"
#include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user_name_hash.h"
@@ -113,13 +112,6 @@ namespace mongo {
// Returns Status::OK() if the document is good, or Status(ErrorCodes::BadValue), otherwise.
Status checkValidPrivilegeDocument(const StringData& dbname, const BSONObj& doc);
- // Parses the privilege document and returns a PrivilegeSet of all the Privileges that
- // the privilege document grants.
- Status buildPrivilegeSet(const std::string& dbname,
- const UserName& user,
- const BSONObj& privilegeDocument,
- PrivilegeSet* result) const;
-
// Given a database name and a readOnly flag return an ActionSet describing all the actions
// that an old-style user with those attributes should be given.
ActionSet getActionsForOldStyleUser(const std::string& dbname, bool readOnly) const;
@@ -170,34 +162,17 @@ namespace mongo {
*/
Status initializeAllV1UserData();
- private:
-
- // Parses the old-style (pre 2.4) privilege document and returns a PrivilegeSet of all the
- // Privileges that the privilege document grants.
- Status _buildPrivilegeSetFromOldStylePrivilegeDocument(
- const std::string& dbname,
- const UserName& user,
- const BSONObj& privilegeDocument,
- PrivilegeSet* result) const ;
-
- // Parses extended-form (2.4+) privilege documents and returns a PrivilegeSet of all the
- // privileges that the document grants.
- //
- // The document, "privilegeDocument", is assumed to describe privileges for "principal", and
- // to come from database "dbname".
- Status _buildPrivilegeSetFromExtendedPrivilegeDocument(
- const std::string& dbname,
- const UserName& user,
- const BSONObj& privilegeDocument,
- PrivilegeSet* result) const;
-
/**
* Parses privDoc and initializes the user object with the information extracted from the
* privilege document.
+ * This should never be called from outside the AuthorizationManager - the only reason it's
+ * public instead of private is so it can be unit tested.
*/
Status _initializeUserFromPrivilegeDocument(User* user,
const BSONObj& privDoc) const;
+ private:
+
/**
* Invalidates all User objects in the cache and removes them from the cache.
* Should only be called when already holding _lock.
diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_manager_test.cpp
index 86078c3439c..4c68e11a389 100644
--- a/src/mongo/db/auth/authorization_manager_test.cpp
+++ b/src/mongo/db/auth/authorization_manager_test.cpp
@@ -49,314 +49,276 @@ namespace {
};
TEST_F(AuthorizationManagerTest, GetPrivilegesFromPrivilegeDocumentCompatible) {
- UserName user("Spencer", "test");
+ User user(UserName("Spencer", "test"));
+ User adminUser(UserName("Spencer", "admin"));
BSONObj invalid;
BSONObj readWrite = BSON("user" << "Spencer" << "pwd" << "passwordHash");
BSONObj readOnly = BSON("user" << "Spencer" << "pwd" << "passwordHash" <<
"readOnly" << true);
- PrivilegeSet privilegeSet;
- ASSERT_EQUALS(ErrorCodes::UnsupportedFormat,
- authzManager->buildPrivilegeSet("test",
- user,
- invalid,
- &privilegeSet).code());
-
- ASSERT_OK(authzManager->buildPrivilegeSet("test",
- user,
- readOnly,
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::insert)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
-
- ASSERT_OK(authzManager->buildPrivilegeSet("test",
- user,
- readWrite,
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::insert)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::userAdmin)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::compact)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::shutdown)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::addShard)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("*", ActionType::find)));
-
- ASSERT_OK(authzManager->buildPrivilegeSet("admin",
- user,
- readOnly,
- &privilegeSet));
- // Should grant privileges on *.
- ASSERT(privilegeSet.hasPrivilege(Privilege("*", ActionType::find)));
-
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::insert)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("*", ActionType::insert)));
-
- ASSERT_OK(authzManager->buildPrivilegeSet("admin",
- user,
- readWrite,
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("*", ActionType::insert)));
+ ASSERT_NOT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ &user,
+ invalid));
+
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(&user, readOnly));
+ ASSERT(user.getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user.getActionsForResource("test").contains(ActionType::insert));
+
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(&user, readWrite));
+ ASSERT(user.getActionsForResource("test").contains(ActionType::find));
+ ASSERT(user.getActionsForResource("test").contains(ActionType::insert));
+ ASSERT(user.getActionsForResource("test").contains(ActionType::userAdmin));
+ ASSERT(user.getActionsForResource("test").contains(ActionType::compact));
+ ASSERT(!user.getActionsForResource("test").contains(ActionType::shutdown));
+ ASSERT(!user.getActionsForResource("test").contains(ActionType::addShard));
+ ASSERT(!user.getActionsForResource("admin").contains(ActionType::find));
+ ASSERT(!user.getActionsForResource("*").contains(ActionType::find));
+
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(&adminUser, readOnly));
+ ASSERT(adminUser.getActionsForResource("*").contains(ActionType::find));
+ ASSERT(!adminUser.getActionsForResource("admin").contains(ActionType::insert));
+ ASSERT(!adminUser.getActionsForResource("*").contains(ActionType::insert));
+
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(&adminUser, readWrite));
+ ASSERT(adminUser.getActionsForResource("*").contains(ActionType::find));
+ ASSERT(adminUser.getActionsForResource("*").contains(ActionType::insert));
}
class PrivilegeDocumentParsing : public AuthorizationManagerTest {
public:
- PrivilegeDocumentParsing() : user("spencer", "test") {}
+ PrivilegeDocumentParsing() {}
- UserName user;
- PrivilegeSet privilegeSet;
+ scoped_ptr<User> user;
+ scoped_ptr<User> adminUser;
+
+ void setUp() {
+ AuthorizationManagerTest::setUp();
+
+ user.reset(new User(UserName("spencer", "test")));
+ adminUser.reset(new User(UserName("admin", "admin")));
+ }
};
TEST_F(PrivilegeDocumentParsing, VerifyRolesFieldMustBeAnArray) {
- ASSERT_NOT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << "read"),
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
+ ASSERT_NOT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" << "pwd" << "" << "roles" << "read")));
+ ASSERT(user->getActionsForResource("test").empty());
}
TEST_F(PrivilegeDocumentParsing, VerifyInvalidRoleGrantsNoPrivileges) {
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("frim")),
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" << "pwd" << "" << "roles" << BSON_ARRAY("frim"))));
+ ASSERT(user->getActionsForResource("test").empty());
}
TEST_F(PrivilegeDocumentParsing, VerifyInvalidRoleStillAllowsOtherRoles) {
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read" << "frim")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read" << "frim"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::find));
}
TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterAdminRoleFromNonAdminDatabase) {
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read" << "clusterAdmin")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::shutdown)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::dropDatabase)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read" << "clusterAdmin"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("test").contains(ActionType::shutdown));
+ ASSERT(!user->getActionsForResource("test").contains(ActionType::dropDatabase));
}
TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterReadFromNonAdminDatabase) {
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read" << "readAnyDatabase")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::find)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read" << "readAnyDatabase"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("test2").contains(ActionType::find));
}
TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterReadWriteFromNonAdminDatabase) {
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read" << "readWriteAnyDatabase")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::insert)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::insert)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read" << "readWriteAnyDatabase"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("test").contains(ActionType::insert));
+ ASSERT(!user->getActionsForResource("test2").contains(ActionType::insert));
}
TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterUserAdminFromNonAdminDatabase) {
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read" << "userAdminAnyDatabase")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::userAdmin)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::userAdmin)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read" << "userAdminAnyDatabase"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("test").contains(ActionType::userAdmin));
+ ASSERT(!user->getActionsForResource("test2").contains(ActionType::userAdmin));
}
TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterDBAdminFromNonAdminDatabase) {
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read" << "dbAdminAnyDatabase")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::clean)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::clean)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read" << "dbAdminAnyDatabase"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("test").contains(ActionType::clean));
+ ASSERT(!user->getActionsForResource("test2").contains(ActionType::clean));
}
TEST_F(PrivilegeDocumentParsing, VerifyOtherDBRolesMustBeAnObjectOfArraysOfStrings) {
- ASSERT_NOT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read") <<
- "otherDBRoles" << BSON_ARRAY("read")),
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::find)));
-
- ASSERT_NOT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read") <<
- "otherDBRoles" << BSON("test2" << "read")),
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::find)));
+ ASSERT_NOT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read") <<
+ "otherDBRoles" << BSON_ARRAY("read"))));
+ ASSERT(!adminUser->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!adminUser->getActionsForResource("test2").contains(ActionType::find));
+ ASSERT(!adminUser->getActionsForResource("admin").contains(ActionType::find));
+
+ ASSERT_NOT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read") <<
+ "otherDBRoles" << BSON("test2" << "read"))));
+ ASSERT(!adminUser->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!adminUser->getActionsForResource("test2").contains(ActionType::find));
+ ASSERT(!adminUser->getActionsForResource("admin").contains(ActionType::find));
}
TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantPrivilegesOnOtherDatabasesNormally) {
// Cannot grant privileges on other databases, except from admin database.
- ASSERT_NOT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("read") <<
- "otherDBRoles" << BSON("test2" << BSON_ARRAY("read"))),
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::find)));
+ ASSERT_NOT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read") <<
+ "otherDBRoles" << BSON("test2" << BSON_ARRAY("read")))));
+ ASSERT(!user->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("test2").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("admin").contains(ActionType::find));
}
TEST_F(PrivilegeDocumentParsing, SuccessfulSimpleReadGrant) {
// Grant read on test.
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" << "roles" << BSON_ARRAY("read")),
- &privilegeSet));
-
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::find)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("read"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("test2").contains(ActionType::find));
+ ASSERT(!user->getActionsForResource("admin").contains(ActionType::find));
}
TEST_F(PrivilegeDocumentParsing, SuccessfulSimpleUserAdminTest) {
// Grant userAdmin on "test" database.
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "test",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("userAdmin")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::userAdmin)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::userAdmin)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::userAdmin)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("userAdmin"))));
+ ASSERT(user->getActionsForResource("test").contains(ActionType::userAdmin));
+ ASSERT(!user->getActionsForResource("test2").contains(ActionType::userAdmin));
+ ASSERT(!user->getActionsForResource("admin").contains(ActionType::userAdmin));
}
TEST_F(PrivilegeDocumentParsing, GrantUserAdminOnAdmin) {
// Grant userAdmin on admin.
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("userAdmin")),
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::userAdmin)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::userAdmin)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("admin", ActionType::userAdmin)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("userAdmin"))));
+ ASSERT(!adminUser->getActionsForResource("test").contains(ActionType::userAdmin));
+ ASSERT(!adminUser->getActionsForResource("test2").contains(ActionType::userAdmin));
+ ASSERT(adminUser->getActionsForResource("admin").contains(ActionType::userAdmin));
}
TEST_F(PrivilegeDocumentParsing, GrantUserAdminOnTestViaAdmin) {
// Grant userAdmin on test via admin.
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSONArrayBuilder().arr() <<
- "otherDBRoles" << BSON("test" << BSON_ARRAY("userAdmin"))),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::userAdmin)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::userAdmin)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::userAdmin)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSONArrayBuilder().arr() <<
+ "otherDBRoles" << BSON("test" << BSON_ARRAY("userAdmin")))));
+ ASSERT(adminUser->getActionsForResource("test").contains(ActionType::userAdmin));
+ ASSERT(!adminUser->getActionsForResource("test2").contains(ActionType::userAdmin));
+ ASSERT(!adminUser->getActionsForResource("admin").contains(ActionType::userAdmin));
}
TEST_F(PrivilegeDocumentParsing, SuccessfulClusterAdminTest) {
// Grant userAdminAnyDatabase.
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("userAdminAnyDatabase")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::userAdmin)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test2", ActionType::userAdmin)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("admin", ActionType::userAdmin)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("userAdminAnyDatabase"))));
+ ASSERT(adminUser->getActionsForResource("*").contains(ActionType::userAdmin));
}
TEST_F(PrivilegeDocumentParsing, GrantClusterReadWrite) {
// Grant readWrite on everything via the admin database.
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("readWriteAnyDatabase")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test2", ActionType::find)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("admin", ActionType::find)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::insert)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test2", ActionType::insert)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("admin", ActionType::insert)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("readWriteAnyDatabase"))));
+ ASSERT(adminUser->getActionsForResource("*").contains(ActionType::find));
+ ASSERT(adminUser->getActionsForResource("*").contains(ActionType::insert));
}
TEST_F(PrivilegeDocumentParsing, ProhibitGrantOnWildcard) {
- // Cannot grant readWrite to everythign using "otherDBRoles".
- ASSERT_NOT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSONArrayBuilder().arr() <<
- "otherDBRoles" << BSON("*" << BSON_ARRAY("readWrite"))),
- &privilegeSet));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::find)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::insert)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::insert)));
- ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::insert)));
+ // Cannot grant readWrite to everything using "otherDBRoles".
+ ASSERT_NOT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSONArrayBuilder().arr() <<
+ "otherDBRoles" << BSON("*" << BSON_ARRAY("readWrite")))));
+ ASSERT(!adminUser->getActionsForResource("test").contains(ActionType::find));
+ ASSERT(!adminUser->getActionsForResource("test2").contains(ActionType::find));
+ ASSERT(!adminUser->getActionsForResource("admin").contains(ActionType::find));
+ ASSERT(!adminUser->getActionsForResource("test").contains(ActionType::insert));
+ ASSERT(!adminUser->getActionsForResource("test2").contains(ActionType::insert));
+ ASSERT(!adminUser->getActionsForResource("admin").contains(ActionType::insert));
}
TEST_F(PrivilegeDocumentParsing, GrantClusterAdmin) {
// Grant cluster admin
- ASSERT_OK(authzManager->buildPrivilegeSet(
- "admin",
- user,
- BSON("user" << "spencer" << "pwd" << "" <<
- "roles" << BSON_ARRAY("clusterAdmin")),
- &privilegeSet));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::dropDatabase)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("test2", ActionType::dropDatabase)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("admin", ActionType::dropDatabase)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("$SERVER", ActionType::shutdown)));
- ASSERT(privilegeSet.hasPrivilege(Privilege("$CLUSTER", ActionType::moveChunk)));
+ ASSERT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ adminUser.get(),
+ BSON("user" << "admin" <<
+ "pwd" << "" <<
+ "roles" << BSON_ARRAY("clusterAdmin"))));
+ ASSERT(adminUser->getActionsForResource("*").contains(ActionType::dropDatabase));
+ ASSERT(adminUser->getActionsForResource("*").contains(ActionType::shutdown));
+ ASSERT(adminUser->getActionsForResource("*").contains(ActionType::moveChunk));
}
- TEST_F(AuthorizationManagerTest, GetPrivilegesFromPrivilegeDocumentInvalid) {
- BSONObj oldAndNewMixed = BSON("user" << "spencer" <<
- "pwd" << "passwordHash" <<
- "readOnly" << false <<
- "roles" << BSON_ARRAY("write" << "userAdmin"));
-
- UserName user("spencer", "anydb");
- PrivilegeSet result;
- ASSERT_NOT_OK(authzManager->buildPrivilegeSet("anydb", user, oldAndNewMixed, &result));
+ TEST_F(PrivilegeDocumentParsing, GetPrivilegesFromPrivilegeDocumentInvalid) {
+ // Try to mix fields from V0 and V1 privilege documents and make sure it fails.
+ ASSERT_NOT_OK(authzManager->_initializeUserFromPrivilegeDocument(
+ user.get(),
+ BSON("user" << "spencer" <<
+ "pwd" << "passwordHash" <<
+ "readOnly" << false <<
+ "roles" << BSON_ARRAY("read"))));
+ ASSERT(!adminUser->getActionsForResource("test").contains(ActionType::find));
}
TEST_F(AuthorizationManagerTest, DocumentValidationCompatibility) {
diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp
index 89c9664a11f..02d659a1b6a 100644
--- a/src/mongo/db/auth/authorization_session.cpp
+++ b/src/mongo/db/auth/authorization_session.cpp
@@ -24,10 +24,7 @@
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authz_session_external_state.h"
#include "mongo/db/auth/authorization_manager.h"
-#include "mongo/db/auth/principal.h"
-#include "mongo/db/auth/principal_set.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/auth/privilege_set.h"
#include "mongo/db/auth/security_key.h"
#include "mongo/db/client.h"
#include "mongo/db/jsobj.h"
@@ -61,39 +58,6 @@ namespace {
_externalState->startRequest();
}
- void AuthorizationSession::addAndAuthorizePrincipal(Principal* principal) {
-
- // Log out any already-logged-in user on the same database as "principal".
- logoutDatabase(principal->getName().getDB().toString()); // See SERVER-8144.
-
- _authenticatedPrincipals.add(principal);
-
- if (principal->getName() == internalSecurity.user->getName()) {
-
- // Grant full access to internal user
- ActionSet allActions;
- allActions.addAllActions();
- acquirePrivilege(Privilege(AuthorizationManager::WILDCARD_RESOURCE_NAME, allActions),
- principal->getName());
- return;
- }
-
- const std::string dbname = principal->getName().getDB().toString();
- _acquirePrivilegesForPrincipalFromDatabase(ADMIN_DBNAME, principal->getName());
- principal->markDatabaseAsProbed(ADMIN_DBNAME);
- _acquirePrivilegesForPrincipalFromDatabase(dbname, principal->getName());
- principal->markDatabaseAsProbed(dbname);
- _externalState->onAddAuthorizedPrincipal(principal);
- }
-
- void AuthorizationSession::addPrincipal(Principal* principal) {
-
- // Log out any already-logged-in user on the same database as "principal".
- logoutDatabase(principal->getName().getDB().toString()); // See SERVER-8144.
- _authenticatedPrincipals.add(principal);
- _externalState->onAddAuthorizedPrincipal(principal);
- }
-
Status AuthorizationSession::addAndAuthorizeUser(const UserName& userName) {
User* user;
Status status = getAuthorizationManager().acquireUser(userName, &user);
@@ -108,39 +72,15 @@ namespace {
getAuthorizationManager().releaseUser(replacedUser);
}
+ _externalState->onAddAuthorizedUser();
return Status::OK();
}
- void AuthorizationSession::_acquirePrivilegesForPrincipalFromDatabase(
- const std::string& dbname, const UserName& user) {
-
- BSONObj privilegeDocument;
- Status status = _externalState->getAuthorizationManager().getPrivilegeDocument(
- dbname, user, &privilegeDocument);
- if (status.isOK()) {
- status = acquirePrivilegesFromPrivilegeDocument(dbname, user, privilegeDocument);
- }
- if (!status.isOK() && status != ErrorCodes::UserNotFound) {
- log() << "Privilege acquisition failed for " << user << " in database " <<
- dbname << ": " << status.reason() << " (" << status.codeString() << ")" << endl;
- }
- }
-
- Principal* AuthorizationSession::lookupPrincipal(const UserName& name) {
- return _authenticatedPrincipals.lookup(name);
- }
-
User* AuthorizationSession::lookupUser(const UserName& name) {
return _authenticatedUsers.lookup(name);
}
void AuthorizationSession::logoutDatabase(const std::string& dbname) {
- Principal* principal = _authenticatedPrincipals.lookupByDBName(dbname);
- if (principal) {
- _acquiredPrivileges.revokePrivilegesFromUser(principal->getName());
- _authenticatedPrincipals.removeByDBName(dbname);
- }
-
User* removedUser = _authenticatedUsers.removeByDBName(dbname);
if (removedUser) {
getAuthorizationManager().releaseUser(removedUser);
@@ -153,56 +93,15 @@ namespace {
return _authenticatedUsers.getNames();
}
- Status AuthorizationSession::acquirePrivilege(const Privilege& privilege,
- const UserName& authorizingUser) {
- if (!_authenticatedPrincipals.lookup(authorizingUser)) {
- return Status(ErrorCodes::UserNotFound,
- mongoutils::str::stream()
- << "No authenticated user found with name: "
- << authorizingUser.getUser()
- << " from database "
- << authorizingUser.getDB(),
- 0);
- }
- _acquiredPrivileges.grantPrivilege(privilege, authorizingUser);
- return Status::OK();
- }
-
void AuthorizationSession::grantInternalAuthorization() {
- Principal* principal = new Principal(internalSecurity.user->getName());
- ActionSet actions;
- actions.addAllActions();
-
- addPrincipal(principal);
- fassert(16581,
- acquirePrivilege(Privilege(AuthorizationManager::WILDCARD_RESOURCE_NAME, actions),
- principal->getName()).isOK());
-
_authenticatedUsers.add(internalSecurity.user);
}
bool AuthorizationSession::hasInternalAuthorization() {
ActionSet allActions;
allActions.addAllActions();
- return _acquiredPrivileges.hasPrivilege(
- Privilege(AuthorizationManager::WILDCARD_RESOURCE_NAME, allActions));
- }
-
- Status AuthorizationSession::acquirePrivilegesFromPrivilegeDocument(
- const std::string& dbname, const UserName& user, const BSONObj& privilegeDocument) {
- if (!_authenticatedPrincipals.lookup(user)) {
- return Status(ErrorCodes::UserNotFound,
- mongoutils::str::stream()
- << "No authenticated principle found with name: "
- << user.getUser()
- << " from database "
- << user.getDB(),
- 0);
- }
- return _externalState->getAuthorizationManager().buildPrivilegeSet(dbname,
- user,
- privilegeDocument,
- &_acquiredPrivileges);
+ return _checkAuthForPrivilegeHelper(
+ Privilege(AuthorizationManager::WILDCARD_RESOURCE_NAME, allActions)).isOK();
}
bool AuthorizationSession::checkAuthorization(const std::string& resource,
diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h
index 01bcff370df..b8f587b8091 100644
--- a/src/mongo/db/auth/authorization_session.h
+++ b/src/mongo/db/auth/authorization_session.h
@@ -25,10 +25,7 @@
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authz_session_external_state.h"
-#include "mongo/db/auth/principal.h"
-#include "mongo/db/auth/principal_set.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/auth/privilege_set.h"
#include "mongo/db/auth/user_name.h"
#include "mongo/db/auth/user_set.h"
@@ -56,25 +53,12 @@ namespace mongo {
// TODO: try to eliminate the need for this call.
void startRequest();
- // Adds "principal" to the authorization session, acquiring privileges for that principal,
- // and takes ownership of it.
- void addAndAuthorizePrincipal(Principal* principal);
-
- // Adds "principal" to the authorization session and takes ownership of it, without
- // acquiring privileges for it.
- void addPrincipal(Principal* principal);
-
/**
* Adds the User identified by "UserName" to the authorization session, acquiring privileges
* for it in the process.
*/
Status addAndAuthorizeUser(const UserName& userName);
- // Returns the authenticated principal with the given name. Returns NULL
- // if no such user is found.
- // Ownership of the returned Principal remains with _authenticatedPrincipals
- Principal* lookupPrincipal(const UserName& name);
-
// Returns the authenticated user with the given name. Returns NULL
// if no such user is found.
// The user remains in the _authenticatedUsers set for this AuthorizationSession,
@@ -88,10 +72,6 @@ namespace mongo {
// database, and revokes any privileges that were granted via that principal.
void logoutDatabase(const std::string& dbname);
- // Grant this connection the given privilege.
- Status acquirePrivilege(const Privilege& privilege,
- const UserName& authorizingUser);
-
// Adds the internalSecurity user to the set of authenticated users.
// Used to grant internal threads full access.
void grantInternalAuthorization();
@@ -109,12 +89,6 @@ namespace mongo {
// all of the actions may proceed on the resource.
bool checkAuthorization(const std::string& resource, ActionSet actions);
- // Parses the privilege documents and acquires all privileges that the privilege document
- // grants
- Status acquirePrivilegesFromPrivilegeDocument(const std::string& dbname,
- const UserName& user,
- const BSONObj& privilegeDocument);
-
// Checks if this connection has the privileges necessary to perform the given query on the
// given namespace.
Status checkAuthForQuery(const std::string& ns, const BSONObj& query);
@@ -151,11 +125,6 @@ namespace mongo {
// we should even be doing authorization checks in general.
Status _checkAuthForPrivilegeHelper(const Privilege& privilege);
- // Finds the set of privileges attributed to "principal" in database "dbname",
- // and adds them to the set of acquired privileges.
- void _acquirePrivilegesForPrincipalFromDatabase(const std::string& dbname,
- const UserName& user);
-
// Returns a new privilege that has replaced the actions needed to handle special casing
// certain namespaces like system.users and system.profile. Note that the special handling
// of system.indexes takes place in checkAuthForInsert, not here.
@@ -164,10 +133,6 @@ namespace mongo {
scoped_ptr<AuthzSessionExternalState> _externalState;
- // All the privileges that have been acquired by the authenticated principals.
- PrivilegeSet _acquiredPrivileges;
- // All principals who have been authenticated on this connection
- PrincipalSet _authenticatedPrincipals;
// All Users who have been authenticated on this connection
UserSet _authenticatedUsers;
};
diff --git a/src/mongo/db/auth/authz_session_external_state.h b/src/mongo/db/auth/authz_session_external_state.h
index 4e633b3b570..063181615f0 100644
--- a/src/mongo/db/auth/authz_session_external_state.h
+++ b/src/mongo/db/auth/authz_session_external_state.h
@@ -57,7 +57,7 @@ namespace mongo {
// Authorization event hooks
// Handle any global state which needs to be updated when a new user has been authorized
- virtual void onAddAuthorizedPrincipal(Principal*) = 0;
+ virtual void onAddAuthorizedUser() = 0;
// Handle any global state which needs to be updated when a user logs out
virtual void onLogoutDatabase(const std::string& dbname) = 0;
diff --git a/src/mongo/db/auth/authz_session_external_state_d.cpp b/src/mongo/db/auth/authz_session_external_state_d.cpp
index 03c9306bbc5..1736e827bc2 100644
--- a/src/mongo/db/auth/authz_session_external_state_d.cpp
+++ b/src/mongo/db/auth/authz_session_external_state_d.cpp
@@ -43,7 +43,7 @@ namespace mongo {
return cc().isGod() || AuthzSessionExternalStateServerCommon::shouldIgnoreAuthChecks();
}
- void AuthzSessionExternalStateMongod::onAddAuthorizedPrincipal(Principal*) {
+ void AuthzSessionExternalStateMongod::onAddAuthorizedUser() {
// invalidate all thread-local JS scopes due to new user authentication
if (globalScriptEngine)
globalScriptEngine->threadDone();
diff --git a/src/mongo/db/auth/authz_session_external_state_d.h b/src/mongo/db/auth/authz_session_external_state_d.h
index 8e26e2bb518..9cdae29bc1f 100644
--- a/src/mongo/db/auth/authz_session_external_state_d.h
+++ b/src/mongo/db/auth/authz_session_external_state_d.h
@@ -37,7 +37,7 @@ namespace mongo {
virtual void startRequest();
- virtual void onAddAuthorizedPrincipal(Principal*);
+ virtual void onAddAuthorizedUser();
virtual void onLogoutDatabase(const std::string&);
diff --git a/src/mongo/db/auth/authz_session_external_state_mock.h b/src/mongo/db/auth/authz_session_external_state_mock.h
index 967c50d78b2..32b76db5bd1 100644
--- a/src/mongo/db/auth/authz_session_external_state_mock.h
+++ b/src/mongo/db/auth/authz_session_external_state_mock.h
@@ -49,7 +49,7 @@ namespace mongo {
virtual void startRequest() {}
- virtual void onAddAuthorizedPrincipal(Principal*) {}
+ virtual void onAddAuthorizedUser() {}
virtual void onLogoutDatabase(const std::string& dbname) {}
diff --git a/src/mongo/db/auth/authz_session_external_state_s.cpp b/src/mongo/db/auth/authz_session_external_state_s.cpp
index 73585453da8..a7c8bb7cbd4 100644
--- a/src/mongo/db/auth/authz_session_external_state_s.cpp
+++ b/src/mongo/db/auth/authz_session_external_state_s.cpp
@@ -31,7 +31,7 @@ namespace mongo {
AuthzSessionExternalStateServerCommon(authzManager) {}
AuthzSessionExternalStateMongos::~AuthzSessionExternalStateMongos() {}
- void AuthzSessionExternalStateMongos::onAddAuthorizedPrincipal(Principal*) { }
+ void AuthzSessionExternalStateMongos::onAddAuthorizedUser() { }
void AuthzSessionExternalStateMongos::onLogoutDatabase(const std::string&) { }
diff --git a/src/mongo/db/auth/authz_session_external_state_s.h b/src/mongo/db/auth/authz_session_external_state_s.h
index 8a07eb166c5..c91d2826438 100644
--- a/src/mongo/db/auth/authz_session_external_state_s.h
+++ b/src/mongo/db/auth/authz_session_external_state_s.h
@@ -35,7 +35,7 @@ namespace mongo {
virtual void startRequest();
- virtual void onAddAuthorizedPrincipal(Principal*);
+ virtual void onAddAuthorizedUser();
virtual void onLogoutDatabase(const std::string&);
diff --git a/src/mongo/db/auth/principal.cpp b/src/mongo/db/auth/principal.cpp
deleted file mode 100644
index bba850d80c8..00000000000
--- a/src/mongo/db/auth/principal.cpp
+++ /dev/null
@@ -1,44 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mongo/db/auth/principal.h"
-
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <string>
-
-#include "mongo/util/map_util.h"
-
-namespace mongo {
-
- Principal::Principal(const UserName& name) :
- _name(name),
- _expirationTime(boost::posix_time::pos_infin) {
- }
-
- Principal::~Principal() {}
-
- void Principal::setExpirationTime(boost::posix_time::ptime& expiration) {
- _expirationTime = expiration;
- }
-
- bool Principal::isDatabaseProbed(const StringData& dbname) const {
- return mapFindWithDefault(_probedDatabases, dbname, false);
- }
-
- void Principal::markDatabaseAsProbed(const StringData& dbname) {
- _probedDatabases[dbname] = true;
- }
-
-} // namespace mongo
diff --git a/src/mongo/db/auth/principal.h b/src/mongo/db/auth/principal.h
deleted file mode 100644
index 0ebb502b16a..00000000000
--- a/src/mongo/db/auth/principal.h
+++ /dev/null
@@ -1,65 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <string>
-
-#include "mongo/base/disallow_copying.h"
-#include "mongo/base/string_data.h"
-#include "mongo/db/auth/user_name.h"
-#include "mongo/util/string_map.h"
-
-namespace mongo {
-
- /**
- * Represents an authenticated user. Every principal has a name, a time that the user's
- * authentication expires, and a flag that describes whether or not privileges should be
- * acquired implicitly.
- *
- * The implicit privilege acquisition flag defaults to disabled, and the expiration time
- * defaults to never.
- *
- * This class does not do any locking/synchronization, the consumer will be responsible for
- * synchronizing access.
- */
- class Principal {
- MONGO_DISALLOW_COPYING(Principal);
-
- public:
- Principal(const UserName& name,
- const boost::posix_time::ptime& expirationTime);
- explicit Principal(const UserName& name);
- ~Principal();
-
- const UserName& getName() const { return _name; }
-
- // Returns the expiration time of this principal information.
- // No expiration is represented as boost::posix_time::pos_infin
- const boost::posix_time::ptime& getExpirationTime() const { return _expirationTime; }
-
- void setExpirationTime(boost::posix_time::ptime& expiration);
-
- bool isDatabaseProbed(const StringData& dbname) const;
- void markDatabaseAsProbed(const StringData& dbname);
-
- private:
- UserName _name;
- boost::posix_time::ptime _expirationTime;
- StringMap<bool> _probedDatabases;
- };
-
-} // namespace mongo
diff --git a/src/mongo/db/auth/principal_set.cpp b/src/mongo/db/auth/principal_set.cpp
deleted file mode 100644
index 48e9be09d79..00000000000
--- a/src/mongo/db/auth/principal_set.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mongo/pch.h"
-
-#include "mongo/db/auth/principal_set.h"
-
-#include <boost/date_time/posix_time/posix_time.hpp>
-#include <string>
-#include <vector>
-
-#include "mongo/db/auth/principal.h"
-#include "mongo/util/mongoutils/str.h"
-
-namespace mongo {
-
- PrincipalSet::PrincipalSet() {}
- PrincipalSet::~PrincipalSet() {
- for (std::vector<Principal*>::iterator it = _principals.begin();
- it != _principals.end(); ++it) {
- delete *it;
- }
- }
-
- void PrincipalSet::add(Principal* principal) {
- for (std::vector<Principal*>::iterator it = _principals.begin();
- it != _principals.end(); ++it) {
- Principal* current = *it;
- if (current->getName().getDB() == principal->getName().getDB()) {
- // There can be only one principal per database.
- delete current;
- *it = principal;
- return;
- }
- }
- _principals.push_back(principal);
- }
-
- void PrincipalSet::removeByDBName(const StringData& dbname) {
- for (std::vector<Principal*>::iterator it = _principals.begin();
- it != _principals.end(); ++it) {
- Principal* current = *it;
- if (current->getName().getDB() == dbname) {
- delete current;
- _principals.erase(it);
- break;
- }
- }
- }
-
- Principal* PrincipalSet::lookup(const UserName& name) const {
- Principal* principal = lookupByDBName(name.getDB());
- if (principal && principal->getName() == name) {
- return principal;
- }
- return NULL;
- }
-
- Principal* PrincipalSet::lookupByDBName(const StringData& dbname) const {
- for (std::vector<Principal*>::const_iterator it = _principals.begin();
- it != _principals.end(); ++it) {
- Principal* current = *it;
- if (current->getName().getDB() == dbname) {
- return current;
- }
- }
- return NULL;
- }
-
-} // namespace mongo
diff --git a/src/mongo/db/auth/principal_set.h b/src/mongo/db/auth/principal_set.h
deleted file mode 100644
index 90a1c6d8e56..00000000000
--- a/src/mongo/db/auth/principal_set.h
+++ /dev/null
@@ -1,106 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <string>
-#include <vector>
-
-#include "mongo/base/disallow_copying.h"
-#include "mongo/base/string_data.h"
-#include "mongo/db/auth/principal.h"
-#include "mongo/db/auth/user_name.h"
-
-namespace mongo {
-
- /**
- * A collection of authenticated principals.
- * This class does not do any locking/synchronization, the consumer will be responsible for
- * synchronizing access.
- */
- class PrincipalSet {
- MONGO_DISALLOW_COPYING(PrincipalSet);
- public:
- typedef std::vector<Principal*>::const_iterator iterator;
-
- /**
- * Forward iterator over the names of the principals stored in a PrincipalSet.
- *
- * Instances are valid until the underlying vector<Principal*> is modified.
- *
- * more() must be the first method called after construction, and must be checked
- * after each call to next() before calling any other methods.
- */
- class NameIterator {
- public:
- explicit NameIterator(const std::vector<Principal*>& principals) :
- _curr(principals.begin()),
- _end(principals.end()) {
- }
-
- NameIterator() {}
-
- bool more() { return _curr != _end; }
- const UserName& next() {
- const UserName& ret = get();
- ++_curr;
- return ret;
- }
-
- const UserName& get() const { return (*_curr)->getName(); }
-
- const UserName& operator*() const { return get(); }
- const UserName* operator->() const { return &get(); }
-
- private:
- std::vector<Principal*>::const_iterator _curr;
- std::vector<Principal*>::const_iterator _end;
- };
-
- PrincipalSet();
- ~PrincipalSet();
-
- // If the principal is already present, this will replace the existing entry.
- // The PrincipalSet takes ownership of the passed-in principal and is responsible for
- // deleting it eventually
- void add(Principal* principal);
-
- // Removes all principals whose authentication credentials came from dbname.
- void removeByDBName(const StringData& dbname);
-
- // Returns the Principal with the given name, or NULL if not found.
- // Ownership of the returned Principal remains with the PrincipalSet. The pointer
- // returned is only guaranteed to remain valid until the next non-const method is called
- // on the PrincipalSet.
- Principal* lookup(const UserName& name) const;
-
- // Gets the principal whose authentication credentials came from dbname, or NULL if none
- // exist. There should be at most one such principal.
- Principal* lookupByDBName(const StringData& dbname) const;
-
- // Gets an iterator over the names of the principals stored in the set. The iterator is
- // valid until the next non-const method is called on the PrincipalSet.
- NameIterator getNames() const { return NameIterator(_principals); }
-
- iterator begin() const { return _principals.begin(); }
- iterator end() const { return _principals.end(); }
-
- private:
- // The PrincipalSet maintains ownership of the Principals in it, and is responsible for
- // deleting them when done with them.
- std::vector<Principal*> _principals;
- };
-
-} // namespace mongo
diff --git a/src/mongo/db/auth/principal_set_test.cpp b/src/mongo/db/auth/principal_set_test.cpp
deleted file mode 100644
index 7ed30d2930a..00000000000
--- a/src/mongo/db/auth/principal_set_test.cpp
+++ /dev/null
@@ -1,97 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Unit tests of the PrincipalSet type.
- */
-
-#include "mongo/db/auth/principal_set.h"
-#include "mongo/db/auth/principal.h"
-#include "mongo/db/auth/user_name.h"
-#include "mongo/unittest/unittest.h"
-
-#define ASSERT_NULL(EXPR) ASSERT_FALSE((EXPR))
-
-namespace mongo {
-
- static inline std::ostream& operator<<(std::ostream& os, const UserName& uname) {
- return os << uname.toString();
- }
-
-namespace {
-
- TEST(PrincipalSetTest, BasicTest) {
- PrincipalSet set;
-
- Principal* p1 = new Principal(UserName("Bob", "test"));
- Principal* p2 = new Principal(UserName("George", "test"));
- Principal* p3 = new Principal(UserName("Bob", "test2"));
-
- ASSERT_NULL(set.lookup(UserName("Bob", "test")));
- ASSERT_NULL(set.lookup(UserName("George", "test")));
- ASSERT_NULL(set.lookup(UserName("Bob", "test2")));
- ASSERT_NULL(set.lookupByDBName("test"));
- ASSERT_NULL(set.lookupByDBName("test2"));
-
- set.add(p1);
-
- ASSERT_EQUALS(p1, set.lookup(UserName("Bob", "test")));
- ASSERT_EQUALS(p1, set.lookupByDBName("test"));
- ASSERT_NULL(set.lookup(UserName("George", "test")));
- ASSERT_NULL(set.lookup(UserName("Bob", "test2")));
- ASSERT_NULL(set.lookupByDBName("test2"));
-
- // This should not replace the existing user "Bob" because they are different databases
- set.add(p3);
-
- ASSERT_EQUALS(p1, set.lookup(UserName("Bob", "test")));
- ASSERT_EQUALS(p1, set.lookupByDBName("test"));
- ASSERT_NULL(set.lookup(UserName("George", "test")));
- ASSERT_EQUALS(p3, set.lookup(UserName("Bob", "test2")));
- ASSERT_EQUALS(p3, set.lookupByDBName("test2"));
-
- set.add(p2); // This should replace Bob since they're on the same database
-
- ASSERT_NULL(set.lookup(UserName("Bob", "test")));
- ASSERT_EQUALS(p2, set.lookup(UserName("George", "test")));
- ASSERT_EQUALS(p2, set.lookupByDBName("test"));
- ASSERT_EQUALS(p3, set.lookup(UserName("Bob", "test2")));
- ASSERT_EQUALS(p3, set.lookupByDBName("test2"));
-
- set.removeByDBName("test");
-
- ASSERT_NULL(set.lookup(UserName("Bob", "test")));
- ASSERT_NULL(set.lookup(UserName("George", "test")));
- ASSERT_NULL(set.lookupByDBName("test"));
- ASSERT_EQUALS(p3, set.lookup(UserName("Bob", "test2")));
- ASSERT_EQUALS(p3, set.lookupByDBName("test2"));
- }
-
- TEST(PrincipalSetTest, IterateNames) {
- PrincipalSet pset;
- PrincipalSet::NameIterator iter = pset.getNames();
- ASSERT(!iter.more());
-
- pset.add(new Principal(UserName("bob", "test")));
-
- iter = pset.getNames();
- ASSERT(iter.more());
- ASSERT_EQUALS(*iter, UserName("bob", "test"));
- ASSERT_EQUALS(iter.next(), UserName("bob", "test"));
- ASSERT(!iter.more());
- }
-
-} // namespace
-} // namespace mongo
diff --git a/src/mongo/db/auth/privilege.cpp b/src/mongo/db/auth/privilege.cpp
index d1797473aad..b048af41777 100644
--- a/src/mongo/db/auth/privilege.cpp
+++ b/src/mongo/db/auth/privilege.cpp
@@ -19,7 +19,6 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
-#include "mongo/db/auth/principal.h"
namespace mongo {
diff --git a/src/mongo/db/auth/privilege.h b/src/mongo/db/auth/privilege.h
index 0b113c7ff56..114e5315da2 100644
--- a/src/mongo/db/auth/privilege.h
+++ b/src/mongo/db/auth/privilege.h
@@ -20,7 +20,6 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
-#include "mongo/db/auth/principal.h"
namespace mongo {
diff --git a/src/mongo/db/auth/privilege_set.cpp b/src/mongo/db/auth/privilege_set.cpp
deleted file mode 100644
index fa555226255..00000000000
--- a/src/mongo/db/auth/privilege_set.cpp
+++ /dev/null
@@ -1,143 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mongo/pch.h"
-
-#include "mongo/db/auth/privilege_set.h"
-
-#include <map>
-#include <string>
-
-#include "mongo/db/auth/action_set.h"
-#include "mongo/db/auth/action_type.h"
-#include "mongo/db/auth/principal.h"
-#include "mongo/db/namespace_string.h"
-#include "mongo/util/map_util.h"
-
-namespace mongo {
-
- PrivilegeSet::PrivilegeSet() {}
- PrivilegeSet::~PrivilegeSet() {}
-
- void PrivilegeSet::grantPrivilege(const Privilege& privilege,
- const UserName& authorizingUser) {
- grantPrivileges(std::vector<Privilege>(1, privilege), authorizingUser);
- }
-
- void PrivilegeSet::grantPrivileges(const std::vector<Privilege>& privileges,
- const UserName& authorizingUser) {
- StringMap<ActionSet>& byResourceForUser = _byUser[authorizingUser];
- for (std::vector<Privilege>::const_iterator iter = privileges.begin(),
- end = privileges.end();
- iter != end; ++iter) {
-
- byResourceForUser[iter->getResource()].addAllActionsFromSet(iter->getActions());
-
- ResourcePrivilegeCacheEntry* entry = _lookupOrInsertEntry(iter->getResource());
- entry->actions.addAllActionsFromSet(iter->getActions());
- }
- }
-
- void PrivilegeSet::revokePrivilegesFromUser(const UserName& user) {
- UserPrivilegeMap::iterator userEntry = _byUser.find(user);
- if (userEntry == _byUser.end())
- return;
-
- // For every resource that "user" authorizes, mark its entry in the _byResource table
- // as dirty, so that it will be rebuilt on next consultation.
- for (StringMap<ActionSet>::const_iterator resourceEntry = userEntry->second.begin(),
- end = userEntry->second.end();
- resourceEntry != end; ++resourceEntry) {
-
- _lookupOrInsertEntry(resourceEntry->first)->dirty = true;
- }
-
- // Remove the user from the _byUser table.
- _byUser.erase(userEntry);
- }
-
- bool PrivilegeSet::hasPrivilege(const Privilege& desiredPrivilege) {
- if (desiredPrivilege.getActions().empty())
- return true;
-
- StringData resourceSearchList[2];
- resourceSearchList[0] = "*";
- resourceSearchList[1] = nsToDatabaseSubstring(desiredPrivilege.getResource());
-
- ActionSet unmetRequirements = desiredPrivilege.getActions();
- for (int i = 0; i < static_cast<int>(boost::size(resourceSearchList)); ++i) {
- ResourcePrivilegeCacheEntry* entry = _lookupEntry(resourceSearchList[i]);
- if (NULL == entry)
- continue;
- if (entry->dirty)
- _rebuildEntry(resourceSearchList[i], entry);
- unmetRequirements.removeAllActionsFromSet(entry->actions);
- if (unmetRequirements.empty())
- return true;
- }
- return false;
- }
-
- bool PrivilegeSet::hasPrivileges(const std::vector<Privilege>& desiredPrivileges) {
- for (std::vector<Privilege>::const_iterator iter = desiredPrivileges.begin(),
- end = desiredPrivileges.end();
- iter != end; ++iter) {
-
- if (!hasPrivilege(*iter))
- return false;
- }
- return true;
- }
-
- void PrivilegeSet::_rebuildEntry(const StringData& resource,
- ResourcePrivilegeCacheEntry* entry) {
- const ActionSet emptyActionSet;
- entry->actions.removeAllActions();
-
- for (UserPrivilegeMap::const_iterator iter = _byUser.begin(),
- end = _byUser.end();
- iter != end; ++iter) {
-
- entry->actions.addAllActionsFromSet(
- mapFindWithDefault(iter->second, resource, emptyActionSet));
- }
-
- entry->dirty = false;
- }
-
- PrivilegeSet::ResourcePrivilegeCacheEntry* PrivilegeSet::_lookupEntry(
- const StringData& resource) {
-
- if (resource == "*")
- return &_globalPrivilegeEntry;
-
- ResourcePrivilegeCache::const_iterator iter = _byResource.find(resource);
- if (iter != _byResource.end()) {
- // StringMap doesn't have non-const iterators, so there is no way to lookup without
- // inserting and get a mutable value, without const-cast.
- return const_cast<ResourcePrivilegeCacheEntry*>(&iter->second);
- }
- return NULL;
- }
-
- PrivilegeSet::ResourcePrivilegeCacheEntry* PrivilegeSet::_lookupOrInsertEntry(
- const StringData& resource) {
-
- if (resource == "*")
- return &_globalPrivilegeEntry;
- return &_byResource[resource];
- }
-
-} // namespace mongo
diff --git a/src/mongo/db/auth/privilege_set.h b/src/mongo/db/auth/privilege_set.h
deleted file mode 100644
index 209bbb5086a..00000000000
--- a/src/mongo/db/auth/privilege_set.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#pragma once
-
-#include <map>
-#include <string>
-
-#include "mongo/base/disallow_copying.h"
-#include "mongo/db/auth/action_set.h"
-#include "mongo/db/auth/action_type.h"
-#include "mongo/db/auth/privilege.h"
-#include "mongo/db/auth/user_name.h"
-#include "mongo/util/string_map.h"
-
-namespace mongo {
-
- /**
- * A collection of privileges describing which authenticated users bestow the client the
- * ability to perform various actions on specific resources. Since every privilege comes from
- * an authenticated user, removing that user removes all privileges granted by that
- * user.
- *
- * Resources are arranged hierarchically, with a wildcard resource,
- * PrivilegeSet::WILDCARD_RESOURCE, matching any resource. In the current implementation, the
- * only two levels of the hierarchy are the wildcard and one level below, which is analagous to
- * the name of a database. It is future work to support collection or other sub-database
- * resources.
- *
- * This class does not do any locking/synchronization, the consumer will be responsible for
- * synchronizing access.
- */
- class PrivilegeSet {
- MONGO_DISALLOW_COPYING(PrivilegeSet);
- public:
- PrivilegeSet();
- ~PrivilegeSet();
-
- /**
- * Adds the specified privilege to the set, associating it with the named user.
- *
- * The privilege should be on a specific resource, or on the WILDCARD_RESOURCE.
- */
- void grantPrivilege(const Privilege& privilege, const UserName& authorizingUser);
-
- /**
- * Adds the specified privileges to the set, associating them with the named user.
- */
- void grantPrivileges(const std::vector<Privilege>& privileges,
- const UserName& authorizingUser);
-
- /**
- * Removes from the set all privileges associated with the given user.
- *
- * If multiple users enable the same privilege, the set will continue to
- * contain those privileges until all authorizing users have had their
- * privileges revoked from the set.
- */
- void revokePrivilegesFromUser(const UserName& user);
-
- /**
- * Returns true if the set authorizes "desiredPrivilege".
- *
- * The set is considered to authorize "desiredPrivilege" if each action in
- * "desiredPrivilege" is satisfied either on the database component of
- * "desiredPrivilege.getResource()" or on WILDCARD_RESOURCE.
- *
- * TODO: Support checking for the privilege on the full resource name as well as the
- * database component, to support sub-database granularity privilege assignment.
- */
- bool hasPrivilege(const Privilege& desiredPrivilege);
-
- /**
- * Same as hasPrivilege, except checks all the privileges in a vector.
- */
- bool hasPrivileges(const std::vector<Privilege>& desiredPrivileges);
-
- private:
-
- /**
- * Information about privileges held on a resource.
- *
- * Instances are stored in the _byResource map, and accelerate the fast path of
- * hasPrivilege(). Privilege revocations via revokePrivilegesFromUser() can make these
- * entries invalid, at which point they are marked "dirty". Dirty entries are rebuilt via
- * _rebuildEntry(), below, during execution of hasPrivilege().
- */
- class ResourcePrivilegeCacheEntry {
- public:
- ResourcePrivilegeCacheEntry() : actions(), dirty(false) {}
-
- // All actions enabled on the associated resource, provided that "dirty" is false.
- ActionSet actions;
-
- // False if this data is consistent with the full privilege information, stored in the
- // _byUser map.
- bool dirty;
- };
-
- /**
- * Type of map from resource names to authorized actions.
- */
- typedef StringMap<ResourcePrivilegeCacheEntry> ResourcePrivilegeCache;
-
- /**
- * Type of map from user identity to information about the user's privileges. The
- * values in the map are themselves maps from resource names to associated actions.
- */
- typedef std::map<UserName, StringMap<ActionSet> > UserPrivilegeMap;
-
- void _rebuildEntry(const StringData& resource, ResourcePrivilegeCacheEntry* summary);
-
- ResourcePrivilegeCacheEntry* _lookupEntry(const StringData& resource);
- ResourcePrivilegeCacheEntry* _lookupOrInsertEntry(const StringData& resource);
-
- // Information about privileges available on all resources.
- ResourcePrivilegeCacheEntry _globalPrivilegeEntry;
-
- // Cache of privilege information, by resource.
- ResourcePrivilegeCache _byResource;
-
- // Directory of privilege information, by user.
- UserPrivilegeMap _byUser;
- };
-
-} // namespace mongo
diff --git a/src/mongo/db/auth/privilege_set_test.cpp b/src/mongo/db/auth/privilege_set_test.cpp
deleted file mode 100644
index 235fb7f6b7d..00000000000
--- a/src/mongo/db/auth/privilege_set_test.cpp
+++ /dev/null
@@ -1,211 +0,0 @@
-/* Copyright 2012 10gen Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * Unit tests of the PrivilegeSet type.
- */
-
-#include <iostream>
-
-#include "mongo/db/auth/action_set.h"
-#include "mongo/db/auth/privilege_set.h"
-#include "mongo/unittest/unittest.h"
-
-namespace mongo {
-namespace {
-
- // Convenience methods for outputting UserName and construction ActionSets that make tests
- // concise, but that we're reluctant to put into the types themselves.
-
- std::ostream& operator<<(std::ostream& os, const UserName& uname) {
- return os << uname.toString();
- }
-
- std::ostream& operator<<(std::ostream&os, const std::vector<UserName>& ps) {
- os << "[ ";
- for (size_t i = 0; i < ps.size(); ++i)
- os << ps[i] << ' ';
- os << ']';
- return os;
- }
-
- ActionSet operator|(const ActionSet& lhs, const ActionSet& rhs) {
- ActionSet result = lhs;
- result.addAllActionsFromSet(rhs);
- return result;
- }
-
- ActionSet operator|(const ActionSet& lhs, const ActionType& rhs) {
- ActionSet result = lhs;
- result.addAction(rhs);
- return result;
- }
-
- ActionSet operator|(const ActionType& lhs, const ActionType& rhs) {
- ActionSet result;
- result.addAction(lhs);
- result.addAction(rhs);
- return result;
- }
-
- // Tests
-
- TEST(PrivilegeSetTest, PrivilegeSet) {
- PrivilegeSet capSet;
- UserName user1("user1", "test");
- UserName user2("user2", "test2");
-
- // Initially, the capability set contains no privileges at all.
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::find)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("bar", ActionType::find)));
-
- // Grant find and update to "foo", only.
- capSet.grantPrivilege(Privilege("foo", ActionType::find|ActionType::update), user1);
-
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::find)));
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::find|ActionType::update)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::find|ActionType::remove)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("bar", ActionType::find)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::remove)));
-
- // Grant "userAdmin", "update" and "remove" on "foo" to user2, which changes the set of
- // actions this privilege set will approve.
- capSet.grantPrivilege(
- Privilege("foo", ActionType::userAdmin|ActionType::update|ActionType::remove),
- user2);
-
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::userAdmin)));
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::update)));
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::userAdmin)));
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::find|ActionType::remove)));
-
- // Revoke user2's privileges.
- capSet.revokePrivilegesFromUser(user2);
-
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::userAdmin)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::find|ActionType::remove)));
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::update)));
-
- // Revoke user2's privileges again; should be a no-op.
- capSet.revokePrivilegesFromUser(user2);
-
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::userAdmin)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::find|ActionType::remove)));
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::update)));
-
- // Re-grant "userAdmin", "update" and "remove" on "foo" to user2.
- capSet.grantPrivilege(
- Privilege("foo", ActionType::userAdmin|ActionType::update|ActionType::remove),
- user2);
-
- // The set still contains no capabilities on "bar".
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("bar", ActionType::find)));
-
- // Let user2 "find" on "bar".
- capSet.grantPrivilege(Privilege("bar", ActionType::find), user2);
-
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("bar", ActionType::find)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("bar", ActionType::update)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("bar", ActionType::remove)));
-
- // Let user1 "find" and "update" on "bar".
- capSet.grantPrivilege(Privilege("bar", ActionType::update|ActionType::find), user1);
-
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("bar", ActionType::find|ActionType::update)));
- ASSERT_FALSE(capSet.hasPrivilege(
- Privilege("bar",
- ActionType::find|ActionType::update|ActionType::remove)));
-
- // Revoke user1's privileges.
- capSet.revokePrivilegesFromUser(user1);
-
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("foo", ActionType::update)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::find)));
- ASSERT_TRUE(capSet.hasPrivilege(Privilege("bar", ActionType::find)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("bar", ActionType::update)));
-
- // Revoke user2's privileges.
- capSet.revokePrivilegesFromUser(user2);
-
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("foo", ActionType::update)));
- ASSERT_FALSE(capSet.hasPrivilege(Privilege("bar", ActionType::find)));
- }
-
- TEST(PrivilegeSetTest, WildcardPrivileges) {
- // Tests acquisition and revocation of privileges on WILDCARD_RESOURCE.
-
- PrivilegeSet privSet;
-
- UserName user("user", "db");
- Privilege wildcardFind("*", ActionType::find);
- Privilege wildcardUpdate("*", ActionType::update);
- Privilege wildcardFindAndUpdate("*", ActionType::find|ActionType::update);
- Privilege fooFind("foo", ActionType::find);
- Privilege fooUpdate("foo", ActionType::update);
- Privilege fooFindAndUpdate("foo", ActionType::find|ActionType::update);
- Privilege barFind("bar", ActionType::find);
- Privilege barUpdate("bar", ActionType::update);
- Privilege barFindAndUpdate("bar", ActionType::find|ActionType::update);
-
- // With no granted privileges, assert that hasPrivilege returns false.
- ASSERT_FALSE(privSet.hasPrivilege(wildcardFind));
- ASSERT_FALSE(privSet.hasPrivilege(wildcardUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(wildcardFindAndUpdate));
-
- ASSERT_FALSE(privSet.hasPrivilege(fooFind));
- ASSERT_FALSE(privSet.hasPrivilege(fooUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(fooFindAndUpdate));
-
- ASSERT_FALSE(privSet.hasPrivilege(barFind));
- ASSERT_FALSE(privSet.hasPrivilege(barUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(barFindAndUpdate));
-
- // Grant some privileges, and ensure that exactly those privileges are granted.
- std::vector<Privilege> grantedPrivileges;
- grantedPrivileges.push_back(wildcardFind);
- grantedPrivileges.push_back(fooUpdate);
-
- privSet.grantPrivileges(grantedPrivileges, user);
-
- ASSERT_TRUE(privSet.hasPrivilege(wildcardFind));
- ASSERT_FALSE(privSet.hasPrivilege(wildcardUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(wildcardFindAndUpdate));
-
- ASSERT_TRUE(privSet.hasPrivilege(fooFind));
- ASSERT_TRUE(privSet.hasPrivilege(fooUpdate));
- ASSERT_TRUE(privSet.hasPrivilege(fooFindAndUpdate));
-
- ASSERT_TRUE(privSet.hasPrivilege(barFind));
- ASSERT_FALSE(privSet.hasPrivilege(barUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(barFindAndUpdate));
-
- // Revoke the granted privileges, and assert that hasPrivilege returns false.
- privSet.revokePrivilegesFromUser(user);
-
- ASSERT_FALSE(privSet.hasPrivilege(wildcardFind));
- ASSERT_FALSE(privSet.hasPrivilege(wildcardUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(wildcardFindAndUpdate));
-
- ASSERT_FALSE(privSet.hasPrivilege(fooFind));
- ASSERT_FALSE(privSet.hasPrivilege(fooUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(fooFindAndUpdate));
-
- ASSERT_FALSE(privSet.hasPrivilege(barFind));
- ASSERT_FALSE(privSet.hasPrivilege(barUpdate));
- ASSERT_FALSE(privSet.hasPrivilege(barFindAndUpdate));
- }
-
-} // namespace
-} // namespace mongo
diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp
index 2c15d76c393..8b84f3639ad 100644
--- a/src/mongo/db/commands/authentication_commands.cpp
+++ b/src/mongo/db/commands/authentication_commands.cpp
@@ -225,8 +225,6 @@ namespace mongo {
AuthorizationSession* authorizationSession =
ClientBasic::getCurrent()->getAuthorizationSession();
- Principal* principal = new Principal(user);
- authorizationSession->addAndAuthorizePrincipal(principal);
status = authorizationSession->addAndAuthorizeUser(user);
if (!status.isOK()) {
return status;
diff --git a/src/mongo/db/dbeval.cpp b/src/mongo/db/dbeval.cpp
index 97c430fcf3a..94b80c796f3 100644
--- a/src/mongo/db/dbeval.cpp
+++ b/src/mongo/db/dbeval.cpp
@@ -24,7 +24,6 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_manager_global.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/auth/privilege_set.h"
#include "mongo/db/cmdline.h"
#include "mongo/db/commands.h"
#include "mongo/db/introspect.h"
diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp
index 3006c96d98d..2c6311d463a 100644
--- a/src/mongo/db/dbwebserver.cpp
+++ b/src/mongo/db/dbwebserver.cpp
@@ -30,7 +30,6 @@
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_manager_global.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/auth/principal.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/auth/user_name.h"
#include "mongo/db/background.h"
diff --git a/src/mongo/db/repl/rs.cpp b/src/mongo/db/repl/rs.cpp
index 9521be707ed..01a552be5d9 100644
--- a/src/mongo/db/repl/rs.cpp
+++ b/src/mongo/db/repl/rs.cpp
@@ -20,7 +20,6 @@
#include "mongo/base/status.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/authorization_session.h"
-#include "mongo/db/auth/principal.h"
#include "mongo/db/client.h"
#include "mongo/db/cmdline.h"
#include "mongo/db/dbhelpers.h"