diff options
author | Erwin Pe <erwin.pe@mongodb.com> | 2022-02-18 17:58:50 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-02-18 18:53:49 +0000 |
commit | d42d5038a7113609b44e638b296aeaffad969e83 (patch) | |
tree | a6e7ec924d67fd986696a021dd4645ca83dde8e4 /src | |
parent | 1295e77aec0fdd21ff430939453bbba24c77870f (diff) | |
download | mongo-d42d5038a7113609b44e638b296aeaffad969e83.tar.gz |
SERVER-63465 Create index limitations with encrypted fields
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/commands/SConscript | 1 | ||||
-rw-r--r-- | src/mongo/db/commands/create_indexes.cpp | 70 |
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. |