vendredi 8 mai 2015

Checking that two NTAccount objects refer to the same account

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 && 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?

Aucun commentaire:

Enregistrer un commentaire