比较Windows文件(或文件夹)的权限

我偶尔会将某个网站从一台networking服务器迁移到另一台。

将旧服务器中的所有文件复制到新服务器后,需要相当长的一段时间才能熟悉哪些文件夹或文件需要由IIS写入。 (听起来很熟悉,顺便说一下:))

我写了一个WinForms应用程序,允许我select一个起始目录。 应用程序应该(recursion地)比较每个文件/目录的安全权限是否与其父目录的安全权限相同。

我想在旧服务器上使用此应用程序来扫描具有不同权限的目录。

示例: C:\MySites\Uploads does not have the same permissions set as its parent directory. (该文件夹对于IIS用户'IUSR'是可写的,而其父文件夹只能读取。)

这个应用程序几乎完全的 ,因为我设法遍历所有的目录和文件。 我只需要比较他们的权限

你能帮忙吗? 这里是我需要你帮助的地方的摘录。

 string results = ""; string parentFolderPath = "c:\\someParentDir"; string childItemPath = "c:\\someParentDir\\SomeChildDir.ext"; DirectorySecurity parentFolderAccessControl = Directory.GetAccessControl(parentFolderPath); DirectorySecurity childItemAccessControl = Directory.GetAccessControl(childItemPath); if (!parentFolderAccessControl.Equals(childItemAccessControl)) // <-- D'oh here { results += childItemPath + " does not have the same permissions set as its parent directory.\n"; } 

if总是如此,因为DirectorySecurities永远不会是平等的。 (我明白这是为什么:引用不同的内存分配…等等等等。)但是,什么是最好的方式来比较DirectorySecurities?

Solutions Collecting From Web of "比较Windows文件(或文件夹)的权限"

这实际上变得更加复杂了,因为Windows权限可以:

  • 分成允许和拒绝
  • 碎片化多个条目(每个用户每个允许/拒绝多个条目)

