diff options
Diffstat (limited to 'src/mongo/db/ops/write_ops_exec.cpp')
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 58 |
1 files changed, 52 insertions, 6 deletions
diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index 6fd7e2200c7..f7fc2a84efd 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -602,11 +602,36 @@ SingleWriteResult makeWriteResultForInsertOrDeleteRetry() { return res; } + +// Returns the flags that determine the type of document validation we want to +// perform. First item in the tuple determines whether to bypass document validation altogether, +// second item determines if _safeContent_ array can be modified in an encrypted collection. +std::tuple<bool, bool> getDocumentValidationFlags(OperationContext* opCtx, + const write_ops::WriteCommandRequestBase& req) { + auto& encryptionInfo = req.getEncryptionInformation(); + const bool fleCrudProcessed = getFleCrudProcessed(opCtx, encryptionInfo); + return std::make_tuple(req.getBypassDocumentValidation(), fleCrudProcessed); +} } // namespace +bool getFleCrudProcessed(OperationContext* opCtx, + const boost::optional<EncryptionInformation>& encryptionInfo) { + if (encryptionInfo && encryptionInfo->getCrudProcessed().value_or(false)) { + uassert(6666201, + "External users cannot have crudProcessed enabled", + AuthorizationSession::get(opCtx->getClient()) + ->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::internal)); + + return true; + } + return false; +} + WriteResult performInserts(OperationContext* opCtx, const write_ops::InsertCommandRequest& wholeOp, OperationSource source) { + // Insert performs its own retries, so we should only be within a WriteUnitOfWork when run in a // transaction. auto txnParticipant = TransactionParticipant::get(opCtx); @@ -641,8 +666,15 @@ WriteResult performInserts(OperationContext* opCtx, uassertStatusOK(userAllowedWriteNS(opCtx, wholeOp.getNamespace())); } - DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler( - opCtx, wholeOp.getWriteCommandRequestBase().getBypassDocumentValidation()); + const auto [disableDocumentValidation, fleCrudProcessed] = + getDocumentValidationFlags(opCtx, wholeOp.getWriteCommandRequestBase()); + + DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(opCtx, + disableDocumentValidation); + + DisableSafeContentValidationIfTrue safeContentValidationDisabler( + opCtx, disableDocumentValidation, fleCrudProcessed); + LastOpFixer lastOpFixer(opCtx, wholeOp.getNamespace()); WriteResult out; @@ -1000,8 +1032,15 @@ WriteResult performUpdates(OperationContext* opCtx, (txnParticipant && opCtx->inMultiDocumentTransaction())); uassertStatusOK(userAllowedWriteNS(opCtx, ns)); - DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler( - opCtx, wholeOp.getWriteCommandRequestBase().getBypassDocumentValidation()); + const auto [disableDocumentValidation, fleCrudProcessed] = + getDocumentValidationFlags(opCtx, wholeOp.getWriteCommandRequestBase()); + + DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(opCtx, + disableDocumentValidation); + + DisableSafeContentValidationIfTrue safeContentValidationDisabler( + opCtx, disableDocumentValidation, fleCrudProcessed); + LastOpFixer lastOpFixer(opCtx, ns); bool containsRetry = false; @@ -1227,8 +1266,15 @@ WriteResult performDeletes(OperationContext* opCtx, (txnParticipant && opCtx->inMultiDocumentTransaction())); uassertStatusOK(userAllowedWriteNS(opCtx, ns)); - DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler( - opCtx, wholeOp.getWriteCommandRequestBase().getBypassDocumentValidation()); + const auto [disableDocumentValidation, fleCrudProcessed] = + getDocumentValidationFlags(opCtx, wholeOp.getWriteCommandRequestBase()); + + DisableDocumentSchemaValidationIfTrue docSchemaValidationDisabler(opCtx, + disableDocumentValidation); + + DisableSafeContentValidationIfTrue safeContentValidationDisabler( + opCtx, disableDocumentValidation, fleCrudProcessed); + LastOpFixer lastOpFixer(opCtx, ns); bool containsRetry = false; |