Andrew Bartlett wrote:
> 
> Dave Snoopy wrote:
> >
> > What version of OpenLDAP are you compiling/linking
> > against?
> >
> 
> [abartlet@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                                 [EMAIL PROTECTED]
Manager, Authentication Subsystems, Samba Team  [EMAIL PROTECTED]
Student Network Administrator, Hawker College   [EMAIL PROTECTED]
http://samba.org     http://build.samba.org     http://hawkerc.net
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;
 

Reply via email to