我们最近被迫迁移到世界各地的新域名服务器。这可能看起来不像是一个很大的变化,但我们经常运行的其中一个过程突然变成了一个2秒的命令到5分钟的命令。
原因?我们正在基于“模板”目录结构更新许多目录的权限。
我们发现XCOPY可以在相同的两秒钟窗口中更新大多数这些设置。当然,其余的设置都会被取消。
我想弄清楚的是,XCopy如何更快地执行.NET安全类应该本机执行的操作?显然我错过了什么。
在不ping(或最小化ping)域/ Active Directory服务器的情况下复制目录的ACL信息的最佳方法是什么?
这就是我所拥有的:
...
DirectorySecurity TemplateSecurity = new DirectorySecurity(TemplateDir, AccessControlSections.All);
...
public static void UpdateSecurity(string destination, DirectorySecurity TemplateSecurity)
{
DirectorySecurity dSecurity = Directory.GetAccessControl(destination);
// Remove previous security settings. (We have all we need in the other TemplateSecurity setting!!)
AuthorizationRuleCollection acl_old = dSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (FileSystemAccessRule ace in acl_old)
{
// REMOVE IT IF YOU CAN... if you can't don't worry about it.
try
{
dSecurity.RemoveAccessRule(ace);
}
catch { }
}
// Remove the inheritance for the folders...
// Per the business unit, we must specify permissions per folder.
dSecurity.SetAccessRuleProtection(true, true);
// Copy the permissions from TemplateSecurity to Destination folder.
AuthorizationRuleCollection acl = TemplateSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (FileSystemAccessRule ace in acl)
{
// Set the existing security.
dSecurity.AddAccessRule(ace);
try
{
// Remove folder inheritance...
dSecurity.AddAccessRule(new FileSystemAccessRule(
ace.IdentityReference, ace.FileSystemRights,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None,
ace.AccessControlType));
}
catch { }
}
// Apply the new changes.
Directory.SetAccessControl(destination, dSecurity);
}
...
DirectorySecurity TemplateSecurity = new DirectorySecurity(TemplateDir, AccessControlSections.All);
...
public static void UpdateSecurity(string destination, DirectorySecurity TemplateSecurity)
{
DirectorySecurity dSecurity = Directory.GetAccessControl(destination);
// Remove previous security settings. (We have all we need in the other TemplateSecurity setting!!)
AuthorizationRuleCollection acl_old = dSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (FileSystemAccessRule ace in acl_old)
{
// REMOVE IT IF YOU CAN... if you can't don't worry about it.
try
{
dSecurity.RemoveAccessRule(ace);
}
catch { }
}
// Remove the inheritance for the folders...
// Per the business unit, we must specify permissions per folder.
dSecurity.SetAccessRuleProtection(true, true);
// Copy the permissions from TemplateSecurity to Destination folder.
AuthorizationRuleCollection acl = TemplateSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (FileSystemAccessRule ace in acl)
{
// Set the existing security.
dSecurity.AddAccessRule(ace);
try
{
// Remove folder inheritance...
dSecurity.AddAccessRule(new FileSystemAccessRule(
ace.IdentityReference, ace.FileSystemRights,
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit,
PropagationFlags.None,
ace.AccessControlType));
}
catch { }
}
// Apply the new changes.
Directory.SetAccessControl(destination, dSecurity);
}
答案 0 :(得分:1)
好的......我在互联网上进行了一次DONGGING之后的工作原型。毋庸置疑,有很多关于ACL在线的错误信息。我不确定这些信息是天赐之物,还是更多的错误信息。我将不得不为您(用户)做出决定。
我最终得到的是干净,光滑,非常非常快,因为它永远不会触及域服务器。我正在直接复制SDDL条目。等等,你说......你不能在目录上这样做,因为你得到了可怕的SeSecurityPrivilege错误!
如果仅将副本限制为访问控制列表(ACL),则不会。
以下是代码:
public static void UpdateSecurity(string destination, DirectorySecurity templateSecurity)
{
DirectorySecurity dSecurity = Directory.GetAccessControl(destination);
string sddl = templateSecurity.GetSecurityDescriptorSddlForm(AccessControlSections.Access);
try
{
// TOTALLY REPLACE The existing access rights with the new ones.
dSecurity.SetSecurityDescriptorSddlForm(sddl, AccessControlSections.Access);
// Disable inheritance for this directory.
dSecurity.SetAccessRuleProtection(true, true);
// Apply these changes.
Directory.SetAccessControl(destination, dSecurity);
}
catch (Exception ex)
{
// Note the error on the console... we can formally log it later.
Console.WriteLine(pth1 + " : " + ex.Message);
}
// Do some other settings stuff here...
}
public static void UpdateSecurity(string destination, DirectorySecurity templateSecurity)
{
DirectorySecurity dSecurity = Directory.GetAccessControl(destination);
string sddl = templateSecurity.GetSecurityDescriptorSddlForm(AccessControlSections.Access);
try
{
// TOTALLY REPLACE The existing access rights with the new ones.
dSecurity.SetSecurityDescriptorSddlForm(sddl, AccessControlSections.Access);
// Disable inheritance for this directory.
dSecurity.SetAccessRuleProtection(true, true);
// Apply these changes.
Directory.SetAccessControl(destination, dSecurity);
}
catch (Exception ex)
{
// Note the error on the console... we can formally log it later.
Console.WriteLine(pth1 + " : " + ex.Message);
}
// Do some other settings stuff here...
}
注意SDDL方法上的标志。这是使它全部运转的神奇钥匙。