From 01dc0183a3a6c7dcb322713480e69c13965559bd Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Mon, 1 Aug 2005 23:35:44 +0000 Subject: [PATCH] plug leaks; cleanup --- libraries/libldap/abandon.c | 1 + libraries/libldap/request.c | 122 +++++++++++++++++++++++------------- libraries/libldap/result.c | 53 ++++++++++++---- 3 files changed, 120 insertions(+), 56 deletions(-) diff --git a/libraries/libldap/abandon.c b/libraries/libldap/abandon.c index 1b2964961e..1e11effc53 100644 --- a/libraries/libldap/abandon.c +++ b/libraries/libldap/abandon.c @@ -238,6 +238,7 @@ do_abandon( } else { /* send the message */ if ( lr != NULL ) { + assert( lr->lr_conn != NULL ); sb = lr->lr_conn->lconn_sb; } else { sb = ld->ld_sb; diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index 33606bfb1e..cd72f76af9 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -55,6 +55,7 @@ static LDAPConn *find_connection LDAP_P(( LDAP *ld, LDAPURLDesc *srv, int any )); static void use_connection LDAP_P(( LDAP *ld, LDAPConn *lc )); +static void ldap_free_request_int LDAP_P(( LDAP *ld, LDAPRequest *lr )); static BerElement * re_encode_request( LDAP *ld, @@ -234,13 +235,14 @@ ldap_send_server_request( rc = 0; if ( ld->ld_requests && ld->ld_requests->lr_status == LDAP_REQST_WRITING && - ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) { + ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) + { rc = -1; } if ( rc ) return rc; - if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) == - NULL ) { + lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest )); + if ( lr == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; ldap_free_connection( ld, lc, 0, 0 ); ber_free( ber, 1 ); @@ -289,27 +291,36 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, { LDAPConn *lc; LDAPURLDesc *srv; - Sockbuf *sb = NULL; - Debug( LDAP_DEBUG_TRACE, "ldap_new_connection\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, "ldap_new_connection %d %d %d\n", + use_ldsb, connect, (bind != NULL) ); /* * make a new LDAP server connection * XXX open connection synchronously for now */ - if (( lc = (LDAPConn *)LDAP_CALLOC( 1, sizeof( LDAPConn ))) == NULL || - ( !use_ldsb && ( (sb = ber_sockbuf_alloc()) == NULL ))) { - if ( lc != NULL ) { - LDAP_FREE( (char *)lc ); - } + lc = (LDAPConn *)LDAP_CALLOC( 1, sizeof( LDAPConn ) ); + if ( lc == NULL ) { ld->ld_errno = LDAP_NO_MEMORY; return( NULL ); } + + if ( use_ldsb ) { + assert( ld->ld_sb ); + lc->lconn_sb = ld->ld_sb; - lc->lconn_sb = ( use_ldsb ) ? ld->ld_sb : sb; + } else { + lc->lconn_sb = ber_sockbuf_alloc(); + if ( lc->lconn_sb == NULL ) { + LDAP_FREE( (char *)lc ); + ld->ld_errno = LDAP_NO_MEMORY; + return( NULL ); + } + } if ( connect ) { for ( srv = srvlist; srv != NULL; srv = srv->lud_next ) { - if ( ldap_int_open_connection( ld, lc, srv, 0 ) != -1 ) { + if ( ldap_int_open_connection( ld, lc, srv, 0 ) != -1 ) + { break; } } @@ -318,12 +329,12 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, if ( !use_ldsb ) { ber_sockbuf_free( lc->lconn_sb ); } - LDAP_FREE( (char *)lc ); - ld->ld_errno = LDAP_SERVER_DOWN; - return( NULL ); + LDAP_FREE( (char *)lc ); + ld->ld_errno = LDAP_SERVER_DOWN; + return( NULL ); } - lc->lconn_server = ldap_url_dup(srv); + lc->lconn_server = ldap_url_dup( srv ); } lc->lconn_status = LDAP_CONNST_CONNECTED; @@ -338,7 +349,8 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, int err = 0; LDAPConn *savedefconn; - /* Set flag to prevent additional referrals from being processed on this + /* Set flag to prevent additional referrals + * from being processed on this * connection until the bind has completed */ lc->lconn_rebind_inprogress = 1; @@ -355,27 +367,27 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, Debug( LDAP_DEBUG_TRACE, "Call application rebind_proc\n", 0, 0, 0); #ifdef LDAP_R_COMPILE - ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); - ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex ); + ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); + ldap_pvt_thread_mutex_unlock( &ld->ld_res_mutex ); #endif err = (*ld->ld_rebind_proc)( ld, bind->ri_url, bind->ri_request, bind->ri_msgid, ld->ld_rebind_params ); #ifdef LDAP_R_COMPILE - ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex ); - ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); + ldap_pvt_thread_mutex_lock( &ld->ld_res_mutex ); + ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); #endif ld->ld_defconn = savedefconn; --lc->lconn_refcnt; - if( err != 0) { - err = -1; + if ( err != 0 ) { + err = -1; ldap_free_connection( ld, lc, 1, 0 ); lc = NULL; + } + ldap_free_urldesc( srvfunc ); } - ldap_free_urldesc( srvfunc); - } } else { savedefconn = ld->ld_defconn; ++lc->lconn_refcnt; /* avoid premature free */ @@ -396,12 +408,12 @@ ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb, ld->ld_defconn = savedefconn; --lc->lconn_refcnt; - if ( err != 0 ) { - ldap_free_connection( ld, lc, 1, 0 ); - lc = NULL; + if ( err != 0 ) { + ldap_free_connection( ld, lc, 1, 0 ); + lc = NULL; + } } - } - if( lc != NULL) + if ( lc != NULL ) lc->lconn_rebind_inprogress = 0; } @@ -460,7 +472,9 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind ) { LDAPConn *tmplc, *prevlc; - Debug( LDAP_DEBUG_TRACE, "ldap_free_connection\n", 0, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, + "ldap_free_connection %d %d\n", + force, unbind, 0 ); if ( force || --lc->lconn_refcnt <= 0 ) { if ( lc->lconn_status == LDAP_CONNST_CONNECTED ) { @@ -470,7 +484,7 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind ) } } - if( lc->lconn_ber != NULL ) { + if ( lc->lconn_ber != NULL ) { ber_free( lc->lconn_ber, 1 ); } @@ -495,23 +509,45 @@ ldap_free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind ) LDAP_FREE( lc->lconn_krbinstance ); } #endif + + /* FIXME: is this at all possible? */ + if ( force ) { + LDAPRequest *lr; + +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_lock( &ld->ld_req_mutex ); +#endif + for ( lr = ld->ld_requests; lr; ) { + LDAPRequest *lr_next = lr->lr_next; + + if ( lr->lr_conn == lc ) { + ldap_free_request_int( ld, lr ); + } + + lr = lr_next; + } +#ifdef LDAP_R_COMPILE + ldap_pvt_thread_mutex_unlock( &ld->ld_req_mutex ); +#endif + } if ( lc->lconn_sb != ld->ld_sb ) { ber_sockbuf_free( lc->lconn_sb ); } - if( lc->lconn_rebind_queue != NULL) { + if ( lc->lconn_rebind_queue != NULL) { int i; - for( i = 0; lc->lconn_rebind_queue[i] != NULL; i++) { - LDAP_VFREE(lc->lconn_rebind_queue[i]); + for( i = 0; lc->lconn_rebind_queue[i] != NULL; i++ ) { + LDAP_VFREE( lc->lconn_rebind_queue[i] ); } - LDAP_FREE( lc->lconn_rebind_queue); + LDAP_FREE( lc->lconn_rebind_queue ); } LDAP_FREE( lc ); - Debug( LDAP_DEBUG_TRACE, "ldap_free_connection: actually freed\n", - 0, 0, 0 ); + Debug( LDAP_DEBUG_TRACE, + "ldap_free_connection: actually freed\n", + 0, 0, 0 ); } else { lc->lconn_lastused = time( NULL ); Debug( LDAP_DEBUG_TRACE, "ldap_free_connection: refcnt %d\n", - lc->lconn_refcnt, 0, 0 ); + lc->lconn_refcnt, 0, 0 ); } } @@ -709,7 +745,7 @@ int ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char **errstrp, int *hadrefp ) { char *unfollowed; - int unfollowedcnt = 0; + int unfollowedcnt = 0; LDAPRequest *origreq; LDAPURLDesc *srv = NULL; BerElement *ber; @@ -921,11 +957,11 @@ ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr, char **refs, int sref, char * } } /* end for loop */ done: - LDAP_VFREE(refarray); - ldap_free_urllist(srv); + LDAP_VFREE( refarray ); + ldap_free_urllist( srv ); LDAP_FREE( *errstrp ); - if( rc == 0) { + if( rc == 0 ) { *errstrp = NULL; LDAP_FREE( unfollowed ); return count; diff --git a/libraries/libldap/result.c b/libraries/libldap/result.c index 2bf9bf7181..cbb744d882 100644 --- a/libraries/libldap/result.c +++ b/libraries/libldap/result.c @@ -484,7 +484,8 @@ retry_ber: return( -2 ); /* continue looking */ } - if (( lr = ldap_find_request_by_msgid( ld, id )) == NULL ) { + lr = ldap_find_request_by_msgid( ld, id ); + if ( lr == NULL ) { Debug( LDAP_DEBUG_ANY, "no request for response with msgid %ld (tossing)\n", (long) id, 0, 0 ); @@ -551,12 +552,25 @@ nextresp2: } } else { /* Check for V3 referral */ - ber_len_t len; + ber_len_t len; + char *lr_res_error = NULL; + if ( ber_scanf( &tmpber, "{iaa",/*}*/ &lderr, - &lr->lr_res_matched, &lr->lr_res_error ) - != LBER_ERROR ) { + &lr->lr_res_matched, &lr_res_error ) + != LBER_ERROR ) + { + if ( lr_res_error != NULL ) { + if ( lr->lr_res_error != NULL ) { + (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error ); + LDAP_FREE( (char *)lr_res_error ); + + } else { + lr->lr_res_error = lr_res_error; + } + } + /* Check if V3 referral */ - if( ber_peek_tag( &tmpber, &len) == LDAP_TAG_REFERRAL ) { + if ( ber_peek_tag( &tmpber, &len ) == LDAP_TAG_REFERRAL ) { /* We have a V3 referral, assume we cannot chase it */ v3ref = -1; if( LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) @@ -611,6 +625,8 @@ nextresp2: ( lr->lr_parent != NULL || LDAP_BOOL_GET(&ld->ld_options, LDAP_BOOL_REFERRALS) ) ) { + char *lr_res_error = NULL; + tmpber = *ber; /* struct copy */ if ( v3ref == 1 ) { /* V3 search reference or V3 referral @@ -621,8 +637,18 @@ nextresp2: if ( tag == LDAP_RES_SEARCH_RESULT ) refer_cnt = 0; } else if ( ber_scanf( &tmpber, "{iaa}", &lderr, - &lr->lr_res_matched, &lr->lr_res_error ) - != LBER_ERROR ) { + &lr->lr_res_matched, &lr_res_error ) + != LBER_ERROR ) + { + if ( lr_res_error != NULL ) { + if ( lr->lr_res_error != NULL ) { + (void)ldap_append_referral( ld, &lr->lr_res_error, lr_res_error ); + LDAP_FREE( (char *)lr_res_error ); + } else { + lr->lr_res_error = lr_res_error; + } + } + if ( lderr != LDAP_SUCCESS ) { /* referrals are in error string */ refer_cnt = ldap_chase_referrals( ld, lr, @@ -929,10 +955,10 @@ build_result_ber( LDAP *ld, BerElement **bp, LDAPRequest *lr ) } if ( ber_printf( ber, "{it{ess}}", lr->lr_msgid, - lr->lr_res_msgtype, lr->lr_res_errno, - lr->lr_res_matched ? lr->lr_res_matched : "", - lr->lr_res_error ? lr->lr_res_error : "" ) == -1 ) { - + lr->lr_res_msgtype, lr->lr_res_errno, + lr->lr_res_matched ? lr->lr_res_matched : "", + lr->lr_res_error ? lr->lr_res_error : "" ) == -1 ) + { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free(ber, 1); return( LBER_ERROR ); @@ -978,14 +1004,15 @@ merge_error_info( LDAP *ld, LDAPRequest *parentr, LDAPRequest *lr ) lr->lr_res_error ); } } else if ( lr->lr_res_errno != LDAP_SUCCESS && - parentr->lr_res_errno == LDAP_SUCCESS ) { + parentr->lr_res_errno == LDAP_SUCCESS ) + { parentr->lr_res_errno = lr->lr_res_errno; if ( parentr->lr_res_error != NULL ) { LDAP_FREE( parentr->lr_res_error ); } parentr->lr_res_error = lr->lr_res_error; lr->lr_res_error = NULL; - if ( LDAP_NAME_ERROR( lr->lr_res_errno )) { + if ( LDAP_NAME_ERROR( lr->lr_res_errno ) ) { if ( parentr->lr_res_matched != NULL ) { LDAP_FREE( parentr->lr_res_matched ); } -- 2.39.5