3 * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
11 #include <ac/socket.h>
12 #include <ac/string.h>
19 #include "ldap_defaults.h"
21 struct ldapoptions ldap_int_global_options =
22 { LDAP_UNINITIALIZED, LDAP_DEBUG_NONE };
39 static const struct ol_keyvalue deref_kv[] = {
40 {"never", LDAP_DEREF_NEVER},
41 {"searching", LDAP_DEREF_SEARCHING},
42 {"finding", LDAP_DEREF_FINDING},
43 {"always", LDAP_DEREF_ALWAYS},
47 static const struct ol_attribute {
54 {0, ATTR_KV, "DEREF", deref_kv, /* or &deref_kv[0] */
55 offsetof(struct ldapoptions, ldo_deref)},
56 {0, ATTR_INT, "SIZELIMIT", NULL,
57 offsetof(struct ldapoptions, ldo_sizelimit)},
58 {0, ATTR_INT, "TIMELIMIT", NULL,
59 offsetof(struct ldapoptions, ldo_timelimit)},
60 {1, ATTR_STRING, "BINDDN", NULL,
61 offsetof(struct ldapoptions, ldo_defbinddn)},
62 {0, ATTR_STRING, "BASE", NULL,
63 offsetof(struct ldapoptions, ldo_defbase)},
64 {0, ATTR_INT, "PORT", NULL, /* deprecated */
65 offsetof(struct ldapoptions, ldo_defport)},
66 {0, ATTR_OPTION, "HOST", NULL, LDAP_OPT_HOST_NAME}, /* deprecated */
67 {0, ATTR_OPTION, "URI", NULL, LDAP_OPT_URI}, /* replaces HOST/PORT */
68 {0, ATTR_BOOL, "REFERRALS", NULL, LDAP_BOOL_REFERRALS},
69 {0, ATTR_BOOL, "RESTART", NULL, LDAP_BOOL_RESTART},
71 #ifdef HAVE_CYRUS_SASL
72 {1, ATTR_STRING, "SASL_MECH", NULL,
73 offsetof(struct ldapoptions, ldo_def_sasl_mech)},
74 {1, ATTR_STRING, "SASL_REALM", NULL,
75 offsetof(struct ldapoptions, ldo_def_sasl_realm)},
76 {1, ATTR_STRING, "SASL_AUTHCID", NULL,
77 offsetof(struct ldapoptions, ldo_def_sasl_authcid)},
78 {1, ATTR_STRING, "SASL_AUTHZID", NULL,
79 offsetof(struct ldapoptions, ldo_def_sasl_authzid)},
80 {0, ATTR_SASL, "SASL_SECPROPS", NULL, LDAP_OPT_X_SASL_SECPROPS},
84 {1, ATTR_TLS, "TLS_CERT", NULL, LDAP_OPT_X_TLS_CERTFILE},
85 {1, ATTR_TLS, "TLS_KEY", NULL, LDAP_OPT_X_TLS_KEYFILE},
86 {0, ATTR_TLS, "TLS_CACERT", NULL, LDAP_OPT_X_TLS_CACERTFILE},
87 {0, ATTR_TLS, "TLS_CACERTDIR",NULL, LDAP_OPT_X_TLS_CACERTDIR},
88 {0, ATTR_TLS, "TLS_REQCERT", NULL, LDAP_OPT_X_TLS_REQUIRE_CERT},
89 {0, ATTR_TLS, "TLS_RANDFILE", NULL, LDAP_OPT_X_TLS_RANDOM_FILE},
92 {0, ATTR_NONE, NULL, NULL, 0}
95 #define MAX_LDAP_ATTR_LEN sizeof("TLS_CACERTDIR")
96 #define MAX_LDAP_ENV_PREFIX_LEN 8
98 static void openldap_ldap_init_w_conf(
99 const char *file, int userconf )
106 struct ldapoptions *gopts;
108 if ((gopts = LDAP_INT_GLOBAL_OPT()) == NULL) {
109 return; /* Could not allocate mem for global options */
118 LDAP_LOG ( CONFIG, DETAIL1,
119 "openldap_init_w_conf: trying %s\n", file, 0, 0 );
121 Debug(LDAP_DEBUG_TRACE, "ldap_init: trying %s\n", file, 0, 0);
124 fp = fopen(file, "r");
126 /* could not open file */
131 LDAP_LOG ( CONFIG, DETAIL1, "openldap_init_w_conf: using %s\n", file, 0, 0 );
133 Debug(LDAP_DEBUG_TRACE, "ldap_init: using %s\n", file, 0, 0);
136 while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
137 /* skip lines starting with '#' */
138 if(*start == '#') continue;
140 /* trim leading white space */
141 while((*start != '\0') && isspace((unsigned char) *start))
145 if(*start == '\0') continue;
147 /* trim trailing white space */
148 end = &start[strlen(start)-1];
149 while(isspace((unsigned char)*end)) end--;
153 if(*start == '\0') continue;
156 /* parse the command */
158 while((*start != '\0') && !isspace((unsigned char)*start)) {
162 /* command has no argument */
168 /* we must have some whitespace to skip */
169 while(isspace((unsigned char)*start)) start++;
172 for(i=0; attrs[i].type != ATTR_NONE; i++) {
175 if( !userconf && attrs[i].useronly ) {
179 if(strcasecmp(cmd, attrs[i].name) != 0) {
183 switch(attrs[i].type) {
185 if((strcasecmp(opt, "on") == 0)
186 || (strcasecmp(opt, "yes") == 0)
187 || (strcasecmp(opt, "true") == 0))
189 LDAP_BOOL_SET(gopts, attrs[i].offset);
192 LDAP_BOOL_CLR(gopts, attrs[i].offset);
198 p = &((char *) gopts)[attrs[i].offset];
199 * (int*) p = atoi(opt);
203 const struct ol_keyvalue *kv;
205 for(kv = attrs[i].data;
209 if(strcasecmp(opt, kv->key) == 0) {
210 p = &((char *) gopts)[attrs[i].offset];
211 * (int*) p = kv->value;
218 p = &((char *) gopts)[attrs[i].offset];
219 if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
220 * (char**) p = LDAP_STRDUP(opt);
223 ldap_set_option( NULL, attrs[i].offset, opt );
226 #ifdef HAVE_CYRUS_SASL
227 ldap_int_sasl_config( gopts, attrs[i].offset, opt );
232 ldap_int_tls_config( NULL, attrs[i].offset, opt );
244 static void openldap_ldap_init_w_sysconf(const char *file)
246 openldap_ldap_init_w_conf( file, 0 );
249 static void openldap_ldap_init_w_userconf(const char *file)
259 home = getenv("HOME");
263 LDAP_LOG ( CONFIG, ARGS,
264 "openldap_init_w_userconf: HOME env is %s\n", home, 0, 0 );
266 Debug(LDAP_DEBUG_TRACE, "ldap_init: HOME env is %s\n",
269 path = LDAP_MALLOC(strlen(home) + strlen(file) + sizeof( LDAP_DIRSEP "."));
272 LDAP_LOG ( CONFIG, ARGS, "openldap_init_w_userconf: HOME env is NULL\n",
275 Debug(LDAP_DEBUG_TRACE, "ldap_init: HOME env is NULL\n",
280 if(home != NULL && path != NULL) {
281 /* we assume UNIX path syntax is used... */
284 sprintf(path, "%s" LDAP_DIRSEP "%s", home, file);
285 openldap_ldap_init_w_conf(path, 1);
288 sprintf(path, "%s" LDAP_DIRSEP ".%s", home, file);
289 openldap_ldap_init_w_conf(path, 1);
297 openldap_ldap_init_w_conf(file, 1);
300 static void openldap_ldap_init_w_env(
301 struct ldapoptions *gopts,
304 char buf[MAX_LDAP_ATTR_LEN+MAX_LDAP_ENV_PREFIX_LEN];
310 if (prefix == NULL) {
311 prefix = LDAP_ENV_PREFIX;
314 strncpy(buf, prefix, MAX_LDAP_ENV_PREFIX_LEN);
315 buf[MAX_LDAP_ENV_PREFIX_LEN] = '\0';
318 for(i=0; attrs[i].type != ATTR_NONE; i++) {
319 strcpy(&buf[len], attrs[i].name);
326 switch(attrs[i].type) {
328 if((strcasecmp(value, "on") == 0)
329 || (strcasecmp(value, "yes") == 0)
330 || (strcasecmp(value, "true") == 0))
332 LDAP_BOOL_SET(gopts, attrs[i].offset);
335 LDAP_BOOL_CLR(gopts, attrs[i].offset);
340 p = &((char *) gopts)[attrs[i].offset];
341 * (int*) p = atoi(value);
345 const struct ol_keyvalue *kv;
347 for(kv = attrs[i].data;
351 if(strcasecmp(value, kv->key) == 0) {
352 p = &((char *) gopts)[attrs[i].offset];
353 * (int*) p = kv->value;
360 p = &((char *) gopts)[attrs[i].offset];
361 if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
362 if (*value == '\0') {
365 * (char**) p = LDAP_STRDUP(value);
369 ldap_set_option( NULL, attrs[i].offset, value );
372 #ifdef HAVE_CYRUS_SASL
373 ldap_int_sasl_config( gopts, attrs[i].offset, value );
378 ldap_int_tls_config( NULL, attrs[i].offset, value );
385 #if defined(__GNUC__)
386 /* Declare this function as a destructor so that it will automatically be
387 * invoked either at program exit (if libldap is a static library) or
388 * at unload time (if libldap is a dynamic library).
390 * Sorry, don't know how to handle this for non-GCC environments.
392 static void ldap_int_destroy_global_options(void)
393 __attribute__ ((destructor));
397 ldap_int_destroy_global_options(void)
399 struct ldapoptions *gopts = LDAP_INT_GLOBAL_OPT();
401 if ( gopts->ldo_defludp ) {
402 ldap_free_urllist( gopts->ldo_defludp );
403 gopts->ldo_defludp = NULL;
405 #if defined(HAVE_WINSOCK) || defined(HAVE_WINSOCK2)
411 * Initialize the global options structure with default values.
413 void ldap_int_initialize_global_options( struct ldapoptions *gopts, int *dbglvl )
416 gopts->ldo_debug = *dbglvl;
418 gopts->ldo_debug = 0;
420 gopts->ldo_version = LDAP_VERSION2;
421 gopts->ldo_deref = LDAP_DEREF_NEVER;
422 gopts->ldo_timelimit = LDAP_NO_LIMIT;
423 gopts->ldo_sizelimit = LDAP_NO_LIMIT;
425 gopts->ldo_tm_api = (struct timeval *)NULL;
426 gopts->ldo_tm_net = (struct timeval *)NULL;
428 /* ldo_defludp will be freed by the termination handler
430 ldap_url_parselist(&gopts->ldo_defludp, "ldap://localhost/");
431 gopts->ldo_defport = LDAP_PORT;
432 #if !defined(__GNUC__) && !defined(PIC)
433 /* Do this only for a static library, and only if we can't
434 * arrange for it to be executed as a library destructor
436 atexit(ldap_int_destroy_global_options);
439 gopts->ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
440 gopts->ldo_rebind_proc = NULL;
441 gopts->ldo_rebind_params = NULL;
443 LDAP_BOOL_ZERO(gopts);
445 LDAP_BOOL_SET(gopts, LDAP_BOOL_REFERRALS);
447 #ifdef LDAP_CONNECTIONLESS
448 gopts->ldo_peer = NULL;
449 gopts->ldo_cldapdn = NULL;
450 gopts->ldo_is_udp = 0;
453 #ifdef HAVE_CYRUS_SASL
454 gopts->ldo_def_sasl_mech = NULL;
455 gopts->ldo_def_sasl_realm = NULL;
456 gopts->ldo_def_sasl_authcid = NULL;
457 gopts->ldo_def_sasl_authzid = NULL;
459 memset( &gopts->ldo_sasl_secprops,
460 '\0', sizeof(gopts->ldo_sasl_secprops) );
462 gopts->ldo_sasl_secprops.max_ssf = INT_MAX;
463 gopts->ldo_sasl_secprops.maxbufsize = SASL_MAX_BUFF_SIZE;
464 gopts->ldo_sasl_secprops.security_flags =
465 SASL_SEC_NOPLAINTEXT | SASL_SEC_NOANONYMOUS;
468 gopts->ldo_valid = LDAP_INITIALIZED;
472 #if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
473 || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
474 char * ldap_int_hostname = NULL;
477 void ldap_int_initialize( struct ldapoptions *gopts, int *dbglvl )
479 if ( gopts->ldo_valid == LDAP_INITIALIZED ) {
483 ldap_int_error_init();
485 ldap_int_utils_init();
488 { WORD wVersionRequested;
491 wVersionRequested = MAKEWORD( 2, 0 );
492 if ( WSAStartup( wVersionRequested, &wsaData ) != 0 ) {
493 /* Tell the user that we couldn't find a usable */
498 /* Confirm that the WinSock DLL supports 2.0.*/
499 /* Note that if the DLL supports versions greater */
500 /* than 2.0 in addition to 2.0, it will still return */
501 /* 2.0 in wVersion since that is the version we */
504 if ( LOBYTE( wsaData.wVersion ) != 2 ||
505 HIBYTE( wsaData.wVersion ) != 0 )
507 /* Tell the user that we couldn't find a usable */
512 } /* The WinSock DLL is acceptable. Proceed. */
515 if ( WSAStartup( 0x0101, &wsaData ) != 0 ) {
521 #if defined(LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND) \
522 || defined(HAVE_TLS) || defined(HAVE_CYRUS_SASL)
523 ldap_int_hostname = ldap_pvt_get_fqdn( ldap_int_hostname );
525 if ( ldap_int_tblsize == 0 )
528 ldap_int_initialize_global_options(gopts, NULL);
530 if( getenv("LDAPNOINIT") != NULL ) {
534 #ifdef HAVE_CYRUS_SASL
536 /* set authentication identity to current user name */
537 char *user = getenv("USER");
539 if( user == NULL ) user = getenv("USERNAME");
540 if( user == NULL ) user = getenv("LOGNAME");
543 gopts->ldo_def_sasl_authcid = user;
548 openldap_ldap_init_w_sysconf(LDAP_CONF_FILE);
549 openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
552 char *altfile = getenv(LDAP_ENV_PREFIX "CONF");
554 if( altfile != NULL ) {
556 LDAP_LOG ( CONFIG, DETAIL1,
557 "openldap_init_w_userconf: %sCONF env is %s\n",
558 LDAP_ENV_PREFIX, altfile, 0 );
560 Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
561 LDAP_ENV_PREFIX "CONF", altfile, 0);
563 openldap_ldap_init_w_sysconf( altfile );
567 LDAP_LOG ( CONFIG, DETAIL1,
568 "openldap_init_w_userconf: %sCONF env is NULL\n",
569 LDAP_ENV_PREFIX, 0, 0 );
571 Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
572 LDAP_ENV_PREFIX "CONF", 0, 0);
577 char *altfile = getenv(LDAP_ENV_PREFIX "RC");
579 if( altfile != NULL ) {
581 LDAP_LOG ( CONFIG, DETAIL1,
582 "openldap_init_w_userconf: %sRC env is %s\n",
583 LDAP_ENV_PREFIX, altfile, 0 );
585 Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is %s\n",
586 LDAP_ENV_PREFIX "RC", altfile, 0);
588 openldap_ldap_init_w_userconf( altfile );
592 LDAP_LOG ( CONFIG, DETAIL1,
593 "openldap_init_w_userconf: %sRC env is NULL\n",
594 LDAP_ENV_PREFIX, 0, 0 );
596 Debug(LDAP_DEBUG_TRACE, "ldap_init: %s env is NULL\n",
597 LDAP_ENV_PREFIX "RC", 0, 0);
601 openldap_ldap_init_w_env(gopts, NULL);
603 ldap_int_sasl_init();