summaryrefslogtreecommitdiffstats
path: root/utils/exportfs
diff options
context:
space:
mode:
Diffstat (limited to 'utils/exportfs')
-rw-r--r--utils/exportfs/Makefile13
-rw-r--r--utils/exportfs/exportfs.c391
-rw-r--r--utils/exportfs/exportfs.man195
-rw-r--r--utils/exportfs/exports.man306
4 files changed, 905 insertions, 0 deletions
diff --git a/utils/exportfs/Makefile b/utils/exportfs/Makefile
new file mode 100644
index 0000000..851a294
--- /dev/null
+++ b/utils/exportfs/Makefile
@@ -0,0 +1,13 @@
+#
+# dummy Makefile
+#
+
+PROGRAM = exportfs
+OBJS = exportfs.o
+LIBDEPS = $(TOP)support/lib/libexport.a $(TOP)/support/lib/libnfs.a
+LIBS = -lexport -lnfs
+MAN8 = exportfs
+MAN5 = exports
+
+include $(TOP)rules.mk
+
diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
new file mode 100644
index 0000000..44761f8
--- /dev/null
+++ b/utils/exportfs/exportfs.c
@@ -0,0 +1,391 @@
+/*
+ * utils/exportfs/exportfs.c
+ *
+ * Export file systems to knfsd
+ *
+ * Copyright (C) 1995, 1996, 1997 Olaf Kirch <okir@monad.swb.de>
+ *
+ * Extensive changes, 1999, Neil Brown <neilb@cse.unsw.edu.au>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <getopt.h>
+#include <netdb.h>
+#include <errno.h>
+#include "xmalloc.h"
+#include "misc.h"
+#include "nfslib.h"
+#include "exportfs.h"
+#include "xmalloc.h"
+#include "xlog.h"
+
+static void export_all(int verbose);
+static void unexport_all(int verbose);
+static void exportfs(char *arg, char *options, int verbose);
+static void unexportfs(char *arg, int verbose);
+static void exports_update(int verbose);
+static void dump(int verbose);
+static void error(nfs_export *exp, int err);
+static void usage(void);
+
+
+int
+main(int argc, char **argv)
+{
+ char *options = NULL;
+ int f_export = 1;
+ int f_all = 0;
+ int f_verbose = 0;
+ int f_reexport = 0;
+ int f_ignore = 0;
+ int i, c;
+
+ xlog_open("exportfs");
+
+ while ((c = getopt(argc, argv, "aio:ruv")) != EOF) {
+ switch(c) {
+ case 'a':
+ f_all = 1;
+ break;
+ case 'i':
+ f_ignore = 1;
+ break;
+ case 'o':
+ options = optarg;
+ break;
+ case 'r':
+ f_reexport = 1;
+ f_all = 1;
+ break;
+ case 'u':
+ f_export = 0;
+ break;
+ case 'v':
+ f_verbose = 1;
+ break;
+ default:
+ usage();
+ break;
+ }
+ }
+
+ if (optind != argc && f_all) {
+ fprintf(stderr,"exportfs: extra arguments are not permitted with -a or -r.\n");
+ return 1;
+ }
+ if (f_ignore && (f_all || ! f_export)) {
+ fprintf(stderr,"exportfs: -i not meaningful with -a, -r or -u.\n");
+ return 1;
+ }
+ if (f_reexport && ! f_export) {
+ fprintf(stderr, "exportfs: -r and -u are incompatible.\n");
+ return 1;
+ }
+ if (optind == argc && ! f_all) {
+ xtab_export_read();
+ dump(f_verbose);
+ return 0;
+ }
+
+ if (f_export && ! f_ignore)
+ export_read(_PATH_EXPORTS);
+ if (f_export) {
+ if (f_all)
+ export_all(f_verbose);
+ else
+ for (i = optind; i < argc ; i++)
+ exportfs(argv[i], options, f_verbose);
+ }
+ /* note: xtab_*_read does not update entries if they already exist,
+ * so this will not lose new options
+ */
+ if (!f_reexport)
+ xtab_export_read();
+ if (!f_export) {
+ if (f_all)
+ unexport_all(f_verbose);
+ else
+ for (i = optind ; i < argc ; i++)
+ unexportfs(argv[i], f_verbose);
+ }
+ rmtab_read();
+ xtab_mount_read();
+ exports_update(f_verbose);
+ xtab_export_write();
+ xtab_mount_write();
+
+ return 0;
+}
+
+/* we synchronise intention with reality.
+ * entries with m_mayexport get exported
+ * entries with m_exported but not m_mayexport get unexported
+ * looking at m_client->m_type == MCL_FQDN only
+ */
+static void
+exports_update(int verbose)
+{
+ nfs_export *exp;
+
+ for (exp = exportlist[MCL_FQDN]; exp; exp=exp->m_next) {
+ if (exp->m_mayexport && (!exp->m_exported || exp->m_changed)) {
+ if (verbose)
+ printf("%sexporting %s:%s to kernel\n",
+ exp->m_exported ?"re":"",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ if (!export_export(exp))
+ error(exp, errno);
+ }
+ if (exp->m_exported && ! exp->m_mayexport) {
+ if (verbose)
+ printf("unexporting %s:%s from kernel\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ if (!export_unexport(exp))
+ error(exp, errno);
+ }
+ }
+}
+
+/*
+ * export_all finds all entries and
+ * marks them xtabent and mayexport so that they get exported
+ */
+static void
+export_all(int verbose)
+{
+ nfs_export *exp;
+ int i;
+
+ for (i = 0; i < MCL_MAXTYPES; i++) {
+ for (exp = exportlist[i]; exp; exp = exp->m_next) {
+ if (verbose)
+ printf("exporting %s:%s\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ exp->m_xtabent = 1;
+ exp->m_mayexport = 1;
+ exp->m_changed = 1;
+ }
+ }
+}
+/*
+ * unexport_all finds all entries that are mayexport, and
+ * marks them not xtabent and not mayexport
+ */
+static void
+unexport_all(int verbose)
+{
+ nfs_export *exp;
+ int i;
+
+ for (i = 0; i < MCL_MAXTYPES; i++) {
+ for (exp = exportlist[i]; exp; exp = exp->m_next)
+ if (exp->m_mayexport) {
+ if (verbose) {
+ if (exp->m_exported) {
+ printf("unexporting %s:%s from kernel\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ else {
+ printf("unexporting %s:%s\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ }
+ if (exp->m_exported && !export_unexport(exp))
+ error(exp, errno);
+ exp->m_xtabent = 0;
+ exp->m_mayexport = 0;
+ }
+ }
+}
+
+
+static void
+exportfs(char *arg, char *options, int verbose)
+{
+ struct exportent *eep;
+ nfs_export *exp;
+ struct hostent *hp = NULL;
+ char *path;
+ char *hname = arg;
+ int htype;
+
+ if ((path = strchr(arg, ':')) != NULL)
+ *path++ = '\0';
+
+ if (!path || *path != '/') {
+ fprintf(stderr, "Invalid exporting option: %s\n", arg);
+ return;
+ }
+
+ if ((htype = client_gettype(hname)) == MCL_FQDN &&
+ (hp = gethostbyname(hname)) != NULL) {
+ hp = hostent_dup (hp);
+ exp = export_find(hp, path);
+ } else {
+ exp = export_lookup(hname, path);
+ }
+
+ if (!exp) {
+ if (!(eep = mkexportent(hname, path, options)) ||
+ !(exp = export_create(eep))) {
+ if (hp) free (hp);
+ return;
+ }
+ } else if (!updateexportent(&exp->m_export, options)) {
+ if (hp) free (hp);
+ return;
+ }
+
+ if (verbose)
+ printf("exporting %s:%s\n", exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ exp->m_xtabent = 1;
+ exp->m_mayexport = 1;
+ exp->m_changed = 1;
+ if (hp) free (hp);
+}
+
+static void
+unexportfs(char *arg, int verbose)
+{
+ nfs_export *exp;
+ struct hostent *hp = NULL;
+ char *path;
+ char *hname = arg;
+ int htype;
+
+ if ((path = strchr(arg, ':')) != NULL)
+ *path++ = '\0';
+
+ if (!path || *path != '/') {
+ fprintf(stderr, "Invalid unexporting option: %s\n",
+ arg);
+ return;
+ }
+
+ if ((htype = client_gettype(hname)) == MCL_FQDN) {
+ if ((hp = gethostbyname(hname)) != 0) {
+ hp = hostent_dup (hp);
+ hname = (char *) hp->h_name;
+ }
+ }
+
+ for (exp = exportlist[htype]; exp; exp = exp->m_next) {
+ if (path && strcmp(path, exp->m_export.e_path))
+ continue;
+ if (htype != exp->m_client->m_type
+ || (htype == MCL_FQDN
+ && !matchhostname(exp->m_export.e_hostname,
+ hname)))
+ continue;
+ if (verbose) {
+ if (exp->m_exported) {
+ printf("unexporting %s:%s from kernel\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ else {
+ printf("unexporting %s:%s\n",
+ exp->m_client->m_hostname,
+ exp->m_export.e_path);
+ }
+ }
+ if (exp->m_exported && !export_unexport(exp))
+ error(exp, errno);
+ exp->m_xtabent = 0;
+ exp->m_mayexport = 0;
+ }
+
+ if (hp) free (hp);
+}
+
+static char
+dumpopt(char c, char *fmt, ...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ printf("%c", c);
+ vprintf(fmt, ap);
+ va_end(ap);
+ return ',';
+}
+
+static void
+dump(int verbose)
+{
+ nfs_export *exp;
+ struct exportent *ep;
+ int htype;
+ char *hname, c;
+
+ for (htype = 0; htype < MCL_MAXTYPES; htype++) {
+ for (exp = exportlist[htype]; exp; exp = exp->m_next) {
+ ep = &exp->m_export;
+ if (!exp->m_xtabent)
+ continue; /* neilb */
+ if (htype == MCL_ANONYMOUS)
+ hname = "<world>";
+ else
+ hname = ep->e_hostname;
+ if (strlen(ep->e_path) > 14)
+ printf("%-14s\n\t\t%s", ep->e_path, hname);
+ else
+ printf("%-14s\t%s", ep->e_path, hname);
+ if (!verbose) {
+ printf("\n");
+ continue;
+ }
+ c = '(';
+ if (ep->e_flags & NFSEXP_READONLY)
+ c = dumpopt(c, "ro");
+ else
+ c = dumpopt(c, "rw");
+ if (ep->e_flags & NFSEXP_ASYNC)
+ c = dumpopt(c, "async");
+ if (ep->e_flags & NFSEXP_GATHERED_WRITES)
+ c = dumpopt(c, "wdelay");
+ if (ep->e_flags & NFSEXP_INSECURE_PORT)
+ c = dumpopt(c, "insecure");
+ if (ep->e_flags & NFSEXP_ROOTSQUASH)
+ c = dumpopt(c, "root_squash");
+ else
+ c = dumpopt(c, "no_root_squash");
+ if (ep->e_flags & NFSEXP_ALLSQUASH)
+ c = dumpopt(c, "all_squash");
+ if (ep->e_maptype == CLE_MAP_UGIDD)
+ c = dumpopt(c, "mapping=ugidd");
+ else if (ep->e_maptype == CLE_MAP_FILE)
+ c = dumpopt(c, "mapping=file");
+ if (ep->e_anonuid != -2)
+ c = dumpopt(c, "anonuid=%d", ep->e_anonuid);
+ if (ep->e_anongid != -2)
+ c = dumpopt(c, "anongid=%d", ep->e_anongid);
+
+ printf("%c\n", (c != '(')? ')' : ' ');
+ }
+ }
+}
+
+static void
+error(nfs_export *exp, int err)
+{
+ fprintf(stderr, "%s:%s: %s\n", exp->m_client->m_hostname,
+ exp->m_export.e_path, strerror(err));
+}
+
+static void
+usage(void)
+{
+ fprintf(stderr, "usage: exportfs [-aruv] [host:/path]\n");
+ exit(1);
+}
diff --git a/utils/exportfs/exportfs.man b/utils/exportfs/exportfs.man
new file mode 100644
index 0000000..0cd5cca
--- /dev/null
+++ b/utils/exportfs/exportfs.man
@@ -0,0 +1,195 @@
+.\"
+.\" exportfs(8)
+.\"
+.\" Copyright (C) 1995 Olaf Kirch <okir@monad.swb.de>
+.\" Modifications 1999 Neil Brown <neilb@cse.unsw.edu.au>
+.TH exportfs 8 "7 Sep 1999"
+.SH NAME
+exportfs \- maintain list of NFS exported file systems
+.SH SYNOPSIS
+.BI "/usr/sbin/exportfs [-avi] [-o " "options,.." "] [" "client:/path" " ..]
+.br
+.BI "/usr/sbin/exportfs -r [-v]"
+.br
+.BI "/usr/sbin/exportfs [-av] -u [" "client:/path" " ..]
+.br
+.BI "/usr/sbin/exportfs [-v]
+.br
+.SH DESCRIPTION
+The
+.B exportfs
+command is used to maintain the current table of exported file systems for
+NFS. This list is kept in a separate file named
+.BR /var/lib/nfs/xtab
+which is read by
+.B mountd
+when a remote host requests access to mount a file tree, and parts of
+the list which are active are kept in the kernel's export table.
+.P
+Normally this
+.B xtab
+file is initialized with the list of all file systems named in
+.B /etc/exports
+by invoking
+.BR "exportfs -a" .
+.P
+However, administrators can choose to add and delete individual file systems
+without modifying
+.B /etc/exports
+using
+.BR exportfs .
+.P
+Any export requests which identify a specific host (rather than a
+subnet or netgroup etc) are entered directly into the kernel's export
+table as well as being written to
+.BR /var/lib/nfs/xtab .
+Further, any mount points listed in
+.B /var/lib/nfs/rmtab
+which match a non host-specific export request will cause an
+appropriate export entry for the host given in
+.B rmtab
+to be entered
+into the kernel's export table.
+.SH OPTIONS
+.TP
+.B -a
+Export or unexport all directories.
+.TP
+.BI "-o " options,...
+Specify a list of export options in the same manner as in
+.BR exports(5) .
+.TP
+.B -i
+Ignore the
+.B /etc/exports
+file, so that only default options and options given on the command
+line are used.
+.TP
+.B -r
+Reexport all directories. It synchronizes /var/lib/nfs/xtab
+with /etc/exports. It removes entries in /var/lib/nfs/xtab
+which are deleted from /etc/exports, and remove any entries from the
+kernel export table which are no longer valid.
+.TP
+.TP
+.B -u
+Unexport one or more directories.
+.TP
+.B -v
+Be verbose. When exporting or unexporting, show what's going on. When
+displaying the current export list, also display the list of export
+options.
+.SH DISCUSSION
+.\" -------------------- Exporting Directories --------------------
+.SS Exporting Directories
+The first synopsis shows how to invoke the command when adding new
+entries to the export table. When using
+.BR "exportfs -a" ,
+all directories in
+.B exports(5)
+are added to
+.B xtab
+and the resulting list is pushed into the kernel.
+.P
+The
+.I host:/path
+argument specifies the directory to export along with the host or hosts to
+export it to. All formats described in
+.B exports(5)
+are supported; to export a directory to the world, simply specify
+.IR :/path .
+.P
+The export options for a particular host/directory pair derive from
+several sources. There is a set of default options which can be overridden by
+entries in
+.B /etc/exports
+(unless the
+.B -i
+option is given).
+In addition, the administrator may overide any options from these sources
+using the
+.B -o
+argument which takes a comma-separated list of options in the same fashion
+as one would specify them in
+.BR exports(5) .
+Thus,
+.B exportfs
+can also be used to modify the export options of an already exported
+directory.
+.P
+Modifications of the kernel export table used by
+.B nfsd(8)
+take place immediately after parsing the command line and updating the
+.B xtab
+file.
+.P
+The default export options are
+.BR async,ro,root_squash,no_delay .
+.\" -------------------- Unexporting Directories ------------------
+.SS Unexporting Directories
+The third synopsis shows how to unexported a currently exported directory.
+When using
+.BR "exportfs -ua" ,
+all entries listed in
+.B xtab
+are removed from the kernel export tables, and the file is cleared. This
+effectively shuts down all NFS activity.
+.P
+To remove individial export entries, one can specify a
+.I host:/path
+pair. This deletes the specified entry from
+.B xtab
+and removes the corresponding kernel entry (if any).
+.P
+.\" -------------------- Dumping the Export Table -----------------
+.SS Dumping the Export Table
+Invoking
+.B exportfs
+without further options shows the current list of exported file systems.
+When giving the
+.B -v
+option, the list of flags pertaining to each export are shown in addition.
+.\" -------------------- EXAMPLES ---------------------------------
+.SH EXAMPLES
+The following adds all directories listed in
+.B /etc/exports to /var/lib/nfs/xtab
+and pushes the resulting export entries into the kernel:
+.P
+.nf
+.B "# exportfs -a
+.fi
+.P
+To export the
+.B /usr/tmp
+directory to host
+.BR djando ,
+allowing asynchronous writes, one would do this:
+.P
+.nf
+.B "# exportfs -o async django:/usr/tmp
+.fi
+.\" -------------------- DEPENDENCIES -----------------------------
+.SH DEPENDENCIES
+Exporting to IP networks, DNS and NIS domains does not enable clients
+from these groups to access NFS immediately; rather, these sorts of
+exports are hints to
+.B mountd(8)
+to grant any mount requests from these clients.
+This is usually not a big problem, because any existing mounts are preserved
+in
+.B rmtab
+across reboots.
+.P
+When unexporting a network or domain entry, any current exports to members
+of this group will be checked against the remaining valid exports and
+if they themselves are nolonger valid they will be removed.
+.P
+.\" -------------------- SEE ALSO --------------------------------
+.SH SEE ALSO
+.BR exports(5) ", " mountd(8)
+.\" -------------------- AUTHOR ----------------------------------
+.SH AUTHORS
+Olaf Kirch, <okir@monad.swb.de>
+.br
+Neil Brown, <neilb@cse.unsw.edu.au>
+
diff --git a/utils/exportfs/exports.man b/utils/exportfs/exports.man
new file mode 100644
index 0000000..2863fea
--- /dev/null
+++ b/utils/exportfs/exports.man
@@ -0,0 +1,306 @@
+.TH EXPORTS 5 "11 August 1997"
+.UC 5
+.SH NAME
+exports \- NFS file systems being exported
+.SH SYNOPSIS
+.B /etc/exports
+.SH DESCRIPTION
+The file
+.I /etc/exports
+serves as the access control list for file systems which may be
+exported to NFS clients. It it used by both the NFS mount daemon,
+.IR mountd (8)
+and the NFS file server daemon
+.IR nfsd (8).
+.PP
+The file format is similar to the SunOS
+.I exports
+file, except that several additional options are permitted. Each line
+contains a mount point and a list of machine or netgroup names allowed
+to mount the file system at that point. An optional parenthesized list
+of mount parameters may follow each machine name. Blank lines are
+ignored, and a # introduces a comment to the end of the line. Entries may
+be continued across newlines using a backslash.
+.PP
+.SS Machine Name Formats
+NFS clients may be specified in a number of ways:
+.IP "single host
+This is the most common format. You may specify a host either by an
+abbreviated name recognizued be the resolver, the fully qualified domain
+name, or an IP address.
+.IP "netgroups
+NIS netgroups may be given as
+.IR @group .
+Only the host part of all
+netgroup members is extracted and added to the access list. Empty host
+parts or those containing a single dash (\-) are ignored.
+.IP "wildcards
+Machine names may contain the wildcard characters \fI*\fR and \fI?\fR.
+This can be used to make the \fIexports\fR file more compact; for instance,
+\fI*.cs.foo.edu\fR matches all hosts in the domain \fIcs.foo.edu\fR. However,
+these wildcard characters do not match the dots in a domain name, so the
+above pattern does not include hosts such as \fIa.b.cs.foo.edu\fR.
+.IP "IP networks
+You can also export directories to all hosts on an IP (sub-) network
+simultaneously. This is done by specifying an IP address and netmask pair
+as
+.IR address/netmask .
+.TP
+.B =public
+This is a special ``hostname'' that identifies the given directory name
+as the public root directory (see the section on WebNFS in
+.BR nfsd (8)
+for a discussion of WebNFS and the public root handle). When using this
+convention,
+.B =public
+must be the only entry on this line, and must have no export options
+associated with it. Note that this does
+.I not
+actually export the named directory; you still have to set the exports
+options in a separate entry.
+.PP
+The public root path can also be specified by invoking
+.I nfsd
+with the
+.B \-\-public\-root
+option. Multiple specifications of a public root will be ignored.
+.PP
+.SS General Options
+.IR mountd " and " nfsd
+understand the following export options:
+.TP
+.IR secure "\*d
+This option requires that requests originate on an internet port less
+than IPPORT_RESERVED (1024). This option is on by default. To turn it
+off, specify
+.IR insecure .
+.TP
+.IR ro
+Allow only read-only requests on this NFS volume. The default is to
+allow write requests as well, which can also be made explicit by using
+the
+.IR rw " option.
+.TP
+.I noaccess
+This makes everything below the directory inaccessible for the named
+client. This is useful when you want to export a directory hierarchy to
+a client, but exclude certain subdirectories. The client's view of a
+directory flagged with noaccess is very limited; it is allowed to read
+its attributes, and lookup `.' and `..'. These are also the only entries
+returned by a readdir.
+.TP
+.IR link_relative
+Convert absolute symbolic links (where the link contents start with a
+slash) into relative links by prepending the necessary number of ../'s
+to get from the directory containing the link to the root on the
+server. This has subtle, perhaps questionable, semantics when the file
+hierarchy is not mounted at its root.
+.TP
+.IR link_absolute
+Leave all symbolic link as they are. This is the default operation.
+.SS User ID Mapping
+.PP
+.I nfsd
+bases its access control to files on the server machine on the uid and
+gid provided in each NFS RPC request. The normal behavior a user would
+expect is that she can access her files on the server just as she would
+on a normal file system. This requires that the same uids and gids are
+used on the client and the server machine. This is not always true, nor
+is it always desirable.
+.PP
+Very often, it is not desirable that the root user on a client machine
+is also treated as root when accessing files on the NFS server. To this
+end, uid 0 is normally mapped to a different id: the so-called
+anonymous or
+.I nobody
+uid. This mode of operation (called `root squashing') is the default,
+and can be turned off with
+.IR no_root_squash .
+.PP
+By default,
+.I nfsd
+tries to obtain the anonymous uid and gid by looking up user
+.I nobody
+in the password file at startup time. If it isn't found, a uid and gid
+of -2 (i.e. 65534) is used. These values can also be overridden by
+the
+.IR anonuid " and " anongid
+options.
+.PP
+In addition to this,
+.I nfsd
+lets you specify arbitrary uids and gids that should be mapped to user
+nobody as well. Finally, you can map all user requests to the
+anonymous uid by specifying the
+.IR all_squash " option.
+.PP
+For the benefit of installations where uids differ between different
+machines,
+.I nfsd
+provides several mechanism to dynamically map server uids to client
+uids and vice versa: static mapping files, NIS-based mapping, and
+.IR ugidd -based
+mapping.
+.PP
+.IR ugidd -based
+mapping is enabled with the
+.I map_daemon
+option, and uses the UGID RPC protocol. For this to work, you have to run
+the
+.IR ugidd (8)
+mapping daemon on the client host. It is the least secure of the three methods,
+because by running
+.IR ugidd ,
+everybody can query the client host for a list of valid user names. You
+can protect yourself by restricting access to
+.I ugidd
+to valid hosts only. This can be done by entering the list of valid
+hosts into the
+.I hosts.allow
+or
+.I hosts.deny
+file. The service name is
+.IR ugidd .
+For a description of the file's syntax, please read
+.IR hosts_access (5).
+.PP
+Static mapping is enabled by using the
+.I map_static
+option, which takes a file name as an argument that describes the mapping.
+NIS-based mapping queries the client's NIS server to obtain a mapping from
+user and group names on the server host to user and group names on the
+client.
+.PP
+Here's the complete list of mapping options:
+.TP
+.IR root_squash
+Map requests from uid/gid 0 to the anonymous uid/gid. Note that this does
+not apply to any other uids that might be equally sensitive, such as user
+.IR bin .
+.TP
+.IR no_root_squash
+Turn off root squashing. This option is mainly useful for diskless clients.
+.TP
+.IR squash_uids " and " squash_gids
+This option specifies a list of uids or gids that should be subject to
+anonymous mapping. A valid list of ids looks like this:
+.IP
+.IR squash_uids=0-15,20,25-50
+.IP
+Usually, your squash lists will look a lot simpler.
+.TP
+.IR all_squash
+Map all uids and gids to the anonymous user. Useful for NFS-exported
+public FTP directories, news spool directories, etc. The opposite option
+is
+.IR no_all_squash ,
+which is the default setting.
+.TP
+.IR map_daemon
+This option turns on dynamic uid/gid mapping. Each uid in an NFS request
+will be translated to the equivalent server uid, and each uid in an
+NFS reply will be mapped the other way round. This option requires that
+.IR rpc.ugidd (8)
+runs on the client host. The default setting is
+.IR map_identity ,
+which leaves all uids untouched. The normal squash options apply regardless
+of whether dynamic mapping is requested or not.
+.TP
+.IR map_static
+This option enables static mapping. It specifies the name of the file
+that describes the uid/gid mapping, e.g.
+.IP
+.IR map_static=/etc/nfs/foobar.map
+.IP
+The file's format looks like this
+.IP
+.nf
+.ta +3i
+# Mapping for client foobar:
+# remote local
+uid 0-99 - # squash these
+uid 100-500 1000 # map 100-500 to 1000-1500
+gid 0-49 - # squash these
+gid 50-100 700 # map 50-100 to 700-750
+.fi
+.TP
+.IR map_nis
+This option enables NIS-based uid/gid mapping. For instance, when
+the server encounters the uid 123 on the server, it will obtain the
+login name associated with it, and contact the NFS client's NIS server
+to obtain the uid the client associates with the name.
+.IP
+In order to do this, the NFS server must know the client's NIS domain.
+This is specified as an argument to the
+.I map_nis
+options, e.g.
+.IP
+.I map_nis=foo.com
+.IP
+Note that it may not be sufficient to simply specify the NIS domain
+here; you may have to take additional actions before
+.I nfsd
+is actually able to contact the server. If your distribution uses
+the NYS library, you can specify one or more NIS servers for the
+client's domain in
+.IR /etc/yp.conf .
+If you are using a different NIS library, you may have to obtain a
+special
+.IR ypbind (8)
+daemon that can be configured via
+.IR yp.conf .
+.TP
+.IR anonuid " and " anongid
+These options explicitly set the uid and gid of the anonymous account.
+This option is primarily useful for PC/NFS clients, where you might want
+all requests appear to be from one user. As an example, consider the
+export entry for
+.B /home/joe
+in the example section below, which maps all requests to uid 150 (which
+is supposedly that of user joe).
+.IP
+.SH EXAMPLE
+.PP
+.nf
+.ta +3i
+# sample /etc/exports file
+/ master(rw) trusty(rw,no_root_squash)
+/projects proj*.local.domain(rw)
+/usr *.local.domain(ro) @trusted(rw)
+/home/joe pc001(rw,all_squash,anonuid=150,anongid=100)
+/pub (ro,insecure,all_squash)
+/pub/private (noaccess)
+.fi
+.PP
+The first line exports the entire filesystem to machines master and trusty.
+In addition to write access, all uid squashing is turned off for host
+trusty. The second and third entry show examples for wildcard hostnames
+and netgroups (this is the entry `@trusted'). The fourth line shows the
+entry for the PC/NFS client discussed above. Line 5 exports the
+public FTP directory to every host in the world, executing all requests
+under the nobody account. The
+.I insecure
+option in this entry also allows clients with NFS implementations that
+don't use a reserved port for NFS. The last line denies all NFS clients
+access to the private directory.
+.SH CAVEATS
+Unlike other NFS server implementations, this
+.I nfsd
+allows you to export both a directory and a subdirectory thereof to
+the same host, for instance
+.IR /usr " and " /usr/X11R6 .
+In this case, the mount options of the most specific entry apply. For
+instance, when a user on the client host accesses a file in
+.IR /usr/X11R6 ,
+the mount options given in the
+.I /usr/X11R6
+entry apply. This is also true when the latter is a wildcard or netgroup
+entry.
+.SH FILES
+/etc/exports
+.SH DIAGNOSTICS
+An error parsing the file is reported using syslogd(8) as level NOTICE from
+a DAEMON whenever nfsd(8) or mountd(8) is started up. Any unknown
+host is reported at that time, but often not all hosts are not yet known
+to named(8) at boot time, thus as hosts are found they are reported
+with the same syslogd(8) parameters.