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