init.c 18 KB
Newer Older
1
/* $OpenLDAP$ */
2
3
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
4
 * Copyright 1998-2021 The OpenLDAP Foundation.
5
6
7
8
9
10
11
12
13
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
Kurt Zeilenga's avatar
Kurt Zeilenga committed
14
 */
15

16
17
18
#include "portable.h"

#include <stdio.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
19
#include <ac/stdlib.h>
20

21
22
23
24
#ifdef HAVE_GETEUID
#include <ac/unistd.h>
#endif

25
26
#include <ac/socket.h>
#include <ac/string.h>
27
#include <ac/ctype.h>
28
29
#include <ac/time.h>

Kurt Zeilenga's avatar
Kurt Zeilenga committed
30
#ifdef HAVE_LIMITS_H
31
#include <limits.h>
Kurt Zeilenga's avatar
Kurt Zeilenga committed
32
#endif
33

34
#include "ldap-int.h"
35
#include "ldap_defaults.h"
36
#include "lutil.h"
37

38
struct ldapoptions ldap_int_global_options =
39
40
41
42
43
44
	{ LDAP_UNINITIALIZED, LDAP_DEBUG_NONE
		LDAP_LDO_NULLARG
		LDAP_LDO_CONNECTIONLESS_NULLARG
		LDAP_LDO_TLS_NULLARG
		LDAP_LDO_SASL_NULLARG
		LDAP_LDO_MUTEX_NULLARG };
45

46
47
48
49
50
#define ATTR_NONE	0
#define ATTR_BOOL	1
#define ATTR_INT	2
#define ATTR_KV		3
#define ATTR_STRING	4
51
#define ATTR_OPTION	5
52
53
54

#define ATTR_SASL	6
#define ATTR_TLS	7
55

56
57
58
#define ATTR_OPT_TV	8
#define ATTR_OPT_INT	9

59
struct ol_keyvalue {
60
	const char *		key;
61
62
63
	int			value;
};

64
static const struct ol_keyvalue deref_kv[] = {
65
66
67
68
69
70
71
	{"never", LDAP_DEREF_NEVER},
	{"searching", LDAP_DEREF_SEARCHING},
	{"finding", LDAP_DEREF_FINDING},
	{"always", LDAP_DEREF_ALWAYS},
	{NULL, 0}
};

