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