diff options
author | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
---|---|---|
committer | stevel@tonic-gate <none@none> | 2005-06-14 00:00:00 -0700 |
commit | 7c478bd95313f5f23a4c958a745db2134aa03244 (patch) | |
tree | c871e58545497667cbb4b0a4f2daf204743e1fe7 /usr/src/lib/libldap4/common/request.c | |
download | illumos-joyent-7c478bd95313f5f23a4c958a745db2134aa03244.tar.gz |
OpenSolaris Launch
Diffstat (limited to 'usr/src/lib/libldap4/common/request.c')
-rw-r--r-- | usr/src/lib/libldap4/common/request.c | 779 |
1 files changed, 779 insertions, 0 deletions
diff --git a/usr/src/lib/libldap4/common/request.c b/usr/src/lib/libldap4/common/request.c new file mode 100644 index 0000000000..7b0af4c0f7 --- /dev/null +++ b/usr/src/lib/libldap4/common/request.c @@ -0,0 +1,779 @@ +/* + * Copyright 1998-2002 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * Copyright (c) 1995 Regents of the University of Michigan. + * All rights reserved. + * + * request.c - sending of ldap requests; handling of referrals + */ + +#ifndef lint +static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n"; +#endif + +#include <stdio.h> +#include <string.h> +#ifdef MACOS +#include <stdlib.h> +#include <time.h> +#include "macos.h" +#else /* MACOS */ +#if defined( DOS ) || defined( _WIN32 ) +#include "msdos.h" +#include <time.h> +#include <stdlib.h> +#ifdef PCNFS +#include <tklib.h> +#include <tk_errno.h> +#include <bios.h> +#endif /* PCNFS */ +#ifdef NCSA +#include "externs.h" +#endif /* NCSA */ +#else /* DOS */ +#include <sys/time.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <errno.h> +#ifdef _AIX +#include <sys/select.h> +#endif /* _AIX */ +#include "portable.h" +#endif /* DOS */ +#endif /* MACOS */ +#ifdef VMS +#include "ucx_select.h" +#endif +#include "lber.h" +#include "ldap.h" +#include "ldap-private.h" +#include "ldap-int.h" + +#ifdef USE_SYSCONF +#include <unistd.h> +#endif /* USE_SYSCONF */ + +#ifdef NEEDPROTOS +static LDAPConn *find_connection( LDAP *ld, LDAPServer *srv, int any ); +static void use_connection( LDAP *ld, LDAPConn *lc ); +static void free_servers( LDAPServer *srvlist ); +#else /* NEEDPROTOS */ +static LDAPConn *find_connection(); +static void use_connection(); +static void free_servers(); +#endif /* NEEDPROTOS */ + + +#ifdef LDAP_DNS +#ifdef NEEDPROTOS +static LDAPServer *dn2servers( LDAP *ld, char *dn ); +#else /* NEEDPROTOS */ +static LDAPServer *dn2servers(); +#endif /* NEEDPROTOS */ +#endif /* LDAP_DNS */ + + +BerElement * +alloc_ber_with_options( LDAP *ld ) +{ + BerElement *ber; + + if (( ber = ber_alloc_t( ld->ld_lberoptions )) == NULLBER ) { + ld->ld_errno = LDAP_NO_MEMORY; +#ifdef STR_TRANSLATION + } else { + set_ber_options( ld, ber ); +#endif /* STR_TRANSLATION */ + } + + return( ber ); +} + + +void +set_ber_options( LDAP *ld, BerElement *ber ) +{ + ber->ber_options = ld->ld_lberoptions; +#ifdef STR_TRANSLATION + if (( ld->ld_lberoptions & LBER_TRANSLATE_STRINGS ) != 0 ) { + ber_set_string_translators( ber, + ld->ld_lber_encode_translate_proc, + ld->ld_lber_decode_translate_proc ); + } +#endif /* STR_TRANSLATION */ +} + + +int +send_initial_request( LDAP *ld, unsigned int msgtype, char *dn, + BerElement *ber ) +{ + LDAPServer *servers; + int rv; + +#ifdef _REENTRANT + LOCK_LDAP(ld); +#endif + Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 209, "send_initial_request\n"), 0, 0, 0 ); + +#ifdef LDAP_DNS + if (( ld->ld_options & LDAP_OPT_DNS ) != 0 && ldap_is_dns_dn( dn )) { + if (( servers = dn2servers( ld, dn )) == NULL ) { + ber_free( ber, 1 ); +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( -1 ); + } + +#ifdef LDAP_DEBUG + if ( ldap_debug & LDAP_DEBUG_TRACE ) { + LDAPServer *srv; + + for ( srv = servers; srv != NULL; + srv = srv->lsrv_next ) { + fprintf( stderr, + "LDAP server %s: dn %s, port %d\n", + srv->lsrv_host, ( srv->lsrv_dn == NULL ) ? + "(default)" : srv->lsrv_dn, + srv->lsrv_port ); + } + } +#endif /* LDAP_DEBUG */ + } else { +#endif /* LDAP_DNS */ + /* + * use of DNS is turned off or this is an X.500 DN... + * use our default connection + */ + servers = NULL; +#ifdef LDAP_DNS + } +#endif /* LDAP_DNS */ + +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + rv = send_server_request( ld, ber, ld->ld_msgid, NULL, servers, + NULL, 0 ); + return ( rv ); +} + +int +send_server_request( LDAP *ld, BerElement *ber, int msgid, LDAPRequest + *parentreq, LDAPServer *srvlist, LDAPConn *lc, int bind ) +{ + LDAPRequest *lr; + int err; + +#ifdef _REENTRANT + LOCK_LDAP(ld); +#endif + Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 210, "send_server_request\n"), 0, 0, 0 ); + + ld->ld_errno = LDAP_SUCCESS; /* optimistic */ + /* Be optimistic : increment parentreq initially. + If it fails we must decrement it */ + if (parentreq != NULL){ + parentreq->lr_outrefcnt++; + } + + if ( lc == NULL ) { + if ( srvlist == NULL ) { + if (ld->ld_defconn == NULL){ /* Not connected yet on the default connection, ie init was called not open */ + if ((err = open_default_ldap_connection(ld)) != LDAP_SUCCESS){ + ld->ld_errno = err; + ber_free(ber, 1); + if (parentreq != NULL){ + parentreq->lr_outrefcnt--; + } +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( -1 ); + } + } + + lc = ld->ld_defconn; + } else { + if (( lc = find_connection( ld, srvlist, 1 )) == + NULL ) { + lc = new_connection( ld, &srvlist, 0, 1, bind ); + } + free_servers( srvlist ); + } + } + + if ( lc == NULL || lc->lconn_status != LDAP_CONNST_CONNECTED ) { + ber_free( ber, 1 ); + if ( ld->ld_errno == LDAP_SUCCESS ) { + ld->ld_errno = LDAP_SERVER_DOWN; + } + if (parentreq != NULL){ + parentreq->lr_outrefcnt--; + } +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( -1 ); + } + + use_connection( ld, lc ); + if (( lr = (LDAPRequest *)calloc( 1, sizeof( LDAPRequest ))) == + NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + free_connection( ld, lc, 0, 0 ); + ber_free( ber, 1 ); +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( -1 ); + } + lr->lr_msgid = msgid; + lr->lr_status = LDAP_REQST_INPROGRESS; + lr->lr_res_errno = LDAP_SUCCESS; /* optimistic */ + lr->lr_ber = ber; + lr->lr_conn = lc; + if ( parentreq != NULL ) { /* sub-request */ +/* ++parentreq->lr_outrefcnt; */ + lr->lr_origid = parentreq->lr_origid; + lr->lr_parentcnt = parentreq->lr_parentcnt + 1; + lr->lr_parent = parentreq; + lr->lr_refnext = parentreq->lr_refnext; + parentreq->lr_refnext = lr; + } else { /* original request */ + lr->lr_origid = lr->lr_msgid; + } + + if (( lr->lr_next = ld->ld_requests ) != NULL ) { + lr->lr_next->lr_prev = lr; + } + ld->ld_requests = lr; + lr->lr_prev = NULL; + + if ( ber_flush( lc->lconn_sb, ber, 0 ) != 0 ) { +#ifdef notyet + extern int errno; + + if ( errno == EWOULDBLOCK ) { + /* need to continue write later */ + lr->lr_status = LDAP_REQST_WRITING; + mark_select_write( ld, lc->lconn_sb ); + } else { +#else /* notyet */ + ld->ld_errno = LDAP_SERVER_DOWN; + free_request( ld, lr ); + free_connection( ld, lc, 0, 0 ); +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( -1 ); +#endif /* notyet */ +#ifdef notyet + } +#endif /* notyet */ + } else { + if ( parentreq == NULL ) { + ber->ber_end = ber->ber_ptr; + ber->ber_ptr = ber->ber_buf; + } + + /* sent -- waiting for a response */ + mark_select_read( ld, lc->lconn_sb ); + } + + ld->ld_errno = LDAP_SUCCESS; +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( msgid ); +} + + +LDAPConn * +new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb, + int connect, int bind ) +{ + LDAPConn *lc; + LDAPServer *prevsrv, *srv; + Sockbuf *sb; + + /* + * make a new LDAP server connection + * XXX open connection synchronously for now + */ + if (( lc = (LDAPConn *)calloc( 1, sizeof( LDAPConn ))) == NULL || + ( !use_ldsb && ( sb = (Sockbuf *)calloc( 1, sizeof( Sockbuf ))) + == NULL )) { + if ( lc != NULL ) { + free( (char *)lc ); + } + ld->ld_errno = LDAP_NO_MEMORY; + return( NULL ); + } + +#ifdef _REENTRANT + LOCK_LDAP(ld); +#endif + lc->lconn_sb = ( use_ldsb ) ? &ld->ld_sb : sb; + + if ( connect ) { + prevsrv = NULL; + + for ( srv = *srvlistp; srv != NULL; srv = srv->lsrv_next ) { + if ( open_ldap_connection( ld, lc->lconn_sb, + srv->lsrv_host, srv->lsrv_port, + &lc->lconn_krbinstance, 0 ) != -1 ) { + break; + } + prevsrv = srv; + } + + if ( srv == NULL ) { + if ( !use_ldsb ) { + free( (char *)lc->lconn_sb ); + } + free( (char *)lc ); + ld->ld_errno = LDAP_SERVER_DOWN; +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( NULL ); + } + + if ( prevsrv == NULL ) { + *srvlistp = srv->lsrv_next; + } else { + prevsrv->lsrv_next = srv->lsrv_next; + } + lc->lconn_server = srv; + } + + lc->lconn_status = LDAP_CONNST_CONNECTED; + lc->lconn_next = ld->ld_conns; + ld->ld_conns = lc; + + /* + * XXX for now, we always do a synchronous bind. This will have + * to change in the long run... + */ + if ( bind ) { + int err, freepasswd, authmethod; + char *binddn, *passwd; + LDAPConn *savedefconn; + + freepasswd = err = 0; + + if ( ld->ld_version == LDAP_VERSION3 && ld->ld_rebindproc == NULL){ + /* Nothing to do */ + Debug(LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 1280, "new_connection: bind no needed with ldapv3\n"), 0,0,0); + } else { + if ( ld->ld_rebindproc == NULL ) { + binddn = passwd = ""; + authmethod = LDAP_AUTH_SIMPLE; + } else { + if (( err = (*ld->ld_rebindproc)( ld, &binddn, &passwd, + &authmethod, 0, ld->ld_rebind_extra_arg )) == LDAP_SUCCESS ) { + freepasswd = 1; + } else { + ld->ld_errno = err; + err = -1; + } + } + + if ( err == 0 ) { + savedefconn = ld->ld_defconn; + ld->ld_defconn = lc; + ++lc->lconn_refcnt; /* avoid premature free */ + + if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != + LDAP_SUCCESS ) { + err = -1; + } + --lc->lconn_refcnt; + ld->ld_defconn = savedefconn; + } + + if ( freepasswd ) { + (*ld->ld_rebindproc)( ld, &binddn, &passwd, + &authmethod, 1, ld->ld_rebind_extra_arg ); + } + + if ( err != 0 ) { + free_connection( ld, lc, 1, 0 ); + lc = NULL; + } + } + } + +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( lc ); +} + + +static LDAPConn * +find_connection( LDAP *ld, LDAPServer *srv, int any ) +/* + * return an existing connection (if any) to the server srv + * if "any" is non-zero, check for any server in the "srv" chain + */ +{ + LDAPConn *lc; + LDAPServer *ls; + +#ifdef _REENTRANT + LOCK_LDAP(ld); +#endif + for ( lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next ) { + for ( ls = srv; ls != NULL; ls = ls->lsrv_next ) { + if ( lc->lconn_server->lsrv_host != NULL && + ls->lsrv_host != NULL && strcasecmp( + ls->lsrv_host, lc->lconn_server->lsrv_host ) == 0 + && ls->lsrv_port == lc->lconn_server->lsrv_port ) { +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( lc ); + } + if ( !any ) { + break; + } + } + } + +#ifdef _REENTRANT + UNLOCK_LDAP(ld); +#endif + return( NULL ); +} + + + +static void +use_connection( LDAP *ld, LDAPConn *lc ) +{ + ++lc->lconn_refcnt; + lc->lconn_lastused = time( 0 ); +} + + +void +free_connection( LDAP *ld, LDAPConn *lc, int force, int unbind ) +{ + LDAPConn *tmplc, *prevlc; + + Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 211, "free_connection\n"), 0, 0, 0 ); + + if ( force || --lc->lconn_refcnt <= 0 ) { + if ( lc->lconn_status == LDAP_CONNST_CONNECTED ) { + mark_select_clear( ld, lc->lconn_sb ); + if ( unbind ) { + send_unbind( ld, lc->lconn_sb ); + } + close_ldap_connection( lc->lconn_sb ); + if ( lc->lconn_sb->sb_ber.ber_buf != NULL ) { + free( lc->lconn_sb->sb_ber.ber_buf ); + lc->lconn_sb->sb_ber.ber_buf = NULL; + } + } + prevlc = NULL; + for ( tmplc = ld->ld_conns; tmplc != NULL; + tmplc = tmplc->lconn_next ) { + if ( tmplc == lc ) { + if ( prevlc == NULL ) { + ld->ld_conns = tmplc->lconn_next; + } else { + prevlc->lconn_next = tmplc->lconn_next; + } + break; + } + } + free_servers( lc->lconn_server ); + if ( lc->lconn_krbinstance != NULL ) { + free( lc->lconn_krbinstance ); + } + if ( lc->lconn_sb != &ld->ld_sb ) { + free( (char *)lc->lconn_sb ); + } + free( lc ); + Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 212, "free_connection: actually freed\n"), + 0, 0, 0 ); + } else { + lc->lconn_lastused = time( 0 ); + Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 213, "free_connection: refcnt %d\n"), + lc->lconn_refcnt, 0, 0 ); + } +} + + +#ifdef LDAP_DEBUG +void +dump_connection( LDAP *ld, LDAPConn *lconns, int all ) +{ + LDAPConn *lc; + + fprintf( stderr, "** Connection%s:\n", all ? "s" : "" ); + for ( lc = lconns; lc != NULL; lc = lc->lconn_next ) { + if ( lc->lconn_server != NULL ) { + fprintf( stderr, "* host: %s port: %d%s\n", + ( lc->lconn_server->lsrv_host == NULL ) ? "(null)" + : lc->lconn_server->lsrv_host, + lc->lconn_server->lsrv_port, ( lc->lconn_sb == + &ld->ld_sb ) ? " (default)" : "" ); + } + fprintf( stderr, " refcnt: %d status: %s\n", lc->lconn_refcnt, + ( lc->lconn_status == LDAP_CONNST_NEEDSOCKET ) ? + "NeedSocket" : ( lc->lconn_status == + LDAP_CONNST_CONNECTING ) ? "Connecting" : "Connected" ); + fprintf( stderr, " last used: %s\n", + ctime( &lc->lconn_lastused )); + if ( !all ) { + break; + } + } +} + + +void +dump_requests_and_responses( LDAP *ld ) +{ + LDAPRequest *lr; + LDAPMessage *lm, *l; + + fprintf( stderr, "** Outstanding Requests:\n" ); + if (( lr = ld->ld_requests ) == NULL ) { + fprintf( stderr, " Empty\n" ); + } + for ( ; lr != NULL; lr = lr->lr_next ) { + fprintf( stderr, " * msgid %d, origid %d, status %s\n", + lr->lr_msgid, lr->lr_origid, ( lr->lr_status == + LDAP_REQST_INPROGRESS ) ? "InProgress" : + ( lr->lr_status == LDAP_REQST_CHASINGREFS ) ? "ChasingRefs" : + ( lr->lr_status == LDAP_REQST_NOTCONNECTED ) ? "NotConnected" : + "Writing" ); + fprintf( stderr, " outstanding referrals %d, parent count %d\n", + lr->lr_outrefcnt, lr->lr_parentcnt ); + } + + fprintf( stderr, "** Response Queue:\n" ); +#ifdef _REENTRANT + LOCK_RESPONSE(ld); +#endif + if (( lm = ld->ld_responses ) == NULLMSG ) { + fprintf( stderr, " Empty\n" ); + } + for ( ; lm != NULLMSG; lm = lm->lm_next ) { + fprintf( stderr, " * msgid %d, type %d\n", + lm->lm_msgid, lm->lm_msgtype ); + if (( l = lm->lm_chain ) != NULL ) { + fprintf( stderr, " chained responses:\n" ); + for ( ; l != NULLMSG; l = l->lm_chain ) { + fprintf( stderr, + " * msgid %d, type %d\n", + l->lm_msgid, l->lm_msgtype ); + } + } + } +#ifdef _REENTRANT + UNLOCK_RESPONSE(ld); +#endif +} +#endif /* LDAP_DEBUG */ + + +void +free_request( LDAP *ld, LDAPRequest *lr ) +{ + LDAPRequest *tmplr, *nextlr; + int i; + + Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 214, "free_request (origid %1$d, msgid %2$d)\n"), + lr->lr_origid, lr->lr_msgid, 0 ); + + if ( lr->lr_parent != NULL ) { + --lr->lr_parent->lr_outrefcnt; + } else { + /* free all referrals (child requests) */ + for ( tmplr = lr->lr_refnext; tmplr != NULL; tmplr = nextlr ) { + nextlr = tmplr->lr_refnext; + free_request( ld, tmplr ); + } + } + + if ( lr->lr_prev == NULL ) { + ld->ld_requests = lr->lr_next; + } else { + lr->lr_prev->lr_next = lr->lr_next; + } + + if ( lr->lr_next != NULL ) { + lr->lr_next->lr_prev = lr->lr_prev; + } + + if ( lr->lr_ber != NULL ) { + ber_free( lr->lr_ber, 1 ); + } + + if ( lr->lr_res_error != NULL ) { + free( lr->lr_res_error ); + } + + if ( lr->lr_res_matched != NULL ) { + free( lr->lr_res_matched ); + } + + if ( lr->lr_ref_tofollow != NULL ) { + for (i= 0; lr->lr_ref_tofollow[i] != NULL; i++) + free(lr->lr_ref_tofollow[i]); + free(lr->lr_ref_tofollow); + } + if ( lr->lr_ref_unfollowed != NULL ) { + for (i= 0; lr->lr_ref_unfollowed[i] != NULL; i++) + free(lr->lr_ref_unfollowed[i]); + free(lr->lr_ref_unfollowed); + } + if ( lr->lr_ref_followed != NULL ) { + for (i= 0; lr->lr_ref_followed[i] != NULL; i++) + free(lr->lr_ref_followed[i]); + free(lr->lr_ref_followed); + } + + free( lr ); +} + + +static void +free_servers( LDAPServer *srvlist ) +{ + LDAPServer *nextsrv; + + while ( srvlist != NULL ) { + nextsrv = srvlist->lsrv_next; + if ( srvlist->lsrv_dn != NULL ) { + free( srvlist->lsrv_dn ); + } + if ( srvlist->lsrv_host != NULL ) { + free( srvlist->lsrv_host ); + } + free( srvlist ); + srvlist = nextsrv; + } +} + +/* + * nsldapi_connection_lost_nolock() resets "ld" to a non-connected, known + * state. It should be called whenever a fatal error occurs on the + * Sockbuf "sb." sb == NULL means we don't know specifically where + * the problem was so we assume all connections are bad. + */ +void +nsldapi_connection_lost_nolock( LDAP *ld, Sockbuf *sb ) +{ + LDAPRequest *lr; + + /* + * change status of all pending requests that are associated with "sb + * to "connection dead." + * also change the connection status to "dead" and remove it from + * the list of sockets we are interested in. + */ + for ( lr = ld->ld_requests; lr != NULL; lr = lr->lr_next ) { + if ( sb == NULL || + ( lr->lr_conn != NULL && lr->lr_conn->lconn_sb == sb )) { + lr->lr_status = LDAP_REQST_CONNDEAD; + if ( lr->lr_conn != NULL ) { + lr->lr_conn->lconn_status = LDAP_CONNST_DEAD; + } + } + } +} + +#ifdef LDAP_DNS +static LDAPServer * +dn2servers( LDAP *ld, char *dn ) /* dn can also be a domain.... */ +{ + char *p, *domain, *host, *server_dn, **dxs; + int i, port; + LDAPServer *srvlist, *prevsrv, *srv; + + if (( domain = strrchr( dn, '@' )) != NULL ) { + ++domain; + } else { + domain = dn; + } + + if (( dxs = getdxbyname( domain )) == NULL ) { + ld->ld_errno = LDAP_NO_MEMORY; + return( NULL ); + } + + srvlist = NULL; + + for ( i = 0; dxs[ i ] != NULL; ++i ) { + port = LDAP_PORT; + server_dn = NULL; + if ( strchr( dxs[ i ], ':' ) == NULL ) { + host = dxs[ i ]; + } else if ( strlen( dxs[ i ] ) >= 7 && + strncmp( dxs[ i ], "ldap://", 7 ) == 0 ) { + host = dxs[ i ] + 7; + if (( p = strchr( host, ':' )) == NULL ) { + p = host; + } else { + *p++ = '\0'; + port = atoi( p ); + } + if (( p = strchr( p, '/' )) != NULL ) { + server_dn = ++p; + if ( *server_dn == '\0' ) { + server_dn = NULL; + } + } + } else { + host = NULL; + } + + if ( host != NULL ) { /* found a server we can use */ + if (( srv = (LDAPServer *)calloc( 1, + sizeof( LDAPServer ))) == NULL ) { + free_servers( srvlist ); + srvlist = NULL; + break; /* exit loop & return */ + } + + /* add to end of list of servers */ + if ( srvlist == NULL ) { + srvlist = srv; + } else { + prevsrv->lsrv_next = srv; + } + prevsrv = srv; + + /* copy in info. */ + if (( srv->lsrv_host = strdup( host )) == NULL || + ( server_dn != NULL && ( srv->lsrv_dn = + strdup( server_dn )) == NULL )) { + free_servers( srvlist ); + srvlist = NULL; + break; /* exit loop & return */ + } + srv->lsrv_port = port; + } + } + + ldap_value_free( dxs ); + + if ( srvlist == NULL ) { + ld->ld_errno = LDAP_SERVER_DOWN; + } + + return( srvlist ); +} +#endif /* LDAP_DNS */ |