bool AuthzManagerExternalState::hasAnyPrivilegeDocuments() { std::string usersNamespace = "admin.system.users"; BSONObj userBSONObj; BSONObj query; return _findUser(usersNamespace, query, &userBSONObj).isOK(); }
bool AuthzSessionExternalState::_hasPrivilegeDocument(const std::string& dbname) const { std::string usersNamespace = dbname + ".system.users"; BSONObj userBSONObj; BSONObj query; return _findUser(usersNamespace, query, &userBSONObj); }
Status AuthzManagerExternalState::getPrivilegeDocument(const UserName& userName, int authzVersion, BSONObj* result) { if (userName == internalSecurity.user->getName()) { return Status(ErrorCodes::InternalError, "Requested privilege document for the internal user"); } StringData dbname = userName.getDB(); // Make sure the dbname is actually a database if (dbname == StringData("$external", StringData::LiteralTag()) || dbname == AuthorizationManager::SERVER_RESOURCE_NAME || dbname == AuthorizationManager::CLUSTER_RESOURCE_NAME) { return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "No privilege documents stored in the " << dbname << " user source."); } if (!NamespaceString::validDBName(dbname)) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << "Bad database name \"" << dbname << "\""); } // Build the query needed to get the privilege document std::string usersNamespace; BSONObjBuilder queryBuilder; if (authzVersion == 1) { usersNamespace = mongoutils::str::stream() << dbname << ".system.users"; queryBuilder.append(AuthorizationManager::V1_USER_NAME_FIELD_NAME, userName.getUser()); queryBuilder.appendNull(AuthorizationManager::V1_USER_SOURCE_FIELD_NAME); } else if (authzVersion == 2) { usersNamespace = "admin.system.users"; queryBuilder.append(AuthorizationManager::USER_NAME_FIELD_NAME, userName.getUser()); queryBuilder.append(AuthorizationManager::USER_SOURCE_FIELD_NAME, userName.getDB()); } else { return Status(ErrorCodes::UnsupportedFormat, mongoutils::str::stream() << "Unrecognized authorization format version: " << authzVersion); } // Query for the privilege document BSONObj userBSONObj; Status found = _findUser(usersNamespace, queryBuilder.obj(), &userBSONObj); if (!found.isOK()) { if (found.code() == ErrorCodes::UserNotFound) { // Return more detailed status that includes user name. return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "auth: couldn't find user " << userName.toString() << ", " << usersNamespace, 0); } else { return found; } } *result = userBSONObj.getOwned(); return Status::OK(); }
Status AuthzManagerExternalState::getPrivilegeDocument(const std::string& dbname, const UserName& userName, BSONObj* result) const { if (dbname == StringData("$external", StringData::LiteralTag()) || dbname == AuthorizationManager::SERVER_RESOURCE_NAME || dbname == AuthorizationManager::CLUSTER_RESOURCE_NAME) { return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "No privilege documents stored in the " << dbname << " user source."); } if (!NamespaceString::validDBName(dbname)) { return Status(ErrorCodes::BadValue, "Bad database name \"" + dbname + "\""); } if (userName == internalSecurity.user) { if (internalSecurity.pwd.empty()) { return Status(ErrorCodes::UserNotFound, "key file must be used to log in with internal user", 15889); } *result = BSON(AuthorizationManager::USER_NAME_FIELD_NAME << internalSecurity.user.getUser() << AuthorizationManager::PASSWORD_FIELD_NAME << internalSecurity.pwd).getOwned(); return Status::OK(); } std::string usersNamespace = dbname + ".system.users"; BSONObj userBSONObj; BSONObjBuilder queryBuilder; queryBuilder.append(AuthorizationManager::USER_NAME_FIELD_NAME, userName.getUser()); if (userName.getDB() == dbname) { queryBuilder.appendNull(AuthorizationManager::USER_SOURCE_FIELD_NAME); } else { queryBuilder.append(AuthorizationManager::USER_SOURCE_FIELD_NAME, userName.getDB()); } Status found = _findUser(usersNamespace, queryBuilder.obj(), &userBSONObj); if (!found.isOK()) { if (found.code() == ErrorCodes::UserNotFound) { // Return more detailed status that includes user name. return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "auth: couldn't find user " << userName.toString() << ", " << usersNamespace, 0); } else { return found; } } *result = userBSONObj.getOwned(); return Status::OK(); }
Status AuthzManagerExternalState::getPrivilegeDocumentV1(const StringData& dbname, const UserName& userName, BSONObj* result) { if (userName == internalSecurity.user->getName()) { return Status(ErrorCodes::InternalError, "Requested privilege document for the internal user"); } if (!NamespaceString::validDBName(dbname)) { return Status(ErrorCodes::BadValue, mongoutils::str::stream() << "Bad database name \"" << dbname << "\""); } // Build the query needed to get the privilege document std::string usersNamespace; BSONObjBuilder queryBuilder; usersNamespace = mongoutils::str::stream() << dbname << ".system.users"; queryBuilder.append(AuthorizationManager::V1_USER_NAME_FIELD_NAME, userName.getUser()); if (dbname == userName.getDB()) { queryBuilder.appendNull(AuthorizationManager::V1_USER_SOURCE_FIELD_NAME); } else { queryBuilder.append(AuthorizationManager::V1_USER_SOURCE_FIELD_NAME, userName.getDB()); } // Query for the privilege document BSONObj userBSONObj; Status found = _findUser(usersNamespace, queryBuilder.done(), &userBSONObj); if (!found.isOK()) { if (found.code() == ErrorCodes::UserNotFound) { // Return more detailed status that includes user name. return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "auth: couldn't find user " << userName.toString() << ", " << usersNamespace, 0); } else { return found; } } *result = userBSONObj.getOwned(); return Status::OK(); }
Status AuthExternalState::getPrivilegeDocument(const std::string& dbname, const PrincipalName& principalName, BSONObj* result) { if (principalName.getUser() == internalSecurity.user) { if (internalSecurity.pwd.empty()) { return Status(ErrorCodes::UserNotFound, "key file must be used to log in with internal user", 15889); } *result = BSON(USER_FIELD << internalSecurity.user << PASSWORD_FIELD << internalSecurity.pwd).getOwned(); return Status::OK(); } std::string usersNamespace = dbname + ".system.users"; BSONObj userBSONObj; BSONObjBuilder queryBuilder; queryBuilder.append(USER_FIELD, principalName.getUser()); if (principalName.getDB() == dbname) { queryBuilder.appendNull(USER_SOURCE_FIELD); } else { queryBuilder.append(USER_SOURCE_FIELD, principalName.getDB()); } bool found = _findUser(usersNamespace, queryBuilder.obj(), &userBSONObj); if (!found) { return Status(ErrorCodes::UserNotFound, mongoutils::str::stream() << "auth: couldn't find user " << principalName.toString() << ", " << usersNamespace, 0); } *result = userBSONObj.getOwned(); return Status::OK(); }
Status AuthzManagerExternalStateMongod::getUserDescription(const UserName& userName, BSONObj* result) { BSONObj userDoc; Status status = _findUser( "admin.system.users", BSON(AuthorizationManager::USER_NAME_FIELD_NAME << userName.getUser() << AuthorizationManager::USER_SOURCE_FIELD_NAME << userName.getDB()), &userDoc); if (!status.isOK()) return status; BSONElement directRolesElement; status = bsonExtractTypedField(userDoc, "roles", Array, &directRolesElement); if (!status.isOK()) return status; std::vector<User::RoleData> directRoles; status = V2UserDocumentParser::parseRoleVector(BSONArray(directRolesElement.Obj()), &directRoles); if (!status.isOK()) return status; unordered_set<RoleName> indirectRoles; PrivilegeVector allPrivileges; { boost::lock_guard<boost::mutex> lk(_roleGraphMutex); for (size_t i = 0; i < directRoles.size(); ++i) { const User::RoleData& role(directRoles[i]); if (!role.hasRole) continue; indirectRoles.insert(role.name); if (_roleGraphState == roleGraphStateConsistent) { for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates( role.name); subordinates.more(); subordinates.next()) { indirectRoles.insert(subordinates.get()); } } const PrivilegeVector& rolePrivileges( (_roleGraphState == roleGraphStateConsistent) ? _roleGraph.getAllPrivileges(role.name) : _roleGraph.getDirectPrivileges(role.name)); for (PrivilegeVector::const_iterator priv = rolePrivileges.begin(), end = rolePrivileges.end(); priv != end; ++priv) { Privilege::addPrivilegeToPrivilegeVector(&allPrivileges, *priv); } } } mutablebson::Document resultDoc(userDoc, mutablebson::Document::kInPlaceDisabled); mutablebson::Element indirectRolesElement = resultDoc.makeElementArray("indirectRoles"); mutablebson::Element privilegesElement = resultDoc.makeElementArray("privileges"); mutablebson::Element warningsElement = resultDoc.makeElementArray("warnings"); fassert(17158, resultDoc.root().pushBack(privilegesElement)); fassert(17159, resultDoc.root().pushBack(indirectRolesElement)); if (_roleGraphState != roleGraphStateConsistent) { fassert(17160, warningsElement.appendString( "", "Role graph inconsistent, only direct privileges available.")); } addRoleNameObjectsToArrayElement(indirectRolesElement, makeRoleNameIteratorForContainer(indirectRoles)); addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, allPrivileges); if (warningsElement.hasChildren()) { fassert(17161, resultDoc.root().pushBack(warningsElement)); } *result = resultDoc.getObject(); return Status::OK(); }