Deleted Added
sdiff udiff text old ( 150214 ) new ( 158857 )
full compact
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: head/usr.sbin/mountd/mountd.c 150214 2005-09-16 11:24:28Z pjd $");
47
48#include <sys/param.h>
49#include <sys/mount.h>
50#include <sys/fcntl.h>
51#include <sys/stat.h>
52#include <sys/syslog.h>
53#include <sys/sysctl.h>
54#include <sys/linker.h>
55#include <sys/module.h>
56
57#include <rpc/rpc.h>
58#include <rpc/rpc_com.h>
59#include <rpc/pmap_clnt.h>
60#include <rpc/pmap_prot.h>
61#include <rpcsvc/mount.h>
62#include <nfs/rpcv2.h>
63#include <nfs/nfsproto.h>
64#include <nfsserver/nfs.h>
65#include <ufs/ufs/ufsmount.h>
66#include <fs/msdosfs/msdosfsmount.h>
67#include <fs/ntfs/ntfsmount.h>
68#include <isofs/cd9660/cd9660_mount.h> /* XXX need isofs in include */
69
70#include <arpa/inet.h>
71
72#include <ctype.h>
73#include <err.h>
74#include <errno.h>
75#include <grp.h>
76#include <libutil.h>
77#include <limits.h>
78#include <netdb.h>
79#include <pwd.h>
80#include <signal.h>
81#include <stdio.h>
82#include <stdlib.h>
83#include <string.h>
84#include <unistd.h>
85#include "pathnames.h"
86
87#ifdef DEBUG
88#include <stdarg.h>
89#endif
90
91/*
92 * Structures for keeping the mount list and export list
93 */

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

