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;
dc.ctx = "modifyDN";
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
- rc = -1;
+ maperr = 0;
goto cleanup;
}
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;
}
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;
msgid, LDAP_MSG_ALL, tvp, &res );
switch ( rc ) {
case -1:
- rc = -1;
+ maperr = 0;
break;
case 0:
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:
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 );
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;
}
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 ) ) {
dc.ctx = "newSuperiorDN";
if ( ldap_back_dn_massage( &dc, op->orr_newSup, &mnewSuperior ) ) {
rs->sr_err = LDAP_OTHER;
+ maperr = 0;
goto cleanup;
}
}
dc.ctx = "modrDN";
if ( ldap_back_dn_massage( &dc, &op->o_req_dn, &mdn ) ) {
rs->sr_err = LDAP_OTHER;
+ maperr = 0;
goto cleanup;
}
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;
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;
if ( rc != LDAP_SUCCESS ) {
rs->sr_err = rc;
}
+ maperr = 1;
break;
default:
}
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 );
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;
}
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:
goto finish;
}
}
+
+ savepriv = op->o_private;
+ op->o_private = (void *)i;
+ send_ldap_result( op, rs );
+ op->o_private = savepriv;
+ goto finish;
}
/*
}
op->o_private = savepriv;
+ /* don't wait any longer... */
gotit = 1;
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
#if 0
/*
* 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 );
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
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:
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;
}
}
+ /* 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;
}
}
}
}
- meta_back_release_conn( op, mc );
+ if ( mc ) {
+ meta_back_release_conn( op, mc );
+ }
return rs->sr_err;
}
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: