summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorErwin Pe <erwin.pe@mongodb.com>2022-02-18 17:58:50 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-02-18 18:53:49 +0000
commitd42d5038a7113609b44e638b296aeaffad969e83 (patch)
treea6e7ec924d67fd986696a021dd4645ca83dde8e4 /src/mongo
parent1295e77aec0fdd21ff430939453bbba24c77870f (diff)
downloadmongo-d42d5038a7113609b44e638b296aeaffad969e83.tar.gz
SERVER-63465 Create index limitations with encrypted fields
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/commands/SConscript1
-rw-r--r--src/mongo/db/commands/create_indexes.cpp70
2 files changed, 71 insertions, 0 deletions
diff --git a/src/mongo/db/commands/SConscript b/src/mongo/db/commands/SConscript
index 60fa18346ac..6e17b42669a 100644
--- a/src/mongo/db/commands/SConscript
+++ b/src/mongo/db/commands/SConscript
@@ -367,6 +367,7 @@ env.Library(
],
LIBDEPS_PRIVATE=[
'$BUILD_DIR/mongo/base',
+ '$BUILD_DIR/mongo/crypto/encrypted_field_config',
'$BUILD_DIR/mongo/db/api_parameters',
'$BUILD_DIR/mongo/db/catalog/catalog_helpers',
'$BUILD_DIR/mongo/db/catalog/collection_query_info',
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 8496c2fe0ee..92c3efb2bbf 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -35,6 +35,7 @@
#include <vector>
#include "mongo/base/string_data.h"
+#include "mongo/crypto/encryption_fields_gen.h"
#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/catalog/clustered_collection_util.h"
#include "mongo/db/catalog/collection.h"
@@ -195,6 +196,74 @@ void validateTTLOptions(OperationContext* opCtx,
}
}
+void checkEncryptedFieldIndexRestrictions(OperationContext* opCtx,
+ const NamespaceString& ns,
+ const CreateIndexesCommand& cmd) {
+ if (!gFeatureFlagFLE2.isEnabledAndIgnoreFCV()) {
+ return;
+ }
+
+ AutoGetCollection collection(opCtx, ns, MODE_IS);
+ if (!collection) {
+ return;
+ }
+
+ const auto& encryptConfig = collection->getCollectionOptions().encryptedFieldConfig;
+ if (!encryptConfig) {
+ // this collection is not encrypted
+ return;
+ }
+
+ auto& encryptedFields = encryptConfig->getFields();
+ std::vector<FieldRef> encryptedFieldRefs;
+
+ for (const auto& index : cmd.getIndexes()) {
+
+ // Do not allow TTL indexes on encrypted collections because automatic
+ // deletion of encrypted documents would require the deletion tokens
+ // for each encrypted field, which the server does not have.
+ uassert(6346501,
+ "TTL indexes are not allowed on encrypted collections",
+ !index_key_validate::isIndexTTL(index));
+
+ if (!index.hasField(IndexDescriptor::kUniqueFieldName) ||
+ index.getBoolField(IndexDescriptor::kUniqueFieldName) == false) {
+ // skip if not attempting to create a unique index
+ continue;
+ }
+
+ // Create the FieldRefs for each encrypted field (if not already created)
+ if (encryptedFieldRefs.empty() && !encryptedFields.empty()) {
+ std::transform(encryptedFields.begin(),
+ encryptedFields.end(),
+ std::back_inserter(encryptedFieldRefs),
+ [](auto& path) { return FieldRef(path.getPath()); });
+ }
+
+ // Do not allow unique indexes on encrypted fields, or prefixes of encrypted fields.
+ auto keyObject = index[IndexDescriptor::kKeyPatternFieldName].Obj();
+ for (const auto& keyElement : keyObject) {
+
+ FieldRef keyFieldRef(keyElement.fieldNameStringData());
+
+ for (const auto& encryptedFieldRef : encryptedFieldRefs) {
+ auto common = keyFieldRef.commonPrefixSize(encryptedFieldRef);
+ uassert(
+ 6346502,
+ str::stream()
+ << "Unique indexes are not allowed on, or a prefix of, the encrypted field "
+ << encryptedFieldRef.dottedField(),
+ common != keyFieldRef.numParts());
+ uassert(6346503,
+ str::stream() << "Unique indexes are not allowed on keys whose prefix is "
+ "the encrypted field "
+ << encryptedFieldRef.dottedField(),
+ common != encryptedFieldRef.numParts());
+ }
+ }
+ }
+}
+
/**
* Retrieves the commit quorum from 'cmdObj' if it is present. If it isn't, we provide a default
* commit quorum, which consists of all the data-bearing nodes.
@@ -423,6 +492,7 @@ CreateIndexesReply runCreateIndexesWithCoordinator(OperationContext* opCtx,
}
validateTTLOptions(opCtx, ns, cmd);
+ checkEncryptedFieldIndexRestrictions(opCtx, ns, cmd);
// Preliminary checks before handing control over to IndexBuildsCoordinator:
// 1) We are in a replication mode that allows for index creation.