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