[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: ldap_unbind unhandled SIGPIPE (ITS#5127)



ando@sys-net.it wrote:
> ando@sys-net.it wrote:
>> I've seen something similar in recent code.  I was just tracking it
>> down, so you basically saved me the effort of opening a ticket :).  What
>> I found so far is that when ldap_unbind(3) is called (which is required
>> to release resources after the connection broke), the client library
>> tries to send a LDAPUnbind request to the server, even though it just
>> got a LDAP_SERVER_DOWN (-1).  The behavior seems to be more frequent
>> when the connection brakes while using ldapi://, and I couldn't spot the
>> difference up to now, I'm just mentioning it in case it rings any bells.
> 
> 
> What happens is that when try_read1msg() finds out the connection is
> broken, it sets ld_errno to LDAP_SERVER_DOWN, but leaves
> lc->lconn_status to LDAP_CONNST_CONNECTED, so a subsequent call to
> ldap_unbind_ext causes ldap_free_connection() to try sending the
> LDAPUnbind anyway.  Either we also check that ld->ld_errno is not
> LDAP_SERVER_DOWN (provided no one resets it in the meanwhile), or clear
> lc->lconn_status as soon as we find out the connection is broken.  I'd
> go for the second, but probably someone else is more familiar than me
> with the library's internals.

This is the fix I propose:

==========================================
diff -u -r1.154 result.c
--- libraries/libldap/result.c  14 Jun 2007 20:35:41 -0000      1.154
+++ libraries/libldap/result.c  7 Sep 2007 20:57:52 -0000
@@ -558,6 +558,14 @@
                if ( sock_errno() == EAGAIN ) return
LDAP_MSG_X_KEEP_LOOKING;
 #endif
                ld->ld_errno = LDAP_SERVER_DOWN;
+#ifdef LDAP_R_COMPILE
+               ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex );
+#endif
+               ldap_free_connection( ld, lc, 1, 0 );
+#ifdef LDAP_R_COMPILE
+               ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex );
+#endif
+               lc = *lcp = NULL;
                return -1;

        default:
==========================================

I've prepared a trivial client that ldap_sasl_bind_s(), holds on while I
shut down the server, ldap_search_ext_s() with LDAP_SERVER_DOWN and
ldap_unbind_ext().  Prior to patching, I always got SIGPIPE.

p.



Ing. Pierangelo Masarati
OpenLDAP Core Team

SysNet s.r.l.
via Dossi, 8 - 27100 Pavia - ITALIA
http://www.sys-net.it
---------------------------------------
Office:  +39 02 23998309
Mobile:  +39 333 4963172
Email:   pierangelo.masarati@sys-net.it
---------------------------------------