"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' "
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 );
}
**
*/
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);
}
BackendDB *db;
slap_overinst *on;
Filter *orig;
- Filter *rmt;
- Filter *lcl;
Avlnode *list;
int step;
} trans_ctx;
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;
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;
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;
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",
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 */
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;
}