mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-29 11:09:34 -05:00
more on recovery (ITS#4429)
This commit is contained in:
parent
19a0d82937
commit
c853ba1f0e
5 changed files with 125 additions and 81 deletions
|
|
@ -299,8 +299,9 @@ extern void
|
|||
meta_back_release_conn_lock(
|
||||
Operation *op,
|
||||
metaconn_t *mc,
|
||||
int dofree,
|
||||
int dolock );
|
||||
#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 1 )
|
||||
#define meta_back_release_conn(op, mc) meta_back_release_conn_lock( (op), (mc), 0, 1 )
|
||||
|
||||
extern int
|
||||
meta_back_retry(
|
||||
|
|
@ -343,7 +344,7 @@ extern int
|
|||
meta_back_single_dobind(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
metaconn_t *msc,
|
||||
metaconn_t **mcp,
|
||||
int candidate,
|
||||
ldap_back_send_t sendok,
|
||||
int retries,
|
||||
|
|
@ -401,6 +402,11 @@ extern int
|
|||
meta_clear_one_candidate(
|
||||
metasingleconn_t *mc );
|
||||
|
||||
extern int
|
||||
meta_clear_candidates(
|
||||
Operation *op,
|
||||
metaconn_t *mc );
|
||||
|
||||
/*
|
||||
* Dn cache stuff (experimental)
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -179,6 +179,10 @@ meta_back_bind( Operation *op, SlapReply *rs )
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
@ -214,11 +218,7 @@ retry_lock:;
|
|||
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;
|
||||
|
|
@ -305,8 +305,9 @@ meta_back_single_bind(
|
|||
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 {
|
||||
|
|
@ -376,8 +377,8 @@ retry:;
|
|||
}
|
||||
|
||||
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 );
|
||||
|
|
@ -442,7 +443,7 @@ int
|
|||
meta_back_single_dobind(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
metaconn_t *mc,
|
||||
metaconn_t **mcp,
|
||||
int candidate,
|
||||
ldap_back_send_t sendok,
|
||||
int nretries,
|
||||
|
|
@ -450,6 +451,7 @@ meta_back_single_dobind(
|
|||
{
|
||||
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( "" );
|
||||
|
|
@ -459,6 +461,24 @@ meta_back_single_dobind(
|
|||
|
||||
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
|
||||
|
|
@ -533,8 +553,8 @@ retry:;
|
|||
}
|
||||
|
||||
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 );
|
||||
|
|
@ -591,9 +611,15 @@ retry:;
|
|||
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;
|
||||
|
|
@ -659,28 +685,21 @@ meta_back_dobind(
|
|||
}
|
||||
|
||||
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 ) ) {
|
||||
|
|
@ -690,8 +709,9 @@ retry:;
|
|||
}
|
||||
|
||||
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 );
|
||||
|
|
@ -709,6 +729,7 @@ retry:;
|
|||
bound = 0;
|
||||
goto done;
|
||||
}
|
||||
|
||||
continue;
|
||||
} /* else */
|
||||
|
||||
|
|
@ -734,15 +755,18 @@ done:;
|
|||
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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -206,3 +206,22 @@ meta_clear_one_candidate(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* meta_clear_candidates
|
||||
*
|
||||
* clears all candidates
|
||||
*/
|
||||
int
|
||||
meta_clear_candidates( Operation *op, metaconn_t *mc )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
int c;
|
||||
|
||||
for ( c = 0; c < mi->mi_ntargets; c++ ) {
|
||||
if ( mc->mc_conns[ c ].msc_ld != NULL ) {
|
||||
meta_clear_one_candidate( &mc->mc_conns[ c ] );
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -517,26 +517,12 @@ meta_back_retry(
|
|||
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 ) {
|
||||
|
|
@ -1246,6 +1232,7 @@ void
|
|||
meta_back_release_conn_lock(
|
||||
Operation *op,
|
||||
metaconn_t *mc,
|
||||
int dofree,
|
||||
int dolock )
|
||||
{
|
||||
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
|
||||
|
|
@ -1258,7 +1245,8 @@ meta_back_release_conn_lock(
|
|||
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",
|
||||
|
|
@ -1266,6 +1254,7 @@ meta_back_release_conn_lock(
|
|||
(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 );
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -604,30 +604,27 @@ really_bad:;
|
|||
|
||||
/* massage matchedDN if need be */
|
||||
if ( candidates[ i ].sr_matched != NULL ) {
|
||||
{
|
||||
struct berval match, mmatch;
|
||||
struct berval match, mmatch;
|
||||
|
||||
ber_str2bv( candidates[ i ].sr_matched,
|
||||
0, 0, &match );
|
||||
candidates[ i ].sr_matched = NULL;
|
||||
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 );
|
||||
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;
|
||||
}
|
||||
} else {
|
||||
candidates[ i ].sr_matched = mmatch.bv_val;
|
||||
}
|
||||
|
||||
candidate_match++;
|
||||
}
|
||||
ldap_memfree( match.bv_val );
|
||||
}
|
||||
candidate_match++;
|
||||
}
|
||||
ldap_memfree( match.bv_val );
|
||||
}
|
||||
|
||||
|
||||
/* add references to array */
|
||||
if ( references ) {
|
||||
BerVarray sr_ref;
|
||||
|
|
@ -662,13 +659,21 @@ really_bad:;
|
|||
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:
|
||||
|
|
@ -1151,6 +1156,7 @@ next_attr:;
|
|||
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:
|
||||
|
|
|
|||
Loading…
Reference in a new issue