diff --git a/servers/slapd/back-meta/modify.c b/servers/slapd/back-meta/modify.c index fd54c03fcca7f4b88832cbf321540f020f0eb33e..c17af5e928c675583d8805229255a9a499371025 100644 --- a/servers/slapd/back-meta/modify.c +++ b/servers/slapd/back-meta/modify.c @@ -37,6 +37,7 @@ meta_back_modify( Operation *op, SlapReply *rs ) metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private; metaconn_t *mc; int rc = 0; + int maperr = 1; LDAPMod **modv = NULL; LDAPMod *mods = NULL; Modifications *ml; @@ -64,7 +65,7 @@ meta_back_modify( Operation *op, SlapReply *rs ) dc.ctx = "modifyDN"; if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) { - rc = -1; + maperr = 0; goto cleanup; } @@ -74,13 +75,13 @@ meta_back_modify( Operation *op, SlapReply *rs ) mods = ch_malloc( sizeof( LDAPMod )*i ); if ( mods == NULL ) { rs->sr_err = LDAP_NO_MEMORY; - rc = -1; + maperr = 0; goto cleanup; } modv = ( LDAPMod ** )ch_malloc( ( i + 1 )*sizeof( LDAPMod * ) ); if ( modv == NULL ) { rs->sr_err = LDAP_NO_MEMORY; - rc = -1; + maperr = 0; goto cleanup; } @@ -178,9 +179,10 @@ retry:; modv, op->o_ctrls, NULL, &msgid ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; - if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) { + if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) { goto retry; } + goto done; } else if ( rs->sr_err == LDAP_SUCCESS ) { struct timeval tv, *tvp = NULL; @@ -197,7 +199,7 @@ retry:; msgid, LDAP_MSG_ALL, tvp, &res ); switch ( rc ) { case -1: - rc = -1; + maperr = 0; break; case 0: @@ -205,7 +207,7 @@ retry:; msgid, NULL, NULL ); rs->sr_err = op->o_protocol >= LDAP_VERSION3 ? LDAP_ADMINLIMIT_EXCEEDED : LDAP_OPERATIONS_ERROR; - rc = -1; + maperr = 0; break; case LDAP_RES_MODIFY: @@ -214,17 +216,25 @@ retry:; if ( rc != LDAP_SUCCESS ) { rs->sr_err = rc; } - rc = 0; + maperr = 1; break; default: - rc = -1; + maperr = 0; ldap_msgfree( res ); break; } } cleanup:; + if ( maperr ) { + rc = meta_back_op_result( mc, op, rs, candidate ); + + } else { + send_ldap_result( op, rs ); + } + +done:; if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); BER_BVZERO( &mdn ); @@ -237,16 +247,10 @@ cleanup:; free( mods ); free( modv ); - if ( rc != -1 ) { - rc = meta_back_op_result( mc, op, rs, candidate ); - - } else { - send_ldap_result( op, rs ); - rc = 0; + if ( mc ) { + meta_back_release_conn( op, mc ); } - meta_back_release_conn( op, mc ); - - return rc; + return rs->sr_err; } diff --git a/servers/slapd/back-meta/modrdn.c b/servers/slapd/back-meta/modrdn.c index 0b0fcfb0edf3a22f64fd897c08dafe74745328c5..a490553b64762317e15abd0d0a816eb3b936d4d2 100644 --- a/servers/slapd/back-meta/modrdn.c +++ b/servers/slapd/back-meta/modrdn.c @@ -42,6 +42,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) dncookie dc; int msgid; int do_retry = 1; + int maperr = 1; mc = meta_back_getconn( op, rs, &candidate, LDAP_BACK_SENDERR ); if ( !mc || !meta_back_dobind( op, rs, mc, LDAP_BACK_SENDERR ) ) { @@ -87,6 +88,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) dc.ctx = "newSuperiorDN"; if ( ldap_back_dn_massage( &dc, op->orr_newSup, &mnewSuperior ) ) { rs->sr_err = LDAP_OTHER; + maperr = 0; goto cleanup; } } @@ -98,6 +100,7 @@ meta_back_modrdn( Operation *op, SlapReply *rs ) dc.ctx = "modrDN"; if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) { rs->sr_err = LDAP_OTHER; + maperr = 0; goto cleanup; } @@ -108,9 +111,10 @@ retry:; op->o_ctrls, NULL, &msgid ); if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { do_retry = 0; - if ( meta_back_retry( op, rs, mc, candidate, LDAP_BACK_SENDERR ) ) { + if ( meta_back_retry( op, rs, &mc, candidate, LDAP_BACK_SENDERR ) ) { goto retry; } + goto done; } else if ( rs->sr_err == LDAP_SUCCESS ) { struct timeval tv, *tvp = NULL; @@ -126,6 +130,7 @@ retry:; rs->sr_err = LDAP_OTHER; rc = ldap_result( mc->mc_conns[ candidate ].msc_ld, msgid, LDAP_MSG_ALL, tvp, &res ); + maperr = 0; switch ( rc ) { case -1: break; @@ -143,6 +148,7 @@ retry:; if ( rc != LDAP_SUCCESS ) { rs->sr_err = rc; } + maperr = 1; break; default: @@ -152,6 +158,14 @@ retry:; } cleanup:; + if ( maperr ) { + meta_back_op_result( mc, op, rs, candidate ); + + } else { + send_ldap_result( op, rs ); + } + +done:; if ( mdn.bv_val != op->o_req_dn.bv_val ) { free( mdn.bv_val ); BER_BVZERO( &mdn ); @@ -164,14 +178,10 @@ cleanup:; BER_BVZERO( &mnewSuperior ); } - if ( rs->sr_err == LDAP_SUCCESS ) { - meta_back_op_result( mc, op, rs, candidate ); - } else { - send_ldap_result( op, rs ); + if ( mc ) { + meta_back_release_conn( op, mc ); } - meta_back_release_conn( op, mc ); - return rs->sr_err; } diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c index 668f8c94473707c29bf48f551afafcba9e9eff5b..edbf6550ea6b0bd9902d65be35197a79b1e9f9f1 100644 --- a/servers/slapd/back-meta/search.c +++ b/servers/slapd/back-meta/search.c @@ -416,7 +416,7 @@ really_bad:; if ( candidates[ i ].sr_type == REP_INTERMEDIATE ) { candidates[ i ].sr_type = REP_RESULT; - if ( meta_back_retry( op, rs, mc, i, LDAP_BACK_DONTSEND ) ) { + if ( meta_back_retry( op, rs, &mc, i, LDAP_BACK_DONTSEND ) ) { switch ( meta_back_search_start( op, rs, &dc, msc, i, candidates ) ) { case META_SEARCH_CANDIDATE: @@ -427,6 +427,12 @@ really_bad:; goto finish; } } + + savepriv = op->o_private; + op->o_private = (void *)i; + send_ldap_result( op, rs ); + op->o_private = savepriv; + goto finish; } /* @@ -468,7 +474,10 @@ really_bad:; } op->o_private = savepriv; + /* don't wait any longer... */ gotit = 1; + tv.tv_sec = 0; + tv.tv_usec = 0; #if 0 /* @@ -574,16 +583,16 @@ really_bad:; * back-meta would need to merge them * consistently (think of pagedResults...) */ - if ( ldap_parse_result( msc->msc_ld, + rs->sr_err = ldap_parse_result( msc->msc_ld, res, &candidates[ i ].sr_err, (char **)&candidates[ i ].sr_matched, NULL /* (char **)&candidates[ i ].sr_text */ , &references, NULL /* &candidates[ i ].sr_ctrls (unused) */ , - 1 ) != LDAP_SUCCESS ) - { - res = NULL; + 1 ); + res = NULL; + if ( rs->sr_err != LDAP_SUCCESS ) { ldap_get_option( msc->msc_ld, LDAP_OPT_ERROR_NUMBER, &rs->sr_err ); @@ -592,10 +601,6 @@ really_bad:; goto really_bad; } - rs->sr_err = candidates[ i ].sr_err; - sres = slap_map_api2result( rs ); - res = NULL; - /* massage matchedDN if need be */ if ( candidates[ i ].sr_matched != NULL ) { #ifndef LDAP_NULL_IS_NULL @@ -671,13 +676,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 ( StatslogTest( 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: @@ -697,6 +710,26 @@ really_bad:; is_ok++; break; + case LDAP_SIZELIMIT_EXCEEDED: + /* if a target returned sizelimitExceeded + * and the entry count is equal to the + * proxy's limit, the target would have + * returned more, and the error must be + * propagated to the client; otherwise, + * the target enforced a limit lower + * than what requested by the proxy; + * ignore it */ + if ( rs->sr_nentries == op->ors_slimit + || META_BACK_ONERR_STOP( mi ) ) + { + savepriv = op->o_private; + op->o_private = (void *)i; + send_ldap_result( op, rs ); + op->o_private = savepriv; + goto finish; + } + break; + default: if ( META_BACK_ONERR_STOP( mi ) ) { savepriv = op->o_private; @@ -743,13 +776,11 @@ really_bad:; } } + /* if no entry was found during this loop, + * set a minimal timeout */ if ( gotit == 0 ) { LDAP_BACK_TV_SET( &tv ); ldap_pvt_thread_yield(); - - } else { - tv.tv_sec = 0; - tv.tv_usec = 0; } } @@ -903,7 +934,9 @@ finish:; } } - meta_back_release_conn( op, mc ); + if ( mc ) { + meta_back_release_conn( op, mc ); + } return rs->sr_err; } @@ -1158,6 +1191,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: