int ldap_open_defconn( LDAP *ld )
{
- LDAPServer *srv;
-
- if (( srv = (LDAPServer *)LDAP_CALLOC( 1, sizeof( LDAPServer ))) ==
- NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host =
- LDAP_STRDUP( ld->ld_defhost )) == NULL ))
- {
- if( srv != NULL ) LDAP_FREE( (char*) srv );
- ld->ld_errno = LDAP_NO_MEMORY;
- return -1;
- }
-
- srv->lsrv_port = ld->ld_defport;
-
- if (( ld->ld_defconn = ldap_new_connection( ld, &srv, 1,1,0 )) == NULL )
+ if (( ld->ld_defconn = ldap_new_connection( ld, ld->ld_options.ldo_defludp, 1,1,0 )) == NULL )
{
- if ( ld->ld_defhost != NULL ) LDAP_FREE( srv->lsrv_host );
- LDAP_FREE( (char *)srv );
ld->ld_errno = LDAP_SERVER_DOWN;
return -1;
}
*/
LDAP *
ldap_init( LDAP_CONST char *defhost, int defport )
+{
+ LDAP *ld;
+ int rc;
+
+ rc = ldap_create(&ld);
+ if ( rc != LDAP_SUCCESS )
+ return NULL;
+
+ if (defport != 0)
+ ld->ld_options.ldo_defport = defport;
+
+ if (defhost != NULL) {
+ rc = ldap_set_option(ld, LDAP_OPT_HOST_NAME, defhost);
+ if ( rc != LDAP_SUCCESS ) {
+ ldap_ld_free(ld, 1, NULL, NULL);
+ return NULL;
+ }
+ }
+
+ return( ld );
+}
+
+int
+ldap_create( LDAP **ldp )
{
LDAP *ld;
+ *ldp = NULL;
if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) {
ldap_int_initialize();
}
#ifdef HAVE_WINSOCK2
{ WORD wVersionRequested;
WSADATA wsaData;
- int err;
wVersionRequested = MAKEWORD( 2, 0 );
-
- err = WSAStartup( wVersionRequested, &wsaData );
- if ( err != 0 ) {
+ if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
/* Tell the user that we couldn't find a usable */
/* WinSock DLL. */
- return NULL;
+ return LDAP_LOCAL_ERROR;
}
/* Confirm that the WinSock DLL supports 2.0.*/
/* Tell the user that we couldn't find a usable */
/* WinSock DLL. */
WSACleanup( );
- return NULL;
+ return LDAP_LOCAL_ERROR;
}
} /* The WinSock DLL is acceptable. Proceed. */
#elif HAVE_WINSOCK
{ WSADATA wsaData;
if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
- return( NULL );
+ return LDAP_LOCAL_ERROR;
}
}
#endif
if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) {
WSACleanup( );
- return( NULL );
+ return( LDAP_NO_MEMORY );
}
/* copy the global options */
ld->ld_valid = LDAP_VALID_SESSION;
/* but not pointers to malloc'ed items */
- ld->ld_options.ldo_defbase = NULL;
- ld->ld_options.ldo_defhost = NULL;
+ ld->ld_options.ldo_defludp = NULL;
ld->ld_options.ldo_sctrls = NULL;
ld->ld_options.ldo_cctrls = NULL;
- if ( defhost != NULL ) {
- ld->ld_options.ldo_defhost = LDAP_STRDUP( defhost );
- } else {
- ld->ld_options.ldo_defhost = LDAP_STRDUP(
- ldap_int_global_options.ldo_defhost);
- }
+ ld->ld_options.ldo_defludp =
+ ldap_url_duplist(ldap_int_global_options.ldo_defludp);
- if ( ld->ld_options.ldo_defhost == NULL ) {
+ if ( ld->ld_options.ldo_defludp == NULL ) {
LDAP_FREE( (char*)ld );
WSACleanup( );
- return( NULL );
- }
-
- if ( ldap_int_global_options.ldo_defbase != NULL ) {
- ld->ld_options.ldo_defbase = LDAP_STRDUP(
- ldap_int_global_options.ldo_defbase);
+ return LDAP_NO_MEMORY;
}
if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) {
- LDAP_FREE( (char*) ld->ld_options.ldo_defhost );
- if ( ld->ld_options.ldo_defbase != NULL ) {
- LDAP_FREE( (char*) ld->ld_options.ldo_defbase );
- }
+ ldap_free_urllist( ld->ld_options.ldo_defludp );
LDAP_FREE( (char*) ld );
WSACleanup( );
- return( NULL );
- }
-
- if(defport != 0) {
- ld->ld_defport = defport;
+ return LDAP_NO_MEMORY;
}
ld->ld_lberoptions = LBER_USE_DER;
ber_pvt_sb_init( &(ld->ld_sb) );
- return( ld );
+ *ldp = ld;
+ return LDAP_SUCCESS;
}
+int
+ldap_initialize( LDAP **ldp, LDAP_CONST char *url )
+{
+ int rc;
+ LDAP *ld;
+
+ *ldp = NULL;
+ rc = ldap_create(&ld);
+ if ( rc != LDAP_SUCCESS )
+ return rc;
+
+ if (url != NULL) {
+ rc = ldap_set_option(ld, LDAP_OPT_URI, url);
+ if ( rc != LDAP_SUCCESS ) {
+ ldap_ld_free(ld, 1, NULL, NULL);
+ return rc;
+ }
+ }
+
+ *ldp = ld;
+ return LDAP_SUCCESS;
+}
int
-open_ldap_connection( LDAP *ld, Sockbuf *sb, const char *host, int defport,
+open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv,
char **krbinstancep, int async )
{
int rc = -1;
- int port;
- const char *p, *q;
- char *r, *curhost, hostname[ 2*MAXHOSTNAMELEN ];
+ int port;
+ long addr;
Debug( LDAP_DEBUG_TRACE, "open_ldap_connection\n", 0, 0, 0 );
- defport = htons( (short) defport );
-
- if ( host != NULL ) {
- for ( p = host; p != NULL && *p != '\0'; p = q ) {
- if (( q = strchr( p, ' ' )) != NULL ) {
- strncpy( hostname, p, q - p );
- hostname[ q - p ] = '\0';
- curhost = hostname;
- while ( *q == ' ' ) {
- ++q;
- }
- } else {
- curhost = (char *) p; /* avoid copy if possible */
- q = NULL;
- }
-
- if (( r = strchr( curhost, ':' )) != NULL ) {
- if ( curhost != hostname ) {
- strcpy( hostname, curhost ); /* now copy */
- r = hostname + ( r - curhost );
- curhost = hostname;
- }
- *r++ = '\0';
- port = htons( (short) atoi( r ) );
- } else {
- port = defport;
- }
-
- if (( rc = ldap_connect_to_host( ld, sb, curhost, 0L,
- port, async )) != -1 ) {
- break;
- }
- }
- } else {
- rc = ldap_connect_to_host( ld, sb, 0, htonl( INADDR_LOOPBACK ),
- defport, async );
- }
+ port = srv->lud_port;
+ if (port == 0)
+ port = ld->ld_options.ldo_defport;
+ port = htons( (short) port );
+
+ addr = 0;
+ if ( srv->lud_host == NULL )
+ addr = htonl( INADDR_LOOPBACK );
+ rc = ldap_connect_to_host( ld, sb, srv->lud_host, addr, port, async );
if ( rc == -1 ) {
return( rc );
}
ber_pvt_sb_set_io( sb, &ber_pvt_sb_io_tcp, NULL );
#ifdef HAVE_TLS
- if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD ) {
+ if ( ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD
+ || srv->lud_ldaps != 0 )
+ {
/*
* Fortunately, the lib uses blocking io...
*/
return LDAP_OPT_SUCCESS;
case LDAP_OPT_HOST_NAME:
- * (char **) outvalue = LDAP_STRDUP(lo->ldo_defhost);
+ * (char **) outvalue = ldap_url_list2hosts(lo->ldo_defludp);
+ return LDAP_OPT_SUCCESS;
+
+ case LDAP_OPT_URI:
+ * (char **) outvalue = ldap_url_list2urls(lo->ldo_defludp);
return LDAP_OPT_SUCCESS;
case LDAP_OPT_ERROR_NUMBER:
default:
#ifdef HAVE_TLS
- if ( ldap_pvt_tls_get_option(lo, option, outvalue ) == 0 )
+ if ( ldap_pvt_tls_get_option((struct ldapoptions *)lo, option, outvalue ) == 0 )
return LDAP_OPT_SUCCESS;
#endif
/* bad param */
case LDAP_OPT_HOST_NAME: {
const char *host = (const char *) invalue;
+ LDAPURLDesc *ludlist = NULL;
+ int rc = LDAP_OPT_SUCCESS;
+
+ if(host != NULL) {
+ rc = ldap_url_parsehosts(&ludlist, host);
+
+ } else if(ld == NULL) {
+ /*
+ * must want global default returned
+ * to initial condition.
+ */
+ rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
- if(lo->ldo_defhost != NULL) {
- LDAP_FREE(lo->ldo_defhost);
- lo->ldo_defhost = NULL;
+ } else {
+ /*
+ * must want the session default
+ * updated to the current global default
+ */
+ ludlist = ldap_url_duplist(
+ ldap_int_global_options.ldo_defludp);
+ if (ludlist == NULL)
+ rc = LDAP_NO_MEMORY;
}
- if(host != NULL) {
- lo->ldo_defhost = LDAP_STRDUP(host);
- return LDAP_OPT_SUCCESS;
+ if (rc == LDAP_OPT_SUCCESS) {
+ if (lo->ldo_defludp != NULL)
+ ldap_free_urllist(lo->ldo_defludp);
+ lo->ldo_defludp = ludlist;
}
+ return rc;
+ }
- if(ld == NULL) {
+ case LDAP_OPT_URI: {
+ const char *urls = (const char *) invalue;
+ LDAPURLDesc *ludlist = NULL;
+ int rc = LDAP_OPT_SUCCESS;
+
+ if(urls != NULL) {
+ rc = ldap_url_parselist(&ludlist, urls);
+
+ } else if(ld == NULL) {
/*
* must want global default returned
* to initial condition.
*/
- lo->ldo_defhost = LDAP_STRDUP("localhost");
+ rc = ldap_url_parselist(&ludlist, "ldap://localhost/");
} else {
/*
* must want the session default
* updated to the current global default
*/
- lo->ldo_defhost = LDAP_STRDUP(
- ldap_int_global_options.ldo_defhost);
+ ludlist = ldap_url_duplist(
+ ldap_int_global_options.ldo_defludp);
+ if (ludlist == NULL)
+ rc = LDAP_NO_MEMORY;
}
- } return LDAP_OPT_SUCCESS;
+
+ if (rc == LDAP_OPT_SUCCESS) {
+ if (lo->ldo_defludp != NULL)
+ ldap_free_urllist(lo->ldo_defludp);
+ lo->ldo_defludp = ludlist;
+ }
+ return rc;
+ }
case LDAP_OPT_ERROR_NUMBER: {
int err = * (const int *) invalue;
default:
#ifdef HAVE_TLS
- if ( ldap_pvt_tls_set_option( lo, option, invalue ) == 0 )
+ if ( ldap_pvt_tls_set_option( lo, option, (void *)invalue ) == 0 )
return LDAP_OPT_SUCCESS;
#endif
/* bad param */
#include "ldap-int.h"
#include "lber.h"
-static LDAPConn *find_connection LDAP_P(( LDAP *ld, LDAPServer *srv, int any ));
+static LDAPConn *find_connection LDAP_P(( LDAP *ld, LDAPURLDesc *srv, int any ));
static void use_connection LDAP_P(( LDAP *ld, LDAPConn *lc ));
-static void free_servers LDAP_P(( LDAPServer *srvlist ));
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-static LDAPServer *dn2servers LDAP_P(( LDAP *ld, const char *dn ));
+static LDAPURLDesc *dn2servers LDAP_P(( LDAP *ld, const char *dn ));
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
static BerElement *re_encode_request LDAP_P((
const char *dn,
BerElement *ber )
{
- LDAPServer *servers;
+ LDAPURLDesc *servers;
+ int rc;
Debug( LDAP_DEBUG_TRACE, "ldap_send_initial_request\n", 0, 0, 0 );
#ifdef LDAP_DEBUG
if ( ldap_debug & LDAP_DEBUG_TRACE ) {
- LDAPServer *srv;
+ LDAPURLDesc *srv;
- for ( srv = servers; srv != NULL;
- srv = srv->lsrv_next ) {
+ for ( srv = servers;
+ srv != NULL;
+ srv = srv->lud_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 );
+ srv->lud_host, ( srv->lud_dn == NULL ) ?
+ "(default)" : srv->lud_dn,
+ srv->lud_port );
}
}
#endif /* LDAP_DEBUG */
servers = NULL;
}
- return( ldap_send_server_request( ld, ber, ld->ld_msgid, NULL, servers,
- NULL, 0 ));
+ rc = ldap_send_server_request( ld, ber, ld->ld_msgid, NULL,
+ servers, NULL, 0 );
+ if (servers)
+ ldap_free_urllist(servers);
+ return(rc);
}
BerElement *ber,
ber_int_t msgid,
LDAPRequest *parentreq,
- LDAPServer *srvlist,
+ LDAPURLDesc *srvlist,
LDAPConn *lc,
int bind )
{
incparent = 1;
++parentreq->lr_outrefcnt;
}
- lc = ldap_new_connection( ld, &srvlist, 0, 1, bind );
+ lc = ldap_new_connection( ld, srvlist, 0, 1, bind );
}
- free_servers( srvlist );
}
}
LDAPConn *
-ldap_new_connection( LDAP *ld, LDAPServer **srvlistp, int use_ldsb,
+ldap_new_connection( LDAP *ld, LDAPURLDesc *srvlist, int use_ldsb,
int connect, int bind )
{
LDAPConn *lc;
- LDAPServer *prevsrv, *srv;
+ LDAPURLDesc *srv;
Sockbuf *sb;
/*
lc->lconn_sb = ( use_ldsb ) ? &ld->ld_sb : sb;
if ( connect ) {
- prevsrv = NULL;
-
- for ( srv = *srvlistp; srv != NULL; srv = srv->lsrv_next ) {
+ for ( srv = srvlist; srv != NULL; srv = srv->lud_next ) {
if ( open_ldap_connection( ld, lc->lconn_sb,
- srv->lsrv_host, srv->lsrv_port,
- &lc->lconn_krbinstance, 0 ) != -1 ) {
+ srv, &lc->lconn_krbinstance, 0 ) != -1 )
+ {
break;
}
- prevsrv = srv;
}
if ( srv == NULL ) {
- if ( !use_ldsb ) {
- ber_sockbuf_free( lc->lconn_sb );
- }
+ if ( !use_ldsb ) {
+ ber_sockbuf_free( lc->lconn_sb );
+ }
LDAP_FREE( (char *)lc );
ld->ld_errno = LDAP_SERVER_DOWN;
return( NULL );
}
- if ( prevsrv == NULL ) {
- *srvlistp = srv->lsrv_next;
- } else {
- prevsrv->lsrv_next = srv->lsrv_next;
- }
- lc->lconn_server = srv;
+ lc->lconn_server = ldap_url_dup(srv);
}
lc->lconn_status = LDAP_CONNST_CONNECTED;
static LDAPConn *
-find_connection( LDAP *ld, LDAPServer *srv, int any )
+find_connection( LDAP *ld, LDAPURLDesc *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;
+ LDAPURLDesc *ls;
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 ) {
+ for ( ls = srv; ls != NULL; ls = ls->lud_next ) {
+ if ( lc->lconn_server->lud_host != NULL &&
+ ls->lud_host != NULL && strcasecmp(
+ ls->lud_host, lc->lconn_server->lud_host ) == 0
+ && ls->lud_port == lc->lconn_server->lud_port ) {
return( lc );
}
if ( !any ) {
}
prevlc = tmplc;
}
- free_servers( lc->lconn_server );
+ ldap_free_urllist( lc->lconn_server );
if ( lc->lconn_krbinstance != NULL ) {
LDAP_FREE( lc->lconn_krbinstance );
}
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 ==
+ ( lc->lconn_server->lud_host == NULL ) ? "(null)"
+ : lc->lconn_server->lud_host,
+ lc->lconn_server->lud_port, ( lc->lconn_sb ==
&ld->ld_sb ) ? " (default)" : "" );
}
fprintf( stderr, " refcnt: %d status: %s\n", lc->lconn_refcnt,
}
-static void
-free_servers( LDAPServer *srvlist )
-{
- LDAPServer *nextsrv;
-
- while ( srvlist != NULL ) {
- nextsrv = srvlist->lsrv_next;
- if ( srvlist->lsrv_dn != NULL ) {
- LDAP_FREE( srvlist->lsrv_dn );
- }
- if ( srvlist->lsrv_host != NULL ) {
- LDAP_FREE( srvlist->lsrv_host );
- }
- LDAP_FREE( srvlist );
- srvlist = nextsrv;
- }
-}
-
-
/*
* XXX merging of errors in this routine needs to be improved
*/
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
char *p, *ports, *ref, *tmpref, *refdn, *unfollowed;
LDAPRequest *origreq;
- LDAPServer *srv;
+ LDAPURLDesc *srv;
BerElement *ber;
Debug( LDAP_DEBUG_TRACE, "ldap_chase_referrals\n", 0, 0, 0 );
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
if ( ldapref ) {
#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_DNS */
- if (( srv = (LDAPServer *)LDAP_CALLOC( 1,
- sizeof( LDAPServer ))) == NULL ) {
+ if (( srv = (LDAPURLDesc *)LDAP_CALLOC( 1,
+ sizeof( LDAPURLDesc ))) == NULL ) {
ber_free( ber, 1 );
ld->ld_errno = LDAP_NO_MEMORY;
return( -1 );
}
- if (( srv->lsrv_host = LDAP_STRDUP( tmpref )) == NULL ) {
+ if (( srv->lud_host = LDAP_STRDUP( tmpref )) == NULL ) {
LDAP_FREE( (char *)srv );
ber_free( ber, 1 );
ld->ld_errno = LDAP_NO_MEMORY;
return( -1 );
}
- if (( ports = strchr( srv->lsrv_host, ':' )) != NULL ) {
+ if (( ports = strchr( srv->lud_host, ':' )) != NULL ) {
*ports++ = '\0';
- srv->lsrv_port = atoi( ports );
+ srv->lud_port = atoi( ports );
} else {
- srv->lsrv_port = ldap_int_global_options.ldo_defport;
+ srv->lud_port = ldap_int_global_options.ldo_defport;
}
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
} else {
rc = ldap_append_referral( ld, &unfollowed, ref );
}
+ if (srv != NULL)
+ ldap_free_urllist(srv);
+
if ( !newdn && refdn != NULL ) {
LDAP_FREE( refdn );
}
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_DNS
-static LDAPServer *
+static LDAPURLDesc *
dn2servers( LDAP *ld, const char *dn ) /* dn can also be a domain.... */
{
char *p, *host, *server_dn, **dxs;
const char *domain;
int i, port;
- LDAPServer *srvlist, *prevsrv, *srv;
+ LDAPURLDesc *srvlist, *prevsrv, *srv;
if (( domain = strrchr( dn, '@' )) != NULL ) {
++domain;
}
srvlist = NULL;
-
for ( i = 0; dxs[ i ] != NULL; ++i ) {
- port = ldap_int_global_options.ldo_defport;
- 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 *)LDAP_CALLOC( 1,
- sizeof( LDAPServer ))) == NULL ) {
- free_servers( srvlist );
- srvlist = NULL;
- break; /* exit loop & return */
- }
-
+ if (ldap_url_parselist(&srv, dxs[i]) == LDAP_SUCCESS
+ || ldap_url_parsehosts(&srv, dxs[i]) == LDAP_SUCCESS)
+ {
/* add to end of list of servers */
if ( srvlist == NULL ) {
srvlist = srv;
} else {
- prevsrv->lsrv_next = srv;
+ prevsrv->lud_next = srv;
}
prevsrv = srv;
-
- /* copy in info. */
- if (( srv->lsrv_host = LDAP_STRDUP( host )) == NULL ||
- ( server_dn != NULL && ( srv->lsrv_dn =
- LDAP_STRDUP( server_dn )) == NULL )) {
- free_servers( srvlist );
- srvlist = NULL;
- break; /* exit loop & return */
- }
- srv->lsrv_port = port;
}
}
ld->ld_selectinfo = NULL;
}
- if ( ld->ld_options.ldo_defbase != NULL ) {
- LDAP_FREE( ld->ld_options.ldo_defbase );
- ld->ld_options.ldo_defbase = NULL;
- }
-
- if ( ld->ld_options.ldo_defhost != NULL ) {
- LDAP_FREE( ld->ld_options.ldo_defhost );
- ld->ld_options.ldo_defhost = NULL;
+ if ( ld->ld_options.ldo_defludp != NULL ) {
+ ldap_free_urllist( ld->ld_options.ldo_defludp );
+ ld->ld_options.ldo_defludp = NULL;
}
if ( ld->ld_options.ldo_tm_api != NULL ) {