Esecuzione di operazioni con privilegi con C++

Le applicazioni client speciali possono richiamare operazioni con privilegi. Ad esempio, un'applicazione potrebbe consentire a un responsabile di riavviare un computer ufficio non rispondente. Usando Strumentazione gestione Windows (WMI), è possibile eseguire un'operazione con privilegi chiamando il provider WMI per l'operazione con privilegi.

La procedura seguente descrive come chiamare un provider per un'operazione con privilegi.

Per chiamare un provider per un'operazione con privilegi

  1. Ottenere le autorizzazioni per il processo client per eseguire l'operazione con privilegi.

    In genere, un amministratore imposta le autorizzazioni usando gli strumenti di amministrazione del sistema, prima di eseguire il processo.

  2. Ottenere l'autorizzazione per il processo del provider per abilitare l'operazione con privilegi.

    In genere, è possibile impostare le autorizzazioni del provider con una chiamata alla funzione AdjustTokenPrivileges .

  3. Ottenere l'autorizzazione per il processo client per abilitare l'operazione con privilegi.

    Questo passaggio è necessario solo se il provider è locale al client. Se il client e il provider esistono nello stesso computer, il client deve abilitare in modo specifico l'operazione con privilegi usando una delle tecniche seguenti:

    • Se il client possiede il processo, il client può usare AdjustTokenPrivileges per modificare il token di processo prima di chiamare WMI. In questo caso, non è necessario codificare ulteriormente.
    • Se il client non può accedere al token client, il client può usare la procedura seguente per creare un token di thread e usare AdjustTokenPrivileges su tale token.

La procedura seguente descrive come creare un token di thread e usare AdjustTokenPrivileges in tale token.

Per creare un token di thread e usare AdjustTokenPrivileges nel token

  1. Creare una copia del token di processo chiamando ImpersonateSelf.

  2. Recuperare il token di thread appena creato chiamando GetTokenInformation.

  3. Abilitare l'operazione con privilegi con una chiamata a AdjustTokenPrivileges nel nuovo token.

  4. Ottenere un puntatore a IWbemServices.

  5. Mascherare il puntatore a IWbemServices con una chiamata a CoSetProxyBlanket.

  6. Ripetere i passaggi da 1 a 5 per ogni chiamata a WMI.

    Nota

    È necessario ripetere i passaggi perché i token COM memorizzano nella cache in modo errato.

     

L'esempio di codice in questo argomento richiede la compilazione corretta dell'istruzione #include seguente.

#include <wbemidl.h>

Nell'esempio di codice seguente viene illustrato come abilitare i privilegi in un computer locale.

// 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;