mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-04-12 15:10:31 +08:00
ITS#10164 back-meta hangs when used with dynlist overlay
Make sure every proxied operation has a separate candidates structure.
This commit is contained in:
parent
aedc51888a
commit
493e991ebc
@ -47,15 +47,17 @@ meta_back_add( Operation *op, SlapReply *rs )
|
||||
int msgid;
|
||||
ldap_back_send_t retrying = LDAP_BACK_RETRYING;
|
||||
LDAPControl **ctrls = NULL;
|
||||
|
||||
SlapReply *candidates = NULL;
|
||||
Debug(LDAP_DEBUG_ARGS, "==> meta_back_add: %s\n",
|
||||
op->o_req_dn.bv_val );
|
||||
|
||||
/*
|
||||
* get the current connection
|
||||
*/
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
candidates = meta_back_candidates_get( op );
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR, candidates );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
@ -181,7 +183,7 @@ retry:;
|
||||
mt->mt_timeout[ SLAP_OP_ADD ], ( LDAP_BACK_SENDRESULT | retrying ) );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) {
|
||||
retrying &= ~LDAP_BACK_RETRYING;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
/* if the identity changed, there might be need to re-authz */
|
||||
(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
|
||||
goto retry;
|
||||
@ -205,7 +207,7 @@ done:;
|
||||
if ( mc ) {
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
@ -489,7 +489,8 @@ meta_back_getconn(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
int *candidate,
|
||||
ldap_back_send_t sendok );
|
||||
ldap_back_send_t sendok,
|
||||
SlapReply *candidates );
|
||||
|
||||
extern void
|
||||
meta_back_release_conn_lock(
|
||||
@ -504,7 +505,8 @@ meta_back_retry(
|
||||
SlapReply *rs,
|
||||
metaconn_t **mcp,
|
||||
int candidate,
|
||||
ldap_back_send_t sendok );
|
||||
ldap_back_send_t sendok,
|
||||
SlapReply *candidates );
|
||||
|
||||
extern void
|
||||
meta_back_conn_free(
|
||||
@ -538,7 +540,8 @@ meta_back_dobind(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
metaconn_t *mc,
|
||||
ldap_back_send_t sendok );
|
||||
ldap_back_send_t sendok,
|
||||
SlapReply *candidates );
|
||||
|
||||
extern int
|
||||
meta_back_single_dobind(
|
||||
@ -625,7 +628,8 @@ meta_back_select_unique_candidate(
|
||||
extern int
|
||||
meta_clear_unused_candidates(
|
||||
Operation *op,
|
||||
int candidate );
|
||||
int candidate,
|
||||
SlapReply *candidates );
|
||||
|
||||
extern int
|
||||
meta_clear_one_candidate(
|
||||
|
@ -89,10 +89,11 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
candidates = meta_back_candidates_get( op );
|
||||
/* we need meta_back_getconn() not send result even on error,
|
||||
* because we want to intercept the error and make it
|
||||
* invalidCredentials */
|
||||
mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_DONTSEND );
|
||||
mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_DONTSEND, candidates );
|
||||
if ( !mc ) {
|
||||
Debug(LDAP_DEBUG_ANY,
|
||||
"%s meta_back_bind: no target " "for dn \"%s\" (%d%s%s).\n",
|
||||
@ -110,11 +111,10 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
||||
break;
|
||||
}
|
||||
send_ldap_result( op, rs );
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
candidates = meta_back_candidates_get( op );
|
||||
|
||||
/*
|
||||
* Each target is scanned ...
|
||||
*/
|
||||
@ -284,10 +284,12 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
||||
rs->sr_err = slap_map_api2result( rs );
|
||||
}
|
||||
send_ldap_result( op, rs );
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
|
||||
}
|
||||
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
@ -672,7 +674,8 @@ meta_back_dobind(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
metaconn_t *mc,
|
||||
ldap_back_send_t sendok )
|
||||
ldap_back_send_t sendok,
|
||||
SlapReply *candidates )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
|
||||
@ -680,8 +683,6 @@ meta_back_dobind(
|
||||
i,
|
||||
isroot = 0;
|
||||
|
||||
SlapReply *candidates;
|
||||
|
||||
if ( be_isroot( op ) ) {
|
||||
isroot = 1;
|
||||
}
|
||||
@ -704,8 +705,6 @@ meta_back_dobind(
|
||||
goto done;
|
||||
}
|
||||
|
||||
candidates = meta_back_candidates_get( op );
|
||||
|
||||
for ( i = 0; i < mi->mi_ntargets; i++ ) {
|
||||
metatarget_t *mt = mi->mi_targets[ i ];
|
||||
metasingleconn_t *msc = &mc->mc_conns[ i ];
|
||||
@ -761,7 +760,7 @@ retry_binding:;
|
||||
if ( rc == LDAP_UNAVAILABLE ) {
|
||||
/* FIXME: meta_back_retry() already re-calls
|
||||
* meta_back_single_dobind() */
|
||||
if ( meta_back_retry( op, rs, &mc, i, sendok ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, i, sendok, candidates ) ) {
|
||||
goto retry_ok;
|
||||
}
|
||||
|
||||
|
@ -222,11 +222,11 @@ meta_back_select_unique_candidate(
|
||||
int
|
||||
meta_clear_unused_candidates(
|
||||
Operation *op,
|
||||
int candidate )
|
||||
int candidate,
|
||||
SlapReply *candidates )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
int i;
|
||||
SlapReply *candidates = meta_back_candidates_get( op );
|
||||
|
||||
for ( i = 0; i < mi->mi_ntargets; ++i ) {
|
||||
if ( i == candidate ) {
|
||||
|
@ -46,9 +46,12 @@ meta_back_compare( Operation *op, SlapReply *rs )
|
||||
int msgid;
|
||||
ldap_back_send_t retrying = LDAP_BACK_RETRYING;
|
||||
LDAPControl **ctrls = NULL;
|
||||
SlapReply *candidates = NULL;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
candidates = meta_back_candidates_get( op );
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR, candidates );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
@ -127,7 +130,7 @@ retry:;
|
||||
mt->mt_timeout[ SLAP_OP_COMPARE ], ( LDAP_BACK_SENDRESULT | retrying ) );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) {
|
||||
retrying &= ~LDAP_BACK_RETRYING;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
/* if the identity changed, there might be need to re-authz */
|
||||
(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
|
||||
goto retry;
|
||||
@ -149,6 +152,7 @@ cleanup:;
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
@ -699,7 +699,8 @@ meta_back_retry(
|
||||
SlapReply *rs,
|
||||
metaconn_t **mcp,
|
||||
int candidate,
|
||||
ldap_back_send_t sendok )
|
||||
ldap_back_send_t sendok,
|
||||
SlapReply *candidates )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metatarget_t *mt = mi->mi_targets[ candidate ];
|
||||
@ -971,64 +972,14 @@ meta_back_get_candidate(
|
||||
return candidate;
|
||||
}
|
||||
|
||||
static void *meta_back_candidates_dummy;
|
||||
|
||||
static void
|
||||
meta_back_candidates_keyfree(
|
||||
void *key,
|
||||
void *data )
|
||||
{
|
||||
metacandidates_t *mc = (metacandidates_t *)data;
|
||||
|
||||
ber_memfree_x( mc->mc_candidates, NULL );
|
||||
ber_memfree_x( data, NULL );
|
||||
}
|
||||
|
||||
SlapReply *
|
||||
meta_back_candidates_get( Operation *op )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metacandidates_t *mc;
|
||||
SlapReply *candidates;
|
||||
|
||||
if ( op->o_threadctx ) {
|
||||
void *data = NULL;
|
||||
|
||||
ldap_pvt_thread_pool_getkey( op->o_threadctx,
|
||||
&meta_back_candidates_dummy, &data, NULL );
|
||||
mc = (metacandidates_t *)data;
|
||||
|
||||
} else {
|
||||
mc = mi->mi_candidates;
|
||||
}
|
||||
|
||||
if ( mc == NULL ) {
|
||||
mc = ch_calloc( sizeof( metacandidates_t ), 1 );
|
||||
mc->mc_ntargets = mi->mi_ntargets;
|
||||
mc->mc_candidates = ch_calloc( sizeof( SlapReply ), mc->mc_ntargets );
|
||||
if ( op->o_threadctx ) {
|
||||
void *data = NULL;
|
||||
|
||||
data = (void *)mc;
|
||||
ldap_pvt_thread_pool_setkey( op->o_threadctx,
|
||||
&meta_back_candidates_dummy, data,
|
||||
meta_back_candidates_keyfree,
|
||||
NULL, NULL );
|
||||
|
||||
} else {
|
||||
mi->mi_candidates = mc;
|
||||
}
|
||||
|
||||
} else if ( mc->mc_ntargets < mi->mi_ntargets ) {
|
||||
/* NOTE: in the future, may want to allow back-config
|
||||
* to add/remove targets from back-meta... */
|
||||
mc->mc_candidates = ch_realloc( mc->mc_candidates,
|
||||
sizeof( SlapReply ) * mi->mi_ntargets );
|
||||
memset( &mc->mc_candidates[ mc->mc_ntargets ], 0,
|
||||
sizeof( SlapReply ) * ( mi->mi_ntargets - mc->mc_ntargets ) );
|
||||
mc->mc_ntargets = mi->mi_ntargets;
|
||||
}
|
||||
|
||||
return mc->mc_candidates;
|
||||
candidates = op->o_tmpcalloc( mi->mi_ntargets, sizeof( SlapReply ), op->o_tmpmemctx );
|
||||
return candidates;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1066,10 +1017,11 @@ meta_back_candidates_get( Operation *op )
|
||||
*/
|
||||
metaconn_t *
|
||||
meta_back_getconn(
|
||||
Operation *op,
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
int *candidate,
|
||||
ldap_back_send_t sendok )
|
||||
ldap_back_send_t sendok,
|
||||
SlapReply *candidates )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metaconn_t *mc = NULL,
|
||||
@ -1090,8 +1042,6 @@ meta_back_getconn(
|
||||
struct berval ndn = op->o_req_ndn,
|
||||
pndn;
|
||||
|
||||
SlapReply *candidates = meta_back_candidates_get( op );
|
||||
|
||||
/* Internal searches are privileged and shared. So is root. */
|
||||
if ( ( !BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ALWAYS( mi ) )
|
||||
|| ( BER_BVISEMPTY( &op->o_ndn ) && META_BACK_PROXYAUTHZ_ANON( mi ) )
|
||||
@ -1474,7 +1424,7 @@ retry_lock2:;
|
||||
/*
|
||||
* Clear all other candidates
|
||||
*/
|
||||
( void )meta_clear_unused_candidates( op, i );
|
||||
( void )meta_clear_unused_candidates( op, i, candidates );
|
||||
|
||||
mt = mi->mi_targets[ i ];
|
||||
msc = &mc->mc_conns[ i ];
|
||||
|
@ -43,9 +43,12 @@ meta_back_delete( Operation *op, SlapReply *rs )
|
||||
int msgid;
|
||||
ldap_back_send_t retrying = LDAP_BACK_RETRYING;
|
||||
LDAPControl **ctrls = NULL;
|
||||
SlapReply *candidates = NULL;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
candidates = meta_back_candidates_get( op );
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR, candidates );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
@ -79,7 +82,7 @@ retry:;
|
||||
mt->mt_timeout[ SLAP_OP_DELETE ], ( LDAP_BACK_SENDRESULT | retrying ) );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) {
|
||||
retrying &= ~LDAP_BACK_RETRYING;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
/* if the identity changed, there might be need to re-authz */
|
||||
(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
|
||||
goto retry;
|
||||
@ -98,6 +101,7 @@ cleanup:;
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
@ -49,9 +49,12 @@ meta_back_modify( Operation *op, SlapReply *rs )
|
||||
int msgid;
|
||||
ldap_back_send_t retrying = LDAP_BACK_RETRYING;
|
||||
LDAPControl **ctrls = NULL;
|
||||
SlapReply *candidates = NULL;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
candidates = meta_back_candidates_get( op );
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR, candidates );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
@ -180,7 +183,7 @@ retry:;
|
||||
mt->mt_timeout[ SLAP_OP_MODIFY ], ( LDAP_BACK_SENDRESULT | retrying ) );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) {
|
||||
retrying &= ~LDAP_BACK_RETRYING;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
/* if the identity changed, there might be need to re-authz */
|
||||
(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
|
||||
goto retry;
|
||||
@ -205,6 +208,7 @@ cleanup:;
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
@ -45,9 +45,12 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
|
||||
ldap_back_send_t retrying = LDAP_BACK_RETRYING;
|
||||
LDAPControl **ctrls = NULL;
|
||||
struct berval newrdn = BER_BVNULL;
|
||||
SlapReply *candidates = NULL;
|
||||
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
|
||||
candidates = meta_back_candidates_get( op );
|
||||
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR, candidates );
|
||||
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
@ -142,7 +145,7 @@ retry:;
|
||||
mt->mt_timeout[ SLAP_OP_MODRDN ], ( LDAP_BACK_SENDRESULT | retrying ) );
|
||||
if ( rs->sr_err == LDAP_UNAVAILABLE && retrying ) {
|
||||
retrying &= ~LDAP_BACK_RETRYING;
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR, candidates ) ) {
|
||||
/* if the identity changed, there might be need to re-authz */
|
||||
(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
|
||||
goto retry;
|
||||
@ -172,6 +175,7 @@ cleanup:;
|
||||
meta_back_release_conn( mi, mc );
|
||||
}
|
||||
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
@ -722,7 +722,7 @@ retry:;
|
||||
break;
|
||||
|
||||
case LDAP_SERVER_DOWN:
|
||||
if ( nretries && meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND ) ) {
|
||||
if ( nretries && meta_back_retry( op, rs, mcp, candidate, LDAP_BACK_DONTSEND, candidates ) ) {
|
||||
nretries = 0;
|
||||
/* if the identity changed, there might be need to re-authz */
|
||||
(void)mi->mi_ldap_extra->controls_free( op, rs, &ctrls );
|
||||
@ -798,8 +798,9 @@ meta_back_search( Operation *op, SlapReply *rs )
|
||||
* FIXME: in case of values return filter, we might want
|
||||
* to map attrs and maybe rewrite value
|
||||
*/
|
||||
candidates = meta_back_candidates_get( op );
|
||||
getconn:;
|
||||
mc = meta_back_getconn( op, rs, NULL, sendok );
|
||||
mc = meta_back_getconn( op, rs, NULL, sendok, candidates );
|
||||
if ( !mc ) {
|
||||
return rs->sr_err;
|
||||
}
|
||||
@ -807,7 +808,6 @@ getconn:;
|
||||
dc.conn = op->o_conn;
|
||||
dc.rs = rs;
|
||||
|
||||
if ( candidates == NULL ) candidates = meta_back_candidates_get( op );
|
||||
/*
|
||||
* Inits searches
|
||||
*/
|
||||
@ -1146,7 +1146,7 @@ really_bad:;
|
||||
if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) {
|
||||
candidates[ i ].sr_type = REP_RESULT;
|
||||
|
||||
if ( meta_back_retry( op, rs, &mc, i, LDAP_BACK_DONTSEND ) ) {
|
||||
if ( meta_back_retry( op, rs, &mc, i, LDAP_BACK_DONTSEND, candidates ) ) {
|
||||
candidates[ i ].sr_msgid = META_MSGID_IGNORE;
|
||||
switch ( meta_back_search_start( op, rs, &dc, &mc, i, candidates, NULL, 0 ) )
|
||||
{
|
||||
@ -1997,6 +1997,7 @@ finish:;
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
||||
op->o_tmpfree( candidates, op->o_tmpmemctx );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user