Ian Kent a347ae
autofs-5.0.4 - fix map type info parse error update
Ian Kent a347ae
Ian Kent a347ae
From: Ian Kent <raven@themaw.net>
Ian Kent a347ae
Ian Kent a347ae
Make parsing map type info more robust.
Ian Kent a347ae
---
Ian Kent a347ae
Ian Kent a347ae
 lib/parse_subs.c |  123 +++++++++++++++++++++++++++++++++++++++++++++---------
Ian Kent a347ae
 1 files changed, 102 insertions(+), 21 deletions(-)
Ian Kent a347ae
Ian Kent a347ae
Ian Kent a347ae
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
Ian Kent a347ae
index 0608cb7..2326838 100644
Ian Kent a347ae
--- a/lib/parse_subs.c
Ian Kent a347ae
+++ b/lib/parse_subs.c
Ian Kent a347ae
@@ -20,6 +20,30 @@
Ian Kent a347ae
 #include <ctype.h>
Ian Kent a347ae
 #include "automount.h"
Ian Kent a347ae
 
Ian Kent a347ae
+struct types {
Ian Kent a347ae
+	char *type;
Ian Kent a347ae
+	unsigned int len;
Ian Kent a347ae
+};
Ian Kent a347ae
+
Ian Kent a347ae
+static struct types map_type[] = {
Ian Kent a347ae
+	{ "file", 4 },
Ian Kent a347ae
+	{ "program", 7 },
Ian Kent a347ae
+	{ "yp", 2 },
Ian Kent a347ae
+	{ "nis", 3 },
Ian Kent a347ae
+	{ "nisplus", 7 },
Ian Kent a347ae
+	{ "ldap", 4 },
Ian Kent a347ae
+	{ "ldaps", 5 },
Ian Kent a347ae
+	{ "hesiod", 6 },
Ian Kent a347ae
+	{ "userdir", 7 },
Ian Kent a347ae
+};
Ian Kent a347ae
+static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types);
Ian Kent a347ae
+
Ian Kent a347ae
+static struct types format_type[] = {
Ian Kent a347ae
+	{ "sun", 3 },
Ian Kent a347ae
+	{ "hesiod", 6 },
Ian Kent a347ae
+};
Ian Kent a347ae
+static unsigned int format_type_count = sizeof(format_type)/sizeof(struct types);
Ian Kent a347ae
+
Ian Kent a347ae
 /*
Ian Kent a347ae
  * Skip whitespace in a string; if we hit a #, consider the rest of the
Ian Kent a347ae
  * entry a comment.
Ian Kent a347ae
@@ -315,7 +339,7 @@ struct map_type_info *parse_map_type_info(const char *str)
Ian Kent a347ae
 {
Ian Kent a347ae
 	struct map_type_info *info;
Ian Kent a347ae
 	char *buf, *type, *fmt, *map, *tmp;
Ian Kent a347ae
-	int seen_colon = 0;
Ian Kent a347ae
+	char *pos;
Ian Kent a347ae
 
Ian Kent a347ae
 	buf = strdup(str);
Ian Kent a347ae
 	if (!buf)
Ian Kent a347ae
@@ -328,32 +352,89 @@ struct map_type_info *parse_map_type_info(const char *str)
Ian Kent a347ae
 	}
Ian Kent a347ae
 	memset(info, 0, sizeof(struct map_type_info));
Ian Kent a347ae
 
Ian Kent a347ae
-	type = fmt = NULL;
Ian Kent a347ae
+	type = fmt = map = NULL;
Ian Kent a347ae
+
Ian Kent a347ae
+	tmp = strchr(buf, ':');
Ian Kent a347ae
+	if (!tmp) {
Ian Kent a347ae
+		pos = buf;
Ian Kent a347ae
+		while (*pos == ' ')
Ian Kent a347ae
+			*pos++ = '\0';
Ian Kent a347ae
+		map = pos;
Ian Kent a347ae
+	} else {
Ian Kent a347ae
+		int i, j;
Ian Kent a347ae
+
Ian Kent a347ae
+		for (i = 0; i < map_type_count; i++) {
Ian Kent a347ae
+			char *m_type = map_type[i].type;
Ian Kent a347ae
+			unsigned int m_len = map_type[i].len;
Ian Kent a347ae
+
Ian Kent a347ae
+			pos = buf;
Ian Kent a347ae
+
Ian Kent a347ae
+			if (strncmp(m_type, pos, m_len))
Ian Kent a347ae
+				continue;
Ian Kent a347ae
+
Ian Kent a347ae
+			type = pos;
Ian Kent a347ae
+			pos += m_len;
Ian Kent a347ae
+
Ian Kent a347ae
+			if (*pos == ' ' || *pos == ':') {
Ian Kent a347ae
+				while (*pos == ' ')
Ian Kent a347ae
+					*pos++ = '\0';
Ian Kent a347ae
+				if (*pos != ':') {
Ian Kent a347ae
+					free(buf);
Ian Kent a347ae
+					free(info);
Ian Kent a347ae
+					return NULL;
Ian Kent a347ae
+				} else {
Ian Kent a347ae
+					*pos++ = '\0';
Ian Kent a347ae
+					while (*pos == ' ')
Ian Kent a347ae
+						*pos++ = '\0';
Ian Kent a347ae
+					map = pos;
Ian Kent a347ae
+					break;
Ian Kent a347ae
+				}
Ian Kent a347ae
+			}
Ian Kent a347ae
+
Ian Kent a347ae
+			if (*pos == ',') {
Ian Kent a347ae
+				*pos++ = '\0';
Ian Kent a347ae
+				for (j = 0; j < format_type_count; j++) {
Ian Kent a347ae
+					char *f_type = format_type[j].type;
Ian Kent a347ae
+					unsigned int f_len = format_type[j].len;
Ian Kent a347ae
+				
Ian Kent a347ae
+					if (strncmp(f_type, pos, f_len))
Ian Kent a347ae
+						continue;
Ian Kent a347ae
+
Ian Kent a347ae
+					fmt = pos;
Ian Kent a347ae
+					pos += f_len;
Ian Kent a347ae
+
Ian Kent a347ae
+					if (*pos == ' ' || *pos == ':') {
Ian Kent a347ae
+						while (*pos == ' ')
Ian Kent a347ae
+							*pos++ = '\0';
Ian Kent a347ae
+						if (*pos != ':') {
Ian Kent a347ae
+							free(buf);
Ian Kent a347ae
+							free(info);
Ian Kent a347ae
+							return NULL;
Ian Kent a347ae
+						} else {
Ian Kent a347ae
+							*pos++ = '\0';
Ian Kent a347ae
+							while (*pos == ' ')
Ian Kent a347ae
+								*pos++ = '\0';
Ian Kent a347ae
+							map = pos;
Ian Kent a347ae
+							break;
Ian Kent a347ae
+						}
Ian Kent a347ae
+					}
Ian Kent a347ae
+				}
Ian Kent a347ae
+			}
Ian Kent a347ae
+		}
Ian Kent a347ae
+
Ian Kent a347ae
+		if (!type) {
Ian Kent a347ae
+			pos = buf;
Ian Kent a347ae
+			while (*pos == ' ')
Ian Kent a347ae
+				*pos++ = '\0';
Ian Kent a347ae
+			map = pos;
Ian Kent a347ae
+		}
Ian Kent a347ae
+	}
Ian Kent a347ae
 
Ian Kent a347ae
 	/* Look for space terminator - ignore local options */
