Deleted Added
full compact
mountd.c (150214) mountd.c (158857)
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: head/usr.sbin/mountd/mountd.c 150214 2005-09-16 11:24:28Z pjd $");
46__FBSDID("$FreeBSD: head/usr.sbin/mountd/mountd.c 158857 2006-05-23 17:10:17Z rodrigc $");
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>
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"
65
66#include <arpa/inet.h>
67
68#include <ctype.h>
69#include <err.h>
70#include <errno.h>
71#include <grp.h>
72#include <libutil.h>
73#include <limits.h>
74#include <netdb.h>
75#include <pwd.h>
76#include <signal.h>
77#include <stdio.h>
78#include <stdlib.h>
79#include <string.h>
80#include <unistd.h>
81#include "pathnames.h"
82#include "mntopts.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;
83
84#ifdef DEBUG
85#include <stdarg.h>
86#endif
87
88/*
89 * Structures for keeping the mount list and export list
90 */

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

955 * Get the export list
956 */
957void
958get_exportlist()
959{
960 struct exportlist *ep, *ep2;
961 struct grouplist *grp, *tgrp;
962 struct exportlist **epp;
963 struct export_args export;
966 struct dirlist *dirhead;
964 struct dirlist *dirhead;
965 struct iovec *iov;
967 struct statfs fsb, *fsp;
968 struct xucred anon;
969 char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
966 struct statfs fsb, *fsp;
967 struct xucred anon;
968 char *cp, *endcp, *dirp, *hst, *usr, *dom, savedc;
969 char errmsg[255];
970 int len, has_host, exflags, got_nondir, dirplen, num, i, netgrp;
970 int len, has_host, exflags, got_nondir, dirplen, num, i, netgrp;
971 int iovlen;
971
972
973 bzero(&export, sizeof(export));
974 export.ex_flags = MNT_DELEXPORT;
972 dirp = NULL;
973 dirplen = 0;
975 dirp = NULL;
976 dirplen = 0;
977 iov = NULL;
978 iovlen = 0;
979 bzero(errmsg, sizeof(errmsg));
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);
980
981 /*
982 * First, get rid of the old list
983 */
984 ep = exphead;
985 while (ep) {
986 ep2 = ep;
987 ep = ep->ex_next;

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

999
1000 /*
1001 * And delete exports that are in the kernel for all local
1002 * filesystems.
1003 * XXX: Should know how to handle all local exportable filesystems
1004 * instead of just "ufs".
1005 */
1006 num = getmntinfo(&fsp, MNT_NOWAIT);
1007
1008 if (num > 0) {
1009 build_iovec(&iov, &iovlen, "fstype", NULL, 0);
1010 build_iovec(&iov, &iovlen, "fspath", NULL, 0);
1011 build_iovec(&iov, &iovlen, "from", NULL, 0);
1012 build_iovec(&iov, &iovlen, "update", NULL, 0);
1013 build_iovec(&iov, &iovlen, "export", &export, sizeof(export));
1014 build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
1015 }
1016
1001 for (i = 0; i < num; i++) {
1017 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")) {
1018
1019 if (!strcmp(fsp->f_fstypename, "ufs") ||
1020 !strcmp(fsp->f_fstypename, "msdosfs") ||
1021 !strcmp(fsp->f_fstypename, "ntfs") ||
1022 !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)
1023 iov[1].iov_base = fsp->f_fstypename;
1024 iov[1].iov_len = strlen(fsp->f_fstypename) + 1;
1025 iov[3].iov_base = fsp->f_mntonname;
1026 iov[3].iov_len = strlen(fsp->f_mntonname) + 1;
1027 iov[5].iov_base = fsp->f_mntfromname;
1028 iov[5].iov_len = strlen(fsp->f_mntfromname) + 1;
1029
1030 /*
1031 * Kick out MNT_ROOTFS. It should not be passed from
1032 * userland to kernel. It should only be used
1033 * internally in the kernel.
1034 */
1035 if (fsp->f_flags & MNT_ROOTFS) {
1036 fsp->f_flags &= ~MNT_ROOTFS;
1037 }
1038
1039 if (nmount(iov, iovlen, fsp->f_flags) < 0 &&
1040 errno != ENOENT) {
1019 syslog(LOG_ERR,
1041 syslog(LOG_ERR,
1020 "can't delete exports for %s: %m",
1021 fsp->f_mntonname);
1042 "can't delete exports for %s: %m %s",
1043 fsp->f_mntonname, errmsg);
1044 }
1022 }
1023 fsp++;
1024 }
1025
1045 }
1046 fsp++;
1047 }
1048
1049 if (iov != NULL) {
1050 /* Free strings allocated by strdup() in getmntopts.c */
1051 free(iov[0].iov_base); /* fstype */
1052 free(iov[2].iov_base); /* fspath */
1053 free(iov[4].iov_base); /* from */
1054 free(iov[6].iov_base); /* update */
1055 free(iov[8].iov_base); /* export */
1056 free(iov[10].iov_base); /* errmsg */
1057
1058 /* free iov, allocated by realloc() */
1059 free(iov);
1060 iovlen = 0;
1061 }
1062
1026 /*
1027 * Read in the exports file and build the list, calling
1063 /*
1064 * Read in the exports file and build the list, calling
1028 * mount() as we go along to push the export rules into the kernel.
1065 * nmount() 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/*
1066 */
1067 if ((exp_file = fopen(exname, "r")) == NULL) {
1068 syslog(LOG_ERR, "can't open %s", exname);
1069 exit(2);
1070 }
1071 dirhead = (struct dirlist *)NULL;
1072 while (get_line()) {
1073 if (debug)

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

1810out_of_mem()
1811{
1812
1813 syslog(LOG_ERR, "out of memory");
1814 exit(2);
1815}
1816
1817/*
1781 * Do the mount syscall with the update flag to push the export info into
1818 * Do the nmount() syscall with the update flag to push the export info into
1782 * the kernel.
1783 */
1784int
1819 * the kernel.
1820 */
1821int
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;
1822do_mount(struct exportlist *ep, struct grouplist *grp, int exflags,
1823 struct xucred *anoncrp, char *dirp, int dirplen, struct statfs *fsb)
1793{
1794 struct statfs fsb1;
1795 struct addrinfo *ai;
1824{
1825 struct statfs fsb1;
1826 struct addrinfo *ai;
1796 struct export_args *eap;
1797 char *cp = NULL;
1827 struct export_args eap;
1828 char errmsg[255];
1829 char *cp;
1798 int done;
1830 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;
1831 char savedc;
1832 struct iovec *iov;
1833 int iovlen;
1834 int ret;
1806
1835
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;
1836 cp = NULL;
1837 savedc = '\0';
1838 iov = NULL;
1839 iovlen = 0;
1840 ret = 0;
1811
1841
1812 eap->ex_flags = exflags;
1813 eap->ex_anon = *anoncrp;
1814 eap->ex_indexfile = ep->ex_indexfile;
1842 bzero(&eap, sizeof(eap));
1843 bzero(errmsg, sizeof(errmsg));
1844 eap.ex_flags = exflags;
1845 eap.ex_anon = *anoncrp;
1846 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;
1847 if (grp->gr_type == GT_HOST)
1848 ai = grp->gr_ptr.gt_addrinfo;
1849 else
1850 ai = NULL;
1851 done = FALSE;
1852
1853 build_iovec(&iov, &iovlen, "fstype", NULL, 0);
1854 build_iovec(&iov, &iovlen, "fspath", NULL, 0);
1855 build_iovec(&iov, &iovlen, "from", NULL, 0);
1856 build_iovec(&iov, &iovlen, "update", NULL, 0);
1857 build_iovec(&iov, &iovlen, "export", &eap, sizeof(eap));
1858 build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg));
1859
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;
1860 while (!done) {
1861 switch (grp->gr_type) {
1862 case GT_HOST:
1863 if (ai->ai_addr->sa_family == AF_INET6 && have_v6 == 0)
1864 goto skip;
1825 eap->ex_addr = ai->ai_addr;
1826 eap->ex_addrlen = ai->ai_addrlen;
1827 eap->ex_masklen = 0;
1865 eap.ex_addr = ai->ai_addr;
1866 eap.ex_addrlen = ai->ai_addrlen;
1867 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;
1868 break;
1869 case GT_NET:
1870 if (grp->gr_ptr.gt_net.nt_net.ss_family == AF_INET6 &&
1871 have_v6 == 0)
1872 goto skip;
1833 eap->ex_addr =
1873 eap.ex_addr =
1834 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_net;
1874 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_net;
1835 eap->ex_addrlen = args.ua.export.ex_addr->sa_len;
1836 eap->ex_mask =
1875 eap.ex_addrlen =
1876 ((struct sockaddr *)&grp->gr_ptr.gt_net.nt_net)->sa_len;
1877 eap.ex_mask =
1837 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_mask;
1878 (struct sockaddr *)&grp->gr_ptr.gt_net.nt_mask;
1838 eap->ex_masklen = args.ua.export.ex_mask->sa_len;
1879 eap.ex_masklen = ((struct sockaddr *)&grp->gr_ptr.gt_net.nt_mask)->sa_len;
1839 break;
1840 case GT_DEFAULT:
1880 break;
1881 case GT_DEFAULT:
1841 eap->ex_addr = NULL;
1842 eap->ex_addrlen = 0;
1843 eap->ex_mask = NULL;
1844 eap->ex_masklen = 0;
1882 eap.ex_addr = NULL;
1883 eap.ex_addrlen = 0;
1884 eap.ex_mask = NULL;
1885 eap.ex_masklen = 0;
1845 break;
1846 case GT_IGNORE:
1886 break;
1887 case GT_IGNORE:
1847 return(0);
1888 ret = 0;
1889 goto error_exit;
1848 break;
1849 default:
1850 syslog(LOG_ERR, "bad grouptype");
1851 if (cp)
1852 *cp = savedc;
1890 break;
1891 default:
1892 syslog(LOG_ERR, "bad grouptype");
1893 if (cp)
1894 *cp = savedc;
1853 return (1);
1895 ret = 1;
1896 goto error_exit;
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 */
1897 };
1898
1899 /*
1900 * XXX:
1901 * Maybe I should just use the fsb->f_mntonname path instead
1902 * of looping back up the dirp to the mount point??
1903 * Also, needs to know how to export all types of local
1904 * exportable filesystems and not just "ufs".
1905 */
1863 while (mount(fsb->f_fstypename, dirp,
1864 fsb->f_flags | MNT_UPDATE, (caddr_t)&args) < 0) {
1906 iov[1].iov_base = fsb->f_fstypename; /* "fstype" */
1907 iov[1].iov_len = strlen(fsb->f_fstypename) + 1;
1908 iov[3].iov_base = fsb->f_mntonname; /* "fspath" */
1909 iov[3].iov_len = strlen(fsb->f_mntonname) + 1;
1910 iov[5].iov_base = fsb->f_mntfromname; /* "from" */
1911 iov[5].iov_len = strlen(fsb->f_mntfromname) + 1;
1912
1913 while (nmount(iov, iovlen, 0) < 0) {
1865 if (cp)
1866 *cp-- = savedc;
1867 else
1868 cp = dirp + dirplen - 1;
1914 if (cp)
1915 *cp-- = savedc;
1916 else
1917 cp = dirp + dirplen - 1;
1869 if (opt_flags & OP_QUIET)
1870 return (1);
1918 if (opt_flags & OP_QUIET) {
1919 ret = 1;
1920 goto error_exit;
1921 }
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);
1922 if (errno == EPERM) {
1923 if (debug)
1924 warnx("can't change attributes for %s",
1925 dirp);
1926 syslog(LOG_ERR,
1927 "can't change attributes for %s", dirp);
1877 return (1);
1928 ret = 1;
1929 goto error_exit;
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);
1930 }
1931 if (opt_flags & OP_ALLDIRS) {
1932 if (errno == EINVAL)
1933 syslog(LOG_ERR,
1934 "-alldirs requested but %s is not a filesystem mountpoint",
1935 dirp);
1936 else
1937 syslog(LOG_ERR,
1938 "could not remount %s: %m",
1939 dirp);
1888 return (1);
1940 ret = 1;
1941 goto error_exit;
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);
1942 }
1943 /* back up over the last component */
1944 while (*cp == '/' && cp > dirp)
1945 cp--;
1946 while (*(cp - 1) != '/' && cp > dirp)
1947 cp--;
1948 if (cp == dirp) {
1949 if (debug)
1950 warnx("mnt unsucc");
1951 syslog(LOG_ERR, "can't export %s", dirp);
1899 return (1);
1952 ret = 1;
1953 goto error_exit;
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);
1954 }
1955 savedc = *cp;
1956 *cp = '\0';
1957 /* Check that we're still on the same filesystem. */
1958 if (statfs(dirp, &fsb1) != 0 || bcmp(&fsb1.f_fsid,
1959 &fsb->f_fsid, sizeof(fsb1.f_fsid)) != 0) {
1960 *cp = savedc;
1961 syslog(LOG_ERR, "can't export %s", dirp);
1908 return (1);
1962 ret = 1;
1963 goto error_exit;
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;
1964 }
1965 }
1966skip:
1967 if (ai != NULL)
1968 ai = ai->ai_next;
1969 if (ai == NULL)
1970 done = TRUE;
1971 }
1972 if (cp)
1973 *cp = savedc;
1919 return (0);
1974error_exit:
1975 /* free strings allocated by strdup() in getmntopts.c */
1976 if (iov != NULL) {
1977 free(iov[0].iov_base); /* fstype */
1978 free(iov[2].iov_base); /* fspath */
1979 free(iov[4].iov_base); /* from */
1980 free(iov[6].iov_base); /* update */
1981 free(iov[8].iov_base); /* export */
1982 free(iov[10].iov_base); /* errmsg */
1983
1984 /* free iov, allocated by realloc() */
1985 free(iov);
1986 }
1987 return (ret);
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 ---
1988}
1989
1990/*
1991 * Translate a net address.
1992 *
1993 * If `maskflg' is nonzero, then `cp' is a netmask, not a network address.
1994 */
1995int

--- 608 unchanged lines hidden ---