Getting the Current Permissions in a Named Permission Set

There are several named permission sets defined by default in the CLR security policy:

  • FullTrust
  • SkipVerification
  • Execution
  • Nothing
  • LocalIntranet
  • Internet
  • Everything

These sets are used to create the default policy, however there's nothing stopping any user from modifying them (adding or removing permissions for instance), or creating their own named permission sets.  Sometimes its useful to be able to determine what permissions are in each named permission set from code.

At first glance this seems easy ... since the PolicyLevel class exposes a GetNamedPermissionSet method.  However, there are several complications along the way.  To start with, we'll need to check each policy level, since nothing is stopping someone from defining another set of permissions with the same name on another level.

OK, to solve that problem, we can just loop over each level, and check to see if there's a named permission set on that level.  If there is a named set on multiple levels, we'll need to merge them together.  I've chosen to intersect them which leads to another interesting problem.  Intersecting permission sets can result in a null return if the intersection is an empty set.

With all that in mind, it becomes pretty easy to write this method:

/// <summary>
/// Get a named permission set from the security policy
/// </summary>
/// <param name="name">Name of the permission set to retrieve</param>
/// <exception cref="ArgumentException">If name is null or empty</exception>
/// <returns>
/// The intersection of permission sets with the given name from all policy
/// levels, or an empty set if the name is not found
/// </returns>
public static PermissionSet GetNamedPermissionSet(string name)
{
    if(String.IsNullOrEmpty(name))
        throw new ArgumentException("name", "Cannot search for a permission set without a name");

    bool foundName = false;
    PermissionSet setIntersection = new PermissionSet(PermissionState.Unrestricted);

    // iterate over each policy level
    IEnumerator levelEnumerator = SecurityManager.PolicyHierarchy();
    while(levelEnumerator.MoveNext())
    {
        PolicyLevel level = levelEnumerator.Current as PolicyLevel;
        Debug.Assert(level != null);

        // if this level has defined a named permission set with the
        // given name, then intersect it with what we've retrieved
        // from all the previous levels
        PermissionSet levelSet = level.GetNamedPermissionSet(name);
        if(levelSet != null)
        {
            foundName = true;
            setIntersection = setIntersection.Intersect(levelSet);
        }
    }

     // Intersect() can return null for an empty set, so convert that
    // to an empty set object. Also return an empty set if we didn't find
    // the named permission set we were looking for
    if(setIntersection == null || !foundName)
        setIntersection = new PermissionSet(PermissionState.None);
    else
        setIntersection = new NamedPermissionSet(name, setIntersection);

    // if no named permission sets were found, return an empty set,
    // otherwise return the set that was found
    return setIntersection;
}

Using this method is equally easy.  Calling GetNamedPermissionSet("Internet") will retrieve you the current set of permissions in the Internet permission set on all policy levels.