rpms/autofs/FC-6 autofs-5.0.1-rc3-consistent-dquote-handling.patch, NONE, 1.1 autofs-5.0.1-rc3-match-export-fqdn.patch, NONE, 1.1 autofs-5.0.1-rc3-trailing-whitespace.patch, NONE, 1.1 autofs.spec, 1.168, 1.169

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Mon Jan 29 06:47:19 UTC 2007


Author: ikent

Update of /cvs/dist/rpms/autofs/FC-6
In directory cvs.devel.redhat.com:/tmp/cvs-serv17468

Modified Files:
	autofs.spec 
Added Files:
	autofs-5.0.1-rc3-consistent-dquote-handling.patch 
	autofs-5.0.1-rc3-match-export-fqdn.patch 
	autofs-5.0.1-rc3-trailing-whitespace.patch 
Log Message:
* Mon Jan 29 2007 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc3.12
- make double quote handing consistent (at least as much as we can).
- fix handling of trailing white space in wildcard lookup (forward port bz 199720).
- check fqdn of each interface when matching export access list (bz 213700).
- Resolves: rhbz#222872 rhbz#213700


autofs-5.0.1-rc3-consistent-dquote-handling.patch:
 CHANGELOG             |    1 
 lib/parse_subs.c      |   24 ++++++++++++++-
 modules/lookup_file.c |   36 +++++++++++++++++++++--
 modules/parse_sun.c   |   76 ++++++++++++++++++++++++++++++++------------------
 samples/auto.smb      |   11 ++++++-
 5 files changed, 114 insertions(+), 34 deletions(-)

--- NEW FILE autofs-5.0.1-rc3-consistent-dquote-handling.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index b77c2cd..5bbf9a1 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -5,6 +5,7 @@
 - ignore "winbind" if it appears in "automount" nsswitch.conf.
 - fix another expire regression introduced in the "mitigate manual umount" patch.
 - correct check for busy offset mounts before offset umount.
+- make double quote handing consistent.
 
 4/1/2007 autofs-5.0.1 rc3
 -------------------------
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index d4ddbe4..81db459 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -89,6 +89,18 @@ int chunklen(const char *whence, int expect_colon)
 				quote = 1;
 				continue;
 			}
+		case '"':
+			if (quote)
+				break;
+			while (*str) {
+				str++;
+				n++;
+				if (*str == '"')
+					break;
+				if (*str == ':')
+					expect_colon = 0;
+			}
+			break;
 		case ':':
 			if (expect_colon)
 				expect_colon = 0;
@@ -185,11 +197,19 @@ int span_space(const char *str, unsigned int maxlen)
 	const char *p = str;
 	unsigned int len = 0;
 
-	while (!isblank(*(p++)) && len++ < maxlen) {
-		if (*p == '\\') {
+	while (*p && !isblank(*p) && len < maxlen) {
+		if (*p == '"') {
+			while (*p++ && len++ < maxlen) {
+				if (*p == '"')
+					break;
+			}
+		} else if (*p == '\\') {
 			p += 2;
 			len += 2;
+			continue;
 		}
+		p++;
+		len++;
 	}
 	return len;
 }
diff --git a/modules/lookup_file.c b/modules/lookup_file.c
index 051e5b5..0f4d8f1 100644
--- a/modules/lookup_file.c
+++ b/modules/lookup_file.c
@@ -41,7 +41,7 @@ typedef enum {
 } LOOKUP_STATE;
 
 typedef enum { got_nothing, got_star, got_real, got_plus } FOUND_STATE;
-typedef enum { esc_none, esc_char, esc_val } ESCAPES;
+typedef enum { esc_none, esc_char, esc_val, esc_all } ESCAPES;
 
 
 struct lookup_context {
@@ -143,6 +143,8 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
 				ungetc(nch, f);
 				escape = esc_char;
 			}
+			if (ch == '"')
+				escape = esc_all;
 			break;
 
 		case esc_char:
@@ -152,6 +154,11 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
 		case esc_val:
 			escape = esc_none;
 			break;
+
+		case esc_all:
+			if (ch == '"')
+				escape = esc_none;
+			break;
 		}
 
 		switch (state) {
@@ -171,6 +178,10 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
 					*(kptr++) = ch;
 					key_len++;
 				}
