]> git.sur5r.net Git - openldap/blob - libraries/libldap/init.c
Merge in all -devel changes made since branch was created.
[openldap] / libraries / libldap / init.c
1 /*
2  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
4  */
5 #include "portable.h"
6
7 #include <stdio.h>
8 #include <ac/stdlib.h>
9
10 #include <ac/socket.h>
11 #include <ac/string.h>
12 #include <ac/ctype.h>
13 #include <ac/time.h>
14
15 #include "ldap-int.h"
16 #include "ldap_defaults.h"
17
18 struct ldapoptions ldap_int_global_options =
19         { LDAP_UNINITIALIZED, LDAP_DEBUG_NONE };  
20
21 #undef gopts
22 #define gopts ldap_int_global_options
23
24 #define ATTR_NONE       0
25 #define ATTR_BOOL       1
26 #define ATTR_INT        2
27 #define ATTR_KV         3
28 #define ATTR_STRING     4
29 #define ATTR_TLS        5
30
31 struct ol_keyvalue {
32         const char *            key;
33         int                     value;
34 };
35
36 static const struct ol_keyvalue deref_kv[] = {
37         {"never", LDAP_DEREF_NEVER},
38         {"searching", LDAP_DEREF_SEARCHING},
39         {"finding", LDAP_DEREF_FINDING},
40         {"always", LDAP_DEREF_ALWAYS},
41         {NULL, 0}
42 };
43
44 static const struct ol_attribute {
45         int                     type;
46         const char *    name;
47         const void *    data;
48         size_t          offset;
49 } attrs[] = {
50         {ATTR_KV,               "DEREF",        deref_kv, /* or &deref_kv[0] */
51                 offsetof(struct ldapoptions, ldo_deref)},
52         {ATTR_INT,              "SIZELIMIT",    NULL,
53                 offsetof(struct ldapoptions, ldo_sizelimit)},
54         {ATTR_INT,              "TIMELIMIT",    NULL,
55                 offsetof(struct ldapoptions, ldo_timelimit)},
56         {ATTR_STRING,   "BASE",                 NULL,
57                 offsetof(struct ldapoptions, ldo_defbase)},
58         {ATTR_STRING,   "HOST",                 NULL,
59                 offsetof(struct ldapoptions, ldo_defhost)},
60         {ATTR_INT,              "PORT",                 NULL,
61                 offsetof(struct ldapoptions, ldo_defport)},
62         {ATTR_BOOL,             "REFERRALS",    NULL,   LDAP_BOOL_REFERRALS},
63         {ATTR_BOOL,             "RESTART",              NULL,   LDAP_BOOL_RESTART},
64         {ATTR_BOOL,             "DNS",                  NULL,   LDAP_BOOL_DNS},
65         {ATTR_BOOL,             "TLS",                  NULL,   LDAP_OPT_X_TLS},
66         {ATTR_TLS,              "TLS_CERT",             NULL,   LDAP_OPT_X_TLS_CERTFILE},
67         {ATTR_TLS,              "TLS_KEY",              NULL,   LDAP_OPT_X_TLS_KEYFILE},
68         {ATTR_TLS,              "TLS_CACERT",   NULL,   LDAP_OPT_X_TLS_CACERTFILE},
69         {ATTR_TLS,              "TLS_CACERTDIR",NULL,   LDAP_OPT_X_TLS_CACERTDIR},
70         {ATTR_TLS,              "TLS_REQCERT",  NULL,   LDAP_OPT_X_TLS_REQUIRE_CERT},
71         {ATTR_NONE,             NULL,           NULL,   0}
72 };
73
74 #define MAX_LDAP_ATTR_LEN  sizeof("TLS_CACERTDIR")
75 #define MAX_LDAP_ENV_PREFIX_LEN 8
76
77 static void openldap_ldap_init_w_conf(const char *file)
78 {
79         char linebuf[128];
80         FILE *fp;
81         int i;
82         char *cmd, *opt;
83         char *start, *end;
84
85         if (file == NULL) {
86                 /* no file name */
87                 return;
88         }
89
90         fp = fopen(file, "r");
91         if(fp == NULL) {
92                 /* could not open file */
93                 return;
94         }
95
96         while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
97                 /* skip lines starting with '#' */
98                 if(*start == '#') continue;
99
100                 /* trim leading white space */
101                 while((*start != '\0') && isspace((unsigned char) *start))
102                         start++;
103
104                 /* anything left? */
105                 if(*start == '\0') continue;
106
107                 /* trim trailing white space */
108                 end = &start[strlen(start)-1];
109                 while(isspace((unsigned char)*end)) end--;
110                 end[1] = '\0';
111
112                 /* anything left? */
113                 if(*start == '\0') continue;
114                 
115
116                 /* parse the command */
117                 cmd=start;
118                 while((*start != '\0') && !isspace((unsigned char)*start)) {
119                         start++;
120                 }
121                 if(*start == '\0') {
122                         /* command has no argument */
123                         continue;
124                 } 
125
126                 *start++ = '\0';
127
128                 /* we must have some non-whitespace to skip */
129                 while(isspace((unsigned char)*start)) start++;
130                 opt = start;
131
132                 for(i=0; attrs[i].type != ATTR_NONE; i++) {
133                         void *p;
134
135                         if(strcasecmp(cmd, attrs[i].name) != 0) {
136                                 continue;
137                         }
138
139                         switch(attrs[i].type) {
140                         case ATTR_BOOL:
141                                 if((strcasecmp(opt, "on") == 0) 
142                                         || (strcasecmp(opt, "yes") == 0)
143                                         || (strcasecmp(opt, "true") == 0))
144                                 {
145                                         LDAP_BOOL_SET(&gopts, attrs[i].offset);
146
147                                 } else {
148                                         LDAP_BOOL_CLR(&gopts, attrs[i].offset);
149                                 }
150
151                                 break;
152
153                         case ATTR_INT:
154                                 p = &((char *) &gopts)[attrs[i].offset];
155                                 * (int*) p = atoi(opt);
156                                 break;
157
158                         case ATTR_KV: {
159                                         const struct ol_keyvalue *kv;
160
161                                         for(kv = attrs[i].data;
162                                                 kv->key != NULL;
163                                                 kv++) {
164
165                                                 if(strcasecmp(opt, kv->key) == 0) {
166                                                         p = &((char *) &gopts)[attrs[i].offset];
167                                                         * (int*) p = kv->value;
168                                                         break;
169                                                 }
170                                         }
171                                 } break;
172
173                         case ATTR_STRING:
174                                 p = &((char *) &gopts)[attrs[i].offset];
175                                 if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
176                                 * (char**) p = LDAP_STRDUP(opt);
177                                 break;
178                         case ATTR_TLS:
179 #ifdef HAVE_TLS
180                                 ldap_pvt_tls_config( &gopts, attrs[i].offset, opt );
181 #endif
182                                 break;
183                         }
184                 }
185         }
186
187         fclose(fp);
188 }
189
190 static void openldap_ldap_init_w_userconf(const char *file)
191 {
192         char *home;
193         char *path;
194
195         if (file == NULL) {
196                 /* no file name */
197                 return;
198         }
199
200         home = getenv("HOME");
201
202         if (home != NULL) {
203                 path = LDAP_MALLOC(strlen(home) + strlen(file) + 3);
204         } else {
205                 path = LDAP_MALLOC(strlen(file) + 3);
206         }
207
208         if(home != NULL && path != NULL) {
209                 /* we assume UNIX path syntax is used... */
210
211                 /* try ~/file */
212                 sprintf(path, "%s/%s", home, file);
213                 openldap_ldap_init_w_conf(path);
214
215                 /* try ~/.file */
216                 sprintf(path, "%s/.%s", home, file);
217                 openldap_ldap_init_w_conf(path);
218         }
219
220         if(path != NULL) {
221                 LDAP_FREE(path);
222         }
223
224         /* try file */
225         openldap_ldap_init_w_conf(file);
226 }
227
228 static void openldap_ldap_init_w_env(const char *prefix)
229 {
230         char buf[MAX_LDAP_ATTR_LEN+MAX_LDAP_ENV_PREFIX_LEN];
231         int len;
232         int i;
233         void *p;
234         char *value;
235
236         if (prefix == NULL) {
237                 prefix = LDAP_ENV_PREFIX;
238         }
239
240         strncpy(buf, prefix, MAX_LDAP_ENV_PREFIX_LEN);
241         buf[MAX_LDAP_ENV_PREFIX_LEN] = '\0';
242         len = strlen(buf);
243
244         for(i=0; attrs[i].type != ATTR_NONE; i++) {
245                 strcpy(&buf[len], attrs[i].name);
246                 value = getenv(buf);
247
248                 if(value == NULL) {
249                         continue;
250                 }
251
252                 switch(attrs[i].type) {
253                 case ATTR_BOOL:
254                         if((strcasecmp(value, "on") == 0) 
255                                 || (strcasecmp(value, "yes") == 0)
256                                 || (strcasecmp(value, "true") == 0))
257                         {
258                                 LDAP_BOOL_SET(&gopts, attrs[i].offset);
259
260                         } else {
261                                 LDAP_BOOL_CLR(&gopts, attrs[i].offset);
262                         }
263                         break;
264
265                 case ATTR_INT:
266                         p = &((char *) &gopts)[attrs[i].offset];
267                         * (int*) p = atoi(value);
268                         break;
269
270                 case ATTR_KV: {
271                                 const struct ol_keyvalue *kv;
272
273                                 for(kv = attrs[i].data;
274                                         kv->key != NULL;
275                                         kv++) {
276
277                                         if(strcasecmp(value, kv->key) == 0) {
278                                                 p = &((char *) &gopts)[attrs[i].offset];
279                                                 * (int*) p = kv->value;
280                                                 break;
281                                         }
282                                 }
283                         } break;
284
285                 case ATTR_STRING:
286                         p = &((char *) &gopts)[attrs[i].offset];
287                         if (* (char**) p != NULL) LDAP_FREE(* (char**) p);
288                         if (*value == '\0') {
289                                 * (char**) p = NULL;
290                         } else {
291                                 * (char**) p = LDAP_STRDUP(value);
292                         }
293                         break;
294                 case ATTR_TLS:
295 #ifdef HAVE_TLS
296                         ldap_pvt_tls_config( attrs[i].offset, value );
297 #endif                          
298                         break;
299                 }
300         }
301 }
302
303 void ldap_int_initialize( void )
304 {
305         if ( gopts.ldo_valid == LDAP_INITIALIZED ) {
306                 return;
307         }
308
309         ldap_int_utils_init();
310
311 #ifdef HAVE_TLS
312         ldap_pvt_tls_init();
313 #endif
314
315         if ( ldap_int_tblsize == 0 )
316                 ldap_int_ip_init();
317
318         gopts.ldo_debug = 0;
319
320         gopts.ldo_version =     LDAP_VERSION2;
321         gopts.ldo_deref =       LDAP_DEREF_NEVER;
322         gopts.ldo_timelimit = LDAP_NO_LIMIT;
323         gopts.ldo_sizelimit = LDAP_NO_LIMIT;
324
325         gopts.ldo_tm_api = (struct timeval *)NULL;
326         gopts.ldo_tm_net = (struct timeval *)NULL;
327
328         gopts.ldo_defhost = LDAP_STRDUP("localhost");
329         gopts.ldo_defport = LDAP_PORT;
330
331         gopts.ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
332
333         LDAP_BOOL_ZERO(&gopts);
334
335         LDAP_BOOL_SET(&gopts, LDAP_BOOL_REFERRALS);
336
337 #ifdef HAVE_TLS
338         gopts.ldo_tls_ctx = NULL;
339 #endif
340
341         gopts.ldo_valid = LDAP_INITIALIZED;
342
343         if( getenv("LDAPNOINIT") != NULL ) {
344                 return;
345         }
346
347         openldap_ldap_init_w_conf(LDAP_CONF_FILE);
348         openldap_ldap_init_w_userconf(LDAP_USERRC_FILE);
349
350         {
351                 char *altfile = getenv(LDAP_ENV_PREFIX "CONF");
352
353                 if( altfile != NULL ) {
354                         openldap_ldap_init_w_conf( altfile );
355                 }
356         }
357
358         {
359                 char *altfile = getenv(LDAP_ENV_PREFIX "RC");
360
361                 if( altfile != NULL ) {
362                         openldap_ldap_init_w_userconf( altfile );
363                 }
364         }
365
366         openldap_ldap_init_w_env(NULL);
367 }