]> git.sur5r.net Git - openldap/blob - libraries/libldap/init.c
Commit preliminary fix for ldap.conf base usage.
[openldap] / libraries / libldap / init.c
1 #include "portable.h"
2
3 #include <stdio.h>
4 #include <stdlib.h>
5
6 #include <ac/socket.h>
7 #include <ac/string.h>
8 #include <ac/ctype.h>
9 #include <ac/time.h>
10
11 #include "ldap-int.h"
12 #include "ldapconfig.h"
13
14 struct ldapoptions openldap_ldap_global_options; 
15
16 #undef gopts
17 #define gopts openldap_ldap_global_options
18
19 int     openldap_ldap_initialized = 0;
20
21 #define ATTR_NONE       0
22 #define ATTR_BOOL       1
23 #define ATTR_INT        2
24 #define ATTR_KV         3
25 #define ATTR_STRING     4
26
27 struct ol_keyvalue {
28         char*           key;
29         int                     value;
30 };
31
32 static struct ol_keyvalue deref_kv[] = {
33         {"never", LDAP_DEREF_NEVER},
34         {"searching", LDAP_DEREF_SEARCHING},
35         {"finding", LDAP_DEREF_FINDING},
36         {"always", LDAP_DEREF_ALWAYS},
37         {NULL, 0}
38 };
39
40 static struct ol_attribute {
41         int                     type;
42         char*           name;
43         void*           data;
44         size_t          offset;
45 } attrs[] = {
46         {ATTR_KV,               "DEREF",        deref_kv, /* or &deref_kv[0] */
47                 offsetof(struct ldapoptions, ldo_deref)},
48         {ATTR_INT,              "SIZELIMIT",    NULL,
49                 offsetof(struct ldapoptions, ldo_sizelimit)},
50         {ATTR_INT,              "TIMELIMIT",    NULL,
51                 offsetof(struct ldapoptions, ldo_timelimit)},
52         {ATTR_STRING,   "BASE",                 NULL,
53                 offsetof(struct ldapoptions, ldo_defbase)},
54         {ATTR_STRING,   "HOST",                 NULL,
55                 offsetof(struct ldapoptions, ldo_defhost)},
56         {ATTR_INT,              "PORT",                 NULL,
57                 offsetof(struct ldapoptions, ldo_defport)},
58         {ATTR_BOOL,             "REFERRALS",    (void *) LDAP_BOOL_REFERRALS, 0},
59         {ATTR_BOOL,             "RESTART",              (void *) LDAP_BOOL_RESTART, 0},
60         {ATTR_BOOL,             "DNS",                  (void *) LDAP_BOOL_DNS, 0},
61         {ATTR_NONE,             NULL,           NULL,   0}
62 };
63
64 #define MAX_LDAP_ATTR_LEN  sizeof("SIZELIMIT")
65 #define MAX_LDAP_ENV_PREFIX_LEN 8
66
67 static void openldap_ldap_init_w_conf(const char *file)
68 {
69         char linebuf[128];
70         FILE *fp;
71         int i;
72         char *cmd, *opt;
73         char *start, *end;
74
75         if (file == NULL) {
76                 /* no file name */
77                 return;
78         }
79
80         fp = fopen(file, "r");
81         if(fp == NULL) {
82                 /* could not open file */
83                 return;
84         }
85
86         while((start = fgets(linebuf, sizeof(linebuf), fp)) != NULL) {
87                 /* skip lines starting with '#' */
88                 if(*start == '#') continue;
89
90                 /* trim leading white space */
91                 while((*start != '\0') && isspace(*start)) start++;
92
93                 /* anything left? */
94                 if(*start == '\0') continue;
95
96                 /* trim trailing white space */
97                 end = &start[strlen(start)-1];
98                 while(isspace(*end)) end--;
99                 end[1] = '\0';
100
101                 /* anything left? */
102                 if(*start == '\0') continue;
103                 
104
105                 /* parse the command */
106                 cmd=start;
107                 while((*start != '\0') && !isspace(*start)) {
108                         start++;
109                 }
110                 if(*start == '\0') {
111                         /* command has no argument */
112                         continue;
113                 } 
114
115                 *start++ = '\0';
116
117                 /* we must have some non-whitespace to skip */
118                 while(isspace(*start)) start++;
119                 opt = start;
120
121                 for(i=0; attrs[i].type != ATTR_NONE; i++) {
122                         void *p;
123
124                         if(strcasecmp(cmd, attrs[i].name) != 0) {
125                                 continue;
126                         }
127
128                         p = &((char *) &gopts)[attrs[i].offset];
129
130                         switch(attrs[i].type) {
131                         case ATTR_BOOL:
132                                 if((strcasecmp(opt, "on") == 0) 
133                                         || (strcasecmp(opt, "yes") == 0)
134                                         || (strcasecmp(opt, "true") == 0))
135                                 {
136                                         LDAP_BOOL_SET(&gopts, (int) attrs[i].data);
137
138                                 } else {
139                                         LDAP_BOOL_CLR(&gopts, (int) attrs[i].data);
140                                 }
141
142                                 break;
143
144                         case ATTR_INT:
145                                 * (int*) p = atoi(opt);
146                                 break;
147
148                         case ATTR_KV: {
149                                         struct ol_keyvalue *kv;
150
151                                         for(kv = (struct ol_keyvalue *) attrs[i].data;
152                                                 kv->key != NULL;
153                                                 kv++) {
154
155                                                 if(strcasecmp(opt, kv->key) == 0) {
156                                                         * (int*) p = kv->value;
157                                                         break;
158                                                 }
159                                         }
160                                 } break;
161
162                         case ATTR_STRING:
163                                 if (* (char**) p != NULL) free(* (char**) p);
164                                 * (char**) p = ldap_strdup(opt);
165                                 break;
166                         }
167                 }
168         }
169 }
170
171 static void openldap_ldap_init_w_userconf(const char *file)
172 {
173         char *home;
174         char *path;
175
176         if (file == NULL) {
177                 /* no file name */
178                 return;
179         }
180
181         home = getenv("HOME");
182
183         if (home != NULL) {
184                 path = malloc(strlen(home) + strlen(file) + 3);
185         } else {
186                 path = malloc(strlen(file) + 3);
187         }
188
189         if(home != NULL && path != NULL) {
190                 /* we assume UNIX path syntax is used... */
191
192                 /* try ~/file */
193                 sprintf(path, "%s/%s", home, file);
194                 openldap_ldap_init_w_conf(path);
195
196                 /* try ~/.file */
197                 sprintf(path, "%s/.%s", home, file);
198                 openldap_ldap_init_w_conf(path);
199         }
200
201         if(path != NULL) {
202                 free(path);
203         }
204
205         /* try file */
206         openldap_ldap_init_w_conf(file);
207 }
208
209 static void openldap_ldap_init_w_env(const char *prefix)
210 {
211         char buf[MAX_LDAP_ATTR_LEN+MAX_LDAP_ENV_PREFIX_LEN];
212         int len;
213         int i;
214         void *p;
215         char *value;
216
217         if (prefix == NULL) {
218                 prefix = DEFAULT_LDAP_ENV_PREFIX;
219         }
220
221         strncpy(buf, prefix, MAX_LDAP_ENV_PREFIX_LEN);
222         buf[MAX_LDAP_ENV_PREFIX_LEN] = '\0';
223         len = strlen(buf);
224
225         for(i=0; attrs[i].type != ATTR_NONE; i++) {
226                 strcpy(&buf[len], attrs[i].name);
227                 value = getenv(buf);
228
229                 if(value == NULL) {
230                         continue;
231                 }
232
233                 p = &((char *) &gopts)[attrs[i].offset];
234
235                 switch(attrs[i].type) {
236                 case ATTR_BOOL:
237                         if((strcasecmp(value, "on") == 0) 
238                                 || (strcasecmp(value, "yes") == 0)
239                                 || (strcasecmp(value, "true") == 0))
240                         {
241                                 LDAP_BOOL_SET(&gopts, (int) attrs[i].data);
242
243                         } else {
244                                 LDAP_BOOL_CLR(&gopts, (int) attrs[i].data);
245                         }
246                         break;
247
248                 case ATTR_INT:
249                         * (int*) p = atoi(value);
250                         break;
251
252                 case ATTR_KV: {
253                                 struct ol_keyvalue *kv;
254
255                                 for(kv = (struct ol_keyvalue *) attrs[i].data;
256                                         kv->key != NULL;
257                                         kv++) {
258
259                                         if(strcasecmp(value, kv->key) == 0) {
260                                                 * (int*) p = kv->value;
261                                                 break;
262                                         }
263                                 }
264                         } break;
265
266                 case ATTR_STRING:
267                         if (* (char**) p != NULL) free(* (char**) p);
268                         if (*value == '\0') {
269                                 * (char**) p = NULL;
270                         } else {
271                                 * (char**) p = ldap_strdup(value);
272                         }
273                         break;
274                 }
275         }
276 }
277
278 void openldap_ldap_initialize( void )
279 {
280         if ( openldap_ldap_initialized ) {
281                 return;
282         }
283
284         gopts.ldo_version =     LDAP_VERSION2;
285         gopts.ldo_deref =       LDAP_DEREF_NEVER;
286         gopts.ldo_timelimit = LDAP_NO_LIMIT;
287         gopts.ldo_sizelimit = LDAP_NO_LIMIT;
288
289         gopts.ldo_defhost = ldap_strdup("localhost");
290         gopts.ldo_defport = LDAP_PORT;
291
292         gopts.ldo_refhoplimit = LDAP_DEFAULT_REFHOPLIMIT;
293
294         LDAP_BOOL_ZERO(&gopts);
295
296 #if defined( LDAP_API_FEATURE_X_OPENLDAP_V2_REFERRALS ) || \
297         LDAP_VERSION_MAX > LDAP_VERSION2
298         LDAP_BOOL_SET(&gopts, LDAP_BOOL_REFERRALS);
299 #endif
300
301         openldap_ldap_init_w_conf(DEFAULT_LDAP_CONF_FILE);
302         openldap_ldap_init_w_userconf(DEFAULT_LDAP_USERRC_FILE);
303
304         {
305                 char *altfile = getenv("LDAPRC");
306
307                 if( altfile != NULL ) {
308                         openldap_ldap_init_w_conf( altfile );
309                 }
310         }
311
312         openldap_ldap_init_w_env(NULL);
313
314         openldap_ldap_initialized = 1;
315 }