2016-04-22 102 views
1

我有一段代碼應該能夠判斷應用程序是否在管理員用戶下運行。檢查令牌是否屬於管理員組的成員

現在,我可以獲取進程的標記並提取進程所有者的SID。效果很好。所以我有這個「SecurityIdentifier」對象,但我不知道如何檢查它是否確實是管理員組的成員。

所以,如果有人知道一種方式,那就太好了。但是,現在,我找到了一種方法來從我從進程中檢索到的令牌創建一個WindowsIdentity對象,並且它似乎目前正在模擬。但是,在調用WindowsPrincipal.IsInRole方法之後,我從Win32中得到一個很大的「Access Denied」錯誤。所以我實際上碰到了另一個死衚衕。

有什麼想法?

如果答案依賴於WinAPI或.NetFramework,則無關緊要。

感謝

+0

您可能,例如,使用的System.DirectoryServices,通過所有的用戶,直到找到所需的一個再檢查她的組 –

+0

你能告訴我們你怎麼弄SID通過Win32?如果這可以在.Net中完成,則可以調用IsInRole –

+0

@AlexK。更多信息添加。 –

回答

1

好了,檢查的WindowsIdentityWindowsPrincipal類的源代碼後,我發現,越來越原因「拒絕訪問」是我檢索到的令牌在首位的方式。 讓我們從頭開始:

WindowsIdentity是一個表示進程/線程令牌的類。所以初始化一個方法是提供一個令牌。在我的情況下,我使用OpenProcessToken函數從另一個進程中檢索到該令牌。

這適用於查詢令牌數據和檢索信息。就像我的情況一樣。但是,在WindowsPrincipal班旁邊使用時,這還不夠。

WindowsPrincipal.IsInRole使用CheckTokenMembershipEx來查看令牌是否屬於用戶組。但爲了能夠使用CheckTokenMembershipEx函數,您需要模擬進程/線程令牌。 WindowsPrincipal.IsInRole完全意識到這一點,並且如果提供的WindowsIdentity具有模擬級別None,將使用DuplicateTokenEx創建模擬令牌。

不幸的是,我犯了一個錯誤。當打開獲取令牌的過程時,我並沒有期待這種行爲。事實上,我甚至不知道WindowsPrincipal.IsInRole在底層使用了CheckTokenMembershipEx函數。所以打開進程標記時我沒有要求Duplicate訪問。這導致DuplicateTokenEx失敗並顯示「訪問被拒絕」消息。添加正確的,解決了一切。

這裏是任何有興趣的代碼:

public static WindowsIdentity GetProcessIdentity(Process process) 
    { 
     SafeTokenHandle token = SafeTokenHandle.InvalidHandle; 
     try 
     { 
      if (!Methods.OpenProcessToken(process.Handle, TokenAccessLevels.Query | TokenAccessLevels.Duplicate, out token)) 
      { 
       throw new Win32Exception(); 
      } 
      return new WindowsIdentity(token.DangerousGetHandle()); 
     } 
     finally 
     { 
      token.Dispose(); 
     } 
    } 

    private static TokenElevationType GetTokenElevation(IntPtr token) 
    { 
     var elevationTypeLength = Marshal.SizeOf(typeof (int)); 
     var elevationType = (TokenElevationType) 0; 
     if (!Methods.GetTokenInformation(token, 
      TokenInformationClass.TokenElevationType, 
      ref elevationType, elevationTypeLength, out elevationTypeLength)) 
     { 
      throw new Win32Exception(); 
     } 
     return elevationType; 
    } 

    public static bool IsProcessElevated(Process process) 
    { 
     WindowsIdentity processIdentity = GetProcessIdentity(process); 
     var tokenElevation = GetTokenElevation(processIdentity.Token); 
     if (tokenElevation == TokenElevationType.Limited) 
     { 
      return false; 
     } 
     if (tokenElevation == TokenElevationType.Full) 
     { 
      return true; 
     } 
     // Do we have a Default elevation type? Then the process elevation status depends directly 
     // to the owner user being a member of the Administrative group. 
     return new WindowsPrincipal(processIdentity).IsInRole(WindowsBuiltInRole.Administrator); 
    } 
相關問題