Share via


Ejecutar operaciones con privilegios mediante C++

Las aplicaciones cliente especiales pueden invocar operaciones con privilegios. Por ejemplo, una aplicación podría permitir que un administrador reinicie un equipo de oficina que no responde. Con Windows Management Instrumentation (WMI), puede ejecutar una operación privilegiada llamando al proveedor WMI para la operación privilegiada.

En el procedimiento siguiente se describe cómo llamar a un proveedor para una operación con privilegios.

Para llamar a un proveedor para una operación con privilegios

  1. Obtenga permisos para que el proceso de cliente ejecute la operación con privilegios.

    Normalmente, un administrador establece los permisos mediante herramientas administrativas del sistema, antes de ejecutar el proceso.

  2. Obtenga el permiso para que el proceso de proveedor habilite la operación con privilegios.

    Normalmente, puede establecer permisos de proveedor con una llamada a la función AdjustTokenPrivileges.

  3. Obtenga el permiso para que el proceso de cliente habilite la operación con privilegios.

    Este paso solo es necesario si el proveedor es local para el cliente. Si el cliente y el proveedor existen en el mismo equipo, el cliente debe habilitar específicamente la operación con privilegios mediante una de las técnicas siguientes:

    • Si el cliente posee el proceso, el cliente puede usar AdjustTokenPrivileges para ajustar el token de proceso antes de llamar a WMI. En este caso, no es necesario codificar más.
    • Si el cliente no puede acceder al token de cliente, el cliente puede usar el procedimiento siguiente para crear un token de subproceso y usar AdjustTokenPrivileges en ese token.

En el procedimiento siguiente se describe cómo crear un token de subproceso y usar AdjustTokenPrivileges en ese token.

Para crear un token de subproceso y usar AdjustTokenPrivileges en ese token

  1. Cree una copia del token de proceso mediante una llamada a ImpersonateSelf.

  2. Recupere el token de subproceso recién creado mediante una llamada a GetTokenInformation.

  3. Habilite la operación con privilegios con una llamada a AdjustTokenPrivileges en el nuevo token.

  4. Obtenga un puntero a IWbemServices.

  5. Oculte el puntero a IWbemServices con una llamada a CoSetProxyBlanket.

  6. Repita los pasos del 1 al 5 en cada llamada a WMI.

    Nota

    Debe repetir los pasos porque COM almacena en caché los tokens incorrectamente.

     

El ejemplo de código de este tema requiere la siguiente instrucción #include para compilarse correctamente.

#include <wbemidl.h>

En el ejemplo de código siguiente se muestra cómo habilitar privilegios en un equipo local.

// Get the privileges 
// The token has been obtained outside the scope of this code sample
// ================== 
DWORD dwLen;
bool bRes;
HANDLE hToken;

// obtain dwLen
bRes = GetTokenInformation(
  hToken, 
  TokenPrivileges, 
  NULL, 
  0,
  &dwLen
); 

BYTE* pBuffer = new BYTE[dwLen];
if(pBuffer == NULL)
{
  CloseHandle(hToken);
  return WBEM_E_OUT_OF_MEMORY;
} 

bRes = GetTokenInformation(
  hToken, 
  TokenPrivileges, 
  pBuffer,     
  dwLen,        
  &dwLen
);

if (!bRes)
{
  CloseHandle(hToken);
  delete [] pBuffer;
  return WBEM_E_ACCESS_DENIED;
} 

// Iterate through all the privileges and enable them all
// ====================================================== 
TOKEN_PRIVILEGES* pPrivs = (TOKEN_PRIVILEGES*)pBuffer;
for (DWORD i = 0; i < pPrivs->PrivilegeCount; i++)
{
  pPrivs->Privileges[i].Attributes |= SE_PRIVILEGE_ENABLED;
} 
// Store the information back in the token
// ========================================= 
bRes = AdjustTokenPrivileges(
  hToken, 
  FALSE, 
  pPrivs, 
  0, NULL, NULL
);

delete [] pBuffer;
CloseHandle(hToken); 

if (!bRes)
  return WBEM_E_ACCESS_DENIED;
else
  return WBEM_S_NO_ERROR;