X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fsearch.c;h=9d27820f93fa7114993c74e5a2d4165f3e0aab69;hb=df8f7cbb9b79be3be9205d116d1dd0b263d6861a;hp=117d5f4d2ee1f7b9db238d6ca25502433bee531a;hpb=8153a4039b9049da4fc324cd0807d3dc964596ab;p=openldap diff --git a/libraries/libldap/search.c b/libraries/libldap/search.c index 117d5f4d2e..9d27820f93 100644 --- a/libraries/libldap/search.c +++ b/libraries/libldap/search.c @@ -12,7 +12,8 @@ #include "portable.h" #include -#include + +#include #include #include @@ -21,16 +22,141 @@ #include "ldap-int.h" -static char *find_right_paren LDAP_P(( char *s )); -static char *put_complex_filter LDAP_P(( BerElement *ber, char *str, - unsigned long tag, int not )); -static int put_filter LDAP_P(( BerElement *ber, char *str )); -static int put_simple_filter LDAP_P(( BerElement *ber, char *str )); -static int put_substring_filter LDAP_P(( BerElement *ber, char *type, char *str )); -static int put_filter_list LDAP_P(( BerElement *ber, char *str )); +static char *find_right_paren LDAP_P(( + char *s )); + +static char *put_complex_filter LDAP_P(( + BerElement *ber, + char *str, + ber_tag_t tag, + int not )); + +static int put_filter LDAP_P(( + BerElement *ber, + char *str )); + +static int put_simple_filter LDAP_P(( + BerElement *ber, + char *str )); + +static int put_substring_filter LDAP_P(( + BerElement *ber, + char *type, + char *str )); + +static int put_filter_list LDAP_P(( + BerElement *ber, + char *str )); /* - * ldap_search - initiate an ldap (and X.500) search operation. Parameters: + * ldap_search_ext - initiate an ldap search operation. + * + * Parameters: + * + * ld LDAP descriptor + * base DN of the base object + * scope the search scope - one of LDAP_SCOPE_BASE, + * LDAP_SCOPE_ONELEVEL, LDAP_SCOPE_SUBTREE + * filter a string containing the search filter + * (e.g., "(|(cn=bob)(sn=bob))") + * attrs list of attribute types to return for matches + * attrsonly 1 => attributes only 0 => attributes and values + * + * Example: + * char *attrs[] = { "mail", "title", 0 }; + * ldap_search_ext( ld, "c=us@o=UM", LDAP_SCOPE_SUBTREE, "cn~=bob", + * attrs, attrsonly, sctrls, ctrls, timeout, sizelimit, + * &msgid ); + */ +int +ldap_search_ext( + LDAP *ld, + LDAP_CONST char *base, + int scope, + LDAP_CONST char *filter, + char **attrs, + int attrsonly, + LDAPControl **sctrls, + LDAPControl **cctrls, + struct timeval *timeout, + int sizelimit, + int *msgidp ) +{ + BerElement *ber; + int timelimit; + + Debug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 ); + + /* + * if timeout is provided, use only tv_sec as timelimit. + * otherwise, use default. + */ + timelimit = (timeout != NULL) + ? timeout->tv_sec + : -1; + + ber = ldap_build_search_req( ld, base, scope, filter, attrs, + attrsonly, sctrls, cctrls, timelimit, sizelimit ); + + if ( ber == NULL ) { + return ld->ld_errno; + } + +#ifndef LDAP_NOCACHE + if ( ld->ld_cache != NULL ) { + if ( ldap_check_cache( ld, LDAP_REQ_SEARCH, ber ) == 0 ) { + ber_free( ber, 1 ); + ld->ld_errno = LDAP_SUCCESS; + *msgidp = ld->ld_msgid; + return ld->ld_errno; + } + ldap_add_request_to_cache( ld, LDAP_REQ_SEARCH, ber ); + } +#endif /* LDAP_NOCACHE */ + + /* send the message */ + *msgidp = ldap_send_initial_request( ld, LDAP_REQ_SEARCH, base, ber ); + + if( *msgidp < 0 ) + return ld->ld_errno; + + return LDAP_SUCCESS; +} + +int +ldap_search_ext_s( + LDAP *ld, + LDAP_CONST char *base, + int scope, + LDAP_CONST char *filter, + char **attrs, + int attrsonly, + LDAPControl **sctrls, + LDAPControl **cctrls, + struct timeval *timeout, + int sizelimit, + LDAPMessage **res ) +{ + int rc; + int msgid; + + rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly, + sctrls, cctrls, timeout, sizelimit, &msgid ); + + if ( rc != LDAP_SUCCESS ) { + return( rc ); + } + + if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 ) + return( ld->ld_errno ); + + return( ldap_result2error( ld, *res, 0 ) ); +} + +/* + * ldap_search - initiate an ldap search operation. + * + * Parameters: * * ld LDAP descriptor * base DN of the base object @@ -47,15 +173,18 @@ static int put_filter_list LDAP_P(( BerElement *ber, char *str )); * attrs, attrsonly ); */ int -ldap_search( LDAP *ld, char *base, int scope, char *filter, +ldap_search( + LDAP *ld, LDAP_CONST char *base, int scope, LDAP_CONST char *filter, char **attrs, int attrsonly ) { BerElement *ber; Debug( LDAP_DEBUG_TRACE, "ldap_search\n", 0, 0, 0 ); - if (( ber = ldap_build_search_req( ld, base, scope, filter, attrs, - attrsonly )) == NULLBER ) { + ber = ldap_build_search_req( ld, base, scope, filter, attrs, + attrsonly, NULL, NULL, -1, -1 ); + + if ( ber == NULL ) { return( -1 ); } @@ -76,11 +205,22 @@ ldap_search( LDAP *ld, char *base, int scope, char *filter, BerElement * -ldap_build_search_req( LDAP *ld, char *base, int scope, char *filter, - char **attrs, int attrsonly ) +ldap_build_search_req( + LDAP *ld, + LDAP_CONST char *base_in, + ber_int_t scope, + LDAP_CONST char *filter_in, + char **attrs, + ber_int_t attrsonly, + LDAPControl **sctrls, + LDAPControl **cctrls, + ber_int_t timelimit, + ber_int_t sizelimit ) { BerElement *ber; int err; + char *base; + char *filter; /* * Create the search request. It looks like this: @@ -107,13 +247,15 @@ ldap_build_search_req( LDAP *ld, char *base, int scope, char *filter, */ /* create a message to send */ - if ( (ber = ldap_alloc_ber_with_options( ld )) == NULLBER ) { - return( NULLBER ); + if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) { + return( NULL ); } - if ( base == NULL ) { + if ( base_in == NULL ) { /* no base provided, use session default base */ base = ld->ld_options.ldo_defbase; + } else { + base = (char *) base_in; } if ( base == NULL ) { @@ -124,13 +266,17 @@ ldap_build_search_req( LDAP *ld, char *base, int scope, char *filter, #ifdef LDAP_CONNECTIONLESS if ( ld->ld_cldapnaddr > 0 ) { err = ber_printf( ber, "{ist{seeiib", ++ld->ld_msgid, - ld->ld_cldapdn, LDAP_REQ_SEARCH, base, scope, ld->ld_deref, - ld->ld_sizelimit, ld->ld_timelimit, attrsonly ); + ld->ld_cldapdn, LDAP_REQ_SEARCH, base, scope, ld->ld_deref, + (sizelimit < 0) ? ld->ld_sizelimit : sizelimit, + (timelimit < 0) ? ld->ld_timelimit : timelimit, + attrsonly ); } else { #endif /* LDAP_CONNECTIONLESS */ err = ber_printf( ber, "{it{seeiib", ++ld->ld_msgid, - LDAP_REQ_SEARCH, base, scope, ld->ld_deref, - ld->ld_sizelimit, ld->ld_timelimit, attrsonly ); + LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref, + (sizelimit < 0) ? ld->ld_sizelimit : sizelimit, + (timelimit < 0) ? ld->ld_timelimit : timelimit, + attrsonly ); #ifdef LDAP_CONNECTIONLESS } #endif /* LDAP_CONNECTIONLESS */ @@ -138,23 +284,35 @@ ldap_build_search_req( LDAP *ld, char *base, int scope, char *filter, if ( err == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); - return( NULLBER ); + return( NULL ); } - filter = strdup( filter ); + filter = LDAP_STRDUP( filter_in ); err = put_filter( ber, filter ); - free( filter ); + LDAP_FREE( filter ); if ( err == -1 ) { ld->ld_errno = LDAP_FILTER_ERROR; ber_free( ber, 1 ); - return( NULLBER ); + return( NULL ); } - if ( ber_printf( ber, "{v}}}", attrs ) == -1 ) { + if ( ber_printf( ber, /*{*/ "{v}}", attrs ) == -1 ) { ld->ld_errno = LDAP_ENCODING_ERROR; ber_free( ber, 1 ); - return( NULLBER ); + return( NULL ); + } + + /* Put Server Controls */ + if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) { + ber_free( ber, 1 ); + return( NULL ); + } + + if ( ber_printf( ber, /*{*/ "}", attrs ) == -1 ) { + ld->ld_errno = LDAP_ENCODING_ERROR; + ber_free( ber, 1 ); + return( NULL ); } return( ber ); @@ -186,7 +344,7 @@ find_right_paren( char *s ) } static char * -put_complex_filter( BerElement *ber, char *str, unsigned long tag, int not ) +put_complex_filter( BerElement *ber, char *str, ber_tag_t tag, int not ) { char *next; @@ -198,12 +356,8 @@ put_complex_filter( BerElement *ber, char *str, unsigned long tag, int not ) */ /* put explicit tag */ - if ( ber_printf( ber, "t{", tag ) == -1 ) - return( NULL ); -/* - if ( !not && ber_printf( ber, "{" ) == -1 ) + if ( ber_printf( ber, "t{" /*}*/, tag ) == -1 ) return( NULL ); -*/ str++; if ( (next = find_right_paren( str )) == NULL ) @@ -215,12 +369,8 @@ put_complex_filter( BerElement *ber, char *str, unsigned long tag, int not ) *next++ = ')'; /* flush explicit tagged thang */ - if ( ber_printf( ber, "}" ) == -1 ) + if ( ber_printf( ber, /*{*/ "}" ) == -1 ) return( NULL ); -/* - if ( !not && ber_printf( ber, "}" ) == -1 ) - return( NULL ); -*/ return( next ); } @@ -241,8 +391,9 @@ put_filter( BerElement *ber, char *str ) * substrings [4] SubstringFilter, * greaterOrEqual [5] AttributeValueAssertion, * lessOrEqual [6] AttributeValueAssertion, - * present [7] AttributeType,, - * approxMatch [8] AttributeValueAssertion + * present [7] AttributeType, + * approxMatch [8] AttributeValueAssertion, + * extensibleMatch [9] MatchingRuleAssertion -- LDAPv3 * } * * SubstringFilter ::= SEQUENCE { @@ -253,6 +404,13 @@ put_filter( BerElement *ber, char *str ) * final [2] IA5String * } * } + * + * MatchingRuleAssertion ::= SEQUENCE { -- LDAPv3 + * matchingRule [1] MatchingRuleId OPTIONAL, + * type [2] AttributeDescription OPTIONAL, + * matchValue [3] AssertionValue, + * dnAttributes [4] BOOLEAN DEFAULT FALSE } + * * Note: tags in a choice are always explicit */ @@ -323,7 +481,7 @@ put_filter( BerElement *ber, char *str ) return( -1 ); *next = '\0'; - tmp = strdup( str ); + tmp = LDAP_STRDUP( str ); if ( gotescape ) { escape = 0; for ( s = d = tmp; *s; s++ ) { @@ -337,10 +495,10 @@ put_filter( BerElement *ber, char *str ) *d = '\0'; } if ( put_simple_filter( ber, tmp ) == -1 ) { - free( tmp ); + LDAP_FREE( tmp ); return( -1 ); } - free( tmp ); + LDAP_FREE( tmp ); *next++ = ')'; str = next; parens--; @@ -351,7 +509,7 @@ put_filter( BerElement *ber, char *str ) case ')': Debug( LDAP_DEBUG_TRACE, "put_filter: end\n", 0, 0, 0 ); - if ( ber_printf( ber, "]" ) == -1 ) + if ( ber_printf( ber, /*[*/ "]" ) == -1 ) return( -1 ); str++; parens--; @@ -365,7 +523,7 @@ put_filter( BerElement *ber, char *str ) Debug( LDAP_DEBUG_TRACE, "put_filter: default\n", 0, 0, 0 ); next = strchr( str, '\0' ); - tmp = strdup( str ); + tmp = LDAP_STRDUP( str ); if ( strchr( tmp, '\\' ) != NULL ) { escape = 0; for ( s = d = tmp; *s; s++ ) { @@ -379,10 +537,10 @@ put_filter( BerElement *ber, char *str ) *d = '\0'; } if ( put_simple_filter( ber, tmp ) == -1 ) { - free( tmp ); + LDAP_FREE( tmp ); return( -1 ); } - free( tmp ); + LDAP_FREE( tmp ); str = next; break; } @@ -426,11 +584,13 @@ put_filter_list( BerElement *ber, char *str ) } static int -put_simple_filter( BerElement *ber, char *str ) +put_simple_filter( + BerElement *ber, + char *str ) { char *s; char *value, savechar; - unsigned long ftype; + ber_tag_t ftype; int rc; Debug( LDAP_DEBUG_TRACE, "put_simple_filter \"%s\"\n", str, 0, 0 ); @@ -454,6 +614,10 @@ put_simple_filter( BerElement *ber, char *str ) ftype = LDAP_FILTER_APPROX; *s = '\0'; break; + case ':': /* LDAPv3 extended filter */ + ftype = LDAP_FILTER_EXTENDED; + return -1; + break; default: if ( strchr( value, '*' ) == NULL ) { ftype = LDAP_FILTER_EQUALITY; @@ -482,12 +646,12 @@ static int put_substring_filter( BerElement *ber, char *type, char *val ) { char *nextstar, gotstar = 0; - unsigned long ftype; + ber_tag_t ftype = LDAP_FILTER_SUBSTRINGS; Debug( LDAP_DEBUG_TRACE, "put_substring_filter \"%s=%s\"\n", type, val, 0 ); - if ( ber_printf( ber, "t{s{", LDAP_FILTER_SUBSTRINGS, type ) == -1 ) + if ( ber_printf( ber, "t{s{", ftype, type ) == -1 ) return( -1 ); while ( val != NULL ) { @@ -512,14 +676,16 @@ put_substring_filter( BerElement *ber, char *type, char *val ) val = nextstar; } - if ( ber_printf( ber, "}}" ) == -1 ) + if ( ber_printf( ber, /* {{ */ "}}" ) == -1 ) return( -1 ); return( 0 ); } int -ldap_search_st( LDAP *ld, char *base, int scope, char *filter, char **attrs, +ldap_search_st( + LDAP *ld, LDAP_CONST char *base, int scope, + LDAP_CONST char *filter, char **attrs, int attrsonly, struct timeval *timeout, LDAPMessage **res ) { int msgid; @@ -541,8 +707,14 @@ ldap_search_st( LDAP *ld, char *base, int scope, char *filter, char **attrs, } int -ldap_search_s( LDAP *ld, char *base, int scope, char *filter, char **attrs, - int attrsonly, LDAPMessage **res ) +ldap_search_s( + LDAP *ld, + LDAP_CONST char *base, + int scope, + LDAP_CONST char *filter, + char **attrs, + int attrsonly, + LDAPMessage **res ) { int msgid;