X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fstr2filter.c;h=374ec60b2f45b3e14544fd35a85bf224b49a769d;hb=9ea910fd41118db2270b37755cb9e561cdb89a24;hp=7af30358ea8aec9865ab219950f8fe2552807258;hpb=0dbaf87730ec9afe44dceaa452ae51e1dcaac3e7;p=openldap diff --git a/servers/slapd/str2filter.c b/servers/slapd/str2filter.c index 7af30358ea..374ec60b2f 100644 --- a/servers/slapd/str2filter.c +++ b/servers/slapd/str2filter.c @@ -1,8 +1,27 @@ -/* str2filter.c - parse an rfc 1588 string filter */ +/* str2filter.c - parse an RFC 2554 string filter */ /* $OpenLDAP$ */ -/* - * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2005 The OpenLDAP Foundation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ +/* Portions Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that this notice is preserved and that due credit is given + * to the University of Michigan at Ann Arbor. The name of the University + * may not be used to endorse or promote products derived from this + * software without specific prior written permission. This software + * is provided ``as is'' without express or implied warranty. */ #include "portable.h" @@ -14,268 +33,52 @@ #include #include "slap.h" -#include -static char *find_matching_paren( const char *s ); -static Filter *str2list( const char *str, long unsigned int ftype); -static Filter *str2simple( const char *str); -static int str2subvals( const char *val, Filter *f); Filter * -str2filter( const char *str ) +str2filter_x( Operation *op, const char *str ) { + int rc; Filter *f = NULL; - char *end, *freeme; + BerElementBuffer berbuf; + BerElement *ber = (BerElement *)&berbuf; + const char *text = NULL; Debug( LDAP_DEBUG_FILTER, "str2filter \"%s\"\n", str, 0, 0 ); if ( str == NULL || *str == '\0' ) { - return( NULL ); + 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 '&': - Debug( LDAP_DEBUG_FILTER, "str2filter: AND\n", - 0, 0, 0 ); - - str++; - f = str2list( str, LDAP_FILTER_AND ); - break; - - case '|': - Debug( LDAP_DEBUG_FILTER, "put_filter: OR\n", - 0, 0, 0 ); - - str++; - f = str2list( str, LDAP_FILTER_OR ); - break; - - case '!': - Debug( LDAP_DEBUG_FILTER, "put_filter: NOT\n", - 0, 0, 0 ); - - str++; - f = str2list( str, LDAP_FILTER_NOT ); - break; - - default: - Debug( LDAP_DEBUG_FILTER, "str2filter: simple\n", - 0, 0, 0 ); - - f = str2simple( str ); - break; - } - *end = ')'; - break; - - default: /* assume it's a simple type=value filter */ - Debug( LDAP_DEBUG_FILTER, "str2filter: default\n", 0, 0, - 0 ); - - f = str2simple( str ); - break; + ber_init2( ber, NULL, LBER_USE_DER ); + if ( op->o_tmpmemctx ) { + ber_set_option( ber, LBER_OPT_BER_MEMCTX, &op->o_tmpmemctx ); } - 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; - - Debug( LDAP_DEBUG_FILTER, "str2list \"%s\"\n", str, 0, 0 ); - - 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; + rc = ldap_pvt_put_filter( ber, str ); + if( rc < 0 ) { + goto done; } - *fp = NULL; - return( f ); -} + ber_reset( ber, 1 ); -static Filter * -str2simple( const char *str ) -{ - Filter *f; - char *s; - char *value, savechar; + rc = get_filter( op, ber, &f, &text ); - Debug( LDAP_DEBUG_FILTER, "str2simple \"%s\"\n", str, 0, 0 ); +done: + ber_free_buf( ber ); - if ( (s = strchr( str, '=' )) == NULL ) { - return( NULL ); - } - value = &s[1]; - *s-- = '\0'; - 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'; - break; - - default: - if ( ldap_pvt_find_wildcard( value ) == NULL ) { - f->f_choice = LDAP_FILTER_EQUALITY; - } else if ( strcmp( value, "*" ) == 0 ) { - f->f_choice = LDAP_FILTER_PRESENT; - } else { - f->f_choice = LDAP_FILTER_SUBSTRINGS; -#ifndef SLAPD_SCHEMA_NOT_COMPAT - f->f_sub_type = ch_strdup( str ); - if ( str2subvals( value, f ) != 0 ) { - filter_free( f ); - *(value-1) = '='; - return( NULL ); - } - *(value-1) = '='; - return( f ); -#endif - } - break; - } - -#ifndef SLAPD_SCHEMA_NOT_COMPAT - if ( f->f_choice == LDAP_FILTER_PRESENT ) { - f->f_type = ch_strdup( str ); - } else { - f->f_avtype = ch_strdup( str ); - f->f_avvalue.bv_val = ch_strdup( value ); - ldap_pvt_filter_value_unescape( f->f_avvalue.bv_val ); - f->f_avvalue.bv_len = strlen( value ); - } - - *s = savechar; - *(value-1) = '='; -#endif - return( f ); -} - -static int -str2subvals( const char *in, Filter *f ) -{ - char *nextstar, *val, *freeme; - int gotstar; - - Debug( LDAP_DEBUG_FILTER, "str2subvals \"%s\"\n", in, 0, 0 ); - - if( in == NULL ) return 0; - - val = freeme = ch_strdup( in ); - gotstar = 0; - - while ( *val ) { - if ( (nextstar = ldap_pvt_find_wildcard( val )) != NULL ) - *nextstar++ = '\0'; - - ldap_pvt_filter_value_unescape( val ); - - if ( gotstar == 0 ) { - f->f_sub_initial = ber_bvstrdup( val ); - - } else if ( nextstar == NULL ) { - f->f_sub_final = ber_bvstrdup( val ); - - } else { - charray_add( (char ***) &f->f_sub_any, (char *) ber_bvstrdup( val ) ); - } - - gotstar = 1; - val = nextstar; - } - - free( freeme ); - return( 0 ); + return f; } -/* - * find_matching_paren - return a pointer to the right paren in s matching - * the left paren to which *s currently points - */ - -static char * -find_matching_paren( const char *s ) +Filter * +str2filter( const char *str ) { - int balance, escape; + Operation op = {0}; + Opheader ohdr = {0}; - 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; - } + op.o_hdr = &ohdr; + op.o_tmpmemctx = NULL; + op.o_tmpmfuncs = &ch_mfuncs; - return NULL; + return str2filter_x( &op, str ); }