72
static const struct ol_attribute {
73
	int			useronly;
74
	int			type;
75
76
	const char *	name;
	const void *	data;
77
78
	size_t		offset;
} attrs[] = {
79
80
81
	{0, ATTR_OPT_TV,	"TIMEOUT",		NULL,	LDAP_OPT_TIMEOUT},
	{0, ATTR_OPT_TV,	"NETWORK_TIMEOUT",	NULL,	LDAP_OPT_NETWORK_TIMEOUT},
	{0, ATTR_OPT_INT,	"VERSION",		NULL,	LDAP_OPT_PROTOCOL_VERSION},
82
	{0, ATTR_KV,		"DEREF",	deref_kv, /* or &deref_kv[0] */
83
		offsetof(struct ldapoptions, ldo_deref)},
84
	{0, ATTR_INT,		"SIZELIMIT",	NULL,
85
		offsetof(struct ldapoptions, ldo_sizelimit)},
86
	{0, ATTR_INT,		"TIMELIMIT",	NULL,
87
		offsetof(struct ldapoptions, ldo_timelimit)},
88
89
	{1, ATTR_STRING,	"BINDDN",		NULL,
		offsetof(struct ldapoptions, ldo_defbinddn)},
90
	{0, ATTR_STRING,	"BASE",			NULL,
91
		offsetof(struct ldapoptions, ldo_defbase)},
92
	{0, ATTR_INT,		"PORT",			NULL,		/* deprecated */
93
		offsetof(struct ldapoptions, ldo_defport)},
94
95
	{0, ATTR_OPTION,	"HOST",			NULL,	LDAP_OPT_HOST_NAME}, /* deprecated */
	{0, ATTR_OPTION,	"URI",			NULL,	LDAP_OPT_URI}, /* replaces HOST/PORT */
96
	{0, ATTR_BOOL,		"REFERRALS",	NULL,	LDAP_BOOL_REFERRALS},
97
98
99
100
	{0, ATTR_INT,		"KEEPALIVE_IDLE",	NULL,	LDAP_OPT_X_KEEPALIVE_IDLE},
	{0, ATTR_INT,		"KEEPALIVE_PROBES",	NULL,	LDAP_OPT_X_KEEPALIVE_PROBES},
	{0, ATTR_INT,		"KEEPALIVE_INTERVAL",	NULL,	LDAP_OPT_X_KEEPALIVE_INTERVAL},

101
102
#if 0
	/* This should only be allowed via ldap_set_option(3) */
103
	{0, ATTR_BOOL,		"RESTART",		NULL,	LDAP_BOOL_RESTART},
104
#endif
105

106
#ifdef HAVE_CYRUS_SASL
107
	{0, ATTR_STRING,	"SASL_MECH",		NULL,
108
		offsetof(struct ldapoptions, ldo_def_sasl_mech)},
109
	{0, ATTR_STRING,	"SASL_REALM",		NULL,
110
111
112
113
114
115
		offsetof(struct ldapoptions, ldo_def_sasl_realm)},
	{1, ATTR_STRING,	"SASL_AUTHCID",		NULL,
		offsetof(struct ldapoptions, ldo_def_sasl_authcid)},
	{1, ATTR_STRING,	"SASL_AUTHZID",		NULL,
		offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
	{0, ATTR_SASL,		"SASL_SECPROPS",	NULL,	LDAP_OPT_X_SASL_SECPROPS},
116
	{0, ATTR_BOOL,		"SASL_NOCANON",	NULL,	LDAP_BOOL_SASL_NOCANON},
117
	{0, ATTR_SASL,		"SASL_CBINDING",	NULL,	LDAP_OPT_X_SASL_CBINDING},
118
119
#endif

120
#ifdef HAVE_TLS
121
122
123
124
125
	{1, ATTR_TLS,	"TLS_CERT",			NULL,	LDAP_OPT_X_TLS_CERTFILE},
	{1, ATTR_TLS,	"TLS_KEY",			NULL,	LDAP_OPT_X_TLS_KEYFILE},
  	{0, ATTR_TLS,	"TLS_CACERT",		NULL,	LDAP_OPT_X_TLS_CACERTFILE},
  	{0, ATTR_TLS,	"TLS_CACERTDIR",	NULL,	LDAP_OPT_X_TLS_CACERTDIR},
  	{0, ATTR_TLS,	"TLS_REQCERT",		NULL,	LDAP_OPT_X_TLS_REQUIRE_CERT},
Howard Chu's avatar
Howard Chu committed
126
	{0, ATTR_TLS,	"TLS_REQSAN",		NULL,	LDAP_OPT_X_TLS_REQUIRE_SAN},
127
128
	{0, ATTR_TLS,	"TLS_RANDFILE",		NULL,	LDAP_OPT_X_TLS_RANDOM_FILE},
	{0, ATTR_TLS,	"TLS_CIPHER_SUITE",	NULL,	LDAP_OPT_X_TLS_CIPHER_SUITE},
129
	{0, ATTR_TLS,	"TLS_PROTOCOL_MIN",	NULL,	LDAP_OPT_X_TLS_PROTOCOL_MIN},
130
	{0, ATTR_TLS,	"TLS_PEERKEY_HASH",	NULL,	LDAP_OPT_X_TLS_PEERKEY_HASH},
131
	{0, ATTR_TLS,	"TLS_ECNAME",		NULL,	LDAP_OPT_X_TLS_ECNAME},
132

133
#ifdef HAVE_OPENSSL
134
	{0, ATTR_TLS,	"TLS_CRLCHECK",		NULL,	LDAP_OPT_X_TLS_CRLCHECK},
135
#endif
136
#ifdef HAVE_GNUTLS
Howard Chu's avatar
Howard Chu committed
137
	{0, ATTR_TLS,	"TLS_CRLFILE",			NULL,	LDAP_OPT_X_TLS_CRLFILE},
138
#endif
139
        
140
141
#endif

142
	{0, ATTR_NONE,		NULL,		NULL,	0}
143
144
};

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
145
#define MAX_LDAP_ATTR_LEN  sizeof("TLS_CIPHER_SUITE")
146
147
#define MAX_LDAP_ENV_PREFIX_LEN 8

148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
static int
ldap_int_conf_option(
	struct ldapoptions *gopts,
	char *cmd, char *opt, int userconf )
{
	int i;

	for(i=0; attrs[i].type != ATTR_NONE; i++) {
		void *p;

		if( !userconf && attrs[i].useronly ) {
			continue;
		}

		if(strcasecmp(cmd, attrs[i].name) != 0) {
			continue;
		}

		switch(attrs[i].type) {
		case ATTR_BOOL:
			if((strcasecmp(opt, "on") == 0)
				|| (strcasecmp(opt, "yes") == 0)
				|| (strcasecmp(opt, "true") == 0))
			{
				LDAP_BOOL_SET(gopts, attrs[i].offset);

			} else {
				LDAP_BOOL_CLR(gopts, attrs[i].offset);
			}

			break;

		case ATTR_INT: {
			char *next;
			long l;
			p = &((char *) gopts)[attrs[i].offset];
			l = strtol( opt, &next, 10 );
			if ( next != opt && next[ 0 ] == '\0' ) {
				* (int*) p = l;
			}
			} break;

		case ATTR_KV: {
				const struct ol_keyvalue *kv;

				for(kv = attrs[i].data;
					kv->key != NULL;
					kv++) {

					if(strcasecmp(opt, kv->key) == 0) {
						p = &((char *) gopts)[attrs[i].offset];
						* (int*) p = kv->value;
						break;
					}
				}
			} break;

		case ATTR_STRING:
			p = &((char *) gopts)[attrs[i].offset];
			if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
			* (char**) p = LDAP_STRDUP(opt);
			break;
		case ATTR_OPTION:
			ldap_set_option( NULL, attrs[i].offset, opt );
			break;
		case ATTR_SASL:
#ifdef HAVE_CYRUS_SASL
			ldap_int_sasl_config( gopts, attrs[i].offset, opt );
#endif
			break;
		case ATTR_TLS:
#ifdef HAVE_TLS
			ldap_pvt_tls_config( NULL, attrs[i].offset, opt );
#endif
			break;
		case ATTR_OPT_TV: {
			struct timeval tv;
			char *next;
			tv.tv_usec = 0;
			tv.tv_sec = strtol( opt, &next, 10 );
			if ( next != opt && next[ 0 ] == '\0' && tv.tv_sec > 0 ) {
				(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&tv );
			}
			} break;
		case ATTR_OPT_INT: {
			long l;
			char *next;
			l = strtol( opt, &next, 10 );
			if ( next != opt && next[ 0 ] == '\0' && l > 0 && (long)((int)l) == l ) {
				int v = (int)l;
				(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&v );
			}
			} break;
		}

		break;
	}

	if ( attrs[i].type == ATTR_NONE ) {
247
		Debug1( LDAP_DEBUG_TRACE, "ldap_pvt_tls_config: "
248
				"unknown option '%s'",
249
				cmd );
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
		return 1;
	}

	return 0;
}

int
ldap_pvt_conf_option(
	char *cmd, char *opt, int userconf )
{
	struct ldapoptions *gopts;
	int rc = LDAP_OPT_ERROR;

	/* Get pointer to global option structure */
	gopts = LDAP_INT_GLOBAL_OPT();
	if (NULL == gopts) {
		return LDAP_NO_MEMORY;
	}

	if ( gopts->ldo_valid != LDAP_INITIALIZED ) {
		ldap_int_initialize(gopts, NULL);
		if ( gopts->ldo_valid != LDAP_INITIALIZED )
			return LDAP_LOCAL_ERROR;
	}

	return ldap_int_conf_option( gopts, cmd, opt, userconf );
}

278
279
static void openldap_ldap_init_w_conf(
	const char *file, int userconf )
280
{
Pierangelo Masarati's avatar
Pierangelo Masarati committed
281
	char linebuf[ AC_LINE_MAX ];
282
283
284
285
	FILE *fp;
	int i;
	char *cmd, *opt;
	char *start, *end;
286
287
288
289
290
	struct ldapoptions *gopts;

	if ((gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
		return;			/* Could not allocate mem for global options */
	}
291

292
293
294
295
296
	if (file == NULL) {
		/* no file name */
		return;
	}

297
	Debug1(LDAP_DEBUG_TRACE, "ldap_init: trying %s\n", file );
298

299
300
301
302
303
304
	fp = fopen(file, "r");
	if(fp == NULL) {
		/* could not open file */
		return;
	}

305
	Debug1(LDAP_DEBUG_TRACE, "ldap_init: using %s\n", file );
306

307
308
309
310
311
	while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
		/* skip lines starting with '#' */
		if(*start == '#') continue;

		/* trim leading white space */
312
313
		while((*start != '\0') && isspace((unsigned char) *start))
			start++;
314
315
316
317
318
319

		/* anything left? */
		if(*start == '\0') continue;

		/* trim trailing white space */
		end = &start[strlen(start)-1];
320
		while(isspace((unsigned char)*end)) end--;
321
322
323
324
325
326
327
328
		end[1] = '\0';

		/* anything left? */
		if(*start == '\0') continue;
		

		/* parse the command */
		cmd=start;
329
		while((*start != '\0') && !isspace((unsigned char)*start)) {
330
331
332
333
334
335
336
337
338
			start++;
		}
		if(*start == '\0') {
			/* command has no argument */
			continue;
		} 

		*start++ = '\0';

339
		/* we must have some whitespace to skip */
340
		while(isspace((unsigned char)*start)) start++;
341
342
		opt = start;

343
		ldap_int_conf_option( gopts, cmd, opt, userconf );
344
	}
345
346

	fclose(fp);
347
348
}

349
350
351
352
353
static void openldap_ldap_init_w_sysconf(const char *file)
{
	openldap_ldap_init_w_conf( file, 0 );
}

354
355
static void openldap_ldap_init_w_userconf(const char *file)
{
356
	char *home;
357
	char *path = NULL;
358
359
360
361
362
363
364
365

	if (file == NULL) {
		/* no file name */
		return;
	}

	home = getenv("HOME");

Kurt Zeilenga's avatar
Kurt Zeilenga committed
366
	if (home != NULL) {
367
368
		Debug1(LDAP_DEBUG_TRACE, "ldap_init: HOME env is %s\n",
		      home );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
369
		path = LDAP_MALLOC(strlen(home) + strlen(file) + sizeof( LDAP_DIRSEP "."));
Kurt Zeilenga's avatar
Kurt Zeilenga committed
370
	} else {
371
		Debug0(LDAP_DEBUG_TRACE, "ldap_init: HOME env is NULL\n" );
Kurt Zeilenga's avatar
Kurt Zeilenga committed
372
373
374
	}

	if(home != NULL && path != NULL) {
375
376
		/* we assume UNIX path syntax is used... */

Kurt Zeilenga's avatar
Kurt Zeilenga committed
377
		/* try ~/file */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
378
		sprintf(path, "%s" LDAP_DIRSEP "%s", home, file);
379
		openldap_ldap_init_w_conf(path, 1);
380

Kurt Zeilenga's avatar
Kurt Zeilenga committed
381
		/* try ~/.file */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
382
		sprintf(path, "%s" LDAP_DIRSEP ".%s", home, file);
383
		openldap_ldap_init_w_conf(path, 1);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
384
	}
385
386

	if(path != NULL) {
387
		LDAP_FREE(path);
388
	}
389
390

	/* try file */
391
	openldap_ldap_init_w_conf(file, 1);
392
393
}

394
395
396
static void openldap_ldap_init_w_env(
		struct ldapoptions *gopts,
		const char *prefix)
397
398
399
400
401
402
403
404
{
	char buf[MAX_LDAP_ATTR_LEN+MAX_LDAP_ENV_PREFIX_LEN];
	int len;
	int i;
	void *p;
	char *value;

	if (prefix == NULL) {
405
		prefix = LDAP_ENV_PREFIX;
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
	}

	strncpy(buf, prefix, MAX_LDAP_ENV_PREFIX_LEN);
	buf[MAX_LDAP_ENV_PREFIX_LEN] = '\0';
	len = strlen(buf);

	for(i=0; attrs[i].type != ATTR_NONE; i++) {
		strcpy(&buf[len], attrs[i].name);
		value = getenv(buf);

		if(value == NULL) {
			continue;
		}

		switch(attrs[i].type) {
		case ATTR_BOOL:
			if((strcasecmp(value, "on") == 0) 
				|| (strcasecmp(value, "yes") == 0)
				|| (strcasecmp(value, "true") == 0))
			{
426
				LDAP_BOOL_SET(gopts, attrs[i].offset);
427
428

			} else {
429
				LDAP_BOOL_CLR(gopts, attrs[i].offset);
430
431
432
433
			}
			break;

		case ATTR_INT:
434
			p = &((char *) gopts)[attrs[i].offset];
435
436
437
438
			* (int*) p = atoi(value);
			break;

		case ATTR_KV: {
439
				const struct ol_keyvalue *kv;
440

441
				for(kv = attrs[i].data;
442
443
444
445
					kv->key != NULL;
					kv++) {

					if(strcasecmp(value, kv->key) == 0) {
446
						p = &((char *) gopts)[attrs[i].offset];
447
448
449
450
451
452
453
						* (int*) p = kv->value;
						break;
					}
				}
			} break;

		case ATTR_STRING:
454
			p = &((char *) gopts)[attrs[i].offset];
455
			if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
456
457
458
			if (*value == '\0') {
				* (char**) p = NULL;
			} else {
459
				* (char**) p = LDAP_STRDUP(value);
460
461
			}
			break;
462
463
		case ATTR_OPTION:
			ldap_set_option( NULL, attrs[i].offset, value );
464
			break;
465
466
467
468
469
470
471
		case ATTR_SASL:
#ifdef HAVE_CYRUS_SASL
		   	ldap_int_sasl_config( gopts, attrs[i].offset, value );
#endif			 	
		   	break;
		case ATTR_TLS:
#ifdef HAVE_TLS
472
		   	ldap_pvt_tls_config( NULL, attrs[i].offset, value );
473
474
#endif			 	
		   	break;
Howard Chu's avatar
Howard Chu committed
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
		case ATTR_OPT_TV: {
			struct timeval tv;
			char *next;
			tv.tv_usec = 0;
			tv.tv_sec = strtol( value, &next, 10 );
			if ( next != value && next[ 0 ] == '\0' && tv.tv_sec > 0 ) {
				(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&tv );
			}
			} break;
		case ATTR_OPT_INT: {
			long l;
			char *next;
			l = strtol( value, &next, 10 );
			if ( next != value && next[ 0 ] == '\0' && l > 0 && (long)((int)l) == l ) {
				int v = (int)l;
				(void)ldap_set_option( NULL, attrs[i].offset, (const void *)&v );
			}
			} break;
493
494
495
496
		}
	}
}

497
498
499
500
501
502
503
504
505
506
507
#if defined(__GNUC__)
/* Declare this function as a destructor so that it will automatically be
 * invoked either at program exit (if libldap is a static library) or
 * at unload time (if libldap is a dynamic library).
 *
 * Sorry, don't know how to handle this for non-GCC environments.
 */
static void ldap_int_destroy_global_options(void)
	__attribute__ ((destructor));
#endif

508
static void
Howard Chu's avatar
Howard Chu committed
509
ldap_int_destroy_global_options(void)
510
511
512
{
	struct ldapoptions *gopts = LDAP_INT_GLOBAL_OPT();

513
514
515
	if ( gopts == NULL )
		return;

516
517
	gopts->ldo_valid = LDAP_UNINITIALIZED;

518
519
520
521
	if ( gopts->ldo_defludp ) {
		ldap_free_urllist( gopts->ldo_defludp );
		gopts->ldo_defludp = NULL;
	}
522
523
524
#if defined(HAVE_WINSOCK) || defined(HAVE_WINSOCK2)
	WSACleanup( );
#endif
Pierangelo Masarati's avatar
Pierangelo Masarati committed
525

526
#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
Pierangelo Masarati's avatar
Pierangelo Masarati committed
527
528
529
530
	if ( ldap_int_hostname ) {
		LDAP_FREE( ldap_int_hostname );
		ldap_int_hostname = NULL;
	}
Pierangelo Masarati's avatar
Pierangelo Masarati committed
531
#endif
532
533
534
535
536
537
#ifdef HAVE_CYRUS_SASL
	if ( gopts->ldo_def_sasl_authcid ) {
		LDAP_FREE( gopts->ldo_def_sasl_authcid );
		gopts->ldo_def_sasl_authcid = NULL;
	}
#endif
Howard Chu's avatar
Howard Chu committed
538
539
540
#ifdef HAVE_TLS
	ldap_int_tls_destroy( gopts );
#endif
541
542
}

543
544
545
546
/* 
 * Initialize the global options structure with default values.
 */
void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl )
547
{
548
	if (dbglvl)
549
	    gopts->ldo_debug = *dbglvl;
550
	else
551
		gopts->ldo_debug = 0;
552

553
554
555
556
	gopts->ldo_version   = LDAP_VERSION2;
	gopts->ldo_deref     = LDAP_DEREF_NEVER;
	gopts->ldo_timelimit = LDAP_NO_LIMIT;
	gopts->ldo_sizelimit = LDAP_NO_LIMIT;
557

Howard Chu's avatar
Howard Chu committed
558
559
	gopts->ldo_tm_api.tv_sec = -1;
	gopts->ldo_tm_net.tv_sec = -1;
560

561
	/* ldo_defludp will be freed by the termination handler
562
	 */
563
564
	ldap_url_parselist(&gopts->ldo_defludp, "ldap://localhost/");
	gopts->ldo_defport = LDAP_PORT;
565
566
567
568
#if !defined(__GNUC__) && !defined(PIC)
	/* Do this only for a static library, and only if we can't
	 * arrange for it to be executed as a library destructor
	 */
569
	atexit(ldap_int_destroy_global_options);
570
#endif
571

572
	gopts->ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
573
574
	gopts->ldo_rebind_proc = NULL;
	gopts->ldo_rebind_params = NULL;
575

576
	LDAP_BOOL_ZERO(gopts);
577

578
	LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
579

580
581
582
#ifdef LDAP_CONNECTIONLESS
	gopts->ldo_peer = NULL;
	gopts->ldo_cldapdn = NULL;
Howard Chu's avatar
Howard Chu committed
583
	gopts->ldo_is_udp = 0;
584
585
#endif

586
#ifdef HAVE_CYRUS_SASL
587
588
589
590
591
	gopts->ldo_def_sasl_mech = NULL;
	gopts->ldo_def_sasl_realm = NULL;
	gopts->ldo_def_sasl_authcid = NULL;
	gopts->ldo_def_sasl_authzid = NULL;

Kurt Zeilenga's avatar
Kurt Zeilenga committed
592
593
	memset( &gopts->ldo_sasl_secprops,
		'\0', sizeof(gopts->ldo_sasl_secprops) );
594
595

	gopts->ldo_sasl_secprops.max_ssf = INT_MAX;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
596
597
598
	gopts->ldo_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE;
	gopts->ldo_sasl_secprops.security_flags =
		SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
599
#endif
600

601
602
603
#ifdef HAVE_TLS
	gopts->ldo_tls_connect_cb = NULL;
	gopts->ldo_tls_connect_arg = NULL;
Howard Chu's avatar
Howard Chu committed
604
	gopts->ldo_tls_require_cert = LDAP_OPT_X_TLS_DEMAND;
Howard Chu's avatar
Howard Chu committed
605
	gopts->ldo_tls_require_san = LDAP_OPT_X_TLS_ALLOW;
606
#endif
607
608
609
	gopts->ldo_keepalive_probes = 0;
	gopts->ldo_keepalive_interval = 0;
	gopts->ldo_keepalive_idle = 0;
610

Howard Chu's avatar
Howard Chu committed
611
612
613
#ifdef LDAP_R_COMPILE
	ldap_pvt_thread_mutex_init( &gopts->ldo_mutex );
#endif
614
615
616
617
	gopts->ldo_valid = LDAP_INITIALIZED;
   	return;
}

