summaryrefslogtreecommitdiff
path: root/src/mongo/db/auth/privilege_set.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/auth/privilege_set.h')
-rw-r--r--src/mongo/db/auth/privilege_set.h127
1 files changed, 96 insertions, 31 deletions
diff --git a/src/mongo/db/auth/privilege_set.h b/src/mongo/db/auth/privilege_set.h
index 7033e738a4d..1c110f13681 100644
--- a/src/mongo/db/auth/privilege_set.h
+++ b/src/mongo/db/auth/privilege_set.h
@@ -22,51 +22,116 @@
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/privilege.h"
-#include "mongo/db/auth/principal.h"
+#include "mongo/db/auth/principal_name.h"
+#include "mongo/util/string_map.h"
namespace mongo {
/**
- * A collection of privileges describing which authenticated principals bestow the client
- * the ability to perform various actions on specific resources. Since every privilege
- * comes from an authenticated principal, removing that principal can remove all privileges
- * that that principal granted.
+ * A collection of privileges describing which authenticated principals bestow the client the
+ * ability to perform various actions on specific resources. Since every privilege comes from
+ * an authenticated principal, removing that principal removes all privileges granted by that
+ * principal.
+ *
+ * Resources are arranged hierarchically, with a wildcard resource,
+ * PrivilegeSet::WILDCARD_RESOURCE, matching any resource. In the current implementation, the
+ * only two levels of the hierarchy are the wildcard and one level below, which is analagous to
+ * the name of a database. It is future work to support collection or other sub-database
+ * resources.
+ *
* This class does not do any locking/synchronization, the consumer will be responsible for
* synchronizing access.
*/
class PrivilegeSet {
MONGO_DISALLOW_COPYING(PrivilegeSet);
public:
- PrivilegeSet(){}
- ~PrivilegeSet(){}
-
- void grantPrivilege(const AcquiredPrivilege& privilege);
- void revokePrivilegesFromPrincipal(Principal* principal);
-
- // Returns the first privilege found that grants the given action on the given resource.
- // Returns NULL if there is no such privilege.
- // Ownership of the returned Privilege remains with the PrivilegeSet. The pointer
- // returned is only guaranteed to remain valid until the next non-const method is called
- // on the PrivilegeSet.
- const AcquiredPrivilege* getPrivilegeForAction(const std::string& resource,
- const ActionType& action) const;
- // Same as above but takes an ActionSet. The AcquiredPrivilege returned must include
- // permission to perform all the actions in the ActionSet on the given resource.
- const AcquiredPrivilege* getPrivilegeForActions(const std::string& resource,
- const ActionSet& action) const;
+ static const std::string WILDCARD_RESOURCE;
+
+ PrivilegeSet();
+ ~PrivilegeSet();
+
+ /**
+ * Adds the specified privilege to the set, associating it with the named principal.
+ *
+ * The privilege should be on a specific resource, or on the WILDCARD_RESOURCE.
+ */
+ void grantPrivilege(const Privilege& privilege, const PrincipalName& authorizingPrincipal);
+
+ /**
+ * Adds the specified privileges to the set, associating them with the named principal.
+ */
+ void grantPrivileges(const std::vector<Privilege>& privileges,
+ const PrincipalName& authorizingPrincipal);
+
+ /**
+ * Removes from the set all privileges associated with the given principal.
+ *
+ * If multiple princpals enable the same privilege, the set will continue to
+ * contain those privileges until all authorizing principals have had their
+ * privileges revoked from the set.
+ */
+ void revokePrivilegesFromPrincipal(const PrincipalName& principal);
+
+ /**
+ * Returns true if the set authorizes "desiredPrivilege".
+ *
+ * The set is considered to authorize "desiredPrivilege" if each action in
+ * "desiredPrivilege" is satisfied either on "desiredPrivilege.getResource()" or on
+ * WILDCARD_RESOURCE.
+ */
+ bool hasPrivilege(const Privilege& desiredPrivilege);
+
+ /**
+ * Same as hasPrivilege, except checks all the privileges in a vector.
+ */
+ bool hasPrivileges(const std::vector<Privilege>& desiredPrivileges);
private:
- // Key is the resource the privilege is on.
- typedef std::multimap<const std::string, AcquiredPrivilege> PrivilegeMap;
- typedef PrivilegeMap::iterator PrivilegeRangeIterator;
- typedef std::pair<PrivilegeRangeIterator, PrivilegeRangeIterator> PrivilegeSetRange;
- typedef PrivilegeMap::const_iterator PrivilegeRangeConstIterator;
- typedef std::pair<PrivilegeRangeConstIterator, PrivilegeRangeConstIterator>
- PrivilegeSetConstRange;
+ /**
+ * Information about privileges held on a resource.
+ *
+ * Instances are stored in the _byResource map, and accelerate the fast path of
+ * hasPrivilege(). Privilege revocations via revokePrivilegesFromPrincipal() can make these
+ * entries invalid, at which point they are marked "dirty". Dirty entries are rebuilt via
+ * _rebuildEntry(), below, during execution of hasPrivilege().
+ */
+ class ResourcePrivilegeCacheEntry {
+ public:
+ ResourcePrivilegeCacheEntry() : actions(), dirty(false) {}
+
+ // All actions enabled on the associated resource, provided that "dirty" is false.
+ ActionSet actions;
+
+ // False if this data is consistent with the full privilege information, stored in the
+ // _byPrincipal map.
+ bool dirty;
+ };
+
+ /**
+ * Type of map from resource names to authorized actions.
+ */
+ typedef StringMap<ResourcePrivilegeCacheEntry> ResourcePrivilegeCache;
+
+ /**
+ * Type of map from principal identity to information about the principal's privileges. The
+ * values in the map are themselves maps from resource names to associated actions.
+ */
+ typedef std::map<PrincipalName, StringMap<ActionSet> > PrincipalPrivilegeMap;
+
+ void _rebuildEntry(const StringData& resource, ResourcePrivilegeCacheEntry* summary);
+
+ ResourcePrivilegeCacheEntry* _lookupEntry(const StringData& resource);
+ ResourcePrivilegeCacheEntry* _lookupOrInsertEntry(const StringData& resource);
+
+ // Information about privileges available on all resources.
+ ResourcePrivilegeCacheEntry _globalPrivilegeEntry;
+
+ // Cache of privilege information, by resource.
+ ResourcePrivilegeCache _byResource;
- // Maps resource to privileges
- PrivilegeMap _privileges;
+ // Directory of privilege information, by principal.
+ PrincipalPrivilegeMap _byPrincipal;
};
} // namespace mongo