Blame SOURCES/autofs-5.1.5-fix-macro-expansion-in-selector-values.patch

c3f1f8
autofs-5.1.5 - fix macro expansion in selector values
c3f1f8
c3f1f8
From: Ian Kent <raven@themaw.net>
c3f1f8
c3f1f8
Macro expansion is not done in selector values before use, for example
c3f1f8
in "hostd==${/key}.<donain>.<name>" the ${/key} is not expanded before
c3f1f8
use leading to an attempt to use an invalid host name.
c3f1f8
c3f1f8
Signed-off-by: Ian Kent <raven@themaw.net>
c3f1f8
---
c3f1f8
 CHANGELOG           |    1 
c3f1f8
 modules/parse_amd.c |  286 ++++++++++++++++++++++++++++++++++------------------
c3f1f8
 2 files changed, 193 insertions(+), 94 deletions(-)
c3f1f8
c3f1f8
--- autofs-5.1.4.orig/CHANGELOG
c3f1f8
+++ autofs-5.1.4/CHANGELOG
c3f1f8
@@ -52,6 +52,7 @@ xx/xx/2018 autofs-5.1.5
c3f1f8
 - log mount call arguments if mount_verbose is set.
c3f1f8
 - make expire remaining log level debug.
c3f1f8
 - allow period following macro in selector value.
c3f1f8
+- fix macro expansion in selector values.
c3f1f8
 
c3f1f8
 19/12/2017 autofs-5.1.4
c3f1f8
 - fix spec file url.
c3f1f8
--- autofs-5.1.4.orig/modules/parse_amd.c
c3f1f8
+++ autofs-5.1.4/modules/parse_amd.c
c3f1f8
@@ -231,17 +231,29 @@ static struct substvar *add_lookup_vars(
c3f1f8
 	return list;
c3f1f8
 }
c3f1f8
 
