X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fstr2filter.c;h=ff7cd450adfc7eea72d5e479af5fd74831697131;hb=ecfb311f8f2b4f8b8e74c0ee88b8ef572e792c99;hp=de8aba8b256736bc1fee59e832b5ae138fff0e79;hpb=2a799ef855b434a9f0a4eeafe6ac2f1d7476302b;p=openldap diff --git a/servers/slapd/str2filter.c b/servers/slapd/str2filter.c index de8aba8b25..ff7cd450ad 100644 --- a/servers/slapd/str2filter.c +++ b/servers/slapd/str2filter.c @@ -1,7 +1,7 @@ /* str2filter.c - parse an rfc 1588 string filter */ /* $OpenLDAP$ */ /* - * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ @@ -24,12 +24,16 @@ static int str2subvals( const char *val, Filter *f); Filter * str2filter( const char *str ) { + int rc; Filter *f = NULL; - char *end, *freeme; + BerElement *ber; + char berbuf[256]; + struct berval *bv = NULL; + Connection conn; + const char *text = NULL; #ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, - "str2filter: \"%s\"\n", str )); + LDAP_LOG( FILTER, ENTRY, "str2filter: \"%s\"\n", str, 0, 0 ); #else Debug( LDAP_DEBUG_FILTER, "str2filter \"%s\"\n", str, 0, 0 ); #endif @@ -38,347 +42,35 @@ str2filter( const char *str ) return NULL; } - str = freeme = ch_strdup( str ); - - switch ( *str ) { - case '(': - if ( (end = find_matching_paren( str )) == NULL ) { - filter_free( f ); - free( freeme ); - return NULL; - } - *end = '\0'; - - str++; - switch ( *str ) { - case '&': -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, - "str2filter: AND\n" )); -#else - Debug( LDAP_DEBUG_FILTER, "str2filter: AND\n", - 0, 0, 0 ); -#endif - - str++; - f = str2list( str, LDAP_FILTER_AND ); - break; - - case '|': -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, - "str2filter: OR\n" )); -#else - Debug( LDAP_DEBUG_FILTER, "put_filter: OR\n", - 0, 0, 0 ); -#endif - - str++; - f = str2list( str, LDAP_FILTER_OR ); - break; - - case '!': -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, - "str2filter: NOT\n" )); -#else - Debug( LDAP_DEBUG_FILTER, "put_filter: NOT\n", - 0, 0, 0 ); -#endif - - str++; - f = str2list( str, LDAP_FILTER_NOT ); - break; - - default: -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, - "str2filter: simple\n" )); -#else - Debug( LDAP_DEBUG_FILTER, "str2filter: simple\n", - 0, 0, 0 ); -#endif - - f = str2simple( str ); - break; - } - *end = ')'; - break; - - default: /* assume it's a simple type=value filter */ -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, - "str2filter: default\n" )); -#else - Debug( LDAP_DEBUG_FILTER, "str2filter: default\n", - 0, 0, 0 ); -#endif - - f = str2simple( str ); - break; - } - - free( freeme ); - return( f ); -} - -/* - * Put a list of filters like this "(filter1)(filter2)..." - */ - -static Filter * -str2list( const char *str, unsigned long ftype ) -{ - Filter *f; - Filter **fp; - char *next; - char save; - -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, - "str2list: \"%s\"\n", str )); -#else - Debug( LDAP_DEBUG_FILTER, "str2list \"%s\"\n", str, 0, 0 ); -#endif - - f = (Filter *) ch_calloc( 1, sizeof(Filter) ); - f->f_choice = ftype; - fp = &f->f_list; - - while ( *str ) { - while ( *str && isspace( (unsigned char) *str ) ) - str++; - if ( *str == '\0' ) - break; - - if ( (next = find_matching_paren( str )) == NULL ) { - filter_free( f ); - return( NULL ); - } - save = *++next; - *next = '\0'; - - /* now we have "(filter)" with str pointing to it */ - if ( (*fp = str2filter( str )) == NULL ) { - filter_free( f ); - *next = save; - return( NULL ); - } - *next = save; - - str = next; - fp = &(*fp)->f_next; - } - *fp = NULL; - - return( f ); -} - -static Filter * -str2simple( const char *str ) -{ - Filter *f; - char *s; - char *value, savechar; - int rc; - const char *text; - -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, - "str2simple: \"%s\"\n", str )); -#else - Debug( LDAP_DEBUG_FILTER, "str2simple \"%s\"\n", str, 0, 0 ); -#endif - - if ( (s = strchr( str, '=' )) == NULL ) { + ber = ber_alloc_t( LBER_USE_DER ); + if( ber == NULL ) { return NULL; } - value = &s[1]; - - *s-- = '\0'; /* we shouldn't be mucking with str */ - savechar = *s; - - f = (Filter *) ch_calloc( 1, sizeof(Filter) ); - - switch ( *s ) { - case '<': - f->f_choice = LDAP_FILTER_LE; - *s = '\0'; - break; - case '>': - f->f_choice = LDAP_FILTER_GE; - *s = '\0'; - break; - case '~': - f->f_choice = LDAP_FILTER_APPROX; - *s = '\0'; - break; - case ':': - f->f_choice = LDAP_FILTER_EXT; - *s = '\0'; - return NULL; - break; - - default: { - char *nextstar = ldap_pvt_find_wildcard( value ); - if ( nextstar == NULL ) { - filter_free( f ); - *(value-1) = '='; - return NULL; - - } else if ( *nextstar == '\0' ) { - f->f_choice = LDAP_FILTER_EQUALITY; - - } else if ( strcmp( value, "*" ) == 0 ) { - f->f_choice = LDAP_FILTER_PRESENT; - - } else { - f->f_choice = LDAP_FILTER_SUBSTRINGS; - f->f_sub = ch_calloc( 1, sizeof( SubstringsAssertion ) ); - - rc = slap_str2ad( str, &f->f_sub_desc, &text ); - if( rc != LDAP_SUCCESS ) { - filter_free( f ); - *(value-1) = '='; - return NULL; - } - - if ( str2subvals( value, f ) != 0 ) { - filter_free( f ); - *(value-1) = '='; - return NULL; - } - *(value-1) = '='; - return f; - } - } break; + rc = ldap_pvt_put_filter( ber, str ); + if( rc < 0 ) { + goto done; } - if ( f->f_choice == LDAP_FILTER_PRESENT ) { - rc = slap_str2ad( str, &f->f_desc, &text ); - if( rc != LDAP_SUCCESS ) { - filter_free( f ); - *(value-1) = '='; - return NULL; - } - - } else { - ber_slen_t len; - char *tmp; - - f->f_ava = ch_calloc( 1, sizeof( AttributeAssertion ) ); - f->f_av_desc = NULL; - rc = slap_str2ad( str, &f->f_av_desc, &text ); - if( rc != LDAP_SUCCESS ) { - filter_free( f ); - *(value-1) = '='; - return NULL; - } - - tmp = ch_strdup( value ); - len = ldap_pvt_filter_value_unescape( tmp ); - if( len < 0 ) { - filter_free( f ); - *(value-1) = '='; - free( tmp ); - return NULL; - } - ber_str2bv( tmp, 0, 0, &f->f_av_value ); + rc = ber_flatten( ber, &bv ); + if( rc < 0 ) { + goto done; } - *s = savechar; - *(value-1) = '='; - - return f; -} - -static int -str2subvals( const char *in, Filter *f ) -{ - ber_slen_t len; - char *nextstar, *val, *freeme; - int gotstar; - int final; - -#ifdef NEW_LOGGING - LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, - "str2subvals: \"%s\"\n", in )); -#else - Debug( LDAP_DEBUG_FILTER, "str2subvals \"%s\"\n", in, 0, 0 ); -#endif - - if( in == NULL ) return 0; - - val = freeme = ch_strdup( in ); - gotstar = final = 0; - - while ( *val ) { - nextstar = ldap_pvt_find_wildcard( val ); - - if ( nextstar == NULL ) { - free( freeme ); - return -1; - - } else if( *nextstar == '\0' ) { - final = 1; - - } else { - gotstar++; - *nextstar = '\0'; - } + ber_free( ber, 0 ); - len = ldap_pvt_filter_value_unescape( val ); - if( len < 0 ) { - free( freeme ); - return -1; - } + ber = (BerElement *)berbuf; + ber_init2( ber, bv, 0 ); - if ( final ) { - ber_str2bv( val, 0, 1, &f->f_sub_final ); + conn.c_connid = 0; - } else if ( gotstar <= 1 ) { - ber_str2bv( val, 0, 1, &f->f_sub_initial ); - - } else { - charray_add( (char ***) &f->f_sub_any, - (char *) ber_bvstrdup( val ) ); - } - - val = nextstar+1; + rc = get_filter( &conn, ber, &f, &text ); + if( rc ) { + goto done; } - free( freeme ); - return 0; -} - -/* - * find_matching_paren - return a pointer to the right paren in s matching - * the left paren to which *s currently points - */ +done: + ber_bvfree( bv ); -static char * -find_matching_paren( const char *s ) -{ - int balance, escape; - - balance = 0; - escape = 0; - for ( ; *s; s++ ) { - if ( escape == 0 ) { - if ( *s == '(' ) - balance++; - else if ( *s == ')' ) - balance--; - } - if ( balance == 0 ) { - return (char *) s; - } - if ( *s == '\\' && ! escape ) - escape = 1; - else - escape = 0; - } - - return NULL; + return f; }