+/* LIBLDAP url.c -- LDAP URL (RFC 2255) related routines */
/* $OpenLDAP$ */
-/*
- * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-/* Portions
- * Copyright (c) 1996 Regents of the University of Michigan.
- * All rights reserved.
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 1998-2004 The OpenLDAP Foundation.
+ * All rights reserved.
*
- * LIBLDAP url.c -- LDAP URL (RFC 2255) related routines
+ * 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
+ * <http://www.OpenLDAP.org/license.html>.
+ */
+/* Portions Copyright (c) 1996 Regents of the University of Michigan.
+ * All rights reserved.
+ */
+
+
+/*
* LDAP URLs look like this:
* ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
*
* scope is one of these three strings: base one sub (default=base)
* filter is an string-represented filter as in RFC 2254
*
- * e.g., ldap://host:port/dc=com?o,cn?base?o=openldap?extension
+ * e.g., ldap://host:port/dc=com?o,cn?base?(o=openldap)?extension
*
* We also tolerate URLs that look like: <ldapurl> and <URL:ldapurl>
*/
#include "ldap-int.h"
-
/* local functions */
static const char* skip_url_prefix LDAP_P((
const char *url,
return -1;
}
-LDAP_F(int) ldap_pvt_url_scheme2tls( const char *scheme )
+int
+ldap_pvt_url_scheme2tls( const char *scheme )
{
assert( scheme );
int *enclosedp,
const char **scheme )
{
-/*
- * 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
- */
+ /*
+ * 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
+ */
const char *p;
if ( url == NULL ) {
if ( strcasecmp( p, "one" ) == 0 ) {
return LDAP_SCOPE_ONELEVEL;
- } else if ( strcasecmp( p, "onetree" ) == 0 ) {
+ } else if ( strcasecmp( p, "onelevel" ) == 0 ) {
return LDAP_SCOPE_ONELEVEL;
} else if ( strcasecmp( p, "base" ) == 0 ) {
} else if ( strcasecmp( p, "subtree" ) == 0 ) {
return LDAP_SCOPE_SUBTREE;
+
+#ifdef LDAP_SCOPE_SUBORDINATE
+ } else if ( strcasecmp( p, "subordinate" ) == 0 ) {
+ return LDAP_SCOPE_SUBORDINATE;
+
+ } else if ( strcasecmp( p, "children" ) == 0 ) {
+ return LDAP_SCOPE_SUBORDINATE;
+#endif
}
return( -1 );
}
}
+ buf[pos] = '\0';
return pos;
}
if ( len ) len++; /* ? */
switch( u->lud_scope ) {
+ case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE:
- case LDAP_SCOPE_BASE:
- len += sizeof("base");
+#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
+ case LDAP_SCOPE_SUBORDINATE:
+#endif
+ len += sizeof("subordinate");
if( !sep ) sep = 3;
break;
};
if( u->lud_port ) {
- len+=6;
+ len += sizeof(":65535") - 1;
}
if( u->lud_host ) {
strcpy( &s[sofar], "sub" );
sofar += sizeof("sub") - 1;
break;
+#ifdef LDAP_FEATURE_SUBORDINATE_SCOPE
+ case LDAP_SCOPE_SUBORDINATE:
+ strcpy( &s[sofar], "children" );
+ sofar += sizeof("children") - 1;
+ break;
+#endif
}
if( sep < 4 ) goto done;
* because a call to LDAP_INT_GLOBAL_OPT() will try to allocate
* the options and cause infinite recursion
*/
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ENTRY, "ldap_url_parse_ext(%s)\n", url_in, 0, 0 );
+#else
Debug( LDAP_DEBUG_TRACE, "ldap_url_parse_ext(%s)\n", url_in, 0, 0 );
+#endif
#endif
*ludpp = NULL; /* pessimistic */
ludp->lud_port = 0;
ludp->lud_dn = NULL;
ludp->lud_attrs = NULL;
- ludp->lud_filter = NULL;
ludp->lud_scope = LDAP_SCOPE_DEFAULT;
ludp->lud_filter = NULL;
ludp->lud_exts = NULL;
}
if ( q != NULL ) {
+ char *next;
+
*q++ = '\0';
ldap_pvt_hex_unescape( q );
return LDAP_URL_ERR_BADURL;
}
- ludp->lud_port = atoi( q );
+ ludp->lud_port = strtol( q, &next, 10 );
+ if ( next == NULL || next[0] != '\0' ) {
+ LDAP_FREE( url );
+ ldap_free_urldesc( ludp );
+ return LDAP_URL_ERR_BADURL;
+ }
}
ldap_pvt_hex_unescape( url );
return LDAP_URL_ERR_BADFILTER;
}
- LDAP_FREE( ludp->lud_filter );
ludp->lud_filter = LDAP_STRDUP( p );
if( ludp->lud_filter == NULL ) {
int
ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
+{
+ return ldap_url_parselist_ext( ludlist, url, ", " );
+}
+
+int
+ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep )
{
int i, rc;
LDAPURLDesc *ludp;
char **urls;
- *ludlist = NULL;
+ assert( ludlist != NULL );
+ assert( url != NULL );
- if (url == NULL)
- return LDAP_PARAM_ERROR;
+ *ludlist = NULL;
- urls = ldap_str2charray((char *)url, ", ");
+ urls = ldap_str2charray(url, sep);
if (urls == NULL)
return LDAP_NO_MEMORY;
LDAPURLDesc *ludp;
char **specs, *p;
- *ludlist = NULL;
+ assert( ludlist != NULL );
+ assert( hosts != NULL );
- if (hosts == NULL)
- return LDAP_PARAM_ERROR;
+ *ludlist = NULL;
- specs = ldap_str2charray((char *)hosts, ", ");
+ specs = ldap_str2charray(hosts, ", ");
if (specs == NULL)
return LDAP_NO_MEMORY;
}
}
if (p != NULL) {
+ char *next;
+
*p++ = 0;
ldap_pvt_hex_unescape(p);
- ludp->lud_port = atoi(p);
+ ludp->lud_port = strtol( p, &next, 10 );
+ if ( next == NULL || next[0] != '\0' ) {
+ return LDAP_PARAM_ERROR;
+ }
}
}
ldap_pvt_hex_unescape(ludp->lud_host);
/* figure out how big the string is */
size = 1; /* nul-term */
for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
- size += strlen(ludp->lud_scheme) + strlen(ludp->lud_host);
- if (strchr(ludp->lud_host, ':')) /* will add [ ] below */
- size += 2;
+ size += strlen(ludp->lud_scheme);
+ if ( ludp->lud_host ) {
+ size += strlen(ludp->lud_host);
+ /* will add [ ] below */
+ if (strchr(ludp->lud_host, ':'))
+ size += 2;
+ }
size += sizeof(":/// ");
if (ludp->lud_port != 0) {
p = s;
for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
- p += sprintf(p,
- strchr(ludp->lud_host, ':') ? "%s://[%s]" : "%s://%s",
- ludp->lud_scheme, ludp->lud_host);
+ p += sprintf(p, "%s://", ludp->lud_scheme);
+ if ( ludp->lud_host ) {
+ p += sprintf(p, strchr(ludp->lud_host, ':')
+ ? "[%s]" : "%s", ludp->lud_host);
+ }
if (ludp->lud_port != 0)
p += sprintf(p, ":%d", ludp->lud_port);
*p++ = '/';
LDAP_FREE( ludp );
}
-
-
-int
-ldap_url_search( LDAP *ld, LDAP_CONST char *url, int attrsonly )
-{
- int err;
- LDAPURLDesc *ludp;
- BerElement *ber;
- LDAPreqinfo bind;
-
- assert( ld != NULL );
- assert( LDAP_VALID( ld ) );
-
- if ( ldap_url_parse( url, &ludp ) != 0 ) {
- ld->ld_errno = LDAP_PARAM_ERROR;
- return( -1 );
- }
-
- if( ludp->lud_crit_exts ) {
- /* we don't support any extension (yet) */
- ld->ld_errno = LDAP_NOT_SUPPORTED;
- return( -1 );
- }
-
- ber = ldap_build_search_req( ld, ludp->lud_dn, ludp->lud_scope,
- ludp->lud_filter, ludp->lud_attrs, attrsonly, NULL, NULL,
- -1, -1 );
-
- if ( ber == NULL ) {
- err = -1;
- } else {
- bind.ri_request = LDAP_REQ_SEARCH;
- bind.ri_msgid = ld->ld_msgid;
- bind.ri_url = (char *)url;
- err = ldap_send_server_request(
- ld, ber, ld->ld_msgid, NULL,
- NULL, NULL, &bind );
- }
-
- ldap_free_urldesc( ludp );
- return( err );
-}
-
-
-int
-ldap_url_search_st( LDAP *ld, LDAP_CONST char *url, int attrsonly,
- struct timeval *timeout, LDAPMessage **res )
+static int
+ldap_int_unhex( int c )
{
- int msgid;
-
- if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) {
- return( ld->ld_errno );
- }
-
- if ( ldap_result( ld, msgid, 1, timeout, res ) == -1 ) {
- return( ld->ld_errno );
- }
-
- if ( ld->ld_errno == LDAP_TIMEOUT ) {
- (void) ldap_abandon( ld, msgid );
- ld->ld_errno = LDAP_TIMEOUT;
- return( ld->ld_errno );
- }
-
- return( ldap_result2error( ld, *res, 0 ));
-}
-
-
-int
-ldap_url_search_s(
- LDAP *ld, LDAP_CONST char *url, int attrsonly, LDAPMessage **res )
-{
- int msgid;
-
- if (( msgid = ldap_url_search( ld, url, attrsonly )) == -1 ) {
- return( ld->ld_errno );
- }
-
- if ( ldap_result( ld, msgid, 1, (struct timeval *)NULL, res ) == -1 ) {
- return( ld->ld_errno );
- }
-
- return( ldap_result2error( ld, *res, 0 ));
+ return( c >= '0' && c <= '9' ? c - '0'
+ : c >= 'A' && c <= 'F' ? c - 'A' + 10
+ : c - 'a' + 10 );
}
-
void
ldap_pvt_hex_unescape( char *s )
{
for ( p = s; *s != '\0'; ++s ) {
if ( *s == '%' ) {
- if ( *++s != '\0' ) {
- *p = ldap_pvt_unhex( *s ) << 4;
+ if ( *++s == '\0' ) {
+ break;
}
- if ( *++s != '\0' ) {
- *p++ += ldap_pvt_unhex( *s );
+ *p = ldap_int_unhex( *s ) << 4;
+ if ( *++s == '\0' ) {
+ break;
}
+ *p++ += ldap_int_unhex( *s );
} else {
*p++ = *s;
}
}
-int
-ldap_pvt_unhex( int c )
-{
- return( c >= '0' && c <= '9' ? c - '0'
- : c >= 'A' && c <= 'F' ? c - 'A' + 10
- : c - 'a' + 10 );
-}