- /*
- * modify the filter to be something like this:
- *
- * parent=baseobject & originalfilter
- */
-
- f = (Filter *) ch_malloc( sizeof(Filter) );
- f->f_next = NULL;
- f->f_choice = LDAP_FILTER_AND;
- f->f_and = (Filter *) ch_malloc( sizeof(Filter) );
- f->f_and->f_choice = LDAP_FILTER_EQUALITY;
- f->f_and->f_ava.ava_type = ch_strdup( "id2children" );
- sprintf( buf, "%ld", e != NULL ? e->e_id : 0 );
- f->f_and->f_ava.ava_value.bv_val = ch_strdup( buf );
- f->f_and->f_ava.ava_value.bv_len = strlen( buf );
- f->f_and->f_next = filter;
-
- /* from here, it's just like subtree_candidates */
- candidates = subtree_candidates( be, conn, op, base, f, attrs,
- attrsonly, matched, e, err, 0 );
-
- /* free up just the filter stuff we allocated above */
- f->f_and->f_next = NULL;
- filter_free( f );
-
- /* free entry and reader lock */
- cache_return_entry_r( &li->li_cache, e );
- return( candidates );
-}
-
-static IDList *
-subtree_candidates(
- Backend *be,
- Connection *conn,
- Operation *op,
- char *base,
- Filter *filter,
- char **attrs,
- int attrsonly,
- char **matched,
- Entry *e,
- int *err,
- int lookupbase
-)
-{
- struct ldbminfo *li = (struct ldbminfo *) be->be_private;
- Filter *f, **filterarg_ptr;
- IDList *candidates;
-
- Debug(LDAP_DEBUG_TRACE, "subtree_candidates: base: %s\n",
- base ? base : "NULL", 0, 0);
-
- /*
- * get the base object - unless we already have it (from one-level).
- * also, unless this is a one-level search or a subtree search
- * starting at the very top of our subtree, we need to modify the
- * filter to be something like this:
- *
- * dn=*baseobjectdn & (originalfilter | ref=*)
- *
- * the "objectclass=referral" part is used to select referrals to return
- */
-
- *err = LDAP_SUCCESS;
- f = NULL;
- if ( lookupbase ) {
- if ( base != NULL && *base != '\0' &&
- (e = dn2entry_r( be, base, matched )) == NULL )
- {
- *err = LDAP_NO_SUCH_OBJECT;
- return( NULL );
- }
-
- if (e) {
- cache_return_entry_r( &li->li_cache, e );
- }
-
- f = (Filter *) ch_malloc( sizeof(Filter) );
- f->f_next = NULL;
- f->f_choice = LDAP_FILTER_OR;
- f->f_or = (Filter *) ch_malloc( sizeof(Filter) );
- f->f_or->f_choice = LDAP_FILTER_EQUALITY;
- f->f_or->f_avtype = ch_strdup( "objectclass" );
- /* Patch to use normalized uppercase */
- f->f_or->f_avvalue.bv_val = ch_strdup( "REFERRAL" );
- f->f_or->f_avvalue.bv_len = strlen( "REFERRAL" );
- filterarg_ptr = &f->f_or->f_next;
- *filterarg_ptr = filter;
- filter = f;
-
- if ( ! be_issuffix( be, base ) ) {
- f = (Filter *) ch_malloc( sizeof(Filter) );
- f->f_next = NULL;
- f->f_choice = LDAP_FILTER_AND;
- f->f_and = (Filter *) ch_malloc( sizeof(Filter) );
- f->f_and->f_choice = LDAP_FILTER_SUBSTRINGS;
- f->f_and->f_sub_type = ch_strdup( "dn" );
- f->f_and->f_sub_initial = NULL;
- f->f_and->f_sub_any = NULL;
- f->f_and->f_sub_final = ch_strdup( base );
- value_normalize( f->f_and->f_sub_final, SYNTAX_CIS );
- f->f_and->f_next = filter;
- filter = f;
- }