+ switch ( f->f_result ) {
+ case LDAP_COMPARE_FALSE:
+ tmp = ber_bvfalse;
+ break;
+
+ case LDAP_COMPARE_TRUE:
+ tmp = ber_bvtrue;
+ break;
+
+ case SLAPD_COMPARE_UNDEFINED:
+ tmp = ber_bvundefined;
+ break;
+
+ default:
+ tmp = ber_bverror;
+ break;
+ }
+
+ ber_dupbv_x( fstr, &tmp, op->o_tmpmemctx );
+ break;
+
+ default:
+ ber_dupbv_x( fstr, &ber_bvunknown, op->o_tmpmemctx );
+ break;
+ }
+}
+
+void
+filter2bv( Filter *f, struct berval *fstr )
+{
+ Operation op;
+ Opheader ohdr;
+
+ op.o_hdr = &ohdr;
+ op.o_tmpmemctx = NULL;
+ op.o_tmpmfuncs = &ch_mfuncs;
+
+ filter2bv_x( &op, f, fstr );
+}
+
+Filter *
+filter_dup( Filter *f, void *memctx )
+{
+ BerMemoryFunctions *mf = &slap_sl_mfuncs;
+ Filter *n;
+
+ if ( !f )
+ return NULL;
+
+ n = mf->bmf_malloc( sizeof(Filter), memctx );
+ n->f_choice = f->f_choice;
+ n->f_next = NULL;
+
+ switch( f->f_choice & SLAPD_FILTER_MASK ) {
+ case SLAPD_FILTER_COMPUTED:
+ n->f_result = f->f_result;
+ break;
+ case LDAP_FILTER_PRESENT:
+ if ( f->f_desc->ad_flags & SLAP_DESC_TEMPORARY )
+ n->f_desc = slap_bv2tmp_ad( &f->f_desc->ad_cname, memctx );
+ else
+ n->f_desc = f->f_desc;
+ break;
+ case LDAP_FILTER_EQUALITY:
+ case LDAP_FILTER_GE:
+ case LDAP_FILTER_LE:
+ case LDAP_FILTER_APPROX:
+ /* Should this be ava_dup() ? */
+ n->f_ava = mf->bmf_calloc( 1, sizeof(AttributeAssertion), memctx );
+ *n->f_ava = *f->f_ava;
+ if ( f->f_av_desc->ad_flags & SLAP_DESC_TEMPORARY )
+ n->f_av_desc = slap_bv2tmp_ad( &f->f_av_desc->ad_cname, memctx );
+ ber_dupbv_x( &n->f_av_value, &f->f_av_value, memctx );
+ break;
+ case LDAP_FILTER_SUBSTRINGS:
+ n->f_sub = mf->bmf_calloc( 1, sizeof(SubstringsAssertion), memctx );
+ if ( f->f_sub_desc->ad_flags & SLAP_DESC_TEMPORARY )
+ n->f_sub_desc = slap_bv2tmp_ad( &f->f_sub_desc->ad_cname, memctx );
+ else
+ n->f_sub_desc = f->f_sub_desc;
+ if ( !BER_BVISNULL( &f->f_sub_initial ))
+ ber_dupbv_x( &n->f_sub_initial, &f->f_sub_initial, memctx );
+ if ( f->f_sub_any ) {
+ int i;
+ for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ );
+ n->f_sub_any = mf->bmf_malloc(( i+1 )*sizeof( struct berval ),
+ memctx );
+ for ( i = 0; !BER_BVISNULL( &f->f_sub_any[i] ); i++ ) {
+ ber_dupbv_x( &n->f_sub_any[i], &f->f_sub_any[i], memctx );
+ }
+ BER_BVZERO( &n->f_sub_any[i] );
+ }
+ if ( !BER_BVISNULL( &f->f_sub_final ))
+ ber_dupbv_x( &n->f_sub_final, &f->f_sub_final, memctx );
+ break;
+ case LDAP_FILTER_EXT: {
+ /* Should this be mra_dup() ? */
+ ber_len_t length;
+ length = sizeof(MatchingRuleAssertion);
+ if ( !BER_BVISNULL( &f->f_mr_rule_text ))
+ length += f->f_mr_rule_text.bv_len + 1;
+ n->f_mra = mf->bmf_calloc( 1, length, memctx );
+ *n->f_mra = *f->f_mra;
+ if ( f->f_mr_desc && ( f->f_sub_desc->ad_flags & SLAP_DESC_TEMPORARY ))
+ n->f_mr_desc = slap_bv2tmp_ad( &f->f_mr_desc->ad_cname, memctx );
+ ber_dupbv_x( &n->f_mr_value, &f->f_mr_value, memctx );
+ if ( !BER_BVISNULL( &f->f_mr_rule_text )) {
+ n->f_mr_rule_text.bv_val = (char *)(n->f_mra+1);
+ AC_MEMCPY(n->f_mr_rule_text.bv_val,
+ f->f_mr_rule_text.bv_val, f->f_mr_rule_text.bv_len );
+ }
+ } break;
+ case LDAP_FILTER_AND:
+ case LDAP_FILTER_OR:
+ case LDAP_FILTER_NOT: {
+ Filter **p;
+ for ( p = &n->f_list, f = f->f_list; f; f = f->f_next ) {
+ *p = filter_dup( f, memctx );
+ p = &(*p)->f_next;
+ }
+ } break;
+ }
+ return n;
+}
+
+static int
+get_simple_vrFilter(
+ Operation *op,
+ BerElement *ber,
+ ValuesReturnFilter **filt,
+ const char **text )
+{
+ ber_tag_t tag;
+ ber_len_t len;
+ int err;
+ ValuesReturnFilter vrf;
+
+ Debug( LDAP_DEBUG_FILTER, "begin get_simple_vrFilter\n", 0, 0, 0 );
+
+ tag = ber_peek_tag( ber, &len );
+
+ if( tag == LBER_ERROR ) {
+ *text = "error decoding filter";
+ return SLAPD_DISCONNECT;
+ }
+
+ vrf.vrf_next = NULL;
+
+ err = LDAP_SUCCESS;
+ vrf.vrf_choice = tag;
+
+ switch ( vrf.vrf_choice ) {
+ case LDAP_FILTER_EQUALITY:
+ Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 );
+ err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_EQUALITY, text );
+ if ( err != LDAP_SUCCESS ) {
+ break;
+ }
+
+ assert( vrf.vrf_ava != NULL );
+ break;
+
+ case LDAP_FILTER_SUBSTRINGS:
+ Debug( LDAP_DEBUG_FILTER, "SUBSTRINGS\n", 0, 0, 0 );
+ err = get_ssa( op, ber, (Filter *)&vrf, text );
+ break;
+
+ case LDAP_FILTER_GE:
+ Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 );
+ err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_ORDERING, text );
+ if ( err != LDAP_SUCCESS ) {
+ break;
+ }
+ break;
+
+ case LDAP_FILTER_LE:
+ Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 );
+ err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_ORDERING, text );
+ if ( err != LDAP_SUCCESS ) {
+ break;
+ }
+ break;
+
+ case LDAP_FILTER_PRESENT: {
+ struct berval type;
+
+ Debug( LDAP_DEBUG_FILTER, "PRESENT\n", 0, 0, 0 );
+ if ( ber_scanf( ber, "m", &type ) == LBER_ERROR ) {
+ err = SLAPD_DISCONNECT;
+ *text = "error decoding filter";
+ break;
+ }
+
+ vrf.vrf_desc = NULL;
+ err = slap_bv2ad( &type, &vrf.vrf_desc, text );
+
+ if( err != LDAP_SUCCESS ) {
+ vrf.vrf_choice |= SLAPD_FILTER_UNDEFINED;
+ err = slap_bv2undef_ad( &type, &vrf.vrf_desc, text,
+ SLAP_AD_PROXIED);
+
+ if( err != LDAP_SUCCESS ) {
+ /* unrecognized attribute description or other error */
+ Debug( LDAP_DEBUG_ANY,
+ "get_simple_vrFilter: conn %lu unknown "
+ "attribute type=%s (%d)\n",
+ op->o_connid, type.bv_val, err );
+
+ vrf.vrf_choice = SLAPD_FILTER_COMPUTED;
+ vrf.vrf_result = LDAP_COMPARE_FALSE;
+ err = LDAP_SUCCESS;
+ break;
+ }
+ }
+ } break;
+
+ case LDAP_FILTER_APPROX:
+ Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 );
+ err = get_ava( op, ber, (Filter *)&vrf, SLAP_MR_EQUALITY_APPROX, text );
+ if ( err != LDAP_SUCCESS ) {
+ break;
+ }
+ break;
+
+ case LDAP_FILTER_EXT:
+ Debug( LDAP_DEBUG_FILTER, "EXTENSIBLE\n", 0, 0, 0 );
+
+ err = get_mra( op, ber, (Filter *)&vrf, text );
+ if ( err != LDAP_SUCCESS ) {
+ break;
+ }
+
+ assert( vrf.vrf_mra != NULL );