2010-02-12 5 views
6

Мне нужно получить идентификатор SID компьютера (а не SID учетной записи компьютера) на C#. Компьютер указан как имя хоста, это не обязательно локальный компьютер, и он может быть компьютером домена или компьютером рабочей группы. Я с помощью этого вспомогательный класс для вызова LookupAccountName функции API:получить машину SID (включая основной контроллер домена)

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(); 
     } 
    } 

и использовать его как это:

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 

Моя единственная проблема в том, что это не работает, если компьютер является контроллером домена (я нужен для получения SID домена в этом случае).

ответ

2

Оказывается, что для большинства компьютеров, выполните следующие действия:

LookupAccountName ("", "Имя_компьютер", ...); ConvertSidToStringSid (...)

Но для контроллеров домена вам нужно добавить знак доллара к параметру имени компьютера, а затем удалить последний сегмент в возвращаемом идентификаторе SID.