Comment faire pour déterminer si un thread est en cours d'exécution dans le contexte utilisateur du compte administrateur local

Traductions disponibles Traductions disponibles
Numéro d'article: 118626 - Voir les produits auxquels s'applique cet article
Agrandir tout | Réduire tout

Sommaire

Résumé

Pour déterminer si un thread s'exécute sous un compte d'administrateur local, vous devez examiner le jeton d'accès qui est associé au thread. Cet article décrit comment procéder.

Avec Windows 2000 et versions ultérieures, vous pouvez utiliser l'API CheckTokenMembership() au lieu des étapes décrites dans cet article. Pour plus d'informations, consultez la documentation du Kit de développement Microsoft Platform SDK.

Plus d'informations

Par défaut, le jeton qui est associé à un thread est celui de son processus contenant. Ce «contexte de l'utilisateur» est remplacé par n'importe quel jeton directement attaché au thread. Par conséquent, pour déterminer le contexte de l'utilisateur d'un thread, vous devez tout d'abord tenter d'obtenir un jeton pour le thread avec la fonction OpenThreadToken. Si cette méthode échoue et que la fonction GetLastError signale ERROR_NO_TOKEN, puis vous pouvez obtenir le jeton pour le processus à l'aide de la fonction de OpenProcessToken.

Après avoir obtenu le jeton de l'utilisateur actuel, vous pouvez utiliser la fonction AccessCheck pour détecter si l'utilisateur est un administrateur. Pour ce faire, procédez comme suit :
  1. Créer un identificateur de sécurité (SID) pour le groupe administrateur local à l'aide de la fonction AllocateAndInitializeSid.
  2. Construire un nouveau descripteur de sécurité (SD) avec un accès discrétionnaire contrôle List (DACL, Discretionary Access Control List) qui contient une entrée de contrôle d'accès (ACE) pour le SID du groupe administrateur.
  3. Appelez AccessCheck avec le jeton de l'utilisateur actuel et le descripteur de sécurité nouvellement construit pour détecter si l'utilisateur est un administrateur.
L'exemple de code suivant utilise les fonctions qui sont mentionnées plus haut dans cet article pour vérifier si le thread en cours est en cours d'exécution en tant qu'utilisateur qui est administrateur sur l'ordinateur local.

Exemple de code


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

Propriétés

Numéro d'article: 118626 - Dernière mise à jour: mardi 21 novembre 2006 - Version: 4.3
Les informations contenues dans cet article s'appliquent au(x) produit(s) suivant(s):
  • Microsoft Win32 Application Programming Interface sur le système suivant
    • Microsoft Windows NT 4.0
    • the operating system: Microsoft Windows 2000
    • the operating system: Microsoft Windows XP
Mots-clés : 
kbmt kbapi kbhowto kbkernbase kbsecurity KB118626 KbMtfr
Traduction automatique
IMPORTANT : Cet article est issu du système de traduction automatique mis au point par Microsoft (http://support.microsoft.com/gp/mtdetails). Un certain nombre d?articles obtenus par traduction automatique sont en effet mis à votre disposition en complément des articles traduits en langue française par des traducteurs professionnels. Cela vous permet d?avoir accès, dans votre propre langue, à l?ensemble des articles de la base de connaissances rédigés originellement en langue anglaise. Les articles traduits automatiquement ne sont pas toujours parfaits et peuvent comporter des erreurs de vocabulaire, de syntaxe ou de grammaire (probablement semblables aux erreurs que ferait une personne étrangère s?exprimant dans votre langue !). Néanmoins, mis à part ces imperfections, ces articles devraient suffire à vous orienter et à vous aider à résoudre votre problème. Microsoft s?efforce aussi continuellement de faire évoluer son système de traduction automatique.
La version anglaise de cet article est la suivante: 118626
L'INFORMATION CONTENUE DANS CE DOCUMENT EST FOURNIE PAR MICROSOFT SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE. L'UTILISATEUR ASSUME LE RISQUE DE L'UTILISATION DU CONTENU DE CE DOCUMENT. CE DOCUMENT NE PEUT ETRE REVENDU OU CEDE EN ECHANGE D'UN QUELCONQUE PROFIT.

Envoyer des commentaires

 

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