mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-06 10:46:21 +08:00
seems to definitely fix issues related to ITS#3808
This commit is contained in:
parent
cbe9c74675
commit
9e811df052
@ -54,6 +54,7 @@ ldap_back_add(
|
||||
|
||||
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
|
||||
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
|
||||
lc = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -116,6 +117,10 @@ cleanup:
|
||||
ch_free( attrs );
|
||||
}
|
||||
|
||||
if ( lc ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_ARGS, "<== ldap_back_add(\"%s\"): %d\n",
|
||||
op->o_req_dn.bv_val, rs->sr_err, 0 );
|
||||
|
||||
|
@ -39,6 +39,7 @@ struct ldapconn {
|
||||
int lc_bound;
|
||||
int lc_ispriv;
|
||||
ldap_pvt_thread_mutex_t lc_mutex;
|
||||
unsigned lc_refcnt;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -101,31 +101,38 @@ done:;
|
||||
|
||||
/* must re-insert if local DN changed as result of bind */
|
||||
if ( lc->lc_bound && !dn_match( &op->o_req_ndn, &lc->lc_local_ndn ) ) {
|
||||
struct ldapconn *tmplc;
|
||||
int lerr;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
tmplc = avl_delete( &li->conntree, (caddr_t)lc,
|
||||
ldap_back_conn_cmp );
|
||||
if ( tmplc != NULL ) {
|
||||
if ( !BER_BVISNULL( &lc->lc_local_ndn ) ) {
|
||||
ch_free( lc->lc_local_ndn.bv_val );
|
||||
}
|
||||
ber_dupbv( &lc->lc_local_ndn, &op->o_req_ndn );
|
||||
lerr = avl_insert( &li->conntree, (caddr_t)lc,
|
||||
ldap_back_conn_cmp, ldap_back_conn_dup );
|
||||
|
||||
} else {
|
||||
/* something BAD happened */
|
||||
lerr = -1;
|
||||
rc = LDAP_OTHER;
|
||||
/* wait for all other ops to release the connection */
|
||||
while ( lc->lc_refcnt > 1 ) {
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
ldap_pvt_thread_yield();
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
}
|
||||
assert( lc->lc_refcnt == 1 );
|
||||
lc = avl_delete( &li->conntree, (caddr_t)lc,
|
||||
ldap_back_conn_cmp );
|
||||
assert( lc != NULL );
|
||||
|
||||
if ( !BER_BVISNULL( &lc->lc_local_ndn ) ) {
|
||||
ch_free( lc->lc_local_ndn.bv_val );
|
||||
}
|
||||
ber_dupbv( &lc->lc_local_ndn, &op->o_req_ndn );
|
||||
lerr = avl_insert( &li->conntree, (caddr_t)lc,
|
||||
ldap_back_conn_cmp, ldap_back_conn_dup );
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
if ( lerr == -1 ) {
|
||||
/* handle this! (e.g. wait until refcnt goes to 1...) */
|
||||
ldap_back_conn_free( lc );
|
||||
lc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return( rc );
|
||||
}
|
||||
|
||||
@ -223,13 +230,12 @@ ldap_back_freeconn( Operation *op, struct ldapconn *lc )
|
||||
int rc = 0;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
lc = avl_delete( &li->conntree, (caddr_t)lc,
|
||||
ldap_back_conn_cmp );
|
||||
if ( lc == NULL ) {
|
||||
/* something BAD happened */
|
||||
rc = -1;
|
||||
assert( lc->lc_refcnt > 0 );
|
||||
if ( --lc->lc_refcnt == 0 ) {
|
||||
lc = avl_delete( &li->conntree, (caddr_t)lc,
|
||||
ldap_back_conn_cmp );
|
||||
assert( lc != NULL );
|
||||
|
||||
} else {
|
||||
ldap_back_conn_free( (void *)lc );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
@ -358,6 +364,7 @@ retry:;
|
||||
memset( *lcp, 0, sizeof( struct ldapconn ) );
|
||||
}
|
||||
(*lcp)->lc_ld = ld;
|
||||
(*lcp)->lc_refcnt = 1;
|
||||
|
||||
error_return:;
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
@ -407,10 +414,13 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
lc = (struct ldapconn *)avl_find( li->conntree,
|
||||
(caddr_t)&lc_curr, ldap_back_conn_cmp );
|
||||
if ( lc != NULL ) {
|
||||
lc->lc_refcnt++;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
|
||||
/* Looks like we didn't get a bind. Open a new session... */
|
||||
if ( !lc ) {
|
||||
if ( lc == NULL ) {
|
||||
/* lc here must be NULL */
|
||||
if ( ldap_back_prepare_conn( &lc, op, rs, sendok ) != LDAP_SUCCESS ) {
|
||||
return NULL;
|
||||
@ -440,6 +450,7 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
|
||||
|
||||
/* Inserts the newly created ldapconn in the avl tree */
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
assert( lc->lc_refcnt == 1 );
|
||||
rs->sr_err = avl_insert( &li->conntree, (caddr_t)lc,
|
||||
ldap_back_conn_cmp, ldap_back_conn_dup );
|
||||
|
||||
@ -450,7 +461,8 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_getconn: conn %p inserted\n", (void *) lc, 0, 0 );
|
||||
"=>ldap_back_getconn: conn %p inserted (refcnt=%u)\n",
|
||||
(void *)lc, lc->lc_refcnt, 0 );
|
||||
|
||||
/* Err could be -1 in case a duplicate ldapconn is inserted */
|
||||
if ( rs->sr_err != 0 ) {
|
||||
@ -464,12 +476,27 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
|
||||
}
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_getconn: conn %p fetched\n", (void *) lc, 0, 0 );
|
||||
"=>ldap_back_getconn: conn %p fetched (refcnt=%u)\n",
|
||||
(void *)lc, lc->lc_refcnt, 0 );
|
||||
}
|
||||
|
||||
return lc;
|
||||
}
|
||||
|
||||
void
|
||||
ldap_back_release_conn(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
struct ldapconn *lc )
|
||||
{
|
||||
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
|
||||
assert( lc->lc_refcnt > 0 );
|
||||
lc->lc_refcnt--;
|
||||
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
* ldap_back_dobind
|
||||
*
|
||||
|
@ -44,6 +44,7 @@ ldap_back_compare(
|
||||
|
||||
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
|
||||
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
|
||||
lc = NULL;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
@ -70,5 +71,9 @@ retry:
|
||||
cleanup:
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
@ -1573,6 +1573,11 @@ retry:
|
||||
if (rs->sr_err != LDAP_SUCCESS) {
|
||||
rs->sr_err = slap_map_api2result( rs );
|
||||
}
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( &op2, rs, lc );
|
||||
}
|
||||
|
||||
} else {
|
||||
/* else just do the same as before */
|
||||
bv = (struct berval *) ch_malloc( sizeof(struct berval) );
|
||||
|
@ -45,8 +45,7 @@ ldap_back_delete(
|
||||
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
|
||||
|
||||
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
|
||||
rc = -1;
|
||||
goto cleanup;
|
||||
return -1;
|
||||
}
|
||||
|
||||
ctrls = op->o_ctrls;
|
||||
@ -71,5 +70,9 @@ retry:
|
||||
cleanup:
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -68,7 +68,8 @@ ldap_back_extended(
|
||||
op->o_ctrls = oldctrls;
|
||||
send_ldap_result( op, rs );
|
||||
rs->sr_text = NULL;
|
||||
return rs->sr_err;
|
||||
rc = rs->sr_err;
|
||||
goto done;
|
||||
}
|
||||
|
||||
rc = ( *exop_table[i].extended )( op, rs );
|
||||
@ -79,6 +80,11 @@ ldap_back_extended(
|
||||
}
|
||||
op->o_ctrls = oldctrls;
|
||||
|
||||
done:;
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
@ -170,5 +176,9 @@ retry:
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -202,8 +202,10 @@ void
|
||||
ldap_back_conn_free( void *v_lc )
|
||||
{
|
||||
struct ldapconn *lc = v_lc;
|
||||
|
||||
ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
|
||||
|
||||
if ( lc->lc_ld != NULL ) {
|
||||
ldap_unbind_ext_s( lc->lc_ld, NULL, NULL );
|
||||
}
|
||||
if ( !BER_BVISNULL( &lc->lc_bound_ndn ) ) {
|
||||
ch_free( lc->lc_bound_ndn.bv_val );
|
||||
}
|
||||
|
@ -122,6 +122,10 @@ cleanup:;
|
||||
}
|
||||
ch_free( modv );
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -45,7 +45,7 @@ ldap_back_modrdn(
|
||||
|
||||
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
|
||||
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
|
||||
return( -1 );
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ( op->orr_newSup ) {
|
||||
@ -78,6 +78,10 @@ retry:
|
||||
cleanup:
|
||||
(void)ldap_back_proxy_authz_ctrl_free( op, &ctrls );
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -50,6 +50,7 @@ extern BI_entry_get_rw ldap_back_entry_get;
|
||||
|
||||
int ldap_back_freeconn( Operation *op, struct ldapconn *lc );
|
||||
struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs, ldap_back_send_t sendok);
|
||||
void ldap_back_release_conn( struct slap_op *op, struct slap_rep *rs, struct ldapconn *lc );
|
||||
int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
|
||||
int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok);
|
||||
int ldap_back_map_result(SlapReply *rs);
|
||||
|
@ -157,7 +157,7 @@ ldap_back_search(
|
||||
LDAPControl **ctrls = NULL;
|
||||
|
||||
lc = ldap_back_getconn( op, rs, LDAP_BACK_SENDERR );
|
||||
if ( !lc ) {
|
||||
if ( !lc || !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
@ -165,9 +165,6 @@ ldap_back_search(
|
||||
* FIXME: in case of values return filter, we might want
|
||||
* to map attrs and maybe rewrite value
|
||||
*/
|
||||
if ( !ldap_back_dobind( lc, op, rs, LDAP_BACK_SENDERR ) ) {
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
/* should we check return values? */
|
||||
if ( op->ors_deref != -1 ) {
|
||||
@ -441,6 +438,10 @@ finish:;
|
||||
ch_free( attrs );
|
||||
}
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, rs, lc );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -722,6 +723,10 @@ cleanup:
|
||||
ch_free( filter );
|
||||
}
|
||||
|
||||
if ( lc != NULL ) {
|
||||
ldap_back_release_conn( op, &rs, lc );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -53,8 +53,10 @@ ldap_back_conn_destroy(
|
||||
|
||||
if ( lc ) {
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"=>ldap_back_conn_destroy: destroying conn %ld\n",
|
||||
lc->lc_conn->c_connid, 0, 0 );
|
||||
"=>ldap_back_conn_destroy: destroying conn %ld (refcnt=%u)\n",
|
||||
lc->lc_conn->c_connid, lc->lc_refcnt, 0 );
|
||||
|
||||
assert( lc->lc_refcnt == 0 );
|
||||
|
||||
/*
|
||||
* Needs a test because the handler may be corrupted,
|
||||
|
Loading…
Reference in New Issue
Block a user