/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
- * Copyright 1999-2005 The OpenLDAP Foundation.
+ * Copyright 1999-2006 The OpenLDAP Foundation.
* Portions Copyright 2001-2003 Pierangelo Masarati.
* Portions Copyright 1999-2003 Howard Chu.
* All rights reserved.
Operation *op,
SlapReply *rs,
metaconn_t *mc,
- int candidate );
+ int candidate,
+ int massage );
int
meta_back_bind( Operation *op, SlapReply *rs )
if ( META_BACK_DEFER_ROOTDN_BIND( mi ) ) {
rs->sr_err = LDAP_SUCCESS;
rs->sr_text = NULL;
- send_ldap_result( op, rs );
+ /* frontend will return success */
return rs->sr_err;
}
/* we need meta_back_getconn() not send result even on error,
* because we want to intercept the error and make it
* invalidCredentials */
- mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_DONTSEND );
+ mc = meta_back_getconn( op, rs, NULL, LDAP_BACK_BIND_SERR );
if ( !mc ) {
char buf[ SLAP_TEXT_BUFLEN ];
for ( i = 0; i < mi->mi_ntargets; i++ ) {
int lerr;
Operation op2 = *op;
+ int massage = 1;
/*
* Skip non-candidates
*/
Debug( LDAP_DEBUG_ANY,
"### %s meta_back_bind: more than one"
- " candidate is trying to bind...\n",
+ " candidate selected...\n",
op->o_log_prefix, 0, 0 );
}
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;
+
+ massage = 0;
}
- lerr = meta_back_single_bind( &op2, rs, mc, i );
+ lerr = meta_back_single_bind( &op2, rs, mc, i, massage );
+
if ( lerr != LDAP_SUCCESS ) {
- rs->sr_err = lerr;
+ rc = rs->sr_err = lerr;
candidates[ i ].sr_tag = META_NOT_CANDIDATE;
-
- if ( META_BACK_ONERR_STOP( mi ) ) {
- rc = rs->sr_err;
- break;
- }
+ break;
}
}
/* wait for all other ops to release the connection */
retry_lock:;
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+ ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
if ( mc->mc_refcnt > 1 ) {
- ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
ldap_pvt_thread_yield();
goto retry_lock;
}
assert( mc->mc_refcnt == 1 );
- mc = avl_delete( &mi->mi_conntree, (caddr_t)mc,
+ mc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
meta_back_conn_cmp );
assert( mc != NULL );
ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
- lerr = avl_insert( &mi->mi_conntree, (caddr_t)mc,
+ lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
meta_back_conn_cmp, meta_back_conn_dup );
- ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
if ( lerr == -1 ) {
for ( i = 0; i < mi->mi_ntargets; ++i ) {
if ( mc->mc_conns[ i ].msc_ld != NULL ) {
Operation *op,
SlapReply *rs,
metaconn_t *mc,
- int candidate )
+ int candidate,
+ int massage )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = &mi->mi_targets[ candidate ];
struct berval mdn = BER_BVNULL;
- dncookie dc;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int msgid,
rebinding = 0;
/*
* Rewrite the bind dn if needed
*/
- dc.target = mt;
- dc.conn = op->o_conn;
- dc.rs = rs;
- dc.ctx = "bindDN";
+ if ( massage ) {
+ dncookie dc;
- if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
- send_ldap_result( op, rs );
- return -1;
+ dc.target = mt;
+ dc.conn = op->o_conn;
+ dc.rs = rs;
+ dc.ctx = "bindDN";
+
+ if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
+ send_ldap_result( op, rs );
+ return -1;
+ }
+
+ } else {
+ mdn = op->o_req_dn;
}
/* FIXME: this fixes the bind problem right now; we need
struct timeval tv;
int rc;
int nretries = mt->mt_nretries;
+ char buf[ SLAP_TEXT_BUFLEN ];
LDAP_BACK_TV_SET( &tv );
* handle response!!!
*/
retry:;
- tv.tv_sec = 0;
- tv.tv_usec = META_BIND_TIMEOUT;
- switch ( ldap_result( msc->msc_ld, msgid, 0, &tv, &res ) ) {
+ switch ( ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) ) {
case 0:
- Debug( LDAP_DEBUG_ANY,
- "%s meta_back_single_bind: "
+ snprintf( buf, sizeof( buf ),
"ldap_result=0 nretries=%d%s\n",
- op->o_log_prefix, nretries,
- rebinding ? " rebinding" : "" );
+ nretries, rebinding ? " rebinding" : "" );
+ Debug( LDAP_DEBUG_ANY,
+ "%s meta_back_single_bind[%d]: %s.\n",
+ op->o_log_prefix, candidate, buf );
if ( nretries != META_RETRY_NEVER ) {
ldap_pvt_thread_yield();
if ( nretries > 0 ) {
nretries--;
}
- LDAP_BACK_TV_SET( &tv );
+ tv = mt->mt_bind_timeout;
goto retry;
}
rs->sr_err = LDAP_BUSY;
ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL );
}
+ snprintf( buf, sizeof( buf ),
+ "err=%d nretries=%d",
+ rs->sr_err, nretries );
Debug( LDAP_DEBUG_ANY,
- "### %s meta_back_single_bind: "
- "err=%d nretries=%d\n",
- op->o_log_prefix, rs->sr_err, nretries );
+ "### %s meta_back_single_bind[%d]: %s.\n",
+ op->o_log_prefix, candidate, buf );
rc = slap_map_api2result( rs );
if ( rs->sr_err == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
- if ( mc->mc_refcnt == 1 ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
- LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
-
- ( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
-
- /* mc here must be the regular mc,
- * reset and ready for init */
- rc = meta_back_init_one_conn( op, rs,
- mt, mc, msc, LDAP_BACK_CONN_ISPRIV( mc ),
- candidate == mc->mc_authz_target,
- LDAP_BACK_DONTSEND );
-
- } else {
- /* can't do anything about it */
- rc = 0;
- }
-
- ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
-
+ rc = meta_back_retry( op, rs, mc, candidate, LDAP_BACK_DONTSEND );
if ( rc ) {
if ( nretries > 0 ) {
nretries--;
if ( rc == LDAP_SUCCESS ) {
LDAPMessage *res;
struct timeval tv;
+ char buf[ SLAP_TEXT_BUFLEN ];
LDAP_BACK_TV_SET( &tv );
* handle response!!!
*/
retry:;
- tv.tv_sec = 0;
- tv.tv_usec = META_BIND_TIMEOUT;
- switch ( ldap_result( msc->msc_ld, msgid, 0, &tv, &res ) ) {
+ switch ( ldap_result( msc->msc_ld, msgid, LDAP_MSG_ALL, &tv, &res ) ) {
case 0:
+ snprintf( buf, sizeof( buf ),
+ "ldap_result=0 nretries=%d%s",
+ nretries, rebinding ? " rebinding" : "" );
Debug( LDAP_DEBUG_ANY,
- "%s meta_back_single_dobind: "
- "ldap_result=0 nretries=%d%s\n",
- op->o_log_prefix, nretries,
- rebinding ? " rebinding" : "" );
+ "%s meta_back_single_dobind[%d]: %s.\n",
+ op->o_log_prefix, candidate, buf );
if ( nretries != META_RETRY_NEVER ) {
ldap_pvt_thread_yield();
if ( nretries > 0 ) {
nretries--;
}
- LDAP_BACK_TV_SET( &tv );
+ tv = mt->mt_bind_timeout;
goto retry;
}
ldap_abandon_ext( msc->msc_ld, msgid, NULL, NULL );
}
+ snprintf( buf, sizeof( buf ),
+ "err=%d nretries=%d",
+ rs->sr_err, nretries );
Debug( LDAP_DEBUG_ANY,
- "### %s meta_back_single_dobind: "
- "err=%d nretries=%d\n",
- op->o_log_prefix, rs->sr_err, nretries );
+ "### %s meta_back_single_dobind[%d]: %s.\n",
+ op->o_log_prefix, candidate, buf );
rc = slap_map_api2result( rs );
if ( rc == LDAP_UNAVAILABLE && nretries != META_RETRY_NEVER ) {
+ /* NOTE: we do not use meta_back_retry() here
+ * to avoid circular loops; mc_mutex is set
+ * by the caller */
if ( dolock ) {
- ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex );
+ ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
}
if ( mc->mc_refcnt == 1 ) {
- ldap_unbind_ext_s( msc->msc_ld, NULL, NULL );
- msc->msc_ld = NULL;
+ meta_clear_one_candidate( msc );
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
( void )rewrite_session_delete( mt->mt_rwmap.rwm_rw, op->o_conn );
/* mc here must be the regular mc,
* reset and ready for init */
rc = meta_back_init_one_conn( op, rs,
- mt, mc, msc,
+ mt, mc, candidate,
LDAP_BACK_CONN_ISPRIV( mc ),
- candidate == mc->mc_authz_target,
LDAP_BACK_DONTSEND );
-
} else {
/* can't do anything about it */
}
if ( dolock ) {
- ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex );
+ ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
}
if ( rc == LDAP_SUCCESS ) {
rootdn = mi->mi_targets[ i ].mt_pseudorootdn.bv_val;
- rc = meta_back_single_bind( &op2, rs, mc, i );
+ rc = meta_back_single_bind( &op2, rs, mc, i, 0 );
} else {
rc = meta_back_single_dobind( op, rs, mc, i,