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?