您目前已離線,請等候您的網際網路重新連線

如何判斷執行緒是否正在執行的本機系統管理員帳戶的使用者內容中

重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。

按一下這裡查看此文章的英文版本:118626
結論
若要判斷執行緒是否要在本機系統管理員帳戶下執行,您必須檢查與執行緒相關聯的存取權杖。本文將告訴您,如何執行這項操作。

Windows 2000 以及更新版本中,您可以使用 CheckTokenMembership() API 而非本文所述的步驟。如需詳細資訊請參閱 Microsoft 平台 SDK 文件。
其他相關資訊
預設情況下,與執行緒關聯的語彙基元是,其包含的處理序。這個 「 使用者內容 」 是任何附加直接至執行緒的語彙基元所取代。因此,來決定執行緒的使用者內容,您應該先嘗試取得具有 OpenThreadToken 函式執行緒語彙基元。如果這個方法會失敗並 GetLastError 函式報告 ERROR_NO_TOKEN,然後您可以取得處理序 OpenProcessToken 函式的語彙基元。

取得目前使用者的權杖之後您可以使用 AccessCheck 函數來偵測使用者是否是系統管理員。要這麼做,請您執行下列步驟:
  1. 使用 AllocateAndInitializeSid 函數,以建立本機系統管理員群組的安全性識別碼 (SID)。
  2. 建構新安全性描述元 (SD) 與一個判別存取控制清單 (DACL) 含有存取控制項目 (ACE) 之系統管理員群組的 SID。
  3. 呼叫 AccessCheck 與目前的使用者和新建構的 SD 來偵測使用者是否是系統管理員的語彙基元。
下列範例程式碼使用本文稍早若要測試是否使用者是本機電腦的系統管理員身分執行目前執行緒所述的函式。

範例程式碼

#include <windows.h>#include <stdio.h>#include <lmcons.h>BOOL IsCurrentUserLocalAdministrator(void);void main(int argc, char **argv){   if (IsCurrentUserLocalAdministrator())      printf("You are an administrator\n");   else      printf("You are not an administrator\n");}/*--------------------------------------------------------------------------IsCurrentUserLocalAdministrator ()This function checks the token of the calling thread to see if the callerbelongs to the Administrators group.Return Value:   TRUE if the caller is an administrator on the local machine.   Otherwise, FALSE.--------------------------------------------------------------------------*/BOOL IsCurrentUserLocalAdministrator(void){   BOOL   fReturn         = FALSE;   DWORD  dwStatus;   DWORD  dwAccessMask;   DWORD  dwAccessDesired;   DWORD  dwACLSize;   DWORD  dwStructureSize = sizeof(PRIVILEGE_SET);   PACL   pACL            = NULL;   PSID   psidAdmin       = NULL;   HANDLE hToken              = NULL;   HANDLE hImpersonationToken = NULL;   PRIVILEGE_SET   ps;   GENERIC_MAPPING GenericMapping;   PSECURITY_DESCRIPTOR     psdAdmin           = NULL;   SID_IDENTIFIER_AUTHORITY SystemSidAuthority = SECURITY_NT_AUTHORITY;   /*      Determine if the current thread is running as a user that is a member of      the local admins group.  To do this, create a security descriptor that      has a DACL which has an ACE that allows only local aministrators access.      Then, call AccessCheck with the current thread's token and the security      descriptor.  It will say whether the user could access an object if it      had that security descriptor.  Note: you do not need to actually create      the object.  Just checking access against the security descriptor alone      will be sufficient.   */   const DWORD ACCESS_READ  = 1;   const DWORD ACCESS_WRITE = 2;   __try   {      /*         AccessCheck() requires an impersonation token.  We first get a primary         token and then create a duplicate impersonation token.  The         impersonation token is not actually assigned to the thread, but is         used in the call to AccessCheck.  Thus, this function itself never         impersonates, but does use the identity of the thread.  If the thread         was impersonating already, this function uses that impersonation context.      */      if (!OpenThreadToken(GetCurrentThread(), TOKEN_DUPLICATE|TOKEN_QUERY, TRUE, &hToken))      {         if (GetLastError() != ERROR_NO_TOKEN)            __leave;         if (!OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE|TOKEN_QUERY, &hToken))            __leave;      }      if (!DuplicateToken (hToken, SecurityImpersonation, &hImpersonationToken))          __leave;      /*        Create the binary representation of the well-known SID that        represents the local administrators group.  Then create the security        descriptor and DACL with an ACE that allows only local admins access.        After that, perform the access check.  This will determine whether        the current user is a local admin.      */      if (!AllocateAndInitializeSid(&SystemSidAuthority, 2,                                    SECURITY_BUILTIN_DOMAIN_RID,                                    DOMAIN_ALIAS_RID_ADMINS,                                    0, 0, 0, 0, 0, 0, &psidAdmin))         __leave;      psdAdmin = LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH);      if (psdAdmin == NULL)         __leave;      if (!InitializeSecurityDescriptor(psdAdmin, SECURITY_DESCRIPTOR_REVISION))         __leave;      // Compute size needed for the ACL.      dwACLSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +                  GetLengthSid(psidAdmin) - sizeof(DWORD);      pACL = (PACL)LocalAlloc(LPTR, dwACLSize);      if (pACL == NULL)         __leave;      if (!InitializeAcl(pACL, dwACLSize, ACL_REVISION2))         __leave;      dwAccessMask= ACCESS_READ | ACCESS_WRITE;      if (!AddAccessAllowedAce(pACL, ACL_REVISION2, dwAccessMask, psidAdmin))         __leave;      if (!SetSecurityDescriptorDacl(psdAdmin, TRUE, pACL, FALSE))         __leave;      /*         AccessCheck validates a security descriptor somewhat; set the group         and owner so that enough of the security descriptor is filled out to         make AccessCheck happy.      */      SetSecurityDescriptorGroup(psdAdmin, psidAdmin, FALSE);      SetSecurityDescriptorOwner(psdAdmin, psidAdmin, FALSE);      if (!IsValidSecurityDescriptor(psdAdmin))         __leave;      dwAccessDesired = ACCESS_READ;      /*         Initialize GenericMapping structure even though you         do not use generic rights.      */      GenericMapping.GenericRead    = ACCESS_READ;      GenericMapping.GenericWrite   = ACCESS_WRITE;      GenericMapping.GenericExecute = 0;      GenericMapping.GenericAll     = ACCESS_READ | ACCESS_WRITE;      if (!AccessCheck(psdAdmin, hImpersonationToken, dwAccessDesired,                       &GenericMapping, &ps, &dwStructureSize, &dwStatus,                       &fReturn))      {         fReturn = FALSE;         __leave;      }   }   __finally   {      // Clean up.      if (pACL) LocalFree(pACL);      if (psdAdmin) LocalFree(psdAdmin);      if (psidAdmin) FreeSid(psidAdmin);      if (hImpersonationToken) CloseHandle (hImpersonationToken);      if (hToken) CloseHandle (hToken);   }   return fReturn;}

警告:本文為自動翻譯

內容

文章識別碼:118626 - 最後檢閱時間:11/21/2006 15:29:45 - 修訂: 4.3

Microsoft Win32 Application Programming Interface

  • kbmt kbapi kbhowto kbkernbase kbsecurity KB118626 KbMtzh
意見反應