Make sure every proxied operation has a separate candidates structure.
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;
}
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;
if ( mc ) {
meta_back_release_conn( mi, mc );
}
-
+ op->o_tmpfree( candidates, op->o_tmpmemctx );
return rs->sr_err;
}
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(
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(
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(
extern int
meta_clear_unused_candidates(
Operation *op,
- int candidate );
+ int candidate,
+ SlapReply *candidates );
extern int
meta_clear_one_candidate(
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",
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 ...
*/
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;
}
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;
i,
isroot = 0;
- SlapReply *candidates;
-
if ( be_isroot( op ) ) {
isroot = 1;
}
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 ];
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;
}
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 ) {
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;
}
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;
meta_back_release_conn( mi, mc );
}
+ op->o_tmpfree( candidates, op->o_tmpmemctx );
return rs->sr_err;
}
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 ];
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;
-
- 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;
+ SlapReply *candidates;
- } 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;
}
/*
*/
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,
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 ) )
/*
* 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 ];
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;
}
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;
meta_back_release_conn( mi, mc );
}
+ op->o_tmpfree( candidates, op->o_tmpmemctx );
return rs->sr_err;
}
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;
}
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;
meta_back_release_conn( mi, mc );
}
+ op->o_tmpfree( candidates, op->o_tmpmemctx );
return rs->sr_err;
}
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;
}
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;
meta_back_release_conn( mi, mc );
}
+ op->o_tmpfree( candidates, op->o_tmpmemctx );
return rs->sr_err;
}
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 );
* 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;
}
dc.conn = op->o_conn;
dc.rs = rs;
- if ( candidates == NULL ) candidates = meta_back_candidates_get( op );
/*
* Inits searches
*/
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 ) )
{
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
}
+ op->o_tmpfree( candidates, op->o_tmpmemctx );
return rs->sr_err;
}