--- servers/slapd/filter.c 2001/06/02 00:47:49 1.13.4.7 +++ servers/slapd/filter.c 2000/05/15 21:36:37 1.30 @@ -1,5 +1,5 @@ /* filter.c - routines for parsing and dealing with filters */ -/* $OpenLDAP: pkg/ldap/servers/slapd/filter.c,v 1.13.4.6 2000/10/11 02:43:58 kurt Exp $ */ +/* $OpenLDAP: pkg/ldap/servers/slapd/filter.c,v 1.29 2000/05/15 17:28:26 kurt Exp $ */ /* * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file @@ -19,18 +19,13 @@ static int get_filter_list( BerElement *ber, Filter **f, char **fstr, - const char **text ); - + char **text ); static int get_substring_filter( Connection *conn, BerElement *ber, Filter *f, char **fstr, - const char **text ); - -static int filter_escape_value( - struct berval *in, - struct berval *out ); + char **text ); int get_filter( @@ -38,14 +33,13 @@ get_filter( BerElement *ber, Filter **filt, char **fstr, - const char **text ) + char **text ) { ber_tag_t tag; ber_len_t len; int err; Filter *f; char *ftmp = NULL; - struct berval escaped; Debug( LDAP_DEBUG_FILTER, "begin get_filter\n", 0, 0, 0 ); @@ -100,24 +94,27 @@ get_filter( case LDAP_FILTER_EQUALITY: Debug( LDAP_DEBUG_FILTER, "EQUALITY\n", 0, 0, 0 ); - err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY, text ); - if ( err != LDAP_SUCCESS ) { + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "error decoding filter"; break; } - assert( f->f_ava != NULL ); - - filter_escape_value( f->f_av_value, &escaped ); - +#ifdef SLAPD_SCHEMA_NOT_COMPAT *fstr = ch_malloc( sizeof("(=)") + f->f_av_desc->ad_cname->bv_len - + escaped.bv_len ); + + f->f_av_value->bv_len ); sprintf( *fstr, "(%s=%s)", f->f_av_desc->ad_cname->bv_val, - escaped.bv_val ); + f->f_av_value->bv_val ); - ber_memfree( escaped.bv_val ); +#else + *fstr = ch_malloc( sizeof("(=)") + + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s=%s)", f->f_avtype, + f->f_avvalue.bv_val ); +#endif break; case LDAP_FILTER_SUBSTRINGS: @@ -128,44 +125,53 @@ get_filter( case LDAP_FILTER_GE: Debug( LDAP_DEBUG_FILTER, "GE\n", 0, 0, 0 ); - err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text ); - if ( err != LDAP_SUCCESS ) { + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "decoding filter error"; break; } - filter_escape_value( f->f_av_value, &escaped ); - +#ifdef SLAPD_SCHEMA_NOT_COMPAT *fstr = ch_malloc( sizeof("(>=)") + f->f_av_desc->ad_cname->bv_len - + escaped.bv_len ); + + f->f_av_value->bv_len ); sprintf( *fstr, "(%s>=%s)", f->f_av_desc->ad_cname->bv_val, - escaped.bv_val ); + f->f_av_value->bv_val ); - ber_memfree( escaped.bv_val ); +#else + *fstr = ch_malloc( sizeof("(>=)") + + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s>=%s)", f->f_avtype, + f->f_avvalue.bv_val ); +#endif break; case LDAP_FILTER_LE: Debug( LDAP_DEBUG_FILTER, "LE\n", 0, 0, 0 ); - err = get_ava( ber, &f->f_ava, SLAP_MR_ORDERING, text ); - if ( err != LDAP_SUCCESS ) { + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "decoding filter error"; break; } - - filter_escape_value( f->f_av_value, &escaped ); - +#ifdef SLAPD_SCHEMA_NOT_COMPAT *fstr = ch_malloc( sizeof("(<=)") + f->f_av_desc->ad_cname->bv_len - + escaped.bv_len ); + + f->f_av_value->bv_len ); sprintf( *fstr, "(%s<=%s)", f->f_av_desc->ad_cname->bv_val, - escaped.bv_val ); + f->f_av_value->bv_val ); - ber_memfree( escaped.bv_val ); +#else + *fstr = ch_malloc( sizeof("(<=)") + + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s<=%s)", f->f_avtype, + f->f_avvalue.bv_val ); +#endif break; case LDAP_FILTER_PRESENT: { @@ -179,42 +185,60 @@ get_filter( break; } - f->f_desc = NULL; - err = slap_bv2ad( &type, &f->f_desc, text ); +#ifdef SLAPD_SCHEMA_NOT_COMPAT + { + char *text; + int rc; + + err = slap_bv2ad( &type, &f->f_desc, &text ); + + if( err != LDAP_SUCCESS ) { + ch_free( type.bv_val ); + break; + } - if( err != LDAP_SUCCESS ) { ch_free( type.bv_val ); - break; } - ch_free( type.bv_val ); - *fstr = ch_malloc( sizeof("(=*)") + f->f_desc->ad_cname->bv_len ); sprintf( *fstr, "(%s=*)", f->f_desc->ad_cname->bv_val ); +#else + f->f_type = type.bv_val; + err = LDAP_SUCCESS; + attr_normalize( f->f_type ); + *fstr = ch_malloc( sizeof("(=*)") + + strlen( f->f_type ) ); + sprintf( *fstr, "(%s=*)", f->f_type ); +#endif } break; case LDAP_FILTER_APPROX: Debug( LDAP_DEBUG_FILTER, "APPROX\n", 0, 0, 0 ); - err = get_ava( ber, &f->f_ava, SLAP_MR_EQUALITY_APPROX, text ); - if ( err != LDAP_SUCCESS ) { + if ( (err = get_ava( ber, &f->f_ava )) != LDAP_SUCCESS ) { + *text = "decoding filter error"; break; } - filter_escape_value( f->f_av_value, &escaped ); - +#ifdef SLAPD_SCHEMA_NOT_COMPAT *fstr = ch_malloc( sizeof("(~=)") + f->f_av_desc->ad_cname->bv_len - + escaped.bv_len ); + + f->f_av_value->bv_len ); sprintf( *fstr, "(%s~=%s)", f->f_av_desc->ad_cname->bv_val, - escaped.bv_val ); + f->f_av_value->bv_val ); - ber_memfree( escaped.bv_val ); +#else + *fstr = ch_malloc( sizeof("(~=)") + + strlen( f->f_avtype ) + + f->f_avvalue.bv_len); + sprintf( *fstr, "(%s~=%s)", f->f_avtype, + f->f_avvalue.bv_val ); +#endif break; case LDAP_FILTER_AND: @@ -257,15 +281,13 @@ get_filter( case LDAP_FILTER_EXT: /* not yet implemented */ Debug( LDAP_DEBUG_ANY, "extensible match not yet implemented.\n", - 0, 0, 0 ); - (void) ber_skip_tag( ber, &len ); + f->f_choice, 0, 0 ); f->f_choice = SLAPD_FILTER_COMPUTED; f->f_result = SLAPD_COMPARE_UNDEFINED; *fstr = ch_strdup( "(extended)" ); break; default: - (void) ber_skip_tag( ber, &len ); Debug( LDAP_DEBUG_ANY, "get_filter: unknown filter type=%lu\n", f->f_choice, 0, 0 ); f->f_choice = SLAPD_FILTER_COMPUTED; @@ -274,36 +296,23 @@ get_filter( break; } - free( ftmp ); - if ( err != LDAP_SUCCESS ) { + free( (char *) f ); if ( *fstr != NULL ) { free( *fstr ); } - - if( err != SLAPD_DISCONNECT ) { - /* ignore error */ - f->f_choice = SLAPD_FILTER_COMPUTED; - f->f_result = SLAPD_COMPARE_UNDEFINED; - *fstr = ch_strdup( "(badfilter)" ); - err = LDAP_SUCCESS; - *filt = f; - - } else { - free(f); - } } else { *filt = f; } + free( ftmp ); + Debug( LDAP_DEBUG_FILTER, "end get_filter %d\n", err, 0, 0 ); return( err ); } static int -get_filter_list( Connection *conn, BerElement *ber, - Filter **f, char **fstr, - const char **text ) +get_filter_list( Connection *conn, BerElement *ber, Filter **f, char **fstr, char **text ) { Filter **new; int err; @@ -344,164 +353,118 @@ get_substring_filter( BerElement *ber, Filter *f, char **fstr, - const char **text + char **text ) { ber_tag_t tag; ber_len_t len; ber_tag_t rc; - struct berval *value; - struct berval escaped; + struct berval *val; char *last; - struct berval type; - struct berval *nvalue; + char *type; + int syntax; + *text = "error decoding filter"; Debug( LDAP_DEBUG_FILTER, "begin get_substring_filter\n", 0, 0, 0 ); - if ( ber_scanf( ber, "{o" /*}*/, &type ) == LBER_ERROR ) { + if ( ber_scanf( ber, "{a" /*}*/, &type ) == LBER_ERROR ) { return SLAPD_DISCONNECT; } - f->f_sub = ch_calloc( 1, sizeof(SubstringsAssertion) ); - f->f_sub_desc = NULL; - rc = slap_bv2ad( &type, &f->f_sub_desc, text ); - - ch_free( type.bv_val ); - - if( rc != LDAP_SUCCESS ) { - text = NULL; - ch_free( f->f_sub ); - f->f_choice = SLAPD_FILTER_COMPUTED; - f->f_result = SLAPD_COMPARE_UNDEFINED; - *fstr = ch_strdup( "(undefined)" ); - return LDAP_SUCCESS; - } +#ifdef SLAPD_SCHEMA_NOT_COMPAT + /* not yet implemented */ +#else + f->f_sub_type = type; + attr_normalize( f->f_sub_type ); + + /* should get real syntax and see if we have a substring matching rule */ + syntax = attr_syntax( f->f_sub_type ); +#endif f->f_sub_initial = NULL; f->f_sub_any = NULL; f->f_sub_final = NULL; +#ifdef SLAPD_SCHEMA_NOT_COMPAT + /* not yet implemented */ +#else if( fstr ) { - *fstr = ch_malloc( sizeof("(=" /*)*/) + - f->f_sub_desc->ad_cname->bv_len ); - sprintf( *fstr, "(%s=" /*)*/, f->f_sub_desc->ad_cname->bv_val ); + *fstr = ch_malloc( strlen( f->f_sub_type ) + 3 ); + sprintf( *fstr, "(%s=" /*)*/, f->f_sub_type ); } +#endif for ( tag = ber_first_element( ber, &len, &last ); tag != LBER_DEFAULT; tag = ber_next_element( ber, &len, last ) ) { - unsigned usage; - - rc = ber_scanf( ber, "O", &value ); + rc = ber_scanf( ber, "O", &val ); if ( rc == LBER_ERROR ) { rc = SLAPD_DISCONNECT; goto return_error; } - if ( value == NULL || value->bv_len == 0 ) { - ber_bvfree( value ); + if ( val == NULL || val->bv_len == 0 ) { + ber_bvfree( val ); rc = LDAP_INVALID_SYNTAX; goto return_error; } - switch ( tag ) { - case LDAP_SUBSTRING_INITIAL: - usage = SLAP_MR_SUBSTR_INITIAL; - break; - - case LDAP_SUBSTRING_ANY: - usage = SLAP_MR_SUBSTR_ANY; - break; - - case LDAP_SUBSTRING_FINAL: - usage = SLAP_MR_SUBSTR_FINAL; - break; - - default: - rc = LDAP_PROTOCOL_ERROR; - - Debug( LDAP_DEBUG_FILTER, - " unknown substring choice=%ld\n", - (long) tag, 0, 0 ); - - ber_bvfree( value ); - goto return_error; - } - - rc = value_normalize( f->f_sub_desc, usage, value, &nvalue, text ); - ber_bvfree( value ); - - if( rc != LDAP_SUCCESS ) { - goto return_error; - } - - value = nvalue; - rc = LDAP_PROTOCOL_ERROR; +#ifdef SLAPD_SCHEMA_NOT_COMPAT + /* not yet implemented */ +#else + /* we should call a substring syntax normalization routine */ + value_normalize( val->bv_val, syntax ); + /* this is bogus, value_normalize should take a berval */ + val->bv_len = strlen( val->bv_val ); +#endif + switch ( tag ) { case LDAP_SUBSTRING_INITIAL: Debug( LDAP_DEBUG_FILTER, " INITIAL\n", 0, 0, 0 ); - if ( f->f_sub_initial != NULL - || f->f_sub_any != NULL - || f->f_sub_final != NULL ) - { - ber_bvfree( value ); + if ( f->f_sub_initial != NULL ) { + ber_bvfree( val ); goto return_error; } - - f->f_sub_initial = value; + f->f_sub_initial = val; if( fstr ) { - filter_escape_value( value, &escaped ); *fstr = ch_realloc( *fstr, - strlen( *fstr ) + escaped.bv_len + 1 ); - strcat( *fstr, escaped.bv_val ); - ber_memfree( escaped.bv_val ); + strlen( *fstr ) + val->bv_len + 1 ); + strcat( *fstr, val->bv_val ); } break; case LDAP_SUBSTRING_ANY: Debug( LDAP_DEBUG_FILTER, " ANY\n", 0, 0, 0 ); - - if ( f->f_sub_final != NULL ) { - ber_bvfree( value ); - goto return_error; - } - - if( ber_bvecadd( &f->f_sub_any, value ) < 0 ) { - ber_bvfree( value ); + if( ber_bvecadd( &f->f_sub_any, val ) < 0 ) { + ber_bvfree( val ); goto return_error; } if( fstr ) { - filter_escape_value( value, &escaped ); *fstr = ch_realloc( *fstr, - strlen( *fstr ) + escaped.bv_len + 2 ); + strlen( *fstr ) + val->bv_len + 2 ); strcat( *fstr, "*" ); - strcat( *fstr, escaped.bv_val ); - ber_memfree( escaped.bv_val ); + strcat( *fstr, val->bv_val ); } break; case LDAP_SUBSTRING_FINAL: Debug( LDAP_DEBUG_FILTER, " FINAL\n", 0, 0, 0 ); - if ( f->f_sub_final != NULL ) { - ber_bvfree( value ); + ber_bvfree( val ); goto return_error; } - - f->f_sub_final = value; + f->f_sub_final = val; if( fstr ) { - filter_escape_value( value, &escaped ); *fstr = ch_realloc( *fstr, - strlen( *fstr ) + escaped.bv_len + 2 ); + strlen( *fstr ) + val->bv_len + 2 ); strcat( *fstr, "*" ); - strcat( *fstr, escaped.bv_val ); - ber_memfree( escaped.bv_val ); + strcat( *fstr, val->bv_val ); } break; @@ -510,7 +473,7 @@ get_substring_filter( " unknown substring type=%ld\n", (long) tag, 0, 0 ); - ber_bvfree( value ); + ber_bvfree( val ); return_error: Debug( LDAP_DEBUG_FILTER, " error=%ld\n", @@ -521,11 +484,14 @@ return_error: *fstr = NULL; } - ad_free( f->f_sub_desc, 1 ); +#ifdef SLAPD_SCHEMA_NOT_COMPAT + /* not yet implemented */ +#else + ch_free( f->f_sub_type ); +#endif ber_bvfree( f->f_sub_initial ); ber_bvecfree( f->f_sub_any ); ber_bvfree( f->f_sub_final ); - ch_free( f->f_sub ); return rc; } } @@ -553,17 +519,28 @@ filter_free( Filter *f ) switch ( f->f_choice ) { case LDAP_FILTER_PRESENT: +#ifdef SLAPD_SCHEMA_NOT_COMPAT ad_free( f->f_desc, 1 ); +#else + if ( f->f_type != NULL ) { + free( f->f_type ); + } +#endif break; case LDAP_FILTER_EQUALITY: case LDAP_FILTER_GE: case LDAP_FILTER_LE: case LDAP_FILTER_APPROX: +#ifdef SLAPD_SCHEMA_NOT_COMPAT ava_free( f->f_ava, 1 ); +#else + ava_free( &f->f_ava, 0 ); +#endif break; case LDAP_FILTER_SUBSTRINGS: +#ifdef SLAPD_SCHEMA_NOT_COMPAT ad_free( f->f_sub_desc, 1 ); if ( f->f_sub_initial != NULL ) { ber_bvfree( f->f_sub_initial ); @@ -572,6 +549,18 @@ filter_free( Filter *f ) if ( f->f_sub_final != NULL ) { ber_bvfree( f->f_sub_final ); } +#else + if ( f->f_sub_type != NULL ) { + free( f->f_sub_type ); + } + if ( f->f_sub_initial != NULL ) { + ber_bvfree( f->f_sub_initial ); + } + ber_bvecfree( f->f_sub_any ); + if ( f->f_sub_final != NULL ) { + ber_bvfree( f->f_sub_final ); + } +#endif break; case LDAP_FILTER_AND: @@ -596,12 +585,12 @@ filter_free( Filter *f ) } #ifdef LDAP_DEBUG + void filter_print( Filter *f ) { int i; Filter *p; - struct berval escaped; if ( f == NULL ) { fprintf( stderr, "No filter!" ); @@ -609,66 +598,86 @@ filter_print( Filter *f ) switch ( f->f_choice ) { case LDAP_FILTER_EQUALITY: - filter_escape_value( f->f_av_value, &escaped ); +#ifdef SLAPD_SCHEMA_NOT_COMPAT fprintf( stderr, "(%s=%s)", f->f_av_desc->ad_cname->bv_val, - escaped.bv_val ); - ber_memfree( escaped.bv_val ); + f->f_av_value->bv_val ); +#else + fprintf( stderr, "(%s=%s)", + f->f_ava.ava_type, + f->f_ava.ava_value.bv_val ); +#endif break; case LDAP_FILTER_GE: - filter_escape_value( f->f_av_value, &escaped ); +#ifdef SLAPD_SCHEMA_NOT_COMPAT fprintf( stderr, "(%s>=%s)", f->f_av_desc->ad_cname->bv_val, - escaped.bv_val ); - ber_memfree( escaped.bv_val ); + f->f_av_value->bv_val ); +#else + fprintf( stderr, "(%s>=%s)", + f->f_ava.ava_type, + f->f_ava.ava_value.bv_val ); +#endif break; case LDAP_FILTER_LE: - filter_escape_value( f->f_av_value, &escaped ); +#ifdef SLAPD_SCHEMA_NOT_COMPAT fprintf( stderr, "(%s<=%s)", f->f_ava->aa_desc->ad_cname->bv_val, - escaped.bv_val ); - ber_memfree( escaped.bv_val ); + f->f_ava->aa_value->bv_val ); +#else + fprintf( stderr, "(%s<=%s)", + f->f_ava.ava_type, + f->f_ava.ava_value.bv_val ); +#endif break; case LDAP_FILTER_APPROX: - filter_escape_value( f->f_av_value, &escaped ); +#ifdef SLAPD_SCHEMA_NOT_COMPAT fprintf( stderr, "(%s~=%s)", f->f_ava->aa_desc->ad_cname->bv_val, - escaped.bv_val ); - ber_memfree( escaped.bv_val ); + f->f_ava->aa_value->bv_val ); +#else + fprintf( stderr, "(%s~=%s)", + f->f_ava.ava_type, + f->f_ava.ava_value.bv_val ); +#endif break; case LDAP_FILTER_SUBSTRINGS: +#ifdef SLAPD_SCHEMA_NOT_COMPAT fprintf( stderr, "(%s=" /*)*/, f->f_sub_desc->ad_cname->bv_val ); +#else + fprintf( stderr, "(%s=" /*)*/, + f->f_sub_type ); +#endif if ( f->f_sub_initial != NULL ) { - filter_escape_value( f->f_sub_initial, &escaped ); fprintf( stderr, "%s", - escaped.bv_val ); - ber_memfree( escaped.bv_val ); + f->f_sub_initial->bv_val ); } if ( f->f_sub_any != NULL ) { for ( i = 0; f->f_sub_any[i] != NULL; i++ ) { - filter_escape_value( f->f_sub_any[i], &escaped ); fprintf( stderr, "*%s", - escaped.bv_val ); - ber_memfree( escaped.bv_val ); + f->f_sub_any[i]->bv_val ); } } if ( f->f_sub_final != NULL ) { - filter_escape_value( f->f_sub_final, &escaped ); fprintf( stderr, - "*%s", escaped.bv_val ); - ber_memfree( escaped.bv_val ); + "*%s", f->f_sub_final->bv_val ); } fprintf( stderr, /*(*/ ")" ); break; case LDAP_FILTER_PRESENT: +#ifdef SLAPD_SCHEMA_NOT_COMPAT fprintf( stderr, "(%s=*)", f->f_desc->ad_cname->bv_val ); +#else + fprintf( stderr, "(%s=*)", + f->f_type ); +#endif break; case LDAP_FILTER_AND: @@ -698,28 +707,3 @@ filter_print( Filter *f ) } #endif /* ldap_debug */ - -int filter_escape_value( - struct berval *in, - struct berval *out ) -{ - ber_len_t i; - assert( in ); - assert( out ); - - out->bv_val = (char *) ch_malloc( ( in->bv_len * 3 ) + 1 ); - out->bv_len = 0; - - for( i=0; i < in->bv_len ; i++ ) { - if( FILTER_ESCAPE(in->bv_val[i]) ) { - out->bv_val[out->bv_len++] = SLAP_ESCAPE_CHAR; - out->bv_val[out->bv_len++] = SLAP_ESCAPE_HI( in->bv_val[i] ); - out->bv_val[out->bv_len++] = SLAP_ESCAPE_LO( in->bv_val[i] ); - } else { - out->bv_val[out->bv_len++] = in->bv_val[i]; - } - } - - out->bv_val[out->bv_len] = '\0'; - return LDAP_SUCCESS; -}