diff options
Diffstat (limited to 'utils/exportfs')
-rw-r--r-- | utils/exportfs/Makefile | 13 | ||||
-rw-r--r-- | utils/exportfs/exportfs.c | 391 | ||||
-rw-r--r-- | utils/exportfs/exportfs.man | 195 | ||||
-rw-r--r-- | utils/exportfs/exports.man | 306 |
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. |