.BR (!(objectClass=*)) ,
which corresponds to the empty result set.
+.TP
+.B onerr {CONTINUE|stop}
+This directive allows to select the behavior in case an error is returned
+by the remote server during a search.
+The default, \fBcontinue\fP, consists in returning success.
+If the value is set to \fBstop\fP, the error is returned to the client.
+
.TP
.B protocol\-version {0,2,3}
This directive indicates what protocol version must be used to contact
#define LDAP_BACK_F_NOREFS (0x00080000U)
#define LDAP_BACK_F_NOUNDEFFILTER (0x00100000U)
+#define LDAP_BACK_F_ONERR_STOP (0x00200000U)
+
#define LDAP_BACK_ISSET_F(ff,f) ( ( (ff) & (f) ) == (f) )
#define LDAP_BACK_ISMASK_F(ff,m,f) ( ( (ff) & (m) ) == (f) )
#define LDAP_BACK_NOREFS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_NOREFS)
#define LDAP_BACK_NOUNDEFFILTER(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_NOUNDEFFILTER)
+#define LDAP_BACK_ONERR_STOP(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_ONERR_STOP)
+
int li_version;
unsigned long li_conn_nextid;
LDAP_BACK_CFG_ST_REQUEST,
LDAP_BACK_CFG_NOREFS,
LDAP_BACK_CFG_NOUNDEFFILTER,
+ LDAP_BACK_CFG_ONERR,
LDAP_BACK_CFG_REWRITE,
"SYNTAX OMsBoolean "
"SINGLE-VALUE )",
NULL, NULL },
+ { "onerr", "CONTINUE|report|stop", 2, 2, 0,
+ ARG_MAGIC|LDAP_BACK_CFG_ONERR,
+ ldap_back_cf_gen, "( OLcfgDbAt:3.108 "
+ "NAME 'olcDbOnErr' "
+ "DESC 'error handling' "
+ "SYNTAX OMsDirectoryString "
+ "SINGLE-VALUE )",
+ NULL, NULL },
{ "idassert-passThru", "authzRule", 2, 2, 0,
ARG_MAGIC|LDAP_BACK_CFG_IDASSERT_PASSTHRU,
ldap_back_cf_gen, "( OLcfgDbAt:3.27 "
#endif /* SLAP_CONTROL_X_SESSION_TRACKING */
"$ olcDbNoRefs "
"$ olcDbNoUndefFilter "
+ "$ olcDbOnErr "
") )",
Cft_Database, ldapcfg},
{ NULL, 0, NULL }
{ BER_BVNULL, 0 }
};
+static slap_verbmasks onerr_mode[] = {
+ { BER_BVC( "stop" ), LDAP_BACK_F_ONERR_STOP },
+ { BER_BVC( "report" ), LDAP_BACK_F_ONERR_STOP }, /* same behavior */
+ { BER_BVC( "continue" ), LDAP_BACK_F_NONE },
+ { BER_BVNULL, 0 }
+};
+
/* see enum in slap.h */
static slap_cf_aux_table timeout_table[] = {
{ BER_BVC("bind="), SLAP_OP_BIND * sizeof( time_t ), 'u', 0, NULL },
c->value_int = LDAP_BACK_NOUNDEFFILTER( li );
break;
+ case LDAP_BACK_CFG_ONERR:
+ enum_to_verb( onerr_mode, li->li_flags & LDAP_BACK_F_ONERR_STOP, &bv );
+ if ( BER_BVISNULL( &bv )) {
+ rc = 1;
+ } else {
+ value_add_one( &c->rvalue_vals, &bv );
+ }
+ break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
li->li_flags &= ~LDAP_BACK_F_NOUNDEFFILTER;
break;
+ case LDAP_BACK_CFG_ONERR:
+ li->li_flags &= ~LDAP_BACK_F_ONERR_STOP;
+ break;
+
default:
/* FIXME: we need to handle all... */
assert( 0 );
}
break;
+ case LDAP_BACK_CFG_ONERR:
+ /* onerr? */
+ i = verb_to_mask( c->argv[1], onerr_mode );
+ if ( BER_BVISNULL( &onerr_mode[i].word ) ) {
+ snprintf( c->cr_msg, sizeof( c->cr_msg ),
+ "%s unknown argument \"%s\"",
+ c->argv[0], c->argv[1] );
+ Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg, 0 );
+ return 1;
+ }
+ li->li_flags &= ~LDAP_BACK_F_ONERR_STOP;
+ li->li_flags |= onerr_mode[i].mask;
+ break;
+
case LDAP_BACK_CFG_REWRITE:
snprintf( c->cr_msg, sizeof( c->cr_msg ),
"rewrite/remap capabilities have been moved "
}
}
- if ( rc == -1 && dont_retry == 0 ) {
- if ( do_retry ) {
- do_retry = 0;
- if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) {
- goto retry;
+ if ( rc == -1 ) {
+ if ( dont_retry == 0 ) {
+ if ( do_retry ) {
+ do_retry = 0;
+ if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) {
+ goto retry;
+ }
}
+
+ rs->sr_err = LDAP_SERVER_DOWN;
+ rs->sr_err = slap_map_api2result( rs );
+ goto finish;
+
+ } else if ( LDAP_BACK_ONERR_STOP( li ) ) {
+ /* if onerr == STOP */
+ rs->sr_err = LDAP_SERVER_DOWN;
+ rs->sr_err = slap_map_api2result( rs );
+ goto finish;
}
- rs->sr_err = LDAP_SERVER_DOWN;
- rs->sr_err = slap_map_api2result( rs );
- goto finish;
}
/*
rs->sr_matched = pmatch.bv_val;
rs->sr_flags |= REP_MATCHED_MUSTBEFREED;
}
+
+finish:;
if ( !BER_BVISNULL( &match ) ) {
ber_memfree( match.bv_val );
}
rs->sr_err = LDAP_REFERRAL;
}
-finish:;
if ( LDAP_BACK_QUARANTINE( li ) ) {
ldap_back_quarantine( op, rs );
}