if ( lerr != LDAP_SUCCESS ) {
rc = rs->sr_err = lerr;
+ /* FIXME: in some cases (e.g. unavailable)
+ * do not assume it's not candidate; rather
+ * mark this as an error to be eventually
+ * reported to client */
candidates[ i ].sr_tag = META_NOT_CANDIDATE;
break;
}
meta_back_conndn_cmp, meta_back_conndn_dup );
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 ) {
- meta_clear_one_candidate( &mc->mc_conns[ i ] );
- }
- }
+ meta_clear_candidates( op, mc );
/* we can do this because mc_refcnt == 1 */
mc->mc_refcnt = 0;
dc.ctx = "bindDN";
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
- send_ldap_result( op, rs );
- return -1;
+ rs->sr_text = "DN rewrite error";
+ rs->sr_err = LDAP_OTHER;
+ return rs->sr_err;
}
} else {
}
snprintf( buf, sizeof( buf ),
- "err=%d nretries=%d",
- rs->sr_err, nretries );
+ "err=%d (%s) nretries=%d",
+ rs->sr_err, ldap_err2string( rs->sr_err ), nretries );
Debug( LDAP_DEBUG_ANY,
"### %s meta_back_single_bind[%d]: %s.\n",
op->o_log_prefix, candidate, buf );
meta_back_single_dobind(
Operation *op,
SlapReply *rs,
- metaconn_t *mc,
+ metaconn_t **mcp,
int candidate,
ldap_back_send_t sendok,
int nretries,
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
metatarget_t *mt = &mi->mi_targets[ candidate ];
+ metaconn_t *mc = *mcp;
metasingleconn_t *msc = &mc->mc_conns[ candidate ];
int rc;
static struct berval cred = BER_BVC( "" );
assert( !LDAP_BACK_CONN_ISBOUND( msc ) );
+ /*
+ * meta_back_single_dobind() calls meta_back_single_bind()
+ * if required.
+ */
+ if ( be_isroot( op ) && !BER_BVISNULL( &mi->mi_targets[ candidate ].mt_pseudorootdn ) )
+ {
+ Operation op2 = *op;
+
+ op2.o_tag = LDAP_REQ_BIND;
+ op2.o_req_dn = mi->mi_targets[ candidate ].mt_pseudorootdn;
+ op2.o_req_ndn = mi->mi_targets[ candidate ].mt_pseudorootdn;
+ op2.orb_cred = mi->mi_targets[ candidate ].mt_pseudorootpw;
+ op2.orb_method = LDAP_AUTH_SIMPLE;
+
+ rc = meta_back_single_bind( &op2, rs, *mcp, candidate, 0 );
+ goto done;
+ }
+
/*
* Otherwise an anonymous bind is performed
* (note: if the target was already bound, the anonymous
}
snprintf( buf, sizeof( buf ),
- "err=%d nretries=%d",
- rs->sr_err, nretries );
+ "err=%d (%s) nretries=%d",
+ rs->sr_err, ldap_err2string( rs->sr_err ), nretries );
Debug( LDAP_DEBUG_ANY,
"### %s meta_back_single_dobind[%d]: %s.\n",
op->o_log_prefix, candidate, buf );
rc = slap_map_api2result( rs );
}
+done:;
rs->sr_err = rc;
- if ( rc != LDAP_SUCCESS && ( sendok & LDAP_BACK_SENDERR ) ) {
- send_ldap_result( op, rs );
+ if ( rc != LDAP_SUCCESS && META_BACK_ONERR_STOP( mi ) ) {
+ meta_back_release_conn_lock( op, mc, 1, dolock );
+ *mcp = NULL;
+
+ if ( sendok & LDAP_BACK_SENDERR ) {
+ send_ldap_result( op, rs );
+ }
}
return rc;
}
retry:;
- if ( isroot && !BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) )
- {
- Operation op2 = *op;
-
- op2.o_tag = LDAP_REQ_BIND;
- 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;
-
- rootdn = mi->mi_targets[ i ].mt_pseudorootdn.bv_val;
-
- rc = meta_back_single_bind( &op2, rs, mc, i, 0 );
-
- } else {
- rc = meta_back_single_dobind( op, rs, mc, i,
- LDAP_BACK_DONTSEND, mt->mt_nretries, 1 );
- }
-
+ rc = meta_back_single_dobind( op, rs, &mc, i,
+ LDAP_BACK_DONTSEND, mt->mt_nretries, 1 );
+ /*
+ * NOTE: meta_back_single_dobind() already retries;
+ * in case of failure, it resets mc...
+ */
if ( rc != LDAP_SUCCESS ) {
char buf[ SLAP_TEXT_BUFLEN ];
+ if ( mc == NULL ) {
+ /* meta_back_single_dobind() already sent
+ * response and released connection */
+ goto send_err;
+ }
+
if ( rc == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0;
if ( meta_back_retry( op, rs, &mc, i, sendok ) ) {
}
snprintf( buf, sizeof( buf ),
- "meta_back_dobind[%d]: (%s) err=%d.",
- i, rootdn ? rootdn : "anonymous", rc );
+ "meta_back_dobind[%d]: (%s) err=%d (%s).",
+ i, rootdn ? rootdn : "anonymous",
+ rc, ldap_err2string( rc ) );
Debug( LDAP_DEBUG_ANY,
"%s %s\n",
op->o_log_prefix, buf, 0 );
bound = 0;
goto done;
}
+
continue;
} /* else */
if ( bound == 0 ) {
meta_back_release_conn( op, mc );
+send_err:;
if ( sendok & LDAP_BACK_SENDERR ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
rs->sr_err = LDAP_BUSY;
}
send_ldap_result( op, rs );
}
+
+ return 0;
}
- return( bound > 0 );
+ return ( bound > 0 );
}
/*
LDAP_BACK_CONN_ISPRIV( mc ), sendok );
if ( rc == LDAP_SUCCESS ) {
- if ( be_isroot( op ) && !BER_BVISNULL( &mi->mi_targets[ candidate ].mt_pseudorootdn ) )
- {
- Operation op2 = *op;
-
- op2.o_tag = LDAP_REQ_BIND;
- op2.o_req_dn = mi->mi_targets[ candidate ].mt_pseudorootdn;
- op2.o_req_ndn = mi->mi_targets[ candidate ].mt_pseudorootdn;
- op2.orb_cred = mi->mi_targets[ candidate ].mt_pseudorootpw;
- op2.orb_method = LDAP_AUTH_SIMPLE;
-
- rc = meta_back_single_bind( &op2, rs, mc, candidate, 0 );
-
- } else {
- rc = meta_back_single_dobind( op, rs, mc, candidate,
- sendok, mt->mt_nretries, 0 );
- }
+ rc = meta_back_single_dobind( op, rs, mcp, candidate,
+ sendok, mt->mt_nretries, 0 );
}
} else {
- meta_back_release_conn_lock( op, mc, 0 );
+ meta_back_release_conn_lock( op, mc, 1, 0 );
*mcp = NULL;
if ( sendok ) {
meta_back_release_conn_lock(
Operation *op,
metaconn_t *mc,
+ int dofree,
int dolock )
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
assert( mc->mc_refcnt > 0 );
mc->mc_refcnt--;
LDAP_BACK_CONN_BINDING_CLEAR( mc );
- if ( ( mi->mi_conn_ttl != 0 && op->o_time > mc->mc_create_time + mi->mi_conn_ttl )
+ if ( dofree
+ || ( 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 ) )
{
Debug( LDAP_DEBUG_TRACE, "%s meta_back_release_conn: mc=%p conn=%ld expired.\n",
(void)avl_delete( &mi->mi_conninfo.lai_tree,
( caddr_t )mc, meta_back_conndnmc_cmp );
if ( mc->mc_refcnt == 0 ) {
+ meta_clear_candidates( op, mc );
meta_back_conn_free( mc );
}
}
/* massage matchedDN if need be */
if ( candidates[ i ].sr_matched != NULL ) {
- {
- struct berval match, mmatch;
-
- ber_str2bv( candidates[ i ].sr_matched,
- 0, 0, &match );
- candidates[ i ].sr_matched = NULL;
-
- dc.ctx = "matchedDN";
- dc.target = &mi->mi_targets[ i ];
- 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 );
- }
- }
+ struct berval match, mmatch;
+
+ ber_str2bv( candidates[ i ].sr_matched,
+ 0, 0, &match );
+ candidates[ i ].sr_matched = NULL;
+
+ dc.ctx = "matchedDN";
+ dc.target = &mi->mi_targets[ i ];
+ 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 );
+ }
/* add references to array */
if ( references ) {
rs->sr_err = candidates[ i ].sr_err;
sres = slap_map_api2result( rs );
- snprintf( buf, sizeof( buf ),
- "%s meta_back_search[%ld] "
- "match=\"%s\" err=%ld\n",
- op->o_log_prefix, i,
- candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
- (long) candidates[ i ].sr_err );
- Debug( LDAP_DEBUG_ANY, "%s", buf, 0, 0 );
+ if ( LogTest( LDAP_DEBUG_TRACE | LDAP_DEBUG_ANY ) ) {
+ snprintf( buf, sizeof( buf ),
+ "%s meta_back_search[%ld] "
+ "match=\"%s\" err=%ld",
+ op->o_log_prefix, i,
+ candidates[ i ].sr_matched ? candidates[ i ].sr_matched : "",
+ (long) candidates[ i ].sr_err );
+ if ( candidates[ i ].sr_err == LDAP_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE, "%s.\n", buf, 0, 0 );
+
+ } else {
+ Debug( LDAP_DEBUG_ANY, "%s (%s).\n",
+ buf, ldap_err2string( candidates[ i ].sr_err ), 0 );
+ }
+ }
switch ( sres ) {
case LDAP_NO_SUCH_OBJECT:
rs->sr_entry = &ent;
rs->sr_attrs = op->ors_attrs;
rs->sr_flags = 0;
+ rs->sr_err = LDAP_SUCCESS;
rc = send_search_entry( op, rs );
switch ( rc ) {
case LDAP_UNAVAILABLE: