2

我需要从共享的特定子文件夹上的 ACL 中删除某些帐户(例如“每个人”受托人或某个全局组,它允许每个人访问文件夹)。我得到一个 DirectorySecurity 对象,获取并遍历 AuthorizationRuleCollection,从 ACL 中删除有问题的 AccessRule,然后调用 SetAccessControl 来应用更改。如果目标文件夹很小,一切正常,但如果它有很多子文件夹和文件,则应用更改可能需要很长时间(比手动执行要长得多)。我只想处理目标文件夹上的 ACL。有没有办法使用 .net DirectorySecurity 类来做到这一点?还是我必须求助于 Win32 API 或其他解决方案?谢谢。

这是一段代码。当文件夹大小非常大时,对 dirInfo.SetAccessControl(dirSec) 的调用会挂起。

DirectoryInfo dirInfo = new DirectoryInfo(path);
DirectorySecurity dirSec = dirInfo.GetAccessControl();
AuthorizationRuleCollection acl = dirSec.GetAccessRules(true, true,     
                                  typeof(System.Security.Principal.NTAccount));
foreach (FileSystemAccessRule ace in acl)
{
    if (groupsToRemove.Contains(ace.IdentityReference.Value))
    {
        dirSec.RemoveAccessRuleSpecific(ace);
        dirInfo.SetAccessControl(dirSec);
    }
}
4

2 回答 2

2
DirectoryInfo dirInfo = new DirectoryInfo(path);
DirectorySecurity dirSec = dirInfo.GetAccessControl();
AuthorizationRuleCollection acl = dirSec.GetAccessRules(true, true,     
                                  typeof(System.Security.Principal.NTAccount));
foreach (FileSystemAccessRule ace in acl)
{
    if (groupsToRemove.Contains(ace.IdentityReference.Value))
    {
        dirSec.RemoveAccessRuleSpecific(ace);
        dirInfo.SetAccessControl(dirSec);
    }
}

在您的代码中,您在循环的每次交互中都将更新应用到 ACL,这会变得非常昂贵。你试过搬到dirInfo.SetAccessControl(dirSec);外面去foreach吗?这应该SetAccessControl在您的DirectoryInfo对象上调用一次方法,一次应用所有更改,如下所示:

foreach (FileSystemAccessRule ace in acl)
{
    if (groupsToRemove.Contains(ace.IdentityReference.Value))
    {
        dirSec.RemoveAccessRuleSpecific(ace);        
    }
}
dirInfo.SetAccessControl(dirSec);
于 2012-03-10T21:03:23.760 回答
1

您必须设置SE_DACL_PROTECTED标志以“防止在父容器的 DACL 上设置的 ACE,以及​​目录层次结构中父容器上方的任何对象应用于对象 DACL。” 这可能会加快您的操作,因为它不必将其应用于所有子对象。同样来自 MSDN,

请注意,必须存在 SE_DACL_PRESENT 标志才能设置 SE_DACL_PROTECTED,并且必须存在 SE_SACL_PRESENT 才能设置 SE_SACL_PROTECTED。

然后,您必须使用IADsSecurityDescriptor.Control属性来控制 DACL 和 SACL 是否由对象从其父容器继承。

MSDN 上提供了有关IADsSecurityDescriptor接口的更多信息。

于 2011-07-20T19:21:55.743 回答