X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=libraries%2Flibldap%2Fopen.c;h=e8785387f5507c4cb7b6f3328e1953b70d51ef4e;hb=403f4479bc9f9a864122d4aeecf7284408918302;hp=a145ca07831497692f4ae5aeff0a51268e711caf;hpb=29eda9c7997e57c4907534e817850389e966c23a;p=openldap diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c index a145ca0783..e8785387f5 100644 --- a/libraries/libldap/open.c +++ b/libraries/libldap/open.c @@ -1,52 +1,31 @@ +/* $OpenLDAP$ */ /* + * Copyright 1998-1999 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. * * open.c */ -#ifndef lint -static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n"; -#endif +#include "portable.h" #include -#include - -#ifdef MACOS -#include -#include "macos.h" -#endif /* MACOS */ - -#if defined( DOS ) || defined( _WIN32 ) -#include "msdos.h" -#include -#endif /* DOS */ - -#if !defined(MACOS) && !defined(DOS) && !defined( _WIN32 ) -#include -#include -#include -#ifndef VMS -#include -#endif -#include -#endif -#include "lber.h" -#include "ldap.h" -#include "ldap-int.h" -#ifdef LDAP_DEBUG -int ldap_debug; -#endif +#include -#ifndef INADDR_LOOPBACK -#define INADDR_LOOPBACK ((unsigned long) 0x7f000001) -#endif +#include +#include +#include -#ifndef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 64 +#ifdef HAVE_SYS_PARAM_H +#include #endif +#include "ldap-int.h" + /* * ldap_open - initialize and connect to an ldap server. A magic cookie to @@ -59,12 +38,10 @@ int ldap_debug; */ LDAP * -ldap_open( char *host, int port ) +ldap_open( LDAP_CONST char *host, int port ) { LDAP *ld; -#ifdef LDAP_REFERRALS LDAPServer *srv; -#endif /* LDAP_REFERRALS */ Debug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 ); @@ -72,31 +49,23 @@ ldap_open( char *host, int port ) return( NULL ); } -#ifdef LDAP_REFERRALS - if (( srv = (LDAPServer *)calloc( 1, sizeof( LDAPServer ))) == + if (( srv = (LDAPServer *)LDAP_CALLOC( 1, sizeof( LDAPServer ))) == NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host = - strdup( ld->ld_defhost )) == NULL )) { - ldap_ld_free( ld, 0 ); + LDAP_STRDUP( ld->ld_defhost )) == NULL )) { + if(srv != NULL) LDAP_FREE( (char*) srv ); + ldap_ld_free( ld, 0, NULL, NULL ); 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 ); + if ( ld->ld_defhost != NULL ) LDAP_FREE( srv->lsrv_host ); + LDAP_FREE( (char *)srv ); + ldap_ld_free( ld, 0, NULL, NULL ); return( NULL ); } ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ -#else /* LDAP_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 ); - return( NULL ); - } -#endif /* LDAP_REFERRALS */ - Debug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n", ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 ); @@ -107,50 +76,111 @@ 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. - * "defhost" may be a space-separated list of hosts or IP addresses + * "host" may be a space-separated list of hosts or IP addresses * * Example: * LDAP *ld; - * ld = ldap_open( default_hostname, default_port ); + * ld = ldap_open( host, port ); */ LDAP * -ldap_init( char *defhost, int defport ) +ldap_init( LDAP_CONST char *defhost, int defport ) { LDAP *ld; + if( ldap_int_global_options.ldo_valid != LDAP_INITIALIZED ) { + ldap_int_initialize(); + } + Debug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 ); +#ifdef HAVE_WINSOCK2 +{ WORD wVersionRequested; + WSADATA wsaData; + int err; + + wVersionRequested = MAKEWORD( 2, 0 ); + + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) { + /* Tell the user that we couldn't find a usable */ + /* WinSock DLL. */ + return NULL; + } + + /* Confirm that the WinSock DLL supports 2.0.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.0 in addition to 2.0, it will still return */ + /* 2.0 in wVersion since that is the version we */ + /* requested. */ + + if ( LOBYTE( wsaData.wVersion ) != 2 || + HIBYTE( wsaData.wVersion ) != 0 ) + { + /* Tell the user that we couldn't find a usable */ + /* WinSock DLL. */ + WSACleanup( ); + return NULL; + } +} /* The WinSock DLL is acceptable. Proceed. */ - if ( (ld = (LDAP *) calloc( 1, sizeof(LDAP) )) == NULL ) { +#elif HAVE_WINSOCK +{ WSADATA wsaData; + if ( WSAStartup( 0x0101, &wsaData ) != 0 ) { + return( NULL ); + } +} +#endif + + if ( (ld = (LDAP *) LDAP_CALLOC( 1, sizeof(LDAP) )) == NULL ) { + WSACleanup( ); return( NULL ); } + + /* copy the global options */ + memcpy(&ld->ld_options, &ldap_int_global_options, + sizeof(ld->ld_options)); -#ifdef LDAP_REFERRALS - if (( ld->ld_selectinfo = ldap_new_select_info()) == NULL ) { - free( (char*)ld ); + 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_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); + } + + if ( ld->ld_options.ldo_defhost == NULL ) { + LDAP_FREE( (char*)ld ); + WSACleanup( ); return( NULL ); } - ld->ld_options = LDAP_OPT_REFERRALS; -#endif /* LDAP_REFERRALS */ - if ( defhost != NULL && - ( ld->ld_defhost = strdup( defhost )) == NULL ) { -#ifdef LDAP_REFERRALS - ldap_free_select_info( ld->ld_selectinfo ); -#endif /* LDAP_REFERRALS */ - free( (char*)ld ); + if ( ldap_int_global_options.ldo_defbase != NULL ) { + ld->ld_options.ldo_defbase = LDAP_STRDUP( + ldap_int_global_options.ldo_defbase); + } + + 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( (char*) ld ); + WSACleanup( ); return( NULL ); } + if(defport != 0) { + ld->ld_defport = defport; + } - ld->ld_defport = ( defport == 0 ) ? LDAP_PORT : defport; - ld->ld_version = LDAP_VERSION; ld->ld_lberoptions = LBER_USE_DER; - ld->ld_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT; - -#ifdef LDAP_REFERRALS - ld->ld_options |= LDAP_OPT_REFERRALS; -#endif /* LDAP_REFERRALS */ #if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET ) ld->ld_lberoptions |= LBER_TRANSLATE_STRINGS; @@ -159,21 +189,27 @@ ldap_init( char *defhost, int defport ) #endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */ #endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */ + /* we'll assume we're talking version 2 for now */ + ld->ld_version = LDAP_VERSION2; + + ber_pvt_sb_init( &(ld->ld_sb) ); + return( ld ); } int -open_ldap_connection( LDAP *ld, Sockbuf *sb, char *host, int defport, +open_ldap_connection( LDAP *ld, Sockbuf *sb, const char *host, int defport, char **krbinstancep, int async ) { - int rc, port; - char *p, *q, *r; - char *curhost, hostname[ 2*MAXHOSTNAMELEN ]; + int rc = -1; + int port; + const char *p, *q; + char *r, *curhost, hostname[ 2*MAXHOSTNAMELEN ]; Debug( LDAP_DEBUG_TRACE, "open_ldap_connection\n", 0, 0, 0 ); - defport = htons( defport ); + defport = htons( (short) defport ); if ( host != NULL ) { for ( p = host; p != NULL && *p != '\0'; p = q ) { @@ -185,7 +221,7 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, char *host, int defport, ++q; } } else { - curhost = p; /* avoid copy if possible */ + curhost = (char *) p; /* avoid copy if possible */ q = NULL; } @@ -196,34 +232,51 @@ open_ldap_connection( LDAP *ld, Sockbuf *sb, char *host, int defport, curhost = hostname; } *r++ = '\0'; - port = htons( (short)atoi( r )); + port = htons( (short) atoi( r ) ); } else { port = defport; } - if (( rc = ldap_connect_to_host( sb, curhost, 0L, + if (( rc = ldap_connect_to_host( ld, sb, curhost, 0L, port, async )) != -1 ) { break; } } } else { - rc = ldap_connect_to_host( sb, NULL, htonl( INADDR_LOOPBACK ), + rc = ldap_connect_to_host( ld, sb, 0, htonl( INADDR_LOOPBACK ), defport, 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 ) { + /* + * Fortunately, the lib uses blocking io... + */ + if ( ldap_pvt_tls_connect( sb, ld->ld_options.ldo_tls_ctx ) < + 0 ) { + return -1; + } + /* FIXME: hostname of server must be compared with name in + * certificate.... + */ + } +#endif if ( krbinstancep != NULL ) { -#ifdef KERBEROS +#ifdef HAVE_KERBEROS + char *c; if (( *krbinstancep = ldap_host_connected_to( sb )) != NULL && - ( p = strchr( *krbinstancep, '.' )) != NULL ) { - *p = '\0'; + ( c = strchr( *krbinstancep, '.' )) != NULL ) { + *c = '\0'; } -#else /* KERBEROS */ +#else /* HAVE_KERBEROS */ krbinstancep = NULL; -#endif /* KERBEROS */ +#endif /* HAVE_KERBEROS */ } return( 0 );