618
#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
619
char * ldap_int_hostname = NULL;
620
621
#endif

Howard Chu's avatar
Howard Chu committed
622
623
624
625
#ifdef LDAP_R_COMPILE
int	ldap_int_stackguard;
#endif

626
627
void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
{
628
#ifdef LDAP_R_COMPILE
629
630
	static ldap_pvt_thread_mutex_t init_mutex;
	LDAP_PVT_MUTEX_FIRSTCREATE( init_mutex );
631

632
633
	LDAP_MUTEX_LOCK( &init_mutex );
#endif
634
	if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
635
		/* someone else got here first */
636
		goto done;
637
638
	}

639
640
	ldap_int_error_init();

641
642
	ldap_int_utils_init();

643
644
645
646
647
648
649
650
#ifdef HAVE_WINSOCK2
{	WORD wVersionRequested;
	WSADATA wsaData;
 
	wVersionRequested = MAKEWORD( 2, 0 );
	if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
		/* Tell the user that we couldn't find a usable */
		/* WinSock DLL.                                  */
651
		goto done;
652
653
654
655
656
657
658
659
660
661
662
663
664
665
	}
 
	/* Confirm that the WinSock DLL supports 2.0.*/
	/* Note that if the DLL supports versions greater    */
	/* than 2.0 in addition to 2.0, it will still return */
	/* 2.0 in wVersion since that is the version we      */
	/* requested.                                        */
 
	if ( LOBYTE( wsaData.wVersion ) != 2 ||
		HIBYTE( wsaData.wVersion ) != 0 )
	{
	    /* Tell the user that we couldn't find a usable */
	    /* WinSock DLL.                                  */
	    WSACleanup( );
666
	    goto done;
667
668
	}
}	/* The WinSock DLL is acceptable. Proceed. */
Howard Chu's avatar
Howard Chu committed
669
#elif defined(HAVE_WINSOCK)
670
671
{	WSADATA wsaData;
	if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
672
	    goto done;
673
674
	}
}
675
676
#endif

