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