bool AuthzManagerExternalStateMongod::needsLockForUserName(OperationContext* opCtx, const UserName& name) { return (shouldUseRolesFromConnection(opCtx, name) == false); }
Status AuthzManagerExternalStateMongos::getUserDescription(OperationContext* opCtx, const UserName& userName, BSONObj* result) { if (!shouldUseRolesFromConnection(opCtx, userName)) { BSONObj usersInfoCmd = BSON("usersInfo" << BSON_ARRAY(BSON(AuthorizationManager::USER_NAME_FIELD_NAME << userName.getUser() << AuthorizationManager::USER_DB_FIELD_NAME << userName.getDB())) << "showPrivileges" << true << "showCredentials" << true); BSONObjBuilder builder; const bool ok = Grid::get(opCtx)->catalogClient()->runUserManagementReadCommand( opCtx, "admin", usersInfoCmd, &builder); BSONObj cmdResult = builder.obj(); if (!ok) { return getStatusFromCommandResult(cmdResult); } std::vector<BSONElement> foundUsers = cmdResult["users"].Array(); if (foundUsers.size() == 0) { return Status(ErrorCodes::UserNotFound, "User \"" + userName.toString() + "\" not found"); } if (foundUsers.size() > 1) { return Status(ErrorCodes::UserDataInconsistent, str::stream() << "Found multiple users on the \"" << userName.getDB() << "\" database with name \"" << userName.getUser() << "\""); } *result = foundUsers[0].Obj().getOwned(); return Status::OK(); } else { // Obtain privilege information from the config servers for all roles acquired from the X509 // certificate. BSONArrayBuilder userRolesBuilder; auto& sslPeerInfo = SSLPeerInfo::forSession(opCtx->getClient()->session()); for (const RoleName& role : sslPeerInfo.roles) { userRolesBuilder.append(BSON(AuthorizationManager::ROLE_NAME_FIELD_NAME << role.getRole() << AuthorizationManager::ROLE_DB_FIELD_NAME << role.getDB())); } BSONArray providedRoles = userRolesBuilder.arr(); BSONObj rolesInfoCmd = BSON("rolesInfo" << providedRoles << "showPrivileges" << "asUserFragment"); BSONObjBuilder cmdResultBuilder; const bool cmdOk = Grid::get(opCtx)->catalogClient()->runUserManagementReadCommand( opCtx, "admin", rolesInfoCmd, &cmdResultBuilder); BSONObj cmdResult = cmdResultBuilder.obj(); if (!cmdOk || !cmdResult["userFragment"].ok()) { return Status(ErrorCodes::FailedToParse, "Unable to get resolved X509 roles from config server: " + getStatusFromCommandResult(cmdResult).toString()); } cmdResult = cmdResult["userFragment"].Obj().getOwned(); BSONElement userRoles = cmdResult["roles"]; BSONElement userInheritedRoles = cmdResult["inheritedRoles"]; BSONElement userInheritedPrivileges = cmdResult["inheritedPrivileges"]; if (userRoles.eoo() || userInheritedRoles.eoo() || userInheritedPrivileges.eoo() || !userRoles.isABSONObj() || !userInheritedRoles.isABSONObj() || !userInheritedPrivileges.isABSONObj()) { return Status( ErrorCodes::UserDataInconsistent, "Recieved malformed response to request for X509 roles from config server"); } *result = BSON("_id" << userName.getUser() << "user" << userName.getUser() << "db" << userName.getDB() << "credentials" << BSON("external" << true) << "roles" << BSONArray(cmdResult["roles"].Obj()) << "inheritedRoles" << BSONArray(cmdResult["inheritedRoles"].Obj()) << "inheritedPrivileges" << BSONArray(cmdResult["inheritedPrivileges"].Obj())); return Status::OK(); } }