From: Pierangelo Masarati Date: Fri, 9 Jul 2004 18:32:00 +0000 (+0000) Subject: import fix to ITS#3217 (cached connections failover) from HEAD X-Git-Tag: OPENLDAP_REL_ENG_2_2_15~33 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=69c71697ec4b3943dd00f04da7ce24a0030cfa21;p=openldap import fix to ITS#3217 (cached connections failover) from HEAD --- diff --git a/CHANGES b/CHANGES index db6596061f..8bc7d643b3 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ OpenLDAP 2.2.15 Engineering Fixed back-bdb dbcache locking bug (ITS#3201) Fixed back-bdb ctxcsn locking bug Fixed back-ldap validate/pretty values (ITS#3218) + Fixed back-ldap shared connections failover (ITS#3217) Fixed slapd oidValidate 0 bug (ITS#3211) Fixed slapd uniqueMember/nameUID bugs (ITS#3210) Fixed slapd operational attribute log message bug (ITS#3205) diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 6e9de5f4e3..a4df5890af 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -118,6 +118,7 @@ typedef struct dncookie { #endif } dncookie; +int ldap_back_freeconn( Operation *op, struct ldapconn *lc ); struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs); int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs); int ldap_back_map_result(SlapReply *rs); diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c index a4185efa6b..dc3ff1574e 100644 --- a/servers/slapd/back-ldap/bind.c +++ b/servers/slapd/back-ldap/bind.c @@ -209,6 +209,20 @@ static void myprint( Avlnode *root ) } #endif /* PRINT_CONNTREE */ +int +ldap_back_freeconn( Operation *op, struct ldapconn *lc ) +{ + struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; + + ldap_pvt_thread_mutex_lock( &li->conn_mutex ); + lc = avl_delete( &li->conntree, (caddr_t)lc, + ldap_back_conn_cmp ); + ldap_back_conn_free( (void *)lc ); + ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); + + return 0; +} + struct ldapconn * ldap_back_getconn(Operation *op, SlapReply *rs) { @@ -516,16 +530,16 @@ ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs, if ( ERR_OK( rs->sr_err ) ) { /* if result parsing fails, note the failure reason */ if ( ldap_result( lc->ld, msgid, 1, NULL, &res ) == -1 ) { - ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, - &rs->sr_err); + ldap_get_option( lc->ld, LDAP_OPT_ERROR_NUMBER, + &rs->sr_err ); /* otherwise get the result; if it is not * LDAP_SUCCESS, record it in the reply * structure (this includes * LDAP_COMPARE_{TRUE|FALSE}) */ } else { - int rc = ldap_parse_result(lc->ld, res, &rs->sr_err, - &match, &text, NULL, NULL, 1); + int rc = ldap_parse_result( lc->ld, res, &rs->sr_err, + &match, &text, NULL, NULL, 1 ); rs->sr_text = text; if ( rc != LDAP_SUCCESS ) rs->sr_err = rc; } diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 4ba0036665..665c26ba10 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -510,6 +510,9 @@ ldap_back_exop_whoami( if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) { ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rs->sr_err); + ldap_back_freeconn( op, lc ); + lc = NULL; + } else { rs->sr_err = ldap_parse_whoami(lc->ld, res, &bv); ldap_msgfree(res); diff --git a/servers/slapd/back-ldap/extended.c b/servers/slapd/back-ldap/extended.c index 6f35c898a2..ecd6f4dcaf 100644 --- a/servers/slapd/back-ldap/extended.c +++ b/servers/slapd/back-ldap/extended.c @@ -145,6 +145,9 @@ ldap_back_exop_passwd( if (rc == LDAP_SUCCESS) { if (ldap_result(lc->ld, msgid, 1, NULL, &res) == -1) { ldap_get_option(lc->ld, LDAP_OPT_ERROR_NUMBER, &rc); + ldap_back_freeconn( op, lc ); + lc = NULL; + } else { /* sigh. parse twice, because parse_passwd doesn't give * us the err / match / msg info. diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index bce3827aad..f88edeb943 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -58,6 +58,7 @@ ldap_back_search( struct berval mbase; struct berval mfilter = BER_BVNULL; int dontfreetext = 0; + int freeconn = 0; dncookie dc; #ifdef LDAP_BACK_PROXY_AUTHZ LDAPControl **ctrls = NULL; @@ -77,11 +78,14 @@ ldap_back_search( } /* should we check return values? */ - if (op->ors_deref != -1) - ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&op->ors_deref); - if (op->ors_tlimit != SLAP_NO_LIMIT) { + if ( op->ors_deref != -1 ) { + ldap_set_option( lc->ld, LDAP_OPT_DEREF, (void *)&op->ors_deref ); + } + + if ( op->ors_tlimit != SLAP_NO_LIMIT ) { tv.tv_sec = op->ors_tlimit; tv.tv_usec = 0; + } else { tv.tv_sec = 0; } @@ -127,7 +131,7 @@ ldap_back_search( rs->sr_err = ldap_back_map_attrs( &li->rwmap.rwm_at, op->ors_attrs, BACKLDAP_MAP, &mapped_attrs ); - if ( rs->sr_err ) { + if ( rs->sr_err != LDAP_SUCCESS ) { rc = -1; goto finish; } @@ -140,7 +144,7 @@ ldap_back_search( } #endif /* LDAP_BACK_PROXY_AUTHZ */ - rs->sr_err = ldap_search_ext(lc->ld, mbase.bv_val, + rs->sr_err = ldap_search_ext( lc->ld, mbase.bv_val, op->ors_scope, mfilter.bv_val, mapped_attrs, op->ors_attrsonly, #ifdef LDAP_BACK_PROXY_AUTHZ @@ -154,7 +158,11 @@ ldap_back_search( if ( rs->sr_err != LDAP_SUCCESS ) { fail:; - rc = ldap_back_op_result(lc, op, rs, msgid, 0); + rc = ldap_back_op_result( lc, op, rs, msgid, 0 ); + if ( freeconn ) { + ldap_back_freeconn( op, lc ); + lc = NULL; + } goto finish; } @@ -163,27 +171,28 @@ fail:; * but this is necessary for version matching, and for ACL processing. */ - for ( rc=0; rc != -1; rc = ldap_result(lc->ld, msgid, 0, &tv, &res)) + for ( rc = 0; rc != -1; rc = ldap_result( lc->ld, msgid, 0, &tv, &res ) ) { /* check for abandon */ - if (op->o_abandon) { - ldap_abandon(lc->ld, msgid); + if ( op->o_abandon ) { + ldap_abandon( lc->ld, msgid ); rc = 0; goto finish; } - if (rc == 0) { + if ( rc == 0 ) { tv.tv_sec = 0; tv.tv_usec = 100000; ldap_pvt_thread_yield(); - } else if (rc == LDAP_RES_SEARCH_ENTRY) { + } else if ( rc == LDAP_RES_SEARCH_ENTRY ) { Entry ent = {0}; struct berval bdn; int abort = 0; - e = ldap_first_entry(lc->ld,res); - if ( ( rc = ldap_build_entry(op, e, &ent, &bdn, - LDAP_BUILD_ENTRY_PRIVATE)) == LDAP_SUCCESS ) { + e = ldap_first_entry( lc->ld, res ); + rc = ldap_build_entry( op, e, &ent, &bdn, + LDAP_BUILD_ENTRY_PRIVATE ); + if ( rc == LDAP_SUCCESS ) { rs->sr_entry = &ent; rs->sr_attrs = op->ors_attrs; rs->sr_flags = 0; @@ -196,10 +205,12 @@ fail:; ent.e_attrs = a->a_next; v = a->a_vals; - if (a->a_vals != &dummy) + if ( a->a_vals != &dummy ) { ber_bvarray_free(a->a_vals); - if (a->a_nvals != v) + } + if ( a->a_nvals != v ) { ber_bvarray_free(a->a_nvals); + } ch_free(a); } @@ -208,9 +219,9 @@ fail:; if ( ent.e_ndn ) free( ent.e_ndn ); } - ldap_msgfree(res); + ldap_msgfree( res ); if ( abort ) { - ldap_abandon(lc->ld, msgid); + ldap_abandon( lc->ld, msgid ); goto finish; } @@ -255,18 +266,24 @@ fail:; } } else { - rc = ldap_parse_result(lc->ld, res, &rs->sr_err, + rc = ldap_parse_result( lc->ld, res, &rs->sr_err, &match.bv_val, (char **)&rs->sr_text, - NULL, NULL, 1); - if (rc != LDAP_SUCCESS ) rs->sr_err = rc; + NULL, NULL, 1 ); + if (rc != LDAP_SUCCESS ) { + rs->sr_err = rc; + } rs->sr_err = slap_map_api2result( rs ); rc = 0; break; } } - if (rc == -1) + if ( rc == -1 ) { + /* FIXME: invalidate the connection? */ + rs->sr_err = LDAP_SERVER_DOWN; + freeconn = 1; goto fail; + } /* * Rewrite the matched portion of the search base, if required @@ -281,7 +298,7 @@ fail:; dc.normalized = 0; #endif match.bv_len = strlen( match.bv_val ); - ldap_back_dn_massage(&dc, &match, &mdn); + ldap_back_dn_massage( &dc, &match, &mdn ); rs->sr_matched = mdn.bv_val; } if ( rs->sr_v2ref ) {