]> git.sur5r.net Git - openldap/commitdiff
add support for 'onerr' (ITS#7492)
authorPierangelo Masarati <ando@OpenLDAP.org>
Fri, 11 Jan 2013 23:13:07 +0000 (00:13 +0100)
committerPierangelo Masarati <ando@OpenLDAP.org>
Fri, 11 Jan 2013 23:13:42 +0000 (00:13 +0100)
doc/man/man5/slapd-ldap.5
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/config.c
servers/slapd/back-ldap/search.c
servers/slapd/back-meta/back-meta.h

index f91d583abe07b66e6c338a70b1ab4c73241723e1..1244d1fe088101d645b41a9074990a1a5ef62e2b 100644 (file)
@@ -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
index 8b765acc0f38d5699fd32bfa0670d5d114f9fa29..048ca7f1ecace002be009167a8431e179c3cb7bc 100644 (file)
@@ -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;
index 4feb898fb050b23f926f8065eb625411761487ff..fdba1d3cf62be951f32690f9151dc4394ddb112c 100644 (file)
@@ -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 "
index 8e09dbb19f53b106e834d34a79c54c439e0a39a9..094d76ec424a6910565514df592667e29972d1a3 100644 (file)
@@ -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 );
        }
index b34a74b149d0177c7ea975716fee0b5d67128103..d116c2e95f02fe36b709902cbad8d6594d908bea 100644 (file)
@@ -456,7 +456,7 @@ typedef struct metainfo_t {
 
 #define        li_flags                mi_flags
 /* uses flags as defined in <back-ldap/back-ldap.h> */
-#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)