使用C#获取服务器和映射驱动器的ACL列表

16
我们IT小组的生产变更实施者被分配任务,审查我们小组所有各种对象的安全性,主要是为了确保已经离开我们雇用或转到其他小组的人员不再访问我们的服务器共享、Web目录、SQL数据库等等。最近我们完成了SQL部分,并且有一个可重复使用的脚本,可以每年运行一次(或任何我们想要的频率)。它效果很好,我们在几分钟内审核了10个左右服务器上的20个数据库。
现在是服务器的事情。我编写了一个使用.NET 2.0的C#应用程序,它会递归扫描一个目录列表并将ACL(访问控制列表)转储到文本文件中。这非常有效,但只能在本地计算机上运行。UNC和映射路径不起作用,我得到以下异常消息:“进程没有拥有所需此操作的“SeSecurityPrivilege”特权。” 在这一行:
DirectorySecurity DirSec = di.GetAccessControl(AccessControlSections.All);

其中 di 是从 DirectoryInfo[] 数组枚举出的 DirectoryInfo 对象。

我们可能无法获得 SeSecurityPrivilege 权限,但我认为这并不是必要的。我可以打开文件夹,右键单击属性,然后点击安全选项卡,在 GUI 中查看它。我应该也能以编程方式访问它。

您有什么想法,如何更改此代码部分以获取目标文件夹的权限?

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();
}

编辑: 如果获取根文件夹的“GetAccessControl()”方法失败,我该如何检查远程文件夹中ACL的读取属性?(如果我传入\ server \ path,则在获取\ server \ path的信息时出错)。

用户帐户是域帐户,我有权限读取文件结构。 我可以从文件/文件夹属性中查看安全性。

我将检查进程监视器,但我不确定是否能在服务器上运行它(我不是所涉及服务器的管理员)。


1
这个问题/代码示例真的非常有帮助。我使用这段代码为我们内部系统构建了一个文件权限监视器。 - Michael Kniskern
2个回答

23

你遇到错误是因为“审核”选项卡,我相信你实际上只想访问“权限”选项卡中的数据。SeSecurityPrivilege控制对SACL的访问权限。

尝试更改

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

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

那么你应该停止出现这个错误


哎呀!我不知道为什么我没有更仔细地查看那些其他的枚举。我明天会尝试一下,看看结果如何。谢谢! - bdwakefield
3
再次感谢这个stackoverflow问题和答案,我觉得它们非常有帮助。+1 - Michael Kniskern

1

请检查远程文件夹是否授予运行代码的用户在ACL中读取属性的权限。

还要记住,权限是在远程(服务器)机器上解决的,因此本地组(用户和管理员)成员身份可能不包括在客户端上运行的用户帐户。

在服务器上运行进程监视器(过滤到相关文件夹/文件)可能有助于解决失败原因的详细信息。


嗯...没有管理员权限,你将会受制于奇怪的权限问题,或者发现调试非常困难。 - Richard

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接