SERVER-6246 SERVER-9515 Update usersInfo and rolesInfo commands to new API
This commit is contained in:
@@ -186,7 +186,7 @@ var testOps = function(db, allowedActions) {
|
||||
}, db);
|
||||
|
||||
checkErr(allowedActions.hasOwnProperty('user_r'), function() {
|
||||
var result = db.runCommand({usersInfo: /.*/});
|
||||
var result = db.runCommand({usersInfo: 1});
|
||||
if (!result.ok) {
|
||||
throw new Error(tojson(result));
|
||||
}
|
||||
|
||||
@@ -225,8 +225,9 @@ namespace mongo {
|
||||
Status AuthorizationManager::queryAuthzDocument(
|
||||
const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor) {
|
||||
return _externalState->query(collectionName, query, resultProcessor);
|
||||
return _externalState->query(collectionName, query, projection, resultProcessor);
|
||||
}
|
||||
|
||||
Status AuthorizationManager::updateAuthzDocuments(const NamespaceString& collectionName,
|
||||
|
||||
@@ -217,6 +217,7 @@ namespace mongo {
|
||||
*/
|
||||
Status queryAuthzDocument(const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor);
|
||||
|
||||
// Checks to see if "doc" is a valid privilege document, assuming it is stored in the
|
||||
|
||||
@@ -156,6 +156,7 @@ namespace mongo {
|
||||
*/
|
||||
virtual Status query(const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor) = 0;
|
||||
|
||||
/**
|
||||
|
||||
@@ -237,11 +237,12 @@ namespace {
|
||||
Status AuthzManagerExternalStateMongod::query(
|
||||
const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor) {
|
||||
try {
|
||||
DBDirectClient client;
|
||||
Client::GodScope gs;
|
||||
client.query(resultProcessor, collectionName.ns(), query);
|
||||
client.query(resultProcessor, collectionName.ns(), query, &projection);
|
||||
return Status::OK();
|
||||
} catch (const DBException& e) {
|
||||
return e.toStatus();
|
||||
@@ -452,6 +453,7 @@ namespace {
|
||||
Status status = query(
|
||||
AuthorizationManager::rolesCollectionNamespace,
|
||||
BSONObj(),
|
||||
BSONObj(),
|
||||
boost::bind(addRoleFromDocumentOrWarn, &newRoleGraph, _1));
|
||||
if (!status.isOK())
|
||||
return status;
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace mongo {
|
||||
BSONObj* result);
|
||||
virtual Status query(const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor);
|
||||
virtual Status insert(const NamespaceString& collectionName,
|
||||
const BSONObj& document,
|
||||
|
||||
@@ -213,6 +213,7 @@ namespace {
|
||||
Status AuthzManagerExternalStateMock::query(
|
||||
const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj&,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor) {
|
||||
std::vector<BSONObjCollection::iterator> iterVector;
|
||||
Status status = _queryVector(collectionName, query, &iterVector);
|
||||
|
||||
@@ -87,6 +87,7 @@ namespace mongo {
|
||||
|
||||
virtual Status query(const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection, // Currently unused in mock
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor);
|
||||
|
||||
// This implementation does not understand uniqueness constraints.
|
||||
|
||||
@@ -79,8 +79,14 @@ namespace {
|
||||
AuthorizationManager::usersCollectionNamespace));
|
||||
BSONObj cmdResult;
|
||||
conn->get()->runCommand(
|
||||
userName.getDB().toString(), // TODO: Change usersInfo so this command can always go to "admin".
|
||||
BSON("usersInfo" << userName.getUser() << "details" << true),
|
||||
"admin",
|
||||
BSON("usersInfo" <<
|
||||
BSON_ARRAY(BSON(AuthorizationManager::USER_NAME_FIELD_NAME <<
|
||||
userName.getUser() <<
|
||||
AuthorizationManager::USER_SOURCE_FIELD_NAME <<
|
||||
userName.getDB())) <<
|
||||
"showPrivileges" << true <<
|
||||
"showCredentials" << true),
|
||||
cmdResult);
|
||||
if (!cmdResult["ok"].trueValue()) {
|
||||
int code = cmdResult["code"].numberInt();
|
||||
@@ -102,8 +108,12 @@ namespace {
|
||||
AuthorizationManager::rolesCollectionNamespace));
|
||||
BSONObj cmdResult;
|
||||
conn->get()->runCommand(
|
||||
roleName.getDB().toString(), // TODO: Change rolesInfo so this command can always go to "admin".
|
||||
BSON("rolesInfo" << roleName.getRole()),
|
||||
"admin",
|
||||
BSON("rolesInfo" <<
|
||||
BSON_ARRAY(BSON(AuthorizationManager::ROLE_NAME_FIELD_NAME <<
|
||||
roleName.getRole() <<
|
||||
AuthorizationManager::ROLE_SOURCE_FIELD_NAME <<
|
||||
roleName.getDB()))),
|
||||
cmdResult);
|
||||
if (!cmdResult["ok"].trueValue()) {
|
||||
int code = cmdResult["code"].numberInt();
|
||||
@@ -138,10 +148,11 @@ namespace {
|
||||
Status AuthzManagerExternalStateMongos::query(
|
||||
const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor) {
|
||||
try {
|
||||
scoped_ptr<ScopedDbConnection> conn(getConnectionForAuthzCollection(collectionName));
|
||||
conn->get()->query(resultProcessor, collectionName.ns(), query);
|
||||
conn->get()->query(resultProcessor, collectionName.ns(), query, &projection);
|
||||
return Status::OK();
|
||||
} catch (const DBException& e) {
|
||||
return e.toStatus();
|
||||
|
||||
@@ -66,6 +66,7 @@ namespace mongo {
|
||||
BSONObj* result);
|
||||
virtual Status query(const NamespaceString& collectionName,
|
||||
const BSONObj& query,
|
||||
const BSONObj& projection,
|
||||
const boost::function<void(const BSONObj&)>& resultProcessor);
|
||||
virtual Status insert(const NamespaceString& collectionName,
|
||||
const BSONObj& document,
|
||||
|
||||
@@ -81,44 +81,82 @@ namespace auth {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status parseRoleNamesFromBSONArray(const BSONArray& rolesArray,
|
||||
const StringData& dbname,
|
||||
const StringData& rolesFieldName,
|
||||
std::vector<RoleName>* parsedRoleNames) {
|
||||
for (BSONObjIterator it(rolesArray); it.more(); it.next()) {
|
||||
BSONElement element = *it;
|
||||
if (element.type() == String) {
|
||||
parsedRoleNames->push_back(RoleName(element.String(), dbname));
|
||||
}
|
||||
else if (element.type() == Object) {
|
||||
BSONObj roleObj = element.Obj();
|
||||
// Extracts a UserName or RoleName object from a BSONElement.
|
||||
template <typename Name>
|
||||
Status _parseNameFromBSONElement(const BSONElement& element,
|
||||
const StringData& dbname,
|
||||
const StringData& nameFieldName,
|
||||
const StringData& sourceFieldName,
|
||||
Name* parsedName) {
|
||||
if (element.type() == String) {
|
||||
*parsedName = Name(element.String(), dbname);
|
||||
}
|
||||
else if (element.type() == Object) {
|
||||
BSONObj obj = element.Obj();
|
||||
|
||||
std::string roleNameString;
|
||||
std::string roleSource;
|
||||
Status status = bsonExtractStringField(roleObj,
|
||||
AuthorizationManager::ROLE_NAME_FIELD_NAME,
|
||||
&roleNameString);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
status = bsonExtractStringField(roleObj,
|
||||
AuthorizationManager::ROLE_SOURCE_FIELD_NAME,
|
||||
&roleSource);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
std::string name;
|
||||
std::string source;
|
||||
Status status = bsonExtractStringField(obj, nameFieldName, &name);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
status = bsonExtractStringField(obj, sourceFieldName, &source);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
parsedRoleNames->push_back(RoleName(roleNameString, roleSource));
|
||||
}
|
||||
else {
|
||||
return Status(ErrorCodes::BadValue,
|
||||
mongoutils::str::stream() << "Values in \"" << rolesFieldName <<
|
||||
"\" array must be sub-documents or strings");
|
||||
}
|
||||
*parsedName = Name(name, source);
|
||||
}
|
||||
else {
|
||||
return Status(ErrorCodes::BadValue,
|
||||
"User and role names must be either strings or objects");
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
// Extracts UserName or RoleName objects from a BSONArray of role/user names.
|
||||
template <typename Name>
|
||||
Status _parseNamesFromBSONArray(const BSONArray& array,
|
||||
const StringData& dbname,
|
||||
const StringData& nameFieldName,
|
||||
const StringData& sourceFieldName,
|
||||
std::vector<Name>* parsedNames) {
|
||||
for (BSONObjIterator it(array); it.more(); it.next()) {
|
||||
BSONElement element = *it;
|
||||
Name name;
|
||||
Status status = _parseNameFromBSONElement(element,
|
||||
dbname,
|
||||
nameFieldName,
|
||||
sourceFieldName,
|
||||
&name);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
parsedNames->push_back(name);
|
||||
}
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status _parseUserNamesFromBSONArray(const BSONArray& usersArray,
|
||||
const StringData& dbname,
|
||||
std::vector<UserName>* parsedUserNames) {
|
||||
return _parseNamesFromBSONArray(usersArray,
|
||||
dbname,
|
||||
AuthorizationManager::USER_NAME_FIELD_NAME,
|
||||
AuthorizationManager::USER_SOURCE_FIELD_NAME,
|
||||
parsedUserNames);
|
||||
}
|
||||
|
||||
Status parseRoleNamesFromBSONArray(const BSONArray& rolesArray,
|
||||
const StringData& dbname,
|
||||
std::vector<RoleName>* parsedRoleNames) {
|
||||
return _parseNamesFromBSONArray(rolesArray,
|
||||
dbname,
|
||||
AuthorizationManager::ROLE_NAME_FIELD_NAME,
|
||||
AuthorizationManager::ROLE_SOURCE_FIELD_NAME,
|
||||
parsedRoleNames);
|
||||
}
|
||||
|
||||
Status _extractRoleDataFromBSONArray(const BSONElement& rolesElement,
|
||||
const std::string& dbname,
|
||||
std::vector<User::RoleData> *parsedRoleData) {
|
||||
@@ -208,7 +246,6 @@ namespace auth {
|
||||
|
||||
status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()),
|
||||
dbname,
|
||||
rolesFieldName,
|
||||
parsedRoleNames);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
@@ -342,44 +379,89 @@ namespace auth {
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status parseAndValidateInfoCommands(const BSONObj& cmdObj,
|
||||
const StringData& cmdName,
|
||||
const std::string& dbname,
|
||||
bool* parsedAnyDB,
|
||||
BSONElement* parsedNameFilter) {
|
||||
Status parseUsersInfoCommand(const BSONObj& cmdObj,
|
||||
const StringData& dbname,
|
||||
UsersInfoArgs* parsedArgs) {
|
||||
unordered_set<std::string> validFieldNames;
|
||||
validFieldNames.insert(cmdName.toString());
|
||||
validFieldNames.insert("anyDB");
|
||||
validFieldNames.insert("writeConcern");
|
||||
validFieldNames.insert("details");
|
||||
validFieldNames.insert("usersInfo");
|
||||
validFieldNames.insert("showPrivileges");
|
||||
validFieldNames.insert("showCredentials");
|
||||
|
||||
Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
|
||||
Status status = _checkNoExtraFields(cmdObj, "usersInfo", validFieldNames);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (cmdObj[cmdName].type() != String && cmdObj[cmdName].type() != RegEx) {
|
||||
return Status(ErrorCodes::BadValue,
|
||||
mongoutils::str::stream() << "Argument to \"" << cmdName <<
|
||||
"\"command must be either a string or a regex");
|
||||
}
|
||||
*parsedNameFilter = cmdObj[cmdName];
|
||||
|
||||
|
||||
bool anyDB = false;
|
||||
if (cmdObj.hasField("anyDB")) {
|
||||
if (dbname == "admin") {
|
||||
Status status = bsonExtractBooleanField(cmdObj, "anyDB", &anyDB);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
return Status(ErrorCodes::BadValue,
|
||||
mongoutils::str::stream() << "\"anyDB\" argument to \"" << cmdName <<
|
||||
"\"command is only valid when run on the \"admin\" database");
|
||||
if (cmdObj["usersInfo"].numberInt() == 1) {
|
||||
parsedArgs->allForDB = true;
|
||||
} else if (cmdObj["usersInfo"].type() == Array) {
|
||||
status = _parseUserNamesFromBSONArray(BSONArray(cmdObj["usersInfo"].Obj()),
|
||||
dbname,
|
||||
&parsedArgs->userNames);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
UserName name;
|
||||
status = _parseNameFromBSONElement(cmdObj["usersInfo"],
|
||||
dbname,
|
||||
AuthorizationManager::USER_NAME_FIELD_NAME,
|
||||
AuthorizationManager::USER_SOURCE_FIELD_NAME,
|
||||
&name);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
parsedArgs->userNames.push_back(name);
|
||||
}
|
||||
|
||||
status = bsonExtractBooleanFieldWithDefault(cmdObj,
|
||||
"showPrivileges",
|
||||
false,
|
||||
&parsedArgs->showPrivileges);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
status = bsonExtractBooleanFieldWithDefault(cmdObj,
|
||||
"showCredentials",
|
||||
false,
|
||||
&parsedArgs->showCredentials);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
Status parseRolesInfoCommand(const BSONObj& cmdObj,
|
||||
const StringData& dbname,
|
||||
std::vector<RoleName>* parsedRoleNames) {
|
||||
unordered_set<std::string> validFieldNames;
|
||||
validFieldNames.insert("rolesInfo");
|
||||
|
||||
Status status = _checkNoExtraFields(cmdObj, "rolesInfo", validFieldNames);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
|
||||
if (cmdObj["rolesInfo"].type() == Array) {
|
||||
status = parseRoleNamesFromBSONArray(BSONArray(cmdObj["rolesInfo"].Obj()),
|
||||
dbname,
|
||||
parsedRoleNames);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
} else {
|
||||
RoleName name;
|
||||
status = _parseNameFromBSONElement(cmdObj["rolesInfo"],
|
||||
dbname,
|
||||
AuthorizationManager::ROLE_NAME_FIELD_NAME,
|
||||
AuthorizationManager::ROLE_SOURCE_FIELD_NAME,
|
||||
&name);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
}
|
||||
parsedRoleNames->push_back(name);
|
||||
}
|
||||
*parsedAnyDB = anyDB;
|
||||
|
||||
return Status::OK();
|
||||
}
|
||||
@@ -467,7 +549,6 @@ namespace auth {
|
||||
}
|
||||
status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()),
|
||||
dbname,
|
||||
"roles",
|
||||
&parsedArgs->roles);
|
||||
if (!status.isOK()) {
|
||||
return status;
|
||||
|
||||
@@ -99,17 +99,29 @@ namespace auth {
|
||||
const std::string& dbname,
|
||||
BSONObj* parsedWriteConcern);
|
||||
|
||||
struct UsersInfoArgs {
|
||||
std::vector<UserName> userNames;
|
||||
bool allForDB;
|
||||
bool showPrivileges;
|
||||
bool showCredentials;
|
||||
UsersInfoArgs() : allForDB(false), showPrivileges(false), showCredentials(false) {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Takes a command object describing an invocation of the "usersInfo" or "rolesInfo" commands
|
||||
* (which command it is is specified in the "cmdName" argument) and parses out a BSONElement
|
||||
* with the user/role name filter to be applied, as well as the anyDB boolean.
|
||||
* Also validates the input and returns a non-ok Status if there is anything wrong.
|
||||
* Takes a command object describing an invocation of the "usersInfo" command and parses out
|
||||
* all the arguments into the "parsedArgs" output param.
|
||||
*/
|
||||
Status parseAndValidateInfoCommands(const BSONObj& cmdObj,
|
||||
const StringData& cmdName,
|
||||
const std::string& dbname,
|
||||
bool* parsedAnyDb,
|
||||
BSONElement* parsedNameFilter);
|
||||
Status parseUsersInfoCommand(const BSONObj& cmdObj,
|
||||
const StringData& dbname,
|
||||
UsersInfoArgs* parsedArgs);
|
||||
|
||||
/**
|
||||
* Takes a command object describing an invocation of the "rolesInfo" command and parses out
|
||||
* the role names requested into the "parsedRoleNames" output param.
|
||||
*/
|
||||
Status parseRolesInfoCommand(const BSONObj& cmdObj,
|
||||
const StringData& dbname,
|
||||
std::vector<RoleName>* parsedRoleNames);
|
||||
|
||||
struct CreateOrUpdateRoleArgs {
|
||||
RoleName roleName;
|
||||
@@ -173,7 +185,6 @@ namespace auth {
|
||||
*/
|
||||
Status parseRoleNamesFromBSONArray(const BSONArray& rolesArray,
|
||||
const StringData& dbname,
|
||||
const StringData& rolesFieldName,
|
||||
std::vector<RoleName>* parsedRoleNames);
|
||||
|
||||
} // namespace auth
|
||||
|
||||
@@ -980,56 +980,79 @@ namespace mongo {
|
||||
BSONObjBuilder& result,
|
||||
bool fromRepl) {
|
||||
|
||||
bool anyDB = false;
|
||||
BSONElement usersFilter;
|
||||
Status status = auth::parseAndValidateInfoCommands(cmdObj,
|
||||
"usersInfo",
|
||||
dbname,
|
||||
&anyDB,
|
||||
&usersFilter);
|
||||
auth::UsersInfoArgs args;
|
||||
Status status = auth::parseUsersInfoCommand(cmdObj, dbname, &args);
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool wantsDetails = cmdObj["details"].trueValue();
|
||||
if (wantsDetails) {
|
||||
if (anyDB || usersFilter.type() != String) {
|
||||
addStatus(Status(ErrorCodes::IllegalOperation,
|
||||
"Cannot only get privilege details on exact-match usersInfo "
|
||||
"queries."),
|
||||
result);
|
||||
return false;
|
||||
}
|
||||
|
||||
BSONObj userDetails;
|
||||
status = getGlobalAuthorizationManager()->getUserDescription(
|
||||
UserName(usersFilter.str(), dbname), &userDetails);
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
return false;
|
||||
}
|
||||
result.append("users", BSON_ARRAY(userDetails));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
BSONObjBuilder queryBuilder;
|
||||
queryBuilder.appendAs(usersFilter, AuthorizationManager::USER_NAME_FIELD_NAME);
|
||||
if (!anyDB) {
|
||||
queryBuilder.append(AuthorizationManager::USER_SOURCE_FIELD_NAME, dbname);
|
||||
if (args.allForDB && args.showPrivileges) {
|
||||
addStatus(Status(ErrorCodes::IllegalOperation,
|
||||
"Cannot only get privilege details on exact-match usersInfo "
|
||||
"queries."),
|
||||
result);
|
||||
return false;
|
||||
}
|
||||
|
||||
BSONArrayBuilder usersArrayBuilder;
|
||||
BSONArrayBuilder& (BSONArrayBuilder::* appendBSONObj) (const BSONObj&) =
|
||||
&BSONArrayBuilder::append<BSONObj>;
|
||||
const boost::function<void(const BSONObj&)> function =
|
||||
boost::bind(appendBSONObj, &usersArrayBuilder, _1);
|
||||
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
|
||||
authzManager->queryAuthzDocument(NamespaceString("admin.system.users"),
|
||||
queryBuilder.done(),
|
||||
function);
|
||||
if (args.showPrivileges) {
|
||||
// If you want privileges you need to call getUserDescription on each user.
|
||||
for (size_t i = 0; i < args.userNames.size(); ++i) {
|
||||
BSONObj userDetails;
|
||||
status = getGlobalAuthorizationManager()->getUserDescription(
|
||||
args.userNames[i], &userDetails);
|
||||
if (status.code() == ErrorCodes::UserNotFound) {
|
||||
continue;
|
||||
}
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
return false;
|
||||
}
|
||||
if (!args.showCredentials) {
|
||||
// getUserDescription always includes credentials, need to strip it out
|
||||
BSONObjBuilder userWithoutCredentials(usersArrayBuilder.subobjStart());
|
||||
for (BSONObjIterator it(userDetails); it.more(); ) {
|
||||
BSONElement e = it.next();
|
||||
if (e.fieldNameStringData() != "credentials")
|
||||
userWithoutCredentials.append(e);
|
||||
}
|
||||
userWithoutCredentials.doneFast();
|
||||
} else {
|
||||
usersArrayBuilder.append(userDetails);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If you don't need privileges, you can just do a regular query on system.users
|
||||
BSONObjBuilder queryBuilder;
|
||||
if (args.allForDB) {
|
||||
queryBuilder.append(AuthorizationManager::USER_SOURCE_FIELD_NAME, dbname);
|
||||
} else {
|
||||
BSONArrayBuilder usersMatchArray;
|
||||
for (size_t i = 0; i < args.userNames.size(); ++i) {
|
||||
usersMatchArray.append(BSON(AuthorizationManager::USER_NAME_FIELD_NAME <<
|
||||
args.userNames[i].getUser() <<
|
||||
AuthorizationManager::USER_SOURCE_FIELD_NAME <<
|
||||
args.userNames[i].getDB()));
|
||||
}
|
||||
queryBuilder.append("$or", usersMatchArray.arr());
|
||||
|
||||
}
|
||||
|
||||
AuthorizationManager* authzManager = getGlobalAuthorizationManager();
|
||||
BSONObjBuilder projection;
|
||||
if (!args.showCredentials) {
|
||||
projection.append("credentials", 0);
|
||||
}
|
||||
BSONArrayBuilder& (BSONArrayBuilder::* appendBSONObj) (const BSONObj&) =
|
||||
&BSONArrayBuilder::append<BSONObj>;
|
||||
const boost::function<void(const BSONObj&)> function =
|
||||
boost::bind(appendBSONObj, &usersArrayBuilder, _1);
|
||||
authzManager->queryAuthzDocument(AuthorizationManager::usersCollectionNamespace,
|
||||
queryBuilder.done(),
|
||||
projection.done(),
|
||||
function);
|
||||
}
|
||||
result.append("users", usersArrayBuilder.arr());
|
||||
return true;
|
||||
}
|
||||
@@ -1577,7 +1600,6 @@ namespace mongo {
|
||||
std::vector<RoleName> roles;
|
||||
status = auth::parseRoleNamesFromBSONArray(BSONArray(roleDoc["roles"].Obj()),
|
||||
roleName.getDB(),
|
||||
"roles",
|
||||
&roles);
|
||||
|
||||
for (vector<RoleName>::iterator it = rolesToAdd.begin(); it != rolesToAdd.end(); ++it) {
|
||||
@@ -1600,7 +1622,6 @@ namespace mongo {
|
||||
status = auth::parseRoleNamesFromBSONArray(
|
||||
BSONArray(roleDoc["indirectRoles"].Obj()),
|
||||
roleName.getDB(),
|
||||
"indirectRoles",
|
||||
&indirectSubordinatesOfToAdd);
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
@@ -1712,7 +1733,6 @@ namespace mongo {
|
||||
std::vector<RoleName> roles;
|
||||
status = auth::parseRoleNamesFromBSONArray(BSONArray(roleDoc["roles"].Obj()),
|
||||
roleName.getDB(),
|
||||
"roles",
|
||||
&roles);
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
@@ -1940,26 +1960,28 @@ namespace mongo {
|
||||
BSONObjBuilder& result,
|
||||
bool fromRepl) {
|
||||
|
||||
bool anyDB = false;
|
||||
BSONElement rolesFilter;
|
||||
Status status = auth::parseAndValidateInfoCommands(cmdObj,
|
||||
"rolesInfo",
|
||||
dbname,
|
||||
&anyDB,
|
||||
&rolesFilter);
|
||||
std::vector<RoleName> roleNames;
|
||||
Status status = auth::parseRolesInfoCommand(cmdObj, dbname, &roleNames);
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
return false;
|
||||
}
|
||||
|
||||
BSONObj roleObj;
|
||||
status = getGlobalAuthorizationManager()->getRoleDescription(
|
||||
RoleName(rolesFilter.str(), dbname), &roleObj);
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
return false;
|
||||
BSONArrayBuilder rolesArrayBuilder;
|
||||
for (size_t i = 0; i < roleNames.size(); ++i) {
|
||||
BSONObj roleDetails;
|
||||
status = getGlobalAuthorizationManager()->getRoleDescription(
|
||||
roleNames[i], &roleDetails);
|
||||
if (status.code() == ErrorCodes::RoleNotFound) {
|
||||
continue;
|
||||
}
|
||||
if (!status.isOK()) {
|
||||
addStatus(status, result);
|
||||
return false;
|
||||
}
|
||||
rolesArrayBuilder.append(roleDetails);
|
||||
}
|
||||
result.append("roles", BSON_ARRAY(roleObj));
|
||||
result.append("roles", rolesArrayBuilder.arr());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -1234,7 +1234,7 @@ DB.prototype.getUser = function(username) {
|
||||
}
|
||||
|
||||
DB.prototype.getUsers = function() {
|
||||
var res = this.runCommand({usersInfo: /.*/});
|
||||
var res = this.runCommand({usersInfo: 1});
|
||||
if (!res.ok) {
|
||||
throw Error(res.errmsg);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user