Thanks to some answers on SO I've come up with an answer. Although it is not the exact answer to my question, it fulfills my need. On this question's answers I found the solution. This solution tells me if the given FileSystemRights
is bound to the current windows user on acl(AuthorizationRuleCollection
) of given folder.
Almost all answers in the question I've referred to are giving the result, In my opinion the most accurate one is @Olivier Jacot-Descombes's answer since it calculates the allow rules, deny rules, and inherited rules precedences over each other.
So what I did is this:
WindowsIdentity _currentUser;
WindowsPrincipal _currentPrincipal;
using ( new Impersonator(userName, passwordOfTheUser) )
{
_currentUser = WindowsIdentity.GetCurrent();
_currentPrincipal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
}
if ( !Directory.Exists(path) ) throw new Exception("Directory does not exist");
var di = new DirectoryInfo(path);
var directoryACLs = di.GetAccessControl().GetAccessRules(true, true, typeof(SecurityIdentifier));
///rw_accessRules list consists of the rules for ReadWrite permissons.
bool auth_RW = rw_accessRules.All(aR => HasFileOrDirectoryAccess(_currentUser, _currentPrincipal, aR, directoryACLs));
And here is the ``HasFileOrDirectoryAccess` method:
bool HasFileOrDirectoryAccess ( WindowsIdentity _currentUser, WindowsPrincipal _currentPrincipal, FileSystemRights right, AuthorizationRuleCollection acl )
{
bool allow = false;
bool inheritedAllow = false;
bool inheritedDeny = false;
foreach ( FileSystemAccessRule currentRule in acl )
{
// If the current rule applies to the current user.
if ( _currentUser.User.Equals(currentRule.IdentityReference) || _currentPrincipal.IsInRole((SecurityIdentifier)currentRule.IdentityReference) )
{
if ( currentRule.AccessControlType.Equals(AccessControlType.Deny) )
{
if ( ( currentRule.FileSystemRights & right ) == right )
{
if ( currentRule.IsInherited )
{
inheritedDeny = true;
}
else
{ // Non inherited "deny" takes overall precedence.
return false;
}
}
}
else if ( currentRule.AccessControlType.Equals(AccessControlType.Allow) )
{
if ( ( currentRule.FileSystemRights & right ) == right )
{
if ( currentRule.IsInherited )
{
inheritedAllow = true;
}
else
{
allow = true;
}
}
}
}
}
if ( allow )
{ // Non inherited "allow" takes precedence over inherited rules.
return true;
}
return inheritedAllow && !inheritedDeny;
}
I first impersonate for the given user, get his principal and identity, then check if he has the authority of the given rule set.
This one works for my case, but you'll notice that we need password of the user that we want check the permissions of. If there is any way to do this without the password, it will be great.