Jak zjistit, zda je vlákno spuštěné v kontextu uživatele z místní účet správce

Překlady článku Překlady článku
ID článku: 118626 - Produkty, které se vztahují k tomuto článku.
Rozbalit všechny záložky | Minimalizovat všechny záložky

Na této stránce

Souhrn

Zjistit, zda je podproces v rámci účtu místního správce, budete muset zkontrolovat token přístupu přidružený k podprocesu. Tento článek popisuje, jak postupovat.

Se systémem Windows 2000 a novější verze můžete použít CheckTokenMembership() API namísto kroky popsané v tomto článku. Další informace naleznete v dokumentaci k sadě Microsoft Platform SDK.

Další informace

Ve výchozím token, který je přidružen k podprocesu je jeho obsahující procesu. Tato "kontext uživatele" je nahrazeno podle jakékoli token, který je připojeno přímo k podprocesu. Proto k určení podprocesu uživatelský kontext, měli byste se nejprve pokusit získat token podprocesu pomocí funkce OpenThreadToken. Pokud tato metoda se nezdaří a funkce GetLastError sestavy ERROR_NO_TOKEN, pak můžete získat token procesu pomocí funkce OpenProcessToken.

Po získání tokenu aktuálního uživatele, můžete zjistit, zda je uživatel správce funkce AccessCheck. Chcete-li to provést, postupujte takto:
  1. Pomocí funkce AllocateAndInitializeSid vytvořit identifikátor zabezpečení (SID) pro skupiny místních správců.
  2. Vytvořit nový popisovač zabezpečení (SD) s volitelné Access ovládací seznam (DACL) obsahující položky řízení přístupu (ACE) pro SID skupiny správců.
  3. Volání AccessCheck s tokenem aktuálního uživatele a nově vytvořené SD ke zjištění, zda je uživatel správcem.
Následující ukázkový kód používá funkce, které jsou uvedené dříve v tomto článku a otestujte, zda je aktuální podproces spuštěn jako uživatel, který je správcem místního počítače.

Ukázkový kód


#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 caller
belongs 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;
}

Vlastnosti

ID článku: 118626 - Poslední aktualizace: 21. listopadu 2006 - Revize: 4.3
Informace v tomto článku jsou určeny pro produkt:
  • Microsoft Win32 Application Programming Interface na těchto platformách
    • Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows XP
Klíčová slova: 
kbmt kbapi kbhowto kbkernbase kbsecurity KB118626 KbMtcs
Strojově přeložený článek
Důležité: Tento článek byl přeložen pomocí software společnosti Microsoft na strojový překlad, ne profesionálním překladatelem. Společnost Microsoft nabízí jak články přeložené překladatelem, tak články přeložené pomocí software na strojový překlad, takže všechny články ve Znalostní databázi (Knowledge Base) jsou dostupné v češtině. Překlad pomocí software na strojový překlad ale není bohužel vždy dokonalý. Obsahuje chyby ve skloňování slov, skladbě vět, nebo gramatice, podobně jako když cizinci dělají chyby při mluvení v češtině. Společnost Microsoft není právně zodpovědná za nepřesnosti, chyby nebo škody vzniklé chybami v překladu, nebo při použití nepřesně přeložených instrukcí v článku zákazníkem. Společnost Microsoft aktualizuje software na strojový překlad, aby byl počet chyb omezen na minimum.
Projděte si také anglickou verzi článku:118626

Dejte nám zpětnou vazbu

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com