more on error handling reworking; should address ITS#3672 and ITS#3676

This commit is contained in:
Pierangelo Masarati 2005-04-22 21:43:52 +00:00
parent 8d0fba2d97
commit 41aad6e27f
14 changed files with 711 additions and 558 deletions

View file

@ -35,8 +35,8 @@
int
meta_back_add( Operation *op, SlapReply *rs )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *mc;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
int i, candidate = -1;
int isupdate;
Attribute *a;
@ -52,7 +52,7 @@ meta_back_add( Operation *op, SlapReply *rs )
* get the current connection
*/
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !mc || !meta_back_dobind( mc, op, LDAP_BACK_SENDERR ) ) {
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
@ -61,7 +61,7 @@ meta_back_add( Operation *op, SlapReply *rs )
/*
* Rewrite the add dn, if needed
*/
dc.rwmap = &li->mi_targets[ candidate ]->mt_rwmap;
dc.rwmap = &mi->mi_targets[ candidate ]->mt_rwmap;
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "addDN";
@ -93,7 +93,7 @@ meta_back_add( Operation *op, SlapReply *rs )
mapped = a->a_desc->ad_cname;
} else {
ldap_back_map( &li->mi_targets[ candidate ]->mt_rwmap.rwm_at,
ldap_back_map( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_at,
&a->a_desc->ad_cname, &mapped, BACKLDAP_MAP );
if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
continue;
@ -118,11 +118,11 @@ meta_back_add( Operation *op, SlapReply *rs )
for ( j = 0; !BER_BVISNULL( &a->a_vals[ j ] ); ) {
struct ldapmapping *mapping;
ldap_back_mapping( &li->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
ldap_back_mapping( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
&a->a_vals[ j ], &mapping, BACKLDAP_MAP );
if ( mapping == NULL ) {
if ( li->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
if ( mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
continue;
}
attrs[ i ]->mod_bvalues[ j ] = &a->a_vals[ j ];

View file

@ -83,7 +83,7 @@ typedef struct dncookie {
} dncookie;
#define META_BIND_NRETRIES 3
#define META_BIND_TIMEOUT 1000
#define META_BIND_TIMEOUT 10000
int ldap_back_dn_massage(dncookie *dc, struct berval *dn,
struct berval *res);
@ -105,48 +105,58 @@ void ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *m,
#define BACKLDAP_REMAP 1
char *
ldap_back_map_filter(
struct ldapmap *at_map,
struct ldapmap *oc_map,
struct berval *f,
int remap
);
struct ldapmap *at_map,
struct ldapmap *oc_map,
struct berval *f,
int remap );
int
ldap_back_map_attrs(
struct ldapmap *at_map,
AttributeName *a,
int remap,
char ***mapped_attrs
);
struct ldapmap *at_map,
AttributeName *a,
int remap,
char ***mapped_attrs );
extern int ldap_back_map_config(
struct ldapmap *oc_map,
struct ldapmap *at_map,
const char *fname,
int lineno,
int argc,
char **argv );
struct ldapmap *oc_map,
struct ldapmap *at_map,
const char *fname,
int lineno,
int argc,
char **argv );
extern int
ldap_back_filter_map_rewrite(
dncookie *dc,
Filter *f,
struct berval *fstr,
int remap );
dncookie *dc,
Filter *f,
struct berval *fstr,
int remap );
/* suffix massaging by means of librewrite */
#ifdef ENABLE_REWRITE
extern int suffix_massage_config( struct rewrite_info *info,
struct berval *pvnc, struct berval *nvnc,
struct berval *prnc, struct berval *nrnc);
extern int
suffix_massage_config( struct rewrite_info *info,
struct berval *pvnc,
struct berval *nvnc,
struct berval *prnc,
struct berval *nrnc );
#endif /* ENABLE_REWRITE */
extern int ldap_back_referral_result_rewrite( dncookie *dc, BerVarray a_vals );
extern int ldap_dnattr_rewrite( dncookie *dc, BerVarray a_vals );
extern int ldap_dnattr_result_rewrite( dncookie *dc, BerVarray a_vals );
extern int
ldap_back_referral_result_rewrite(
dncookie *dc,
BerVarray a_vals );
extern int
ldap_dnattr_rewrite(
dncookie *dc,
BerVarray a_vals );
extern int
ldap_dnattr_result_rewrite(
dncookie *dc,
BerVarray a_vals );
/* (end of) from back-ldap.h before rwm removal */
struct metasingleconn {
typedef struct metasingleconn_t {
int msc_candidate;
#define META_NOT_CANDIDATE ((ber_tag_t)0)
#define META_CANDIDATE ((ber_tag_t)1)
@ -159,11 +169,11 @@ struct metasingleconn {
#define META_UNBOUND 0
#define META_BOUND 1
#define META_ANONYMOUS 2
};
} metasingleconn_t;
#define META_LAST(lsc) ((lsc)->msc_candidate == META_LAST_CONN)
#define META_LAST(msc) ((msc)->msc_candidate == META_LAST_CONN)
struct metaconn {
typedef struct metaconn_t {
struct slap_conn *mc_conn;
ldap_pvt_thread_mutex_t mc_mutex;
@ -175,10 +185,10 @@ struct metaconn {
#define META_BOUND_NONE (-1)
#define META_BOUND_ALL (-2)
/* supersedes the connection stuff */
struct metasingleconn *mc_conns;
};
metasingleconn_t *mc_conns;
} metaconn_t;
struct metatarget {
typedef struct metatarget_t {
char *mt_uri;
struct berval mt_psuffix; /* pretty suffix */
struct berval mt_nsuffix; /* normalized suffix */
@ -189,26 +199,26 @@ struct metatarget {
struct berval mt_pseudorootpw;
struct ldaprwmap mt_rwmap;
};
} metatarget_t;
struct metadncache {
typedef struct metadncache_t {
ldap_pvt_thread_mutex_t mutex;
Avlnode *tree;
#define META_DNCACHE_DISABLED (0)
#define META_DNCACHE_FOREVER (-1)
long int ttl; /* seconds; 0: no cache, -1: no expiry */
};
} metadncache_t;
struct metainfo {
typedef struct metainfo_t {
int mi_ntargets;
int mi_defaulttarget;
int mi_network_timeout;
#define META_DEFAULT_TARGET_NONE (-1)
struct metatarget **mi_targets;
metatarget_t **mi_targets;
SlapReply *mi_candidates;
struct metadncache mi_cache;
metadncache_t mi_cache;
ldap_pvt_thread_mutex_t mi_conn_mutex;
Avlnode *mi_conntree;
@ -222,7 +232,7 @@ struct metainfo {
#define LDAP_BACK_F_TLS_CRITICAL ( 0x04U | LDAP_BACK_F_USE_TLS )
#define LDAP_BACK_F_CHASE_REFERRALS 0x8U
#endif
};
} metainfo_t;
typedef enum meta_op_type {
META_OP_ALLOW_MULTIPLE = 0,
@ -233,113 +243,123 @@ typedef enum meta_op_type {
SlapReply *
meta_back_candidates_get( Operation *op );
extern struct metaconn *
extern metaconn_t *
meta_back_getconn(
Operation *op,
SlapReply *rs,
int *candidate,
ldap_back_send_t sendok );
Operation *op,
SlapReply *rs,
int *candidate,
ldap_back_send_t sendok );
extern int
meta_back_retry(
Operation *op,
SlapReply *rs,
struct metaconn *mc,
int candidate,
ldap_back_send_t sendok );
Operation *op,
SlapReply *rs,
metaconn_t *mc,
int candidate,
ldap_back_send_t sendok );
extern void
meta_back_conn_free( struct metaconn *mc );
meta_back_conn_free( metaconn_t *mc );
extern int
meta_back_init_one_conn(
Operation *op,
SlapReply *rs,
metatarget_t *mt,
metasingleconn_t *msc,
ldap_back_send_t sendok );
extern int
meta_back_dobind(
struct metaconn *lc,
Operation *op,
ldap_back_send_t sendok );
Operation *op,
SlapReply *rs,
metaconn_t *mc,
ldap_back_send_t sendok );
int
meta_back_single_dobind(
Operation *op,
struct metasingleconn *msc,
SlapReply *rs,
metaconn_t *msc,
int candidate,
ldap_back_send_t sendok,
int retries );
extern int
meta_back_op_result(
struct metaconn *lc,
Operation *op,
SlapReply *rs,
int candidate );
metaconn_t *mc,
Operation *op,
SlapReply *rs,
int candidate );
extern int
back_meta_LTX_init_module(
int argc,
char *argv[] );
int argc,
char *argv[] );
extern int
meta_back_conn_cmp(
const void *c1,
const void *c2 );
const void *c1,
const void *c2 );
extern int
meta_back_conn_dup(
void *c1,
void *c2 );
void *c1,
void *c2 );
/*
* Candidate stuff
*/
extern int
meta_back_is_candidate(
struct berval *nsuffix,
struct berval *ndn,
int scope );
struct berval *nsuffix,
struct berval *ndn,
int scope );
extern int
meta_back_select_unique_candidate(
struct metainfo *li,
struct berval *ndn );
metainfo_t *mi,
struct berval *ndn );
extern int
meta_clear_unused_candidates(
Operation *op,
struct metaconn *lc,
int candidate );
Operation *op,
int candidate );
extern int
meta_clear_one_candidate(
struct metasingleconn *lc );
metasingleconn_t *mc );
/*
* Dn cache stuff (experimental)
*/
extern int
meta_dncache_cmp(
const void *c1,
const void *c2 );
const void *c1,
const void *c2 );
extern int
meta_dncache_dup(
void *c1,
void *c2 );
void *c1,
void *c2 );
#define META_TARGET_NONE (-1)
#define META_TARGET_MULTIPLE (-2)
extern int
meta_dncache_get_target(
struct metadncache *cache,
struct berval *ndn );
metadncache_t *cache,
struct berval *ndn );
extern int
meta_dncache_update_entry(
struct metadncache *cache,
struct berval *ndn,
int target );
metadncache_t *cache,
struct berval *ndn,
int target );
extern int
meta_dncache_delete_entry(
struct metadncache *cache,
struct berval *ndn );
metadncache_t *cache,
struct berval *ndn );
extern void
meta_dncache_free( void *entry );

View file

