Executar operações privilegiadas usando C++
Aplicativos cliente especiais podem invocar operações privilegiadas. Por exemplo, um aplicativo pode permitir que um gerente reinicie um computador do escritório sem resposta. Usando a WMI (Instrumentação de Gerenciamento do Windows), você pode executar uma operação privilegiada chamando o provedor WMI para a operação privilegiada.
O procedimento a seguir descreve como chamar um provedor para uma operação privilegiada.
Para chamar um provedor para uma operação privilegiada
Obtenha permissões para o processo do cliente a fim de executar a operação com privilégios.
Normalmente, um administrador define as permissões usando ferramentas administrativas do sistema antes de executar o processo.
Obtenha permissão para o processo do provedor para habilitar a operação privilegiada.
Normalmente, você pode definir permissões de provedor com uma chamada para a função AdjustTokenPrivileges.
Obtenha permissão para o processo do cliente para habilitar a operação privilegiada.
Essa etapa só será necessária se o provedor for local em relação ao cliente. Se o cliente e o provedor existirem no mesmo computador, o cliente deverá habilitar especificamente a operação privilegiada usando uma das seguintes técnicas:
- Se o cliente for proprietário do processo, o cliente poderá usar AdjustTokenPrivileges para ajustar o token de processo antes de chamar o WMI. Nesse caso, você não precisa de nenhum código adicional.
- Se o cliente não puder acessar o token do cliente, o cliente poderá usar o procedimento a seguir para criar um token de thread e usar AdjustTokenPrivileges nesse token.
O procedimento a seguir descreve como criar um token de thread e usar AdjustTokenPrivileges nesse token.
Para criar um token de thread e usar AdjustTokenPrivileges nesse token
Crie uma cópia do token de processo chamando ImpersonateSelf.
Recupere o token de thread recém-criado chamando GetTokenInformation.
Habilite a operação privilegiada com uma chamada para AdjustTokenPrivileges no novo token.
Obtenha um ponteiro para IWbemServices.
Camufle o ponteiro para IWbemServices com uma chamada para CoSetProxyBlanket.
Repita as etapas de 1 a 5 em cada chamada ao WMI.
Observação
Você deve repetir as etapas porque o COM armazena tokens em cache incorretamente.
O exemplo de código neste tópico requer a instrução #include a seguir para compilar corretamente.
#include <wbemidl.h>
O exemplo de código a seguir mostra como habilitar privilégios em um computador 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;