This is a multi-part message in MIME format. --------------090400040509090303060604 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit
[email protected] wrote: > [email protected] wrote: > >> Following ldapsearch crashes when referral chasing is enabled in very unusual >> environment with many AD servers referring to each other (I had to increase >> refhoplimit to chase all the referrals). > > Thanks for the detailed report. However, IMHO, automatic referral > chasing Is Broken. Clients should explicitly chase them, possibly > providing some interactive means for rebinding. This is what is > currently done, for example, by slapd when using slapo-chain(5), and > what should be done by proxy backends as well. nss_ldap does not have an option to chase referrals, it depends on ldap libraries to do the dirty job. I think that referral chasing in OpenLDAP libraries works pretty well apart my crash. Is there anything I am not aware of? Instead adding new features to nss_ldap, it would be better to fix OpenLDAP, more applications would benefit from that. I tried to work around the crash, see patch attached (apply to current 2.4 branch in CVS). I was not able to prevent deleting connections during referral chasing (I admit I got lost in the code and various code paths). So I added very simple mechanism to detect possibly freed connection and restart the loop in wait4msg(). It seems to help in my scenario. Jan --------------090400040509090303060604 Content-Type: text/plain; name="openldap-2.4-refer-crash.patch" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="openldap-2.4-refer-crash.patch" Index: libraries/libldap/ldap-int.h =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/libraries/libldap/ldap-int.h,v retrieving revision 1.168.2.9 diff -u -r1.168.2.9 ldap-int.h --- libraries/libldap/ldap-int.h 8 Nov 2008 00:14:45 -0000 1.168.2.9 +++ libraries/libldap/ldap-int.h 14 Jan 2009 14:54:09 -0000 @@ -401,6 +401,7 @@ LDAPConn *ld_defconn; /* default connection */ LDAPConn *ld_conns; /* list of server connections */ + int ld_conns_version; /* unique id tracking deletions in ld_conns list */ void *ld_selectinfo; /* platform specifics for select */ }; #define LDAP_VALID(ld) ( (ld)->ld_valid == LDAP_VALID_SESSION ) Index: libraries/libldap/request.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/libraries/libldap/request.c,v retrieving revision 1.125.2.12 diff -u -r1.125.2.12 request.c --- libraries/libldap/request.c 8 Nov 2008 01:15:17 -0000 1.125.2.12 +++ libraries/libldap/request.c 14 Jan 2009 14:54:09 -0000 @@ -697,6 +698,7 @@ } prevlc = tmplc; } + ld->ld_conns_version++; #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex ); #endif Index: libraries/libldap/result.c =================================================================== RCS file: /repo/OpenLDAP/pkg/ldap/libraries/libldap/result.c,v retrieving revision 1.124.2.14 diff -u -r1.124.2.14 result.c --- libraries/libldap/result.c 10 Nov 2008 17:39:16 -0000 1.124.2.14 +++ libraries/libldap/result.c 14 Jan 2009 14:54:09 -0000 @@ -396,6 +396,7 @@ if ( lc->lconn_status == LDAP_CONNST_CONNECTED && ldap_is_read_ready( ld, lc->lconn_sb ) ) { + int version = ld->ld_conns_version; #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_unlock( &ld->ld_conn_mutex ); #endif @@ -403,12 +404,12 @@ #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_lock( &ld->ld_conn_mutex ); #endif - if ( lc == NULL ) { + if ( version != ld->ld_conns_version || lc == NULL ) { /* if lc gets free()'d, * there's no guarantee - * lc->lconn_next is still + * lc or lc->lconn_next is still * sane; better restart - * (ITS#4405) */ + * (ITS#4405, ITS#5853) */ lc = ld->ld_conns; /* don't get to next conn! */ --------------090400040509090303060604--
