C# Get “Apply To” information from “Advanced Secur

2019-06-05 02:11发布

问题:

I'm writing an application that is used to search through folders for their permissions and return details such as Rights (eg Full Control, Read), AccessControlType (eg Allow, Deny) and Apply To information (eg This folder, subfolders and files).

Most of this information I am able to obtain using DirectoryInfo's GetAccessControl(DirectorySecurity) method. However, I can't accurately obtain the directory's Apply To information. After much research I came across this StackOverflow Q&A How to change the "Applies To" field under folder auditing options programatically (.NET) which led me to this comprehensive page http://msmvps.com/blogs/p3net/pages/access-control-in-net.aspx but using the rules that both specify, I do not get the same Apply To permissions as I do in Windows Explorer.

(Table from http://msmvps.com/blogs/p3net/pages/access-control-in-net.aspx)

This is the code I use to try and convert a combination of InheritanceFlags and PropogationFlags:

private ApplyToType GetApplyToType(InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
{
    if (propagationFlags == PropagationFlags.None && 
        inheritanceFlags == InheritanceFlags.None) 
        return ApplyToType.ThisFolderOnly;

    if (propagationFlags == PropagationFlags.None && 
        inheritanceFlags == InheritanceFlags.ContainerInherit) 
        return ApplyToType.ThisFolderAndSubfolders;

    if (propagationFlags == PropagationFlags.None && 
        inheritanceFlags == InheritanceFlags.ObjectInherit) 
        return ApplyToType.ThisFolderAndFiles;

    if (propagationFlags == PropagationFlags.None && 
        inheritanceFlags == (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit)) 
        return ApplyToType.ThisFolderSubfoldersAndFiles;

    if (propagationFlags == PropagationFlags.InheritOnly && 
        inheritanceFlags == InheritanceFlags.ContainerInherit)
        return ApplyToType.SubfoldersOnly;

    if (propagationFlags == PropagationFlags.InheritOnly && 
        inheritanceFlags == InheritanceFlags.ObjectInherit)
        return ApplyToType.FilesOnly;

    if (propagationFlags == PropagationFlags.InheritOnly && 
        inheritanceFlags == (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit))
        return ApplyToType.SubfoldersAndFilesOnly;

    return ApplyToType.AndreDoesntKnow;
}

And the following code is used to query directories:

var directory = new DirectoryInfo(directoryPath);
var accessControl = directory.GetAccessControl(AccessControlSections.Access);
var rules = accessControl.GetAccessRules(includeExplicit, includeInherited, targetType);
foreach (FileSystemAccessRule rule in rules)
{
    var applyToType = GetApplyToType(rule.InheritanceFlags, rule.PropagationFlags);
    Console.WriteLine(string.Format("Identity:{0}, Rights:{1}, AccessType:{2}, ApplyTo:{3}", rule.IdentityReference, rule.FileSystemRights, rule.AccessControlType, applyToType));
}

However when I look at these permissions in Windows Explorer I see the following:

And when I use my application to query the same folder, I get:

  • Identity:BUILTIN\Administrators, Rights:FullControl, AccessType:Allow, ApplyTo:ThisFolderOnly

  • Identity:BUILTIN\Administrators, Rights:268435456, AccessType:Allow, ApplyTo:SubfoldersAndFilesOnly

  • Identity:NT AUTHORITY\SYSTEM, Rights:FullControl, AccessType:Allow, ApplyTo:ThisFolderOnly

  • Identity:NT AUTHORITY\SYSTEM, Rights:268435456, AccessType:Allow, ApplyTo:SubfoldersAndFilesOnly

  • Identity:BUILTIN\Users, Rights:ReadAndExecute, Synchronize, AccessType:Allow, ApplyTo:ThisFolderSubfoldersAndFiles

  • Identity:NT AUTHORITY\Authenticated Users, Rights:Modify, Synchronize, AccessType:Allow, ApplyTo:ThisFolderOnly

  • Identity:NT AUTHORITY\Authenticated Users, Rights:-536805376, AccessType:Allow, ApplyTo:SubfoldersAndFilesOnly

As you can see, using the rules from these other sites, my derived ApplyTo does not match with Windows Explorer ApplyTo.

Is there more to it than this? What am I doing wrong? What else do I need to resolve the same ApplyTo rules that Windows Explorer reports?

I should also mention that these results were from my development PC which is running Windows 7 x64. According to our users, on their work environment (Windows XP x86), they observe the correct behavior. I don't know enough about Windows permissions to know whether there are differences in them between Windows 7 x64 and Window XP x86.

回答1:

All of this looks correct to me. The one thing I would try is, over the years, I've learned not to check flags with just

propagationFlags == PropagationFlags.None

Isntead, I tend to use

(propagationFlags & PropagationFlags.None) == PropagationFlags.None

This makes my code more resilient if new flags show up on the bit fields as new versions of APIs come around.

This principle applies even with the more complicated expressions, such as

(inheritanceFlags & (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit)) == (InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit)

That's the one thing I would try right away.