- fix uri list locking (again). - check for stale SASL credentials upon connect fail. - add "forcestart" and "forcerestart" init script options to allow use of 5.0.3 strartup behavior if required. - always read entire file map into cache to speed lookups. - make MAX_ERR_BUF and PARSE_MAX_BUF use easier to audit. - make some easy alloca replacements. - update to configure libtirpc if present. - update to provide ipv6 name and address support. - update to provide ipv6 address parsing.
463 lines
11 KiB
Diff
463 lines
11 KiB
Diff
autofs-5.0.4 - ipv6 parse
|
|
|
|
From: Ian Kent <raven@themaw.net>
|
|
|
|
Since ipv6 addresses use a colon separator and we use the colon quite a
|
|
bit as a delimiting character we need to distinguish between when the
|
|
colon is the delimeter we are looking for and when it is part of an ipv6
|
|
address. Since there is widespread use of "[" and "]" to provide the
|
|
ability to separate a port specification from an ipv6 address this
|
|
convention has also been used in autofs.
|
|
---
|
|
|
|
CHANGELOG | 1
|
|
include/parse_subs.h | 8 +++
|
|
lib/master_tok.l | 10 ++--
|
|
lib/parse_subs.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++---
|
|
modules/lookup_file.c | 40 +++++++------------
|
|
modules/lookup_ldap.c | 21 ++++++++--
|
|
modules/mount_autofs.c | 29 +++++---------
|
|
modules/parse_sun.c | 16 ++++---
|
|
modules/replicated.c | 26 +++++++++++-
|
|
9 files changed, 187 insertions(+), 63 deletions(-)
|
|
|
|
|
|
--- autofs-5.0.4.orig/include/parse_subs.h
|
|
+++ autofs-5.0.4/include/parse_subs.h
|
|
@@ -20,6 +20,12 @@
|
|
|
|
struct mapent;
|
|
|
|
+struct map_type_info {
|
|
+ char *type;
|
|
+ char *format;
|
|
+ char *map;
|
|
+};
|
|
+
|
|
const char *skipspace(const char *);
|
|
int check_colon(const char *);
|
|
int chunklen(const char *, int);
|
|
@@ -27,5 +33,7 @@ int strmcmp(const char *, const char *,
|
|
char *dequote(const char *, int, unsigned int);
|
|
int span_space(const char *, unsigned int);
|
|
char *sanitize_path(const char *, int, unsigned int, unsigned int);
|
|
+void free_map_type_info(struct map_type_info *);
|
|
+struct map_type_info *parse_map_type_info(const char *);
|
|
|
|
#endif
|
|
--- autofs-5.0.4.orig/lib/master_tok.l
|
|
+++ autofs-5.0.4/lib/master_tok.l
|
|
@@ -96,10 +96,12 @@ SLASHIFYSTR (--(no-)?slashify-colons)
|
|
NUMBER [0-9]+
|
|
|
|
DNSERVSTR1 ([[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?:)
|
|
-DNSERVSTR2 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
|
|
-DNSERVSTR3 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
|
|
-DNSERVSTR4 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
|
|
-DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4})
|
|
+DNSERVSTR2 (\[([[:xdigit:]]:.)+\](:[0-9]+)?:)
|
|
+DNSERVSTR3 (\/\/[[:alpha:]][[:alnum:]\-.]*(:[0-9]+)?\/)
|
|
+DNSERVSTR4 (\/\/\[([[:xdigit:]]:.)+\](:[0-9]+)?\/)
|
|
+DNSERVSTR5 (([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?:)
|
|
+DNSERVSTR6 (\/\/([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}(:[0-9]+)?\/)
|
|
+DNSERVERSTR ({DNSERVSTR1}|{DNSERVSTR2}|{DNSERVSTR3}|{DNSERVSTR4}|{DNSERVSTR5}|{DNSERVSTR6})
|
|
|
|
AT_CN ([cC][[nN])
|
|
AT_NMN ([nN][iI][sS][Mm][aA][pP][Nn][aA][mM][eE])
|
|
--- autofs-5.0.4.orig/lib/parse_subs.c
|
|
+++ autofs-5.0.4/lib/parse_subs.c
|
|
@@ -56,14 +56,13 @@ int check_colon(const char *str)
|
|
char *ptr = (char *) str;
|
|
|
|
/* Colon escape */
|
|
- if (*ptr == ':')
|
|
+ if (!strncmp(ptr, ":/", 2))
|
|
return 1;
|
|
|
|
- while (*ptr && *ptr != ':' && *ptr != '/') {
|
|
+ while (*ptr && strncmp(ptr, ":/", 2))
|
|
ptr++;
|
|
- }
|
|
|
|
- if (!*ptr || *ptr == '/')
|
|
+ if (!*ptr)
|
|
return 0;
|
|
|
|
return 1;
|
|
@@ -93,12 +92,12 @@ int chunklen(const char *whence, int exp
|
|
n++;
|
|
if (*str == '"')
|
|
break;
|
|
- if (*str == ':')
|
|
+ if (!strncmp(str, ":/", 2))
|
|
expect_colon = 0;
|
|
}
|
|
break;
|
|
case ':':
|
|
- if (expect_colon)
|
|
+ if (expect_colon && !strncmp(str, ":/", 2))
|
|
expect_colon = 0;
|
|
continue;
|
|
case ' ':
|
|
@@ -300,3 +299,91 @@ char *sanitize_path(const char *path, in
|
|
return s_path;
|
|
}
|
|
|
|
+void free_map_type_info(struct map_type_info *info)
|
|
+{
|
|
+ if (info->type)
|
|
+ free(info->type);
|
|
+ if (info->format)
|
|
+ free(info->format);
|
|
+ if (info->map)
|
|
+ free(info->map);
|
|
+ free(info);
|
|
+ return;
|
|
+}
|
|
+
|
|
+struct map_type_info *parse_map_type_info(const char *str)
|
|
+{
|
|
+ struct map_type_info *info;
|
|
+ char *buf, *type, *fmt, *map, *tmp;
|
|
+
|
|
+ buf = strdup(str);
|
|
+ if (!buf)
|
|
+ return NULL;
|
|
+
|
|
+ info = malloc(sizeof(struct map_type_info));
|
|
+ if (!info) {
|
|
+ free(buf);
|
|
+ return NULL;
|
|
+ }
|
|
+ memset(info, 0, sizeof(struct map_type_info));
|
|
+
|
|
+ type = fmt = NULL;
|
|
+
|
|
+ /* Look for space terminator - ignore local options */
|
|
+ map = buf;
|
|
+ for (tmp = buf; *tmp; tmp++) {
|
|
+ if (*tmp == ' ') {
|
|
+ *tmp = '\0';
|
|
+ break;
|
|
+ } else if (*tmp == ',') {
|
|
+ type = buf;
|
|
+ *tmp++ = '\0';
|
|
+ fmt = tmp;
|
|
+ } else if (*tmp == ':') {
|
|
+ if (!fmt)
|
|
+ type = buf;
|
|
+ *tmp++ = '\0';
|
|
+ map = tmp;
|
|
+ } else if (*tmp == '[') {
|
|
+ /*
|
|
+ * Unescaped '[' is a syntax error here as only
|
|
+ * an ldap map with a type specified should contain
|
|
+ * them.
|
|
+ */
|
|
+ free(buf);
|
|
+ return 0;
|
|
+ }
|
|
+ if (*tmp == '\\')
|
|
+ tmp++;
|
|
+ }
|
|
+
|
|
+ if (type) {
|
|
+ info->type = strdup(type);
|
|
+ if (!info->type) {
|
|
+ free(buf);
|
|
+ free_map_type_info(info);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ if (fmt) {
|
|
+ info->format = strdup(fmt);
|
|
+ if (!info->format) {
|
|
+ free(buf);
|
|
+ free_map_type_info(info);
|
|
+ return NULL;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ info->map = strdup(map);
|
|
+ if (!info->map) {
|
|
+ free(buf);
|
|
+ free_map_type_info(info);
|
|
+ return NULL;
|
|
+ }
|
|
+
|
|
+ free(buf);
|
|
+
|
|
+ return info;
|
|
+}
|
|
+
|
|
--- autofs-5.0.4.orig/modules/lookup_file.c
|
|
+++ autofs-5.0.4/modules/lookup_file.c
|
|
@@ -523,10 +523,10 @@ prepare_plus_include(struct autofs_point
|
|
{
|
|
struct map_source *current;
|
|
struct map_source *source;
|
|
- char *type, *map, *fmt;
|
|
+ struct map_type_info *info;
|
|
const char *argv[2];
|
|
int argc;
|
|
- char *buf, *tmp;
|
|
+ char *buf;
|
|
|
|
current = ap->entry->current;
|
|
ap->entry->current = NULL;
|
|
@@ -548,33 +548,19 @@ prepare_plus_include(struct autofs_point
|
|
return NULL;
|
|
}
|
|
|
|
- type = fmt = NULL;
|
|
-
|
|
- /* Look for space terminator - ignore local options */
|
|
- map = buf;
|
|
- for (tmp = buf; *tmp; tmp++) {
|
|
- if (*tmp == ' ') {
|
|
- *tmp = '\0';
|
|
- break;
|
|
- } else if (*tmp == ',') {
|
|
- type = buf;
|
|
- *tmp++ = '\0';
|
|
- fmt = tmp;
|
|
- } else if (*tmp == ':') {
|
|
- if (!fmt)
|
|
- type = buf;
|
|
- *tmp++ = '\0';
|
|
- map = tmp;
|
|
- }
|
|
- if (*tmp == '\\')
|
|
- tmp++;
|
|
+ if (!(info = parse_map_type_info(buf))) {
|
|
+ error(ap->logopt, MODPREFIX "failed to parse map info");
|
|
+ free(buf);
|
|
+ return NULL;
|
|
}
|
|
|
|
argc = 1;
|
|
- argv[0] = map;
|
|
+ argv[0] = info->map;
|
|
argv[1] = NULL;
|
|
|
|
- source = master_find_source_instance(current, type, fmt, argc, argv);
|
|
+ source = master_find_source_instance(current,
|
|
+ info->type, info->format,
|
|
+ argc, argv);
|
|
if (source)
|
|
/*
|
|
* Make sure included map age is in sync with its owner
|
|
@@ -582,8 +568,11 @@ prepare_plus_include(struct autofs_point
|
|
*/
|
|
source->age = age;
|
|
else {
|
|
- source = master_add_source_instance(current, type, fmt, age, argc, argv);
|
|
+ source = master_add_source_instance(current,
|
|
+ info->type, info->format,
|
|
+ age, argc, argv);
|
|
if (!source) {
|
|
+ free_map_type_info(info);
|
|
free(buf);
|
|
error(ap->logopt, "failed to add included map instance");
|
|
return NULL;
|
|
@@ -594,6 +583,7 @@ prepare_plus_include(struct autofs_point
|
|
if (inc)
|
|
source->recurse = 1;
|
|
|
|
+ free_map_type_info(info);
|
|
free(buf);
|
|
|
|
return source;
|
|
--- autofs-5.0.4.orig/modules/lookup_ldap.c
|
|
+++ autofs-5.0.4/modules/lookup_ldap.c
|
|
@@ -1119,11 +1119,26 @@ static int parse_server_string(unsigned
|
|
memcpy(ctxt->server, s, l);
|
|
*/
|
|
}
|
|
- } else if (strchr(ptr, ':') != NULL) {
|
|
- char *q = NULL;
|
|
+ } else if (strchr(ptr, ':') != NULL || *ptr == '[') {
|
|
+ const char *q = NULL;
|
|
|
|
/* Isolate the server. Include the port spec */
|
|
- q = strchr(ptr, ':');
|
|
+ if (*ptr != '[')
|
|
+ q = strchr(ptr, ':');
|
|
+ else {
|
|
+ q = ++ptr;
|
|
+ while (*q == ':' || isxdigit(*q))
|
|
+ q++;
|
|
+ if (*q != ']') {
|
|
+ crit(logopt, MODPREFIX
|
|
+ "invalid LDAP map syntax %s", ptr);
|
|
+ return 0;
|
|
+ }
|
|
+ q++;
|
|
+ if (*q == ':')
|
|
+ q++;
|
|
+ }
|
|
+
|
|
if (isdigit(*q))
|
|
while (isdigit(*q))
|
|
q++;
|
|
--- autofs-5.0.4.orig/modules/mount_autofs.c
|
|
+++ autofs-5.0.4/modules/mount_autofs.c
|
|
@@ -50,7 +50,7 @@ int mount_mount(struct autofs_point *ap,
|
|
int argc, status, ghost = ap->flags & MOUNT_FLAG_GHOST;
|
|
time_t timeout = ap->exp_timeout;
|
|
unsigned logopt = ap->logopt;
|
|
- char *type, *format, *tmp, *tmp2;
|
|
+ struct map_type_info *info;
|
|
struct master *master;
|
|
struct master_mapent *entry;
|
|
struct map_source *source;
|
|
@@ -174,21 +174,12 @@ int mount_mount(struct autofs_point *ap,
|
|
|
|
argc = 1;
|
|
|
|
- type = NULL;
|
|
- format = NULL;
|
|
-
|
|
- tmp = strchr(what, ':');
|
|
- if (tmp) {
|
|
- *tmp++ = '\0';
|
|
- tmp2 = strchr(what, ',');
|
|
- if (tmp2) {
|
|
- *tmp2++ = '\0';
|
|
- format = tmp2;
|
|
- }
|
|
- type = (char *) what;
|
|
- argv[0] = tmp;
|
|
- } else
|
|
- argv[0] = (char *) what;
|
|
+ if (!(info = parse_map_type_info(what))) {
|
|
+ error(ap->logopt, MODPREFIX "failed to parse map info");
|
|
+ master_free_mapent(entry);
|
|
+ return 1;
|
|
+ }
|
|
+ argv[0] = info->map;
|
|
|
|
if (options) {
|
|
p = options;
|
|
@@ -202,13 +193,17 @@ int mount_mount(struct autofs_point *ap,
|
|
}
|
|
argv[argc] = NULL;
|
|
|
|
- source = master_add_map_source(entry, type, format, time(NULL), argc, argv);
|
|
+ source = master_add_map_source(entry,
|
|
+ info->type, info->format,
|
|
+ time(NULL), argc, argv);
|
|
if (!source) {
|
|
error(ap->logopt,
|
|
MODPREFIX "failed to add map source to entry");
|
|
master_free_mapent(entry);
|
|
+ free_map_type_info(info);
|
|
return 1;
|
|
}
|
|
+ free_map_type_info(info);
|
|
|
|
source->mc = cache_init(entry->ap, source);
|
|
if (!source->mc) {
|
|
--- autofs-5.0.4.orig/modules/parse_sun.c
|
|
+++ autofs-5.0.4/modules/parse_sun.c
|
|
@@ -245,7 +245,9 @@ int expandsunent(const char *src, char *
|
|
*(dst++) =
|
|
(seen_colons && slashify_colons) ? '/' : ':';
|
|
len++;
|
|
- seen_colons = 1;
|
|
+ /* Were looking for the colon preceeding a path */
|
|
+ if (*src == '/')
|
|
+ seen_colons = 1;
|
|
break;
|
|
|
|
default:
|
|
@@ -814,21 +816,23 @@ static int validate_location(char *loc)
|
|
return 1;
|
|
|
|
/*
|
|
- * If a ':' is present now it must be a host name, except
|
|
+ * If a ':/' is present now it must be a host name, except
|
|
* for those special file systems like sshfs which use "#"
|
|
- * and "@" in the host name part.
|
|
+ * and "@" in the host name part and ipv6 addresses that
|
|
+ * have ":", "[" and "]".
|
|
*/
|
|
if (check_colon(ptr)) {
|
|
- while (*ptr && *ptr != ':') {
|
|
+ while (*ptr && strncmp(ptr, ":/", 2)) {
|
|
if (!(isalnum(*ptr) ||
|
|
*ptr == '-' || *ptr == '.' || *ptr == '_' ||
|
|
*ptr == ',' || *ptr == '(' || *ptr == ')' ||
|
|
- *ptr == '#' || *ptr == '@'))
|
|
+ *ptr == '#' || *ptr == '@' || *ptr == ':' ||
|
|
+ *ptr == '[' || *ptr == ']'))
|
|
return 0;
|
|
ptr++;
|
|
}
|
|
|
|
- if (*ptr && *ptr == ':')
|
|
+ if (*ptr && !strncmp(ptr, ":/", 2))
|
|
ptr++;
|
|
}
|
|
|
|
--- autofs-5.0.4.orig/modules/replicated.c
|
|
+++ autofs-5.0.4/modules/replicated.c
|
|
@@ -1168,6 +1168,28 @@ static int add_local_path(struct host **
|
|
return 1;
|
|
}
|
|
|
|
+static char *seek_delim(const char *s)
|
|
+{
|
|
+ const char *p = s;
|
|
+ char *delim;
|
|
+
|
|
+ delim = strpbrk(p, "(, \t:");
|
|
+ if (delim && *delim != ':')
|
|
+ return delim;
|
|
+
|
|
+ while (*p) {
|
|
+ if (*p != ':') {
|
|
+ p++;
|
|
+ continue;
|
|
+ }
|
|
+ if (!strncmp(p, ":/", 2))
|
|
+ return (char *) p;
|
|
+ p++;
|
|
+ }
|
|
+
|
|
+ return NULL;
|
|
+}
|
|
+
|
|
int parse_location(unsigned logopt, struct host **hosts, const char *list)
|
|
{
|
|
char *str, *p, *delim;
|
|
@@ -1187,7 +1209,7 @@ int parse_location(unsigned logopt, stru
|
|
int weight = 0;
|
|
|
|
p += strspn(p, " \t,");
|
|
- delim = strpbrk(p, "(, \t:");
|
|
+ delim = seek_delim(p);
|
|
|
|
if (delim) {
|
|
if (*delim == '(') {
|
|
@@ -1211,7 +1233,7 @@ int parse_location(unsigned logopt, stru
|
|
|
|
/* Oh boy - might have spaces in the path */
|
|
next = path;
|
|
- while (*next && *next != ':')
|
|
+ while (*next && strncmp(next, ":/", 2))
|
|
next++;
|
|
|
|
/* No spaces in host names at least */
|
|
--- autofs-5.0.4.orig/CHANGELOG
|
|
+++ autofs-5.0.4/CHANGELOG
|
|
@@ -19,6 +19,7 @@
|
|
- make some easy alloca replacements (Valerie Aurora Henson).
|
|
- update to configure libtirpc if present.
|
|
- update to provide ipv6 name and address support.
|
|
+- update to provide ipv6 address parsing.
|
|
|
|
4/11/2008 autofs-5.0.4
|
|
-----------------------
|