958 * Get the export list
959 */
960void
961get_exportlist()
962{
963 struct exportlist *ep, *ep2;
964 struct grouplist *grp, *tgrp;
965 struct exportlist **epp;
966 struct dirlist *dirhead;
967 struct statfs fsb, *fsp;
968 struct xucred anon;
969 char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
970 int len, has_host, exflags, got_nondir, dirplen, num, i, netgrp;
971
972 dirp = NULL;
973 dirplen = 0;
974
975 /*
976 * First, get rid of the old list
977 */
978 ep = exphead;
979 while (ep) {
980 ep2 = ep;
981 ep = ep->ex_next;

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

993
994 /*
995 * And delete exports that are in the kernel for all local
996 * filesystems.
997 * XXX: Should know how to handle all local exportable filesystems
998 * instead of just "ufs".
999 */
1000 num = getmntinfo(&fsp, MNT_NOWAIT);
1001 for (i = 0; i < num; i++) {
1002 union {
1003 struct ufs_args ua;
1004 struct iso_args ia;
1005 struct msdosfs_args da;
1006 struct ntfs_args na;
1007 } targs;
1008
1009 if (!strcmp(fsp->f_fstypename, "ufs") ||
1010 !strcmp(fsp->f_fstypename, "msdosfs") ||
1011 !strcmp(fsp->f_fstypename, "ntfs") ||
1012 !strcmp(fsp->f_fstypename, "cd9660")) {
1013 bzero(&targs, sizeof targs);
1014 targs.ua.fspec = NULL;
1015 targs.ua.export.ex_flags = MNT_DELEXPORT;
1016 if (mount(fsp->f_fstypename, fsp->f_mntonname,
1017 fsp->f_flags | MNT_UPDATE, (caddr_t)&targs) < 0 &&
1018 errno != ENOENT)
1019 syslog(LOG_ERR,
1020 "can't delete exports for %s: %m",
1021 fsp->f_mntonname);
1022 }
1023 fsp++;
1024 }
1025
1026 /*
1027 * Read in the exports file and build the list, calling
1028 * mount() as we go along to push the export rules into the kernel.
1029 */
1030 if ((exp_file = fopen(exname, "r")) == NULL) {
1031 syslog(LOG_ERR, "can't open %s", exname);
1032 exit(2);
1033 }
1034 dirhead = (struct dirlist *)NULL;
1035 while (get_line()) {
1036 if (debug)

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

1773out_of_mem()
1774{
1775
1776 syslog(LOG_ERR, "out of memory");
1777 exit(2);
1778}
1779
1780/*
1781 * Do the mount syscall with the update flag to push the export info into
1782 * the kernel.
1783 */
1784int
1785do_mount(ep, grp, exflags, anoncrp, dirp, dirplen, fsb)
1786 struct exportlist *ep;
1787 struct grouplist *grp;
1788 int exflags;
1789 struct xucred *anoncrp;
1790 char *dirp;
1791 int dirplen;
1792 struct statfs *fsb;
1793{
1794 struct statfs fsb1;
1795 struct addrinfo *ai;
1796 struct export_args *eap;
1797 char *cp = NULL;
1798 int done;
1799 char savedc = '\0';
1800 union {
1801 struct ufs_args ua;
1802 struct iso_args ia;
1803 struct msdosfs_args da;
1804 struct ntfs_args na;
1805 } args;
1806
1807 bzero(&args, sizeof args);
1808 /* XXX, we assume that all xx_args look like ufs_args. */
1809 args.ua.fspec = 0;
1810 eap = &args.ua.export;
1811
1812 eap->ex_flags = exflags;
1813 eap->ex_anon = *anoncrp;
1814 eap->ex_indexfile = ep->ex_indexfile;
1815 if (grp->gr_type == GT_HOST)
1816 ai = grp->gr_ptr.gt_addrinfo;
1817 else
1818 ai = NULL;
1819 done = FALSE;
1820 while (!done) {
1821 switch (grp->gr_type) {
1822 case GT_HOST:
1823 if (ai->ai_addr->sa_family == AF_INET6 && have_v6 == 0)
1824 goto skip;
1825 eap->ex_addr = ai->ai_addr;
1826 eap->ex_addrlen = ai->ai_addrlen;
1827 eap->ex_masklen = 0;
1828 break;
1829 case GT_NET:
1830 if (grp->gr_ptr.gt_net.nt_net.ss_family == AF_INET6 &&
1831 have_v6 == 0)
1832 goto skip;
1833 eap->ex_addr =
1834 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_net;
1835 eap->ex_addrlen = args.ua.export.ex_addr->sa_len;
1836 eap->ex_mask =
1837 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_mask;
1838 eap->ex_masklen = args.ua.export.ex_mask->sa_len;
1839 break;
1840 case GT_DEFAULT:
1841 eap->ex_addr = NULL;
1842 eap->ex_addrlen = 0;
1843 eap->ex_mask = NULL;
1844 eap->ex_masklen = 0;
1845 break;
1846 case GT_IGNORE:
1847 return(0);
1848 break;
1849 default:
1850 syslog(LOG_ERR, "bad grouptype");
1851 if (cp)
1852 *cp = savedc;
1853 return (1);
1854 };
1855
1856 /*
1857 * XXX:
1858 * Maybe I should just use the fsb->f_mntonname path instead
1859 * of looping back up the dirp to the mount point??
1860 * Also, needs to know how to export all types of local
1861 * exportable filesystems and not just "ufs".
1862 */
1863 while (mount(fsb->f_fstypename, dirp,
1864 fsb->f_flags | MNT_UPDATE, (caddr_t)&args) < 0) {
1865 if (cp)
1866 *cp-- = savedc;
1867 else
1868 cp = dirp + dirplen - 1;
1869 if (opt_flags & OP_QUIET)
1870 return (1);
1871 if (errno == EPERM) {
1872 if (debug)
1873 warnx("can't change attributes for %s",
1874 dirp);
1875 syslog(LOG_ERR,
1876 "can't change attributes for %s", dirp);
1877 return (1);
1878 }
1879 if (opt_flags & OP_ALLDIRS) {
1880 if (errno == EINVAL)
1881 syslog(LOG_ERR,
1882 "-alldirs requested but %s is not a filesystem mountpoint",
1883 dirp);
1884 else
1885 syslog(LOG_ERR,
1886 "could not remount %s: %m",
1887 dirp);
1888 return (1);
1889 }
1890 /* back up over the last component */
1891 while (*cp == '/' && cp > dirp)
1892 cp--;
1893 while (*(cp - 1) != '/' && cp > dirp)
1894 cp--;
1895 if (cp == dirp) {
1896 if (debug)
1897 warnx("mnt unsucc");
1898 syslog(LOG_ERR, "can't export %s", dirp);
1899 return (1);
1900 }
1901 savedc = *cp;
1902 *cp = '\0';
1903 /* Check that we're still on the same filesystem. */
1904 if (statfs(dirp, &fsb1) != 0 || bcmp(&fsb1.f_fsid,
1905 &fsb->f_fsid, sizeof(fsb1.f_fsid)) != 0) {
1906 *cp = savedc;
1907 syslog(LOG_ERR, "can't export %s", dirp);
1908 return (1);
1909 }
1910 }
1911skip:
1912 if (ai != NULL)
1913 ai = ai->ai_next;
1914 if (ai == NULL)
1915 done = TRUE;
1916 }
1917 if (cp)
1918 *cp = savedc;
1919 return (0);
1920}
1921
1922/*
1923 * Translate a net address.
1924 *
1925 * If `maskflg' is nonzero, then `cp' is a netmask, not a network address.
1926 */
1927int

--- 608 unchanged lines hidden ---