--- a/usr/src/cmd/fs.d/nfs/mountd/mountd.c Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/cmd/fs.d/nfs/mountd/mountd.c Thu Nov 03 11:18:52 2011 +0400
@@ -17,10 +17,9 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-
-/*
+ *
* Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -112,7 +111,6 @@
static void sh_free(struct sh_list *);
static void umount(struct svc_req *);
static void umountall(struct svc_req *);
-static int netmatch(struct netbuf *, char *);
static void sigexit(int);
static int newopts(char *);
static tsol_tpent_t *get_client_template(struct sockaddr *);
@@ -1711,10 +1709,10 @@
* We match on aliases of the hostname as well as on the canonical name.
* Names in the access list may be either hosts or netgroups; they're
* not distinguished syntactically. We check for hosts first because
- * it's cheaper (just M*N strcmp()s), then try netgroups.
+ * it's cheaper, then try netgroups.
*
* If pnb and pclnames are NULL, it means that we have to use transp
- * to resolve client's IP address to host name. If they aren't NULL
+ * to resolve client IP address to hostname. If they aren't NULL
* then transp argument won't be used and can be NULL.
*/
int
@@ -1722,84 +1720,112 @@
struct nd_hostservlist **pclnames,
char *access_list) /* N.B. we clobber this "input" parameter */
{
- int nentries;
- char *gr;
- char *lasts;
+ char addr[INET_ADDRSTRLEN];
+ char buff[256];
+ int nentries = 0;
+ char *cstr = access_list;
+ char *gr = access_list;
char *host;
int off;
int i;
- int netgroup_match;
int response;
+ int sbr = 0;
struct nd_hostservlist *clnames;
+ struct netent n, *np;
- /*
- * If no access list - then it's unrestricted
- */
+ /* If no access list - then it's unrestricted */
if (access_list == NULL || *access_list == '\0')
return (1);
assert(transp != NULL || (*pnb != NULL && *pclnames != NULL));
- nentries = 0;
+ /* Get client address if it wasn't provided */
+ if (*pnb == NULL)
+ /* Don't grant access if client address isn't known */
+ if ((*pnb = svc_getrpccaller(transp)) == NULL)
+ return (0);
+
+ /* Try to lookup client hostname if it wasn't provided */
+ if (*pclnames == NULL)
+ getclientsnames(transp, pnb, pclnames);
+ clnames = *pclnames;
- for (gr = strtok_r(access_list, ":", &lasts);
- gr != NULL; gr = strtok_r(NULL, ":", &lasts)) {
+ for (;;) {
+ if ((cstr = strpbrk(cstr, "[]:")) != NULL) {
+ switch (*cstr) {
+ case '[':
+ case ']':
+ sbr = !sbr;
+ cstr++;
+ continue;
+ case ':':
+ if (sbr) {
+ cstr++;
+ continue;
+ }
+ *cstr = '\0';
+ }
+ }
/*
- * If the list name has a '-' prepended
- * then a match of the following name
- * implies failure instead of success.
+ * If the list name has a '-' prepended then a match of
+ * the following name implies failure instead of success.
*/
if (*gr == '-') {
response = 0;
gr++;
- } else
+ } else {
response = 1;
+ }
/*
- * If the list name begins with an at
- * sign then do a network comparison.
+ * First check if we have '@' entry, as it doesn't
+ * require client hostname.
*/
if (*gr == '@') {
- /*
- * Just get the netbuf, avoiding the costly name
- * lookup. This will suffice for access based
- * solely on addresses.
- */
- if (*pnb == NULL) {
- /*
- * Don't grant access if client's address isn't
- * known.
- */
- if ((*pnb = svc_getrpccaller(transp)) == NULL)
- return (0);
+ gr++;
+
+ /* Netname support */
+ if (!isdigit(*gr) && *gr != '[') {
+ if ((np = getnetbyname_r(gr, &n, buff,
+ sizeof (buff))) != NULL &&
+ np->n_net != 0) {
+ while ((np->n_net & 0xFF000000u) == 0)
+ np->n_net <<= 8;
+ np->n_net = htonl(np->n_net);
+ if (inet_ntop(AF_INET, &np->n_net, addr,
+ INET_ADDRSTRLEN) == NULL)
+ break;
+ if (inet_matchaddr((*pnb)->buf, addr))
+ return (response);
+ }
+ } else {
+ if (inet_matchaddr((*pnb)->buf, gr))
+ return (response);
}
- if (netmatch(*pnb, gr + 1))
- return (response);
+ if (cstr == NULL)
+ break;
+
+ gr = ++cstr;
+
continue;
}
/*
- * We need to get the host name if we haven't gotten
- * it by now!
+ * No other checks can be performed if client address
+ * can't be resolved.
*/
- if (*pclnames == NULL) {
- DTRACE_PROBE(mountd, name_by_addrlist);
- /*
- * Do not grant access if we can't
- * get a name!
- */
- if (getclientsnames(transp, pnb, pclnames) != 0)
- return (0);
+ if (clnames == NULL) {
+ if (cstr == NULL)
+ break;
+
+ gr = ++cstr;
+
+ continue;
}
- clnames = *pclnames;
-
- /*
- * The following loops through all the
- * client's aliases. Usually it's just one name.
- */
+ /* Otherwise loop through all client hostname aliases */
for (i = 0; i < clnames->h_cnt; i++) {
host = clnames->h_hostservs[i].h_host;
@@ -1820,120 +1846,25 @@
return (response);
}
}
- } else
-
- /*
- * Just do a hostname match
- */
- if (strcasecmp(gr, host) == 0) {
- return (response); /* Matched a hostname */
+ } else {
+ /* Just do a hostname match */
+ if (strcasecmp(gr, host) == 0)
+ return (response);
}
}
nentries++;
- }
- /*
- * We need to get the host name if we haven't gotten
- * it by now!
- */
- if (*pclnames == NULL) {
- DTRACE_PROBE(mountd, name_by_netgroup);
- /*
- * Do not grant access if we can't
- * get a name!
- */
- if (getclientsnames(transp, pnb, pclnames) != 0)
- return (0);
+ if (cstr == NULL)
+ break;
+
+ gr = ++cstr;
}
- netgroup_match = netgroup_check(*pclnames, access_list, nentries);
-
- return (netgroup_match);
-}
-
-int
-netmatch(struct netbuf *nb, char *name)
-{
- uint_t claddr;
- struct netent n, *np;
- char *mp, *p;
- uint_t addr, mask;
- int i, bits;
- char buff[256];
-
- /*
- * Check if it's an IPv4 addr
- */
- if (nb->len != sizeof (struct sockaddr_in))
+ if (clnames == NULL)
return (0);
- (void) memcpy(&claddr,
- /* LINTED pointer alignment */
- &((struct sockaddr_in *)nb->buf)->sin_addr.s_addr,
- sizeof (struct in_addr));
- claddr = ntohl(claddr);
-
- mp = strchr(name, '/');
- if (mp)
- *mp++ = '\0';
-
- if (isdigit(*name)) {
- /*
- * Convert a dotted IP address
- * to an IP address. The conversion
- * is not the same as that in inet_addr().
- */
- p = name;
- addr = 0;
- for (i = 0; i < 4; i++) {
- addr |= atoi(p) << ((3-i) * 8);
- p = strchr(p, '.');
- if (p == NULL)
- break;
- p++;
- }
- } else {
- /*
- * Turn the netname into
- * an IP address.
- */
- np = getnetbyname_r(name, &n, buff, sizeof (buff));
- if (np == NULL) {
- syslog(LOG_DEBUG, "getnetbyname_r: %s: %m", name);
- return (0);
- }
- addr = np->n_net;
- }
-
- /*
- * If the mask is specified explicitly then
- * use that value, e.g.
- *
- * @109.104.56/28
- *
- * otherwise assume a mask from the zero octets
- * in the least significant bits of the address, e.g.
- *
- * @109.104 or @109.104.0.0
- */
- if (mp) {
- bits = atoi(mp);
- mask = bits ? ~0 << ((sizeof (struct in_addr) * NBBY) - bits)
- : 0;
- addr &= mask;
- } else {
- if ((addr & IN_CLASSA_HOST) == 0)
- mask = IN_CLASSA_NET;
- else if ((addr & IN_CLASSB_HOST) == 0)
- mask = IN_CLASSB_NET;
- else if ((addr & IN_CLASSC_HOST) == 0)
- mask = IN_CLASSC_NET;
- else
- mask = IN_CLASSE_NET;
- }
-
- return ((claddr & mask) == addr);
+ return (netgroup_check(clnames, access_list, nentries));
}
--- a/usr/src/head/arpa/inet.h Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/head/arpa/inet.h Thu Nov 03 11:18:52 2011 +0400
@@ -17,10 +17,11 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-/*
+ *
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
@@ -56,6 +57,7 @@
#ifdef __STDC__
#if !defined(_XPG4_2) || defined(__EXTENSIONS__)
extern int inet_net_pton(int, const char *, void *, size_t);
+extern boolean_t inet_matchaddr(const void *, const char *);
#endif /* !defined(_XPG4_2) || defined(__EXTENSIONS__) */
#if !defined(_XPG4_2) || defined(_XPG6) || defined(__EXTENSIONS__)
--- a/usr/src/lib/libnsl/Makefile.com Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/lib/libnsl/Makefile.com Thu Nov 03 11:18:52 2011 +0400
@@ -21,6 +21,7 @@
#
# Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
#
LIBRARY= libnsl.a
@@ -41,8 +42,8 @@
NSS= \
gethostbyname_r.o gethostent.o gethostent_r.o gethostent6.o gethostby_door.o \
-getipnodeby_door.o getipnodeby.o getrpcent.o getrpcent_r.o inet_pton.o \
-inet_ntop.o netdir_inet.o netdir_inet_sundry.o \
+getipnodeby_door.o getipnodeby.o getrpcent.o getrpcent_r.o inet_matchaddr.o \
+inet_pton.o inet_ntop.o netdir_inet.o netdir_inet_sundry.o \
parse.o getauthattr.o getprofattr.o getexecattr.o getuserattr.o getauuser.o
NETSELECT= netselect.o
--- a/usr/src/lib/libnsl/common/llib-lnsl Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/lib/libnsl/common/llib-lnsl Thu Nov 03 11:18:52 2011 +0400
@@ -22,6 +22,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
@@ -437,6 +439,9 @@
void endrpcent(void);
struct rpcent *getrpcent_r(struct rpcent *result, char *buffer, int buflen);
+/* inet_matchaddr.c */
+boolean_t inet_matchaddr(const void *, const char *);
+
/* inet_ntop.c */
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);
--- a/usr/src/lib/libnsl/common/mapfile-vers Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/lib/libnsl/common/mapfile-vers Thu Nov 03 11:18:52 2011 +0400
@@ -20,7 +20,7 @@
#
#
# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
-#
+# Copyright 2011 Nexenta Systems, Inc. All rights reserved.
#
#
@@ -467,6 +467,7 @@
SYMBOL_VERSION SUNWprivate_1.5 {
global:
+ inet_matchaddr;
clnt_create_service_timed;
} SUNWprivate_1.4;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libnsl/nss/inet_matchaddr.c Thu Nov 03 11:18:52 2011 +0400
@@ -0,0 +1,150 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source. A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ *
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
+ */
+
+/*
+ * inet_matchaddr
+ *
+ * Match IPv4 or IPv6 address provided in sa (sockaddr_in/sockaddr_in6)
+ * against standard text representation specified in name:
+ *
+ * IPv4:
+ * IPv4
+ * IPv4/netmask
+ *
+ * IPv6:
+ * [IPv6]
+ * [IPv6]/prefix
+ */
+
+#include <sys/socket.h>
+#include <sys/types.h>
+
+#include <arpa/inet.h>
+
+#include <netinet/in.h>
+
+#include <ctype.h>
+#include <err.h>
+#include <netdb.h>
+#include <stdlib.h>
+#include <strings.h>
+
+
+boolean_t
+inet_matchaddr(const void *sa, const char *name)
+{
+ boolean_t ret = B_FALSE;
+ char *lname, *mp, *p;
+ uint32_t claddr4 = 0;
+
+ if ((p = lname = strdup(name)) == NULL)
+ err(1, "strdup");
+
+ if ((mp = strchr(p, '/')) != NULL)
+ *mp++ = '\0';
+
+ switch (((struct sockaddr_in *)sa)->sin_family) {
+ case AF_INET6: {
+ char *pp;
+ int prefix6;
+ ipaddr_t ipaddr4;
+ struct in6_addr hcaddr6;
+ struct in6_addr *claddr6 =
+ &((struct sockaddr_in6 *)sa)->sin6_addr;
+
+ if (!IN6_IS_ADDR_V4MAPPED(claddr6)) {
+ /* IPv6 address */
+ if ((p = strchr(p, '[')) == NULL)
+ break;
+ p++;
+
+ if ((pp = strchr(p, ']')) == NULL)
+ break;
+ *pp = '\0';
+
+ if (inet_pton(AF_INET6, p, &hcaddr6) != 1)
+ break;
+
+ if (mp != NULL) {
+ /* Match only first prefix bits */
+ if ((prefix6 = (int)strtol(mp,
+ (char **)NULL, 10)) == 0)
+ break;
+ ret = IN6_ARE_PREFIXEDADDR_EQUAL(claddr6,
+ &hcaddr6, prefix6);
+ break;
+ } else {
+ /* No prefix, exact match */
+ ret = IN6_ARE_ADDR_EQUAL(claddr6, &hcaddr6);
+ break;
+ }
+ } else {
+ /* IPv4-mapped IPv6 address, fallthrough to IPv4 */
+ IN6_V4MAPPED_TO_IPADDR(claddr6, ipaddr4);
+ claddr4 = ntohl(ipaddr4);
+ }
+ /*FALLTHROUGH*/
+ }
+ case AF_INET: {
+ int bits, i;
+ uint32_t hcaddr4 = 0, mask4;
+
+ if (claddr4 == 0)
+ claddr4 = ntohl(
+ ((struct sockaddr_in *)sa)->sin_addr.s_addr);
+
+ for (i = 0; i < 4; i++) {
+ hcaddr4 |= (int)strtol(p, (char **)NULL, 10) <<
+ ((3 - i) * 8);
+ if ((p = strchr(p, '.')) == NULL)
+ break;
+ p++;
+ }
+
+ if (hcaddr4 == 0)
+ break;
+
+ if (mp != NULL) {
+ /* Mask is specified explicitly */
+ if ((bits = (int)strtol(mp, (char **)NULL, 10)) == 0)
+ break;
+ mask4 = bits ? ~0 << ((sizeof (struct in_addr) * NBBY)
+ - bits) : 0;
+ hcaddr4 &= mask4;
+ } else {
+ /*
+ * Use old-fashioned implicit netmasking by checking
+ * for lower-end zeroes. On the off chance we don't
+ * match any well-known prefixes, return an exact-
+ * match prefix which is misleadingly labelled as
+ * IN_CLASSE_NET.
+ */
+ if ((hcaddr4 & IN_CLASSA_HOST) == 0)
+ mask4 = IN_CLASSA_NET;
+ else if ((hcaddr4 & IN_CLASSB_HOST) == 0)
+ mask4 = IN_CLASSB_NET;
+ else if ((hcaddr4 & IN_CLASSC_HOST) == 0)
+ mask4 = IN_CLASSC_NET;
+ else
+ mask4 = IN_CLASSE_NET;
+ }
+
+ ret = ((claddr4 & mask4) == hcaddr4);
+ break;
+ }
+ }
+
+ free(lname);
+
+ return (ret);
+}
--- a/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/lib/smbsrv/libmlsvc/common/smb_share.c Thu Nov 03 11:18:52 2011 +0400
@@ -17,9 +17,9 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-/*
+ *
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
@@ -739,9 +739,6 @@
* Precedence is none is checked first followed by ro then rw if
* needed. If x is wildcard (< 0) then check to see if the other
* values are a match. If a match, that wins.
- *
- * ipv6 is wide open (returns SMB_SHRF_ACC_OPEN) for now until the underlying
- * functions support ipv6.
*/
uint32_t
smb_shr_hostaccess(smb_inaddr_t *ipaddr, char *none_list, char *ro_list,
@@ -753,10 +750,6 @@
int rw = 0;
if (!smb_inet_iszero(ipaddr)) {
-
- if (ipaddr->a_family == AF_INET6)
- return (SMB_SHRF_ACC_OPEN);
-
if ((flag & SMB_SHRF_ACC_NONE) != 0)
none = smb_chk_hostaccess(ipaddr, none_list);
if ((flag & SMB_SHRF_ACC_RO) != 0)
--- a/usr/src/lib/smbsrv/libsmb/common/smb_util.c Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/lib/smbsrv/libsmb/common/smb_util.c Thu Nov 03 11:18:52 2011 +0400
@@ -77,11 +77,9 @@
static smb_log_t *smb_log_get(smb_log_hdl_t);
static void smb_log_dump(smb_log_t *);
-static uint_t smb_make_mask(char *, uint_t);
-static boolean_t smb_netmatch(struct netbuf *, char *);
static boolean_t smb_netgroup_match(struct nd_hostservlist *, char *, int);
-extern int __multi_innetgr();
+extern int __multi_innetgr();
extern int __netdir_getbyaddr_nosrv(struct netconfig *,
struct nd_hostservlist **, struct netbuf *);
@@ -413,54 +411,80 @@
int
smb_chk_hostaccess(smb_inaddr_t *ipaddr, char *access_list)
{
- int nentries;
- char *gr;
- char *lasts;
+ char addr[INET_ADDRSTRLEN];
+ char buff[256];
+ char *cstr = access_list, *gr = access_list;
char *host;
- int off;
+ int clres;
int i;
+ int nentries = 0;
+ int off;
int response;
- int clres;
+ int sbr = 0;
struct nd_hostservlist *clnames;
struct in_addr inaddr;
struct sockaddr_in sa;
+ struct sockaddr_in6 sa6;
struct netbuf buf;
struct netconfig *config;
+ struct netent n, *np;
if (access_list == NULL)
return (0);
- inaddr.s_addr = ipaddr->a_ipv4;
-
- /*
- * If access list is empty or "*" - then it's "all"
- */
+ /* If access list is empty or "*" - then it's "all" */
if (*access_list == '\0' || strcmp(access_list, "*") == 0)
return (-1);
- nentries = 0;
+ switch (ipaddr->a_family) {
+ case AF_INET:
+ inaddr.s_addr = ipaddr->a_ipv4;
+ sa.sin_family = AF_INET;
+ sa.sin_port = 0;
+ sa.sin_addr = inaddr;
+ buf.len = buf.maxlen = sizeof (sa);
+ buf.buf = (char *)&sa;
+ config = getnetconfigent("tcp");
+ break;
+ case AF_INET6:
+ sa6.sin6_family = AF_INET6;
+ sa6.sin6_port = 0;
+ sa6.sin6_addr = ipaddr->a_ipv6;
+ buf.len = buf.maxlen = sizeof (sa6);
+ buf.buf = (char *)&sa6;
+ config = getnetconfigent("tcp6");
+ break;
+ default:
+ return (1);
+ }
- sa.sin_family = AF_INET;
- sa.sin_port = 0;
- sa.sin_addr = inaddr;
-
- buf.len = buf.maxlen = sizeof (sa);
- buf.buf = (char *)&sa;
-
- config = getnetconfigent("tcp");
if (config == NULL)
return (1);
+ /* Try to lookup client hostname */
clres = __netdir_getbyaddr_nosrv(config, &clnames, &buf);
freenetconfigent(config);
- for (gr = strtok_r(access_list, ":", &lasts);
- gr != NULL; gr = strtok_r(NULL, ":", &lasts)) {
+ for (;;) {
+ if ((cstr = strpbrk(cstr, "[]:")) != NULL) {
+ switch (*cstr) {
+ case '[':
+ case ']':
+ sbr = !sbr;
+ cstr++;
+ continue;
+ case ':':
+ if (sbr) {
+ cstr++;
+ continue;
+ }
+ *cstr = '\0';
+ }
+ }
/*
- * If the list name has a '-' prepended
- * then a match of the following name
- * implies failure instead of success.
+ * If the list name has a '-' prepended then a match of
+ * the following name implies failure instead of success.
*/
if (*gr == '-') {
response = 0;
@@ -470,21 +494,53 @@
}
/*
- * First check if we have '@' entry, as smb_netmatch doesn't
- * care if client address can be resolved.
+ * First check if we have '@' entry, as it doesn't
+ * require client hostname.
*/
- if (*gr == '@')
- if (smb_netmatch(&buf, gr + 1))
- return (response);
+ if (*gr == '@') {
+ gr++;
+
+ if (!isdigit(*gr) && *gr != '[') {
+ /* Netname support */
+ if ((np = getnetbyname_r(gr, &n, buff,
+ sizeof (buff))) != NULL &&
+ np->n_net != 0) {
+ while ((np->n_net & 0xFF000000u) == 0)
+ np->n_net <<= 8;
+ np->n_net = htonl(np->n_net);
+ if (inet_ntop(AF_INET, &np->n_net, addr,
+ INET_ADDRSTRLEN) == NULL)
+ break;
+ if (inet_matchaddr(buf.buf, addr))
+ return (response);
+ }
+ } else {
+ if (inet_matchaddr(buf.buf, gr))
+ return (response);
+ }
+
+ if (cstr == NULL)
+ break;
+
+ gr = ++cstr;
+
+ continue;
+ }
+
/*
* No other checks can be performed if client address
* can't be resolved.
*/
- if (clres)
+ if (clres) {
+ if (cstr == NULL)
+ break;
+
+ gr = ++cstr;
+
continue;
- /*
- * Otherwise loop through all client hostname aliases.
- */
+ }
+
+ /* Otherwise loop through all client hostname aliases */
for (i = 0; i < clnames->h_cnt; i++) {
host = clnames->h_hostservs[i].h_host;
/*
@@ -494,7 +550,7 @@
* suffix.
*/
if (*gr == '.') {
- if (*(gr + 1) == '\0') { /* single dot */
+ if (*(gr + 1) == '\0') {
if (strchr(host, '.') == NULL)
return (response);
} else {
@@ -505,15 +561,18 @@
}
}
} else {
- /*
- * Just do a hostname match
- */
+ /* Just do a hostname match */
if (strcasecmp(gr, host) == 0)
return (response);
}
}
nentries++;
+
+ if (cstr == NULL)
+ break;
+
+ gr = ++cstr;
}
if (clres)
@@ -523,116 +582,6 @@
}
/*
- * smb_make_mask
- *
- * Construct a mask for an IPv4 address using the @<dotted-ip>/<len>
- * syntax or use the default mask for the IP address.
- */
-static uint_t
-smb_make_mask(char *maskstr, uint_t addr)
-{
- uint_t mask;
- uint_t bits;
-
- /*
- * If the mask is specified explicitly then
- * use that value, e.g.
- *
- * @109.104.56/28
- *
- * otherwise assume a mask from the zero octets
- * in the least significant bits of the address, e.g.
- *
- * @109.104 or @109.104.0.0
- */
- if (maskstr) {
- bits = atoi(maskstr);
- mask = bits ? ~0 << ((sizeof (struct in_addr) * NBBY) - bits)
- : 0;
- addr &= mask;
- } else {
- if ((addr & IN_CLASSA_HOST) == 0)
- mask = IN_CLASSA_NET;
- else if ((addr & IN_CLASSB_HOST) == 0)
- mask = IN_CLASSB_NET;
- else if ((addr & IN_CLASSC_HOST) == 0)
- mask = IN_CLASSC_NET;
- else
- mask = IN_CLASSE_NET;
- }
-
- return (mask);
-}
-
-/*
- * smb_netmatch
- *
- * Check to see if the address in the netbuf matches the "net"
- * specified by name. The format of "name" can be:
- * fully qualified domain name
- * dotted IP address
- * dotted IP address followed by '/<len>'
- * See sharen_nfs(1M) for details.
- */
-
-static boolean_t
-smb_netmatch(struct netbuf *nb, char *name)
-{
- uint_t claddr;
- struct netent n, *np;
- char *mp, *p;
- uint_t addr, mask;
- int i;
- char buff[256];
-
- /*
- * Check if it's an IPv4 addr
- */
- if (nb->len != sizeof (struct sockaddr_in))
- return (B_FALSE);
-
- (void) memcpy(&claddr,
- /* LINTED pointer alignment */
- &((struct sockaddr_in *)nb->buf)->sin_addr.s_addr,
- sizeof (struct in_addr));
- claddr = ntohl(claddr);
-
- mp = strchr(name, '/');
- if (mp)
- *mp++ = '\0';
-
- if (isdigit(*name)) {
- /*
- * Convert a dotted IP address
- * to an IP address. The conversion
- * is not the same as that in inet_addr().
- */
- p = name;
- addr = 0;
- for (i = 0; i < 4; i++) {
- addr |= atoi(p) << ((3-i) * 8);
- p = strchr(p, '.');
- if (p == NULL)
- break;
- p++;
- }
- } else {
- /*
- * Turn the netname into
- * an IP address.
- */
- np = getnetbyname_r(name, &n, buff, sizeof (buff));
- if (np == NULL) {
- return (B_FALSE);
- }
- addr = np->n_net;
- }
-
- mask = smb_make_mask(mp, addr);
- return ((claddr & mask) == addr);
-}
-
-/*
* smb_netgroup_match
*
* Check whether any of the hostnames in clnames are
--- a/usr/src/uts/common/netinet/in.h Tue Nov 01 10:17:46 2011 +0400
+++ b/usr/src/uts/common/netinet/in.h Thu Nov 03 11:18:52 2011 +0400
@@ -1,6 +1,8 @@
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Copyright (c) 1982, 1986 Regents of the University of California.
@@ -839,6 +841,38 @@
((addr1)->_S6_un._S6_u32[1] == (addr2)->_S6_un._S6_u32[1]) && \
((addr1)->_S6_un._S6_u32[0] == (addr2)->_S6_un._S6_u32[0]))
+/*
+ * IN6_ARE_PREFIXEDADDR_EQUAL (not defined in RFCs)
+ * Compares if prefixed parts of IPv6 addresses are equal.
+ *
+ * uint32_t IN6_MASK_FROM_PREFIX(int, int);
+ * bool IN6_ARE_PREFIXEDADDR_EQUAL(const struct in6_addr *,
+ * const struct in6_addr *,
+ * int);
+ */
+#define IN6_MASK_FROM_PREFIX(qoctet, prefix) \
+ ((((qoctet) + 1) * 32 < (prefix)) ? 0xFFFFFFFFu : \
+ ((((qoctet) * 32) >= (prefix)) ? 0x00000000u : \
+ 0xFFFFFFFFu << (((qoctet) + 1) * 32 - (prefix))))
+
+#define IN6_ARE_PREFIXEDADDR_EQUAL(addr1, addr2, prefix) \
+ (((ntohl((addr1)->_S6_un._S6_u32[0]) & \
+ IN6_MASK_FROM_PREFIX(0, prefix)) == \
+ (ntohl((addr2)->_S6_un._S6_u32[0]) & \
+ IN6_MASK_FROM_PREFIX(0, prefix))) && \
+ ((ntohl((addr1)->_S6_un._S6_u32[1]) & \
+ IN6_MASK_FROM_PREFIX(1, prefix)) == \
+ (ntohl((addr2)->_S6_un._S6_u32[1]) & \
+ IN6_MASK_FROM_PREFIX(1, prefix))) && \
+ ((ntohl((addr1)->_S6_un._S6_u32[2]) & \
+ IN6_MASK_FROM_PREFIX(2, prefix)) == \
+ (ntohl((addr2)->_S6_un._S6_u32[2]) & \
+ IN6_MASK_FROM_PREFIX(2, prefix))) && \
+ ((ntohl((addr1)->_S6_un._S6_u32[3]) & \
+ IN6_MASK_FROM_PREFIX(3, prefix)) == \
+ (ntohl((addr2)->_S6_un._S6_u32[3]) & \
+ IN6_MASK_FROM_PREFIX(3, prefix))))
+
#endif /* !defined(_XPG4_2) || defined(_XPG6) || defined(__EXTENSIONS__) */