Establecer el nivel de seguridad de proceso predeterminado mediante C++

Cuando una aplicación cliente inicia sesión en Instrumental de administración de Windows (WMI) por primera vez, debe establecer el nivel de seguridad de proceso predeterminado con una llamada a CoInitializeSecurity. COM usa la información de la llamada para determinar la cantidad de seguridad que debe tener otro proceso para acceder al proceso de aplicación cliente.

En este tema se describen las secciones siguientes:

Para la mayoría de las aplicaciones cliente, los argumentos que se muestran en el ejemplo siguiente establecen la seguridad predeterminada para 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;
}

El código requiere las siguientes referencias e instrucciones #include para compilar correctamente.

#define _WIN32_DCOM
#include <iostream>
using namespace std;
#include <Wbemidl.h>

#pragma comment(lib, "wbemuuid.lib")

Establecer el nivel de autenticación en RPC_C_AUTHN_LEVEL_DEFAULT permite a DCOM negociar el nivel de autenticación para que coincida con las demandas de seguridad del equipo de destino. Para obtener más información, consulte Cambiar las credenciales de autenticación predeterminadas mediante C++ y Cambiar la configuración de suplantación predeterminada mediante C++.

Cambiar las credenciales de autenticación predeterminadas mediante C++

Las credenciales de autenticación predeterminadas funcionan en la mayoría de las situaciones, pero es posible que tenga que usar diferentes credenciales de autenticación en diferentes situaciones. Por ejemplo, puede agregar cifrado a los procedimientos de autenticación.

En la tabla siguiente se enumeran y describen los distintos niveles de autenticación.

Nivel de autenticación Descripción
RPC_C_AUTHN_LEVEL_DEFAULT Autenticación de seguridad predeterminada.
RPC_C_AUTHN_LEVEL_NONE Sin autenticación.
RPC_C_AUTHN_LEVEL_CONNECT Autenticación solo cuando el cliente crea una relación con el servidor.
RPC_C_AUTHN_LEVEL_CALL Autenticación cada vez que el servidor recibe una RPC.
RPC_C_AUTHN_LEVEL_PKT Autenticación cada vez que el servidor recibe datos de un cliente.
RPC_C_AUTHN_LEVEL_PKT_INTEGRITY Autenticación que no se ha modificado ningún dato del paquete.
RPC_C_AUTHN_LEVEL_PKT_PRIVACY Incluye todos los niveles de autenticación anteriores y cifra el valor de cada llamada RPC.

 

Puede especificar las credenciales de autenticación predeterminadas para varios usuarios mediante una estructura SOLE_AUTHENTICATION_LIST en el parámetro pAuthList de CoInitializeSecurity.

En el ejemplo de código siguiente se muestra cómo cambiar las credenciales de autenticación.

// 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);

Cambiar los niveles de suplantación predeterminados mediante C++

COM proporciona los niveles de seguridad predeterminados leídos del registro del sistema. Sin embargo, a menos que se modifique específicamente, la configuración del Registro establece el nivel de suplantación demasiado bajo para que WMI funcione. Normalmente, el nivel de suplantación predeterminado es RPC_C_IMP_LEVEL_IDENTIFY, pero WMI necesita al menos RPC_C_IMP_LEVEL_IMPERSONATE para funcionar con la mayoría de los proveedores, y es posible que encuentre una situación en la que necesite establecer un nivel superior de suplantación. Para obtener más información, consulte Conexión a WMI en un equipo remoto (puede estar en inglés). En la tabla siguiente se enumeran los distintos niveles de suplantación.

Nivel Descripción
RPC_C_IMP_LEVEL_DEFAULT El sistema operativo elige el nivel de suplantación.
RPC_C_IMP_LEVEL_ANONYMOUS El servidor puede suplantar al cliente, pero el token de suplantación no se puede usar para nada.
RPC_C_IMP_LEVEL_IDENTIFY El servidor puede obtener la identidad del cliente y suplantar al cliente para la comprobación de ACL.
RPC_C_IMP_LEVEL_IMPERSONATE El servidor puede suplantar al cliente a través de un límite de equipo.
RPC_C_IMP_LEVEL_DELEGATE El servidor puede suplantar al cliente a través de varios límites y realizar llamadas en nombre del cliente.