From ebf23f81879a2c23b8b4af906b50df227befc851 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Sat, 12 Jan 2013 00:13:07 +0100 Subject: [PATCH] add support for 'onerr' (ITS#7492) --- doc/man/man5/slapd-ldap.5 | 7 +++++ servers/slapd/back-ldap/back-ldap.h | 4 +++ servers/slapd/back-ldap/config.c | 44 +++++++++++++++++++++++++++++ servers/slapd/back-ldap/search.c | 28 ++++++++++++------ servers/slapd/back-meta/back-meta.h | 2 +- 5 files changed, 75 insertions(+), 10 deletions(-) diff --git a/doc/man/man5/slapd-ldap.5 b/doc/man/man5/slapd-ldap.5 index f91d583abe..1244d1fe08 100644 --- a/doc/man/man5/slapd-ldap.5 +++ b/doc/man/man5/slapd-ldap.5 @@ -450,6 +450,13 @@ with .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 diff --git a/servers/slapd/back-ldap/back-ldap.h b/servers/slapd/back-ldap/back-ldap.h index 8b765acc0f..048ca7f1ec 100644 --- a/servers/slapd/back-ldap/back-ldap.h +++ b/servers/slapd/back-ldap/back-ldap.h @@ -332,6 +332,8 @@ typedef struct ldapinfo_t { #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) ) @@ -373,6 +375,8 @@ typedef struct ldapinfo_t { #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; diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c index 4feb898fb0..fdba1d3cf6 100644 --- a/servers/slapd/back-ldap/config.c +++ b/servers/slapd/back-ldap/config.c @@ -71,6 +71,7 @@ enum { LDAP_BACK_CFG_ST_REQUEST, LDAP_BACK_CFG_NOREFS, LDAP_BACK_CFG_NOUNDEFFILTER, + LDAP_BACK_CFG_ONERR, LDAP_BACK_CFG_REWRITE, @@ -325,6 +326,14 @@ static ConfigTable ldapcfg[] = { "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 " @@ -383,6 +392,7 @@ static ConfigOCs ldapocs[] = { #endif /* SLAP_CONTROL_X_SESSION_TRACKING */ "$ olcDbNoRefs " "$ olcDbNoUndefFilter " + "$ olcDbOnErr " ") )", Cft_Database, ldapcfg}, { NULL, 0, NULL } @@ -472,6 +482,13 @@ static slap_verbmasks cancel_mode[] = { { 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 }, @@ -1378,6 +1395,15 @@ ldap_back_cf_gen( ConfigArgs *c ) 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 ); @@ -1541,6 +1567,10 @@ ldap_back_cf_gen( ConfigArgs *c ) 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 ); @@ -2207,6 +2237,20 @@ done_url:; } 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 " diff --git a/servers/slapd/back-ldap/search.c b/servers/slapd/back-ldap/search.c index 8e09dbb19f..094d76ec42 100644 --- a/servers/slapd/back-ldap/search.c +++ b/servers/slapd/back-ldap/search.c @@ -554,16 +554,25 @@ retry: } } - 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; } /* @@ -579,6 +588,8 @@ retry: rs->sr_matched = pmatch.bv_val; rs->sr_flags |= REP_MATCHED_MUSTBEFREED; } + +finish:; if ( !BER_BVISNULL( &match ) ) { ber_memfree( match.bv_val ); } @@ -587,7 +598,6 @@ retry: rs->sr_err = LDAP_REFERRAL; } -finish:; if ( LDAP_BACK_QUARANTINE( li ) ) { ldap_back_quarantine( op, rs ); } diff --git a/servers/slapd/back-meta/back-meta.h b/servers/slapd/back-meta/back-meta.h index b34a74b149..d116c2e95f 100644 --- a/servers/slapd/back-meta/back-meta.h +++ b/servers/slapd/back-meta/back-meta.h @@ -456,7 +456,7 @@ typedef struct metainfo_t { #define li_flags mi_flags /* uses flags as defined in */ -#define META_BACK_F_ONERR_STOP (0x01000000U) +#define META_BACK_F_ONERR_STOP LDAP_BACK_F_ONERR_STOP #define META_BACK_F_ONERR_REPORT (0x02000000U) #define META_BACK_F_ONERR_MASK (META_BACK_F_ONERR_STOP|META_BACK_F_ONERR_REPORT) #define META_BACK_F_DEFER_ROOTDN_BIND (0x04000000U) -- 2.39.5