1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

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.
This commit is contained in:
Alexander Bokovoy 2012-05-24 15:38:41 +03:00
parent 838435ab30
commit 72029d5547
2 changed files with 21 additions and 1 deletions

View File

@ -44,6 +44,8 @@ struct smbldap_state {
bool anonymous;
char *bind_dn;
char *bind_secret;
int (*bind_callback)(LDAP *ldap_struct, struct smbldap_state *ldap_state, void *data);
void *bind_callback_data;
bool paged_results;

View File

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