summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2013-05-14 17:33:25 -0400
committerSpencer T Brody <spencer@10gen.com>2013-05-22 19:14:01 -0400
commiteb719438afc316e9bf56bf716a129def27f5e768 (patch)
treeb00f395fec7c39ebc2e074cc77e4bd1bf9bbca2b /src
parent83900ac233c2a94e0f3e6a1628cf822f9bb88425 (diff)
downloadmongo-eb719438afc316e9bf56bf716a129def27f5e768.tar.gz
Split AuthorizationManager into 2 classes: AuthorizationManager and AuthorizationSession.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/auth/SConscript3
-rw-r--r--src/mongo/db/auth/auth_external_state_d.cpp2
-rw-r--r--src/mongo/db/auth/auth_external_state_s.cpp2
-rw-r--r--src/mongo/db/auth/authorization_manager.cpp783
-rw-r--r--src/mongo/db/auth/authorization_manager.h182
-rw-r--r--src/mongo/db/auth/authorization_session.cpp804
-rw-r--r--src/mongo/db/auth/authorization_session.h194
-rw-r--r--src/mongo/db/auth/authorization_session_test.cpp (renamed from src/mongo/db/auth/authorization_manager_test.cpp)137
-rw-r--r--src/mongo/db/client.cpp4
-rw-r--r--src/mongo/db/client_basic.cpp18
-rw-r--r--src/mongo/db/client_basic.h10
-rw-r--r--src/mongo/db/clientcursor.cpp4
-rw-r--r--src/mongo/db/commands.cpp2
-rw-r--r--src/mongo/db/commands/apply_ops.cpp5
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp14
-rw-r--r--src/mongo/db/commands/connection_status.cpp7
-rw-r--r--src/mongo/db/commands/cpuprofile.cpp2
-rw-r--r--src/mongo/db/commands/distinct.cpp2
-rw-r--r--src/mongo/db/commands/fsync.cpp2
-rw-r--r--src/mongo/db/commands/hashcmd.cpp2
-rw-r--r--src/mongo/db/commands/server_status.cpp5
-rw-r--r--src/mongo/db/compact.cpp2
-rw-r--r--src/mongo/db/db.cpp1
-rw-r--r--src/mongo/db/dbcommands.cpp3
-rw-r--r--src/mongo/db/dbcommands_admin.cpp2
-rw-r--r--src/mongo/db/dbcommands_generic.cpp2
-rw-r--r--src/mongo/db/dbeval.cpp4
-rw-r--r--src/mongo/db/dbwebserver.cpp10
-rw-r--r--src/mongo/db/driverHelpers.cpp2
-rw-r--r--src/mongo/db/index.cpp2
-rw-r--r--src/mongo/db/instance.cpp22
-rw-r--r--src/mongo/db/introspect.cpp13
-rw-r--r--src/mongo/db/pdfile.cpp6
-rw-r--r--src/mongo/db/range_deleter_db_env.cpp3
-rw-r--r--src/mongo/db/repl/oplogreader.cpp3
-rw-r--r--src/mongo/db/repl/replset_commands.cpp2
-rw-r--r--src/mongo/db/repl/rs.cpp3
-rw-r--r--src/mongo/db/server_extra_log_context.cpp6
-rw-r--r--src/mongo/s/client_info.cpp6
-rw-r--r--src/mongo/s/commands_admin.cpp2
-rw-r--r--src/mongo/s/commands_public.cpp5
-rw-r--r--src/mongo/s/cursors.cpp10
-rw-r--r--src/mongo/s/d_migrate.cpp3
-rw-r--r--src/mongo/s/d_writeback.cpp2
-rw-r--r--src/mongo/s/s_only.cpp7
-rw-r--r--src/mongo/s/strategy.cpp2
-rw-r--r--src/mongo/s/strategy_shard.cpp38
-rw-r--r--src/mongo/s/strategy_single.cpp9
-rw-r--r--src/mongo/s/writeback_listener.cpp3
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();