[Samba] [PATCH] chages to pdb_ldap for new OpenLDAP versions and for better rebinds

Andrew Bartlett abartlet at samba.org
Sun Jun 16 01:44:24 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 mailing list