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.
Comments
- Anonymous
October 31, 2004
Of course the really annoying thing is that mscorlib has an "internal" version of all the named permission sets that are used for the PermissionSetAttribute... argh! Make them public!!! :-) - Anonymous
February 01, 2006
The comment has been removed - Anonymous
November 14, 2006
Every once in a while I find some code doing something similar to this: new NamedPermissionSet ( "LocalIntranet"