[PATCH] chages to pdb_ldap for new OpenLDAP versions and for better
rebinds
Andrew Bartlett
abartlet at samba.org
Sun Jun 16 01:44:01 GMT 2002
Andrew Bartlett wrote:
>
> Dave Snoopy wrote:
> >
> > What version of OpenLDAP are you compiling/linking
> > against?
> >
>
> [abartlet at piglett abartlet]$ rpm -q openldap
> openldap-2.0.23-4
I would appricate it if some people could test out the attached patch to
current Samba HEAD (pserver.samba.org). The patch does the appropriate
#ifdef magic for the various implementations of ldap_set_rebind_proc(),
including the version that is currectly breaking builds.
In particular, I would appricate it if sombody could test the actual
rebind functionality itself - needed for some master/slave ldap setups.
Thankyou,
Andrew Bartlett
--
Andrew Bartlett abartlet at pcug.org.au
Manager, Authentication Subsystems, Samba Team abartlet at samba.org
Student Network Administrator, Hawker College abartlet at hawkerc.net
http://samba.org http://build.samba.org http://hawkerc.net
-------------- next part --------------
Index: source/passdb/pdb_ldap.c
===================================================================
RCS file: /home/cvs/samba/source/passdb/pdb_ldap.c,v
retrieving revision 1.41
diff -u -r1.41 pdb_ldap.c
--- source/passdb/pdb_ldap.c 2002/06/14 14:12:27 1.41
+++ source/passdb/pdb_ldap.c 2002/06/16 03:03:51
@@ -70,6 +70,9 @@
uint32 low_nua_rid;
uint32 high_nua_rid;
+
+ char *bind_dn;
+ char *bind_secret;
};
static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
@@ -252,42 +255,116 @@
/*******************************************************************
- Add a rebind function for authenticated referrals
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
******************************************************************/
-static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
- int *method, int freeit )
+static int rebindproc_with_state (LDAP * ld, char **whop, char **credp,
+ int *methodp, int freeit, void *arg)
+{
+ struct ldapsam_privates *ldap_state = arg;
+
+ /** @TODO Should we be doing something to check what servers we rebind to?
+ Could we get a referral to a machine that we don't want to give our
+ username and password to? */
+
+ if (freeit) {
+ SAFE_FREE(*whop);
+ memset(*credp, '\0', strlen(*credp));
+ SAFE_FREE(*credp);
+ } else {
+ DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
+ ldap_state->bind_dn));
+
+ *whop = strdup(ldap_state->bind_dn);
+ if (!*whop) {
+ return LDAP_NO_MEMORY;
+ }
+ *credp = strdup(ldap_state->bind_secret);
+ if (!*credp) {
+ SAFE_FREE(*whop);
+ return LDAP_NO_MEMORY;
+ }
+ *methodp = LDAP_AUTH_SIMPLE;
+ }
+ return 0;
+}
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ This version takes a void* that we can shove useful stuff in :-)
+ and actually does the connection.
+******************************************************************/
+
+static int rebindproc_connect_with_state (LDAP *ldap_struct, LDAP_CONST char *url, ber_tag_t request,
+ ber_int_t msgid, void *arg)
{
+ struct ldapsam_privates *ldap_state = arg;
int rc;
- char *ldap_dn;
- char *ldap_secret;
+ DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
+ ldap_state->bind_dn));
/** @TODO Should we be doing something to check what servers we rebind to?
Could we get a referral to a machine that we don't want to give our
username and password to? */
+
+ rc = ldap_simple_bind_s(ldap_struct, ldap_state->bind_dn, ldap_state->bind_secret);
- if (freeit != 0)
+ return rc;
+}
+
+/*******************************************************************
+ Add a rebind function for authenticated referrals
+******************************************************************/
+
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+ int *method, int freeit )
+{
+ int rc;
+ struct ldapsam_privates pretend_privates;
+
+ ZERO_STRUCT(pretend_privates);
+
+ if (!fetch_ldapsam_pw(&pretend_privates.bind_dn, &pretend_privates.bind_secret))
{
-
- if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
- {
- DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
- return LDAP_OPERATIONS_ERROR; /* No idea what to return */
- }
-
- DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n",
- ldap_dn));
+ DEBUG(0, ("ldap_connect_system: Failed to retrieve password from secrets.tdb\n"));
+ return LDAP_OPERATIONS_ERROR; /* No idea what to return */
+ }
- rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
-
- SAFE_FREE(ldap_dn);
- SAFE_FREE(ldap_secret);
+ rc = rebindproc_with_state(ldap_struct, whop, credp,
+ method, freeit, &pretend_privates);
+
+ SAFE_FREE(pretend_privates.bind_dn);
+ SAFE_FREE(pretend_privates.bind_secret);
+
+ return rc;
+
+}
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ this also does the connection, but no void*.
+******************************************************************/
+
+static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, ber_tag_t request,
+ ber_int_t msgid)
+{
+ int method;
+ struct ldapsam_privates pretend_privates;
+ int rc;
+
+ ZERO_STRUCT(pretend_privates);
- return rc;
+ rc = rebindproc (ld, &pretend_privates.bind_dn, &pretend_privates.bind_secret, &method, False);
+
+ if (rc == 0) {
+ rc = rebindproc_connect_with_state(ld, url, request, msgid, &pretend_privates);
+ rebindproc (ld, &pretend_privates.bind_dn, &pretend_privates.bind_secret, &method, True); /* Free it */
}
- return 0;
+ return rc;
}
+
/*******************************************************************
connect to the ldap server under system privilege.
******************************************************************/
@@ -304,19 +381,32 @@
return False;
}
+ ldap_state->bind_dn = ldap_dn;
+ ldap_state->bind_secret = ldap_secret;
+
/* removed the sasl_bind_s "EXTERNAL" stuff, as my testsuite
(OpenLDAP) doesnt' seem to support it */
DEBUG(10,("ldap_connect_system: Binding to ldap server as \"%s\"\n",
ldap_dn));
-
- ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
+#if LDAP_SET_REBIND_PROC_ARGS == 2
+ ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc_connect));
+#endif
+#if LDAP_SET_REBIND_PROC_ARGS == 3
+ ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc_connect_with_state), (void *)ldap_state);
+#endif
+#else
+#if LDAP_SET_REBIND_PROC_ARGS == 2
+ ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc));
+#endif
+#if LDAP_SET_REBIND_PROC_ARGS == 3
+ ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc_with_state), (void *)ldap_state);
+#endif
+#endif
rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
- SAFE_FREE(ldap_dn);
- SAFE_FREE(ldap_secret);
-
if (rc != LDAP_SUCCESS)
{
DEBUG(0, ("Bind failed: %s\n", ldap_err2string(rc)));
@@ -1360,7 +1450,7 @@
return False;
if (!ldapsam_connect_system(ldap_state, ldap_struct)) /* connect as system account */
- {
+{
ldap_unbind(ldap_struct);
return False;
}
@@ -1529,6 +1619,9 @@
if ((*ldap_state)->ldap_struct) {
ldap_unbind((*ldap_state)->ldap_struct);
}
+
+ SAFE_FREE((*ldap_state)->bind_dn);
+ SAFE_FREE((*ldap_state)->bind_secret);
*ldap_state = NULL;
More information about the samba-technical
mailing list