检查两个NTAccount对象的相等性

时间:2015-05-08 16:15:13

标签: c# .net windows service permissions

我正在尝试检查服务是否具有对特定本地目录的访问权限:

public static bool HasDirectoryPermissions(String path, FileSystemRights rights, String serviceName)
{
    try
    {
        var directoryAccessControl = Directory.GetAccessControl(path);
        ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_Service where Name='" + serviceName + "'");
        var queryResults = (from ManagementObject x in query.Get() select x);
        if (queryResults.Count() > 0)
        {
            var serviceUser = (string)queryResults.FirstOrDefault().Properties["StartName"].Value;
            var serviceUserAccount = new NTAccount(serviceUser);
            var rules = directoryAccessControl.GetAccessRules(true, true, typeof(NTAccount));
            foreach (var rule in rules)
            {
                if (rule.GetType() == typeof(FileSystemAccessRule))
                {
                    var accessRule = (FileSystemAccessRule)rule;
                    if (accessRule.IdentityReference == serviceUserAccount && (accessRule.FileSystemRights & rights) == rights && accessRule.AccessControlType == AccessControlType.Allow)
                    {
                        Console.WriteLine("The {0} service has permissions to {1}.", serviceName, path);
                        return true;
                    }
                }
            }
            Console.WriteLine("The {0} service does not have directory permissions for {1}.", serviceName, path);
            return false;
        }
        else
        {
            Console.WriteLine("Could not get directory permissions for {0} because the {1} service is not installed.", path, serviceName);
            return false;
        }
    }
    catch (Exception exception)
    {
        Console.WriteLine("Directory permissions could not be obtained for the {0} service against {1}. {2}", serviceName, path, exception.ToString());
        return false;
    }
}

然而,问题是accessRule.IdentityReference == serviceUserAccount永远不会成立,因为,一方面,我有一个类型为NTAccount的IdentityReference,其名称为NT AUTHORITY\NETWORK SERVICE,而我计算的serviceUserAccount对象是NT AUTHORITY\NetworkService。虽然这两个帐户是相同的,但是相等测试失败,因为这些字符串不完全匹配。你怎么能正确地测试两个NTAccount对象是否相同,尽管它们的语法略有不同?

1 个答案:

答案 0 :(得分:1)

我刚试过的一个解决方案是将每个帐户转换为各自的SecurityIdentifier然后进行比较:

accessRule.IdentityReference.Translate(typeof(SecurityIdentifier)) == serviceUserAccount.Translate(typeof(SecurityIdentifier))

PS:并非所有IdentityReference对象都可以转换为SID,因此请务必将其包装在try-catch块中。