Update the rebind code in pdb_ldap.
authorAndrew Bartlett <abartlet@samba.org>
Sat, 27 Jul 2002 06:07:53 +0000 (06:07 +0000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 27 Jul 2002 06:07:53 +0000 (06:07 +0000)
I've still not tested this, but I didn't test the last lot and I'm pretty
sure I stuffed it up - but at least this rebind procedure matches the
function prototype.

It should also be fine on OpenLDAP 2.1 if I'm lucky.

Andrew Bartlett
(This used to be commit 064f269508d05cc833cf7bfd5613e4fe389f32dc)

source3/passdb/pdb_ldap.c

index 45e71b7a149dba97ce49895ebc78eaa673f49988..581aa48b9971337659a5a9e31530b05522fa4eb1 100644 (file)
@@ -70,8 +70,14 @@ struct ldapsam_privates {
        
        uint32 low_nua_rid; 
        uint32 high_nua_rid; 
+
+       char *bind_dn;
+       char *bind_secret;
 };
 
+
+static struct ldapsam_privates *static_ldap_state;
+
 static uint32 ldapsam_get_next_available_nua_rid(struct ldapsam_privates *ldap_state);
 
 /*******************************************************************
@@ -157,7 +163,7 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
                DEBUG(0, ("ldap_open_connection: cannot access LDAP when not root..\n"));
                return False;
        }
-       
+
 #if defined(LDAP_API_FEATURE_X_OPENLDAP) && (LDAP_API_VERSION > 2000)
        DEBUG(10, ("ldapsam_open_connection: %s\n", ldap_state->uri));
        
@@ -252,42 +258,91 @@ static BOOL ldapsam_open_connection (struct ldapsam_privates *ldap_state, LDAP *
 
 
 /*******************************************************************
- 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)
 {
-       int rc;
-       char *ldap_dn;
-       char *ldap_secret;
+       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 != 0)
-       {
-               
-               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 */
-               }
-               
+       if (freeit) {
+               SAFE_FREE(*whop);
+               memset(*credp, '\0', strlen(*credp));
+               SAFE_FREE(*credp);
+       } else {
                DEBUG(5,("ldap_connect_system: Rebinding as \"%s\"\n", 
-                         ldap_dn));
-
-               rc = ldap_simple_bind_s(ldap_struct, ldap_dn, ldap_secret);
-               
-               SAFE_FREE(ldap_dn);
-               SAFE_FREE(ldap_secret);
+                         ldap_state->bind_dn));
 
-               return rc;
+               *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;
+       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);
+       
+       return rc;
+}
+
+/*******************************************************************
+ Add a rebind function for authenticated referrals
+******************************************************************/
+
+static int rebindproc (LDAP *ldap_struct, char **whop, char **credp,
+                      int *method, int freeit )
+{
+       return rebindproc_with_state(ldap_struct, whop, credp,
+                                  method, freeit, static_ldap_state);
+       
+}
+
+/*******************************************************************
+ a rebind function for authenticated referrals
+ this also does the connection, but no void*.
+******************************************************************/
+
+static int rebindproc_connect (LDAP * ld, LDAP_CONST char *url, int request,
+                              ber_int_t msgid)
+{
+       return rebindproc_connect_with_state(ld, url, (ber_tag_t)request, msgid, 
+                                            static_ldap_state);
+}
+
+
 /*******************************************************************
  connect to the ldap server under system privilege.
 ******************************************************************/
@@ -297,6 +352,10 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
        char *ldap_dn;
        char *ldap_secret;
 
+       /* The rebind proc needs this *HACK*.  We are not multithreaded, so
+          this will work, but it's not nice. */
+       static_ldap_state = ldap_state;
+
        /* get the password */
        if (!fetch_ldapsam_pw(&ldap_dn, &ldap_secret))
        {
@@ -304,24 +363,32 @@ static BOOL ldapsam_connect_system(struct ldapsam_privates *ldap_state, LDAP * l
                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));
 
-#if LDAP_SET_REBIND_PROC_ARGS == 3
-               ldap_set_rebind_proc(ldap_struct, (LDAP_REBIND_PROC *)(&rebindproc), NULL);
-#elif LDAP_SET_REBIND_PROC_ARGS == 2
-               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, &rebindproc_connect); 
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc_connect_with_state, (void *)ldap_state);  
+# endif
+#else
+# if LDAP_SET_REBIND_PROC_ARGS == 2    
+       ldap_set_rebind_proc(ldap_struct, &rebindproc); 
+# endif
+# if LDAP_SET_REBIND_PROC_ARGS == 3    
+       ldap_set_rebind_proc(ldap_struct, &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)));
@@ -761,18 +828,20 @@ static BOOL init_sam_from_ldap (struct ldapsam_privates *ldap_state,
                /* leave as default */
        } else {
                pdb_gethexpwd(temp, smblmpwd);
-               memset((char *)temp, '\0', sizeof(temp));
+               memset((char *)temp, '\0', strlen(temp)+1);
                if (!pdb_set_lanman_passwd(sampass, smblmpwd))
                        return False;
+               ZERO_STRUCT(smblmpwd);
        }
 
        if (!get_single_attribute (ldap_struct, entry, "ntPassword", temp)) {
                /* leave as default */
        } else {
                pdb_gethexpwd(temp, smbntpwd);
-               memset((char *)temp, '\0', sizeof(temp));
+               memset((char *)temp, '\0', strlen(temp)+1);
                if (!pdb_set_nt_passwd(sampass, smbntpwd))
                        return False;
+               ZERO_STRUCT(smbntpwd);
        }
 
        if (!get_single_attribute (ldap_struct, entry, "acctFlags", temp)) {
@@ -1158,6 +1227,10 @@ static BOOL ldapsam_getsampwent(struct pdb_methods *my_methods, SAM_ACCOUNT * us
        struct ldapsam_privates *ldap_state = (struct ldapsam_privates *)my_methods->private_data;
        BOOL ret = False;
 
+       /* The rebind proc needs this *HACK*.  We are not multithreaded, so
+          this will work, but it's not nice. */
+       static_ldap_state = ldap_state;
+
        while (!ret) {
                if (!ldap_state->entry)
                        return False;
@@ -1535,6 +1608,13 @@ static void free_private_data(void **vp)
                ldap_unbind((*ldap_state)->ldap_struct);
        }
 
+       if ((*ldap_state)->bind_secret) {
+               memset((*ldap_state)->bind_secret, '\0', strlen((*ldap_state)->bind_secret));
+       }
+
+       SAFE_FREE((*ldap_state)->bind_dn);
+       SAFE_FREE((*ldap_state)->bind_secret);
+
        *ldap_state = NULL;
 
        /* No need to free any further, as it is talloc()ed */