diff options
author | Billy Donahue <billy.donahue@mongodb.com> | 2018-05-03 15:28:36 -0400 |
---|---|---|
committer | Billy Donahue <billy.donahue@mongodb.com> | 2018-05-10 16:31:43 -0400 |
commit | e2ff0151038bc01a4e8992169ed37c63de1d5a6a (patch) | |
tree | 875451f50fc372296b554091ab88f856e30004a7 /src | |
parent | 4f9bdd18edb24c66fbb587833bff8c1bcba91c80 (diff) | |
download | mongo-e2ff0151038bc01a4e8992169ed37c63de1d5a6a.tar.gz |
SERVER-34653 linearize control flow in Command::_checkAuthorizationImpl.
Also relevant to SERVER-29862.
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/commands.cpp | 67 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 2 |
2 files changed, 31 insertions, 38 deletions
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index d84a387d7b7..30e064221d9 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -352,12 +352,14 @@ CommandInvocation::~CommandInvocation() = default; void CommandInvocation::checkAuthorization(OperationContext* opCtx, const OpMsgRequest& request) const { - Status status = _checkAuthorizationImpl(opCtx, request); - if (!status.isOK()) { - log(LogComponent::kAccessControl) << status; + try { + _checkAuthorizationImpl(opCtx, request); + CommandHelpers::logAuthViolation(opCtx, this, request, ErrorCodes::OK); + } catch (const DBException& e) { + log(LogComponent::kAccessControl) << e.toStatus(); + CommandHelpers::logAuthViolation(opCtx, this, request, e.code()); + throw; } - CommandHelpers::logAuthViolation(opCtx, this, request, status.code()); - uassertStatusOK(status); } ////////////////////////////////////////////////////////////// @@ -457,43 +459,34 @@ Status BasicCommand::checkAuthForCommand(Client* client, return Status(ErrorCodes::Unauthorized, "unauthorized"); } -Status CommandInvocation::_checkAuthorizationImpl(OperationContext* opCtx, - const OpMsgRequest& request) const { - namespace mmb = mutablebson; +void CommandInvocation::_checkAuthorizationImpl(OperationContext* opCtx, + const OpMsgRequest& request) const { const Command* c = definition(); auto client = opCtx->getClient(); auto dbname = request.getDatabase(); - if (c->adminOnly() && dbname != "admin") { - return Status(ErrorCodes::Unauthorized, - str::stream() << c->getName() - << " may only be run against the admin database."); + uassert(ErrorCodes::Unauthorized, + str::stream() << c->getName() << " may only be run against the admin database.", + !c->adminOnly() || dbname == NamespaceString::kAdminDb); + if (!AuthorizationSession::get(client)->getAuthorizationManager().isAuthEnabled()) { + // Running without auth, so everything should be allowed except remotely invoked commands + // that have the 'localHostOnlyIfNoAuth' restriction. + uassert(ErrorCodes::Unauthorized, + str::stream() << c->getName() + << " must run from localhost when running db without auth", + !c->adminOnly() || !c->localHostOnlyIfNoAuth() || + client->getIsLocalHostConnection()); + return; // Blanket authorization: don't need to check anything else. } - if (AuthorizationSession::get(client)->getAuthorizationManager().isAuthEnabled()) { - Status status = [&] { - try { - doCheckAuthorization(opCtx); - return Status::OK(); - } catch (const DBException& e) { - return e.toStatus(); - } - }(); - if (status == ErrorCodes::Unauthorized) { - mmb::Document cmdToLog(request.body, mmb::Document::kInPlaceDisabled); - c->redactForLogging(&cmdToLog); - return Status(ErrorCodes::Unauthorized, - str::stream() << "not authorized on " << dbname << " to execute command " - << redact(cmdToLog.getObject())); - } - if (!status.isOK()) { - return status; - } - } else if (c->adminOnly() && c->localHostOnlyIfNoAuth() && - !client->getIsLocalHostConnection()) { - return Status(ErrorCodes::Unauthorized, - str::stream() << c->getName() - << " must run from localhost when running db without auth"); + try { + doCheckAuthorization(opCtx); + } catch (const ExceptionFor<ErrorCodes::Unauthorized>&) { + namespace mmb = mutablebson; + mmb::Document cmdToLog(request.body, mmb::Document::kInPlaceDisabled); + c->redactForLogging(&cmdToLog); + uasserted(ErrorCodes::Unauthorized, + str::stream() << "not authorized on " << dbname << " to execute command " + << redact(cmdToLog.getObject())); } - return Status::OK(); } void Command::generateHelpResponse(OperationContext* opCtx, diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index 8d467747a28..40248943ef0 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -532,7 +532,7 @@ private: */ virtual void doCheckAuthorization(OperationContext* opCtx) const = 0; - Status _checkAuthorizationImpl(OperationContext* opCtx, const OpMsgRequest& request) const; + void _checkAuthorizationImpl(OperationContext* opCtx, const OpMsgRequest& request) const; const Command* const _definition; }; |