0

I have a simple job which I don't know how to accomplish, and as deeper I search it I got lost deeper.

I need to write a method which returns the FileSystemAccessRule of a given user(I am given his samAccountName, objectGUID) over a given folder path.

I've done adding or removing FileSystemAccessRule's to a path before like this:

var fSecurity = Directory.GetAccessControl(physicalPath);

fSecurity.AddAccessRule(new FileSystemAccessRule(samAccountName, FileSystemRights.FullControl, AccessControlType.Allow));
fSecurity.RemoveAccessRule(new FileSystemAccessRule(samAccountName, FileSystemRights.FullControl, AccessControlType.Allow));

Directory.SetAccessControl(physicalPath, fSecurity);

Checking if the given user has some certain the access rights over a path a similiar job? Or should go to another way? Something like DirectoryEntry or LDAP or Active Directory or so?

What I want is a method which maybe looks like this:

FileSystemAccessRule[] GetAccessRulesOfTheUserOverPath(string samAccountName, string folderPath)
{
    /// how?
}
Tolga Evcimen
  • 7,112
  • 11
  • 58
  • 91

1 Answers1

0

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.

Community
  • 1
  • 1
Tolga Evcimen
  • 7,112
  • 11
  • 58
  • 91