On Thu, 2007-01-25 at 16:37 +0900, Ian Kent wrote: > On Wed, 2007-01-24 at 13:13 -0600, Bill Maloy wrote: > > Solaris NFS servers can be configured to use a network > > specifier in the access_list of an NFS exported file > > system. > > > > >From <http://docs.sun.com/app/docs/doc/816-0211/6m6nc676n?a=view> > > "The network or subnet component is preceded by an at-sign (@). " > > *Sigh* > I missed that as well when I updated to account for the Solaris export > semantics.
How about trying this patch out. I haven't had a chance to test this at all yet so beware. Ian diff --git a/lib/rpc_subs.c b/lib/rpc_subs.c index b4e9c91..a794d76 100644 --- a/lib/rpc_subs.c +++ b/lib/rpc_subs.c @@ -31,6 +31,7 @@ #include <rpcsvc/ypclnt.h> #include <errno.h> #include <sys/ioctl.h> +#include <pthread.h> #include "mount.h" #include "rpc_subs.h" @@ -43,9 +44,14 @@ #endif #define MAX_ERR_BUF 512 +/* Get numeric value of the n bits starting at position p */ +#define getbits(x, p, n) ((x >> (p + 1 - n)) & ~(~0 << n)) static char *ypdomain = NULL; +inline void dump_core(void); +static pthread_mutex_t networks_mutex = PTHREAD_MUTEX_INITIALIZER; + /* * Create a UDP RPC client */ @@ -965,12 +971,127 @@ static int string_match(const char *myname, const char *pattern) return ret; } +static unsigned int get_networks_mask(struct netent *net) +{ + if (IN_CLASSC(net->n_net)) + return 24; + else if (IN_CLASSB(net->n_net)) + return 16; + else if (IN_CLASSA(net->n_net)) + return 8; + + return 0; +} + +static unsigned int inet_get_net_len(uint32_t net) +{ + int i; + + for (i = 0; i < 32; i++) { + if (getbits(net, i, 1)) + break; + } + + return (unsigned int) i; +} + +static char *inet_fill_net(const char *net_num, char *net) +{ + char *np; + unsigned int dots = 3; + + *net = '\0'; + strcpy(net, net_num); + + np = net; + while (*np) { + if (*np++ == '.') { + dots--; + if (!*np && dots) + strcat(net, "0"); + } + } + + while (dots--) + strcat(net, ".0"); + + return net; +} + +static int match_network(const char *network) +{ + struct netent *pnent, nent; + const char *pcnet; + char *net, cnet[17], mask[4], *pmask; + unsigned int size; + int status; + + net = alloca(strlen(network) + 1); + if (!net) + return 0; + strcpy(net, network); + + if ((pmask = strchr(net, '/'))) + *pmask++ = '\0'; + + status = pthread_mutex_lock(&networks_mutex); + if (status) + fatal(status); + + pnent = getnetbyname(net); + if (pnent) + memcpy(&nent, pnent, sizeof(struct netent)); + + status = pthread_mutex_unlock(&networks_mutex); + if (status) + fatal(status); + + if (pnent) { + uint32_t n_net; + + n_net = ntohl(nent.n_net); + pcnet = inet_ntop(nent.n_addrtype, &n_net, cnet, 16); + if (!pcnet) + return 0; + + if (!pmask) { + size = get_networks_mask(&nent); + if (!size) + return 0; + } + } else { + struct in_addr addr; + int ret; + + pcnet = inet_fill_net(net, cnet); + if (!pcnet) + return 0; + + ret = inet_pton(AF_INET, pcnet, &addr); + if (ret <= 0) + return 0; + + if (!pmask) { + size = inet_get_net_len(htonl(addr.s_addr)); + if (!size) + return 0; + } + } + + if (!pmask) { + if (sprintf(mask, "%u", size) <= 0) + return 0; + pmask = mask; + } + + return masked_match(pcnet, mask); +} + static int host_match(char *pattern) { unsigned int negate = (*pattern == '-'); const char *m_pattern = (negate ? pattern + 1 : pattern); char myname[MAXHOSTNAMELEN + 1] = "\0"; - struct in_addr tmp; int ret = 0; if (gethostname(myname, MAXHOSTNAMELEN)) @@ -982,26 +1103,13 @@ static int host_match(char *pattern) if (*m_pattern == '@') { if (ypdomain) ret = innetgr(m_pattern + 1, myname, NULL, ypdomain); - } else if (inet_aton(m_pattern, &tmp) || strchr(m_pattern, '/')) { - size_t len = strlen(m_pattern) + 1; - char *addr, *mask; - - addr = alloca(len); - if (!addr) - return 0; - - memset(addr, 0, len); - memcpy(addr, m_pattern, len - 1); - mask = strchr(addr, '/'); - if (mask) { - *mask++ = '\0'; - ret = masked_match(addr, mask); - } else - ret = masked_match(addr, "32"); + if (!ret) + ret = match_network(m_pattern + 1); } else if (!strcmp(m_pattern, "gss/krb5")) { /* Leave this to the GSS layer */ ret = 1; - } else + } else if ((ret = match_network(m_pattern))) ; + else ret = string_match(myname, m_pattern); if (negate) _______________________________________________ autofs mailing list autofs@linux.kernel.org http://linux.kernel.org/mailman/listinfo/autofs