All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chuck Lever <chuck.lever@oracle.com>
To: linux-nfs@vger.kernel.org
Subject: [PATCH 5/5] sm-notify: sm-notify doesn't handle localhost properly
Date: Wed, 24 Aug 2011 11:34:32 -0400	[thread overview]
Message-ID: <20110824153432.3138.94316.stgit@matisse.1015granger.net> (raw)
In-Reply-To: <20110824153024.3138.63294.stgit@matisse.1015granger.net>

It looks like the existing algorithm for verifying the passed-in bind
address is as broken as statd_matchhostname() used to be: for IP
addresses, AI_CANONNAME is useless.  We need to have getnameinfo(3) or
equivalent in there.

Clean up: extract the logic that verifies the command line bind
address into its own function, and make it handle canonical name
lookup correctly.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/statd/sm-notify.c |  127 ++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 102 insertions(+), 25 deletions(-)

diff --git a/utils/statd/sm-notify.c b/utils/statd/sm-notify.c
index f05eadf..2421f8b 100644
--- a/utils/statd/sm-notify.c
+++ b/utils/statd/sm-notify.c
@@ -93,6 +93,101 @@ smn_lookup(const char *name)
 	return ai;
 }
 
+#ifdef HAVE_GETNAMEINFO
+static char *
+smn_get_hostname(const struct sockaddr *sap, const socklen_t salen,
+		const char *name)
+{
+	char buf[NI_MAXHOST];
+	int error;
+
+	error = getnameinfo(sap, salen, buf, sizeof(buf), NULL, 0, NI_NAMEREQD);
+	if (error != 0) {
+		xlog(L_ERROR, "my_name '%s' is unusable: %s",
+			name, gai_strerror(error));
+		return NULL;
+	}
+	return strdup(buf);
+}
+#else	/* !HAVE_GETNAMEINFO */
+static char *
+smn_get_hostname(const struct sockaddr *sap,
+		__attribute__ ((unused)) const socklen_t salen,
+		const char *name)
+{
+	const struct sockaddr_in *sin = (const struct sockaddr_in *)(char *)sap;
+	const struct in_addr *addr = &sin->sin_addr;
+	struct hostent *hp;
+
+	if (sap->sa_family != AF_INET) {
+		xlog(L_ERROR, "my_name '%s' is unusable: Bad address family",
+			name);
+		return NULL;
+	}
+
+	hp = gethostbyaddr(addr, (socklen_t)sizeof(addr), AF_INET);
+	if (hp == NULL) {
+		xlog(L_ERROR, "my_name '%s' is unusable: %s",
+			name, hstrerror(h_errno));
+		return NULL;
+	}
+	return strdup(hp->h_name);
+}
+#endif	/* !HAVE_GETNAMEINFO */
+
+/*
+ * Presentation addresses are converted to their canonical hostnames.
+ * If the IP address does not map to a hostname, it is an error:
+ * we never send a presentation address as the argument of SM_NOTIFY.
+ *
+ * If "name" is not a presentation address, it is left alone.  This
+ * allows the administrator some flexibility if DNS isn't configured
+ * exactly how sm-notify prefers it.
+ *
+ * Returns NUL-terminated C string containing the result, or NULL
+ * if the canonical name doesn't exist or cannot be determined.
+ * The caller must free the result with free(3).
+ */
+__attribute_malloc__
+static char *
+smn_verify_my_name(const char *name)
+{
+	struct addrinfo *ai = NULL;
+	struct addrinfo hint = {
+#ifdef IPV6_SUPPORTED
+		.ai_family	= AF_UNSPEC,
+#else	/* !IPV6_SUPPORTED */
+		.ai_family	= AF_INET,
+#endif	/* !IPV6_SUPPORTED */
+		.ai_flags	= AI_NUMERICHOST,
+	};
+	char *retval;
+	int error;
+
+	error = getaddrinfo(name, NULL, &hint, &ai);
+	switch (error) {
+	case 0:
+		/* @name was a presentation address */
+		retval = smn_get_hostname(ai->ai_addr, ai->ai_addrlen, name);
+		freeaddrinfo(ai);
+		if (retval == NULL)
+			return NULL;
+		break;
+	case EAI_NONAME:
+		/* @name was not a presentation address */
+		retval = strdup(name);
+		break;
+	default:
+		xlog(L_ERROR, "my_name '%s' is unusable: %s",
+			name, gai_strerror(error));
+		return NULL;
+	}
+
+	xlog(D_GENERAL, "Canonical name for my_name '%s': %s",
+			name, retval);
+	return retval;
+}
+
 __attribute_malloc__
 static struct nsm_host *
 smn_alloc_host(const char *hostname, const char *mon_name,
@@ -416,32 +511,14 @@ usage:		fprintf(stderr,
 	}
 
 	if (opt_srcaddr != NULL) {
-		struct addrinfo *ai = NULL;
-		struct addrinfo hint = {
-			.ai_family	= AF_UNSPEC,
-			.ai_flags	= AI_NUMERICHOST,
-		};
-
-		if (getaddrinfo(opt_srcaddr, NULL, &hint, &ai))
-			/* not a presentation address - use it */
-			strncpy(nsm_hostname, opt_srcaddr, sizeof(nsm_hostname));
-		else {
-			/* was a presentation address - look it up in
-			 * /etc/hosts, so it can be used for my_name */
-			int error;
+		char *name;
 
-			freeaddrinfo(ai);
-			hint.ai_flags = AI_CANONNAME;
-			error = getaddrinfo(opt_srcaddr, NULL, &hint, &ai);
-			if (error != 0) {
-				xlog(L_ERROR, "Bind address %s is unusable: %s",
-						opt_srcaddr, gai_strerror(error));
-				exit(1);
-			}
-			strncpy(nsm_hostname, ai->ai_canonname,
-							sizeof(nsm_hostname));
-			freeaddrinfo(ai);
-		}
+		name = smn_verify_my_name(opt_srcaddr);
+		if (name == NULL)
+			exit(1);
+
+		strncpy(nsm_hostname, name, sizeof(nsm_hostname));
+		free(name);
 	}
 
 	(void)nsm_retire_monitored_hosts();


  parent reply	other threads:[~2011-08-24 15:34 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-24 15:33 [PATCH 0/5] Possible fixes for statd / sm-notify / exportfs Chuck Lever
2011-08-24 15:33 ` [PATCH 1/5] statd: Report count of loaded hosts correctly Chuck Lever
2011-08-24 15:34 ` [PATCH 2/5] sm-notify: Disable syslog messages when debugging is enabled Chuck Lever
2011-08-24 15:34 ` [PATCH 3/5] statd: statd_matchhostname() doesn't handle localhost properly Chuck Lever
2011-08-24 15:34 ` [PATCH 4/5] exportfs: matchhostname() " Chuck Lever
2011-08-24 15:34 ` Chuck Lever [this message]
2011-08-29 17:48 ` [PATCH 0/5] Possible fixes for statd / sm-notify / exportfs Steve Dickson

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20110824153432.3138.94316.stgit@matisse.1015granger.net \
    --to=chuck.lever@oracle.com \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.