summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2018-02-06 15:51:41 -0500
committerTess Avitabile <tess.avitabile@mongodb.com>2018-02-08 14:51:05 -0500
commitd337da259248c785f4014b565742300eb08ecd4f (patch)
treec34b437747a75f2454f2d4ad2d8a7b4b3ef6cf27 /src/mongo
parent2e287a4bc99f3c774a5322eae477f626638c6a81 (diff)
downloadmongo-d337da259248c785f4014b565742300eb08ecd4f.tar.gz
SERVER-32894 Disallow creation of system.indexes
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/commands/clone_collection.cpp21
-rw-r--r--src/mongo/db/commands/create_indexes.cpp5
-rw-r--r--src/mongo/db/ops/insert.cpp13
3 files changed, 29 insertions, 10 deletions
diff --git a/src/mongo/db/commands/clone_collection.cpp b/src/mongo/db/commands/clone_collection.cpp
index abaafb799e0..146aef53fcc 100644
--- a/src/mongo/db/commands/clone_collection.cpp
+++ b/src/mongo/db/commands/clone_collection.cpp
@@ -125,8 +125,18 @@ public:
}
}
- string collection = parseNs(dbname, cmdObj);
- Status allowedWriteStatus = userAllowedWriteNS(dbname, collection);
+ auto ns = parseNs(dbname, cmdObj);
+
+ // In order to clone a namespace, a user must be allowed to both create and write to that
+ // namespace. There exist namespaces that are legal to create but not write to (e.g.
+ // system.profile), and there exist namespaces that are legal to write to but not create
+ // (e.g. system.indexes), so we must check that it is legal to both create and write to the
+ // namespace.
+ auto allowedCreateStatus = userAllowedCreateNS(dbname, nsToCollectionSubstring(ns));
+ if (!allowedCreateStatus.isOK()) {
+ return CommandHelpers::appendCommandStatus(result, allowedCreateStatus);
+ }
+ auto allowedWriteStatus = userAllowedWriteNS(dbname, nsToCollectionSubstring(ns));
if (!allowedWriteStatus.isOK()) {
return CommandHelpers::appendCommandStatus(result, allowedWriteStatus);
}
@@ -138,9 +148,8 @@ public:
BSONElement copyIndexesSpec = cmdObj.getField("copyindexes");
bool copyIndexes = copyIndexesSpec.isBoolean() ? copyIndexesSpec.boolean() : true;
- log() << "cloneCollection. db:" << dbname << " collection:" << collection
- << " from: " << fromhost << " query: " << redact(query) << " "
- << (copyIndexes ? "" : ", not copying indexes");
+ log() << "cloneCollection. collection: " << ns << " from: " << fromhost
+ << " query: " << redact(query) << " " << (copyIndexes ? "" : ", not copying indexes");
Cloner cloner;
auto myconn = stdx::make_unique<DBClientConnection>();
@@ -150,7 +159,7 @@ public:
cloner.setConnection(std::move(myconn));
return cloner.copyCollection(
- opCtx, collection, query, errmsg, copyIndexes, CollectionOptions::parseForCommand);
+ opCtx, ns, query, errmsg, copyIndexes, CollectionOptions::parseForCommand);
}
} cmdCloneCollection;
diff --git a/src/mongo/db/commands/create_indexes.cpp b/src/mongo/db/commands/create_indexes.cpp
index 830d7098f78..81b424e574a 100644
--- a/src/mongo/db/commands/create_indexes.cpp
+++ b/src/mongo/db/commands/create_indexes.cpp
@@ -280,6 +280,11 @@ public:
result, {ErrorCodes::CommandNotSupportedOnView, errmsg});
}
+ status = userAllowedCreateNS(ns.db(), ns.coll());
+ if (!status.isOK()) {
+ return CommandHelpers::appendCommandStatus(result, status);
+ }
+
writeConflictRetry(opCtx, kCommandName, ns.ns(), [&] {
WriteUnitOfWork wunit(opCtx);
collection = db->createCollection(opCtx, ns.ns(), CollectionOptions());
diff --git a/src/mongo/db/ops/insert.cpp b/src/mongo/db/ops/insert.cpp
index 8ed9abbd634..af50aca6415 100644
--- a/src/mongo/db/ops/insert.cpp
+++ b/src/mongo/db/ops/insert.cpp
@@ -189,6 +189,9 @@ Status userAllowedWriteNS(StringData db, StringData coll) {
return Status(ErrorCodes::InvalidNamespace,
str::stream() << "cannot write to '" << db << ".system.profile'");
}
+ if (coll == "system.indexes") {
+ return Status::OK();
+ }
return userAllowedCreateNS(db, coll);
}
@@ -222,8 +225,6 @@ Status userAllowedCreateNS(StringData db, StringData coll) {
if (coll.startsWith("system.")) {
- if (coll == "system.indexes")
- return Status::OK();
if (coll == "system.js")
return Status::OK();
if (coll == "system.profile")
@@ -261,8 +262,12 @@ Status userAllowedCreateNS(StringData db, StringData coll) {
// some special rules
if (coll.find(".system.") != string::npos) {
- // If this is metadata for the sessions collection, shard servers need to be able to
- // write to it.
+ // Writes are permitted to the persisted chunk metadata collections. These collections are
+ // named based on the name of the sharded collection, e.g.
+ // 'config.cache.chunks.dbname.collname'. Since there is a sharded collection
+ // 'config.system.sessions', there will be a corresponding persisted chunk metadata
+ // collection 'config.cache.chunks.config.system.sessions'. We wish to allow writes to this
+ // collection.
if (coll.find(".system.sessions") != string::npos) {
return Status::OK();
}