]>
Commit | Line | Data |
---|---|---|
3d551623 PG |
1 | diff --git a/CHANGELOG b/CHANGELOG |
2 | index 6b16b0f..d66b8fc 100644 | |
3 | --- a/CHANGELOG | |
4 | +++ b/CHANGELOG | |
5 | @@ -3,6 +3,7 @@ | |
6 | - include krb5.h in lookup_ldap.h (some openssl doesn't implicitly include it). | |
7 | - correct initialization of local var in parse_server_string. | |
8 | - add missing "multi" map support. | |
9 | +- add multi nsswitch lookup. | |
10 | ||
11 | 18/06/2007 autofs-5.0.2 | |
12 | ----------------------- | |
13 | diff --git a/lib/master_parse.y b/lib/master_parse.y | |
14 | index f9cba05..ab2895d 100644 | |
15 | --- a/lib/master_parse.y | |
16 | +++ b/lib/master_parse.y | |
17 | @@ -45,6 +45,7 @@ extern void master_set_scan_buffer(const char *); | |
18 | static char *master_strdup(char *); | |
19 | static void local_init_vars(void); | |
20 | static void local_free_vars(void); | |
21 | +static void trim_maptype(char *); | |
22 | static int add_multi_mapstr(void); | |
23 | ||
24 | static int master_error(const char *s); | |
25 | @@ -141,21 +142,9 @@ line: | |
26 | } | |
27 | | PATH MULTITYPE maplist | |
28 | { | |
29 | - char *tmp; | |
30 | - | |
31 | - tmp = strchr($2, ':'); | |
32 | - if (tmp) | |
33 | - *tmp = '\0'; | |
34 | - else { | |
35 | - int len = strlen($2); | |
36 | - while (len-- && isblank($2[len])) | |
37 | - $2[len] = '\0'; | |
38 | - if (len < 4) { | |
39 | - master_notify($2); | |
40 | - local_free_vars(); | |
41 | - YYABORT; | |
42 | - } | |
43 | - } | |
44 | + char *tmp = NULL; | |
45 | + | |
46 | + trim_maptype($2); | |
47 | ||
48 | path = master_strdup($1); | |
49 | if (!path) { | |
50 | @@ -312,81 +301,93 @@ map: PATH | |
51 | YYABORT; | |
52 | } | |
53 | } | |
54 | - | MAPTYPE COLON PATH | |
55 | + | MAPTYPE PATH | |
56 | { | |
57 | char *tmp = NULL; | |
58 | ||
59 | + trim_maptype($1); | |
60 | + | |
61 | if ((tmp = strchr($1, ','))) | |
62 | *tmp++ = '\0'; | |
63 | ||
64 | type = master_strdup($1); | |
65 | if (!type) { | |
66 | + master_error("memory allocation error"); | |
67 | local_free_vars(); | |
68 | YYABORT; | |
69 | } | |
70 | if (tmp) { | |
71 | format = master_strdup(tmp); | |
72 | if (!format) { | |
73 | + master_error("memory allocation error"); | |
74 | local_free_vars(); | |
75 | YYABORT; | |
76 | } | |
77 | } | |
78 | tmp_argc++; | |
79 | - tmp_argv = add_argv(tmp_argc, tmp_argv, $3); | |
80 | + tmp_argv = add_argv(tmp_argc, tmp_argv, $2); | |
81 | if (!tmp_argv) { | |
82 | master_error("memory allocation error"); | |
83 | local_free_vars(); | |
84 | YYABORT; | |
85 | } | |
86 | } | |
87 | - | MAPTYPE COLON MAPNAME | |
88 | + | MAPTYPE MAPNAME | |
89 | { | |
90 | char *tmp = NULL; | |
91 | ||
92 | + trim_maptype($1); | |
93 | + | |
94 | if ((tmp = strchr($1, ','))) | |
95 | *tmp++ = '\0'; | |
96 | ||
97 | type = master_strdup($1); | |
98 | if (!type) { | |
99 | + master_error("memory allocation error"); | |
100 | local_free_vars(); | |
101 | YYABORT; | |
102 | } | |
103 | if (tmp) { | |
104 | format = master_strdup(tmp); | |
105 | if (!format) { | |
106 | + master_error("memory allocation error"); | |
107 | local_free_vars(); | |
108 | YYABORT; | |
109 | } | |
110 | } | |
111 | tmp_argc++; | |
112 | - tmp_argv = add_argv(tmp_argc, tmp_argv, $3); | |
113 | + tmp_argv = add_argv(tmp_argc, tmp_argv, $2); | |
114 | if (!tmp_argv) { | |
115 | master_error("memory allocation error"); | |
116 | local_free_vars(); | |
117 | YYABORT; | |
118 | } | |
119 | } | |
120 | - | MAPTYPE COLON dn | |
121 | + | MAPTYPE dn | |
122 | { | |
123 | char *tmp = NULL; | |
124 | ||
125 | + trim_maptype($1); | |
126 | + | |
127 | if ((tmp = strchr($1, ','))) | |
128 | *tmp++ = '\0'; | |
129 | ||
130 | type = master_strdup($1); | |
131 | if (!type) { | |
132 | + master_error("memory allocation error"); | |
133 | local_free_vars(); | |
134 | YYABORT; | |
135 | } | |
136 | if (tmp) { | |
137 | format = master_strdup(tmp); | |
138 | if (!format) { | |
139 | + master_error("memory allocation error"); | |
140 | local_free_vars(); | |
141 | YYABORT; | |
142 | } | |
143 | } | |
144 | tmp_argc++; | |
145 | - tmp_argv = add_argv(tmp_argc, tmp_argv, $3); | |
146 | + tmp_argv = add_argv(tmp_argc, tmp_argv, $2); | |
147 | if (!tmp_argv) { | |
148 | master_error("memory allocation error"); | |
149 | local_free_vars(); | |
150 | @@ -396,6 +397,7 @@ map: PATH | |
151 | if (*tmp_argv[0]) { | |
152 | tmp = malloc(strlen(type) + strlen(tmp_argv[0]) + 2); | |
153 | if (!tmp) { | |
154 | + master_error("memory allocation error"); | |
155 | local_free_vars(); | |
156 | YYABORT; | |
157 | } | |
158 | @@ -628,33 +630,47 @@ static void local_free_vars(void) | |
159 | } | |
160 | } | |
161 | ||
162 | -static int add_multi_mapstr(void) | |
163 | +static void trim_maptype(char *type) | |
164 | { | |
165 | - /* We need the individual map types for a multi map */ | |
166 | - if (!type) { | |
167 | - if (tmp_argc > 0 && *tmp_argv[0] == '/') | |
168 | - type = strdup("file"); | |
169 | - else | |
170 | - return 0; | |
171 | + char *tmp; | |
172 | + | |
173 | + tmp = strchr(type, ':'); | |
174 | + if (tmp) | |
175 | + *tmp = '\0'; | |
176 | + else { | |
177 | + int len = strlen(type); | |
178 | + while (len-- && isblank(type[len])) | |
179 | + type[len] = '\0'; | |
180 | } | |
181 | + return; | |
182 | +} | |
183 | + | |
184 | +static int add_multi_mapstr(void) | |
185 | +{ | |
186 | + if (type) { | |
187 | + /* If type given and format is non-null add it back */ | |
188 | + if (format) { | |
189 | + int len = strlen(type) + strlen(format) + 2; | |
190 | + char *tmp = realloc(type, len); | |
191 | + if (!tmp) | |
192 | + return 0; | |
193 | + type = tmp; | |
194 | + strcat(type, ","); | |
195 | + strcat(type, format); | |
196 | + free(format); | |
197 | + format = NULL; | |
198 | + } | |
199 | ||
200 | - if (format) { | |
201 | - char *tmp = realloc(type, strlen(type) + strlen(format) + 2); | |
202 | - if (!tmp) | |
203 | + local_argc++; | |
204 | + local_argv = add_argv(local_argc, local_argv, type); | |
205 | + if (!local_argv) { | |
206 | + free(type); | |
207 | + type = NULL; | |
208 | return 0; | |
209 | - type = tmp; | |
210 | - strcat(type, ","); | |
211 | - strcat(type, format); | |
212 | - free(format); | |
213 | - format = NULL; | |
214 | - } | |
215 | + } | |
216 | ||
217 | - local_argc++; | |
218 | - local_argv = add_argv(local_argc, local_argv, type); | |
219 | - if (!local_argv) { | |
220 | free(type); | |
221 | type = NULL; | |
222 | - return 0; | |
223 | } | |
224 | ||
225 | local_argv = append_argv(local_argc, local_argv, tmp_argc, tmp_argv); | |
226 | @@ -667,8 +683,6 @@ static int add_multi_mapstr(void) | |
227 | ||
228 | tmp_argc = 0; | |
229 | tmp_argv = NULL; | |
230 | - free(type); | |
231 | - type = NULL; | |
232 | ||
233 | return 1; | |
234 | } | |
235 | diff --git a/lib/master_tok.l b/lib/master_tok.l | |
236 | index 0548de1..9bfeefa 100644 | |
237 | --- a/lib/master_tok.l | |
238 | +++ b/lib/master_tok.l | |
239 | @@ -111,9 +111,9 @@ DNATTRSTR {AT_CN}|{AT_NMN}|{AT_AMN}|{AT_OU}|{AT_DC}|{AT_O}|{AT_C} | |
240 | DNNAMESTR ([[:alnum:]_.\-]+) | |
241 | ||
242 | INTMAP (-hosts|-null) | |
243 | -MULTI ((multi)(,(sun|hesiod))?[\:]?{OPTWS}) | |
244 | +MULTI ((multi)(,(sun|hesiod))?(:{OPTWS}|{WS})) | |
245 | MULTISEP ([\-]{2}[[:blank:]]+) | |
246 | -MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?) | |
247 | +MTYPE ((file|program|yp|nis|nisplus|ldap|ldaps|hesiod|userdir)(,(sun|hesiod))?(:{OPTWS}|{WS})) | |
248 | ||
249 | ||
250 | OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) | |
251 | @@ -192,7 +192,7 @@ OPTTOUT (-t{OPTWS}|-t{OPTWS}={OPTWS}|--timeout{OPTWS}|--timeout{OPTWS}={OPTWS}) | |
252 | return(MULTITYPE); | |
253 | } | |
254 | ||
255 | - {MTYPE}/":" { | |
256 | + {MTYPE} { | |
257 | strcpy(master_lval.strtype, master_text); | |
258 | return(MAPTYPE); | |
259 | } | |
260 | diff --git a/man/auto.master.5.in b/man/auto.master.5.in | |
261 | index 0e36a6f..98afaa9 100644 | |
262 | --- a/man/auto.master.5.in | |
263 | +++ b/man/auto.master.5.in | |
264 | @@ -103,6 +103,10 @@ entries are used for maps. | |
265 | .B ldap \fPor\fB ldaps | |
266 | The map is stored in an LDAP directory. If \fBldaps\fP is used the | |
267 | appropriate certificate must be configured in the LDAP client. | |
268 | +.TP | |
269 | +.B multi | |
270 | +This map type allows the specification of multiple maps separated | |
271 | +by "--". These maps are searched in order to resolve key lookups. | |
272 | .RE | |
273 | .TP | |
274 | \fBformat\fP | |
275 | diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c | |
276 | index 38ca36c..8fa94ae 100644 | |
277 | --- a/modules/lookup_multi.c | |
278 | +++ b/modules/lookup_multi.c | |
279 | @@ -19,6 +19,7 @@ | |
280 | #include <stdio.h> | |
281 | #include <string.h> | |
282 | #include <unistd.h> | |
283 | +#include <sys/stat.h> | |
284 | ||
285 | #define MODULE_LOOKUP | |
286 | #include "automount.h" | |
287 | @@ -28,7 +29,7 @@ | |
288 | ||
289 | struct module_info { | |
290 | int argc; | |
291 | - const char *const *argv; | |
292 | + const char **argv; | |
293 | struct lookup_mod *mod; | |
294 | }; | |
295 | ||
296 | @@ -40,11 +41,105 @@ struct lookup_context { | |
297 | ||
298 | int lookup_version = AUTOFS_LOOKUP_VERSION; /* Required by protocol */ | |
299 | ||
300 | +static struct lookup_mod *nss_open_lookup(const char *format, int argc, const char **argv) | |
301 | +{ | |
302 | + struct list_head nsslist; | |
303 | + struct list_head *head, *p; | |
304 | + struct lookup_mod *mod; | |
305 | + char buf[MAX_ERR_BUF], *estr; | |
306 | + | |
307 | + if (!argv || !argv[0]) | |
308 | + return NULL; | |
309 | + | |
310 | + if (*argv[0] == '/') | |
311 | + return open_lookup("file", MODPREFIX, format, argc, argv); | |
312 | + | |
313 | + if (!strncmp(argv[0], "file", 4) || | |
314 | + !strncmp(argv[0], "yp", 2) || | |
315 | + !strncmp(argv[0], "nisplus", 7) || | |
316 | + !strncmp(argv[0], "nis", 3) || | |
317 | + !strncmp(argv[0], "ldaps", 5) || | |
318 | + !strncmp(argv[0], "ldap", 4)) { | |
319 | + const char *fmt = strchr(argv[0], ','); | |
320 | + if (fmt) | |
321 | + fmt++; | |
322 | + else | |
323 | + fmt = format; | |
324 | + return open_lookup(argv[0], MODPREFIX, fmt, argc -1, argv + 1); | |
325 | + } | |
326 | + | |
327 | + INIT_LIST_HEAD(&nsslist); | |
328 | + | |
329 | + if (nsswitch_parse(&nsslist)) { | |
330 | + if (!list_empty(&nsslist)) | |
331 | + free_sources(&nsslist); | |
332 | + error(LOGOPT_ANY, "can't to read name service switch config."); | |
333 | + return NULL; | |
334 | + } | |
335 | + | |
336 | + head = &nsslist; | |
337 | + list_for_each(p, head) { | |
338 | + struct nss_source *this; | |
339 | + | |
340 | + this = list_entry(p, struct nss_source, list); | |
341 | + | |
342 | + if (!strcmp(this->source, "files")) { | |
343 | + char src_file[] = "file"; | |
344 | + char src_prog[] = "program"; | |
345 | + struct stat st; | |
346 | + char *type, *path, *save_argv0; | |
347 | + | |
348 | + path = malloc(strlen(AUTOFS_MAP_DIR) + strlen(argv[0]) + 2); | |
349 | + if (!path) { | |
350 | + estr = strerror_r(errno, buf, MAX_ERR_BUF); | |
351 | + crit(LOGOPT_ANY, MODPREFIX "error: %s", estr); | |
352 | + free_sources(&nsslist); | |
353 | + return NULL; | |
354 | + } | |
355 | + strcpy(path, AUTOFS_MAP_DIR); | |
356 | + strcat(path, "/"); | |
357 | + strcat(path, argv[0]); | |
358 | + | |
359 | + if (stat(path, &st) == -1 || !S_ISREG(st.st_mode)) { | |
360 | + free(path); | |
361 | + continue; | |
362 | + } | |
363 | + | |
364 | + if (st.st_mode & __S_IEXEC) | |
365 | + type = src_prog; | |
366 | + else | |
367 | + type = src_file; | |
368 | + | |
369 | + save_argv0 = (char *) argv[0]; | |
370 | + argv[0] = path; | |
371 | + | |
372 | + mod = open_lookup(type, MODPREFIX, format, argc, argv); | |
373 | + if (mod) { | |
374 | + free_sources(&nsslist); | |
375 | + free(save_argv0); | |
376 | + return mod; | |
377 | + } | |
378 | + | |
379 | + argv[0] = save_argv0; | |
380 | + free(path); | |
381 | + } | |
382 | + | |
383 | + mod = open_lookup(this->source, MODPREFIX, format, argc, argv); | |
384 | + if (mod) { | |
385 | + free_sources(&nsslist); | |
386 | + return mod; | |
387 | + } | |
388 | + } | |
389 | + free_sources(&nsslist); | |
390 | + | |
391 | + return NULL; | |
392 | +} | |
393 | + | |
394 | int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void **context) | |
395 | { | |
396 | struct lookup_context *ctxt; | |
397 | char buf[MAX_ERR_BUF]; | |
398 | - char *map, *mapfmt; | |
399 | + char **args; | |
400 | int i, an; | |
401 | char *estr; | |
402 | ||
403 | @@ -73,39 +168,42 @@ int lookup_init(const char *my_mapfmt, int argc, const char *const *argv, void * | |
404 | ||
405 | memcpy(ctxt->argl, argv, (argc + 1) * sizeof(const char *)); | |
406 | ||
407 | + args = NULL; | |
408 | for (i = an = 0; ctxt->argl[an]; an++) { | |
409 | if (ctxt->m[i].argc == 0) { | |
410 | - ctxt->m[i].argv = &ctxt->argl[an]; | |
411 | + args = (char **) &ctxt->argl[an]; | |
412 | } | |
413 | if (!strcmp(ctxt->argl[an], "--")) { | |
414 | ctxt->argl[an] = NULL; | |
415 | + if (!args) { | |
416 | + crit(LOGOPT_ANY, | |
417 | + MODPREFIX "error assigning map args"); | |
418 | + goto error_out; | |
419 | + } | |
420 | + ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args); | |
421 | + if (!ctxt->m[i].argv) | |
422 | + goto nomem; | |
423 | + args = NULL; | |
424 | i++; | |
425 | } else { | |
426 | ctxt->m[i].argc++; | |
427 | } | |
428 | } | |
429 | ||
430 | - for (i = 0; i < ctxt->n; i++) { | |
431 | - if (!ctxt->m[i].argv[0]) { | |
432 | - crit(LOGOPT_ANY, MODPREFIX "missing module name"); | |
433 | - goto error_out; | |
434 | - } | |
435 | - map = strdup(ctxt->m[i].argv[0]); | |
436 | - if (!map) | |
437 | + /* catch the last one */ | |
438 | + if (args) { | |
439 | + ctxt->m[i].argv = copy_argv(ctxt->m[i].argc, (const char **) args); | |
440 | + if (!ctxt->m[i].argv) | |
441 | goto nomem; | |
442 | + } | |
443 | ||
444 | - if ((mapfmt = strchr(map, ','))) | |
445 | - *(mapfmt++) = '\0'; | |
446 | - | |
447 | - if (!(ctxt->m[i].mod = open_lookup(map, MODPREFIX, | |
448 | - mapfmt ? mapfmt : my_mapfmt, | |
449 | - ctxt->m[i].argc - 1, | |
450 | - ctxt->m[i].argv + 1))) { | |
451 | + for (i = 0; i < ctxt->n; i++) { | |
452 | + ctxt->m[i].mod = nss_open_lookup(my_mapfmt, | |
453 | + ctxt->m[i].argc, ctxt->m[i].argv); | |
454 | + if (!ctxt->m[i].mod) { | |
455 | error(LOGOPT_ANY, MODPREFIX "error opening module"); | |
456 | - free(map); | |
457 | goto error_out; | |
458 | } | |
459 | - free(map); | |
460 | } | |
461 | ||
462 | *context = ctxt; | |
463 | @@ -116,9 +214,12 @@ nomem: | |
464 | crit(LOGOPT_ANY, MODPREFIX "error: %s", estr); | |
465 | error_out: | |
466 | if (ctxt) { | |
467 | - for (i = 0; i < ctxt->n; i++) | |
468 | + for (i = 0; i < ctxt->n; i++) { | |
469 | if (ctxt->m[i].mod) | |
470 | close_lookup(ctxt->m[i].mod); | |
471 | + if (ctxt->m[i].argv) | |
472 | + free_argv(ctxt->m[i].argc, ctxt->m[i].argv); | |
473 | + } | |
474 | if (ctxt->m) | |
475 | free(ctxt->m); | |
476 | if (ctxt->argl) | |
477 | @@ -188,6 +289,8 @@ int lookup_done(void *context) | |
478 | for (i = 0; i < ctxt->n; i++) { | |
479 | if (ctxt->m[i].mod) | |
480 | rv = rv || close_lookup(ctxt->m[i].mod); | |
481 | + if (ctxt->m[i].argv) | |
482 | + free_argv(ctxt->m[i].argc, ctxt->m[i].argv); | |
483 | } | |
484 | free(ctxt->argl); | |
485 | free(ctxt->m); |