Using C# to get a list of ACLs for Servers and map

2019-02-02 10:04发布

问题:

The production change implementers for our IT group have been tasked with reviewing the security for all of the various objects in our group, primarily to make sure that people who have left our employ or have transferred to other groups no longer have access to our server shares, web directories, sql databases, etc etc. We recently completed the SQL portion and we have a re-usable script that can be run annually (or at whatever frequency we come up with). It worked great and we audited 20 databases across 10 or so servers withing a few minutes.

Now, for the server stuff. I have an application that I wrote in C# using .NET 2.0 that will recursively scan a list of directories and dump the ACLs to a text file. This works excellent. On the local machine. UNC and Mapped paths do not work, I get the following exception message: The process does not possess the 'SeSecurityPrivilege' privilege which is required for this operation.

On this line:

DirectorySecurity DirSec = di.GetAccessControl(AccessControlSections.All);

Where di is a DirectoryInfo object enumerated from a DirectoryInfo[] array.

We are not likely going to be able to be granted the SeSecurityPrivilege privilege. However I don't think this should be necessary. I can open the folder and right click for properties and click the security tab and view it in the GUI. I should be able to access it programmatically as well.

Any thoughts on how I can change this section of code to get the permissions for the targeted folder?

private void CheckSecurity(DirectoryInfo[] DIArray)
{
    foreach (DirectoryInfo di in DIArray)
    {
        DirectorySecurity DirSec = di.GetAccessControl(AccessControlSections.All);
        string sAccessInfo = string.Empty;

        foreach (FileSystemAccessRule FSAR in DirSec.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount)))
        {
            sAccessInfo += GetAceInformation(FSAR);
        }

        if (sAccessInfo != string.Empty)
        {
            // Write info to text file
        }
    }
}

private string GetAceInformation(FileSystemAccessRule ace)
{
    StringBuilder info = new StringBuilder();
    string line = string.Format("Account: {0}", ace.IdentityReference.Value);
    info.AppendLine(line);
    line = string.Format("Type: {0}", ace.AccessControlType);
    info.AppendLine(line);
    line = string.Format("Rights: {0}", ace.FileSystemRights);
    info.AppendLine(line);
    line = string.Format("Inherited ACE: {0}", ace.IsInherited);
    info.AppendLine(line);
    return info.ToString();
}

Edit: How would I check the remote folder for the read attrib in the ACL when it fails on getting the "GetAccessControl()" method for the root folder? (If I pass in \server\path, it errors on getting the info for \server\path).

The user account is a domain account and I have permissions to read the file structure. I can view the security from the properties of the folder/files.

I will check out the process monitor but I am not sure that I am going to be able to run it on the server (I am not an admin on the server(s) in question).

回答1:

Your getting the error because of the 'Auditing' tab, though I'm fairly sure all you really want to access on the screen is the data on the 'Permissions' tab. The SeSecurityPrivilege controls the access to the SACL.

Try changing

DirectorySecurity DirSec = di.GetAccessControl(AccessControlSections.All);

to

DirectorySecurity DirSec = di.GetAccessControl(AccessControlSections.Access);

then you should stop getting the error



回答2:

Check that the remote folder grants the user running the code Read Attributes in the ACL.

Also remember that the permissions are resolved on the remote (server) machines, so local group (Users and Administrators) membership may not include the user account running on the client.

Having Process Monitor running on the server (filtered to the folders/files in question) may help resolve details of why it is failing.