changeset 13927:4801c57f1ca7

3485 statd is not handling incoming SM_NOTIFY properly when the hostname is not resolvable Reviewed by: Gordon Ross <Gordon.Ross@nexenta.com> Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com> Reviewed by: Dan McDonald <danmcd@nexenta.com> Reviewed by: Albert Lee <trisk@nexenta.com> Reviewed by: Richard Lowe <richlowe@richlowe.net> Reviewed by: Jeremy Jones <jeremy@delphix.com> Approved by: Christopher Siden <csiden@delphix.com>
author Marcel Telka <marcel.telka@nexenta.com>
date Fri, 25 Jan 2013 10:08:50 -0800
parents 864d02b072c2
children b13e6c26bd03
files usr/src/cmd/fs.d/nfs/statd/sm_proc.c
diffstat 1 files changed, 43 insertions(+), 42 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/cmd/fs.d/nfs/statd/sm_proc.c	Tue Jan 22 12:11:15 2013 -0500
+++ b/usr/src/cmd/fs.d/nfs/statd/sm_proc.c	Fri Jan 25 10:08:50 2013 -0800
@@ -23,6 +23,9 @@
  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
+/*
+ * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
+ */
 
 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
 /*	  All Rights Reserved  	*/
@@ -37,8 +40,6 @@
  * contributors.
  */
 
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 #include <stdio.h>
 #include <sys/types.h>
 #include <stdlib.h>
@@ -729,14 +730,12 @@
 
 	if (statd_call_lockd(&minfop->id, minfop->state) == -1) {
 		if (debug && minfop->id.mon_id.mon_name)
-			(void) printf(
-		"problem with notifying %s failure, give up\n",
-			minfop->id.mon_id.mon_name);
+			(void) printf("problem with notifying %s failure, "
+			    "give up\n", minfop->id.mon_id.mon_name);
 	} else {
 		if (debug)
-			(void) printf(
-		"send_notice: %s, %d notified.\n",
-		minfop->id.mon_id.mon_name, minfop->state);
+			(void) printf("send_notice: %s, %d notified.\n",
+			    minfop->id.mon_id.mon_name, minfop->state);
 	}
 
 	free(minfop->id.mon_id.mon_name);
@@ -914,24 +913,22 @@
 	(void) printf("name-to-address translation table:\n");
 	for (entry = name_addr; entry != NULL; entry = entry->next) {
 		(void) printf("\t%s: ",
-				(entry->name ? entry->name : "(null)"));
+		    (entry->name ? entry->name : "(null)"));
 		for (addr = entry->addresses; addr; addr = addr->next) {
 			switch (addr->family) {
-				case AF_INET:
-					ipv4_addr = *(struct in_addr *)addr->ah.
-n_bytes;
-					(void) printf(" %s (fam %d)",
-							inet_ntoa(ipv4_addr),
-							addr->family);
-					break;
-				case AF_INET6:
-					ipv6_addr = (char *)addr->ah.n_bytes;
-					(void) printf(" %s (fam %d)",
-							inet_ntop(addr->family,
-ipv6_addr, abuf, sizeof (abuf)), addr->family);
-					break;
-				default:
-					return;
+			case AF_INET:
+				ipv4_addr = *(struct in_addr *)addr->ah.n_bytes;
+				(void) printf(" %s (fam %d)",
+				    inet_ntoa(ipv4_addr), addr->family);
+				break;
+			case AF_INET6:
+				ipv6_addr = (char *)addr->ah.n_bytes;
+				(void) printf(" %s (fam %d)",
+				    inet_ntop(addr->family, ipv6_addr, abuf,
+				    sizeof (abuf)), addr->family);
+				break;
+			default:
+				return;
 			}
 		}
 		printf("\n");
@@ -939,14 +936,13 @@
 }
 
 /*
- * Statd has trouble dealing with hostname aliases because two
- * different aliases for the same machine don't match each other
- * when using strcmp.  To deal with this, the hostnames must be
- * translated into some sort of universal identifier.  These
- * identifiers can be compared.  Universal network addresses are
- * currently used for this identifier because it is general and
- * easy to do.  Other schemes are possible and this routine
- * could be converted if required.
+ * First, try to compare the hostnames as strings.  If the hostnames does not
+ * match we might deal with the hostname aliases.  In this case two different
+ * aliases for the same machine don't match each other when using strcmp.  To
+ * deal with this, the hostnames must be translated into some sort of universal
+ * identifier.  These identifiers can be compared.  Universal network addresses
+ * are currently used for this identifier because it is general and easy to do.
+ * Other schemes are possible and this routine could be converted if required.
  *
  * If it can't find an address for some reason, 0 is returned.
  */
