diff options
Diffstat (limited to 'src/mongo/db/auth/authorization_session.cpp')
-rw-r--r-- | src/mongo/db/auth/authorization_session.cpp | 115 |
1 files changed, 69 insertions, 46 deletions
diff --git a/src/mongo/db/auth/authorization_session.cpp b/src/mongo/db/auth/authorization_session.cpp index a934ee3aae6..fa0594b429f 100644 --- a/src/mongo/db/auth/authorization_session.cpp +++ b/src/mongo/db/auth/authorization_session.cpp @@ -67,14 +67,15 @@ namespace { return _externalState->getAuthorizationManager(); } - void AuthorizationSession::startRequest() { - _externalState->startRequest(); - _refreshUserInfoAsNeeded(); + void AuthorizationSession::startRequest(OperationContext* txn) { + _externalState->startRequest(txn); + _refreshUserInfoAsNeeded(txn); } - Status AuthorizationSession::addAndAuthorizeUser(const UserName& userName) { + Status AuthorizationSession::addAndAuthorizeUser( + OperationContext* txn, const UserName& userName) { User* user; - Status status = getAuthorizationManager().acquireUser(userName, &user); + Status status = getAuthorizationManager().acquireUser(txn, userName, &user); if (!status.isOK()) { return status; } @@ -160,29 +161,32 @@ namespace { return defaultPrivileges; } - Status AuthorizationSession::checkAuthForQuery(const NamespaceString& ns, + Status AuthorizationSession::checkAuthForQuery(OperationContext* txn, + const NamespaceString& ns, const BSONObj& query) { if (MONGO_unlikely(ns.isCommand())) { return Status(ErrorCodes::InternalError, mongoutils::str::stream() << "Checking query auth on command namespace " << ns.ns()); } - if (!isAuthorizedForActionsOnNamespace(ns, ActionType::find)) { + if (!isAuthorizedForActionsOnNamespace(txn, ns, ActionType::find)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized for query on " << ns.ns()); } return Status::OK(); } - Status AuthorizationSession::checkAuthForGetMore(const NamespaceString& ns, + Status AuthorizationSession::checkAuthForGetMore(OperationContext* txn, + const NamespaceString& ns, long long cursorID) { - if (!isAuthorizedForActionsOnNamespace(ns, ActionType::find)) { + if (!isAuthorizedForActionsOnNamespace(txn, ns, ActionType::find)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized for getmore on " << ns.ns()); } return Status::OK(); } - Status AuthorizationSession::checkAuthForInsert(const NamespaceString& ns, + Status AuthorizationSession::checkAuthForInsert(OperationContext* txn, + const NamespaceString& ns, const BSONObj& document) { if (ns.coll() == StringData("system.indexes", StringData::LiteralTag())) { BSONElement nsElement = document["ns"]; @@ -191,13 +195,13 @@ namespace { "system.indexes documents without a string-typed \"ns\" field."); } NamespaceString indexNS(nsElement.str()); - if (!isAuthorizedForActionsOnNamespace(indexNS, ActionType::createIndex)) { + if (!isAuthorizedForActionsOnNamespace(txn, indexNS, ActionType::createIndex)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized to create index on " << indexNS.ns()); } } else { - if (!isAuthorizedForActionsOnNamespace(ns, ActionType::insert)) { + if (!isAuthorizedForActionsOnNamespace(txn, ns, ActionType::insert)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized for insert on " << ns.ns()); @@ -207,12 +211,13 @@ namespace { return Status::OK(); } - Status AuthorizationSession::checkAuthForUpdate(const NamespaceString& ns, + Status AuthorizationSession::checkAuthForUpdate(OperationContext* txn, + const NamespaceString& ns, const BSONObj& query, const BSONObj& update, bool upsert) { if (!upsert) { - if (!isAuthorizedForActionsOnNamespace(ns, ActionType::update)) { + if (!isAuthorizedForActionsOnNamespace(txn, ns, ActionType::update)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized for update on " << ns.ns()); @@ -222,7 +227,7 @@ namespace { ActionSet required; required.addAction(ActionType::update); required.addAction(ActionType::insert); - if (!isAuthorizedForActionsOnNamespace(ns, required)) { + if (!isAuthorizedForActionsOnNamespace(txn, ns, required)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized for upsert on " << ns.ns()); @@ -231,19 +236,22 @@ namespace { return Status::OK(); } - Status AuthorizationSession::checkAuthForDelete(const NamespaceString& ns, + Status AuthorizationSession::checkAuthForDelete(OperationContext* txn, + const NamespaceString& ns, const BSONObj& query) { - if (!isAuthorizedForActionsOnNamespace(ns, ActionType::remove)) { + if (!isAuthorizedForActionsOnNamespace(txn, ns, ActionType::remove)) { return Status(ErrorCodes::Unauthorized, mongoutils::str::stream() << "not authorized to remove from " << ns.ns()); } return Status::OK(); } - Status AuthorizationSession::checkAuthorizedToGrantPrivilege(const Privilege& privilege) { + Status AuthorizationSession::checkAuthorizedToGrantPrivilege( + OperationContext* txn, const Privilege& privilege) { const ResourcePattern& resource = privilege.getResourcePattern(); if (resource.isDatabasePattern() || resource.isExactNamespacePattern()) { if (!isAuthorizedForActionsOnResource( + txn, ResourcePattern::forDatabaseName(resource.databaseToMatch()), ActionType::grantRole)) { return Status(ErrorCodes::Unauthorized, @@ -251,7 +259,9 @@ namespace { << resource.databaseToMatch() << "database"); } } else if (!isAuthorizedForActionsOnResource( - ResourcePattern::forDatabaseName("admin"), ActionType::grantRole)) { + txn, + ResourcePattern::forDatabaseName("admin"), + ActionType::grantRole)) { return Status(ErrorCodes::Unauthorized, "To grant privileges affecting multiple databases or the cluster," " must be authorized to grant roles from the admin database"); @@ -260,10 +270,12 @@ namespace { } - Status AuthorizationSession::checkAuthorizedToRevokePrivilege(const Privilege& privilege) { + Status AuthorizationSession::checkAuthorizedToRevokePrivilege( + OperationContext* txn, const Privilege& privilege) { const ResourcePattern& resource = privilege.getResourcePattern(); if (resource.isDatabasePattern() || resource.isExactNamespacePattern()) { if (!isAuthorizedForActionsOnResource( + txn, ResourcePattern::forDatabaseName(resource.databaseToMatch()), ActionType::revokeRole)) { return Status(ErrorCodes::Unauthorized, @@ -271,7 +283,9 @@ namespace { << resource.databaseToMatch() << "database"); } } else if (!isAuthorizedForActionsOnResource( - ResourcePattern::forDatabaseName("admin"), ActionType::revokeRole)) { + txn, + ResourcePattern::forDatabaseName("admin"), + ActionType::revokeRole)) { return Status(ErrorCodes::Unauthorized, "To revoke privileges affecting multiple databases or the cluster," " must be authorized to revoke roles from the admin database"); @@ -279,55 +293,62 @@ namespace { return Status::OK(); } - bool AuthorizationSession::isAuthorizedToGrantRole(const RoleName& role) { + bool AuthorizationSession::isAuthorizedToGrantRole( + OperationContext* txn, const RoleName& role) { return isAuthorizedForActionsOnResource( - ResourcePattern::forDatabaseName(role.getDB()), - ActionType::grantRole); + txn, + ResourcePattern::forDatabaseName(role.getDB()), + ActionType::grantRole); } - bool AuthorizationSession::isAuthorizedToRevokeRole(const RoleName& role) { + bool AuthorizationSession::isAuthorizedToRevokeRole( + OperationContext* txn, const RoleName& role) { return isAuthorizedForActionsOnResource( - ResourcePattern::forDatabaseName(role.getDB()), - ActionType::revokeRole); + txn, + ResourcePattern::forDatabaseName(role.getDB()), + ActionType::revokeRole); } - bool AuthorizationSession::isAuthorizedForPrivilege(const Privilege& privilege) { + bool AuthorizationSession::isAuthorizedForPrivilege( + OperationContext* txn, const Privilege& privilege) { if (_externalState->shouldIgnoreAuthChecks()) return true; - return _isAuthorizedForPrivilege(privilege); + return _isAuthorizedForPrivilege(txn, privilege); } - bool AuthorizationSession::isAuthorizedForPrivileges(const vector<Privilege>& privileges) { + bool AuthorizationSession::isAuthorizedForPrivileges( + OperationContext* txn, const vector<Privilege>& privileges) { if (_externalState->shouldIgnoreAuthChecks()) return true; for (size_t i = 0; i < privileges.size(); ++i) { - if (!_isAuthorizedForPrivilege(privileges[i])) + if (!_isAuthorizedForPrivilege(txn, privileges[i])) return false; } return true; } - bool AuthorizationSession::isAuthorizedForActionsOnResource(const ResourcePattern& resource, - ActionType action) { - return isAuthorizedForPrivilege(Privilege(resource, action)); + bool AuthorizationSession::isAuthorizedForActionsOnResource( + OperationContext* txn, const ResourcePattern& resource, ActionType action) { + return isAuthorizedForPrivilege(txn, Privilege(resource, action)); } - bool AuthorizationSession::isAuthorizedForActionsOnResource(const ResourcePattern& resource, - const ActionSet& actions) { - return isAuthorizedForPrivilege(Privilege(resource, actions)); + bool AuthorizationSession::isAuthorizedForActionsOnResource( + OperationContext* txn, const ResourcePattern& resource, const ActionSet& actions) { + return isAuthorizedForPrivilege(txn, Privilege(resource, actions)); } - bool AuthorizationSession::isAuthorizedForActionsOnNamespace(const NamespaceString& ns, - ActionType action) { - return isAuthorizedForPrivilege(Privilege(ResourcePattern::forExactNamespace(ns), action)); + bool AuthorizationSession::isAuthorizedForActionsOnNamespace( + OperationContext* txn, const NamespaceString& ns, ActionType action) { + return isAuthorizedForPrivilege(txn, Privilege(ResourcePattern::forExactNamespace(ns), action)); } - bool AuthorizationSession::isAuthorizedForActionsOnNamespace(const NamespaceString& ns, - const ActionSet& actions) { - return isAuthorizedForPrivilege(Privilege(ResourcePattern::forExactNamespace(ns), actions)); + bool AuthorizationSession::isAuthorizedForActionsOnNamespace( + OperationContext* txn, const NamespaceString& ns, const ActionSet& actions) { + return isAuthorizedForPrivilege( + txn, Privilege(ResourcePattern::forExactNamespace(ns), actions)); } static const int resourceSearchListCapacity = 5; @@ -422,7 +443,7 @@ namespace { return false; } - void AuthorizationSession::_refreshUserInfoAsNeeded() { + void AuthorizationSession::_refreshUserInfoAsNeeded(OperationContext* txn) { AuthorizationManager& authMan = getAuthorizationManager(); UserSet::iterator it = _authenticatedUsers.begin(); while (it != _authenticatedUsers.end()) { @@ -434,7 +455,7 @@ namespace { UserName name = user->getName(); User* updatedUser; - Status status = authMan.acquireUser(name, &updatedUser); + Status status = authMan.acquireUser(txn, name, &updatedUser); switch (status.code()) { case ErrorCodes::OK: { // Success! Replace the old User object with the updated one. @@ -463,7 +484,8 @@ namespace { } } - bool AuthorizationSession::_isAuthorizedForPrivilege(const Privilege& privilege) { + bool AuthorizationSession::_isAuthorizedForPrivilege( + OperationContext* txn, const Privilege& privilege) { const ResourcePattern& target(privilege.getResourcePattern()); ResourcePattern resourceSearchList[resourceSearchListCapacity]; @@ -498,6 +520,7 @@ namespace { UserName name = user->getName(); User* updatedUser; Status status = getAuthorizationManager().acquireV1UserProbedForDb( + txn, name, target.databaseToMatch(), &updatedUser); |