do_dse_search(struct dse *pdse, Slapi_PBlock *pb, int scope, const Slapi_DN *basedn, Slapi_Filter *filter, char **attrs, int attrsonly)
{
    struct magicSearchStuff stuff;
    stuff.pb = pb;
    stuff.pdse = pdse;
    stuff.scope = scope;
    stuff.basedn = basedn;
    stuff.filter = filter;
    stuff.nentries = 0;
    stuff.attrs = attrs;
    stuff.attrsonly = attrsonly;
    stuff.ss = NULL;
    Operation *pb_op = NULL;
    slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);

    /*
     * If this is a persistent search and the client is only interested in
     * entries that change, we skip looking through the DSE entries.
     */
    if (pb_op == NULL || !operation_is_flag_set(pb_op, OP_FLAG_PS_CHANGESONLY)) {
        if (pdse->dse_rwlock)
            slapi_rwlock_rdlock(pdse->dse_rwlock);
        dse_apply_nolock(pdse, dse_search_filter_entry, (caddr_t)&stuff);
        if (pdse->dse_rwlock)
            slapi_rwlock_unlock(pdse->dse_rwlock);
    }

    if (stuff.ss) /* something was found which matched our criteria */
    {
        Slapi_Entry *e = NULL;
        for (e = dse_search_set_get_next_entry(stuff.ss);
             e;
             e = dse_search_set_get_next_entry(stuff.ss)) {
            int returncode = 0;
            char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";

            if (dse_call_callback(pdse, pb, SLAPI_OPERATION_SEARCH,
                                  DSE_FLAG_PREOP, e, NULL, &returncode, returntext) == SLAPI_DSE_CALLBACK_OK) {
                dse_search_set *ss = NULL;
                slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &ss);
                /* if this is the first entry - allocate dse_search_set structure */
                if (ss == NULL) {
                    ss = dse_search_set_new();
                    slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, ss);
                }
                /* make another reference to e (stuff.ss references it too)
                   the stuff.ss reference is removed by dse_search_set_clean()
                   below, leaving ss as the sole owner of the memory */
                dse_search_set_add_entry(ss, e);
            } else {
                stuff.nentries--; /* rejected entry */
                /* this leaves a freed pointer in stuff.ss, but that's ok because
                   it should never be referenced, and the reference is removed by
                   the call to dse_search_set_clean() below */
                slapi_entry_free(e);
            }
        }
        dse_search_set_clean(stuff.ss);
    }

    /* the pblock ss now contains the "real" search result set and the copies of
       the entries allocated in dse_search_filter_entry; any entries rejected by
       the search callback were freed above by the call to slapi_entry_free() */
    return stuff.nentries;
}
do_dse_search(struct dse *pdse, Slapi_PBlock *pb, int scope, const Slapi_DN *basedn, Slapi_Filter *filter, char **attrs, int attrsonly)
{
    struct magicSearchStuff stuff;
    stuff.pb = pb;
    stuff.pdse = pdse;
    stuff.scope = scope;
    stuff.basedn = basedn;
    stuff.filter = filter;
    stuff.nentries = 0;
    stuff.attrs = attrs;
    stuff.attrsonly = attrsonly;
    stuff.ss = NULL;
    Operation *pb_op = NULL;
    slapi_pblock_get(pb, SLAPI_OPERATION, &pb_op);

     
    if (pb_op == NULL || !operation_is_flag_set(pb_op, OP_FLAG_PS_CHANGESONLY)) {
        if (pdse->dse_rwlock)
            slapi_rwlock_rdlock(pdse->dse_rwlock);
        dse_apply_nolock(pdse, dse_search_filter_entry, (caddr_t)&stuff);
        if (pdse->dse_rwlock)
            slapi_rwlock_unlock(pdse->dse_rwlock);
    }

    if (stuff.ss)  
    {
        Slapi_Entry *e = NULL;
        for (e = dse_search_set_get_next_entry(stuff.ss);
             e;
             e = dse_search_set_get_next_entry(stuff.ss)) {
            int returncode = 0;
            char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";

            if (dse_call_callback(pdse, pb, SLAPI_OPERATION_SEARCH,
                                  DSE_FLAG_PREOP, e, NULL, &returncode, returntext) == SLAPI_DSE_CALLBACK_OK) {
                dse_search_set *ss = NULL;
                slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_SET, &ss);
                 
                if (ss == NULL) {
                    ss = dse_search_set_new();
                    slapi_pblock_set(pb, SLAPI_SEARCH_RESULT_SET, ss);
                }
                 
                dse_search_set_add_entry(ss, e);
            } else {
                stuff.nentries--;  
                 
                slapi_entry_free(e);
            }
        }
        dse_search_set_clean(stuff.ss);
    }

     
    return stuff.nentries;
}