Definindo a autenticação usando C++
Uma das principais tarefas do IWbemLocator::ConnectServer para WMI é devolver um ponteiro para um proxy IWbemServices . Através do IWbemServices proxy, você pode acessar os recursos da infraestrutura WMI. No entanto, o ponteiro para o proxy de IWbemServices tem a identidade do processo do aplicativo cliente e não a identidade do processo de IWbemServices . Portanto, se você tentar acessar IWbemServices com o ponteiro, poderá receber um código de acesso negado, como E_ACCESSDENIED. Para evitar o erro de acesso negado, você deve definir a identidade do novo ponteiro com uma chamada para o CoSetProxyBlanket interface.
Um provedor pode definir a segurança em um namespace para que nenhum dado seja retornado, a menos que você use a privacidade de pacotes (PktPrivacy) em sua conexão com esse namespace. Isso garante que os dados sejam criptografados à medida que atravessam a rede. Se você tentar definir um nível de autenticação mais baixo, receberá uma mensagem de acesso negado. Para obter mais informações, consulte definindo descritores de segurança Namepace.
Para obter mais informações sobre como definir a autenticação em scripts, consulte Definindo o nível de segurança do processo padrão usando o VBScript.
Definindo a segurança em uma interface IUnknown remota
Em algumas situações, é necessário mais acesso a um servidor do que apenas um ponteiro para um proxy. Às vezes, você pode precisar obter uma conexão segura com o IUnknown interface do proxy. Usando IUnknown, você pode consultar o sistema remoto para interfaces e outras técnicas necessárias.
Quando um proxy está localizado em um computador remoto, o servidor delega todas as chamadas para o IUnknown interface do proxy para o IUnknown interface. Por exemplo, se você chamar QueryInterface em um proxy e a interface solicitada não fizer parte do proxy, o proxy enviará a chamada para o servidor remoto. Por sua vez, o servidor remoto verifica o suporte de interface apropriado. Se o servidor suportar a interface, COM marshals um novo proxy de volta para o cliente para que o aplicativo possa usar a nova interface.
Os problemas surgem se o cliente não tiver permissões de acesso ao servidor remoto, mas estiver usando as credenciais de um usuário que o faça. Nessa situação, qualquer tentativa de acessar QueryInterface no servidor remoto falhará. A versão final no proxy também falha, porque o usuário atual não tem acesso ao servidor remoto. Um sintoma disso é um atraso de um ou dois segundos antes de a aplicação cliente falhar na execução final do proxy. A falha ocorre porque COM tentou acessar o servidor remoto usando as configurações de segurança padrão do usuário atual, que não incluem as credenciais modificadas que permitiram o acesso ao servidor em primeiro lugar. Para obter mais informações, consulte Definindo a segurança no IWbemServices e outros proxies.
Para evitar a conexão com falha, use CoSetProxyBlanket para definir explicitamente a autenticação de segurança no ponteiro retornado de IUnknown. Usando CoSetProxyBlanket, você pode garantir que o servidor remoto receba a identidade de autenticação correta.
O exemplo de código a seguir mostra como usar CoSetProxyBlanket para acessar um remoto IUnknown interface.
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;
Observação
Quando você define a segurança no IUnknown interface de um proxy, COM cria uma cópia do proxy que não pode ser liberada até que você chame CoUninitialize.
Tópicos relacionados