summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2022-03-31 23:48:29 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-04-01 05:53:42 +0000
commitbde82201650d83dc86aa7795594a0264feb95c7f (patch)
treeb71211dd250042aa5e0000957d97fcc61f076012
parentcbd9d61b6e44a560cb01b7412093502148327d56 (diff)
downloadmongo-bde82201650d83dc86aa7795594a0264feb95c7f.tar.gz
SERVER-64644 Prohibit sharding of FLE 2 state collections
-rw-r--r--jstests/fle2/shard_collection.js41
-rw-r--r--src/mongo/db/namespace_string.cpp11
-rw-r--r--src/mongo/db/namespace_string.h5
-rw-r--r--src/mongo/s/commands/cluster_shard_collection_cmd.cpp4
4 files changed, 61 insertions, 0 deletions
diff --git a/jstests/fle2/shard_collection.js b/jstests/fle2/shard_collection.js
new file mode 100644
index 00000000000..5f55e944d97
--- /dev/null
+++ b/jstests/fle2/shard_collection.js
@@ -0,0 +1,41 @@
+/**
+ * Verify valid and invalid scenarios for shard collection
+ *
+ * @tags: [
+ * featureFlagFLE2,
+ * ]
+ */
+load("jstests/fle2/libs/encrypted_client_util.js");
+
+(function() {
+'use strict';
+
+if (!isFLE2ShardingEnabled()) {
+ return;
+}
+
+let dbName = 'shard_state';
+let dbTest = db.getSiblingDB(dbName);
+dbTest.dropDatabase();
+
+let client = new EncryptedClient(db.getMongo(), dbName);
+
+assert.commandWorked(client.createEncryptionCollection("basic", {
+ encryptedFields:
+ {"fields": [{"path": "first", "bsonType": "string", "queries": {"queryType": "equality"}}]}
+}));
+
+const result = dbTest.getCollectionInfos({name: "basic"});
+print("result" + tojson(result));
+const ef = result[0].options.encryptedFields;
+assert.eq(ef.escCollection, "fle2.basic.esc");
+assert.eq(ef.eccCollection, "fle2.basic.ecc");
+assert.eq(ef.ecocCollection, "fle2.basic.ecoc");
+
+assert.commandFailedWithCode(
+ db.adminCommand({shardCollection: 'shard_state.fle2.basic.esc', key: {_id: 1}}), 6464401);
+assert.commandFailedWithCode(
+ db.adminCommand({shardCollection: 'shard_state.fle2.basic.ecc', key: {_id: 1}}), 6464401);
+assert.commandFailedWithCode(
+ db.adminCommand({shardCollection: 'shard_state.fle2.basic.ecoc', key: {_id: 1}}), 6464401);
+}());
diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp
index bd9d3a68d93..2eab32c841f 100644
--- a/src/mongo/db/namespace_string.cpp
+++ b/src/mongo/db/namespace_string.cpp
@@ -45,6 +45,11 @@ constexpr auto listCollectionsCursorCol = "$cmd.listCollections"_sd;
constexpr auto collectionlessAggregateCursorCol = "$cmd.aggregate"_sd;
constexpr auto dropPendingNSPrefix = "system.drop."_sd;
+constexpr auto fle2Prefix = "fle2."_sd;
+constexpr auto fle2EscSuffix = ".esc"_sd;
+constexpr auto fle2EccSuffix = ".ecc"_sd;
+constexpr auto fle2EcocSuffix = ".ecoc"_sd;
+
} // namespace
constexpr StringData NamespaceString::kAdminDb;
@@ -374,6 +379,12 @@ bool NamespaceString::isConfigTransactionsCollection() const {
return ns() == kSessionTransactionsTableNamespace.ns();
}
+bool NamespaceString::isFLE2StateCollection() const {
+ return coll().startsWith(fle2Prefix) &&
+ (coll().endsWith(fle2EscSuffix) || coll().endsWith(fle2EccSuffix) ||
+ coll().endsWith(fle2EcocSuffix));
+}
+
NamespaceString NamespaceString::makeTimeseriesBucketsNamespace() const {
return {db(), kTimeseriesBucketsCollectionPrefix.toString() + coll()};
}
diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h
index 6a9418f1775..599f5aac11f 100644
--- a/src/mongo/db/namespace_string.h
+++ b/src/mongo/db/namespace_string.h
@@ -415,6 +415,11 @@ public:
bool isConfigTransactionsCollection() const;
/**
+ * Returns whether the specified namespace is <database>.fle2.<.+>.(esc|ecc|ecoc).
+ */
+ bool isFLE2StateCollection() const;
+
+ /**
* Returns the time-series buckets namespace for this view.
*/
NamespaceString makeTimeseriesBucketsNamespace() const;
diff --git a/src/mongo/s/commands/cluster_shard_collection_cmd.cpp b/src/mongo/s/commands/cluster_shard_collection_cmd.cpp
index 6624a1ec2bc..70fa815b574 100644
--- a/src/mongo/s/commands/cluster_shard_collection_cmd.cpp
+++ b/src/mongo/s/commands/cluster_shard_collection_cmd.cpp
@@ -90,6 +90,10 @@ public:
"Sharding a buckets collection is not allowed",
!nss.isTimeseriesBucketsCollection());
+ uassert(6464401,
+ "Sharding a FLE 2 state collection is not allowed",
+ !nss.isFLE2StateCollection());
+
auto shardCollRequest =
ShardCollection::parse(IDLParserErrorContext("ShardCollection"), cmdObj);