@ -37,16 +37,16 @@ static LDAP_REBIND_PROC meta_back_rebind;
static int
meta_back_single_bind(
Operation *op,
SlapReply *rs,
struct metaconn *mc,
int candidate );
Operation *op,
SlapReply *rs,
metaconn_t *mc,
int candidate );
int
meta_back_bind( Operation *op, SlapReply *rs )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *mc;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
int rc = LDAP_OTHER,
i, gotit = 0, isroot = 0;
@ -90,7 +90,7 @@ meta_back_bind( Operation *op, SlapReply *rs )
* Each target is scanned ...
*/
mc->mc_auth_target = META_BOUND_NONE;
for ( i = 0; i < li->mi_ntargets; i++ ) {
for ( i = 0; i < mi->mi_ntargets; i++ ) {
int lerr;
Operation op2 = *op;
@ -115,11 +115,11 @@ meta_back_bind( Operation *op, SlapReply *rs )
0, 0, 0 );
}
if ( isroot && !BER_BVISNULL( &li->mi_targets[ i ]->mt_pseudorootdn ) )
if ( isroot && !BER_BVISNULL( &mi->mi_targets[ i ]->mt_pseudorootdn ) )
{
op2.o_req_dn = li->mi_targets[ i ]->mt_pseudorootdn;
op2.o_req_ndn = li->mi_targets[ i ]->mt_pseudorootdn;
op2.orb_cred = li->mi_targets[ i ]->mt_pseudorootpw;
op2.o_req_dn = mi->mi_targets[ i ]->mt_pseudorootdn;
op2.o_req_ndn = mi->mi_targets[ i ]->mt_pseudorootdn;
op2.orb_cred = mi->mi_targets[ i ]->mt_pseudorootpw;
op2.orb_method = LDAP_AUTH_SIMPLE;
}
@ -171,22 +171,22 @@ meta_back_bind( Operation *op, SlapReply *rs )
*/
static int
meta_back_single_bind(
Operation *op,
SlapReply *rs,
struct metaconn *mc,
int candidate
)
Operation *op,
SlapReply *rs,
metaconn_t *mc,
int candidate )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = mi->mi_targets[ candidate ];
struct berval mdn = BER_BVNULL;
dncookie dc;
struct metasingleconn *msc = &mc->mc_conns[ candidate ];
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int msgid;
/*
* Rewrite the bind dn if needed
*/
dc.rwmap = &li->mi_targets[ candidate ]->mt_rwmap;
dc.rwmap = &mi->mi_targets[ candidate ]->mt_rwmap;
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "bindDN";
@ -201,6 +201,7 @@ meta_back_single_bind(
* and more in case of failure ... */
/* FIXME: should be check if at least some of the op->o_ctrls
* can/should be passed? */
rebind:;
rs->sr_err = ldap_sasl_bind( msc->msc_ld, mdn.bv_val,
LDAP_SASL_SIMPLE, &op->orb_cred,
op->o_ctrls, NULL, &msgid );
@ -229,10 +230,22 @@ retry:;
case -1:
ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER,
&rs->sr_err );
Debug( LDAP_DEBUG_ANY, "### %s meta_back_single_bind(%s) err=%d\n",
op->o_log_prefix, mdn.bv_val, rs->sr_err );
if ( rs->sr_err == LDAP_UNAVAILABLE && nretries > 0 ) {
nretries--;
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
msc->msc_ld = NULL;
msc->msc_bound = 0;
/* mc here must be the regular mc, reset and ready for init */
rc = meta_back_init_one_conn( op, rs, mt, msc,
LDAP_BACK_DONTSEND );
if ( rc ) {
nretries--;
ldap_pvt_thread_yield();
goto rebind;
}
}
break;
@ -256,15 +269,15 @@ retry:;
msc->msc_bound = META_BOUND;
mc->mc_auth_target = candidate;
if ( LDAP_BACK_SAVECRED( li ) ) {
if ( LDAP_BACK_SAVECRED( mi ) ) {
ber_bvreplace( &msc->msc_cred, &op->orb_cred );
ldap_set_rebind_proc( msc->msc_ld, meta_back_rebind, msc );
}
if ( li->mi_cache.ttl != META_DNCACHE_DISABLED
if ( mi->mi_cache.ttl != META_DNCACHE_DISABLED
&& op->o_req_ndn.bv_len != 0 )
{
( void )meta_dncache_update_entry( &li->mi_cache,
( void )meta_dncache_update_entry( &mi->mi_cache,
&op->o_req_ndn, candidate );
}
@ -282,13 +295,18 @@ return_results:;
int
meta_back_single_dobind(
Operation *op,
struct metasingleconn *msc,
SlapReply *rs,
metaconn_t *mc,
int candidate,
ldap_back_send_t sendok,
int retries )
{
int rc;
struct berval cred = BER_BVC( "" );
int msgid;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = mi->mi_targets[ candidate ];
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int rc;
struct berval cred = BER_BVC( "" );
int msgid;
/*
* Otherwise an anonymous bind is performed
@ -300,9 +318,7 @@ meta_back_single_dobind(
BER_BVZERO( &msc->msc_bound_ndn );
}
if ( /* FIXME: need li ... li->savecred && */
!BER_BVISNULL( &msc->msc_cred ) )
{
if ( !BER_BVISNULL( &msc->msc_cred ) ) {
/* destroy sensitive data */
memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
ber_memfree( msc->msc_cred.bv_val );
@ -311,23 +327,23 @@ meta_back_single_dobind(
/* FIXME: should we check if at least some of the op->o_ctrls
* can/should be passed? */
rebind:;
rc = ldap_sasl_bind( msc->msc_ld, "", LDAP_SASL_SIMPLE, &cred,
NULL, NULL, &msgid );
if ( rc == LDAP_SUCCESS ) {
LDAPMessage *res;
struct timeval tv = { 0, 0 };
int err;
/*
* handle response!!!
*/
retry:;
tv.tv_sec = 0;
tv.tv_usec = META_BIND_TIMEOUT;
switch ( ldap_result( msc->msc_ld, msgid, 0, &tv, &res ) ) {
case 0:
if ( retries > 0 ) {
ldap_pvt_thread_yield();
tv.tv_sec = 0;
tv.tv_usec = META_BIND_TIMEOUT;
retries--;
goto retry;
}
@ -337,19 +353,43 @@ retry:;
case -1:
ldap_get_option( msc->msc_ld,
LDAP_OPT_ERROR_NUMBER, &rc );
LDAP_OPT_ERROR_NUMBER, &rs->sr_err );
Debug( LDAP_DEBUG_ANY, "### %s meta_back_single_dobind(\"\") err=%d\n",
op->o_log_prefix, rs->sr_err, 0 );
rc = slap_map_api2result( rs );
if ( rc == LDAP_UNAVAILABLE && retries > 0 ) {
ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
msc->msc_ld = NULL;
msc->msc_bound = 0;
/* mc here must be the regular mc, reset and ready for init */
rc = meta_back_init_one_conn( op, rs, mt, msc, LDAP_BACK_DONTSEND );
if ( rc ) {
ldap_pvt_thread_yield();
retries--;
goto rebind;
}
}
break;
default:
rc = ldap_parse_result( msc->msc_ld, res, &err,
rc = ldap_parse_result( msc->msc_ld, res, &rs->sr_err,
NULL, NULL, NULL, NULL, 1 );
if ( rc == LDAP_SUCCESS ) {
rc = err;
rc = slap_map_api2result( rs );
}
break;
}
}
if ( rc != LDAP_SUCCESS && ( sendok & LDAP_BACK_SENDERR ) ) {
rs->sr_err = rc;
send_ldap_result( op, rs );
}
return rc;
}
@ -357,9 +397,13 @@ retry:;
* meta_back_dobind
*/
int
meta_back_dobind( struct metaconn *mc, Operation *op, ldap_back_send_t sendok )
meta_back_dobind(
Operation *op,
SlapReply *rs,
metaconn_t *mc,
ldap_back_send_t sendok )
{
struct metasingleconn *msc;
metasingleconn_t *msc;
int bound = 0, i;
SlapReply *candidates = meta_back_candidates_get( op );
@ -392,7 +436,8 @@ meta_back_dobind( struct metaconn *mc, Operation *op, ldap_back_send_t sendok )
continue;
}
rc = meta_back_single_dobind( op, msc, sendok, META_BIND_NRETRIES );
rc = meta_back_single_dobind( op, rs, mc, i,
LDAP_BACK_DONTSEND, META_BIND_NRETRIES );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "%s meta_back_dobind[%d]: "
"(anonymous) err=%d\n",
@ -420,6 +465,13 @@ meta_back_dobind( struct metaconn *mc, Operation *op, ldap_back_send_t sendok )
done:;
ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
if ( bound == 0 && sendok & LDAP_BACK_SENDERR ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
rs->sr_err = LDAP_BUSY;
}
send_ldap_result( op, rs );
}
return( bound > 0 );
}
@ -430,10 +482,14 @@ done:;
* credentials as the original user on this session.
*/
static int
meta_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
ber_int_t msgid, void *params )
meta_back_rebind(
LDAP *ld,
LDAP_CONST char *url,
ber_tag_t request,
ber_int_t msgid,
void *params )
{
struct metasingleconn *msc = (struct metasingleconn *)params;
metasingleconn_t *msc = ( metasingleconn_t * )params;
return ldap_sasl_bind_s( ld, msc->msc_bound_ndn.bv_val,
LDAP_SASL_SIMPLE, &msc->msc_cred,
@ -445,14 +501,14 @@ meta_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
*/
int
meta_back_op_result(
struct metaconn *mc,
metaconn_t *mc,
Operation *op,
SlapReply *rs,
int candidate )
{
int i,
rerr = LDAP_SUCCESS;
struct metasingleconn *msc;
metasingleconn_t *msc;
char *rmsg = NULL;
char *rmatch = NULL;
int free_rmsg = 0,

View file

@ -52,9 +52,8 @@
static int
meta_back_is_candidate_unique(
struct metainfo *li,
struct berval *ndn
);
metainfo_t *mi,
struct berval *ndn );
/*
* returns 1 if suffix is candidate for dn, otherwise 0
@ -63,10 +62,9 @@ meta_back_is_candidate_unique(
*/
int
meta_back_is_candidate(
struct berval *nsuffix,
struct berval *ndn,
int scope
)
struct berval *nsuffix,
struct berval *ndn,
int scope )
{
if ( dnIsSuffix( ndn, nsuffix ) ) {
return META_CANDIDATE;
@ -90,11 +88,10 @@ meta_back_is_candidate(
*/
static int
meta_back_is_candidate_unique(
struct metainfo *li,
struct berval *ndn
)
metainfo_t *mi,
struct berval *ndn )
{
switch ( meta_back_select_unique_candidate( li, ndn ) ) {
switch ( meta_back_select_unique_candidate( mi, ndn ) ) {
case META_TARGET_MULTIPLE:
case META_TARGET_NONE:
return 0;
@ -112,14 +109,13 @@ meta_back_is_candidate_unique(
*/
int
meta_back_select_unique_candidate(
struct metainfo *li,
struct berval *ndn
)
metainfo_t *mi,
struct berval *ndn )
{
int i, candidate = META_TARGET_NONE;
for ( i = 0; i < li->mi_ntargets; ++i ) {
if ( meta_back_is_candidate( &li->mi_targets[ i ]->mt_nsuffix, ndn, LDAP_SCOPE_BASE ) )
for ( i = 0; i < mi->mi_ntargets; ++i ) {
if ( meta_back_is_candidate( &mi->mi_targets[ i ]->mt_nsuffix, ndn, LDAP_SCOPE_BASE ) )
{
if ( candidate == META_TARGET_NONE ) {
candidate = i;
@ -140,16 +136,14 @@ meta_back_select_unique_candidate(
*/
int
meta_clear_unused_candidates(
Operation *op,
struct metaconn *lc,
int candidate
)
Operation *op,
int candidate )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
int i;
SlapReply *candidates = meta_back_candidates_get( op );
for ( i = 0; i < li->mi_ntargets; ++i ) {
for ( i = 0; i < mi->mi_ntargets; ++i ) {
if ( i == candidate ) {
continue;
}
@ -166,22 +160,21 @@ meta_clear_unused_candidates(
*/
int
meta_clear_one_candidate(
struct metasingleconn *lsc
)
metasingleconn_t *msc )
{
if ( lsc->msc_ld ) {
ldap_unbind_ext_s( lsc->msc_ld, NULL, NULL );
lsc->msc_ld = NULL;
if ( msc->msc_ld ) {
ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
msc->msc_ld = NULL;
}
if ( !BER_BVISNULL( &lsc->msc_bound_ndn ) ) {
ber_memfree( lsc->msc_bound_ndn.bv_val );
BER_BVZERO( &lsc->msc_bound_ndn );
if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
ber_memfree( msc->msc_bound_ndn.bv_val );
BER_BVZERO( &msc->msc_bound_ndn );
}
if ( !BER_BVISNULL( &lsc->msc_cred ) ) {
ber_memfree( lsc->msc_cred.bv_val );
BER_BVZERO( &lsc->msc_cred );
if ( !BER_BVISNULL( &msc->msc_cred ) ) {
ber_memfree( msc->msc_cred.bv_val );
BER_BVZERO( &msc->msc_cred );
}
return 0;

View file

@ -34,9 +34,9 @@
int
meta_back_compare( Operation *op, SlapReply *rs )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *lc;
struct metasingleconn *lsc;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
metasingleconn_t *msc;
char *match = NULL,
*err = NULL;
struct berval mmatch = BER_BVNULL;
@ -52,12 +52,12 @@ meta_back_compare( Operation *op, SlapReply *rs )
SlapReply *candidates = meta_back_candidates_get( op );
lc = meta_back_getconn( op, rs, NULL, LDAP_BACK_SENDERR );
if ( !lc || !meta_back_dobind( lc, op, LDAP_BACK_SENDERR ) ) {
mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_SENDERR );
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
msgid = ch_calloc( sizeof( int ), li->mi_ntargets );
msgid = ch_calloc( sizeof( int ), mi->mi_ntargets );
if ( msgid == NULL ) {
return -1;
}
@ -69,7 +69,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
dc.rs = rs;
dc.ctx = "compareDN";
for ( i = 0, lsc = &lc->mc_conns[ 0 ]; !META_LAST( lsc ); ++i, ++lsc ) {
for ( i = 0, msc = &mc->mc_conns[ 0 ]; !META_LAST( msc ); ++i, ++msc ) {
struct berval mdn = BER_BVNULL;
struct berval mapped_attr = op->orc_ava->aa_desc->ad_cname;
struct berval mapped_value = op->orc_ava->aa_value;
@ -82,7 +82,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
/*
* Rewrite the compare dn, if needed
*/
dc.rwmap = &li->mi_targets[ i ]->mt_rwmap;
dc.rwmap = &mi->mi_targets[ i ]->mt_rwmap;
switch ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
case LDAP_UNWILLING_TO_PERFORM:
@ -97,7 +97,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
* if attr is objectClass, try to remap the value
*/
if ( op->orc_ava->aa_desc == slap_schema.si_ad_objectClass ) {
ldap_back_map( &li->mi_targets[ i ]->mt_rwmap.rwm_oc,
ldap_back_map( &mi->mi_targets[ i ]->mt_rwmap.rwm_oc,
&op->orc_ava->aa_value,
&mapped_value, BACKLDAP_MAP );
@ -108,7 +108,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
* else try to remap the attribute
*/
} else {
ldap_back_map( &li->mi_targets[ i ]->mt_rwmap.rwm_at,
ldap_back_map( &mi->mi_targets[ i ]->mt_rwmap.rwm_at,
&op->orc_ava->aa_desc->ad_cname,
&mapped_attr, BACKLDAP_MAP );
if ( BER_BVISNULL( &mapped_attr ) || mapped_attr.bv_val[0] == '\0' ) {
@ -136,7 +136,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
* that returns determines the result; a constraint on unicity
* of the result ought to be enforced
*/
rc = ldap_compare_ext( lc->mc_conns[ i ].msc_ld, mdn.bv_val,
rc = ldap_compare_ext( mc->mc_conns[ i ].msc_ld, mdn.bv_val,
mapped_attr.bv_val, &mapped_value,
op->o_ctrls, NULL, &msgid[ i ] );
@ -171,7 +171,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
/*
* FIXME: should we check for abandon?
*/
for ( i = 0, lsc = &lc->mc_conns[ 0 ]; !META_LAST( lsc ); lsc++, i++ ) {
for ( i = 0, msc = &mc->mc_conns[ 0 ]; !META_LAST( msc ); msc++, i++ ) {
int lrc;
LDAPMessage *res = NULL;
struct timeval tv = { 0 };
@ -183,7 +183,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
continue;
}
lrc = ldap_result( lsc->msc_ld, msgid[ i ],
lrc = ldap_result( msc->msc_ld, msgid[ i ],
0, &tv, &res );
if ( lrc == 0 ) {
@ -193,7 +193,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
} else if ( lrc == -1 ) {
/* we do not retry in this case;
* only for unique operations... */
ldap_get_option( lsc->msc_ld,
ldap_get_option( msc->msc_ld,
LDAP_OPT_ERROR_NUMBER, &rs->sr_err );
rres = slap_map_api2result( rs );
rres = rc;
@ -207,7 +207,7 @@ meta_back_compare( Operation *op, SlapReply *rs )
goto finish;
}
rc = ldap_parse_result( lsc->msc_ld, res,
rc = ldap_parse_result( msc->msc_ld, res,
&rs->sr_err,
NULL, NULL, NULL, NULL, 1 );
if ( rc != LDAP_SUCCESS ) {
@ -224,8 +224,8 @@ meta_back_compare( Operation *op, SlapReply *rs )
* true or false, got it;
* sending to cache ...
*/
if ( li->mi_cache.ttl != META_DNCACHE_DISABLED ) {
( void )meta_dncache_update_entry( &li->mi_cache, &op->o_req_ndn, i );
if ( mi->mi_cache.ttl != META_DNCACHE_DISABLED ) {
( void )meta_dncache_update_entry( &mi->mi_cache, &op->o_req_ndn, i );
}
count++;
@ -238,13 +238,13 @@ meta_back_compare( Operation *op, SlapReply *rs )
if ( err != NULL ) {
free( err );
}
ldap_get_option( lsc->msc_ld,
ldap_get_option( msc->msc_ld,
LDAP_OPT_ERROR_STRING, &err );
if ( match != NULL ) {
free( match );
}
ldap_get_option( lsc->msc_ld,
ldap_get_option( msc->msc_ld,
LDAP_OPT_MATCHED_DN, &match );
last = i;

View file

@ -34,20 +34,21 @@
#include "../../../libraries/libldap/ldap-int.h"
#include "back-meta.h"
static struct metatarget *
static metatarget_t *
new_target( void )
{
struct metatarget *lt;
metatarget_t *mt;
struct ldapmapping *mapping;
lt = ch_calloc( sizeof( struct metatarget ), 1 );
if ( lt == NULL ) {
mt = ch_malloc( sizeof( metatarget_t ) );
if ( mt == NULL ) {
return NULL;
}
memset( mt, 0, sizeof( metatarget_t ) );
lt->mt_rwmap.rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
if ( lt->mt_rwmap.rwm_rw == NULL ) {
free( lt );
mt->mt_rwmap.rwm_rw = rewrite_info_init( REWRITE_MODE_USE_DEFAULT );
if ( mt->mt_rwmap.rwm_rw == NULL ) {
free( mt );
return NULL;
}
@ -62,19 +63,19 @@ new_target( void )
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "searchFilter";
rargv[ 2 ] = NULL;
rewrite_parse( lt->mt_rwmap.rwm_rw, "<suffix massage>",
rewrite_parse( mt->mt_rwmap.rwm_rw, "<suffix massage>",
1, 2, rargv );
rargv[ 0 ] = "rewriteContext";
rargv[ 1 ] = "default";
rargv[ 2 ] = NULL;
rewrite_parse( lt->mt_rwmap.rwm_rw, "<suffix massage>",
rewrite_parse( mt->mt_rwmap.rwm_rw, "<suffix massage>",
1, 2, rargv );
}
ldap_back_map_init( &lt->mt_rwmap.rwm_at, &mapping );
ldap_back_map_init( &mt->mt_rwmap.rwm_at, &mapping );
return lt;
return mt;
}
int
@ -86,9 +87,9 @@ meta_back_db_config(
char **argv
)
{
struct metainfo *li = ( struct metainfo * )be->be_private;
metainfo_t *mi = ( metainfo_t * )be->be_private;
if ( li == NULL ) {
if ( mi == NULL ) {
fprintf( stderr,
"%s: line %d: meta backend info is null!\n",
fname, lineno );
@ -97,7 +98,7 @@ meta_back_db_config(
/* URI of server to query */
if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) {
int i = li->mi_ntargets;
int i = mi->mi_ntargets;
#if 0
int j;
#endif /* uncomment if uri MUST be a branch of suffix */
@ -113,11 +114,11 @@ meta_back_db_config(
return 1;
}
++li->mi_ntargets;
++mi->mi_ntargets;
li->mi_targets = ch_realloc( li->mi_targets,
sizeof( struct metatarget *)*li->mi_ntargets );
if ( li->mi_targets == NULL ) {
mi->mi_targets = ( metatarget_t ** )ch_realloc( mi->mi_targets,
sizeof( metatarget_t * ) * mi->mi_ntargets );
if ( mi->mi_targets == NULL ) {
fprintf( stderr,
"%s: line %d: out of memory while storing server name"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@ -125,7 +126,7 @@ meta_back_db_config(
return 1;
}
if ( ( li->mi_targets[ i ] = new_target() ) == NULL ) {
if ( ( mi->mi_targets[ i ] = new_target() ) == NULL ) {
fprintf( stderr,
"%s: line %d: unable to init server"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@ -161,8 +162,8 @@ meta_back_db_config(
dn.bv_val = ludp->lud_dn;
dn.bv_len = strlen( ludp->lud_dn );
rc = dnPrettyNormal( NULL, &dn, &li->mi_targets[ i ]->mt_psuffix,
&li->mi_targets[ i ]->mt_nsuffix, NULL );
rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ]->mt_psuffix,
&mi->mi_targets[ i ]->mt_nsuffix, NULL );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: line %d: "
"target '%s' DN is invalid\n",
@ -188,9 +189,9 @@ meta_back_db_config(
}
}
li->mi_targets[ i ]->mt_uri = ldap_url_list2urls( ludp );
mi->mi_targets[ i ]->mt_uri = ldap_url_list2urls( ludp );
ldap_free_urllist( ludp );
if ( li->mi_targets[ i ]->mt_uri == NULL) {
if ( mi->mi_targets[ i ]->mt_uri == NULL) {
fprintf( stderr, "%s: line %d: no memory?\n",
fname, lineno );
return( 1 );
@ -200,7 +201,7 @@ meta_back_db_config(
* uri MUST be a branch of suffix!
*/
#if 0 /* too strict a constraint */
if ( select_backend( &li->mi_targets[ i ]->suffix, 0, 0 ) != be ) {
if ( select_backend( &mi->mi_targets[ i ]->suffix, 0, 0 ) != be ) {
fprintf( stderr,
"%s: line %d: <naming context> of URI does not refer to current backend"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@ -211,7 +212,7 @@ meta_back_db_config(
/*
* uri MUST be a branch of a suffix!
*/
if ( select_backend( &li->mi_targets[ i ]->mt_nsuffix, 0, 0 ) == NULL ) {
if ( select_backend( &mi->mi_targets[ i ]->mt_nsuffix, 0, 0 ) == NULL ) {
fprintf( stderr,
"%s: line %d: <naming context> of URI does not resolve to a backend"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@ -228,8 +229,8 @@ meta_back_db_config(
* or worked out, at least, in some manner
*/
for ( j = 0; j < i-1; j++ ) {
if ( dn_match( &li->mi_targets[ i ]->suffix,
&li->mi_targets[ j ]->suffix ) ) {
if ( dn_match( &mi->mi_targets[ i ]->suffix,
&mi->mi_targets[ j ]->suffix ) ) {
fprintf( stderr,
"%s: line %d: naming context \"%s\" already used"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
@ -241,13 +242,13 @@ meta_back_db_config(
#if 0
fprintf(stderr, "%s: line %d: URI \"%s\", suffix \"%s\"\n",
fname, lineno, li->mi_targets[ i ]->uri,
li->mi_targets[ i ]->psuffix.bv_val );
fname, lineno, mi->mi_targets[ i ]->uri,
mi->mi_targets[ i ]->psuffix.bv_val );
#endif
/* default target directive */
} else if ( strcasecmp( argv[ 0 ], "default-target" ) == 0 ) {
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
if ( argc == 1 ) {
if ( i < 0 ) {
@ -257,7 +258,7 @@ meta_back_db_config(
fname, lineno );
return 1;
}
li->mi_defaulttarget = i;
mi->mi_defaulttarget = i;
} else {
if ( strcasecmp( argv[ 1 ], "none" ) == 0 ) {
if ( i >= 0 ) {
@ -266,7 +267,7 @@ meta_back_db_config(
" should go before uri definitions\n",
fname, lineno );
}
li->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
} else {
char *next;
@ -277,7 +278,7 @@ meta_back_db_config(
fname, lineno, n );
return 1;
}
li->mi_defaulttarget = n;
mi->mi_defaulttarget = n;
}
}
@ -291,11 +292,11 @@ meta_back_db_config(
}
if ( strcasecmp( argv[ 1 ], "forever" ) == 0 ) {
li->mi_cache.ttl = META_DNCACHE_FOREVER;
mi->mi_cache.ttl = META_DNCACHE_FOREVER;
} else if ( strcasecmp( argv[ 1 ], "disabled" ) == 0 ) {
li->mi_cache.ttl = META_DNCACHE_DISABLED;
mi->mi_cache.ttl = META_DNCACHE_DISABLED;
} else {
li->mi_cache.ttl = atol( argv[ 1 ] );
mi->mi_cache.ttl = atol( argv[ 1 ] );
}
/* network timeout when connecting to ldap servers */
@ -306,13 +307,13 @@ meta_back_db_config(
fname, lineno );
return 1;
}
li->mi_network_timeout = atol(argv[ 1 ]);
mi->mi_network_timeout = atol(argv[ 1 ]);
/* name to use for meta_back_group */
} else if ( strcasecmp( argv[ 0 ], "acl-authcDN" ) == 0
|| strcasecmp( argv[ 0 ], "binddn" ) == 0 )
{
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
struct berval dn;
if ( i < 0 ) {
@ -339,7 +340,7 @@ meta_back_db_config(
dn.bv_val = argv[ 1 ];
dn.bv_len = strlen( argv[ 1 ] );
if ( dnNormalize( 0, NULL, NULL, &dn, &li->mi_targets[ i ]->mt_binddn,
if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ]->mt_binddn,
NULL ) != LDAP_SUCCESS )
{
fprintf( stderr, "%s: line %d: "
@ -352,7 +353,7 @@ meta_back_db_config(
} else if ( strcasecmp( argv[ 0 ], "acl-passwd" ) == 0
|| strcasecmp( argv[ 0 ], "bindpw" ) == 0 )
{
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
if ( i < 0 ) {
fprintf( stderr,
@ -376,7 +377,7 @@ meta_back_db_config(
/* FIXME: some day we'll need to throw an error */
}
ber_str2bv( argv[ 1 ], 0L, 1, &li->mi_targets[ i ]->mt_bindpw );
ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ]->mt_bindpw );
/* save bind creds for referral rebinds? */
} else if ( strcasecmp( argv[0], "rebind-as-user" ) == 0 ) {
@ -387,7 +388,7 @@ meta_back_db_config(
return( 1 );
}
li->flags |= LDAP_BACK_F_SAVECRED;
mi->flags |= LDAP_BACK_F_SAVECRED;
} else if ( strcasecmp( argv[0], "chase-referrals" ) == 0 ) {
if ( argc != 1 ) {
@ -397,7 +398,7 @@ meta_back_db_config(
return( 1 );
}
li->flags |= LDAP_BACK_F_CHASE_REFERRALS;
mi->flags |= LDAP_BACK_F_CHASE_REFERRALS;
} else if ( strcasecmp( argv[0], "dont-chase-referrals" ) == 0 ) {
if ( argc != 1 ) {
@ -407,7 +408,7 @@ meta_back_db_config(
return( 1 );
}
li->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
mi->flags &= ~LDAP_BACK_F_CHASE_REFERRALS;
} else if ( strncasecmp( argv[0], "tls-", STRLENOF( "tls-" ) ) == 0 ) {
@ -419,7 +420,7 @@ meta_back_db_config(
fname, lineno );
return( 1 );
}
li->flags |= ( LDAP_BACK_F_USE_TLS | LDAP_BACK_F_TLS_CRITICAL );
mi->flags |= ( LDAP_BACK_F_USE_TLS | LDAP_BACK_F_TLS_CRITICAL );
/* try start tls */
} else if ( strcasecmp( argv[0], "tls-try-start" ) == 0 ) {
@ -429,8 +430,8 @@ meta_back_db_config(
fname, lineno );
return( 1 );
}
li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
li->flags |= LDAP_BACK_F_USE_TLS;
mi->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
mi->flags |= LDAP_BACK_F_USE_TLS;
/* propagate start tls */
} else if ( strcasecmp( argv[0], "tls-propagate" ) == 0 ) {
@ -440,7 +441,7 @@ meta_back_db_config(
fname, lineno );
return( 1 );
}
li->flags |= ( LDAP_BACK_F_PROPAGATE_TLS | LDAP_BACK_F_TLS_CRITICAL );
mi->flags |= ( LDAP_BACK_F_PROPAGATE_TLS | LDAP_BACK_F_TLS_CRITICAL );
/* try start tls */
} else if ( strcasecmp( argv[0], "tls-try-propagate" ) == 0 ) {
@ -450,13 +451,13 @@ meta_back_db_config(
fname, lineno );
return( 1 );
}
li->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
li->flags |= LDAP_BACK_F_PROPAGATE_TLS;
mi->flags &= ~LDAP_BACK_F_TLS_CRITICAL;
mi->flags |= LDAP_BACK_F_PROPAGATE_TLS;
}
/* name to use as pseudo-root dn */
} else if ( strcasecmp( argv[ 0 ], "pseudorootdn" ) == 0 ) {
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
struct berval dn;
if ( i < 0 ) {
@ -476,7 +477,7 @@ meta_back_db_config(
dn.bv_val = argv[ 1 ];
dn.bv_len = strlen( argv[ 1 ] );
if ( dnNormalize( 0, NULL, NULL, &dn,
&li->mi_targets[ i ]->mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
&mi->mi_targets[ i ]->mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
{
fprintf( stderr, "%s: line %d: "
"pseudoroot DN '%s' is invalid\n",
@ -486,7 +487,7 @@ meta_back_db_config(
/* password to use as pseudo-root */
} else if ( strcasecmp( argv[ 0 ], "pseudorootpw" ) == 0 ) {
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
if ( i < 0 ) {
fprintf( stderr,
@ -501,12 +502,12 @@ meta_back_db_config(
fname, lineno );
return 1;
}
ber_str2bv( argv[ 1 ], 0L, 1, &li->mi_targets[ i ]->mt_pseudorootpw );
ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ]->mt_pseudorootpw );
/* dn massaging */
} else if ( strcasecmp( argv[ 0 ], "suffixmassage" ) == 0 ) {
BackendDB *tmp_be;
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
struct berval dn, nvnc, pvnc, nrnc, prnc;
if ( i < 0 ) {
@ -586,12 +587,12 @@ meta_back_db_config(
* FIXME: no extra rewrite capabilities should be added
* to the database
*/
return suffix_massage_config( li->mi_targets[ i ]->mt_rwmap.rwm_rw,
return suffix_massage_config( mi->mi_targets[ i ]->mt_rwmap.rwm_rw,
&pvnc, &nvnc, &prnc, &nrnc );
/* rewrite stuff ... */
} else if ( strncasecmp( argv[ 0 ], "rewrite", 7 ) == 0 ) {
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
if ( i < 0 ) {
fprintf( stderr, "%s: line %d: \"rewrite\" "
@ -600,12 +601,12 @@ meta_back_db_config(
return 1;
}
return rewrite_parse( li->mi_targets[ i ]->mt_rwmap.rwm_rw,
return rewrite_parse( mi->mi_targets[ i ]->mt_rwmap.rwm_rw,
fname, lineno, argc, argv );
/* objectclass/attribute mapping */
} else if ( strcasecmp( argv[ 0 ], "map" ) == 0 ) {
int i = li->mi_ntargets - 1;
int i = mi->mi_ntargets - 1;
if ( i < 0 ) {
fprintf( stderr,
@ -614,8 +615,8 @@ meta_back_db_config(
return 1;
}
return ldap_back_map_config( &li->mi_targets[ i ]->mt_rwmap.rwm_oc,
&li->mi_targets[ i ]->mt_rwmap.rwm_at,
return ldap_back_map_config( &mi->mi_targets[ i ]->mt_rwmap.rwm_oc,
&mi->mi_targets[ i ]->mt_rwmap.rwm_at,
fname, lineno, argc, argv );
/* anything else */
} else {

View file

@ -49,8 +49,8 @@ meta_back_conn_cmp(
const void *c1,
const void *c2 )
{
struct metaconn *mc1 = ( struct metaconn * )c1;
struct metaconn *mc2 = ( struct metaconn * )c2;
metaconn_t *mc1 = ( metaconn_t * )c1;
metaconn_t *mc2 = ( metaconn_t * )c2;
return SLAP_PTRCMP( mc1->mc_conn, mc2->mc_conn );
}
@ -66,8 +66,8 @@ meta_back_conn_dup(
void *c1,
void *c2 )
{
struct metaconn *mc1 = ( struct metaconn * )c1;
struct metaconn *mc2 = ( struct metaconn * )c2;
metaconn_t *mc1 = ( metaconn_t * )c1;
metaconn_t *mc2 = ( metaconn_t * )c2;
return( ( mc1->mc_conn == mc2->mc_conn ) ? -1 : 0 );
}
@ -91,7 +91,7 @@ ravl_print( Avlnode *root, int depth )
printf( " " );
}
printf( "c(%d) %d\n", ( ( struct metaconn * )root->avl_data )->mc_conn->c_connid, root->avl_bf );
printf( "c(%d) %d\n", ( ( metaconn_t * )root->avl_data )->mc_conn->c_connid, root->avl_bf );
ravl_print( root->avl_left, depth + 1 );
}
@ -119,21 +119,22 @@ myprint( Avlnode *root )
*
* Allocates a connection structure, making room for all the referenced targets
*/
static struct metaconn *
metaconn_alloc( int ntargets )
static metaconn_t *
metaconn_alloc(
int ntargets )
{
struct metaconn *mc;
metaconn_t *mc;
assert( ntargets > 0 );
/* malloc once only; leave an extra one for one-past-end */
mc = ch_malloc( sizeof( struct metaconn )
+ sizeof( struct metasingleconn ) * ( ntargets + 1 ) );
mc = ( metaconn_t * )ch_malloc( sizeof( metaconn_t )
+ sizeof( metasingleconn_t ) * ( ntargets + 1 ) );
if ( mc == NULL ) {
return NULL;
}
mc->mc_conns = (struct metasingleconn *)&mc[ 1 ];
mc->mc_conns = ( metasingleconn_t * )&mc[ 1 ];
/* FIXME: needed by META_LAST() */
mc->mc_conns[ ntargets ].msc_candidate = META_LAST_CONN;
@ -157,7 +158,8 @@ metaconn_alloc( int ntargets )
* clears a metaconn
*/
void
meta_back_conn_free( struct metaconn *mc )
meta_back_conn_free(
metaconn_t *mc )
{
if ( mc == NULL ) {
return;
@ -173,15 +175,15 @@ meta_back_conn_free( struct metaconn *mc )
*
* Initializes one connection
*/
static int
int
meta_back_init_one_conn(
Operation *op,
SlapReply *rs,
struct metatarget *lt,
struct metasingleconn *msc,
ldap_back_send_t sendok )
Operation *op,
SlapReply *rs,
metatarget_t *mt,
metasingleconn_t *msc,
ldap_back_send_t sendok )
{
struct metainfo *mi = ( struct metainfo * )op->o_bd->be_private;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
int vers;
dncookie dc;
@ -196,7 +198,7 @@ meta_back_init_one_conn(
/*
* Attempts to initialize the connection to the target ds
*/
rs->sr_err = ldap_initialize( &msc->msc_ld, lt->mt_uri );
rs->sr_err = ldap_initialize( &msc->msc_ld, mt->mt_uri );
if ( rs->sr_err != LDAP_SUCCESS ) {
goto error_return;
}
@ -216,7 +218,7 @@ meta_back_init_one_conn(
#ifdef HAVE_TLS
/* start TLS ("start-tls"/"try-start-tls" statements) */
if ( ( LDAP_BACK_USE_TLS( mi ) || ( op->o_conn->c_is_tls && LDAP_BACK_PROPAGATE_TLS( mi ) ) )
&& !ldap_is_ldaps_url( lt->mt_uri ) )
&& !ldap_is_ldaps_url( mt->mt_uri ) )
{
#ifdef SLAP_STARTTLS_ASYNCHRONOUS
/*
@ -318,13 +320,13 @@ retry:;
/*
* Sets a cookie for the rewrite session
*/
( void )rewrite_session_init( lt->mt_rwmap.rwm_rw, op->o_conn );
( void )rewrite_session_init( mt->mt_rwmap.rwm_rw, op->o_conn );
/*
* If the connection DN is not null, an attempt to rewrite it is made
*/
if ( !BER_BVISEMPTY( &op->o_conn->c_dn ) ) {
dc.rwmap = &lt->mt_rwmap;
dc.rwmap = &mt->mt_rwmap;
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "bindDN";
@ -370,16 +372,16 @@ error_return:;
*/
int
meta_back_retry(
Operation *op,
SlapReply *rs,
struct metaconn *mc,
int candidate,
ldap_back_send_t sendok )
Operation *op,
SlapReply *rs,
metaconn_t *mc,
int candidate,
ldap_back_send_t sendok )
{
struct metainfo *mi = (struct metainfo *)op->o_bd->be_private;
struct metatarget *lt = mi->mi_targets[ candidate ];
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = mi->mi_targets[ candidate ];
int rc;
struct metasingleconn *msc = &mc->mc_conns[ candidate ];
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
ldap_pvt_thread_mutex_lock( &mc->mc_mutex );
@ -388,10 +390,11 @@ meta_back_retry(
msc->msc_bound = 0;
/* mc here must be the regular mc, reset and ready for init */
rc = meta_back_init_one_conn( op, rs, lt, msc, sendok );
rc = meta_back_init_one_conn( op, rs, mt, msc, sendok );
if ( rc == LDAP_SUCCESS ) {
rc = meta_back_single_dobind( op, msc, sendok, 0 );
rc = meta_back_single_dobind( op, rs, mc, candidate, sendok,
META_BIND_NRETRIES );
}
ldap_pvt_thread_mutex_unlock( &mc->mc_mutex );
@ -430,7 +433,7 @@ meta_back_get_candidate(
SlapReply *rs,
struct berval *ndn )
{
struct metainfo *mi = ( struct metainfo * )op->o_bd->be_private;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
int candidate;
/*
@ -507,7 +510,9 @@ meta_back_get_candidate(
}
static void
meta_back_candidate_keyfree( void *key, void *data )
meta_back_candidate_keyfree(
void *key,
void *data )
{
ber_memfree_x( data, NULL );
}
@ -515,7 +520,7 @@ meta_back_candidate_keyfree( void *key, void *data )
SlapReply *
meta_back_candidates_get( Operation *op )
{
struct metainfo *mi = ( struct metainfo * )op->o_bd->be_private;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
void *data = NULL;
if ( op->o_threadctx ) {
@ -573,15 +578,15 @@ meta_back_candidates_get( Operation *op )
* that exactly none (noSuchObject) or one (TRUE/FALSE/UNDEFINED) is
* returned.
*/
struct metaconn *
metaconn_t *
meta_back_getconn(
Operation *op,
SlapReply *rs,
int *candidate,
ldap_back_send_t sendok )
Operation *op,
SlapReply *rs,
int *candidate,
ldap_back_send_t sendok )
{
struct metainfo *mi = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *mc, mc_curr;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc, mc_curr;
int cached = META_TARGET_NONE,
i = META_TARGET_NONE,
err = LDAP_SUCCESS,
@ -598,7 +603,7 @@ meta_back_getconn(
/* Searches for a metaconn in the avl tree */
mc_curr.mc_conn = op->o_conn;
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
mc = (struct metaconn *)avl_find( mi->mi_conntree,
mc = (metaconn_t *)avl_find( mi->mi_conntree,
(caddr_t)&mc_curr, meta_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
@ -732,7 +737,7 @@ meta_back_getconn(
/* Retries searching for a metaconn in the avl tree */
mc_curr.mc_conn = op->o_conn;
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
mc = (struct metaconn *)avl_find( mi->mi_conntree,
mc = (metaconn_t *)avl_find( mi->mi_conntree,
(caddr_t)&mc_curr, meta_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
@ -746,7 +751,7 @@ meta_back_getconn(
/*
* Clear all other candidates
*/
( void )meta_clear_unused_candidates( op, mc, i );
( void )meta_clear_unused_candidates( op, i );
/*
* The target is activated; if needed, it is

View file

@ -34,24 +34,24 @@
int
meta_back_delete( Operation *op, SlapReply *rs )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *lc;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
int candidate = -1;
struct berval mdn = BER_BVNULL;
dncookie dc;
int msgid, do_retry = 1;
lc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !lc || !meta_back_dobind( lc, op, LDAP_BACK_SENDERR ) ) {
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
assert( lc->mc_conns[ candidate ].msc_ld != NULL );
assert( mc->mc_conns[ candidate ].msc_ld != NULL );
/*
* Rewrite the compare dn, if needed
*/
dc.rwmap = &li->mi_targets[ candidate ]->mt_rwmap;
dc.rwmap = &mi->mi_targets[ candidate ]->mt_rwmap;
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "deleteDN";
@ -62,11 +62,11 @@ meta_back_delete( Operation *op, SlapReply *rs )
}
retry:;
rs->sr_err = ldap_delete_ext_s( lc->mc_conns[ candidate ].msc_ld,
rs->sr_err = ldap_delete_ext_s( mc->mc_conns[ candidate ].msc_ld,
mdn.bv_val, op->o_ctrls, NULL );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, lc, candidate, LDAP_BACK_SENDERR ) ) {
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
}
}
@ -76,6 +76,6 @@ retry:;
BER_BVZERO( &mdn );
}
return meta_back_op_result( lc, op, rs, candidate );
return meta_back_op_result( mc, op, rs, candidate );
}

View file

@ -23,6 +23,7 @@
#include "portable.h"
#include <stdio.h>
#include <ac/string.h>
#include "slap.h"
#include "../back-ldap/back-ldap.h"
@ -32,12 +33,12 @@
* The dncache, at present, maps an entry to the target that holds it.
*/
struct metadncacheentry {
typedef struct metadncacheentry_t {
struct berval dn;
int target;
time_t lastupdated;
};
} metadncacheentry_t;
/*
* meta_dncache_cmp
@ -48,12 +49,11 @@ struct metadncacheentry {
*/
int
meta_dncache_cmp(
const void *c1,
const void *c2
)
const void *c1,
const void *c2 )
{
struct metadncacheentry *cc1 = ( struct metadncacheentry * )c1;
struct metadncacheentry *cc2 = ( struct metadncacheentry * )c2;
metadncacheentry_t *cc1 = ( metadncacheentry_t * )c1;
metadncacheentry_t *cc2 = ( metadncacheentry_t * )c2;
/*
* case sensitive, because the dn MUST be normalized
@ -69,12 +69,11 @@ meta_dncache_cmp(
*/
int
meta_dncache_dup(
void *c1,
void *c2
)
void *c1,
void *c2 )
{
struct metadncacheentry *cc1 = ( struct metadncacheentry * )c1;
struct metadncacheentry *cc2 = ( struct metadncacheentry * )c2;
metadncacheentry_t *cc1 = ( metadncacheentry_t * )c1;
metadncacheentry_t *cc2 = ( metadncacheentry_t * )c2;
/*
* case sensitive, because the dn MUST be normalized
@ -90,20 +89,20 @@ meta_dncache_dup(
*/
int
meta_dncache_get_target(
struct metadncache *cache,
struct berval *ndn
)
metadncache_t *cache,
struct berval *ndn )
{
struct metadncacheentry tmp_entry, *entry;
time_t curr_time;
int target = META_TARGET_NONE;
metadncacheentry_t tmp_entry,
*entry;
time_t curr_time;
int target = META_TARGET_NONE;
assert( cache );
assert( ndn );
tmp_entry.dn = *ndn;
ldap_pvt_thread_mutex_lock( &cache->mutex );
entry = ( struct metadncacheentry * )avl_find( cache->tree,
entry = ( metadncacheentry_t * )avl_find( cache->tree,
( caddr_t )&tmp_entry, meta_dncache_cmp );
if ( entry != NULL ) {
@ -141,14 +140,14 @@ meta_dncache_get_target(
*/
int
meta_dncache_update_entry(
struct metadncache *cache,
struct berval *ndn,
int target
)
metadncache_t *cache,
struct berval *ndn,
int target )
{
struct metadncacheentry *entry, tmp_entry;
time_t curr_time = 0L;
int err = 0;
metadncacheentry_t *entry,
tmp_entry;
time_t curr_time = 0L;
int err = 0;
assert( cache );
assert( ndn );
@ -169,24 +168,22 @@ meta_dncache_update_entry(
tmp_entry.dn = *ndn;
ldap_pvt_thread_mutex_lock( &cache->mutex );
entry = ( struct metadncacheentry * )avl_find( cache->tree,
entry = ( metadncacheentry_t * )avl_find( cache->tree,
( caddr_t )&tmp_entry, meta_dncache_cmp );
if ( entry != NULL ) {
entry->target = target;
entry->lastupdated = curr_time;
} else {
entry = ch_calloc( sizeof( struct metadncacheentry ), 1 );
entry = ch_malloc( sizeof( metadncacheentry_t ) + ndn->bv_len + 1 );
if ( entry == NULL ) {
ldap_pvt_thread_mutex_unlock( &cache->mutex );
return -1;
}
ber_dupbv( &entry->dn, ndn );
if ( entry->dn.bv_val == NULL ) {
ldap_pvt_thread_mutex_unlock( &cache->mutex );
return -1;
}
entry->dn.bv_val = (char *)&entry[ 1 ];
AC_MEMCPY( entry->dn.bv_val, ndn->bv_val, ndn->bv_len + 1 );
entry->target = target;
entry->lastupdated = curr_time;
@ -206,11 +203,11 @@ meta_dncache_update_entry(
*/
int
meta_dncache_delete_entry(
struct metadncache *cache,
struct berval *ndn
)
metadncache_t *cache,
struct berval *ndn )
{
struct metadncacheentry *entry, tmp_entry;
metadncacheentry_t *entry,
tmp_entry;
assert( cache );
assert( ndn );
@ -237,11 +234,8 @@ meta_dncache_delete_entry(
*/
void
meta_dncache_free(
void *e
)
void *e )
{
struct metadncacheentry *entry = ( struct metadncacheentry * )e;
free( entry->dn.bv_val );
free( e );
}

View file

@ -28,8 +28,7 @@
int
meta_back_open(
BackendInfo *bi
)
BackendInfo *bi )
{
bi->bi_controls = slap_known_controls;
return 0;
@ -37,8 +36,7 @@ meta_back_open(
int
meta_back_initialize(
BackendInfo *bi
)
BackendInfo *bi )
{
bi->bi_open = meta_back_open;
bi->bi_config = 0;
@ -73,58 +71,58 @@ meta_back_initialize(
int
meta_back_db_init(
Backend *be
)
Backend *be )
{
struct metainfo *li;
metainfo_t *mi;
li = ch_calloc( 1, sizeof( struct metainfo ) );
if ( li == NULL ) {
mi = ch_malloc( sizeof( metainfo_t ) );
if ( mi == NULL ) {
return -1;
}
memset( mi, 0, sizeof( metainfo_t ) );
/*
* At present the default is no default target;
* this may change
*/
li->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
ldap_pvt_thread_mutex_init( &li->mi_conn_mutex );
ldap_pvt_thread_mutex_init( &li->mi_cache.mutex );
be->be_private = li;
ldap_pvt_thread_mutex_init( &mi->mi_conn_mutex );
ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex );
be->be_private = mi;
return 0;
}
static void
conn_free(
void *v_lc
)
void *v_mc )
{
struct metaconn *lc = v_lc;
struct metasingleconn *lsc;
metaconn_t *mc = v_mc;
metasingleconn_t *msc;
assert( lc->mc_conns != NULL );
assert( mc->mc_conns != NULL );
for ( lsc = &lc->mc_conns[ 0 ]; !META_LAST( lsc ); lsc++ ) {
if ( lsc->msc_ld != NULL ) {
ldap_unbind_ext_s( lsc->msc_ld, NULL, NULL );
for ( msc = &mc->mc_conns[ 0 ]; !META_LAST( msc ); msc++ ) {
if ( msc->msc_ld != NULL ) {
ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
}
if ( !BER_BVISNULL( &lsc->msc_bound_ndn ) ) {
ber_memfree( lsc->msc_bound_ndn.bv_val );
if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
ber_memfree( msc->msc_bound_ndn.bv_val );
}
if ( !BER_BVISNULL( &lsc->msc_cred ) ) {
if ( !BER_BVISNULL( &msc->msc_cred ) ) {
/* destroy sensitive data */
memset( lsc->msc_cred.bv_val, 0, lsc->msc_cred.bv_len );
ber_memfree( lsc->msc_cred.bv_val );
memset( msc->msc_cred.bv_val, 0, msc->msc_cred.bv_len );
ber_memfree( msc->msc_cred.bv_val );
}
}
free( lc );
free( mc );
}
static void
mapping_free( void *v_mapping )
mapping_free(
void *v_mapping )
{
struct ldapmapping *mapping = v_mapping;
ch_free( mapping->src.bv_val );
@ -134,84 +132,82 @@ mapping_free( void *v_mapping )
static void
target_free(
struct metatarget *lt
)
metatarget_t *mt )
{
if ( lt->mt_uri ) {
free( lt->mt_uri );
if ( mt->mt_uri ) {
free( mt->mt_uri );
}
if ( !BER_BVISNULL( &lt->mt_psuffix ) ) {
free( lt->mt_psuffix.bv_val );
if ( !BER_BVISNULL( &mt->mt_psuffix ) ) {
free( mt->mt_psuffix.bv_val );
}
if ( !BER_BVISNULL( &lt->mt_nsuffix ) ) {
free( lt->mt_nsuffix.bv_val );
if ( !BER_BVISNULL( &mt->mt_nsuffix ) ) {
free( mt->mt_nsuffix.bv_val );
}
if ( !BER_BVISNULL( &lt->mt_binddn ) ) {
free( lt->mt_binddn.bv_val );
if ( !BER_BVISNULL( &mt->mt_binddn ) ) {
free( mt->mt_binddn.bv_val );
}
if ( !BER_BVISNULL( &lt->mt_bindpw ) ) {
free( lt->mt_bindpw.bv_val );
if ( !BER_BVISNULL( &mt->mt_bindpw ) ) {
free( mt->mt_bindpw.bv_val );
}
if ( !BER_BVISNULL( &lt->mt_pseudorootdn ) ) {
free( lt->mt_pseudorootdn.bv_val );
if ( !BER_BVISNULL( &mt->mt_pseudorootdn ) ) {
free( mt->mt_pseudorootdn.bv_val );
}
if ( !BER_BVISNULL( &lt->mt_pseudorootpw ) ) {
free( lt->mt_pseudorootpw.bv_val );
if ( !BER_BVISNULL( &mt->mt_pseudorootpw ) ) {
free( mt->mt_pseudorootpw.bv_val );
}
if ( lt->mt_rwmap.rwm_rw ) {
rewrite_info_delete( &lt->mt_rwmap.rwm_rw );
if ( mt->mt_rwmap.rwm_rw ) {
rewrite_info_delete( &mt->mt_rwmap.rwm_rw );
}
avl_free( lt->mt_rwmap.rwm_oc.remap, NULL );
avl_free( lt->mt_rwmap.rwm_oc.map, mapping_free );
avl_free( lt->mt_rwmap.rwm_at.remap, NULL );
avl_free( lt->mt_rwmap.rwm_at.map, mapping_free );
avl_free( mt->mt_rwmap.rwm_oc.remap, NULL );
avl_free( mt->mt_rwmap.rwm_oc.map, mapping_free );
avl_free( mt->mt_rwmap.rwm_at.remap, NULL );
avl_free( mt->mt_rwmap.rwm_at.map, mapping_free );
}
int
meta_back_db_destroy(
Backend *be
)
Backend *be )
{
struct metainfo *li;
metainfo_t *mi;
if ( be->be_private ) {
int i;
li = ( struct metainfo * )be->be_private;
mi = ( metainfo_t * )be->be_private;
/*
* Destroy the connection tree
*/
ldap_pvt_thread_mutex_lock( &li->mi_conn_mutex );
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
if ( li->mi_conntree ) {
avl_free( li->mi_conntree, conn_free );
if ( mi->mi_conntree ) {
avl_free( mi->mi_conntree, conn_free );
}
/*
* Destroy the per-target stuff (assuming there's at
* least one ...)
*/
for ( i = 0; i < li->mi_ntargets; i++ ) {
target_free( li->mi_targets[ i ] );
free( li->mi_targets[ i ] );
for ( i = 0; i < mi->mi_ntargets; i++ ) {
target_free( mi->mi_targets[ i ] );
free( mi->mi_targets[ i ] );
}
free( li->mi_targets );
free( mi->mi_targets );
ldap_pvt_thread_mutex_lock( &li->mi_cache.mutex );
if ( li->mi_cache.tree ) {
avl_free( li->mi_cache.tree, meta_dncache_free );
ldap_pvt_thread_mutex_lock( &mi->mi_cache.mutex );
if ( mi->mi_cache.tree ) {
avl_free( mi->mi_cache.tree, meta_dncache_free );
}
ldap_pvt_thread_mutex_unlock( &li->mi_cache.mutex );
ldap_pvt_thread_mutex_destroy( &li->mi_cache.mutex );
ldap_pvt_thread_mutex_unlock( &mi->mi_cache.mutex );
ldap_pvt_thread_mutex_destroy( &mi->mi_cache.mutex );
ldap_pvt_thread_mutex_unlock( &li->mi_conn_mutex );
ldap_pvt_thread_mutex_destroy( &li->mi_conn_mutex );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
ldap_pvt_thread_mutex_destroy( &mi->mi_conn_mutex );
if ( li->mi_candidates != NULL ) {
ber_memfree_x( li->mi_candidates, NULL );
if ( mi->mi_candidates != NULL ) {
ber_memfree_x( mi->mi_candidates, NULL );
}
}

View file

@ -34,8 +34,8 @@
int
meta_back_modify( Operation *op, SlapReply *rs )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *lc;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
int rc = 0;
LDAPMod **modv = NULL;
LDAPMod *mods = NULL;
@ -45,19 +45,19 @@ meta_back_modify( Operation *op, SlapReply *rs )
struct berval mdn = BER_BVNULL;
struct berval mapped;
dncookie dc;
int msgid, do_retry = 1;
int do_retry = 1;
lc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !lc || !meta_back_dobind( lc, op, LDAP_BACK_SENDERR ) ) {
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
assert( lc->mc_conns[ candidate ].msc_ld != NULL );
assert( mc->mc_conns[ candidate ].msc_ld != NULL );
/*
* Rewrite the modify dn, if needed
*/
dc.rwmap = &li->mi_targets[ candidate ]->mt_rwmap;
dc.rwmap = &mi->mi_targets[ candidate ]->mt_rwmap;
dc.conn = op->o_conn;
dc.rs = rs;
dc.ctx = "modifyDN";
@ -99,7 +99,7 @@ meta_back_modify( Operation *op, SlapReply *rs )
mapped = ml->sml_desc->ad_cname;
} else {
ldap_back_map( &li->mi_targets[ candidate ]->mt_rwmap.rwm_at,
ldap_back_map( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_at,
&ml->sml_desc->ad_cname, &mapped,
BACKLDAP_MAP );
if ( BER_BVISNULL( &mapped ) || BER_BVISEMPTY( &mapped ) ) {
@ -126,11 +126,11 @@ meta_back_modify( Operation *op, SlapReply *rs )
for ( j = 0; !BER_BVISNULL( &ml->sml_values[ j ] ); ) {
struct ldapmapping *mapping;
ldap_back_mapping( &li->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
ldap_back_mapping( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc,
&ml->sml_values[ j ], &mapping, BACKLDAP_MAP );
if ( mapping == NULL ) {
if ( li->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
if ( mi->mi_targets[ candidate ]->mt_rwmap.rwm_oc.drop_missing ) {
continue;
}
mods[ i ].mod_bvalues[ j ] = &ml->sml_values[ j ];
@ -172,11 +172,11 @@ meta_back_modify( Operation *op, SlapReply *rs )
modv[ i ] = 0;
retry:;
rs->sr_err = ldap_modify_ext_s( lc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
rs->sr_err = ldap_modify_ext_s( mc->mc_conns[ candidate ].msc_ld, mdn.bv_val,
modv, op->o_ctrls, NULL );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, lc, candidate, LDAP_BACK_SENDERR ) ) {
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
}
}
@ -195,7 +195,7 @@ cleanup:;
free( modv );
if ( rc != -1 ) {
return meta_back_op_result( lc, op, rs, candidate );
return meta_back_op_result( mc, op, rs, candidate );
}
send_ldap_result( op, rs );

View file

@ -34,26 +34,20 @@
int
meta_back_modrdn( Operation *op, SlapReply *rs )
{
struct metainfo *li = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *lc;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
int candidate = -1;
struct berval mdn = BER_BVNULL,
mnewSuperior = BER_BVNULL;
dncookie dc;
int msgid, do_retry = 1;
lc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !lc ) {
mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR );
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
assert( candidate != META_TARGET_NONE );
if ( !meta_back_dobind( lc, op, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
assert( lc->mc_conns[ candidate ].msc_ld != NULL );
assert( mc->mc_conns[ candidate ].msc_ld != NULL );
dc.conn = op->o_conn;
dc.rs = rs;
@ -82,13 +76,13 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
/* newSuperior needs LDAPv3; if we got here, we can safely
* enforce it */
ldap_set_option( lc->mc_conns[ candidate ].msc_ld,
ldap_set_option( mc->mc_conns[ candidate ].msc_ld,
LDAP_OPT_PROTOCOL_VERSION, &version );
/*
* Rewrite the new superior, if defined and required
*/
dc.rwmap = &li->mi_targets[ candidate ]->mt_rwmap;
dc.rwmap = &mi->mi_targets[ candidate ]->mt_rwmap;
dc.ctx = "newSuperiorDN";
if ( ldap_back_dn_massage( &dc, op->orr_newSup, &mnewSuperior ) ) {
rs->sr_err = LDAP_OTHER;
@ -99,7 +93,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
/*
* Rewrite the modrdn dn, if required
*/
dc.rwmap = &li->mi_targets[ candidate ]->mt_rwmap;
dc.rwmap = &mi->mi_targets[ candidate ]->mt_rwmap;
dc.ctx = "modrDN";
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
rs->sr_err = LDAP_OTHER;
@ -107,13 +101,13 @@ meta_back_modrdn( Operation *op, SlapReply *rs )
}
retry:;
rs->sr_err = ldap_rename_s( lc->mc_conns[ candidate ].msc_ld,
rs->sr_err = ldap_rename_s( mc->mc_conns[ candidate ].msc_ld,
mdn.bv_val, op->orr_newrdn.bv_val,
mnewSuperior.bv_val, op->orr_deleteoldrdn,
op->o_ctrls, NULL );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, lc, candidate, LDAP_BACK_SENDERR ) ) {
if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) {
goto retry;
}
}
@ -132,7 +126,7 @@ cleanup:;
}
if ( rs->sr_err == LDAP_SUCCESS ) {
meta_back_op_result( lc, op, rs, candidate );
meta_back_op_result( mc, op, rs, candidate );
}
send_ldap_result( op, rs );

View file

@ -39,7 +39,7 @@ static int
meta_send_entry(
Operation *op,
SlapReply *rs,
struct metaconn *lc,
metaconn_t *mc,
int i,
LDAPMessage *e );
@ -48,12 +48,12 @@ meta_back_search_start(
Operation *op,
SlapReply *rs,
dncookie *dc,
struct metasingleconn *msc,
metasingleconn_t *msc,
int candidate,
int *msgidp
SlapReply *candidates
)
{
struct metainfo *mi = ( struct metainfo * )op->o_bd->be_private;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
struct berval realbase = op->o_req_dn;
int realscope = op->ors_scope;
ber_len_t suffixlen = 0;
@ -176,8 +176,7 @@ meta_back_search_start(
* Maps required attributes
*/
rc = ldap_back_map_attrs( &mi->mi_targets[ candidate ]->mt_rwmap.rwm_at,
op->ors_attrs, BACKLDAP_MAP,
&mapped_attrs );
op->ors_attrs, BACKLDAP_MAP, &mapped_attrs );
if ( rc != LDAP_SUCCESS ) {
/*
* this target is no longer candidate
@ -192,28 +191,25 @@ meta_back_search_start(
rc = ldap_search_ext( msc->msc_ld,
mbase.bv_val, realscope, mfilter.bv_val,
mapped_attrs, op->ors_attrsonly,
op->o_ctrls, NULL,
NULL, op->ors_slimit, msgidp );
op->o_ctrls, NULL, NULL, op->ors_slimit,
&candidates[ candidate ].sr_msgid );
if ( rc == LDAP_SUCCESS ) {
rc = 1;
} else {
*msgidp = -1;
candidates[ candidate ].sr_msgid = -1;
rc = 0;
}
done:;
if ( mapped_attrs ) {
free( mapped_attrs );
mapped_attrs = NULL;
}
if ( mfilter.bv_val != op->ors_filterstr.bv_val ) {
free( mfilter.bv_val );
BER_BVZERO( &mfilter );
}
if ( mbase.bv_val != realbase.bv_val ) {
free( mbase.bv_val );
BER_BVZERO( &mbase );
}
return rc;
@ -222,24 +218,19 @@ done:;
int
meta_back_search( Operation *op, SlapReply *rs )
{
struct metainfo *mi = ( struct metainfo * )op->o_bd->be_private;
struct metaconn *lc;
struct metasingleconn *msc;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metaconn_t *mc;
metasingleconn_t *msc;
struct timeval tv = { 0, 0 };
LDAPMessage *res = NULL, *e;
int rc = 0, sres = LDAP_SUCCESS;
char *err = NULL;
struct berval match = BER_BVNULL, mmatch = BER_BVNULL;
BerVarray v2refs = NULL;
BerVarray refs = NULL, v2refs = NULL;
char *matched = NULL;
int i, last = 0, ncandidates = 0,
initial_candidates = 0, candidate_match = 0;
dncookie dc;
int is_ok = 0;
void *savepriv;
SlapReply *candidates = meta_back_candidates_get( op );
/*
@ -248,8 +239,8 @@ meta_back_search( Operation *op, SlapReply *rs )
* FIXME: in case of values return filter, we might want
* to map attrs and maybe rewrite value
*/
lc = meta_back_getconn( op, rs, NULL, LDAP_BACK_SENDERR );
if ( !lc || !meta_back_dobind( lc, op, LDAP_BACK_SENDERR ) ) {
mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_SENDERR );
if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) {
return rs->sr_err;
}
@ -259,14 +250,19 @@ meta_back_search( Operation *op, SlapReply *rs )
/*
* Inits searches
*/
for ( i = 0, msc = &lc->mc_conns[ 0 ]; !META_LAST( msc ); ++i, ++msc ) {
for ( i = 0, msc = &mc->mc_conns[ 0 ]; !META_LAST( msc ); ++i, ++msc ) {
candidates[ i ].sr_msgid = -1;
if ( candidates[ i ].sr_tag != META_CANDIDATE ) {
continue;
}
candidates[ i ].sr_err = LDAP_SUCCESS;
candidates[ i ].sr_matched = NULL;
candidates[ i ].sr_text = NULL;
candidates[ i ].sr_ref = NULL;
candidates[ i ].sr_ctrls = NULL;
switch ( meta_back_search_start( op, rs, &dc, msc, i, &candidates[ i ].sr_msgid ) )
switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) )
{
case 0:
break;
@ -322,9 +318,9 @@ meta_back_search( Operation *op, SlapReply *rs )
* among the candidates
*/
for ( rc = 0; ncandidates > 0; ) {
int gotit = 0;
int gotit = 0, doabandon = 0;
for ( i = 0, msc = &lc->mc_conns[ 0 ]; !META_LAST( msc ); msc++, i++ ) {
for ( i = 0, msc = &mc->mc_conns[ 0 ]; !META_LAST( msc ); msc++, i++ ) {
if ( candidates[ i ].sr_msgid == -1 ) {
continue;
}
@ -334,8 +330,7 @@ meta_back_search( Operation *op, SlapReply *rs )
break;
}
if ( op->ors_slimit > 0
&& rs->sr_nentries == op->ors_slimit )
if ( op->ors_slimit > 0 && rs->sr_nentries == op->ors_slimit )
{
rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
rs->sr_v2ref = v2refs;
@ -367,13 +362,14 @@ meta_back_search( Operation *op, SlapReply *rs )
} else if ( rc == -1 ) {
really_bad:;
/* something REALLY bad happened! */
( void )meta_clear_unused_candidates( op, lc, -1 );
( void )meta_clear_unused_candidates( op, -1 );
rs->sr_err = LDAP_OTHER;
rs->sr_v2ref = v2refs;
savepriv = op->o_private;
op->o_private = (void *)i;
send_ldap_result( op, rs );
op->o_private = savepriv;
rs->sr_v2ref = NULL;
/* anything else needs be done? */
@ -388,7 +384,7 @@ really_bad:;
e = ldap_first_entry( msc->msc_ld, res );
savepriv = op->o_private;
op->o_private = (void *)i;
meta_send_entry( op, rs, lc, i, e );
meta_send_entry( op, rs, mc, i, e );
op->o_private = savepriv;
ldap_msgfree( res );
@ -404,6 +400,7 @@ really_bad:;
if ( op->ors_scope == LDAP_SCOPE_BASE
&& rs->sr_nentries > 0 )
{
doabandon = 1;
ncandidates = 0;
sres = LDAP_SUCCESS;
break;
@ -435,6 +432,9 @@ really_bad:;
dc.tofrom = 0;
dc.normalized = 0;
#endif /* ! ENABLE_REWRITE */
/* FIXME: merge all and return at the end */
for ( cnt = 0; references[ cnt ]; cnt++ )
;
@ -469,17 +469,96 @@ really_bad:;
}
} else if ( rc == LDAP_RES_SEARCH_RESULT ) {
char buf[ SLAP_TEXT_BUFLEN ];
char buf[ SLAP_TEXT_BUFLEN ];
char **references = NULL;
if ( ldap_parse_result( msc->msc_ld, res,
&rs->sr_err,
NULL, NULL, NULL, NULL, 1 ) )
if ( ldap_parse_result( msc->msc_ld,
res,
&candidates[ i ].sr_err,
(char **)&candidates[ i ].sr_matched,
NULL /* (char **)&candidates[ i ].sr_text */ ,
&references,
&candidates[ i ].sr_ctrls, 1 ) )
{
res = NULL;
ldap_get_option( msc->msc_ld,
LDAP_OPT_ERROR_NUMBER,
&rs->sr_err );
sres = slap_map_api2result( rs );
goto really_bad;
}
rs->sr_err = candidates[ i ].sr_err;
sres = slap_map_api2result( rs );
res = NULL;
/* massage matchedDN if need be */
if ( candidates[ i ].sr_matched != NULL ) {
if ( candidates[ i ].sr_matched[ 0 ] == '\0' ) {
ldap_memfree( (char *)candidates[ i ].sr_matched );
candidates[ i ].sr_matched = NULL;
} else {
struct berval match, mmatch;
ber_str2bv( candidates[ i ].sr_matched,
0, 0, &match );
dc.ctx = "matchedDN";
dc.rwmap = &mi->mi_targets[ i ]->mt_rwmap;
if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
if ( mmatch.bv_val == match.bv_val ) {
candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val );
} else {
candidates[ i ].sr_matched = mmatch.bv_val;
}
candidate_match++;
}
ldap_memfree( match.bv_val );
}
}
/* just get rid of the error message, if any */
if ( candidates[ i ].sr_text && candidates[ i ].sr_text[ 0 ] == '\0' )
{
ldap_memfree( (char *)candidates[ i ].sr_text );
candidates[ i ].sr_text = NULL;
}
/* add references to array */
if ( references ) {
BerVarray sr_ref;
int cnt;
for ( cnt = 0; references[ cnt ]; cnt++ )
;
sr_ref = ch_calloc( sizeof( struct berval ), cnt + 1 );
for ( cnt = 0; references[ cnt ]; cnt++ ) {
ber_str2bv( references[ cnt ], 0, 1, &sr_ref[ cnt ] );
}
BER_BVZERO( &sr_ref[ cnt ] );
( void )ldap_back_referral_result_rewrite( &dc, sr_ref );
/* cleanup */
ldap_value_free( references );
if ( refs == NULL ) {
refs = sr_ref;
} else {
for ( cnt = 0; !BER_BVISNULL( &sr_ref[ cnt ] ); cnt++ ) {
ber_bvarray_add( &refs, &sr_ref[ cnt ] );
}
ber_memfree( sr_ref );
}
}
rs->sr_err = candidates[ i ].sr_err;
sres = slap_map_api2result( rs );
switch ( sres ) {
case LDAP_NO_SUCH_OBJECT:
@ -499,29 +578,14 @@ really_bad:;
break;
}
if ( err != NULL ) {
free( err );
}
ldap_get_option( msc->msc_ld,
LDAP_OPT_ERROR_STRING, &err );
if ( !BER_BVISNULL( &match ) ) {
free( match.bv_val );
BER_BVZERO( &match );
}
ldap_get_option( msc->msc_ld,
LDAP_OPT_MATCHED_DN, &match.bv_val );
if ( !BER_BVISNULL( &match ) ) {
match.bv_len = strlen( match.bv_val );
}
snprintf( buf, sizeof( buf ),
"%s meta_back_search[%d] "
"match=\"%s\" err=\"%s\"\n",
"match=\"%s\" err=%d\n",
op->o_log_prefix, i,
match.bv_val, err );
candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
candidates[ i ].sr_err );
Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
candidate_match++;
last = i;
rc = 0;
@ -539,13 +603,19 @@ really_bad:;
}
/* check for abandon */
if ( op->o_abandon ) {
for ( i = 0, msc = lc->mc_conns; !META_LAST( msc ); msc++, i++ ) {
ldap_abandon_ext( msc->msc_ld, candidates[ i ].sr_msgid, NULL, NULL );
if ( op->o_abandon || doabandon ) {
for ( i = 0, msc = mc->mc_conns; !META_LAST( msc ); msc++, i++ ) {
if ( candidates[ i ].sr_msgid != -1 ) {
ldap_abandon_ext( msc->msc_ld,
candidates[ i ].sr_msgid,
NULL, NULL );
}
}
rc = SLAPD_ABANDON;
goto finish;
if ( op->o_abandon ) {
rc = SLAPD_ABANDON;
goto finish;
}
}
if ( gotit == 0 ) {
@ -563,7 +633,7 @@ really_bad:;
/*
* FIXME: need a better strategy to handle errors
*/
rc = meta_back_op_result( lc, op, rs, META_TARGET_NONE );
rc = meta_back_op_result( mc, op, rs, META_TARGET_NONE );
goto finish;
}
@ -572,25 +642,19 @@ really_bad:;
*
* FIXME: only the last one gets caught!
*/
if ( candidate_match == initial_candidates
&& !BER_BVISNULL( &match ) && !BER_BVISEMPTY( &match ) )
{
dc.ctx = "matchedDN";
dc.rwmap = &mi->mi_targets[ last ]->mt_rwmap;
if ( ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
BER_BVZERO( &mmatch );
if ( candidate_match > 0 && rs->sr_nentries > 0 ) {
/* we use the first one */
for ( i = 0; i < mi->mi_ntargets; i++ ) {
if ( candidates[ i ].sr_tag == META_CANDIDATE
&& candidates[ i ].sr_matched )
{
matched = (char *)candidates[ i ].sr_matched;
candidates[ i ].sr_matched = NULL;
break;
}
}
}
/*
* In case we returned at least one entry, we return LDAP_SUCCESS
* otherwise, the latter error code we got
*
* FIXME: we should handle error codes and return the more
* important/reasonable
*/
#if 0
{
char buf[BUFSIZ];
@ -613,33 +677,64 @@ really_bad:;
}
#endif
if ( sres == LDAP_SUCCESS && v2refs ) {
/*
* In case we returned at least one entry, we return LDAP_SUCCESS
* otherwise, the latter error code we got
*
* FIXME: we should handle error codes and return the more
* important/reasonable
*/
if ( sres == LDAP_SUCCESS && ( v2refs || refs ) ) {
sres = LDAP_REFERRAL;
}
rs->sr_err = sres;
rs->sr_matched = mmatch.bv_val;
rs->sr_matched = matched;
rs->sr_v2ref = v2refs;
rs->sr_ref = refs;
savepriv = op->o_private;
op->o_private = (void *)mi->mi_ntargets;
send_ldap_result( op, rs );
op->o_private = savepriv;
rs->sr_matched = NULL;
rs->sr_v2ref = NULL;
rs->sr_ref = NULL;
finish:;
if ( !BER_BVISNULL( &match ) ) {
if ( !BER_BVISNULL( &mmatch ) && mmatch.bv_val != match.bv_val )
{
free( mmatch.bv_val );
if ( matched ) {
free( matched );
}
if ( refs ) {
ber_bvarray_free( refs );
}
for ( i = 0; i < mi->mi_ntargets; i++ ) {
if ( candidates[ i ].sr_tag != META_CANDIDATE ) {
continue;
}
if ( candidates[ i ].sr_matched ) {
free( (char *)candidates[ i ].sr_matched );
candidates[ i ].sr_matched = NULL;
}
if ( candidates[ i ].sr_text ) {
ldap_memfree( (char *)candidates[ i ].sr_text );
candidates[ i ].sr_text = NULL;
}
if ( candidates[ i ].sr_ref ) {
ber_bvarray_free( candidates[ i ].sr_ref );
candidates[ i ].sr_ref = NULL;
}
if ( candidates[ i ].sr_ctrls ) {
ldap_controls_free( candidates[ i ].sr_ctrls );
candidates[ i ].sr_ctrls = NULL;
}
free( match.bv_val );
}
if ( err ) {
free( err );
}
return rc;
}
@ -647,11 +742,11 @@ static int
meta_send_entry(
Operation *op,
SlapReply *rs,
struct metaconn *lc,
metaconn_t *mc,
int target,
LDAPMessage *e )
{
struct metainfo *mi = ( struct metainfo * )op->o_bd->be_private;
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
struct berval a, mapped;
Entry ent = { 0 };
BerElement ber = *e->lm_ber;
@ -802,7 +897,7 @@ meta_send_entry(
attr->a_desc->ad_type->sat_equality->smr_normalize ) {
int i;
attr->a_nvals = ch_malloc((last + 1)*sizeof(struct berval));
attr->a_nvals = ch_malloc( ( last + 1 ) * sizeof( struct berval ) );
for ( i = 0; i<last; i++ ) {
attr->a_desc->ad_type->sat_equality->smr_normalize(
SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,

View file

@ -34,44 +34,43 @@
int
meta_back_conn_destroy(
Backend *be,
Connection *conn
)
Backend *be,
Connection *conn )
{
struct metainfo *li = ( struct metainfo * )be->be_private;
struct metaconn *lc,
lc_curr = { 0 };
metainfo_t *mi = ( metainfo_t * )be->be_private;
metaconn_t *mc,
mc_curr = { 0 };
Debug( LDAP_DEBUG_TRACE,
"=>meta_back_conn_destroy: fetching conn %ld\n",
conn->c_connid, 0, 0 );
lc_curr.mc_conn = conn;
mc_curr.mc_conn = conn;
ldap_pvt_thread_mutex_lock( &li->mi_conn_mutex );
lc = avl_delete( &li->mi_conntree, ( caddr_t )&lc_curr,
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr,
meta_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &li->mi_conn_mutex );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
if ( lc ) {
if ( mc ) {
int i;
Debug( LDAP_DEBUG_TRACE,
"=>meta_back_conn_destroy: destroying conn %ld\n",
lc->mc_conn->c_connid, 0, 0 );
mc->mc_conn->c_connid, 0, 0 );
/*
* Cleanup rewrite session
*/
for ( i = 0; i < li->mi_ntargets; ++i ) {
if ( lc->mc_conns[ i ].msc_ld == NULL ) {
for ( i = 0; i < mi->mi_ntargets; ++i ) {
if ( mc->mc_conns[ i ].msc_ld == NULL ) {
continue;
}
rewrite_session_delete( li->mi_targets[ i ]->mt_rwmap.rwm_rw, conn );
meta_clear_one_candidate( &lc->mc_conns[ i ] );
rewrite_session_delete( mi->mi_targets[ i ]->mt_rwmap.rwm_rw, conn );
meta_clear_one_candidate( &mc->mc_conns[ i ] );
}
meta_back_conn_free( lc );
meta_back_conn_free( mc );
}
/* no response to unbind */