summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSpencer T Brody <spencer@10gen.com>2013-07-02 17:47:19 -0400
committerSpencer T Brody <spencer@10gen.com>2013-07-09 14:22:04 -0400
commitd067cc3531d62db6791d095c0471ee1aa245d471 (patch)
tree17af6f5c3c5902e8f5d6e8a492b16b8072e76e60
parentb8f0ec598013009c56dee527e76429ffa7b8c394 (diff)
downloadmongo-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.cpp9
-rw-r--r--src/mongo/db/commands.h24
-rw-r--r--src/mongo/db/dbcommands.cpp6
-rw-r--r--src/mongo/s/s_only.cpp11
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;
}
}