diff options
author | Spencer Jackson <spencer.jackson@mongodb.com> | 2018-04-09 21:13:08 -0400 |
---|---|---|
committer | Spencer Jackson <spencer.jackson@mongodb.com> | 2018-04-13 11:11:32 -0400 |
commit | 0f0caff9af9abc11004853477a34072b5aa8a017 (patch) | |
tree | e99d4ff84dea4463cbee8f9d8bef05256689495e /src/mongo | |
parent | 4f0c2f4047bdafe7a5d952a9671bf436a763c4d5 (diff) | |
download | mongo-0f0caff9af9abc11004853477a34072b5aa8a017.tar.gz |
SERVER-34401: Add support for {forAllDBs: true} to usersInfo
Diffstat (limited to 'src/mongo')
5 files changed, 26 insertions, 7 deletions
diff --git a/src/mongo/db/auth/role_graph_builtin_roles.cpp b/src/mongo/db/auth/role_graph_builtin_roles.cpp index 551b42118c4..79be5b05108 100644 --- a/src/mongo/db/auth/role_graph_builtin_roles.cpp +++ b/src/mongo/db/auth/role_graph_builtin_roles.cpp @@ -364,6 +364,8 @@ void addUserAdminAnyDbPrivileges(PrivilegeVector* privileges) { Privilege::addPrivilegeToPrivilegeVector( privileges, Privilege(ResourcePattern::forClusterResource(), ActionType::invalidateUserCache)); + Privilege::addPrivilegeToPrivilegeVector( + privileges, Privilege(ResourcePattern::forClusterResource(), ActionType::viewUser)); ActionSet readRoleAndIndexActions; diff --git a/src/mongo/db/auth/user_management_commands_parser.cpp b/src/mongo/db/auth/user_management_commands_parser.cpp index 3785dea3cf8..f6017699738 100644 --- a/src/mongo/db/auth/user_management_commands_parser.cpp +++ b/src/mongo/db/auth/user_management_commands_parser.cpp @@ -342,8 +342,12 @@ Status parseUsersInfoCommand(const BSONObj& cmdObj, StringData dbname, UsersInfo } if (cmdObj["usersInfo"].numberInt() == 1) { - parsedArgs->allForDB = true; + parsedArgs->target = UsersInfoArgs::Target::kDB; + } else if (cmdObj["usersInfo"].type() == Object && + cmdObj["usersInfo"].Obj().getBoolField("forAllDBs")) { + parsedArgs->target = UsersInfoArgs::Target::kGlobal; } else if (cmdObj["usersInfo"].type() == Array) { + parsedArgs->target = UsersInfoArgs::Target::kExplicitUsers; status = parseUserNamesFromBSONArray( BSONArray(cmdObj["usersInfo"].Obj()), dbname, &parsedArgs->userNames); if (!status.isOK()) { @@ -351,6 +355,7 @@ Status parseUsersInfoCommand(const BSONObj& cmdObj, StringData dbname, UsersInfo } std::sort(parsedArgs->userNames.begin(), parsedArgs->userNames.end()); } else { + parsedArgs->target = UsersInfoArgs::Target::kExplicitUsers; UserName name; status = _parseNameFromBSONElement(cmdObj["usersInfo"], dbname, diff --git a/src/mongo/db/auth/user_management_commands_parser.h b/src/mongo/db/auth/user_management_commands_parser.h index 535c7257f9b..d58b13b7039 100644 --- a/src/mongo/db/auth/user_management_commands_parser.h +++ b/src/mongo/db/auth/user_management_commands_parser.h @@ -103,8 +103,10 @@ Status parseAndValidateDropAllUsersFromDatabaseCommand(const BSONObj& cmdObj, const std::string& dbname); struct UsersInfoArgs { + enum class Target { kExplicitUsers, kDB, kGlobal }; + std::vector<UserName> userNames; - bool allForDB = false; + Target target; bool showPrivileges = false; AuthenticationRestrictionsFormat authenticationRestrictionsFormat = AuthenticationRestrictionsFormat::kOmit; diff --git a/src/mongo/db/commands/user_management_commands.cpp b/src/mongo/db/commands/user_management_commands.cpp index ffa163b3ec3..aa126b229da 100644 --- a/src/mongo/db/commands/user_management_commands.cpp +++ b/src/mongo/db/commands/user_management_commands.cpp @@ -1359,7 +1359,7 @@ public: return CommandHelpers::appendCommandStatus(result, status); } - if ((args.allForDB || args.filter) && + if ((args.target != auth::UsersInfoArgs::Target::kExplicitUsers || args.filter) && (args.showPrivileges || args.authenticationRestrictionsFormat == AuthenticationRestrictionsFormat::kShow)) { return CommandHelpers::appendCommandStatus( @@ -1370,8 +1370,9 @@ public: } BSONArrayBuilder usersArrayBuilder; - if (args.showPrivileges || - args.authenticationRestrictionsFormat == AuthenticationRestrictionsFormat::kShow) { + if (args.target == auth::UsersInfoArgs::Target::kExplicitUsers && + (args.showPrivileges || + args.authenticationRestrictionsFormat == AuthenticationRestrictionsFormat::kShow)) { // If you want privileges or restrictions you need to call getUserDescription on each // user. for (size_t i = 0; i < args.userNames.size(); ++i) { @@ -1416,7 +1417,9 @@ public: // If you don't need privileges, or authenticationRestrictions, you can just do a // regular query on system.users std::vector<BSONObj> pipeline; - if (args.allForDB) { + if (args.target == auth::UsersInfoArgs::Target::kGlobal) { + // Leave the pipeline unconstrained, we want to return every user. + } else if (args.target == auth::UsersInfoArgs::Target::kDB) { pipeline.push_back( BSON("$match" << BSON(AuthorizationManager::USER_DB_FIELD_NAME << dbname))); } else { diff --git a/src/mongo/db/commands/user_management_commands_common.cpp b/src/mongo/db/commands/user_management_commands_common.cpp index 97c739479fe..106bfe8c860 100644 --- a/src/mongo/db/commands/user_management_commands_common.cpp +++ b/src/mongo/db/commands/user_management_commands_common.cpp @@ -419,13 +419,20 @@ Status checkAuthForUsersInfoCommand(Client* client, return status; } - if (args.allForDB) { + if (args.target == auth::UsersInfoArgs::Target::kDB) { if (!authzSession->isAuthorizedForActionsOnResource( ResourcePattern::forDatabaseName(dbname), ActionType::viewUser)) { return Status(ErrorCodes::Unauthorized, str::stream() << "Not authorized to view users from the " << dbname << " database"); } + } else if (args.target == auth::UsersInfoArgs::Target::kGlobal) { + if (!authzSession->isAuthorizedForActionsOnResource(ResourcePattern::forClusterResource(), + ActionType::viewUser)) { + return Status(ErrorCodes::Unauthorized, + str::stream() << "Not authorized to view users from all" + << " databases"); + } } else { for (size_t i = 0; i < args.userNames.size(); ++i) { if (authzSession->lookupUser(args.userNames[i])) { |