我们创建了一个应用程序,它提供了在某个Active Directory组的Windows文件夹上设置递归“拒绝”的功能。基本上与进入Windows资源管理器中的属性对话框并单击安全性并添加具有Deny权限的AD组相同。 我们正在使用此代码:
public void DenyAccessInherited(string DomainAndSamAccountName)
{
SetPermissionAndInherit(this.FolderPath,
NTFSPermission.PropagationFlags.CONTAINER_AND_OBJECT_INHERIT_ACE,
NTFSPermission.NTFSPermission_FULL_CONTROL, NTFSPermission.ACETypes.ADS_ACETYPE_ACCESS_DENIED,
DomainAndSamAccountName);
}
public static void SetPermissionAndInherit(string FolderPath, PropagationFlags Inheritance, int Permission, ACETypes ACETypeAccessAllowedDenied, string DomainAndUsername)
{
AccessControlList dacl = new AccessControlList();
SecurityDescriptor sd = new SecurityDescriptor();
AccessControlEntry newAce = new AccessControlEntry();
ADsSecurityUtility sdUtil = new ADsSecurityUtility();
OnProgress(DomainAndUsername, FolderPath);
sd = sdUtil.GetSecurityDescriptor(FolderPath, ADS_PATH_FILE, ADS_SD_FORMAT_IID);
dacl = sd.DiscretionaryAcl;
RemoveTrusteeFromDACL(dacl, DomainAndUsername);
newAce.Trustee = DomainAndUsername;
newAce.AccessMask = Permission;
newAce.AceFlags = (int)Inheritance;
newAce.AceType = (int)ACETypeAccessAllowedDenied;
dacl.AddAce(newAce);
sdUtil.SetSecurityDescriptor(FolderPath, ADS_PATH_FILE, sd, ADS_SD_FORMAT_IID);
foreach (string File in Directory.GetFiles(FolderPath))
{
SetACE(File, DomainAndUsername, Permission, PropagationFlags.INHERITED_ACE, ACETypeAccessAllowedDenied);
}
foreach (string SubFolderPath in Directory.GetDirectories(FolderPath))
{
SetInheritedPermission(SubFolderPath, DomainAndUsername, Permission, ACETypeAccessAllowedDenied);
}
}
private static void SetInheritedPermission(string FolderPath, string DomainAndUsername, int PermissionFlags, ACETypes AccessFlags)
{
AccessControlList dacl = new AccessControlList();
SecurityDescriptor sd = new SecurityDescriptor();
AccessControlEntry newAce = new AccessControlEntry();
ADsSecurityUtility sdUtil = new ADsSecurityUtility();
SetACE(FolderPath, DomainAndUsername, PermissionFlags, (PropagationFlags)(PropagationFlags.CONTAINER_AND_OBJECT_INHERIT_ACE | PropagationFlags.INHERITED_ACE), AccessFlags);
foreach (string File in Directory.GetFiles(FolderPath))
{
SetACE(File, DomainAndUsername, PermissionFlags, PropagationFlags.INHERITED_ACE, AccessFlags);
}
foreach (string SubFolderPath in Directory.GetDirectories(FolderPath))
{
SetInheritedPermission(SubFolderPath, DomainAndUsername, PermissionFlags, AccessFlags);
}
}
private static void SetACE(string FileOrFolder, string DomainAndUsername, int PermissionFlags, PropagationFlags InheritanceFlags, ACETypes AccessFlags)
{
AccessControlList dacl = new AccessControlList();
SecurityDescriptor sd = new SecurityDescriptor();
AccessControlEntry newAce = new AccessControlEntry();
ADsSecurityUtility sdUtil = new ADsSecurityUtility(); sd = sdUtil.GetSecurityDescriptor(FileOrFolder, ADS_PATH_FILE, ADS_SD_FORMAT_IID);
sd.Control = sd.Control;
OnProgress(DomainAndUsername, FileOrFolder);
dacl = sd.DiscretionaryAcl;
RemoveTrusteeFromDACL(dacl, DomainAndUsername);
newAce.Trustee = DomainAndUsername;
newAce.AccessMask = PermissionFlags;
newAce.AceFlags = (int)InheritanceFlags;
newAce.AceType = (int)AccessFlags;
dacl.AddAce(newAce);
sdUtil.SetSecurityDescriptor(FileOrFolder, ADS_PATH_FILE, sd, ADS_SD_FORMAT_IID);
}
现在我们遇到了一个包含大量html文档的大文件夹,大约12000个文件,上面的方法非常慢。处理文件安全性大约需要7分钟。但是,当通过Windows资源管理器/安全管理安全性时,它只需要大约20秒,因此必须有一些方法在C#中优化它。
编辑:当我省略递归并且只在顶级文件夹上设置SecurityDescriptor时,它下面的任何文件都没有拒绝AD组,只有顶级文件夹。
答案 0 :(得分:2)
我解决了。我完全抛弃了上面的代码并采取了另一种方式:
public override void DenyAccessInherited(string FolderPath,string DomainAndSamAccountName)
{
using (Impersonator imp = new Impersonator(this.connection.GetSamAccountName(), this.connection.GetDomain(), this.connection.Password))
{
FileSystemAccessRule rule = new FileSystemAccessRule(DomainAndSamAccountName, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, System.Security.AccessControl.PropagationFlags.InheritOnly, AccessControlType.Deny);
DirectoryInfo di = new DirectoryInfo(FolderPath);
DirectorySecurity security = di.GetAccessControl(AccessControlSections.All);
bool modified;
security.ModifyAccessRule(AccessControlModification.Add, rule, out modified);
if (modified)
di.SetAccessControl(security);
}
}
这非常苗条而且非常快。
答案 1 :(得分:0)
嵌套文件夹和文件应该继承父级的安全设置,因此您不需要为所有人设置递归。尝试仅为根文件夹设置它。