Deleted Added
full compact
mountd.c (75754) mountd.c (75801)
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Herb Hasler and Rick Macklem at The University of Guelph.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 31 unchanged lines hidden (view full) ---

40 The Regents of the University of California. All rights reserved.\n";
41#endif /*not lint*/
42
43#ifndef lint
44#if 0
45static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95";
46#endif
47static const char rcsid[] =
1/*
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Herb Hasler and Rick Macklem at The University of Guelph.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 31 unchanged lines hidden (view full) ---

40 The Regents of the University of California. All rights reserved.\n";
41#endif /*not lint*/
42
43#ifndef lint
44#if 0
45static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95";
46#endif
47static const char rcsid[] =
48 "$FreeBSD: head/usr.sbin/mountd/mountd.c 75754 2001-04-21 00:55:17Z iedowse $";
48 "$FreeBSD: head/usr.sbin/mountd/mountd.c 75801 2001-04-21 20:06:18Z iedowse $";
49#endif /*not lint*/
50
51#include <sys/param.h>
52#include <sys/mount.h>
53#include <sys/fcntl.h>
54#include <sys/stat.h>
55#include <sys/syslog.h>
56#include <sys/sysctl.h>

--- 63 unchanged lines hidden (view full) ---

120 char *ex_fsdir;
121 char *ex_indexfile;
122};
123/* ex_flag bits */
124#define EX_LINKED 0x1
125
126struct netmsk {
127 struct sockaddr_storage nt_net;
49#endif /*not lint*/
50
51#include <sys/param.h>
52#include <sys/mount.h>
53#include <sys/fcntl.h>
54#include <sys/stat.h>
55#include <sys/syslog.h>
56#include <sys/sysctl.h>

--- 63 unchanged lines hidden (view full) ---

120 char *ex_fsdir;
121 char *ex_indexfile;
122};
123/* ex_flag bits */
124#define EX_LINKED 0x1
125
126struct netmsk {
127 struct sockaddr_storage nt_net;
128 u_int32_t nt_mask;
128 struct sockaddr_storage nt_mask;
129 char *nt_name;
130};
131
132union grouptypes {
133 struct addrinfo *gt_addrinfo;
134 struct netmsk gt_net;
135};
136

--- 23 unchanged lines hidden (view full) ---

160
161/* Global defs */
162char *add_expdir __P((struct dirlist **, char *, int));
163void add_dlist __P((struct dirlist **, struct dirlist *,
164 struct grouplist *, int));
165void add_mlist __P((char *, char *));
166int check_dirpath __P((char *));
167int check_options __P((struct dirlist *));
129 char *nt_name;
130};
131
132union grouptypes {
133 struct addrinfo *gt_addrinfo;
134 struct netmsk gt_net;
135};
136

--- 23 unchanged lines hidden (view full) ---

160
161/* Global defs */
162char *add_expdir __P((struct dirlist **, char *, int));
163void add_dlist __P((struct dirlist **, struct dirlist *,
164 struct grouplist *, int));
165void add_mlist __P((char *, char *));
166int check_dirpath __P((char *));
167int check_options __P((struct dirlist *));
168int checkmask(struct sockaddr *sa);
168int chk_host __P((struct dirlist *, struct sockaddr *, int *, int *));
169void del_mlist(char *hostp, char *dirp);
170struct dirlist *dirp_search __P((struct dirlist *, char *));
171int do_mount __P((struct exportlist *, struct grouplist *, int,
172 struct xucred *, char *, int, struct statfs *));
173int do_opt __P((char **, char **, struct exportlist *, struct grouplist *,
174 int *, int *, struct xucred *));
175struct exportlist *ex_search __P((fsid_t *));

--- 8 unchanged lines hidden (view full) ---

184int get_line __P((void));
185void get_mountlist __P((void));
186int get_net __P((char *, struct netmsk *, int));
187void getexp_err __P((struct exportlist *, struct grouplist *));
188struct grouplist *get_grp __P((void));
189void hang_dirp __P((struct dirlist *, struct grouplist *,
190 struct exportlist *, int));
191void huphandler(int sig);
169int chk_host __P((struct dirlist *, struct sockaddr *, int *, int *));
170void del_mlist(char *hostp, char *dirp);
171struct dirlist *dirp_search __P((struct dirlist *, char *));
172int do_mount __P((struct exportlist *, struct grouplist *, int,
173 struct xucred *, char *, int, struct statfs *));
174int do_opt __P((char **, char **, struct exportlist *, struct grouplist *,
175 int *, int *, struct xucred *));
176struct exportlist *ex_search __P((fsid_t *));

--- 8 unchanged lines hidden (view full) ---

