summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2022-09-26 14:56:04 -0500
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-10-05 15:25:09 +0000
commit27d9725cf5272c63b412588a061e1dae0f65e682 (patch)
treec14538f5f1c27be8995c325fef49eecaa400d9ee
parentfed2a61d2bfaaaa5183caa2d67df5b68d27e4080 (diff)
downloadmongo-27d9725cf5272c63b412588a061e1dae0f65e682.tar.gz
SERVER-70147 Migrate addRequiredPrivileges to checkAuthForOperation
-rw-r--r--src/mongo/db/commands.cpp12
-rw-r--r--src/mongo/db/commands.h22
-rw-r--r--src/mongo/db/commands/authentication_commands.cpp8
-rw-r--r--src/mongo/db/commands/collection_to_capped.cpp52
-rw-r--r--src/mongo/db/commands/compact.cpp25
-rw-r--r--src/mongo/db/commands/conn_pool_stats.cpp17
-rw-r--r--src/mongo/db/commands/conn_pool_sync.cpp17
-rw-r--r--src/mongo/db/commands/cpuload.cpp21
-rw-r--r--src/mongo/db/commands/dbcommands.cpp9
-rw-r--r--src/mongo/db/commands/dbcommands_d.cpp21
-rw-r--r--src/mongo/db/commands/dbhash.cpp16
-rw-r--r--src/mongo/db/commands/driverHelpers.cpp10
-rw-r--r--src/mongo/db/commands/drop_indexes.cpp18
-rw-r--r--src/mongo/db/commands/fail_point_cmd.cpp8
-rw-r--r--src/mongo/db/commands/fsync.cpp24
-rw-r--r--src/mongo/db/commands/generic.cpp27
-rw-r--r--src/mongo/db/commands/get_last_error.cpp9
-rw-r--r--src/mongo/db/commands/hashcmd.cpp16
-rw-r--r--src/mongo/db/commands/isself.cpp16
-rw-r--r--src/mongo/db/commands/map_reduce_command_base.h8
-rw-r--r--src/mongo/db/commands/mr_common.cpp25
-rw-r--r--src/mongo/db/commands/mr_common.h8
-rw-r--r--src/mongo/db/commands/parameters.cpp49
-rw-r--r--src/mongo/db/commands/server_status.h6
-rw-r--r--src/mongo/db/commands/server_status_command.cpp27
-rw-r--r--src/mongo/db/commands/shutdown.h7
-rw-r--r--src/mongo/db/commands/sleep_command.cpp8
-rw-r--r--src/mongo/db/commands/test_api_version_2_commands.cpp24
-rw-r--r--src/mongo/db/commands/test_commands.cpp68
-rw-r--r--src/mongo/db/commands/test_deprecation_command.cpp8
-rw-r--r--src/mongo/db/commands/top_command.cpp34
-rw-r--r--src/mongo/db/commands/validate.cpp17
-rw-r--r--src/mongo/db/commands/whats_my_sni_command.cpp8
-rw-r--r--src/mongo/db/commands/whats_my_uri_cmd.cpp8
-rw-r--r--src/mongo/db/exec/stagedebug_cmd.cpp11
-rw-r--r--src/mongo/db/free_mon/free_mon_status.cpp12
-rw-r--r--src/mongo/db/index/index_access_method.cpp2
-rw-r--r--src/mongo/db/index_builds_coordinator.h2
-rw-r--r--src/mongo/db/repl/replication_info.cpp8
-rw-r--r--src/mongo/db/s/check_sharding_index_command.cpp17
-rw-r--r--src/mongo/db/s/cluster_count_cmd_d.cpp15
-rw-r--r--src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp52
-rw-r--r--src/mongo/db/s/migration_destination_manager_legacy_commands.cpp82
-rw-r--r--src/mongo/db/s/sharding_state_command.cpp17
-rw-r--r--src/mongo/embedded/embedded_ismaster.cpp8
-rw-r--r--src/mongo/s/commands/cluster_add_shard_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_build_info.cpp8
-rw-r--r--src/mongo/s/commands/cluster_coll_stats_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_compact_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp16
-rw-r--r--src/mongo/s/commands/cluster_count_cmd.h18
-rw-r--r--src/mongo/s/commands/cluster_count_cmd_s.cpp5
-rw-r--r--src/mongo/s/commands/cluster_create_indexes_cmd.cpp14
-rw-r--r--src/mongo/s/commands/cluster_distinct_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_drop_indexes_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_filemd5_cmd.cpp15
-rw-r--r--src/mongo/s/commands/cluster_find_and_modify_cmd.cpp24
-rw-r--r--src/mongo/s/commands/cluster_fsync_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_get_last_error_cmd.cpp12
-rw-r--r--src/mongo/s/commands/cluster_hello_cmd.cpp8
-rw-r--r--src/mongo/s/commands/cluster_is_db_grid_cmd.cpp18
-rw-r--r--src/mongo/s/commands/cluster_list_shards_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_multicast_cmd.cpp8
-rw-r--r--src/mongo/s/commands/cluster_netstat_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_remove_shard_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_validate_cmd.cpp17
-rw-r--r--src/mongo/s/commands/cluster_whats_my_uri_cmd.cpp16
-rw-r--r--src/mongo/s/commands/flush_router_config_cmd.cpp17
-rw-r--r--src/mongo/s/commands/get_shard_map_cmd.cpp17
69 files changed, 772 insertions, 473 deletions
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 24ef5e32b36..e3371fde4e4 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -994,18 +994,6 @@ Status BasicCommandWithReplyBuilderInterface::explain(OperationContext* opCtx,
return {ErrorCodes::IllegalOperation, str::stream() << "Cannot explain cmd: " << getName()};
}
-Status BasicCommandWithReplyBuilderInterface::checkAuthForOperation(OperationContext* opCtx,
- const DatabaseName& dbName,
- const BSONObj& cmdObj) const {
- std::vector<Privilege> privileges;
- this->addRequiredPrivileges(dbName.db(), cmdObj, &privileges);
- if (!AuthorizationSession::get(opCtx->getClient())->isAuthorizedForPrivileges(privileges)) {
- return {ErrorCodes::Unauthorized, "unauthorized"};
- }
-
- return Status::OK();
-}
-
void Command::generateHelpResponse(OperationContext* opCtx,
rpc::ReplyBuilderInterface* replyBuilder,
const Command& command) {
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index 3e5b9d7d4e4..1f151f58435 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -902,11 +902,13 @@ public:
/**
* Checks if the client associated with the given OperationContext is authorized to run this
- * command. Default implementation checks via addRequiredPrivileges().
+ * command.
+ * Command imlpementations MUST provide a method here, even if no authz checks are required.
+ * Such commands should return Status::OK(), with a comment stating "No auth required".
*/
virtual Status checkAuthForOperation(OperationContext* opCtx,
const DatabaseName& dbName,
- const BSONObj& cmdObj) const;
+ const BSONObj& cmdObj) const = 0;
/**
* supportsWriteConcern returns true if this command should be parsed for a writeConcern
@@ -969,22 +971,6 @@ public:
private:
std::unique_ptr<CommandInvocation> parse(OperationContext* opCtx,
const OpMsgRequest& request) final;
-
- //
- // Deprecated virtual methods.
- //
-
- /**
- * 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 checkAuthForOperation (which takes an OperationContext*), instead.
- */
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- // The default implementation of addRequiredPrivileges should never be hit.
- fassertFailed(16940);
- }
};
/**
diff --git a/src/mongo/db/commands/authentication_commands.cpp b/src/mongo/db/commands/authentication_commands.cpp
index 826bc6b23a0..b8af6c12551 100644
--- a/src/mongo/db/commands/authentication_commands.cpp
+++ b/src/mongo/db/commands/authentication_commands.cpp
@@ -113,11 +113,13 @@ public:
bool requiresAuth() const override {
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const final {
+
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
// No auth required since this command was explicitly part
// of an authentication workflow.
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/collection_to_capped.cpp b/src/mongo/db/commands/collection_to_capped.cpp
index 456c76ceb13..c709a7b2617 100644
--- a/src/mongo/db/commands/collection_to_capped.cpp
+++ b/src/mongo/db/commands/collection_to_capped.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/catalog/capped_utils.h"
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
@@ -50,34 +51,40 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kNever;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return true;
}
+
std::string help() const override {
return "{ cloneCollectionAsCapped:<fromName>, toCollection:<toName>, size:<sizeInBytes> }";
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet sourceActions;
- sourceActions.addAction(ActionType::find);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), sourceActions));
-
- ActionSet targetActions;
- targetActions.addAction(ActionType::insert);
- targetActions.addAction(ActionType::createIndex);
- targetActions.addAction(ActionType::convertToCapped);
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::find)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
const auto nssElt = cmdObj["toCollection"];
uassert(ErrorCodes::TypeMismatch,
"'toCollection' must be of type String",
nssElt.type() == BSONType::String);
- const NamespaceString nss(dbname, nssElt.valueStringData());
+ const NamespaceString nss(dbName, nssElt.valueStringData());
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "Invalid target namespace: " << nss.ns(),
nss.isValid());
- out->push_back(Privilege(ResourcePattern::forExactNamespace(nss), targetActions));
+ if (!as->isAuthorizedForActionsOnResource(
+ ResourcePattern::forExactNamespace(nss),
+ {ActionType::insert, ActionType::createIndex, ActionType::convertToCapped})) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
@@ -154,12 +161,17 @@ public:
std::string help() const override {
return "{ convertToCapped:<fromCollectionName>, size:<sizeInBytes> }";
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::convertToCapped);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::convertToCapped)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp
index e20e9905b19..db2e6ecf75f 100644
--- a/src/mongo/db/commands/compact.cpp
+++ b/src/mongo/db/commands/compact.cpp
@@ -49,22 +49,30 @@ using std::stringstream;
class CompactCmd : public BasicCommand {
public:
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
- virtual bool adminOnly() const {
+
+ bool adminOnly() const override {
return false;
}
+
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::compact);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::compact)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
+
std::string help() const override {
return "compact collection\n"
"warning: this operation locks the database and is slow. you can cancel with "
@@ -72,6 +80,7 @@ public:
"{ compact : <collection_name>, [force:<bool>] }\n"
" force - allows to run on a replica set primary\n";
}
+
CompactCmd() : BasicCommand("compact") {}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/conn_pool_stats.cpp b/src/mongo/db/commands/conn_pool_stats.cpp
index 25c0a385952..da62689917c 100644
--- a/src/mongo/db/commands/conn_pool_stats.cpp
+++ b/src/mongo/db/commands/conn_pool_stats.cpp
@@ -36,6 +36,7 @@
#include "mongo/client/connpool.h"
#include "mongo/client/dbclient_connection.h"
#include "mongo/client/global_conn_pool.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/repl/replication_coordinator.h"
#include "mongo/executor/connection_pool_stats.h"
@@ -62,12 +63,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::connPoolStats);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::connPoolStats)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/conn_pool_sync.cpp b/src/mongo/db/commands/conn_pool_sync.cpp
index 2111ec42931..e83a4ef41d3 100644
--- a/src/mongo/db/commands/conn_pool_sync.cpp
+++ b/src/mongo/db/commands/conn_pool_sync.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
#include "mongo/client/global_conn_pool.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
namespace mongo {
@@ -51,12 +52,16 @@ public:
return AllowedOnSecondary::kAlways;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::connPoolSync);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::connPoolSync)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/cpuload.cpp b/src/mongo/db/commands/cpuload.cpp
index 7699275426b..532354d7d4e 100644
--- a/src/mongo/db/commands/cpuload.cpp
+++ b/src/mongo/db/commands/cpuload.cpp
@@ -45,13 +45,16 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
+
virtual bool isWriteCommandForConfigServer() const {
return false;
}
+
bool skipApiVersionCheck() const override {
// Internal command (server to server).
return true;
}
+
std::string help() const override {
return "internal. for testing only."
"{ cpuload : 1, cpuFactor : 1 } Runs a straight CPU load. Length of execution "
@@ -59,13 +62,17 @@ public:
"Useful for testing the stability of the performance of the underlying system,"
"by running the command repeatedly and observing the variation in execution time.";
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {} // No auth required
- virtual bool run(OperationContext* txn,
- const DatabaseName&,
- const BSONObj& cmdObj,
- BSONObjBuilder& result) {
+
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
+
+ bool run(OperationContext* txn,
+ const DatabaseName&,
+ const BSONObj& cmdObj,
+ BSONObjBuilder& result) override {
double cpuFactor = 1;
if (cmdObj["cpuFactor"].isNumber()) {
cpuFactor = cmdObj["cpuFactor"].number();
diff --git a/src/mongo/db/commands/dbcommands.cpp b/src/mongo/db/commands/dbcommands.cpp
index 19fd21c513e..9d134a12685 100644
--- a/src/mongo/db/commands/dbcommands.cpp
+++ b/src/mongo/db/commands/dbcommands.cpp
@@ -729,9 +729,12 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const final {} // No auth required
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
+
std::string help() const final {
return "get version #, etc.\n"
"{ buildinfo:1 }";
diff --git a/src/mongo/db/commands/dbcommands_d.cpp b/src/mongo/db/commands/dbcommands_d.cpp
index b1596fdc81b..86aebefde31 100644
--- a/src/mongo/db/commands/dbcommands_d.cpp
+++ b/src/mongo/db/commands/dbcommands_d.cpp
@@ -217,7 +217,7 @@ public:
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
@@ -225,8 +225,7 @@ public:
return true;
}
- virtual NamespaceString parseNs(const DatabaseName& dbName,
- const BSONObj& cmdObj) const override {
+ NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
std::string collectionName;
if (const auto rootElt = cmdObj["root"]) {
uassert(ErrorCodes::InvalidNamespace,
@@ -240,16 +239,22 @@ public:
return NamespaceString(dbName, collectionName);
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), ActionType::find));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::find)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
const DatabaseName& dbName,
const BSONObj& jsobj,
- BSONObjBuilder& result) {
+ BSONObjBuilder& result) override {
const NamespaceString nss(parseNs(dbName, jsobj));
md5digest d;
diff --git a/src/mongo/db/commands/dbhash.cpp b/src/mongo/db/commands/dbhash.cpp
index 627e2fe4d86..442c3fe728d 100644
--- a/src/mongo/db/commands/dbhash.cpp
+++ b/src/mongo/db/commands/dbhash.cpp
@@ -106,12 +106,16 @@ public:
kDefaultReadConcernNotPermitted};
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::dbHash);
- out->push_back(Privilege(ResourcePattern::forDatabaseName(dbname), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(dbName.db()),
+ ActionType::dbHash)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/driverHelpers.cpp b/src/mongo/db/commands/driverHelpers.cpp
index f6db10738db..7328eab0633 100644
--- a/src/mongo/db/commands/driverHelpers.cpp
+++ b/src/mongo/db/commands/driverHelpers.cpp
@@ -67,9 +67,13 @@ public:
class ObjectIdTest : public BasicDriverHelper {
public:
ObjectIdTest() : BasicDriverHelper("driverOIDTest") {}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {} // No auth required
+
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
+
bool run(OperationContext* opCtx,
const DatabaseName& dbName,
const BSONObj& cmdObj,
diff --git a/src/mongo/db/commands/drop_indexes.cpp b/src/mongo/db/commands/drop_indexes.cpp
index 4d899e91c6f..46122c7fe5d 100644
--- a/src/mongo/db/commands/drop_indexes.cpp
+++ b/src/mongo/db/commands/drop_indexes.cpp
@@ -136,13 +136,19 @@ public:
std::string help() const override {
return "re-index a collection (can only be run on a standalone mongod)";
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::reIndex);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::reIndex)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
+
CmdReIndex() : BasicCommand("reIndex") {}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/fail_point_cmd.cpp b/src/mongo/db/commands/fail_point_cmd.cpp
index 00a2626e8cc..7e868735f5b 100644
--- a/src/mongo/db/commands/fail_point_cmd.cpp
+++ b/src/mongo/db/commands/fail_point_cmd.cpp
@@ -87,9 +87,11 @@ public:
}
// No auth needed because it only works when enabled via command line.
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {}
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ return Status::OK();
+ }
std::string help() const override {
return "modifies the settings of a fail point";
diff --git a/src/mongo/db/commands/fsync.cpp b/src/mongo/db/commands/fsync.cpp
index f84b77bff5c..db6dd91ff33 100644
--- a/src/mongo/db/commands/fsync.cpp
+++ b/src/mongo/db/commands/fsync.cpp
@@ -108,24 +108,32 @@ public:
}
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
+
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual bool adminOnly() const {
+
+ bool adminOnly() const override {
return true;
}
+
std::string help() const override {
return url();
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::fsync);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::fsync)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/generic.cpp b/src/mongo/db/commands/generic.cpp
index f61ead33f83..c5f8dde7e74 100644
--- a/src/mongo/db/commands/generic.cpp
+++ b/src/mongo/db/commands/generic.cpp
@@ -148,26 +148,35 @@ public:
std::string help() const override {
return "get a list of all db commands";
}
+
ListCommandsCmd() : BasicCommand("listCommands") {}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
+
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual bool adminOnly() const {
+
+ bool adminOnly() const override {
return false;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {} // No auth required
+
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
+
bool requiresAuth() const final {
return false;
}
- virtual bool run(OperationContext* opCtx,
- const DatabaseName&,
- const BSONObj& cmdObj,
- BSONObjBuilder& result) {
+
+ bool run(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj& cmdObj,
+ BSONObjBuilder& result) override {
// Sort the command names before building the result BSON.
std::vector<Command*> commands;
for (const auto& command : globalCommandRegistry()->allCommands()) {
diff --git a/src/mongo/db/commands/get_last_error.cpp b/src/mongo/db/commands/get_last_error.cpp
index 23d7d68e3ed..7ef994bd772 100644
--- a/src/mongo/db/commands/get_last_error.cpp
+++ b/src/mongo/db/commands/get_last_error.cpp
@@ -49,9 +49,12 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {} // No auth required
+
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
bool requiresAuth() const override {
return false;
diff --git a/src/mongo/db/commands/hashcmd.cpp b/src/mongo/db/commands/hashcmd.cpp
index ff6335ec6dc..7caee184863 100644
--- a/src/mongo/db/commands/hashcmd.cpp
+++ b/src/mongo/db/commands/hashcmd.cpp
@@ -52,17 +52,23 @@ using std::stringstream;
// Testing only, enabled via command-line.
class CmdHashElt : public BasicCommand {
public:
- CmdHashElt() : BasicCommand("_hashBSONElement"){};
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ CmdHashElt() : BasicCommand("_hashBSONElement") {}
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
+
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
+
// No auth needed because it only works when enabled via command line.
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
+
std::string help() const override {
return "returns the hash of the first BSONElement val in a BSONObj";
}
diff --git a/src/mongo/db/commands/isself.cpp b/src/mongo/db/commands/isself.cpp
index 2139d822c03..04c10b43f18 100644
--- a/src/mongo/db/commands/isself.cpp
+++ b/src/mongo/db/commands/isself.cpp
@@ -44,22 +44,30 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
+
bool skipApiVersionCheck() const override {
// Internal command (server to server).
return true;
}
+
std::string help() const override {
return "{ _isSelf : 1 } INTERNAL ONLY";
}
+
bool requiresAuth() const override {
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {}
+
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
+
bool run(OperationContext* opCtx,
const DatabaseName&,
const BSONObj& cmdObj,
diff --git a/src/mongo/db/commands/map_reduce_command_base.h b/src/mongo/db/commands/map_reduce_command_base.h
index 48a9522e0d8..a235b9345da 100644
--- a/src/mongo/db/commands/map_reduce_command_base.h
+++ b/src/mongo/db/commands/map_reduce_command_base.h
@@ -82,10 +82,10 @@ public:
return true;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- map_reduce_common::addPrivilegesRequiredForMapReduce(this, dbname, cmdObj, out);
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ return map_reduce_common::checkAuthForMapReduce(this, opCtx, dbName, cmdObj);
}
virtual void _explainImpl(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/mr_common.cpp b/src/mongo/db/commands/mr_common.cpp
index 0cc2b224bf2..a75b69b9549 100644
--- a/src/mongo/db/commands/mr_common.cpp
+++ b/src/mongo/db/commands/mr_common.cpp
@@ -34,6 +34,7 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/catalog/document_validation.h"
#include "mongo/db/commands.h"
@@ -330,18 +331,22 @@ OutputOptions parseOutputOptions(const std::string& dbname, const BSONObj& cmdOb
return outputOptions;
}
-void addPrivilegesRequiredForMapReduce(const BasicCommand* commandTemplate,
- const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- OutputOptions outputOptions = parseOutputOptions(dbname, cmdObj);
+Status checkAuthForMapReduce(const BasicCommand* commandTemplate,
+ OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) {
+ OutputOptions outputOptions = parseOutputOptions(dbName.db(), cmdObj);
- ResourcePattern inputResource(commandTemplate->parseResourcePattern(dbname, cmdObj));
+ ResourcePattern inputResource(commandTemplate->parseResourcePattern(dbName.db(), cmdObj));
uassert(ErrorCodes::InvalidNamespace,
str::stream() << "Invalid input namespace " << inputResource.databaseToMatch() << "."
<< cmdObj["mapReduce"].String(),
inputResource.isExactNamespacePattern());
- out->push_back(Privilege(inputResource, ActionType::find));
+
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(inputResource, ActionType::find)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
if (outputOptions.outType != OutputType::InMemory) {
ActionSet outputActions;
@@ -363,8 +368,12 @@ void addPrivilegesRequiredForMapReduce(const BasicCommand* commandTemplate,
outputResource.ns().isValid());
// TODO: check if outputNs exists and add createCollection privilege if not
- out->push_back(Privilege(outputResource, outputActions));
+ if (!as->isAuthorizedForActionsOnResource(outputResource, outputActions)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
}
+
+ return Status::OK();
}
bool mrSupportsWriteConcern(const BSONObj& cmd) {
diff --git a/src/mongo/db/commands/mr_common.h b/src/mongo/db/commands/mr_common.h
index 344d819841f..965553e9ca8 100644
--- a/src/mongo/db/commands/mr_common.h
+++ b/src/mongo/db/commands/mr_common.h
@@ -51,10 +51,10 @@ struct OutputOptions {
OutputOptions parseOutputOptions(const std::string& dbname, const BSONObj& cmdObj);
-void addPrivilegesRequiredForMapReduce(const BasicCommand* commandTemplate,
- const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out);
+Status checkAuthForMapReduce(const BasicCommand* command,
+ OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj);
/**
* Returns true if the provided mapReduce command has an 'out' parameter.
diff --git a/src/mongo/db/commands/parameters.cpp b/src/mongo/db/commands/parameters.cpp
index 574f47e91bb..0cfb0f6dcf2 100644
--- a/src/mongo/db/commands/parameters.cpp
+++ b/src/mongo/db/commands/parameters.cpp
@@ -35,6 +35,7 @@
#include "mongo/client/replica_set_monitor.h"
#include "mongo/config.h"
#include "mongo/db/auth/authorization_manager.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/parameters_gen.h"
#include "mongo/db/commands/parse_log_component_settings.h"
@@ -206,19 +207,27 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual bool adminOnly() const {
+
+ bool adminOnly() const override {
return true;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::getParameter);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::getParameter)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
+
std::string help() const override {
std::string h =
"get administrative option(s)\nexample:\n"
@@ -265,19 +274,27 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual bool adminOnly() const {
+
+ bool adminOnly() const override {
return true;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::setParameter);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::setParameter)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
+
std::string help() const override {
std::string h =
"set administrative option(s)\n"
diff --git a/src/mongo/db/commands/server_status.h b/src/mongo/db/commands/server_status.h
index d5f08eef962..1d10d805968 100644
--- a/src/mongo/db/commands/server_status.h
+++ b/src/mongo/db/commands/server_status.h
@@ -65,10 +65,12 @@ public:
virtual bool includeByDefault() const = 0;
/**
- * Adds the privileges that are required to view this section
+ * Perform authorization checks required to show this status section.
* TODO: Remove this empty default implementation and implement for every section.
*/
- virtual void addRequiredPrivileges(std::vector<Privilege>* out){};
+ virtual Status checkAuthForOperation(OperationContext* opCtx) const {
+ return Status::OK();
+ }
/**
* actually generate the result
diff --git a/src/mongo/db/commands/server_status_command.cpp b/src/mongo/db/commands/server_status_command.cpp
index f1dbbcea879..62433e57e62 100644
--- a/src/mongo/db/commands/server_status_command.cpp
+++ b/src/mongo/db/commands/server_status_command.cpp
@@ -66,16 +66,20 @@ public:
"retrieve all server status sections.";
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const final {
- ActionSet actions;
- actions.addAction(ActionType::serverStatus);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::serverStatus)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
- const DatabaseName&,
+ const DatabaseName& dbName,
const BSONObj& cmdObj,
BSONObjBuilder& result) final {
const auto service = opCtx->getServiceContext();
@@ -83,8 +87,6 @@ public:
const auto runStart = clock->now();
BSONObjBuilder timeBuilder(256);
- const auto authSession = AuthorizationSession::get(Client::getCurrent());
-
// This command is important to observability, and like FTDC, does not need to acquire the
// PBWM lock to return correct results.
ShouldNotConflictWithSecondaryBatchApplicationBlock noPBWMBlock(opCtx->lockState());
@@ -115,10 +117,9 @@ public:
for (auto i = registry->begin(); i != registry->end(); ++i) {
ServerStatusSection* section = i->second;
- std::vector<Privilege> requiredPrivileges;
- section->addRequiredPrivileges(&requiredPrivileges);
- if (!authSession->isAuthorizedForPrivileges(requiredPrivileges))
+ if (!section->checkAuthForOperation(opCtx).isOK()) {
continue;
+ }
bool include = section->includeByDefault();
const auto& elem = cmdObj[section->getSectionName()];
@@ -264,8 +265,6 @@ public:
return false;
}
- void addRequiredPrivileges(std::vector<Privilege>* out) final {}
-
BSONObj generateSection(OperationContext*, const BSONElement& configElement) const final {
return HttpClient::getServerStatus();
}
diff --git a/src/mongo/db/commands/shutdown.h b/src/mongo/db/commands/shutdown.h
index 757f14b432c..446c78632e0 100644
--- a/src/mongo/db/commands/shutdown.h
+++ b/src/mongo/db/commands/shutdown.h
@@ -114,13 +114,6 @@ public:
Command::AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return Command::AllowedOnSecondary::kAlways;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::shutdown);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
- }
};
} // namespace mongo
diff --git a/src/mongo/db/commands/sleep_command.cpp b/src/mongo/db/commands/sleep_command.cpp
index efee82ad827..159a57e213f 100644
--- a/src/mongo/db/commands/sleep_command.cpp
+++ b/src/mongo/db/commands/sleep_command.cpp
@@ -66,9 +66,11 @@ public:
}
// No auth needed because it only works when enabled via command line.
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
/**
* An empty 'ns' causes the global lock to be taken.
diff --git a/src/mongo/db/commands/test_api_version_2_commands.cpp b/src/mongo/db/commands/test_api_version_2_commands.cpp
index be228e1afe3..713b5aacebd 100644
--- a/src/mongo/db/commands/test_api_version_2_commands.cpp
+++ b/src/mongo/db/commands/test_api_version_2_commands.cpp
@@ -51,6 +51,12 @@ public:
return false;
}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
+
bool run(OperationContext* opCtx,
const DatabaseName&,
const BSONObj& cmdObj,
@@ -77,6 +83,12 @@ public:
return false;
}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
+
bool run(OperationContext* opCtx,
const DatabaseName&,
const BSONObj& cmdObj,
@@ -107,6 +119,12 @@ public:
return false;
}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
+
bool run(OperationContext* opCtx,
const DatabaseName&,
const BSONObj& cmdObj,
@@ -133,6 +151,12 @@ public:
return false;
}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
+
bool run(OperationContext* opCtx,
const DatabaseName&,
const BSONObj& cmdObj,
diff --git a/src/mongo/db/commands/test_commands.cpp b/src/mongo/db/commands/test_commands.cpp
index 5cedacf760f..4cea5de379d 100644
--- a/src/mongo/db/commands/test_commands.cpp
+++ b/src/mongo/db/commands/test_commands.cpp
@@ -64,19 +64,25 @@ using std::stringstream;
class GodInsert : public BasicCommand {
public:
GodInsert() : BasicCommand("godinsert") {}
- virtual bool adminOnly() const {
+ bool adminOnly() const override {
return false;
}
+
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return true;
}
+
// No auth needed because it only works when enabled via command line.
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
+
std::string help() const override {
return "internal. for testing only.";
}
@@ -120,20 +126,26 @@ MONGO_REGISTER_TEST_COMMAND(GodInsert);
class CapTrunc : public BasicCommand {
public:
CapTrunc() : BasicCommand("captrunc") {}
+
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kNever;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return true;
}
+
// No auth needed because it only works when enabled via command line.
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {}
- virtual bool run(OperationContext* opCtx,
- const DatabaseName& dbName,
- const BSONObj& cmdObj,
- BSONObjBuilder& result) {
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
+
+ bool run(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj,
+ BSONObjBuilder& result) override {
const NamespaceString fullNs = CommandHelpers::parseNsCollectionRequired(dbName, cmdObj);
if (!fullNs.isValid()) {
uasserted(ErrorCodes::InvalidNamespace,
@@ -195,18 +207,22 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kNever;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return true;
}
+
// No auth needed because it only works when enabled via command line.
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {}
-
- virtual bool run(OperationContext* opCtx,
- const DatabaseName& dbName,
- const BSONObj& cmdObj,
- BSONObjBuilder& result) {
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
+
+ bool run(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj,
+ BSONObjBuilder& result) override {
const NamespaceString nss = CommandHelpers::parseNsCollectionRequired(dbName, cmdObj);
uassertStatusOK(emptyCapped(opCtx, nss));
@@ -237,9 +253,11 @@ public:
}
// No auth needed because it only works when enabled via command line.
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
std::string help() const override {
return "pins the oldest timestamp";
diff --git a/src/mongo/db/commands/test_deprecation_command.cpp b/src/mongo/db/commands/test_deprecation_command.cpp
index 4e4362322ed..bdf5c0d0a4e 100644
--- a/src/mongo/db/commands/test_deprecation_command.cpp
+++ b/src/mongo/db/commands/test_deprecation_command.cpp
@@ -60,9 +60,11 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
std::string help() const override {
return "replies with the values of the OperationContext's API parameters";
diff --git a/src/mongo/db/commands/top_command.cpp b/src/mongo/db/commands/top_command.cpp
index bea0c20f800..0eadc4fdecf 100644
--- a/src/mongo/db/commands/top_command.cpp
+++ b/src/mongo/db/commands/top_command.cpp
@@ -32,6 +32,7 @@
#include "mongo/base/init.h"
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/client.h"
#include "mongo/db/commands.h"
@@ -50,26 +51,35 @@ public:
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kAlways;
}
- virtual bool adminOnly() const {
+
+ bool adminOnly() const override {
return true;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
+
std::string help() const override {
return "usage by collection, in micros ";
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::top);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::top)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
- virtual bool run(OperationContext* opCtx,
- const DatabaseName&,
- const BSONObj& cmdObj,
- BSONObjBuilder& result) {
+
+ bool run(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj& cmdObj,
+ BSONObjBuilder& result) override {
{
BSONObjBuilder b(result.subobjStart("totals"));
b.append("note", "all times in microseconds");
diff --git a/src/mongo/db/commands/validate.cpp b/src/mongo/db/commands/validate.cpp
index 832f2f8f6e0..ed81cd48eab 100644
--- a/src/mongo/db/commands/validate.cpp
+++ b/src/mongo/db/commands/validate.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/catalog/collection.h"
#include "mongo/db/catalog/collection_validation.h"
#include "mongo/db/client.h"
@@ -113,12 +114,16 @@ public:
return false;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::validate);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::validate)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/commands/whats_my_sni_command.cpp b/src/mongo/db/commands/whats_my_sni_command.cpp
index f0d1838b312..3073fdfa033 100644
--- a/src/mongo/db/commands/whats_my_sni_command.cpp
+++ b/src/mongo/db/commands/whats_my_sni_command.cpp
@@ -70,9 +70,11 @@ public:
return AllowedOnSecondary::kAlways;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
};
MONGO_REGISTER_TEST_COMMAND(CmdWhatsMySNI)
diff --git a/src/mongo/db/commands/whats_my_uri_cmd.cpp b/src/mongo/db/commands/whats_my_uri_cmd.cpp
index 33634534444..e791d492a7b 100644
--- a/src/mongo/db/commands/whats_my_uri_cmd.cpp
+++ b/src/mongo/db/commands/whats_my_uri_cmd.cpp
@@ -55,9 +55,11 @@ public:
return "{whatsmyuri:1}";
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {} // No auth required
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ return Status::OK(); // No auth required
+ }
bool run(OperationContext* opCtx,
const DatabaseName&,
diff --git a/src/mongo/db/exec/stagedebug_cmd.cpp b/src/mongo/db/exec/stagedebug_cmd.cpp
index 3d52323be75..8c909acffdf 100644
--- a/src/mongo/db/exec/stagedebug_cmd.cpp
+++ b/src/mongo/db/exec/stagedebug_cmd.cpp
@@ -116,11 +116,12 @@ public:
return {};
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- // Command is testing-only, and can only be enabled at command line. Hence, no auth
- // check needed.
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ // Command is testing-only, and can only be enabled at command line.
+ // Hence, no auth check needed.
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/free_mon/free_mon_status.cpp b/src/mongo/db/free_mon/free_mon_status.cpp
index dc201956a8d..5d69473ea5e 100644
--- a/src/mongo/db/free_mon/free_mon_status.cpp
+++ b/src/mongo/db/free_mon/free_mon_status.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands/server_status.h"
#include "mongo/db/free_mon/free_mon_controller.h"
#include "mongo/db/free_mon/free_mon_options.h"
@@ -44,9 +45,14 @@ public:
return true;
}
- void addRequiredPrivileges(std::vector<Privilege>* out) final {
- out->push_back(Privilege(ResourcePattern::forClusterResource(),
- ActionType::checkFreeMonitoringStatus));
+ Status checkAuthForOperation(OperationContext* opCtx) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::checkFreeMonitoringStatus)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const final {
diff --git a/src/mongo/db/index/index_access_method.cpp b/src/mongo/db/index/index_access_method.cpp
index a3ef4649369..bdc0db61e8d 100644
--- a/src/mongo/db/index/index_access_method.cpp
+++ b/src/mongo/db/index/index_access_method.cpp
@@ -92,8 +92,6 @@ public:
return true;
}
- void addRequiredPrivileges(std::vector<Privilege>* out) final {}
-
BSONObj generateSection(OperationContext* opCtx, const BSONElement& configElement) const final {
BSONObjBuilder builder;
builder.append("count", count.loadRelaxed());
diff --git a/src/mongo/db/index_builds_coordinator.h b/src/mongo/db/index_builds_coordinator.h
index 9431f157bee..bff4df93c56 100644
--- a/src/mongo/db/index_builds_coordinator.h
+++ b/src/mongo/db/index_builds_coordinator.h
@@ -497,8 +497,6 @@ public:
return true;
}
- void addRequiredPrivileges(std::vector<Privilege>* out) final {}
-
BSONObj generateSection(OperationContext* opCtx,
const BSONElement& configElement) const final {
BSONObjBuilder indexBuilds;
diff --git a/src/mongo/db/repl/replication_info.cpp b/src/mongo/db/repl/replication_info.cpp
index 3cd9fa9c591..aa442ee1465 100644
--- a/src/mongo/db/repl/replication_info.cpp
+++ b/src/mongo/db/repl/replication_info.cpp
@@ -338,9 +338,11 @@ public:
{kImplicitDefaultReadConcernNotPermitted}};
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const final {} // No auth required
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
bool runWithReplyBuilder(OperationContext* opCtx,
const DatabaseName& dbName,
diff --git a/src/mongo/db/s/check_sharding_index_command.cpp b/src/mongo/db/s/check_sharding_index_command.cpp
index 79db79a2b56..9c642d8f6de 100644
--- a/src/mongo/db/s/check_sharding_index_command.cpp
+++ b/src/mongo/db/s/check_sharding_index_command.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
#include "mongo/db/auth/action_type.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/catalog/index_catalog.h"
#include "mongo/db/commands.h"
@@ -58,12 +59,16 @@ public:
return AllowedOnSecondary::kNever;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::find);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::find)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
NamespaceString parseNs(const DatabaseName& dbName, const BSONObj& cmdObj) const override {
diff --git a/src/mongo/db/s/cluster_count_cmd_d.cpp b/src/mongo/db/s/cluster_count_cmd_d.cpp
index e291ec2ee29..27c64148cc9 100644
--- a/src/mongo/db/s/cluster_count_cmd_d.cpp
+++ b/src/mongo/db/s/cluster_count_cmd_d.cpp
@@ -27,6 +27,7 @@
* it in the license file.
*/
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/s/sharding_state.h"
#include "mongo/s/commands/cluster_count_cmd.h"
#include "mongo/s/grid.h"
@@ -44,12 +45,14 @@ struct ClusterCountCmdD {
return kNoApiVersions;
}
- static void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ static Status checkAuthForOperation(OperationContext* opCtx) {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
static void checkCanRunHere(OperationContext* opCtx) {
diff --git a/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp b/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp
index 7f64c9614ad..8bb1cde264d 100644
--- a/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp
+++ b/src/mongo/db/s/migration_chunk_cloner_source_legacy_commands.cpp
@@ -146,12 +146,16 @@ public:
return true;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
@@ -213,12 +217,16 @@ public:
return true;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
@@ -255,7 +263,7 @@ public:
return "internal";
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
@@ -263,16 +271,20 @@ public:
return AllowedOnSecondary::kNever;
}
- virtual bool adminOnly() const {
+ bool adminOnly() const override {
return true;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
/**
diff --git a/src/mongo/db/s/migration_destination_manager_legacy_commands.cpp b/src/mongo/db/s/migration_destination_manager_legacy_commands.cpp
index 6e820d5bef0..f0dfc08b1c1 100644
--- a/src/mongo/db/s/migration_destination_manager_legacy_commands.cpp
+++ b/src/mongo/db/s/migration_destination_manager_legacy_commands.cpp
@@ -80,12 +80,16 @@ public:
return NamespaceString(dbName.tenantId(), CommandHelpers::parseNsFullyQualified(cmdObj));
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool supportsRetryableWrite() const final {
@@ -181,12 +185,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
@@ -226,16 +234,20 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
- const DatabaseName& dbname,
+ const DatabaseName& dbName,
const BSONObj& cmdObj,
BSONObjBuilder& result) override {
auto const sessionId = uassertStatusOK(MigrationSessionId::extractFromBSON(cmdObj));
@@ -280,12 +292,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
@@ -338,12 +354,16 @@ public:
return true;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::internal);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::internal)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/db/s/sharding_state_command.cpp b/src/mongo/db/s/sharding_state_command.cpp
index c9f43ea3e0f..e2e52c5efc5 100644
--- a/src/mongo/db/s/sharding_state_command.cpp
+++ b/src/mongo/db/s/sharding_state_command.cpp
@@ -32,6 +32,7 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/commands.h"
#include "mongo/db/s/collection_sharding_state.h"
@@ -60,12 +61,16 @@ public:
return true;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::shardingState);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::shardingState)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/embedded/embedded_ismaster.cpp b/src/mongo/embedded/embedded_ismaster.cpp
index 3894f9b83d5..bcd5089523b 100644
--- a/src/mongo/embedded/embedded_ismaster.cpp
+++ b/src/mongo/embedded/embedded_ismaster.cpp
@@ -60,9 +60,11 @@ public:
return false;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {} // No auth required
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
CmdIsMaster() : BasicCommand("isMaster", "ismaster") {}
diff --git a/src/mongo/s/commands/cluster_add_shard_cmd.cpp b/src/mongo/s/commands/cluster_add_shard_cmd.cpp
index 9b7e013accd..9c059c51e59 100644
--- a/src/mongo/s/commands/cluster_add_shard_cmd.cpp
+++ b/src/mongo/s/commands/cluster_add_shard_cmd.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/s/client/shard_registry.h"
#include "mongo/s/grid.h"
@@ -65,12 +66,16 @@ public:
return "add a new shard to the system";
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::addShard);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::addShard)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_build_info.cpp b/src/mongo/s/commands/cluster_build_info.cpp
index c946ab8e6af..18abb7c950b 100644
--- a/src/mongo/s/commands/cluster_build_info.cpp
+++ b/src/mongo/s/commands/cluster_build_info.cpp
@@ -90,9 +90,11 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const final {} // No auth required
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
+ }
std::string help() const final {
return "get version #, etc.\n"
diff --git a/src/mongo/s/commands/cluster_coll_stats_cmd.cpp b/src/mongo/s/commands/cluster_coll_stats_cmd.cpp
index 25b3e15b578..b33da24608f 100644
--- a/src/mongo/s/commands/cluster_coll_stats_cmd.cpp
+++ b/src/mongo/s/commands/cluster_coll_stats_cmd.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/timeseries/timeseries_commands_conversion_helper.h"
#include "mongo/logv2/log.h"
@@ -182,12 +183,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::collStats);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::collStats)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_compact_cmd.cpp b/src/mongo/s/commands/cluster_compact_cmd.cpp
index 055e8d81688..e53ce4ef780 100644
--- a/src/mongo/s/commands/cluster_compact_cmd.cpp
+++ b/src/mongo/s/commands/cluster_compact_cmd.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
namespace mongo {
@@ -46,12 +47,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::compact);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::compact)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool supportsWriteConcern(const BSONObj& cmd) const override {
diff --git a/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp b/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp
index 35f7e9d9701..a34450631fb 100644
--- a/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp
+++ b/src/mongo/s/commands/cluster_convert_to_capped_cmd.cpp
@@ -91,12 +91,16 @@ public:
return CommandHelpers::parseNsCollectionRequired(dbName, cmdObj);
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::convertToCapped);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::convertToCapped)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_count_cmd.h b/src/mongo/s/commands/cluster_count_cmd.h
index 32aae8fb5f6..d90421f550f 100644
--- a/src/mongo/s/commands/cluster_count_cmd.h
+++ b/src/mongo/s/commands/cluster_count_cmd.h
@@ -32,6 +32,7 @@
#include <vector>
#include "mongo/bson/util/bson_extract.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/fle_crud.h"
#include "mongo/db/query/count_command_as_aggregation_command.h"
@@ -86,13 +87,16 @@ public:
Status::OK()};
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::find);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
- Impl::addRequiredPrivileges(dbname, cmdObj, out);
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::find)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Impl::checkAuthForOperation(opCtx);
}
bool errmsgRun(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_count_cmd_s.cpp b/src/mongo/s/commands/cluster_count_cmd_s.cpp
index d177d19d5ec..4226d06a189 100644
--- a/src/mongo/s/commands/cluster_count_cmd_s.cpp
+++ b/src/mongo/s/commands/cluster_count_cmd_s.cpp
@@ -42,10 +42,9 @@ struct ClusterCountCmdS {
return kApiVersions1;
}
- static void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
+ static Status checkAuthForOperation(OperationContext*) {
// No additional required privileges on a mongos.
+ return Status::OK();
}
static void checkCanRunHere(OperationContext* opCtx) {
diff --git a/src/mongo/s/commands/cluster_create_indexes_cmd.cpp b/src/mongo/s/commands/cluster_create_indexes_cmd.cpp
index 3a56ea99141..7699a802d01 100644
--- a/src/mongo/s/commands/cluster_create_indexes_cmd.cpp
+++ b/src/mongo/s/commands/cluster_create_indexes_cmd.cpp
@@ -68,10 +68,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const final {
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), ActionType::createIndex));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::createIndex)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool supportsWriteConcern(const BSONObj& cmd) const final {
diff --git a/src/mongo/s/commands/cluster_distinct_cmd.cpp b/src/mongo/s/commands/cluster_distinct_cmd.cpp
index a4690c8c4db..1bcddd4aa80 100644
--- a/src/mongo/s/commands/cluster_distinct_cmd.cpp
+++ b/src/mongo/s/commands/cluster_distinct_cmd.cpp
@@ -31,6 +31,7 @@
#include "mongo/platform/basic.h"
#include "mongo/bson/bsonobj_comparator.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/db/query/collation/collator_factory_interface.h"
#include "mongo/db/query/parsed_distinct.h"
@@ -89,12 +90,16 @@ public:
return ReadConcernSupportResult::allSupportedAndDefaultPermitted();
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::find);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::find)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool allowedInTransactions() const final {
diff --git a/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp b/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp
index 45b20abae15..076b8a1d61d 100644
--- a/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp
+++ b/src/mongo/s/commands/cluster_drop_indexes_cmd.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/logv2/log.h"
#include "mongo/rpc/get_status_from_command_result.h"
@@ -62,12 +63,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::dropIndex);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::dropIndex)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
void validateResult(const BSONObj& resultObj) final {
diff --git a/src/mongo/s/commands/cluster_filemd5_cmd.cpp b/src/mongo/s/commands/cluster_filemd5_cmd.cpp
index 3922205749c..600f41ba3bd 100644
--- a/src/mongo/s/commands/cluster_filemd5_cmd.cpp
+++ b/src/mongo/s/commands/cluster_filemd5_cmd.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/s/cluster_commands_helpers.h"
@@ -71,10 +72,16 @@ public:
return NamespaceString(dbName, collectionName);
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), ActionType::find));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::find)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool supportsWriteConcern(const BSONObj& cmd) const override {
diff --git a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
index d373c9d753b..e51c61b3acc 100644
--- a/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
+++ b/src/mongo/s/commands/cluster_find_and_modify_cmd.cpp
@@ -347,12 +347,12 @@ public:
{{ErrorCodes::InvalidOptions, "default read concern not permitted"}}};
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- bool update = cmdObj["update"].trueValue();
- bool upsert = cmdObj["upsert"].trueValue();
- bool remove = cmdObj["remove"].trueValue();
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ const bool update = cmdObj["update"].trueValue();
+ const bool upsert = cmdObj["upsert"].trueValue();
+ const bool remove = cmdObj["remove"].trueValue();
ActionSet actions;
actions.addAction(ActionType::find);
@@ -369,12 +369,18 @@ public:
actions.addAction(ActionType::bypassDocumentValidation);
}
- std::string ns = CommandHelpers::parseNsFromCommand(dbname, cmdObj);
- ResourcePattern resource(CommandHelpers::resourcePatternForNamespace(ns));
+ auto nss = CommandHelpers::parseNsFromCommand(dbName, cmdObj);
+ ResourcePattern resource(CommandHelpers::resourcePatternForNamespace(nss.ns()));
uassert(17137,
"Invalid target namespace " + resource.toString(),
resource.isExactNamespacePattern());
- out->push_back(Privilege(resource, actions));
+
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(resource, actions)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
Status explain(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_fsync_cmd.cpp b/src/mongo/s/commands/cluster_fsync_cmd.cpp
index 00972e17815..b79193f2b65 100644
--- a/src/mongo/s/commands/cluster_fsync_cmd.cpp
+++ b/src/mongo/s/commands/cluster_fsync_cmd.cpp
@@ -31,6 +31,7 @@
#include "mongo/client/read_preference.h"
#include "mongo/client/remote_command_targeter.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/s/client/shard.h"
#include "mongo/s/client/shard_registry.h"
@@ -59,12 +60,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::fsync);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::fsync)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool errmsgRun(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_get_last_error_cmd.cpp b/src/mongo/s/commands/cluster_get_last_error_cmd.cpp
index 008a4d349e3..2b7f8c322ff 100644
--- a/src/mongo/s/commands/cluster_get_last_error_cmd.cpp
+++ b/src/mongo/s/commands/cluster_get_last_error_cmd.cpp
@@ -39,7 +39,7 @@ class GetLastErrorCmd : public BasicCommand {
public:
GetLastErrorCmd() : BasicCommand("getLastError", "getlasterror") {}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
@@ -51,17 +51,17 @@ public:
return "no longer supported";
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- // No auth required for getlasterror
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
}
bool requiresAuth() const override {
return false;
}
- virtual bool run(OperationContext*, const DatabaseName&, const BSONObj&, BSONObjBuilder&) {
+ bool run(OperationContext*, const DatabaseName&, const BSONObj&, BSONObjBuilder&) override {
uasserted(5739001, "getLastError command is not supported");
return false;
}
diff --git a/src/mongo/s/commands/cluster_hello_cmd.cpp b/src/mongo/s/commands/cluster_hello_cmd.cpp
index 005a6e2ec26..9c6b2f4fb9f 100644
--- a/src/mongo/s/commands/cluster_hello_cmd.cpp
+++ b/src/mongo/s/commands/cluster_hello_cmd.cpp
@@ -104,10 +104,10 @@ public:
return "Status information for clients negotiating a connection with this server";
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const final {
- // No auth required
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
}
bool requiresAuth() const final {
diff --git a/src/mongo/s/commands/cluster_is_db_grid_cmd.cpp b/src/mongo/s/commands/cluster_is_db_grid_cmd.cpp
index 6fc4f1b9263..d962e62e510 100644
--- a/src/mongo/s/commands/cluster_is_db_grid_cmd.cpp
+++ b/src/mongo/s/commands/cluster_is_db_grid_cmd.cpp
@@ -43,7 +43,7 @@ public:
return false;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ bool supportsWriteConcern(const BSONObj& cmd) const override {
return false;
}
@@ -51,16 +51,16 @@ public:
return AllowedOnSecondary::kAlways;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- // No auth required
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
}
- virtual bool run(OperationContext* opCtx,
- const DatabaseName&,
- const BSONObj& cmdObj,
- BSONObjBuilder& result) {
+ bool run(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj& cmdObj,
+ BSONObjBuilder& result) override {
result.append("isdbgrid", 1);
result.append("hostname", getHostNameCached());
return true;
diff --git a/src/mongo/s/commands/cluster_list_shards_cmd.cpp b/src/mongo/s/commands/cluster_list_shards_cmd.cpp
index cb5fb91c6ec..e7b84626963 100644
--- a/src/mongo/s/commands/cluster_list_shards_cmd.cpp
+++ b/src/mongo/s/commands/cluster_list_shards_cmd.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/s/catalog/type_shard.h"
#include "mongo/s/grid.h"
@@ -56,12 +57,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::listShards);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::listShards)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_multicast_cmd.cpp b/src/mongo/s/commands/cluster_multicast_cmd.cpp
index 90ff772122f..0d82a3d85a1 100644
--- a/src/mongo/s/commands/cluster_multicast_cmd.cpp
+++ b/src/mongo/s/commands/cluster_multicast_cmd.cpp
@@ -83,9 +83,11 @@ public:
}
// no privs because it's a test command
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {}
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK();
+ }
bool run(OperationContext* opCtx,
const DatabaseName&,
diff --git a/src/mongo/s/commands/cluster_netstat_cmd.cpp b/src/mongo/s/commands/cluster_netstat_cmd.cpp
index 1b1fd469d6c..1003b9b0e44 100644
--- a/src/mongo/s/commands/cluster_netstat_cmd.cpp
+++ b/src/mongo/s/commands/cluster_netstat_cmd.cpp
@@ -29,6 +29,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/s/catalog/sharding_catalog_client.h"
#include "mongo/s/client/shard_registry.h"
@@ -57,12 +58,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::netstat);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::netstat)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_remove_shard_cmd.cpp b/src/mongo/s/commands/cluster_remove_shard_cmd.cpp
index ef31d7dce15..28b3e549d22 100644
--- a/src/mongo/s/commands/cluster_remove_shard_cmd.cpp
+++ b/src/mongo/s/commands/cluster_remove_shard_cmd.cpp
@@ -32,6 +32,7 @@
#include <string>
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/s/client/shard.h"
#include "mongo/s/client/shard_registry.h"
@@ -63,12 +64,16 @@ public:
return true;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::removeShard);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::removeShard)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/cluster_validate_cmd.cpp b/src/mongo/s/commands/cluster_validate_cmd.cpp
index e54997ace56..237895fa301 100644
--- a/src/mongo/s/commands/cluster_validate_cmd.cpp
+++ b/src/mongo/s/commands/cluster_validate_cmd.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/rpc/get_status_from_command_result.h"
#include "mongo/s/cluster_commands_helpers.h"
@@ -57,12 +58,16 @@ public:
return false;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::validate);
- out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName& dbName,
+ const BSONObj& cmdObj) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(parseResourcePattern(dbName.db(), cmdObj),
+ ActionType::validate)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool supportsWriteConcern(const BSONObj& cmd) const override {
diff --git a/src/mongo/s/commands/cluster_whats_my_uri_cmd.cpp b/src/mongo/s/commands/cluster_whats_my_uri_cmd.cpp
index d8581f2706e..6191134aec8 100644
--- a/src/mongo/s/commands/cluster_whats_my_uri_cmd.cpp
+++ b/src/mongo/s/commands/cluster_whats_my_uri_cmd.cpp
@@ -55,16 +55,16 @@ public:
return false;
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const {
- // No auth required
+ Status checkAuthForOperation(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ return Status::OK(); // No auth required
}
- virtual bool run(OperationContext* opCtx,
- const DatabaseName&,
- const BSONObj& cmdObj,
- BSONObjBuilder& result) {
+ bool run(OperationContext*,
+ const DatabaseName&,
+ const BSONObj&,
+ BSONObjBuilder& result) override {
result << "you" << cc().getRemote().toString();
return true;
}
diff --git a/src/mongo/s/commands/flush_router_config_cmd.cpp b/src/mongo/s/commands/flush_router_config_cmd.cpp
index addbd88edfc..e3bc756e510 100644
--- a/src/mongo/s/commands/flush_router_config_cmd.cpp
+++ b/src/mongo/s/commands/flush_router_config_cmd.cpp
@@ -30,6 +30,7 @@
#include "mongo/platform/basic.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/commands.h"
#include "mongo/logv2/log.h"
#include "mongo/s/grid.h"
@@ -67,12 +68,16 @@ public:
"{flushRouterconfig: 'db.coll'} flushes only the given collection";
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::flushRouterConfig);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::flushRouterConfig)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,
diff --git a/src/mongo/s/commands/get_shard_map_cmd.cpp b/src/mongo/s/commands/get_shard_map_cmd.cpp
index bbdf20d5ff0..f59d59717f4 100644
--- a/src/mongo/s/commands/get_shard_map_cmd.cpp
+++ b/src/mongo/s/commands/get_shard_map_cmd.cpp
@@ -31,6 +31,7 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/commands.h"
#include "mongo/s/grid.h"
@@ -58,12 +59,16 @@ public:
return true;
}
- void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) const override {
- ActionSet actions;
- actions.addAction(ActionType::getShardMap);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+ Status checkAuthForOperation(OperationContext* opCtx,
+ const DatabaseName&,
+ const BSONObj&) const override {
+ auto* as = AuthorizationSession::get(opCtx->getClient());
+ if (!as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::getShardMap)) {
+ return {ErrorCodes::Unauthorized, "unauthorized"};
+ }
+
+ return Status::OK();
}
bool run(OperationContext* opCtx,