summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorA. Jesse Jiryu Davis <jesse@mongodb.com>2020-08-11 11:17:08 -0400
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2020-08-13 19:32:49 +0000
commitf4ed96b5a788003322a2dc36b46063475a0b36ca (patch)
tree78bcdd4a6ba79586131222de0c228dfb4fc6e9b3 /src
parent53b690294d160a6e1cd0f4a004cb55c4835a48b8 (diff)
downloadmongo-f4ed96b5a788003322a2dc36b46063475a0b36ca.tar.gz
SERVER-49858 Don't forward API params from drop/dropDatabase to config servers
There are two mongos commands in API Version 1 that forward their parameters to internal commands: "drop" forwards to "_configsvrDropCollection" and "dropDatabase" forwards to "_configsvrDropDatabase". Users should be permitted to call the mongos commands with apiVersion: "1", apiStrict: true, but the internal commands aren't in Version 1 and they'll reject these parameters. So, strip the API version parameters when forwarding.
Diffstat (limited to 'src')
-rw-r--r--src/mongo/db/command_generic_argument.cpp78
-rw-r--r--src/mongo/db/command_generic_argument.h5
-rw-r--r--src/mongo/db/commands.cpp37
-rw-r--r--src/mongo/db/commands.h6
-rw-r--r--src/mongo/db/s/config/configsvr_drop_collection_command.cpp4
-rw-r--r--src/mongo/db/s/config/configsvr_drop_database_command.cpp4
-rw-r--r--src/mongo/s/commands/cluster_drop_cmd.cpp2
-rw-r--r--src/mongo/s/commands/cluster_drop_database_cmd.cpp4
8 files changed, 88 insertions, 52 deletions
diff --git a/src/mongo/db/command_generic_argument.cpp b/src/mongo/db/command_generic_argument.cpp
index 86e6f6c0196..4f4c9f34816 100644
--- a/src/mongo/db/command_generic_argument.cpp
+++ b/src/mongo/db/command_generic_argument.cpp
@@ -44,6 +44,7 @@ namespace {
struct SpecialArgRecord {
StringData name;
bool isGeneric;
+ bool isApiParameter;
bool stripFromRequest;
bool stripFromReply;
};
@@ -54,42 +55,43 @@ struct SpecialArgRecord {
// clang-format off
static constexpr std::array<SpecialArgRecord, 34> specials{{
// /-isGeneric
- // | /-stripFromRequest
- // | | /-stripFromReply
- {"apiVersion"_sd, 1, 0, 0},
- {"apiStrict"_sd, 1, 0, 0},
- {"apiDeprecationErrors"_sd, 1, 0, 0},
- {"$audit"_sd, 1, 1, 0},
- {"$client"_sd, 1, 1, 0},
- {"$configServerState"_sd, 1, 1, 1},
- {"$db"_sd, 1, 1, 0},
- {"allowImplicitCollectionCreation"_sd, 1, 1, 0},
- {"$oplogQueryData"_sd, 1, 1, 1},
- {"$queryOptions"_sd, 1, 0, 0},
- {"$readPreference"_sd, 1, 1, 0},
- {"$replData"_sd, 1, 1, 1},
- {"$clusterTime"_sd, 1, 1, 1},
- {"maxTimeMS"_sd, 1, 0, 0},
- {"readConcern"_sd, 1, 0, 0},
- {"databaseVersion"_sd, 1, 1, 0},
- {"shardVersion"_sd, 1, 1, 0},
- {"tracking_info"_sd, 1, 1, 0},
- {"writeConcern"_sd, 1, 0, 0},
- {"lsid"_sd, 1, 0, 0},
- {"clientOperationKey"_sd, 1, 0, 0},
- {"txnNumber"_sd, 1, 0, 0},
- {"autocommit"_sd, 1, 0, 0},
- {"coordinator"_sd, 1, 0, 0},
- {"startTransaction"_sd, 1, 0, 0},
- {"stmtId"_sd, 1, 0, 0},
- {"$gleStats"_sd, 0, 0, 1},
- {"operationTime"_sd, 0, 0, 1},
- {"lastCommittedOpTime"_sd, 0, 0, 1},
- {"readOnly"_sd, 0, 0, 1},
- {"comment"_sd, 1, 0, 0},
- {"maxTimeMSOpOnly"_sd, 1, 0, 0},
- {"$configTime"_sd, 1, 1, 1},
- {"$topologyTime"_sd, 1, 1, 1}}};
+ // | /-isApiParameter
+ // | | /-stripFromRequest
+ // | | | /-stripFromReply
+ {"apiVersion"_sd, 1, 1, 0, 0},
+ {"apiStrict"_sd, 1, 1, 0, 0},
+ {"apiDeprecationErrors"_sd, 1, 1, 0, 0},
+ {"$audit"_sd, 1, 0, 1, 0},
+ {"$client"_sd, 1, 0, 1, 0},
+ {"$configServerState"_sd, 1, 0, 1, 1},
+ {"$db"_sd, 1, 0, 1, 0},
+ {"allowImplicitCollectionCreation"_sd, 1, 0, 1, 0},
+ {"$oplogQueryData"_sd, 1, 0, 1, 1},
+ {"$queryOptions"_sd, 1, 0, 0, 0},
+ {"$readPreference"_sd, 1, 0, 1, 0},
+ {"$replData"_sd, 1, 0, 1, 1},
+ {"$clusterTime"_sd, 1, 0, 1, 1},
+ {"maxTimeMS"_sd, 1, 0, 0, 0},
+ {"readConcern"_sd, 1, 0, 0, 0},
+ {"databaseVersion"_sd, 1, 0, 1, 0},
+ {"shardVersion"_sd, 1, 0, 1, 0},
+ {"tracking_info"_sd, 1, 0, 1, 0},
+ {"writeConcern"_sd, 1, 0, 0, 0},
+ {"lsid"_sd, 1, 0, 0, 0},
+ {"clientOperationKey"_sd, 1, 0, 0, 0},
+ {"txnNumber"_sd, 1, 0, 0, 0},
+ {"autocommit"_sd, 1, 0, 0, 0},
+ {"coordinator"_sd, 1, 0, 0, 0},
+ {"startTransaction"_sd, 1, 0, 0, 0},
+ {"stmtId"_sd, 1, 0, 0, 0},
+ {"$gleStats"_sd, 0, 0, 0, 1},
+ {"operationTime"_sd, 0, 0, 0, 1},
+ {"lastCommittedOpTime"_sd, 0, 0, 0, 1},
+ {"readOnly"_sd, 0, 0, 0, 1},
+ {"comment"_sd, 1, 0, 0, 0},
+ {"maxTimeMSOpOnly"_sd, 1, 0, 0, 0},
+ {"$configTime"_sd, 1, 0, 1, 1},
+ {"$topologyTime"_sd, 1, 0, 1, 1}}};
// clang-format on
template <bool SpecialArgRecord::*pmo>
@@ -112,6 +114,10 @@ bool isGenericArgument(StringData arg) {
return filteredSpecialsContains<&SpecialArgRecord::isGeneric>(arg);
}
+bool isApiParameter(StringData arg) {
+ return filteredSpecialsContains<&SpecialArgRecord::isApiParameter>(arg);
+}
+
bool isRequestStripArgument(StringData arg) {
return filteredSpecialsContains<&SpecialArgRecord::stripFromRequest>(arg);
}
diff --git a/src/mongo/db/command_generic_argument.h b/src/mongo/db/command_generic_argument.h
index 69d695250ec..7f66a101137 100644
--- a/src/mongo/db/command_generic_argument.h
+++ b/src/mongo/db/command_generic_argument.h
@@ -41,6 +41,11 @@ namespace mongo {
bool isGenericArgument(StringData arg);
/**
+ * Returns true if the provided argument is related to the MongoDB Versioned API.
+ */
+bool isApiParameter(StringData arg);
+
+/**
* Returns true if arg must be stripped from requests that are forwarded to shards.
* Only generic arguments are stripped, and some of them are not.
* See 'CommandHelpers::filterCommandRequestForPassthrough'.
diff --git a/src/mongo/db/commands.cpp b/src/mongo/db/commands.cpp
index 579603598e7..7fcbd220b6d 100644
--- a/src/mongo/db/commands.cpp
+++ b/src/mongo/db/commands.cpp
@@ -358,18 +358,45 @@ void CommandHelpers::appendCommandWCStatus(BSONObjBuilder& result,
}
}
-BSONObj CommandHelpers::appendPassthroughFields(const BSONObj& cmdObjWithPassthroughFields,
- const BSONObj& request) {
+namespace {
+
+enum class FilterApiParameters { kPreserveApiParameters, kRemoveApiParameters };
+
+BSONObj _appendPassthroughFields(const BSONObj& cmdObjWithPassthroughFields,
+ const BSONObj& request,
+ FilterApiParameters filterApiParameters) {
BSONObjBuilder b;
b.appendElements(request);
- for (const auto& elem : filterCommandRequestForPassthrough(cmdObjWithPassthroughFields)) {
+ for (const auto& elem :
+ CommandHelpers::filterCommandRequestForPassthrough(cmdObjWithPassthroughFields)) {
const auto name = elem.fieldNameStringData();
- if (isGenericArgument(name) && !request.hasField(name)) {
- b.append(elem);
+ if (request.hasField(name)) {
+ continue;
+ }
+ if (filterApiParameters == FilterApiParameters::kRemoveApiParameters &&
+ isApiParameter(name)) {
+ continue;
}
+ if (!isGenericArgument(name)) {
+ continue;
+ }
+ b.append(elem);
}
return b.obj();
}
+} // namespace
+
+BSONObj CommandHelpers::appendPassthroughFields(const BSONObj& cmdObjWithPassthroughFields,
+ const BSONObj& request) {
+ return _appendPassthroughFields(
+ cmdObjWithPassthroughFields, request, FilterApiParameters::kPreserveApiParameters);
+}
+
+BSONObj CommandHelpers::appendInternalPassthroughFields(const BSONObj& cmdObjWithPassthroughFields,
+ const BSONObj& request) {
+ return _appendPassthroughFields(
+ cmdObjWithPassthroughFields, request, FilterApiParameters::kRemoveApiParameters);
+}
BSONObj CommandHelpers::appendMajorityWriteConcern(const BSONObj& cmdObj,
WriteConcernOptions defaultWC) {
diff --git a/src/mongo/db/commands.h b/src/mongo/db/commands.h
index 590be041081..91e3c4b80f0 100644
--- a/src/mongo/db/commands.h
+++ b/src/mongo/db/commands.h
@@ -178,6 +178,12 @@ struct CommandHelpers {
const BSONObj& request);
/**
+ * Appends passthrough fields from a cmdObj to a given *internal* command request.
+ */
+ static BSONObj appendInternalPassthroughFields(const BSONObj& cmdObjWithPassthroughFields,
+ const BSONObj& request);
+
+ /**
* Returns a copy of 'cmdObj' with a majority writeConcern appended. If the command object does
* not contain a writeConcern, 'defaultWC' will be used instead, if supplied.
*/
diff --git a/src/mongo/db/s/config/configsvr_drop_collection_command.cpp b/src/mongo/db/s/config/configsvr_drop_collection_command.cpp
index fc74fafc0c5..77cf249fd41 100644
--- a/src/mongo/db/s/config/configsvr_drop_collection_command.cpp
+++ b/src/mongo/db/s/config/configsvr_drop_collection_command.cpp
@@ -59,10 +59,6 @@ class ConfigSvrDropCollectionCommand : public BasicCommand {
public:
ConfigSvrDropCollectionCommand() : BasicCommand("_configsvrDropCollection") {}
- const std::set<std::string>& apiVersions() const {
- return kApiVersions1;
- }
-
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kNever;
}
diff --git a/src/mongo/db/s/config/configsvr_drop_database_command.cpp b/src/mongo/db/s/config/configsvr_drop_database_command.cpp
index eb3ef547e70..56aa8db1d94 100644
--- a/src/mongo/db/s/config/configsvr_drop_database_command.cpp
+++ b/src/mongo/db/s/config/configsvr_drop_database_command.cpp
@@ -54,10 +54,6 @@ class ConfigSvrDropDatabaseCommand : public BasicCommand {
public:
ConfigSvrDropDatabaseCommand() : BasicCommand("_configsvrDropDatabase") {}
- const std::set<std::string>& apiVersions() const {
- return kApiVersions1;
- }
-
AllowedOnSecondary secondaryAllowed(ServiceContext*) const override {
return AllowedOnSecondary::kNever;
}
diff --git a/src/mongo/s/commands/cluster_drop_cmd.cpp b/src/mongo/s/commands/cluster_drop_cmd.cpp
index a69e3292597..608c5504ecd 100644
--- a/src/mongo/s/commands/cluster_drop_cmd.cpp
+++ b/src/mongo/s/commands/cluster_drop_cmd.cpp
@@ -96,7 +96,7 @@ public:
ReadPreferenceSetting(ReadPreference::PrimaryOnly),
"admin",
CommandHelpers::appendMajorityWriteConcern(
- CommandHelpers::appendPassthroughFields(
+ CommandHelpers::appendInternalPassthroughFields(
cmdObj, BSON("_configsvrDropCollection" << nss.toString())),
opCtx->getWriteConcern()),
Shard::RetryPolicy::kIdempotent));
diff --git a/src/mongo/s/commands/cluster_drop_database_cmd.cpp b/src/mongo/s/commands/cluster_drop_database_cmd.cpp
index a78cb00fd79..dc04c7f21c3 100644
--- a/src/mongo/s/commands/cluster_drop_database_cmd.cpp
+++ b/src/mongo/s/commands/cluster_drop_database_cmd.cpp
@@ -97,8 +97,8 @@ public:
ReadPreferenceSetting(ReadPreference::PrimaryOnly),
"admin",
CommandHelpers::appendMajorityWriteConcern(
- CommandHelpers::appendPassthroughFields(cmdObj,
- BSON("_configsvrDropDatabase" << dbname)),
+ CommandHelpers::appendInternalPassthroughFields(
+ cmdObj, BSON("_configsvrDropDatabase" << dbname)),
opCtx->getWriteConcern()),
Shard::RetryPolicy::kIdempotent));