From e5ebc553ac1fc7adf6fdea9a3b8918967eba2231 Mon Sep 17 00:00:00 2001 From: Kurt Zeilenga Date: Wed, 7 Jun 2000 01:09:40 +0000 Subject: [PATCH] Rework URI parser to provide true scheme not proto/properties. Plus more pthread rwlock code --- clients/mail500/main.c | 2 +- configure | 4 +- configure.in | 2 +- include/ldap.h | 15 +-- include/ldap_pvt.h | 12 +++ libraries/libldap/open.c | 5 +- libraries/libldap/request.c | 9 ++ libraries/libldap/url.c | 152 ++++++++++++++++++++--------- servers/slapd/back-ldbm/cache.c | 2 + servers/slapd/back-ldbm/id2entry.c | 2 +- servers/slapd/daemon.c | 6 +- 11 files changed, 142 insertions(+), 69 deletions(-) diff --git a/clients/mail500/main.c b/clients/mail500/main.c index 7aa1e50146..9a2ad1aceb 100644 --- a/clients/mail500/main.c +++ b/clients/mail500/main.c @@ -831,7 +831,7 @@ search_ldap_url( rc = ldap_url_parse( url, &ludp ); if ( rc ) { switch ( rc ) { - case LDAP_URL_ERR_NOTLDAP: + case LDAP_URL_ERR_BADSCHEME: syslog( LOG_ALERT, "Not an LDAP URL: %s", url ); break; diff --git a/configure b/configure index a85886930b..76413d50fe 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # $OpenLDAP$ -# from OpenLDAP: pkg/ldap/configure.in,v 1.307 2000/06/05 21:56:28 kurt Exp +# from OpenLDAP: pkg/ldap/configure.in,v 1.308 2000/06/05 23:23:19 kurt Exp # Copyright 1998-2000 The OpenLDAP Foundation. All Rights Reserved. # @@ -9979,7 +9979,7 @@ done echo "configure: warning: could not locate sched_yield() or pthread_yield()" 1>&2 fi - for ac_func in pthread_kill + for ac_func in pthread_kill pthread_rwlock_destroy do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 echo "configure:9986: checking for $ac_func" >&5 diff --git a/configure.in b/configure.in index 1ca60f29ea..88d85232d7 100644 --- a/configure.in +++ b/configure.in @@ -1215,7 +1215,7 @@ dnl [ol_cv_pthread_lpthread_lexc]) fi dnl Check functions for compatibility - AC_CHECK_FUNCS(pthread_kill) + AC_CHECK_FUNCS(pthread_kill pthread_rwlock_destroy) dnl Check for pthread_detach with inclusion dnl as it's symbol may have been mangled. diff --git a/include/ldap.h b/include/ldap.h index 09595d9034..e1e6f010cc 100644 --- a/include/ldap.h +++ b/include/ldap.h @@ -173,13 +173,11 @@ typedef struct ldapcontrol { #define LDAP_CONTROL_MANAGEDSAIT "2.16.840.1.113730.3.4.2" /* Experimental Controls */ -#define LDAP_CONTROL_X_MODIFY_PASSWD "1.3.6.1.4.1.4203.666.5.1" /* LDAP Unsolicited Notifications */ #define LDAP_NOTICE_OF_DISCONNECTION "1.3.6.1.4.1.1466.20036" #define LDAP_NOTICE_DISCONNECT LDAP_NOTICE_OF_DISCONNECTION - /* LDAP Extended Operations */ #define LDAP_EXOP_START_TLS "1.3.6.1.4.1.1466.20037" @@ -493,8 +491,7 @@ typedef struct ldap_friendly { */ typedef struct ldap_url_desc { struct ldap_url_desc *lud_next; - unsigned long lud_properties; - int lud_protocol; + char *lud_scheme; char *lud_host; int lud_port; char *lud_dn; @@ -504,19 +501,11 @@ typedef struct ldap_url_desc { char **lud_exts; } LDAPURLDesc; -/* lud_properties */ -#define LDAP_URL_USE_SSL 0x00000001 - -/* lud_protocol */ -#define LDAP_PROTO_TCP 0x00 -#define LDAP_PROTO_UDP 0x01 -#define LDAP_PROTO_LOCAL 0x02 - #define LDAP_URL_SUCCESS 0x00 /* Success */ #define LDAP_URL_ERR_MEM 0x01 /* can't allocate memory space */ #define LDAP_URL_ERR_PARAM 0x02 /* parameter is bad */ -#define LDAP_URL_ERR_NOTLDAP 0x03 /* URL doesn't begin with "ldap[s]://" */ +#define LDAP_URL_ERR_BADSCHEME 0x03 /* URL doesn't begin with "ldap[si]://" */ #define LDAP_URL_ERR_BADENCLOSURE 0x04 /* URL is missing trailing ">" */ #define LDAP_URL_ERR_BADURL 0x05 /* URL is bad */ #define LDAP_URL_ERR_BADHOST 0x06 /* host port is bad */ diff --git a/include/ldap_pvt.h b/include/ldap_pvt.h index aeb8ca8c5f..7107c9b8ec 100644 --- a/include/ldap_pvt.h +++ b/include/ldap_pvt.h @@ -21,6 +21,18 @@ LDAP_BEGIN_DECL +#define LDAP_PROTO_TCP 1 +#define LDAP_PROTO_UDP 2 +#define LDAP_PROTO_IPC 3 + +LIBLDAP_F ( int ) +ldap_pvt_url_scheme2proto LDAP_P(( + const char * )); +LIBLDAP_F ( int ) +ldap_pvt_url_scheme2tls LDAP_P(( + const char * )); + + LIBLDAP_F ( int ) ldap_pvt_domain2dn LDAP_P(( LDAP_CONST char *domain, diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index d8b1aaeb55..f97b6c8b9b 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -281,7 +281,7 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv, if ( srv->lud_host == NULL || *srv->lud_host == 0 ) addr = htonl( INADDR_LOOPBACK ); - switch ( srv->lud_protocol ) { + switch ( ldap_pvt_url_scheme2proto( srv->lud_scheme ) ) { case LDAP_PROTO_TCP: rc = ldap_connect_to_host( ld, sb, srv->lud_host, addr, port, async ); @@ -321,7 +321,8 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv, #ifdef HAVE_TLS if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD || - (srv->lud_properties & LDAP_URL_USE_SSL)) { + strcmp( srv->lud_scheme, "ldaps" ) == 0 ) + { rc = ldap_pvt_tls_start( ld, sb, ld->ld_options.ldo_tls_ctx ); if (rc != LDAP_SUCCESS) return rc; diff --git a/libraries/libldap/request.c b/libraries/libldap/request.c index cabdaca6b3..ec6ee54274 100644 --- a/libraries/libldap/request.c +++ b/libraries/libldap/request.c @@ -827,6 +827,8 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp ) ldap_pvt_hex_unescape( ref ); len = strlen( ref ); + /* FIXME: we should use the URL Parser */ + if ( len > LDAP_LDAP_REF_STR_LEN && strncasecmp( ref, LDAP_LDAP_REF_STR, LDAP_LDAP_REF_STR_LEN ) == 0 ) { Debug( LDAP_DEBUG_TRACE, @@ -865,6 +867,13 @@ ldap_chase_referrals( LDAP *ld, LDAPRequest *lr, char **errstrp, int *hadrefp ) return( -1 ); } + if (( srv->lud_scheme = LDAP_STRDUP("ldap")) == NULL ) { + LDAP_FREE( (char *)srv ); + ber_free( ber, 1 ); + ld->ld_errno = LDAP_NO_MEMORY; + return( -1 ); + } + if (( srv->lud_host = LDAP_STRDUP( tmpref )) == NULL ) { LDAP_FREE( (char *)srv ); ber_free( ber, 1 ); diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c index 6098bb8910..d72dbcb5b2 100644 --- a/libraries/libldap/url.c +++ b/libraries/libldap/url.c @@ -10,7 +10,7 @@ * LIBLDAP url.c -- LDAP URL (RFC 2255) related routines * * LDAP URLs look like this: - * ldap[s]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]] + * ldap[is]://host:port[/[dn[?[attributes][?[scope][?[filter][?exts]]]]]] * * where: * attributes is a comma separated list @@ -40,51 +40,98 @@ static const char* skip_url_prefix LDAP_P(( const char *url, int *enclosedp, - unsigned long *properties, - int *protocol)); + const char **scheme )); +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; + } + + return -1; +} + +int ldap_pvt_url_scheme2tls( const char *scheme ) +{ + assert( scheme ); + + if( scheme == NULL ) { + return -1; + } + + return strcmp("ldaps", scheme) == 0; +} int ldap_is_ldap_url( LDAP_CONST char *url ) { - int enclosed, protocol; - unsigned long properties; + int enclosed; + const char * scheme; if( url == NULL ) { return 0; } - if( skip_url_prefix( url, &enclosed, &properties, &protocol) == NULL ) { + if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) { return 0; } - return !(properties & LDAP_URL_USE_SSL); + return 1; } int ldap_is_ldaps_url( LDAP_CONST char *url ) { - int enclosed, protocol; - unsigned long properties; + int enclosed; + const char * scheme; if( url == NULL ) { return 0; } - if( skip_url_prefix( url, &enclosed, &properties, &protocol) == NULL ) { + if( skip_url_prefix( url, &enclosed, &scheme ) == NULL ) { return 0; } - return (properties & LDAP_URL_USE_SSL); + 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; } static const char* skip_url_prefix( const char *url, int *enclosedp, - unsigned long *properties, - int *protocol - ) + const char **scheme ) { /* * return non-zero if this looks like a LDAP URL; zero if not @@ -112,13 +159,11 @@ skip_url_prefix( p += LDAP_URL_URLCOLON_LEN; } - *properties = 0; - /* 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; - *protocol = LDAP_PROTO_TCP; + *scheme = "ldap"; return( p ); } @@ -126,8 +171,7 @@ skip_url_prefix( if ( strncasecmp( p, LDAPS_URL_PREFIX, LDAPS_URL_PREFIX_LEN ) == 0 ) { /* skip over "ldaps://" prefix and return success */ p += LDAPS_URL_PREFIX_LEN; - *protocol = LDAP_PROTO_TCP; - *properties |= LDAP_URL_USE_SSL; + *scheme = "ldaps"; return( p ); } @@ -135,16 +179,7 @@ skip_url_prefix( if ( strncasecmp( p, LDAPI_URL_PREFIX, LDAPI_URL_PREFIX_LEN ) == 0 ) { /* skip over "ldapi://" prefix and return success */ p += LDAPI_URL_PREFIX_LEN; - *protocol = LDAP_PROTO_LOCAL; - return( p ); - } - - /* check for "ldapis://" prefix: should this be legal? */ - if ( strncasecmp( p, LDAPIS_URL_PREFIX, LDAPIS_URL_PREFIX_LEN ) == 0 ) { - /* skip over "ldapis://" prefix and return success */ - p += LDAPIS_URL_PREFIX_LEN; - *protocol = LDAP_PROTO_LOCAL; - *properties |= LDAP_URL_USE_SSL; + *scheme = "ldapi"; return( p ); } @@ -183,8 +218,8 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) LDAPURLDesc *ludp; char *p, *q; - int i, enclosed, protocol; - unsigned long properties; + int i, enclosed; + const char *scheme = NULL; const char *url_tmp; char *url; @@ -196,12 +231,14 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) *ludpp = NULL; /* pessimistic */ - url_tmp = skip_url_prefix( url_in, &enclosed, &properties, &protocol ); + url_tmp = skip_url_prefix( url_in, &enclosed, &scheme ); if ( url_tmp == NULL ) { - return LDAP_URL_ERR_NOTLDAP; + return LDAP_URL_ERR_BADSCHEME; } + assert( scheme ); + /* make working copy of the remainder of the URL */ if (( url = LDAP_STRDUP( url_tmp )) == NULL ) { return( LDAP_URL_ERR_MEM ); @@ -232,13 +269,12 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) ludp->lud_dn = NULL; ludp->lud_attrs = NULL; ludp->lud_filter = NULL; - ludp->lud_properties = properties; - ludp->lud_protocol = protocol; ludp->lud_scope = LDAP_SCOPE_BASE; + ludp->lud_filter = NULL; - ludp->lud_filter = LDAP_STRDUP("(objectClass=*)"); + ludp->lud_scheme = LDAP_STRDUP( scheme ); - if( ludp->lud_filter == NULL ) { + if ( ludp->lud_scheme == NULL ) { LDAP_FREE( url ); ldap_free_urldesc( ludp ); return LDAP_URL_ERR_MEM; @@ -275,7 +311,7 @@ ldap_url_parse( LDAP_CONST char *url_in, LDAPURLDesc **ludpp ) } /* - * Kluge. ldap://111.222.333.444:389??cn=abc,o=company + * 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, @@ -484,8 +520,22 @@ ldap_url_dup ( LDAPURLDesc *ludp ) 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) { @@ -602,7 +652,8 @@ ldap_url_parsehosts (LDAPURLDesc **ludlist, const char *hosts ) return LDAP_NO_MEMORY; /* count the URLs... */ - for (i = 0; specs[i] != NULL; i++) ; + for (i = 0; specs[i] != NULL; i++) /* EMPTY */; + /* ...and put them in the "stack" backward */ while (--i >= 0) { ludp = LDAP_CALLOC( 1, sizeof(LDAPURLDesc) ); @@ -621,8 +672,7 @@ ldap_url_parsehosts (LDAPURLDesc **ludlist, const char *hosts ) ludp->lud_port = atoi(p); } ldap_pvt_hex_unescape(ludp->lud_host); - ludp->lud_protocol = LDAP_PROTO_TCP; - ludp->lud_properties = 0; + ludp->lud_scheme = LDAP_STRDUP("ldap"); ludp->lud_next = *ludlist; *ludlist = ludp; } @@ -668,7 +718,8 @@ ldap_url_list2hosts (LDAPURLDesc *ludlist) } char * -ldap_url_list2urls (LDAPURLDesc *ludlist) +ldap_url_list2urls( + LDAPURLDesc *ludlist ) { LDAPURLDesc *ludp; int size; @@ -680,17 +731,22 @@ ldap_url_list2urls (LDAPURLDesc *ludlist) /* 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 + sizeof("ldapis:///"); /* prefix, host, /, and space */ - if (ludp->lud_port != 0) + size += strlen(ludp->lud_scheme) + strlen(ludp->lud_host); + size += sizeof(":/// "); + + if (ludp->lud_port != 0) { size += sprintf(buf, ":%d", ludp->lud_port); + } } + s = LDAP_MALLOC(size); - if (s == NULL) + if (s == NULL) { return NULL; + } p = s; for (ludp = ludlist; ludp != NULL; ludp = ludp->lud_next) { - p += sprintf(p, "ldap%s://%s", (ludp->lud_properties & LDAP_URL_USE_SSL) ? "s" : "", ludp->lud_host); + p += sprintf(p, "%s://%s", ludp->lud_scheme, ludp->lud_host); if (ludp->lud_port != 0) p += sprintf(p, ":%d", ludp->lud_port); *p++ = '/'; @@ -720,6 +776,10 @@ ldap_free_urldesc( LDAPURLDesc *ludp ) return; } + if ( ludp->lud_scheme != NULL ) { + LDAP_FREE( ludp->lud_scheme ); + } + if ( ludp->lud_host != NULL ) { LDAP_FREE( ludp->lud_host ); } diff --git a/servers/slapd/back-ldbm/cache.c b/servers/slapd/back-ldbm/cache.c index ed57db5fb0..819e2a8130 100644 --- a/servers/slapd/back-ldbm/cache.c +++ b/servers/slapd/back-ldbm/cache.c @@ -685,7 +685,9 @@ cache_release_all( Cache *cache ) Debug( LDAP_DEBUG_TRACE, "====> cache_release_all\n", 0, 0, 0 ); while ( (e = cache->c_lrutail) != NULL && LEI(e)->lei_refcnt == 0 ) { +#ifdef LDAP_RDWR_DEBUG assert(!ldap_pvt_thread_rdwr_active(&LEI(e)->lei_rdwr)); +#endif /* delete from cache and lru q */ /* XXX do we need rc ? */ diff --git a/servers/slapd/back-ldbm/id2entry.c b/servers/slapd/back-ldbm/id2entry.c index fa0ea1f97e..f38802126d 100644 --- a/servers/slapd/back-ldbm/id2entry.c +++ b/servers/slapd/back-ldbm/id2entry.c @@ -72,7 +72,7 @@ id2entry_delete( Backend *be, Entry *e ) e->e_dn, 0 ); #ifdef notdef -#ifdef LDAP_DEBUG +#ifdef LDAP_RDWR_DEBUG /* check for writer lock */ assert(ldap_pvt_thread_rdwr_writers(&e->e_rdwr) == 1); #endif diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 2d87463c85..5dc5aaaa13 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -218,7 +218,7 @@ static Listener * open_listener( const char* url ) } #ifndef HAVE_TLS - if( lud->lud_properties & LDAP_URL_USE_SSL ) { + if( ldap_is_ldaps_url( lud ) ) { Debug( LDAP_DEBUG_ANY, "daemon: TLS not supported (%s)\n", url, 0, 0 ); @@ -231,10 +231,10 @@ static Listener * open_listener( const char* url ) } #else - l.sl_is_tls = (lud->lud_properties & LDAP_URL_USE_SSL); + l.sl_is_tls = ldap_is_ldaps_url( lud ); if(! lud->lud_port ) { - lud->lud_port = (lud->lud_properties & LDAP_URL_USE_SSL) ? LDAPS_PORT : LDAP_PORT; + lud->lud_port = l.sl_is_tls ? LDAPS_PORT : LDAP_PORT; } #endif -- 2.39.5