1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 3*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 4*7c478bd9Sstevel@tonic-gate */ 5*7c478bd9Sstevel@tonic-gate 6*7c478bd9Sstevel@tonic-gate 7*7c478bd9Sstevel@tonic-gate /* 8*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 9*7c478bd9Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 10*7c478bd9Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 11*7c478bd9Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 12*7c478bd9Sstevel@tonic-gate * 13*7c478bd9Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 14*7c478bd9Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 15*7c478bd9Sstevel@tonic-gate * implied. See the License for the specific language governing 16*7c478bd9Sstevel@tonic-gate * rights and limitations under the License. 17*7c478bd9Sstevel@tonic-gate * 18*7c478bd9Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 19*7c478bd9Sstevel@tonic-gate * March 31, 1998. 20*7c478bd9Sstevel@tonic-gate * 21*7c478bd9Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 22*7c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 23*7c478bd9Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 24*7c478bd9Sstevel@tonic-gate * Rights Reserved. 25*7c478bd9Sstevel@tonic-gate * 26*7c478bd9Sstevel@tonic-gate * Contributor(s): 27*7c478bd9Sstevel@tonic-gate */ 28*7c478bd9Sstevel@tonic-gate /* 29*7c478bd9Sstevel@tonic-gate * Copyright (c) 1995 Regents of the University of Michigan. 30*7c478bd9Sstevel@tonic-gate * All rights reserved. 31*7c478bd9Sstevel@tonic-gate */ 32*7c478bd9Sstevel@tonic-gate /* 33*7c478bd9Sstevel@tonic-gate * open.c 34*7c478bd9Sstevel@tonic-gate */ 35*7c478bd9Sstevel@tonic-gate 36*7c478bd9Sstevel@tonic-gate #if 0 37*7c478bd9Sstevel@tonic-gate #ifndef lint 38*7c478bd9Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1995 Regents of the University of Michigan.\nAll rights reserved.\n"; 39*7c478bd9Sstevel@tonic-gate #endif 40*7c478bd9Sstevel@tonic-gate #endif 41*7c478bd9Sstevel@tonic-gate 42*7c478bd9Sstevel@tonic-gate #include "ldap-int.h" 43*7c478bd9Sstevel@tonic-gate #ifdef LDAP_SASLIO_HOOKS 44*7c478bd9Sstevel@tonic-gate /* Valid for any ANSI C compiler */ 45*7c478bd9Sstevel@tonic-gate #include <limits.h> 46*7c478bd9Sstevel@tonic-gate #endif 47*7c478bd9Sstevel@tonic-gate 48*7c478bd9Sstevel@tonic-gate #define VI_PRODUCTVERSION 3 49*7c478bd9Sstevel@tonic-gate 50*7c478bd9Sstevel@tonic-gate #ifndef INADDR_LOOPBACK 51*7c478bd9Sstevel@tonic-gate #define INADDR_LOOPBACK ((unsigned long) 0x7f000001) 52*7c478bd9Sstevel@tonic-gate #endif 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #ifndef MAXHOSTNAMELEN 55*7c478bd9Sstevel@tonic-gate #define MAXHOSTNAMELEN 64 56*7c478bd9Sstevel@tonic-gate #endif 57*7c478bd9Sstevel@tonic-gate 58*7c478bd9Sstevel@tonic-gate #ifdef LDAP_DEBUG 59*7c478bd9Sstevel@tonic-gate int ldap_debug; 60*7c478bd9Sstevel@tonic-gate #endif 61*7c478bd9Sstevel@tonic-gate 62*7c478bd9Sstevel@tonic-gate 63*7c478bd9Sstevel@tonic-gate /* 64*7c478bd9Sstevel@tonic-gate * global defaults for callbacks are stored here. callers of the API set 65*7c478bd9Sstevel@tonic-gate * these by passing a NULL "ld" to ldap_set_option(). Everything in 66*7c478bd9Sstevel@tonic-gate * nsldapi_ld_defaults can be overridden on a per-ld basis as well (the 67*7c478bd9Sstevel@tonic-gate * memory allocation functions are global to all ld's). 68*7c478bd9Sstevel@tonic-gate */ 69*7c478bd9Sstevel@tonic-gate struct ldap nsldapi_ld_defaults; 70*7c478bd9Sstevel@tonic-gate struct ldap_memalloc_fns nsldapi_memalloc_fns = { 0, 0, 0, 0 }; 71*7c478bd9Sstevel@tonic-gate int nsldapi_initialized = 0; 72*7c478bd9Sstevel@tonic-gate 73*7c478bd9Sstevel@tonic-gate #ifndef _WINDOWS 74*7c478bd9Sstevel@tonic-gate #include <pthread.h> 75*7c478bd9Sstevel@tonic-gate static pthread_key_t nsldapi_key; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate struct nsldapi_ldap_error { 78*7c478bd9Sstevel@tonic-gate int le_errno; 79*7c478bd9Sstevel@tonic-gate char *le_matched; 80*7c478bd9Sstevel@tonic-gate char *le_errmsg; 81*7c478bd9Sstevel@tonic-gate }; 82*7c478bd9Sstevel@tonic-gate #else 83*7c478bd9Sstevel@tonic-gate __declspec ( thread ) int nsldapi_gldaperrno; 84*7c478bd9Sstevel@tonic-gate __declspec ( thread ) char *nsldapi_gmatched = NULL; 85*7c478bd9Sstevel@tonic-gate __declspec ( thread ) char *nsldapi_gldaperror = NULL; 86*7c478bd9Sstevel@tonic-gate #endif /* _WINDOWS */ 87*7c478bd9Sstevel@tonic-gate 88*7c478bd9Sstevel@tonic-gate #ifdef _WINDOWS 89*7c478bd9Sstevel@tonic-gate #define LDAP_MUTEX_T HANDLE 90*7c478bd9Sstevel@tonic-gate 91*7c478bd9Sstevel@tonic-gate int 92*7c478bd9Sstevel@tonic-gate pthread_mutex_init( LDAP_MUTEX_T *mp, void *attr) 93*7c478bd9Sstevel@tonic-gate { 94*7c478bd9Sstevel@tonic-gate if ( (*mp = CreateMutex(NULL, FALSE, NULL)) == NULL ) 95*7c478bd9Sstevel@tonic-gate return( 1 ); 96*7c478bd9Sstevel@tonic-gate else 97*7c478bd9Sstevel@tonic-gate return( 0 ); 98*7c478bd9Sstevel@tonic-gate } 99*7c478bd9Sstevel@tonic-gate 100*7c478bd9Sstevel@tonic-gate static void * 101*7c478bd9Sstevel@tonic-gate pthread_mutex_alloc( void ) 102*7c478bd9Sstevel@tonic-gate { 103*7c478bd9Sstevel@tonic-gate LDAP_MUTEX_T *mutexp; 104*7c478bd9Sstevel@tonic-gate 105*7c478bd9Sstevel@tonic-gate if ( (mutexp = malloc( sizeof(LDAP_MUTEX_T) )) != NULL ) { 106*7c478bd9Sstevel@tonic-gate pthread_mutex_init( mutexp, NULL ); 107*7c478bd9Sstevel@tonic-gate } 108*7c478bd9Sstevel@tonic-gate return( mutexp ); 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate 111*7c478bd9Sstevel@tonic-gate int 112*7c478bd9Sstevel@tonic-gate pthread_mutex_destroy( LDAP_MUTEX_T *mp ) 113*7c478bd9Sstevel@tonic-gate { 114*7c478bd9Sstevel@tonic-gate if ( !(CloseHandle(*mp)) ) 115*7c478bd9Sstevel@tonic-gate return( 1 ); 116*7c478bd9Sstevel@tonic-gate else 117*7c478bd9Sstevel@tonic-gate return( 0 ); 118*7c478bd9Sstevel@tonic-gate } 119*7c478bd9Sstevel@tonic-gate 120*7c478bd9Sstevel@tonic-gate static void 121*7c478bd9Sstevel@tonic-gate pthread_mutex_free( void *mutexp ) 122*7c478bd9Sstevel@tonic-gate { 123*7c478bd9Sstevel@tonic-gate pthread_mutex_destroy( (LDAP_MUTEX_T *) mutexp ); 124*7c478bd9Sstevel@tonic-gate free( mutexp ); 125*7c478bd9Sstevel@tonic-gate } 126*7c478bd9Sstevel@tonic-gate 127*7c478bd9Sstevel@tonic-gate int 128*7c478bd9Sstevel@tonic-gate pthread_mutex_lock( LDAP_MUTEX_T *mp ) 129*7c478bd9Sstevel@tonic-gate { 130*7c478bd9Sstevel@tonic-gate if ( (WaitForSingleObject(*mp, INFINITE) != WAIT_OBJECT_0) ) 131*7c478bd9Sstevel@tonic-gate return( 1 ); 132*7c478bd9Sstevel@tonic-gate else 133*7c478bd9Sstevel@tonic-gate return( 0 ); 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate 136*7c478bd9Sstevel@tonic-gate int 137*7c478bd9Sstevel@tonic-gate pthread_mutex_unlock( LDAP_MUTEX_T *mp ) 138*7c478bd9Sstevel@tonic-gate { 139*7c478bd9Sstevel@tonic-gate if ( !(ReleaseMutex(*mp)) ) 140*7c478bd9Sstevel@tonic-gate return( 1 ); 141*7c478bd9Sstevel@tonic-gate else 142*7c478bd9Sstevel@tonic-gate return( 0 ); 143*7c478bd9Sstevel@tonic-gate } 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate static int 146*7c478bd9Sstevel@tonic-gate get_errno( void ) 147*7c478bd9Sstevel@tonic-gate { 148*7c478bd9Sstevel@tonic-gate return errno; 149*7c478bd9Sstevel@tonic-gate } 150*7c478bd9Sstevel@tonic-gate 151*7c478bd9Sstevel@tonic-gate static void 152*7c478bd9Sstevel@tonic-gate set_errno( int Errno ) 153*7c478bd9Sstevel@tonic-gate { 154*7c478bd9Sstevel@tonic-gate errno = Errno; 155*7c478bd9Sstevel@tonic-gate } 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate static int 158*7c478bd9Sstevel@tonic-gate get_ld_error( char **LDMatched, char **LDError, void * Args ) 159*7c478bd9Sstevel@tonic-gate { 160*7c478bd9Sstevel@tonic-gate if ( LDMatched != NULL ) 161*7c478bd9Sstevel@tonic-gate { 162*7c478bd9Sstevel@tonic-gate *LDMatched = nsldapi_gmatched; 163*7c478bd9Sstevel@tonic-gate } 164*7c478bd9Sstevel@tonic-gate if ( LDError != NULL ) 165*7c478bd9Sstevel@tonic-gate { 166*7c478bd9Sstevel@tonic-gate *LDError = nsldapi_gldaperror; 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate return nsldapi_gldaperrno; 169*7c478bd9Sstevel@tonic-gate } 170*7c478bd9Sstevel@tonic-gate 171*7c478bd9Sstevel@tonic-gate static void 172*7c478bd9Sstevel@tonic-gate set_ld_error( int LDErrno, char * LDMatched, char * LDError, 173*7c478bd9Sstevel@tonic-gate void * Args ) 174*7c478bd9Sstevel@tonic-gate { 175*7c478bd9Sstevel@tonic-gate /* Clean up any previous string storage. */ 176*7c478bd9Sstevel@tonic-gate if ( nsldapi_gmatched != NULL ) 177*7c478bd9Sstevel@tonic-gate { 178*7c478bd9Sstevel@tonic-gate ldap_memfree( nsldapi_gmatched ); 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate if ( nsldapi_gldaperror != NULL ) 181*7c478bd9Sstevel@tonic-gate { 182*7c478bd9Sstevel@tonic-gate ldap_memfree( nsldapi_gldaperror ); 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate nsldapi_gldaperrno = LDErrno; 186*7c478bd9Sstevel@tonic-gate nsldapi_gmatched = LDMatched; 187*7c478bd9Sstevel@tonic-gate nsldapi_gldaperror = LDError; 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate #else 190*7c478bd9Sstevel@tonic-gate static void * 191*7c478bd9Sstevel@tonic-gate pthread_mutex_alloc( void ) 192*7c478bd9Sstevel@tonic-gate { 193*7c478bd9Sstevel@tonic-gate pthread_mutex_t *mutexp; 194*7c478bd9Sstevel@tonic-gate 195*7c478bd9Sstevel@tonic-gate if ( (mutexp = malloc( sizeof(pthread_mutex_t) )) != NULL ) { 196*7c478bd9Sstevel@tonic-gate pthread_mutex_init( mutexp, NULL ); 197*7c478bd9Sstevel@tonic-gate } 198*7c478bd9Sstevel@tonic-gate return( mutexp ); 199*7c478bd9Sstevel@tonic-gate } 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate static void 202*7c478bd9Sstevel@tonic-gate pthread_mutex_free( void *mutexp ) 203*7c478bd9Sstevel@tonic-gate { 204*7c478bd9Sstevel@tonic-gate pthread_mutex_destroy( (pthread_mutex_t *) mutexp ); 205*7c478bd9Sstevel@tonic-gate free( mutexp ); 206*7c478bd9Sstevel@tonic-gate } 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate static void 209*7c478bd9Sstevel@tonic-gate set_ld_error( int err, char *matched, char *errmsg, void *dummy ) 210*7c478bd9Sstevel@tonic-gate { 211*7c478bd9Sstevel@tonic-gate struct nsldapi_ldap_error *le; 212*7c478bd9Sstevel@tonic-gate void *tsd; 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate le = pthread_getspecific( nsldapi_key ); 215*7c478bd9Sstevel@tonic-gate 216*7c478bd9Sstevel@tonic-gate if (le == NULL) { 217*7c478bd9Sstevel@tonic-gate tsd = (void *)calloc(1, sizeof(struct nsldapi_ldap_error)); 218*7c478bd9Sstevel@tonic-gate pthread_setspecific( nsldapi_key, tsd ); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate le = pthread_getspecific( nsldapi_key ); 222*7c478bd9Sstevel@tonic-gate 223*7c478bd9Sstevel@tonic-gate if (le == NULL) { 224*7c478bd9Sstevel@tonic-gate free(tsd); 225*7c478bd9Sstevel@tonic-gate return; 226*7c478bd9Sstevel@tonic-gate } 227*7c478bd9Sstevel@tonic-gate 228*7c478bd9Sstevel@tonic-gate le->le_errno = err; 229*7c478bd9Sstevel@tonic-gate 230*7c478bd9Sstevel@tonic-gate if ( le->le_matched != NULL ) { 231*7c478bd9Sstevel@tonic-gate ldap_memfree( le->le_matched ); 232*7c478bd9Sstevel@tonic-gate } 233*7c478bd9Sstevel@tonic-gate le->le_matched = matched; 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate if ( le->le_errmsg != NULL ) { 236*7c478bd9Sstevel@tonic-gate ldap_memfree( le->le_errmsg ); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate le->le_errmsg = errmsg; 239*7c478bd9Sstevel@tonic-gate } 240*7c478bd9Sstevel@tonic-gate 241*7c478bd9Sstevel@tonic-gate static int 242*7c478bd9Sstevel@tonic-gate get_ld_error( char **matched, char **errmsg, void *dummy ) 243*7c478bd9Sstevel@tonic-gate { 244*7c478bd9Sstevel@tonic-gate struct nsldapi_ldap_error *le; 245*7c478bd9Sstevel@tonic-gate 246*7c478bd9Sstevel@tonic-gate le = pthread_getspecific( nsldapi_key ); 247*7c478bd9Sstevel@tonic-gate if (le != NULL) { 248*7c478bd9Sstevel@tonic-gate if ( matched != NULL ) { 249*7c478bd9Sstevel@tonic-gate *matched = le->le_matched; 250*7c478bd9Sstevel@tonic-gate } 251*7c478bd9Sstevel@tonic-gate if ( errmsg != NULL ) { 252*7c478bd9Sstevel@tonic-gate *errmsg = le->le_errmsg; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate return( le->le_errno ); 255*7c478bd9Sstevel@tonic-gate } else { 256*7c478bd9Sstevel@tonic-gate if ( matched != NULL ) 257*7c478bd9Sstevel@tonic-gate *matched = NULL; 258*7c478bd9Sstevel@tonic-gate if ( errmsg != NULL ) 259*7c478bd9Sstevel@tonic-gate *errmsg = NULL; 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate return (LDAP_SUCCESS); 262*7c478bd9Sstevel@tonic-gate } 263*7c478bd9Sstevel@tonic-gate 264*7c478bd9Sstevel@tonic-gate static void 265*7c478bd9Sstevel@tonic-gate set_errno( int err ) 266*7c478bd9Sstevel@tonic-gate { 267*7c478bd9Sstevel@tonic-gate errno = err; 268*7c478bd9Sstevel@tonic-gate } 269*7c478bd9Sstevel@tonic-gate 270*7c478bd9Sstevel@tonic-gate static int 271*7c478bd9Sstevel@tonic-gate get_errno( void ) 272*7c478bd9Sstevel@tonic-gate { 273*7c478bd9Sstevel@tonic-gate return( errno ); 274*7c478bd9Sstevel@tonic-gate } 275*7c478bd9Sstevel@tonic-gate #endif /* _WINDOWS */ 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate static struct ldap_thread_fns 278*7c478bd9Sstevel@tonic-gate nsldapi_default_thread_fns = { 279*7c478bd9Sstevel@tonic-gate (void *(*)(void))pthread_mutex_alloc, 280*7c478bd9Sstevel@tonic-gate (void (*)(void *))pthread_mutex_free, 281*7c478bd9Sstevel@tonic-gate (int (*)(void *))pthread_mutex_lock, 282*7c478bd9Sstevel@tonic-gate (int (*)(void *))pthread_mutex_unlock, 283*7c478bd9Sstevel@tonic-gate (int (*)(void))get_errno, 284*7c478bd9Sstevel@tonic-gate (void (*)(int))set_errno, 285*7c478bd9Sstevel@tonic-gate (int (*)(char **, char **, void *))get_ld_error, 286*7c478bd9Sstevel@tonic-gate (void (*)(int, char *, char *, void *))set_ld_error, 287*7c478bd9Sstevel@tonic-gate 0 }; 288*7c478bd9Sstevel@tonic-gate 289*7c478bd9Sstevel@tonic-gate static struct ldap_extra_thread_fns 290*7c478bd9Sstevel@tonic-gate nsldapi_default_extra_thread_fns = { 291*7c478bd9Sstevel@tonic-gate 0, 0, 0, 0, 0, 292*7c478bd9Sstevel@tonic-gate #ifdef _WINDOWS 293*7c478bd9Sstevel@tonic-gate 0 294*7c478bd9Sstevel@tonic-gate #else 295*7c478bd9Sstevel@tonic-gate (void *(*)(void))pthread_self 296*7c478bd9Sstevel@tonic-gate #endif /* _WINDOWS */ 297*7c478bd9Sstevel@tonic-gate }; 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate void 300*7c478bd9Sstevel@tonic-gate nsldapi_initialize_defaults( void ) 301*7c478bd9Sstevel@tonic-gate { 302*7c478bd9Sstevel@tonic-gate 303*7c478bd9Sstevel@tonic-gate if ( nsldapi_initialized ) { 304*7c478bd9Sstevel@tonic-gate return; 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 307*7c478bd9Sstevel@tonic-gate /* 308*7c478bd9Sstevel@tonic-gate * This has to be called before nsldapi_initialized is set to 1 309*7c478bd9Sstevel@tonic-gate * because nsldapi_initialized does not have mutex protection 310*7c478bd9Sstevel@tonic-gate */ 311*7c478bd9Sstevel@tonic-gate prldap_nspr_init(); 312*7c478bd9Sstevel@tonic-gate #endif 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate #ifndef _WINDOWS 315*7c478bd9Sstevel@tonic-gate if ( pthread_key_create(&nsldapi_key, free ) != 0) { 316*7c478bd9Sstevel@tonic-gate perror("pthread_key_create"); 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate #endif /* _WINDOWS */ 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate nsldapi_initialized = 1; 321*7c478bd9Sstevel@tonic-gate memset( &nsldapi_memalloc_fns, 0, sizeof( nsldapi_memalloc_fns )); 322*7c478bd9Sstevel@tonic-gate memset( &nsldapi_ld_defaults, 0, sizeof( nsldapi_ld_defaults )); 323*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_options = LDAP_BITOPT_REFERRALS; 324*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_version = LDAP_VERSION2; 325*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_lberoptions = LBER_OPT_USE_DER; 326*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT; 327*7c478bd9Sstevel@tonic-gate 328*7c478bd9Sstevel@tonic-gate #ifdef LDAP_SASLIO_HOOKS 329*7c478bd9Sstevel@tonic-gate /* SASL default option settings */ 330*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_def_sasl_mech = NULL; 331*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_def_sasl_realm = NULL; 332*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_def_sasl_authcid = NULL; 333*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_def_sasl_authzid = NULL; 334*7c478bd9Sstevel@tonic-gate /* SASL Security properties */ 335*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_sasl_secprops.max_ssf = UINT_MAX; 336*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE; 337*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_sasl_secprops.security_flags = 338*7c478bd9Sstevel@tonic-gate SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS; 339*7c478bd9Sstevel@tonic-gate #endif 340*7c478bd9Sstevel@tonic-gate 341*7c478bd9Sstevel@tonic-gate #if defined( STR_TRANSLATION ) && defined( LDAP_DEFAULT_CHARSET ) 342*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_lberoptions |= LBER_OPT_TRANSLATE_STRINGS; 343*7c478bd9Sstevel@tonic-gate #if LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET 344*7c478bd9Sstevel@tonic-gate ldap_set_string_translators( &nsldapi_ld_defaults, ldap_8859_to_t61, 345*7c478bd9Sstevel@tonic-gate ldap_t61_to_8859 ); 346*7c478bd9Sstevel@tonic-gate #endif /* LDAP_CHARSET_8859 == LDAP_DEFAULT_CHARSET */ 347*7c478bd9Sstevel@tonic-gate #endif /* STR_TRANSLATION && LDAP_DEFAULT_CHARSET */ 348*7c478bd9Sstevel@tonic-gate 349*7c478bd9Sstevel@tonic-gate /* set default connect timeout (in milliseconds) */ 350*7c478bd9Sstevel@tonic-gate /* this was picked as it is the standard tcp timeout as well */ 351*7c478bd9Sstevel@tonic-gate nsldapi_ld_defaults.ld_connect_timeout = LDAP_X_IO_TIMEOUT_NO_TIMEOUT; 352*7c478bd9Sstevel@tonic-gate 353*7c478bd9Sstevel@tonic-gate /* load up default platform specific locking routines */ 354*7c478bd9Sstevel@tonic-gate if (ldap_set_option( NULL, LDAP_OPT_THREAD_FN_PTRS, 355*7c478bd9Sstevel@tonic-gate (void *)&nsldapi_default_thread_fns) != LDAP_SUCCESS) { 356*7c478bd9Sstevel@tonic-gate return; 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate #ifndef _WINDOWS 360*7c478bd9Sstevel@tonic-gate /* load up default threadid function */ 361*7c478bd9Sstevel@tonic-gate if (ldap_set_option( NULL, LDAP_OPT_EXTRA_THREAD_FN_PTRS, 362*7c478bd9Sstevel@tonic-gate (void *)&nsldapi_default_extra_thread_fns) != LDAP_SUCCESS) { 363*7c478bd9Sstevel@tonic-gate return; 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate #endif /* _WINDOWS */ 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate 369*7c478bd9Sstevel@tonic-gate /* 370*7c478bd9Sstevel@tonic-gate * ldap_version - report version levels for important properties 371*7c478bd9Sstevel@tonic-gate * This function is deprecated. Use ldap_get_option( ..., LDAP_OPT_API_INFO, 372*7c478bd9Sstevel@tonic-gate * ... ) instead. 373*7c478bd9Sstevel@tonic-gate * 374*7c478bd9Sstevel@tonic-gate * Example: 375*7c478bd9Sstevel@tonic-gate * LDAPVersion ver; 376*7c478bd9Sstevel@tonic-gate * ldap_version( &ver ); 377*7c478bd9Sstevel@tonic-gate * if ( (ver.sdk_version < 100) || (ver.SSL_version < 300) ) 378*7c478bd9Sstevel@tonic-gate * fprintf( stderr, "LDAP SDK level insufficient\n" ); 379*7c478bd9Sstevel@tonic-gate * 380*7c478bd9Sstevel@tonic-gate * or: 381*7c478bd9Sstevel@tonic-gate * if ( ldap_version(NULL) < 100 ) 382*7c478bd9Sstevel@tonic-gate * fprintf( stderr, "LDAP SDK level insufficient\n" ); 383*7c478bd9Sstevel@tonic-gate * 384*7c478bd9Sstevel@tonic-gate */ 385*7c478bd9Sstevel@tonic-gate 386*7c478bd9Sstevel@tonic-gate int 387*7c478bd9Sstevel@tonic-gate LDAP_CALL 388*7c478bd9Sstevel@tonic-gate ldap_version( LDAPVersion *ver ) 389*7c478bd9Sstevel@tonic-gate { 390*7c478bd9Sstevel@tonic-gate if ( NULL != ver ) 391*7c478bd9Sstevel@tonic-gate { 392*7c478bd9Sstevel@tonic-gate memset( ver, 0, sizeof(*ver) ); 393*7c478bd9Sstevel@tonic-gate ver->sdk_version = (int)(VI_PRODUCTVERSION * 100); 394*7c478bd9Sstevel@tonic-gate ver->protocol_version = LDAP_VERSION_MAX * 100; 395*7c478bd9Sstevel@tonic-gate ver->SSL_version = SSL_VERSION * 100; 396*7c478bd9Sstevel@tonic-gate /* 397*7c478bd9Sstevel@tonic-gate * set security to none by default 398*7c478bd9Sstevel@tonic-gate */ 399*7c478bd9Sstevel@tonic-gate 400*7c478bd9Sstevel@tonic-gate ver->security_level = LDAP_SECURITY_NONE; 401*7c478bd9Sstevel@tonic-gate #if defined(LINK_SSL) 402*7c478bd9Sstevel@tonic-gate ver->security_level = 128; 403*7c478bd9Sstevel@tonic-gate #endif 404*7c478bd9Sstevel@tonic-gate 405*7c478bd9Sstevel@tonic-gate } 406*7c478bd9Sstevel@tonic-gate return (int)(VI_PRODUCTVERSION * 100); 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate /* 410*7c478bd9Sstevel@tonic-gate * ldap_open - initialize and connect to an ldap server. A magic cookie to 411*7c478bd9Sstevel@tonic-gate * be used for future communication is returned on success, NULL on failure. 412*7c478bd9Sstevel@tonic-gate * "host" may be a space-separated list of hosts or IP addresses 413*7c478bd9Sstevel@tonic-gate * 414*7c478bd9Sstevel@tonic-gate * Example: 415*7c478bd9Sstevel@tonic-gate * LDAP *ld; 416*7c478bd9Sstevel@tonic-gate * ld = ldap_open( hostname, port ); 417*7c478bd9Sstevel@tonic-gate */ 418*7c478bd9Sstevel@tonic-gate 419*7c478bd9Sstevel@tonic-gate LDAP * 420*7c478bd9Sstevel@tonic-gate LDAP_CALL 421*7c478bd9Sstevel@tonic-gate ldap_open( const char *host, int port ) 422*7c478bd9Sstevel@tonic-gate { 423*7c478bd9Sstevel@tonic-gate LDAP *ld; 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open\n", 0, 0, 0 ); 426*7c478bd9Sstevel@tonic-gate 427*7c478bd9Sstevel@tonic-gate if (( ld = ldap_init( host, port )) == NULL ) { 428*7c478bd9Sstevel@tonic-gate return( NULL ); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate LDAP_MUTEX_LOCK( ld, LDAP_CONN_LOCK ); 432*7c478bd9Sstevel@tonic-gate if ( nsldapi_open_ldap_defconn( ld ) < 0 ) { 433*7c478bd9Sstevel@tonic-gate LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK ); 434*7c478bd9Sstevel@tonic-gate ldap_ld_free( ld, NULL, NULL, 0 ); 435*7c478bd9Sstevel@tonic-gate return( NULL ); 436*7c478bd9Sstevel@tonic-gate } 437*7c478bd9Sstevel@tonic-gate 438*7c478bd9Sstevel@tonic-gate LDAP_MUTEX_UNLOCK( ld, LDAP_CONN_LOCK ); 439*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_open successful, ld_host is %s\n", 440*7c478bd9Sstevel@tonic-gate ( ld->ld_host == NULL ) ? "(null)" : ld->ld_host, 0, 0 ); 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate return( ld ); 443*7c478bd9Sstevel@tonic-gate } 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate 446*7c478bd9Sstevel@tonic-gate /* 447*7c478bd9Sstevel@tonic-gate * ldap_init - initialize the LDAP library. A magic cookie to be used for 448*7c478bd9Sstevel@tonic-gate * future communication is returned on success, NULL on failure. 449*7c478bd9Sstevel@tonic-gate * "defhost" may be a space-separated list of hosts or IP addresses 450*7c478bd9Sstevel@tonic-gate * 451*7c478bd9Sstevel@tonic-gate * Example: 452*7c478bd9Sstevel@tonic-gate * LDAP *ld; 453*7c478bd9Sstevel@tonic-gate * ld = ldap_init( default_hostname, default_port ); 454*7c478bd9Sstevel@tonic-gate */ 455*7c478bd9Sstevel@tonic-gate LDAP * 456*7c478bd9Sstevel@tonic-gate LDAP_CALL 457*7c478bd9Sstevel@tonic-gate ldap_init( const char *defhost, int defport ) 458*7c478bd9Sstevel@tonic-gate { 459*7c478bd9Sstevel@tonic-gate LDAP *ld; 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate if ( !nsldapi_initialized ) { 462*7c478bd9Sstevel@tonic-gate nsldapi_initialize_defaults(); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate if ( defport < 0 || defport > LDAP_PORT_MAX ) { 466*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_ANY, 467*7c478bd9Sstevel@tonic-gate "ldap_init: port %d is invalid (port numbers must range from 1 to %d)\n", 468*7c478bd9Sstevel@tonic-gate defport, LDAP_PORT_MAX, 0 ); 469*7c478bd9Sstevel@tonic-gate #if !defined( macintosh ) && !defined( DOS ) 470*7c478bd9Sstevel@tonic-gate errno = EINVAL; 471*7c478bd9Sstevel@tonic-gate #endif 472*7c478bd9Sstevel@tonic-gate return( NULL ); 473*7c478bd9Sstevel@tonic-gate } 474*7c478bd9Sstevel@tonic-gate 475*7c478bd9Sstevel@tonic-gate LDAPDebug( LDAP_DEBUG_TRACE, "ldap_init\n", 0, 0, 0 ); 476*7c478bd9Sstevel@tonic-gate 477*7c478bd9Sstevel@tonic-gate if ( (ld = (LDAP*)NSLDAPI_MALLOC( sizeof(struct ldap) )) == NULL ) { 478*7c478bd9Sstevel@tonic-gate return( NULL ); 479*7c478bd9Sstevel@tonic-gate } 480*7c478bd9Sstevel@tonic-gate 481*7c478bd9Sstevel@tonic-gate /* copy defaults */ 482*7c478bd9Sstevel@tonic-gate SAFEMEMCPY( ld, &nsldapi_ld_defaults, sizeof( struct ldap )); 483*7c478bd9Sstevel@tonic-gate if ( nsldapi_ld_defaults.ld_io_fns_ptr != NULL ) { 484*7c478bd9Sstevel@tonic-gate if (( ld->ld_io_fns_ptr = (struct ldap_io_fns *)NSLDAPI_MALLOC( 485*7c478bd9Sstevel@tonic-gate sizeof( struct ldap_io_fns ))) == NULL ) { 486*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( (char *)ld ); 487*7c478bd9Sstevel@tonic-gate return( NULL ); 488*7c478bd9Sstevel@tonic-gate } 489*7c478bd9Sstevel@tonic-gate /* struct copy */ 490*7c478bd9Sstevel@tonic-gate *(ld->ld_io_fns_ptr) = *(nsldapi_ld_defaults.ld_io_fns_ptr); 491*7c478bd9Sstevel@tonic-gate } 492*7c478bd9Sstevel@tonic-gate 493*7c478bd9Sstevel@tonic-gate /* call the new handle I/O callback if one is defined */ 494*7c478bd9Sstevel@tonic-gate if ( ld->ld_extnewhandle_fn != NULL ) { 495*7c478bd9Sstevel@tonic-gate /* 496*7c478bd9Sstevel@tonic-gate * We always pass the session extended I/O argument to 497*7c478bd9Sstevel@tonic-gate * the new handle callback. 498*7c478bd9Sstevel@tonic-gate */ 499*7c478bd9Sstevel@tonic-gate if ( ld->ld_extnewhandle_fn( ld, ld->ld_ext_session_arg ) 500*7c478bd9Sstevel@tonic-gate != LDAP_SUCCESS ) { 501*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( (char*)ld ); 502*7c478bd9Sstevel@tonic-gate return( NULL ); 503*7c478bd9Sstevel@tonic-gate } 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate 506*7c478bd9Sstevel@tonic-gate /* allocate session-specific resources */ 507*7c478bd9Sstevel@tonic-gate if (( ld->ld_sbp = ber_sockbuf_alloc()) == NULL || 508*7c478bd9Sstevel@tonic-gate ( defhost != NULL && 509*7c478bd9Sstevel@tonic-gate ( ld->ld_defhost = nsldapi_strdup( defhost )) == NULL ) || 510*7c478bd9Sstevel@tonic-gate ((ld->ld_mutex = (void **) NSLDAPI_CALLOC( LDAP_MAX_LOCK, sizeof(void *))) == NULL )) { 511*7c478bd9Sstevel@tonic-gate if ( ld->ld_sbp != NULL ) { 512*7c478bd9Sstevel@tonic-gate ber_sockbuf_free( ld->ld_sbp ); 513*7c478bd9Sstevel@tonic-gate } 514*7c478bd9Sstevel@tonic-gate if( ld->ld_mutex != NULL ) { 515*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( ld->ld_mutex ); 516*7c478bd9Sstevel@tonic-gate } 517*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( (char*)ld ); 518*7c478bd9Sstevel@tonic-gate return( NULL ); 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate 521*7c478bd9Sstevel@tonic-gate /* install Sockbuf I/O functions if set in LDAP * */ 522*7c478bd9Sstevel@tonic-gate if ( ld->ld_extread_fn != NULL || ld->ld_extwrite_fn != NULL ) { 523*7c478bd9Sstevel@tonic-gate struct lber_x_ext_io_fns lberiofns; 524*7c478bd9Sstevel@tonic-gate 525*7c478bd9Sstevel@tonic-gate memset( &lberiofns, 0, sizeof( lberiofns )); 526*7c478bd9Sstevel@tonic-gate 527*7c478bd9Sstevel@tonic-gate lberiofns.lbextiofn_size = LBER_X_EXTIO_FNS_SIZE; 528*7c478bd9Sstevel@tonic-gate lberiofns.lbextiofn_read = ld->ld_extread_fn; 529*7c478bd9Sstevel@tonic-gate lberiofns.lbextiofn_write = ld->ld_extwrite_fn; 530*7c478bd9Sstevel@tonic-gate lberiofns.lbextiofn_writev = ld->ld_extwritev_fn; 531*7c478bd9Sstevel@tonic-gate lberiofns.lbextiofn_socket_arg = NULL; 532*7c478bd9Sstevel@tonic-gate ber_sockbuf_set_option( ld->ld_sbp, LBER_SOCKBUF_OPT_EXT_IO_FNS, 533*7c478bd9Sstevel@tonic-gate (void *)&lberiofns ); 534*7c478bd9Sstevel@tonic-gate } 535*7c478bd9Sstevel@tonic-gate 536*7c478bd9Sstevel@tonic-gate #ifdef _SOLARIS_SDK 537*7c478bd9Sstevel@tonic-gate /* Install the functions for IPv6 support */ 538*7c478bd9Sstevel@tonic-gate /* code sequencing is critical from here to nsldapi_mutex_alloc_all */ 539*7c478bd9Sstevel@tonic-gate if ( prldap_install_thread_functions( ld, 1 ) != 0 || 540*7c478bd9Sstevel@tonic-gate prldap_install_io_functions( ld, 1 ) != 0 || 541*7c478bd9Sstevel@tonic-gate prldap_install_dns_functions( ld ) != 0 ) { 542*7c478bd9Sstevel@tonic-gate /* go through ld and free resources */ 543*7c478bd9Sstevel@tonic-gate ldap_unbind( ld ); 544*7c478bd9Sstevel@tonic-gate ld = NULL; 545*7c478bd9Sstevel@tonic-gate return( NULL ); 546*7c478bd9Sstevel@tonic-gate } 547*7c478bd9Sstevel@tonic-gate #else 548*7c478bd9Sstevel@tonic-gate 549*7c478bd9Sstevel@tonic-gate /* allocate mutexes */ 550*7c478bd9Sstevel@tonic-gate nsldapi_mutex_alloc_all( ld ); 551*7c478bd9Sstevel@tonic-gate #endif 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate /* set default port */ 554*7c478bd9Sstevel@tonic-gate ld->ld_defport = ( defport == 0 ) ? LDAP_PORT : defport; 555*7c478bd9Sstevel@tonic-gate 556*7c478bd9Sstevel@tonic-gate return( ld ); 557*7c478bd9Sstevel@tonic-gate } 558*7c478bd9Sstevel@tonic-gate 559*7c478bd9Sstevel@tonic-gate void 560*7c478bd9Sstevel@tonic-gate nsldapi_mutex_alloc_all( LDAP *ld ) 561*7c478bd9Sstevel@tonic-gate { 562*7c478bd9Sstevel@tonic-gate int i; 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate if ( ld != &nsldapi_ld_defaults && ld->ld_mutex != NULL ) { 565*7c478bd9Sstevel@tonic-gate for ( i = 0; i<LDAP_MAX_LOCK; i++ ) { 566*7c478bd9Sstevel@tonic-gate ld->ld_mutex[i] = LDAP_MUTEX_ALLOC( ld ); 567*7c478bd9Sstevel@tonic-gate ld->ld_mutex_threadid[i] = (void *) -1; 568*7c478bd9Sstevel@tonic-gate ld->ld_mutex_refcnt[i] = 0; 569*7c478bd9Sstevel@tonic-gate } 570*7c478bd9Sstevel@tonic-gate } 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate 573*7c478bd9Sstevel@tonic-gate 574*7c478bd9Sstevel@tonic-gate void 575*7c478bd9Sstevel@tonic-gate nsldapi_mutex_free_all( LDAP *ld ) 576*7c478bd9Sstevel@tonic-gate { 577*7c478bd9Sstevel@tonic-gate int i; 578*7c478bd9Sstevel@tonic-gate 579*7c478bd9Sstevel@tonic-gate if ( ld != &nsldapi_ld_defaults && ld->ld_mutex != NULL ) { 580*7c478bd9Sstevel@tonic-gate for ( i = 0; i<LDAP_MAX_LOCK; i++ ) { 581*7c478bd9Sstevel@tonic-gate LDAP_MUTEX_FREE( ld, ld->ld_mutex[i] ); 582*7c478bd9Sstevel@tonic-gate } 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate } 585*7c478bd9Sstevel@tonic-gate 586*7c478bd9Sstevel@tonic-gate /* returns 0 if connection opened and -1 if an error occurs */ 587*7c478bd9Sstevel@tonic-gate int 588*7c478bd9Sstevel@tonic-gate nsldapi_open_ldap_defconn( LDAP *ld ) 589*7c478bd9Sstevel@tonic-gate { 590*7c478bd9Sstevel@tonic-gate LDAPServer *srv; 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate if (( srv = (LDAPServer *)NSLDAPI_CALLOC( 1, sizeof( LDAPServer ))) == 593*7c478bd9Sstevel@tonic-gate NULL || ( ld->ld_defhost != NULL && ( srv->lsrv_host = 594*7c478bd9Sstevel@tonic-gate nsldapi_strdup( ld->ld_defhost )) == NULL )) { 595*7c478bd9Sstevel@tonic-gate LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL ); 596*7c478bd9Sstevel@tonic-gate return( -1 ); 597*7c478bd9Sstevel@tonic-gate } 598*7c478bd9Sstevel@tonic-gate srv->lsrv_port = ld->ld_defport; 599*7c478bd9Sstevel@tonic-gate 600*7c478bd9Sstevel@tonic-gate #ifdef LDAP_SSLIO_HOOKS 601*7c478bd9Sstevel@tonic-gate if (( ld->ld_options & LDAP_BITOPT_SSL ) != 0 ) { 602*7c478bd9Sstevel@tonic-gate srv->lsrv_options |= LDAP_SRV_OPT_SECURE; 603*7c478bd9Sstevel@tonic-gate } 604*7c478bd9Sstevel@tonic-gate #endif 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate if (( ld->ld_defconn = nsldapi_new_connection( ld, &srv, 1, 1, 0 )) 607*7c478bd9Sstevel@tonic-gate == NULL ) { 608*7c478bd9Sstevel@tonic-gate if ( ld->ld_defhost != NULL ) { 609*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( srv->lsrv_host ); 610*7c478bd9Sstevel@tonic-gate } 611*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( (char *)srv ); 612*7c478bd9Sstevel@tonic-gate return( -1 ); 613*7c478bd9Sstevel@tonic-gate } 614*7c478bd9Sstevel@tonic-gate ++ld->ld_defconn->lconn_refcnt; /* so it never gets closed/freed */ 615*7c478bd9Sstevel@tonic-gate 616*7c478bd9Sstevel@tonic-gate return( 0 ); 617*7c478bd9Sstevel@tonic-gate } 618*7c478bd9Sstevel@tonic-gate 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate struct ldap_x_hostlist_status { 621*7c478bd9Sstevel@tonic-gate char *lhs_hostlist; 622*7c478bd9Sstevel@tonic-gate char *lhs_nexthost; 623*7c478bd9Sstevel@tonic-gate int lhs_defport; 624*7c478bd9Sstevel@tonic-gate }; 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate /* 627*7c478bd9Sstevel@tonic-gate * Return the first host and port in hostlist (setting *hostp and *portp). 628*7c478bd9Sstevel@tonic-gate * Return value is an LDAP API error code (LDAP_SUCCESS if all goes well). 629*7c478bd9Sstevel@tonic-gate * Note that a NULL or zero-length hostlist causes the host "127.0.0.1" to 630*7c478bd9Sstevel@tonic-gate * be returned. 631*7c478bd9Sstevel@tonic-gate */ 632*7c478bd9Sstevel@tonic-gate int LDAP_CALL 633*7c478bd9Sstevel@tonic-gate ldap_x_hostlist_first( const char *hostlist, int defport, char **hostp, 634*7c478bd9Sstevel@tonic-gate int *portp, struct ldap_x_hostlist_status **statusp ) 635*7c478bd9Sstevel@tonic-gate { 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate if ( NULL == hostp || NULL == portp || NULL == statusp ) { 638*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 639*7c478bd9Sstevel@tonic-gate } 640*7c478bd9Sstevel@tonic-gate 641*7c478bd9Sstevel@tonic-gate if ( NULL == hostlist || *hostlist == '\0' ) { 642*7c478bd9Sstevel@tonic-gate *hostp = nsldapi_strdup( "127.0.0.1" ); 643*7c478bd9Sstevel@tonic-gate if ( NULL == *hostp ) { 644*7c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY ); 645*7c478bd9Sstevel@tonic-gate } 646*7c478bd9Sstevel@tonic-gate *portp = defport; 647*7c478bd9Sstevel@tonic-gate *statusp = NULL; 648*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 649*7c478bd9Sstevel@tonic-gate } 650*7c478bd9Sstevel@tonic-gate 651*7c478bd9Sstevel@tonic-gate *statusp = NSLDAPI_CALLOC( 1, sizeof( struct ldap_x_hostlist_status )); 652*7c478bd9Sstevel@tonic-gate if ( NULL == *statusp ) { 653*7c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY ); 654*7c478bd9Sstevel@tonic-gate } 655*7c478bd9Sstevel@tonic-gate (*statusp)->lhs_hostlist = nsldapi_strdup( hostlist ); 656*7c478bd9Sstevel@tonic-gate if ( NULL == (*statusp)->lhs_hostlist ) { 657*7c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY ); 658*7c478bd9Sstevel@tonic-gate } 659*7c478bd9Sstevel@tonic-gate (*statusp)->lhs_nexthost = (*statusp)->lhs_hostlist; 660*7c478bd9Sstevel@tonic-gate (*statusp)->lhs_defport = defport; 661*7c478bd9Sstevel@tonic-gate return( ldap_x_hostlist_next( hostp, portp, *statusp )); 662*7c478bd9Sstevel@tonic-gate } 663*7c478bd9Sstevel@tonic-gate 664*7c478bd9Sstevel@tonic-gate /* 665*7c478bd9Sstevel@tonic-gate * Return the next host and port in hostlist (setting *hostp and *portp). 666*7c478bd9Sstevel@tonic-gate * Return value is an LDAP API error code (LDAP_SUCCESS if all goes well). 667*7c478bd9Sstevel@tonic-gate * If no more hosts are available, LDAP_SUCCESS is returned but *hostp is set 668*7c478bd9Sstevel@tonic-gate * to NULL. 669*7c478bd9Sstevel@tonic-gate */ 670*7c478bd9Sstevel@tonic-gate int LDAP_CALL 671*7c478bd9Sstevel@tonic-gate ldap_x_hostlist_next( char **hostp, int *portp, 672*7c478bd9Sstevel@tonic-gate struct ldap_x_hostlist_status *status ) 673*7c478bd9Sstevel@tonic-gate { 674*7c478bd9Sstevel@tonic-gate char *q; 675*7c478bd9Sstevel@tonic-gate int squarebrackets = 0; 676*7c478bd9Sstevel@tonic-gate 677*7c478bd9Sstevel@tonic-gate if ( NULL == hostp || NULL == portp ) { 678*7c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 679*7c478bd9Sstevel@tonic-gate } 680*7c478bd9Sstevel@tonic-gate 681*7c478bd9Sstevel@tonic-gate if ( NULL == status || NULL == status->lhs_nexthost ) { 682*7c478bd9Sstevel@tonic-gate *hostp = NULL; 683*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 684*7c478bd9Sstevel@tonic-gate } 685*7c478bd9Sstevel@tonic-gate 686*7c478bd9Sstevel@tonic-gate /* 687*7c478bd9Sstevel@tonic-gate * skip past leading '[' if present (IPv6 addresses may be surrounded 688*7c478bd9Sstevel@tonic-gate * with square brackets, e.g., [fe80::a00:20ff:fee5:c0b4]:389 689*7c478bd9Sstevel@tonic-gate */ 690*7c478bd9Sstevel@tonic-gate if ( status->lhs_nexthost[0] == '[' ) { 691*7c478bd9Sstevel@tonic-gate ++status->lhs_nexthost; 692*7c478bd9Sstevel@tonic-gate squarebrackets = 1; 693*7c478bd9Sstevel@tonic-gate } 694*7c478bd9Sstevel@tonic-gate 695*7c478bd9Sstevel@tonic-gate /* copy host into *hostp */ 696*7c478bd9Sstevel@tonic-gate if ( NULL != ( q = strchr( status->lhs_nexthost, ' ' ))) { 697*7c478bd9Sstevel@tonic-gate size_t len = q - status->lhs_nexthost; 698*7c478bd9Sstevel@tonic-gate *hostp = NSLDAPI_MALLOC( len + 1 ); 699*7c478bd9Sstevel@tonic-gate if ( NULL == *hostp ) { 700*7c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY ); 701*7c478bd9Sstevel@tonic-gate } 702*7c478bd9Sstevel@tonic-gate strncpy( *hostp, status->lhs_nexthost, len ); 703*7c478bd9Sstevel@tonic-gate (*hostp)[len] = '\0'; 704*7c478bd9Sstevel@tonic-gate status->lhs_nexthost += ( len + 1 ); 705*7c478bd9Sstevel@tonic-gate } else { /* last host */ 706*7c478bd9Sstevel@tonic-gate *hostp = nsldapi_strdup( status->lhs_nexthost ); 707*7c478bd9Sstevel@tonic-gate if ( NULL == *hostp ) { 708*7c478bd9Sstevel@tonic-gate return( LDAP_NO_MEMORY ); 709*7c478bd9Sstevel@tonic-gate } 710*7c478bd9Sstevel@tonic-gate status->lhs_nexthost = NULL; 711*7c478bd9Sstevel@tonic-gate } 712*7c478bd9Sstevel@tonic-gate 713*7c478bd9Sstevel@tonic-gate /* 714*7c478bd9Sstevel@tonic-gate * Look for closing ']' and skip past it before looking for port. 715*7c478bd9Sstevel@tonic-gate */ 716*7c478bd9Sstevel@tonic-gate if ( squarebrackets && NULL != ( q = strchr( *hostp, ']' ))) { 717*7c478bd9Sstevel@tonic-gate *q++ = '\0'; 718*7c478bd9Sstevel@tonic-gate } else { 719*7c478bd9Sstevel@tonic-gate q = *hostp; 720*7c478bd9Sstevel@tonic-gate } 721*7c478bd9Sstevel@tonic-gate 722*7c478bd9Sstevel@tonic-gate /* determine and set port */ 723*7c478bd9Sstevel@tonic-gate if ( NULL != ( q = strchr( q, ':' ))) { 724*7c478bd9Sstevel@tonic-gate *q++ = '\0'; 725*7c478bd9Sstevel@tonic-gate *portp = atoi( q ); 726*7c478bd9Sstevel@tonic-gate } else { 727*7c478bd9Sstevel@tonic-gate *portp = status->lhs_defport; 728*7c478bd9Sstevel@tonic-gate } 729*7c478bd9Sstevel@tonic-gate 730*7c478bd9Sstevel@tonic-gate return( LDAP_SUCCESS ); 731*7c478bd9Sstevel@tonic-gate } 732*7c478bd9Sstevel@tonic-gate 733*7c478bd9Sstevel@tonic-gate 734*7c478bd9Sstevel@tonic-gate void LDAP_CALL 735*7c478bd9Sstevel@tonic-gate ldap_x_hostlist_statusfree( struct ldap_x_hostlist_status *status ) 736*7c478bd9Sstevel@tonic-gate { 737*7c478bd9Sstevel@tonic-gate if ( NULL != status ) { 738*7c478bd9Sstevel@tonic-gate if ( NULL != status->lhs_hostlist ) { 739*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( status->lhs_hostlist ); 740*7c478bd9Sstevel@tonic-gate } 741*7c478bd9Sstevel@tonic-gate NSLDAPI_FREE( status ); 742*7c478bd9Sstevel@tonic-gate } 743*7c478bd9Sstevel@tonic-gate } 744*7c478bd9Sstevel@tonic-gate 745*7c478bd9Sstevel@tonic-gate 746*7c478bd9Sstevel@tonic-gate 747*7c478bd9Sstevel@tonic-gate /* 748*7c478bd9Sstevel@tonic-gate * memory allocation functions. we include these in open.c since every 749*7c478bd9Sstevel@tonic-gate * LDAP application is likely to pull the rest of the code in this file 750*7c478bd9Sstevel@tonic-gate * in anyways. 751*7c478bd9Sstevel@tonic-gate */ 752*7c478bd9Sstevel@tonic-gate void * 753*7c478bd9Sstevel@tonic-gate ldap_x_malloc( size_t size ) 754*7c478bd9Sstevel@tonic-gate { 755*7c478bd9Sstevel@tonic-gate return( nsldapi_memalloc_fns.ldapmem_malloc == NULL ? 756*7c478bd9Sstevel@tonic-gate malloc( size ) : 757*7c478bd9Sstevel@tonic-gate nsldapi_memalloc_fns.ldapmem_malloc( size )); 758*7c478bd9Sstevel@tonic-gate } 759*7c478bd9Sstevel@tonic-gate 760*7c478bd9Sstevel@tonic-gate 761*7c478bd9Sstevel@tonic-gate void * 762*7c478bd9Sstevel@tonic-gate ldap_x_calloc( size_t nelem, size_t elsize ) 763*7c478bd9Sstevel@tonic-gate { 764*7c478bd9Sstevel@tonic-gate return( nsldapi_memalloc_fns.ldapmem_calloc == NULL ? 765*7c478bd9Sstevel@tonic-gate calloc( nelem, elsize ) : 766*7c478bd9Sstevel@tonic-gate nsldapi_memalloc_fns.ldapmem_calloc( nelem, elsize )); 767*7c478bd9Sstevel@tonic-gate } 768*7c478bd9Sstevel@tonic-gate 769*7c478bd9Sstevel@tonic-gate 770*7c478bd9Sstevel@tonic-gate void * 771*7c478bd9Sstevel@tonic-gate ldap_x_realloc( void *ptr, size_t size ) 772*7c478bd9Sstevel@tonic-gate { 773*7c478bd9Sstevel@tonic-gate return( nsldapi_memalloc_fns.ldapmem_realloc == NULL ? 774*7c478bd9Sstevel@tonic-gate realloc( ptr, size ) : 775*7c478bd9Sstevel@tonic-gate nsldapi_memalloc_fns.ldapmem_realloc( ptr, size )); 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate 779*7c478bd9Sstevel@tonic-gate void 780*7c478bd9Sstevel@tonic-gate ldap_x_free( void *ptr ) 781*7c478bd9Sstevel@tonic-gate { 782*7c478bd9Sstevel@tonic-gate if ( nsldapi_memalloc_fns.ldapmem_free == NULL ) { 783*7c478bd9Sstevel@tonic-gate free( ptr ); 784*7c478bd9Sstevel@tonic-gate } else { 785*7c478bd9Sstevel@tonic-gate nsldapi_memalloc_fns.ldapmem_free( ptr ); 786*7c478bd9Sstevel@tonic-gate } 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate 790*7c478bd9Sstevel@tonic-gate /* if s is NULL, returns NULL */ 791*7c478bd9Sstevel@tonic-gate char * 792*7c478bd9Sstevel@tonic-gate nsldapi_strdup( const char *s ) 793*7c478bd9Sstevel@tonic-gate { 794*7c478bd9Sstevel@tonic-gate char *p; 795*7c478bd9Sstevel@tonic-gate 796*7c478bd9Sstevel@tonic-gate if ( s == NULL || 797*7c478bd9Sstevel@tonic-gate (p = (char *)NSLDAPI_MALLOC( strlen( s ) + 1 )) == NULL ) 798*7c478bd9Sstevel@tonic-gate return( NULL ); 799*7c478bd9Sstevel@tonic-gate 800*7c478bd9Sstevel@tonic-gate strcpy( p, s ); 801*7c478bd9Sstevel@tonic-gate 802*7c478bd9Sstevel@tonic-gate return( p ); 803*7c478bd9Sstevel@tonic-gate } 804