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