X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Furl.c;h=b632c688f8da78a9b5014bf506d60ab48bef76a9;hb=91e24173d0fa168bdd3e585af2d56f3299a20c00;hp=97b01b8aae9e86c699cc8a0d1e13e57caa67a7c6;hpb=463a7ec91deb32259fa09431f4e86ebe8928413a;p=openldap diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index 97b01b8aae..b632c688f8 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -1,3 +1,4 @@ +/* $OpenLDAP$ */ /* * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file @@ -6,15 +7,15 @@ * Copyright (c) 1996 Regents of the University of Michigan. * All rights reserved. * - * LIBLDAP url.c -- LDAP URL related routines + * LIBLDAP url.c -- LDAP URL (RFC 2255) related routines * * LDAP URLs look like this: - * ldap[s]://host:port/dn[[?attributes[?scope[?filter[?extensions]]]] + * ldap[s]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]] * * where: * attributes is a comma separated list * scope is one of these three strings: base one sub (default=base) - * filter is an string-represented filter as in RFC 1558 + * filter is an string-represented filter as in RFC 2254 * * e.g., ldap://host:port/dc=com?o,cn?base?o=openldap?extension * @@ -40,8 +41,6 @@ static const char* skip_url_prefix LDAP_P(( const char *url, int *enclosedp, int *ldaps )); -static void hex_unescape LDAP_P(( char *s )); -static int unhex( char c ); int @@ -88,13 +87,13 @@ skip_url_prefix( * return non-zero if this looks like a LDAP URL; zero if not * if non-zero returned, *urlp will be moved past "ldap://" part of URL */ - char* p; + const char *p; if ( url == NULL ) { return( NULL ); } - p = (char *) url; + p = url; /* skip leading '<' (if any) */ if ( *p == '<' ) { @@ -161,7 +160,7 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) LDAPURLDesc *ludp; char *p, *q; - int enclosed, ldaps; + int i, enclosed, ldaps; const char *url_tmp; char *url; @@ -210,6 +209,7 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) ludp->lud_filter = NULL; ludp->lud_ldaps = ldaps; ludp->lud_scope = LDAP_SCOPE_BASE; + ludp->lud_filter = LDAP_STRDUP("(objectClass=*)"); if( ludp->lud_filter == NULL ) { @@ -221,18 +221,14 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) /* scan forward for '/' that marks end of hostport and begin. of dn */ p = strchr( url, '/' ); - if( p == NULL ) { - LDAP_FREE( url ); - ldap_free_urldesc( ludp ); - return LDAP_URL_ERR_BADURL; + if( p != NULL ) { + /* terminate hostport; point to start of dn */ + *p++ = '\0'; } - /* terminate hostport; point to start of dn */ - *p++ = '\0'; - if (( q = strchr( url, ':' )) != NULL ) { *q++ = '\0'; - hex_unescape( q ); + ldap_pvt_hex_unescape( q ); if( *q == '\0' ) { LDAP_FREE( url ); @@ -243,7 +239,7 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) ludp->lud_port = atoi( q ); } - hex_unescape( url ); + ldap_pvt_hex_unescape( url ); ludp->lud_host = LDAP_STRDUP( url ); if( ludp->lud_host == NULL ) { @@ -252,28 +248,27 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) return LDAP_URL_ERR_MEM; } - /* scan forward for '?' that may marks end of dn */ - q = strchr( p, '?' ); - - if( q == NULL ) { - /* no '?' */ - hex_unescape( p ); - ludp->lud_dn = LDAP_STRDUP( p ); - - if( ludp->lud_dn == NULL ) { - LDAP_FREE( url ); - ldap_free_urldesc( ludp ); - return LDAP_URL_ERR_MEM; - } - + if( p == NULL ) { LDAP_FREE( url ); *ludpp = ludp; return LDAP_URL_SUCCESS; } - *q++ = '\0'; - hex_unescape( p ); - ludp->lud_dn = LDAP_STRDUP( p ); + /* scan forward for '?' that may marks end of dn */ + q = strchr( p, '?' ); + + if( q != NULL ) { + /* terminate dn part */ + *q++ = '\0'; + } + + if( *p != '\0' ) { + /* parse dn part */ + ldap_pvt_hex_unescape( p ); + ludp->lud_dn = LDAP_STRDUP( p ); + } else { + ludp->lud_dn = LDAP_STRDUP( "" ); + } if( ludp->lud_dn == NULL ) { LDAP_FREE( url ); @@ -281,13 +276,25 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) return LDAP_URL_ERR_MEM; } + if( q == NULL ) { + /* no more */ + LDAP_FREE( url ); + *ludpp = ludp; + return LDAP_URL_SUCCESS; + } + /* scan forward for '?' that may marks end of attributes */ p = q; q = strchr( p, '?' ); - if( q == NULL ) { - /* no '?' */ - hex_unescape( p ); + if( q != NULL ) { + /* terminate attributes part */ + *q++ = '\0'; + } + + if( *p != '\0' ) { + /* parse attributes */ + ldap_pvt_hex_unescape( p ); ludp->lud_attrs = ldap_str2charray( p, "," ); if( ludp->lud_attrs == NULL ) { @@ -295,40 +302,27 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) ldap_free_urldesc( ludp ); return LDAP_URL_ERR_BADATTRS; } + } + if ( q == NULL ) { + /* no more */ LDAP_FREE( url ); *ludpp = ludp; return LDAP_URL_SUCCESS; } - *q++ = '\0'; - hex_unescape( p ); - ludp->lud_attrs = ldap_str2charray( p, "," ); - /* scan forward for '?' that may marks end of scope */ p = q; q = strchr( p, '?' ); - if( q == NULL ) { - /* no '?' */ - hex_unescape( p ); - ludp->lud_scope = str2scope( p ); - - if( ludp->lud_scope == -1 ) { - LDAP_FREE( url ); - ldap_free_urldesc( ludp ); - return LDAP_URL_ERR_BADSCOPE; - } - - LDAP_FREE( url ); - *ludpp = ludp; - return LDAP_URL_SUCCESS; + if( q != NULL ) { + /* terminate the scope part */ + *q++ = '\0'; } - *q++ = '\0'; - hex_unescape( p ); - if( *p != '\0' ) { + /* parse the scope */ + ldap_pvt_hex_unescape( p ); ludp->lud_scope = str2scope( p ); if( ludp->lud_scope == -1 ) { @@ -336,7 +330,10 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) ldap_free_urldesc( ludp ); return LDAP_URL_ERR_BADSCOPE; } + } + if ( q == NULL ) { + /* no more */ LDAP_FREE( url ); *ludpp = ludp; return LDAP_URL_SUCCESS; @@ -346,9 +343,14 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) p = q; q = strchr( p, '?' ); + if( q != NULL ) { + /* terminate the filter part */ + *q++ = '\0'; + } + if( *p != '\0' ) { - /* no '?' */ - hex_unescape( p ); + /* parse the filter */ + ldap_pvt_hex_unescape( p ); if( ! *p ) { /* missing filter */ @@ -357,6 +359,7 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) return LDAP_URL_ERR_BADFILTER; } + LDAP_FREE( ludp->lud_filter ); ludp->lud_filter = LDAP_STRDUP( p ); if( ludp->lud_filter == NULL ) { @@ -364,25 +367,15 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) ldap_free_urldesc( ludp ); return LDAP_URL_ERR_MEM; } + } + if ( q == NULL ) { + /* no more */ LDAP_FREE( url ); *ludpp = ludp; return LDAP_URL_SUCCESS; } - *q++ = '\0'; - hex_unescape( p ); - - if( *p != '\0' ) { - ludp->lud_filter = LDAP_STRDUP( p ); - - if( ludp->lud_filter == NULL ) { - LDAP_FREE( url ); - ldap_free_urldesc( ludp ); - return LDAP_URL_ERR_MEM; - } - } - /* scan forward for '?' that may marks end of extensions */ p = q; q = strchr( p, '?' ); @@ -394,6 +387,7 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) return LDAP_URL_ERR_BADURL; } + /* parse the extensions */ ludp->lud_exts = ldap_str2charray( p, "," ); if( ludp->lud_exts == NULL ) { @@ -402,8 +396,20 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) return LDAP_URL_ERR_BADEXTS; } - *ludpp = ludp; + for( i=0; ludp->lud_exts[i] != NULL; i++ ) { + ldap_pvt_hex_unescape( ludp->lud_exts[i] ); + } + + if( i == 0 ) { + /* must have 1 or more */ + ldap_charray_free( ludp->lud_exts ); + LDAP_FREE( url ); + ldap_free_urldesc( ludp ); + return LDAP_URL_ERR_BADEXTS; + } + /* no more */ + *ludpp = ludp; LDAP_FREE( url ); return LDAP_URL_SUCCESS; } @@ -537,8 +543,8 @@ ldap_url_search_s( } -static void -hex_unescape( char *s ) +void +ldap_pvt_hex_unescape( char *s ) { /* * Remove URL hex escapes from s... done in place. The basic concept for @@ -549,10 +555,10 @@ hex_unescape( char *s ) for ( p = s; *s != '\0'; ++s ) { if ( *s == '%' ) { if ( *++s != '\0' ) { - *p = unhex( *s ) << 4; + *p = ldap_pvt_unhex( *s ) << 4; } if ( *++s != '\0' ) { - *p++ += unhex( *s ); + *p++ += ldap_pvt_unhex( *s ); } } else { *p++ = *s; @@ -563,8 +569,8 @@ hex_unescape( char *s ) } -static int -unhex( char c ) +int +ldap_pvt_unhex( int c ) { return( c >= '0' && c <= '9' ? c - '0' : c >= 'A' && c <= 'F' ? c - 'A' + 10