在我们开始之前,我先说一下:
System.Security.Principal.NTAccount account =
(System.Security.Principal.NTAccount)rule.IdentityReference.Translate(typeof(System.Security.Principal.NTAccount));
if (account.Value != "BUILTIN\\Administrators")
is 完全没有必要.
内置的管理员组是一个知名安全主体 https://support.microsoft.com/en-us/kb/243330,并保证always具有相同的安全标识符(S-1-5-32-544
),易于比较。
您当前为所有已经拥有访问规则的主体显式授予“拒绝删除”的过程也可能会适得其反。
假设 ACL 中已存在具有以下特征的访问规则:
身份:每个人
访问权: Read
控制类型: Allow
恭喜!你现在已经含蓄地否认了everyone删除文件的权利,包括管理员组。
你想做的是:
- 确保管理员组是文件的所有者
- 删除所有授予“允许删除”权限的现有访问规则(明确or隐含地)
- 添加单个访问规则,授予管理员组允许完全控制权
- 删除所有继承的规则并保护 ACL 免遭继承
// Way safer than string comparison against "BUILTIN\\Administrators"
IdentityReference BuiltinAdministrators = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, null);
// Grab ACL from file
FileSecurity FileACL = File.GetAccessControl(TargetFilePath);
// Check if correct owner is set
if (FileACL.GetOwner(typeof(SecurityIdentifier)) != BuiltinAdministrators)
{
// If not, make it so!
FileACL.SetOwner(BuiltinAdministrators);
}
foreach (FileSystemAccessRule fsRule in FileACL.GetAccessRules(true, false, typeof(SecurityIdentifier)))
{
// Check if rule grants delete
if ((fsRule.FileSystemRights & FileSystemRights.Delete) == FileSystemRights.Delete)
{
// If so, nuke it!
FileACL.RemoveAccessRule(fsRule);
}
}
// Add a single explicit rule to allow FullControl
FileACL.AddAccessRule(new FileSystemAccessRule(BuiltinAdministrators, FileSystemRights.FullControl, AccessControlType.Allow));
// Enable protection from inheritance, remove existing inherited rules
FileACL.SetAccessRuleProtection(true, false);
// Write ACL back to file
File.SetAccessControl(TargetFilePath, FileACL);