I have a SID of a user account, and I want the SIDs of the groups it belongs to

狂风中的少年 提交于 2019-12-06 00:38:28

问题


This has to be obtained from a remote machine. The following query works not for SIDs, but for group and account names.

"SELECT GroupComponent FROM Win32_GroupUser WHERE PartComponent = \"Win32_UserAccount.Domain='" + accountDomain + "',Name='" + accountName + "'\""

The Win32_Group objects it returns come in the forms of strings, and they only have domain and name (even though Win32_Group has a SID property).

I have this sinking feeling I'll have to:

  1. Turn the SID into an account name by querying Win32_SID;
  2. Perform the query above;
  3. Turn each of the resulting group names into SIDs by querying Win32_Group.

回答1:


Can you use the System.DirectoryServices.AccountManagement namespace classes?

using (var context = new PrincipalContext( ContextType.Domain ))
{
    using (var user = UserPrincipal.FindByIdentity( context, accountName ))
    {
        var groups = user.GetAuthorizationGroups();
        ...iterate through groups and find SIDs for each one
    }
}

It should work with ContextType.Machine, though you'd need to specify the machine name and have appropriate privileges.

using (var context = new PrincipalContext( ContextType.Machine,
                                           "MyComputer",
                                           userid,
                                           password ))
{
   ...
}

There's a nice MSDN article (longish, though) on using the new .NET 3.5 account management namespace.




回答2:


Yes there is but some methods depend on having a domain.

  1. See this page for how to convert a SID to a user id using P/Invoke and the Windows API, or with .NET 2.0+ and no P/Invoke.

    using System.Security.Principal;

    // convert the user sid to a domain\name string account = new SecurityIdentifier(stringSid).Translate(typeof(NTAccount)).ToString();

  2. If you have AD and the user id in there then use the DirectorySearcher method or Account Management APIs to find the groups. Otherwise use the method outlined in this article to get local groups.

  3. Now use the API suggested by @tvanfosson to iterate the groups and get the SIDs. Or follow the info below.

In an ASP.NET application it is possible to use code like this to access group info provided a user is authenticated by Windows and not Forms authentication. In this example I've left an interesting note about exceptions that are thrown in that environment but it may apply to other users:

public List<string> GetGroupsFromLogonUserIdentity()
{
    List<string> groups = new List<string>();
    HttpRequest request = HttpContext.Current.Request;

    if (request.LogonUserIdentity.Groups != null)
    {
        foreach (IdentityReference group in request.LogonUserIdentity.Groups)
        {
            try
            {
                groups.Add(group.Translate(typeof(NTAccount)).ToString());
            }
            catch (IdentityNotMappedException)
            {
                // Swallow these exceptions without throwing an error. They are
                // the result of dead objects in AD which are associated with
                // user accounts. In this application users may have a group
                // name associated with their AD profile which cannot be
                // resolved in the Active Directory.
            }
        }
    }

    return groups;
}

LogonUserIdentity is based on the WindowsIdentity class. You could modify my code sample to use WindowsIdentity and function in a non-Web application. Once you iterate over a group you should be able to do something like this to get the SecurityIdentifier:

SecurityIdentifier secid = group as SecurityIdentifier;


来源:https://stackoverflow.com/questions/2495185/i-have-a-sid-of-a-user-account-and-i-want-the-sids-of-the-groups-it-belongs-to

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!