Module Name: src
Committed By: christos
Date: Wed Dec 23 16:19:49 UTC 2015
Modified Files:
src/usr.sbin/mountd: Makefile mountd.c
Added Files:
src/usr.sbin/mountd: get_net.c mountd.h
Log Message:
Split out get_net function so that it is easily testable. Restore
functionality where 1.2.3/24 -> 1.2.3.0/24 not 1.2.0.3/24 now that
getaddrinfo(3) parses old-style incomplete dotted quads as old
style addresses.
To generate a diff of this commit:
cvs rdiff -u -r1.18 -r1.19 src/usr.sbin/mountd/Makefile
cvs rdiff -u -r0 -r1.1 src/usr.sbin/mountd/get_net.c \
src/usr.sbin/mountd/mountd.h
cvs rdiff -u -r1.128 -r1.129 src/usr.sbin/mountd/mountd.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/usr.sbin/mountd/Makefile
diff -u src/usr.sbin/mountd/Makefile:1.18 src/usr.sbin/mountd/Makefile:1.19
--- src/usr.sbin/mountd/Makefile:1.18 Mon May 28 08:06:37 2007
+++ src/usr.sbin/mountd/Makefile Wed Dec 23 11:19:49 2015
@@ -1,10 +1,10 @@
-# $NetBSD: Makefile,v 1.18 2007/05/28 12:06:37 tls Exp $
+# $NetBSD: Makefile,v 1.19 2015/12/23 16:19:49 christos Exp $
# @(#)Makefile 8.3 (Berkeley) 1/25/94
USE_FORT?= yes # network server
PROG= mountd
-SRCS= mountd.c ipsec.c
+SRCS= mountd.c ipsec.c get_net.c
MAN= exports.5 mountd.8
INETDDIR= ${.CURDIR}/../inetd
Index: src/usr.sbin/mountd/mountd.c
diff -u src/usr.sbin/mountd/mountd.c:1.128 src/usr.sbin/mountd/mountd.c:1.129
--- src/usr.sbin/mountd/mountd.c:1.128 Sun Nov 8 16:03:16 2015
+++ src/usr.sbin/mountd/mountd.c Wed Dec 23 11:19:49 2015
@@ -1,4 +1,4 @@
-/* $NetBSD: mountd.c,v 1.128 2015/11/08 21:03:16 christos Exp $ */
+/* $NetBSD: mountd.c,v 1.129 2015/12/23 16:19:49 christos Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1989, 19
#if 0
static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95";
#else
-__RCSID("$NetBSD: mountd.c,v 1.128 2015/11/08 21:03:16 christos Exp $");
+__RCSID("$NetBSD: mountd.c,v 1.129 2015/12/23 16:19:49 christos Exp $");
#endif
#endif /* not lint */
@@ -105,6 +105,8 @@ __RCSID("$NetBSD: mountd.c,v 1.128 2015/
#define DEBUGGING 0
#endif
+#include "mountd.h"
+
/*
* Structures for keeping the mount list and export list
*/
@@ -140,12 +142,6 @@ struct exportlist {
/* ex_flag bits */
#define EX_LINKED 0x1
-struct netmsk {
- struct sockaddr_storage nt_net;
- int nt_len;
- char *nt_name;
-};
-
union grouptypes {
struct addrinfo *gt_addrinfo;
struct netmsk gt_net;
@@ -206,7 +202,6 @@ static int get_host(const char *, size_t
struct grouplist *);
static struct hostlist *get_ht(void);
static void get_mountlist(void);
-static int get_net(char *, struct netmsk *, int);
static void free_exp_grp(struct exportlist *, struct grouplist *);
static struct grouplist *get_grp(void);
static void hang_dirp(struct dirlist *, struct grouplist *,
@@ -225,7 +220,6 @@ static int bitcmp(void *, void *, int);
static int netpartcmp(struct sockaddr *, struct sockaddr *, int);
static int sacmp(struct sockaddr *, struct sockaddr *);
static int allones(struct sockaddr_storage *, int);
-static int countones(struct sockaddr *);
static void bind_resv_port(int, sa_family_t, in_port_t);
__dead static void no_nfs(int);
static struct exportlist *exphead;
@@ -240,22 +234,11 @@ static struct uucred def_anon = {
{ 0 }
};
-static int opt_flags;
+int opt_flags;
static int have_v6 = 1;
-static const int ninumeric = NI_NUMERICHOST;
-
-/* Bits for above */
-#define OP_MAPROOT 0x001
-#define OP_MAPALL 0x002
-#define OP_KERB 0x004
-#define OP_MASK 0x008
-#define OP_NET 0x010
-#define OP_ALLDIRS 0x040
-#define OP_NORESPORT 0x080
-#define OP_NORESMNT 0x100
-#define OP_MASKLEN 0x200
+const int ninumeric = NI_NUMERICHOST;
-static int debug = DEBUGGING;
+int debug = DEBUGGING;
#if 0
static void SYSLOG(int, const char *,...);
#endif
@@ -1590,41 +1573,6 @@ allones(struct sockaddr_storage *ssp, in
}
static int
-countones(struct sockaddr *sa)
-{
- void *mask;
- int i, bits = 0, bytelen;
- u_int8_t *p;
-
- switch (sa->sa_family) {
- case AF_INET:
- mask = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr;
- bytelen = 4;
- break;
- case AF_INET6:
- mask = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr;
- bytelen = 16;
- break;
- default:
- return 0;
- }
-
- p = mask;
-
- for (i = 0; i < bytelen; i++, p++) {
- if (*p != 0xff) {
- for (bits = 0; bits < 8; bits++) {
- if (!(*p & (1 << (7 - bits))))
- break;
- }
- break;
- }
- }
-
- return (i * 8 + bits);
-}
-
-static int
sacmp(struct sockaddr *sa1, struct sockaddr *sa2)
{
void *p1, *p2;
@@ -2051,125 +1999,6 @@ skip:
}
/*
- * Translate a net address.
- */
-static int
-get_net(char *cp, struct netmsk *net, int maskflg)
-{
- struct netent *np;
- char *nname, *p, *prefp;
- struct sockaddr_in sin, *sinp;
- struct sockaddr *sa;
- struct addrinfo hints, *ai = NULL;
- char netname[NI_MAXHOST];
- long preflen;
- int ecode;
-
- (void)memset(&sin, 0, sizeof(sin));
- if ((opt_flags & OP_MASKLEN) && !maskflg) {
- p = strchr(cp, '/');
- *p = '\0';
- prefp = p + 1;
- } else {
- p = NULL; /* XXXGCC -Wuninitialized */
- prefp = NULL; /* XXXGCC -Wuninitialized */
- }
-
- if ((np = getnetbyname(cp)) != NULL) {
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof sin;
- sin.sin_addr = inet_makeaddr(np->n_net, 0);
- sa = (struct sockaddr *)&sin;
- } else if (isdigit((unsigned char)*cp)) {
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(cp, NULL, &hints, &ai) != 0) {
- /*
- * If getaddrinfo() failed, try the inet4 network
- * notation with less than 3 dots.
- */
- sin.sin_family = AF_INET;
- sin.sin_len = sizeof sin;
- sin.sin_addr = inet_makeaddr(inet_network(cp),0);
- if (debug)
- fprintf(stderr, "get_net: v4 addr %x\n",
- sin.sin_addr.s_addr);
- sa = (struct sockaddr *)&sin;
- } else
- sa = ai->ai_addr;
- } else if (isxdigit((unsigned char)*cp) || *cp == ':') {
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(cp, NULL, &hints, &ai) == 0)
- sa = ai->ai_addr;
- else
- goto fail;
- } else
- goto fail;
-
- /*
- * Only allow /pref notation for v6 addresses.
- */
- if (sa->sa_family == AF_INET6 && (!(opt_flags & OP_MASKLEN) || maskflg))
- return 1;
-
- ecode = getnameinfo(sa, sa->sa_len, netname, sizeof netname,
- NULL, 0, ninumeric);
- if (ecode != 0)
- goto fail;
-
- if (maskflg)
- net->nt_len = countones(sa);
- else {
- if (opt_flags & OP_MASKLEN) {
- errno = 0;
- preflen = strtol(prefp, NULL, 10);
- if (preflen == LONG_MIN && errno == ERANGE)
- goto fail;
- net->nt_len = (int)preflen;
- *p = '/';
- }
-
- if (np)
- nname = np->n_name;
- else {
- if (getnameinfo(sa, sa->sa_len, netname, sizeof netname,
- NULL, 0, ninumeric) != 0)
- strlcpy(netname, "?", sizeof(netname));
- nname = netname;
- }
- net->nt_name = estrdup(nname);
- memcpy(&net->nt_net, sa, sa->sa_len);
- }
-
- if (!maskflg && sa->sa_family == AF_INET &&
- !(opt_flags & (OP_MASK|OP_MASKLEN))) {
- sinp = (struct sockaddr_in *)sa;
- if (IN_CLASSA(sinp->sin_addr.s_addr))
- net->nt_len = 8;
- else if (IN_CLASSB(sinp->sin_addr.s_addr))
- net->nt_len = 16;
- else if (IN_CLASSC(sinp->sin_addr.s_addr))
- net->nt_len = 24;
- else if (IN_CLASSD(sinp->sin_addr.s_addr))
- net->nt_len = 28;
- else
- net->nt_len = 32; /* XXX */
- }
-
- if (ai)
- freeaddrinfo(ai);
- return 0;
-
-fail:
- if (ai)
- freeaddrinfo(ai);
- return 1;
-}
-
-/*
* Parse out the next white space separated field
*/
static void
Added files:
Index: src/usr.sbin/mountd/get_net.c
diff -u /dev/null src/usr.sbin/mountd/get_net.c:1.1
--- /dev/null Wed Dec 23 11:19:49 2015
+++ src/usr.sbin/mountd/get_net.c Wed Dec 23 11:19:49 2015
@@ -0,0 +1,236 @@
+/* $NetBSD: get_net.c,v 1.1 2015/12/23 16:19:49 christos Exp $ */
+
+/*
+ * Copyright (c) 1989, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Herb Hasler and Rick Macklem at The University of Guelph.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: get_net.c,v 1.1 2015/12/23 16:19:49 christos Exp $");
+
+#include <sys/types.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <limits.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <util.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+
+#include "mountd.h"
+
+#ifdef TEST
+int opt_flags;
+const int ninumeric = NI_NUMERICHOST;
+int debug = 1;
+#endif
+
+static int
+isdottedquad(const char *cp)
+{
+ for (;;)
+ switch (*cp++) {
+ case '\0':
+ return 1;
+ case '.':
+ case '0': case '1': case '2': case '3': case '4':
+ case '5': case '6': case '7': case '8': case '9':
+ continue;
+ default:
+ return 0;
+ }
+}
+
+static int
+countones(struct sockaddr *sa)
+{
+ void *mask;
+ int i, bits = 0, bytelen;
+ u_int8_t *p;
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ mask = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr;
+ bytelen = 4;
+ break;
+ case AF_INET6:
+ mask = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr;
+ bytelen = 16;
+ break;
+ default:
+ return 0;
+ }
+
+ p = mask;
+
+ for (i = 0; i < bytelen; i++, p++) {
+ if (*p != 0xff) {
+ for (bits = 0; bits < 8; bits++) {
+ if (!(*p & (1 << (7 - bits))))
+ break;
+ }
+ break;
+ }
+ }
+
+ return (i * 8 + bits);
+}
+
+/*
+ * Translate a net address.
+ */
+int
+get_net(char *cp, struct netmsk *net, int maskflg)
+{
+ struct netent *np;
+ char *nname, *p, *prefp;
+ struct sockaddr_in sin, *sinp;
+ struct sockaddr *sa;
+ struct addrinfo hints, *ai = NULL;
+ char netname[NI_MAXHOST];
+ long preflen;
+ int ecode;
+
+ (void)memset(&sin, 0, sizeof(sin));
+ if ((opt_flags & OP_MASKLEN) && !maskflg) {
+ p = strchr(cp, '/');
+ *p = '\0';
+ prefp = p + 1;
+ } else {
+ p = NULL; /* XXXGCC -Wuninitialized */
+ prefp = NULL; /* XXXGCC -Wuninitialized */
+ }
+
+ if ((np = getnetbyname(cp)) != NULL) {
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof sin;
+ sin.sin_addr = inet_makeaddr(np->n_net, 0);
+ sa = (struct sockaddr *)&sin;
+ } else if (isdottedquad(cp)) {
+ /*
+ * Handle dotted quad [or less than quad] notation specially
+ * because getaddrinfo() will parse them in the old style:
+ * i.e. 1.2.3 -> 1.2.0.3 not 1.2.3.0
+ */
+ sin.sin_family = AF_INET;
+ sin.sin_len = sizeof sin;
+ sin.sin_addr = inet_makeaddr(inet_network(cp), 0);
+ if (debug)
+ fprintf(stderr, "get_net: '%s' v4 addr %x\n",
+ cp, sin.sin_addr.s_addr);
+ sa = (struct sockaddr *)&sin;
+ } else {
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(cp, NULL, &hints, &ai) == 0)
+ sa = ai->ai_addr;
+ else
+ goto fail;
+ }
+
+ /*
+ * Only allow /pref notation for v6 addresses.
+ */
+ if (sa->sa_family == AF_INET6 && (!(opt_flags & OP_MASKLEN) || maskflg))
+ return 1;
+
+ ecode = getnameinfo(sa, sa->sa_len, netname, sizeof netname,
+ NULL, 0, ninumeric);
+ if (ecode != 0)
+ goto fail;
+
+ if (maskflg)
+ net->nt_len = countones(sa);
+ else {
+ if (opt_flags & OP_MASKLEN) {
+ errno = 0;
+ preflen = strtol(prefp, NULL, 10);
+ if (preflen == LONG_MIN && errno == ERANGE)
+ goto fail;
+ net->nt_len = (int)preflen;
+ *p = '/';
+ }
+
+ if (np)
+ nname = np->n_name;
+ else {
+ if (getnameinfo(sa, sa->sa_len, netname, sizeof netname,
+ NULL, 0, ninumeric) != 0)
+ strlcpy(netname, "?", sizeof(netname));
+ nname = netname;
+ }
+ net->nt_name = estrdup(nname);
+ memcpy(&net->nt_net, sa, sa->sa_len);
+ }
+
+ if (!maskflg && sa->sa_family == AF_INET &&
+ !(opt_flags & (OP_MASK|OP_MASKLEN))) {
+ sinp = (struct sockaddr_in *)sa;
+ if (IN_CLASSA(sinp->sin_addr.s_addr))
+ net->nt_len = 8;
+ else if (IN_CLASSB(sinp->sin_addr.s_addr))
+ net->nt_len = 16;
+ else if (IN_CLASSC(sinp->sin_addr.s_addr))
+ net->nt_len = 24;
+ else if (IN_CLASSD(sinp->sin_addr.s_addr))
+ net->nt_len = 28;
+ else
+ net->nt_len = 32; /* XXX */
+ }
+
+ if (ai)
+ freeaddrinfo(ai);
+ return 0;
+
+fail:
+ if (ai)
+ freeaddrinfo(ai);
+ return 1;
+}
+
+#ifdef TEST
+int
+main(int argc, char *argv[])
+{
+ char buf[1024];
+ struct netmsk nm;
+
+ if (get_net(argv[1], &nm, 0))
+ errx(EXIT_FAILURE, "get_net failed");
+
+ sockaddr_snprintf(buf, sizeof(buf), "%a:%p", (void *)&nm.nt_net);
+ printf("%s %d %s\n", buf, nm.nt_len, nm.nt_name);
+ return 0;
+}
+#endif
Index: src/usr.sbin/mountd/mountd.h
diff -u /dev/null src/usr.sbin/mountd/mountd.h:1.1
--- /dev/null Wed Dec 23 11:19:49 2015
+++ src/usr.sbin/mountd/mountd.h Wed Dec 23 11:19:49 2015
@@ -0,0 +1,22 @@
+
+#define OP_MAPROOT 0x001
+#define OP_MAPALL 0x002
+#define OP_KERB 0x004
+#define OP_MASK 0x008
+#define OP_NET 0x010
+#define OP_ALLDIRS 0x040
+#define OP_NORESPORT 0x080
+#define OP_NORESMNT 0x100
+#define OP_MASKLEN 0x200
+
+extern int opt_flags;
+extern int debug;
+extern const int ninumeric;
+
+struct netmsk {
+ struct sockaddr_storage nt_net;
+ int nt_len;
+ char *nt_name;
+};
+
+int get_net(char *, struct netmsk *, int);