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();
next prev 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).