summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth/role_graph.h
diff options
context:
space:
mode:
authorMark Benvenuto <mark.benvenuto@mongodb.com>2015-06-20 00:22:50 -0400
committerMark Benvenuto <mark.benvenuto@mongodb.com>2015-06-20 10:56:02 -0400
commit9c2ed42daa8fbbef4a919c21ec564e2db55e8d60 (patch)
tree3814f79c10d7b490948d8cb7b112ac1dd41ceff1 /src/mongo/db/auth/role_graph.h
parent01965cf52bce6976637ecb8f4a622aeb05ab256a (diff)
downloadmongo-9c2ed42daa8fbbef4a919c21ec564e2db55e8d60.tar.gz
SERVER-18579: Clang-Format - reformat code, no comment reflow
Diffstat (limited to 'src/mongo/db/auth/role_graph.h')
-rw-r--r--src/mongo/db/auth/role_graph.h528
1 files changed, 263 insertions, 265 deletions
diff --git a/src/mongo/db/auth/role_graph.h b/src/mongo/db/auth/role_graph.h
index bec12b6d1e2..50a0c47a857 100644
--- a/src/mongo/db/auth/role_graph.h
+++ b/src/mongo/db/auth/role_graph.h
@@ -41,273 +41,271 @@
namespace mongo {
+/**
+ * A graph of role and privilege relationships.
+ *
+ * This structure is used to store an in-memory representation of the admin.system.roledata
+ * collection, specifically the graph of which roles are members of other roles and what
+ * privileges each role has, both directly and transitively through membership in other roles.
+ * There are some restrictions on calls to getAllPrivileges(), specifically, one must call
+ * recomputePrivilegeData() before calling getAllPrivileges() if any of the mutation methods
+ * have been called on the instance since the later of its construction or the last call to
+ * recomputePrivilegeData() on the object.
+ */
+class RoleGraph {
+public:
+ /**
+ * Adds to "privileges" the privileges associated with the named built-in role, and returns
+ * true. Returns false if "role" does not name a built-in role, and does not modify
+ * "privileges". Addition of new privileges is done as with
+ * Privilege::addPrivilegeToPrivilegeVector.
+ */
+ static bool addPrivilegesForBuiltinRole(const RoleName& role, PrivilegeVector* privileges);
+
+ RoleGraph();
+ RoleGraph(const RoleGraph& other);
+ ~RoleGraph();
+
+ // Built-in roles for backwards compatibility with 2.2 and prior
+ static const std::string BUILTIN_ROLE_V0_READ;
+ static const std::string BUILTIN_ROLE_V0_READ_WRITE;
+ static const std::string BUILTIN_ROLE_V0_ADMIN_READ;
+ static const std::string BUILTIN_ROLE_V0_ADMIN_READ_WRITE;
+
+ // Swaps the contents of this RoleGraph with those of "other"
+ void swap(RoleGraph& other);
+
+ /**
+ * Adds to "privileges" the necessary privileges to do absolutely anything on the system.
+ */
+ static void generateUniversalPrivileges(PrivilegeVector* privileges);
+
+ /**
+ * Returns an iterator over the RoleNames of the "members" of the given role.
+ * Members of a role are roles that have been granted this role directly (roles that are
+ * members transitively through another role are not included). These are the "parents" of
+ * this node in the graph.
+ */
+ RoleNameIterator getDirectMembers(const RoleName& role);
+
+ /**
+ * Returns an iterator over the RoleNames of the "subordinates" of the given role.
+ * Subordinate roles are the roles that this role has been granted directly (roles
+ * that have been granted transitively through another role are not included). These are
+ * the "children" of this node in the graph.
+ */
+ RoleNameIterator getDirectSubordinates(const RoleName& role);
+
+ /**
+ * Returns an iterator that can be used to get a full list of roles that this role inherits
+ * privileges from. This includes its direct subordinate roles as well as the subordinates
+ * of its subordinates, and so on.
+ */
+ RoleNameIterator getIndirectSubordinates(const RoleName& role);
+
+ /**
+ * Returns an iterator that can be used to get a full list of roles (in lexicographical
+ * order) that are defined on the given database.
+ */
+ RoleNameIterator getRolesForDatabase(const std::string& dbname);
+
+ /**
+ * Returns a vector of the privileges that the given role has been directly granted.
+ * Privileges that have been granted transitively through this role's subordinate roles are
+ * not included.
+ */
+ const PrivilegeVector& getDirectPrivileges(const RoleName& role);
+
/**
- * A graph of role and privilege relationships.
+ * Returns a vector of all privileges that the given role contains. This includes both the
+ * privileges that have been granted to this role directly, as well as any privileges
+ * inherited from the role's subordinate roles.
+ */
+ const PrivilegeVector& getAllPrivileges(const RoleName& role);
+
+ /**
+ * Returns whether or not the given role exists in the role graph. Will implicitly
+ * add the role to the graph if it is a built-in role and isn't already in the graph.
+ */
+ bool roleExists(const RoleName& role);
+
+ /**
+ * Returns whether the given role corresponds to a built-in role.
+ */
+ static bool isBuiltinRole(const RoleName& role);
+
+ // Mutation functions
+
+ /**
+ * Puts an entry into the RoleGraph for the given RoleName.
+ * Returns DuplicateKey if the role already exists.
+ */
+ Status createRole(const RoleName& role);
+
+ /**
+ * Deletes the given role by first removing it from the members/subordinates arrays for
+ * all other roles, and then by removing its own entries in the 4 member maps.
+ * Returns RoleNotFound if the role doesn't exist.
+ * Returns InvalidRoleModification if "role" is a built-in role.
+ */
+ Status deleteRole(const RoleName& role);
+
+ /**
+ * Grants "role" to "recipient". This leaves "recipient" as a member of "role" and "role"
+ * as a subordinate of "recipient".
+ * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in
+ * the RoleGraph.
+ * Returns InvalidRoleModification if "recipient" is a built-in role.
+ */
+ Status addRoleToRole(const RoleName& recipient, const RoleName& role);
+
+ /**
+ * Revokes "role" from "recipient".
+ * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in
+ * the RoleGraph. Returns RolesNotRelated if "recipient" is not currently a
+ * member of "role".
+ * Returns InvalidRoleModification if "role" is a built-in role.
+ */
+ Status removeRoleFromRole(const RoleName& recipient, const RoleName& role);
+
+ /**
+ * Removes all roles held by "victim".
+ * Returns RoleNotFound if "victim" doesn't exist in the role graph.
+ * Returns InvalidRoleModification if "victim" is a built-in role.
+ */
+ Status removeAllRolesFromRole(const RoleName& victim);
+
+ /**
+ * Grants "privilegeToAdd" to "role".
+ * Returns RoleNotFound if "role" doesn't exist in the role graph.
+ * Returns InvalidRoleModification if "role" is a built-in role.
+ */
+ Status addPrivilegeToRole(const RoleName& role, const Privilege& privilegeToAdd);
+
+ /**
+ * Grants Privileges from "privilegesToAdd" to "role".
+ * Returns RoleNotFound if "role" doesn't exist in the role graph.
+ * Returns InvalidRoleModification if "role" is a built-in role.
+ */
+ Status addPrivilegesToRole(const RoleName& role, const PrivilegeVector& privilegesToAdd);
+
+ /**
+ * Removes "privilegeToRemove" from "role".
+ * Returns RoleNotFound if "role" doesn't exist in the role graph.
+ * Returns PrivilegeNotFound if "role" doesn't contain the full privilege being removed.
+ * Returns InvalidRoleModification if "role" is a built-in role.
+ */
+ Status removePrivilegeFromRole(const RoleName& role, const Privilege& privilegeToRemove);
+
+ /**
+ * Removes all privileges in the "privilegesToRemove" vector from "role".
+ * Returns RoleNotFound if "role" doesn't exist in the role graph.
+ * Returns InvalidRoleModification if "role" is a built-in role.
+ * Returns PrivilegeNotFound if "role" is missing any of the privileges being removed. If
+ * PrivilegeNotFound is returned then the graph may be in an inconsistent state and needs to
+ * be abandoned.
+ */
+ Status removePrivilegesFromRole(const RoleName& role,
+ const PrivilegeVector& privilegesToRemove);
+
+ /**
+ * Removes all privileges from "role".
+ * Returns RoleNotFound if "role" doesn't exist in the role graph.
+ * Returns InvalidRoleModification if "role" is a built-in role.
+ */
+ Status removeAllPrivilegesFromRole(const RoleName& role);
+
+ /**
+ * Updates the RoleGraph by adding the role named "roleName", with the given role
+ * memberships and privileges. If the name "roleName" already exists, it is replaced. Any
+ * subordinate roles mentioned in role.roles are created, if needed, with empty privilege
+ * and subordinate role lists.
+ *
+ * Should _only_ fail if the role to replace is a builtin role, in which
+ * case it will return ErrorCodes::InvalidRoleModification.
+ */
+ Status replaceRole(const RoleName& roleName,
+ const std::vector<RoleName>& roles,
+ const PrivilegeVector& privileges);
+
+ /**
+ * Adds the role described in "doc" the role graph.
+ */
+ Status addRoleFromDocument(const BSONObj& doc);
+
+ /**
+ * Applies to the RoleGraph the oplog operation described by the parameters.
*
- * This structure is used to store an in-memory representation of the admin.system.roledata
- * collection, specifically the graph of which roles are members of other roles and what
- * privileges each role has, both directly and transitively through membership in other roles.
- * There are some restrictions on calls to getAllPrivileges(), specifically, one must call
- * recomputePrivilegeData() before calling getAllPrivileges() if any of the mutation methods
- * have been called on the instance since the later of its construction or the last call to
- * recomputePrivilegeData() on the object.
+ * Returns Status::OK() on success, ErrorCodes::OplogOperationUnsupported if the oplog
+ * operation is not supported, and other codes (typically BadValue) if the oplog operation
+ * is ill-described.
*/
- class RoleGraph {
- public:
- /**
- * Adds to "privileges" the privileges associated with the named built-in role, and returns
- * true. Returns false if "role" does not name a built-in role, and does not modify
- * "privileges". Addition of new privileges is done as with
- * Privilege::addPrivilegeToPrivilegeVector.
- */
- static bool addPrivilegesForBuiltinRole(const RoleName& role, PrivilegeVector* privileges);
-
- RoleGraph();
- RoleGraph(const RoleGraph& other);
- ~RoleGraph();
-
- // Built-in roles for backwards compatibility with 2.2 and prior
- static const std::string BUILTIN_ROLE_V0_READ;
- static const std::string BUILTIN_ROLE_V0_READ_WRITE;
- static const std::string BUILTIN_ROLE_V0_ADMIN_READ;
- static const std::string BUILTIN_ROLE_V0_ADMIN_READ_WRITE;
-
- // Swaps the contents of this RoleGraph with those of "other"
- void swap(RoleGraph& other);
-
- /**
- * Adds to "privileges" the necessary privileges to do absolutely anything on the system.
- */
- static void generateUniversalPrivileges(PrivilegeVector* privileges);
-
- /**
- * Returns an iterator over the RoleNames of the "members" of the given role.
- * Members of a role are roles that have been granted this role directly (roles that are
- * members transitively through another role are not included). These are the "parents" of
- * this node in the graph.
- */
- RoleNameIterator getDirectMembers(const RoleName& role);
-
- /**
- * Returns an iterator over the RoleNames of the "subordinates" of the given role.
- * Subordinate roles are the roles that this role has been granted directly (roles
- * that have been granted transitively through another role are not included). These are
- * the "children" of this node in the graph.
- */
- RoleNameIterator getDirectSubordinates(const RoleName& role);
-
- /**
- * Returns an iterator that can be used to get a full list of roles that this role inherits
- * privileges from. This includes its direct subordinate roles as well as the subordinates
- * of its subordinates, and so on.
- */
- RoleNameIterator getIndirectSubordinates(const RoleName& role);
-
- /**
- * Returns an iterator that can be used to get a full list of roles (in lexicographical
- * order) that are defined on the given database.
- */
- RoleNameIterator getRolesForDatabase(const std::string& dbname);
-
- /**
- * Returns a vector of the privileges that the given role has been directly granted.
- * Privileges that have been granted transitively through this role's subordinate roles are
- * not included.
- */
- const PrivilegeVector& getDirectPrivileges(const RoleName& role);
-
- /**
- * Returns a vector of all privileges that the given role contains. This includes both the
- * privileges that have been granted to this role directly, as well as any privileges
- * inherited from the role's subordinate roles.
- */
- const PrivilegeVector& getAllPrivileges(const RoleName& role);
-
- /**
- * Returns whether or not the given role exists in the role graph. Will implicitly
- * add the role to the graph if it is a built-in role and isn't already in the graph.
- */
- bool roleExists(const RoleName& role);
-
- /**
- * Returns whether the given role corresponds to a built-in role.
- */
- static bool isBuiltinRole(const RoleName& role);
-
- // Mutation functions
-
- /**
- * Puts an entry into the RoleGraph for the given RoleName.
- * Returns DuplicateKey if the role already exists.
- */
- Status createRole(const RoleName& role);
-
- /**
- * Deletes the given role by first removing it from the members/subordinates arrays for
- * all other roles, and then by removing its own entries in the 4 member maps.
- * Returns RoleNotFound if the role doesn't exist.
- * Returns InvalidRoleModification if "role" is a built-in role.
- */
- Status deleteRole(const RoleName& role);
-
- /**
- * Grants "role" to "recipient". This leaves "recipient" as a member of "role" and "role"
- * as a subordinate of "recipient".
- * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in
- * the RoleGraph.
- * Returns InvalidRoleModification if "recipient" is a built-in role.
- */
- Status addRoleToRole(const RoleName& recipient, const RoleName& role);
-
- /**
- * Revokes "role" from "recipient".
- * Returns RoleNotFound if either of "role" or "recipient" doesn't exist in
- * the RoleGraph. Returns RolesNotRelated if "recipient" is not currently a
- * member of "role".
- * Returns InvalidRoleModification if "role" is a built-in role.
- */
- Status removeRoleFromRole(const RoleName& recipient, const RoleName& role);
-
- /**
- * Removes all roles held by "victim".
- * Returns RoleNotFound if "victim" doesn't exist in the role graph.
- * Returns InvalidRoleModification if "victim" is a built-in role.
- */
- Status removeAllRolesFromRole(const RoleName& victim);
-
- /**
- * Grants "privilegeToAdd" to "role".
- * Returns RoleNotFound if "role" doesn't exist in the role graph.
- * Returns InvalidRoleModification if "role" is a built-in role.
- */
- Status addPrivilegeToRole(const RoleName& role, const Privilege& privilegeToAdd);
-
- /**
- * Grants Privileges from "privilegesToAdd" to "role".
- * Returns RoleNotFound if "role" doesn't exist in the role graph.
- * Returns InvalidRoleModification if "role" is a built-in role.
- */
- Status addPrivilegesToRole(const RoleName& role, const PrivilegeVector& privilegesToAdd);
-
- /**
- * Removes "privilegeToRemove" from "role".
- * Returns RoleNotFound if "role" doesn't exist in the role graph.
- * Returns PrivilegeNotFound if "role" doesn't contain the full privilege being removed.
- * Returns InvalidRoleModification if "role" is a built-in role.
- */
- Status removePrivilegeFromRole(const RoleName& role,
- const Privilege& privilegeToRemove);
-
- /**
- * Removes all privileges in the "privilegesToRemove" vector from "role".
- * Returns RoleNotFound if "role" doesn't exist in the role graph.
- * Returns InvalidRoleModification if "role" is a built-in role.
- * Returns PrivilegeNotFound if "role" is missing any of the privileges being removed. If
- * PrivilegeNotFound is returned then the graph may be in an inconsistent state and needs to
- * be abandoned.
- */
- Status removePrivilegesFromRole(const RoleName& role,
- const PrivilegeVector& privilegesToRemove);
-
- /**
- * Removes all privileges from "role".
- * Returns RoleNotFound if "role" doesn't exist in the role graph.
- * Returns InvalidRoleModification if "role" is a built-in role.
- */
- Status removeAllPrivilegesFromRole(const RoleName& role);
-
- /**
- * Updates the RoleGraph by adding the role named "roleName", with the given role
- * memberships and privileges. If the name "roleName" already exists, it is replaced. Any
- * subordinate roles mentioned in role.roles are created, if needed, with empty privilege
- * and subordinate role lists.
- *
- * Should _only_ fail if the role to replace is a builtin role, in which
- * case it will return ErrorCodes::InvalidRoleModification.
- */
- Status replaceRole(const RoleName& roleName,
- const std::vector<RoleName>& roles,
- const PrivilegeVector& privileges);
-
- /**
- * Adds the role described in "doc" the role graph.
- */
- Status addRoleFromDocument(const BSONObj& doc);
-
- /**
- * Applies to the RoleGraph the oplog operation described by the parameters.
- *
- * Returns Status::OK() on success, ErrorCodes::OplogOperationUnsupported if the oplog
- * operation is not supported, and other codes (typically BadValue) if the oplog operation
- * is ill-described.
- */
- Status handleLogOp(
- const char* op,
- const NamespaceString& ns,
- const BSONObj& o,
- const BSONObj* o2);
-
- /**
- * Recomputes the indirect (getAllPrivileges) data for this graph.
- *
- * Must be called between calls to any of the mutation functions and calls
- * to getAllPrivileges().
- *
- * Returns Status::OK() on success. If a cycle is detected, returns
- * ErrorCodes::GraphContainsCycle, and the status message reveals the cycle.
- */
- Status recomputePrivilegeData();
-
- private:
- // Helper method doing a topological DFS to compute the indirect privilege
- // data and look for cycles
- Status _recomputePrivilegeDataHelper(const RoleName& currentRole,
- unordered_set<RoleName>& visitedRoles);
-
- /**
- * If the role name given is not a built-in role, or it is but it's already in the role
- * graph, then this does nothing. If it *is* a built-in role and this is the first time
- * this function has been called for this role, it will add the role into the role graph.
- */
- void _createBuiltinRoleIfNeeded(const RoleName& role);
-
- /**
- * Adds the built-in roles for the given database name to the role graph if they aren't
- * already present.
- */
- void _createBuiltinRolesForDBIfNeeded(const std::string& dbname);
-
- /**
- * Returns whether or not the given role exists strictly within the role graph.
- */
- bool _roleExistsDontCreateBuiltin(const RoleName& role);
-
- /**
- * Just creates the role in the role graph, without checking whether or not the role already
- * exists.
- */
- void _createRoleDontCheckIfRoleExists(const RoleName& role);
-
- /**
- * Grants "privilegeToAdd" to "role".
- * Doesn't do any checking as to whether the role exists or is a built-in role.
- */
- void _addPrivilegeToRoleNoChecks(const RoleName& role, const Privilege& privilegeToAdd);
-
-
- // Represents all the outgoing edges to other roles from any given role.
- typedef unordered_map<RoleName, std::vector<RoleName> > EdgeSet;
- // Maps a role name to a list of privileges associated with that role.
- typedef unordered_map<RoleName, PrivilegeVector> RolePrivilegeMap;
-
- EdgeSet _roleToSubordinates;
- unordered_map<RoleName, unordered_set<RoleName> > _roleToIndirectSubordinates;
- EdgeSet _roleToMembers;
- RolePrivilegeMap _directPrivilegesForRole;
- RolePrivilegeMap _allPrivilegesForRole;
- std::set<RoleName> _allRoles;
- };
-
- void swap(RoleGraph& lhs, RoleGraph& rhs);
+ Status handleLogOp(const char* op,
+ const NamespaceString& ns,
+ const BSONObj& o,
+ const BSONObj* o2);
+
+ /**
+ * Recomputes the indirect (getAllPrivileges) data for this graph.
+ *
+ * Must be called between calls to any of the mutation functions and calls
+ * to getAllPrivileges().
+ *
+ * Returns Status::OK() on success. If a cycle is detected, returns
+ * ErrorCodes::GraphContainsCycle, and the status message reveals the cycle.
+ */
+ Status recomputePrivilegeData();
+
+private:
+ // Helper method doing a topological DFS to compute the indirect privilege
+ // data and look for cycles
+ Status _recomputePrivilegeDataHelper(const RoleName& currentRole,
+ unordered_set<RoleName>& visitedRoles);
+
+ /**
+ * If the role name given is not a built-in role, or it is but it's already in the role
+ * graph, then this does nothing. If it *is* a built-in role and this is the first time
+ * this function has been called for this role, it will add the role into the role graph.
+ */
+ void _createBuiltinRoleIfNeeded(const RoleName& role);
+
+ /**
+ * Adds the built-in roles for the given database name to the role graph if they aren't
+ * already present.
+ */
+ void _createBuiltinRolesForDBIfNeeded(const std::string& dbname);
+
+ /**
+ * Returns whether or not the given role exists strictly within the role graph.
+ */
+ bool _roleExistsDontCreateBuiltin(const RoleName& role);
+
+ /**
+ * Just creates the role in the role graph, without checking whether or not the role already
+ * exists.
+ */
+ void _createRoleDontCheckIfRoleExists(const RoleName& role);
+
+ /**
+ * Grants "privilegeToAdd" to "role".
+ * Doesn't do any checking as to whether the role exists or is a built-in role.
+ */
+ void _addPrivilegeToRoleNoChecks(const RoleName& role, const Privilege& privilegeToAdd);
+
+
+ // Represents all the outgoing edges to other roles from any given role.
+ typedef unordered_map<RoleName, std::vector<RoleName>> EdgeSet;
+ // Maps a role name to a list of privileges associated with that role.
+ typedef unordered_map<RoleName, PrivilegeVector> RolePrivilegeMap;
+
+ EdgeSet _roleToSubordinates;
+ unordered_map<RoleName, unordered_set<RoleName>> _roleToIndirectSubordinates;
+ EdgeSet _roleToMembers;
+ RolePrivilegeMap _directPrivilegesForRole;
+ RolePrivilegeMap _allPrivilegesForRole;
+ std::set<RoleName> _allRoles;
+};
+
+void swap(RoleGraph& lhs, RoleGraph& rhs);
} // namespace mongo