检查两个NTAccount对象的相等性

时间:2023-02-10 22:58:57

I am trying to check that a service has access rights to a particular local directory:

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

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;
    }
}

However, the problem is that accessRule.IdentityReference == serviceUserAccount is never true, because, on one hand, I have an IdentityReference of type NTAccount who's name is NT AUTHORITY\NETWORK SERVICE, and my calculated serviceUserAccount object is NT AUTHORITY\NetworkService. Although these two are the same account, the equality test fails because these strings do not match exactly. How can you properly test that two NTAccount objects are the same, despite their syntax being marginally different?

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

1 个解决方案

#1


One solution I just tried which works is to translate each account to their respective SecurityIdentifier and then comparing them:

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

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

PS: Not all IdentityReference objects can be translated to a SID so be sure to wrap this in a try-catch block.

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

#1


One solution I just tried which works is to translate each account to their respective SecurityIdentifier and then comparing them:

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

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

PS: Not all IdentityReference objects can be translated to a SID so be sure to wrap this in a try-catch block.

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