diff options
author | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2016-06-02 15:04:38 +0300 |
---|---|---|
committer | Kaloian Manassiev <kaloian.manassiev@mongodb.com> | 2016-06-03 17:46:21 +0300 |
commit | af2f8a7df6b0658d4ff89dea84628886c958c640 (patch) | |
tree | bb665e48b56e42c2b6b1d9517196a89118a63a55 | |
parent | dd61c323913de91fd8d65a57324b9aa5079ff931 (diff) | |
download | mongo-af2f8a7df6b0658d4ff89dea84628886c958c640.tar.gz |
SERVER-23889 Make ClusterPlanCache* commands correctly validate the namespace
-rw-r--r-- | src/mongo/db/commands.cpp | 30 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 6 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_plan_cache_cmd.cpp | 10 |
3 files changed, 25 insertions, 21 deletions
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp index abfd3c221f5..a0efb121a0f 100644 --- a/src/mongo/db/commands.cpp +++ b/src/mongo/db/commands.cpp @@ -75,31 +75,33 @@ ExportedServerParameter<bool, ServerParameterType::kStartupOnly> testCommandsPar Command::~Command() = default; -string Command::parseNsFullyQualified(const string& dbname, const BSONObj& cmdObj) const { +string Command::parseNsFullyQualified(const string& dbname, const BSONObj& cmdObj) { BSONElement first = cmdObj.firstElement(); - uassert(17005, - mongoutils::str::stream() << "Main argument to " << first.fieldNameStringData() - << " must be a fully qualified namespace string. Found: " - << first.toString(false), - first.type() == mongo::String && - NamespaceString::validCollectionComponent(first.valuestr())); - return first.String(); + uassert(ErrorCodes::BadValue, + str::stream() << "collection name has invalid type " << typeName(first.type()), + first.canonicalType() == canonicalizeBSONType(mongo::String)); + const NamespaceString nss(first.valueStringData()); + uassert(ErrorCodes::InvalidNamespace, + str::stream() << "Invalid namespace specified '" << nss.ns() << "'", + nss.isValid()); + return nss.ns(); } -NamespaceString Command::parseNsCollectionRequired(const string& dbname, - const BSONObj& cmdObj) const { +NamespaceString Command::parseNsCollectionRequired(const string& dbname, const BSONObj& cmdObj) { // Accepts both BSON String and Symbol for collection name per SERVER-16260 // TODO(kangas) remove Symbol support in MongoDB 3.0 after Ruby driver audit BSONElement first = cmdObj.firstElement(); - uassert(40072, + uassert(ErrorCodes::BadValue, str::stream() << "collection name has invalid type " << typeName(first.type()), first.canonicalType() == canonicalizeBSONType(mongo::String)); - NamespaceString nss(dbname, first.valuestr()); - uassert(ErrorCodes::InvalidNamespace, "Not a valid namespace", nss.isValid()); + const NamespaceString nss(dbname, first.valueStringData()); + uassert(ErrorCodes::InvalidNamespace, + str::stream() << "Invalid namespace specified '" << nss.ns() << "'", + nss.isValid()); return nss; } -/*virtual*/ string Command::parseNs(const string& dbname, const BSONObj& cmdObj) const { +string Command::parseNs(const string& dbname, const BSONObj& cmdObj) const { BSONElement first = cmdObj.firstElement(); if (first.type() != mongo::String) return dbname; diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h index d543f8a6dbd..874f728ae21 100644 --- a/src/mongo/db/commands.h +++ b/src/mongo/db/commands.h @@ -68,12 +68,12 @@ class Command { protected: // The type of the first field in 'cmdObj' must be mongo::String. The first field is // interpreted as a collection name. - std::string parseNsFullyQualified(const std::string& dbname, const BSONObj& cmdObj) const; + static std::string parseNsFullyQualified(const std::string& dbname, const BSONObj& cmdObj); // The type of the first field in 'cmdObj' must be mongo::String or Symbol. // The first field is interpreted as a collection name. - NamespaceString parseNsCollectionRequired(const std::string& dbname, - const BSONObj& cmdObj) const; + static NamespaceString parseNsCollectionRequired(const std::string& dbname, + const BSONObj& cmdObj); public: typedef StringMap<Command*> CommandMap; diff --git a/src/mongo/s/commands/cluster_plan_cache_cmd.cpp b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp index 32d87ac39bf..9da09c470a0 100644 --- a/src/mongo/s/commands/cluster_plan_cache_cmd.cpp +++ b/src/mongo/s/commands/cluster_plan_cache_cmd.cpp @@ -61,8 +61,7 @@ public: return true; } - - virtual bool supportsWriteConcern(const BSONObj& cmd) const override { + bool supportsWriteConcern(const BSONObj& cmd) const override { return false; } @@ -70,6 +69,10 @@ public: ss << _helpText; } + std::string parseNs(const std::string& dbname, const BSONObj& cmdObj) const override { + return parseNsCollectionRequired(dbname, cmdObj).ns(); + } + Status checkAuthForCommand(ClientBasic* client, const std::string& dbname, const BSONObj& cmdObj) { @@ -114,8 +117,7 @@ bool ClusterPlanCacheCmd::run(OperationContext* txn, int options, std::string& errMsg, BSONObjBuilder& result) { - const std::string fullns = parseNs(dbName, cmdObj); - NamespaceString nss(fullns); + const NamespaceString nss(parseNsCollectionRequired(dbName, cmdObj)); // Dispatch command to all the shards. // Targeted shard commands are generally data-dependent but plan cache |