开发者

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

开发者 https://www.devze.com 2022-12-24 19:34 出处:网络
This has to be obtained from a remote machine. The following query works not for SIDs, but for group and account names.

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 = \"Win3开发者_如何转开发2_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.


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.


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

精彩评论

暂无评论...
验证码 换一张
取 消