Blame SOURCES/autofs-5.1.0-beta1-allow-empty-value-for-some-map-options.patch

304803
autofs-5.1.0-beta1 - allow empty value for some map options
304803
304803
From: Ian Kent <raven@themaw.net>
304803
304803
Some map options may be given but left blank, possibly with the intent
304803
the mount location mount attempt will not be done or fail, such as when
304803
the delay option is also given.
304803
304803
autofs doesn't implement the delay option but it shouldn't fail to parse
304803
these locations so that a valid locations in the list can be tried.
304803
---
304803
 CHANGELOG           |    1 
304803
 lib/parse_subs.c    |   12 +++-
304803
 modules/amd_parse.y |   36 ++++++++++++++
304803
 modules/amd_tok.l   |   35 ++++++++++++--
304803
 modules/parse_amd.c |  125 ++++++++++++++++++++++++++++++++--------------------
304803
 5 files changed, 155 insertions(+), 54 deletions(-)
304803
304803
--- autofs-5.0.7.orig/CHANGELOG
304803
+++ autofs-5.0.7/CHANGELOG
304803
@@ -124,6 +124,7 @@
304803
 - add plus to path match pattern.
304803
 - fix multi entry ldap option handling.
304803
 - cleanup options in amd_parse.c
304803
+- allow empty value for some map options.
304803
 
304803
 25/07/2012 autofs-5.0.7
304803
 =======================
304803
--- autofs-5.0.7.orig/lib/parse_subs.c
304803
+++ autofs-5.0.7/lib/parse_subs.c
304803
@@ -889,14 +889,20 @@ char *merge_options(const char *opt1, co
304803
 	char *tok, *ptr = NULL;
304803
 	size_t len;
304803
 
304803
-	if (!opt1 && !opt2)
304803
+	if ((!opt1 || !*opt1) && (!opt2 || !*opt2))
304803
 		return NULL;
304803
 
304803
-	if (!opt2)
304803
+	if (!opt2 || !*opt2) {
304803
+		if (!*opt1)
304803
+			return NULL;
304803
 		return strdup(opt1);
304803
+	}
304803
 
304803
-	if (!opt1)
304803
+	if (!opt1 || !*opt1) {
304803
+		if (!*opt2)
304803
+			return NULL;
304803
 		return strdup(opt2);
304803
+	}
304803
 
304803
 	if (!strcmp(opt1, opt2))
304803
 		return strdup(opt1);
304803
--- autofs-5.0.7.orig/modules/amd_parse.y
304803
+++ autofs-5.0.7/modules/amd_parse.y
304803
@@ -335,6 +335,15 @@ option_assignment: MAP_OPTION OPTION_ASS
304803
 			YYABORT;
304803
 		}
304803
 	}
304803
+	| MAP_OPTION OPTION_ASSIGN
304803
+	{
304803
+		if (!strcmp($1, "fs"))
304803
+			entry.fs = amd_strdup("");
304803
+		else {
304803
+			amd_notify($1);
304803
+			YYABORT;
304803
+		}
304803
+	}
304803
 	| FS_OPTION OPTION_ASSIGN FS_OPT_VALUE
304803
 	{
304803
 		if (!strcmp($1, "rhost"))
304803
@@ -358,6 +367,19 @@ option_assignment: MAP_OPTION OPTION_ASS
304803
 			YYABORT;
304803
 		}
304803
 	}
304803
+	| FS_OPTION OPTION_ASSIGN
304803
+	{
304803
+		if (!strcmp($1, "rhost"))
304803
+			entry.rhost = amd_strdup("");
304803
+		else if (!strcmp($1, "rfs"))
304803
+			entry.rfs = amd_strdup("");
304803
+		else if (!strcmp($1, "dev"))
304803
+			entry.dev = amd_strdup("");
304803
+		else {
304803
+			amd_notify($1);
304803
+			YYABORT;
304803
+		}
304803
+	}
304803
 	| MNT_OPTION OPTION_ASSIGN options
