次の方法で共有


C++ を使用した認証の設定

IWbemLocator::ConnectServer for WMI の主なタスクの 1 つは、IWbemServices プロキシへのポインターを返します。 IWbemServices プロキシを使用して、WMI インフラストラクチャの機能にアクセスできます。 ただし、IWbemServices プロキシへのポインターには、IWbemServices プロセスの ID ではなく、クライアント アプリケーション プロセスの ID があります。 したがって、ポインター IWbemServices にアクセスしようとすると、E_ACCESSDENIEDなどのアクセス拒否コードを受け取ることができます。 アクセス拒否エラーを回避するには、CoSetProxyBlanket インターフェイスを呼び出して、新しいポインターの ID を設定する必要があります。

プロバイダーは、その名前空間への接続でパケット プライバシー (PktPrivacy) を使用しない限り、データが返されないように、名前空間にセキュリティを設定できます。 これにより、ネットワークを通過するデータが暗号化されます。 低い認証レベルを設定しようとすると、アクセス拒否メッセージが表示されます。 詳細については、「Namepace セキュリティ記述子の設定」を参照してください。

スクリプトでの認証の設定の詳細については、「VBScriptを使用した既定のプロセス セキュリティ レベルの設定」を参照してください。

リモート IUnknown インターフェイスでのセキュリティの設定

場合によっては、プロキシへのポインターだけでなく、サーバーへのアクセスが多くなります。 場合によっては、プロキシの IUnknown インターフェイスへのセキュリティで保護された接続が必要になる場合があります。 IUnknownを使用すると、リモート システムに対してインターフェイスやその他の必要な手法を照会できます。

プロキシがリモート コンピューター上にある場合、サーバーはプロキシの IUnknown インターフェイスへのすべての呼び出しを、IUnknown インターフェイスに委任します。 たとえば、プロキシ QueryInterface を呼び出し、要求されたインターフェイスがプロキシの一部ではなかった場合、プロキシはリモート サーバーに呼び出しを送信します。 次に、リモート サーバーは、適切なインターフェイスのサポートを確認します。 サーバーがインターフェイスをサポートしている場合、COM は新しいプロキシをクライアントにマーシャリングして、アプリケーションが新しいインターフェイスを使用できるようにします。

クライアントがリモート サーバーへのアクセス許可を持っていないが、そのユーザーの資格情報を使用している場合、問題が発生します。 このような状況では、リモート サーバー QueryInterface にアクセスしようとすると失敗します。 現在のユーザーがリモート サーバーにアクセスできないため、プロキシの最終リリースも失敗します。 この現象は、クライアント アプリケーションが最終的なプロキシ リリースに失敗するまでの 1 秒または 2 秒のラグです。 このエラーは、COM が現在のユーザーの既定のセキュリティ設定を使用してリモート サーバーにアクセスしようとしたために発生します。この設定には、最初にサーバーへのアクセスを許可した変更された資格情報は含まれません。 詳細については、「IWbemServices およびその他のプロキシでのセキュリティの設定」を参照してください。

接続の失敗を回避するには、CoSetProxyBlanket を使用して、IUnknownから返されるポインターセキュリティ認証を明示的に設定します。 CoSetProxyBlanketを使用して、リモート サーバーが正しい認証 ID を受け取っていることを確認できます。

次のコード例は、CoSetProxyBlanket を使用して、リモート IUnknown インターフェイスにアクセスする方法を示しています。

SEC_WINNT_AUTH_IDENTITY_W* pAuthIdentity = 
   new SEC_WINNT_AUTH_IDENTITY_W;
ZeroMemory(pAuthIdentity, sizeof(SEC_WINNT_AUTH_IDENTITY_W));

pAuthIdentity->User = new WCHAR[32];
StringCbCopyW(pAuthIdentity->User,sizeof(L"MyUser"),L"MyUser");
pAuthIdentity->UserLength = wcslen(pAuthIdentity->User);

pAuthIdentity->Domain = new WCHAR[32];
StringCbCopyW(pAuthIdentity->Domain,sizeof(L"MyDomain"),L"MyDomain");
pAuthIdentity->DomainLength = wcslen(pAuthIdentity->Domain);

pAuthIdentity->Password = new WCHAR[32];
pAuthIdentity->Password[0] = NULL;
pAuthIdentity->PasswordLength = wcslen( pAuthIdentity->Password);

pAuthIdentity->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;

IWbemServices* pWbemServices = 0;

// Set proxy security
hr = CoSetProxyBlanket(pWbemServices, 
                       RPC_C_AUTHN_DEFAULT, 
                       RPC_C_AUTHZ_NONE, 
                       COLE_DEFAULT_PRINCIPAL, 
                       RPC_C_AUTHN_LEVEL_DEFAULT, 
                       RPC_C_IMP_LEVEL_IMPERSONATE, 
                       pAuthIdentity, 
                       EOAC_NONE 
);
if (FAILED(hr))
{
   cout << "Count not set proxy blanket. Error code = 0x"
        << hex << hr << endl;
   pWbemServices->Release();
   return 1;
}

// Set IUnknown security
IUnknown*    pUnk = NULL;
pWbemServices->QueryInterface(IID_IUnknown, (void**) &pUnk);

hr = CoSetProxyBlanket(pUnk, 
                       RPC_C_AUTHN_DEFAULT, 
                       RPC_C_AUTHZ_NONE, 
                       COLE_DEFAULT_PRINCIPAL, 
                       RPC_C_AUTHN_LEVEL_DEFAULT, 
                       RPC_C_IMP_LEVEL_IMPERSONATE, 
                       pAuthIdentity, 
                       EOAC_NONE 
);
if (FAILED(hr))
{
   cout << "Count not set proxy blanket. Error code = 0x"
        << hex << hr << endl;
   pUnk->Release();
   pWbemServices->Release();
   delete [] pAuthIdentity->User;
   delete [] pAuthIdentity->Domain;
   delete [] pAuthIdentity->Password;
   delete pAuthIdentity;   
   return 1;
}

// cleanup IUnknown
pUnk->Release();

//
// Perform a bunch of operations
//

// Cleanup
pWbemServices->Release();

delete [] pAuthIdentity->User;
delete [] pAuthIdentity->Domain;
delete [] pAuthIdentity->Password;

delete pAuthIdentity;

手記

プロキシの IUnknown インターフェイスにセキュリティを設定すると、CoUninitializeを呼び出すまで解放できないプロキシのコピーが COM によって作成されます。

 

WMI での認証の設定