]> git.pld-linux.org Git - packages/autofs.git/blame - autofs-5.0.2-add-multi-nsswitch-lookup.patch
- rel.1, lets try
[packages/autofs.git] / autofs-5.0.2-add-multi-nsswitch-lookup.patch
CommitLineData
3d551623
PG
1diff --git a/CHANGELOG b/CHANGELOG
2index 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 -----------------------
13diff --git a/lib/master_parse.y b/lib/master_parse.y
14index 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 }
235diff --git a/lib/master_tok.l b/lib/master_tok.l
236index 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 }
260diff --git a/man/auto.master.5.in b/man/auto.master.5.in
261index 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
275diff --git a/modules/lookup_multi.c b/modules/lookup_multi.c
276index 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);
This page took 0.689999 seconds and 4 git commands to generate.