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 --- |