Eu tenho um SID de uma conta de usuário e quero o SIDS dos grupos que pertence

StackOverflow https://stackoverflow.com/questions/2495185

  •  21-09-2019
  •  | 
  •  

Pergunta

Isso deve ser obtido de uma máquina remota. A consulta a seguir funciona não para SIDS, mas para nomes de grupo e contas.

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

Os objetos Win32_Group que ele retorna vêm nas formas de strings, e eles têm apenas domínio e nome (mesmo que o Win32_Group tenha uma propriedade SID).

Eu tenho essa sensação de afundar que vou ter que:

  1. Transforme o SID em um nome de conta, consultando Win32_SID;
  2. Execute a consulta acima;
  3. Virar cada Dos nomes de grupo resultantes no SIDS, consultando Win32_Group.
Foi útil?

Solução

Você pode usar o System.DirectoryServices.AccountManagement Classes de namespace?

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

Ele deve funcionar com o ContextType.Machine, embora você precise especificar o nome da máquina e ter privilégios apropriados.

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

Há um bom msdn artigo (porém, longish, porém) ao usar o novo espaço para nome de gerenciamento de contas .NET 3.5.

Outras dicas

Sim, há apenas alguns métodos de dependem de ter um domínio.

  1. Veja isso página Para como converter um SID em um ID de usuário usando P/Invoke e a API do Windows, ou com .NET 2.0+ e sem P/Invoke.

    usando o System.Security.Principal;

    // Converta o usuário SID em um domínio name string conta = new SecurityIdentifier (stringsid) .Translate (typeof (ntaccount)). ToString ();

  2. Se você tem o AD e o ID do usuário lá, use o método do diretório do pesquisador ou APIs de gerenciamento de contas para encontrar os grupos. Caso contrário, use o método descrito emisto artigo para obter grupos locais.

  3. Agora use a API sugerida por @tvanfosson para iterar os grupos e obter o SIDS. Ou siga as informações abaixo.

Em um aplicativo ASP.NET, é possível usar o código como esse para acessar informações do grupo, desde que um usuário seja autenticado pelo Windows e não formasse a autenticação. Neste exemplo, deixei uma nota interessante sobre exceções que são jogadas nesse ambiente, mas podem se aplicar a outros usuários:

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 é baseado no WindowsIdentity classe. Você pode modificar meu exemplo de código para usar o WindowsIdentity e funcionar em um aplicativo não-Web. Depois de iterar sobre um grupo, você poderá fazer algo assim para obter o SecurityIdentifier:

SecurityIdentifier secid = group as SecurityIdentifier;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top