185int get_line __P((void));
186void get_mountlist __P((void));
187int get_net __P((char *, struct netmsk *, int));
188void getexp_err __P((struct exportlist *, struct grouplist *));
189struct grouplist *get_grp __P((void));
190void hang_dirp __P((struct dirlist *, struct grouplist *,
191 struct exportlist *, int));
192void huphandler(int sig);
193int makemask(struct sockaddr_storage *ssp, int bitlen);
192void mntsrv __P((struct svc_req *, SVCXPRT *));
193void nextfield __P((char **, char **));
194void out_of_mem __P((void));
195void parsecred __P((char *, struct xucred *));
196int put_exlist __P((struct dirlist *, XDR *, struct dirlist *, int *));
194void mntsrv __P((struct svc_req *, SVCXPRT *));
195void nextfield __P((char **, char **));
196void out_of_mem __P((void));
197void parsecred __P((char *, struct xucred *));
198int put_exlist __P((struct dirlist *, XDR *, struct dirlist *, int *));
199void *sa_rawaddr(struct sockaddr *sa, int *nbytes);
200int sacmp(struct sockaddr *sa1, struct sockaddr *sa2,
201 struct sockaddr *samask);
197int scan_tree __P((struct dirlist *, struct sockaddr *));
198static void usage __P((void));
199int xdr_dir __P((XDR *, char *));
200int xdr_explist __P((XDR *, caddr_t));
201int xdr_fhs __P((XDR *, caddr_t));
202int xdr_mlist __P((XDR *, caddr_t));
203void terminate __P((int));
204
202int scan_tree __P((struct dirlist *, struct sockaddr *));
203static void usage __P((void));
204int xdr_dir __P((XDR *, char *));
205int xdr_explist __P((XDR *, caddr_t));
206int xdr_fhs __P((XDR *, caddr_t));
207int xdr_mlist __P((XDR *, caddr_t));
208void terminate __P((int));
209
205static int bitcmp __P((void *, void *, int));
206static int netpartcmp __P((struct sockaddr *, struct sockaddr *, int));
207static int sacmp __P((struct sockaddr *, struct sockaddr *));
208static int allones __P((struct sockaddr_storage *, int));
209static int countones __P((struct sockaddr *));
210
211struct exportlist *exphead;
212struct mountlist *mlhead;
213struct grouplist *grphead;
214char exname[MAXPATHLEN];
215struct xucred def_anon = {
216 0,
217 (uid_t)-2,
218 1,

--- 10 unchanged lines hidden (view full) ---

229static int have_v6 = 1;
230#ifdef NI_WITHSCOPEID
231static const int ninumeric = NI_NUMERICHOST | NI_WITHSCOPEID;
232#else
233static const int ninumeric = NI_NUMERICHOST;
234#endif
235
236int mountdlockfd;
210struct exportlist *exphead;
211struct mountlist *mlhead;
212struct grouplist *grphead;
213char exname[MAXPATHLEN];
214struct xucred def_anon = {
215 0,
216 (uid_t)-2,
217 1,

--- 10 unchanged lines hidden (view full) ---

228static int have_v6 = 1;
229#ifdef NI_WITHSCOPEID
230static const int ninumeric = NI_NUMERICHOST | NI_WITHSCOPEID;
231#else
232static const int ninumeric = NI_NUMERICHOST;
233#endif
234
235int mountdlockfd;
237/* Bits for above */
236/* Bits for opt_flags above */
238#define OP_MAPROOT 0x01
239#define OP_MAPALL 0x02
240#define OP_KERB 0x04
241#define OP_MASK 0x08
242#define OP_NET 0x10
243#define OP_ALLDIRS 0x40
237#define OP_MAPROOT 0x01
238#define OP_MAPALL 0x02
239#define OP_KERB 0x04
240#define OP_MASK 0x08
241#define OP_NET 0x10
242#define OP_ALLDIRS 0x40
243#define OP_HAVEMASK 0x80 /* A mask was specified or inferred. */
244#define OP_MASKLEN 0x200
245
246#ifdef DEBUG
247int debug = 1;
248void SYSLOG __P((int, const char *, ...));
249#define syslog SYSLOG
250#else
251int debug = 0;

--- 859 unchanged lines hidden (view full) ---

1111 if (debug)
1112 warnx("adding a default entry");
1113
1114 /*
1115 * Don't allow a network export coincide with a list of
1116 * host(s) on the same line.
1117 */
1118 } else if ((opt_flags & OP_NET) && tgrp->gr_next) {
244#define OP_MASKLEN 0x200
245
246#ifdef DEBUG
247int debug = 1;
248void SYSLOG __P((int, const char *, ...));
249#define syslog SYSLOG
250#else
251int debug = 0;

--- 859 unchanged lines hidden (view full) ---

1111 if (debug)
1112 warnx("adding a default entry");
1113
1114 /*
1115 * Don't allow a network export coincide with a list of
1116 * host(s) on the same line.
1117 */
1118 } else if ((opt_flags & OP_NET) && tgrp->gr_next) {
1119 syslog(LOG_ERR, "network/host conflict");
1119 getexp_err(ep, tgrp);
1120 goto nextline;
1121
1122 /*
1123 * If an export list was specified on this line, make sure
1124 * that we have at least one valid entry, otherwise skip it.
1125 */
1126 } else {

--- 265 unchanged lines hidden (view full) ---

1392 return (dirp_search(dp->dp_right, dirp));
1393 else
1394 return (dp);
1395 }
1396 return (dp);
1397}
1398
1399/*
1120 getexp_err(ep, tgrp);
1121 goto nextline;
1122
1123 /*
1124 * If an export list was specified on this line, make sure
1125 * that we have at least one valid entry, otherwise skip it.
1126 */
1127 } else {

--- 265 unchanged lines hidden (view full) ---

1393 return (dirp_search(dp->dp_right, dirp));
1394 else
1395 return (dp);
1396 }
1397 return (dp);
1398}
1399
1400/*
1400 * Some helper functions for netmasks. They all assume masks in network
1401 * order (big endian).
1402 */
1403static int
1404bitcmp(void *dst, void *src, int bitlen)
1405{
1406 int i;
1407 u_int8_t *p1 = dst, *p2 = src;
1408 u_int8_t bitmask;
1409 int bytelen, bitsleft;
1410
1411 bytelen = bitlen / 8;
1412 bitsleft = bitlen % 8;
1413
1414 if (debug) {
1415 printf("comparing:\n");
1416 for (i = 0; i < (bitsleft ? bytelen + 1 : bytelen); i++)
1417 printf("%02x", p1[i]);
1418 printf("\n");
1419 for (i = 0; i < (bitsleft ? bytelen + 1 : bytelen); i++)
1420 printf("%02x", p2[i]);
1421 printf("\n");
1422 }
1423
1424 for (i = 0; i < bytelen; i++) {
1425 if (*p1 != *p2)
1426 return 1;
1427 p1++;
1428 p2++;
1429 }
1430
1431 for (i = 0; i < bitsleft; i++) {
1432 bitmask = 1 << (7 - i);
1433 if ((*p1 & bitmask) != (*p2 & bitmask))
1434 return 1;
1435 }
1436
1437 return 0;
1438}
1439
1440/*
1441 * Scan for a host match in a directory tree.
1442 */
1443int
1444chk_host(dp, saddr, defsetp, hostsetp)
1445 struct dirlist *dp;
1446 struct sockaddr *saddr;
1447 int *defsetp;
1448 int *hostsetp;

