diff options
author | Spencer T Brody <spencer@10gen.com> | 2013-07-02 17:47:19 -0400 |
---|---|---|
committer | Spencer T Brody <spencer@10gen.com> | 2013-07-09 14:22:04 -0400 |
commit | d067cc3531d62db6791d095c0471ee1aa245d471 (patch) | |
tree | 17af6f5c3c5902e8f5d6e8a492b16b8072e76e60 | |
parent | b8f0ec598013009c56dee527e76429ffa7b8c394 (diff) | |
download | mongo-d067cc3531d62db6791d095c0471ee1aa245d471.tar.gz |
SERVER-9740 Add checkAuthForCommand method to all commands and use that for auth checking from now on
-rw-r--r-- | src/mongo/db/commands.cpp | 9 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 24 | ||||
-rw-r--r-- | src/mongo/db/dbcommands.cpp | 6 | ||||
-rw-r--r-- | src/mongo/s/s_only.cpp | 11 |
4 files changed, 36 insertions, 14 deletions
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index 0b62cf50429..493f8793644 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -27,6 +27,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" @@ -200,6 +201,14 @@ namespace mongo { } } + Status Command::checkAuthForCommand(ClientBasic* client, + const std::string& dbname, + const BSONObj& cmdObj) { + std::vector<Privilege> privileges; + this->addRequiredPrivileges(dbname, cmdObj, &privileges); + return client->getAuthorizationSession()->checkAuthForPrivileges(privileges); + } + void Command::logIfSlow( const Timer& timer, const string& msg ) { int ms = timer.millis(); if ( ms > cmdLine.slowMS ) { diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index d96e63faa36..5f52aa97de7 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -19,6 +19,7 @@ #include <vector> +#include "mongo/base/status.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/client_basic.h" #include "mongo/db/jsobj.h" @@ -111,12 +112,12 @@ namespace mongo { virtual void help( stringstream& help ) const; /** - * Appends to "*out" the privileges required to run this command on database "dbname" with - * the invocation described by "cmdObj". + * Checks if the given client is authorized to run this command on database "dbname" + * with the invocation described by "cmdObj". */ - virtual void addRequiredPrivileges(const std::string& dbname, - const BSONObj& cmdObj, - std::vector<Privilege>* out) = 0; + virtual Status checkAuthForCommand(ClientBasic* client, + const std::string& dbname, + const BSONObj& cmdObj); /* Return true if a replica set secondary should go into "recovering" (unreadable) state while running this command. @@ -136,6 +137,19 @@ namespace mongo { virtual ~Command() {} protected: + + /** + * Appends to "*out" the privileges required to run this command on database "dbname" with + * the invocation described by "cmdObj". New commands shouldn't implement this, they should + * implement checkAuthForCommand instead. + */ + virtual void addRequiredPrivileges(const std::string& dbname, + const BSONObj& cmdObj, + std::vector<Privilege>* out) { + // The default implementation of addRequiredPrivileges should never be hit. + fassertFailed(16940); + } + BSONObj getQuery( const BSONObj& cmdObj ) { if ( cmdObj["query"].type() == Object ) return cmdObj["query"].embeddedObject(); diff --git a/src/mongo/db/dbcommands.cpp b/src/mongo/db/dbcommands.cpp index 138b89e6297..8ab4b4a0d14 100644 --- a/src/mongo/db/dbcommands.cpp +++ b/src/mongo/db/dbcommands.cpp @@ -2126,11 +2126,11 @@ namespace mongo { } if (AuthorizationManager::isAuthEnabled()) { - std::vector<Privilege> privileges; - c->addRequiredPrivileges(dbname, cmdObj, &privileges); - Status status = client.getAuthorizationSession()->checkAuthForPrivileges(privileges); + Status status = c->checkAuthForCommand(&client, dbname, cmdObj); if (!status.isOK()) { log() << "command denied: " << cmdObj.toString() << endl; + result.append("note", str::stream() << "not authorized for command: " << + c->name << " on database " << dbname); appendCommandStatus(result, false, status.reason()); return; } diff --git a/src/mongo/s/s_only.cpp b/src/mongo/s/s_only.cpp index 644938256f1..10b9eb43366 100644 --- a/src/mongo/s/s_only.cpp +++ b/src/mongo/s/s_only.cpp @@ -128,13 +128,12 @@ namespace mongo { // Access control checks if (AuthorizationManager::isAuthEnabled()) { - std::vector<Privilege> privileges; - c->addRequiredPrivileges(dbname, cmdObj, &privileges); - AuthorizationSession* authSession = client.getAuthorizationSession(); - if (!authSession->checkAuthForPrivileges(privileges).isOK()) { + Status status = c->checkAuthForCommand(&client, dbname, cmdObj); + if (!status.isOK()) { + log() << "command denied: " << cmdObj.toString() << endl; result.append("note", str::stream() << "not authorized for command: " << - c->name << " on database " << dbname); - appendCommandStatus(result, false, "unauthorized"); + c->name << " on database " << dbname); + appendCommandStatus(result, false, status.reason()); return; } } |