Выполнение привилегированных операций с помощью C++
Специальные клиентские приложения могут вызывать привилегированные операции. Например, приложение может дать возможность руководителю перезагрузить не отвечающий офисный компьютер. С помощью инструментария управления Windows (WMI) можно выполнить привилегированную операцию, вызвав поставщика WMI для привилегированной операции.
В следующей процедуре описывается вызов поставщика для привилегированной операции.
Вызов поставщика для привилегированной операции
Получите разрешения для клиентского процесса на выполнение привилегированной операции.
Как правило, администратор задает разрешения с помощью системных средств администрирования перед выполнением процесса.
Получите разрешения для процесса поставщика, чтобы включить привилегированную операцию.
Как правило, можно задать разрешения поставщика с вызовом функции AdjustTokenPrivileges.
Получите разрешение для клиентского процесса, чтобы включить привилегированную операцию.
Этот шаг необходим, только если поставщик является локальным для клиента. Если клиент и поставщик существуют на одном компьютере, клиент должен специально включить привилегированную операцию с помощью одного из следующих методов:
- Если клиент владеет процессом, клиент может использовать AdjustTokenPrivileges для настройки маркера процесса перед вызовом WMI. В этом случае вам не нужно кодировать дальше.
- Если клиент не может получить доступ к маркеру клиента, клиент может использовать следующую процедуру для создания маркера потока и использования AdjustTokenPrivileges на этом маркере.
В следующей процедуре описывается создание маркера потока и использование в этом токене с помощью AdjustTokenPrivileges.
Создать маркер потока и применить AdjustTokenPrivileges к этому маркеру
Создайте копию маркера процесса, вызвав ImpersonateSelf.
Получите созданный маркер потока путем вызова GetTokenInformation.
Активируйте привилегированную функцию, вызвав AdjustTokenPrivileges на новом токене.
Получите указатель на IWbemServices.
Замаскировать указатель на IWbemServices с вызовом CoSetProxyBlanket.
Повторите шаги 1–5 для каждого вызова WMI.
Заметка
Необходимо повторить шаги, так как токены COM кэшируются некорректно.
В примере кода в этом разделе требуется следующая инструкция #include для правильной компиляции.
#include <wbemidl.h>
В следующем примере кода показано, как включить привилегии на локальном компьютере.
// 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;