openldap/libraries/libldap/url.c

1236 lines
24 KiB
C
Raw Normal View History

/* $OpenLDAP$ */
1998-08-09 08:43:13 +08:00
/*
2000-05-13 10:36:07 +08:00
* Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
1998-12-29 04:53:15 +08:00
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/* Portions
1998-08-09 08:43:13 +08:00
* Copyright (c) 1996 Regents of the University of Michigan.
* All rights reserved.
*
1999-07-24 05:56:21 +08:00
* LIBLDAP url.c -- LDAP URL (RFC 2255) related routines
1998-08-09 08:43:13 +08:00
*
* LDAP URLs look like this:
* ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]]
1998-08-09 08:43:13 +08:00
*
* where:
* attributes is a comma separated list
* scope is one of these three strings: base one sub (default=base)
1999-07-24 05:56:21 +08:00
* filter is an string-represented filter as in RFC 2254
1998-08-09 08:43:13 +08:00
*
2001-12-09 10:34:45 +08:00
* e.g., ldap://host:port/dc=com?o,cn?base?(o=openldap)?extension
1998-08-09 08:43:13 +08:00
*
* We also tolerate URLs that look like: <ldapurl> and <URL:ldapurl>
*/
#include "portable.h"
1998-08-09 08:43:13 +08:00
#include <stdio.h>
1999-06-03 08:37:44 +08:00
#include <ac/stdlib.h>
1998-08-09 08:43:13 +08:00
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
1998-08-09 08:43:13 +08:00
#include "ldap-int.h"
/* local functions */
1999-07-20 03:32:47 +08:00
static const char* skip_url_prefix LDAP_P((
const char *url,
int *enclosedp,
const char **scheme ));
1998-08-09 08:43:13 +08:00
int ldap_pvt_url_scheme2proto( const char *scheme )
{
assert( scheme );
if( scheme == NULL ) {
return -1;
}
if( strcmp("ldap", scheme) == 0 ) {
return LDAP_PROTO_TCP;
}
if( strcmp("ldapi", scheme) == 0 ) {
return LDAP_PROTO_IPC;
}
if( strcmp("ldaps", scheme) == 0 ) {
return LDAP_PROTO_TCP;
}
#ifdef LDAP_CONNECTIONLESS
if( strcmp("cldap", scheme) == 0 ) {
return LDAP_PROTO_UDP;
}
#endif
return -1;
}
2001-12-07 12:03:25 +08:00
int
ldap_pvt_url_scheme2tls( const char *scheme )
{
assert( scheme );
if( scheme == NULL ) {
return -1;
}
return strcmp("ldaps", scheme) == 0;
}
1998-08-09 08:43:13 +08:00
int
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
ldap_is_ldap_url( LDAP_CONST char *url )
1998-08-09 08:43:13 +08:00
{
int enclosed;
const char * scheme;
1998-08-09 08:43:13 +08:00
1999-07-20 03:32:47 +08:00
if( url == NULL ) {
return 0;
}
if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
1999-07-20 03:32:47 +08:00
return 0;
}
return 1;
1998-08-09 08:43:13 +08:00
}
1999-07-20 03:32:47 +08:00
int
ldap_is_ldaps_url( LDAP_CONST char *url )
{
int enclosed;
const char * scheme;
1999-07-20 03:32:47 +08:00
if( url == NULL ) {
return 0;
}
if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
1999-07-20 03:32:47 +08:00
return 0;
}
return strcmp(scheme, "ldaps") == 0;
}
int
ldap_is_ldapi_url( LDAP_CONST char *url )
{
int enclosed;
const char * scheme;
if( url == NULL ) {
return 0;
}
if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
return 0;
}
return strcmp(scheme, "ldapi") == 0;
1999-07-20 03:32:47 +08:00
}
1998-08-09 08:43:13 +08:00
#ifdef LDAP_CONNECTIONLESS
int
ldap_is_ldapc_url( LDAP_CONST char *url )
{
int enclosed;
const char * scheme;
if( url == NULL ) {
return 0;
}
if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) {
return 0;
}
return strcmp(scheme, "cldap") == 0;
}
#endif
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
static const char*
1999-07-20 03:32:47 +08:00
skip_url_prefix(
const char *url,
int *enclosedp,
const char **scheme )
1998-08-09 08:43:13 +08:00
{
2001-11-29 00:49:46 +08:00
/*
* 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;
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
if ( url == NULL ) {
return( NULL );
1998-08-09 08:43:13 +08:00
}
p = url;
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
1998-08-09 08:43:13 +08:00
/* skip leading '<' (if any) */
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
if ( *p == '<' ) {
1998-08-09 08:43:13 +08:00
*enclosedp = 1;
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
++p;
1998-08-09 08:43:13 +08:00
} else {
*enclosedp = 0;
}
/* skip leading "URL:" (if any) */
if ( strncasecmp( p, LDAP_URL_URLCOLON, LDAP_URL_URLCOLON_LEN ) == 0 ) {
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
p += LDAP_URL_URLCOLON_LEN;
1998-08-09 08:43:13 +08:00
}
1999-07-20 03:32:47 +08:00
/* check for "ldap://" prefix */
if ( strncasecmp( p, LDAP_URL_PREFIX, LDAP_URL_PREFIX_LEN ) == 0 ) {
/* skip over "ldap://" prefix and return success */
p += LDAP_URL_PREFIX_LEN;
*scheme = "ldap";
1999-07-20 03:32:47 +08:00
return( p );
}
/* check for "ldaps://" prefix */
if ( strncasecmp( p, LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) {
/* skip over "ldaps://" prefix and return success */
p += LDAPS_URL_PREFIX_LEN;
*scheme = "ldaps";
return( p );
}
/* check for "ldapi://" prefix */
if ( strncasecmp( p, LDAPI_URL_PREFIX, LDAPI_URL_PREFIX_LEN ) == 0 ) {
/* skip over "ldapi://" prefix and return success */
p += LDAPI_URL_PREFIX_LEN;
*scheme = "ldapi";
1999-07-20 03:32:47 +08:00
return( p );
1998-08-09 08:43:13 +08:00
}
#ifdef LDAP_CONNECTIONLESS
/* check for "cldap://" prefix */
if ( strncasecmp( p, LDAPC_URL_PREFIX, LDAPC_URL_PREFIX_LEN ) == 0 ) {
/* skip over "cldap://" prefix and return success */
p += LDAPC_URL_PREFIX_LEN;
*scheme = "cldap";
return( p );
}
#endif
1999-07-20 03:32:47 +08:00
return( NULL );
1998-08-09 08:43:13 +08:00
}
1999-07-20 03:32:47 +08:00
static int str2scope( const char *p )
{
if ( strcasecmp( p, "one" ) == 0 ) {
return LDAP_SCOPE_ONELEVEL;
} else if ( strcasecmp( p, "onetree" ) == 0 ) {
return LDAP_SCOPE_ONELEVEL;
} else if ( strcasecmp( p, "base" ) == 0 ) {
return LDAP_SCOPE_BASE;
} else if ( strcasecmp( p, "sub" ) == 0 ) {
return LDAP_SCOPE_SUBTREE;
} else if ( strcasecmp( p, "subtree" ) == 0 ) {
return LDAP_SCOPE_SUBTREE;
}
return( -1 );
}
2001-09-25 02:30:57 +08:00
static int hex_escape( char *buf, const char *s, int list )
{
int i;
int pos;
static const char hex[] = "0123456789ABCDEF";
if( s == NULL ) return 0;
for( pos=0,i=0; s[i]; i++ ) {
int escape = 0;
switch( s[i] ) {
case ',':
escape = list;
break;
case '%':
case '?':
case ' ':
case '<':
case '>':
case '"':
case '#':
case '{':
case '}':
case '|':
case '\\':
case '^':
case '~':
case '`':
case '[':
case ']':
escape = 1;
break;
default:
escape = s[i] < 0x20 || 0x1f >= s[i];
}
if( escape ) {
buf[pos++] = '%';
buf[pos++] = hex[ (s[i] >> 4) & 0x0f ];
buf[pos++] = hex[ s[i] & 0x0f ];
} else {
buf[pos++] = s[i];
}
}
2001-10-26 10:01:42 +08:00
buf[pos] = '\0';
2001-09-25 02:30:57 +08:00
return pos;
}
static int hex_escape_args( char *buf, char **s )
{
int pos;
int i;
if( s == NULL ) return 0;
pos = 0;
for( i=0; s[i] != NULL; i++ ) {
if( pos ) {
buf[pos++] = ',';
}
pos += hex_escape( &buf[pos], s[i], 1 );
}
return pos;
}
char * ldap_url_desc2str( LDAPURLDesc *u )
{
char *s;
int i;
int sep = 0;
int sofar;
size_t len = 0;
if( u == NULL ) return NULL;
if( u->lud_exts ) {
for( i=0; u->lud_exts[i]; i++ ) {
len += strlen( u->lud_exts[i] ) + 1;
}
if( !sep ) sep = 5;
}
if( u->lud_filter ) {
len += strlen( u->lud_filter );
if( !sep ) sep = 4;
}
if ( len ) len++; /* ? */
switch( u->lud_scope ) {
case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE:
case LDAP_SCOPE_BASE:
len += sizeof("base");
if( !sep ) sep = 3;
break;
default:
if ( len ) len++; /* ? */
}
if( u->lud_attrs ) {
for( i=0; u->lud_attrs[i]; i++ ) {
len += strlen( u->lud_attrs[i] ) + 1;
}
if( !sep ) sep = 2;
} else if ( len ) len++; /* ? */
if( u->lud_dn ) {
len += strlen( u->lud_dn ) + 1;
if( !sep ) sep = 1;
};
if( u->lud_port ) {
len+=6;
}
if( u->lud_host ) {
len+=strlen( u->lud_host );
}
len += strlen( u->lud_scheme ) + sizeof("://");
/* allocate enough to hex escape everything -- overkill */
s = LDAP_MALLOC( 3*len );
if( s == NULL ) return NULL;
if( u->lud_port ) {
sprintf( s, "%s://%s:%d%n", u->lud_scheme,
u->lud_host, u->lud_port, &sofar );
} else {
sprintf( s, "%s://%s%n", u->lud_scheme,
u->lud_host, &sofar );
}
if( sep < 1 ) goto done;
s[sofar++] = '/';
sofar += hex_escape( &s[sofar], u->lud_dn, 0 );
if( sep < 2 ) goto done;
s[sofar++] = '?';
sofar += hex_escape_args( &s[sofar], u->lud_attrs );
if( sep < 3 ) goto done;
s[sofar++] = '?';
switch( u->lud_scope ) {
case LDAP_SCOPE_BASE:
strcpy( &s[sofar], "base" );
sofar += sizeof("base") - 1;
break;
case LDAP_SCOPE_ONELEVEL:
strcpy( &s[sofar], "one" );
sofar += sizeof("one") - 1;
break;
case LDAP_SCOPE_SUBTREE:
strcpy( &s[sofar], "sub" );
sofar += sizeof("sub") - 1;
break;
}
if( sep < 4 ) goto done;
s[sofar++] = '?';
sofar += hex_escape( &s[sofar], u->lud_filter, 0 );
if( sep < 5 ) goto done;
s[sofar++] = '?';
sofar += hex_escape_args( &s[sofar], u->lud_exts );
done:
s[sofar] = '\0';
return s;
}
1998-08-09 08:43:13 +08:00
int
ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
1998-08-09 08:43:13 +08:00
{
/*
* Pick apart the pieces of an LDAP URL.
*/
LDAPURLDesc *ludp;
char *p, *q, *r;
int i, enclosed;
const char *scheme = NULL;
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
const char *url_tmp;
char *url;
1998-08-09 08:43:13 +08:00
2001-04-13 07:05:19 +08:00
if( url_in == NULL || ludpp == NULL ) {
1999-07-20 03:32:47 +08:00
return LDAP_URL_ERR_PARAM;
}
#ifndef LDAP_INT_IN_KERNEL
2000-06-13 13:50:23 +08:00
/* Global options may not be created yet
* We can't test if the global options are initialized
* because a call to LDAP_INT_GLOBAL_OPT() will try to allocate
* the options and cause infinite recursion
*/
Debug( LDAP_DEBUG_TRACE, "ldap_url_parse_ext(%s)\n", url_in, 0, 0 );
#endif
1998-08-09 08:43:13 +08:00
*ludpp = NULL; /* pessimistic */
url_tmp = skip_url_prefix( url_in, &enclosed, &scheme );
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
if ( url_tmp == NULL ) {
return LDAP_URL_ERR_BADSCHEME;
1998-08-09 08:43:13 +08:00
}
assert( scheme );
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
/* make working copy of the remainder of the URL */
2000-06-13 13:50:23 +08:00
url = LDAP_STRDUP( url_tmp );
if ( url == NULL ) {
return LDAP_URL_ERR_MEM;
1998-08-09 08:43:13 +08:00
}
1999-07-20 03:32:47 +08:00
if ( enclosed ) {
p = &url[strlen(url)-1];
1998-08-09 08:43:13 +08:00
1999-07-20 03:32:47 +08:00
if( *p != '>' ) {
LDAP_FREE( url );
return LDAP_URL_ERR_BADENCLOSURE;
}
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
1998-08-09 08:43:13 +08:00
*p = '\0';
}
1999-07-20 03:32:47 +08:00
/* allocate return struct */
ludp = (LDAPURLDesc *)LDAP_CALLOC( 1, sizeof( LDAPURLDesc ));
if ( ludp == NULL ) {
LDAP_FREE( url );
return LDAP_URL_ERR_MEM;
}
ludp->lud_next = NULL;
1999-07-20 03:32:47 +08:00
ludp->lud_host = NULL;
2001-09-25 02:30:57 +08:00
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;
1999-07-24 06:02:57 +08:00
ludp->lud_scheme = LDAP_STRDUP( scheme );
1998-08-09 08:43:13 +08:00
if ( ludp->lud_scheme == NULL ) {
1999-07-20 03:32:47 +08:00
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_MEM;
}
1998-08-09 08:43:13 +08:00
/* scan forward for '/' that marks end of hostport and begin. of dn */
1999-07-20 03:32:47 +08:00
p = strchr( url, '/' );
if( p != NULL ) {
/* terminate hostport; point to start of dn */
*p++ = '\0';
1998-08-09 08:43:13 +08:00
}
/* IPv6 syntax with [ip address]:port */
if ( *url == '[' ) {
r = strchr( url, ']' );
if ( r == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADURL;
}
*r++ = '\0';
q = strchr( r, ':' );
} else {
q = strchr( url, ':' );
}
2000-06-13 13:50:23 +08:00
if ( q != NULL ) {
1999-07-20 03:32:47 +08:00
*q++ = '\0';
ldap_pvt_hex_unescape( q );
1998-08-09 08:43:13 +08:00
1999-07-20 03:32:47 +08:00
if( *q == '\0' ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADURL;
}
ludp->lud_port = atoi( q );
1998-08-09 08:43:13 +08:00
}
ldap_pvt_hex_unescape( url );
/* If [ip address]:port syntax, url is [ip and we skip the [ */
ludp->lud_host = LDAP_STRDUP( url + ( *url == '[' ) );
1999-07-20 03:32:47 +08:00
if( ludp->lud_host == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_MEM;
}
/*
* Kludge. ldap://111.222.333.444:389??cn=abc,o=company
*
* On early Novell releases, search references/referrals were returned
* in this format, i.e., the dn was kind of in the scope position,
* but the required slash is missing. The whole thing is illegal syntax,
* but we need to account for it. Fortunately it can't be confused with
* anything real.
*/
2000-06-13 13:50:23 +08:00
if( (p == NULL) && (q != NULL) && ((q = strchr( q, '?')) != NULL)) {
q++;
/* ? immediately followed by question */
if( *q == '?') {
q++;
if( *q != '\0' ) {
/* parse dn part */
ldap_pvt_hex_unescape( q );
ludp->lud_dn = LDAP_STRDUP( q );
} else {
ludp->lud_dn = LDAP_STRDUP( "" );
}
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;
}
1999-07-20 03:32:47 +08:00
/* 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 );
1999-07-20 03:32:47 +08:00
ludp->lud_dn = LDAP_STRDUP( p );
} else {
ludp->lud_dn = LDAP_STRDUP( "" );
1998-08-09 08:43:13 +08:00
}
1999-07-20 03:32:47 +08:00
if( ludp->lud_dn == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_MEM;
1998-08-09 08:43:13 +08:00
}
if( q == NULL ) {
/* no more */
LDAP_FREE( url );
*ludpp = ludp;
return LDAP_URL_SUCCESS;
}
1999-07-20 03:32:47 +08:00
/* scan forward for '?' that may marks end of attributes */
p = q;
q = strchr( p, '?' );
if( q != NULL ) {
/* terminate attributes part */
*q++ = '\0';
}
if( *p != '\0' ) {
/* parse attributes */
ldap_pvt_hex_unescape( p );
1999-07-20 03:32:47 +08:00
ludp->lud_attrs = ldap_str2charray( p, "," );
if( ludp->lud_attrs == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADATTRS;
1998-08-09 08:43:13 +08:00
}
}
if ( q == NULL ) {
/* no more */
1999-07-20 03:32:47 +08:00
LDAP_FREE( url );
*ludpp = ludp;
return LDAP_URL_SUCCESS;
}
/* scan forward for '?' that may marks end of scope */
p = q;
q = strchr( p, '?' );
if( q != NULL ) {
/* terminate the scope part */
*q++ = '\0';
1999-07-20 03:32:47 +08:00
}
1999-07-20 03:32:47 +08:00
if( *p != '\0' ) {
/* parse the scope */
ldap_pvt_hex_unescape( p );
1999-07-20 03:32:47 +08:00
ludp->lud_scope = str2scope( p );
if( ludp->lud_scope == -1 ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADSCOPE;
1998-08-09 08:43:13 +08:00
}
}
if ( q == NULL ) {
/* no more */
1999-07-20 03:32:47 +08:00
LDAP_FREE( url );
*ludpp = ludp;
return LDAP_URL_SUCCESS;
}
/* scan forward for '?' that may marks end of filter */
p = q;
q = strchr( p, '?' );
if( q != NULL ) {
/* terminate the filter part */
*q++ = '\0';
}
1999-07-20 03:32:47 +08:00
if( *p != '\0' ) {
/* parse the filter */
ldap_pvt_hex_unescape( p );
1999-07-20 03:32:47 +08:00
if( ! *p ) {
/* missing filter */
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADFILTER;
}
1999-07-24 06:02:57 +08:00
LDAP_FREE( ludp->lud_filter );
1999-07-20 03:32:47 +08:00
ludp->lud_filter = LDAP_STRDUP( p );
if( ludp->lud_filter == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_MEM;
}
}
if ( q == NULL ) {
/* no more */
1999-07-20 03:32:47 +08:00
LDAP_FREE( url );
*ludpp = ludp;
return LDAP_URL_SUCCESS;
}
/* scan forward for '?' that may marks end of extensions */
p = q;
q = strchr( p, '?' );
if( q != NULL ) {
/* extra '?' */
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADURL;
}
/* parse the extensions */
1999-07-20 03:32:47 +08:00
ludp->lud_exts = ldap_str2charray( p, "," );
if( ludp->lud_exts == NULL ) {
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADEXTS;
1999-07-22 04:44:40 +08:00
}
for( i=0; ludp->lud_exts[i] != NULL; i++ ) {
ldap_pvt_hex_unescape( ludp->lud_exts[i] );
if( *ludp->lud_exts[i] == '!' ) {
/* count the number of critical extensions */
ludp->lud_crit_exts++;
}
1999-07-22 04:44:40 +08:00
}
if( i == 0 ) {
/* must have 1 or more */
1999-07-22 04:44:40 +08:00
LDAP_FREE( url );
ldap_free_urldesc( ludp );
return LDAP_URL_ERR_BADEXTS;
1998-08-09 08:43:13 +08:00
}
/* no more */
1998-08-09 08:43:13 +08:00
*ludpp = ludp;
1999-07-20 03:32:47 +08:00
LDAP_FREE( url );
return LDAP_URL_SUCCESS;
1998-08-09 08:43:13 +08:00
}
int
ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp )
{
int rc = ldap_url_parse_ext( url_in, ludpp );
if( rc != LDAP_URL_SUCCESS ) {
return rc;
}
if ((*ludpp)->lud_scope == LDAP_SCOPE_DEFAULT) {
(*ludpp)->lud_scope = LDAP_SCOPE_BASE;
}
if ((*ludpp)->lud_host != NULL && *(*ludpp)->lud_host == '\0') {
LDAP_FREE( (*ludpp)->lud_host );
(*ludpp)->lud_host = NULL;
}
2001-09-25 02:30:57 +08:00
if ((*ludpp)->lud_port == 0) {
if( strcmp((*ludpp)->lud_scheme, "ldap") == 0 ) {
(*ludpp)->lud_port = LDAP_PORT;
#ifdef LDAP_CONNECTIONLESS
} else if( strcmp((*ludpp)->lud_scheme, "cldap") == 0 ) {
(*ludpp)->lud_port = LDAP_PORT;
#endif
2001-09-25 02:30:57 +08:00
} else if( strcmp((*ludpp)->lud_scheme, "ldaps") == 0 ) {
(*ludpp)->lud_port = LDAPS_PORT;
}
}
return rc;
}
LDAPURLDesc *
ldap_url_dup ( LDAPURLDesc *ludp )
{
LDAPURLDesc *dest;
if ( ludp == NULL ) {
return NULL;
}
dest = LDAP_MALLOC( sizeof(LDAPURLDesc) );
if (dest == NULL)
return NULL;
*dest = *ludp;
dest->lud_scheme = NULL;
dest->lud_host = NULL;
dest->lud_dn = NULL;
dest->lud_filter = NULL;
dest->lud_attrs = NULL;
dest->lud_exts = NULL;
dest->lud_next = NULL;
if ( ludp->lud_scheme != NULL ) {
dest->lud_scheme = LDAP_STRDUP( ludp->lud_scheme );
if (dest->lud_scheme == NULL) {
ldap_free_urldesc(dest);
return NULL;
}
}
if ( ludp->lud_host != NULL ) {
dest->lud_host = LDAP_STRDUP( ludp->lud_host );
if (dest->lud_host == NULL) {
ldap_free_urldesc(dest);
return NULL;
}
}
if ( ludp->lud_dn != NULL ) {
dest->lud_dn = LDAP_STRDUP( ludp->lud_dn );
if (dest->lud_dn == NULL) {
ldap_free_urldesc(dest);
return NULL;
}
}
if ( ludp->lud_filter != NULL ) {
dest->lud_filter = LDAP_STRDUP( ludp->lud_filter );
if (dest->lud_filter == NULL) {
ldap_free_urldesc(dest);
return NULL;
}
}
if ( ludp->lud_attrs != NULL ) {
dest->lud_attrs = ldap_charray_dup( ludp->lud_attrs );
if (dest->lud_attrs == NULL) {
ldap_free_urldesc(dest);
return NULL;
}
}
if ( ludp->lud_exts != NULL ) {
dest->lud_exts = ldap_charray_dup( ludp->lud_exts );
if (dest->lud_exts == NULL) {
ldap_free_urldesc(dest);
return NULL;
}
}
return dest;
}
LDAPURLDesc *
ldap_url_duplist (LDAPURLDesc *ludlist)
{
LDAPURLDesc *dest, *tail, *ludp, *newludp;
dest = NULL;
tail = NULL;
for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
newludp = ldap_url_dup(ludp);
if (newludp == NULL) {
ldap_free_urllist(dest);
return NULL;
}
if (tail == NULL)
dest = newludp;
else
tail->lud_next = newludp;
tail = newludp;
}
return dest;
}
int
ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
{
int i, rc;
LDAPURLDesc *ludp;
char **urls;
*ludlist = NULL;
if (url == NULL)
return LDAP_PARAM_ERROR;
urls = ldap_str2charray((char *)url, ", ");
if (urls == NULL)
return LDAP_NO_MEMORY;
/* count the URLs... */
for (i = 0; urls[i] != NULL; i++) ;
/* ...and put them in the "stack" backward */
while (--i >= 0) {
rc = ldap_url_parse( urls[i], &ludp );
if ( rc != 0 ) {
ldap_charray_free(urls);
ldap_free_urllist(*ludlist);
*ludlist = NULL;
return rc;
}
ludp->lud_next = *ludlist;
*ludlist = ludp;
}
ldap_charray_free(urls);
return LDAP_SUCCESS;
}
int
2000-09-02 07:03:17 +08:00
ldap_url_parsehosts(
LDAPURLDesc **ludlist,
const char *hosts,
int port )
{
int i;
LDAPURLDesc *ludp;
char **specs, *p;
*ludlist = NULL;
if (hosts == NULL)
return LDAP_PARAM_ERROR;
specs = ldap_str2charray((char *)hosts, ", ");
if (specs == NULL)
return LDAP_NO_MEMORY;
/* count the URLs... */
for (i = 0; specs[i] != NULL; i++) /* EMPTY */;
/* ...and put them in the "stack" backward */
while (--i >= 0) {
ludp = LDAP_CALLOC( 1, sizeof(LDAPURLDesc) );
if (ludp == NULL) {
ldap_charray_free(specs);
ldap_free_urllist(*ludlist);
*ludlist = NULL;
return LDAP_NO_MEMORY;
}
2000-09-02 07:03:17 +08:00
ludp->lud_port = port;
ludp->lud_host = specs[i];
specs[i] = NULL;
p = strchr(ludp->lud_host, ':');
if (p != NULL) {
/* more than one :, IPv6 address */
if ( strchr(p+1, ':') != NULL ) {
/* allow [address] and [address]:port */
if ( *ludp->lud_host == '[' ) {
p = LDAP_STRDUP(ludp->lud_host+1);
/* copied, make sure we free source later */
specs[i] = ludp->lud_host;
ludp->lud_host = p;
p = strchr( ludp->lud_host, ']' );
if ( p == NULL )
return LDAP_PARAM_ERROR;
*p++ = '\0';
if ( *p != ':' ) {
if ( *p != '\0' )
return LDAP_PARAM_ERROR;
p = NULL;
}
} else {
p = NULL;
}
}
if (p != NULL) {
*p++ = 0;
ldap_pvt_hex_unescape(p);
ludp->lud_port = atoi(p);
}
}
ldap_pvt_hex_unescape(ludp->lud_host);
ludp->lud_scheme = LDAP_STRDUP("ldap");
ludp->lud_next = *ludlist;
*ludlist = ludp;
}
/* this should be an array of NULLs now */
/* except entries starting with [ */
ldap_charray_free(specs);
return LDAP_SUCCESS;
}
char *
ldap_url_list2hosts (LDAPURLDesc *ludlist)
{
LDAPURLDesc *ludp;
int size;
char *s, *p, buf[32]; /* big enough to hold a long decimal # (overkill) */
if (ludlist == NULL)
return NULL;
/* figure out how big the string is */
size = 1; /* nul-term */
for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
size += strlen(ludp->lud_host) + 1; /* host and space */
if (strchr(ludp->lud_host, ':')) /* will add [ ] below */
size += 2;
if (ludp->lud_port != 0)
size += sprintf(buf, ":%d", ludp->lud_port);
}
s = LDAP_MALLOC(size);
if (s == NULL)
return NULL;
p = s;
for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) {
if (strchr(ludp->lud_host, ':')) {
p += sprintf(p, "[%s]", ludp->lud_host);
} else {
strcpy(p, ludp->lud_host);
p += strlen(ludp->lud_host);
}
if (ludp->lud_port != 0)
p += sprintf(p, ":%d", ludp->lud_port);
*p++ = ' ';
}
if (p != s)
p--; /* nuke that extra space */
*p = 0;
return s;
}
char *
ldap_url_list2urls(
LDAPURLDesc *ludlist )
{
LDAPURLDesc *ludp;
int size;
char *s, *p, buf[32]; /* big enough to hold a long decimal # (overkill) */
if (ludlist == NULL)
return NULL;
/* 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 += sizeof(":/// ");
if (ludp->lud_port != 0) {
size += sprintf(buf, ":%d", ludp->lud_port);
}
}
s = LDAP_MALLOC(size);
if (s == NULL) {
return NULL;
}
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);
if (ludp->lud_port != 0)
p += sprintf(p, ":%d", ludp->lud_port);
*p++ = '/';
*p++ = ' ';
}
if (p != s)
p--; /* nuke that extra space */
*p = 0;
return s;
}
void
ldap_free_urllist( LDAPURLDesc *ludlist )
{
LDAPURLDesc *ludp, *next;
for (ludp = ludlist; ludp != NULL; ludp = next) {
next = ludp->lud_next;
ldap_free_urldesc(ludp);
}
}
1998-08-09 08:43:13 +08:00
void
ldap_free_urldesc( LDAPURLDesc *ludp )
{
1999-07-20 03:32:47 +08:00
if ( ludp == NULL ) {
return;
}
if ( ludp->lud_scheme != NULL ) {
LDAP_FREE( ludp->lud_scheme );
}
1999-07-20 03:32:47 +08:00
if ( ludp->lud_host != NULL ) {
LDAP_FREE( ludp->lud_host );
1999-07-20 03:32:47 +08:00
}
if ( ludp->lud_dn != NULL ) {
LDAP_FREE( ludp->lud_dn );
1998-08-09 08:43:13 +08:00
}
1999-07-20 03:32:47 +08:00
if ( ludp->lud_filter != NULL ) {
LDAP_FREE( ludp->lud_filter);
}
if ( ludp->lud_attrs != NULL ) {
LDAP_VFREE( ludp->lud_attrs );
}
if ( ludp->lud_exts != NULL ) {
LDAP_VFREE( ludp->lud_exts );
}
LDAP_FREE( ludp );
1998-08-09 08:43:13 +08:00
}
int
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
ldap_url_search( LDAP *ld, LDAP_CONST char *url, int attrsonly )
1998-08-09 08:43:13 +08:00
{
int err;
LDAPURLDesc *ludp;
BerElement *ber;
LDAPreqinfo bind;
1998-08-09 08:43:13 +08:00
2000-10-19 00:32:57 +08:00
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
1998-08-09 08:43:13 +08:00
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;
1998-08-09 08:43:13 +08:00
} 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,
2001-11-29 00:49:46 +08:00
ludp, NULL, &bind );
1998-08-09 08:43:13 +08:00
}
ldap_free_urldesc( ludp );
return( err );
}
int
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
ldap_url_search_st( LDAP *ld, LDAP_CONST char *url, int attrsonly,
1998-08-09 08:43:13 +08:00
struct timeval *timeout, LDAPMessage **res )
{
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
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
ldap_url_search_s(
LDAP *ld, LDAP_CONST char *url, int attrsonly, LDAPMessage **res )
1998-08-09 08:43:13 +08:00
{
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 ));
}
void
ldap_pvt_hex_unescape( char *s )
1998-08-09 08:43:13 +08:00
{
/*
* Remove URL hex escapes from s... done in place. The basic concept for
* this routine is borrowed from the WWW library HTUnEscape() routine.
*/
1998-08-09 08:43:13 +08:00
char *p;
for ( p = s; *s != '\0'; ++s ) {
if ( *s == '%' ) {
if ( *++s != '\0' ) {
*p = ldap_pvt_unhex( *s ) << 4;
1998-08-09 08:43:13 +08:00
}
if ( *++s != '\0' ) {
*p++ += ldap_pvt_unhex( *s );
1998-08-09 08:43:13 +08:00
}
} else {
*p++ = *s;
}
}
*p = '\0';
}
int
ldap_pvt_unhex( int c )
1998-08-09 08:43:13 +08:00
{
return( c >= '0' && c <= '9' ? c - '0'
: c >= 'A' && c <= 'F' ? c - 'A' + 10
: c - 'a' + 10 );
}