]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/translucent.c
Avoid use of uninitialized variable 'e' after failed overlay_entry_get_ov().
[openldap] / servers / slapd / overlays / translucent.c
index 9d88129f40660f56e6bb0bee61be841e832d9458..3fadbbf6b1b935031ef6fa67e5cb2702e7a9d330 100644 (file)
@@ -94,7 +94,8 @@ static ConfigOCs translucentocs[] = {
          "NAME 'olcTranslucentConfig' "
          "DESC 'Translucent configuration' "
          "SUP olcOverlayConfig "
-         "MAY ( olcTranslucentStrict $ olcTranslucentNoGlue ) )",
+         "MAY ( olcTranslucentStrict $ olcTranslucentNoGlue $"
+         " olcTranslucentLocal $ olcTranslucentRemote ) )",
          Cft_Overlay, translucentcfg, NULL, translucent_cfadd },
        { "( OLcfgOvOc:14.2 "
          "NAME 'olcTranslucentDatabase' "
@@ -182,6 +183,8 @@ translucent_cf_gen( ConfigArgs *c )
                an = &ov->remote;
 
        if ( c->op == SLAP_CONFIG_EMIT ) {
+               if ( !*an )
+                       return 1;
                for ( i = 0; !BER_BVISNULL(&(*an)[i].an_name); i++ ) {
                        value_add_one( &c->rvalue_vals, &(*an)[i].an_name );
                }
@@ -602,7 +605,7 @@ static int translucent_compare(Operation *op, SlapReply *rs) {
 **
 */
        rc = overlay_entry_get_ov(op, &op->o_req_ndn, NULL, ava->aa_desc, 0, &e, on);
-       if(e && rc == LDAP_SUCCESS) {
+       if(rc == LDAP_SUCCESS && e) {
                overlay_entry_release_ov(op, e, 0, on);
                return(SLAP_CB_CONTINUE);
        }
@@ -648,8 +651,6 @@ typedef struct trans_ctx {
        BackendDB *db;
        slap_overinst *on;
        Filter *orig;
-       Filter *rmt;
-       Filter *lcl;
        Avlnode *list;
        int step;
 } trans_ctx;
@@ -785,16 +786,13 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) {
                                re->e_attrs = as;
                        }
                }
+               /* If both filters, save entry for later */
                if ( tc->step == (USE_LIST|RMT_SIDE) ) {
-                       rc = test_filter( op, re, tc->orig );
-                       if ( rc == LDAP_COMPARE_TRUE ) {
-                               tavl_insert( &tc->list, re, entry_dn_cmp, avl_dup_error );
-                       } else {
-                               entry_free( re );
-                       }
+                       tavl_insert( &tc->list, re, entry_dn_cmp, avl_dup_error );
                        rs->sr_entry = NULL;
                        rc = 0;
                } else {
+               /* send it now */
                        rs->sr_entry = re;
                        rs->sr_flags |= REP_ENTRY_MUSTBEFREED;
                        rc = SLAP_CB_CONTINUE;
@@ -886,7 +884,7 @@ trans_filter_dup(Operation *op, Filter *f, AttributeName *an)
                        return NULL;
                }
                /* Only 1 element in this list */
-               if ((f->f_choice & SLAPD_FILTER_MASK) != LDAP_FILTER_NOT &&
+               if ((n->f_choice & SLAPD_FILTER_MASK) != LDAP_FILTER_NOT &&
                        !n->f_list->f_next ) {
                        f = n->f_list;
                        *n = *f;
@@ -898,6 +896,35 @@ trans_filter_dup(Operation *op, Filter *f, AttributeName *an)
        return n;
 }
 
+static void
+trans_filter_free( Operation *op, Filter *f )
+{
+       Filter *n, *p, *next;
+
+       f->f_choice &= SLAPD_FILTER_MASK;
+
+       switch( f->f_choice ) {
+       case LDAP_FILTER_AND:
+       case LDAP_FILTER_OR:
+       case LDAP_FILTER_NOT:
+               /* Free in reverse order */
+               n = NULL;
+               for ( p = f->f_list; p; p = next ) {
+                       next = p->f_next;
+                       p->f_next = n;
+                       n = p;
+               }
+               for ( p = n; p; p = next ) {
+                       next = p->f_next;
+                       trans_filter_free( op, p );
+               }
+               break;
+       default:
+               break;
+       }
+       op->o_tmpfree( f, op->o_tmpmemctx );
+}
+
 /*
 ** translucent_search()
 **     search via captive backend;
@@ -911,6 +938,7 @@ static int translucent_search(Operation *op, SlapReply *rs) {
        slap_callback cb = { NULL, NULL, NULL, NULL };
        trans_ctx tc;
        Filter *fl, *fr;
+       struct berval fbv;
        int rc = 0;
 
        Debug(LDAP_DEBUG_TRACE, "==> translucent_search: <%s> %s\n",
@@ -931,27 +959,34 @@ static int translucent_search(Operation *op, SlapReply *rs) {
        tc.db = op->o_bd;
        tc.on = on;
        tc.orig = op->ors_filter;
-       tc.rmt = fr;
-       tc.lcl = fl;
        tc.list = NULL;
        tc.step = 0;
+       fbv = op->ors_filterstr;
 
        op->o_callback = &cb;
 
        if ( fr || !fl ) {
-               tc.step |= RMT_SIDE;
-               if ( fl ) tc.step |= USE_LIST;
                op->o_bd = &ov->db;
-               if ( fl )
+               tc.step |= RMT_SIDE;
+               if ( fl ) {
+                       tc.step |= USE_LIST;
                        op->ors_filter = fr;
+                       filter2bv_x( op, fr, &op->ors_filterstr );
+               }
                rc = ov->db.bd_info->bi_op_search(op, rs);
                op->o_bd = tc.db;
+               if ( fl ) {
+                       op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+               }
        }
        if ( fl && !rc ) {
                tc.step |= LCL_SIDE;
                op->ors_filter = fl;
+               filter2bv_x( op, fl, &op->ors_filterstr );
                rc = overlay_op_walk( op, rs, op_search, on->on_info, on->on_next );
+               op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
        }
+       op->ors_filterstr = fbv;
        op->ors_filter = tc.orig;
        op->o_callback = cb.sc_next;
        /* Send out anything remaining on the list and finish */
@@ -961,17 +996,29 @@ static int translucent_search(Operation *op, SlapReply *rs) {
 
                        av = tavl_end( tc.list, TAVL_DIR_LEFT );
                        while ( av ) {
-                               rs->sr_flags = REP_ENTRY_MUSTBEFREED;
                                rs->sr_entry = av->avl_data;
-                               rc = send_search_entry( op, rs );
-                               if ( rc ) break;
+                               rc = test_filter( op, rs->sr_entry, op->ors_filter );
+                               if ( rc == LDAP_COMPARE_TRUE ) {
+                                       rs->sr_flags = REP_ENTRY_MUSTBEFREED;
+                                       rc = send_search_entry( op, rs );
+                                       if ( rc ) break;
+                               } else {
+                                       entry_free( rs->sr_entry );
+                               }
                                av = tavl_next( av, TAVL_DIR_RIGHT );
                        }
                        tavl_free( tc.list, NULL );
+                       rs->sr_entry = NULL;
                }
                send_ldap_result( op, rs );
        }
 
+       /* Free in reverse order */
+       if ( fl )
+               trans_filter_free( op, fl );
+       if ( fr )
+               trans_filter_free( op, fr );
+
        return rc;
 }