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--


Reply via email to