]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/translucent.c
For refresh_purge, only delete entry if ours is the last queryid on it.
[openldap] / servers / slapd / overlays / translucent.c
index 92d9a211517b2f9d65ac73a18a5624b37edee06c..f7c443631ff5608c12e28aa6fd52462724050437 100644 (file)
@@ -281,22 +281,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;
@@ -785,6 +769,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) {
@@ -809,6 +795,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;
 
@@ -834,6 +827,11 @@ static int translucent_search_cb(Operation *op, SlapReply *rs) {
                                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 );
@@ -883,12 +881,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;
                                }
                        }
@@ -963,6 +965,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;
 }
 
@@ -1105,11 +1112,16 @@ static int translucent_search(Operation *op, SlapReply *rs) {
        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 ) {
@@ -1118,6 +1130,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 );
@@ -1133,6 +1146,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 ) {
@@ -1157,6 +1173,8 @@ static int translucent_search(Operation *op, SlapReply *rs) {
                send_ldap_result( op, rs );
        }
 
+       op->ors_slimit = tc.slimit;
+
        /* Free in reverse order */
        if ( fl )
                trans_filter_free( op, fl );