677
#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
Howard Chu's avatar
Howard Chu committed
678
	LDAP_MUTEX_LOCK( &ldap_int_hostname_mutex );
Pierangelo Masarati's avatar
Pierangelo Masarati committed
679
680
681
682
683
684
685
686
687
	{
		char	*name = ldap_int_hostname;

		ldap_int_hostname = ldap_pvt_get_fqdn( name );

		if ( name != NULL && name != ldap_int_hostname ) {
			LDAP_FREE( name );
		}
	}
Howard Chu's avatar
Howard Chu committed
688
	LDAP_MUTEX_UNLOCK( &ldap_int_hostname_mutex );
689
#endif
690
691
692
693

#ifndef HAVE_POLL
	if ( ldap_int_tblsize == 0 ) ldap_int_ip_init();
#endif
694

695
696
#ifdef HAVE_CYRUS_SASL
	if ( ldap_int_sasl_init() != 0 ) {
697
		goto done;
698
699
700
	}
#endif

701
	ldap_int_initialize_global_options(gopts, dbglvl);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
702
703

	if( getenv("LDAPNOINIT") != NULL ) {
704
		goto done;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
705
706
	}

Howard Chu's avatar
Howard Chu committed
707
708
709
710
711
712
#ifdef LDAP_R_COMPILE
	if( getenv("LDAPSTACKGUARD") != NULL ) {
		ldap_int_stackguard = 1;
	}
