Blame SOURCES/autofs-5.0.7-allow-use-of-hosts-map-in-maps.patch

304803
autofs-5.0.7 - allow use of hosts map in maps
304803
304803
From: Ian Kent <raven@themaw.net>
304803
304803
At the moment the internal hosts map can only be use as an entry in the
304803
master map but there's no reason (I can think of so far) that it shouldn't
304803
be possible to use it in map entries.
304803
---
304803
 lib/parse_subs.c       |   17 ++++++-----
304803
 modules/mount_autofs.c |   29 ++++++++++++++++----
304803
 modules/parse_sun.c    |   71 +++++++++++++++++++++++++++++++------------------
304803
 3 files changed, 80 insertions(+), 37 deletions(-)
304803
304803
--- autofs-5.0.7.orig/lib/parse_subs.c
304803
+++ autofs-5.0.7/lib/parse_subs.c
304803
@@ -35,6 +35,7 @@ static struct types map_type[] = {
304803
 	{ "ldaps", 5 },
304803
 	{ "hesiod", 6 },
304803
 	{ "userdir", 7 },
304803
+	{ "hosts", 5 },
304803
 };
304803
 static unsigned int map_type_count = sizeof(map_type)/sizeof(struct types);
304803
 
304803
@@ -384,7 +385,7 @@ struct map_type_info *parse_map_type_inf
304803
 					return NULL;
304803
 				} else {
304803
 					*pos++ = '\0';
304803
-					while (*pos == ' ')
304803
+					while (*pos && *pos == ' ')
304803
 						*pos++ = '\0';
304803
 					map = pos;
304803
 					break;
304803
@@ -412,7 +413,7 @@ struct map_type_info *parse_map_type_inf
304803
 							return NULL;
304803
 						} else {
304803
 							*pos++ = '\0';
304803
-							while (*pos == ' ')
304803
+							while (*pos && *pos == ' ')
304803
 								*pos++ = '\0';
304803
 							map = pos;
304803
 							break;
304803
@@ -458,11 +459,13 @@ struct map_type_info *parse_map_type_inf
304803
 		}
304803
 	}
304803
 
