bool run(const string& dbname, BSONObj& cmdObj, int options, string& errmsg, BSONObjBuilder& result, bool fromRepl) { AuthorizationManager* authzManager = getGlobalAuthorizationManager(); AuthzDocumentsUpdateGuard updateGuard(authzManager); if (!updateGuard.tryLock("Grant role delegation to user")) { addStatus(Status(ErrorCodes::LockBusy, "Could not lock auth data update lock."), result); return false; } UserName userName; std::vector<RoleName> roles; BSONObj writeConcern; Status status = auth::parseUserRoleManipulationCommand(cmdObj, "grantDelegateRolesToUser", dbname, authzManager, &userName, &roles, &writeConcern); if (!status.isOK()) { addStatus(status, result); return false; } User::RoleDataMap userRoles; status = getCurrentUserRoles(authzManager, userName, &userRoles); if (!status.isOK()) { addStatus(status, result); return false; } for (vector<RoleName>::iterator it = roles.begin(); it != roles.end(); ++it) { RoleName& roleName = *it; User::RoleData& role = userRoles[roleName]; if (role.name.empty()) { role.name = roleName; } role.canDelegate = true; } BSONArray newRolesBSONArray = rolesToBSONArray(userRoles); status = authzManager->updatePrivilegeDocument( userName, BSON("$set" << BSON("roles" << newRolesBSONArray)), writeConcern); // Must invalidate even on bad status - what if the write succeeded but the GLE failed? authzManager->invalidateUserByName(userName); if (!status.isOK()) { addStatus(status, result); return false; } return true; }
bool run(const string& dbname, BSONObj& cmdObj, int options, string& errmsg, BSONObjBuilder& result, bool fromRepl) { AuthorizationManager* authzManager = getGlobalAuthorizationManager(); AuthzDocumentsUpdateGuard updateGuard(authzManager); if (!updateGuard.tryLock("Update user")) { addStatus(Status(ErrorCodes::LockBusy, "Could not lock auth data update lock."), result); return false; } BSONObj updateObj; UserName userName; BSONObj writeConcern; Status status = auth::parseAndValidateUpdateUserCommand(cmdObj, dbname, authzManager, &updateObj, &userName, &writeConcern); if (!status.isOK()) { addStatus(status, result); return false; } status = authzManager->updatePrivilegeDocument(userName, updateObj, writeConcern); // Must invalidate even on bad status - what if the write succeeded but the GLE failed? authzManager->invalidateUserByName(userName); if (!status.isOK()) { addStatus(status, result); return false; } return true; }
bool run(const string& dbname, BSONObj& cmdObj, int options, string& errmsg, BSONObjBuilder& result, bool fromRepl) { AuthorizationManager* authzManager = getGlobalAuthorizationManager(); AuthzDocumentsUpdateGuard updateGuard(authzManager); if (!updateGuard.tryLock("Revoke role delegation from user")) { addStatus(Status(ErrorCodes::LockBusy, "Could not lock auth data update lock."), result); return false; } UserName userName; std::vector<RoleName> roles; BSONObj writeConcern; Status status = auth::parseUserRoleManipulationCommand(cmdObj, "revokeDelegateRolesFromUser", dbname, authzManager, &userName, &roles, &writeConcern); if (!status.isOK()) { addStatus(status, result); return false; } User::RoleDataMap userRoles; status = getCurrentUserRoles(authzManager, userName, &userRoles); if (!status.isOK()) { addStatus(status, result); return false; } for (vector<RoleName>::iterator it = roles.begin(); it != roles.end(); ++it) { RoleName& roleName = *it; User::RoleDataMap::iterator roleDataIt = userRoles.find(roleName); if (roleDataIt == userRoles.end()) { continue; // User already doesn't have the role, nothing to do } User::RoleData& role = roleDataIt->second; if (role.hasRole) { // If the user still has the role, need to leave it in the roles array role.canDelegate = false; } else { // If the user doesn't have the role, and now can't delegate it either, remove // the role from that user's roles array entirely userRoles.erase(roleDataIt); } } BSONArray newRolesBSONArray = rolesToBSONArray(userRoles); status = authzManager->updatePrivilegeDocument( userName, BSON("$set" << BSON("roles" << newRolesBSONArray)), writeConcern); // Must invalidate even on bad status - what if the write succeeded but the GLE failed? authzManager->invalidateUserByName(userName); if (!status.isOK()) { addStatus(status, result); return false; } return true; }