Logic for determining if a user has write access to a folder not working

652 views Asked by At

I have the following method in a dialog in my application that is intended to determine if a user has write access to a folder:

private bool UserCanWriteToFolder( FileSystemNode node ) {
    try {
        WindowsIdentity currentUser = WindowsIdentity.GetCurrent();
        WindowsPrincipal principal = new WindowsPrincipal( currentUser );

        DirectoryInfo directoryInfo = new DirectoryInfo( node.FullPath );
        DirectorySecurity acl = directoryInfo.GetAccessControl( AccessControlSections.All );

        AuthorizationRuleCollection rules = acl.GetAccessRules( true, true, typeof( NTAccount ) );

        foreach ( AuthorizationRule rule in rules ) {
            FileSystemAccessRule fsAccessRule = rule as FileSystemAccessRule;
            if ( fsAccessRule == null )
                continue;

            if ( ( fsAccessRule.FileSystemRights & FileSystemRights.WriteData ) > 0 ) {
                NTAccount ntAccount = rule.IdentityReference as NTAccount;
                if ( ntAccount == null )
                    continue;

                if ( principal.IsInRole( ntAccount.Value ) )
                    return true;
            }
        }
    } catch ( Exception ) {
        return false;
    }
    return false;
}

This logic works, but there is a problem.

My user is in the Administrators group. When I choose the C:\Windows folder, this method returns true, yet, when my program tries to write to the C:\Windows folder, the program throws an UnauthorizedAccessException. Obviously there's something different about that folder that my code isn't taking into account.

Here's the output of iacls for the C:\Windows folder on my machine:

C:\Windows NT SERVICE\TrustedInstaller:(F)
           NT SERVICE\TrustedInstaller:(CI)(IO)(F)
           NT AUTHORITY\SYSTEM:(M)
           NT AUTHORITY\SYSTEM:(OI)(CI)(IO)(F)
           BUILTIN\Administrators:(M)
           BUILTIN\Administrators:(OI)(CI)(IO)(F)
           BUILTIN\Users:(RX)
           BUILTIN\Users:(OI)(CI)(IO)(GR,GE)
           CREATOR OWNER:(OI)(CI)(IO)(F)
           APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(RX)
           APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(OI)(CI)(IO)(GR,GE)

Successfully processed 1 files; Failed processing 0 files

Unfortunately, I don't know which line in the ACL is the one that's causing the UnauthorizedAccessException to be thrown. Can someone point out the problem to me?

1

There are 1 answers

1
Tony Vitabile On

I've decided to abandon the above code. When I start the program as a normal user, the line that retrieves the ACL throws a PrivilegeNotHeldException. Specifically, the message text reads

The process does not possess the 'SeSecurityPrivilege' privilege which is required for this operation.

At this point, what I'm going to do is try to create a temporary file in the selected folder. If that succeeds, I'll delete it and return true. If that fails (an exception is thrown), I'll return false. In any case, I have to catch any exceptions that occur when actually writing to the folder and display a useful error message, since, as has been said in the comments, the security could change between this method exits and the write is performed.