Read Permissions to a directory in C#

c#, directory, permissions

Solution

It gets very tricky because ACL's allow inheritance, but they also have a model of most restrictive access. In other words, if you have a DENY anywhere in your user chain to a resource, no matter how many other groups may give you an ALLOW, you are denied. There is a good article on the subect on MSDN.

Problem

I've noticed if you change the security settings for a particular directory, you can make that folder no longer "browsable" in windows. In particular, changing the "Read" permission for Administrators to "Deny" will make that folder inaccessible. The question I now have, is how do I figure this out in code? I following gets me close, but it still ain't right: ``` /// <summary> /// Takes in a directory and determines if the current user has read access to it (doesn't work for network drives) /// THIS IS VERY HACKY /// </summary> /// <param name="dInfo">directoryInfo object to the directory to examine</param> /// <returns>true if read access is available, false otherwise</returns> public static bool IsDirectoryReadable(DirectoryInfo dInfo) { try { System.Security.AccessControl.DirectorySecurity dirSec = dInfo.GetAccessControl(); System.Security.Principal.WindowsIdentity self = System.Security.Principal.WindowsIdentity.GetCurrent(); System.Security.Principal.WindowsPrincipal selfGroup = new System.Security.Principal.WindowsPrincipal(self); // Go through each access rule found for the directory foreach (System.Security.AccessControl.FileSystemAccessRule ar in dirSec.GetAccessRules(true, true, typeof(System.Security.Principal.SecurityIdentifier))) { if (selfGroup.IsInRole((System.Security.Principal.SecurityIdentifier)ar.IdentityReference)) { // See if the Read right is included if ((ar.FileSystemRights & System.Security.AccessControl.FileSystemRights.Read) == System.Security.AccessControl.FileSystemRights.Read) { if (ar.AccessControlType == System.Security.AccessControl.AccessControlType.Allow) { // If all of the above are true, we do have read access to this directory return true; } else { return false; } } } } // If we didn't find anything return false; } catch { // If anything goes wrong, assume false return false; } } ``` I'm close with the above, but I'm still missing something huge. If I right click on a folder to set permissions, I see (in my example) 3 groups or user names: "Administrators, myUserName and SYSTEM". If I set the "Read" to Deny for either "Administrators" or "myUserName" I can no longer browse the directory. If I only set "System" to "Deny", I can still browse it. There seems to be some sort of permission hierarchy implied, where either myUserName or Administrator supersedes the SYSTEM group/user. The code above looks for the first Allow for "Read" it finds for my user identity and returns true. I could also write code that looks for the first "Deny" for Read and returns false. I can set a folder to be Read - "Deny" for SYSTEM and Read - "Allow" for the other two accounts and still read the folder. If I change the code to look for Deny's and it encounters the SYSTEM user identity first, my function will return "false", which is... false. It might very well be Read - "Allow" for the other two accounts. The problem that I still can't figure out is, how can I determine which user identity permission has priority over all of the others?

Original source