init.c 17.7 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-2020 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
#if 0
	/* This should only be allowed via ldap_set_option(3) */
99
	{0, ATTR_BOOL,		"RESTART",		NULL,	LDAP_BOOL_RESTART},
100
#endif
101

102
#ifdef HAVE_CYRUS_SASL
103
	{0, ATTR_STRING,	"SASL_MECH",		NULL,
104
		offsetof(struct ldapoptions, ldo_def_sasl_mech)},
105
	{0, ATTR_STRING,	"SASL_REALM",		NULL,
106
107
108
109
110
111
		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},
112
	{0, ATTR_BOOL,		"SASL_NOCANON",	NULL,	LDAP_BOOL_SASL_NOCANON},
113
	{0, ATTR_SASL,		"SASL_CBINDING",	NULL,	LDAP_OPT_X_SASL_CBINDING},
114
115
#endif

116
#ifdef HAVE_TLS
117
118
119
120
121
	{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
122
	{0, ATTR_TLS,	"TLS_REQSAN",		NULL,	LDAP_OPT_X_TLS_REQUIRE_SAN},
123
124
	{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},
125
	{0, ATTR_TLS,	"TLS_PROTOCOL_MIN",	NULL,	LDAP_OPT_X_TLS_PROTOCOL_MIN},
126
	{0, ATTR_TLS,	"TLS_PEERKEY_HASH",	NULL,	LDAP_OPT_X_TLS_PEERKEY_HASH},
127
	{0, ATTR_TLS,	"TLS_ECNAME",		NULL,	LDAP_OPT_X_TLS_ECNAME},
128

129
#ifdef HAVE_OPENSSL
130
	{0, ATTR_TLS,	"TLS_CRLCHECK",		NULL,	LDAP_OPT_X_TLS_CRLCHECK},
131
#endif
132
#ifdef HAVE_GNUTLS
Howard Chu's avatar
Howard Chu committed
133
	{0, ATTR_TLS,	"TLS_CRLFILE",			NULL,	LDAP_OPT_X_TLS_CRLFILE},
134
#endif
135
        
136
137
#endif

138
	{0, ATTR_NONE,		NULL,		NULL,	0}
139
140
};

Quanah Gibson-Mount's avatar
Quanah Gibson-Mount committed
141
#define MAX_LDAP_ATTR_LEN  sizeof("TLS_CIPHER_SUITE")
142
143
#define MAX_LDAP_ENV_PREFIX_LEN 8

144
145
146
147
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
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 ) {
243
		Debug1( LDAP_DEBUG_TRACE, "ldap_pvt_tls_config: "
244
				"unknown option '%s'",
245
				cmd );
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
		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 );
}

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

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

288
289
290
291
292
	if (file == NULL) {
		/* no file name */
		return;
	}

293
	Debug1(LDAP_DEBUG_TRACE, "ldap_init: trying %s\n", file );
294

295
296
297
298
299
300
	fp = fopen(file, "r");
	if(fp == NULL) {
		/* could not open file */
		return;
	}

301
	Debug1(LDAP_DEBUG_TRACE, "ldap_init: using %s\n", file );
302

303
304
305
306
307
	while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
		/* skip lines starting with '#' */
		if(*start == '#') continue;

		/* trim leading white space */
308
309
		while((*start != '\0') && isspace((unsigned char) *start))
			start++;
310
311
312
313
314
315

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

		/* trim trailing white space */
		end = &start[strlen(start)-1];
316
		while(isspace((unsigned char)*end)) end--;
317
318
319
320
321
322
323
324
		end[1] = '\0';

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

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

		*start++ = '\0';

335
		/* we must have some whitespace to skip */
336
		while(isspace((unsigned char)*start)) start++;
337
338
		opt = start;

339
		ldap_int_conf_option( gopts, cmd, opt, userconf );
340
	}
341
342

	fclose(fp);
343
344
}

345
346
347
348
349
static void openldap_ldap_init_w_sysconf(const char *file)
{
	openldap_ldap_init_w_conf( file, 0 );
}

350
351
static void openldap_ldap_init_w_userconf(const char *file)
{
352
	char *home;
353
	char *path = NULL;
354
355
356
357
358
359
360
361

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

	home = getenv("HOME");

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

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

Kurt Zeilenga's avatar
Kurt Zeilenga committed
373
		/* try ~/file */
Kurt Zeilenga's avatar
Kurt Zeilenga committed
374
		sprintf(path, "%s" LDAP_DIRSEP "%s", home, file);
375
		openldap_ldap_init_w_conf(path, 1);
376

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);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
380
	}
