]> git.pld-linux.org Git - packages/autofs.git/blob - autofs-5.0.2-add-multi-nsswitch-lookup.patch
45e44b2c9001c299baeeb27da72ae267765df022
[packages/autofs.git] / autofs-5.0.2-add-multi-nsswitch-lookup.patch
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);
This page took 0.054138 seconds and 2 git commands to generate.