From: Chuck Lever <chuck.lever@oracle.com>
Date: Mon, 29 Aug 2011 17:20:22 +0000 (-0400)
Subject: exportfs: matchhostname() doesn't handle localhost properly
X-Git-Tag: debian/1%1.2.5-1~11^2~23
X-Git-Url: https://git.decadent.org.uk/gitweb/?a=commitdiff_plain;h=b52f41ccc1cb58bb3f3db928ebcc6f1cbce6d751;p=nfs-utils.git

exportfs: matchhostname() doesn't handle localhost properly

Same change as statd_matchhostname() is necessary for the logic in
exportfs.

Recall that these are "separate but nearly equal" because the exportfs
version requires extra expensive string checking that would be onerous
for statd.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Steve Dickson <steved@redhat.com>
---

diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index b107c7c..12e8bf1 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -448,6 +448,36 @@ is_hostname(const char *sp)
 	return true;
 }
 
+/*
+ * Take care to perform an explicit reverse lookup on presentation
+ * addresses.  Otherwise we don't get a real canonical name or a
+ * complete list of addresses.
+ */
+static struct addrinfo *
+address_list(const char *hostname)
+{
+	struct addrinfo *ai;
+	char *cname;
+
+	ai = host_pton(hostname);
+	if (ai != NULL) {
+		/* @hostname was a presentation address */
+		cname = host_canonname(ai->ai_addr);
+		freeaddrinfo(ai);
+		if (cname != NULL)
+			goto out;
+	}
+	/* @hostname was a hostname or had no reverse mapping */
+	cname = strdup(hostname);
+	if (cname == NULL)
+		return NULL;
+
+out:
+	ai = host_addrinfo(cname);
+	free(cname);
+	return ai;
+}
+
 static int
 matchhostname(const char *hostname1, const char *hostname2)
 {
@@ -464,10 +494,10 @@ matchhostname(const char *hostname1, const char *hostname2)
 	if (!is_hostname(hostname1) || !is_hostname(hostname2))
 		return 0;
 
-	results1 = host_addrinfo(hostname1);
+	results1 = address_list(hostname1);
 	if (results1 == NULL)
 		goto out;
-	results2 = host_addrinfo(hostname2);
+	results2 = address_list(hostname2);
 	if (results2 == NULL)
 		goto out;