diff options
author | Spencer T Brody <spencer@10gen.com> | 2013-05-14 17:33:25 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2013-05-22 19:14:01 -0400 |
commit | eb719438afc316e9bf56bf716a129def27f5e768 (patch) | |
tree | b00f395fec7c39ebc2e074cc77e4bd1bf9bbca2b /src | |
parent | 83900ac233c2a94e0f3e6a1628cf822f9bb88425 (diff) | |
download | mongo-eb719438afc316e9bf56bf716a129def27f5e768.tar.gz |
Split AuthorizationManager into 2 classes: AuthorizationManager and AuthorizationSession.
Diffstat (limited to 'src')
49 files changed, 1229 insertions, 1128 deletions
diff --git a/src/mongo/db/auth/SConscript b/src/mongo/db/auth/SConscript index 6d8e9b3aa10..2ca9b8d87e0 100644 --- a/src/mongo/db/auth/SConscript +++ b/src/mongo/db/auth/SConscript @@ -14,6 +14,7 @@ env.StaticLibrary('authcore', ['action_set.cpp', 'authorization_manager.cpp', 'role_graph.cpp', 'role_name.cpp', + 'authorization_session.cpp', 'principal.cpp', 'principal_name.cpp', 'principal_set.cpp', @@ -42,5 +43,5 @@ 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('authorization_manager_test', 'authorization_manager_test.cpp', +env.CppUnitTest('authorization_session_test', 'authorization_session_test.cpp', LIBDEPS=['authcore']) diff --git a/src/mongo/db/auth/auth_external_state_d.cpp b/src/mongo/db/auth/auth_external_state_d.cpp index b125b889475..48dd9b7adca 100644 --- a/src/mongo/db/auth/auth_external_state_d.cpp +++ b/src/mongo/db/auth/auth_external_state_d.cpp @@ -18,7 +18,7 @@ #include "mongo/base/status.h" #include "mongo/client/dbclientinterface.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/client.h" #include "mongo/db/dbhelpers.h" #include "mongo/db/d_concurrency.h" diff --git a/src/mongo/db/auth/auth_external_state_s.cpp b/src/mongo/db/auth/auth_external_state_s.cpp index ca4f5f96cb4..612072f7e14 100644 --- a/src/mongo/db/auth/auth_external_state_s.cpp +++ b/src/mongo/db/auth/auth_external_state_s.cpp @@ -20,7 +20,7 @@ #include "mongo/base/status.h" #include "mongo/client/dbclientinterface.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/jsobj.h" #include "mongo/s/grid.h" diff --git a/src/mongo/db/auth/authorization_manager.cpp b/src/mongo/db/auth/authorization_manager.cpp index 194c59e81e6..68a728fa754 100644 --- a/src/mongo/db/auth/authorization_manager.cpp +++ b/src/mongo/db/auth/authorization_manager.cpp @@ -17,23 +17,6 @@ #include "mongo/db/auth/authorization_manager.h" #include <string> -#include <vector> - -#include "mongo/base/init.h" -#include "mongo/base/status.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/auth_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/client.h" -#include "mongo/db/jsobj.h" -#include "mongo/db/namespacestring.h" -#include "mongo/util/assert_util.h" -#include "mongo/util/log.h" -#include "mongo/util/mongoutils/str.h" namespace mongo { @@ -51,196 +34,14 @@ namespace mongo { bool AuthorizationManager::_doesSupportOldStylePrivileges = true; bool AuthorizationManager::_authEnabled = false; -namespace { - const std::string ADMIN_DBNAME = "admin"; - const std::string LOCAL_DBNAME = "local"; - - const std::string ROLES_FIELD_NAME = "roles"; - const std::string OTHER_DB_ROLES_FIELD_NAME = "otherDBRoles"; - const std::string READONLY_FIELD_NAME = "readOnly"; - - const std::string SYSTEM_ROLE_READ = "read"; - const std::string SYSTEM_ROLE_READ_WRITE = "readWrite"; - const std::string SYSTEM_ROLE_USER_ADMIN = "userAdmin"; - const std::string SYSTEM_ROLE_DB_ADMIN = "dbAdmin"; - const std::string SYSTEM_ROLE_CLUSTER_ADMIN = "clusterAdmin"; - const std::string SYSTEM_ROLE_READ_ANY_DB = "readAnyDatabase"; - const std::string SYSTEM_ROLE_READ_WRITE_ANY_DB = "readWriteAnyDatabase"; - const std::string SYSTEM_ROLE_USER_ADMIN_ANY_DB = "userAdminAnyDatabase"; - const std::string SYSTEM_ROLE_DB_ADMIN_ANY_DB = "dbAdminAnyDatabase"; - -} // namespace - - // ActionSets for the various system roles. These ActionSets contain all the actions that - // a user of each system role is granted. - ActionSet readRoleActions; - ActionSet readWriteRoleActions; - ActionSet userAdminRoleActions; - ActionSet dbAdminRoleActions; - ActionSet clusterAdminRoleActions; - // Can only be performed by internal connections. Nothing ever explicitly grants these actions, - // but they're included when calling addAllActions on an ActionSet, which is how internal - // connections are granted their privileges. - ActionSet internalActions; - // Old-style user roles - ActionSet compatibilityReadOnlyActions; - ActionSet compatibilityReadWriteActions; - ActionSet compatibilityReadOnlyAdminActions; - ActionSet compatibilityReadWriteAdminActions; - - // This sets up the system role ActionSets. This is what determines what actions each role - // is authorized to perform - MONGO_INITIALIZER(AuthorizationSystemRoles)(InitializerContext* context) { - // Read role - readRoleActions.addAction(ActionType::cloneCollectionLocalSource); - readRoleActions.addAction(ActionType::collStats); - readRoleActions.addAction(ActionType::dbHash); - readRoleActions.addAction(ActionType::dbStats); - readRoleActions.addAction(ActionType::find); - readRoleActions.addAction(ActionType::indexRead); - readRoleActions.addAction(ActionType::killCursors); - - // Read-write role - readWriteRoleActions.addAllActionsFromSet(readRoleActions); - readWriteRoleActions.addAction(ActionType::cloneCollectionTarget); - readWriteRoleActions.addAction(ActionType::convertToCapped); - readWriteRoleActions.addAction(ActionType::createCollection); // dbAdmin gets this also - readWriteRoleActions.addAction(ActionType::dropCollection); // dbAdmin gets this also - readWriteRoleActions.addAction(ActionType::dropIndexes); // dbAdmin gets this also - readWriteRoleActions.addAction(ActionType::emptycapped); - readWriteRoleActions.addAction(ActionType::ensureIndex); // dbAdmin gets this also - readWriteRoleActions.addAction(ActionType::insert); - readWriteRoleActions.addAction(ActionType::remove); - readWriteRoleActions.addAction(ActionType::renameCollectionSameDB); // dbAdmin gets this also - readWriteRoleActions.addAction(ActionType::update); - - // User admin role - userAdminRoleActions.addAction(ActionType::userAdmin); - - // DB admin role - dbAdminRoleActions.addAction(ActionType::clean); - dbAdminRoleActions.addAction(ActionType::cloneCollectionLocalSource); - dbAdminRoleActions.addAction(ActionType::collMod); - dbAdminRoleActions.addAction(ActionType::collStats); - dbAdminRoleActions.addAction(ActionType::compact); - dbAdminRoleActions.addAction(ActionType::convertToCapped); - dbAdminRoleActions.addAction(ActionType::createCollection); // readWrite gets this also - dbAdminRoleActions.addAction(ActionType::dbStats); - dbAdminRoleActions.addAction(ActionType::dropCollection); // readWrite gets this also - dbAdminRoleActions.addAction(ActionType::dropIndexes); // readWrite gets this also - dbAdminRoleActions.addAction(ActionType::ensureIndex); // readWrite gets this also - dbAdminRoleActions.addAction(ActionType::indexRead); - dbAdminRoleActions.addAction(ActionType::indexStats); - dbAdminRoleActions.addAction(ActionType::profileEnable); - dbAdminRoleActions.addAction(ActionType::profileRead); - dbAdminRoleActions.addAction(ActionType::reIndex); - dbAdminRoleActions.addAction(ActionType::renameCollectionSameDB); // readWrite gets this also - dbAdminRoleActions.addAction(ActionType::storageDetails); - dbAdminRoleActions.addAction(ActionType::validate); - - // We separate clusterAdmin read-only and read-write actions for backwards - // compatibility with old-style read-only admin users. This separation is not exposed to - // the user, and could go away once we stop supporting old-style privilege documents. - ActionSet clusterAdminRoleReadActions; - ActionSet clusterAdminRoleWriteActions; - - // Cluster admin role - clusterAdminRoleReadActions.addAction(ActionType::connPoolStats); - clusterAdminRoleReadActions.addAction(ActionType::connPoolSync); - clusterAdminRoleReadActions.addAction(ActionType::getCmdLineOpts); - clusterAdminRoleReadActions.addAction(ActionType::getLog); - clusterAdminRoleReadActions.addAction(ActionType::getParameter); - clusterAdminRoleReadActions.addAction(ActionType::getShardMap); - clusterAdminRoleReadActions.addAction(ActionType::getShardVersion); - clusterAdminRoleReadActions.addAction(ActionType::hostInfo); - clusterAdminRoleReadActions.addAction(ActionType::listDatabases); - clusterAdminRoleReadActions.addAction(ActionType::listShards); - clusterAdminRoleReadActions.addAction(ActionType::logRotate); - clusterAdminRoleReadActions.addAction(ActionType::netstat); - clusterAdminRoleReadActions.addAction(ActionType::replSetFreeze); - clusterAdminRoleReadActions.addAction(ActionType::replSetGetStatus); - clusterAdminRoleReadActions.addAction(ActionType::replSetMaintenance); - clusterAdminRoleReadActions.addAction(ActionType::replSetStepDown); - clusterAdminRoleReadActions.addAction(ActionType::replSetSyncFrom); - clusterAdminRoleReadActions.addAction(ActionType::setParameter); - clusterAdminRoleReadActions.addAction(ActionType::setShardVersion); // TODO: should this be internal? - clusterAdminRoleReadActions.addAction(ActionType::serverStatus); - clusterAdminRoleReadActions.addAction(ActionType::splitVector); - clusterAdminRoleReadActions.addAction(ActionType::shutdown); - clusterAdminRoleReadActions.addAction(ActionType::top); - clusterAdminRoleReadActions.addAction(ActionType::touch); - clusterAdminRoleReadActions.addAction(ActionType::unlock); - clusterAdminRoleReadActions.addAction(ActionType::unsetSharding); - clusterAdminRoleReadActions.addAction(ActionType::writeBacksQueued); - - clusterAdminRoleWriteActions.addAction(ActionType::addShard); - clusterAdminRoleWriteActions.addAction(ActionType::closeAllDatabases); - clusterAdminRoleWriteActions.addAction(ActionType::cpuProfiler); - clusterAdminRoleWriteActions.addAction(ActionType::cursorInfo); - clusterAdminRoleWriteActions.addAction(ActionType::diagLogging); - clusterAdminRoleWriteActions.addAction(ActionType::dropDatabase); // TODO: Should there be a CREATE_DATABASE also? - clusterAdminRoleWriteActions.addAction(ActionType::enableSharding); - clusterAdminRoleWriteActions.addAction(ActionType::flushRouterConfig); - clusterAdminRoleWriteActions.addAction(ActionType::fsync); - clusterAdminRoleWriteActions.addAction(ActionType::inprog); - clusterAdminRoleWriteActions.addAction(ActionType::killop); - clusterAdminRoleWriteActions.addAction(ActionType::moveChunk); - clusterAdminRoleWriteActions.addAction(ActionType::movePrimary); - clusterAdminRoleWriteActions.addAction(ActionType::removeShard); - clusterAdminRoleWriteActions.addAction(ActionType::repairDatabase); - clusterAdminRoleWriteActions.addAction(ActionType::replSetInitiate); - clusterAdminRoleWriteActions.addAction(ActionType::replSetReconfig); - clusterAdminRoleWriteActions.addAction(ActionType::resync); - clusterAdminRoleWriteActions.addAction(ActionType::shardCollection); - clusterAdminRoleWriteActions.addAction(ActionType::shardingState); - clusterAdminRoleWriteActions.addAction(ActionType::split); - clusterAdminRoleWriteActions.addAction(ActionType::splitChunk); - - clusterAdminRoleActions.addAllActionsFromSet(clusterAdminRoleReadActions); - clusterAdminRoleActions.addAllActionsFromSet(clusterAdminRoleWriteActions); - clusterAdminRoleActions.addAction(ActionType::killCursors); - - // Old-style user actions, for backwards compatibility - compatibilityReadOnlyActions.addAllActionsFromSet(readRoleActions); - - compatibilityReadWriteActions.addAllActionsFromSet(readWriteRoleActions); - compatibilityReadWriteActions.addAllActionsFromSet(dbAdminRoleActions); - compatibilityReadWriteActions.addAllActionsFromSet(userAdminRoleActions); - compatibilityReadWriteActions.addAction(ActionType::clone); - compatibilityReadWriteActions.addAction(ActionType::copyDBTarget); - compatibilityReadWriteActions.addAction(ActionType::dropDatabase); - compatibilityReadWriteActions.addAction(ActionType::repairDatabase); - - compatibilityReadOnlyAdminActions.addAllActionsFromSet(compatibilityReadOnlyActions); - compatibilityReadOnlyAdminActions.addAllActionsFromSet(clusterAdminRoleReadActions); - - compatibilityReadWriteAdminActions.addAllActionsFromSet(compatibilityReadWriteActions); - compatibilityReadWriteAdminActions.addAllActionsFromSet(compatibilityReadOnlyAdminActions); - compatibilityReadWriteAdminActions.addAllActionsFromSet(clusterAdminRoleWriteActions); - - // Internal commands - internalActions.addAction(ActionType::clone); - internalActions.addAction(ActionType::handshake); - internalActions.addAction(ActionType::mapReduceShardedFinish); - internalActions.addAction(ActionType::replSetElect); - internalActions.addAction(ActionType::replSetFresh); - internalActions.addAction(ActionType::replSetGetRBID); - internalActions.addAction(ActionType::replSetHeartbeat); - internalActions.addAction(ActionType::writebacklisten); - internalActions.addAction(ActionType::_migrateClone); - internalActions.addAction(ActionType::_recvChunkAbort); - internalActions.addAction(ActionType::_recvChunkCommit); - internalActions.addAction(ActionType::_recvChunkStart); - internalActions.addAction(ActionType::_recvChunkStatus); - internalActions.addAction(ActionType::_transferMods); - - return Status::OK(); - } - void AuthorizationManager::setSupportOldStylePrivilegeDocuments(bool enabled) { _doesSupportOldStylePrivileges = enabled; } + bool AuthorizationManager::getSupportOldStylePrivilegeDocuments() { + return _doesSupportOldStylePrivileges; + } + void AuthorizationManager::setAuthEnabled(bool enabled) { _authEnabled = enabled; } @@ -249,580 +50,4 @@ namespace { return _authEnabled; } - static inline Status _oldPrivilegeFormatNotSupported() { - return Status(ErrorCodes::UnsupportedFormat, - "Support for compatibility-form privilege documents disabled; " - "All system.users entries must contain a 'roles' field"); - } - - static inline Status _badValue(const char* reason, int location) { - return Status(ErrorCodes::BadValue, reason, location); - } - - static inline Status _badValue(const std::string& reason, int location) { - return Status(ErrorCodes::BadValue, reason, location); - } - - static inline StringData makeStringDataFromBSONElement(const BSONElement& element) { - return StringData(element.valuestr(), element.valuestrsize() - 1); - } - - static Status _checkRolesArray(const BSONElement& rolesElement) { - if (rolesElement.type() != Array) { - return _badValue("Role fields must be an array when present in system.users entries", - 0); - } - for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) { - BSONElement element = *iter; - if (element.type() != String || makeStringDataFromBSONElement(element).empty()) { - return _badValue("Roles must be non-empty strings.", 0); - } - } - return Status::OK(); - } - - Status AuthorizationManager::checkValidPrivilegeDocument(const StringData& dbname, - const BSONObj& doc) { - BSONElement userElement = doc[USER_NAME_FIELD_NAME]; - BSONElement userSourceElement = doc[USER_SOURCE_FIELD_NAME]; - BSONElement passwordElement = doc[PASSWORD_FIELD_NAME]; - BSONElement rolesElement = doc[ROLES_FIELD_NAME]; - BSONElement otherDBRolesElement = doc[OTHER_DB_ROLES_FIELD_NAME]; - BSONElement readOnlyElement = doc[READONLY_FIELD_NAME]; - - // Validate the "user" element. - if (userElement.type() != String) - return _badValue("system.users entry needs 'user' field to be a string", 14051); - if (makeStringDataFromBSONElement(userElement).empty()) - return _badValue("system.users entry needs 'user' field to be non-empty", 14053); - - // Must set exactly one of "userSource" and "pwd" fields. - if (userSourceElement.eoo() == passwordElement.eoo()) { - return _badValue("system.users entry must have either a 'pwd' field or a 'userSource' " - "field, but not both", 0); - } - - if (!_doesSupportOldStylePrivileges && rolesElement.eoo()) { - return _oldPrivilegeFormatNotSupported(); - } - - // Cannot have both "roles" and "readOnly" elements. - if (!rolesElement.eoo() && !readOnlyElement.eoo()) { - return _badValue("system.users entry must not have both 'roles' and 'readOnly' fields", - 0); - } - - // Validate the "pwd" element, if present. - if (!passwordElement.eoo()) { - if (passwordElement.type() != String) - return _badValue("system.users entry needs 'pwd' field to be a string", 14052); - if (makeStringDataFromBSONElement(passwordElement).empty()) - return _badValue("system.users entry needs 'pwd' field to be non-empty", 14054); - } - - // Validate the "userSource" element, if present. - if (!userSourceElement.eoo()) { - if (userSourceElement.type() != String || - makeStringDataFromBSONElement(userSourceElement).empty()) { - - return _badValue("system.users entry needs 'userSource' field to be a non-empty " - "string, if present", 0); - } - if (userSourceElement.str() == dbname) { - return _badValue(mongoutils::str::stream() << "'" << dbname << - "' is not a valid value for the userSource field in " << - dbname << ".system.users entries", - 0); - } - if (rolesElement.eoo()) { - return _badValue("system.users entry needs 'roles' field if 'userSource' field " - "is present.", 0); - } - } - - // Validate the "roles" element. - if (!rolesElement.eoo()) { - Status status = _checkRolesArray(rolesElement); - if (!status.isOK()) - return status; - } - - if (!otherDBRolesElement.eoo()) { - if (dbname != ADMIN_DBNAME) { - return _badValue("Only admin.system.users entries may contain 'otherDBRoles' " - "fields", 0); - } - if (rolesElement.eoo()) { - return _badValue("system.users entries with 'otherDBRoles' fields must contain " - "'roles' fields", 0); - } - if (otherDBRolesElement.type() != Object) { - return _badValue("'otherDBRoles' field must be an object when present in " - "system.users entries", 0); - } - for (BSONObjIterator iter(otherDBRolesElement.embeddedObject()); - iter.more(); iter.next()) { - - Status status = _checkRolesArray(*iter); - if (!status.isOK()) - return status; - } - } - - return Status::OK(); - } - - AuthorizationManager::AuthorizationManager(AuthExternalState* externalState) { - _externalState.reset(externalState); - } - - AuthorizationManager::~AuthorizationManager(){} - - ActionSet AuthorizationManager::getAllUserActions() { - ActionSet allActions; - allActions.addAllActionsFromSet(readRoleActions); - allActions.addAllActionsFromSet(readWriteRoleActions); - allActions.addAllActionsFromSet(userAdminRoleActions); - allActions.addAllActionsFromSet(dbAdminRoleActions); - allActions.addAllActionsFromSet(clusterAdminRoleActions); - return allActions; - } - - void AuthorizationManager::startRequest() { - _externalState->startRequest(); - } - - void AuthorizationManager::addAuthorizedPrincipal(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->isImplicitPrivilegeAcquisitionEnabled()) - return; - _acquirePrivilegesForPrincipalFromDatabase(ADMIN_DBNAME, principal->getName()); - principal->markDatabaseAsProbed(ADMIN_DBNAME); - const std::string dbname = principal->getName().getDB().toString(); - _acquirePrivilegesForPrincipalFromDatabase(dbname, principal->getName()); - principal->markDatabaseAsProbed(dbname); - _externalState->onAddAuthorizedPrincipal(principal); - } - - void AuthorizationManager::_acquirePrivilegesForPrincipalFromDatabase( - const std::string& dbname, const PrincipalName& principal) { - - BSONObj privilegeDocument; - Status status = getPrivilegeDocument(dbname, principal, &privilegeDocument); - if (status.isOK()) { - status = acquirePrivilegesFromPrivilegeDocument(dbname, principal, privilegeDocument); - } - if (!status.isOK() && status != ErrorCodes::UserNotFound) { - log() << "Privilege acquisition failed for " << principal << " in database " << - dbname << ": " << status.reason() << " (" << status.codeString() << ")" << endl; - } - } - - Principal* AuthorizationManager::lookupPrincipal(const PrincipalName& name) { - return _authenticatedPrincipals.lookup(name); - } - - void AuthorizationManager::logoutDatabase(const std::string& dbname) { - Principal* principal = _authenticatedPrincipals.lookupByDBName(dbname); - if (!principal) - return; - _acquiredPrivileges.revokePrivilegesFromPrincipal(principal->getName()); - _authenticatedPrincipals.removeByDBName(dbname); - _externalState->onLogoutDatabase(dbname); - } - - PrincipalSet::NameIterator AuthorizationManager::getAuthenticatedPrincipalNames() { - return _authenticatedPrincipals.getNames(); - } - - Status AuthorizationManager::acquirePrivilege(const Privilege& privilege, - const PrincipalName& authorizingPrincipal) { - if (!_authenticatedPrincipals.lookup(authorizingPrincipal)) { - return Status(ErrorCodes::UserNotFound, - mongoutils::str::stream() - << "No authenticated principle found with name: " - << authorizingPrincipal.getUser() - << " from database " - << authorizingPrincipal.getDB(), - 0); - } - _acquiredPrivileges.grantPrivilege(privilege, authorizingPrincipal); - return Status::OK(); - } - - void AuthorizationManager::grantInternalAuthorization(const std::string& principalName) { - Principal* principal = new Principal(PrincipalName(principalName, "local")); - ActionSet actions; - actions.addAllActions(); - - addAuthorizedPrincipal(principal); - fassert(16581, acquirePrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, actions), - principal->getName()).isOK()); - } - - bool AuthorizationManager::hasInternalAuthorization() { - ActionSet allActions; - allActions.addAllActions(); - return _acquiredPrivileges.hasPrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, - allActions)); - } - - ActionSet AuthorizationManager::getActionsForOldStyleUser(const std::string& dbname, - bool readOnly) { - if (dbname == ADMIN_DBNAME || dbname == LOCAL_DBNAME) { - if (readOnly) { - return compatibilityReadOnlyAdminActions; - } else { - return compatibilityReadWriteAdminActions; - } - } else { - if (readOnly) { - return compatibilityReadOnlyActions; - } else { - return compatibilityReadWriteActions; - } - } - } - - Status AuthorizationManager::acquirePrivilegesFromPrivilegeDocument( - const std::string& dbname, const PrincipalName& principal, const BSONObj& privilegeDocument) { - if (!_authenticatedPrincipals.lookup(principal)) { - return Status(ErrorCodes::UserNotFound, - mongoutils::str::stream() - << "No authenticated principle found with name: " - << principal.getUser() - << " from database " - << principal.getDB(), - 0); - } - if (principal.getUser() == internalSecurity.user) { - // Grant full access to internal user - ActionSet allActions; - allActions.addAllActions(); - return acquirePrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, allActions), - principal); - } - return buildPrivilegeSet(dbname, principal, privilegeDocument, &_acquiredPrivileges); - } - - Status AuthorizationManager::buildPrivilegeSet(const std::string& dbname, - const PrincipalName& principal, - const BSONObj& privilegeDocument, - PrivilegeSet* result) { - if (!privilegeDocument.hasField(ROLES_FIELD_NAME)) { - // Old-style (v2.2 and prior) privilege document - if (_doesSupportOldStylePrivileges) { - return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname, - principal, - privilegeDocument, - result); - } - else { - return _oldPrivilegeFormatNotSupported(); - } - } - else { - return _buildPrivilegeSetFromExtendedPrivilegeDocument( - dbname, principal, privilegeDocument, result); - } - } - - Status AuthorizationManager::_buildPrivilegeSetFromOldStylePrivilegeDocument( - const std::string& dbname, - const PrincipalName& principal, - const BSONObj& privilegeDocument, - PrivilegeSet* result) { - if (!(privilegeDocument.hasField(USER_NAME_FIELD_NAME) && - privilegeDocument.hasField(PASSWORD_FIELD_NAME))) { - - return Status(ErrorCodes::UnsupportedFormat, - mongoutils::str::stream() << "Invalid old-style privilege document " - "received when trying to extract privileges: " - << privilegeDocument, - 0); - } - if (privilegeDocument[USER_NAME_FIELD_NAME].str() != principal.getUser()) { - return Status(ErrorCodes::BadValue, - mongoutils::str::stream() << "Principal name from privilege document \"" - << privilegeDocument[USER_NAME_FIELD_NAME].str() - << "\" doesn't match name of provided Principal \"" - << principal.getUser() - << "\"", - 0); - } - - bool readOnly = privilegeDocument[READONLY_FIELD_NAME].trueValue(); - ActionSet actions = getActionsForOldStyleUser(dbname, readOnly); - std::string resourceName = (dbname == ADMIN_DBNAME || dbname == LOCAL_DBNAME) ? - PrivilegeSet::WILDCARD_RESOURCE : dbname; - result->grantPrivilege(Privilege(resourceName, actions), principal); - - return Status::OK(); - } - - /** - * Adds to "outPrivileges" the privileges associated with having the named "role" on "dbname". - * - * Returns non-OK status if "role" is not a defined role in "dbname". - */ - static void _addPrivilegesForSystemRole(const std::string& dbname, - const std::string& role, - std::vector<Privilege>* outPrivileges) { - const bool isAdminDB = (dbname == ADMIN_DBNAME); - - if (role == SYSTEM_ROLE_READ) { - outPrivileges->push_back(Privilege(dbname, readRoleActions)); - } - else if (role == SYSTEM_ROLE_READ_WRITE) { - outPrivileges->push_back(Privilege(dbname, readWriteRoleActions)); - } - else if (role == SYSTEM_ROLE_USER_ADMIN) { - outPrivileges->push_back(Privilege(dbname, userAdminRoleActions)); - } - else if (role == SYSTEM_ROLE_DB_ADMIN) { - outPrivileges->push_back(Privilege(dbname, dbAdminRoleActions)); - } - else if (isAdminDB && role == SYSTEM_ROLE_READ_ANY_DB) { - outPrivileges->push_back(Privilege(PrivilegeSet::WILDCARD_RESOURCE, readRoleActions)); - } - else if (isAdminDB && role == SYSTEM_ROLE_READ_WRITE_ANY_DB) { - outPrivileges->push_back( - Privilege(PrivilegeSet::WILDCARD_RESOURCE, readWriteRoleActions)); - } - else if (isAdminDB && role == SYSTEM_ROLE_USER_ADMIN_ANY_DB) { - outPrivileges->push_back( - Privilege(PrivilegeSet::WILDCARD_RESOURCE, userAdminRoleActions)); - } - else if (isAdminDB && role == SYSTEM_ROLE_DB_ADMIN_ANY_DB) { - outPrivileges->push_back( - Privilege(PrivilegeSet::WILDCARD_RESOURCE, dbAdminRoleActions)); - } - else if (isAdminDB && role == SYSTEM_ROLE_CLUSTER_ADMIN) { - outPrivileges->push_back( - Privilege(PrivilegeSet::WILDCARD_RESOURCE, clusterAdminRoleActions)); - } - else { - warning() << "No such role, \"" << role << "\", in database " << dbname << - ". No privileges will be acquired from this role" << endl; - } - } - - /** - * 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. - */ - static 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 == PrivilegeSet::WILDCARD_RESOURCE) { - return Status(ErrorCodes::BadValue, - PrivilegeSet::WILDCARD_RESOURCE + " 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 PrincipalName& principal, - const BSONObj& privilegeDocument, - PrivilegeSet* result) { - - 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, principal); - return Status::OK(); - } - - bool AuthorizationManager::checkAuthorization(const std::string& resource, - ActionType action) { - return checkAuthForPrivilege(Privilege(resource, action)).isOK(); - } - - bool AuthorizationManager::checkAuthorization(const std::string& resource, - ActionSet actions) { - return checkAuthForPrivilege(Privilege(resource, actions)).isOK(); - } - - Status AuthorizationManager::checkAuthForQuery(const std::string& ns) { - NamespaceString namespaceString(ns); - verify(!namespaceString.isCommand()); - if (!checkAuthorization(ns, ActionType::find)) { - return Status(ErrorCodes::Unauthorized, - mongoutils::str::stream() << "not authorized for query on " << ns, - 0); - } - return Status::OK(); - } - - Status AuthorizationManager::checkAuthForInsert(const std::string& ns) { - NamespaceString namespaceString(ns); - if (!checkAuthorization(ns, ActionType::insert)) { - return Status(ErrorCodes::Unauthorized, - mongoutils::str::stream() << "not authorized for insert on " << ns, - 0); - } - return Status::OK(); - } - - Status AuthorizationManager::checkAuthForUpdate(const std::string& ns, bool upsert) { - NamespaceString namespaceString(ns); - if (!upsert) { - if (!checkAuthorization(ns, ActionType::update)) { - return Status(ErrorCodes::Unauthorized, - mongoutils::str::stream() << "not authorized for update on " << ns, - 0); - } - } - else { - ActionSet required; - required.addAction(ActionType::update); - required.addAction(ActionType::insert); - if (!checkAuthorization(ns, required)) { - return Status(ErrorCodes::Unauthorized, - mongoutils::str::stream() << "not authorized for upsert on " << ns, - 0); - } - } - return Status::OK(); - } - - Status AuthorizationManager::checkAuthForDelete(const std::string& ns) { - NamespaceString namespaceString(ns); - if (!checkAuthorization(ns, ActionType::remove)) { - return Status(ErrorCodes::Unauthorized, - mongoutils::str::stream() << "not authorized to remove from " << ns, - 0); - } - return Status::OK(); - } - - Status AuthorizationManager::checkAuthForGetMore(const std::string& ns) { - return checkAuthForQuery(ns); - } - - Privilege AuthorizationManager::_modifyPrivilegeForSpecialCases(const Privilege& privilege) { - ActionSet newActions; - newActions.addAllActionsFromSet(privilege.getActions()); - std::string collectionName = NamespaceString(privilege.getResource()).coll; - if (collectionName == "system.users") { - newActions.removeAction(ActionType::find); - newActions.removeAction(ActionType::insert); - newActions.removeAction(ActionType::update); - newActions.removeAction(ActionType::remove); - newActions.addAction(ActionType::userAdmin); - } else if (collectionName == "system.profile") { - newActions.removeAction(ActionType::find); - newActions.addAction(ActionType::profileRead); - } else if (collectionName == "system.indexes" && newActions.contains(ActionType::find)) { - newActions.removeAction(ActionType::find); - newActions.addAction(ActionType::indexRead); - } - - return Privilege(privilege.getResource(), newActions); - } - - Status AuthorizationManager::checkAuthForPrivilege(const Privilege& privilege) { - if (_externalState->shouldIgnoreAuthChecks()) - return Status::OK(); - - return _probeForPrivilege(privilege); - } - - Status AuthorizationManager::checkAuthForPrivileges(const vector<Privilege>& privileges) { - if (_externalState->shouldIgnoreAuthChecks()) - return Status::OK(); - - for (size_t i = 0; i < privileges.size(); ++i) { - Status status = _probeForPrivilege(privileges[i]); - if (!status.isOK()) - return status; - } - - return Status::OK(); - } - - Status AuthorizationManager::_probeForPrivilege(const Privilege& privilege) { - Privilege modifiedPrivilege = _modifyPrivilegeForSpecialCases(privilege); - if (_acquiredPrivileges.hasPrivilege(modifiedPrivilege)) - return Status::OK(); - - std::string dbname = nsToDatabase(modifiedPrivilege.getResource()); - for (PrincipalSet::iterator iter = _authenticatedPrincipals.begin(), - end = _authenticatedPrincipals.end(); - iter != end; ++iter) { - - Principal* principal = *iter; - if (!principal->isImplicitPrivilegeAcquisitionEnabled()) - continue; - if (principal->isDatabaseProbed(dbname)) - continue; - _acquirePrivilegesForPrincipalFromDatabase(dbname, principal->getName()); - principal->markDatabaseAsProbed(dbname); - if (_acquiredPrivileges.hasPrivilege(modifiedPrivilege)) - return Status::OK(); - } - return Status(ErrorCodes::Unauthorized, "unauthorized", 0); - } - } // namespace mongo diff --git a/src/mongo/db/auth/authorization_manager.h b/src/mongo/db/auth/authorization_manager.h index 905180470ea..4935caccf50 100644 --- a/src/mongo/db/auth/authorization_manager.h +++ b/src/mongo/db/auth/authorization_manager.h @@ -1,5 +1,5 @@ /** -* Copyright (C) 2012 10gen Inc. +* Copyright (C) 2013 10gen Inc. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, @@ -17,18 +17,8 @@ #pragma once #include <string> -#include <vector> #include "mongo/base/disallow_copying.h" -#include "mongo/base/status.h" -#include "mongo/db/auth/action_set.h" -#include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/auth_external_state.h" -#include "mongo/db/auth/principal.h" -#include "mongo/db/auth/principal_name.h" -#include "mongo/db/auth/principal_set.h" -#include "mongo/db/auth/privilege.h" -#include "mongo/db/auth/privilege_set.h" namespace mongo { @@ -37,17 +27,13 @@ namespace mongo { */ struct AuthInfo { AuthInfo(); - string user; - string pwd; + std::string user; + std::string pwd; }; extern AuthInfo internalSecurity; // set at startup and not changed after initialization. /** - * Contains all the authorization logic for a single client connection. It contains a set of - * the principals which have been authenticated, as well as a set of privileges that have been - * granted by those principals to perform various actions. - * An AuthorizationManager object is present within every mongo::Client object, therefore there - * is one per thread that corresponds to an incoming client connection. + * Contains server/cluster-wide information about Authorization. */ class AuthorizationManager { MONGO_DISALLOW_COPYING(AuthorizationManager); @@ -60,152 +46,29 @@ namespace mongo { static const std::string USER_SOURCE_FIELD_NAME; static const std::string PASSWORD_FIELD_NAME; + /** + * Sets whether or not we allow old style (pre v2.4) privilege documents for this whole + * server. + */ static void setSupportOldStylePrivilegeDocuments(bool enabled); - // Sets whether or not access control enforcement is enabled for this whole server.. + /** + * Returns true if we allow old style privilege privilege documents for this whole server. + */ + static bool getSupportOldStylePrivilegeDocuments(); + + /** + * Sets whether or not access control enforcement is enabled for this whole server. + */ static void setAuthEnabled(bool enabled); - // Returns true if access control is enabled on this server. + /** + * Returns true if access control is enabled on this server. + */ static bool isAuthEnabled(); - // Checks to see if "doc" is a valid privilege document, assuming it is stored in the - // "system.users" collection of database "dbname". - // - // Returns Status::OK() if the document is good, or Status(ErrorCodes::BadValue), otherwise. - static Status checkValidPrivilegeDocument(const StringData& dbname, const BSONObj& doc); - - // Takes ownership of the externalState. - explicit AuthorizationManager(AuthExternalState* externalState); - ~AuthorizationManager(); - - // Should be called at the beginning of every new request. This performs the checks - // necessary to determine if localhost connections should be given full access. - // TODO: try to eliminate the need for this call. - void startRequest(); - - // Adds "principal" to the authorization manager, and takes ownership of it. - void addAuthorizedPrincipal(Principal* principal); - - // 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 PrincipalName& name); - - // Gets an iterator over the names of all authenticated principals stored in this manager. - PrincipalSet::NameIterator getAuthenticatedPrincipalNames(); - - // Removes any authenticated principals whose authorization credentials came from the given - // 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 PrincipalName& authorizingPrincipal); - - // Adds a new principal with the given principal name and authorizes it with full access. - // Used to grant internal threads full access. - void grantInternalAuthorization(const std::string& principalName); - - // Checks if this connection has been authenticated as an internal user. - bool hasInternalAuthorization(); - - // Checks if this connection has the privileges required to perform the given action - // on the given resource. Contains all the authorization logic including handling things - // like the localhost exception. Returns true if the action may proceed on the resource. - // Note: this may acquire a database read lock (for automatic privilege acquisition). - bool checkAuthorization(const std::string& resource, ActionType action); - - // Same as above but takes an ActionSet instead of a single ActionType. Returns true if - // 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 PrincipalName& principal, - const BSONObj& privilegeDocument); - - // Returns the privilege document with the given user name in the given database. Currently - // this information comes from the system.users collection in that database. - Status getPrivilegeDocument(const std::string& dbname, - const PrincipalName& userName, - BSONObj* result) { - return _externalState->getPrivilegeDocument(dbname, userName, result); - } - - // Checks if this connection has the privileges necessary to perform a query on the given - // namespace. - Status checkAuthForQuery(const std::string& ns); - - // Checks if this connection has the privileges necessary to perform an update on the given - // namespace. - Status checkAuthForUpdate(const std::string& ns, bool upsert); - - // Checks if this connection has the privileges necessary to perform an insert to the given - // namespace. - Status checkAuthForInsert(const std::string& ns); - - // Checks if this connection has the privileges necessary to perform a delete on the given - // namespace. - Status checkAuthForDelete(const std::string& ns); - - // Checks if this connection has the privileges necessary to perform a getMore on the given - // namespace. - Status checkAuthForGetMore(const std::string& ns); - - // Checks if this connection is authorized for the given Privilege. - Status checkAuthForPrivilege(const Privilege& privilege); - - // Checks if this connection is authorized for all the given Privileges. - Status checkAuthForPrivileges(const vector<Privilege>& privileges); - - // 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. - static ActionSet getActionsForOldStyleUser(const std::string& dbname, bool readOnly); - - // Parses the privilege document and returns a PrivilegeSet of all the Privileges that - // the privilege document grants. - static Status buildPrivilegeSet(const std::string& dbname, - const PrincipalName& principal, - const BSONObj& privilegeDocument, - PrivilegeSet* result); - - // Returns an ActionSet of all actions that can be be granted to users. This does not - // include internal-only actions. - static ActionSet getAllUserActions(); private: - // 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 PrincipalName& principal); - - // Checks to see if the given privilege is allowed, performing implicit privilege - // acquisition if enabled and necessary to resolve the privilege. - Status _probeForPrivilege(const Privilege& privilege); - - // Parses the old-style (pre 2.4) privilege document and returns a PrivilegeSet of all the - // Privileges that the privilege document grants. - static Status _buildPrivilegeSetFromOldStylePrivilegeDocument( - const std::string& dbname, - const PrincipalName& principal, - const BSONObj& privilegeDocument, - PrivilegeSet* result); - - // 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". - static Status _buildPrivilegeSetFromExtendedPrivilegeDocument( - const std::string& dbname, - const PrincipalName& principal, - const BSONObj& privilegeDocument, - PrivilegeSet* result); - - // Returns a new privilege that has replaced the actions needed to handle special casing - // certain namespaces like system.users and system.profile. - Privilege _modifyPrivilegeForSpecialCases(const Privilege& privilege); static bool _doesSupportOldStylePrivileges; @@ -213,13 +76,6 @@ namespace mongo { // --auth or --keyFile). // This is a config setting, set at startup and not changing after initialization. static bool _authEnabled; - - scoped_ptr<AuthExternalState> _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; }; } // namespace mongo diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp new file mode 100644 index 00000000000..054e030a0d4 --- /dev/null +++ b/src/mongo/db/auth/authorization_session.cpp @@ -0,0 +1,804 @@ +/** +* Copyright (C) 2012 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "mongo/db/auth/authorization_session.h" + +#include <string> +#include <vector> + +#include "mongo/base/init.h" +#include "mongo/base/status.h" +#include "mongo/db/auth/action_set.h" +#include "mongo/db/auth/action_type.h" +#include "mongo/db/auth/auth_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/client.h" +#include "mongo/db/jsobj.h" +#include "mongo/db/namespacestring.h" +#include "mongo/util/assert_util.h" +#include "mongo/util/log.h" +#include "mongo/util/mongoutils/str.h" + +namespace mongo { + +namespace { + const std::string ADMIN_DBNAME = "admin"; + const std::string LOCAL_DBNAME = "local"; + + const std::string ROLES_FIELD_NAME = "roles"; + const std::string OTHER_DB_ROLES_FIELD_NAME = "otherDBRoles"; + const std::string READONLY_FIELD_NAME = "readOnly"; + + const std::string SYSTEM_ROLE_READ = "read"; + const std::string SYSTEM_ROLE_READ_WRITE = "readWrite"; + const std::string SYSTEM_ROLE_USER_ADMIN = "userAdmin"; + const std::string SYSTEM_ROLE_DB_ADMIN = "dbAdmin"; + const std::string SYSTEM_ROLE_CLUSTER_ADMIN = "clusterAdmin"; + const std::string SYSTEM_ROLE_READ_ANY_DB = "readAnyDatabase"; + const std::string SYSTEM_ROLE_READ_WRITE_ANY_DB = "readWriteAnyDatabase"; + const std::string SYSTEM_ROLE_USER_ADMIN_ANY_DB = "userAdminAnyDatabase"; + const std::string SYSTEM_ROLE_DB_ADMIN_ANY_DB = "dbAdminAnyDatabase"; + +} // namespace + + // ActionSets for the various system roles. These ActionSets contain all the actions that + // a user of each system role is granted. + ActionSet readRoleActions; + ActionSet readWriteRoleActions; + ActionSet userAdminRoleActions; + ActionSet dbAdminRoleActions; + ActionSet clusterAdminRoleActions; + // Can only be performed by internal connections. Nothing ever explicitly grants these actions, + // but they're included when calling addAllActions on an ActionSet, which is how internal + // connections are granted their privileges. + ActionSet internalActions; + // Old-style user roles + ActionSet compatibilityReadOnlyActions; + ActionSet compatibilityReadWriteActions; + ActionSet compatibilityReadOnlyAdminActions; + ActionSet compatibilityReadWriteAdminActions; + + // This sets up the system role ActionSets. This is what determines what actions each role + // is authorized to perform + MONGO_INITIALIZER(AuthorizationSystemRoles)(InitializerContext* context) { + // Read role + readRoleActions.addAction(ActionType::cloneCollectionLocalSource); + readRoleActions.addAction(ActionType::collStats); + readRoleActions.addAction(ActionType::dbHash); + readRoleActions.addAction(ActionType::dbStats); + readRoleActions.addAction(ActionType::find); + readRoleActions.addAction(ActionType::indexRead); + readRoleActions.addAction(ActionType::killCursors); + + // Read-write role + readWriteRoleActions.addAllActionsFromSet(readRoleActions); + readWriteRoleActions.addAction(ActionType::cloneCollectionTarget); + readWriteRoleActions.addAction(ActionType::convertToCapped); + readWriteRoleActions.addAction(ActionType::createCollection); // db admin gets this also + readWriteRoleActions.addAction(ActionType::dropCollection); + readWriteRoleActions.addAction(ActionType::dropIndexes); + readWriteRoleActions.addAction(ActionType::emptycapped); + readWriteRoleActions.addAction(ActionType::ensureIndex); + readWriteRoleActions.addAction(ActionType::insert); + readWriteRoleActions.addAction(ActionType::remove); + readWriteRoleActions.addAction(ActionType::renameCollectionSameDB); // db admin gets this also + readWriteRoleActions.addAction(ActionType::update); + + // User admin role + userAdminRoleActions.addAction(ActionType::userAdmin); + + // DB admin role + dbAdminRoleActions.addAction(ActionType::clean); + dbAdminRoleActions.addAction(ActionType::cloneCollectionLocalSource); + dbAdminRoleActions.addAction(ActionType::collMod); + dbAdminRoleActions.addAction(ActionType::collStats); + dbAdminRoleActions.addAction(ActionType::compact); + dbAdminRoleActions.addAction(ActionType::convertToCapped); + dbAdminRoleActions.addAction(ActionType::createCollection); // read_write gets this also + dbAdminRoleActions.addAction(ActionType::dbStats); + dbAdminRoleActions.addAction(ActionType::dropCollection); + dbAdminRoleActions.addAction(ActionType::dropIndexes); + dbAdminRoleActions.addAction(ActionType::ensureIndex); + dbAdminRoleActions.addAction(ActionType::indexRead); + dbAdminRoleActions.addAction(ActionType::indexStats); + dbAdminRoleActions.addAction(ActionType::profileEnable); + dbAdminRoleActions.addAction(ActionType::profileRead); + dbAdminRoleActions.addAction(ActionType::reIndex); + dbAdminRoleActions.addAction(ActionType::renameCollectionSameDB); // read_write gets this also + dbAdminRoleActions.addAction(ActionType::storageDetails); + dbAdminRoleActions.addAction(ActionType::validate); + + // We separate clusterAdmin read-only and read-write actions for backwards + // compatibility with old-style read-only admin users. This separation is not exposed to + // the user, and could go away once we stop supporting old-style privilege documents. + ActionSet clusterAdminRoleReadActions; + ActionSet clusterAdminRoleWriteActions; + + // Cluster admin role + clusterAdminRoleReadActions.addAction(ActionType::connPoolStats); + clusterAdminRoleReadActions.addAction(ActionType::connPoolSync); + clusterAdminRoleReadActions.addAction(ActionType::getCmdLineOpts); + clusterAdminRoleReadActions.addAction(ActionType::getLog); + clusterAdminRoleReadActions.addAction(ActionType::getParameter); + clusterAdminRoleReadActions.addAction(ActionType::getShardMap); + clusterAdminRoleReadActions.addAction(ActionType::getShardVersion); + clusterAdminRoleReadActions.addAction(ActionType::hostInfo); + clusterAdminRoleReadActions.addAction(ActionType::listDatabases); + clusterAdminRoleReadActions.addAction(ActionType::listShards); + clusterAdminRoleReadActions.addAction(ActionType::logRotate); + clusterAdminRoleReadActions.addAction(ActionType::netstat); + clusterAdminRoleReadActions.addAction(ActionType::replSetFreeze); + clusterAdminRoleReadActions.addAction(ActionType::replSetGetStatus); + clusterAdminRoleReadActions.addAction(ActionType::replSetMaintenance); + clusterAdminRoleReadActions.addAction(ActionType::replSetStepDown); + clusterAdminRoleReadActions.addAction(ActionType::replSetSyncFrom); + clusterAdminRoleReadActions.addAction(ActionType::setParameter); + clusterAdminRoleReadActions.addAction(ActionType::setShardVersion); // TODO: should this be internal? + clusterAdminRoleReadActions.addAction(ActionType::serverStatus); + clusterAdminRoleReadActions.addAction(ActionType::splitVector); + clusterAdminRoleReadActions.addAction(ActionType::shutdown); + clusterAdminRoleReadActions.addAction(ActionType::top); + clusterAdminRoleReadActions.addAction(ActionType::touch); + clusterAdminRoleReadActions.addAction(ActionType::unlock); + clusterAdminRoleReadActions.addAction(ActionType::unsetSharding); + clusterAdminRoleReadActions.addAction(ActionType::writeBacksQueued); + + clusterAdminRoleWriteActions.addAction(ActionType::addShard); + clusterAdminRoleWriteActions.addAction(ActionType::closeAllDatabases); + clusterAdminRoleWriteActions.addAction(ActionType::cpuProfiler); + clusterAdminRoleWriteActions.addAction(ActionType::cursorInfo); + clusterAdminRoleWriteActions.addAction(ActionType::diagLogging); + clusterAdminRoleWriteActions.addAction(ActionType::dropDatabase); // TODO: Should there be a CREATE_DATABASE also? + clusterAdminRoleWriteActions.addAction(ActionType::enableSharding); + clusterAdminRoleWriteActions.addAction(ActionType::flushRouterConfig); + clusterAdminRoleWriteActions.addAction(ActionType::fsync); + clusterAdminRoleWriteActions.addAction(ActionType::inprog); + clusterAdminRoleWriteActions.addAction(ActionType::killop); + clusterAdminRoleWriteActions.addAction(ActionType::moveChunk); + clusterAdminRoleWriteActions.addAction(ActionType::movePrimary); + clusterAdminRoleWriteActions.addAction(ActionType::removeShard); + clusterAdminRoleWriteActions.addAction(ActionType::repairDatabase); + clusterAdminRoleWriteActions.addAction(ActionType::replSetInitiate); + clusterAdminRoleWriteActions.addAction(ActionType::replSetReconfig); + clusterAdminRoleWriteActions.addAction(ActionType::resync); + clusterAdminRoleWriteActions.addAction(ActionType::shardCollection); + clusterAdminRoleWriteActions.addAction(ActionType::shardingState); + clusterAdminRoleWriteActions.addAction(ActionType::split); + clusterAdminRoleWriteActions.addAction(ActionType::splitChunk); + + clusterAdminRoleActions.addAllActionsFromSet(clusterAdminRoleReadActions); + clusterAdminRoleActions.addAllActionsFromSet(clusterAdminRoleWriteActions); + clusterAdminRoleActions.addAction(ActionType::killCursors); + + // Old-style user actions, for backwards compatibility + compatibilityReadOnlyActions.addAllActionsFromSet(readRoleActions); + + compatibilityReadWriteActions.addAllActionsFromSet(readWriteRoleActions); + compatibilityReadWriteActions.addAllActionsFromSet(dbAdminRoleActions); + compatibilityReadWriteActions.addAllActionsFromSet(userAdminRoleActions); + compatibilityReadWriteActions.addAction(ActionType::clone); + compatibilityReadWriteActions.addAction(ActionType::copyDBTarget); + compatibilityReadWriteActions.addAction(ActionType::dropDatabase); + compatibilityReadWriteActions.addAction(ActionType::repairDatabase); + + compatibilityReadOnlyAdminActions.addAllActionsFromSet(compatibilityReadOnlyActions); + compatibilityReadOnlyAdminActions.addAllActionsFromSet(clusterAdminRoleReadActions); + + compatibilityReadWriteAdminActions.addAllActionsFromSet(compatibilityReadWriteActions); + compatibilityReadWriteAdminActions.addAllActionsFromSet(compatibilityReadOnlyAdminActions); + compatibilityReadWriteAdminActions.addAllActionsFromSet(clusterAdminRoleWriteActions); + + // Internal commands + internalActions.addAction(ActionType::clone); + internalActions.addAction(ActionType::handshake); + internalActions.addAction(ActionType::mapReduceShardedFinish); + internalActions.addAction(ActionType::replSetElect); + internalActions.addAction(ActionType::replSetFresh); + internalActions.addAction(ActionType::replSetGetRBID); + internalActions.addAction(ActionType::replSetHeartbeat); + internalActions.addAction(ActionType::writebacklisten); + internalActions.addAction(ActionType::_migrateClone); + internalActions.addAction(ActionType::_recvChunkAbort); + internalActions.addAction(ActionType::_recvChunkCommit); + internalActions.addAction(ActionType::_recvChunkStart); + internalActions.addAction(ActionType::_recvChunkStatus); + internalActions.addAction(ActionType::_transferMods); + + return Status::OK(); + } + + static inline Status _oldPrivilegeFormatNotSupported() { + return Status(ErrorCodes::UnsupportedFormat, + "Support for compatibility-form privilege documents disabled; " + "All system.users entries must contain a 'roles' field"); + } + + static inline Status _badValue(const char* reason, int location) { + return Status(ErrorCodes::BadValue, reason, location); + } + + static inline Status _badValue(const std::string& reason, int location) { + return Status(ErrorCodes::BadValue, reason, location); + } + + static inline StringData makeStringDataFromBSONElement(const BSONElement& element) { + return StringData(element.valuestr(), element.valuestrsize() - 1); + } + + static Status _checkRolesArray(const BSONElement& rolesElement) { + if (rolesElement.type() != Array) { + return _badValue("Role fields must be an array when present in system.users entries", + 0); + } + for (BSONObjIterator iter(rolesElement.embeddedObject()); iter.more(); iter.next()) { + BSONElement element = *iter; + if (element.type() != String || makeStringDataFromBSONElement(element).empty()) { + return _badValue("Roles must be non-empty strings.", 0); + } + } + return Status::OK(); + } + + Status AuthorizationSession::checkValidPrivilegeDocument(const StringData& dbname, + const BSONObj& doc) { + BSONElement userElement = doc[AuthorizationManager::USER_NAME_FIELD_NAME]; + BSONElement userSourceElement = doc[AuthorizationManager::USER_SOURCE_FIELD_NAME]; + BSONElement passwordElement = doc[AuthorizationManager::PASSWORD_FIELD_NAME]; + BSONElement rolesElement = doc[ROLES_FIELD_NAME]; + BSONElement otherDBRolesElement = doc[OTHER_DB_ROLES_FIELD_NAME]; + BSONElement readOnlyElement = doc[READONLY_FIELD_NAME]; + + // Validate the "user" element. + if (userElement.type() != String) + return _badValue("system.users entry needs 'user' field to be a string", 14051); + if (makeStringDataFromBSONElement(userElement).empty()) + return _badValue("system.users entry needs 'user' field to be non-empty", 14053); + + // Must set exactly one of "userSource" and "pwd" fields. + if (userSourceElement.eoo() == passwordElement.eoo()) { + return _badValue("system.users entry must have either a 'pwd' field or a 'userSource' " + "field, but not both", 0); + } + + if (!AuthorizationManager::getSupportOldStylePrivilegeDocuments() && rolesElement.eoo()) { + return _oldPrivilegeFormatNotSupported(); + } + + // Cannot have both "roles" and "readOnly" elements. + if (!rolesElement.eoo() && !readOnlyElement.eoo()) { + return _badValue("system.users entry must not have both 'roles' and 'readOnly' fields", + 0); + } + + // Validate the "pwd" element, if present. + if (!passwordElement.eoo()) { + if (passwordElement.type() != String) + return _badValue("system.users entry needs 'pwd' field to be a string", 14052); + if (makeStringDataFromBSONElement(passwordElement).empty()) + return _badValue("system.users entry needs 'pwd' field to be non-empty", 14054); + } + + // Validate the "userSource" element, if present. + if (!userSourceElement.eoo()) { + if (userSourceElement.type() != String || + makeStringDataFromBSONElement(userSourceElement).empty()) { + + return _badValue("system.users entry needs 'userSource' field to be a non-empty " + "string, if present", 0); + } + if (userSourceElement.str() == dbname) { + return _badValue(mongoutils::str::stream() << "'" << dbname << + "' is not a valid value for the userSource field in " << + dbname << ".system.users entries", + 0); + } + if (rolesElement.eoo()) { + return _badValue("system.users entry needs 'roles' field if 'userSource' field " + "is present.", 0); + } + } + + // Validate the "roles" element. + if (!rolesElement.eoo()) { + Status status = _checkRolesArray(rolesElement); + if (!status.isOK()) + return status; + } + + if (!otherDBRolesElement.eoo()) { + if (dbname != ADMIN_DBNAME) { + return _badValue("Only admin.system.users entries may contain 'otherDBRoles' " + "fields", 0); + } + if (rolesElement.eoo()) { + return _badValue("system.users entries with 'otherDBRoles' fields must contain " + "'roles' fields", 0); + } + if (otherDBRolesElement.type() != Object) { + return _badValue("'otherDBRoles' field must be an object when present in " + "system.users entries", 0); + } + for (BSONObjIterator iter(otherDBRolesElement.embeddedObject()); + iter.more(); iter.next()) { + + Status status = _checkRolesArray(*iter); + if (!status.isOK()) + return status; + } + } + + return Status::OK(); + } + + AuthorizationSession::AuthorizationSession(AuthExternalState* externalState) { + _externalState.reset(externalState); + } + + AuthorizationSession::~AuthorizationSession(){} + + ActionSet AuthorizationSession::getAllUserActions() { + ActionSet allActions; + allActions.addAllActionsFromSet(readRoleActions); + allActions.addAllActionsFromSet(readWriteRoleActions); + allActions.addAllActionsFromSet(userAdminRoleActions); + allActions.addAllActionsFromSet(dbAdminRoleActions); + allActions.addAllActionsFromSet(clusterAdminRoleActions); + return allActions; + } + + void AuthorizationSession::startRequest() { + _externalState->startRequest(); + } + + void AuthorizationSession::addAuthorizedPrincipal(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->isImplicitPrivilegeAcquisitionEnabled()) + return; + _acquirePrivilegesForPrincipalFromDatabase(ADMIN_DBNAME, principal->getName()); + principal->markDatabaseAsProbed(ADMIN_DBNAME); + const std::string dbname = principal->getName().getDB().toString(); + _acquirePrivilegesForPrincipalFromDatabase(dbname, principal->getName()); + principal->markDatabaseAsProbed(dbname); + _externalState->onAddAuthorizedPrincipal(principal); + } + + void AuthorizationSession::_acquirePrivilegesForPrincipalFromDatabase( + const std::string& dbname, const PrincipalName& principal) { + + BSONObj privilegeDocument; + Status status = getPrivilegeDocument(dbname, principal, &privilegeDocument); + if (status.isOK()) { + status = acquirePrivilegesFromPrivilegeDocument(dbname, principal, privilegeDocument); + } + if (!status.isOK() && status != ErrorCodes::UserNotFound) { + log() << "Privilege acquisition failed for " << principal << " in database " << + dbname << ": " << status.reason() << " (" << status.codeString() << ")" << endl; + } + } + + Principal* AuthorizationSession::lookupPrincipal(const PrincipalName& name) { + return _authenticatedPrincipals.lookup(name); + } + + void AuthorizationSession::logoutDatabase(const std::string& dbname) { + Principal* principal = _authenticatedPrincipals.lookupByDBName(dbname); + if (!principal) + return; + _acquiredPrivileges.revokePrivilegesFromPrincipal(principal->getName()); + _authenticatedPrincipals.removeByDBName(dbname); + _externalState->onLogoutDatabase(dbname); + } + + PrincipalSet::NameIterator AuthorizationSession::getAuthenticatedPrincipalNames() { + return _authenticatedPrincipals.getNames(); + } + + Status AuthorizationSession::acquirePrivilege(const Privilege& privilege, + const PrincipalName& authorizingPrincipal) { + if (!_authenticatedPrincipals.lookup(authorizingPrincipal)) { + return Status(ErrorCodes::UserNotFound, + mongoutils::str::stream() + << "No authenticated principle found with name: " + << authorizingPrincipal.getUser() + << " from database " + << authorizingPrincipal.getDB(), + 0); + } + _acquiredPrivileges.grantPrivilege(privilege, authorizingPrincipal); + return Status::OK(); + } + + void AuthorizationSession::grantInternalAuthorization(const std::string& principalName) { + Principal* principal = new Principal(PrincipalName(principalName, "local")); + ActionSet actions; + actions.addAllActions(); + + addAuthorizedPrincipal(principal); + fassert(16581, acquirePrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, actions), + principal->getName()).isOK()); + } + + bool AuthorizationSession::hasInternalAuthorization() { + ActionSet allActions; + allActions.addAllActions(); + return _acquiredPrivileges.hasPrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, + allActions)); + } + + ActionSet AuthorizationSession::getActionsForOldStyleUser(const std::string& dbname, + bool readOnly) { + if (dbname == ADMIN_DBNAME || dbname == LOCAL_DBNAME) { + if (readOnly) { + return compatibilityReadOnlyAdminActions; + } else { + return compatibilityReadWriteAdminActions; + } + } else { + if (readOnly) { + return compatibilityReadOnlyActions; + } else { + return compatibilityReadWriteActions; + } + } + } + + Status AuthorizationSession::acquirePrivilegesFromPrivilegeDocument( + const std::string& dbname, const PrincipalName& principal, const BSONObj& privilegeDocument) { + if (!_authenticatedPrincipals.lookup(principal)) { + return Status(ErrorCodes::UserNotFound, + mongoutils::str::stream() + << "No authenticated principle found with name: " + << principal.getUser() + << " from database " + << principal.getDB(), + 0); + } + if (principal.getUser() == internalSecurity.user) { + // Grant full access to internal user + ActionSet allActions; + allActions.addAllActions(); + return acquirePrivilege(Privilege(PrivilegeSet::WILDCARD_RESOURCE, allActions), + principal); + } + return buildPrivilegeSet(dbname, principal, privilegeDocument, &_acquiredPrivileges); + } + + Status AuthorizationSession::buildPrivilegeSet(const std::string& dbname, + const PrincipalName& principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result) { + if (!privilegeDocument.hasField(ROLES_FIELD_NAME)) { + // Old-style (v2.2 and prior) privilege document + if (AuthorizationManager::getSupportOldStylePrivilegeDocuments()) { + return _buildPrivilegeSetFromOldStylePrivilegeDocument(dbname, + principal, + privilegeDocument, + result); + } + else { + return _oldPrivilegeFormatNotSupported(); + } + } + else { + return _buildPrivilegeSetFromExtendedPrivilegeDocument( + dbname, principal, privilegeDocument, result); + } + } + + Status AuthorizationSession::_buildPrivilegeSetFromOldStylePrivilegeDocument( + const std::string& dbname, + const PrincipalName& principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result) { + 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 != principal.getUser()) { + return Status(ErrorCodes::BadValue, + mongoutils::str::stream() << "Principal name from privilege document \"" + << userName + << "\" doesn't match name of provided Principal \"" + << principal.getUser() + << "\"", + 0); + } + + bool readOnly = privilegeDocument[READONLY_FIELD_NAME].trueValue(); + ActionSet actions = getActionsForOldStyleUser(dbname, readOnly); + std::string resourceName = (dbname == ADMIN_DBNAME || dbname == LOCAL_DBNAME) ? + PrivilegeSet::WILDCARD_RESOURCE : dbname; + result->grantPrivilege(Privilege(resourceName, actions), principal); + + return Status::OK(); + } + + /** + * Adds to "outPrivileges" the privileges associated with having the named "role" on "dbname". + * + * Returns non-OK status if "role" is not a defined role in "dbname". + */ + static void _addPrivilegesForSystemRole(const std::string& dbname, + const std::string& role, + std::vector<Privilege>* outPrivileges) { + const bool isAdminDB = (dbname == ADMIN_DBNAME); + + if (role == SYSTEM_ROLE_READ) { + outPrivileges->push_back(Privilege(dbname, readRoleActions)); + } + else if (role == SYSTEM_ROLE_READ_WRITE) { + outPrivileges->push_back(Privilege(dbname, readWriteRoleActions)); + } + else if (role == SYSTEM_ROLE_USER_ADMIN) { + outPrivileges->push_back(Privilege(dbname, userAdminRoleActions)); + } + else if (role == SYSTEM_ROLE_DB_ADMIN) { + outPrivileges->push_back(Privilege(dbname, dbAdminRoleActions)); + } + else if (isAdminDB && role == SYSTEM_ROLE_READ_ANY_DB) { + outPrivileges->push_back(Privilege(PrivilegeSet::WILDCARD_RESOURCE, readRoleActions)); + } + else if (isAdminDB && role == SYSTEM_ROLE_READ_WRITE_ANY_DB) { + outPrivileges->push_back( + Privilege(PrivilegeSet::WILDCARD_RESOURCE, readWriteRoleActions)); + } + else if (isAdminDB && role == SYSTEM_ROLE_USER_ADMIN_ANY_DB) { + outPrivileges->push_back( + Privilege(PrivilegeSet::WILDCARD_RESOURCE, userAdminRoleActions)); + } + else if (isAdminDB && role == SYSTEM_ROLE_DB_ADMIN_ANY_DB) { + outPrivileges->push_back( + Privilege(PrivilegeSet::WILDCARD_RESOURCE, dbAdminRoleActions)); + } + else if (isAdminDB && role == SYSTEM_ROLE_CLUSTER_ADMIN) { + outPrivileges->push_back( + Privilege(PrivilegeSet::WILDCARD_RESOURCE, clusterAdminRoleActions)); + } + else { + warning() << "No such role, \"" << role << "\", in database " << dbname << + ". No privileges will be acquired from this role" << endl; + } + } + + /** + * 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. + */ + static 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 == PrivilegeSet::WILDCARD_RESOURCE) { + return Status(ErrorCodes::BadValue, + PrivilegeSet::WILDCARD_RESOURCE + " 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 AuthorizationSession::_buildPrivilegeSetFromExtendedPrivilegeDocument( + const std::string& dbname, + const PrincipalName& principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result) { + + 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, principal); + return Status::OK(); + } + + bool AuthorizationSession::checkAuthorization(const std::string& resource, + ActionType action) { + return checkAuthForPrivilege(Privilege(resource, action)).isOK(); + } + + bool AuthorizationSession::checkAuthorization(const std::string& resource, + ActionSet actions) { + return checkAuthForPrivilege(Privilege(resource, actions)).isOK(); + } + + Status AuthorizationSession::checkAuthForQuery(const std::string& ns) { + NamespaceString namespaceString(ns); + verify(!namespaceString.isCommand()); + if (!checkAuthorization(ns, ActionType::find)) { + return Status(ErrorCodes::Unauthorized, + mongoutils::str::stream() << "not authorized for query on " << ns, + 0); + } + return Status::OK(); + } + + Status AuthorizationSession::checkAuthForInsert(const std::string& ns) { + NamespaceString namespaceString(ns); + if (!checkAuthorization(ns, ActionType::insert)) { + return Status(ErrorCodes::Unauthorized, + mongoutils::str::stream() << "not authorized for insert on " << ns, + 0); + } + return Status::OK(); + } + + Status AuthorizationSession::checkAuthForUpdate(const std::string& ns, bool upsert) { + NamespaceString namespaceString(ns); + if (!upsert) { + if (!checkAuthorization(ns, ActionType::update)) { + return Status(ErrorCodes::Unauthorized, + mongoutils::str::stream() << "not authorized for update on " << ns, + 0); + } + } + else { + ActionSet required; + required.addAction(ActionType::update); + required.addAction(ActionType::insert); + if (!checkAuthorization(ns, required)) { + return Status(ErrorCodes::Unauthorized, + mongoutils::str::stream() << "not authorized for upsert on " << ns, + 0); + } + } + return Status::OK(); + } + + Status AuthorizationSession::checkAuthForDelete(const std::string& ns) { + NamespaceString namespaceString(ns); + if (!checkAuthorization(ns, ActionType::remove)) { + return Status(ErrorCodes::Unauthorized, + mongoutils::str::stream() << "not authorized to remove from " << ns, + 0); + } + return Status::OK(); + } + + Status AuthorizationSession::checkAuthForGetMore(const std::string& ns) { + return checkAuthForQuery(ns); + } + + Privilege AuthorizationSession::_modifyPrivilegeForSpecialCases(const Privilege& privilege) { + ActionSet newActions; + newActions.addAllActionsFromSet(privilege.getActions()); + std::string collectionName = NamespaceString(privilege.getResource()).coll; + if (collectionName == "system.users") { + newActions.removeAction(ActionType::find); + newActions.removeAction(ActionType::insert); + newActions.removeAction(ActionType::update); + newActions.removeAction(ActionType::remove); + newActions.addAction(ActionType::userAdmin); + } else if (collectionName == "system.profile") { + newActions.removeAction(ActionType::find); + newActions.addAction(ActionType::profileRead); + } else if (collectionName == "system.indexes" && newActions.contains(ActionType::find)) { + newActions.removeAction(ActionType::find); + newActions.addAction(ActionType::indexRead); + } + + return Privilege(privilege.getResource(), newActions); + } + + Status AuthorizationSession::checkAuthForPrivilege(const Privilege& privilege) { + if (_externalState->shouldIgnoreAuthChecks()) + return Status::OK(); + + return _probeForPrivilege(privilege); + } + + Status AuthorizationSession::checkAuthForPrivileges(const vector<Privilege>& privileges) { + if (_externalState->shouldIgnoreAuthChecks()) + return Status::OK(); + + for (size_t i = 0; i < privileges.size(); ++i) { + Status status = _probeForPrivilege(privileges[i]); + if (!status.isOK()) + return status; + } + + return Status::OK(); + } + + Status AuthorizationSession::_probeForPrivilege(const Privilege& privilege) { + Privilege modifiedPrivilege = _modifyPrivilegeForSpecialCases(privilege); + if (_acquiredPrivileges.hasPrivilege(modifiedPrivilege)) + return Status::OK(); + + std::string dbname = nsToDatabase(modifiedPrivilege.getResource()); + for (PrincipalSet::iterator iter = _authenticatedPrincipals.begin(), + end = _authenticatedPrincipals.end(); + iter != end; ++iter) { + + Principal* principal = *iter; + if (!principal->isImplicitPrivilegeAcquisitionEnabled()) + continue; + if (principal->isDatabaseProbed(dbname)) + continue; + _acquirePrivilegesForPrincipalFromDatabase(dbname, principal->getName()); + principal->markDatabaseAsProbed(dbname); + if (_acquiredPrivileges.hasPrivilege(modifiedPrivilege)) + return Status::OK(); + } + return Status(ErrorCodes::Unauthorized, "unauthorized", 0); + } + +} // namespace mongo diff --git a/src/mongo/db/auth/authorization_session.h b/src/mongo/db/auth/authorization_session.h new file mode 100644 index 00000000000..7c109058068 --- /dev/null +++ b/src/mongo/db/auth/authorization_session.h @@ -0,0 +1,194 @@ +/** +* Copyright (C) 2012 10gen Inc. +* +* This program is free software: you can redistribute it and/or modify +* it under the terms of the GNU Affero General Public License, version 3, +* as published by the Free Software Foundation. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Affero General Public License for more details. +* +* You should have received a copy of the GNU Affero General Public License +* along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#pragma once + +#include <string> +#include <vector> + +#include "mongo/base/disallow_copying.h" +#include "mongo/base/status.h" +#include "mongo/db/auth/action_set.h" +#include "mongo/db/auth/action_type.h" +#include "mongo/db/auth/auth_external_state.h" +#include "mongo/db/auth/principal.h" +#include "mongo/db/auth/principal_name.h" +#include "mongo/db/auth/principal_set.h" +#include "mongo/db/auth/privilege.h" +#include "mongo/db/auth/privilege_set.h" + +namespace mongo { + + /** + * Contains all the authorization logic for a single client connection. It contains a set of + * the principals which have been authenticated, as well as a set of privileges that have been + * granted by those principals to perform various actions. + * An AuthorizationSession object is present within every mongo::Client object, therefore there + * is one per thread that corresponds to an incoming client connection. + */ + class AuthorizationSession { + MONGO_DISALLOW_COPYING(AuthorizationSession); + public: + + // Checks to see if "doc" is a valid privilege document, assuming it is stored in the + // "system.users" collection of database "dbname". + // + // Returns Status::OK() if the document is good, or Status(ErrorCodes::BadValue), otherwise. + static Status checkValidPrivilegeDocument(const StringData& dbname, const BSONObj& doc); + + // Takes ownership of the externalState. + explicit AuthorizationSession(AuthExternalState* externalState); + ~AuthorizationSession(); + + // Should be called at the beginning of every new request. This performs the checks + // necessary to determine if localhost connections should be given full access. + // TODO: try to eliminate theneed for this call. + void startRequest(); + + // Adds "principal" to the authorization manager, and takes ownership of it. + void addAuthorizedPrincipal(Principal* principal); + + // 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 PrincipalName& name); + + // Gets an iterator over the names of all authenticated principals stored in this manager. + PrincipalSet::NameIterator getAuthenticatedPrincipalNames(); + + // Removes any authenticated principals whose authorization credentials came from the given + // 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 PrincipalName& authorizingPrincipal); + + // Adds a new principal with the given principal name and authorizes it with full access. + // Used to grant internal threads full access. + void grantInternalAuthorization(const std::string& principalName); + + // Checks if this connection has been authenticated as an internal user. + bool hasInternalAuthorization(); + + // Checks if this connection has the privileges required to perform the given action + // on the given resource. Contains all the authorization logic including handling things + // like the localhost exception. Returns true if the action may proceed on the resource. + // Note: this may acquire a database read lock (for automatic privilege acquisition). + bool checkAuthorization(const std::string& resource, ActionType action); + + // Same as above but takes an ActionSet instead of a single ActionType. Returns true if + // 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 PrincipalName& principal, + const BSONObj& privilegeDocument); + + // Returns the privilege document with the given user name in the given database. Currently + // this information comes from the system.users collection in that database. + Status getPrivilegeDocument(const std::string& dbname, + const PrincipalName& userName, + BSONObj* result) { + return _externalState->getPrivilegeDocument(dbname, userName, result); + } + + // Checks if this connection has the privileges necessary to perform a query on the given + // namespace. + Status checkAuthForQuery(const std::string& ns); + + // Checks if this connection has the privileges necessary to perform an update on the given + // namespace. + Status checkAuthForUpdate(const std::string& ns, bool upsert); + + // Checks if this connection has the privileges necessary to perform an insert to the given + // namespace. + Status checkAuthForInsert(const std::string& ns); + + // Checks if this connection has the privileges necessary to perform a delete on the given + // namespace. + Status checkAuthForDelete(const std::string& ns); + + // Checks if this connection has the privileges necessary to perform a getMore on the given + // namespace. + Status checkAuthForGetMore(const std::string& ns); + + // Checks if this connection is authorized for the given Privilege. + Status checkAuthForPrivilege(const Privilege& privilege); + + // Checks if this connection is authorized for all the given Privileges. + Status checkAuthForPrivileges(const vector<Privilege>& privileges); + + // 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. + static ActionSet getActionsForOldStyleUser(const std::string& dbname, bool readOnly); + + // Parses the privilege document and returns a PrivilegeSet of all the Privileges that + // the privilege document grants. + static Status buildPrivilegeSet(const std::string& dbname, + const PrincipalName& principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result); + + // Returns an ActionSet of all actions that can be be granted to users. This does not + // include internal-only actions. + static ActionSet getAllUserActions(); + + private: + // 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 PrincipalName& principal); + + // Checks to see if the given privilege is allowed, performing implicit privilege + // acquisition if enabled and necessary to resolve the privilege. + Status _probeForPrivilege(const Privilege& privilege); + + // Parses the old-style (pre 2.4) privilege document and returns a PrivilegeSet of all the + // Privileges that the privilege document grants. + static Status _buildPrivilegeSetFromOldStylePrivilegeDocument( + const std::string& dbname, + const PrincipalName& principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result); + + // 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". + static Status _buildPrivilegeSetFromExtendedPrivilegeDocument( + const std::string& dbname, + const PrincipalName& principal, + const BSONObj& privilegeDocument, + PrivilegeSet* result); + + // Returns a new privilege that has replaced the actions needed to handle special casing + // certain namespaces like system.users and system.profile. + Privilege _modifyPrivilegeForSpecialCases(const Privilege& privilege); + + + scoped_ptr<AuthExternalState> _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; + }; + +} // namespace mongo diff --git a/src/mongo/db/auth/authorization_manager_test.cpp b/src/mongo/db/auth/authorization_session_test.cpp index 9df59339dab..9f11605d20c 100644 --- a/src/mongo/db/auth/authorization_manager_test.cpp +++ b/src/mongo/db/auth/authorization_session_test.cpp @@ -14,12 +14,13 @@ */ /** - * Unit tests of the AuthorizationManager type. + * Unit tests of the AuthorizationSession type. */ #include "mongo/base/status.h" #include "mongo/db/auth/auth_external_state_mock.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/jsobj.h" #include "mongo/db/namespacestring.h" #include "mongo/unittest/unittest.h" @@ -31,38 +32,38 @@ namespace mongo { namespace { - TEST(AuthorizationManagerTest, AcquirePrivilegeAndCheckAuthorization) { + TEST(AuthorizationSessionTest, AcquirePrivilegeAndCheckAuthorization) { Principal* principal = new Principal(PrincipalName("Spencer", "test")); ActionSet actions; actions.addAction(ActionType::insert); Privilege writePrivilege("test", actions); Privilege allDBsWritePrivilege("*", actions); AuthExternalStateMock* externalState = new AuthExternalStateMock(); - AuthorizationManager authManager(externalState); + AuthorizationSession authzSession(externalState); - ASSERT_FALSE(authManager.checkAuthorization("test", ActionType::insert)); + ASSERT_FALSE(authzSession.checkAuthorization("test", ActionType::insert)); externalState->setReturnValueForShouldIgnoreAuthChecks(true); - ASSERT_TRUE(authManager.checkAuthorization("test", ActionType::insert)); + ASSERT_TRUE(authzSession.checkAuthorization("test", ActionType::insert)); externalState->setReturnValueForShouldIgnoreAuthChecks(false); - ASSERT_FALSE(authManager.checkAuthorization("test", ActionType::insert)); + ASSERT_FALSE(authzSession.checkAuthorization("test", ActionType::insert)); ASSERT_EQUALS(ErrorCodes::UserNotFound, - authManager.acquirePrivilege(writePrivilege, principal->getName())); - authManager.addAuthorizedPrincipal(principal); - ASSERT_OK(authManager.acquirePrivilege(writePrivilege, principal->getName())); - ASSERT_TRUE(authManager.checkAuthorization("test", ActionType::insert)); - - ASSERT_FALSE(authManager.checkAuthorization("otherDb", ActionType::insert)); - ASSERT_OK(authManager.acquirePrivilege(allDBsWritePrivilege, principal->getName())); - ASSERT_TRUE(authManager.checkAuthorization("otherDb", ActionType::insert)); + authzSession.acquirePrivilege(writePrivilege, principal->getName())); + authzSession.addAuthorizedPrincipal(principal); + ASSERT_OK(authzSession.acquirePrivilege(writePrivilege, principal->getName())); + ASSERT_TRUE(authzSession.checkAuthorization("test", ActionType::insert)); + + ASSERT_FALSE(authzSession.checkAuthorization("otherDb", ActionType::insert)); + ASSERT_OK(authzSession.acquirePrivilege(allDBsWritePrivilege, principal->getName())); + ASSERT_TRUE(authzSession.checkAuthorization("otherDb", ActionType::insert)); // Auth checks on a collection should be applied to the database name. - ASSERT_TRUE(authManager.checkAuthorization("otherDb.collectionName", ActionType::insert)); + ASSERT_TRUE(authzSession.checkAuthorization("otherDb.collectionName", ActionType::insert)); - authManager.logoutDatabase("test"); - ASSERT_FALSE(authManager.checkAuthorization("test", ActionType::insert)); + authzSession.logoutDatabase("test"); + ASSERT_FALSE(authzSession.checkAuthorization("test", ActionType::insert)); } - TEST(AuthorizationManagerTest, GetPrivilegesFromPrivilegeDocumentCompatible) { + TEST(AuthorizationSessionTest, GetPrivilegesFromPrivilegeDocumentCompatible) { PrincipalName principal ("Spencer", "test"); BSONObj invalid; BSONObj readWrite = BSON("user" << "Spencer" << "pwd" << "passwordHash"); @@ -71,22 +72,22 @@ namespace { PrivilegeSet privilegeSet; ASSERT_EQUALS(ErrorCodes::UnsupportedFormat, - AuthorizationManager::buildPrivilegeSet("test", - principal, - invalid, - &privilegeSet).code()); - - ASSERT_OK(AuthorizationManager::buildPrivilegeSet("test", - principal, - readOnly, - &privilegeSet)); + AuthorizationSession::buildPrivilegeSet("test", + principal, + invalid, + &privilegeSet).code()); + + ASSERT_OK(AuthorizationSession::buildPrivilegeSet("test", + principal, + readOnly, + &privilegeSet)); ASSERT(!privilegeSet.hasPrivilege(Privilege("test", ActionType::insert))); ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find))); - ASSERT_OK(AuthorizationManager::buildPrivilegeSet("test", - principal, - readWrite, - &privilegeSet)); + ASSERT_OK(AuthorizationSession::buildPrivilegeSet("test", + principal, + readWrite, + &privilegeSet)); ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::find))); ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::insert))); ASSERT(privilegeSet.hasPrivilege(Privilege("test", ActionType::userAdmin))); @@ -96,20 +97,20 @@ namespace { ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::find))); ASSERT(!privilegeSet.hasPrivilege(Privilege("*", ActionType::find))); - ASSERT_OK(AuthorizationManager::buildPrivilegeSet("admin", - principal, - readOnly, - &privilegeSet)); + ASSERT_OK(AuthorizationSession::buildPrivilegeSet("admin", + principal, + 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(AuthorizationManager::buildPrivilegeSet("admin", - principal, - readWrite, - &privilegeSet)); + ASSERT_OK(AuthorizationSession::buildPrivilegeSet("admin", + principal, + readWrite, + &privilegeSet)); ASSERT(privilegeSet.hasPrivilege(Privilege("*", ActionType::insert))); } @@ -122,7 +123,7 @@ namespace { }; TEST_F(PrivilegeDocumentParsing, VerifyRolesFieldMustBeAnArray) { - ASSERT_NOT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_NOT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -132,7 +133,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyInvalidRoleGrantsNoPrivileges) { - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -142,7 +143,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyInvalidRoleStillAllowsOtherRoles) { - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -152,7 +153,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterAdminRoleFromNonAdminDatabase) { - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -164,7 +165,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterReadFromNonAdminDatabase) { - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -175,7 +176,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterReadWriteFromNonAdminDatabase) { - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -187,7 +188,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterUserAdminFromNonAdminDatabase) { - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -199,7 +200,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantClusterDBAdminFromNonAdminDatabase) { - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -211,7 +212,7 @@ namespace { } TEST_F(PrivilegeDocumentParsing, VerifyOtherDBRolesMustBeAnObjectOfArraysOfStrings) { - ASSERT_NOT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_NOT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -222,7 +223,7 @@ namespace { ASSERT(!privilegeSet.hasPrivilege(Privilege("test2", ActionType::find))); ASSERT(!privilegeSet.hasPrivilege(Privilege("admin", ActionType::find))); - ASSERT_NOT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_NOT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -236,7 +237,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, VerifyCannotGrantPrivilegesOnOtherDatabasesNormally) { // Cannot grant privileges on other databases, except from admin database. - ASSERT_NOT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_NOT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -249,7 +250,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, SuccessfulSimpleReadGrant) { // Grant read on test. - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << "roles" << BSON_ARRAY("read")), @@ -262,7 +263,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, SuccessfulSimpleUserAdminTest) { // Grant userAdmin on "test" database. - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "test", user, BSON("user" << "spencer" << "pwd" << "" << @@ -275,7 +276,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, GrantUserAdminOnAdmin) { // Grant userAdmin on admin. - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -288,7 +289,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, GrantUserAdminOnTestViaAdmin) { // Grant userAdmin on test via admin. - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -302,7 +303,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, SuccessfulClusterAdminTest) { // Grant userAdminAnyDatabase. - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -316,7 +317,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, GrantClusterReadWrite) { // Grant readWrite on everything via the admin database. - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -332,7 +333,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, ProhibitGrantOnWildcard) { // Cannot grant readWrite to everythign using "otherDBRoles". - ASSERT_NOT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_NOT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -349,7 +350,7 @@ namespace { TEST_F(PrivilegeDocumentParsing, GrantClusterAdmin) { // Grant cluster admin - ASSERT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_OK(AuthorizationSession::buildPrivilegeSet( "admin", user, BSON("user" << "spencer" << "pwd" << "" << @@ -362,7 +363,7 @@ namespace { ASSERT(privilegeSet.hasPrivilege(Privilege("$CLUSTER", ActionType::moveChunk))); } - TEST(AuthorizationManagerTest, GetPrivilegesFromPrivilegeDocumentInvalid) { + TEST(AuthorizationSessionTest, GetPrivilegesFromPrivilegeDocumentInvalid) { BSONObj oldAndNewMixed = BSON("user" << "spencer" << "pwd" << "passwordHash" << "readOnly" << false << @@ -370,13 +371,13 @@ namespace { PrincipalName principal("spencer", "anydb"); PrivilegeSet result; - ASSERT_NOT_OK(AuthorizationManager::buildPrivilegeSet( + ASSERT_NOT_OK(AuthorizationSession::buildPrivilegeSet( "anydb", principal, oldAndNewMixed, &result)); } - TEST(AuthorizationManagerTest, DocumentValidationCompatibility) { + TEST(AuthorizationSessionTest, DocumentValidationCompatibility) { Status (*check)(const StringData&, const BSONObj&) = - &AuthorizationManager::checkValidPrivilegeDocument; + &AuthorizationSession::checkValidPrivilegeDocument; // Good documents, with and without "readOnly" fields. ASSERT_OK(check("test", BSON("user" << "andy" << "pwd" << "a"))); @@ -414,9 +415,9 @@ namespace { } }; - TEST(AuthorizationManagerTest, DisableCompatibilityMode) { + TEST(AuthorizationSessionTest, DisableCompatibilityMode) { Status (*check)(const StringData&, const BSONObj&) = - &AuthorizationManager::checkValidPrivilegeDocument; + &AuthorizationSession::checkValidPrivilegeDocument; CompatibilityModeDisabler disabler; @@ -429,9 +430,9 @@ namespace { "roles" << BSON_ARRAY("dbAdmin" << "read")))); } - TEST(AuthorizationManagerTest, DocumentValidationExtended) { + TEST(AuthorizationSessionTest, DocumentValidationExtended) { Status (*check)(const StringData&, const BSONObj&) = - &AuthorizationManager::checkValidPrivilegeDocument; + &AuthorizationSession::checkValidPrivilegeDocument; // Document describing new-style user on "test". ASSERT_OK(check("test", BSON("user" << "andy" << "pwd" << "a" << @@ -536,11 +537,11 @@ namespace { class ImplicitPriviligesTest : public ::mongo::unittest::Test { public: AuthExternalStateImplictPriv* state; - scoped_ptr<AuthorizationManager> authman; + scoped_ptr<AuthorizationSession> authman; void setUp() { state = new AuthExternalStateImplictPriv; - authman.reset(new AuthorizationManager(state)); + authman.reset(new AuthorizationSession(state)); } }; diff --git a/src/mongo/db/client.cpp b/src/mongo/db/client.cpp index d40ac0ac644..2a86d15da34 100644 --- a/src/mongo/db/client.cpp +++ b/src/mongo/db/client.cpp @@ -30,7 +30,7 @@ #include "mongo/base/status.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/auth_external_state_d.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/db.h" @@ -132,7 +132,7 @@ namespace mongo { Client *c = new Client( fullDesc, mp ); currentClient.reset(c); mongo::lastError.initThread(); - c->setAuthorizationManager(new AuthorizationManager(new AuthExternalStateMongod())); + c->setAuthorizationSession(new AuthorizationSession(new AuthExternalStateMongod())); return *c; } diff --git a/src/mongo/db/client_basic.cpp b/src/mongo/db/client_basic.cpp index 33185b5aae1..2d917703da0 100644 --- a/src/mongo/db/client_basic.cpp +++ b/src/mongo/db/client_basic.cpp @@ -17,7 +17,7 @@ #include "mongo/db/client_basic.h" #include "mongo/db/auth/authentication_session.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" namespace mongo { @@ -41,22 +41,22 @@ namespace mongo { _authenticationSession.swap(other); } - bool ClientBasic::hasAuthorizationManager() const { - return _authorizationManager.get(); + bool ClientBasic::hasAuthorizationSession() const { + return _authorizationSession.get(); } - AuthorizationManager* ClientBasic::getAuthorizationManager() const { + AuthorizationSession* ClientBasic::getAuthorizationSession() const { massert(16481, "No AuthorizationManager has been set up for this connection", - hasAuthorizationManager()); - return _authorizationManager.get(); + hasAuthorizationSession()); + return _authorizationSession.get(); } - void ClientBasic::setAuthorizationManager(AuthorizationManager* authorizationManager) { + void ClientBasic::setAuthorizationSession(AuthorizationSession* authorizationSession) { massert(16477, "An AuthorizationManager has already been set up for this connection", - !hasAuthorizationManager()); - _authorizationManager.reset(authorizationManager); + !hasAuthorizationSession()); + _authorizationSession.reset(authorizationSession); } } // namespace mongo diff --git a/src/mongo/db/client_basic.h b/src/mongo/db/client_basic.h index 703263e18f7..6616e8f30a1 100644 --- a/src/mongo/db/client_basic.h +++ b/src/mongo/db/client_basic.h @@ -25,7 +25,7 @@ namespace mongo { class AuthenticationInfo; class AuthenticationSession; - class AuthorizationManager; + class AuthorizationSession; /** * this is the base class for Client and ClientInfo @@ -41,9 +41,9 @@ namespace mongo { void resetAuthenticationSession(AuthenticationSession* newSession); void swapAuthenticationSession(boost::scoped_ptr<AuthenticationSession>& other); - bool hasAuthorizationManager() const; - AuthorizationManager* getAuthorizationManager() const; - void setAuthorizationManager(AuthorizationManager* authorizationManager); + bool hasAuthorizationSession() const; + AuthorizationSession* getAuthorizationSession() const; + void setAuthorizationSession(AuthorizationSession* authorizationSession); bool getIsLocalHostConnection() { if (!hasRemote()) { @@ -67,7 +67,7 @@ namespace mongo { private: boost::scoped_ptr<AuthenticationSession> _authenticationSession; - boost::scoped_ptr<AuthorizationManager> _authorizationManager; + boost::scoped_ptr<AuthorizationSession> _authorizationSession; AbstractMessagingPort* const _messagingPort; }; } diff --git a/src/mongo/db/clientcursor.cpp b/src/mongo/db/clientcursor.cpp index 38151bd2a8a..df854bf46ef 100644 --- a/src/mongo/db/clientcursor.cpp +++ b/src/mongo/db/clientcursor.cpp @@ -33,7 +33,7 @@ #include "mongo/client/dbclientinterface.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/commands.h" #include "mongo/db/commands/server_status.h" @@ -893,7 +893,7 @@ namespace mongo { } // Can't be in a lock when checking authorization - if (!cc().getAuthorizationManager()->checkAuthorization(ns, ActionType::killCursors)) { + if (!cc().getAuthorizationSession()->checkAuthorization(ns, ActionType::killCursors)) { return false; } diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index 368b1ea8cdc..0ef14225107 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -26,7 +26,7 @@ #include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
-#include "mongo/db/auth/authorization_manager.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/client.h"
#include "mongo/db/jsobj.h"
diff --git a/src/mongo/db/commands/apply_ops.cpp b/src/mongo/db/commands/apply_ops.cpp index 6c04cc5f3ec..170d2e7377e 100644 --- a/src/mongo/db/commands/apply_ops.cpp +++ b/src/mongo/db/commands/apply_ops.cpp @@ -18,8 +18,9 @@ #include <string> #include <vector> -#include "mongo/db/jsobj.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" +#include "mongo/db/jsobj.h" #include "mongo/db/commands.h" #include "mongo/db/instance.h" #include "mongo/db/matcher.h" @@ -40,7 +41,7 @@ namespace mongo { std::vector<Privilege>* out) { // applyOps can do pretty much anything, so require all privileges. out->push_back(Privilege(PrivilegeSet::WILDCARD_RESOURCE, - AuthorizationManager::getAllUserActions())); + AuthorizationSession::getAllUserActions())); } virtual bool run(const string& dbname, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp index 8d3b498a54a..f3395c6eaed 100644 --- a/src/mongo/db/commands/authentication_commands.cpp +++ b/src/mongo/db/commands/authentication_commands.cpp @@ -25,6 +25,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/mongo_authentication_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/client_basic.h" @@ -152,7 +153,7 @@ namespace mongo { BSONObj userObj; string pwd; - Status status = ClientBasic::getCurrent()->getAuthorizationManager()->getPrivilegeDocument( + Status status = ClientBasic::getCurrent()->getAuthorizationSession()->getPrivilegeDocument( dbname, PrincipalName(user, dbname), &userObj); if (!status.isOK()) { log() << status.reason() << std::endl; @@ -182,11 +183,11 @@ namespace mongo { return false; } - AuthorizationManager* authorizationManager = - ClientBasic::getCurrent()->getAuthorizationManager(); + AuthorizationSession* authorizationSession = + ClientBasic::getCurrent()->getAuthorizationSession(); Principal* principal = new Principal(PrincipalName(user, dbname)); principal->setImplicitPrivilegeAcquisition(true); - authorizationManager->addAuthorizedPrincipal(principal); + authorizationSession->addAuthorizedPrincipal(principal); result.append( "dbname" , dbname ); result.append( "user" , user ); @@ -214,8 +215,9 @@ namespace mongo { string& errmsg, BSONObjBuilder& result, bool fromRepl) { - AuthorizationManager* authManager = ClientBasic::getCurrent()->getAuthorizationManager(); - authManager->logoutDatabase(dbname); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); + authSession->logoutDatabase(dbname); return true; } } cmdLogout; diff --git a/src/mongo/db/commands/connection_status.cpp b/src/mongo/db/commands/connection_status.cpp index 39a03fe5564..f481efa4063 100644 --- a/src/mongo/db/commands/connection_status.cpp +++ b/src/mongo/db/commands/connection_status.cpp @@ -16,7 +16,7 @@ #include <mongo/pch.h> -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" namespace mongo { @@ -36,13 +36,14 @@ namespace mongo { bool run(const string&, BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { - AuthorizationManager* authMgr = ClientBasic::getCurrent()->getAuthorizationManager(); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); BSONObjBuilder authInfo(result.subobjStart("authInfo")); { BSONArrayBuilder authenticatedUsers(authInfo.subarrayStart("authenticatedUsers")); - PrincipalSet::NameIterator nameIter = authMgr->getAuthenticatedPrincipalNames(); + PrincipalSet::NameIterator nameIter = authSession->getAuthenticatedPrincipalNames(); for ( ; nameIter.more(); nameIter.next()) { BSONObjBuilder principal(authenticatedUsers.subobjStart()); principal.append("user", nameIter->getUser()); diff --git a/src/mongo/db/commands/cpuprofile.cpp b/src/mongo/db/commands/cpuprofile.cpp index 51883a21c27..bab81269280 100644 --- a/src/mongo/db/commands/cpuprofile.cpp +++ b/src/mongo/db/commands/cpuprofile.cpp @@ -44,7 +44,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/commands.h" #include "mongo/db/jsobj.h" diff --git a/src/mongo/db/commands/distinct.cpp b/src/mongo/db/commands/distinct.cpp index c47e3340c0d..968e0ad79cd 100644 --- a/src/mongo/db/commands/distinct.cpp +++ b/src/mongo/db/commands/distinct.cpp @@ -21,7 +21,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/clientcursor.h" #include "mongo/db/commands.h" diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp index e822374ed48..0e15006c151 100644 --- a/src/mongo/db/commands/fsync.cpp +++ b/src/mongo/db/commands/fsync.cpp @@ -25,7 +25,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/d_concurrency.h" #include "mongo/db/commands.h" diff --git a/src/mongo/db/commands/hashcmd.cpp b/src/mongo/db/commands/hashcmd.cpp index 94a7183e858..7422247351a 100644 --- a/src/mongo/db/commands/hashcmd.cpp +++ b/src/mongo/db/commands/hashcmd.cpp @@ -27,7 +27,7 @@ #include "mongo/base/status.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/commands.h" #include "mongo/db/hasher.h" diff --git a/src/mongo/db/commands/server_status.cpp b/src/mongo/db/commands/server_status.cpp index 1515514e7f3..bc1e7436370 100644 --- a/src/mongo/db/commands/server_status.cpp +++ b/src/mongo/db/commands/server_status.cpp @@ -20,6 +20,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/client_basic.h" #include "mongo/db/cmdline.h" @@ -82,7 +83,7 @@ namespace mongo { BSONObjBuilder timeBuilder(256); const ClientBasic* myClientBasic = ClientBasic::getCurrent(); - AuthorizationManager* authManager = myClientBasic->getAuthorizationManager(); + AuthorizationSession* authSession = myClientBasic->getAuthorizationSession(); // --- basic fields that are global @@ -104,7 +105,7 @@ namespace mongo { std::vector<Privilege> requiredPrivileges; section->addRequiredPrivileges(&requiredPrivileges); - if (!authManager->checkAuthForPrivileges(requiredPrivileges).isOK()) + if (!authSession->checkAuthForPrivileges(requiredPrivileges).isOK()) continue; bool include = section->includeByDefault(); diff --git a/src/mongo/db/compact.cpp b/src/mongo/db/compact.cpp index 4b4bae53719..70d9618ba89 100644 --- a/src/mongo/db/compact.cpp +++ b/src/mongo/db/compact.cpp @@ -25,7 +25,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/background.h" #include "mongo/db/commands.h" diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp index 86bd1d25b64..1f035123048 100644 --- a/src/mongo/db/db.cpp +++ b/src/mongo/db/db.cpp @@ -23,6 +23,7 @@ #include <fstream> #include "mongo/base/initializer.h" +#include "mongo/db/auth/authorization_manager.h" #include "mongo/db/client.h" #include "mongo/db/clientcursor.h" #include "mongo/db/cmdline.h" diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index 76f47a0e876..b86bd0f1029 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -32,6 +32,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/background.h" #include "mongo/db/btreecursor.h" @@ -2069,7 +2070,7 @@ namespace mongo { if (AuthorizationManager::isAuthEnabled()) { std::vector<Privilege> privileges; c->addRequiredPrivileges(dbname, cmdObj, &privileges); - Status status = client.getAuthorizationManager()->checkAuthForPrivileges(privileges); + Status status = client.getAuthorizationSession()->checkAuthForPrivileges(privileges); if (!status.isOK()) { log() << "command denied: " << cmdObj.toString() << endl; appendCommandStatus(result, false, status.reason()); diff --git a/src/mongo/db/dbcommands_admin.cpp b/src/mongo/db/dbcommands_admin.cpp index 81e66efe1e1..606f397cdcd 100644 --- a/src/mongo/db/dbcommands_admin.cpp +++ b/src/mongo/db/dbcommands_admin.cpp @@ -34,7 +34,7 @@ #include "mongo/base/status.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/cmdline.h" #include "mongo/db/commands.h" diff --git a/src/mongo/db/dbcommands_generic.cpp b/src/mongo/db/dbcommands_generic.cpp index d39e412b2c8..ea3ae7c0a30 100644 --- a/src/mongo/db/dbcommands_generic.cpp +++ b/src/mongo/db/dbcommands_generic.cpp @@ -24,7 +24,7 @@ #include "mongo/client/dbclient_rs.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/background.h" #include "mongo/db/commands.h" diff --git a/src/mongo/db/dbeval.cpp b/src/mongo/db/dbeval.cpp index 3be7333a288..bb358fa7534 100644 --- a/src/mongo/db/dbeval.cpp +++ b/src/mongo/db/dbeval.cpp @@ -21,6 +21,8 @@ #include <time.h> #include "mongo/bson/util/builder.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" @@ -121,7 +123,7 @@ namespace mongo { std::vector<Privilege>* out) { // $eval can do pretty much anything, so require all privileges. out->push_back(Privilege(PrivilegeSet::WILDCARD_RESOURCE, - AuthorizationManager::getAllUserActions())); + AuthorizationSession::getAllUserActions())); } CmdEval() : Command("eval", false, "$eval") { } bool run(const string& dbname , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool fromRepl) { diff --git a/src/mongo/db/dbwebserver.cpp b/src/mongo/db/dbwebserver.cpp index 18750404de9..8f22c55e6e6 100644 --- a/src/mongo/db/dbwebserver.cpp +++ b/src/mongo/db/dbwebserver.cpp @@ -26,7 +26,7 @@ #include <boost/date_time/posix_time/posix_time.hpp> #include <pcrecpp.h> -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/principal.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/background.h" @@ -79,12 +79,12 @@ namespace mongo { void _authorizePrincipal(const std::string& principalName, bool readOnly) { Principal* principal = new Principal(PrincipalName(principalName, "local")); - ActionSet actions = AuthorizationManager::getActionsForOldStyleUser( + ActionSet actions = AuthorizationSession::getActionsForOldStyleUser( "admin", readOnly); - AuthorizationManager* authorizationManager = cc().getAuthorizationManager(); - authorizationManager->addAuthorizedPrincipal(principal); - Status status = authorizationManager->acquirePrivilege( + AuthorizationSession* authorizationSession = cc().getAuthorizationSession(); + authorizationSession->addAuthorizedPrincipal(principal); + Status status = authorizationSession->acquirePrivilege( Privilege(PrivilegeSet::WILDCARD_RESOURCE, actions), principal->getName()); verify (status == Status::OK()); } diff --git a/src/mongo/db/driverHelpers.cpp b/src/mongo/db/driverHelpers.cpp index 6eb86b1d0bf..75cab78119e 100644 --- a/src/mongo/db/driverHelpers.cpp +++ b/src/mongo/db/driverHelpers.cpp @@ -29,7 +29,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/cmdline.h" #include "mongo/db/commands.h" diff --git a/src/mongo/db/index.cpp b/src/mongo/db/index.cpp index c71b2a34195..3bb21d89d0f 100644 --- a/src/mongo/db/index.cpp +++ b/src/mongo/db/index.cpp @@ -23,7 +23,7 @@ #include <boost/checked_delete.hpp> #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/background.h" #include "mongo/db/btree.h" #include "mongo/db/index_legacy.h" diff --git a/src/mongo/db/instance.cpp b/src/mongo/db/instance.cpp index 75c90ad4c2d..f0ef2fdb177 100644 --- a/src/mongo/db/instance.cpp +++ b/src/mongo/db/instance.cpp @@ -30,7 +30,7 @@ #include "mongo/base/status.h" #include "mongo/bson/util/atomic_int.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/background.h" #include "mongo/db/cmdline.h" #include "mongo/db/commands/fsync.h" @@ -128,7 +128,7 @@ namespace mongo { void inProgCmd( Message &m, DbResponse &dbresponse ) { BSONObjBuilder b; - if (!cc().getAuthorizationManager()->checkAuthorization( + if (!cc().getAuthorizationSession()->checkAuthorization( AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::inprog)) { b.append("err", "unauthorized"); } @@ -182,7 +182,7 @@ namespace mongo { void killOp( Message &m, DbResponse &dbresponse ) { BSONObj obj; - if (!cc().getAuthorizationManager()->checkAuthorization( + if (!cc().getAuthorizationSession()->checkAuthorization( AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::killop)) { obj = fromjson("{\"err\":\"unauthorized\"}"); } @@ -208,7 +208,7 @@ namespace mongo { bool _unlockFsync(); void unlockFsync(const char *ns, Message& m, DbResponse &dbresponse) { BSONObj obj; - if (!cc().getAuthorizationManager()->checkAuthorization( + if (!cc().getAuthorizationSession()->checkAuthorization( AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::unlock)) { obj = fromjson("{\"err\":\"unauthorized\"}"); } @@ -242,7 +242,7 @@ namespace mongo { try { if (!NamespaceString(d.getns()).isCommand()) { // Auth checking for Commands happens later. - Status status = cc().getAuthorizationManager()->checkAuthForQuery(d.getns()); + Status status = cc().getAuthorizationSession()->checkAuthForQuery(d.getns()); uassert(16550, status.reason(), status.isOK()); } dbresponse.exhaustNS = runQuery(m, q, op, *resp); @@ -360,7 +360,7 @@ namespace mongo { globalOpCounters.gotOp( op , isCommand ); Client& c = cc(); - c.getAuthorizationManager()->startRequest(); + c.getAuthorizationSession()->startRequest(); auto_ptr<CurOp> nestedOp; CurOp* currentOpP = c.curop(); @@ -546,7 +546,7 @@ namespace mongo { bool multi = flags & UpdateOption_Multi; bool broadcast = flags & UpdateOption_Broadcast; - Status status = cc().getAuthorizationManager()->checkAuthForUpdate(ns, upsert); + Status status = cc().getAuthorizationSession()->checkAuthForUpdate(ns, upsert); uassert(16538, status.reason(), status.isOK()); op.debug().query = query; @@ -581,7 +581,7 @@ namespace mongo { DbMessage d(m); const char *ns = d.getns(); - Status status = cc().getAuthorizationManager()->checkAuthForDelete(ns); + Status status = cc().getAuthorizationSession()->checkAuthForDelete(ns); uassert(16542, status.reason(), status.isOK()); op.debug().ns = ns; @@ -647,7 +647,7 @@ namespace mongo { const NamespaceString nsString( ns ); uassert( 16258, str::stream() << "Invalid ns [" << ns << "]", nsString.isValid() ); - Status status = cc().getAuthorizationManager()->checkAuthForGetMore(ns); + Status status = cc().getAuthorizationSession()->checkAuthForGetMore(ns); uassert(16543, status.reason(), status.isOK()); if (str::startsWith(ns, "local.oplog.")){ @@ -810,7 +810,7 @@ namespace mongo { // Auth checking for index writes happens further down in this function. if (!isIndexWrite) { - Status status = cc().getAuthorizationManager()->checkAuthForInsert(ns); + Status status = cc().getAuthorizationSession()->checkAuthForInsert(ns); uassert(16544, status.reason(), status.isOK()); } @@ -828,7 +828,7 @@ namespace mongo { uassert(16548, mongoutils::str::stream() << "not authorized to create index on " << indexNS, - cc().getAuthorizationManager()->checkAuthorization( + cc().getAuthorizationSession()->checkAuthorization( indexNS, ActionType::ensureIndex)); } } diff --git a/src/mongo/db/introspect.cpp b/src/mongo/db/introspect.cpp index 2c6fa6c5600..a7671bc4497 100644 --- a/src/mongo/db/introspect.cpp +++ b/src/mongo/db/introspect.cpp @@ -20,6 +20,7 @@ #include "mongo/bson/util/builder.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/principal_set.h" #include "mongo/db/curop.h" #include "mongo/db/databaseholder.h" @@ -35,8 +36,10 @@ namespace { namespace mongo { namespace { - void _appendUserInfo(const Client& c, BSONObjBuilder& builder, AuthorizationManager* authManager) { - PrincipalSet::NameIterator nameIter = authManager->getAuthenticatedPrincipalNames(); + void _appendUserInfo(const Client& c, + BSONObjBuilder& builder, + AuthorizationSession* authSession) { + PrincipalSet::NameIterator nameIter = authSession->getAuthenticatedPrincipalNames(); PrincipalName bestUser; if (nameIter.more()) @@ -76,8 +79,8 @@ namespace { b.appendDate("ts", jsTime()); b.append("client", c.clientAddress()); - AuthorizationManager* authManager = c.getAuthorizationManager(); - _appendUserInfo(c, b, authManager); + AuthorizationSession * authSession = c.getAuthorizationSession(); + _appendUserInfo(c, b, authSession); BSONObj p = b.done(); @@ -90,7 +93,7 @@ namespace { BSONObjBuilder b(profileBufBuilder); b.appendDate("ts", jsTime()); b.append("client", c.clientAddress() ); - _appendUserInfo(c, b, authManager); + _appendUserInfo(c, b, authSession); b.append("err", "profile line too large (max is 100KB)"); diff --git a/src/mongo/db/pdfile.cpp b/src/mongo/db/pdfile.cpp index 8331fc87006..3314cb91921 100644 --- a/src/mongo/db/pdfile.cpp +++ b/src/mongo/db/pdfile.cpp @@ -35,7 +35,7 @@ _ disallow system* manipulations from the database. #include "mongo/base/counter.h" #include "mongo/base/owned_pointer_vector.h" #include "mongo/db/auth/auth_index_d.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/pdfile_private.h" #include "mongo/db/background.h" #include "mongo/db/btree.h" @@ -1174,7 +1174,7 @@ namespace mongo { NamespaceString nsstring(ns); if (nsstring.coll == "system.users") { - uassertStatusOK(AuthorizationManager::checkValidPrivilegeDocument(nsstring.db, objNew)); + uassertStatusOK(AuthorizationSession::checkValidPrivilegeDocument(nsstring.db, objNew)); } uassert( 13596 , str::stream() << "cannot change _id of a document old:" << objOld << " new:" << objNew, @@ -1413,7 +1413,7 @@ namespace mongo { else if ( legalClientSystemNS( ns , true ) ) { if ( obuf && strstr( ns , ".system.users" ) ) { BSONObj t( reinterpret_cast<const char *>( obuf ) ); - uassertStatusOK(AuthorizationManager::checkValidPrivilegeDocument( + uassertStatusOK(AuthorizationSession::checkValidPrivilegeDocument( nsToDatabaseSubstring(ns), t)); } } diff --git a/src/mongo/db/range_deleter_db_env.cpp b/src/mongo/db/range_deleter_db_env.cpp index 1349fcc38e2..b7b5bb65331 100644 --- a/src/mongo/db/range_deleter_db_env.cpp +++ b/src/mongo/db/range_deleter_db_env.cpp @@ -17,6 +17,7 @@ #include "mongo/db/range_deleter_db_env.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/clientcursor.h" #include "mongo/db/cmdline.h" #include "mongo/db/dbhelpers.h" @@ -49,7 +50,7 @@ namespace mongo { } if (AuthorizationManager::isAuthEnabled()) { - cc().getAuthorizationManager()->grantInternalAuthorization("_cleanupOldData"); + cc().getAuthorizationSession()->grantInternalAuthorization("_cleanupOldData"); } ShardForceVersionOkModeBlock forceVersion; diff --git a/src/mongo/db/repl/oplogreader.cpp b/src/mongo/db/repl/oplogreader.cpp index f92734ec523..092a989e493 100644 --- a/src/mongo/db/repl/oplogreader.cpp +++ b/src/mongo/db/repl/oplogreader.cpp @@ -22,6 +22,7 @@ #include "mongo/base/counter.h" #include "mongo/client/dbclientinterface.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands/server_status.h" #include "mongo/db/dbhelpers.h" #include "mongo/db/jsobj.h" @@ -52,7 +53,7 @@ namespace mongo { if(!AuthorizationManager::isAuthEnabled()) { return true; } - if (!skipAuthCheck && !cc().getAuthorizationManager()->hasInternalAuthorization()) { + if (!skipAuthCheck && !cc().getAuthorizationSession()->hasInternalAuthorization()) { log() << "replauthenticate: requires internal authorization, failing" << endl; return false; } diff --git a/src/mongo/db/repl/replset_commands.cpp b/src/mongo/db/repl/replset_commands.cpp index ef6dcd8e7a6..f1bb0b7a838 100644 --- a/src/mongo/db/repl/replset_commands.cpp +++ b/src/mongo/db/repl/replset_commands.cpp @@ -20,7 +20,7 @@ #include "mongo/base/status.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/cmdline.h" #include "mongo/db/commands.h" #include "mongo/db/dbwebserver.h" diff --git a/src/mongo/db/repl/rs.cpp b/src/mongo/db/repl/rs.cpp index 6193db5b9b3..445e4069777 100644 --- a/src/mongo/db/repl/rs.cpp +++ b/src/mongo/db/repl/rs.cpp @@ -19,6 +19,7 @@ #include "mongo/base/owned_pointer_vector.h" #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" @@ -866,7 +867,7 @@ namespace mongo { void replLocalAuth() { if (!AuthorizationManager::isAuthEnabled()) return; - cc().getAuthorizationManager()->grantInternalAuthorization("_repl"); + cc().getAuthorizationSession()->grantInternalAuthorization("_repl"); } const char* ReplSetImpl::_initialSyncFlagString = "doingInitialSync"; diff --git a/src/mongo/db/server_extra_log_context.cpp b/src/mongo/db/server_extra_log_context.cpp index dc5b1d94041..b183c202751 100644 --- a/src/mongo/db/server_extra_log_context.cpp +++ b/src/mongo/db/server_extra_log_context.cpp @@ -18,7 +18,7 @@ #include "mongo/base/init.h" #include "mongo/bson/util/builder.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/principal_set.h" #include "mongo/db/client_basic.h" #include "mongo/db/server_parameters.h" @@ -38,11 +38,11 @@ namespace { ClientBasic* clientBasic = ClientBasic::getCurrent(); if (!clientBasic) return; - if (!clientBasic->hasAuthorizationManager()) + if (!clientBasic->hasAuthorizationSession()) return; PrincipalSet::NameIterator principals = - clientBasic->getAuthorizationManager()->getAuthenticatedPrincipalNames(); + clientBasic->getAuthorizationSession()->getAuthenticatedPrincipalNames(); if (!principals.more()) return; diff --git a/src/mongo/s/client_info.cpp b/src/mongo/s/client_info.cpp index b373e54c010..24b51d6bdcd 100644 --- a/src/mongo/s/client_info.cpp +++ b/src/mongo/s/client_info.cpp @@ -18,7 +18,7 @@ #include "pch.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/auth_external_state_s.h" #include "server.h" #include "../util/scopeguard.h" @@ -77,14 +77,14 @@ namespace mongo { _cur = _prev; _prev = temp; _cur->clear(); - getAuthorizationManager()->startRequest(); + getAuthorizationSession()->startRequest(); } ClientInfo* ClientInfo::create(AbstractMessagingPort* messagingPort) { ClientInfo * info = _tlInfo.get(); massert(16472, "A ClientInfo already exists for this thread", !info); info = new ClientInfo(messagingPort); - info->setAuthorizationManager(new AuthorizationManager(new AuthExternalStateMongos())); + info->setAuthorizationSession(new AuthorizationSession(new AuthExternalStateMongos())); _tlInfo.reset( info ); info->newRequest(); return info; diff --git a/src/mongo/s/commands_admin.cpp b/src/mongo/s/commands_admin.cpp index cb25aeb88d1..d6dac2c12d6 100644 --- a/src/mongo/s/commands_admin.cpp +++ b/src/mongo/s/commands_admin.cpp @@ -22,7 +22,7 @@ #include "mongo/client/dbclientcursor.h" #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/dbmessage.h" #include "mongo/db/stats/counters.h" diff --git a/src/mongo/s/commands_public.cpp b/src/mongo/s/commands_public.cpp index ed92792ba70..6b36c5b739b 100644 --- a/src/mongo/s/commands_public.cpp +++ b/src/mongo/s/commands_public.cpp @@ -24,6 +24,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/commands/find_and_modify.h" #include "mongo/db/commands/mr.h" @@ -1708,7 +1709,7 @@ namespace mongo { std::vector<Privilege>* out) { // applyOps can do pretty much anything, so require all privileges. out->push_back(Privilege(PrivilegeSet::WILDCARD_RESOURCE, - AuthorizationManager::getAllUserActions())); + AuthorizationSession::getAllUserActions())); } virtual bool run(const string& dbName , BSONObj& cmdObj, int, string& errmsg, BSONObjBuilder& result, bool) { errmsg = "applyOps not allowed through mongos"; @@ -1741,7 +1742,7 @@ namespace mongo { std::vector<Privilege>* out) { // $eval can do pretty much anything, so require all privileges. out->push_back(Privilege(PrivilegeSet::WILDCARD_RESOURCE, - AuthorizationManager::getAllUserActions())); + AuthorizationSession::getAllUserActions())); } virtual bool run(const string& dbName, BSONObj& cmdObj, diff --git a/src/mongo/s/cursors.cpp b/src/mongo/s/cursors.cpp index 53e08fc48ad..1373002a0c8 100644 --- a/src/mongo/s/cursors.cpp +++ b/src/mongo/s/cursors.cpp @@ -25,7 +25,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/client/connpool.h" #include "mongo/db/commands.h" @@ -283,8 +283,8 @@ namespace mongo { uassert( 13287 , "too many cursors to kill" , n < 30000 ); long long * cursors = (long long *)x; - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); for ( int i=0; i<n; i++ ) { long long id = cursors[i]; LOG(_myLogLevel) << "CursorCache::gotKillCursors id: " << id << endl; @@ -300,7 +300,7 @@ namespace mongo { MapSharded::iterator i = _cursors.find( id ); if ( i != _cursors.end() ) { - if (authManager->checkAuthorization(i->second->getNS(), + if (authSession->checkAuthorization(i->second->getNS(), ActionType::killCursors)) { _cursors.erase( i ); } @@ -314,7 +314,7 @@ namespace mongo { continue; } verify(refsNSIt != _refsNS.end()); - if (!authManager->checkAuthorization(refsNSIt->second, ActionType::killCursors)) { + if (!authSession->checkAuthorization(refsNSIt->second, ActionType::killCursors)) { continue; } server = refsIt->second; diff --git a/src/mongo/s/d_migrate.cpp b/src/mongo/s/d_migrate.cpp index 7f323c7f351..be819c890cb 100644 --- a/src/mongo/s/d_migrate.cpp +++ b/src/mongo/s/d_migrate.cpp @@ -36,6 +36,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/btreecursor.h" #include "mongo/db/clientcursor.h" @@ -1879,7 +1880,7 @@ namespace mongo { Client::initThread( "migrateThread" ); if (AuthorizationManager::isAuthEnabled()) { ShardedConnectionInfo::addHook(); - cc().getAuthorizationManager()->grantInternalAuthorization("_migrateThread"); + cc().getAuthorizationSession()->grantInternalAuthorization("_migrateThread"); } migrateStatus.go(); cc().shutdown(); diff --git a/src/mongo/s/d_writeback.cpp b/src/mongo/s/d_writeback.cpp index 1b08c25a81e..05339a6d25e 100644 --- a/src/mongo/s/d_writeback.cpp +++ b/src/mongo/s/d_writeback.cpp @@ -25,7 +25,7 @@ #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/client.h" #include "mongo/db/commands.h" diff --git a/src/mongo/s/s_only.cpp b/src/mongo/s/s_only.cpp index 2c4fdfe5928..bcbdcef114a 100644 --- a/src/mongo/s/s_only.cpp +++ b/src/mongo/s/s_only.cpp @@ -19,6 +19,7 @@ #include "mongo/client/connpool.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/auth_external_state_s.h" #include "mongo/s/shard.h" #include "mongo/s/grid.h" @@ -76,7 +77,7 @@ namespace mongo { Client *c = new Client( fullDesc, mp ); currentClient.reset(c); mongo::lastError.initThread(); - c->setAuthorizationManager(new AuthorizationManager(new AuthExternalStateMongos())); + c->setAuthorizationSession(new AuthorizationSession(new AuthExternalStateMongos())); return *c; } @@ -127,8 +128,8 @@ namespace mongo { if (AuthorizationManager::isAuthEnabled()) { std::vector<Privilege> privileges; c->addRequiredPrivileges(dbname, cmdObj, &privileges); - AuthorizationManager* authManager = client.getAuthorizationManager(); - if (!authManager->checkAuthForPrivileges(privileges).isOK()) { + AuthorizationSession* authSession = client.getAuthorizationSession(); + if (!authSession->checkAuthForPrivileges(privileges).isOK()) { result.append("note", str::stream() << "not authorized for command: " << c->name << " on database " << dbname); appendCommandStatus(result, false, "unauthorized"); diff --git a/src/mongo/s/strategy.cpp b/src/mongo/s/strategy.cpp index da04511fd0f..7032965658a 100644 --- a/src/mongo/s/strategy.cpp +++ b/src/mongo/s/strategy.cpp @@ -22,7 +22,7 @@ #include "mongo/client/connpool.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" #include "mongo/s/chunk_version.h" #include "mongo/s/grid.h" diff --git a/src/mongo/s/strategy_shard.cpp b/src/mongo/s/strategy_shard.cpp index ed67e9bdffa..9fd747a5df6 100644 --- a/src/mongo/s/strategy_shard.cpp +++ b/src/mongo/s/strategy_shard.cpp @@ -23,7 +23,7 @@ #include "mongo/client/connpool.h" #include "mongo/client/dbclientcursor.h" #include "mongo/db/auth/action_type.h" -#include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" #include "mongo/db/index.h" #include "mongo/db/namespacestring.h" @@ -53,9 +53,9 @@ namespace mongo { QueryMessage q( r.d() ); - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); - Status status = authManager->checkAuthForQuery(q.ns); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); + Status status = authSession->checkAuthForQuery(q.ns); uassert(16549, status.reason(), status.isOK()); LOG(3) << "shard query: " << q.ns << " " << q.query << endl; @@ -170,9 +170,9 @@ namespace mongo { const char *ns = r.getns(); - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); - Status status = authManager->checkAuthForGetMore(ns); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); + Status status = authSession->checkAuthForGetMore(ns); uassert(16539, status.reason(), status.isOK()); // TODO: Handle stale config exceptions here from coll being dropped or sharded during op @@ -512,9 +512,9 @@ namespace mongo { const string& ns = r.getns(); - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); - Status status = authManager->checkAuthForInsert(ns); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); + Status status = authSession->checkAuthForInsert(ns); uassert(16540, status.reason(), status.isOK()); @@ -1007,9 +1007,9 @@ namespace mongo { const BSONObj query = d.nextJsObj(); bool upsert = flags & UpdateOption_Upsert; - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); - Status status = authManager->checkAuthForUpdate(ns, upsert); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); + Status status = authSession->checkAuthForUpdate(ns, upsert); uassert(16537, status.reason(), status.isOK()); uassert( 10201 , "invalid update" , d.moreJSObjs() ); @@ -1168,9 +1168,9 @@ namespace mongo { const string& ns = r.getns(); int flags = d.pullInt(); - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); - Status status = authManager->checkAuthForDelete(ns); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); + Status status = authSession->checkAuthForDelete(ns); uassert(16541, status.reason(), status.isOK()); uassert( 10203 , "bad delete message" , d.moreJSObjs() ); @@ -1237,11 +1237,11 @@ namespace mongo { if (op == dbInsert) { // Insert is the only write op allowed on system.indexes, so it's the only one // we check auth for. - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); uassert(16547, mongoutils::str::stream() << "not authorized to create index on " << ns, - authManager->checkAuthorization(ns, ActionType::ensureIndex)); + authSession->checkAuthorization(ns, ActionType::ensureIndex)); } if ( r.getConfig()->isShardingEnabled() ){ diff --git a/src/mongo/s/strategy_single.cpp b/src/mongo/s/strategy_single.cpp index 02785d19738..cc95e9cf890 100644 --- a/src/mongo/s/strategy_single.cpp +++ b/src/mongo/s/strategy_single.cpp @@ -20,6 +20,7 @@ #include "mongo/client/connpool.h" #include "mongo/client/dbclientinterface.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/commands.h" #include "mongo/s/request.h" #include "mongo/s/cursors.h" @@ -127,13 +128,13 @@ namespace mongo { BSONObjBuilder b; vector<Shard> shards; - AuthorizationManager* authManager = - ClientBasic::getCurrent()->getAuthorizationManager(); + AuthorizationSession* authSession = + ClientBasic::getCurrent()->getAuthorizationSession(); if ( strcmp( ns , "inprog" ) == 0 ) { uassert(16545, "not authorized to run inprog", - authManager->checkAuthorization(AuthorizationManager::SERVER_RESOURCE_NAME, + authSession->checkAuthorization(AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::inprog)); Shard::getAllShards( shards ); @@ -175,7 +176,7 @@ namespace mongo { else if ( strcmp( ns , "killop" ) == 0 ) { uassert(16546, "not authorized to run killop", - authManager->checkAuthorization(AuthorizationManager::SERVER_RESOURCE_NAME, + authSession->checkAuthorization(AuthorizationManager::SERVER_RESOURCE_NAME, ActionType::killop)); BSONElement e = q.query["op"]; diff --git a/src/mongo/s/writeback_listener.cpp b/src/mongo/s/writeback_listener.cpp index f7adc0ad8b8..3de3c7ff434 100644 --- a/src/mongo/s/writeback_listener.cpp +++ b/src/mongo/s/writeback_listener.cpp @@ -21,6 +21,7 @@ #include "writeback_listener.h" #include "mongo/db/auth/authorization_manager.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/s/chunk_version.h" #include "mongo/s/client_info.h" #include "mongo/s/config.h" @@ -297,7 +298,7 @@ namespace mongo { ClientInfo * ci = r.getClientInfo(); if (AuthorizationManager::isAuthEnabled()) { - ci->getAuthorizationManager()->grantInternalAuthorization( + ci->getAuthorizationSession()->grantInternalAuthorization( "_writebackListener"); } ci->noAutoSplit(); |