diff options
author | Tess Avitabile <tess.avitabile@mongodb.com> | 2018-02-06 15:51:41 -0500 |
---|---|---|
committer | Tess Avitabile <tess.avitabile@mongodb.com> | 2018-02-08 14:51:05 -0500 |
commit | d337da259248c785f4014b565742300eb08ecd4f (patch) | |
tree | c34b437747a75f2454f2d4ad2d8a7b4b3ef6cf27 /src/mongo | |
parent | 2e287a4bc99f3c774a5322eae477f626638c6a81 (diff) | |
download | mongo-d337da259248c785f4014b565742300eb08ecd4f.tar.gz |
SERVER-32894 Disallow creation of system.indexes
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/db/commands/clone_collection.cpp | 21 | ||||
-rw-r--r-- | src/mongo/db/commands/create_indexes.cpp | 5 | ||||
-rw-r--r-- | src/mongo/db/ops/insert.cpp | 13 |
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(); } |