mountd.c (324955) | mountd.c (329392) |
---|---|
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 --- 29 unchanged lines hidden (view full) --- 38 39#if 0 40#ifndef lint 41static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95"; 42#endif /*not lint*/ 43#endif 44 45#include <sys/cdefs.h> | 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 --- 29 unchanged lines hidden (view full) --- 38 39#if 0 40#ifndef lint 41static char sccsid[] = "@(#)mountd.c 8.15 (Berkeley) 5/1/95"; 42#endif /*not lint*/ 43#endif 44 45#include <sys/cdefs.h> |
46__FBSDID("$FreeBSD: stable/11/usr.sbin/mountd/mountd.c 324955 2017-10-24 14:33:38Z manu $"); | 46__FBSDID("$FreeBSD: stable/11/usr.sbin/mountd/mountd.c 329392 2018-02-16 18:49:50Z brd $"); |
47 48#include <sys/param.h> 49#include <sys/fcntl.h> 50#include <sys/linker.h> 51#include <sys/module.h> 52#include <sys/mount.h> 53#include <sys/queue.h> 54#include <sys/stat.h> --- 139 unchanged lines hidden (view full) --- 194static void free_grp(struct grouplist *); 195static void free_host(struct hostlist *); 196static void get_exportlist(void); 197static int get_host(char *, struct grouplist *, struct grouplist *); 198static struct hostlist *get_ht(void); 199static int get_line(void); 200static void get_mountlist(void); 201static int get_net(char *, struct netmsk *, int); | 47 48#include <sys/param.h> 49#include <sys/fcntl.h> 50#include <sys/linker.h> 51#include <sys/module.h> 52#include <sys/mount.h> 53#include <sys/queue.h> 54#include <sys/stat.h> --- 139 unchanged lines hidden (view full) --- 194static void free_grp(struct grouplist *); 195static void free_host(struct hostlist *); 196static void get_exportlist(void); 197static int get_host(char *, struct grouplist *, struct grouplist *); 198static struct hostlist *get_ht(void); 199static int get_line(void); 200static void get_mountlist(void); 201static int get_net(char *, struct netmsk *, int); |
202static void getexp_err(struct exportlist *, struct grouplist *); | 202static void getexp_err(struct exportlist *, struct grouplist *, const char *); |
203static struct grouplist *get_grp(void); 204static void hang_dirp(struct dirlist *, struct grouplist *, 205 struct exportlist *, int); 206static void huphandler(int sig); 207static int makemask(struct sockaddr_storage *ssp, int bitlen); 208static void mntsrv(struct svc_req *, SVCXPRT *); 209static void nextfield(char **, char **); 210static void out_of_mem(void); --- 1232 unchanged lines hidden (view full) --- 1443 1444 /* 1445 * Create new exports list entry 1446 */ 1447 len = endcp-cp; 1448 tgrp = grp = get_grp(); 1449 while (len > 0) { 1450 if (len > MNTNAMLEN) { | 203static struct grouplist *get_grp(void); 204static void hang_dirp(struct dirlist *, struct grouplist *, 205 struct exportlist *, int); 206static void huphandler(int sig); 207static int makemask(struct sockaddr_storage *ssp, int bitlen); 208static void mntsrv(struct svc_req *, SVCXPRT *); 209static void nextfield(char **, char **); 210static void out_of_mem(void); --- 1232 unchanged lines hidden (view full) --- 1443 1444 /* 1445 * Create new exports list entry 1446 */ 1447 len = endcp-cp; 1448 tgrp = grp = get_grp(); 1449 while (len > 0) { 1450 if (len > MNTNAMLEN) { |
1451 getexp_err(ep, tgrp); | 1451 getexp_err(ep, tgrp, "mountpoint too long"); |
1452 goto nextline; 1453 } 1454 if (*cp == '-') { 1455 if (ep == (struct exportlist *)NULL) { | 1452 goto nextline; 1453 } 1454 if (*cp == '-') { 1455 if (ep == (struct exportlist *)NULL) { |
1456 getexp_err(ep, tgrp); | 1456 getexp_err(ep, tgrp, 1457 "flag before export path definition"); |
1457 goto nextline; 1458 } 1459 if (debug) 1460 warnx("doing opt %s", cp); 1461 got_nondir = 1; 1462 if (do_opt(&cp, &endcp, ep, grp, &has_host, 1463 &exflags, &anon)) { | 1458 goto nextline; 1459 } 1460 if (debug) 1461 warnx("doing opt %s", cp); 1462 got_nondir = 1; 1463 if (do_opt(&cp, &endcp, ep, grp, &has_host, 1464 &exflags, &anon)) { |
1464 getexp_err(ep, tgrp); | 1465 getexp_err(ep, tgrp, NULL); |
1465 goto nextline; 1466 } 1467 } else if (*cp == '/') { 1468 savedc = *endcp; 1469 *endcp = '\0'; 1470 if (v4root_phase > 1) { 1471 if (dirp != NULL) { | 1466 goto nextline; 1467 } 1468 } else if (*cp == '/') { 1469 savedc = *endcp; 1470 *endcp = '\0'; 1471 if (v4root_phase > 1) { 1472 if (dirp != NULL) { |
1472 syslog(LOG_ERR, "Multiple V4 dirs"); 1473 getexp_err(ep, tgrp); | 1473 getexp_err(ep, tgrp, "Multiple V4 dirs"); |
1474 goto nextline; 1475 } 1476 } 1477 if (check_dirpath(cp) && 1478 statfs(cp, &fsb) >= 0) { 1479 if ((fsb.f_flags & MNT_AUTOMOUNTED) != 0) 1480 syslog(LOG_ERR, "Warning: exporting of " 1481 "automounted fs %s not supported", cp); 1482 if (got_nondir) { | 1474 goto nextline; 1475 } 1476 } 1477 if (check_dirpath(cp) && 1478 statfs(cp, &fsb) >= 0) { 1479 if ((fsb.f_flags & MNT_AUTOMOUNTED) != 0) 1480 syslog(LOG_ERR, "Warning: exporting of " 1481 "automounted fs %s not supported", cp); 1482 if (got_nondir) { |
1483 syslog(LOG_ERR, "dirs must be first"); 1484 getexp_err(ep, tgrp); | 1483 getexp_err(ep, tgrp, "dirs must be first"); |
1485 goto nextline; 1486 } 1487 if (v4root_phase == 1) { 1488 if (dirp != NULL) { | 1484 goto nextline; 1485 } 1486 if (v4root_phase == 1) { 1487 if (dirp != NULL) { |
1489 syslog(LOG_ERR, "Multiple V4 dirs"); 1490 getexp_err(ep, tgrp); | 1488 getexp_err(ep, tgrp, "Multiple V4 dirs"); |
1491 goto nextline; 1492 } 1493 if (strlen(v4root_dirpath) == 0) { 1494 strlcpy(v4root_dirpath, cp, 1495 sizeof (v4root_dirpath)); 1496 } else if (strcmp(v4root_dirpath, cp) 1497 != 0) { 1498 syslog(LOG_ERR, 1499 "different V4 dirpath %s", cp); | 1489 goto nextline; 1490 } 1491 if (strlen(v4root_dirpath) == 0) { 1492 strlcpy(v4root_dirpath, cp, 1493 sizeof (v4root_dirpath)); 1494 } else if (strcmp(v4root_dirpath, cp) 1495 != 0) { 1496 syslog(LOG_ERR, 1497 "different V4 dirpath %s", cp); |
1500 getexp_err(ep, tgrp); | 1498 getexp_err(ep, tgrp, NULL); |
1501 goto nextline; 1502 } 1503 dirp = cp; 1504 v4root_phase = 2; 1505 got_nondir = 1; 1506 ep = get_exp(); 1507 } else { 1508 if (ep) { 1509 if (ep->ex_fs.val[0] != 1510 fsb.f_fsid.val[0] || 1511 ep->ex_fs.val[1] != 1512 fsb.f_fsid.val[1]) { | 1499 goto nextline; 1500 } 1501 dirp = cp; 1502 v4root_phase = 2; 1503 got_nondir = 1; 1504 ep = get_exp(); 1505 } else { 1506 if (ep) { 1507 if (ep->ex_fs.val[0] != 1508 fsb.f_fsid.val[0] || 1509 ep->ex_fs.val[1] != 1510 fsb.f_fsid.val[1]) { |
1513 getexp_err(ep, tgrp); | 1511 getexp_err(ep, tgrp, 1512 "fsid mismatch"); |
1514 goto nextline; 1515 } 1516 } else { 1517 /* 1518 * See if this directory is already 1519 * in the list. 1520 */ 1521 ep = ex_search(&fsb.f_fsid); --- 16 unchanged lines hidden (view full) --- 1538 1539 /* 1540 * Add dirpath to export mount point. 1541 */ 1542 dirp = add_expdir(&dirhead, cp, len); 1543 dirplen = len; 1544 } 1545 } else { | 1513 goto nextline; 1514 } 1515 } else { 1516 /* 1517 * See if this directory is already 1518 * in the list. 1519 */ 1520 ep = ex_search(&fsb.f_fsid); --- 16 unchanged lines hidden (view full) --- 1537 1538 /* 1539 * Add dirpath to export mount point. 1540 */ 1541 dirp = add_expdir(&dirhead, cp, len); 1542 dirplen = len; 1543 } 1544 } else { |
1546 getexp_err(ep, tgrp); | 1545 getexp_err(ep, tgrp, 1546 "symbolic link in export path or statfs failed"); |
1547 goto nextline; 1548 } 1549 *endcp = savedc; 1550 } else { 1551 savedc = *endcp; 1552 *endcp = '\0'; 1553 got_nondir = 1; 1554 if (ep == (struct exportlist *)NULL) { | 1547 goto nextline; 1548 } 1549 *endcp = savedc; 1550 } else { 1551 savedc = *endcp; 1552 *endcp = '\0'; 1553 got_nondir = 1; 1554 if (ep == (struct exportlist *)NULL) { |
1555 getexp_err(ep, tgrp); | 1555 getexp_err(ep, tgrp, 1556 "host(s) before export path definition"); |
1556 goto nextline; 1557 } 1558 1559 /* 1560 * Get the host or netgroup. 1561 */ 1562 setnetgrent(cp); 1563 netgrp = getnetgrent(&hst, &usr, &dom); --- 21 unchanged lines hidden (view full) --- 1585 endnetgrent(); 1586 *endcp = savedc; 1587 } 1588 cp = endcp; 1589 nextfield(&cp, &endcp); 1590 len = endcp - cp; 1591 } 1592 if (check_options(dirhead)) { | 1557 goto nextline; 1558 } 1559 1560 /* 1561 * Get the host or netgroup. 1562 */ 1563 setnetgrent(cp); 1564 netgrp = getnetgrent(&hst, &usr, &dom); --- 21 unchanged lines hidden (view full) --- 1586 endnetgrent(); 1587 *endcp = savedc; 1588 } 1589 cp = endcp; 1590 nextfield(&cp, &endcp); 1591 len = endcp - cp; 1592 } 1593 if (check_options(dirhead)) { |
1593 getexp_err(ep, tgrp); | 1594 getexp_err(ep, tgrp, NULL); |
1594 goto nextline; 1595 } 1596 if (!has_host) { 1597 grp->gr_type = GT_DEFAULT; 1598 if (debug) 1599 warnx("adding a default entry"); 1600 1601 /* 1602 * Don't allow a network export coincide with a list of 1603 * host(s) on the same line. 1604 */ 1605 } else if ((opt_flags & OP_NET) && tgrp->gr_next) { | 1595 goto nextline; 1596 } 1597 if (!has_host) { 1598 grp->gr_type = GT_DEFAULT; 1599 if (debug) 1600 warnx("adding a default entry"); 1601 1602 /* 1603 * Don't allow a network export coincide with a list of 1604 * host(s) on the same line. 1605 */ 1606 } else if ((opt_flags & OP_NET) && tgrp->gr_next) { |
1606 syslog(LOG_ERR, "network/host conflict"); 1607 getexp_err(ep, tgrp); | 1607 getexp_err(ep, tgrp, "network/host conflict"); |
1608 goto nextline; 1609 1610 /* 1611 * If an export list was specified on this line, make sure 1612 * that we have at least one valid entry, otherwise skip it. 1613 */ 1614 } else { 1615 grp = tgrp; 1616 while (grp && grp->gr_type == GT_IGNORE) 1617 grp = grp->gr_next; 1618 if (! grp) { | 1608 goto nextline; 1609 1610 /* 1611 * If an export list was specified on this line, make sure 1612 * that we have at least one valid entry, otherwise skip it. 1613 */ 1614 } else { 1615 grp = tgrp; 1616 while (grp && grp->gr_type == GT_IGNORE) 1617 grp = grp->gr_next; 1618 if (! grp) { |
1619 getexp_err(ep, tgrp); | 1619 getexp_err(ep, tgrp, "no valid entries"); |
1620 goto nextline; 1621 } 1622 } 1623 1624 if (v4root_phase == 1) { | 1620 goto nextline; 1621 } 1622 } 1623 1624 if (v4root_phase == 1) { |
1625 syslog(LOG_ERR, "V4:root, no dirp, ignored"); 1626 getexp_err(ep, tgrp); | 1625 getexp_err(ep, tgrp, "V4:root, no dirp, ignored"); |
1627 goto nextline; 1628 } 1629 1630 /* 1631 * Loop through hosts, pushing the exports into the kernel. 1632 * After loop, tgrp points to the start of the list and 1633 * grp points to the last entry in the list. 1634 */ 1635 grp = tgrp; 1636 do { 1637 if (do_mount(ep, grp, exflags, &anon, dirp, dirplen, 1638 &fsb)) { | 1626 goto nextline; 1627 } 1628 1629 /* 1630 * Loop through hosts, pushing the exports into the kernel. 1631 * After loop, tgrp points to the start of the list and 1632 * grp points to the last entry in the list. 1633 */ 1634 grp = tgrp; 1635 do { 1636 if (do_mount(ep, grp, exflags, &anon, dirp, dirplen, 1637 &fsb)) { |
1639 getexp_err(ep, tgrp); | 1638 getexp_err(ep, tgrp, NULL); |
1640 goto nextline; 1641 } 1642 } while (grp->gr_next && (grp = grp->gr_next)); 1643 1644 /* 1645 * For V4: don't enter in mount lists. 1646 */ 1647 if (v4root_phase > 0 && v4root_phase <= 2) { --- 225 unchanged lines hidden (view full) --- 1873 out_of_mem(); 1874 return (gp); 1875} 1876 1877/* 1878 * Clean up upon an error in get_exportlist(). 1879 */ 1880static void | 1639 goto nextline; 1640 } 1641 } while (grp->gr_next && (grp = grp->gr_next)); 1642 1643 /* 1644 * For V4: don't enter in mount lists. 1645 */ 1646 if (v4root_phase > 0 && v4root_phase <= 2) { --- 225 unchanged lines hidden (view full) --- 1872 out_of_mem(); 1873 return (gp); 1874} 1875 1876/* 1877 * Clean up upon an error in get_exportlist(). 1878 */ 1879static void |
1881getexp_err(struct exportlist *ep, struct grouplist *grp) | 1880getexp_err(struct exportlist *ep, struct grouplist *grp, const char *reason) |
1882{ 1883 struct grouplist *tgrp; 1884 | 1881{ 1882 struct grouplist *tgrp; 1883 |
1885 if (!(opt_flags & OP_QUIET)) 1886 syslog(LOG_ERR, "bad exports list line %s", line); | 1884 if (!(opt_flags & OP_QUIET)) { 1885 if (reason != NULL) 1886 syslog(LOG_ERR, "bad exports list line '%s': %s", line, 1887 reason); 1888 else 1889 syslog(LOG_ERR, "bad exports list line '%s'", line); 1890 } |
1887 if (ep && (ep->ex_flag & EX_LINKED) == 0) 1888 free_exp(ep); 1889 while (grp) { 1890 tgrp = grp; 1891 grp = grp->gr_next; 1892 free_grp(tgrp); 1893 } 1894} --- 1362 unchanged lines hidden --- | 1891 if (ep && (ep->ex_flag & EX_LINKED) == 0) 1892 free_exp(ep); 1893 while (grp) { 1894 tgrp = grp; 1895 grp = grp->gr_next; 1896 free_grp(tgrp); 1897 } 1898} --- 1362 unchanged lines hidden --- |