+			} else if (escape == esc_all) {
+				state = st_compare;
+				*(kptr++) = ch;
+				key_len++;
 			} else if (escape == esc_char);
 			else
 				state = st_badent;
@@ -181,7 +192,11 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
 				state = st_begin;
 				if (gotten == got_plus)
 					goto got_it;
-				if (escape != esc_val)
+				else if (escape == esc_all) {
+					warn(LOGOPT_ANY, MODPREFIX
+					    "unmatched \" in map key %s", key);
+					goto next;
+				} else if (escape != esc_val)
 					goto got_it;
 			} else if (isspace(ch) && !escape) {
 				getting = got_real;
@@ -199,6 +214,10 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
 					      "length is %d", key,
 					      KEY_MAX_LEN);
 				} else {
+					if (escape == esc_val) {
+						*(kptr++) = '\\';
+						key_len++;
+					}
 					*(kptr++) = ch;
 					key_len++;
 				}
@@ -237,9 +256,12 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
 						break;
 					}
 					p = mapent;
-					*(p++) = '\\';
+					if (escape == esc_val) {
+						*(p++) = '\\';
+						mapent_len++;
+					}
 					*(p++) = ch;
-					mapent_len = 2;
+					mapent_len++;
 				} else {
 					p = mapent;
 					*(p++) = ch;
@@ -264,6 +286,12 @@ static int read_one(FILE *f, char *key, unsigned int *k_len, char *mapent, unsig
 				}
 				ungetc(nch, f);
 				state = st_begin;
+				if (escape == esc_all) {
+					warn(LOGOPT_ANY, MODPREFIX
+					     "unmatched \" in %s for key %s",
+					     mapent, key);
+					goto next;
+				}
 				if (gotten == got_real || gotten == getting)
 					goto got_it;
 			} else if (mapent_len < MAPENT_MAX_LEN) {
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 6b2a640..0a3cac9 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -193,6 +193,23 @@ int expandsunent(const char *src, char *dst, const char *key,
 			}
 			break;
 
+		case '"':
+			len++;
+			if (dst)
+				*dst++ = ch;
+
+			while (*src && *src != '"') {
+				len++;
+				if (dst)
+					*dst++ = *src;
+				src++;
+			}
+			if (*src && dst) {
+				len++;
+				*dst++ = *src++;
+			}
+			break;
+
 		case ':':
 			if (dst)
 				*(dst++) = 
@@ -573,7 +590,10 @@ static int check_is_multi(const char *mapent)
 		     MODPREFIX "unexpected NULL map entry pointer");
 		return 0;
 	}
-	
+
+	if (*p == '"')
+		p++;
+
 	/* If first character is "/" it's a multi-mount */
 	if (*p == '/')
 		return 1;
