1 /* $NetBSD: init.c,v 1.3 2021/08/14 16:14:56 christos Exp $ */
2
3 /* $OpenLDAP$ */
4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1998-2021 The OpenLDAP Foundation.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17
18 #include <sys/cdefs.h>
19 __RCSID("$NetBSD: init.c,v 1.3 2021/08/14 16:14:56 christos Exp $");
20
21 #include "portable.h"
22
23 #include <stdio.h>
24 #include <ac/stdlib.h>
25
26 #ifdef HAVE_GETEUID
27 #include <ac/unistd.h>
28 #endif
29
30 #include <ac/socket.h>
31 #include <ac/string.h>
32 #include <ac/ctype.h>
33 #include <ac/time.h>
34
35 #ifdef HAVE_LIMITS_H
36 #include <limits.h>
37 #endif
38
39 #include "ldap-int.h"
40 #include "ldap_defaults.h"
41 #include "lutil.h"
42
43 struct ldapoptions ldap_int_global_options =
44 { LDAP_UNINITIALIZED, LDAP_DEBUG_NONE
45 LDAP_LDO_NULLARG
46 LDAP_LDO_SOURCEIP_NULLARG
47 LDAP_LDO_CONNECTIONLESS_NULLARG
48 LDAP_LDO_TLS_NULLARG
49 LDAP_LDO_SASL_NULLARG
50 LDAP_LDO_GSSAPI_NULLARG
51 LDAP_LDO_MUTEX_NULLARG };
52
53 #define ATTR_NONE 0
54 #define ATTR_BOOL 1
55 #define ATTR_INT 2
56 #define ATTR_KV 3
57 #define ATTR_STRING 4
58 #define ATTR_OPTION 5
59
60 #define ATTR_SASL 6
61 #define ATTR_TLS 7
62
63 #define ATTR_OPT_TV 8
64 #define ATTR_OPT_INT 9
65
66 #define ATTR_GSSAPI 10
67
68 struct ol_keyvalue {
69 const char * key;
70 int value;
71 };
72
73 static const struct ol_keyvalue deref_kv[] = {
74 {"never", LDAP_DEREF_NEVER},
75 {"searching", LDAP_DEREF_SEARCHING},
76 {"finding", LDAP_DEREF_FINDING},
77 {"always", LDAP_DEREF_ALWAYS},
78 {NULL, 0}
79 };
80
81 static const struct ol_attribute {
82 int useronly;
83 int type;
84 const char * name;
85 const void * data;
86 size_t offset;
87 } attrs[] = {
88 {0, ATTR_OPT_TV, "TIMEOUT", NULL, LDAP_OPT_TIMEOUT},
89 {0, ATTR_OPT_TV, "NETWORK_TIMEOUT", NULL, LDAP_OPT_NETWORK_TIMEOUT},
90 {0, ATTR_OPT_INT, "VERSION", NULL, LDAP_OPT_PROTOCOL_VERSION},
91 {0, ATTR_KV, "DEREF", deref_kv, /* or &deref_kv[0] */
92 offsetof(struct ldapoptions, ldo_deref)},
93 {0, ATTR_INT, "SIZELIMIT", NULL,
94 offsetof(struct ldapoptions, ldo_sizelimit)},
95 {0, ATTR_INT, "TIMELIMIT", NULL,
96 offsetof(struct ldapoptions, ldo_timelimit)},
97 {1, ATTR_STRING, "BINDDN", NULL,
98 offsetof(struct ldapoptions, ldo_defbinddn)},
99 {0, ATTR_STRING, "BASE", NULL,
100 offsetof(struct ldapoptions, ldo_defbase)},
101 {0, ATTR_INT, "PORT", NULL, /* deprecated */
102 offsetof(struct ldapoptions, ldo_defport)},
103 {0, ATTR_OPTION, "HOST", NULL, LDAP_OPT_HOST_NAME}, /* deprecated */
104 {0, ATTR_OPTION, "URI", NULL, LDAP_OPT_URI}, /* replaces HOST/PORT */
105 {0, ATTR_OPTION, "SOCKET_BIND_ADDRESSES", NULL, LDAP_OPT_SOCKET_BIND_ADDRESSES},
106 {0, ATTR_BOOL, "REFERRALS", NULL, LDAP_BOOL_REFERRALS},
107 {0, ATTR_INT, "KEEPALIVE_IDLE", NULL, LDAP_OPT_X_KEEPALIVE_IDLE},
108 {0, ATTR_INT, "KEEPALIVE_PROBES", NULL, LDAP_OPT_X_KEEPALIVE_PROBES},
109 {0, ATTR_INT, "KEEPALIVE_INTERVAL", NULL, LDAP_OPT_X_KEEPALIVE_INTERVAL},
110
111 #if 0
112 /* This should only be allowed via ldap_set_option(3) */
113 {0, ATTR_BOOL, "RESTART", NULL, LDAP_BOOL_RESTART},
114 #endif
115
116 #ifdef HAVE_CYRUS_SASL
117 {0, ATTR_STRING, "SASL_MECH", NULL,
118 offsetof(struct ldapoptions, ldo_def_sasl_mech)},
119 {0, ATTR_STRING, "SASL_REALM", NULL,
120 offsetof(struct ldapoptions, ldo_def_sasl_realm)},
121 {1, ATTR_STRING, "SASL_AUTHCID", NULL,
122 offsetof(struct ldapoptions, ldo_def_sasl_authcid)},
123 {1, ATTR_STRING, "SASL_AUTHZID", NULL,
124 offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
125 {0, ATTR_SASL, "SASL_SECPROPS", NULL, LDAP_OPT_X_SASL_SECPROPS},
126 {0, ATTR_BOOL, "SASL_NOCANON", NULL, LDAP_BOOL_SASL_NOCANON},
127 {0, ATTR_SASL, "SASL_CBINDING", NULL, LDAP_OPT_X_SASL_CBINDING},
128 #endif
129
130 #ifdef HAVE_GSSAPI
131 {0, ATTR_GSSAPI,"GSSAPI_SIGN", NULL, LDAP_OPT_SIGN},
132 {0, ATTR_GSSAPI,"GSSAPI_ENCRYPT", NULL, LDAP_OPT_ENCRYPT},
133 {0, ATTR_GSSAPI,"GSSAPI_ALLOW_REMOTE_PRINCIPAL",NULL, LDAP_OPT_X_GSSAPI_ALLOW_REMOTE_PRINCIPAL},
134 #endif
135
136 #ifdef HAVE_TLS
137 {1, ATTR_TLS, "TLS_CERT", NULL, LDAP_OPT_X_TLS_CERTFILE},
138 {1, ATTR_TLS, "TLS_KEY", NULL, LDAP_OPT_X_TLS_KEYFILE},
139 {0, ATTR_TLS, "TLS_CACERT", NULL, LDAP_OPT_X_TLS_CACERTFILE},
140 {0, ATTR_TLS, "TLS_CACERTDIR", NULL, LDAP_OPT_X_TLS_CACERTDIR},
141 {0, ATTR_TLS, "TLS_REQCERT", NULL, LDAP_OPT_X_TLS_REQUIRE_CERT},
142 {0, ATTR_TLS, "TLS_REQSAN", NULL, LDAP_OPT_X_TLS_REQUIRE_SAN},
143 {0, ATTR_TLS, "TLS_RANDFILE", NULL, LDAP_OPT_X_TLS_RANDOM_FILE},
144 {0, ATTR_TLS, "TLS_CIPHER_SUITE", NULL, LDAP_OPT_X_TLS_CIPHER_SUITE},
145 {0, ATTR_TLS, "TLS_PROTOCOL_MIN", NULL, LDAP_OPT_X_TLS_PROTOCOL_MIN},
146 {0, ATTR_TLS, "TLS_PROTOCOL_MAX", NULL, LDAP_OPT_X_TLS_PROTOCOL_MAX},
147 {0, ATTR_TLS, "TLS_PEERKEY_HASH", NULL, LDAP_OPT_X_TLS_PEERKEY_HASH},
148 {0, ATTR_TLS, "TLS_ECNAME", NULL, LDAP_OPT_X_TLS_ECNAME},
149
150 #ifdef HAVE_OPENSSL
151 {0, ATTR_TLS, "TLS_CRLCHECK", NULL, LDAP_OPT_X_TLS_CRLCHECK},
152 #endif
153 #ifdef HAVE_GNUTLS
154 {0, ATTR_TLS, "TLS_CRLFILE", NULL, LDAP_OPT_X_TLS_CRLFILE},
155 #endif
156
157 #endif
158
159 {0, ATTR_NONE, NULL, NULL, 0}
160 };
161
162 #ifdef HAVE_GSSAPI
163 #define MAX_LDAP_ATTR_LEN sizeof("GSSAPI_ALLOW_REMOTE_PRINCIPAL")
164 #else
165 #define MAX_LDAP_ATTR_LEN sizeof("SOCKET_BIND_ADDRESSES")
166 #endif
167 #define MAX_LDAP_ENV_PREFIX_LEN 8
168
169 static int
ldap_int_conf_option(struct ldapoptions * gopts,char * cmd,char * opt,int userconf)170 ldap_int_conf_option(
171 struct ldapoptions *gopts,
172 char *cmd, char *opt, int userconf )
173 {
174 int i;
175
176 for(i=0; attrs[i].type != ATTR_NONE; i++) {
177 void *p;
178
179 if( !userconf && attrs[i].useronly ) {
180 continue;
181 }
182
183 if(strcasecmp(cmd, attrs[i].name) != 0) {
184 continue;
185 }
186
187 switch(attrs[i].type) {
188 case ATTR_BOOL:
189 if((strcasecmp(opt, "on") == 0)
190 || (strcasecmp(opt, "yes") == 0)
191 || (strcasecmp(opt, "true") == 0))
192 {
193 LDAP_BOOL_SET(gopts, attrs[i].offset);
194
195 } else {
196 LDAP_BOOL_CLR(gopts, attrs[i].offset);
197 }
198
199 break;
200
201 case ATTR_INT: {
202 char *next;
203 long l;
204 p = &((char *) gopts)[attrs[i].offset];
205 l = strtol( opt, &next, 10 );
206 if ( next != opt && next[ 0 ] == '\0' ) {
207 * (int*) p = l;
208 }
209 } break;
210
211 case ATTR_KV: {
212 const struct ol_keyvalue *kv;
213
214 for(kv = attrs[i].data;
215 kv->key != NULL;
216 kv++) {
217
218 if(strcasecmp(opt, kv->key) == 0) {
219 p = &((char *) gopts)[attrs[i].offset];
220 * (int*) p = kv->value;
221 break;
222 }
223 }
224 } break;
225
226 case ATTR_STRING:
227 p = &((char *) gopts)[attrs[i].offset];
228 if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
229 * (char**) p = LDAP_STRDUP(opt);
230 break;
231 case ATTR_OPTION:
232 ldap_set_option( NULL, attrs[i].offset, opt );
233 break;
234 case ATTR_SASL:
235 #ifdef HAVE_CYRUS_SASL
236 ldap_int_sasl_config( gopts, attrs[i].offset, opt );
237 #endif
238 break;
239 case ATTR_GSSAPI:
240 #ifdef HAVE_GSSAPI
241 ldap_int_gssapi_config( gopts, attrs[i].offset, opt );
242 #endif
243 break;
244 case ATTR_TLS:
245 #ifdef HAVE_TLS
246 ldap_pvt_tls_config( NULL, attrs[i].offset, opt );
247 #endif
248 break;
249 case ATTR_OPT_TV: {
250 struct timeval tv;
251 char *next;
252 tv.tv_usec = 0;
253 tv.tv_sec = strtol( opt, &next, 10 );
254 if ( next != opt && next[ 0 ] == '\0' && tv.tv_sec > 0 ) {
255 (void)ldap_set_option( NULL, attrs[i].offset, (const void *)&tv );
256 }
257 } break;
258 case ATTR_OPT_INT: {
259 long l;
260 char *next;
261 l = strtol( opt, &next, 10 );
262 if ( next != opt && next[ 0 ] == '\0' && l > 0 && (long)((int)l) == l ) {
263 int v = (int)l;
264 (void)ldap_set_option( NULL, attrs[i].offset, (const void *)&v );
265 }
266 } break;
267 }
268
269 break;
270 }
271
272 if ( attrs[i].type == ATTR_NONE ) {
273 Debug1( LDAP_DEBUG_TRACE, "ldap_pvt_tls_config: "
274 "unknown option '%s'",
275 cmd );
276 return 1;
277 }
278
279 return 0;
280 }
281
282 int
ldap_pvt_conf_option(char * cmd,char * opt,int userconf)283 ldap_pvt_conf_option(
284 char *cmd, char *opt, int userconf )
285 {
286 struct ldapoptions *gopts;
287 int rc = LDAP_OPT_ERROR;
288
289 /* Get pointer to global option structure */
290 gopts = LDAP_INT_GLOBAL_OPT();
291 if (NULL == gopts) {
292 return LDAP_NO_MEMORY;
293 }
294
295 if ( gopts->ldo_valid != LDAP_INITIALIZED ) {
296 ldap_int_initialize(gopts, NULL);
297 if ( gopts->ldo_valid != LDAP_INITIALIZED )
298 return LDAP_LOCAL_ERROR;
299 }
300
301 return ldap_int_conf_option( gopts, cmd, opt, userconf );
302 }
303
openldap_ldap_init_w_conf(const char * file,int userconf)304 static void openldap_ldap_init_w_conf(
305 const char *file, int userconf )
306 {
307 char linebuf[ AC_LINE_MAX ];
308 FILE *fp;
309 int i;
310 char *cmd, *opt;
311 char *start, *end;
312 struct ldapoptions *gopts;
313
314 if ((gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
315 return; /* Could not allocate mem for global options */
316 }
317
318 if (file == NULL) {
319 /* no file name */
320 return;
321 }
322
323 Debug1(LDAP_DEBUG_TRACE, "ldap_init: trying %s\n", file );
324
325 fp = fopen(file, "r");
326 if(fp == NULL) {
327 /* could not open file */
328 return;
329 }
330
331 Debug1(LDAP_DEBUG_TRACE, "ldap_init: using %s\n", file );
332
333 while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
334 /* skip lines starting with '#' */
335 if(*start == '#') continue;
336
337 /* trim leading white space */
338 while((*start != '\0') && isspace((unsigned char) *start))
339 start++;
340
341 /* anything left? */
342 if(*start == '\0') continue;
343
344 /* trim trailing white space */
345 end = &start[strlen(start)-1];
346 while(isspace((unsigned char)*end)) end--;
347 end[1] = '\0';
348
349 /* anything left? */
350 if(*start == '\0') continue;
351
352
353 /* parse the command */
354 cmd=start;
355 while((*start != '\0') && !isspace((unsigned char)*start)) {
356 start++;
357 }
358 if(*start == '\0') {
359 /* command has no argument */
360 continue;
361 }
362
363 *start++ = '\0';
364
365 /* we must have some whitespace to skip */
366 while(isspace((unsigned char)*start)) start++;
367 opt = start;
368
369 ldap_int_conf_option( gopts, cmd, opt, userconf );
370 }
371
372 fclose(fp);
373 }
374
openldap_ldap_init_w_sysconf(const char * file)375 static void openldap_ldap_init_w_sysconf(const char *file)
376 {
377 openldap_ldap_init_w_conf( file, 0 );
378 }
379
openldap_ldap_init_w_userconf(const char * file)380 static void openldap_ldap_init_w_userconf(const char *file)
381 {
382 char *home;
383 char *path = NULL;
384
385 if (file == NULL) {
386 /* no file name */
387 return;
388 }
389
390 home = getenv("HOME");
391
392 if (home != NULL) {
393 Debug1(LDAP_DEBUG_TRACE, "ldap_init: HOME env is %s\n",
394 home );
395 path = LDAP_MALLOC(strlen(home) + strlen(file) + sizeof( LDAP_DIRSEP "."));
396 } else {
397 Debug0(LDAP_DEBUG_TRACE, "ldap_init: HOME env is NULL\n" );
398 }
399
400 if(home != NULL && path != NULL) {
401 /* we assume UNIX path syntax is used... */
402
403 /* try ~/file */
404 sprintf(path, "%s" LDAP_DIRSEP "%s", home, file);
405 openldap_ldap_init_w_conf(path, 1);
406
407 /* try ~/.file */
408 sprintf(path, "%s" LDAP_DIRSEP ".%s", home, file);
409 openldap_ldap_init_w_conf(path, 1);
410 }
411
412 if(path != NULL) {
413 LDAP_FREE(path);
414 }
415
416 /* try file */
417 openldap_ldap_init_w_conf(file, 1);
418 }
419
openldap_ldap_init_w_env(struct ldapoptions * gopts,const char * prefix)420 static void openldap_ldap_init_w_env(
421 struct ldapoptions *gopts,
422 const char *prefix)
423 {
424 char buf[MAX_LDAP_ATTR_LEN+MAX_LDAP_ENV_PREFIX_LEN];
425 int len;
426 int i;
427 void *p;
428 char *value;
429
430 if (prefix == NULL) {
431 prefix = LDAP_ENV_PREFIX;
432 }
433
434 strncpy(buf, prefix, MAX_LDAP_ENV_PREFIX_LEN);
435 buf[MAX_LDAP_ENV_PREFIX_LEN] = '\0';
436 len = strlen(buf);
437
438 for(i=0; attrs[i].type != ATTR_NONE; i++) {
439 strcpy(&buf[len], attrs[i].name);
440 value = getenv(buf);
441
442 if(value == NULL) {
443 continue;
444 }
445
446 switch(attrs[i].type) {
447 case ATTR_BOOL:
448 if((strcasecmp(value, "on") == 0)
449 || (strcasecmp(value, "yes") == 0)
450 || (strcasecmp(value, "true") == 0))
451 {
452 LDAP_BOOL_SET(gopts, attrs[i].offset);
453
454 } else {
455 LDAP_BOOL_CLR(gopts, attrs[i].offset);
456 }
457 break;
458
459 case ATTR_INT:
460 p = &((char *) gopts)[attrs[i].offset];
461 * (int*) p = atoi(value);
462 break;
463
464 case ATTR_KV: {
465 const struct ol_keyvalue *kv;
466
467 for(kv = attrs[i].data;
468 kv->key != NULL;
469 kv++) {
470
471 if(strcasecmp(value, kv->key) == 0) {
472 p = &((char *) gopts)[attrs[i].offset];
473 * (int*) p = kv->value;
474 break;
475 }
476 }
477 } break;
478
479 case ATTR_STRING:
480 p = &((char *) gopts)[attrs[i].offset];
481 if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
482 if (*value == '\0') {
483 * (char**) p = NULL;
484 } else {
485 * (char**) p = LDAP_STRDUP(value);
486 }
487 break;
488 case ATTR_OPTION:
489 ldap_set_option( NULL, attrs[i].offset, value );
490 break;
491 case ATTR_SASL:
492 #ifdef HAVE_CYRUS_SASL
493 ldap_int_sasl_config( gopts, attrs[i].offset, value );
494 #endif
495 break;
496 case ATTR_GSSAPI:
497 #ifdef HAVE_GSSAPI
498 ldap_int_gssapi_config( gopts, attrs[i].offset, value );
499 #endif
500 break;
501 case ATTR_TLS:
502 #ifdef HAVE_TLS
503 ldap_pvt_tls_config( NULL, attrs[i].offset, value );
504 #endif
505 break;
506 case ATTR_OPT_TV: {
507 struct timeval tv;
508 char *next;
509 tv.tv_usec = 0;
510 tv.tv_sec = strtol( value, &next, 10 );
511 if ( next != value && next[ 0 ] == '\0' && tv.tv_sec > 0 ) {
512 (void)ldap_set_option( NULL, attrs[i].offset, (const void *)&tv );
513 }
514 } break;
515 case ATTR_OPT_INT: {
516 long l;
517 char *next;
518 l = strtol( value, &next, 10 );
519 if ( next != value && next[ 0 ] == '\0' && l > 0 && (long)((int)l) == l ) {
520 int v = (int)l;
521 (void)ldap_set_option( NULL, attrs[i].offset, (const void *)&v );
522 }
523 } break;
524 }
525 }
526 }
527
528 #if defined(__GNUC__)
529 /* Declare this function as a destructor so that it will automatically be
530 * invoked either at program exit (if libldap is a static library) or
531 * at unload time (if libldap is a dynamic library).
532 *
533 * Sorry, don't know how to handle this for non-GCC environments.
534 */
535 static void ldap_int_destroy_global_options(void)
536 __attribute__ ((destructor));
537 #endif
538
539 static void
ldap_int_destroy_global_options(void)540 ldap_int_destroy_global_options(void)
541 {
542 struct ldapoptions *gopts = LDAP_INT_GLOBAL_OPT();
543
544 if ( gopts == NULL )
545 return;
546
547 gopts->ldo_valid = LDAP_UNINITIALIZED;
548
549 if ( gopts->ldo_defludp ) {
550 ldap_free_urllist( gopts->ldo_defludp );
551 gopts->ldo_defludp = NULL;
552 }
553
554 if ( gopts->ldo_local_ip_addrs.local_ip_addrs ) {
555 LDAP_FREE( gopts->ldo_local_ip_addrs.local_ip_addrs );
556 gopts->ldo_local_ip_addrs.local_ip_addrs = NULL;
557 }
558
559 #if defined(HAVE_WINSOCK) || defined(HAVE_WINSOCK2)
560 WSACleanup( );
561 #endif
562
563 #if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
564 if ( ldap_int_hostname ) {
565 LDAP_FREE( ldap_int_hostname );
566 ldap_int_hostname = NULL;
567 }
568 #endif
569 #ifdef HAVE_CYRUS_SASL
570 if ( gopts->ldo_def_sasl_authcid ) {
571 LDAP_FREE( gopts->ldo_def_sasl_authcid );
572 gopts->ldo_def_sasl_authcid = NULL;
573 }
574 #endif
575 #ifdef HAVE_TLS
576 ldap_int_tls_destroy( gopts );
577 #endif
578 }
579
580 /*
581 * Initialize the global options structure with default values.
582 */
ldap_int_initialize_global_options(struct ldapoptions * gopts,int * dbglvl)583 void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl )
584 {
585 if (dbglvl)
586 gopts->ldo_debug = *dbglvl;
587 else
588 gopts->ldo_debug = 0;
589
590 gopts->ldo_version = LDAP_VERSION2;
591 gopts->ldo_deref = LDAP_DEREF_NEVER;
592 gopts->ldo_timelimit = LDAP_NO_LIMIT;
593 gopts->ldo_sizelimit = LDAP_NO_LIMIT;
594
595 gopts->ldo_tm_api.tv_sec = -1;
596 gopts->ldo_tm_net.tv_sec = -1;
597
598 memset( &gopts->ldo_local_ip_addrs, 0,
599 sizeof( gopts->ldo_local_ip_addrs ) );
600
601 /* ldo_defludp will be freed by the termination handler
602 */
603 ldap_url_parselist(&gopts->ldo_defludp, "ldap://localhost/");
604 gopts->ldo_defport = LDAP_PORT;
605 #if !defined(__GNUC__) && !defined(PIC)
606 /* Do this only for a static library, and only if we can't
607 * arrange for it to be executed as a library destructor
608 */
609 atexit(ldap_int_destroy_global_options);
610 #endif
611
612 gopts->ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
613 gopts->ldo_rebind_proc = NULL;
614 gopts->ldo_rebind_params = NULL;
615
616 LDAP_BOOL_ZERO(gopts);
617
618 LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
619
620 #ifdef LDAP_CONNECTIONLESS
621 gopts->ldo_peer = NULL;
622 gopts->ldo_cldapdn = NULL;
623 gopts->ldo_is_udp = 0;
624 #endif
625
626 #ifdef HAVE_CYRUS_SASL
627 gopts->ldo_def_sasl_mech = NULL;
628 gopts->ldo_def_sasl_realm = NULL;
629 gopts->ldo_def_sasl_authcid = NULL;
630 gopts->ldo_def_sasl_authzid = NULL;
631
632 memset( &gopts->ldo_sasl_secprops,
633 '\0', sizeof(gopts->ldo_sasl_secprops) );
634
635 gopts->ldo_sasl_secprops.max_ssf = INT_MAX;
636 gopts->ldo_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE;
637 gopts->ldo_sasl_secprops.security_flags =
638 SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
639 #endif
640
641 #ifdef HAVE_TLS
642 gopts->ldo_tls_connect_cb = NULL;
643 gopts->ldo_tls_connect_arg = NULL;
644 gopts->ldo_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
645 gopts->ldo_tls_require_san = LDAP_OPT_X_TLS_ALLOW;
646 #endif
647 gopts->ldo_keepalive_probes = 0;
648 gopts->ldo_keepalive_interval = 0;
649 gopts->ldo_keepalive_idle = 0;
650
651 gopts->ldo_tcp_user_timeout = 0;
652
653 #ifdef LDAP_R_COMPILE
654 ldap_pvt_thread_mutex_init( &gopts->ldo_mutex );
655 #endif
656 gopts->ldo_valid = LDAP_INITIALIZED;
657 return;
658 }
659
660 #if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
661 char * ldap_int_hostname = NULL;
662 #endif
663
664 #ifdef LDAP_R_COMPILE
665 int ldap_int_stackguard;
666 #endif
667
ldap_int_initialize(struct ldapoptions * gopts,int * dbglvl)668 void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
669 {
670 #ifdef LDAP_R_COMPILE
671 static ldap_pvt_thread_mutex_t init_mutex;
672 LDAP_PVT_MUTEX_FIRSTCREATE( init_mutex );
673
674 LDAP_MUTEX_LOCK( &init_mutex );
675 #endif
676 if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
677 /* someone else got here first */
678 goto done;
679 }
680
681 ldap_int_error_init();
682
683 ldap_int_utils_init();
684
685 #ifdef HAVE_WINSOCK2
686 { WORD wVersionRequested;
687 WSADATA wsaData;
688
689 wVersionRequested = MAKEWORD( 2, 0 );
690 if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
691 /* Tell the user that we couldn't find a usable */
692 /* WinSock DLL. */
693 goto done;
694 }
695
696 /* Confirm that the WinSock DLL supports 2.0.*/
697 /* Note that if the DLL supports versions greater */
698 /* than 2.0 in addition to 2.0, it will still return */
699 /* 2.0 in wVersion since that is the version we */
700 /* requested. */
701
702 if ( LOBYTE( wsaData.wVersion ) != 2 ||
703 HIBYTE( wsaData.wVersion ) != 0 )
704 {
705 /* Tell the user that we couldn't find a usable */
706 /* WinSock DLL. */
707 WSACleanup( );
708 goto done;
709 }
710 } /* The WinSock DLL is acceptable. Proceed. */
711 #elif defined(HAVE_WINSOCK)
712 { WSADATA wsaData;
713 if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
714 goto done;
715 }
716 }
717 #endif
718
719 #if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
720 LDAP_MUTEX_LOCK( &ldap_int_hostname_mutex );
721 {
722 char *name = ldap_int_hostname;
723
724 ldap_int_hostname = ldap_pvt_get_fqdn( name );
725
726 if ( name != NULL && name != ldap_int_hostname ) {
727 LDAP_FREE( name );
728 }
729 }
730 LDAP_MUTEX_UNLOCK( &ldap_int_hostname_mutex );
731 #endif
732
733 #ifndef HAVE_POLL
734 if ( ldap_int_tblsize == 0 ) ldap_int_ip_init();
735 #endif
736
737 #ifdef HAVE_CYRUS_SASL
738 if ( ldap_int_sasl_init() != 0 ) {
739 goto done;
740 }
741 #endif
742
743 ldap_int_initialize_global_options(gopts, dbglvl);
744
745 if( getenv("LDAPNOINIT") != NULL ) {
746 goto done;
747 }
748
749 #ifdef LDAP_R_COMPILE
750 if( getenv("LDAPSTACKGUARD") != NULL ) {
751 ldap_int_stackguard = 1;
752 }
753 #endif
754
755 #ifdef HAVE_CYRUS_SASL
756 {
757 /* set authentication identity to current user name */
758 char *user = getenv("USER");
759
760 if( user == NULL ) user = getenv("USERNAME");
761 if( user == NULL ) user = getenv("LOGNAME");
762
763 if( user != NULL ) {
764 gopts->ldo_def_sasl_authcid = LDAP_STRDUP( user );
765 }
766 }
767 #endif
768
769 openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
770
771 #ifdef HAVE_GETEUID
772 if ( geteuid() != getuid() )
773 goto done;
774 #endif
775
776 openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
777
778 {
779 char *altfile = getenv(LDAP_ENV_PREFIX "CONF");
780
781 if( altfile != NULL ) {
782 Debug2(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
783 LDAP_ENV_PREFIX "CONF", altfile );
784 openldap_ldap_init_w_sysconf( altfile );
785 }
786 else
787 Debug1(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
788 LDAP_ENV_PREFIX "CONF" );
789 }
790
791 {
792 char *altfile = getenv(LDAP_ENV_PREFIX "RC");
793
794 if( altfile != NULL ) {
795 Debug2(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
796 LDAP_ENV_PREFIX "RC", altfile );
797 openldap_ldap_init_w_userconf( altfile );
798 }
799 else
800 Debug1(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
801 LDAP_ENV_PREFIX "RC" );
802 }
803
804 openldap_ldap_init_w_env(gopts, NULL);
805
806 done:;
807 #ifdef LDAP_R_COMPILE
808 LDAP_MUTEX_UNLOCK( &init_mutex );
809 #endif
810 }
811