summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBilly Donahue <billy.donahue@mongodb.com>2018-05-03 15:28:36 -0400
committerBilly Donahue <billy.donahue@mongodb.com>2018-05-10 16:31:43 -0400
commite2ff0151038bc01a4e8992169ed37c63de1d5a6a (patch)
tree875451f50fc372296b554091ab88f856e30004a7 /src
parent4f9bdd18edb24c66fbb587833bff8c1bcba91c80 (diff)
downloadmongo-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.cpp67
-rw-r--r--src/mongo/db/commands.h2
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;
};