summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorseanzimm <sean.zimmerman@mongodb.com>2022-12-19 18:09:15 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-12-19 19:08:06 +0000
commit51756db5965b0f5b5546701085f8a1e5375a35da (patch)
tree6ab77b939c5063b147716fd446adcf5e47a5f410 /src
parentc2e9caa2fe8093a8fde55d1252c8c85d62859f7a (diff)
downloadmongo-51756db5965b0f5b5546701085f8a1e5375a35da.tar.gz
SERVER-71652 Implement BulkWriteCommand Authentication Checks
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/commands/SConscript2
-rw-r--r--src/mongo/db/commands/bulk_write.cpp53
-rw-r--r--src/mongo/db/commands/bulk_write.idl5
3 files changed, 55 insertions, 5 deletions
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index 2d9d35a4b5d..6b2077cc3ce 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -280,7 +280,9 @@ env.Library(
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/crypto/fle_fields',
'$BUILD_DIR/mongo/db/auth/auth',
+ '$BUILD_DIR/mongo/db/auth/authprivilege',
'$BUILD_DIR/mongo/db/commands',
+ '$BUILD_DIR/mongo/db/not_primary_error_tracker',
'$BUILD_DIR/mongo/db/ops/write_ops_parsers',
'$BUILD_DIR/mongo/db/server_base',
'$BUILD_DIR/mongo/db/server_feature_flags',
diff --git a/src/mongo/db/commands/bulk_write.cpp b/src/mongo/db/commands/bulk_write.cpp
index abeff794dde..e2fa09708e3 100644
--- a/src/mongo/db/commands/bulk_write.cpp
+++ b/src/mongo/db/commands/bulk_write.cpp
@@ -32,10 +32,13 @@
#include <string>
#include <vector>
+#include "mongo/db/auth/action_set.h"
+#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/catalog/document_validation.h"
#include "mongo/db/commands.h"
#include "mongo/db/commands/bulk_write_gen.h"
+#include "mongo/db/not_primary_error_tracker.h"
#include "mongo/db/server_feature_flags_gen.h"
#include "mongo/db/server_options.h"
#include "mongo/db/service_context.h"
@@ -98,12 +101,12 @@ public:
"BulkWrite may not be run without featureFlagBulkWriteCommand enabled",
gFeatureFlagBulkWriteCommand.isEnabled(serverGlobalParams.featureCompatibility));
- // Validate that every ops entry has a valid nsInfo index
+ // Validate that every ops entry has a valid nsInfo index.
auto& req = request();
- auto ops = req.getOps();
- auto nsInfo = req.getNsInfo();
+ const auto& ops = req.getOps();
+ const auto& nsInfo = req.getNsInfo();
- for (auto& op : ops) {
+ for (const auto& op : ops) {
unsigned int nsInfoIdx = op.getInsert();
uassert(ErrorCodes::BadValue,
str::stream() << "BulkWrite ops entry " << op.toBSON()
@@ -118,6 +121,48 @@ public:
return reply;
}
+
+ void doCheckAuthorization(OperationContext* opCtx) const final try {
+ auto session = AuthorizationSession::get(opCtx->getClient());
+ const auto& ops = request().getOps();
+ const auto& nsInfo = request().getNsInfo();
+
+ std::vector<Privilege> privileges;
+ privileges.reserve(nsInfo.size());
+ ActionSet actions;
+ if (request().getBypassDocumentValidation()) {
+ actions.addAction(ActionType::bypassDocumentValidation);
+ }
+
+ // Create initial Privilege entry for each nsInfo entry.
+ for (const auto& ns : nsInfo) {
+ privileges.emplace_back(ResourcePattern::forExactNamespace(ns.getNs()), actions);
+ }
+
+ // Iterate over each op and assign the appropriate actions to the namespace privilege.
+ for (const auto& op : ops) {
+ unsigned int nsInfoIdx = op.getInsert();
+ uassert(ErrorCodes::BadValue,
+ str::stream() << "BulkWrite ops entry " << op.toBSON()
+ << " has an invalid nsInfo index.",
+ nsInfoIdx < nsInfo.size());
+
+ auto& privilege = privileges[nsInfoIdx];
+ ActionSet newActions;
+
+ // TODO SERVER-72092 Make this logic handle different types of `op`.
+ newActions.addAction(ActionType::insert);
+ privilege.addActions(newActions);
+ }
+
+ // Make sure all privileges are authorized.
+ uassert(ErrorCodes::Unauthorized,
+ "unauthorized",
+ session->isAuthorizedForPrivileges(privileges));
+ } catch (const DBException& ex) {
+ NotPrimaryErrorTracker::get(opCtx->getClient()).recordError(ex.code());
+ throw;
+ }
};
} bulkWriteCmd;
diff --git a/src/mongo/db/commands/bulk_write.idl b/src/mongo/db/commands/bulk_write.idl
index 70a49f6c172..22edb378042 100644
--- a/src/mongo/db/commands/bulk_write.idl
+++ b/src/mongo/db/commands/bulk_write.idl
@@ -158,7 +158,10 @@ commands:
namespace: ignored
api_version: "1"
access_check:
- none: true
+ simple:
+ privilege:
+ resource_pattern: exact_namespace
+ action_type: [bypassDocumentValidation, find, insert, update, remove]
reply_type: BulkWriteCommandReply
fields:
ops: