Status AuthzManagerExternalStateLocal::_getRoleDescription_inlock(const RoleName& roleName, bool showPrivileges, BSONObj* result) { if (!_roleGraph.roleExists(roleName)) return Status(ErrorCodes::RoleNotFound, "No role named " + roleName.toString()); mutablebson::Document resultDoc; fassert(17162, resultDoc.root().appendString( AuthorizationManager::ROLE_NAME_FIELD_NAME, roleName.getRole())); fassert(17163, resultDoc.root().appendString( AuthorizationManager::ROLE_SOURCE_FIELD_NAME, roleName.getDB())); fassert(17267, resultDoc.root().appendBool("isBuiltin", _roleGraph.isBuiltinRole(roleName))); mutablebson::Element rolesElement = resultDoc.makeElementArray("roles"); fassert(17164, resultDoc.root().pushBack(rolesElement)); mutablebson::Element inheritedRolesElement = resultDoc.makeElementArray("inheritedRoles"); fassert(17165, resultDoc.root().pushBack(inheritedRolesElement)); mutablebson::Element privilegesElement = resultDoc.makeElementArray("privileges"); mutablebson::Element inheritedPrivilegesElement = resultDoc.makeElementArray("inheritedPrivileges"); if (showPrivileges) { fassert(17166, resultDoc.root().pushBack(privilegesElement)); } mutablebson::Element warningsElement = resultDoc.makeElementArray("warnings"); addRoleNameObjectsToArrayElement(rolesElement, _roleGraph.getDirectSubordinates(roleName)); if (_roleGraphState == roleGraphStateConsistent) { addRoleNameObjectsToArrayElement( inheritedRolesElement, _roleGraph.getIndirectSubordinates(roleName)); if (showPrivileges) { addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, _roleGraph.getDirectPrivileges(roleName)); addPrivilegeObjectsOrWarningsToArrayElement( inheritedPrivilegesElement, warningsElement, _roleGraph.getAllPrivileges(roleName)); fassert(17323, resultDoc.root().pushBack(inheritedPrivilegesElement)); } } else if (showPrivileges) { warningsElement.appendString( "", "Role graph state inconsistent; only direct privileges available."); addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, _roleGraph.getDirectPrivileges(roleName)); } if (warningsElement.hasChildren()) { fassert(17167, resultDoc.root().pushBack(warningsElement)); } *result = resultDoc.getObject(); return Status::OK(); }
Status AuthzManagerExternalStateMock::getUserDescription( const UserName& userName, BSONObj* result) { BSONObj privDoc; Status status = getPrivilegeDocument(userName, 2, &privDoc); if (!status.isOK()) return status; unordered_set<RoleName> indirectRoles; PrivilegeVector allPrivileges; for (BSONObjIterator iter(privDoc["roles"].Obj()); iter.more(); iter.next()) { if (!(*iter)["hasRole"].trueValue()) continue; RoleName roleName((*iter)[AuthorizationManager::ROLE_NAME_FIELD_NAME].str(), (*iter)[AuthorizationManager::ROLE_SOURCE_FIELD_NAME].str()); indirectRoles.insert(roleName); for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates( roleName); subordinates.more(); subordinates.next()) { indirectRoles.insert(subordinates.get()); } const PrivilegeVector& rolePrivileges(_roleGraph.getAllPrivileges(roleName)); for (PrivilegeVector::const_iterator priv = rolePrivileges.begin(), end = rolePrivileges.end(); priv != end; ++priv) { Privilege::addPrivilegeToPrivilegeVector(&allPrivileges, *priv); } } mutablebson::Document userDoc(privDoc, mutablebson::Document::kInPlaceDisabled); mutablebson::Element indirectRolesElement = userDoc.makeElementArray("indirectRoles"); mutablebson::Element privilegesElement = userDoc.makeElementArray("privileges"); mutablebson::Element warningsElement = userDoc.makeElementArray("warnings"); fassert(17180, userDoc.root().pushBack(privilegesElement)); fassert(17181, userDoc.root().pushBack(indirectRolesElement)); addRoleNameObjectsToArrayElement(indirectRolesElement, makeRoleNameIteratorForContainer(indirectRoles)); addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, allPrivileges); if (warningsElement.hasChildren()) { fassert(17182, userDoc.root().pushBack(warningsElement)); } *result = userDoc.getObject(); return Status::OK(); }
Status AuthzManagerExternalStateLocal::getUserDescription( const UserName& userName, BSONObj* result) { BSONObj userDoc; Status status = _getUserDocument(userName, &userDoc); if (!status.isOK()) return status; BSONElement directRolesElement; status = bsonExtractTypedField(userDoc, "roles", Array, &directRolesElement); if (!status.isOK()) return status; std::vector<RoleName> directRoles; status = V2UserDocumentParser::parseRoleVector(BSONArray(directRolesElement.Obj()), &directRoles); if (!status.isOK()) return status; unordered_set<RoleName> indirectRoles; PrivilegeVector allPrivileges; bool isRoleGraphInconsistent; { boost::lock_guard<boost::mutex> lk(_roleGraphMutex); isRoleGraphInconsistent = _roleGraphState == roleGraphStateConsistent; for (size_t i = 0; i < directRoles.size(); ++i) { const RoleName& role(directRoles[i]); indirectRoles.insert(role); if (isRoleGraphInconsistent) { for (RoleNameIterator subordinates = _roleGraph.getIndirectSubordinates(role); subordinates.more(); subordinates.next()) { indirectRoles.insert(subordinates.get()); } } const PrivilegeVector& rolePrivileges( isRoleGraphInconsistent ? _roleGraph.getAllPrivileges(role) : _roleGraph.getDirectPrivileges(role)); 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 inheritedRolesElement = resultDoc.makeElementArray("inheritedRoles"); mutablebson::Element privilegesElement = resultDoc.makeElementArray("inheritedPrivileges"); mutablebson::Element warningsElement = resultDoc.makeElementArray("warnings"); fassert(17159, resultDoc.root().pushBack(inheritedRolesElement)); fassert(17158, resultDoc.root().pushBack(privilegesElement)); if (!isRoleGraphInconsistent) { fassert(17160, warningsElement.appendString( "", "Role graph inconsistent, only direct privileges available.")); } addRoleNameObjectsToArrayElement(inheritedRolesElement, makeRoleNameIteratorForContainer(indirectRoles)); addPrivilegeObjectsOrWarningsToArrayElement( privilegesElement, warningsElement, allPrivileges); if (warningsElement.hasChildren()) { fassert(17161, resultDoc.root().pushBack(warningsElement)); } *result = resultDoc.getObject(); return Status::OK(); }