From b17f03d7d89b75b69b9b7db22f2316b700e3a5a8 Mon Sep 17 00:00:00 2001 From: Marcel Telka Date: Fri, 25 Jan 2013 10:08:50 -0800 Subject: [PATCH] 3485 statd is not handling incoming SM_NOTIFY properly when the hostname is not resolvable Reviewed by: Gordon Ross Reviewed by: Yuri Pankov Reviewed by: Dan McDonald Reviewed by: Albert Lee Reviewed by: Richard Lowe Reviewed by: Jeremy Jones Approved by: Christopher Siden --- usr/src/cmd/fs.d/nfs/statd/sm_proc.c | 85 ++++++++++++++++++------------------ 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/usr/src/cmd/fs.d/nfs/statd/sm_proc.c b/usr/src/cmd/fs.d/nfs/statd/sm_proc.c index f9c8d7a66d..492cb9c639 100644 --- a/usr/src/cmd/fs.d/nfs/statd/sm_proc.c +++ b/usr/src/cmd/fs.d/nfs/statd/sm_proc.c @@ -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 #include #include @@ -729,14 +730,12 @@ thr_send_notice(void *arg) 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 @@ pr_name_addr(name_addr_entry_t *name_addr) (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 @@ ipv6_addr, abuf, sizeof (abuf)), addr->family); } /* - * 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 @@ hostname_eq(char *host1, char *host2) 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 @@ get_system_id(char *hostname) } 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 @@ merge_hosts(void) 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 @@ merge_hosts(void) /* 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 @@ merge_hosts(void) 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 @@ str_cmp_unqual_hostname(char *rawname1, char *rawname2) if (debug) { (void) printf("str_cmp_unqual: rawname1= %s, rawname2= %s\n", - rawname1, rawname2); + rawname1, rawname2); } unq_len1 = strcspn(rawname1, "."); @@ -1224,12 +1225,12 @@ str_cmp_unqual_hostname(char *rawname1, char *rawname2) 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 @@ str_cmp_address_specifier(char *specifier1, char *specifier2) if (debug) { (void) printf("str_cmp_addr: specifier1= %s, specifier2= %s\n", - specifier1, specifier2); + specifier1, specifier2); } /* @@ -1293,8 +1294,8 @@ str_cmp_address_specifier(char *specifier1, char *specifier2) ++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); } } -- 2.11.4.GIT