381
382

	if(path != NULL) {
383
		LDAP_FREE(path);
384
	}
385
386

	/* try file */
387
	openldap_ldap_init_w_conf(file, 1);
388
389
}

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

	if (prefix == NULL) {
401
		prefix = LDAP_ENV_PREFIX;
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
	}

	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))
			{
422
				LDAP_BOOL_SET(gopts, attrs[i].offset);
423
424

			} else {
425
				LDAP_BOOL_CLR(gopts, attrs[i].offset);
426
427
428
429
			}
			break;

		case ATTR_INT:
430
			p = &((char *) gopts)[attrs[i].offset];
431
432
433
434
			* (int*) p = atoi(value);
			break;

		case ATTR_KV: {
435
				const struct ol_keyvalue *kv;
436

437
				for(kv = attrs[i].data;
438
439
440
441
					kv->key != NULL;
					kv++) {

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

		case ATTR_STRING:
450
			p = &((char *) gopts)[attrs[i].offset];
451
			if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
452
453
454
			if (*value == '\0') {
				* (char**) p = NULL;
			} else {
455
				* (char**) p = LDAP_STRDUP(value);
456
457
			}
			break;
458
459
		case ATTR_OPTION:
			ldap_set_option( NULL, attrs[i].offset, value );
460
			break;
461
462
463
464
465
466
467
		case ATTR_SASL:
#ifdef HAVE_CYRUS_SASL
		   	ldap_int_sasl_config( gopts, attrs[i].offset, value );
#endif			 	
		   	break;
		case ATTR_TLS:
#ifdef HAVE_TLS
468
		   	ldap_pvt_tls_config( NULL, attrs[i].offset, value );
469
470
#endif			 	
		   	break;
Howard Chu's avatar
Howard Chu committed
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
		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;
489
490
491
492
		}
	}
}

493
494
495
496
497
498
499
500
501
502
503
#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

504
static void
Howard Chu's avatar
Howard Chu committed
505
ldap_int_destroy_global_options(void)
506
507
508
{
	struct ldapoptions *gopts = LDAP_INT_GLOBAL_OPT();

509
510
511
	if ( gopts == NULL )
		return;

512
513
	gopts->ldo_valid = LDAP_UNINITIALIZED;

514
515
516
517
	if ( gopts->ldo_defludp ) {
		ldap_free_urllist( gopts->ldo_defludp );
		gopts->ldo_defludp = NULL;
	}
518
519
520
#if defined(HAVE_WINSOCK) || defined(HAVE_WINSOCK2)
	WSACleanup( );
#endif
Pierangelo Masarati's avatar
Pierangelo Masarati committed
521

522
#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
Pierangelo Masarati's avatar
Pierangelo Masarati committed
523
524
525
526
	if ( ldap_int_hostname ) {
		LDAP_FREE( ldap_int_hostname );
		ldap_int_hostname = NULL;
	}
Pierangelo Masarati's avatar
Pierangelo Masarati committed
527
#endif
528
529
530
531
532
533
#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
534
535
536
#ifdef HAVE_TLS
	ldap_int_tls_destroy( gopts );
#endif
537
538
}

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

549
550
551
552
	gopts->ldo_version   = LDAP_VERSION2;
	gopts->ldo_deref     = LDAP_DEREF_NEVER;
	gopts->ldo_timelimit = LDAP_NO_LIMIT;
	gopts->ldo_sizelimit = LDAP_NO_LIMIT;
553

Howard Chu's avatar
Howard Chu committed
554
555
	gopts->ldo_tm_api.tv_sec = -1;
	gopts->ldo_tm_net.tv_sec = -1;
556

557
	/* ldo_defludp will be freed by the termination handler
558
	 */
559
560
	ldap_url_parselist(&gopts->ldo_defludp, "ldap://localhost/");
	gopts->ldo_defport = LDAP_PORT;
561
562
563
564
#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
	 */
565
	atexit(ldap_int_destroy_global_options);
566
#endif
567

568
	gopts->ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
569
570
	gopts->ldo_rebind_proc = NULL;
	gopts->ldo_rebind_params = NULL;
571

572
	LDAP_BOOL_ZERO(gopts);
573

574
	LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
575

576
577
578
#ifdef LDAP_CONNECTIONLESS
	gopts->ldo_peer = NULL;
	gopts->ldo_cldapdn = NULL;
Howard Chu's avatar
Howard Chu committed
579
	gopts->ldo_is_udp = 0;
580
581
#endif

582
#ifdef HAVE_CYRUS_SASL
583
584
585
586
587
	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
588
589
	memset( &gopts->ldo_sasl_secprops,
		'\0', sizeof(gopts->ldo_sasl_secprops) );
590
591

	gopts->ldo_sasl_secprops.max_ssf = INT_MAX;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
592
593
594
	gopts->ldo_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE;
	gopts->ldo_sasl_secprops.security_flags =
		SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
595
#endif
596

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

607
608
609
610
	gopts->ldo_valid = LDAP_INITIALIZED;
   	return;
}

611
#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
612
char * ldap_int_hostname = NULL;
613
614
#endif

Howard Chu's avatar
Howard Chu committed
615
616
617
618
#ifdef LDAP_R_COMPILE
int	ldap_int_stackguard;
#endif

619
620
void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
{
621
#ifdef LDAP_R_COMPILE
622
623
	static ldap_pvt_thread_mutex_t init_mutex;
	LDAP_PVT_MUTEX_FIRSTCREATE( init_mutex );
624

625
626
	LDAP_MUTEX_LOCK( &init_mutex );
#endif
627
	if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
628
		/* someone else got here first */
629
		goto done;
630
631
	}

632
633
	ldap_int_error_init();

634
635
	ldap_int_utils_init();

636
637
638
639
640
641
642
643
#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.                                  */
644
		goto done;
645
646
647
648
649
650
651
652
653
654
655
656
657
658
	}
 
	/* 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( );
659
	    goto done;
660
661
	}
}	/* The WinSock DLL is acceptable. Proceed. */
Howard Chu's avatar
Howard Chu committed
662
#elif defined(HAVE_WINSOCK)
663
664
{	WSADATA wsaData;
	if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
665
	    goto done;
666
667
	}
}
668
669
#endif

670
#if defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
Howard Chu's avatar
Howard Chu committed
671
	LDAP_MUTEX_LOCK( &ldap_int_hostname_mutex );
Pierangelo Masarati's avatar
Pierangelo Masarati committed
672
673
674
675
676
677
678
679
680
	{
		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
681
	LDAP_MUTEX_UNLOCK( &ldap_int_hostname_mutex );
682
#endif
683
684
685
686

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

688
689
#ifdef HAVE_CYRUS_SASL
	if ( ldap_int_sasl_init() != 0 ) {
690
		goto done;
691
692
693
	}
#endif

694
	ldap_int_initialize_global_options(gopts, dbglvl);
Kurt Zeilenga's avatar
Kurt Zeilenga committed
695
696

	if( getenv("LDAPNOINIT") != NULL ) {
697
		goto done;
Kurt Zeilenga's avatar
Kurt Zeilenga committed
698
699
	}

Howard Chu's avatar
Howard Chu committed
700
701
702
703
704
705
#ifdef LDAP_R_COMPILE
	if( getenv("LDAPSTACKGUARD") != NULL ) {
		ldap_int_stackguard = 1;
	}
#endif

706
707
708
709
710
711
712
713
714
#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 ) {
715
			gopts->ldo_def_sasl_authcid = LDAP_STRDUP( user );
716
717
718
719
		}
    }
#endif

720
	openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
721
722
723

#ifdef HAVE_GETEUID
	if ( geteuid() != getuid() )
724
		goto done;
725
726
#endif

727
	openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
728
729

	{
730
		char *altfile = getenv(LDAP_ENV_PREFIX "CONF");
731
732

		if( altfile != NULL ) {
733
734
			Debug2(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
			      LDAP_ENV_PREFIX "CONF", altfile );
735
			openldap_ldap_init_w_sysconf( altfile );
736
		}
737
		else
738
739
			Debug1(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
			      LDAP_ENV_PREFIX "CONF" );
740
741
	}

742
	{
743
		char *altfile = getenv(LDAP_ENV_PREFIX "RC");
744
745

		if( altfile != NULL ) {
746
747
			Debug2(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
			      LDAP_ENV_PREFIX "RC", altfile );
748
749
			openldap_ldap_init_w_userconf( altfile );
		}
750
		else
751
752
			Debug1(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
			      LDAP_ENV_PREFIX "RC" );
753
754
	}

755
	openldap_ldap_init_w_env(gopts, NULL);
756

757
758
759
760
done:;
#ifdef LDAP_R_COMPILE
	LDAP_MUTEX_UNLOCK( &init_mutex );
#endif
761
}