X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fopen.c;h=d8b1aaeb55dcc0ccce14a7bd1650f13eaf1ebf98;hb=7573a81efea63bc0e07d88ba4c9b6973d51d857d;hp=2aa8eafcb259dc01894da1ca5b3b0b1481af666d;hpb=c24d932b02e97472a67f7e71e01b3963469e3e77;p=openldap diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index 2aa8eafcb2..d8b1aaeb55 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -1,4 +1,9 @@ +/* $OpenLDAP$ */ /* + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ +/* Portions * Copyright (c) 1995 Regents of the University of Michigan. * All rights reserved. * @@ -7,27 +12,30 @@ #include "portable.h" -#ifndef lint -static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n"; -#endif - #include -#include +#include +#include + +#include #include #include #include -#ifdef HAVE_SYS_PARAM_H -#include -#endif - #include "ldap-int.h" -#ifdef LDAP_DEBUG -int ldap_debug; -#endif +int ldap_open_defconn( LDAP *ld ) +{ + if (( ld->ld_defconn = ldap_new_connection( ld, ld->ld_options.ldo_defludp, 1,1,NULL )) == NULL ) + { + ld->ld_errno = LDAP_SERVER_DOWN; + return -1; + } + ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ + + return 0; +} /* * ldap_open - initialize and connect to an ldap server. A magic cookie to @@ -40,12 +48,10 @@ int ldap_debug; */ LDAP * -ldap_open( char *host, int port ) +ldap_open( LDAP_CONST char *host, int port ) { + int rc; LDAP *ld; -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS - LDAPServer *srv; -#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 ); @@ -53,33 +59,12 @@ ldap_open( char *host, int port ) return( NULL ); } - /* we'll assume we're talking version 2 for now */ - ld->ld_version = LDAP_VERSION2; - -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS - if (( srv = (LDAPServer *)calloc( 1, sizeof( LDAPServer ))) == - NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host = - ldap_strdup( ld->ld_defhost )) == NULL )) { - ldap_ld_free( ld, 0 ); - return( NULL ); - } - srv->lsrv_port = ld->ld_defport; - - if (( ld->ld_defconn = ldap_new_connection( ld, &srv, 1,1,0 )) == NULL ) { - if ( ld->ld_defhost != NULL ) free( srv->lsrv_host ); - free( (char *)srv ); - ldap_ld_free( ld, 0 ); - return( NULL ); - } - ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ + rc = ldap_open_defconn( ld ); -#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ - if ( open_ldap_connection( ld, &ld->ld_sb, ld->ld_defhost, - ld->ld_defport, &ld->ld_host, 0 ) < 0 ) { - ldap_ld_free( ld, 0 ); + if( rc < 0 ) { + ldap_ld_free( ld, 0, NULL, NULL ); return( NULL ); } -#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS */ Debug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n", ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 ); @@ -88,22 +73,15 @@ ldap_open( char *host, int port ) } -/* - * ldap_init - initialize the LDAP library. A magic cookie to be used for - * future communication is returned on success, NULL on failure. - * "host" may be a space-separated list of hosts or IP addresses - * - * Example: - * LDAP *ld; - * ld = ldap_open( host, port ); - */ -LDAP * -ldap_init( char *defhost, int defport ) + +int +ldap_create( LDAP **ldp ) { LDAP *ld; - if(!openldap_ldap_initialized) { - openldap_ldap_initialize(); + *ldp = NULL; + if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) { + ldap_int_initialize(NULL); } Debug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 ); @@ -111,15 +89,12 @@ ldap_init( char *defhost, int defport ) #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.*/ @@ -134,131 +109,235 @@ ldap_init( char *defhost, int defport ) /* 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 - if ( WSAStartup( 0x0101, &wsadata ) != 0 ) { - return( NULL ); +{ WSADATA wsaData; + if ( WSAStartup( 0x0101, &wsaData ) != 0 ) { + return LDAP_LOCAL_ERROR; } +} #endif - if ( (ld = (LDAP *) calloc( 1, sizeof(LDAP) )) == NULL ) { + if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) { WSACleanup( ); - return( NULL ); + return( LDAP_NO_MEMORY ); } - + /* copy the global options */ - memcpy(&ld->ld_options, &openldap_ldap_global_options, + memcpy(&ld->ld_options, &ldap_int_global_options, sizeof(ld->ld_options)); - /* but not pointers to malloc'ed strings */ - ld->ld_options.ldo_defbase = NULL; - ld->ld_options.ldo_defhost = NULL; + ld->ld_valid = LDAP_VALID_SESSION; - if ( defhost != NULL ) { - ld->ld_options.ldo_defhost = ldap_strdup( defhost ); - } else { - ld->ld_options.ldo_defhost = ldap_strdup( - openldap_ldap_global_options.ldo_defhost); - } + /* but not pointers to malloc'ed items */ + ld->ld_options.ldo_defludp = NULL; + ld->ld_options.ldo_sctrls = NULL; + ld->ld_options.ldo_cctrls = NULL; + + ld->ld_options.ldo_defludp = + ldap_url_duplist(ldap_int_global_options.ldo_defludp); - if ( ld->ld_options.ldo_defhost == NULL ) { - free( (char*)ld ); + if ( ld->ld_options.ldo_defludp == NULL ) { + LDAP_FREE( (char*)ld ); WSACleanup( ); - return( NULL ); + return LDAP_NO_MEMORY; } -#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) { - free( (char*) ld->ld_options.ldo_defhost ); - free( (char*) ld->ld_options.ldo_defbase ); - free( (char*) ld ); + ldap_free_urllist( ld->ld_options.ldo_defludp ); + LDAP_FREE( (char*) ld ); WSACleanup( ); - return( NULL ); + return LDAP_NO_MEMORY; } -#endif - if(defport != 0) { - ld->ld_defport = defport; + ld->ld_lberoptions = LBER_USE_DER; + + ld->ld_sb = ber_sockbuf_alloc( ); + if ( ld->ld_sb == NULL ) { + ldap_free_urllist( ld->ld_options.ldo_defludp ); + LDAP_FREE( (char*) ld ); + WSACleanup( ); + return LDAP_NO_MEMORY; } - ld->ld_lberoptions = LBER_USE_DER; + *ldp = ld; + return LDAP_SUCCESS; +} -#if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET ) - ld->ld_lberoptions |= LBER_TRANSLATE_STRINGS; -#if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET - ldap_set_string_translators( ld, ldap_8859_to_t61, ldap_t61_to_8859 ); -#endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */ -#endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */ +/* + * ldap_init - initialize the LDAP library. A magic cookie to be used for + * future communication is returned on success, NULL on failure. + * "host" may be a space-separated list of hosts or IP addresses + * + * Example: + * LDAP *ld; + * ld = ldap_open( host, port ); + */ +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 -open_ldap_connection( LDAP *ld, Sockbuf *sb, char *host, int defport, +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 +ldap_start_tls ( LDAP *ld, + LDAPControl **serverctrls, + LDAPControl **clientctrls ) +{ +#ifdef HAVE_TLS + LDAPConn *lc; + int rc; + char *rspoid = NULL; + struct berval *rspdata = NULL; + + if (ld->ld_conns == NULL) { + rc = ldap_open_defconn( ld ); + if (rc != LDAP_SUCCESS) + return(rc); + } + + for (lc = ld->ld_conns; lc != NULL; lc = lc->lconn_next) { + if (ldap_pvt_tls_inplace(lc->lconn_sb) != 0) + return LDAP_OPERATIONS_ERROR; + rc = ldap_extended_operation_s(ld, LDAP_EXOP_START_TLS, + NULL, serverctrls, clientctrls, &rspoid, &rspdata); + if (rc != LDAP_SUCCESS) + return rc; + if (rspoid != NULL) + LDAP_FREE(rspoid); + if (rspdata != NULL) + ber_bvfree(rspdata); + rc = ldap_pvt_tls_start( ld, lc->lconn_sb, ld->ld_options.ldo_tls_ctx ); + if (rc != LDAP_SUCCESS) + return rc; + } + return LDAP_SUCCESS; +#else + return LDAP_NOT_SUPPORTED; +#endif +} + +int +open_ldap_connection( LDAP *ld, Sockbuf *sb, LDAPURLDesc *srv, char **krbinstancep, int async ) { - int rc = -1; - int port; - char *p, *q, *r; - char *curhost, hostname[ 2*MAXHOSTNAMELEN ]; + int rc = -1; + 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 = 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( sb, curhost, 0L, - port, async )) != -1 ) { - break; - } - } - } else { - rc = ldap_connect_to_host( sb, NULL, 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 || *srv->lud_host == 0 ) + addr = htonl( INADDR_LOOPBACK ); + + switch ( srv->lud_protocol ) { + case LDAP_PROTO_TCP: + rc = ldap_connect_to_host( ld, sb, srv->lud_host, + addr, port, async ); + if ( rc == -1 ) + return rc; + ber_sockbuf_add_io( sb, &ber_sockbuf_io_tcp, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + break; + case LDAP_PROTO_UDP: + rc = ldap_connect_to_host( ld, sb, srv->lud_host, + addr, port, async ); + if ( rc == -1 ) + return rc; + ber_sockbuf_add_io( sb, &ber_sockbuf_io_udp, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + break; +#ifdef LDAP_PF_LOCAL + case LDAP_PROTO_LOCAL: + rc = ldap_connect_to_path( ld, sb, srv->lud_host, + async ); + if ( rc == -1 ) + return rc; + ber_sockbuf_add_io( sb, &ber_sockbuf_io_fd, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); + break; +#endif /* LDAP_PF_LOCAL */ + default: + return -1; + break; } - if ( rc == -1 ) { - return( rc ); + ber_sockbuf_add_io( sb, &ber_sockbuf_io_readahead, + LBER_SBIOD_LEVEL_PROVIDER, NULL ); +#ifdef LDAP_DEBUG + ber_sockbuf_add_io( sb, &ber_sockbuf_io_debug, INT_MAX, NULL ); +#endif + +#ifdef HAVE_TLS + if (ld->ld_options.ldo_tls_mode == LDAP_OPT_X_TLS_HARD || + (srv->lud_properties & LDAP_URL_USE_SSL)) { + rc = ldap_pvt_tls_start( ld, sb, ld->ld_options.ldo_tls_ctx ); + if (rc != LDAP_SUCCESS) + return rc; } +#endif if ( krbinstancep != NULL ) { -#ifdef HAVE_KERBEROS +#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND + char *c; if (( *krbinstancep = ldap_host_connected_to( sb )) != NULL && - ( p = strchr( *krbinstancep, '.' )) != NULL ) { - *p = '\0'; + ( c = strchr( *krbinstancep, '.' )) != NULL ) { + *c = '\0'; } -#else /* HAVE_KERBEROS */ - krbinstancep = NULL; -#endif /* HAVE_KERBEROS */ +#else /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */ + *krbinstancep = NULL; +#endif /* LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND */ } return( 0 );