Définition de l’authentification à l’aide de C++

L’une des tâches main de IWbemLocator::ConnectServer pour WMI est de retourner un pointeur vers un proxy IWbemServices. Via le proxy IWbemServices , vous pouvez accéder aux fonctionnalités de l’infrastructure WMI. Toutefois, le pointeur vers le proxy IWbemServices a l’identité du processus d’application client et non l’identité du processus IWbemServices . Par conséquent, si vous tentez d’accéder à IWbemServices avec le pointeur, vous pouvez recevoir un code d’accès refusé tel que E_ACCESSDENIED. Pour éviter l’erreur d’accès refusé, vous devez définir l’identité du nouveau pointeur avec un appel à l’interface CoSetProxyBlanket .

Un fournisseur peut définir la sécurité sur un espace de noms afin qu’aucune donnée ne soit retournée, sauf si vous utilisez la confidentialité des paquets (PktPrivacy) dans votre connexion à cet espace de noms. Cela garantit que les données sont chiffrées au fur et à mesure qu’elles traversent le réseau. Si vous essayez de définir un niveau d’authentification inférieur, vous obtiendrez un message d’accès refusé. Pour plus d’informations, consultez Définition des descripteurs de sécurité Namepace.

Pour plus d’informations sur la définition de l’authentification dans les scripts, consultez Définition du niveau de sécurité du processus par défaut à l’aide de VBScript.

Définition de la sécurité sur une interface IUnknown distante

Dans certaines situations, un accès plus important à un serveur qu’un simple pointeur vers un proxy est requis. Parfois, vous devrez peut-être obtenir une connexion sécurisée à l’interface IUnknown du proxy. À l’aide d’IUnknown, vous pouvez interroger le système distant pour obtenir des interfaces et d’autres techniques nécessaires.

Lorsqu’un proxy se trouve sur un ordinateur distant, le serveur délègue tous les appels à l’interface IUnknown du proxy à l’interface IUnknown . Par exemple, si vous appelez QueryInterface sur un proxy et que l’interface demandée ne faisait pas partie du proxy, le proxy envoie l’appel au serveur distant. À son tour, le serveur distant vérifie la prise en charge de l’interface appropriée. Si le serveur prend en charge l’interface, COM marshale un nouveau proxy vers le client afin que l’application puisse utiliser la nouvelle interface.

Des problèmes se produisent si le client ne dispose pas d’autorisations d’accès au serveur distant, mais utilise les informations d’identification d’un utilisateur qui le fait. Dans ce cas, toute tentative d’accès à QueryInterface sur le serveur distant échoue. La version finale sur le proxy échoue également, car l’utilisateur actuel n’a pas accès au serveur distant. Un symptôme de cette situation est un décalage d’un ou deux secondes avant que l’application cliente échoue à la version finale du proxy. L’échec se produit parce que COM a tenté d’accéder au serveur distant à l’aide des paramètres de sécurité par défaut de l’utilisateur actuel, qui n’incluent pas les informations d’identification modifiées qui permettaient d’accéder au serveur en premier lieu. Pour plus d’informations, consultez Définition de la sécurité sur IWbemServices et d’autres proxys.

Pour éviter l’échec de la connexion, utilisez CoSetProxyBlanket pour définir explicitement l’authentification de sécurité sur le pointeur retourné par IUnknown. À l’aide de CoSetProxyBlanket, vous pouvez vous assurer que le serveur distant reçoit l’identité d’authentification correcte.

L’exemple de code suivant montre comment utiliser CoSetProxyBlanket pour accéder à une interface IUnknown distante.

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;

Notes

Lorsque vous définissez la sécurité sur l’interface IUnknown d’un proxy, COM crée une copie du proxy qui ne peut pas être libérée tant que vous n’appelez pas CoUninitialize.

 

Définition de l’authentification à l’aide de WMI