X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Foverlays%2Ftranslucent.c;h=4f38b92f226405dc47d4a1b23e75f9ce310daec8;hb=3792e9ec5999fa6fce5ea29ebdf3ab6de84ed55a;hp=75b2d2012e759242951ccd6b9a27bfc526b7f047;hpb=5313745e771db6cc0fa47e8322cc25af982d0670;p=openldap diff --git a/servers/slapd/overlays/translucent.c b/servers/slapd/overlays/translucent.c index 75b2d2012e..4f38b92f22 100644 --- a/servers/slapd/overlays/translucent.c +++ b/servers/slapd/overlays/translucent.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2004-2008 The OpenLDAP Foundation. + * Copyright 2004-2012 The OpenLDAP Foundation. * Portions Copyright 2005 Symas Corporation. * All rights reserved. * @@ -95,14 +95,6 @@ static ConfigTable translucentcfg[] = { { NULL, NULL, 0, 0, 0, ARG_IGNORED } }; -static ConfigTable transdummy[] = { - { "", "", 0, 0, 0, ARG_IGNORED, - NULL, "( OLcfgGlAt:13 NAME 'olcDatabase' " - "DESC 'The backend type for a database instance' " - "SUP olcBackend SINGLE-VALUE X-ORDERED 'SIBLINGS' )", NULL, NULL }, - { NULL, NULL, 0, 0, 0, ARG_IGNORED } -}; - static ConfigOCs translucentocs[] = { { "( OLcfgOvOc:14.1 " "NAME 'olcTranslucentConfig' " @@ -115,7 +107,7 @@ static ConfigOCs translucentocs[] = { { "( OLcfgOvOc:14.2 " "NAME 'olcTranslucentDatabase' " "DESC 'Translucent target database configuration' " - "AUXILIARY )", Cft_Misc, transdummy, translucent_ldadd }, + "AUXILIARY )", Cft_Misc, olcDatabaseDummy, translucent_ldadd }, { NULL, 0, NULL } }; /* for translucent_init() */ @@ -166,8 +158,9 @@ translucent_cfadd( Operation *op, SlapReply *rs, Entry *e, ConfigArgs *ca ) /* FIXME: should not hardcode "olcDatabase" here */ bv.bv_len = snprintf( ca->cr_msg, sizeof( ca->cr_msg ), - "olcDatabase=%s", ov->db.bd_info->bi_type ); - if ( bv.bv_len < 0 || bv.bv_len >= sizeof( ca->cr_msg ) ) { + "olcDatabase=" SLAP_X_ORDERED_FMT "%s", + 0, ov->db.bd_info->bi_type ); + if ( bv.bv_len >= sizeof( ca->cr_msg ) ) { return -1; } bv.bv_val = ca->cr_msg; @@ -213,6 +206,7 @@ translucent_cf_gen( ConfigArgs *c ) ch_free( (*an)[i].an_name.bv_val ); do { (*an)[i] = (*an)[i+1]; + i++; } while ( !BER_BVISNULL( &(*an)[i].an_name )); } return 0; @@ -289,22 +283,6 @@ void glue_parent(Operation *op) { return; } -/* -** dup_bervarray() -** copy a BerVarray; -*/ - -BerVarray dup_bervarray(BerVarray b) { - int i, len; - BerVarray nb; - for(len = 0; b[len].bv_val; len++); - nb = ch_malloc((len+1) * sizeof(BerValue)); - for(i = 0; i < len; i++) ber_dupbv(&nb[i], &b[i]); - nb[len].bv_val = NULL; - nb[len].bv_len = 0; - return(nb); -} - /* ** free_attr_chain() ** free only the Attribute*, not the contents; @@ -440,6 +418,7 @@ static int translucent_modify(Operation *op, SlapReply *rs) { db = op->o_bd; op->o_bd = &ov->db; + ov->db.be_acl = op->o_bd->be_acl; rc = ov->db.bd_info->bi_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &re); if(rc != LDAP_SUCCESS || re == NULL ) { send_ldap_error((op), rs, LDAP_NO_SUCH_OBJECT, @@ -607,7 +586,7 @@ static int translucent_compare(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; AttributeAssertion *ava = op->orc_ava; - Entry *e; + Entry *e = NULL; BackendDB *db; int rc; @@ -637,6 +616,7 @@ static int translucent_compare(Operation *op, SlapReply *rs) { */ db = op->o_bd; op->o_bd = &ov->db; + ov->db.be_acl = op->o_bd->be_acl; rc = ov->db.bd_info->bi_op_compare(op, rs); op->o_bd = db; @@ -649,7 +629,6 @@ static int translucent_pwmod(Operation *op, SlapReply *rs) { slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; - const struct berval bv_exop_pwmod = BER_BVC(LDAP_EXOP_MODIFY_PASSWD); Entry *e = NULL, *re = NULL; BackendDB *db; int rc = 0; @@ -669,6 +648,7 @@ static int translucent_pwmod(Operation *op, SlapReply *rs) { */ db = op->o_bd; op->o_bd = &ov->db; + ov->db.be_acl = op->o_bd->be_acl; rc = ov->db.bd_info->bi_entry_get_rw(op, &op->o_req_ndn, NULL, NULL, 0, &re); if(rc != LDAP_SUCCESS || re == NULL ) { send_ldap_error((op), rs, LDAP_NO_SUCH_OBJECT, @@ -743,8 +723,6 @@ static int translucent_pwmod(Operation *op, SlapReply *rs) { } static int translucent_exop(Operation *op, SlapReply *rs) { - SlapReply nrs = { REP_RESULT }; - slap_overinst *on = (slap_overinst *) op->o_bd->bd_info; translucent_info *ov = on->on_bi.bi_private; const struct berval bv_exop_pwmod = BER_BVC(LDAP_EXOP_MODIFY_PASSWD); @@ -790,6 +768,8 @@ typedef struct trans_ctx { Filter *orig; Avlnode *list; int step; + int slimit; + AttributeName *attrs; } trans_ctx; static int translucent_search_cb(Operation *op, SlapReply *rs) { @@ -814,6 +794,13 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) { Debug(LDAP_DEBUG_TRACE, "==> translucent_search_cb: %s\n", rs->sr_entry->e_name.bv_val, 0, 0); + op->ors_slimit = tc->slimit + ( tc->slimit > 0 ? 1 : 0 ); + if ( op->ors_attrs == slap_anlist_all_attributes ) { + op->ors_attrs = tc->attrs; + rs->sr_attrs = tc->attrs; + rs->sr_attr_flags = slap_attr_flags( rs->sr_attrs ); + } + on = tc->on; ov = on->on_bi.bi_private; @@ -827,18 +814,16 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) { if ( tc->step & USE_LIST ) { re = tavl_delete( &tc->list, le, entry_dn_cmp ); if ( re ) { - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - } - if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - rs->sr_flags ^= REP_ENTRY_MUSTBEFREED; - entry_free( rs->sr_entry ); - } + rs_flush_entry( op, rs, on ); rc = test_filter( op, re, tc->orig ); if ( rc == LDAP_COMPARE_TRUE ) { rs->sr_flags |= REP_ENTRY_MUSTBEFREED; rs->sr_entry = re; + + if ( tc->slimit >= 0 && rs->sr_nentries >= tc->slimit ) { + return LDAP_SIZELIMIT_EXCEEDED; + } + return SLAP_CB_CONTINUE; } else { entry_free( re ); @@ -858,17 +843,11 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) { } else { /* Else we have remote, get local */ op->o_bd = tc->db; + le = NULL; rc = overlay_entry_get_ov(op, &rs->sr_entry->e_nname, NULL, NULL, 0, &le, on); if ( rc == LDAP_SUCCESS && le ) { re = entry_dup( rs->sr_entry ); - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - } - if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - rs->sr_flags ^= REP_ENTRY_MUSTBEFREED; - entry_free( rs->sr_entry ); - } + rs_flush_entry( op, rs, on ); } else { le = NULL; } @@ -888,12 +867,16 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) { for(ax = le->e_attrs; ax; ax = ax->a_next) { for(a = re->e_attrs; a; a = a->a_next) { if(a->a_desc == ax->a_desc) { + test_f = 1; if(a->a_vals != a->a_nvals) ber_bvarray_free(a->a_nvals); ber_bvarray_free(a->a_vals); - a->a_vals = dup_bervarray(ax->a_vals); - a->a_nvals = (ax->a_vals == ax->a_nvals) ? - a->a_vals : dup_bervarray(ax->a_nvals); + ber_bvarray_dup_x( &a->a_vals, ax->a_vals, NULL ); + if ( ax->a_vals == ax->a_nvals ) { + a->a_nvals = a->a_vals; + } else { + ber_bvarray_dup_x( &a->a_nvals, ax->a_nvals, NULL ); + } break; } } @@ -904,14 +887,7 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) { } /* Dispose of local entry */ if ( tc->step & LCL_SIDE ) { - if ( rs->sr_flags & REP_ENTRY_MUSTRELEASE ) { - rs->sr_flags ^= REP_ENTRY_MUSTRELEASE; - overlay_entry_release_ov( op, rs->sr_entry, 0, on ); - } - if ( rs->sr_flags & REP_ENTRY_MUSTBEFREED ) { - rs->sr_flags ^= REP_ENTRY_MUSTBEFREED; - entry_free( rs->sr_entry ); - } + rs_flush_entry(op, rs, on); } else { overlay_entry_release_ov(op, le, 0, on); } @@ -968,6 +944,11 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) { } op->o_bd = db; + + if ( rc == SLAP_CB_CONTINUE && tc->slimit >= 0 && rs->sr_nentries >= tc->slimit ) { + return LDAP_SIZELIMIT_EXCEEDED; + } + return rc; } @@ -1104,16 +1085,22 @@ static int translucent_search(Operation *op, SlapReply *rs) { cb.sc_private = &tc; cb.sc_next = op->o_callback; + ov->db.be_acl = op->o_bd->be_acl; tc.db = op->o_bd; tc.on = on; tc.orig = op->ors_filter; tc.list = NULL; tc.step = 0; + tc.slimit = op->ors_slimit; + tc.attrs = NULL; fbv = op->ors_filterstr; op->o_callback = &cb; if ( fr || !fl ) { + tc.attrs = op->ors_attrs; + op->ors_slimit = SLAP_NO_LIMIT; + op->ors_attrs = slap_anlist_all_attributes; op->o_bd = &ov->db; tc.step |= RMT_SIDE; if ( fl ) { @@ -1122,6 +1109,7 @@ static int translucent_search(Operation *op, SlapReply *rs) { filter2bv_x( op, fr, &op->ors_filterstr ); } rc = ov->db.bd_info->bi_op_search(op, rs); + op->ors_attrs = tc.attrs; op->o_bd = tc.db; if ( fl ) { op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); @@ -1137,6 +1125,9 @@ static int translucent_search(Operation *op, SlapReply *rs) { op->ors_filterstr = fbv; op->ors_filter = tc.orig; op->o_callback = cb.sc_next; + rs->sr_attrs = op->ors_attrs; + rs->sr_attr_flags = slap_attr_flags( rs->sr_attrs ); + /* Send out anything remaining on the list and finish */ if ( tc.step & USE_LIST ) { if ( tc.list ) { @@ -1145,22 +1136,25 @@ static int translucent_search(Operation *op, SlapReply *rs) { av = tavl_end( tc.list, TAVL_DIR_LEFT ); while ( av ) { rs->sr_entry = av->avl_data; - rc = test_filter( op, rs->sr_entry, op->ors_filter ); - if ( rc == LDAP_COMPARE_TRUE ) { + if ( rc == LDAP_SUCCESS && LDAP_COMPARE_TRUE == + test_filter( op, rs->sr_entry, op->ors_filter )) + { 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_flags = 0; rs->sr_entry = NULL; } send_ldap_result( op, rs ); } + op->ors_slimit = tc.slimit; + /* Free in reverse order */ if ( fl ) trans_filter_free( op, fl ); @@ -1201,6 +1195,7 @@ static int translucent_bind(Operation *op, SlapReply *rs) { db = op->o_bd; op->o_bd = &ov->db; + ov->db.be_acl = op->o_bd->be_acl; rc = ov->db.bd_info->bi_op_bind(op, rs); op->o_bd = db; @@ -1276,7 +1271,6 @@ static int translucent_db_init(BackendDB *be, ConfigReply *cr) { on->on_bi.bi_private = ov; ov->db = *be; ov->db.be_private = NULL; - ov->db.be_pcl_mutexp = &ov->db.be_pcl_mutex; ov->defer_db_open = 1; if ( !backend_db_init( "ldap", &ov->db, -1, NULL )) { @@ -1366,6 +1360,7 @@ translucent_db_destroy( BackendDB *be, ConfigReply *cr ) backend_stopdown_one( &ov->db ); } + ldap_pvt_thread_mutex_destroy( &ov->db.be_pcl_mutex ); ch_free(ov); on->on_bi.bi_private = NULL; }