@@ -957,6 +953,11 @@
 	char *sysid2;
 	int rv;
 
+	/* Compare hostnames as strings */
+	if (host1 != NULL && host2 != NULL && strcmp(host1, host2) == 0)
+		return (1);
+
+	/* Try harder if hostnames do not match */
 	sysid1 = get_system_id(host1);
 	sysid2 = get_system_id(host2);
 	if ((sysid1 == NULL) || (sysid2 == NULL))
@@ -1003,7 +1004,7 @@
 	}
 	while ((ncp = getnetconfig(hp)) != (struct netconfig *)NULL) {
 		if ((strcmp(ncp->nc_protofmly, NC_INET) == 0) ||
-			(strcmp(ncp->nc_protofmly, NC_INET6) == 0)) {
+		    (strcmp(ncp->nc_protofmly, NC_INET6) == 0)) {
 			addrs = NULL;
 			rv = netdir_getbyname(ncp, &service, &addrs);
 			if (rv != 0) {
@@ -1065,7 +1066,7 @@
 	for (n = lifc->lifc_len / sizeof (struct lifreq); n > 0; n--, lifrp++) {
 
 		(void) strncpy(lifr.lifr_name, lifrp->lifr_name,
-				sizeof (lifr.lifr_name));
+		    sizeof (lifr.lifr_name));
 
 		af = lifrp->lifr_addr.ss_family;
 		sock = socket(af, SOCK_DGRAM, 0);
@@ -1077,7 +1078,7 @@
 		/* If it's the loopback interface, ignore */
 		if (ioctl(sock, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
 			syslog(LOG_ERR,
-				"statd: SIOCGLIFFLAGS failed, error: %m\n");
+			    "statd: SIOCGLIFFLAGS failed, error: %m\n");
 			goto finish;
 		}
 		if (lifr.lifr_flags & IFF_LOOPBACK)
@@ -1085,7 +1086,7 @@
 
 		if (ioctl(sock, SIOCGLIFADDR, (caddr_t)&lifr) < 0) {
 			syslog(LOG_ERR,
-				"statd: SIOCGLIFADDR failed, error: %m\n");
+			    "statd: SIOCGLIFADDR failed, error: %m\n");
 			goto finish;
 		}
 		sa = (struct sockaddr_storage *)&(lifr.lifr_addr);
@@ -1216,7 +1217,7 @@
 
 	if (debug) {
 		(void) printf("str_cmp_unqual: rawname1= %s, rawname2= %s\n",
-				rawname1, rawname2);
+		    rawname1, rawname2);
 	}
 
 	unq_len1 = strcspn(rawname1, ".");
@@ -1224,12 +1225,12 @@
 	domain = strchr(rawname1, '.');
 	if (domain != NULL) {
 		if ((strncmp(rawname1, SM_ADDR_IPV4, unq_len1) == 0) ||
-			(strncmp(rawname1, SM_ADDR_IPV6, unq_len1) == 0))
+		    (strncmp(rawname1, SM_ADDR_IPV6, unq_len1) == 0))
 		return (1);
 	}
 
 	if ((unq_len1 == unq_len2) &&
-			(strncmp(rawname1, rawname2, unq_len1) == 0)) {
+	    (strncmp(rawname1, rawname2, unq_len1) == 0)) {
 		return (0);
 	}
 
@@ -1252,7 +1253,7 @@
 
 	if (debug) {
 		(void) printf("str_cmp_addr: specifier1= %s, specifier2= %s\n",
-				specifier1, specifier2);
+		    specifier1, specifier2);
 	}
 
 	/*
@@ -1293,8 +1294,8 @@
 		++rawaddr2;
 
 		if (inet_pton(af1, rawaddr1, dst1) == 1 &&
-			inet_pton(af2, rawaddr1, dst2) == 1 &&
-			memcmp(dst1, dst2, len) == 0) {
+		    inet_pton(af2, rawaddr1, dst2) == 1 &&
+		    memcmp(dst1, dst2, len) == 0) {
 			return (0);
 		}
 	}