summaryrefslogtreecommitdiff
path: root/src/mongo/db/commands/list_databases.cpp
diff options
context:
space:
mode:
authorSara Golemon <sara.golemon@mongodb.com>2017-12-04 13:52:18 -0500
committerSara Golemon <sara.golemon@mongodb.com>2017-12-05 19:07:59 -0500
commita34fa65325dafc01857a4525d0d8b2f26b485965 (patch)
tree33b77aab43c0ae285ac97468e1c715dc721bfc7a /src/mongo/db/commands/list_databases.cpp
parent3d7be48d3b09db2c7ac723043b10c014430e85ed (diff)
downloadmongo-a34fa65325dafc01857a4525d0d8b2f26b485965.tar.gz
SERVER-6898 Enable listDatabases for all users
Diffstat (limited to 'src/mongo/db/commands/list_databases.cpp')
-rw-r--r--src/mongo/db/commands/list_databases.cpp48
1 files changed, 33 insertions, 15 deletions
diff --git a/src/mongo/db/commands/list_databases.cpp b/src/mongo/db/commands/list_databases.cpp
index fb719e1bda6..15d1139df8b 100644
--- a/src/mongo/db/commands/list_databases.cpp
+++ b/src/mongo/db/commands/list_databases.cpp
@@ -28,6 +28,7 @@
* it in the license file.
*/
+#include "mongo/db/auth/authorization_session.h"
#include "mongo/db/catalog/database.h"
#include "mongo/db/catalog/database_catalog_entry.h"
#include "mongo/db/catalog/database_holder.h"
@@ -56,28 +57,32 @@ intmax_t dbSize(const string& database);
class CmdListDatabases : public BasicCommand {
public:
- virtual bool slaveOk() const {
+ bool slaveOk() const final {
return false;
}
- virtual bool slaveOverrideOk() const {
+ bool slaveOverrideOk() const final {
return true;
}
- virtual bool adminOnly() const {
+ bool adminOnly() const final {
return true;
}
- virtual bool supportsWriteConcern(const BSONObj& cmd) const override {
+ bool supportsWriteConcern(const BSONObj& cmd) const final {
return false;
}
- virtual void help(stringstream& help) const {
+ void help(stringstream& help) const final {
help << "{ listDatabases:1, [filter: <filterObject>] [, nameOnly: true ] }\n"
"list databases on this server";
}
- virtual void addRequiredPrivileges(const std::string& dbname,
- const BSONObj& cmdObj,
- std::vector<Privilege>* out) {
- ActionSet actions;
- actions.addAction(ActionType::listDatabases);
- out->push_back(Privilege(ResourcePattern::forClusterResource(), actions));
+
+ /* listDatabases is always authorized,
+ * however the results returned will be redacted
+ * based on read privileges if auth is enabled
+ * and the current user does not have listDatabases permisison.
+ */
+ Status checkAuthForCommand(Client* client,
+ const std::string& dbname,
+ const BSONObj& cmdObj) final {
+ return Status::OK();
}
CmdListDatabases() : BasicCommand("listDatabases") {}
@@ -85,7 +90,7 @@ public:
bool run(OperationContext* opCtx,
const string& dbname,
const BSONObj& jsobj,
- BSONObjBuilder& result) {
+ BSONObjBuilder& result) final {
// Parse the filter.
std::unique_ptr<MatchExpression> filter;
if (auto filterElt = jsobj[kFilterField]) {
@@ -118,12 +123,25 @@ public:
vector<BSONObj> dbInfos;
- bool filterNameOnly = filter &&
+ // If we have ActionType::listDatabases,
+ // then we don't need to test each record in the output.
+ // Otherwise, we'll test the database names as we enumerate them.
+ const auto as = AuthorizationSession::get(opCtx->getClient());
+ const bool checkAuth = as &&
+ !as->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(),
+ ActionType::listDatabases);
+
+ const bool filterNameOnly = filter &&
filter->getCategory() == MatchExpression::MatchCategory::kLeaf &&
filter->path() == kNameField;
intmax_t totalSize = 0;
- for (vector<string>::iterator i = dbNames.begin(); i != dbNames.end(); ++i) {
- const string& dbname = *i;
+ for (const auto& dbname : dbNames) {
+ if (checkAuth && as &&
+ !as->isAuthorizedForActionsOnResource(ResourcePattern::forDatabaseName(dbname),
+ ActionType::find)) {
+ // We don't have listDatabases on the cluser or find on this database.
+ continue;
+ }
BSONObjBuilder b;
b.append("name", dbname);