mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-01-10 08:53:27 -05:00
- add support for "use-temporary-conn" much like back-ldap
- fix various connection creation/setup concurrency issues - use shared connection when always idasserting (similar to ITS#4781) - reduce the impact of schema mapping when not used (tnx to gprof) - fix temporary/tainted connection leak in abnormal conditions
This commit is contained in:
parent
28793246e6
commit
4e11af075f
9 changed files with 337 additions and 120 deletions
|
|
@ -176,6 +176,13 @@ is set to
|
|||
.B single\-conn {NO|yes}
|
||||
Discards current cached connection when the client rebinds.
|
||||
|
||||
.TP
|
||||
.B use-temporary-conn {NO|yes}
|
||||
when set to
|
||||
.BR yes ,
|
||||
create a temporary connection whenever competing with other threads
|
||||
for a shared one; otherwise, wait until the shared connection is available.
|
||||
|
||||
.SH TARGET SPECIFICATION
|
||||
Target specification starts with a "uri" directive:
|
||||
|
||||
|
|
|
|||
|
|
@ -160,6 +160,35 @@ ldap_dnattr_result_rewrite(
|
|||
|
||||
/* (end of) from back-ldap.h before rwm removal */
|
||||
|
||||
/*
|
||||
* A metasingleconn_t can be in the following, mutually exclusive states:
|
||||
*
|
||||
* - none (0x0U)
|
||||
* - creating META_BACK_FCONN_CREATING
|
||||
* - initialized META_BACK_FCONN_INITED
|
||||
* - binding LDAP_BACK_FCONN_BINDING
|
||||
* - bound/anonymous LDAP_BACK_FCONN_ISBOUND/LDAP_BACK_FCONN_ISANON
|
||||
*
|
||||
* possible modifiers are:
|
||||
*
|
||||
* - privileged LDAP_BACK_FCONN_ISPRIV
|
||||
* - privileged, TLS LDAP_BACK_FCONN_ISTLS
|
||||
* - subjected to idassert LDAP_BACK_FCONN_ISIDASR
|
||||
* - tainted LDAP_BACK_FCONN_TAINTED
|
||||
*/
|
||||
|
||||
#define META_BACK_FCONN_INITED (0x00100000U)
|
||||
#define META_BACK_FCONN_CREATING (0x00200000U)
|
||||
|
||||
#define META_BACK_CONN_INITED(lc) LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_INITED)
|
||||
#define META_BACK_CONN_INITED_SET(lc) LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_INITED)
|
||||
#define META_BACK_CONN_INITED_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), META_BACK_FCONN_INITED)
|
||||
#define META_BACK_CONN_INITED_CPY(lc, mlc) LDAP_BACK_CONN_CPY((lc), META_BACK_FCONN_INITED, (mlc))
|
||||
#define META_BACK_CONN_CREATING(lc) LDAP_BACK_CONN_ISSET((lc), META_BACK_FCONN_CREATING)
|
||||
#define META_BACK_CONN_CREATING_SET(lc) LDAP_BACK_CONN_SET((lc), META_BACK_FCONN_CREATING)
|
||||
#define META_BACK_CONN_CREATING_CLEAR(lc) LDAP_BACK_CONN_CLEAR((lc), META_BACK_FCONN_CREATING)
|
||||
#define META_BACK_CONN_CREATING_CPY(lc, mlc) LDAP_BACK_CONN_CPY((lc), META_BACK_FCONN_CREATING, (mlc))
|
||||
|
||||
struct metainfo_t;
|
||||
|
||||
#define META_NOT_CANDIDATE ((ber_tag_t)0x0)
|
||||
|
|
@ -329,16 +358,18 @@ typedef struct metainfo_t {
|
|||
unsigned mi_flags;
|
||||
#define li_flags mi_flags
|
||||
/* uses flags as defined in <back-ldap/back-ldap.h> */
|
||||
#define META_BACK_F_ONERR_STOP (0x00010000U)
|
||||
#define META_BACK_F_ONERR_REPORT (0x00020000U)
|
||||
#define META_BACK_F_ONERR_STOP (0x00100000U)
|
||||
#define META_BACK_F_ONERR_REPORT (0x00200000U)
|
||||
#define META_BACK_F_ONERR_MASK (META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT)
|
||||
#define META_BACK_F_DEFER_ROOTDN_BIND (0x00040000U)
|
||||
#define META_BACK_F_DEFER_ROOTDN_BIND (0x00400000U)
|
||||
#define META_BACK_F_PROXYAUTHZ_ALWAYS (0x00800000U)
|
||||
|
||||
#define META_BACK_ONERR_STOP(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_STOP )
|
||||
#define META_BACK_ONERR_REPORT(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_REPORT )
|
||||
#define META_BACK_ONERR_CONTINUE(mi) ( !( (mi)->mi_flags & META_BACK_F_ONERR_MASK ) )
|
||||
|
||||
#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND )
|
||||
#define META_BACK_PROXYAUTHZ_ALWAYS(mi) ( (mi)->mi_flags & META_BACK_F_PROXYAUTHZ_ALWAYS )
|
||||
|
||||
int mi_version;
|
||||
time_t mi_network_timeout;
|
||||
|
|
@ -397,7 +428,8 @@ meta_back_init_one_conn(
|
|||
metaconn_t *mc,
|
||||
int candidate,
|
||||
int ispriv,
|
||||
ldap_back_send_t sendok );
|
||||
ldap_back_send_t sendok,
|
||||
int dolock );
|
||||
|
||||
extern void
|
||||
meta_back_quarantine(
|
||||
|
|
|
|||
|
|
@ -399,9 +399,7 @@ retry:;
|
|||
op->o_log_prefix, candidate, (void *)msc->msc_ld );
|
||||
#endif /* DEBUG_205 */
|
||||
|
||||
ldap_unbind_ext( msc->msc_ld, NULL, NULL );
|
||||
msc->msc_ld = NULL;
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
meta_clear_one_candidate( op, mc, candidate );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
|
||||
rs->sr_err = timeout_err;
|
||||
|
|
@ -683,7 +681,8 @@ retry_binding:;
|
|||
++bound;
|
||||
continue;
|
||||
|
||||
} else if ( LDAP_BACK_CONN_BINDING( msc ) ) {
|
||||
} else if ( META_BACK_CONN_CREATING( msc ) || LDAP_BACK_CONN_BINDING( msc ) )
|
||||
{
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
ldap_pvt_thread_yield();
|
||||
goto retry_binding;
|
||||
|
|
@ -710,7 +709,7 @@ retry_binding:;
|
|||
|
||||
|
||||
if ( rc == LDAP_UNAVAILABLE ) {
|
||||
/* FIXME: meta_back_retry() already calls
|
||||
/* FIXME: meta_back_retry() already re-calls
|
||||
* meta_back_single_dobind() */
|
||||
if ( meta_back_retry( op, rs, &mc, i, sendok ) ) {
|
||||
goto retry_ok;
|
||||
|
|
@ -720,6 +719,7 @@ retry_binding:;
|
|||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
meta_back_release_conn( op, mc );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -187,7 +187,7 @@ meta_clear_one_candidate(
|
|||
{
|
||||
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
|
||||
|
||||
if ( msc->msc_ld ) {
|
||||
if ( msc->msc_ld != NULL ) {
|
||||
|
||||
#ifdef DEBUG_205
|
||||
char buf[ BUFSIZ ];
|
||||
|
|
@ -213,6 +213,8 @@ meta_clear_one_candidate(
|
|||
BER_BVZERO( &msc->msc_cred );
|
||||
}
|
||||
|
||||
msc->msc_mscflags = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ static int
|
|||
meta_back_new_target(
|
||||
metatarget_t **mtp )
|
||||
{
|
||||
struct ldapmapping *mapping;
|
||||
char *rargv[ 3 ];
|
||||
metatarget_t *mt;
|
||||
|
||||
|
|
@ -52,7 +51,6 @@ meta_back_new_target(
|
|||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* the filter rewrite as a string must be disabled
|
||||
* by default; it can be re-enabled by adding rules;
|
||||
|
|
@ -68,8 +66,6 @@ meta_back_new_target(
|
|||
rargv[ 2 ] = NULL;
|
||||
rewrite_parse( mt->mt_rwmap.rwm_rw, "<suffix massage>", 1, 2, rargv );
|
||||
|
||||
ldap_back_map_init( &mt->mt_rwmap.rwm_at, &mapping );
|
||||
|
||||
ldap_pvt_thread_mutex_init( &mt->mt_uri_mutex );
|
||||
|
||||
mt->mt_idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
|
||||
|
|
@ -849,6 +845,38 @@ meta_back_db_config(
|
|||
return 1;
|
||||
}
|
||||
|
||||
/* use-temporaries? */
|
||||
} else if ( strcasecmp( argv[ 0 ], "use-temporary-conn" ) == 0 ) {
|
||||
if ( argc != 2 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"use-temporary-conn {FALSE|true}\" takes 1 argument\n",
|
||||
fname, lineno, 0 );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
if ( mi->mi_ntargets > 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"use-temporary-conn\" must appear before target definitions\n",
|
||||
fname, lineno, 0 );
|
||||
return( 1 );
|
||||
}
|
||||
|
||||
switch ( check_true_false( argv[ 1 ] ) ) {
|
||||
case 0:
|
||||
mi->mi_flags &= ~LDAP_BACK_F_USE_TEMPORARIES;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
mi->mi_flags |= LDAP_BACK_F_USE_TEMPORARIES;
|
||||
break;
|
||||
|
||||
default:
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"%s: line %d: \"use-temporary-conn {FALSE|true}\": invalid arg \"%s\".\n",
|
||||
fname, lineno, argv[ 1 ] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
} else if ( strcasecmp( argv[ 0 ], "cancel" ) == 0 ) {
|
||||
unsigned flag = 0;
|
||||
unsigned *flagsp = mi->mi_ntargets ?
|
||||
|
|
@ -1402,7 +1430,7 @@ ldap_back_map_config(
|
|||
if ( strcmp( argv[ 2 ], "*" ) == 0 ) {
|
||||
if ( argc < 4 || strcmp( argv[ 3 ], "*" ) == 0 ) {
|
||||
map->drop_missing = ( argc < 4 );
|
||||
return 0;
|
||||
goto success_return;
|
||||
}
|
||||
src = dst = argv[ 3 ];
|
||||
|
||||
|
|
@ -1416,7 +1444,7 @@ ldap_back_map_config(
|
|||
}
|
||||
|
||||
if ( ( map == at_map )
|
||||
&& ( strcasecmp( src, "objectclass" ) == 0
|
||||
&& ( strcasecmp( src, "objectclass" ) == 0
|
||||
|| strcasecmp( dst, "objectclass" ) == 0 ) )
|
||||
{
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
|
|
@ -1544,6 +1572,12 @@ ldap_back_map_config(
|
|||
avl_insert( &map->remap, (caddr_t)&mapping[ 1 ],
|
||||
mapping_cmp, mapping_dup );
|
||||
|
||||
success_return:;
|
||||
if ( !is_oc && map->map == NULL ) {
|
||||
/* only init if required */
|
||||
ldap_back_map_init( map, &mapping );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
error_return:;
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ metaconn_alloc(
|
|||
|
||||
/* malloc all in one */
|
||||
mc = ( metaconn_t * )ch_calloc( 1, sizeof( metaconn_t )
|
||||
+ sizeof( metasingleconn_t ) * ntargets );
|
||||
+ sizeof( metasingleconn_t ) * ( ntargets - 1 ) );
|
||||
if ( mc == NULL ) {
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -227,7 +227,8 @@ meta_back_init_one_conn(
|
|||
metaconn_t *mc,
|
||||
int candidate,
|
||||
int ispriv,
|
||||
ldap_back_send_t sendok )
|
||||
ldap_back_send_t sendok,
|
||||
int dolock )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
metatarget_t *mt = mi->mi_targets[ candidate ];
|
||||
|
|
@ -235,6 +236,7 @@ meta_back_init_one_conn(
|
|||
int version;
|
||||
dncookie dc;
|
||||
int isauthz = ( candidate == mc->mc_authz_target );
|
||||
int do_return = 0;
|
||||
#ifdef HAVE_TLS
|
||||
int is_ldaps = 0;
|
||||
#endif /* HAVE_TLS */
|
||||
|
|
@ -275,14 +277,62 @@ meta_back_init_one_conn(
|
|||
}
|
||||
}
|
||||
|
||||
retry_lock:;
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
||||
/*
|
||||
* Already init'ed
|
||||
*/
|
||||
if ( msc->msc_ld != NULL ) {
|
||||
return rs->sr_err = LDAP_SUCCESS;
|
||||
if ( LDAP_BACK_CONN_ISBOUND( msc )
|
||||
|| LDAP_BACK_CONN_ISANON( msc ) )
|
||||
{
|
||||
assert( msc->msc_ld != NULL );
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
do_return = 1;
|
||||
|
||||
} else if ( META_BACK_CONN_CREATING( msc )
|
||||
|| LDAP_BACK_CONN_BINDING( msc ) )
|
||||
{
|
||||
if ( !LDAP_BACK_USE_TEMPORARIES( mi ) ) {
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
||||
ldap_pvt_thread_yield();
|
||||
goto retry_lock;
|
||||
}
|
||||
|
||||
/* sounds more appropriate */
|
||||
rs->sr_err = LDAP_BUSY;
|
||||
do_return = 1;
|
||||
|
||||
} else if ( META_BACK_CONN_INITED( msc ) ) {
|
||||
assert( msc->msc_ld != NULL );
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
do_return = 1;
|
||||
|
||||
} else {
|
||||
/*
|
||||
* creating...
|
||||
*/
|
||||
META_BACK_CONN_CREATING_SET( msc );
|
||||
}
|
||||
|
||||
msc->msc_mscflags = 0;
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
||||
if ( do_return ) {
|
||||
if ( rs->sr_err != LDAP_SUCCESS && op->o_conn && ( sendok & LDAP_BACK_SENDERR ) ) {
|
||||
send_ldap_result( op, rs );
|
||||
}
|
||||
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
assert( msc->msc_ld == NULL );
|
||||
|
||||
/*
|
||||
* Attempts to initialize the connection to the target ds
|
||||
|
|
@ -430,8 +480,8 @@ retry:;
|
|||
op->o_log_prefix, candidate, (void *)msc->msc_ld );
|
||||
#endif /* DEBUG_205 */
|
||||
|
||||
ldap_unbind_ext( msc->msc_ld, NULL, NULL );
|
||||
msc->msc_ld = NULL;
|
||||
/* need to trash a failed Start TLS */
|
||||
meta_clear_one_candidate( op, mc, candidate );
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
|
|
@ -500,8 +550,8 @@ retry:;
|
|||
op->o_log_prefix, candidate, (void *)msc->msc_ld );
|
||||
#endif /* DEBUG_205 */
|
||||
|
||||
ldap_unbind_ext( msc->msc_ld, NULL, NULL );
|
||||
msc->msc_ld = NULL;
|
||||
/* need to trash a connection not fully established */
|
||||
meta_clear_one_candidate( op, mc, candidate );
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
|
|
@ -510,6 +560,8 @@ retry:;
|
|||
ber_dupbv( &msc->msc_bound_ndn, &op->o_conn->c_dn );
|
||||
}
|
||||
|
||||
assert( !BER_BVISNULL( &msc->msc_bound_ndn ) );
|
||||
|
||||
} else {
|
||||
ber_dupbv( &msc->msc_bound_ndn, (struct berval *)&slap_empty_bv );
|
||||
}
|
||||
|
|
@ -518,13 +570,22 @@ retry:;
|
|||
assert( !BER_BVISNULL( &msc->msc_bound_ndn ) );
|
||||
|
||||
error_return:;
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
META_BACK_CONN_CREATING_CLEAR( msc );
|
||||
if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
/*
|
||||
* Sets a cookie for the rewrite session
|
||||
*/
|
||||
( void )rewrite_session_init( mt->mt_rwmap.rwm_rw, op->o_conn );
|
||||
META_BACK_CONN_INITED_SET( msc );
|
||||
}
|
||||
if ( dolock ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
||||
} else {
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
rs->sr_err = slap_map_api2result( rs );
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
send_ldap_result( op, rs );
|
||||
|
|
@ -556,13 +617,18 @@ meta_back_retry(
|
|||
binding;
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
|
||||
assert( !META_BACK_CONN_CREATING( msc ) );
|
||||
binding = LDAP_BACK_CONN_BINDING( msc );
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
|
||||
assert( mc->mc_refcnt > 0 );
|
||||
if ( mc->mc_refcnt == 1 ) {
|
||||
if ( LogTest( LDAP_DEBUG_ANY ) ) {
|
||||
char buf[ SLAP_TEXT_BUFLEN ];
|
||||
|
||||
/* this lock is required; however,
|
||||
* it's invoked only when logging is on */
|
||||
ldap_pvt_thread_mutex_lock( &mt->mt_uri_mutex );
|
||||
snprintf( buf, sizeof( buf ),
|
||||
"retrying URI=\"%s\" DN=\"%s\"",
|
||||
|
|
@ -583,7 +649,7 @@ meta_back_retry(
|
|||
|
||||
/* mc here must be the regular mc, reset and ready for init */
|
||||
rc = meta_back_init_one_conn( op, rs, mc, candidate,
|
||||
LDAP_BACK_CONN_ISPRIV( mc ), sendok );
|
||||
LDAP_BACK_CONN_ISPRIV( mc ), sendok, 0 );
|
||||
|
||||
/* restore the "binding" flag, in case */
|
||||
if ( binding ) {
|
||||
|
|
@ -614,6 +680,9 @@ meta_back_retry(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* don't send twice */
|
||||
sendok &= ~LDAP_BACK_SENDERR;
|
||||
}
|
||||
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
|
|
@ -622,9 +691,13 @@ meta_back_retry(
|
|||
candidates[ candidate ].sr_err = rc;
|
||||
|
||||
if ( *mcp != NULL ) {
|
||||
if ( binding ) {
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
if ( mc->mc_refcnt == 1 ) {
|
||||
if ( binding ) {
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
}
|
||||
(void)meta_clear_one_candidate( op, mc, candidate );
|
||||
}
|
||||
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
/* only release if mandatory; otherwise
|
||||
* let the caller do what's best before
|
||||
|
|
@ -632,10 +705,21 @@ meta_back_retry(
|
|||
if ( META_BACK_ONERR_STOP( mi ) ) {
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
*mcp = NULL;
|
||||
|
||||
} else {
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree, ">>> meta_back_retry" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
/* FIXME: could be done better, reworking meta_back_release_conn_lock() */
|
||||
(void)avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
( caddr_t )mc, meta_back_conndnmc_cmp );
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree, "<<< meta_back_retry" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
}
|
||||
}
|
||||
|
||||
if ( sendok ) {
|
||||
if ( sendok & LDAP_BACK_SENDERR ) {
|
||||
rs->sr_err = rc;
|
||||
rs->sr_text = NULL;
|
||||
send_ldap_result( op, rs );
|
||||
|
|
@ -882,8 +966,8 @@ meta_back_getconn(
|
|||
SlapReply *candidates = meta_back_candidates_get( op );
|
||||
|
||||
/* Internal searches are privileged and shared. So is root. */
|
||||
/* FIXME: there seem to be concurrency issues */
|
||||
if ( op->o_do_not_cache || be_isroot( op ) ) {
|
||||
/* FIXME: there seems to be concurrency issues */
|
||||
if ( META_BACK_PROXYAUTHZ_ALWAYS( mi ) || op->o_do_not_cache || be_isroot( op ) ) {
|
||||
mc_curr.mc_local_ndn = op->o_bd->be_rootndn;
|
||||
LDAP_BACK_CONN_ISPRIV_SET( &mc_curr );
|
||||
mc_curr.mc_conn = LDAP_BACK_PCONN_SET( op );
|
||||
|
|
@ -908,33 +992,45 @@ retry_lock:;
|
|||
mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
|
||||
(caddr_t)&mc_curr, meta_back_conndn_cmp );
|
||||
if ( mc ) {
|
||||
if ( ( mi->mi_conn_ttl != 0 && op->o_time > mc->mc_create_time + mi->mi_conn_ttl )
|
||||
|| ( mi->mi_idle_timeout != 0 && op->o_time > mc->mc_time + mi->mi_idle_timeout ) )
|
||||
{
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree, ">>> meta_back_getconn" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
/* don't let anyone else use this expired connection */
|
||||
(void)avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
(caddr_t)mc, meta_back_conndnmc_cmp );
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree, "<<< meta_back_getconn" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "%s meta_back_getconn: mc=%p conn=%ld expired.\n",
|
||||
op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc ) );
|
||||
}
|
||||
/* catch taint errors */
|
||||
assert( !LDAP_BACK_CONN_TAINTED( mc ) );
|
||||
|
||||
/* Don't reuse connections while they're still binding
|
||||
* NOTE: only makes sense for binds */
|
||||
if ( LDAP_BACK_CONN_BINDING( mc ) ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
ldap_pvt_thread_yield();
|
||||
goto retry_lock;
|
||||
}
|
||||
if ( !LDAP_BACK_USE_TEMPORARIES( mi ) ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
|
||||
mc->mc_refcnt++;
|
||||
ldap_pvt_thread_yield();
|
||||
goto retry_lock;
|
||||
}
|
||||
|
||||
/* release conn, and create a temporary */
|
||||
mc = NULL;
|
||||
|
||||
} else {
|
||||
if ( ( mi->mi_conn_ttl != 0 && op->o_time > mc->mc_create_time + mi->mi_conn_ttl )
|
||||
|| ( mi->mi_idle_timeout != 0 && op->o_time > mc->mc_time + mi->mi_idle_timeout ) )
|
||||
{
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree,
|
||||
">>> meta_back_getconn(expired)" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
/* don't let anyone else use this expired connection */
|
||||
(void)avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
(caddr_t)mc, meta_back_conndnmc_cmp );
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree,
|
||||
"<<< meta_back_getconn(expired)" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "%s meta_back_getconn: mc=%p conn=%ld expired (tainted).\n",
|
||||
op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc ) );
|
||||
}
|
||||
|
||||
mc->mc_refcnt++;
|
||||
}
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
|
@ -1010,7 +1106,7 @@ retry_lock:;
|
|||
*/
|
||||
candidates[ i ].sr_err = meta_back_init_one_conn( op,
|
||||
rs, mc, i, LDAP_BACK_CONN_ISPRIV( &mc_curr ),
|
||||
sendok );
|
||||
LDAP_BACK_DONTSEND, !new_conn );
|
||||
if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
|
||||
META_CANDIDATE_SET( &candidates[ i ] );
|
||||
ncandidates++;
|
||||
|
|
@ -1131,13 +1227,24 @@ retry_lock2:;
|
|||
mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
|
||||
(caddr_t)&mc_curr, meta_back_conndn_cmp );
|
||||
if ( mc != NULL ) {
|
||||
/* catch taint errors */
|
||||
assert( !LDAP_BACK_CONN_TAINTED( mc ) );
|
||||
|
||||
/* Don't reuse connections while they're still binding */
|
||||
if ( LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
ldap_pvt_thread_yield();
|
||||
goto retry_lock2;
|
||||
if ( META_BACK_CONN_CREATING( &mc->mc_conns[ i ] )
|
||||
|| LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) )
|
||||
{
|
||||
if ( !LDAP_BACK_USE_TEMPORARIES( mi ) ) {
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
ldap_pvt_thread_yield();
|
||||
goto retry_lock2;
|
||||
}
|
||||
|
||||
mc = NULL;
|
||||
|
||||
} else {
|
||||
mc->mc_refcnt++;
|
||||
}
|
||||
mc->mc_refcnt++;
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
}
|
||||
|
|
@ -1172,7 +1279,7 @@ retry_lock2:;
|
|||
* sends the appropriate result.
|
||||
*/
|
||||
err = meta_back_init_one_conn( op, rs, mc, i,
|
||||
LDAP_BACK_CONN_ISPRIV( &mc_curr ), sendok );
|
||||
LDAP_BACK_CONN_ISPRIV( &mc_curr ), sendok, !new_conn );
|
||||
if ( err != LDAP_SUCCESS ) {
|
||||
/*
|
||||
* FIXME: in case one target cannot
|
||||
|
|
@ -1230,7 +1337,8 @@ retry_lock2:;
|
|||
* also init'd
|
||||
*/
|
||||
int lerr = meta_back_init_one_conn( op, rs, mc, i,
|
||||
LDAP_BACK_CONN_ISPRIV( &mc_curr ), LDAP_BACK_DONTSEND );
|
||||
LDAP_BACK_CONN_ISPRIV( &mc_curr ),
|
||||
LDAP_BACK_DONTSEND, !new_conn );
|
||||
if ( lerr == LDAP_SUCCESS ) {
|
||||
META_CANDIDATE_SET( &candidates[ i ] );
|
||||
candidates[ i ].sr_err = LDAP_SUCCESS;
|
||||
|
|
@ -1262,11 +1370,11 @@ retry_lock2:;
|
|||
err = lerr;
|
||||
|
||||
if ( lerr == LDAP_UNAVAILABLE && mt->mt_isquarantined != LDAP_BACK_FQ_NO ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "%s: meta_back_getconn[%d] quarantined: %d\n",
|
||||
Debug( LDAP_DEBUG_TRACE, "%s: meta_back_getconn[%d] quarantined err=%d\n",
|
||||
op->o_log_prefix, i, lerr );
|
||||
|
||||
} else {
|
||||
Debug( LDAP_DEBUG_ANY, "%s: meta_back_getconn[%d] failed: %d\n",
|
||||
Debug( LDAP_DEBUG_ANY, "%s: meta_back_getconn[%d] failed err=%d\n",
|
||||
op->o_log_prefix, i, lerr );
|
||||
}
|
||||
|
||||
|
|
@ -1362,10 +1470,14 @@ done:;
|
|||
|
||||
case -1:
|
||||
/* duplicate: free and try to get the newly created one */
|
||||
if ( !( sendok & LDAP_BACK_BINDING ) ) {
|
||||
if ( !( sendok & LDAP_BACK_BINDING ) && !LDAP_BACK_USE_TEMPORARIES( mi ) ) {
|
||||
mc->mc_refcnt = 0;
|
||||
meta_back_conn_free( mc );
|
||||
|
||||
new_conn = 0;
|
||||
goto retry_lock;
|
||||
}
|
||||
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
break;
|
||||
|
||||
|
|
@ -1398,7 +1510,7 @@ done:;
|
|||
op->o_log_prefix, ncandidates,
|
||||
LDAP_BACK_PCONN_ID( mc ) );
|
||||
}
|
||||
|
||||
|
||||
return mc;
|
||||
}
|
||||
|
||||
|
|
@ -1424,27 +1536,34 @@ meta_back_release_conn_lock(
|
|||
* the connection space (and eat up resources). Maybe this
|
||||
* should be configurable... */
|
||||
if ( LDAP_BACK_CONN_TAINTED( mc ) ||
|
||||
( !LDAP_BACK_CONN_ISPRIV( mc ) &&
|
||||
LDAP_BACK_PCONN_ISPRIV( mc ) &&
|
||||
mc->mc_refcnt == 0 ) )
|
||||
( !LDAP_BACK_CONN_ISPRIV( mc ) && LDAP_BACK_PCONN_ISPRIV( mc ) && mc->mc_refcnt == 0 ) )
|
||||
{
|
||||
metaconn_t *tmpmc;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "%s meta_back_release_conn: mc=%p conn=%ld tainted.\n",
|
||||
op->o_log_prefix, (void *)mc, LDAP_BACK_PCONN_ID( mc ) );
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree, ">>> meta_back_release_conn" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
(void)avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
tmpmc = avl_delete( &mi->mi_conninfo.lai_tree,
|
||||
( caddr_t )mc, meta_back_conndnmc_cmp );
|
||||
#if META_BACK_PRINT_CONNTREE > 0
|
||||
meta_back_print_conntree( mi->mi_conninfo.lai_tree, "<<< meta_back_release_conn" );
|
||||
#endif /* META_BACK_PRINT_CONNTREE */
|
||||
if ( tmpmc == NULL ) {
|
||||
Debug( LDAP_DEBUG_TRACE, "%s: meta_back_release_conn: unable to find mc=%p\n",
|
||||
op->o_log_prefix, (void *)mc, 0 );
|
||||
} else {
|
||||
assert( tmpmc == mc );
|
||||
}
|
||||
|
||||
if ( mc->mc_refcnt == 0 ) {
|
||||
meta_back_conn_free( mc );
|
||||
mc = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if ( mc != NULL ) {
|
||||
if ( mc != NULL && LDAP_BACK_CONN_BINDING( mc ) ) {
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( mc );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -125,7 +125,9 @@ meta_back_db_open(
|
|||
{
|
||||
metainfo_t *mi = (metainfo_t *)be->be_private;
|
||||
|
||||
int i, rc;
|
||||
int i,
|
||||
not_always = 0,
|
||||
rc;
|
||||
|
||||
for ( i = 0; i < mi->mi_ntargets; i++ ) {
|
||||
slap_bindconf sb = { 0 };
|
||||
|
|
@ -153,6 +155,18 @@ meta_back_db_open(
|
|||
mt->mt_flags |= LDAP_BACK_F_CANCEL_EXOP;
|
||||
}
|
||||
}
|
||||
|
||||
if ( not_always == 0 ) {
|
||||
if ( !( mt->mt_idassert_flags & LDAP_BACK_AUTH_OVERRIDE )
|
||||
|| !( mt->mt_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) )
|
||||
{
|
||||
not_always = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( not_always == 0 ) {
|
||||
mi->mi_flags |= META_BACK_F_PROXYAUTHZ_ALWAYS;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -175,7 +189,6 @@ meta_back_conn_free(
|
|||
assert( mc->mc_refcnt == 0 );
|
||||
|
||||
/* at least one must be present... */
|
||||
assert( mc->mc_conns != NULL );
|
||||
ntargets = mc->mc_info->mi_ntargets;
|
||||
assert( ntargets > 0 );
|
||||
|
||||
|
|
|
|||
|
|
@ -90,19 +90,19 @@ ldap_back_map_init ( struct ldapmap *lm, struct ldapmapping **m )
|
|||
assert( m != NULL );
|
||||
|
||||
*m = NULL;
|
||||
|
||||
|
||||
mapping = (struct ldapmapping *)ch_calloc( 2,
|
||||
sizeof( struct ldapmapping ) );
|
||||
if ( mapping == NULL ) {
|
||||
return;
|
||||
}
|
||||
|
||||
ber_str2bv( "objectclass", sizeof("objectclass")-1, 1, &mapping->src);
|
||||
ber_dupbv( &mapping->dst, &mapping->src );
|
||||
mapping[1].src = mapping->src;
|
||||
mapping[1].dst = mapping->dst;
|
||||
ber_str2bv( "objectclass", STRLENOF("objectclass"), 1, &mapping[0].src);
|
||||
ber_dupbv( &mapping[0].dst, &mapping[0].src );
|
||||
mapping[1].src = mapping[0].src;
|
||||
mapping[1].dst = mapping[0].dst;
|
||||
|
||||
avl_insert( &lm->map, (caddr_t)mapping,
|
||||
avl_insert( &lm->map, (caddr_t)&mapping[0],
|
||||
mapping_cmp, mapping_dup );
|
||||
avl_insert( &lm->remap, (caddr_t)&mapping[1],
|
||||
mapping_cmp, mapping_dup );
|
||||
|
|
@ -120,6 +120,7 @@ ldap_back_mapping ( struct ldapmap *map, struct berval *s, struct ldapmapping **
|
|||
|
||||
if ( remap == BACKLDAP_REMAP ) {
|
||||
tree = map->remap;
|
||||
|
||||
} else {
|
||||
tree = map->map;
|
||||
}
|
||||
|
|
@ -139,6 +140,13 @@ ldap_back_map ( struct ldapmap *map, struct berval *s, struct berval *bv,
|
|||
{
|
||||
struct ldapmapping *mapping;
|
||||
|
||||
/* map->map may be NULL when mapping is configured,
|
||||
* but map->remap can't */
|
||||
if ( map->remap == NULL ) {
|
||||
*bv = *s;
|
||||
return;
|
||||
}
|
||||
|
||||
BER_BVZERO( bv );
|
||||
( void )ldap_back_mapping( map, s, &mapping, remap );
|
||||
if ( mapping != NULL ) {
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ meta_search_dobind_init(
|
|||
bound = 1;
|
||||
}
|
||||
|
||||
snprintf( buf, sizeof( buf ), " mc=%p lc=%p%s DN=\"%s\"",
|
||||
snprintf( buf, sizeof( buf ), " mc=%p ld=%p%s DN=\"%s\"",
|
||||
(void *)mc, (void *)msc->msc_ld,
|
||||
bound ? " bound" : " anonymous",
|
||||
bound == 0 ? "" : msc->msc_bound_ndn.bv_val );
|
||||
|
|
@ -118,13 +118,13 @@ meta_search_dobind_init(
|
|||
|
||||
retcode = META_SEARCH_CANDIDATE;
|
||||
|
||||
} else if ( LDAP_BACK_CONN_BINDING( msc ) ) {
|
||||
} else if ( META_BACK_CONN_CREATING( msc ) || LDAP_BACK_CONN_BINDING( msc ) ) {
|
||||
/* another thread is binding the target for this conn; wait */
|
||||
|
||||
#ifdef DEBUG_205
|
||||
char buf[ SLAP_TEXT_BUFLEN ] = { '\0' };
|
||||
|
||||
snprintf( buf, sizeof( buf ), " mc=%p lc=%p needbind",
|
||||
snprintf( buf, sizeof( buf ), " mc=%p ld=%p needbind",
|
||||
(void *)mc, (void *)msc->msc_ld );
|
||||
Debug( LDAP_DEBUG_ANY, "### %s meta_search_dobind_init[%d]%s\n",
|
||||
op->o_log_prefix, candidate, buf );
|
||||
|
|
@ -145,6 +145,32 @@ meta_search_dobind_init(
|
|||
op->o_log_prefix, candidate, buf );
|
||||
#endif /* DEBUG_205 */
|
||||
|
||||
if ( msc->msc_ld == NULL ) {
|
||||
/* for some reason (e.g. because formerly in "binding"
|
||||
* state, with eventual connection expiration or invalidation)
|
||||
* it was not initialized as expected */
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p ld=NULL\n",
|
||||
op->o_log_prefix, candidate, (void *)mc );
|
||||
|
||||
rc = meta_back_init_one_conn( op, rs, *mcp, candidate,
|
||||
LDAP_BACK_CONN_ISPRIV( *mcp ), LDAP_BACK_DONTSEND, 0 );
|
||||
switch ( rc ) {
|
||||
case LDAP_SUCCESS:
|
||||
assert( msc->msc_ld != NULL );
|
||||
break;
|
||||
|
||||
case LDAP_SERVER_DOWN:
|
||||
case LDAP_UNAVAILABLE:
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
goto down;
|
||||
|
||||
default:
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
goto other;
|
||||
}
|
||||
}
|
||||
|
||||
LDAP_BACK_CONN_BINDING_SET( msc );
|
||||
}
|
||||
|
||||
|
|
@ -154,29 +180,6 @@ meta_search_dobind_init(
|
|||
return retcode;
|
||||
}
|
||||
|
||||
if ( msc->msc_ld == NULL ) {
|
||||
/* for some reason (e.g. because formerly in "binding"
|
||||
* state, with eventual connection expiration or invalidation)
|
||||
* it was not initialized as expected */
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "%s meta_search_dobind_init[%d] mc=%p ld=NULL\n",
|
||||
op->o_log_prefix, candidate, (void *)mc );
|
||||
|
||||
rc = meta_back_init_one_conn( op, rs, *mcp, candidate,
|
||||
LDAP_BACK_CONN_ISPRIV( *mcp ), LDAP_BACK_DONTSEND );
|
||||
switch ( rc ) {
|
||||
case LDAP_SUCCESS:
|
||||
assert( msc->msc_ld != NULL );
|
||||
break;
|
||||
|
||||
case LDAP_SERVER_DOWN:
|
||||
goto down;
|
||||
|
||||
default:
|
||||
goto other;
|
||||
}
|
||||
}
|
||||
|
||||
/* NOTE: this obsoletes pseudorootdn */
|
||||
if ( op->o_conn != NULL &&
|
||||
!op->o_do_not_cache &&
|
||||
|
|
@ -268,7 +271,7 @@ other:;
|
|||
rc = slap_map_api2result( rs );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
meta_clear_one_candidate( op, mc, candidate );
|
||||
if ( META_BACK_ONERR_STOP( mi ) ) {
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
|
|
@ -315,14 +318,17 @@ meta_search_dobind_result(
|
|||
NULL, NULL, NULL, NULL, 0 );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
candidates[ candidate ].sr_err = rc;
|
||||
|
||||
} else {
|
||||
rc = slap_map_api2result( &candidates[ candidate ] );
|
||||
}
|
||||
rc = slap_map_api2result( &candidates[ candidate ] );
|
||||
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( msc );
|
||||
if ( rc != LDAP_SUCCESS ) {
|
||||
if ( META_BACK_ONERR_STOP( mi ) ) {
|
||||
LDAP_BACK_CONN_TAINTED_SET( mc );
|
||||
meta_clear_one_candidate( op, mc, candidate );
|
||||
meta_back_release_conn_lock( op, mc, 0 );
|
||||
*mcp = NULL;
|
||||
retcode = META_SEARCH_ERR;
|
||||
|
|
@ -796,9 +802,8 @@ getconn:;
|
|||
*/
|
||||
for ( rc = 0; ncandidates > 0; ) {
|
||||
int gotit = 0,
|
||||
doabandon = 0;
|
||||
|
||||
needbind = ncandidates;
|
||||
doabandon = 0,
|
||||
alreadybound = ncandidates;
|
||||
|
||||
/* check time limit */
|
||||
if ( op->ors_tlimit != SLAP_NO_LIMIT
|
||||
|
|
@ -834,7 +839,7 @@ getconn:;
|
|||
|
||||
switch ( retcode ) {
|
||||
case META_SEARCH_NEED_BIND:
|
||||
needbind--;
|
||||
alreadybound--;
|
||||
/* fallthru */
|
||||
|
||||
case META_SEARCH_BINDING:
|
||||
|
|
@ -918,11 +923,12 @@ getconn:;
|
|||
|
||||
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
|
||||
snprintf( buf, sizeof( buf ),
|
||||
"%s meta_back_search[%ld] mc=%p msgid=%d%s%s\n",
|
||||
"%s meta_back_search[%ld] mc=%p msgid=%d%s%s%s\n",
|
||||
op->o_log_prefix, (long)i, (void *)mc,
|
||||
candidates[ i ].sr_msgid,
|
||||
META_IS_BINDING( &candidates[ i ] ) ? " binding" : "",
|
||||
LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ? " connbinding" : "" );
|
||||
LDAP_BACK_CONN_BINDING( &mc->mc_conns[ i ] ) ? " connbinding" : "",
|
||||
META_BACK_CONN_CREATING( &mc->mc_conns[ i ] ) ? " conncreating" : "" );
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
|
||||
Debug( LDAP_DEBUG_ANY, "!!! %s\n", buf, 0, 0 );
|
||||
|
|
@ -1376,9 +1382,7 @@ really_bad:;
|
|||
Debug( LDAP_DEBUG_ANY, "### %s\n", buf, 0, 0 );
|
||||
#endif /* DEBUG_205 */
|
||||
|
||||
ldap_unbind_ext( mc->mc_conns[ i ].msc_ld, NULL, NULL );
|
||||
mc->mc_conns[ i ].msc_ld = NULL;
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( &mc->mc_conns[ i ] );
|
||||
meta_clear_one_candidate( op, mc, i );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
META_BINDING_CLEAR( &candidates[ i ] );
|
||||
|
|
@ -1439,7 +1443,7 @@ really_bad:;
|
|||
}
|
||||
#endif
|
||||
|
||||
if ( needbind == 0 ) {
|
||||
if ( alreadybound == 0 ) {
|
||||
#if 0
|
||||
Debug( LDAP_DEBUG_TRACE, "### %s select(%ld.%06ld)\n",
|
||||
op->o_log_prefix, save_tv.tv_sec, save_tv.tv_usec );
|
||||
|
|
@ -1622,9 +1626,7 @@ finish:;
|
|||
#endif /* DEBUG_205 */
|
||||
|
||||
/* if still binding, destroy */
|
||||
ldap_unbind_ext( mc->mc_conns[ i ].msc_ld, NULL, NULL );
|
||||
mc->mc_conns[ i ].msc_ld = NULL;
|
||||
LDAP_BACK_CONN_BINDING_CLEAR( &mc->mc_conns[ i ] );
|
||||
meta_clear_one_candidate( op, mc, i );
|
||||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
|
||||
META_BINDING_CLEAR( &candidates[ i ] );
|
||||
|
|
|
|||
Loading…
Reference in a new issue