diff options
author | Alexander Bokovoy <ab@samba.org> | 2012-05-24 15:38:41 +0300 |
---|---|---|
committer | Alexander Bokovoy <ab@samba.org> | 2012-05-24 16:21:26 +0200 |
commit | 72029d5547766787afb0a76c3959d1820388e28e (patch) | |
tree | 5159b88c04e705bef3565dcb787b8bfaba22a8fd /source3/lib | |
parent | 838435ab30c03e5db7eb1e80f486528231dffdfc (diff) | |
download | samba-72029d5547766787afb0a76c3959d1820388e28e.tar.gz samba-72029d5547766787afb0a76c3959d1820388e28e.tar.bz2 samba-72029d5547766787afb0a76c3959d1820388e28e.zip |
s3-smbldap: Add API for 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 call is wrapped in become_root()/unbecome_root() to allow proper permissions
in smbd to access needed resources in the callback, for example, credential caches.
When run outside smbd, become_root()/unbecome_root() are no-op.
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.
Diffstat (limited to 'source3/lib')
-rw-r--r-- | source3/lib/smbldap.c | 20 |
1 files changed, 19 insertions, 1 deletions
diff --git a/source3/lib/smbldap.c b/source3/lib/smbldap.c index c01d3fdc69..43ddaff53a 100644 --- a/source3/lib/smbldap.c +++ b/source3/lib/smbldap.c @@ -976,7 +976,20 @@ 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) { + /* We have to allow bind callback to be run under become_root/unbecome_root + to make sure within smbd the callback has proper write access to its resources, + like credential cache. This is similar to passdb case where this callback is supposed + to be used. When used outside smbd, become_root()/unbecome_root() are no-op. + */ + become_root(); + rc = ldap_state->bind_callback(ldap_struct, ldap_state, ldap_state->bind_callback_data); + unbecome_root(); + } 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 +1680,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 +1861,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)); |