特定の Active Directory グループの Windows フォルダに再帰的な「拒否」を設定する機能を提供するアプリケーションを作成しました。基本的には、Windows エクスプローラーのプロパティ ダイアログに移動し、セキュリティをクリックして、拒否の権限を持つ 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 グループが拒否されず、最上位フォルダーのみが拒否されます。