最终,我是这样做的:

 private bool compareAccessControls( DirectorySecurity parentAccessControl, DirectorySecurity childAccessControl, out Dictionary<IdentityReference, FileSystemRights> accessAllowRulesGainedByChild, out Dictionary<IdentityReference, FileSystemRights> accessDenyRulesGainedByChild, out Dictionary<IdentityReference, FileSystemRights> accessAllowRulesGainedByParent, out Dictionary<IdentityReference, FileSystemRights> accessDenyRulesGainedByParent ) { // combine parent access rules Dictionary<IdentityReference, FileSystemRights> combinedParentAccessAllowRules = new Dictionary<IdentityReference, FileSystemRights>(); Dictionary<IdentityReference, FileSystemRights> combinedParentAccessDenyRules = new Dictionary<IdentityReference, FileSystemRights>(); foreach (FileSystemAccessRule parentAccessRule in parentAccessControl.GetAccessRules(true, true, typeof(NTAccount))) { if (parentAccessRule.AccessControlType == AccessControlType.Allow) if (combinedParentAccessAllowRules.ContainsKey(parentAccessRule.IdentityReference)) combinedParentAccessAllowRules[parentAccessRule.IdentityReference] = combinedParentAccessAllowRules[parentAccessRule.IdentityReference] | parentAccessRule.FileSystemRights; else combinedParentAccessAllowRules.Add(parentAccessRule.IdentityReference, parentAccessRule.FileSystemRights); else if (combinedParentAccessDenyRules.ContainsKey(parentAccessRule.IdentityReference)) combinedParentAccessDenyRules[parentAccessRule.IdentityReference] = combinedParentAccessDenyRules[parentAccessRule.IdentityReference] | parentAccessRule.FileSystemRights; else combinedParentAccessDenyRules.Add(parentAccessRule.IdentityReference, parentAccessRule.FileSystemRights); } // combine child access rules Dictionary<IdentityReference, FileSystemRights> combinedChildAccessAllowRules = new Dictionary<IdentityReference, FileSystemRights>(); Dictionary<IdentityReference, FileSystemRights> combinedChildAccessDenyRules = new Dictionary<IdentityReference, FileSystemRights>(); foreach (FileSystemAccessRule childAccessRule in childAccessControl.GetAccessRules(true, true, typeof(NTAccount))) { if (childAccessRule.AccessControlType == AccessControlType.Allow) if (combinedChildAccessAllowRules.ContainsKey(childAccessRule.IdentityReference)) combinedChildAccessAllowRules[childAccessRule.IdentityReference] = combinedChildAccessAllowRules[childAccessRule.IdentityReference] | childAccessRule.FileSystemRights; else combinedChildAccessAllowRules.Add(childAccessRule.IdentityReference, childAccessRule.FileSystemRights); else if (combinedChildAccessDenyRules.ContainsKey(childAccessRule.IdentityReference)) combinedChildAccessDenyRules[childAccessRule.IdentityReference] = combinedChildAccessDenyRules[childAccessRule.IdentityReference] | childAccessRule.FileSystemRights; else combinedChildAccessDenyRules.Add(childAccessRule.IdentityReference, childAccessRule.FileSystemRights); } // compare combined rules accessAllowRulesGainedByChild = new Dictionary<IdentityReference, FileSystemRights>(); foreach (KeyValuePair<IdentityReference, FileSystemRights> combinedChildAccessAllowRule in combinedChildAccessAllowRules) { if (combinedParentAccessAllowRules.ContainsKey(combinedChildAccessAllowRule.Key)) { FileSystemRights accessAllowRuleGainedByChild = combinedChildAccessAllowRule.Value & ~combinedParentAccessAllowRules[combinedChildAccessAllowRule.Key]; if (accessAllowRuleGainedByChild != default(FileSystemRights)) accessAllowRulesGainedByChild.Add(combinedChildAccessAllowRule.Key, accessAllowRuleGainedByChild); } else { accessAllowRulesGainedByChild.Add(combinedChildAccessAllowRule.Key, combinedChildAccessAllowRule.Value); } } accessDenyRulesGainedByChild = new Dictionary<IdentityReference, FileSystemRights>(); foreach (KeyValuePair<IdentityReference, FileSystemRights> combinedChildAccessDenyRule in combinedChildAccessDenyRules) { if (combinedParentAccessDenyRules.ContainsKey(combinedChildAccessDenyRule.Key)) { FileSystemRights accessDenyRuleGainedByChild = combinedChildAccessDenyRule.Value & ~combinedParentAccessDenyRules[combinedChildAccessDenyRule.Key]; if (accessDenyRuleGainedByChild != default(FileSystemRights)) accessDenyRulesGainedByChild.Add(combinedChildAccessDenyRule.Key, accessDenyRuleGainedByChild); } else { accessDenyRulesGainedByChild.Add(combinedChildAccessDenyRule.Key, combinedChildAccessDenyRule.Value); } } accessAllowRulesGainedByParent = new Dictionary<IdentityReference, FileSystemRights>(); foreach (KeyValuePair<IdentityReference, FileSystemRights> combinedParentAccessAllowRule in combinedParentAccessAllowRules) { if (combinedChildAccessAllowRules.ContainsKey(combinedParentAccessAllowRule.Key)) { FileSystemRights accessAllowRuleGainedByParent = combinedParentAccessAllowRule.Value & ~combinedChildAccessAllowRules[combinedParentAccessAllowRule.Key]; if (accessAllowRuleGainedByParent != default(FileSystemRights)) accessAllowRulesGainedByParent.Add(combinedParentAccessAllowRule.Key, accessAllowRuleGainedByParent); } else { accessAllowRulesGainedByParent.Add(combinedParentAccessAllowRule.Key, combinedParentAccessAllowRule.Value); } } accessDenyRulesGainedByParent = new Dictionary<IdentityReference, FileSystemRights>(); foreach (KeyValuePair<IdentityReference, FileSystemRights> combinedParentAccessDenyRule in combinedParentAccessDenyRules) { if (combinedChildAccessDenyRules.ContainsKey(combinedParentAccessDenyRule.Key)) { FileSystemRights accessDenyRuleGainedByParent = combinedParentAccessDenyRule.Value & ~combinedChildAccessDenyRules[combinedParentAccessDenyRule.Key]; if (accessDenyRuleGainedByParent != default(FileSystemRights)) accessDenyRulesGainedByParent.Add(combinedParentAccessDenyRule.Key, accessDenyRuleGainedByParent); } else { accessDenyRulesGainedByParent.Add(combinedParentAccessDenyRule.Key, combinedParentAccessDenyRule.Value); } } if (accessAllowRulesGainedByChild.Count > 0 || accessDenyRulesGainedByChild.Count > 0 || accessAllowRulesGainedByParent.Count > 0 || accessDenyRulesGainedByParent.Count > 0) return false; else return true; } 

你不能使用Equals(),因为这个方法是从Object继承的。 您需要在该DirectorySecurity类上找到标识属性。 我想String GetSecurityDescriptorSddlForm()

应该做你的工作。 你可以调用Equals()。

编辑:对不起,这个方法需要一个参数来调用。 尝试在DirectorySecurity上找到另一个比较好的属性。

编辑2:我不熟悉.NET安全框架和权利管理,但这样的事情应该是你的方法。 您可以在FileSystemAccessRule.FileSystemRights上执行!= resp:==,因为该属性是一个枚举(内部为int)。

 ArrayList notIdenticalList = new ArrayList(); DirectorySecurity parentFolderAccessControl = Directory.GetAccessControl(null); DirectorySecurity childItemAccessControl = Directory.GetAccessControl(null); foreach (FileSystemAccessRule parentRule in parentFolderAccessControl.GetAccessRules(true, true, typeof(NTAccount))) { foreach (FileSystemAccessRule childRule in childItemAccessControl.GetAccessRules(true, true, typeof(NTAccount))) { if (parentRule.FileSystemRights != childRule.FileSystemRights) { // add to not identical-list notIdenticalList.Add(fileToAdd...); break; } } }