This is a multi-part message in MIME format.
--------------090400040509090303060604
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
ando(a)sys-net.it wrote:
> jsafrane(a)redhat.com 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--