2010-02-12 4 views
6

Je dois obtenir le SID de la machine (pas le SID du compte d'ordinateur) en C#. L'ordinateur est spécifié comme nom d'hôte, ce n'est pas forcément un ordinateur local et il peut s'agir d'un ordinateur de domaine ou d'un ordinateur de groupe de travail. J'utilise cette classe d'aide pour appeler LookupAccountName fonction API:Obtenir le SID de la machine (y compris le contrôleur de domaine principal)

private static class Helper 
    { 
     internal enum SID_NAME_USE 
     { 
      SidTypeUser = 1, 
      SidTypeGroup, 
      SidTypeDomain, 
      SidTypeAlias, 
      SidTypeWellKnownGroup, 
      SidTypeDeletedAccount, 
      SidTypeInvalid, 
      SidTypeUnknown, 
      SidTypeComputer 
     } 

     [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)] 
     private static extern bool LookupAccountName(
      string systemName, 
      string accountName, 
      byte[] sid, 
      ref int sidLen, 
      System.Text.StringBuilder domainName, 
      ref int domainNameLen, 
      out SID_NAME_USE peUse); 

     public static SecurityIdentifier LookupAccountName(
      string systemName, 
      string accountName, 
      out string strDomainName, 
      out SID_NAME_USE accountType) 
     { 
      const int ERROR_INSUFFICIENT_BUFFER = 122; 

      int lSidSize = 0; 
      int lDomainNameSize = 0; 

      //First get the required buffer sizes for SID and domain name. 
      LookupAccountName(systemName, 
           accountName, 
           null, 
           ref lSidSize, 
           null, 
           ref lDomainNameSize, 
           out accountType); 

      if (Marshal.GetLastWin32Error() == ERROR_INSUFFICIENT_BUFFER) 
      { 
       //Allocate the buffers with actual sizes that are required 
       //for SID and domain name. 
       byte[] sid = new byte[lSidSize]; 
       var sbDomainName = new System.Text.StringBuilder(lDomainNameSize); 

       if (LookupAccountName(systemName, 
             accountName, 
             sid, 
             ref lSidSize, 
             sbDomainName, 
             ref lDomainNameSize, 
             out accountType)) 
       { 
        strDomainName = sbDomainName.ToString(); 
        return new SecurityIdentifier(sid, 0); 
       } 
      } 

      throw new Win32Exception(); 
     } 
    } 

et l'utiliser comme ceci:

Helper.SID_NAME_USE accountType; 
string refDomain; 
SecurityIdentifier sid = Helper.LookupAccountName("falcon.mydomain.local", "falcon", out refDomain, out accountType); //Domain computer 

SecurityIdentifier sid = Helper.LookupAccountName("rat", "rat", out refDomain, out accountType); //Workgroup computer 

Mon seul problème est que cela ne fonctionne pas si l'ordinateur est contrôleur de domaine principal (j'ai besoin pour obtenir le SID de domaine dans ce cas).

Répondre

2

Il semble que pour la plupart des ordinateurs que vous effectuez les opérations suivantes:

LookupAccountName ("", "ComputerName", ...); ConvertSidToStringSid (...)

Mais pour les contrôleurs de domaine, vous devez ajouter un signe dollar au paramètre de nom d'ordinateur, puis supprimer le dernier segment dans le SID renvoyé.

Questions connexes