summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-06-02 15:04:38 +0300
committerKaloian Manassiev <kaloian.manassiev@mongodb.com>2016-06-03 17:46:21 +0300
commitaf2f8a7df6b0658d4ff89dea84628886c958c640 (patch)
treebb665e48b56e42c2b6b1d9517196a89118a63a55
parentdd61c323913de91fd8d65a57324b9aa5079ff931 (diff)
downloadmongo-af2f8a7df6b0658d4ff89dea84628886c958c640.tar.gz
SERVER-23889 Make ClusterPlanCache* commands correctly validate the namespace
-rw-r--r--src/mongo/db/commands.cpp30
-rw-r--r--src/mongo/db/commands.h6
-rw-r--r--src/mongo/s/commands/cluster_plan_cache_cmd.cpp10
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