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