#endif

713
714
715
716
717
718
719
720
721
#ifdef HAVE_CYRUS_SASL
	{
		/* set authentication identity to current user name */
		char *user = getenv("USER");

		if( user == NULL ) user = getenv("USERNAME");
		if( user == NULL ) user = getenv("LOGNAME");

		if( user != NULL ) {
722
			gopts->ldo_def_sasl_authcid = LDAP_STRDUP( user );
723
724
725
726
		}
    }
#endif

727
	openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
728
729
730

#ifdef HAVE_GETEUID
	if ( geteuid() != getuid() )
731
		goto done;
732
733
#endif

734
	openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
735
736

	{
737
		char *altfile = getenv(LDAP_ENV_PREFIX "CONF");
738
739

		if( altfile != NULL ) {
740
741
			Debug2(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
			      LDAP_ENV_PREFIX "CONF", altfile );
742
			openldap_ldap_init_w_sysconf( altfile );
743
		}
744
		else
745
746
			Debug1(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
			      LDAP_ENV_PREFIX "CONF" );
747
748
	}

749
	{
750
		char *altfile = getenv(LDAP_ENV_PREFIX "RC");
751
752

		if( altfile != NULL ) {
753
754
			Debug2(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
			      LDAP_ENV_PREFIX "RC", altfile );
755
756
			openldap_ldap_init_w_userconf( altfile );
		}
757
		else
758
759
			Debug1(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
			      LDAP_ENV_PREFIX "RC" );
760
761
	}

762
	openldap_ldap_init_w_env(gopts, NULL);
763

764
765
766
767
done:;
#ifdef LDAP_R_COMPILE
	LDAP_MUTEX_UNLOCK( &init_mutex );
#endif
768
}