]> git.pld-linux.org Git - packages/autofs.git/blob - autofs-5.0.4-ipv6-parse.patch
- updated to 5.0.5, nfy.
[packages/autofs.git] / autofs-5.0.4-ipv6-parse.patch
1 autofs-5.0.4 - ipv6 parse
2
3 From: Ian Kent <raven@themaw.net>
4
5 Since ipv6 addresses use a colon separator and we use the colon quite a
6 bit as a delimiting character we need to distinguish between when the
7 colon is the delimeter we are looking for and when it is part of an ipv6
8 address. Since there is widespread use of "[" and "]" to provide the
9 ability to separate a port specification from an ipv6 address this
10 convention has also been used in autofs.
11 ---
12
13  include/parse_subs.h   |    8 ++++
14  lib/master_tok.l       |   10 +++--
15  lib/parse_subs.c       |   99 +++++++++++++++++++++++++++++++++++++++++++++---
16  modules/lookup_file.c  |   40 +++++++------------
17  modules/lookup_ldap.c  |   21 +++++++++-
18  modules/mount_autofs.c |   29 ++++++--------
19  modules/parse_sun.c    |   16 +++++---
20  modules/replicated.c   |   26 ++++++++++++-
21  8 files changed, 186 insertions(+), 63 deletions(-)
22
23
24 diff --git a/include/parse_subs.h b/include/parse_subs.h
25 index 643ad68..ecc712d 100644
26 --- a/include/parse_subs.h
27 +++ b/include/parse_subs.h
28 @@ -20,6 +20,12 @@
29  
30  struct mapent;
31  
32 +struct map_type_info {
33 +       char *type;
34 +       char *format;
35 +       char *map;
36 +};
37 +
38  const char *skipspace(const char *);
39  int check_colon(const char *);
40  int chunklen(const char *, int);
41 @@ -27,5 +33,7 @@ int strmcmp(const char *, const char *, int);
42  char *dequote(const char *, int, unsigned int);
43  int span_space(const char *, unsigned int);
44  char *sanitize_path(const char *, int, unsigned int, unsigned int);
45 +void free_map_type_info(struct map_type_info *);
46 +struct map_type_info *parse_map_type_info(const char *);
47  
48  #endif
49 diff --git a/lib/master_tok.l b/lib/master_tok.l
50 index 801aa6f..b6cc8be 100644
51 --- a/lib/master_tok.l
52 +++ b/lib/master_tok.l
53 @@ -96,10 +96,12 @@ SLASHIFYSTR (--(no-)?slashify-colons)
54  NUMBER         [0-9]+
55  
56  DNSERVSTR1     ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:)
57 -DNSERVSTR2     (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
58 -DNSERVSTR3     (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
59 -DNSERVSTR4     (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
60 -DNSERVERSTR    ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4})
61 +DNSERVSTR2     (\[([[:xdigit:]]:.)+\](:[0-9]+)?:)
62 +DNSERVSTR3     (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
63 +DNSERVSTR4     (\/\/\[([[:xdigit:]]:.)+\](:[0-9]+)?\/)
64 +DNSERVSTR5     (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
65 +DNSERVSTR6     (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
66 +DNSERVERSTR    ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}|{DNSERVSTR5}|{DNSERVSTR6})
67  
68  AT_CN          ([cC][[nN])
69  AT_NMN         ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE])
70 diff --git a/lib/parse_subs.c b/lib/parse_subs.c
71 index 8a032e8..0cba95a 100644
72 --- a/lib/parse_subs.c
73 +++ b/lib/parse_subs.c
74 @@ -56,14 +56,13 @@ int check_colon(const char *str)
75         char *ptr = (char *) str;
76  
77         /* Colon escape */
78 -       if (*ptr == ':')
79 +       if (!strncmp(ptr, ":/", 2))
80                 return 1;
81  
82 -       while (*ptr && *ptr != ':' && *ptr != '/') {
83 +       while (*ptr && strncmp(ptr, ":/", 2))
84                 ptr++;
85 -       }
86  
87 -       if (!*ptr || *ptr == '/')
88 +       if (!*ptr)
89                 return 0;
90  
91         return 1;
92 @@ -93,12 +92,12 @@ int chunklen(const char *whence, int expect_colon)
93                                 n++;
94                                 if (*str == '"')
95                                         break;
96 -                               if (*str == ':')
97 +                               if (!strncmp(str, ":/", 2))
98                                         expect_colon = 0;
99                         }
100                         break;
101                 case ':':
102 -                       if (expect_colon)
103 +                       if (expect_colon && !strncmp(str, ":/", 2))
104                                 expect_colon = 0;
105                         continue;
106                 case ' ':
107 @@ -300,3 +299,91 @@ char *sanitize_path(const char *path, int origlen, unsigned int type, unsigned i
108         return s_path;
109  }
110  
111 +void free_map_type_info(struct map_type_info *info)
112 +{
113 +       if (info->type)
114 +               free(info->type);
115 +       if (info->format)
116 +               free(info->format);
117 +       if (info->map)
118 +               free(info->map);
119 +       free(info);
120 +       return;
121 +}
122 +
123 +struct map_type_info *parse_map_type_info(const char *str)
124 +{
125 +       struct map_type_info *info;
126 +       char *buf, *type, *fmt, *map, *tmp;
127 +
128 +       buf = strdup(str);
129 +       if (!buf)
130 +               return NULL;
131 +
132 +       info = malloc(sizeof(struct map_type_info));
133 +       if (!info) {
134 +               free(buf);
135 +               return NULL;
136 +       }
137 +       memset(info, 0, sizeof(struct map_type_info));
138 +
139 +       type = fmt = NULL;
140 +
141 +       /* Look for space terminator - ignore local options */
142 +       map = buf;
143 +       for (tmp = buf; *tmp; tmp++) {
144 +               if (*tmp == ' ') {
145 +                       *tmp = '\0';
146 +                       break;
147 +               } else if (*tmp == ',') {
148 +                       type = buf;
149 +                       *tmp++ = '\0';
150 +                       fmt = tmp;
151 +               } else if (*tmp == ':') {
152 +                       if (!fmt)
153 +                               type = buf;
154 +                       *tmp++ = '\0';
155 +                       map = tmp;
156 +               } else if (*tmp == '[') {
157 +                       /*
158 +                        * Unescaped '[' is a syntax error here as only
159 +                        * an ldap map with a type specified should contain
160 +                        * them. 
161 +                        */
162 +                       free(buf);
163 +                       return 0;
164 +               }
165 +               if (*tmp == '\\')
166 +                       tmp++;
167 +       }
168 +
169 +       if (type) {
170 +               info->type = strdup(type);
171 +               if (!info->type) {
172 +                       free(buf);
173 +                       free_map_type_info(info);
174 +                       return NULL;
175 +               }
176 +       }
177 +
178 +       if (fmt) {
179 +               info->format = strdup(fmt);
180 +               if (!info->format) {
181 +                       free(buf);
182 +                       free_map_type_info(info);
183 +                       return NULL;
184 +               }
185 +       }
186 +
187 +       info->map = strdup(map);
188 +       if (!info->map) {
189 +               free(buf);
190 +               free_map_type_info(info);
191 +               return NULL;
192 +       }
193 +
194 +       free(buf);
195 +
196 +       return info;
197 +}
198 +
199 diff --git a/modules/lookup_file.c b/modules/lookup_file.c
200 index ba80f2a..ec78090 100644
201 --- a/modules/lookup_file.c
202 +++ b/modules/lookup_file.c
203 @@ -523,10 +523,10 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in
204  {
205         struct map_source *current;
206         struct map_source *source;
207 -       char *type, *map, *fmt;
208 +       struct map_type_info *info;
209         const char *argv[2];
210         int argc;
211 -       char *buf, *tmp;
212 +       char *buf;
213  
214         current = ap->entry->current;
215         ap->entry->current = NULL;
216 @@ -548,33 +548,19 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in
217                 return NULL;
218         }
219  
220 -       type = fmt = NULL;
221 -
222 -       /* Look for space terminator - ignore local options */
223 -       map = buf;
224 -       for (tmp = buf; *tmp; tmp++) {
225 -               if (*tmp == ' ') {
226 -                       *tmp = '\0';
227 -                       break;
228 -               } else if (*tmp == ',') {
229 -                       type = buf;
230 -                       *tmp++ = '\0';
231 -                       fmt = tmp;
232 -               } else if (*tmp == ':') {
233 -                       if (!fmt)
234 -                               type = buf;
235 -                       *tmp++ = '\0';
236 -                       map = tmp;
237 -               }
238 -               if (*tmp == '\\')
239 -                       tmp++;
240 +       if (!(info = parse_map_type_info(buf))) {
241 +               error(ap->logopt, MODPREFIX "failed to parse map info");
242 +               free(buf);
243 +               return NULL;
244         }
245  
246         argc = 1;
247 -       argv[0] = map;
248 +       argv[0] = info->map;
249         argv[1] = NULL;
250  
251 -       source = master_find_source_instance(current, type, fmt, argc, argv);
252 +       source = master_find_source_instance(current,
253 +                                            info->type, info->format,
254 +                                            argc, argv);
255         if (source)
256                 /*
257                  * Make sure included map age is in sync with its owner
258 @@ -582,8 +568,11 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in
259                  */
260                 source->age = age;
261         else {
262 -               source = master_add_source_instance(current, type, fmt, age, argc, argv);
263 +               source = master_add_source_instance(current,
264 +                                                   info->type, info->format,
265 +                                                   age, argc, argv);
266                 if (!source) {
267 +                       free_map_type_info(info);
268                         free(buf);
269                         error(ap->logopt, "failed to add included map instance");
270                         return NULL;
271 @@ -594,6 +583,7 @@ prepare_plus_include(struct autofs_point *ap, time_t age, char *key, unsigned in
272         if (inc)
273                 source->recurse = 1;
274  
275 +       free_map_type_info(info);
276         free(buf);
277  
278         return source;
279 diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
280 index 094cbdc..7845bcf 100644
281 --- a/modules/lookup_ldap.c
282 +++ b/modules/lookup_ldap.c
283 @@ -1119,11 +1119,26 @@ static int parse_server_string(unsigned logopt, const char *url, struct lookup_c
284                         memcpy(ctxt->server, s, l);
285  */
286                 }
287 -       } else if (strchr(ptr, ':') != NULL) {
288 -               char *q = NULL;
289 +       } else if (strchr(ptr, ':') != NULL || *ptr == '[') {
290 +               const char *q = NULL;
291  
292                 /* Isolate the server. Include the port spec */
293 -               q = strchr(ptr, ':');
294 +               if (*ptr != '[')
295 +                       q = strchr(ptr, ':');
296 +               else {
297 +                       q = ++ptr;
298 +                       while (*q == ':' || isxdigit(*q))
299 +                               q++;
300 +                       if (*q != ']') {
301 +                               crit(logopt, MODPREFIX
302 +                                    "invalid LDAP map syntax %s", ptr);
303 +                               return 0;
304 +                       }
305 +                       q++;
306 +                       if (*q == ':')
307 +                               q++;
308 +               }
309 +
310                 if (isdigit(*q))
311                         while (isdigit(*q))
312                                 q++;
313 diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
314 index fab2906..14d6307 100644
315 --- a/modules/mount_autofs.c
316 +++ b/modules/mount_autofs.c
317 @@ -50,7 +50,7 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
318         int argc, status, ghost = ap->flags & MOUNT_FLAG_GHOST;
319         time_t timeout = ap->exp_timeout;
320         unsigned logopt = ap->logopt;
321 -       char *type, *format, *tmp, *tmp2;
322 +       struct map_type_info *info;
323         struct master *master;
324         struct master_mapent *entry;
325         struct map_source *source;
326 @@ -174,21 +174,12 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
327  
328         argc = 1;
329  
330 -       type = NULL;
331 -       format = NULL;
332 -
333 -       tmp = strchr(what, ':');
334 -       if (tmp) {
335 -               *tmp++ = '\0';
336 -               tmp2 = strchr(what, ',');
337 -               if (tmp2) {
338 -                       *tmp2++ = '\0';
339 -                       format = tmp2;
340 -               }
341 -               type = (char *) what;
342 -               argv[0] = tmp;
343 -       } else
344 -               argv[0] = (char *) what;
345 +       if (!(info = parse_map_type_info(what))) {
346 +               error(ap->logopt, MODPREFIX "failed to parse map info");
347 +               master_free_mapent(entry);
348 +               return 1;
349 +       }
350 +       argv[0] = info->map;
351  
352         if (options) {
353                 p = options;
354 @@ -202,13 +193,17 @@ int mount_mount(struct autofs_point *ap, const char *root, const char *name,
355         }
356         argv[argc] = NULL;
357  
358 -       source = master_add_map_source(entry, type, format, time(NULL), argc, argv);
359 +       source = master_add_map_source(entry,
360 +                                      info->type, info->format,
361 +                                      time(NULL), argc, argv);
362         if (!source) {
363                 error(ap->logopt,
364                       MODPREFIX "failed to add map source to entry");
365                 master_free_mapent(entry);
366 +               free_map_type_info(info);
367                 return 1;
368         }
369 +       free_map_type_info(info);
370  
371         source->mc = cache_init(entry->ap, source);
372         if (!source->mc) {
373 diff --git a/modules/parse_sun.c b/modules/parse_sun.c
374 index ed73e46..65417e1 100644
375 --- a/modules/parse_sun.c
376 +++ b/modules/parse_sun.c
377 @@ -245,7 +245,9 @@ int expandsunent(const char *src, char *dst, const char *key,
378                                 *(dst++) = 
379                                   (seen_colons && slashify_colons) ? '/' : ':';
380                         len++;
381 -                       seen_colons = 1;
382 +                       /* Were looking for the colon preceeding a path */
383 +                       if (*src == '/')
384 +                               seen_colons = 1;
385                         break;
386  
387                 default:
388 @@ -814,21 +816,23 @@ static int validate_location(char *loc)
389                 return 1;
390  
391         /*
392 -        * If a ':' is present now it must be a host name, except
393 +        * If a ':/' is present now it must be a host name, except
394          * for those special file systems like sshfs which use "#"
395 -        * and "@" in the host name part.
396 +        * and "@" in the host name part and ipv6 addresses that
397 +        * have ":", "[" and "]".
398          */
399         if (check_colon(ptr)) {
400 -               while (*ptr && *ptr != ':') {
401 +               while (*ptr && strncmp(ptr, ":/", 2)) {
402                         if (!(isalnum(*ptr) ||
403                             *ptr == '-' || *ptr == '.' || *ptr == '_' ||
404                             *ptr == ',' || *ptr == '(' || *ptr == ')' ||
405 -                           *ptr == '#' || *ptr == '@'))
406 +                           *ptr == '#' || *ptr == '@' || *ptr == ':' ||
407 +                           *ptr == '[' || *ptr == ']'))
408                                 return 0;
409                         ptr++;
410                 }
411  
412 -               if (*ptr && *ptr == ':')
413 +               if (*ptr && !strncmp(ptr, ":/", 2))
414                         ptr++;
415         }
416  
417 diff --git a/modules/replicated.c b/modules/replicated.c
418 index 9e85c00..79845d0 100644
419 --- a/modules/replicated.c
420 +++ b/modules/replicated.c
421 @@ -1168,6 +1168,28 @@ static int add_local_path(struct host **hosts, const char *path)
422         return 1;
423  }
424  
425 +static char *seek_delim(const char *s)
426 +{
427 +       const char *p = s;
428 +       char *delim;
429 +
430 +       delim = strpbrk(p, "(, \t:");
431 +       if (delim && *delim != ':')
432 +               return delim;
433 +
434 +       while (*p) {
435 +               if (*p != ':') {
436 +                       p++;
437 +                       continue;
438 +               }
439 +               if (!strncmp(p, ":/", 2))
440 +                       return (char *) p;
441 +               p++;
442 +       }
443 +
444 +       return NULL;
445 +}
446 +
447  int parse_location(unsigned logopt, struct host **hosts, const char *list)
448  {
449         char *str, *p, *delim;
450 @@ -1187,7 +1209,7 @@ int parse_location(unsigned logopt, struct host **hosts, const char *list)
451                 int weight = 0;
452  
453                 p += strspn(p, " \t,");
454 -               delim = strpbrk(p, "(, \t:");
455 +               delim = seek_delim(p);
456  
457                 if (delim) {
458                         if (*delim == '(') {
459 @@ -1211,7 +1233,7 @@ int parse_location(unsigned logopt, struct host **hosts, const char *list)
460  
461                                 /* Oh boy - might have spaces in the path */
462                                 next = path;
463 -                               while (*next && *next != ':')
464 +                               while (*next && strncmp(next, ":/", 2))
465                                         next++;
466  
467                                 /* No spaces in host names at least */
This page took 0.093931 seconds and 3 git commands to generate.