From f4239db146c41d1e9eee9f7d6872d23e000135b0 Mon Sep 17 00:00:00 2001 From: Pierangelo Masarati Date: Tue, 19 Jun 2007 22:58:20 +0000 Subject: [PATCH] better implementation for ITS#4996 and docs (ldapsearch(1) only; need to duplicate in other tools man pages) --- clients/tools/common.c | 176 +++++++++++++++++++++++--------------- doc/man/man1/ldapsearch.1 | 11 ++- 2 files changed, 113 insertions(+), 74 deletions(-) diff --git a/clients/tools/common.c b/clients/tools/common.c index 99f0807d28..21656ddbb6 100644 --- a/clients/tools/common.c +++ b/clients/tools/common.c @@ -959,101 +959,135 @@ tool_conn_setup( int dont, void (*private_setup)( LDAP * ) ) ldapuri = ldap_url_desc2str( &url ); } else if ( ldapuri != NULL ) { - LDAPURLDesc *lud; + LDAPURLDesc *ludlist, **ludp; + char **urls = NULL; + int nurls = 0; - rc = ldap_url_parse( ldapuri, &lud ); + rc = ldap_url_parselist( &ludlist, ldapuri ); if ( rc != LDAP_URL_SUCCESS ) { fprintf( stderr, - "Could not parse LDAP URI=%s (%d)\n", + "Could not parse LDAP URI(s)=%s (%d)\n", ldapuri, rc ); exit( EXIT_FAILURE ); } - if ( lud->lud_dn != NULL && lud->lud_dn[ 0 ] != '\0' && - ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) ) - { - /* if no host but a DN is provided, - * use DNS SRV to gather the host list - * and turn it into a list of URIs - * using the scheme provided */ - char *domain = NULL, - *hostlist = NULL, - **hosts = NULL, - **urls = NULL; - int i, - len_proto = strlen( lud->lud_scheme ); - - ber_memfree( ldapuri ); - ldapuri = NULL; - - if ( ldap_dn2domain( lud->lud_dn, &domain ) - || domain == NULL ) + for ( ludp = &ludlist; *ludp != NULL; ) { + LDAPURLDesc *lud = *ludp; + char **tmp; + + if ( lud->lud_dn != NULL && lud->lud_dn[ 0 ] != '\0' && + ( lud->lud_host == NULL || lud->lud_host[0] == '\0' ) ) { - fprintf( stderr, - "DNS SRV: Could not turn " - "DN=\"%s\" into a domain\n", - lud->lud_dn ); - goto dnssrv_free; - } - - rc = ldap_domain2hostlist( domain, &hostlist ); - if ( rc ) { - fprintf( stderr, - "DNS SRV: Could not turn " - "domain=%s into a hostlist\n", - domain ); - goto dnssrv_free; - } + /* if no host but a DN is provided, + * use DNS SRV to gather the host list + * and turn it into a list of URIs + * using the scheme provided */ + char *domain = NULL, + *hostlist = NULL, + **hosts = NULL; + int i, + len_proto = strlen( lud->lud_scheme ); + + if ( ldap_dn2domain( lud->lud_dn, &domain ) + || domain == NULL ) + { + fprintf( stderr, + "DNS SRV: Could not turn " + "DN=\"%s\" into a domain\n", + lud->lud_dn ); + goto dnssrv_free; + } + + rc = ldap_domain2hostlist( domain, &hostlist ); + if ( rc ) { + fprintf( stderr, + "DNS SRV: Could not turn " + "domain=%s into a hostlist\n", + domain ); + goto dnssrv_free; + } - hosts = ldap_str2charray( hostlist, " " ); - if ( hosts == NULL ) { - fprintf( stderr, - "DNS SRV: Could not parse " - "hostlist=\"%s\"\n", - hostlist ); - goto dnssrv_free; - } + hosts = ldap_str2charray( hostlist, " " ); + if ( hosts == NULL ) { + fprintf( stderr, + "DNS SRV: Could not parse " + "hostlist=\"%s\"\n", + hostlist ); + goto dnssrv_free; + } - for ( i = 0; hosts[ i ] != NULL; i++ ) - /* count'em */ ; + for ( i = 0; hosts[ i ] != NULL; i++ ) + /* count'em */ ; - urls = (char **)calloc( sizeof( char * ), i + 1 ); - if ( urls == NULL ) { - fprintf( stderr, - "DNS SRV: out of memory?\n" ); - goto dnssrv_free; - } + tmp = (char **)realloc( urls, sizeof( char * ) * ( nurls + i + 1 ) ); + if ( tmp == NULL ) { + fprintf( stderr, + "DNS SRV: out of memory?\n" ); + goto dnssrv_free; + } + urls = tmp; + urls[ nurls ] = NULL; + + for ( i = 0; hosts[ i ] != NULL; i++ ) { + size_t len = len_proto + + STRLENOF( "://" ) + + strlen( hosts[ i ] ) + + 1; + + urls[ nurls + i + 1 ] = NULL; + urls[ nurls + i ] = (char *)malloc( sizeof( char ) * len ); + if ( urls[ nurls + i ] == NULL ) { + fprintf( stderr, + "DNS SRV: out of memory?\n" ); + goto dnssrv_free; + } + + snprintf( urls[ nurls + i ], len, "%s://%s", + lud->lud_scheme, hosts[ i ] ); + } + nurls += i; - for ( i = 0; hosts[ i ] != NULL; i++ ) { - size_t len = len_proto - + STRLENOF( "://" ) - + strlen( hosts[ i ] ) - + 1; +dnssrv_free:; + ber_memvfree( (void **)hosts ); + ber_memfree( hostlist ); + ber_memfree( domain ); - urls[ i ] = (char *)malloc( sizeof( char ) * len ); - if ( urls[ i ] == NULL ) { + } else { + tmp = (char **)realloc( urls, sizeof( char * ) * ( nurls + 2 ) ); + if ( tmp == NULL ) { fprintf( stderr, "DNS SRV: out of memory?\n" ); - goto dnssrv_free; + break; } + urls = tmp; + urls[ nurls + 1 ] = NULL; - snprintf( urls[ i ], len, "%s://%s", - lud->lud_scheme, hosts[ i ] ); + urls[ nurls ] = ldap_url_desc2str( lud ); + if ( urls[ nurls ] == NULL ) { + fprintf( stderr, + "DNS SRV: out of memory?\n" ); + break; + } + nurls++; } - ldapuri = ldap_charray2str( urls, " " ); + *ludp = lud->lud_next; -dnssrv_free:; - ber_memvfree( (void **)hosts ); - ber_memvfree( (void **)urls ); - ber_memfree( hostlist ); - ber_memfree( domain ); + lud->lud_next = NULL; + ldap_free_urldesc( lud ); } - ldap_free_urldesc( lud ); - if ( ldapuri == NULL ) { + if ( ludlist != NULL ) { + ldap_free_urllist( ludlist ); + exit( EXIT_FAILURE ); + + } else if ( urls == NULL ) { exit( EXIT_FAILURE ); } + + ldap_memfree( ldapuri ); + ldapuri = ldap_charray2str( urls, " " ); + ber_memvfree( (void **)urls ); } if ( verbose ) { diff --git a/doc/man/man1/ldapsearch.1 b/doc/man/man1/ldapsearch.1 index f6480c581f..a4bfdb8866 100644 --- a/doc/man/man1/ldapsearch.1 +++ b/doc/man/man1/ldapsearch.1 @@ -206,9 +206,14 @@ Use complete contents of \fIpasswdfile\fP as the password for simple authentication. .TP .BI \-H \ ldapuri -Specify URI(s) referring to the ldap server(s); only the protocol/host/port -fields are allowed; a list of URI, separated by whitespace or commas -is expected. +Specify URI(s) referring to the ldap server(s); +a list of URI, separated by whitespace or commas is expected; +only the protocol/host/port fields are allowed. +As an exception, if no host/port is specified, but a DN is, +the DN is used to look up the corresponding host(s) using the +DNS SRV records, according to RFC 2782. The DN must be a non-empty +sequence of AVAs whose attribute type is "dc" (domain component), +and must be escaped according to RFC 2396. .TP .BI \-h \ ldaphost Specify an alternate host on which the ldap server is running. -- 2.39.5