* 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
*
const char *url,
int *enclosedp,
int *ldaps ));
-static void hex_unescape LDAP_P(( char *s ));
-static int unhex( char c );
int
* 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 == '<' ) {
LDAPURLDesc *ludp;
char *p, *q;
- int enclosed, ldaps;
+ int i, enclosed, ldaps;
const char *url_tmp;
char *url;
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 ) {
/* 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 );
ludp->lud_port = atoi( q );
}
- hex_unescape( url );
+ ldap_pvt_hex_unescape( url );
ludp->lud_host = LDAP_STRDUP( url );
if( ludp->lud_host == NULL ) {
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 );
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 ) {
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 ) {
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADSCOPE;
}
+ }
+ if ( q == NULL ) {
+ /* no more */
LDAP_FREE( url );
*ludpp = ludp;
return LDAP_URL_SUCCESS;
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 */
return LDAP_URL_ERR_BADFILTER;
}
+ LDAP_FREE( ludp->lud_filter );
ludp->lud_filter = LDAP_STRDUP( p );
if( ludp->lud_filter == NULL ) {
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, '?' );
return LDAP_URL_ERR_BADURL;
}
+ /* parse the extensions */
ludp->lud_exts = ldap_str2charray( p, "," );
if( ludp->lud_exts == NULL ) {
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;
}
}
if ( ludp->lud_host != NULL ) {
- LDAP_FREE( ludp->lud_dn );
+ LDAP_FREE( ludp->lud_host );
}
if ( ludp->lud_dn != NULL ) {
}
-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
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;
}
-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