From eb19fce5b473b1297305c3c6ba11f9d59b325991 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Thu, 15 Mar 2012 16:02:05 +0200 Subject: [PATCH] Add ability to use external callback to perform LDAP bind in smbldap In order to support other bind methods, introduce a generic bind callback. When smbldap_state.bind_callback is set, it means there is an alternative way to perform LDAP bind to ldap_simple_bind_s() so call it instead. The API expectation is similar to ldap_simple_bind_s(). A caller of smbldap API can pass additional information to the callback by setting smbldap_state.bind_callback_data pointer. Both callback and the data pointer elements of smbldap_state structure get cleaned up if someone sets proper credentials on smbldap_state with smbldap_set_creds() so if you are interested in using smbldap_state.bind_dn with the callback, make sure to set callback after credentials are set. --- source3/include/smbldap.h | 3 +++ source3/lib/smbldap.c | 13 ++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/source3/include/smbldap.h b/source3/include/smbldap.h index df9df76..ecb622b 100644 --- a/source3/include/smbldap.h +++ b/source3/include/smbldap.h @@ -32,6 +32,7 @@ * Struct to keep the state for all the ldap stuff * */ +typedef void* smbldap_bind_callback_data; struct smbldap_state { LDAP *ldap_struct; @@ -44,6 +45,8 @@ struct smbldap_state { bool anonymous; char *bind_dn; char *bind_secret; + int (*bind_callback)(LDAP *ldap_struct, struct smbldap_state *ldap_state); + smbldap_bind_callback_data bind_callback_data; bool paged_results; diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index 51bcabd..14da344 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -976,7 +976,13 @@ static int smbldap_connect_system(struct smbldap_state *ldap_state) #endif /*defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)*/ #endif - rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); + /* When there is an alternative bind callback is set, + attempt to use it to perform the bind */ + if (ldap_state->bind_callback != NULL) { + rc = ldap_state->bind_callback(ldap_struct, ldap_state); + } else { + rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret); + } if (rc != LDAP_SUCCESS) { char *ld_error = NULL; @@ -1667,6 +1673,8 @@ void smbldap_free_struct(struct smbldap_state **ldap_state) SAFE_FREE((*ldap_state)->bind_dn); SAFE_FREE((*ldap_state)->bind_secret); + (*ldap_state)->bind_callback = NULL; + (*ldap_state)->bind_callback_data = NULL; TALLOC_FREE(*ldap_state); @@ -1846,6 +1854,9 @@ bool smbldap_set_creds(struct smbldap_state *ldap_state, bool anon, const char * /* free any previously set credential */ SAFE_FREE(ldap_state->bind_dn); + ldap_state->bind_callback = NULL; + ldap_state->bind_callback_data = NULL; + if (ldap_state->bind_secret) { /* make sure secrets are zeroed out of memory */ memset(ldap_state->bind_secret, '\0', strlen(ldap_state->bind_secret)); -- 1.7.9.3