Skip to content
Snippets Groups Projects
Commit 5ea0bf2f authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Use put/get filter to convert string to filter

parent fcf9f451
No related branches found
No related tags found
No related merge requests found
......@@ -24,8 +24,13 @@ 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,
......@@ -38,347 +43,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_int_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) = '=';
ber_free( ber, 0 );
return f;
}
ber = (BerElement *)berbuf;
ber_init2( ber, bv, 0 );
static int
str2subvals( const char *in, Filter *f )
{
ber_slen_t len;
char *nextstar, *val, *freeme;
int gotstar;
int final;
conn.c_connid = 0;
#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';
}
len = ldap_pvt_filter_value_unescape( val );
if( len < 0 ) {
free( freeme );
return -1;
}
if ( final ) {
ber_str2bv( val, 0, 1, &f->f_sub_final );
} 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;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment