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