summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth/user_management_commands_parser.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/auth/user_management_commands_parser.cpp')
-rw-r--r--src/mongo/db/auth/user_management_commands_parser.cpp1032
1 files changed, 500 insertions, 532 deletions
diff --git a/src/mongo/db/auth/user_management_commands_parser.cpp b/src/mongo/db/auth/user_management_commands_parser.cpp
index eecef9d9301..82130e2a530 100644
--- a/src/mongo/db/auth/user_management_commands_parser.cpp
+++ b/src/mongo/db/auth/user_management_commands_parser.cpp
@@ -47,652 +47,620 @@
namespace mongo {
namespace auth {
- using std::vector;
-
- /**
- * Writes into *writeConcern a BSONObj describing the parameters to getLastError to use for
- * the write confirmation.
- */
- Status _extractWriteConcern(const BSONObj& cmdObj, BSONObj* writeConcern) {
- BSONElement writeConcernElement;
- Status status = bsonExtractTypedField(cmdObj, "writeConcern", Object, &writeConcernElement);
- if (!status.isOK()) {
- if (status.code() == ErrorCodes::NoSuchKey) {
- *writeConcern = BSONObj();
- return Status::OK();
- }
- return status;
- }
- *writeConcern = writeConcernElement.Obj().getOwned();;
- return Status::OK();
- }
-
- Status _checkNoExtraFields(const BSONObj& cmdObj,
- StringData cmdName,
- const unordered_set<std::string>& validFieldNames) {
- // Iterate through all fields in command object and make sure there are no unexpected
- // ones.
- for (BSONObjIterator iter(cmdObj); iter.more(); iter.next()) {
- StringData fieldName = (*iter).fieldNameStringData();
- if (!validFieldNames.count(fieldName.toString())) {
- return Status(ErrorCodes::BadValue,
- mongoutils::str::stream() << "\"" << fieldName << "\" is not "
- "a valid argument to " << cmdName);
- }
- }
- return Status::OK();
- }
-
- // Extracts a UserName or RoleName object from a BSONElement.
- template <typename Name>
- Status _parseNameFromBSONElement(const BSONElement& element,
- StringData dbname,
- StringData nameFieldName,
- StringData sourceFieldName,
- Name* parsedName) {
- if (element.type() == String) {
- *parsedName = Name(element.String(), dbname);
- }
- else if (element.type() == Object) {
- BSONObj obj = element.Obj();
-
- 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;
- }
-
- *parsedName = Name(name, source);
- }
- else {
+using std::vector;
+
+/**
+ * Writes into *writeConcern a BSONObj describing the parameters to getLastError to use for
+ * the write confirmation.
+ */
+Status _extractWriteConcern(const BSONObj& cmdObj, BSONObj* writeConcern) {
+ BSONElement writeConcernElement;
+ Status status = bsonExtractTypedField(cmdObj, "writeConcern", Object, &writeConcernElement);
+ if (!status.isOK()) {
+ if (status.code() == ErrorCodes::NoSuchKey) {
+ *writeConcern = BSONObj();
+ return Status::OK();
+ }
+ return status;
+ }
+ *writeConcern = writeConcernElement.Obj().getOwned();
+ ;
+ return Status::OK();
+}
+
+Status _checkNoExtraFields(const BSONObj& cmdObj,
+ StringData cmdName,
+ const unordered_set<std::string>& validFieldNames) {
+ // Iterate through all fields in command object and make sure there are no unexpected
+ // ones.
+ for (BSONObjIterator iter(cmdObj); iter.more(); iter.next()) {
+ StringData fieldName = (*iter).fieldNameStringData();
+ if (!validFieldNames.count(fieldName.toString())) {
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,
- StringData dbname,
- StringData nameFieldName,
- 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,
- StringData dbname,
- std::vector<UserName>* parsedUserNames) {
- return _parseNamesFromBSONArray(usersArray,
- dbname,
- AuthorizationManager::USER_NAME_FIELD_NAME,
- AuthorizationManager::USER_DB_FIELD_NAME,
- parsedUserNames);
- }
-
- Status parseRoleNamesFromBSONArray(const BSONArray& rolesArray,
- StringData dbname,
- std::vector<RoleName>* parsedRoleNames) {
- return _parseNamesFromBSONArray(rolesArray,
- dbname,
- AuthorizationManager::ROLE_NAME_FIELD_NAME,
- AuthorizationManager::ROLE_DB_FIELD_NAME,
- parsedRoleNames);
- }
-
- Status parseRolePossessionManipulationCommands(const BSONObj& cmdObj,
- StringData cmdName,
- const std::string& dbname,
- std::string* parsedName,
- vector<RoleName>* parsedRoleNames,
- BSONObj* parsedWriteConcern) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert(cmdName.toString());
- validFieldNames.insert("roles");
- validFieldNames.insert("writeConcern");
-
- Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
- if (!status.isOK()) {
- return status;
+ mongoutils::str::stream() << "\"" << fieldName << "\" is not "
+ "a valid argument to "
+ << cmdName);
}
+ }
+ return Status::OK();
+}
- status = _extractWriteConcern(cmdObj, parsedWriteConcern);
- if (!status.isOK()) {
- return status;
- }
+// Extracts a UserName or RoleName object from a BSONElement.
+template <typename Name>
+Status _parseNameFromBSONElement(const BSONElement& element,
+ StringData dbname,
+ StringData nameFieldName,
+ StringData sourceFieldName,
+ Name* parsedName) {
+ if (element.type() == String) {
+ *parsedName = Name(element.String(), dbname);
+ } else if (element.type() == Object) {
+ BSONObj obj = element.Obj();
- status = bsonExtractStringField(cmdObj, cmdName, parsedName);
+ std::string name;
+ std::string source;
+ Status status = bsonExtractStringField(obj, nameFieldName, &name);
if (!status.isOK()) {
return status;
}
-
- BSONElement rolesElement;
- status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement);
+ status = bsonExtractStringField(obj, sourceFieldName, &source);
if (!status.isOK()) {
return status;
}
- status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()),
- dbname,
- parsedRoleNames);
- if (!status.isOK()) {
- return status;
- }
+ *parsedName = Name(name, source);
+ } else {
+ return Status(ErrorCodes::BadValue,
+ "User and role names must be either strings or objects");
+ }
+ return Status::OK();
+}
- if (!parsedRoleNames->size()) {
- return Status(ErrorCodes::BadValue,
- mongoutils::str::stream() << cmdName << " command requires a non-empty "
- "\"roles\" array");
- }
- return Status::OK();
- }
-
- Status parseCreateOrUpdateUserCommands(const BSONObj& cmdObj,
- StringData cmdName,
- const std::string& dbname,
- CreateOrUpdateUserArgs* parsedArgs) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert(cmdName.toString());
- validFieldNames.insert("customData");
- validFieldNames.insert("digestPassword");
- validFieldNames.insert("pwd");
- validFieldNames.insert("roles");
- validFieldNames.insert("writeConcern");
-
- Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
+// Extracts UserName or RoleName objects from a BSONArray of role/user names.
+template <typename Name>
+Status _parseNamesFromBSONArray(const BSONArray& array,
+ StringData dbname,
+ StringData nameFieldName,
+ 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,
+ StringData dbname,
+ std::vector<UserName>* parsedUserNames) {
+ return _parseNamesFromBSONArray(usersArray,
+ dbname,
+ AuthorizationManager::USER_NAME_FIELD_NAME,
+ AuthorizationManager::USER_DB_FIELD_NAME,
+ parsedUserNames);
+}
+
+Status parseRoleNamesFromBSONArray(const BSONArray& rolesArray,
+ StringData dbname,
+ std::vector<RoleName>* parsedRoleNames) {
+ return _parseNamesFromBSONArray(rolesArray,
+ dbname,
+ AuthorizationManager::ROLE_NAME_FIELD_NAME,
+ AuthorizationManager::ROLE_DB_FIELD_NAME,
+ parsedRoleNames);
+}
+
+Status parseRolePossessionManipulationCommands(const BSONObj& cmdObj,
+ StringData cmdName,
+ const std::string& dbname,
+ std::string* parsedName,
+ vector<RoleName>* parsedRoleNames,
+ BSONObj* parsedWriteConcern) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert(cmdName.toString());
+ validFieldNames.insert("roles");
+ validFieldNames.insert("writeConcern");
+
+ Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- status = _extractWriteConcern(cmdObj, &parsedArgs->writeConcern);
- if (!status.isOK()) {
- return status;
- }
+ status = _extractWriteConcern(cmdObj, parsedWriteConcern);
+ if (!status.isOK()) {
+ return status;
+ }
- BSONObjBuilder userObjBuilder;
+ status = bsonExtractStringField(cmdObj, cmdName, parsedName);
+ if (!status.isOK()) {
+ return status;
+ }
- // Parse user name
- std::string userName;
- status = bsonExtractStringField(cmdObj, cmdName, &userName);
- if (!status.isOK()) {
- return status;
- }
+ BSONElement rolesElement;
+ status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement);
+ if (!status.isOK()) {
+ return status;
+ }
- parsedArgs->userName = UserName(userName, dbname);
-
- // Parse password
- if (cmdObj.hasField("pwd")) {
- std::string password;
- status = bsonExtractStringField(cmdObj, "pwd", &password);
- if (!status.isOK()) {
- return status;
- }
- if (password.empty()) {
- return Status(ErrorCodes::BadValue, "User passwords must not be empty");
- }
-
- bool digestPassword; // True if the server should digest the password
- status = bsonExtractBooleanFieldWithDefault(cmdObj,
- "digestPassword",
- true,
- &digestPassword);
- if (!status.isOK()) {
- return status;
- }
-
- if (digestPassword) {
- parsedArgs->hashedPassword = mongo::createPasswordDigest(
- userName, password);
- } else {
- parsedArgs->hashedPassword = password;
- }
- parsedArgs->hasHashedPassword = true;
- }
+ status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()), dbname, parsedRoleNames);
+ if (!status.isOK()) {
+ return status;
+ }
- // Parse custom data
- if (cmdObj.hasField("customData")) {
- BSONElement element;
- status = bsonExtractTypedField(cmdObj, "customData", Object, &element);
- if (!status.isOK()) {
- return status;
- }
- parsedArgs->customData = element.Obj();
- parsedArgs->hasCustomData = true;
- }
+ if (!parsedRoleNames->size()) {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream() << cmdName << " command requires a non-empty "
+ "\"roles\" array");
+ }
+ return Status::OK();
+}
+
+Status parseCreateOrUpdateUserCommands(const BSONObj& cmdObj,
+ StringData cmdName,
+ const std::string& dbname,
+ CreateOrUpdateUserArgs* parsedArgs) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert(cmdName.toString());
+ validFieldNames.insert("customData");
+ validFieldNames.insert("digestPassword");
+ validFieldNames.insert("pwd");
+ validFieldNames.insert("roles");
+ validFieldNames.insert("writeConcern");
+
+ Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- // Parse roles
- if (cmdObj.hasField("roles")) {
- BSONElement rolesElement;
- status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement);
- if (!status.isOK()) {
- return status;
- }
- status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()),
- dbname,
- &parsedArgs->roles);
- if (!status.isOK()) {
- return status;
- }
- parsedArgs->hasRoles = true;
- }
+ status = _extractWriteConcern(cmdObj, &parsedArgs->writeConcern);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ BSONObjBuilder userObjBuilder;
- return Status::OK();
+ // Parse user name
+ std::string userName;
+ status = bsonExtractStringField(cmdObj, cmdName, &userName);
+ if (!status.isOK()) {
+ return status;
}
- Status parseAndValidateDropUserCommand(const BSONObj& cmdObj,
- const std::string& dbname,
- UserName* parsedUserName,
- BSONObj* parsedWriteConcern) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert("dropUser");
- validFieldNames.insert("writeConcern");
+ parsedArgs->userName = UserName(userName, dbname);
- Status status = _checkNoExtraFields(cmdObj, "dropUser", validFieldNames);
+ // Parse password
+ if (cmdObj.hasField("pwd")) {
+ std::string password;
+ status = bsonExtractStringField(cmdObj, "pwd", &password);
if (!status.isOK()) {
return status;
}
+ if (password.empty()) {
+ return Status(ErrorCodes::BadValue, "User passwords must not be empty");
+ }
- std::string user;
- status = bsonExtractStringField(cmdObj, "dropUser", &user);
+ bool digestPassword; // True if the server should digest the password
+ status =
+ bsonExtractBooleanFieldWithDefault(cmdObj, "digestPassword", true, &digestPassword);
if (!status.isOK()) {
return status;
}
- status = _extractWriteConcern(cmdObj, parsedWriteConcern);
+ if (digestPassword) {
+ parsedArgs->hashedPassword = mongo::createPasswordDigest(userName, password);
+ } else {
+ parsedArgs->hashedPassword = password;
+ }
+ parsedArgs->hasHashedPassword = true;
+ }
+
+ // Parse custom data
+ if (cmdObj.hasField("customData")) {
+ BSONElement element;
+ status = bsonExtractTypedField(cmdObj, "customData", Object, &element);
if (!status.isOK()) {
return status;
}
-
- *parsedUserName = UserName(user, dbname);
- return Status::OK();
+ parsedArgs->customData = element.Obj();
+ parsedArgs->hasCustomData = true;
}
- Status parseFromDatabaseCommand(const BSONObj& cmdObj,
- const std::string& dbname,
- BSONObj* parsedWriteConcern,
- std::string command) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert(command);
- validFieldNames.insert("writeConcern");
-
- Status status = _checkNoExtraFields(cmdObj, command, validFieldNames);
+ // Parse roles
+ if (cmdObj.hasField("roles")) {
+ BSONElement rolesElement;
+ status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement);
if (!status.isOK()) {
return status;
}
-
- status = _extractWriteConcern(cmdObj, parsedWriteConcern);
+ status =
+ parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()), dbname, &parsedArgs->roles);
if (!status.isOK()) {
return status;
}
+ parsedArgs->hasRoles = true;
+ }
+
+ return Status::OK();
+}
+
+Status parseAndValidateDropUserCommand(const BSONObj& cmdObj,
+ const std::string& dbname,
+ UserName* parsedUserName,
+ BSONObj* parsedWriteConcern) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert("dropUser");
+ validFieldNames.insert("writeConcern");
- return Status::OK();
+ Status status = _checkNoExtraFields(cmdObj, "dropUser", validFieldNames);
+ if (!status.isOK()) {
+ return status;
}
- Status parseAndValidateDropAllUsersFromDatabaseCommand(const BSONObj& cmdObj,
- const std::string& dbname,
- BSONObj* parsedWriteConcern) {
- return parseFromDatabaseCommand(cmdObj, dbname, parsedWriteConcern, "dropAllUsersFromDatabase");
+
+ std::string user;
+ status = bsonExtractStringField(cmdObj, "dropUser", &user);
+ if (!status.isOK()) {
+ return status;
}
- Status parseUsersInfoCommand(const BSONObj& cmdObj,
- StringData dbname,
- UsersInfoArgs* parsedArgs) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert("usersInfo");
- validFieldNames.insert("showPrivileges");
- validFieldNames.insert("showCredentials");
+ status = _extractWriteConcern(cmdObj, parsedWriteConcern);
+ if (!status.isOK()) {
+ return status;
+ }
- Status status = _checkNoExtraFields(cmdObj, "usersInfo", validFieldNames);
- if (!status.isOK()) {
- return status;
- }
+ *parsedUserName = UserName(user, dbname);
+ return Status::OK();
+}
- 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_DB_FIELD_NAME,
- &name);
- if (!status.isOK()) {
- return status;
- }
- parsedArgs->userNames.push_back(name);
- }
+Status parseFromDatabaseCommand(const BSONObj& cmdObj,
+ const std::string& dbname,
+ BSONObj* parsedWriteConcern,
+ std::string command) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert(command);
+ validFieldNames.insert("writeConcern");
+
+ Status status = _checkNoExtraFields(cmdObj, command, validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- status = bsonExtractBooleanFieldWithDefault(cmdObj,
- "showPrivileges",
- false,
- &parsedArgs->showPrivileges);
+ status = _extractWriteConcern(cmdObj, parsedWriteConcern);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ return Status::OK();
+}
+Status parseAndValidateDropAllUsersFromDatabaseCommand(const BSONObj& cmdObj,
+ const std::string& dbname,
+ BSONObj* parsedWriteConcern) {
+ return parseFromDatabaseCommand(cmdObj, dbname, parsedWriteConcern, "dropAllUsersFromDatabase");
+}
+
+Status parseUsersInfoCommand(const BSONObj& cmdObj, StringData dbname, UsersInfoArgs* parsedArgs) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert("usersInfo");
+ validFieldNames.insert("showPrivileges");
+ validFieldNames.insert("showCredentials");
+
+ Status status = _checkNoExtraFields(cmdObj, "usersInfo", validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ 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;
}
- status = bsonExtractBooleanFieldWithDefault(cmdObj,
- "showCredentials",
- false,
- &parsedArgs->showCredentials);
+ } else {
+ UserName name;
+ status = _parseNameFromBSONElement(cmdObj["usersInfo"],
+ dbname,
+ AuthorizationManager::USER_NAME_FIELD_NAME,
+ AuthorizationManager::USER_DB_FIELD_NAME,
+ &name);
if (!status.isOK()) {
return status;
}
+ parsedArgs->userNames.push_back(name);
+ }
- return Status::OK();
+ status = bsonExtractBooleanFieldWithDefault(
+ cmdObj, "showPrivileges", false, &parsedArgs->showPrivileges);
+ if (!status.isOK()) {
+ return status;
+ }
+ status = bsonExtractBooleanFieldWithDefault(
+ cmdObj, "showCredentials", false, &parsedArgs->showCredentials);
+ if (!status.isOK()) {
+ return status;
}
- Status parseRolesInfoCommand(const BSONObj& cmdObj,
- StringData dbname,
- RolesInfoArgs* parsedArgs) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert("rolesInfo");
- validFieldNames.insert("showPrivileges");
- validFieldNames.insert("showBuiltinRoles");
+ return Status::OK();
+}
- Status status = _checkNoExtraFields(cmdObj, "rolesInfo", validFieldNames);
- if (!status.isOK()) {
- return status;
- }
+Status parseRolesInfoCommand(const BSONObj& cmdObj, StringData dbname, RolesInfoArgs* parsedArgs) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert("rolesInfo");
+ validFieldNames.insert("showPrivileges");
+ validFieldNames.insert("showBuiltinRoles");
- if (cmdObj["rolesInfo"].numberInt() == 1) {
- parsedArgs->allForDB = true;
- } else if (cmdObj["rolesInfo"].type() == Array) {
- status = parseRoleNamesFromBSONArray(BSONArray(cmdObj["rolesInfo"].Obj()),
- dbname,
- &parsedArgs->roleNames);
- if (!status.isOK()) {
- return status;
- }
- } else {
- RoleName name;
- status = _parseNameFromBSONElement(cmdObj["rolesInfo"],
- dbname,
- AuthorizationManager::ROLE_NAME_FIELD_NAME,
- AuthorizationManager::ROLE_DB_FIELD_NAME,
- &name);
- if (!status.isOK()) {
- return status;
- }
- parsedArgs->roleNames.push_back(name);
- }
+ Status status = _checkNoExtraFields(cmdObj, "rolesInfo", validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- status = bsonExtractBooleanFieldWithDefault(cmdObj,
- "showPrivileges",
- false,
- &parsedArgs->showPrivileges);
+ if (cmdObj["rolesInfo"].numberInt() == 1) {
+ parsedArgs->allForDB = true;
+ } else if (cmdObj["rolesInfo"].type() == Array) {
+ status = parseRoleNamesFromBSONArray(
+ BSONArray(cmdObj["rolesInfo"].Obj()), dbname, &parsedArgs->roleNames);
if (!status.isOK()) {
return status;
}
-
- status = bsonExtractBooleanFieldWithDefault(cmdObj,
- "showBuiltinRoles",
- false,
- &parsedArgs->showBuiltinRoles);
+ } else {
+ RoleName name;
+ status = _parseNameFromBSONElement(cmdObj["rolesInfo"],
+ dbname,
+ AuthorizationManager::ROLE_NAME_FIELD_NAME,
+ AuthorizationManager::ROLE_DB_FIELD_NAME,
+ &name);
if (!status.isOK()) {
return status;
}
+ parsedArgs->roleNames.push_back(name);
+ }
- return Status::OK();
- }
-
- /*
- * Validates that the given privilege BSONArray is valid.
- * If parsedPrivileges is not NULL, adds to it the privileges parsed out of the input BSONArray.
- */
- Status parseAndValidatePrivilegeArray(const BSONArray& privileges,
- PrivilegeVector* parsedPrivileges) {
- for (BSONObjIterator it(privileges); it.more(); it.next()) {
- BSONElement element = *it;
- if (element.type() != Object) {
- return Status(ErrorCodes::FailedToParse,
- "Elements in privilege arrays must be objects");
- }
-
- ParsedPrivilege parsedPrivilege;
- std::string errmsg;
- if (!parsedPrivilege.parseBSON(element.Obj(), &errmsg)) {
- return Status(ErrorCodes::FailedToParse, errmsg);
- }
- if (!parsedPrivilege.isValid(&errmsg)) {
- return Status(ErrorCodes::FailedToParse, errmsg);
- }
-
- Privilege privilege;
- if (!ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg)) {
- return Status(ErrorCodes::FailedToParse, errmsg);
- }
-
- parsedPrivileges->push_back(privilege);
- }
- return Status::OK();
+ status = bsonExtractBooleanFieldWithDefault(
+ cmdObj, "showPrivileges", false, &parsedArgs->showPrivileges);
+ if (!status.isOK()) {
+ return status;
}
- Status parseCreateOrUpdateRoleCommands(const BSONObj& cmdObj,
- StringData cmdName,
- const std::string& dbname,
- CreateOrUpdateRoleArgs* parsedArgs) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert(cmdName.toString());
- validFieldNames.insert("privileges");
- validFieldNames.insert("roles");
- validFieldNames.insert("writeConcern");
+ status = bsonExtractBooleanFieldWithDefault(
+ cmdObj, "showBuiltinRoles", false, &parsedArgs->showBuiltinRoles);
+ if (!status.isOK()) {
+ return status;
+ }
- Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
- if (!status.isOK()) {
- return status;
- }
+ return Status::OK();
+}
- status = _extractWriteConcern(cmdObj, &parsedArgs->writeConcern);
- if (!status.isOK()) {
- return status;
+/*
+ * Validates that the given privilege BSONArray is valid.
+ * If parsedPrivileges is not NULL, adds to it the privileges parsed out of the input BSONArray.
+ */
+Status parseAndValidatePrivilegeArray(const BSONArray& privileges,
+ PrivilegeVector* parsedPrivileges) {
+ for (BSONObjIterator it(privileges); it.more(); it.next()) {
+ BSONElement element = *it;
+ if (element.type() != Object) {
+ return Status(ErrorCodes::FailedToParse,
+ "Elements in privilege arrays must be objects");
}
- std::string roleName;
- status = bsonExtractStringField(cmdObj, cmdName, &roleName);
- if (!status.isOK()) {
- return status;
+ ParsedPrivilege parsedPrivilege;
+ std::string errmsg;
+ if (!parsedPrivilege.parseBSON(element.Obj(), &errmsg)) {
+ return Status(ErrorCodes::FailedToParse, errmsg);
}
- parsedArgs->roleName = RoleName(roleName, dbname);
-
- // Parse privileges
- if (cmdObj.hasField("privileges")) {
- BSONElement privilegesElement;
- status = bsonExtractTypedField(cmdObj, "privileges", Array, &privilegesElement);
- if (!status.isOK()) {
- return status;
- }
- status = parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()),
- &parsedArgs->privileges);
- if (!status.isOK()) {
- return status;
- }
- parsedArgs->hasPrivileges = true;
+ if (!parsedPrivilege.isValid(&errmsg)) {
+ return Status(ErrorCodes::FailedToParse, errmsg);
}
- // Parse roles
- if (cmdObj.hasField("roles")) {
- BSONElement rolesElement;
- status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement);
- if (!status.isOK()) {
- return status;
- }
- status = parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()),
- dbname,
- &parsedArgs->roles);
- if (!status.isOK()) {
- return status;
- }
- parsedArgs->hasRoles = true;
+ Privilege privilege;
+ if (!ParsedPrivilege::parsedPrivilegeToPrivilege(parsedPrivilege, &privilege, &errmsg)) {
+ return Status(ErrorCodes::FailedToParse, errmsg);
}
- return Status::OK();
- }
-
- Status parseAndValidateRolePrivilegeManipulationCommands(const BSONObj& cmdObj,
- StringData cmdName,
- const std::string& dbname,
- RoleName* parsedRoleName,
- PrivilegeVector* parsedPrivileges,
- BSONObj* parsedWriteConcern) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert(cmdName.toString());
- validFieldNames.insert("privileges");
- validFieldNames.insert("writeConcern");
- Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
- if (!status.isOK()) {
- return status;
- }
-
- status = _extractWriteConcern(cmdObj, parsedWriteConcern);
- if (!status.isOK()) {
- return status;
- }
+ parsedPrivileges->push_back(privilege);
+ }
+ return Status::OK();
+}
+
+Status parseCreateOrUpdateRoleCommands(const BSONObj& cmdObj,
+ StringData cmdName,
+ const std::string& dbname,
+ CreateOrUpdateRoleArgs* parsedArgs) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert(cmdName.toString());
+ validFieldNames.insert("privileges");
+ validFieldNames.insert("roles");
+ validFieldNames.insert("writeConcern");
+
+ Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- BSONObjBuilder roleObjBuilder;
+ status = _extractWriteConcern(cmdObj, &parsedArgs->writeConcern);
+ if (!status.isOK()) {
+ return status;
+ }
- // Parse role name
- std::string roleName;
- status = bsonExtractStringField(cmdObj, cmdName, &roleName);
- if (!status.isOK()) {
- return status;
- }
- *parsedRoleName = RoleName(roleName, dbname);
+ std::string roleName;
+ status = bsonExtractStringField(cmdObj, cmdName, &roleName);
+ if (!status.isOK()) {
+ return status;
+ }
+ parsedArgs->roleName = RoleName(roleName, dbname);
- // Parse privileges
+ // Parse privileges
+ if (cmdObj.hasField("privileges")) {
BSONElement privilegesElement;
status = bsonExtractTypedField(cmdObj, "privileges", Array, &privilegesElement);
if (!status.isOK()) {
return status;
}
status = parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()),
- parsedPrivileges);
+ &parsedArgs->privileges);
if (!status.isOK()) {
return status;
}
- if (!parsedPrivileges->size()) {
- return Status(ErrorCodes::BadValue,
- mongoutils::str::stream() << cmdName << " command requires a non-empty "
- "\"privileges\" array");
- }
-
- return Status::OK();
+ parsedArgs->hasPrivileges = true;
}
- Status parseDropRoleCommand(const BSONObj& cmdObj,
- const std::string& dbname,
- RoleName* parsedRoleName,
- BSONObj* parsedWriteConcern) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert("dropRole");
- validFieldNames.insert("writeConcern");
-
- Status status = _checkNoExtraFields(cmdObj, "dropRole", validFieldNames);
+ // Parse roles
+ if (cmdObj.hasField("roles")) {
+ BSONElement rolesElement;
+ status = bsonExtractTypedField(cmdObj, "roles", Array, &rolesElement);
if (!status.isOK()) {
return status;
}
-
- std::string user;
- status = bsonExtractStringField(cmdObj, "dropRole", &user);
+ status =
+ parseRoleNamesFromBSONArray(BSONArray(rolesElement.Obj()), dbname, &parsedArgs->roles);
if (!status.isOK()) {
return status;
}
+ parsedArgs->hasRoles = true;
+ }
+ return Status::OK();
+}
+
+Status parseAndValidateRolePrivilegeManipulationCommands(const BSONObj& cmdObj,
+ StringData cmdName,
+ const std::string& dbname,
+ RoleName* parsedRoleName,
+ PrivilegeVector* parsedPrivileges,
+ BSONObj* parsedWriteConcern) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert(cmdName.toString());
+ validFieldNames.insert("privileges");
+ validFieldNames.insert("writeConcern");
+
+ Status status = _checkNoExtraFields(cmdObj, cmdName, validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- status = _extractWriteConcern(cmdObj, parsedWriteConcern);
- if (!status.isOK()) {
- return status;
- }
+ status = _extractWriteConcern(cmdObj, parsedWriteConcern);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ BSONObjBuilder roleObjBuilder;
- *parsedRoleName = RoleName(user, dbname);
- return Status::OK();
+ // Parse role name
+ std::string roleName;
+ status = bsonExtractStringField(cmdObj, cmdName, &roleName);
+ if (!status.isOK()) {
+ return status;
}
+ *parsedRoleName = RoleName(roleName, dbname);
- Status parseDropAllRolesFromDatabaseCommand(const BSONObj& cmdObj,
- const std::string& dbname,
- BSONObj* parsedWriteConcern) {
- return parseFromDatabaseCommand(cmdObj, dbname, parsedWriteConcern, "dropAllRolesFromDatabase");
+ // Parse privileges
+ BSONElement privilegesElement;
+ status = bsonExtractTypedField(cmdObj, "privileges", Array, &privilegesElement);
+ if (!status.isOK()) {
+ return status;
+ }
+ status = parseAndValidatePrivilegeArray(BSONArray(privilegesElement.Obj()), parsedPrivileges);
+ if (!status.isOK()) {
+ return status;
+ }
+ if (!parsedPrivileges->size()) {
+ return Status(ErrorCodes::BadValue,
+ mongoutils::str::stream() << cmdName << " command requires a non-empty "
+ "\"privileges\" array");
}
- Status parseMergeAuthzCollectionsCommand(const BSONObj& cmdObj,
- MergeAuthzCollectionsArgs* parsedArgs) {
- unordered_set<std::string> validFieldNames;
- validFieldNames.insert("_mergeAuthzCollections");
- validFieldNames.insert("tempUsersCollection");
- validFieldNames.insert("tempRolesCollection");
- validFieldNames.insert("db");
- validFieldNames.insert("drop");
- validFieldNames.insert("writeConcern");
+ return Status::OK();
+}
- Status status = _checkNoExtraFields(cmdObj, "_mergeAuthzCollections", validFieldNames);
- if (!status.isOK()) {
- return status;
- }
+Status parseDropRoleCommand(const BSONObj& cmdObj,
+ const std::string& dbname,
+ RoleName* parsedRoleName,
+ BSONObj* parsedWriteConcern) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert("dropRole");
+ validFieldNames.insert("writeConcern");
- status = _extractWriteConcern(cmdObj, &parsedArgs->writeConcern);
- if (!status.isOK()) {
- return status;
- }
+ Status status = _checkNoExtraFields(cmdObj, "dropRole", validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- status = bsonExtractStringFieldWithDefault(cmdObj,
- "tempUsersCollection",
- "",
- &parsedArgs->usersCollName);
- if (!status.isOK()) {
- return status;
- }
+ std::string user;
+ status = bsonExtractStringField(cmdObj, "dropRole", &user);
+ if (!status.isOK()) {
+ return status;
+ }
- status = bsonExtractStringFieldWithDefault(cmdObj,
- "tempRolesCollection",
- "",
- &parsedArgs->rolesCollName);
- if (!status.isOK()) {
- return status;
- }
+ status = _extractWriteConcern(cmdObj, parsedWriteConcern);
+ if (!status.isOK()) {
+ return status;
+ }
- status = bsonExtractStringField(cmdObj, "db", &parsedArgs->db);
- if (!status.isOK()) {
- if (status == ErrorCodes::NoSuchKey) {
- return Status(ErrorCodes::OutdatedClient,
- "Missing \"db\" field for _mergeAuthzCollections command. This is "
- "most likely due to running an outdated (pre-2.6.4) version of "
- "mongorestore.");
- }
- return status;
- }
+ *parsedRoleName = RoleName(user, dbname);
+ return Status::OK();
+}
+
+Status parseDropAllRolesFromDatabaseCommand(const BSONObj& cmdObj,
+ const std::string& dbname,
+ BSONObj* parsedWriteConcern) {
+ return parseFromDatabaseCommand(cmdObj, dbname, parsedWriteConcern, "dropAllRolesFromDatabase");
+}
+
+Status parseMergeAuthzCollectionsCommand(const BSONObj& cmdObj,
+ MergeAuthzCollectionsArgs* parsedArgs) {
+ unordered_set<std::string> validFieldNames;
+ validFieldNames.insert("_mergeAuthzCollections");
+ validFieldNames.insert("tempUsersCollection");
+ validFieldNames.insert("tempRolesCollection");
+ validFieldNames.insert("db");
+ validFieldNames.insert("drop");
+ validFieldNames.insert("writeConcern");
+
+ Status status = _checkNoExtraFields(cmdObj, "_mergeAuthzCollections", validFieldNames);
+ if (!status.isOK()) {
+ return status;
+ }
- status = bsonExtractBooleanFieldWithDefault(cmdObj,
- "drop",
- false,
- &parsedArgs->drop);
- if (!status.isOK()) {
- return status;
+ status = _extractWriteConcern(cmdObj, &parsedArgs->writeConcern);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ status = bsonExtractStringFieldWithDefault(
+ cmdObj, "tempUsersCollection", "", &parsedArgs->usersCollName);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ status = bsonExtractStringFieldWithDefault(
+ cmdObj, "tempRolesCollection", "", &parsedArgs->rolesCollName);
+ if (!status.isOK()) {
+ return status;
+ }
+
+ status = bsonExtractStringField(cmdObj, "db", &parsedArgs->db);
+ if (!status.isOK()) {
+ if (status == ErrorCodes::NoSuchKey) {
+ return Status(ErrorCodes::OutdatedClient,
+ "Missing \"db\" field for _mergeAuthzCollections command. This is "
+ "most likely due to running an outdated (pre-2.6.4) version of "
+ "mongorestore.");
}
+ return status;
+ }
- return Status::OK();
+ status = bsonExtractBooleanFieldWithDefault(cmdObj, "drop", false, &parsedArgs->drop);
+ if (!status.isOK()) {
+ return status;
}
-} // namespace auth
-} // namespace mongo
+ return Status::OK();
+}
+
+} // namespace auth
+} // namespace mongo