]> git.pld-linux.org Git - packages/autofs.git/blame - autofs-5.0.4-ipv6-parse.patch
- updated to 5.0.5, nfy.
[packages/autofs.git] / autofs-5.0.4-ipv6-parse.patch
CommitLineData
e5fd101c
PS
1autofs-5.0.4 - ipv6 parse
2
3From: Ian Kent <raven@themaw.net>
4
5Since ipv6 addresses use a colon separator and we use the colon quite a
6bit as a delimiting character we need to distinguish between when the
7colon is the delimeter we are looking for and when it is part of an ipv6
8address. Since there is widespread use of "[" and "]" to provide the
9ability to separate a port specification from an ipv6 address this
10convention 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
24diff --git a/include/parse_subs.h b/include/parse_subs.h
25index 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
49diff --git a/lib/master_tok.l b/lib/master_tok.l
50index 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])
70diff --git a/lib/parse_subs.c b/lib/parse_subs.c
71index 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+
199diff --git a/modules/lookup_file.c b/modules/lookup_file.c
200index 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;
279diff --git a/modules/lookup_ldap.c b/modules/lookup_ldap.c
280index 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++;
313diff --git a/modules/mount_autofs.c b/modules/mount_autofs.c
314index 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) {
373diff --git a/modules/parse_sun.c b/modules/parse_sun.c
374index 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
417diff --git a/modules/replicated.c b/modules/replicated.c
418index 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.074511 seconds and 4 git commands to generate.