--- 7 unchanged lines hidden (view full) ---

1456 *defsetp = dp->dp_flag;
1457 hp = dp->dp_hosts;
1458 while (hp) {
1459 grp = hp->ht_grp;
1460 switch (grp->gr_type) {
1461 case GT_HOST:
1462 ai = grp->gr_ptr.gt_addrinfo;
1463 for (; ai; ai = ai->ai_next) {
1401 * Scan for a host match in a directory tree.
1402 */
1403int
1404chk_host(dp, saddr, defsetp, hostsetp)
1405 struct dirlist *dp;
1406 struct sockaddr *saddr;
1407 int *defsetp;
1408 int *hostsetp;

--- 7 unchanged lines hidden (view full) ---

1416 *defsetp = dp->dp_flag;
1417 hp = dp->dp_hosts;
1418 while (hp) {
1419 grp = hp->ht_grp;
1420 switch (grp->gr_type) {
1421 case GT_HOST:
1422 ai = grp->gr_ptr.gt_addrinfo;
1423 for (; ai; ai = ai->ai_next) {
1464 if (!sacmp(ai->ai_addr, saddr)) {
1424 if (!sacmp(ai->ai_addr, saddr, NULL)) {
1465 *hostsetp =
1466 (hp->ht_flag | DP_HOSTSET);
1467 return (1);
1468 }
1469 }
1425 *hostsetp =
1426 (hp->ht_flag | DP_HOSTSET);
1427 return (1);
1428 }
1429 }
1470 break;
1430 break;
1471 case GT_NET:
1431 case GT_NET:
1472 if (!netpartcmp(saddr,
1473 (struct sockaddr *) &grp->gr_ptr.gt_net.nt_net,
1474 grp->gr_ptr.gt_net.nt_mask)) {
1432 if (!sacmp(saddr, (struct sockaddr *)
1433 &grp->gr_ptr.gt_net.nt_net,
1434 (struct sockaddr *)
1435 &grp->gr_ptr.gt_net.nt_mask)) {
1475 *hostsetp = (hp->ht_flag | DP_HOSTSET);
1476 return (1);
1477 }
1436 *hostsetp = (hp->ht_flag | DP_HOSTSET);
1437 return (1);
1438 }
1478 break;
1479 };
1439 break;
1440 }
1480 hp = hp->ht_next;
1481 }
1482 }
1483 return (0);
1484}
1485
1486/*
1487 * Scan tree for a host that matches the address.

--- 89 unchanged lines hidden (view full) ---

1577 *exflagsp |= MNT_EXPORTANON;
1578 opt_flags |= OP_MAPALL;
1579 } else
1580 opt_flags |= OP_MAPROOT;
1581 } else if (!strcmp(cpopt, "kerb") || !strcmp(cpopt, "k")) {
1582 *exflagsp |= MNT_EXKERB;
1583 opt_flags |= OP_KERB;
1584 } else if (cpoptarg && (!strcmp(cpopt, "mask") ||
1441 hp = hp->ht_next;
1442 }
1443 }
1444 return (0);
1445}
1446
1447/*
1448 * Scan tree for a host that matches the address.

--- 89 unchanged lines hidden (view full) ---

1538 *exflagsp |= MNT_EXPORTANON;
1539 opt_flags |= OP_MAPALL;
1540 } else
1541 opt_flags |= OP_MAPROOT;
1542 } else if (!strcmp(cpopt, "kerb") || !strcmp(cpopt, "k")) {
1543 *exflagsp |= MNT_EXKERB;
1544 opt_flags |= OP_KERB;
1545 } else if (cpoptarg && (!strcmp(cpopt, "mask") ||
1585 !strcmp(cpopt, "m"))) {
1546 !strcmp(cpopt, "m"))) {
1586 if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 1)) {
1587 syslog(LOG_ERR, "bad mask: %s", cpoptarg);
1588 return (1);
1589 }
1590 usedarg++;
1591 opt_flags |= OP_MASK;
1592 } else if (cpoptarg && (!strcmp(cpopt, "network") ||
1593 !strcmp(cpopt, "n"))) {

--- 84 unchanged lines hidden (view full) ---

1678 * for this host in the grouplist.
1679 */
1680 for (checkgrp = tgrp; checkgrp != NULL;
1681 checkgrp = checkgrp->gr_next) {
1682 if (checkgrp->gr_type != GT_HOST)
1683 continue;
1684 for (tai = checkgrp->gr_ptr.gt_addrinfo; tai != NULL;
1685 tai = tai->ai_next) {
1547 if (get_net(cpoptarg, &grp->gr_ptr.gt_net, 1)) {
1548 syslog(LOG_ERR, "bad mask: %s", cpoptarg);
1549 return (1);
1550 }
1551 usedarg++;
1552 opt_flags |= OP_MASK;
1553 } else if (cpoptarg && (!strcmp(cpopt, "network") ||
1554 !strcmp(cpopt, "n"))) {

--- 84 unchanged lines hidden (view full) ---

1639 * for this host in the grouplist.
1640 */
1641 for (checkgrp = tgrp; checkgrp != NULL;
1642 checkgrp = checkgrp->gr_next) {
1643 if (checkgrp->gr_type != GT_HOST)
1644 continue;
1645 for (tai = checkgrp->gr_ptr.gt_addrinfo; tai != NULL;
1646 tai = tai->ai_next) {
1686 if (sacmp(tai->ai_addr, ai->ai_addr) != 0)
1647 if (sacmp(tai->ai_addr, ai->ai_addr, NULL) != 0)
1687 continue;
1688 if (debug)
1689 fprintf(stderr,
1690 "ignoring duplicate host %s\n",
1691 ai->ai_canonname);
1692 grp->gr_type = GT_IGNORE;
1693 return (0);
1694 }

--- 73 unchanged lines hidden (view full) ---

1768 struct exportlist *ep;
1769 struct grouplist *grp;
1770 int exflags;
1771 struct xucred *anoncrp;
1772 char *dirp;
1773 int dirplen;
1774 struct statfs *fsb;
1775{
1648 continue;
1649 if (debug)
1650 fprintf(stderr,
1651 "ignoring duplicate host %s\n",
1652 ai->ai_canonname);
1653 grp->gr_type = GT_IGNORE;
1654 return (0);
1655 }

--- 73 unchanged lines hidden (view full) ---

1729 struct exportlist *ep;
1730 struct grouplist *grp;
1731 int exflags;
1732 struct xucred *anoncrp;
1733 char *dirp;
1734 int dirplen;
1735 struct statfs *fsb;
1736{
1776 struct sockaddr_storage ss;
1777 struct addrinfo *ai;
1737 struct addrinfo *ai;
1738 struct export_args *eap;
1778 char *cp = NULL;
1779 int done;
1780 char savedc = '\0';
1781 union {
1782 struct ufs_args ua;
1783 struct iso_args ia;
1784 struct mfs_args ma;
1739 char *cp = NULL;
1740 int done;
1741 char savedc = '\0';
1742 union {
1743 struct ufs_args ua;
1744 struct iso_args ia;
1745 struct mfs_args ma;
1785#ifdef __NetBSD__
1786 struct msdosfs_args da;
1746 struct msdosfs_args da;
1787 struct adosfs_args aa;
1788#endif
1789 struct ntfs_args na;
1790 } args;
1791
1747 struct ntfs_args na;
1748 } args;
1749
1750 bzero(&args, sizeof args);
1751 /* XXX, we assume that all xx_args look like ufs_args. */
1792 args.ua.fspec = 0;
1752 args.ua.fspec = 0;
1793 args.ua.export.ex_flags = exflags;
1794 args.ua.export.ex_anon = *anoncrp;
1795 args.ua.export.ex_indexfile = ep->ex_indexfile;
1753 eap = &args.ua.export;
1754
1755 eap->ex_flags = exflags;
1756 eap->ex_anon = *anoncrp;
1757 eap->ex_indexfile = ep->ex_indexfile;
1796 if (grp->gr_type == GT_HOST)
1797 ai = grp->gr_ptr.gt_addrinfo;
1798 else
1799 ai = NULL;
1800 done = FALSE;
1801 while (!done) {
1802 switch (grp->gr_type) {
1803 case GT_HOST:
1804 if (ai->ai_addr->sa_family == AF_INET6 && have_v6 == 0)
1805 goto skip;
1758 if (grp->gr_type == GT_HOST)
1759 ai = grp->gr_ptr.gt_addrinfo;
1760 else
1761 ai = NULL;
1762 done = FALSE;
1763 while (!done) {
1764 switch (grp->gr_type) {
1765 case GT_HOST:
1766 if (ai->ai_addr->sa_family == AF_INET6 && have_v6 == 0)
1767 goto skip;
1806 args.ua.export.ex_addr = ai->ai_addr;
1807 args.ua.export.ex_addrlen = ai->ai_addrlen;
1808 args.ua.export.ex_masklen = 0;
1768 eap->ex_addr = ai->ai_addr;
1769 eap->ex_addrlen = ai->ai_addrlen;
1770 eap->ex_masklen = 0;
1809 break;
1810 case GT_NET:
1771 break;
1772 case GT_NET:
1811 args.ua.export.ex_addr = (struct sockaddr *)
1812 &grp->gr_ptr.gt_net.nt_net;
1813 if (args.ua.export.ex_addr->sa_family == AF_INET6 &&
1773 if (grp->gr_ptr.gt_net.nt_net.ss_family == AF_INET6 &&
1814 have_v6 == 0)
1815 goto skip;
1774 have_v6 == 0)
1775 goto skip;
1816 args.ua.export.ex_addrlen =
1817 args.ua.export.ex_addr->sa_len;
1818 memset(&ss, 0, sizeof ss);
1819 ss.ss_family = args.ua.export.ex_addr->sa_family;
1820 ss.ss_len = args.ua.export.ex_addr->sa_len;
1821 if (allones(&ss, grp->gr_ptr.gt_net.nt_mask) != 0) {
1822 syslog(LOG_ERR, "Bad network flag");
1823 if (cp)
1824 *cp = savedc;
1825 return (1);
1826 }
1827 args.ua.export.ex_mask = (struct sockaddr *)&ss;
1828 args.ua.export.ex_masklen = ss.ss_len;
1776 eap->ex_addr =
1777 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_net;
1778 eap->ex_addrlen = args.ua.export.ex_addr->sa_len;
1779 eap->ex_mask =
1780 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_mask;
1781 eap->ex_masklen = args.ua.export.ex_mask->sa_len;
1829 break;
1830 case GT_DEFAULT:
1782 break;
1783 case GT_DEFAULT:
1831 args.ua.export.ex_addr = NULL;
1832 args.ua.export.ex_addrlen = 0;
1833 args.ua.export.ex_mask = NULL;
1834 args.ua.export.ex_masklen = 0;
1784 eap->ex_addr = NULL;
1785 eap->ex_addrlen = 0;
1786 eap->ex_mask = NULL;
1787 eap->ex_masklen = 0;
1835 break;
1836 case GT_IGNORE:
1837 return(0);
1838 break;
1839 default:
1840 syslog(LOG_ERR, "bad grouptype");
1841 if (cp)
1842 *cp = savedc;

--- 48 unchanged lines hidden (view full) ---

1891 }
1892 if (cp)
1893 *cp = savedc;
1894 return (0);
1895}
1896
1897/*
1898 * Translate a net address.
1788 break;
1789 case GT_IGNORE:
1790 return(0);
1791 break;
1792 default:
1793 syslog(LOG_ERR, "bad grouptype");
1794 if (cp)
1795 *cp = savedc;

--- 48 unchanged lines hidden (view full) ---

1844 }
1845 if (cp)
1846 *cp = savedc;
1847 return (0);
1848}
1849
1850/*
1851 * Translate a net address.
1852 *
1853 * If `maskflg' is nonzero, then `cp' is a netmask, not a network address.
1899 */
1900int
1901get_net(cp, net, maskflg)
1902 char *cp;
1903 struct netmsk *net;
1904 int maskflg;
1905{
1906 struct netent *np;
1907 char *name, *p, *prefp;
1854 */
1855int
1856get_net(cp, net, maskflg)
1857 char *cp;
1858 struct netmsk *net;
1859 int maskflg;
1860{
1861 struct netent *np;
1862 char *name, *p, *prefp;
1908 struct sockaddr_in sin, *sinp;
1863 struct sockaddr_in sin;
1909 struct sockaddr *sa;
1910 struct addrinfo hints, *ai = NULL;
1911 char netname[NI_MAXHOST];
1912 long preflen;
1864 struct sockaddr *sa;
1865 struct addrinfo hints, *ai = NULL;
1866 char netname[NI_MAXHOST];
1867 long preflen;
1913 int ecode;
1914
1915 p = prefp = NULL;
1916 if ((opt_flags & OP_MASKLEN) && !maskflg) {
1917 p = strchr(cp, '/');
1918 *p = '\0';
1919 prefp = p + 1;
1920 }
1921
1922 if ((np = getnetbyname(cp)) != NULL) {
1868
1869 p = prefp = NULL;
1870 if ((opt_flags & OP_MASKLEN) && !maskflg) {
1871 p = strchr(cp, '/');
1872 *p = '\0';
1873 prefp = p + 1;
1874 }
1875
1876 if ((np = getnetbyname(cp)) != NULL) {
1877 bzero(&sin, sizeof sin);
1923 sin.sin_family = AF_INET;
1924 sin.sin_len = sizeof sin;
1925 sin.sin_addr = inet_makeaddr(np->n_net, 0);
1926 sa = (struct sockaddr *)&sin;
1878 sin.sin_family = AF_INET;
1879 sin.sin_len = sizeof sin;
1880 sin.sin_addr = inet_makeaddr(np->n_net, 0);
1881 sa = (struct sockaddr *)&sin;
1927 } else if (isdigit(*cp)) {
1882 } else if (isxdigit(*cp) || *cp == ':') {
1928 memset(&hints, 0, sizeof hints);
1883 memset(&hints, 0, sizeof hints);
1929 hints.ai_family = AF_UNSPEC;
1884 /* Ensure the mask and the network have the same family. */
1885 if (maskflg && (opt_flags & OP_NET))
1886 hints.ai_family = net->nt_net.ss_family;
1887 else if (!maskflg && (opt_flags & OP_HAVEMASK))
1888 hints.ai_family = net->nt_mask.ss_family;
1889 else
1890 hints.ai_family = AF_UNSPEC;
1930 hints.ai_flags = AI_NUMERICHOST;
1891 hints.ai_flags = AI_NUMERICHOST;
1931 if (getaddrinfo(cp, NULL, &hints, &ai) != 0) {
1892 if (getaddrinfo(cp, NULL, &hints, &ai) != 0)
1893 goto fail;
1894 if (ai->ai_family == AF_INET) {
1932 /*
1895 /*
1933 * If getaddrinfo() failed, try the inet4 network
1934 * notation with less than 3 dots.
1896 * The address in `cp' is really a network address, so
1897 * use inet_network() to re-interpret this correctly.
1898 * e.g. "127.1" means 127.1.0.0, not 127.0.0.1.
1935 */
1899 */
1900 bzero(&sin, sizeof sin);
1936 sin.sin_family = AF_INET;
1937 sin.sin_len = sizeof sin;
1901 sin.sin_family = AF_INET;
1902 sin.sin_len = sizeof sin;
1938 sin.sin_addr = inet_makeaddr(inet_network(cp),0);
1903 sin.sin_addr = inet_makeaddr(inet_network(cp), 0);
1939 if (debug)
1904 if (debug)
1940 fprintf(stderr, "get_net: v4 addr %x\n",
1941 sin.sin_addr.s_addr);
1905 fprintf(stderr, "get_net: v4 addr %s\n",
1906 inet_ntoa(sin.sin_addr));
1942 sa = (struct sockaddr *)&sin;
1943 } else
1944 sa = ai->ai_addr;
1907 sa = (struct sockaddr *)&sin;
1908 } else
1909 sa = ai->ai_addr;
1945 } else if (isxdigit(*cp) || *cp == ':') {
1946 memset(&hints, 0, sizeof hints);
1947 hints.ai_family = AF_UNSPEC;
1948 hints.ai_flags = AI_NUMERICHOST;
1949 if (getaddrinfo(cp, NULL, &hints, &ai) == 0)
1950 sa = ai->ai_addr;
1951 else
1952 goto fail;
1953 } else
1954 goto fail;
1955
1910 } else
1911 goto fail;
1912
1956 ecode = getnameinfo(sa, sa->sa_len, netname, sizeof netname,
1957 NULL, 0, ninumeric);
1958 if (ecode != 0)
1959 goto fail;
1913 if (maskflg) {
1914 /* The specified sockaddr is a mask. */
1915 if (checkmask(sa) != 0)
1916 goto fail;
1917 bcopy(sa, &net->nt_mask, sa->sa_len);
1918 opt_flags |= OP_HAVEMASK;
1919 } else {
1920 /* The specified sockaddr is a network address. */
1921 bcopy(sa, &net->nt_net, sa->sa_len);
1960
1922
1961 if (maskflg)
1962 net->nt_mask = countones(sa);
1963 else {
1923 /* Get a network name for the export list. */
1924 if (np) {
1925 name = np->n_name;
1926 } else if (getnameinfo(sa, sa->sa_len, netname, sizeof netname,
1927 NULL, 0, ninumeric) == 0) {
1928 name = netname;
1929 } else {
1930 goto fail;
1931 }
1932 if ((net->nt_name = strdup(name)) == NULL)
1933 out_of_mem();
1934
1935 /*
1936 * Extract a mask from either a "/<masklen>" suffix, or
1937 * from the class of an IPv4 address.
1938 */
1964 if (opt_flags & OP_MASKLEN) {
1965 preflen = strtol(prefp, NULL, 10);
1939 if (opt_flags & OP_MASKLEN) {
1940 preflen = strtol(prefp, NULL, 10);
1966 if (preflen == LONG_MIN && errno == ERANGE)
1941 if (preflen < 0L || preflen == LONG_MAX)
1967 goto fail;
1942 goto fail;
1968 net->nt_mask = (int)preflen;
1943 bcopy(sa, &net->nt_mask, sa->sa_len);
1944 if (makemask(&net->nt_mask, (int)preflen) != 0)
1945 goto fail;
1946 opt_flags |= OP_HAVEMASK;
1969 *p = '/';
1947 *p = '/';
1970 }
1948 } else if (sa->sa_family == AF_INET &&
1949 (opt_flags & OP_MASK) == 0) {
1950 in_addr_t addr;
1971
1951
1972 if (np)
1973 name = np->n_name;
1974 else {
1975 if (getnameinfo(sa, sa->sa_len, netname, sizeof netname,
1976 NULL, 0, ninumeric) != 0)
1977 strlcpy(netname, "?", sizeof(netname));
1978 name = netname;
1952 addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
1953 if (IN_CLASSA(addr))
1954 preflen = 8;
1955 else if (IN_CLASSB(addr))
1956 preflen = 16;
1957 else if (IN_CLASSC(addr))
1958 preflen = 24;
1959 else if (IN_CLASSD(addr))
1960 preflen = 28;
1961 else
1962 preflen = 32; /* XXX */
1963
1964 bcopy(sa, &net->nt_mask, sa->sa_len);
1965 makemask(&net->nt_mask, (int)preflen);
1966 opt_flags |= OP_HAVEMASK;
1979 }
1967 }
1980 net->nt_name = strdup(name);
1981 memcpy(&net->nt_net, sa, sa->sa_len);
1982 }
1983
1968 }
1969
1984 if (!maskflg && sa->sa_family == AF_INET &&
1985 !(opt_flags & (OP_MASK|OP_MASKLEN))) {
1986 sinp = (struct sockaddr_in *)sa;
1987 if (IN_CLASSA(sinp->sin_addr.s_addr))
1988 net->nt_mask = 8;
1989 else if (IN_CLASSB(sinp->sin_addr.s_addr))
1990 net->nt_mask = 16;
1991 else if (IN_CLASSC(sinp->sin_addr.s_addr))
1992 net->nt_mask = 24;
1993 else if (IN_CLASSD(sinp->sin_addr.s_addr))
1994 net->nt_mask = 28;
1995 else
1996 net->nt_mask = 32; /* XXX */
1997 }
1998
1999 if (ai)
2000 freeaddrinfo(ai);
2001 return 0;
2002
2003fail:
2004 if (ai)
2005 freeaddrinfo(ai);
2006 return 1;

--- 294 unchanged lines hidden (view full) ---

2301 return (1);
2302 if ((opt_flags & (OP_MAPROOT | OP_MAPALL)) == (OP_MAPROOT | OP_MAPALL) ||
2303 (opt_flags & (OP_MAPROOT | OP_KERB)) == (OP_MAPROOT | OP_KERB) ||
2304 (opt_flags & (OP_MAPALL | OP_KERB)) == (OP_MAPALL | OP_KERB)) {
2305 syslog(LOG_ERR, "-mapall, -maproot and -kerb mutually exclusive");
2306 return (1);
2307 }
2308 if ((opt_flags & OP_MASK) && (opt_flags & OP_NET) == 0) {
1970 if (ai)
1971 freeaddrinfo(ai);
1972 return 0;
1973
1974fail:
1975 if (ai)
1976 freeaddrinfo(ai);
1977 return 1;

--- 294 unchanged lines hidden (view full) ---

2272 return (1);
2273 if ((opt_flags & (OP_MAPROOT | OP_MAPALL)) == (OP_MAPROOT | OP_MAPALL) ||
2274 (opt_flags & (OP_MAPROOT | OP_KERB)) == (OP_MAPROOT | OP_KERB) ||
2275 (opt_flags & (OP_MAPALL | OP_KERB)) == (OP_MAPALL | OP_KERB)) {
2276 syslog(LOG_ERR, "-mapall, -maproot and -kerb mutually exclusive");
2277 return (1);
2278 }
2279 if ((opt_flags & OP_MASK) && (opt_flags & OP_NET) == 0) {
2309 syslog(LOG_ERR, "-mask requires -net");
2310 return (1);
2280 syslog(LOG_ERR, "-mask requires -network");
2281 return (1);
2311 }
2282 }
2283 if ((opt_flags & OP_NET) && (opt_flags & OP_HAVEMASK) == 0) {
2284 syslog(LOG_ERR, "-network requires mask specification");
2285 return (1);
2286 }
2287 if ((opt_flags & OP_MASK) && (opt_flags & OP_MASKLEN)) {
2288 syslog(LOG_ERR, "-mask and /masklen are mutually exclusive");
2289 return (1);
2290 }
2312 if ((opt_flags & OP_ALLDIRS) && dp->dp_left) {
2313 syslog(LOG_ERR, "-alldirs has multiple directories");
2314 return (1);
2315 }
2316 return (0);
2317}
2318
2319/*

--- 17 unchanged lines hidden (view full) ---

2337 }
2338 cp++;
2339 }
2340 if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode))
2341 ret = 0;
2342 return (ret);
2343}
2344
2291 if ((opt_flags & OP_ALLDIRS) && dp->dp_left) {
2292 syslog(LOG_ERR, "-alldirs has multiple directories");
2293 return (1);
2294 }
2295 return (0);
2296}
2297
2298/*

--- 17 unchanged lines hidden (view full) ---

2316 }
2317 cp++;
2318 }
2319 if (lstat(dirp, &sb) < 0 || !S_ISDIR(sb.st_mode))
2320 ret = 0;
2321 return (ret);
2322}
2323
2345static int
2346netpartcmp(struct sockaddr *s1, struct sockaddr *s2, int bitlen)
2324/*
2325 * Make a netmask according to the specified prefix length. The ss_family
2326 * and other non-address fields must be initialised before calling this.
2327 */
2328int
2329makemask(struct sockaddr_storage *ssp, int bitlen)
2347{
2330{
2348 void *src, *dst;
2331 u_char *p;
2332 int bits, i, len;
2349
2333
2350 if (s1->sa_family != s2->sa_family)
2351 return 1;
2334 if ((p = sa_rawaddr((struct sockaddr *)ssp, &len)) == NULL)
2335 return (-1);
2336 if (bitlen > len * NBBY)
2337 return (-1);
2352
2338
2353 switch (s1->sa_family) {
2354 case AF_INET:
2355 src = &((struct sockaddr_in *)s1)->sin_addr;
2356 dst = &((struct sockaddr_in *)s2)->sin_addr;
2357 if (bitlen > sizeof(((struct sockaddr_in *)s1)->sin_addr) * 8)
2358 return 1;
2359 break;
2360 case AF_INET6:
2361 src = &((struct sockaddr_in6 *)s1)->sin6_addr;
2362 dst = &((struct sockaddr_in6 *)s2)->sin6_addr;
2363 if (((struct sockaddr_in6 *)s1)->sin6_scope_id !=
2364 ((struct sockaddr_in6 *)s2)->sin6_scope_id)
2365 return 1;
2366 if (bitlen > sizeof(((struct sockaddr_in6 *)s1)->sin6_addr) * 8)
2367 return 1;
2368 break;
2369 default:
2370 return 1;
2339 for (i = 0; i < len; i++) {
2340 bits = (bitlen > NBBY) ? NBBY : bitlen;
2341 *p++ = (1 << bits) - 1;
2342 bitlen -= bits;
2371 }
2343 }
2372
2373 return bitcmp(src, dst, bitlen);
2344 return 0;
2374}
2375
2345}
2346
2376static int
2377allones(struct sockaddr_storage *ssp, int bitlen)
2347/*
2348 * Check that the sockaddr is a valid netmask. Returns 0 if the mask
2349 * is acceptable (i.e. of the form 1...10....0).
2350 */
2351int
2352checkmask(struct sockaddr *sa)
2378{
2353{
2379 u_int8_t *p;
2380 int bytelen, bitsleft, i;
2381 int zerolen;
2354 u_char *mask;
2355 int i, len;
2382
2356
2383 switch (ssp->ss_family) {
2384 case AF_INET:
2385 p = (u_int8_t *)&((struct sockaddr_in *)ssp)->sin_addr;
2386 zerolen = sizeof (((struct sockaddr_in *)ssp)->sin_addr);
2387 break;
2388 case AF_INET6:
2389 p = (u_int8_t *)&((struct sockaddr_in6 *)ssp)->sin6_addr;
2390 zerolen = sizeof (((struct sockaddr_in6 *)ssp)->sin6_addr);
2391 break;
2392 default:
2393 return -1;
2394 }
2357 if ((mask = sa_rawaddr(sa, &len)) == NULL)
2358 return (-1);
2395
2359
2396 memset(p, 0, zerolen);
2397
2398 bytelen = bitlen / 8;
2399 bitsleft = bitlen % 8;
2400
2401 if (bytelen > zerolen)
2402 return -1;
2403
2404 for (i = 0; i < bytelen; i++)
2405 *p++ = 0xff;
2406
2407 for (i = 0; i < bitsleft; i++)
2408 *p |= 1 << (7 - i);
2409
2410 return 0;
2360 for (i = 0; i < len; i++)
2361 if (mask[i] != 0xff)
2362 break;
2363 if (i < len) {
2364 if (~mask[i] & (u_char)(~mask[i] + 1))
2365 return (-1);
2366 i++;
2367 }
2368 for (; i < len; i++)
2369 if (mask[i] != 0)
2370 return (-1);
2371 return (0);
2411}
2412
2372}
2373
2413static int
2414countones(struct sockaddr *sa)
2374/*
2375 * Compare two sockaddrs according to a specified mask. Return zero if
2376 * `sa1' matches `sa2' when filtered by the netmask in `samask'.
2377 * If samask is NULL, perform a full comparision.
2378 */
2379int
2380sacmp(struct sockaddr *sa1, struct sockaddr *sa2, struct sockaddr *samask)
2415{
2381{
2416 void *mask;
2417 int i, bits = 0, bytelen;
2418 u_int8_t *p;
2382 unsigned char *p1, *p2, *mask;
2383 int len, i;
2419
2384
2420 switch (sa->sa_family) {
2421 case AF_INET:
2422 mask = (u_int8_t *)&((struct sockaddr_in *)sa)->sin_addr;
2423 bytelen = 4;
2424 break;
2385 if (sa1->sa_family != sa2->sa_family ||
2386 (p1 = sa_rawaddr(sa1, &len)) == NULL ||
2387 (p2 = sa_rawaddr(sa2, NULL)) == NULL)
2388 return (1);
2389
2390 switch (sa1->sa_family) {
2425 case AF_INET6:
2391 case AF_INET6:
2426 mask = (u_int8_t *)&((struct sockaddr_in6 *)sa)->sin6_addr;
2427 bytelen = 16;
2392 if (((struct sockaddr_in6 *)sa1)->sin6_scope_id !=
2393 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
2394 return (1);
2428 break;
2395 break;
2429 default:
2430 return 0;
2431 }
2432
2396 }
2397
2433 p = mask;
2398 /* Simple binary comparison if no mask specified. */
2399 if (samask == NULL)
2400 return (memcmp(p1, p2, len));
2434
2401
2435 for (i = 0; i < bytelen; i++, p++) {
2436 if (*p != 0xff) {
2437 for (bits = 0; bits < 8; bits++) {
2438 if (!(*p & (1 << (7 - bits))))
2439 break;
2440 }
2441 break;
2442 }
2443 }
2402 /* Set up the mask, and do a mask-based comparison. */
2403 if (sa1->sa_family != samask->sa_family ||
2404 (mask = sa_rawaddr(samask, NULL)) == NULL)
2405 return (1);
2444
2406
2445 return (i * 8 + bits);
2407 for (i = 0; i < len; i++)
2408 if ((p1[i] & mask[i]) != (p2[i] & mask[i]))
2409 return (1);
2410 return (0);
2446}
2447
2411}
2412
2448static int
2449sacmp(struct sockaddr *sa1, struct sockaddr *sa2)
2450{
2451 void *p1, *p2;
2413/*
2414 * Return a pointer to the part of the sockaddr that contains the
2415 * raw address, and set *nbytes to its length in bytes. Returns
2416 * NULL if the address family is unknown.
2417 */
2418void *
2419sa_rawaddr(struct sockaddr *sa, int *nbytes) {
2420 void *p;
2452 int len;
2453
2421 int len;
2422
2454 if (sa1->sa_family != sa2->sa_family)
2455 return 1;
2456
2457 switch (sa1->sa_family) {
2423 switch (sa->sa_family) {
2458 case AF_INET:
2424 case AF_INET:
2459 p1 = &((struct sockaddr_in *)sa1)->sin_addr;
2460 p2 = &((struct sockaddr_in *)sa2)->sin_addr;
2461 len = 4;
2425 len = sizeof(((struct sockaddr_in *)sa)->sin_addr);
2426 p = &((struct sockaddr_in *)sa)->sin_addr;
2462 break;
2463 case AF_INET6:
2427 break;
2428 case AF_INET6:
2464 p1 = &((struct sockaddr_in6 *)sa1)->sin6_addr;
2465 p2 = &((struct sockaddr_in6 *)sa2)->sin6_addr;
2466 len = 16;
2467 if (((struct sockaddr_in6 *)sa1)->sin6_scope_id !=
2468 ((struct sockaddr_in6 *)sa2)->sin6_scope_id)
2469 return 1;
2429 len = sizeof(((struct sockaddr_in6 *)sa)->sin6_addr);
2430 p = &((struct sockaddr_in6 *)sa)->sin6_addr;
2470 break;
2471 default:
2431 break;
2432 default:
2472 return 1;
2433 p = NULL;
2434 len = 0;
2473 }
2474
2435 }
2436
2475 return memcmp(p1, p2, len);
2437 if (nbytes != NULL)
2438 *nbytes = len;
2439 return (p);
2476}
2477
2478void
2479huphandler(int sig)
2480{
2481 got_sighup = 1;
2482}
2483
2484void terminate(sig)
2485int sig;
2486{
2487 close(mountdlockfd);
2488 unlink(MOUNTDLOCK);
2489 rpcb_unset(RPCPROG_MNT, RPCMNT_VER1, NULL);
2490 rpcb_unset(RPCPROG_MNT, RPCMNT_VER3, NULL);
2491 exit (0);
2492}
2440}
2441
2442void
2443huphandler(int sig)
2444{
2445 got_sighup = 1;
2446}
2447
2448void terminate(sig)
2449int sig;
2450{
2451 close(mountdlockfd);
2452 unlink(MOUNTDLOCK);
2453 rpcb_unset(RPCPROG_MNT, RPCMNT_VER1, NULL);
2454 rpcb_unset(RPCPROG_MNT, RPCMNT_VER3, NULL);
2455 exit (0);
2456}