diff options
author | seanzimm <sean.zimmerman@mongodb.com> | 2022-12-19 18:09:15 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-12-19 19:08:06 +0000 |
commit | 51756db5965b0f5b5546701085f8a1e5375a35da (patch) | |
tree | 6ab77b939c5063b147716fd446adcf5e47a5f410 /src | |
parent | c2e9caa2fe8093a8fde55d1252c8c85d62859f7a (diff) | |
download | mongo-51756db5965b0f5b5546701085f8a1e5375a35da.tar.gz |
SERVER-71652 Implement BulkWriteCommand Authentication Checks
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/commands/SConscript | 2 | ||||
-rw-r--r-- | src/mongo/db/commands/bulk_write.cpp | 53 | ||||
-rw-r--r-- | src/mongo/db/commands/bulk_write.idl | 5 |
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: |