ldap_sasl_bind_s(GSSAPI)-Lo que debe proporcionarse en la estructura BERVAL de credenciales
(3)
ldap_sasl_bind_s
realizar un enlace SASL LDAP sobre GSSAPI, usando ldap_sasl_bind_s
. Para los interesados, aquí hay algunos consejos.
Para una descripción abstracta de las acciones que un cliente y servidor deben realizar durante una autenticación GSSAPI SASL, se debe leer "El Kerberos V5 (" GSSAPI ") Mecanismo simple de autenticación y capa de seguridad (SASL)" RFC; específicamente, la sección ''Lado del Cliente del Intercambio del Protocolo de Autenticación'' es de interés, ya que da una indicación de la secuencia de acciones que debemos realizar para enlazar con éxito a un servidor LDAP sobre Kerberos.
Las credenciales que ldap_sasl_bind_s
espera, su forma y significado, dependen del mecanismo de autenticación real que se utiliza, que en nuestro caso es Kerberos.
En Microsoft SDK, Kerberos está disponible a través de SSPI, que es más o menos la implementación de Microsoft de GSSAPI; los métodos que son relevantes para nuestro caso particular son: AcquireCredentialsHandle
, InitializeSecurityContext
, DecryptMessage
, EncryptMessage
Un enlace SASL LDAP sobre Kerberos tiene 3 fases.
Fase 1
Llame a AcquireCredentialsHandle
y InitializeSecurityContext
.
Notas importantes aquí:
- pasar a
AcquireCredentialsHandle
un puntero a una estructuraSEC_WINNT_AUTH_IDENTITY
que contiene las credenciales reales (dominio, nombre de usuario, contraseña) oNULL
si se van a usar las credenciales del hilo actual - el nombre de destino debe ser un SPN asignado a la cuenta en la que se ejecuta el servidor LDAP
- al llamar a
InitializeSecurityContext
, se debe solicitar la autenticación mutua.
Si todos los argumentos importantes son correctos: credenciales válidas, SPN válidos, token de entrada NULL
, la llamada InitializeSecurityContext
debe devolver SEC_I_CONTINUE_NEEDED
y completar correctamente el token de salida. El contenido de este token de salida debe ir en la estructura ldap_sasl_bind_s
espera como credenciales del cliente.
Llame a ldap_sasl_bind_s
con el token de salida de InitializeSecurityContext
como credenciales del cliente. Si todos los argumentos son correctos, DN vacío, GSSAPI como nombre del mecanismo, la llamada real debe devolver LDAP_SUCCESS
y el error LDAP más reciente para la sesión LDAP debe ser LDAP_SASL_BIND_IN_PROGRESS
.
Como nota al margen, el error LDAP más reciente para una sesión LDAP se puede descubrir llamando a ldap_get_option
en la sesión, con LDAP_OPT_ERROR_NUMBER
como opción.
Fase 2
Después de la llamada exitosa a ldap_sasl_bind_s
, su último argumento apunta a una estructura BERVAL
que contiene las credenciales del servidor. El contenido de esta estructura BERVAL
ahora debe usarse como el token de entrada para la segunda llamada a InitializeSecurityContext
.
Esta segunda llamada a InitializeSecurityContext
debería devolver SEC_OK
y un token de salida vacío.
Este token de salida vacío se debe usar como las credenciales del cliente para otra llamada a ldap_sasl_bind_s
. Esta segunda llamada a ldap_sasl_bind_s
debe devolver LDAP_SUCCESS
, con el error LDAP más reciente para la sesión LDAP siendo LDAP_SASL_BIND_IN_PROGRESS
.
Fase 3
Después de la segunda llamada exitosa a ldap_sasl_bind_s
, su último argumento apunta a una estructura BERVAL
que contiene datos del servidor. Esta información del servidor se debe dar como entrada a DecryptMessage
. Como se especifica en el RFC mencionado anteriormente, los datos descifrados deben tener 4 bytes de longitud.
El cliente debe construir su respuesta de acuerdo con la información en el mismo RFC.
Nota : En mi caso, omití el ID de autorización mencionado en el RFC. A mi entender, una identificación de autorización vacía conduce a la identificación de autenticación que se utiliza para la autorización también.
La respuesta que el cliente construyó se debe pasar como entrada a EncryptMessage
. El resultado de la llamada EncryptMessage
debe pasar como las credenciales del cliente para la tercera y última llamada a ldap_sasl_bind_s
.
Nota : La documentación de MSDN para usar EncryptMessage
en Kerberos parece estar incompleta. La Búsqueda de códigos de Google debería ayudar con un ejemplo de trabajo. Además, para un ejemplo funcional del flujo descrito anteriormente, se puede consultar el código fuente de Samba.
Estoy intentando usar el método ldap_sasl_bind_s
del Microsoft SDK C SDK, con GSSAPI como mecanismo de autenticación. ldap_sasl_bind_s
espera las credenciales como una estructura BERVAL
, que es opaca.
Dado un nombre de usuario (o DN) y una contraseña, ¿cómo llego a la estructura BERVAL
que se supone que debo pasar a ldap_sasl_bind_s
?
Los ejemplos que he encontrado hasta ahora
- son de otros SDK de LDAP C, no el de Microsoft
- use
ldap_sasl_bind_s
cuando desee la autenticación SIMPLE, pero necesito usar GSSAPI - utilice
ldap_sasl_interactive_bind_s
cuando seldap_sasl_interactive_bind_s
otros mecanismos de autenticación SASL. Sin embargo, no hayldap_sasl_interactive_bind_s
en el SDK de Microsoft.
Como nota al margen, el objetivo es poder vincular SASL a una variedad de servidores LDAP; por ahora: ActiveDirectory y OpenLDAP.
Cualquier puntero será muy apreciado.
Encontré el problema.
De acuerdo con este hilo ( https://groups.google.com/group/microsoft.public.active.directory.interfaces/browse_thread/thread/9c13fe85e520f0b4/820a136e032946e9?pli=1 ) hay un error con ldap_sasl_bind_s devolviendo las credenciales del servidor vacío en Windows XP. He probado mi aplicación en Windows 2008 Server y las credenciales se devuelven correctamente.
Artículo de Sun y MSDN . Probablemente, si puede intentar crear un programa de ejemplo, puede obtener las respuestas
PseudoCode
struct berval cred;
char mechanism[BUFSIZ];
getline( mechanism, sizeof(mechanism), stdin, "mechanism? " );
getline( passwd, sizeof(passwd), stdin,"credentials? " );
cred.bv_val = passwd;
cred.bv_len = strlen( passwd );
rc = ldap_sasl_bind_s( ld, dn, mechanism, &cred, NULL, NULL, NULL );