304803
 	{
304803
 		memset(opts, 0, sizeof(opts));
304803
@@ -370,6 +392,20 @@ option_assignment: MAP_OPTION OPTION_ASS
304803
 		else {
304803
 			amd_notify($1);
304803
 			YYABORT;
304803
+		}
304803
+	}
304803
+	| MNT_OPTION OPTION_ASSIGN
304803
+	{
304803
+		memset(opts, 0, sizeof(opts));
304803
+		if (!strcmp($1, "opts"))
304803
+			entry.opts = amd_strdup("");
304803
+		else if (!strcmp($1, "addopts"))
304803
+			entry.addopts = amd_strdup("");
304803
+		else if (!strcmp($1, "remopts"))
304803
+			entry.remopts = amd_strdup("");
304803
+		else {
304803
+			amd_notify($1);
304803
+			YYABORT;
304803
 		}
304803
 	}
304803
 	| MAP_OPTION OPTION_ASSIGN CACHE_OPTION
304803
--- autofs-5.0.7.orig/modules/amd_tok.l
304803
+++ autofs-5.0.7/modules/amd_tok.l
304803
@@ -177,9 +177,14 @@ CUTSEP		(\|\||\/)
304803
 }
304803
 
304803
 <MAPOPTVAL>{
304803
-	{NL} |
304803
+	{NL} {
304803
+		BEGIN(INITIAL);
304803
+		yyless(1);
304803
+	}
304803
+
304803
 	\x00 {
304803
 		BEGIN(INITIAL);
304803
+		return SEPERATOR;
304803
 		yyless(1);
304803
 	}
304803
 
304803
@@ -217,9 +222,14 @@ CUTSEP		(\|\||\/)
304803
 }
304803
 
304803
 <FSOPTVAL>{
304803
-	{NL} |
304803
+	{NL} {
304803
+		BEGIN(INITIAL);
304803
+		yyless(1);
304803
+	}
304803
+
304803
 	\x00 {
304803
 		BEGIN(INITIAL);
304803
+		return SEPERATOR;
304803
 		yyless(1);
304803
 	}
304803
 
304803
@@ -242,9 +252,14 @@ CUTSEP		(\|\||\/)
304803
 }
304803
 
304803
 <MNTOPTVAL>{
304803
-	{NL} |
304803
+	{NL} {
304803
+		BEGIN(INITIAL);
304803
+		yyless(1);
304803
+	}
304803
+
304803
 	\x00 {
304803
 		BEGIN(INITIAL);
304803
+		return SEPERATOR;
304803
 		yyless(1);
304803
 	}
304803
 
304803
@@ -269,9 +284,14 @@ CUTSEP		(\|\||\/)
304803
 }
304803
 
304803
 <SELOPTVAL>{
304803
-	{NL} |
304803
+	{NL} {
304803
+		BEGIN(INITIAL);
304803
+		yyless(1);
304803
+	}
304803
+
304803
 	\x00 {
304803
 		BEGIN(INITIAL);
304803
+		return SEPERATOR;
304803
 		yyless(1);
304803
 	}
304803
 
304803
@@ -296,9 +316,14 @@ CUTSEP		(\|\||\/)
304803
 }
304803
 
