2010-02-12 56 views
6

我需要在C#中得到機器的SID(沒有計算機帳戶的SID)。計算機被指定爲主機名,它不一定是本地計算機,它可以是域計算機或工作組計算機。我使用這個助手類調用LookupAccountName API函數:GET機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中的最後一個段。