C++ を使用した特権操作の実行
特別なクライアント アプリケーションが特権操作を呼び出す場合があります。 たとえば、アプリケーションは、応答しないオフィス コンピューターを再起動することをマネージャーに許可する場合があります。 Windows Management Instrumentation (WMI) を使用すると、特権操作のために WMI プロバイダーを呼び出すことで、特権操作を実行できます。
次の手順では、特権操作のためにプロバイダーを呼び出す方法について説明します。
特権操作のためにプロバイダーを呼び出すには
特権操作を実行するクライアント プロセスのアクセス許可を取得します。
通常、管理者は、プロセスを実行する前に、システム管理ツールを使用してアクセス許可を設定します。
特権操作を有効にするプロバイダー プロセスのアクセス許可を取得します。
通常、AdjustTokenPrivileges 関数を呼び出してプロバイダーのアクセス許可を設定できます。
特権操作を有効にするクライアント プロセスのアクセス許可を取得します。
この手順は、プロバイダーがクライアントに対してローカルである場合にのみ必要です。 クライアントとプロバイダーが同じコンピューター上に存在する場合、クライアントは、次のいずれかの手法を使用して、特権操作を明示的に有効にする必要があります。
- クライアントがプロセスを所有している場合、クライアントは、AdjustTokenPrivileges を使用して、WMI を呼び出す前にプロセス トークンを調整できます。 この場合、これ以上コーディングする必要はありません。
- クライアントがクライアント トークンにアクセスできない場合、クライアントは、次の手順を使用してスレッド トークンを作成し、そのトークンで AdjustTokenPrivileges を使用することができます。
次の手順では、スレッド トークンを作成し、そのトークンで AdjustTokenPrivileges を使用する方法について説明します。
スレッド トークンを作成し、そのトークンで AdjustTokenPrivileges を使用するには
ImpersonateSelf を呼び出して、プロセス トークンのコピーを作成します。
GetTokenInformation を呼び出して、新しく作成されたスレッド トークンを取得します。
新しいトークンで AdjustTokenPrivileges を呼び出して特権操作を有効にします。
IWbemServices へのポインターを取得します。
CoSetProxyBlanket を呼び出して IWbemServices へのポインターをクロークします。
WMI への各呼び出しで手順 1 から 5 を繰り返します。
注意
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;