From: Kurt Zeilenga Date: Mon, 1 Oct 2001 18:53:26 +0000 (+0000) Subject: Import multilevel referral chase bug fix from HEAD X-Git-Tag: OPENLDAP_REL_ENG_2_0_16~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1ff03199354bb67e8700306e6430a33fde052104;p=thirdparty%2Fopenldap.git Import multilevel referral chase bug fix from HEAD --- diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h index d5171055f4..0a2f553cf9 100644 --- a/libraries/libldap/ldap-int.h +++ b/libraries/libldap/ldap-int.h @@ -205,6 +205,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 9d87cd21be..49f8cd8639 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; } @@ -523,25 +523,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 { @@ -567,6 +551,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 c8804e04e9..39b765e6f0 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 0d5f3fe46a..0699a4be0b 100644 --- a/libraries/libldap/unbind.c +++ b/libraries/libldap/unbind.c @@ -70,13 +70,11 @@ 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 ); - } + /* free LDAP structure and outstanding requests/responses */ + while ( ld->ld_requests != NULL ) { + ldap_free_request( ld, ld->ld_requests ); + } /* free and unbind from all open connections */ while ( ld->ld_conns != NULL ) {