在进行从 SID 到 NTAccount 的转换时,我使用以下代码:
DirectorySecurity folder_sec = Directory.GetAccessControl("c:\\test", AccessControlSections.All);
AuthorizationRuleCollection rules = folder_sec.GetAccessRules(true, true, typeof(SecurityIdentifier));
foreach (FileSystemAccessRule rule in rules)
{
SecurityIdentifier sid = new SecurityIdentifier(rule.IdentityReference.Value);
IdentityReference name = sid.Translate(typeof(NTAccount));
string output = name + " | " + sid.tostring();
}
是的,我意识到您可以NTAccount
从该folder_sec.GetAccessRules
方法中获得 from,但我发现SecurityIdentifier.Translate
正在使用相同的子例程,并且发生了相同的错误。归根结底,ACL 只是 SID 数组。
错误是,当您有两个名称完全相同但位于两个独立域(受信任,而非子域)中的活动目录对象(组、用户等)时,该translate
方法会返回错误的 NTAccount。它最终在执行代码的机器所在的域中返回具有相同名称的 NTAccount。NTAccount
从与您域中的另一个对象不同的名称的其他域获取s 返回正常。
假设您在 domain_frank 中的机器上有一个目录,这是 ACL:
- domain_frank\IT 团队
- domain_bob\IT 团队
- domain_frank\戴夫
- domain_bob\Ted
如果你运行它,虽然上面的代码output
看起来像:
domain_frank\IT Team | S-1-5-21-4000000000-4000000000-2000000000-28480
domain_frank\IT Team | S-1-5-21-1000000000-8000000000-3000000000-81912
domain_frank\Dave | S-1-5-21-4000000000-4000000000-2000000000-86875
domain_bob\Ted | S-1-5-21-1000000000-8000000000-3000000000-96521
假设名为 Dave 的对象不在 domain_bob 中,而名为 Ted 的对象不在 domain_frank 中。但是,如果您查看 SID,您可以清楚地看到域部分完全不同,因此您知道正确的对象在 ACL 中,至少在 SID 中。与查找有关的东西正在中断。
对我来说,结果是我必须编写自己的算法来查看 SID 并在 SID 所属的域上进行活动目录查找。非常非常慢,而且很痛苦。
这是一个已知的错误,是否有令人满意的解决方案?