304803
-	info->map = strdup(map);
304803
-	if (!info->map) {
304803
-		free(buf);
304803
-		free_map_type_info(info);
304803
-		return NULL;
304803
+	if (map) {
304803
+		info->map = strdup(map);
304803
+		if (!info->map) {
304803
+			free(buf);
304803
+			free_map_type_info(info);
304803
+			return NULL;
304803
+		}
304803
 	}
304803
 
304803
 	free(buf);
304803
--- autofs-5.0.7.orig/modules/mount_autofs.c
304803
+++ autofs-5.0.7/modules/mount_autofs.c
304803
@@ -62,6 +62,7 @@ int mount_mount(struct autofs_point *ap,
304803
 	char buf[MAX_ERR_BUF];
304803
 	char *options, *p;
304803
 	int len, ret;
304803
+	int hosts = 0;
304803
 
304803
 	/* Root offset of multi-mount */
304803
 	len = strlen(root);
304803
@@ -123,6 +124,8 @@ int mount_mount(struct autofs_point *ap,
304803
 				ghost = 1;
304803
 			else if (strncmp(cp, "symlink", 7) == 0)
304803
 				symlnk = 1;
304803
+			else if (strncmp(cp, "hosts", 5) == 0)
304803
+				hosts = 1;
304803
 			else if (strncmp(cp, "timeout=", 8) == 0) {
304803
 				char *val = strchr(cp, '=');
304803
 				unsigned tout;
304803
@@ -164,7 +167,10 @@ int mount_mount(struct autofs_point *ap,
304803
 	if (symlnk)
304803
 		nap->flags |= MOUNT_FLAG_SYMLINK;
304803
 
304803
-	argc = 1;
304803
+	if (hosts)
304803
+		argc = 0;
304803
+	else
304803
+		argc = 1;
304803
 
304803
 	if (options) {
304803
 		char *t = options;
304803
@@ -176,14 +182,27 @@ int mount_mount(struct autofs_point *ap,
304803
 	}
304803
 	argv = (const char **) alloca((argc + 1) * sizeof(char *));
304803
 
304803
-	argc = 1;
304803
-
304803
-	if (!(info = parse_map_type_info(what))) {
304803
+	if (hosts)
304803
+		argc = 0;
304803
+	else
304803
+		argc = 1;
304803
+
304803
+	/*
304803
+	 * If a mount of a hosts map is being requested it will come
304803
+	 * ro us via the options. Catch that below when processing the
304803
+	 * option and create type info struct then.
304803
+	 */
304803
+	if (hosts)
304803
+		info = parse_map_type_info("hosts:");
304803
+	else
304803
+		info = parse_map_type_info(what);
304803
+	if (!info) {
304803
 		error(ap->logopt, MODPREFIX "failed to parse map info");
304803
 		master_free_mapent(entry);
304803
 		return 1;
304803
 	}
304803
-	argv[0] = info->map;
304803
+	if (info->map)
304803
+		argv[0] = info->map;
304803
 
304803
 	if (options) {
304803
 		p = options;
304803
--- autofs-5.0.7.orig/modules/parse_sun.c
304803
+++ autofs-5.0.7/modules/parse_sun.c
304803
@@ -695,14 +695,18 @@ static int sun_mount(struct autofs_point
304803
 		rv = mount_nfs->mount_mount(ap, root, mountpoint, strlen(mountpoint),
304803
 					    what, fstype, options, mount_nfs->context);
304803
 	} else {
304803
-		what = alloca(loclen + 1);
304803
-		if (*loc == ':') {
304803
-			loclen--;
304803
-			memcpy(what, loc + 1, loclen);
304803
-			what[loclen] = '\0';
304803
-		} else {
304803
-			memcpy(what, loc, loclen);
304803
-			what[loclen] = '\0';
304803
+		if (!loclen)
304803
+			what = NULL;
304803
+		else {
304803
+			what = alloca(loclen + 1);
304803
+			if (*loc == ':') {
304803
+				loclen--;
304803
+				memcpy(what, loc + 1, loclen);
304803
+				what[loclen] = '\0';
304803
+			} else {
304803
+				memcpy(what, loc, loclen);
304803
+				what[loclen] = '\0';
304803
+			}
304803
 		}
304803
 
304803
 		debug(ap->logopt, MODPREFIX
304803
@@ -799,7 +803,8 @@ update_offset_entry(struct autofs_point
304803
 
304803
 	mc = source->mc;
304803
 
304803
-	if (!*path || !*loc) {
304803
+	/* Internal hosts map may have loc == NULL */
304803
+	if (!*path) {
304803
 		error(ap->logopt,
304803
 		      MODPREFIX "syntax error in offset %s -> %s", path, loc);
304803
 		return CHE_FAIL;
304803
@@ -833,8 +838,10 @@ update_offset_entry(struct autofs_point
304803
 	if (*myoptions) {
304803
 		strcpy(m_mapent, "-");
304803
 		strcat(m_mapent, myoptions);
304803
-		strcat(m_mapent, " ");
304803
-		strcat(m_mapent, loc);
304803
+		if (loc) {
304803
+			strcat(m_mapent, " ");
304803
+			strcat(m_mapent, loc);
304803
+		}
304803
 	} else
304803
 		strcpy(m_mapent, loc);
304803
 
304803
@@ -1435,13 +1442,17 @@ int parse_mount(struct autofs_point *ap,
304803
 
304803
 			l = parse_mapent(p, options, &myoptions, &loc, ap->logopt);
304803
 			if (!l) {
304803
-				cache_delete_offset_list(mc, name);
304803
-				cache_multi_unlock(me);
304803
-				cache_unlock(mc);
304803
-				free(path);
304803
-				free(options);
304803
-				pthread_setcancelstate(cur_state, NULL);
304803
-				return 1;
304803
+				if (!(strstr(myoptions, "fstype=autofs") &&
304803
+				      strstr(myoptions, "hosts"))) {
304803
+					error(LOGOPT_ANY, "I think I'm a hosts map? l %d", l);
304803
+					cache_delete_offset_list(mc, name);
304803
+					cache_multi_unlock(me);
304803
+					cache_unlock(mc);
304803
+					free(path);
304803
+					free(options);
304803
+					pthread_setcancelstate(cur_state, NULL);
304803
+					return 1;
304803
+				}
304803
 			}
304803
 
304803
 			p += l;
304803
@@ -1592,13 +1603,23 @@ int parse_mount(struct autofs_point *ap,
304803
 			p = skipspace(p);
304803
 		}
304803
 
304803
-		loclen = strlen(loc);
304803
-		if (loclen == 0) {
304803
-			free(loc);
304803
-			free(options);
304803
-			error(ap->logopt,
304803
-			      MODPREFIX "entry %s is empty!", name);
304803
-			return 1;
304803
+		/*
304803
+		 * If options are asking for a hosts map loc should be
304803
+		 * NULL but we see it can contain junk, so ....
304803
+		 */
304803
+		if ((strstr(options, "fstype=autofs") &&
304803
+		     strstr(options, "hosts"))) {
304803
+			loc = NULL;
304803
+			loclen = 0;
304803
+		} else {
304803
+			loclen = strlen(loc);
304803
+			if (loclen == 0) {
304803
+				free(loc);
304803
+				free(options);
304803
+				error(ap->logopt,
304803
+				      MODPREFIX "entry %s is empty!", name);
304803
+				return 1;
304803
+			}
304803
 		}
304803
 
304803
 		debug(ap->logopt,