Cómo determinar si un subproceso se ejecuta en contexto de usuario de cuenta de administrador local

IMPORTANTE: Este artículo ha sido traducido por un software de traducción automática de Microsoft (http://support.microsoft.com/gp/mtdetails) en lugar de un traductor humano. Microsoft le ofrece artículos traducidos por un traductor humano y artículos traducidos automáticamente para que tenga acceso en su propio idioma a todos los artículos de nuestra base de conocimientos (Knowledge Base). Sin embargo, los artículos traducidos automáticamente pueden contener errores en el vocabulario, la sintaxis o la gramática, como los que un extranjero podría cometer al hablar el idioma. Microsoft no se hace responsable de cualquier imprecisión, error o daño ocasionado por una mala traducción del contenido o como consecuencia de su utilización por nuestros clientes. Microsoft suele actualizar el software de traducción frecuentemente.

Haga clic aquí para ver el artículo original (en inglés): 118626
Resumen
Para determinar si un subproceso se está ejecutando bajo una cuenta de administrador local, tiene que examinar el token de acceso está asociado con el subproceso. En este artículo se explica el procedimiento.

Con Windows 2000 y versiones posteriores, puede utilizar CheckTokenMembership() API en lugar de los pasos descritos en este artículo. Para obtener información adicional, consulte la documentación de Microsoft Platform SDK.
Más información
De manera predeterminada, el token que está asociado con un subproceso es el de su proceso que lo contiene. Este "contexto de usuario" es reemplazada por cualquier símbolo que está conectada directamente al subproceso. Por lo tanto, para determinar el contexto de usuario del subproceso, debe primero intenta obtener un símbolo (token) para el subproceso con la función OpenThreadToken . Si este método falla y la función GetLastError informa de referencia, a continuación, puede obtener el símbolo (token) para el proceso con la función en OpenProcessToken .

Después de obtener el testigo del usuario actual, puede utilizar la función AccessCheck para detectar si el usuario es un administrador. Para ello, siga estos pasos:
  1. Crear un identificador de seguridad (SID) para el grupo de administradores local mediante la función AllocateAndInitializeSid .
  2. Crear un nuevo descriptor de seguridad (SD) con un acceso control lista discrecional (DACL) que contiene una entrada de control de acceso (ACE) para el SID del grupo de administrador.
  3. Llame a AccessCheck con el token del usuario actual y el SD recién construido para detectar si el usuario es un administrador.
El ejemplo de código siguiente utiliza las funciones que se mencionan anteriormente en este artículo para probar si el subproceso actual se está ejecutando como un usuario que es un administrador en el equipo local.

Código de ejemplo

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

Propiedades

Id. de artículo: 118626 - Última revisión: 11/21/2006 15:29:45 - Revisión: 4.3

Microsoft Win32 Application Programming Interface

  • kbmt kbapi kbhowto kbkernbase kbsecurity KB118626 KbMtes
Comentarios