C++ を使用した既定のプロセス セキュリティ レベルの設定
クライアント アプリケーションが Windows Management Instrumentation (WMI) に初めてログオンするときは、CoInitializeSecurity の呼び出しで既定のプロセス セキュリティ レベルを設定する必要があります。 COM は、呼び出し内の情報を使用して、他のプロセスがクライアント アプリケーション プロセスにアクセスするためにどれだけのセキュリティを必要とするかを調べます。
このトピックでは次のセクションを扱います。
ほとんどのクライアント アプリケーションでは、次の例に示す引数で WMI の既定のセキュリティを設定します。
HRESULT hr = NULL;
hr = CoInitializeSecurity(
NULL, // security descriptor
-1, // use this simple setting
NULL, // use this simple setting
NULL, // reserved
RPC_C_AUTHN_LEVEL_DEFAULT, // authentication level
RPC_C_IMP_LEVEL_IMPERSONATE, // impersonation level
NULL, // use this simple setting
EOAC_NONE, // no special capabilities
NULL); // reserved
if (FAILED(hr))
{
CoUninitialize();
cout << "Failed to initialize security. Error code = 0x"
<< hex << hr << endl;
return;
}
コードは、正しくコンパイルするために次の参照と #include ステートメントが必要です。
#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <Wbemidl.h>
#pragma comment(lib, "wbemuuid.lib")
認証レベルを RPC_C_AUTHN_LEVEL_DEFAULT に設定すると、DCOM はターゲット コンピューターのセキュリティ需要に合わせて認証レベルをネゴシエートできます。 詳細については、「C++ を使用した既定の認証資格情報の変更」と「C++ を使用した既定の偽装設定の変更」を参照してください。
C++ を使用した既定の認証資格情報の変更
既定の認証資格情報はほとんどの状況で機能しますが、さまざまな状況で異なる認証資格情報を使用したくなる場合もあるでしょう。 たとえば、認証手順に暗号化を追加するのもよいかもしれません。
次の表に、さまざまな認証レベルの一覧と説明を示します。
認証レベル | 説明 |
---|---|
RPC_C_AUTHN_LEVEL_DEFAULT | 既定のセキュリティ認証。 |
RPC_C_AUTHN_LEVEL_NONE | 認証なし。 |
RPC_C_AUTHN_LEVEL_CONNECT | クライアントがサーバーとのリレーションシップを作成するときに限った認証。 |
RPC_C_AUTHN_LEVEL_CALL | サーバーが RPC を受け取るたびに行われる認証。 |
RPC_C_AUTHN_LEVEL_PKT | サーバーがクライアントからデータを受け取るたびに行われる認証。 |
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY | パケットからのデータが変更されていないことの認証。 |
RPC_C_AUTHN_LEVEL_PKT_PRIVACY | 以前のすべての認証レベルが含まれており、各 RPC 呼び出しの値が暗号化されます。 |
CoInitializeSecurity の pAuthList パラメーターで SOLE_AUTHENTICATION_LIST 構造を使用することで、複数のユーザーの既定の認証資格情報を指定できます。
次のコード例は、認証資格情報を変更する方法を示しています。
// Auth Identity structure
SEC_WINNT_AUTH_IDENTITY_W authidentity;
SecureZeroMemory( &authidentity, sizeof(authidentity) );
authidentity.User = L"MyUser";
authidentity.UserLength = wcslen( authidentity.User );
authidentity.Domain = L"MyDomain ";
authidentity.DomainLength = wcslen( authidentity.Domain );
authidentity.Password = L"";
authidentity.PasswordLength = wcslen( authidentity.Password );
authidentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
SecureZeroMemory( authninfo, sizeof(SOLE_AUTHENTICATION_INFO)*2 );
// NTLM Settings
authninfo[0].dwAuthnSvc = RPC_C_AUTHN_WINNT;
authninfo[0].dwAuthzSvc = RPC_C_AUTHZ_NONE;
authninfo[0].pAuthInfo = &authidentity;
// Kerberos Settings
authninfo[1].dwAuthnSvc = RPC_C_AUTHN_GSS_KERBEROS ;
authninfo[1].dwAuthzSvc = RPC_C_AUTHZ_NONE;
authninfo[1].pAuthInfo = &authidentity;
SOLE_AUTHENTICATION_LIST authentlist;
authentlist.cAuthInfo = 2;
authentlist.aAuthInfo = authninfo;
CoInitializeSecurity(
NULL,
-1,
NULL,
NULL,
RPC_C_AUTHN_LEVEL_CALL,
RPC_C_IMP_LEVEL_IMPERSONATE,
&authentlist,
EOAC_NONE,
NULL);
C++ を使用した既定の偽装レベルの変更
COM から、システム レジストリから読み取られた既定のセキュリティ レベルが提供されます。 ただし、特に変更されない限り、レジストリ設定により設定される偽装レベルは、WMI が機能するには低すぎます。 通常、既定の偽装レベルは RPC_C_IMP_LEVEL_IDENTIFY ですが、WMI はほとんどのプロバイダーで機能するためには RPC_C_IMP_LEVEL_IMPERSONATE 以上を必要とし、もっと高いレベルの偽装の設定が必要になる場合もあるかもしれません。 詳細については、「リモート コンピューター上の WMI への接続」を参照してください。 次の表に、偽装のさまざまなレベルを示します。
Level | 説明 |
---|---|
RPC_C_IMP_LEVEL_DEFAULT | オペレーティング システムが偽装のレベルを選択します。 |
RPC_C_IMP_LEVEL_ANONYMOUS | サーバーはクライアントを偽装できますが、偽装トークンは何のためにも使用することができません。 |
RPC_C_IMP_LEVEL_IDENTIFY | サーバーは、クライアントの ID を取得し、クライアントを偽装して ACL チェックを行うことができます。 |
RPC_C_IMP_LEVEL_IMPERSONATE | サーバーは、1 つのコンピューター境界を越えてクライアントを偽装できます。 |
RPC_C_IMP_LEVEL_DELEGATE | サーバーは、複数の境界にわたってクライアントを偽装でき、クライアントの代わりに呼び出しを行うことができます。 |