diff options
author | A. Jesse Jiryu Davis <jesse@mongodb.com> | 2020-08-11 11:17:08 -0400 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-08-13 19:32:49 +0000 |
commit | f4ed96b5a788003322a2dc36b46063475a0b36ca (patch) | |
tree | 78bcdd4a6ba79586131222de0c228dfb4fc6e9b3 /src | |
parent | 53b690294d160a6e1cd0f4a004cb55c4835a48b8 (diff) | |
download | mongo-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.cpp | 78 | ||||
-rw-r--r-- | src/mongo/db/command_generic_argument.h | 5 | ||||
-rw-r--r-- | src/mongo/db/commands.cpp | 37 | ||||
-rw-r--r-- | src/mongo/db/commands.h | 6 | ||||
-rw-r--r-- | src/mongo/db/s/config/configsvr_drop_collection_command.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/s/config/configsvr_drop_database_command.cpp | 4 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_drop_cmd.cpp | 2 | ||||
-rw-r--r-- | src/mongo/s/commands/cluster_drop_database_cmd.cpp | 4 |
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)); |