[tpop3d-discuss] Memory leak?

Marc Lewis marc at blarg.net
Fri, 10 May 2002 11:12:28 -0700


On Thu, May 09, 2002 at 11:36:00PM +0100, Chris Lightfoot wrote:
> On Thu, May 09, 2002 at 03:07:10PM -0700, Marc Lewis wrote:
> > On Thu, May 09, 2002 at 09:14:03PM +0100, Chris Lightfoot wrote:
> > > On Thu, May 09, 2002 at 12:08:41PM -0700, Marc Lewis wrote:
> > > > On Thu, May 09, 2002 at 11:20:45AM +0100, Chris Lightfoot wrote:
> > >     [...]
> > > > > Cheers. I'll see if I can reproduce anything with my test
> > > > > OpenLDAP installation.
> > > > 
> > > > I'm very interested to hear your results.  
> > > 
> > > OK, I've discovered a few SNAFUs; the following patch
> > > ought to fix them:
> > [snip]
> > 
> > Well, I applied the patch, started up my expect script, after 113
> > successful authentications (no failures), the program died:
> > 
> > auth_ldap_new_user_pass: ldap_search_s: Can't contact LDAP server
> 
> I still don't understand this. The example code in the
> openldap distribution doesn't seem to handle this
> specially.
> 
> > tpop3d: getentry.c:46: ldap_next_entry: Assertion `entry != ((void *)0)'
> > failed.quit: signal 6 post_fork = 0
> > Aborted
> 
> Well, the patch was a bit bogus. Try the following instead
> (it's against the original source code):

Tried applying both patches, and its better, but it still fails after a
bit.  It always seems to fail in the call to ldap_search_s.  The re-bind
patch did seem to slow it down a bit, which is fine by me as long as valid
passwords never get rejected.

This patch, against your patched auth_ldap.c, fixed it for me.  Its
probably the totally wrong way to do it, but I beat the snot out of it with
multiple expect scripts doing nothing but logging in and logging out for 30
minutes, generating between 100 and 150 connections per minute, and had not
a single failure to authenticate.  There were quite a few ldap timeouts,
but it retries and succeeds on the second try.  Not sure why, but it looks
like it needs this on our system.

--- auth_ldap.c	Fri May 10 10:37:32 2002
+++ auth_ldap.c-marc	Fri May 10 10:37:04 2002
@@ -267,8 +267,15 @@
         log_print(LOG_DEBUG, _("auth_ldap_new_user_pass: LDAP search filter: %s"), filter);
 
     /* Look for DN of user in the directory. */
-    if ((ret = ldap_search_s(ldapinfo.ldap, ldapinfo.dn, LDAP_SCOPE_SUBTREE, filter, NULL, 0, &ldapres)) != LDAP_SUCCESS) {
-        log_print(LOG_ERR, "auth_ldap_new_user_pass: ldap_search_s: %s", ldap_err2string(ret));
+    for (i = 0; i < 3; ++i) {
+        ret = ldap_search_s(ldapinfo.ldap, ldapinfo.dn, LDAP_SCOPE_SUBTREE, filter, NULL, 0, &ldapres);
+        if (ret == LDAP_SUCCESS) break;
+        else {
+            if (i < 3) log_print(LOG_ERR, "auth_ldap_new_user_pass: ldap_search_s: %s - trying again", ldap_err2string(ret));
+        }
+    }
+    if (ret != LDAP_SUCCESS) {
+        log_print(LOG_ERR, "auth_ldap_new_user_pass: ldap_search_s: %s - giving up", ldap_err2string(ret));
         goto fail;
     }
  
@@ -298,7 +305,16 @@
     }
 
     /* Now attempt authentication by binding with the user's credentials. */
-    if ((ret = ldap_simple_bind_s(ldapinfo.ldap, user_dn, pass)) != LDAP_SUCCESS) {
+    for (i = 0; i < 3; ++i) {
+        ret = ldap_simple_bind_s(ldapinfo.ldap, user_dn, pass);
+        if (ret == LDAP_INVALID_CREDENTIALS || ret == LDAP_SUCCESS) break;
+        else {
+            if (i < 3) log_print(LOG_ERR, _("auth_ldap_new_user_pass: failed login for %s%s%s - trying again"), local_part, domain ? "@" : "", domain ? domain : "");
+        }
+    }
+
+    /* Now check to make sure that our previous bind succeeded */
+    if (ret != LDAP_SUCCESS) {
         /* Bind failed; user has failed to log in. */
         if (ret == LDAP_INVALID_CREDENTIALS)
             log_print(LOG_ERR, _("auth_ldap_new_user_pass: failed login for %s%s%s"), local_part, domain ? "@" : "", domain ? domain : "");

-- 
Marc Lewis
Network Administrator
Blarg! Online Services, Inc.
http://www.blarg.net/~marc