metatarget_t *mt = mi->mi_targets[ candidate ];
metaconn_t *mc = *mcp;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
- static struct berval cred = BER_BVC( "" );
int msgid;
assert( !LDAP_BACK_CONN_ISBOUND( msc ) );
(void)meta_back_proxy_authz_bind( mc, candidate, op, rs, sendok );
} else {
+ char *binddn = "";
+ struct berval cred = BER_BVC( "" );
+
+ /* use credentials if available */
+ if ( !BER_BVISNULL( &msc->msc_bound_ndn )
+ && !BER_BVISNULL( &msc->msc_cred ) )
+ {
+ binddn = msc->msc_bound_ndn.bv_val;
+ cred = msc->msc_cred;
+ }
/* FIXME: should we check if at least some of the op->o_ctrls
* can/should be passed? */
for (;;) {
rs->sr_err = ldap_sasl_bind( msc->msc_ld,
- "", LDAP_SASL_SIMPLE, &cred,
+ binddn, LDAP_SASL_SIMPLE, &cred,
NULL, NULL, &msgid );
if ( rs->sr_err != LDAP_X_CONNECTING ) {
break;
}
rs->sr_err = meta_back_bind_op_result( op, rs, mc, candidate, msgid, sendok );
+
+ /* if bind succeeded, but anonymous, clear msc_bound_ndn */
+ if ( rs->sr_err == LDAP_SUCCESS ) {
+ if ( binddn[0] == '\0' &&
+ !BER_BVISNULL( &msc->msc_bound_ndn ) &&
+ !BER_BVISEMPTY( &msc->msc_bound_ndn ) )
+ {
+ ber_memfree( msc->msc_bound_ndn.bv_val );
+ BER_BVZERO( &msc->msc_bound_ndn );
+ }
+ }
}
if ( rs->sr_err != LDAP_SUCCESS ) {
if ( dolock ) {
ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
}
- LDAP_BACK_CONN_BINDING_CLEAR( msc );
+ LDAP_BACK_CONN_BINDING_CLEAR( msc );
if ( META_BACK_ONERR_STOP( mi ) ) {
- LDAP_BACK_CONN_TAINTED_SET( mc );
+ LDAP_BACK_CONN_TAINTED_SET( mc );
meta_back_release_conn_lock( mi, mc, 0 );
*mcp = NULL;
}
char *xtext = NULL;
char *xmatched = NULL;
+ if ( msc->msc_ld == NULL ) {
+ continue;
+ }
+
rs->sr_err = LDAP_SUCCESS;
ldap_get_option( msc->msc_ld, LDAP_OPT_RESULT_CODE, &rs->sr_err );
}
done:;
+
+ if ( !BER_BVISEMPTY( binddn ) ) {
+ LDAP_BACK_CONN_ISIDASSERT_SET( msc );
+ }
+
return rs->sr_err;
}
}
ber_bvreplace( &msc->msc_cred, &mt->mt_idassert_passwd );
}
+ LDAP_BACK_CONN_ISIDASSERT_SET( msc );
} else {
ber_bvreplace( &msc->msc_bound_ndn, &slap_empty_bv );
assert( mc->mc_refcnt > 0 );
if ( mc->mc_refcnt == 1 ) {
+ struct berval save_cred;
+
if ( LogTest( LDAP_DEBUG_ANY ) ) {
char buf[ SLAP_TEXT_BUFLEN ];
op->o_log_prefix, candidate, buf );
}
+ /* save credentials, if any, for later use;
+ * meta_clear_one_candidate() would free them */
+ save_cred = msc->msc_cred;
+ BER_BVZERO( &msc->msc_cred );
+
meta_clear_one_candidate( op, mc, candidate );
LDAP_BACK_CONN_ISBOUND_CLEAR( msc );
rc = meta_back_init_one_conn( op, rs, mc, candidate,
LDAP_BACK_CONN_ISPRIV( mc ), sendok, 0 );
+ /* restore credentials, if any;
+ * meta_back_init_one_conn() restores msc_bound_ndn, if any;
+ * if no msc_bound_ndn is restored, destroy credentials */
+ if ( !BER_BVISNULL( &msc->msc_bound_ndn ) ) {
+ msc->msc_cred = save_cred;
+
+ } else if ( !BER_BVISNULL( &save_cred ) ) {
+ memset( save_cred.bv_val, 0, save_cred.bv_len );
+ ber_memfree( save_cred.bv_val );
+ }
+
/* restore the "binding" flag, in case */
if ( binding ) {
LDAP_BACK_CONN_BINDING_SET( msc );
}
if ( mc != NULL ) {
+ /* move to tail of queue */
if ( mc != LDAP_TAILQ_LAST( &mi->mi_conn_priv[ LDAP_BACK_CONN2PRIV( mc ) ].mic_priv,
metaconn_t, mc_q ) )
{