X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Ffilter.c;h=2d05d81c25dc78187d08596ecfd9b5867ff6ef84;hb=62295c0928c071685dbbfb98644cadaeb37333b8;hp=7d40d1ceb472588ee886da4c89df09f19c7a18b5;hpb=8c152396b9ff4fa0f2618435441550c1f12df461;p=openldap diff --git a/libraries/libldap/filter.c b/libraries/libldap/filter.c index 7d40d1ceb4..2d05d81c25 100644 --- a/libraries/libldap/filter.c +++ b/libraries/libldap/filter.c @@ -1,13 +1,20 @@ +/* search.c */ /* $OpenLDAP$ */ -/* - * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved. - * COPYING RESTRICTIONS APPLY, see COPYRIGHT file - */ -/* Portions - * Copyright (c) 1990 Regents of the University of Michigan. - * All rights reserved. +/* This work is part of OpenLDAP Software . + * + * Copyright 1998-2009 The OpenLDAP Foundation. + * All rights reserved. * - * search.c + * 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) 1990 Regents of the University of Michigan. + * All rights reserved. */ #include "portable.h" @@ -43,7 +50,8 @@ static int put_simple_filter LDAP_P(( static int put_substring_filter LDAP_P(( BerElement *ber, char *type, - char *str )); + char *str, + char *nextstar )); static int put_filter_list LDAP_P(( BerElement *ber, @@ -324,44 +332,39 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) int parens, balance, escape; /* - * A Filter looks like this: - * Filter ::= CHOICE { - * and [0] SET OF Filter, - * or [1] SET OF Filter, - * not [2] Filter, - * equalityMatch [3] AttributeValueAssertion, - * substrings [4] SubstringFilter, - * greaterOrEqual [5] AttributeValueAssertion, - * lessOrEqual [6] AttributeValueAssertion, - * present [7] AttributeType, - * approxMatch [8] AttributeValueAssertion, - * extensibleMatch [9] MatchingRuleAssertion -- LDAPv3 - * } + * A Filter looks like this (RFC 4511 as extended by RFC 4526): + * Filter ::= CHOICE { + * and [0] SET SIZE (0..MAX) OF filter Filter, + * or [1] SET SIZE (0..MAX) OF filter Filter, + * not [2] Filter, + * equalityMatch [3] AttributeValueAssertion, + * substrings [4] SubstringFilter, + * greaterOrEqual [5] AttributeValueAssertion, + * lessOrEqual [6] AttributeValueAssertion, + * present [7] AttributeDescription, + * approxMatch [8] AttributeValueAssertion, + * extensibleMatch [9] MatchingRuleAssertion, + * ... } * - * SubstringFilter ::= SEQUENCE { - * type AttributeType, - * SEQUENCE OF CHOICE { - * initial [0] IA5String, - * any [1] IA5String, - * final [2] IA5String - * } - * } + * SubstringFilter ::= SEQUENCE { + * type AttributeDescription, + * substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE { + * initial [0] AssertionValue, -- only once + * any [1] AssertionValue, + * final [2] AssertionValue -- only once + * } + * } * - * MatchingRuleAssertion ::= SEQUENCE { -- LDAPv3 - * matchingRule [1] MatchingRuleId OPTIONAL, - * type [2] AttributeDescription OPTIONAL, - * matchValue [3] AssertionValue, - * dnAttributes [4] BOOLEAN DEFAULT FALSE } + * MatchingRuleAssertion ::= SEQUENCE { + * matchingRule [1] MatchingRuleId OPTIONAL, + * type [2] AttributeDescription OPTIONAL, + * matchValue [3] AssertionValue, + * dnAttributes [4] BOOLEAN DEFAULT FALSE } * - * Note: tags in a choice are always explicit + * Note: tags in a CHOICE are always explicit */ -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_ARGS, "ldap_pvt_put_filter: \"%s\"\n", - str_in )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter: \"%s\"\n", str_in, 0, 0 ); -#endif freeme = LDAP_STRDUP( str_in ); if( freeme == NULL ) return LDAP_NO_MEMORY; @@ -379,13 +382,8 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) switch ( *str ) { case '&': -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: AND\n" )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter: AND\n", 0, 0, 0 ); -#endif str = put_complex_filter( ber, str, LDAP_FILTER_AND, 0 ); @@ -398,13 +396,8 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) break; case '|': -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: OR\n" )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter: OR\n", 0, 0, 0 ); -#endif str = put_complex_filter( ber, str, LDAP_FILTER_OR, 0 ); @@ -417,13 +410,8 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) break; case '!': -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: NOT\n" )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter: NOT\n", 0, 0, 0 ); -#endif str = put_complex_filter( ber, str, LDAP_FILTER_NOT, 0 ); @@ -435,14 +423,13 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) parens--; break; + case '(': + rc = -1; + goto done; + default: -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: simple\n" )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter: simple\n", 0, 0, 0 ); -#endif balance = 1; escape = 0; @@ -487,13 +474,8 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) break; case /*'('*/ ')': -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: end\n" )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter: end\n", 0, 0, 0 ); -#endif if ( ber_printf( ber, /*"["*/ "]" ) == -1 ) { rc = -1; goto done; @@ -507,13 +489,8 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) break; default: /* assume it's a simple type=value filter */ -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: default\n" )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter: default\n", 0, 0, 0 ); -#endif next = strchr( str, '\0' ); if ( put_simple_filter( ber, str ) == -1 ) { rc = -1; @@ -522,9 +499,11 @@ ldap_pvt_put_filter( BerElement *ber, const char *str_in ) str = next; break; } + if ( !parens ) + break; } - rc = parens ? -1 : 0; + rc = ( parens || *str ) ? -1 : 0; done: LDAP_FREE( freeme ); @@ -541,13 +520,8 @@ put_filter_list( BerElement *ber, char *str, ber_tag_t tag ) char *next = NULL; char save; -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_ARGS, - "put_filter_list \"%s\"\n", str )); -#else Debug( LDAP_DEBUG_TRACE, "put_filter_list \"%s\"\n", str, 0, 0 ); -#endif while ( *str ) { while ( *str && LDAP_SPACE( (unsigned char) *str ) ) { @@ -586,13 +560,8 @@ put_simple_filter( ber_tag_t ftype; int rc = -1; -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_ARGS, - "put_simple_filter: \"%s\"\n", str )); -#else Debug( LDAP_DEBUG_TRACE, "put_simple_filter: \"%s\"\n", str, 0, 0 ); -#endif str = LDAP_STRDUP( str ); if( str == NULL ) return -1; @@ -621,7 +590,7 @@ put_simple_filter( break; case ':': - /* RFC2254 extensible filters are off the form: + /* RFC 4515 extensible filters are off the form: * type [:dn] [:rule] := value * or [:dn]:rule := value */ @@ -638,7 +607,7 @@ put_simple_filter( if( rule == NULL ) { /* one colon */ - if ( strcmp(dn, "dn") == 0 ) { + if ( strcasecmp(dn, "dn") == 0 ) { /* must have attribute */ if( !ldap_is_desc( str ) ) { goto done; @@ -655,7 +624,7 @@ put_simple_filter( /* two colons */ *rule++ = '\0'; - if ( strcmp(dn, "dn") != 0 ) { + if ( strcasecmp(dn, "dn") != 0 ) { /* must have "dn" */ goto done; } @@ -725,7 +694,7 @@ put_simple_filter( ftype = LDAP_FILTER_PRESENT; } else { - rc = put_substring_filter( ber, str, value ); + rc = put_substring_filter( ber, str, value, nextstar ); goto done; } } break; @@ -752,31 +721,26 @@ done: } static int -put_substring_filter( BerElement *ber, char *type, char *val ) +put_substring_filter( BerElement *ber, char *type, char *val, char *nextstar ) { - char *nextstar; int gotstar = 0; ber_tag_t ftype = LDAP_FILTER_SUBSTRINGS; -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_ARGS, - "put_substring_filter \"%s=%s\"\n", type, val )); -#else Debug( LDAP_DEBUG_TRACE, "put_substring_filter \"%s=%s\"\n", type, val, 0 ); -#endif if ( ber_printf( ber, "t{s{" /*"}}"*/, ftype, type ) == -1 ) { return -1; } for( ; *val; val=nextstar ) { - nextstar = ldap_pvt_find_wildcard( val ); + if ( gotstar ) + nextstar = ldap_pvt_find_wildcard( val ); if ( nextstar == NULL ) { return -1; } - + if ( *nextstar == '\0' ) { ftype = LDAP_SUBSTRING_FINAL; } else { @@ -791,7 +755,7 @@ put_substring_filter( BerElement *ber, char *type, char *val ) if ( *val != '\0' || ftype == LDAP_SUBSTRING_ANY ) { ber_slen_t len = ldap_pvt_filter_value_unescape( val ); - if ( len < 0 ) { + if ( len <= 0 ) { return -1; } @@ -808,8 +772,8 @@ put_substring_filter( BerElement *ber, char *type, char *val ) return 0; } -int -ldap_pvt_put_vrFilter( BerElement *ber, const char *str_in ) +static int +put_vrFilter( BerElement *ber, const char *str_in ) { int rc; char *freeme; @@ -844,14 +808,11 @@ ldap_pvt_put_vrFilter( BerElement *ber, const char *str_in ) * matchingRule [1] MatchingRuleId OPTIONAL, * type [2] AttributeDescription OPTIONAL, * matchValue [3] AssertionValue } + * + * (Source: RFC 3876) */ -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_ARGS, "ldap_pvt_put_vrFilter: \"%s\"\n", - str_in )); -#else Debug( LDAP_DEBUG_TRACE, "put_vrFilter: \"%s\"\n", str_in, 0, 0 ); -#endif freeme = LDAP_STRDUP( str_in ); if( freeme == NULL ) return LDAP_NO_MEMORY; @@ -891,13 +852,8 @@ ldap_pvt_put_vrFilter( BerElement *ber, const char *str_in ) default: -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_vrFilter: simple\n" )); -#else Debug( LDAP_DEBUG_TRACE, "put_vrFilter: simple\n", 0, 0, 0 ); -#endif balance = 1; escape = 0; @@ -942,13 +898,8 @@ ldap_pvt_put_vrFilter( BerElement *ber, const char *str_in ) break; case /*'('*/ ')': -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: end\n" )); -#else - Debug( LDAP_DEBUG_TRACE, "put_filter: end\n", + Debug( LDAP_DEBUG_TRACE, "put_vrFilter: end\n", 0, 0, 0 ); -#endif if ( ber_printf( ber, /*"["*/ "]" ) == -1 ) { rc = -1; goto done; @@ -962,15 +913,10 @@ ldap_pvt_put_vrFilter( BerElement *ber, const char *str_in ) break; default: /* assume it's a simple type=value filter */ -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_DETAIL1, - "ldap_pvt_put_filter: default\n" )); -#else - Debug( LDAP_DEBUG_TRACE, "put_filter: default\n", + Debug( LDAP_DEBUG_TRACE, "put_vrFilter: default\n", 0, 0, 0 ); -#endif next = strchr( str, '\0' ); - if ( put_simple_filter( ber, str ) == -1 ) { + if ( put_simple_vrFilter( ber, str ) == -1 ) { rc = -1; goto done; } @@ -987,7 +933,7 @@ done: } int -put_vrFilter( BerElement *ber, const char *str_in ) +ldap_put_vrFilter( BerElement *ber, const char *str_in ) { int rc =0; @@ -995,7 +941,7 @@ put_vrFilter( BerElement *ber, const char *str_in ) rc = -1; } - rc = ldap_pvt_put_vrFilter( ber, str_in ); + rc = put_vrFilter( ber, str_in ); if ( ber_printf( ber, /*"{"*/ "N}" ) == -1 ) { rc = -1; @@ -1010,13 +956,8 @@ put_vrFilter_list( BerElement *ber, char *str ) char *next = NULL; char save; -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_ARGS, - "put_vrFilter_list \"%s\"\n", str )); -#else Debug( LDAP_DEBUG_TRACE, "put_vrFilter_list \"%s\"\n", str, 0, 0 ); -#endif while ( *str ) { while ( *str && LDAP_SPACE( (unsigned char) *str ) ) { @@ -1031,7 +972,7 @@ put_vrFilter_list( BerElement *ber, char *str ) /* now we have "(filter)" with str pointing to it */ *next = '\0'; - if ( ldap_pvt_put_vrFilter( ber, str ) == -1 ) return -1; + if ( put_vrFilter( ber, str ) == -1 ) return -1; *next = save; str = next; } @@ -1049,13 +990,8 @@ put_simple_vrFilter( ber_tag_t ftype; int rc = -1; -#ifdef NEW_LOGGING - LDAP_LOG (( "filter", LDAP_LEVEL_ARGS, - "put_simple_vrFilter: \"%s\"\n", str )); -#else Debug( LDAP_DEBUG_TRACE, "put_simple_vrFilter: \"%s\"\n", str, 0, 0 ); -#endif str = LDAP_STRDUP( str ); if( str == NULL ) return -1; @@ -1094,7 +1030,6 @@ put_simple_vrFilter( { char *rule = strchr( str, ':' ); - *rule++ = '\0'; if( rule == NULL ) { /* must have attribute */ @@ -1102,12 +1037,10 @@ put_simple_vrFilter( goto done; } rule = ""; - } else { *rule++ = '\0'; } - if ( *str == '\0' && ( !rule || *rule == '\0' ) ) { /* must have either type or rule */ goto done; @@ -1165,7 +1098,7 @@ put_simple_vrFilter( ftype = LDAP_FILTER_PRESENT; } else { - rc = put_substring_filter( ber, str, value ); + rc = put_substring_filter( ber, str, value, nextstar ); goto done; } } break;