304803
 <SELARGVAL>{
304803
-	{NL} |
304803
+	{NL} {
304803
+		BEGIN(INITIAL);
304803
+		yyless(1);
304803
+	}
304803
+
304803
 	\x00 {
304803
 		BEGIN(INITIAL);
304803
+		return SEPERATOR;
304803
 		yyless(1);
304803
 	}
304803
 
304803
--- autofs-5.0.7.orig/modules/parse_amd.c
304803
+++ autofs-5.0.7/modules/parse_amd.c
304803
@@ -683,7 +683,7 @@ static struct substvar *expand_entry(str
304803
 	unsigned int logopt = ap->logopt;
304803
 	char *expand;
304803
 
304803
-	if (entry->rhost) {
304803
+	if (entry->rhost && *entry->rhost) {
304803
 		char *host = strdup(entry->rhost);
304803
 		char *nn;
304803
 		if (!host) {
304803
@@ -720,7 +720,7 @@ next:
304803
 		sv = macro_addvar(sv, "sublink", 7, entry->sublink);
304803
 	}
304803
 
304803
-	if (entry->rfs) {
304803
+	if (entry->rfs && *entry->rfs) {
304803
 		if (expand_selectors(ap, entry->rfs, &expand, sv)) {
304803
 			debug(logopt, MODPREFIX
304803
 			      "rfs expand(\"%s\") -> %s", entry->rfs, expand);
304803
@@ -730,7 +730,7 @@ next:
304803
 		sv = macro_addvar(sv, "rfs", 3, entry->rfs);
304803
 	}
304803
 
304803
-	if (entry->fs) {
304803
+	if (entry->fs && *entry->fs) {
304803
 		if (expand_selectors(ap, entry->fs, &expand, sv)) {
304803
 			debug(logopt, MODPREFIX
304803
 			      "fs expand(\"%s\") -> %s", entry->fs, expand);
304803
@@ -740,7 +740,7 @@ next:
304803
 		sv = macro_addvar(sv, "fs", 2, entry->fs);
304803
 	}
304803
 
304803
-	if (entry->opts) {
304803
+	if (entry->opts && *entry->opts) {
304803
 		if (expand_selectors(ap, entry->opts, &expand, sv)) {
304803
 			debug(logopt, MODPREFIX
304803
 			      "ops expand(\"%s\") -> %s", entry->opts, expand);
304803
@@ -750,7 +750,7 @@ next:
304803
 		sv = macro_addvar(sv, "opts", 4, entry->opts);
304803
 	}
304803
 
304803
-	if (entry->addopts) {
304803
+	if (entry->addopts && *entry->addopts) {
304803
 		if (expand_selectors(ap, entry->addopts, &expand, sv)) {
304803
 			debug(logopt, MODPREFIX
304803
 			      "addopts expand(\"%s\") -> %s",
304803
@@ -761,7 +761,7 @@ next:
304803
 		sv = macro_addvar(sv, "addopts", 7, entry->addopts);
304803
 	}
304803
 
304803
-	if (entry->remopts) {
304803
+	if (entry->remopts && *entry->remopts) {
304803
 		if (expand_selectors(ap, entry->remopts, &expand, sv)) {
304803
 			debug(logopt, MODPREFIX
304803
 			      "remopts expand(\"%s\") -> %s",
304803
@@ -781,7 +781,7 @@ static void expand_merge_options(struct
304803
 {
304803
 	char *tmp;
304803
 
304803
-	if (entry->opts) {
304803
+	if (entry->opts && *entry->opts) {
304803
 		if (!expand_selectors(ap, entry->opts, &tmp, sv))
304803
 			error(ap->logopt, MODPREFIX "failed to expand opts");
304803
 		else {
304803
@@ -790,7 +790,7 @@ static void expand_merge_options(struct
304803
 		}
304803
 	}
304803
 
304803
-	if (entry->addopts) {
304803
+	if (entry->addopts && *entry->addopts) {
304803
 		if (!expand_selectors(ap, entry->addopts, &tmp, sv))
304803
 			error(ap->logopt, MODPREFIX "failed to expand addopts");
304803
 		else {
304803
@@ -799,7 +799,7 @@ static void expand_merge_options(struct
304803
 		}
304803
 	}
304803
 
304803
-	if (entry->remopts) {
304803
+	if (entry->remopts && *entry->remopts) {
304803
 		if (!expand_selectors(ap, entry->remopts, &tmp, sv))
304803
 			error(ap->logopt, MODPREFIX "failed to expand remopts");
304803
 		else {
304803
@@ -832,11 +832,13 @@ static struct substvar *merge_entry_opti
304803
 			entry->opts = tmp;
304803
 			sv = macro_addvar(sv, "opts", 4, entry->opts);
304803
 		}
304803
-		tmp = strdup(entry->opts);
304803
-		if (tmp) {
304803
-			free(entry->remopts);
304803
-			entry->remopts = tmp;
304803
-			sv = macro_addvar(sv, "remopts", 7, entry->remopts);
304803
+		if (*entry->opts) {
304803
+			tmp = strdup(entry->opts);
304803
+			if (tmp) {
304803
+				free(entry->remopts);
304803
+				entry->remopts = tmp;
304803
+				sv = macro_addvar(sv, "remopts", 7, entry->remopts);
304803
+			}
304803
 		}
304803
 		return sv;
304803
 	}
304803
@@ -853,7 +855,7 @@ static struct substvar *merge_entry_opti
304803
 			entry->opts = tmp;
304803
 			sv = macro_addvar(sv, "opts", 4, entry->opts);
304803
 		}
304803
-	} else if (entry->addopts) {
304803
+	} else if (entry->addopts && *entry->addopts) {
304803
 		tmp = strdup(entry->addopts);
304803
 		if (tmp) {
304803
 			info(ap->logopt, MODPREFIX
304803
@@ -875,7 +877,7 @@ static struct substvar *merge_entry_opti
304803
 			entry->remopts = tmp;
304803
 			sv = macro_addvar(sv, "remopts", 7, entry->remopts);
304803
 		}
304803
-	} else if (entry->addopts) {
304803
+	} else if (entry->addopts && *entry->addopts) {
304803
 		tmp = strdup(entry->addopts);
304803
 		if (tmp) {
304803
 			info(ap->logopt, MODPREFIX
304803
@@ -910,6 +912,7 @@ static int do_link_mount(struct autofs_p
304803
 			 struct amd_entry *entry, unsigned int flags)
304803
 {
304803
 	char target[PATH_MAX + 1];
304803
+	const char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL;
304803
 	int ret;
304803
 
304803
 	if (entry->sublink)
304803
@@ -922,7 +925,7 @@ static int do_link_mount(struct autofs_p
304803
 
304803
 	/* For a sublink this might cause an external mount */
304803
 	ret = do_mount(ap, ap->path,
304803
-		       name, strlen(name), target, "bind", entry->opts);
304803
+		       name, strlen(name), target, "bind", opts);
304803
 	if (!ret)
304803
 		goto out;
304803
 
304803
@@ -967,12 +970,13 @@ static int do_generic_mount(struct autof
304803
 			    struct amd_entry *entry, const char *target,
304803
 			    unsigned int flags)
304803
 {
304803
+	const char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL;
304803
 	unsigned int umount = 0;
304803
 	int ret = 0;
304803
 
304803
 	if (!entry->fs) {
304803
-		ret = do_mount(ap, ap->path, name, strlen(name),
304803
-			       target, entry->type, entry->opts);
304803
+		ret = do_mount(ap, ap->path, name,
304803
+			       strlen(name), target, entry->type, opts);
304803
 	} else {
304803
 		/*
304803
 		 * Careful, external mounts may get mounted
304803
@@ -981,7 +985,7 @@ static int do_generic_mount(struct autof
304803
 		 */
304803
 		if (!is_mounted(_PATH_MOUNTED, entry->fs, MNTS_REAL)) {
304803
 			ret = do_mount(ap, entry->fs, "/", 1,
304803
-				       target, entry->type, entry->opts);
304803
+				       target, entry->type, opts);
304803
 			if (ret)
304803
 				goto out;
304803
 			umount = 1;
304803
@@ -999,7 +1003,7 @@ static int do_nfs_mount(struct autofs_po
304803
 {
304803
 	char target[PATH_MAX + 1];
304803
 	unsigned int proximity;
304803
-	char *opts = entry->opts;
304803
+	char *opts = (entry->opts && *entry->opts) ? entry->opts : NULL;
304803
 	unsigned int umount = 0;
304803
 	int ret = 0;
304803
 
304803
@@ -1008,7 +1012,7 @@ static int do_nfs_mount(struct autofs_po
304803
 	strcat(target, entry->rfs);
304803
 
304803
 	proximity = get_network_proximity(entry->rhost);
304803
-	if (proximity == PROXIMITY_OTHER && entry->remopts)
304803
+	if (proximity == PROXIMITY_OTHER && entry->remopts && *entry->remopts)
304803
 		opts = entry->remopts;
304803
 
304803
 	if (!entry->fs) {
304803
@@ -1120,7 +1124,7 @@ static int do_host_mount(struct autofs_p
304803
 			goto out;
304803
 	}
304803
 
304803
-	if (entry->opts) {
304803
+	if (entry->opts && *entry->opts) {
304803
 		argv[0] = entry->opts;
304803
 		argv[1] = NULL;
304803
 		pargv = argv;
304803
@@ -1180,9 +1184,13 @@ static unsigned int validate_auto_option
304803
 	/*
304803
 	 * The amd manual implies all the mount type auto options
304803
 	 * are optional but I don't think there's much point if
304803
-	 * no map is given.
304803
+	 * no map is given. If the option has been intentionally
304803
+	 * left blank the mount must be expected to fail so don't
304803
+	 * report the error.
304803
 	 */
304803
-	if (!entry->fs) {
304803
+	if (!*entry->fs)
304803
+		return 0;
304803
+	else if (!entry->fs) {
304803
 		error(logopt, MODPREFIX
304803
 		      "%s: file system not given", entry->type);
304803
 		return 0;
304803
@@ -1201,11 +1209,19 @@ static unsigned int validate_nfs_options
304803
 					 struct amd_entry *entry)
304803
 {
304803
 	/*
304803
-	 * Required option rhost will always have a value.
304803
-	 * It is set from ${host} if it is found to be NULL
304803
-	 * earlier in the parsing process.
304803
+	 * Required option rhost will always have a value unless
304803
+	 * it has been intentionally left blank. It is set from
304803
+	 * ${host} if it is found to be NULL earlier in the parsing
304803
+	 * process. Don't report the error if it has been left blank
304803
+	 * or if the fs option has been left blank since the mount is
304803
+	 * expected to fail.
304803
 	 */
304803
-	if (!entry->rfs) {
304803
+	if (!entry->rfs || !*entry->rfs) {
304803
+		if (!*entry->rfs)
304803
+			return 0;
304803
+		/* Map option fs has been intentionally left blank */
304803
+		if (entry->fs && !*entry->fs)
304803
+			return 0;
304803
 		if (entry->fs)
304803
 			entry->rfs = strdup(entry->fs);
304803
 		if (!entry->rfs) {
304803
@@ -1226,14 +1242,22 @@ static unsigned int validate_generic_opt
304803
 					     unsigned long fstype,
304803
 					     struct amd_entry *entry)
304803
 {
304803
+	/*
304803
+	 * If dev or rfs are empty in the map entry the mount is
304803
+	 * expected to fail so don't report the error.
304803
+	 */
304803
 	if (fstype != AMD_MOUNT_TYPE_LOFS) {
304803
-		if (!entry->dev) {
304803
+		if (!*entry->dev)
304803
+			return 0;
304803
+		else if (!entry->dev) {
304803
 			error(logopt, MODPREFIX
304803
 			      "%s: mount device not given", entry->type);
304803
 			return 0;
304803
 		}
304803
 	} else {
304803
-		if (!entry->rfs) {
304803
+		if (!*entry->rfs)
304803
+			return 0;
304803
+		else if (!entry->rfs) {
304803
 			/*
304803
 			 * Can't use entry->type as the mount type to reprot
304803
 			 * the error since entry->type == "bind" not "lofs".
304803
@@ -1270,11 +1294,14 @@ static unsigned int validate_host_option
304803
 					  struct amd_entry *entry)
304803
 {
304803
 	/*
304803
-	 * Not really that useful since rhost is always non-null
304803
-	 * because it will have the the value of the host name if
304803
-	 * it isn't set in the map entry.
304803
+	 * rhost is always non-null, unless it is intentionally left
304803
+	 * empty, because it will have the the value of the host name
304803
+	 * if it isn't given in the map entry. Don't report an error
304803
+	 * if it has been left empty since it's expected to fail.
304803
 	 */
304803
-	if (!entry->rhost) {
304803
+	if (!*entry->rhost)
304803
+		return 0;
304803
+	else if (!entry->rhost) {
304803
 		error(logopt, MODPREFIX
304803
 		      "%s: remote host name not given", entry->type);
304803
 		return 0;
304803
@@ -1382,7 +1409,7 @@ void dequote_entry(struct autofs_point *
304803
 		}
304803
 	}
304803
 
304803
-	if (entry->fs) {
304803
+	if (entry->fs && *entry->fs) {
304803
 		res = dequote(entry->fs, strlen(entry->fs), ap->logopt);
304803
 		if (res) {
304803
 			debug(ap->logopt,
304803
@@ -1393,7 +1420,7 @@ void dequote_entry(struct autofs_point *
304803
 		}
304803
 	}
304803
 
304803
-	if (entry->rfs) {
304803
+	if (entry->rfs && *entry->rfs) {
304803
 		res = dequote(entry->rfs, strlen(entry->rfs), ap->logopt);
304803
 		if (res) {
304803
 			debug(ap->logopt,
304803
@@ -1404,7 +1431,7 @@ void dequote_entry(struct autofs_point *
304803
 		}
304803
 	}
304803
 
304803
-	if (entry->opts) {
304803
+	if (entry->opts && *entry->opts) {
304803
 		res = dequote(entry->opts, strlen(entry->opts), ap->logopt);
304803
 		if (res) {
304803
 			debug(ap->logopt,
304803
@@ -1415,7 +1442,7 @@ void dequote_entry(struct autofs_point *
304803
 		}
304803
 	}
304803
 
304803
-	if (entry->remopts) {
304803
+	if (entry->remopts && *entry->remopts) {
304803
 		res = dequote(entry->remopts, strlen(entry->remopts), ap->logopt);
304803
 		if (res) {
304803
 			debug(ap->logopt,
304803
@@ -1426,7 +1453,7 @@ void dequote_entry(struct autofs_point *
304803
 		}
304803
 	}
304803
 
304803
-	if (entry->addopts) {
304803
+	if (entry->addopts && *entry->addopts) {
304803
 		res = dequote(entry->addopts, strlen(entry->addopts), ap->logopt);
304803
 		if (res) {
304803
 			debug(ap->logopt,
304803
@@ -1446,6 +1473,10 @@ static void normalize_sublink(unsigned i
304803
 	char *new;
304803
 	size_t len;
304803
 
304803
+	/* Normalizing sublink requires a non-blank fs option */
304803
+	if (!*entry->fs)
304803
+		return;
304803
+
304803
 	if (entry->sublink && *entry->sublink != '/') {
304803
 		len = strlen(entry->fs) + strlen(entry->sublink) + 2;
304803
 		new = malloc(len);
304803
@@ -1559,37 +1590,39 @@ static struct amd_entry *dup_defaults_en
304803
 			entry->fs = tmp;
304803
 	}
304803
 
304803
-	if (defaults->rfs) {
304803
+	/* These shouldn't be blank in a defaults entry but ... */
304803
+
304803
+	if (defaults->rfs && *defaults->rfs) {
304803
 		tmp = strdup(defaults->rfs);
304803
 		if (tmp)
304803
 			entry->rfs = tmp;
304803
 	}
304803
 
304803
-	if (defaults->rhost) {
304803
+	if (defaults->rhost && *defaults->rfs) {
304803
 		tmp = strdup(defaults->rhost);
304803
 		if (tmp)
304803
 			entry->rhost = tmp;
304803
 	}
304803
 
304803
-	if (defaults->dev) {
304803
+	if (defaults->dev && *defaults->dev) {
304803
 		tmp = strdup(defaults->dev);
304803
 		if (tmp)
304803
 			entry->dev = tmp;
304803
 	}
304803
 
304803
-	if (defaults->opts) {
304803
+	if (defaults->opts && *defaults->opts) {
304803
 		tmp = strdup(defaults->opts);
304803
 		if (tmp)
304803
 			entry->opts = tmp;
304803
 	}
304803
 
304803
-	if (defaults->addopts) {
304803
+	if (defaults->addopts && *defaults->addopts) {
304803
 		tmp = strdup(defaults->addopts);
304803
 		if (tmp)
304803
 			entry->addopts = tmp;
304803
 	}
304803
 
304803
-	if (defaults->remopts) {
304803
+	if (defaults->remopts && *defaults->remopts) {
304803
 		tmp = strdup(defaults->remopts);
304803
 		if (tmp)
304803
 			entry->remopts = tmp;