@@ -590,6 +610,8 @@ static int check_is_multi(const char *mapent)
 		 * entry.
 		 */
 		if (not_first_chunk) {
+			if (*p == '"')
+				p++;
 			if (*p == '/' || *p == '-') {
 				multi = 1;
 				break;
@@ -749,13 +771,6 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
 
 	debug(logopt, MODPREFIX "gathered options: %s", myoptions);
 
-	/* Location can't begin with a '/' */
-	if (*p == '/') {
-		warn(logopt, MODPREFIX "error location begins with \"/\"");
-		free(myoptions);
-		return 0;
-	}
-
 	l = chunklen(p, check_colon(p));
 	loc = dequote(p, l, logopt);
 	if (!loc) {
@@ -764,6 +779,13 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
 		return 0;
 	}
 
+	/* Location can't begin with a '/' */
+	if (*p == '/') {
+		warn(logopt, MODPREFIX "error location begins with \"/\"");
+		free(myoptions);
+		return 0;
+	}
+
 	if (!validate_location(loc)) {
 		warn(logopt, MODPREFIX "invalid location");
 		free(myoptions);
@@ -776,22 +798,22 @@ static int parse_mapent(const char *ent, char *g_options, char **options, char *
 	p += l;
 	p = skipspace(p);
 
-	while (*p && *p != '/') {
+	while (*p && ((*p == '"' && *(p + 1) != '/') || (*p != '"' && *p != '/'))) {
 		char *tmp, *ent;
 
-		/* Location can't begin with a '/' */
-		if (*p == '/') {
-			warn(logopt,
-			      MODPREFIX "error location begins with \"/\"");
+		l = chunklen(p, check_colon(p));
+		ent = dequote(p, l, logopt);
+		if (!ent) {
+			warn(logopt, MODPREFIX "null location or out of memory");
 			free(myoptions);
 			free(loc);
 			return 0;
 		}
 
-		l = chunklen(p, check_colon(p));
-		ent = dequote(p, l, logopt);
-		if (!ent) {
-			warn(logopt, MODPREFIX "null location or out of memory");
+		/* Location can't begin with a '/' */
+		if (*p == '/') {
+			warn(logopt,
+			      MODPREFIX "error location begins with \"/\"");
 			free(myoptions);
 			free(loc);
 			return 0;
@@ -1077,7 +1099,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
 			char *path, *myoptions, *loc;
 			int status;
 
-			if (*p != '/') {
+			if ((*p == '"' && *(p + 1) != '/') || (*p != '"' && *p != '/')) {
 				l = 0;
 				path = dequote("/", 1, ap->logopt);
 				debug(ap->logopt,
@@ -1139,7 +1161,7 @@ int parse_mount(struct autofs_point *ap, const char *name,
 			free(loc);
 			free(path);
 			free(myoptions);
-		} while (*p == '/');
+		} while (*p == '/' || (*p == '"' && *(p + 1) == '/'));
 
 		/*
 		 * We've got the ordered list of multi-mount entries so go
@@ -1203,14 +1225,6 @@ int parse_mount(struct autofs_point *ap, const char *name,
 		int loclen;
 		int l;
 
-		/* Location can't begin with a '/' */
-		if (*p == '/') {
-			free(options);
-			warn(ap->logopt,
-			      MODPREFIX "error location begins with \"/\"");
-			return 1;
-		}
-
 		l = chunklen(p, check_colon(p));
 		loc = dequote(p, l, ap->logopt);
 		if (!loc) {
@@ -1219,6 +1233,14 @@ int parse_mount(struct autofs_point *ap, const char *name,
 			return 1;
 		}
 
+		/* Location can't begin with a '/' */
+		if (*p == '/') {
+			free(options);
+			warn(ap->logopt,
+			      MODPREFIX "error location begins with \"/\"");
+			return 1;
+		}
+
 		if (!validate_location(loc)) {
 			free(loc);
 			free(options);
diff --git a/samples/auto.smb b/samples/auto.smb
index d0abcd7..56e6232 100755
--- a/samples/auto.smb
+++ b/samples/auto.smb
@@ -20,7 +20,16 @@ done
 
 $SMBCLIENT -gNL $key 2>/dev/null| awk -v key="$key" -v opts="$opts" -F'|' -- '
 	BEGIN	{ ORS=""; first=1 }
-	/Disk/	{ if (first) { print opts; first=0 }; sub(/ /, "\\ ", $2); print " \\\n\t /" $2, "://" key "/" $2 }
+	/Disk/	{
+		  if (first)
+			print opts; first=0
+		  dir = $2
+		  loc = $2
+		  # Enclose mount dir and location in quotes
+		  # Double quote "$" in location as it is special
+		  gsub(/\$$/, "\\$", loc);
+		  print " \\\n\t \"/" dir "\"", "\"://" key "/" loc "\""
+		}
 	END 	{ if (!first) print "\n"; else exit 1 }
 	'
 

autofs-5.0.1-rc3-match-export-fqdn.patch:
 CHANGELOG      |    1 
 lib/rpc_subs.c |  131 +++++++++++++++++++++++++++++++++++++++++++++------------
 2 files changed, 105 insertions(+), 27 deletions(-)

--- NEW FILE autofs-5.0.1-rc3-match-export-fqdn.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index b435501..48b959a 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -7,6 +7,7 @@
 - correct check for busy offset mounts before offset umount.
 - make double quote handing consistent.
 - fix handling of trailing white space in wildcard lookup.
+- check fqdn of each interface when matching export access list.
 
 4/1/2007 autofs-5.0.1 rc3
 -------------------------
diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c
index b4e9c91..1c5f009 100644
--- a/lib/rpc_subs.c
+++ b/lib/rpc_subs.c
@@ -42,7 +42,8 @@
 #include "log.h"
 #endif
 
-#define MAX_ERR_BUF	512
+#define MAX_IFC_BUF	1024
+#define MAX_ERR_BUF	128
 
 static char *ypdomain = NULL;
 
@@ -755,7 +756,7 @@ void rpc_exports_free(exports list)
 
 static int masked_match(const char *addr, const char *mask)
 {
-	char buf[MAX_ERR_BUF], *ptr;
+	char buf[MAX_IFC_BUF], *ptr;
 	struct sockaddr_in saddr;
 	struct sockaddr_in6 saddr6;
 	struct ifconf ifc;
@@ -926,42 +927,118 @@ static int pattern_match(const char *s, const char *pattern)
 	/* NOTREACHED */
 }
 
-static int string_match(const char *myname, const char *pattern)
+static int name_match(const char *name, const char *pattern)
 {
-	struct addrinfo hints, *ni;
 	int ret;
 
-	memset(&hints, 0, sizeof(hints));
-	hints.ai_flags = AI_CANONNAME;
-	hints.ai_family = 0;
-	hints.ai_socktype = 0;
+	if (strchr(pattern, '*') || strchr(pattern, '?'))
+		ret = pattern_match(name, pattern);
+	else {
+		ret = !memcmp(name, pattern, strlen(pattern));
+		/* Name could still be a netgroup (Solaris) */
+		if (!ret && ypdomain)
+			ret = innetgr(pattern, name, NULL, ypdomain);
+	}
+
+	return ret;
+}
+
+static int fqdn_match(const char *pattern)
+{
+	char buf[MAX_IFC_BUF], *ptr;
+	struct ifconf ifc;
+	struct ifreq *ifr;
+	int sock, cl_flags, ret, i;
+	char fqdn[NI_MAXHOST + 1];
+
+	sock = socket(AF_INET, SOCK_DGRAM, 0);
+	if (sock < 0) {
+		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+		error(LOGOPT_ANY, "socket creation failed: %s", estr);
+		return 0;
+	}
+
+	if ((cl_flags = fcntl(sock, F_GETFD, 0)) != -1) {
+		cl_flags |= FD_CLOEXEC;
+		fcntl(sock, F_SETFD, cl_flags);
+	}
 
-	ret = getaddrinfo(myname, NULL, &hints, &ni);
-	if (ret) {
-		error(LOGOPT_ANY, "name lookup failed: %s", gai_strerror(ret));
+	ifc.ifc_len = sizeof(buf);
+	ifc.ifc_req = (struct ifreq *) buf;
+	ret = ioctl(sock, SIOCGIFCONF, &ifc);
+	if (ret == -1) {
+		close(sock);
+		char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
+		error(LOGOPT_ANY, "ioctl: %s", estr);
 		return 0;
 	}
 
-	if (strchr(pattern, '*') || strchr(pattern, '?')) {
-		ret = pattern_match(myname, pattern);
-		if (!ret)
-			ret = pattern_match(ni->ai_canonname, pattern);
-	} else {
-		/* Match simple nane or FQDN */
-		ret = !memcmp(myname, pattern, strlen(pattern));
-		if (!ret)
-			ret = !memcmp(ni->ai_canonname, pattern, strlen(pattern));
+	i = 0;
+	ptr = (char *) &ifc.ifc_buf[0];
 
-		/* Name could still be a netgroup (Solaris) */
-		if (!ret && ypdomain) {
-			ret = innetgr(pattern, myname, NULL, ypdomain);
-			if (!ret)
-				ret = innetgr(pattern,
-					 ni->ai_canonname, NULL, ypdomain);
+	while (ptr < buf + ifc.ifc_len) {
+		ifr = (struct ifreq *) ptr;
+
+		switch (ifr->ifr_addr.sa_family) {
+		case AF_INET:
+		{
+			socklen_t slen = sizeof(struct sockaddr);
+
+			ret = getnameinfo(&ifr->ifr_addr, slen, fqdn,
+					  NI_MAXHOST, NULL, 0, NI_NAMEREQD);
+			if (!ret) {
+				ret = name_match(fqdn, pattern);
+				if (ret) {
+					close(sock);
+					return 1;
+				}
+			}
+			break;
+		}
+
+		/* glibc rpc only understands IPv4 atm */
+		case AF_INET6:
+			break;
+
+		default:
+			break;
 		}
 
+		i++;
+		ptr = (char *) &ifc.ifc_req[i];
 	}
-	freeaddrinfo(ni);
+
+	close(sock);
+	return 0;
+}
+
+static int string_match(const char *myname, const char *pattern)
+{
+	struct addrinfo hints, *ni;
+	int ret;
+
+	/* Try simple name match first */
+	ret = name_match(myname, pattern);
+	if (ret)
+		goto done;
+
+	memset(&hints, 0, sizeof(hints));
+	hints.ai_flags = AI_CANONNAME;
+	hints.ai_family = 0;
+	hints.ai_socktype = 0;
+
+	/* See if our canonical name matches */
+	if (getaddrinfo(myname, NULL, &hints, &ni) == 0) {
+		ret = name_match(ni->ai_canonname, pattern);
+		freeaddrinfo(ni);
+	} else
+		warn(LOGOPT_ANY, "name lookup failed: %s", gai_strerror(ret));
+	if (ret)
+		goto done;
+
+	/* Lastly see if the name of an interfaces matches */
+	ret = fqdn_match(pattern);
+done:
 	return ret;
 }
 

autofs-5.0.1-rc3-trailing-whitespace.patch:
 CHANGELOG           |    1 +
 lib/parse_subs.c    |   12 ++++++++++++
 modules/parse_sun.c |   29 ++++++++++++++++++++++++++---
 3 files changed, 39 insertions(+), 3 deletions(-)

--- NEW FILE autofs-5.0.1-rc3-trailing-whitespace.patch ---
diff --git a/CHANGELOG b/CHANGELOG
index 5bbf9a1..b435501 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -6,6 +6,7 @@
 - fix another expire regression introduced in the "mitigate manual umount" patch.
 - correct check for busy offset mounts before offset umount.
 - make double quote handing consistent.
+- fix handling of trailing white space in wildcard lookup.
 
 4/1/2007 autofs-5.0.1 rc3
 -------------------------
diff --git a/lib/parse_subs.c b/lib/parse_subs.c
index 81db459..bdb19cd 100644
--- a/lib/parse_subs.c
+++ b/lib/parse_subs.c
@@ -157,10 +157,22 @@ char *dequote(const char *str, int origlen, unsigned int logopt)
 	const char *scp;
 	int len = origlen;
 	int quote = 0, dquote = 0;
+	int i, j;
 
 	if (ret == NULL)
 		return NULL;
 
+	/* first thing to do is strip white space from the end */
+	i = len - 1;
+	while (isspace(str[i])) {
+		/* of course, we have to keep escaped white-space */
+		j = i - 1;
+		if (j > 0 && (str[j] == '\\' || str[j] == '"'))
+			break;
+		i--;
+		len--;
+	}
+
 	for (scp = str; len > 0 && *scp; scp++, len--) {
 		if (!quote) {
 			if (*scp == '"') {
diff --git a/modules/parse_sun.c b/modules/parse_sun.c
index 0a3cac9..7020902 100644
--- a/modules/parse_sun.c
+++ b/modules/parse_sun.c
@@ -135,9 +135,32 @@ int expandsunent(const char *src, char *dst, const char *key,
 		switch (ch) {
 		case '&':
 			l = strlen(key);
-			if (dst) {
-				strcpy(dst, key);
-				dst += l;
+			/*
+			 * In order to ensure that any spaces in the key
+			 * re preserved, we need to escape them here.
+			 */
+			if (strchr(key, ' ')) {
+				char *keyp = key;
+				while (*keyp) {
+					if (isspace(*keyp)) {
+						if (dst) {
+							*dst++ = '\\';
+							*dst++ = *keyp++;
+						} else
+							keyp++;
+						l++;
+					} else {
+						if (dst)
+							*dst++ = *keyp++;
+						else
+							keyp++;
+					}
+				}
+			} else {
+				if (dst) {
+					strcpy(dst, key);
+					dst += l;
+				}
 			}
 			len += l;
 			break;


Index: autofs.spec
===================================================================
RCS file: /cvs/dist/rpms/autofs/FC-6/autofs.spec,v
retrieving revision 1.168
retrieving revision 1.169
diff -u -r1.168 -r1.169
--- autofs.spec	19 Jan 2007 06:34:53 -0000	1.168
+++ autofs.spec	29 Jan 2007 06:47:17 -0000	1.169
@@ -4,7 +4,7 @@
 Summary: A tool for automatically mounting and unmounting filesystems
 Name: autofs
 %define version 5.0.1
-%define release 0.rc3.10
+%define release 0.rc3.12
 Version: %{version}
 Release: %{release}
 Epoch: 1
@@ -16,6 +16,9 @@
 Patch3: autofs-5.0.1-rc3-nsswitch-ignore-winbind.patch
 Patch4: autofs-5.0.1-rc3-correct-expire-check.patch
 Patch5: autofs-5.0.1-rc3-correct-offset-mount-busy-check.patch
+Patch6: autofs-5.0.1-rc3-consistent-dquote-handling.patch
+Patch7: autofs-5.0.1-rc3-trailing-whitespace.patch
+Patch8: autofs-5.0.1-rc3-match-export-fqdn.patch
 Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: autoconf, hesiod-devel, openldap-devel, bison, flex, libxml2-devel, cyrus-sasl-devel, openssl-devel
 Conflicts: kernel < 2.6.17
@@ -63,6 +66,9 @@
 %patch3 -p1
 %patch4 -p1
 %patch5 -p1
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
 
 %build
 #CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=/usr --libdir=%{_libdir}
@@ -119,6 +125,11 @@
 %{_libdir}/autofs/*
 
 %changelog
+* Mon Jan 29 2007 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc3.12
+- make double quote handing consistent (at least as much as we can).
+- fix handling of trailing white space in wildcard lookup (forward port bz 199720).
+- check fqdn of each interface when matching export access list (bz 213700).
+
 * Thu Jan 18 2007 Ian Kent <ikent at redhat.com> - 5.0.1-0.rc3.10
 - correct check for busy offset mounts before offset umount (bz 222872).
 




More information about the fedora-cvs-commits mailing list