Ian Kent a347ae
-	map = buf;
Ian Kent a347ae
 	for (tmp = buf; *tmp; tmp++) {
Ian Kent a347ae
 		if (*tmp == ' ') {
Ian Kent a347ae
 			*tmp = '\0';
Ian Kent a347ae
 			break;
Ian Kent a347ae
-		} else if (!seen_colon && *tmp == ',') {
Ian Kent a347ae
-			type = buf;
Ian Kent a347ae
-			*tmp++ = '\0';
Ian Kent a347ae
-			fmt = tmp;
Ian Kent a347ae
-		} else if (*tmp == ':') {
Ian Kent a347ae
-			seen_colon = 1;
Ian Kent a347ae
-			if (!fmt)
Ian Kent a347ae
-				type = buf;
Ian Kent a347ae
-			*tmp++ = '\0';
Ian Kent a347ae
-			map = tmp;
Ian Kent a347ae
-		} else if (*tmp == '[') {
Ian Kent a347ae
-			/*
Ian Kent a347ae
-			 * Unescaped '[' is a syntax error here as only
Ian Kent a347ae
-			 * an ldap map with a type specified should contain
Ian Kent a347ae
-			 * them. 
Ian Kent a347ae
-			 */
Ian Kent a347ae
-			free(buf);
Ian Kent a347ae
-			return 0;
Ian Kent a347ae
 		}
Ian Kent a347ae
 		if (*tmp == '\\')
Ian Kent a347ae
 			tmp++;