Выполнение привилегированных операций с помощью 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;