From: Kurt Zeilenga Date: Mon, 24 Sep 2001 18:50:44 +0000 (+0000) Subject: chasing multi-level referrals core dumps (ITS#1346) bug fix X-Git-Tag: LDBM_PRE_GIANT_RWLOCK~1065 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=790a18cb86311dde3eb2d16cf5e39f0b619fba31;p=openldap chasing multi-level referrals core dumps (ITS#1346) bug fix from Zachary Amsden . --- diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index 70e0417a7d..b90b6ab322 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -209,6 +209,7 @@ typedef struct ldapreq { BerElement *lr_ber; /* ber encoded request contents */ LDAPConn *lr_conn; /* connection used to send request */ struct ldapreq *lr_parent; /* request that spawned this referral */ + struct ldapreq *lr_child; /* first child request */ struct ldapreq *lr_refnext; /* next referral spawned */ struct ldapreq *lr_prev; /* previous request */ struct ldapreq *lr_next; /* next request */ diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 15c51e8e77..576383fb10 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -187,8 +187,8 @@ ldap_send_server_request( lr->lr_origid = parentreq->lr_origid; lr->lr_parentcnt = parentreq->lr_parentcnt + 1; lr->lr_parent = parentreq; - lr->lr_refnext = parentreq->lr_refnext; - parentreq->lr_refnext = lr; + lr->lr_refnext = parentreq->lr_child; + parentreq->lr_child = lr; } else { /* original request */ lr->lr_origid = lr->lr_msgid; } @@ -525,25 +525,9 @@ ldap_dump_requests_and_responses( LDAP *ld ) } #endif /* LDAP_DEBUG */ - void -ldap_free_request( LDAP *ld, LDAPRequest *lr ) +ldap_free_request_int( LDAP *ld, LDAPRequest *lr ) { - LDAPRequest *tmplr, *nextlr; - - Debug( LDAP_DEBUG_TRACE, "ldap_free_request (origid %d, msgid %d)\n", - lr->lr_origid, lr->lr_msgid, 0 ); - - if ( lr->lr_parent != NULL ) { - --lr->lr_parent->lr_outrefcnt; - } else { - /* free all referrals (child requests) */ - for ( tmplr = lr->lr_refnext; tmplr != NULL; tmplr = nextlr ) { - nextlr = tmplr->lr_refnext; - ldap_free_request( ld, tmplr ); - } - } - if ( lr->lr_prev == NULL ) { ld->ld_requests = lr->lr_next; } else { @@ -569,6 +553,29 @@ ldap_free_request( LDAP *ld, LDAPRequest *lr ) LDAP_FREE( lr ); } +void +ldap_free_request( LDAP *ld, LDAPRequest *lr ) +{ + LDAPRequest *tmplr, *nextlr; + LDAPRequest **ttmplr; + + Debug( LDAP_DEBUG_TRACE, "ldap_free_request (origid %d, msgid %d)\n", + lr->lr_origid, lr->lr_msgid, 0 ); + + if ( lr->lr_parent != NULL ) { + --lr->lr_parent->lr_outrefcnt; + for ( ttmplr = &lr->lr_parent->lr_child; *ttmplr && *ttmplr != lr; ttmplr = &(*ttmplr)->lr_refnext ); + if ( *ttmplr == lr ) + *ttmplr = lr->lr_refnext; + } else { + /* free all referrals (child requests) */ + while ( lr->lr_child ) + ldap_free_request( ld, lr->lr_child ); + } + ldap_free_request_int( ld, lr ); +} + + /* * Chase v3 referrals * diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c index 869769e65c..d8c0a6c47a 100644 --- a/libraries/libldap/result.c +++ b/libraries/libldap/result.c @@ -598,9 +598,12 @@ Debug( LDAP_DEBUG_TRACE, } /* Check if all requests are finished, lr is now parent */ - for(tmplr=lr ; tmplr != NULL; tmplr=tmplr->lr_refnext) { + tmplr = lr; + if (tmplr->lr_status == LDAP_REQST_COMPLETED) { + for(tmplr=lr->lr_child; tmplr != NULL; tmplr=tmplr->lr_refnext) { if( tmplr->lr_status != LDAP_REQST_COMPLETED) { break; + } } } diff --git a/libraries/libldap/unbind.c b/libraries/libldap/unbind.c index fe5df23406..7009a052eb 100644 --- a/libraries/libldap/unbind.c +++ b/libraries/libldap/unbind.c @@ -73,12 +73,10 @@ ldap_ld_free( { LDAPMessage *lm, *next; int err = LDAP_SUCCESS; - LDAPRequest *lr, *nextlr; /* free LDAP structure and outstanding requests/responses */ - for ( lr = ld->ld_requests; lr != NULL; lr = nextlr ) { - nextlr = lr->lr_next; - ldap_free_request( ld, lr ); + while ( ld->ld_requests != NULL ) { + ldap_free_request( ld, ld->ld_requests ); } /* free and unbind from all open connections */