c3f1f8
-static int match_my_name(unsigned int logopt, const char *name, struct substvar *sv)
c3f1f8
+static int match_my_name(struct autofs_point *ap, const char *name, struct substvar *sv)
c3f1f8
 {
c3f1f8
 	struct addrinfo hints, *cni, *ni, *haddr;
c3f1f8
 	char host[NI_MAXHOST + 1], numeric[NI_MAXHOST + 1];
c3f1f8
+	unsigned int logopt = ap->logopt;
c3f1f8
 	const struct substvar *v;
c3f1f8
+	char *exp_name = NULL;
c3f1f8
 	int rv = 0, ret;
c3f1f8
 
c3f1f8
+	if (!expand_selectors(ap, name, &exp_name, sv))
c3f1f8
+		exp_name = strdup(name);
c3f1f8
+	if (!exp_name) {
c3f1f8
+		error(logopt,
c3f1f8
+		      MODPREFIX "error: failed to alloc space for name");
c3f1f8
+		goto out;
c3f1f8
+	}
c3f1f8
+
c3f1f8
 	v = macro_findvar(sv, "host", 4);
c3f1f8
 	if (v) {
c3f1f8
-		if (!strcmp(v->val, name))
c3f1f8
-			return 1;
c3f1f8
+		if (!strcmp(v->val, exp_name)) {
c3f1f8
+			rv = 1;
c3f1f8
+			goto out;
c3f1f8
+		}
c3f1f8
 	}
c3f1f8
 
c3f1f8
 	if (!v || !v->val) {
c3f1f8
@@ -268,11 +280,11 @@ static int match_my_name(unsigned int lo
c3f1f8
 	hints.ai_flags = AI_V4MAPPED | AI_ADDRCONFIG | AI_CANONNAME;
c3f1f8
 
c3f1f8
 	/* Resolve comparison name to its names and compare */
c3f1f8
-	ret = getaddrinfo(name, NULL, &hints, &ni);
c3f1f8
+	ret = getaddrinfo(exp_name, NULL, &hints, &ni);
c3f1f8
 	if (ret) {
c3f1f8
 		error(logopt, MODPREFIX
c3f1f8
 		      "hostname lookup for %s failed: %s\n",
c3f1f8
-		      name, gai_strerror(ret));
c3f1f8
+		      exp_name, gai_strerror(ret));
c3f1f8
 		freeaddrinfo(cni);
c3f1f8
 		goto out;
c3f1f8
 	}
c3f1f8
@@ -310,18 +322,180 @@ next:
c3f1f8
 	freeaddrinfo(ni);
c3f1f8
 	freeaddrinfo(cni);
c3f1f8
 out:
c3f1f8
+	if (exp_name)
c3f1f8
+		free(exp_name);
c3f1f8
 	return rv;
c3f1f8
 }
c3f1f8
 
c3f1f8
-static int eval_selector(unsigned int logopt,
c3f1f8
+static int sel_strcmp(struct autofs_point *ap,
c3f1f8
+		      const struct substvar *v, struct selector *s,
c3f1f8
+		      struct substvar *sv)
c3f1f8
+{
c3f1f8
+	char *expand = NULL;
c3f1f8
+	int ret = 0;
c3f1f8
+	int res;
c3f1f8
+
c3f1f8
+	res = expand_selectors(ap, s->comp.value, &expand, sv);
c3f1f8
+	if (res)
c3f1f8
+		res = strcmp(v->val, expand);
c3f1f8
+	else
c3f1f8
+		res = strcmp(v->val, s->comp.value);
c3f1f8
+
c3f1f8
+	if (s->compare & SEL_COMP_EQUAL && !res) {
c3f1f8
+		debug(ap->logopt, MODPREFIX
c3f1f8
+		      "matched selector %s(%s) == %s",
c3f1f8
+		      v->def, v->val, expand ? expand : s->comp.value);
c3f1f8
+		ret = 1;
c3f1f8
+	} else if (s->compare & SEL_COMP_NOTEQUAL && res) {
c3f1f8
+		debug(ap->logopt, MODPREFIX
c3f1f8
+		      "matched selector %s(%s) != %s",
c3f1f8
+		      v->def, v->val, expand ? expand : s->comp.value);
c3f1f8
+		ret = 1;
c3f1f8
+	} else
c3f1f8
+		debug(ap->logopt, MODPREFIX
c3f1f8
+		      "did not match selector %s(%s) %s %s",
c3f1f8
+		      v->def, v->val,
c3f1f8
+		      (s->compare & SEL_COMP_EQUAL ? "==" : "!="),
c3f1f8
+		      expand ? expand : s->comp.value);
c3f1f8
+
c3f1f8
+	if (expand)
c3f1f8
+		free(expand);
c3f1f8
+
c3f1f8
+	return ret;
c3f1f8
+}
c3f1f8
+
c3f1f8
+static int sel_lstat(struct autofs_point *ap,
c3f1f8
+		     struct selector *s, struct substvar *sv)
c3f1f8
+{
c3f1f8
+	struct stat st;
c3f1f8
+	char *expand = NULL;
c3f1f8
+	int res, ret;
c3f1f8
+
c3f1f8
+	/* Sould be OK to fail on any error here */
c3f1f8
+	res = expand_selectors(ap, s->func.arg1, &expand, sv);
c3f1f8
+	if (res)
c3f1f8
+		ret = !lstat(expand, &st);
c3f1f8
+	else
c3f1f8
+		ret = !lstat(s->func.arg1, &st);
c3f1f8
+
c3f1f8
+	if (s->compare == SEL_COMP_NOT)
c3f1f8
+		ret = !ret;
c3f1f8
+	if (ret)
c3f1f8
+		debug(ap->logopt, MODPREFIX
c3f1f8
+		      "matched selector %s(%s)",
c3f1f8
+		      s->sel->name, expand ? expand : s->func.arg1);
c3f1f8
+	else
c3f1f8
+		debug(ap->logopt, MODPREFIX
c3f1f8
+		      "did not match selector %s(%s)",
c3f1f8
+		      s->sel->name, expand ? expand : s->func.arg1);
c3f1f8
+	if (expand)
c3f1f8
+		free(expand);
c3f1f8
+
c3f1f8
+	return ret;
c3f1f8
+}
c3f1f8
+
c3f1f8
+static int sel_in_network(struct autofs_point *ap,
c3f1f8
+			  struct selector *s, struct substvar *sv)
c3f1f8
+{
c3f1f8
+	char *expand = NULL;
c3f1f8
+	int res, ret;
c3f1f8
+
c3f1f8
+	res = expand_selectors(ap, s->func.arg1, &expand, sv);
c3f1f8
+	if (!res)
c3f1f8
+		ret = in_network(s->func.arg1);
c3f1f8
+	else
c3f1f8
+		ret = in_network(expand);
c3f1f8
+
c3f1f8
+	if (s->compare == SEL_COMP_NOT)
c3f1f8
+		ret = !ret;
c3f1f8
+	if (ret)
c3f1f8
+		debug(ap->logopt, MODPREFIX
c3f1f8
+		      "matched selector %s(%s)",
c3f1f8
+		      s->sel->name, expand ? expand : s->func.arg1);
c3f1f8
+	else
c3f1f8
+		debug(ap->logopt, MODPREFIX
c3f1f8
+		      "did not match selector %s(%s)",
c3f1f8
+		      s->sel->name, expand ? expand : s->func.arg1);
c3f1f8
+
c3f1f8
+	if (expand)
c3f1f8
+		free(expand);
c3f1f8
+
c3f1f8
+	return ret;
c3f1f8
+}
c3f1f8
+
c3f1f8
+static int sel_netgrp(struct autofs_point *ap,
c3f1f8
+		      struct selector *s, struct substvar *sv)
c3f1f8
+{
c3f1f8
+	char *exp_arg1 = NULL, *exp_arg2 = NULL;
c3f1f8
+	const struct substvar *v;
c3f1f8
+	int res, ret = 0;
c3f1f8
+	char *host;
c3f1f8
+
c3f1f8
+	if (s->func.arg2) {
c3f1f8
+		res = expand_selectors(ap, s->func.arg2, &exp_arg2, sv);
c3f1f8
+		if (res)
c3f1f8
+			host = exp_arg2;
c3f1f8
+		else
c3f1f8
+			host = s->func.arg2;
c3f1f8
+	} else {
c3f1f8
+		if (s->sel->selector == SEL_NETGRP)
c3f1f8
+			v = macro_findvar(sv, "host", 4);
c3f1f8
+		else
c3f1f8
+			v = macro_findvar(sv, "hostd", 5);
c3f1f8
+		if (!v || !*v->val) {
c3f1f8
+			error(ap->logopt, MODPREFIX
c3f1f8
+			     "failed to get value of ${host}");
c3f1f8
+			goto out;
c3f1f8
+		}
c3f1f8
+		host = v->val;
c3f1f8
+	}
c3f1f8
+
c3f1f8
+	res = expand_selectors(ap, s->func.arg1, &exp_arg1, sv);
c3f1f8
+	if (res)
c3f1f8
+		ret = innetgr(exp_arg1, host, NULL, NULL);
c3f1f8
+	else
c3f1f8
+		ret = innetgr(s->func.arg1, host, NULL, NULL);
c3f1f8
+
c3f1f8
+	if (s->compare == SEL_COMP_NOT)
c3f1f8
+		ret = !ret;
c3f1f8
+	if (ret) {
c3f1f8
+		if (!s->func.arg2)
c3f1f8
+			debug(ap->logopt, MODPREFIX
c3f1f8
+			      "matched selector %s(%s)",
c3f1f8
+			      s->sel->name, exp_arg1 ? exp_arg1 : s->func.arg1);
c3f1f8
+		else
c3f1f8
+			debug(ap->logopt, MODPREFIX
c3f1f8
+			      "matched selector %s(%s,%s)", s->sel->name,
c3f1f8
+			      exp_arg1 ? exp_arg1 : s->func.arg1,
c3f1f8
+			      exp_arg2 ? exp_arg2 : s->func.arg2);
c3f1f8
+	} else {
c3f1f8
+		if (!s->func.arg2)
c3f1f8
+			debug(ap->logopt, MODPREFIX
c3f1f8
+			      "did not match selector %s(%s)",
c3f1f8
+			      s->sel->name, exp_arg1 ? exp_arg1 : s->func.arg1);
c3f1f8
+		else
c3f1f8
+			debug(ap->logopt, MODPREFIX
c3f1f8
+			      "did not match selector %s(%s,%s)", s->sel->name,
c3f1f8
+			      exp_arg1 ? exp_arg1 : s->func.arg1,
c3f1f8
+			      exp_arg2 ? exp_arg2 : s->func.arg2);
c3f1f8
+	}
c3f1f8
+out:
c3f1f8
+	if (exp_arg1)
c3f1f8
+		free(exp_arg1);
c3f1f8
+	if (exp_arg2)
c3f1f8
+		free(exp_arg2);
c3f1f8
+
c3f1f8
+	return ret;
c3f1f8
+}
c3f1f8
+
c3f1f8
+static int eval_selector(struct autofs_point *ap,
c3f1f8
 			 struct amd_entry *this, struct substvar *sv)
c3f1f8
 {
c3f1f8
 	struct selector *s = this->selector;
c3f1f8
+	unsigned int logopt = ap->logopt;
c3f1f8
 	const struct substvar *v;
c3f1f8
 	unsigned int s_type;
c3f1f8
 	unsigned int v_type;
c3f1f8
-	struct stat st;
c3f1f8
-	char *host;
c3f1f8
 	int res, val, ret = 0;
c3f1f8
 
c3f1f8
 	s_type = s->sel->flags & SEL_FLAGS_TYPE_MASK;
c3f1f8
@@ -339,26 +513,7 @@ static int eval_selector(unsigned int lo
c3f1f8
 
c3f1f8
 		switch (v_type) {
c3f1f8
 		case SEL_FLAG_STR:
c3f1f8
-			res = strcmp(v->val, s->comp.value);
c3f1f8
-			if (s->compare & SEL_COMP_EQUAL && !res) {
c3f1f8
-				debug(logopt, MODPREFIX
c3f1f8
-				      "matched selector %s(%s) == %s",
c3f1f8
-				      v->def, v->val, s->comp.value);
c3f1f8
-				ret = 1;
c3f1f8
-				break;
c3f1f8
-			} else if (s->compare & SEL_COMP_NOTEQUAL && res) {
c3f1f8
-				debug(logopt, MODPREFIX
c3f1f8
-				      "matched selector %s(%s) != %s",
c3f1f8
-				      v->def, v->val, s->comp.value);
c3f1f8
-				ret = 1;
c3f1f8
-				break;
c3f1f8
-			}
c3f1f8
-
c3f1f8
-			debug(logopt, MODPREFIX
c3f1f8
-				      "did not match selector %s(%s) %s %s",
c3f1f8
-				      v->def, v->val,
c3f1f8
-				      (s->compare & SEL_COMP_EQUAL ? "==" : "!="),
c3f1f8
-				      s->comp.value);
c3f1f8
+			ret = sel_strcmp(ap, v, s, sv);
c3f1f8
 			break;
c3f1f8
 
c3f1f8
 		case SEL_FLAG_NUM:
c3f1f8
@@ -434,7 +589,7 @@ static int eval_selector(unsigned int lo
c3f1f8
 			break;
c3f1f8
 
c3f1f8
 		case SEL_XHOST:
c3f1f8
-			ret = match_my_name(logopt, s->func.arg1, sv);
c3f1f8
+			ret = match_my_name(ap, s->func.arg1, sv);
c3f1f8
 			if (s->compare == SEL_COMP_NOT)
c3f1f8
 				ret = !ret;
c3f1f8
 			if (ret)
c3f1f8
@@ -448,32 +603,11 @@ static int eval_selector(unsigned int lo
c3f1f8
 			break;
c3f1f8
 
c3f1f8
 		case SEL_EXISTS:
c3f1f8
-			/* Sould be OK to fail on any error here */
c3f1f8
-			ret = !lstat(s->func.arg1, &st);
c3f1f8
-			if (s->compare == SEL_COMP_NOT)
c3f1f8
-				ret = !ret;
c3f1f8
-			if (ret)
c3f1f8
-				debug(logopt, MODPREFIX
c3f1f8
-				      "matched selector %s(%s)",
c3f1f8
-				      s->sel->name, s->func.arg1);
c3f1f8
-			else
c3f1f8
-				debug(logopt, MODPREFIX
c3f1f8
-				      "did not match selector %s(%s)",
c3f1f8
-				      s->sel->name, s->func.arg1);
c3f1f8
+			ret = sel_lstat(ap, s, sv);
c3f1f8
 			break;
c3f1f8
 
c3f1f8
 		case SEL_IN_NETWORK:
c3f1f8
-			ret = in_network(s->func.arg1);
c3f1f8
-			if (s->compare == SEL_COMP_NOT)
c3f1f8
-				ret = !ret;
c3f1f8
-			if (ret)
c3f1f8
-				debug(logopt, MODPREFIX
c3f1f8
-				      "matched selector %s(%s)",
c3f1f8
-				      s->sel->name, s->func.arg1);
c3f1f8
-			else
c3f1f8
-				debug(logopt, MODPREFIX
c3f1f8
-				      "did not match selector %s(%s)",
c3f1f8
-				      s->sel->name, s->func.arg1);
c3f1f8
+			ret = sel_in_network(ap, s, sv);
c3f1f8
 			break;
c3f1f8
 
c3f1f8
 		default:
c3f1f8
@@ -492,43 +626,7 @@ static int eval_selector(unsigned int lo
c3f1f8
 		switch (s->sel->selector) {
c3f1f8
 		case SEL_NETGRP:
c3f1f8
 		case SEL_NETGRPD:
c3f1f8
-			if (s->func.arg2)
c3f1f8
-				host = s->func.arg2;
c3f1f8
-			else {
c3f1f8
-				if (s->sel->selector == SEL_NETGRP)
c3f1f8
-					v = macro_findvar(sv, "host", 4);
c3f1f8
-				else
c3f1f8
-					v = macro_findvar(sv, "hostd", 5);
c3f1f8
-				if (!v || !*v->val) {
c3f1f8
-					error(logopt, MODPREFIX
c3f1f8
-					     "failed to get value of ${host}");
c3f1f8
-					break;
c3f1f8
-				}
c3f1f8
-				host = v->val;
c3f1f8
-			}
c3f1f8
-			ret = innetgr(s->func.arg1, host, NULL, NULL);
c3f1f8
-			if (s->compare == SEL_COMP_NOT)
c3f1f8
-				ret = !ret;
c3f1f8
-			if (ret) {
c3f1f8
-				if (!s->func.arg2)
c3f1f8
-					debug(logopt, MODPREFIX
c3f1f8
-					      "matched selector %s(%s)",
c3f1f8
-					      s->sel->name, s->func.arg1);
c3f1f8
-				else
c3f1f8
-					debug(logopt, MODPREFIX
c3f1f8
-					      "matched selector %s(%s,%s)",
c3f1f8
-					      s->sel->name, s->func.arg1,
c3f1f8
-					      s->func.arg2);
c3f1f8
-			} else {
c3f1f8
-				if (!s->func.arg2)
c3f1f8
-					debug(logopt, MODPREFIX
c3f1f8
-					      "did not match selector %s(%s)",
c3f1f8
-					      s->sel->name, s->func.arg1);
c3f1f8
-				else
c3f1f8
-					debug(logopt, MODPREFIX
c3f1f8
-					      "did not match selector %s(%s,%s)",
c3f1f8
-					      s->sel->name, s->func.arg1, s->func.arg2);
c3f1f8
-			}
c3f1f8
+			ret = sel_netgrp(ap, s, sv);
c3f1f8
 			break;
c3f1f8
 
c3f1f8
 		default:
c3f1f8
@@ -1753,7 +1851,7 @@ static void update_prefix(struct autofs_
c3f1f8
 	return;
c3f1f8
 }
c3f1f8
 
c3f1f8
-static int match_selectors(unsigned int logopt,
c3f1f8
+static int match_selectors(struct autofs_point *ap,
c3f1f8
 			   struct amd_entry *entry, struct substvar *sv)
c3f1f8
 {
c3f1f8
 	struct selector *s = entry->selector;
c3f1f8
@@ -1761,7 +1859,7 @@ static int match_selectors(unsigned int
c3f1f8
 
c3f1f8
 	/* No selectors, always match */
c3f1f8
 	if (!s) {
c3f1f8
-		debug(logopt, MODPREFIX "no selectors found in location");
c3f1f8
+		debug(ap->logopt, MODPREFIX "no selectors found in location");
c3f1f8
 		return 1;
c3f1f8
 	}
c3f1f8
 
c3f1f8
@@ -1769,7 +1867,7 @@ static int match_selectors(unsigned int
c3f1f8
 
c3f1f8
 	/* All selectors must match */
c3f1f8
 	while (s) {
c3f1f8
-		ret = eval_selector(logopt, entry, sv);
c3f1f8
+		ret = eval_selector(ap, entry, sv);
c3f1f8
 		if (!ret)
c3f1f8
 			break;
c3f1f8
 		s = s->next;
c3f1f8
@@ -1939,7 +2037,7 @@ static struct amd_entry *select_default_
c3f1f8
 		if (!this->selector)
c3f1f8
 			continue;
c3f1f8
 
c3f1f8
-		if (match_selectors(ap->logopt, this, sv)) {
c3f1f8
+		if (match_selectors(ap, this, sv)) {
c3f1f8
 			if (entry_default) {
c3f1f8
 				/*update_with_defaults(entry_default, this, sv);*/
c3f1f8
 				free_amd_entry(entry_default);
c3f1f8
@@ -2192,7 +2290,7 @@ int parse_mount(struct autofs_point *ap,
c3f1f8
 			break;
c3f1f8
 		}
c3f1f8
 
c3f1f8
-		if (!match_selectors(ap->logopt, this, sv))
c3f1f8
+		if (!match_selectors(ap, this, sv))
c3f1f8
 			continue;
c3f1f8
 
c3f1f8
 		at_least_one = 1;