ldap_sasl_bind_s (GSSAPI) - Que faut-il prévu dans les pouvoirs la structure BERVAL
Question
Je suis en train d'utiliser le ldap_sasl_bind_s
méthode à partir du SDK C Microsoft LDAP, avec comme mécanisme d'authentification GSSAPI . ldap_sasl_bind_s
attend les informations d'identification en tant que structure BERVAL
, qui est opaque.
Étant donné un nom d'utilisateur (ou DN) et un mot de passe, Comment puis-je obtenir à la structure BERVAL
que je suis censé passer à ldap_sasl_bind_s
?
Les exemples que j'ai trouvé jusqu'à présent
- sont d'autres SDKs C LDAP - pas celui de Microsoft
- Utilisation
ldap_sasl_bind_s
lorsque l'authentification est souhaitée SIMPLE - mais je dois utiliser GSSAPI
utilisation -
ldap_sasl_interactive_bind_s
lorsque d'autres mécanismes d'authentification SASL sont souhaitées. Cependant, il n'y a pasldap_sasl_interactive_bind_s
dans le SDK Microsoft.
Comme une note de côté, l'objectif est d'être capable de se lier sur SASL à une variété de serveurs LDAP; pour l'instant. ActiveDirectory et OpenLDAP
Les pointeurs sera grandement appréciée.
La solution
J'ai réussi à effectuer une liaison LDAP SASL sur GSSAPI, en utilisant ldap_sasl_bind_s
. Pour les intéressés, voici quelques conseils.
Pour une description abstraite des actions d'un client et le serveur besoin d'effectuer lors d'une authentification GSSAPI SASL, "Le Kerberos V5 (" GSSAPI ") simple couche d'authentification et de sécurité (SASL) mécanisme" RFC devrait être lu; Plus précisément, la section « côté client d'authentification Exchange Protocol » est d'intérêt, car elle donne une indication de la séquence d'actions que nous devons effectuer pour lier avec succès à un serveur LDAP sur Kerberos.
Les pouvoirs ldap_sasl_bind_s
- attend leur forme et leur sens -. Dépendent du mécanisme d'authentification réel utilisé, ce qui dans notre cas est Kerberos
Dans le Microsoft SDK, Kerberos est disponible via SSPI - qui est à peu près la mise en œuvre Microsoft de GSSAPI; les méthodes qui sont pertinentes pour notre cas particulier sont les suivants: AcquireCredentialsHandle
, InitializeSecurityContext
, DecryptMessage
, EncryptMessage
Un LDAP SASL bind sur Kerberos a 3 phases.
Phase 1
Appel AcquireCredentialsHandle
et InitializeSecurityContext
.
Remarques importantes ici:
- passer à
AcquireCredentialsHandle
un pointeur sur une structure contenant les informations d'identificationSEC_WINNT_AUTH_IDENTITY
réelles (domaine, nom d'utilisateur, mot de passe), ouNULL
si les informations d'identification du fil en cours doivent être utilisés - le nom de la cible doit être un SPN mis en correspondance avec le compte sous lequel le serveur LDAP est en cours d'exécution
- lors de l'appel
InitializeSecurityContext
, l'authentification mutuelle doit être demandée.
Si tous les arguments importants sont corrects - informations d'identification valides, SPN valides, entrée NULL
jeton - l'appel InitializeSecurityContext
doit retourner SEC_I_CONTINUE_NEEDED
et remplir correctement le jeton de sortie. Le contenu de ce jeton de sortie devrait aller dans la structure de BERVAL
ldap_sasl_bind_s
attend que les informations d'identification des clients.
Appel ldap_sasl_bind_s
avec la sortie de jeton InitializeSecurityContext
comme des informations d'identification des clients. Si tous les arguments sont corrects - vide DN, GSSAPI comme nom de mécanisme - l'appel réel devrait revenir LDAP_SUCCESS
et la plus récente erreur LDAP pour la session LDAP devrait être LDAP_SASL_BIND_IN_PROGRESS
.
Comme une note de côté, la plus récente erreur LDAP pour une session LDAP peut être découverte en appelant ldap_get_option
sur la session, avec LDAP_OPT_ERROR_NUMBER
comme option.
Phase 2
Après l'appel réussi à ldap_sasl_bind_s
, ses derniers points d'argument à une structure BERVAL
contenant les informations d'identification du serveur. Le contenu de cette structure BERVAL
doit maintenant être utilisé comme jeton d'entrée pour le deuxième appel à InitializeSecurityContext
.
Ce deuxième appel à InitializeSecurityContext
doit retourner SEC_OK
et un jeton de sortie vide.
Ce jeton de sortie vide doit être utilisé comme les informations d'identification du client pour un autre appel à ldap_sasl_bind_s
. Ce deuxième appel à ldap_sasl_bind_s
doit retourner LDAP_SUCCESS
, avec le plus d'erreur LDAP récente pour la session LDAP étant LDAP_SASL_BIND_IN_PROGRESS
.
Phase 3
Après le deuxième appel réussi à ldap_sasl_bind_s
, ses derniers points d'argument à une structure BERVAL
contenant des données de serveur. Ces données de serveur doit être donné en entrée à DecryptMessage
. Comme spécifié dans la RFC mentionné précédemment, les données décryptées doivent être de 4 octets de long.
Le client doit construire sa réponse en fonction des informations dans le même RFC.
Remarque : Dans mon cas, j'omis l'ID d'autorisation mentionnée dans le RFC. À ma connaissance, un conduit d'identité d'autorisation vide à l'ID d'authentification utilisés pour l'autorisation ainsi.
La réponse du client construit doit ensuite être transmis en entrée à EncryptMessage
. La sortie de l'appel EncryptMessage
devrait alorsêtre transmis comme les informations d'identification de client pour le troisième et dernier appel à ldap_sasl_bind_s
.
Remarque : La documentation MSDN pour l'utilisation EncryptMessage
sous Kerberos semble être incomplètes. Recherche de code de Google devrait aider à un exemple de travail. En outre, pour un exemple de travail du flux décrit ci-dessus, le code source de Samba peut être consulté.
Autres conseils
Je trouve le problème.
D'après ce fil ( https://groups.google.com/group/microsoft.public.active.directory.interfaces/browse_thread/thread/9c13fe85e520f0b4/820a136e032946e9?pli=1 ) il y a un bug avec ldap_sasl_bind_s retour serveur vide informations d'identification dans Windows XP. Je l'ai testé mon application sous Windows 2008 Server et les informations d'identification sont retournés correctement.
Article de Sun et MSDN . Probablement, si vous pouvez essayer de créer un exemple de programme vous pouvez obtenir les réponses
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 );