summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth/authorization_session.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/auth/authorization_session.cpp')
-rw-r--r--src/mongo/db/auth/authorization_session.cpp115
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);