Remove nfsd and mountd from src/sbin, look for it in src/usr.sbin

This commit is contained in:
Gordon Tetlow 2002-07-07 22:22:16 +00:00
parent c1c086d9fe
commit 1ada226485
9 changed files with 0 additions and 4202 deletions

View File

@ -1,8 +0,0 @@
# From: @(#)Makefile 8.3 (Berkeley) 1/25/94
# $FreeBSD$
PROG= mountd
WARNS= 0
MAN= exports.5 netgroup.5 mountd.8
.include <bsd.prog.mk>

View File

@ -1,323 +0,0 @@
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)exports.5 8.3 (Berkeley) 3/29/95
.\" $FreeBSD$
.\"
.Dd March 29, 1995
.Dt EXPORTS 5
.Os
.Sh NAME
.Nm exports
.Nd define remote mount points for
.Tn NFS
mount requests
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
The
.Nm
file specifies remote mount points for the
.Tn NFS
mount protocol per the
.Tn NFS
server specification; see
.%T "Network File System Protocol Specification" ,
RFC1094, Appendix A and
.%T "NFS: Network File System Version 3 Specification" ,
Appendix I.
.Pp
Each line in the file
(other than comment lines that begin with a #)
specifies the mount point(s) and export flags within one local server
filesystem for one or more hosts.
A long line may be split over several lines by ending all but the
last line with a backslash
.Pq Ql \e .
A host may be specified only once for each local filesystem on the
server and there may be only one default entry for each server
filesystem that applies to all other hosts.
The latter exports the filesystem to the ``world'' and should
be used only when the filesystem contains public information.
.Pp
In a mount entry,
the first field(s) specify the directory path(s) within a server filesystem
that can be mounted on by the corresponding client(s).
There are two forms of this specification.
The first is to list all mount points as absolute
directory paths separated by whitespace.
The second is to specify the pathname of the root of the filesystem
followed by the
.Fl alldirs
flag;
this form allows the host(s) to mount at any point within the filesystem,
including regular files if the
.Fl r
option is used on
.Xr mountd 8 .
The pathnames must not have any symbolic links in them and should not have
any "." or ".." components.
Mount points for a filesystem may appear on multiple lines each with
different sets of hosts and export options.
.Pp
The second component of a line specifies how the filesystem is to be
exported to the host set.
The option flags specify whether the filesystem
is exported read-only or read-write and how the client uid is mapped to
user credentials on the server.
.Pp
Export options are specified as follows:
.Pp
.Sm off
.Fl maproot No = Sy user
.Sm on
The credential of the specified user is used for remote access by root.
The credential includes all the groups to which the user is a member
on the local machine (see
.Xr id 1 ) .
The user may be specified by name or number.
.Pp
.Sm off
.Fl maproot No = Sy user:group1:group2:...
.Sm on
The colon separated list is used to specify the precise credential
to be used for remote access by root.
The elements of the list may be either names or numbers.
Note that user: should be used to distinguish a credential containing
no groups from a complete credential for that user.
.Pp
.Sm off
.Fl mapall No = Sy user
.Sm on
or
.Sm off
.Fl mapall No = Sy user:group1:group2:...
.Sm on
specifies a mapping for all client uids (including root)
using the same semantics as
.Fl maproot .
.Pp
The option
.Fl r
is a synonym for
.Fl maproot
in an effort to be backward compatible with older export file formats.
.Pp
In the absence of
.Fl maproot
and
.Fl mapall
options, remote accesses by root will result in using a credential of -2:-2.
All other users will be mapped to their remote credential.
If a
.Fl maproot
option is given,
remote access by root will be mapped to that credential instead of -2:-2.
If a
.Fl mapall
option is given,
all users (including root) will be mapped to that credential in
place of their own.
.Pp
The
.Fl kerb
option specifies that the Kerberos authentication server should be
used to authenticate and map client credentials.
This option requires that the kernel be built with the NFSKERB option.
The use of this option will prevent the kernel from compiling
unless calls to the appropriate Kerberos encryption routines
are provided in the NFS source.
.Pp
The
.Fl ro
option specifies that the filesystem should be exported read-only
(default read/write).
The option
.Fl o
is a synonym for
.Fl ro
in an effort to be backward compatible with older export file formats.
.Pp
.Tn WebNFS
exports strictly according to the spec (RFC 2054 and RFC 2055) can
be done with the
.Fl public
flag.
However, this flag in itself allows r/w access to all files in
the filesystem, not requiring reserved ports and not remapping uids.
It
is only provided to conform to the spec, and should normally not be used.
For a
.Tn WebNFS
export,
use the
.Fl webnfs
flag, which implies
.Fl public ,
.Sm off
.Fl mapall No = Sy nobody
.Sm on
and
.Fl ro .
.Pp
A
.Sm off
.Fl index No = Sy file
.Sm on
option can be used to specify a file whose handle will be returned if
a directory is looked up using the public filehandle
.Pq Tn WebNFS .
This is to mimic the behavior of URLs.
If no
.Fl index
option is specified, a directory filehandle will be returned as usual.
The
.Fl index
option only makes sense in combination with the
.Fl public
or
.Fl webnfs
flags.
.Pp
The third component of a line specifies the host set to which the line applies.
The set may be specified in three ways.
The first way is to list the host name(s) separated by white space.
(Standard Internet ``dot'' addresses may be used in place of names.)
The second way is to specify a ``netgroup'' as defined in the netgroup file (see
.Xr netgroup 5 ) .
The third way is to specify an Internet subnetwork using a network and
network mask that is defined as the set of all hosts with addresses within
the subnetwork.
This latter approach requires less overhead within the
kernel and is recommended for cases where the export line refers to a
large number of clients within an administrative subnet.
.Pp
The first two cases are specified by simply listing the name(s) separated
by whitespace.
All names are checked to see if they are ``netgroup'' names
first and are assumed to be hostnames otherwise.
Using the full domain specification for a hostname can normally
circumvent the problem of a host that has the same name as a netgroup.
The third case is specified by the flag
.Sm off
.Fl network No = Sy netname
.Sm on
and optionally
.Sm off
.Fl mask No = Sy netmask .
.Sm on
If the mask is not specified, it will default to the mask for that network
class (A, B or C; see
.Xr inet 4 ) .
.Pp
For example:
.Bd -literal -offset indent
/usr /usr/local -maproot=0:10 friends
/usr -maproot=daemon grumpy.cis.uoguelph.ca 131.104.48.16
/usr -ro -mapall=nobody
/u -maproot=bin: -network 131.104.48 -mask 255.255.255.0
/u2 -maproot=root friends
/u2 -alldirs -kerb -network cis-net -mask cis-mask
.Ed
.Pp
Given that
.Sy /usr ,
.Sy /u
and
.Sy /u2
are
local filesystem mount points, the above example specifies the following:
.Sy /usr
is exported to hosts
.Em friends
where friends is specified in the netgroup file
with users mapped to their remote credentials and
root mapped to uid 0 and group 10.
It is exported read-write and the hosts in ``friends'' can mount either /usr
or /usr/local.
It is exported to
.Em 131.104.48.16
and
.Em grumpy.cis.uoguelph.ca
with users mapped to their remote credentials and
root mapped to the user and groups associated with ``daemon'';
it is exported to the rest of the world as read-only with
all users mapped to the user and groups associated with ``nobody''.
.Pp
.Sy /u
is exported to all hosts on the subnetwork
.Em 131.104.48
with root mapped to the uid for ``bin'' and with no group access.
.Pp
.Sy /u2
is exported to the hosts in ``friends'' with root mapped to uid and groups
associated with ``root'';
it is exported to all hosts on network ``cis-net'' allowing mounts at any
directory within /u2 and mapping all uids to credentials for the principal
that is authenticated by a Kerberos ticket.
.Pp
The
.Xr mountd 8
utility can be made to re-read the
.Nm
file by sending it a hangup signal as follows:
.Bd -literal -offset indent
kill -s HUP `cat /var/run/mountd.pid`
.Ed
.Pp
After sending the
.Dv SIGHUP ,
check the
.Xr syslogd 8
output to see whether
.Xr mountd 8
logged any parsing errors in the
.Nm
file.
.Sh FILES
.Bl -tag -width /etc/exports -compact
.It Pa /etc/exports
the default remote mount-point file
.El
.Sh SEE ALSO
.Xr netgroup 5 ,
.Xr mountd 8 ,
.Xr nfsd 8 ,
.Xr showmount 8
.Sh BUGS
The export options are tied to the local mount points in the kernel and
must be non-contradictory for any exported subdirectory of the local
server mount point.
It is recommended that all exported directories within the same server
filesystem be specified on adjacent lines going down the tree.
You cannot specify a hostname that is also the name of a netgroup.
Specifying the full domain specification for a hostname can normally
circumvent the problem.

View File

@ -1,150 +0,0 @@
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)mountd.8 8.4 (Berkeley) 4/28/95
.\" $FreeBSD$
.\"
.Dd April 28, 1995
.Dt MOUNTD 8
.Os
.Sh NAME
.Nm mountd
.Nd service remote
.Tn NFS
mount requests
.Sh SYNOPSIS
.Nm
.Op Fl 2dlnr
.Op Ar exportsfile
.Sh DESCRIPTION
The
.Nm
utility is the server for
.Tn NFS
mount requests from other client machines.
It listens for service requests at the port indicated in the
.Tn NFS
server specification; see
.%T "Network File System Protocol Specification" ,
RFC1094, Appendix A and
.%T "NFS: Network File System Version 3 Protocol Specification" ,
Appendix I.
.Pp
The following options are available:
.Bl -tag -width indent
.It Fl 2
Allow the administrator to force clients to use only the
version 2
.Tn NFS
protocol to mount filesystems from this server.
.It Fl d
Output debugging information.
.It Fl l
Cause all succeeded
.Nm
requests to be logged.
.It Fl n
Allow non-root mount requests to be served.
This should only be specified if there are clients such as PC's,
that require it.
It will automatically clear the vfs.nfsrv.nfs_privport sysctl flag, which
controls if the kernel will accept NFS requests from reserved ports only.
.It Fl r
Allow mount RPCs requests for regular files to be served.
Although this seems to violate the mount protocol specification,
some diskless workstations do mount requests for
their swapfiles and expect them to be regular files.
Since a regular file cannot be specified in
.Pa /etc/exports ,
the entire filesystem in which the swapfiles resides
will have to be exported with the
.Fl alldirs
flag.
.It Ar exportsfile
Specify an alternate location
for the exports file.
.El
.Pp
When
.Nm
is started,
it loads the export host addresses and options into the kernel
using the
.Xr mount 2
system call.
After changing the exports file,
a hangup signal should be sent to the
.Nm
daemon
to get it to reload the export information.
After sending the SIGHUP
(kill \-s HUP `cat /var/run/mountd.pid`),
check the syslog output to see if
.Nm
logged any parsing
errors in the exports file.
.Pp
If
.Nm
detects that the running kernel does not include
.Tn NFS
support, it will attempt to load a loadable kernel module containing
.Tn NFS
code, using
.Xr kldload 8
by way of
.Xr vfsload 3 .
If this fails, or no
.Tn NFS
KLD was available,
.Nm
exits with an error.
.Sh FILES
.Bl -tag -width /var/run/mountd.pid -compact
.It Pa /etc/exports
the list of exported filesystems
.It Pa /var/run/mountd.pid
the pid of the currently running mountd
.It Pa /var/db/mountdtab
the current list of remote mounted filesystems
.El
.Sh SEE ALSO
.Xr nfsstat 1 ,
.Xr exports 5 ,
.Xr kldload 8 ,
.Xr nfsd 8 ,
.Xr rpcbind 8 ,
.Xr showmount 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Bx 4.4 .

File diff suppressed because it is too large Load Diff

View File

@ -1,194 +0,0 @@
.\" Copyright (c) 1992, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)netgroup.5 8.2 (Berkeley) 12/11/93
.\" $FreeBSD$
.\"
.Dd December 11, 1993
.Dt NETGROUP 5
.Os
.Sh NAME
.Nm netgroup
.Nd defines network groups
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
The
.Nm
file
specifies ``netgroups'', which are sets of
.Sy (host, user, domain)
tuples that are to be given similar network access.
.Pp
Each line in the file
consists of a netgroup name followed by a list of the members of the
netgroup.
Each member can be either the name of another netgroup or a specification
of a tuple as follows:
.Bd -literal -offset indent
(host, user, domain)
.Ed
.Pp
where the
.Sy host ,
.Sy user ,
and
.Sy domain
are character string names for the corresponding component.
Any of the comma separated fields may be empty to specify a ``wildcard'' value
or may consist of the string ``-'' to specify ``no valid value''.
The members of the list may be separated by whitespace and/or commas;
the ``\e'' character may be used at the end of a line to specify
line continuation.
Lines are limited to 1024 characters.
The functions specified in
.Xr getnetgrent 3
should normally be used to access the
.Nm
database.
.Pp
Lines that begin with a # are treated as comments.
.Sh NIS/YP INTERACTION
On most other platforms,
.Nm Ns s
are only used in conjunction with
.Tn NIS
and local
.Pa /etc/netgroup
files are ignored.
With
.Fx ,
.Nm Ns s
can be used with either
.Tn NIS
or local files, but there are certain
caveats to consider.
The existing
.Nm
system is extremely inefficient where
.Fn innetgr 3
lookups are concerned since
.Nm
memberships are computed on the fly.
By contrast, the
.Tn NIS
.Nm
database consists of three separate maps (netgroup, netgroup.byuser
and netgroup.byhost) that are keyed to allow
.Fn innetgr 3
lookups to be done quickly.
The
.Fx
.Nm
system can interact with the
.Tn NIS
.Nm
maps in the following ways:
.Bl -bullet -offset indent
.It
If the
.Pa /etc/netgroup
file does not exist, or it exists and is empty, or
it exists and contains only a
.Sq + ,
and
.Tn NIS
is running,
.Nm
lookups will be done exclusively through
.Tn NIS ,
with
.Fn innetgr 3
taking advantage of the netgroup.byuser and
netgroup.byhost maps to speed up searches.
(This
is more or less compatible with the behavior of SunOS and
similar platforms.)
.It
If the
.Pa /etc/netgroup
exists and contains only local
.Nm
information (with no
.Tn NIS
.Sq +
token), then only the local
.Nm
information will be processed (and
.Tn NIS
will be ignored).
.It
If
.Pa /etc/netgroup
exists and contains both local netgroup data
.Pa and
the
.Tn NIS
.Sq +
token, the local data and the
.Tn NIS
netgroup
map will be processed as a single combined
.Nm
database.
While this configuration is the most flexible, it
is also the least efficient: in particular,
.Fn innetgr 3
lookups will be especially slow if the
database is large.
.El
.Sh FILES
.Bl -tag -width /etc/netgroup -compact
.It Pa /etc/netgroup
the netgroup database
.El
.Sh SEE ALSO
.Xr getnetgrent 3 ,
.Xr exports 5
.Sh COMPATIBILITY
The file format is compatible with that of various vendors, however it
appears that not all vendors use an identical format.
.Sh BUGS
The interpretation of access restrictions based on the member tuples of a
netgroup is left up to the various network applications.
Also, it is not obvious how the domain specification
applies to the
.Bx
environment.
.Pp
The
.Nm
database should be stored in the form of a
hashed
.Xr db 3
database just like the
.Xr passwd 5
database to speed up reverse lookups.

View File

@ -1,39 +0,0 @@
/*
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)pathnames.h 8.1 (Berkeley) 6/5/93
*/
#include <paths.h>
#define _PATH_EXPORTS "/etc/exports"
#define _PATH_RMOUNTLIST "/var/db/mountdtab"
#define _PATH_MOUNTDPID "/var/run/mountd.pid"

View File

@ -1,8 +0,0 @@
# @(#)Makefile 8.1 (Berkeley) 6/5/93
# $FreeBSD$
PROG= nfsd
WARNS= 0
MAN= nfsd.8
.include <bsd.prog.mk>

View File

@ -1,191 +0,0 @@
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the University of
.\" California, Berkeley and its contributors.
.\" 4. Neither the name of the University nor the names of its contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.\" @(#)nfsd.8 8.4 (Berkeley) 3/29/95
.\" $FreeBSD$
.\"
.Dd March 29, 1995
.Dt NFSD 8
.Os
.Sh NAME
.Nm nfsd
.Nd remote
.Tn NFS
server
.Sh SYNOPSIS
.Nm
.Op Fl ardut
.Op Fl n Ar num_servers
.Op Fl h Ar bindip
.Sh DESCRIPTION
The
.Nm
utility runs on a server machine to service
.Tn NFS
requests from client machines.
At least one
.Nm
must be running for a machine to operate as a server.
.Pp
Unless otherwise specified, four servers for
.Tn UDP
transport are started.
.Pp
The following options are available:
.Bl -tag -width Ds
.It Fl r
Register the
.Tn NFS
service with
.Xr rpcbind 8
without creating any servers.
This option can be used along with the
.Fl u
or
.Fl t
options to re-register NFS if the rpcbind server is restarted.
.It Fl d
Unregister the
.Tn NFS
service with
.Xr rpcbind 8
without creating any servers.
.It Fl n
Specifies how many servers to create.
.It Fl h Ar bindip
Specifies which IP address or hostname to bind to on the local host.
This option is recommended when a host has multiple interfaces.
Multiple
.Fl h
options may be specified.
.It Fl a
Specifies that nfsd should bind to the wildcard IP address.
This is the default if no
.Fl h
options are given. It may also be specified in addition to any
.Fl h
options given. Note that NFS/UDP does not operate properly when
bound to the wildcard IP address whether you use -a or do not use -h.
.It Fl t
Serve
.Tn TCP NFS
clients.
.It Fl u
Serve
.Tn UDP NFS
clients.
.El
.Pp
For example,
.Dq Li "nfsd -u -t -n 6"
serves
.Tn UDP
and
.Tn TCP
transports using six daemons.
.Pp
A server should run enough daemons to handle
the maximum level of concurrency from its clients,
typically four to six.
.Pp
The
.Nm
utility listens for service requests at the port indicated in the
.Tn NFS
server specification; see
.%T "Network File System Protocol Specification" ,
RFC1094 and
.%T "NFS: Network File System Version 3 Protocol Specification" .
.Pp
If
.Nm
detects that
.Tn NFS
is not loaded in the running kernel, it will attempt
to load a loadable kernel module containing
.Tn NFS
support using
.Xr kldload 8
by way of
.Xr vfsload 3 .
If this fails, or no
.Tn NFS
KLD is available,
.Nm
will exit with an error.
.Pp
If
.Nm
is to be run on a host with multiple interfaces or interface aliases, use
of the
.Fl h
option is recommended. If you do not use the option NFS may not respond to
UDP packets from the same IP address they were sent to. Use of this option
is also recommended when securing NFS exports on a firewalling machine such
that the NFS sockets can only be accessed by the inside interface.
The
.Nm ipfw
utility
would then be used to block nfs-related packets that come in on the outside
interface.
.Pp
The
.Nm
utility has to be terminated with
.Dv SIGUSR1
and cannot be killed with
.Dv SIGTERM
or
.Dv SIGQUIT .
The
.Nm
utility needs to ignore these signals in order to stay alive as long
as possible during a shutdown, otherwise loopback mounts will
not be able to unmount.
If you have to kill
.Nm
just do a
.Dq Li "kill -USR1 <PID of master nfsd>"
.Sh DIAGNOSTICS
.Ex -std
.Sh SEE ALSO
.Xr nfsstat 1 ,
.Xr nfssvc 2 ,
.Xr ipfw 8 ,
.Xr kldload 8 ,
.Xr mountd 8 ,
.Xr nfsiod 8 ,
.Xr rpcbind 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Bx 4.4 .

View File

@ -1,845 +0,0 @@
/*
* Copyright (c) 1989, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Rick Macklem at The University of Guelph.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1989, 1993, 1994\n\
The Regents of the University of California. All rights reserved.\n";
#endif /* not lint */
#ifndef lint
#if 0
static char sccsid[] = "@(#)nfsd.c 8.9 (Berkeley) 3/29/95";
#endif
static const char rcsid[] =
"$FreeBSD$";
#endif /* not lint */
#include <sys/param.h>
#include <sys/syslog.h>
#include <sys/wait.h>
#include <sys/mount.h>
#include <sys/linker.h>
#include <sys/module.h>
#include <rpc/rpc.h>
#include <rpc/pmap_clnt.h>
#include <netdb.h>
#include <arpa/inet.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
#include <nfsserver/nfs.h>
#include <err.h>
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netdb.h>
/* Global defs */
#ifdef DEBUG
#define syslog(e, s...) fprintf(stderr,s)
int debug = 1;
#else
int debug = 0;
#endif
struct nfsd_srvargs nsd;
#define MAXNFSDCNT 20
#define DEFNFSDCNT 4
pid_t children[MAXNFSDCNT]; /* PIDs of children */
int nfsdcnt; /* number of children */
void cleanup(int);
void child_cleanup(int);
void killchildren(void);
void nfsd_exit(int);
void nonfs(int);
void reapchild(int);
int setbindhost(struct addrinfo **ia, const char *bindhost,
struct addrinfo hints);
void start_server(int);
void unregistration(void);
void usage(void);
/*
* Nfs server daemon mostly just a user context for nfssvc()
*
* 1 - do file descriptor and signal cleanup
* 2 - fork the nfsd(s)
* 3 - create server socket(s)
* 4 - register socket with rpcbind
*
* For connectionless protocols, just pass the socket into the kernel via.
* nfssvc().
* For connection based sockets, loop doing accepts. When you get a new
* socket from accept, pass the msgsock into the kernel via. nfssvc().
* The arguments are:
* -r - reregister with rpcbind
* -d - unregister with rpcbind
* -t - support tcp nfs clients
* -u - support udp nfs clients
* followed by "n" which is the number of nfsds' to fork off
*/
int
main(argc, argv, envp)
int argc;
char *argv[], *envp[];
{
struct nfsd_args nfsdargs;
struct addrinfo *ai_udp, *ai_tcp, *ai_udp6, *ai_tcp6, hints;
struct netconfig *nconf_udp, *nconf_tcp, *nconf_udp6, *nconf_tcp6;
struct netbuf nb_udp, nb_tcp, nb_udp6, nb_tcp6;
struct sockaddr_in inetpeer;
struct sockaddr_in6 inet6peer;
fd_set ready, sockbits;
fd_set v4bits, v6bits;
int ch, connect_type_cnt, i, len, maxsock, msgsock;
int on = 1, unregister, reregister, sock;
int tcp6sock, ip6flag, tcpflag, tcpsock;
int udpflag, ecode, s, srvcnt;
int bindhostc, bindanyflag, rpcbreg, rpcbregcnt;
char **bindhost = NULL;
pid_t pid;
if (modfind("nfsserver") < 0) {
/* Not present in kernel, try loading it */
if (kldload("nfsserver") < 0 || modfind("nfsserver") < 0)
errx(1, "NFS server is not available");
}
nfsdcnt = DEFNFSDCNT;
unregister = reregister = tcpflag = maxsock = 0;
bindanyflag = udpflag = connect_type_cnt = bindhostc = 0;
#define GETOPT "ah:n:rdtu"
#define USAGE "[-ardtu] [-n num_servers] [-h bindip]"
while ((ch = getopt(argc, argv, GETOPT)) != -1)
switch (ch) {
case 'a':
bindanyflag = 1;
break;
case 'n':
nfsdcnt = atoi(optarg);
if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
warnx("nfsd count %d; reset to %d", nfsdcnt,
DEFNFSDCNT);
nfsdcnt = DEFNFSDCNT;
}
break;
case 'h':
bindhostc++;
bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
if (bindhost == NULL)
errx(1, "Out of memory");
bindhost[bindhostc-1] = strdup(optarg);
if (bindhost[bindhostc-1] == NULL)
errx(1, "Out of memory");
break;
case 'r':
reregister = 1;
break;
case 'd':
unregister = 1;
break;
case 't':
tcpflag = 1;
break;
case 'u':
udpflag = 1;
break;
default:
case '?':
usage();
};
if (!tcpflag && !udpflag)
udpflag = 1;
argv += optind;
argc -= optind;
/*
* XXX
* Backward compatibility, trailing number is the count of daemons.
*/
if (argc > 1)
usage();
if (argc == 1) {
nfsdcnt = atoi(argv[0]);
if (nfsdcnt < 1 || nfsdcnt > MAXNFSDCNT) {
warnx("nfsd count %d; reset to %d", nfsdcnt,
DEFNFSDCNT);
nfsdcnt = DEFNFSDCNT;
}
}
ip6flag = 1;
s = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (s == -1) {
if (errno != EPROTONOSUPPORT)
err(1, "socket");
ip6flag = 0;
} else if (getnetconfigent("udp6") == NULL ||
getnetconfigent("tcp6") == NULL) {
ip6flag = 0;
}
if (s != -1)
close(s);
if (bindhostc == 0 || bindanyflag) {
bindhostc++;
bindhost = realloc(bindhost,sizeof(char *)*bindhostc);
if (bindhost == NULL)
errx(1, "Out of memory");
bindhost[bindhostc-1] = strdup("*");
if (bindhost[bindhostc-1] == NULL)
errx(1, "Out of memory");
}
if (unregister) {
unregistration();
exit (0);
}
if (reregister) {
if (udpflag) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
if (ecode != 0)
err(1, "getaddrinfo udp: %s", gai_strerror(ecode));
nconf_udp = getnetconfigent("udp");
if (nconf_udp == NULL)
err(1, "getnetconfigent udp failed");
nb_udp.buf = ai_udp->ai_addr;
nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp)) ||
(!rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)))
err(1, "rpcb_set udp failed");
freeaddrinfo(ai_udp);
}
if (udpflag && ip6flag) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
if (ecode != 0)
err(1, "getaddrinfo udp6: %s", gai_strerror(ecode));
nconf_udp6 = getnetconfigent("udp6");
if (nconf_udp6 == NULL)
err(1, "getnetconfigent udp6 failed");
nb_udp6.buf = ai_udp6->ai_addr;
nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6)) ||
(!rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)))
err(1, "rpcb_set udp6 failed");
freeaddrinfo(ai_udp6);
}
if (tcpflag) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp);
if (ecode != 0)
err(1, "getaddrinfo tcp: %s", gai_strerror(ecode));
nconf_tcp = getnetconfigent("tcp");
if (nconf_tcp == NULL)
err(1, "getnetconfigent tcp failed");
nb_tcp.buf = ai_tcp->ai_addr;
nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp, &nb_tcp)) ||
(!rpcb_set(RPCPROG_NFS, 3, nconf_tcp, &nb_tcp)))
err(1, "rpcb_set tcp failed");
freeaddrinfo(ai_tcp);
}
if (tcpflag && ip6flag) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
if (ecode != 0)
err(1, "getaddrinfo tcp6: %s", gai_strerror(ecode));
nconf_tcp6 = getnetconfigent("tcp6");
if (nconf_tcp6 == NULL)
err(1, "getnetconfigent tcp6 failed");
nb_tcp6.buf = ai_tcp6->ai_addr;
nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6)) ||
(!rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6)))
err(1, "rpcb_set tcp6 failed");
freeaddrinfo(ai_tcp6);
}
exit (0);
}
if (debug == 0) {
daemon(0, 0);
(void)signal(SIGHUP, SIG_IGN);
(void)signal(SIGINT, SIG_IGN);
/*
* nfsd sits in the kernel most of the time. It needs
* to ignore SIGTERM/SIGQUIT in order to stay alive as long
* as possible during a shutdown, otherwise loopback
* mounts will not be able to unmount.
*/
(void)signal(SIGTERM, SIG_IGN);
(void)signal(SIGQUIT, SIG_IGN);
}
(void)signal(SIGSYS, nonfs);
(void)signal(SIGCHLD, reapchild);
openlog("nfsd", LOG_PID, LOG_DAEMON);
/* If we use UDP only, we start the last server below. */
srvcnt = tcpflag ? nfsdcnt : nfsdcnt - 1;
for (i = 0; i < srvcnt; i++) {
switch ((pid = fork())) {
case -1:
syslog(LOG_ERR, "fork: %m");
nfsd_exit(1);
case 0:
break;
default:
children[i] = pid;
continue;
}
(void)signal(SIGUSR1, child_cleanup);
setproctitle("server");
start_server(0);
}
(void)signal(SIGUSR1, cleanup);
FD_ZERO(&v4bits);
FD_ZERO(&v6bits);
rpcbregcnt = 0;
/* Set up the socket for udp and rpcb register it. */
if (udpflag) {
rpcbreg = 0;
for (i = 0; i < bindhostc; i++) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
if (setbindhost(&ai_udp, bindhost[i], hints) == 0) {
rpcbreg = 1;
rpcbregcnt++;
if ((sock = socket(ai_udp->ai_family,
ai_udp->ai_socktype,
ai_udp->ai_protocol)) < 0) {
syslog(LOG_ERR,
"can't create udp socket");
nfsd_exit(1);
}
if (bind(sock, ai_udp->ai_addr,
ai_udp->ai_addrlen) < 0) {
syslog(LOG_ERR,
"can't bind udp addr %s: %m",
bindhost[i]);
nfsd_exit(1);
}
freeaddrinfo(ai_udp);
nfsdargs.sock = sock;
nfsdargs.name = NULL;
nfsdargs.namelen = 0;
if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
syslog(LOG_ERR, "can't Add UDP socket");
nfsd_exit(1);
}
(void)close(sock);
}
}
if (rpcbreg == 1) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp);
if (ecode != 0) {
syslog(LOG_ERR, "getaddrinfo udp: %s",
gai_strerror(ecode));
nfsd_exit(1);
}
nconf_udp = getnetconfigent("udp");
if (nconf_udp == NULL)
err(1, "getnetconfigent udp failed");
nb_udp.buf = ai_udp->ai_addr;
nb_udp.len = nb_udp.maxlen = ai_udp->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp, &nb_udp)) ||
(!rpcb_set(RPCPROG_NFS, 3, nconf_udp, &nb_udp)))
err(1, "rpcb_set udp failed");
freeaddrinfo(ai_udp);
}
}
/* Set up the socket for udp6 and rpcb register it. */
if (udpflag && ip6flag) {
rpcbreg = 0;
for (i = 0; i < bindhostc; i++) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
if (setbindhost(&ai_udp6, bindhost[i], hints) == 0) {
rpcbreg = 1;
rpcbregcnt++;
if ((sock = socket(ai_udp6->ai_family,
ai_udp6->ai_socktype,
ai_udp6->ai_protocol)) < 0) {
syslog(LOG_ERR,
"can't create udp6 socket");
nfsd_exit(1);
}
if (setsockopt(sock, IPPROTO_IPV6,
IPV6_BINDV6ONLY,
&on, sizeof on) < 0) {
syslog(LOG_ERR,
"can't set v6-only binding for "
"udp6 socket: %m");
nfsd_exit(1);
}
if (bind(sock, ai_udp6->ai_addr,
ai_udp6->ai_addrlen) < 0) {
syslog(LOG_ERR,
"can't bind udp6 addr %s: %m",
bindhost[i]);
nfsd_exit(1);
}
freeaddrinfo(ai_udp6);
nfsdargs.sock = sock;
nfsdargs.name = NULL;
nfsdargs.namelen = 0;
if (nfssvc(NFSSVC_ADDSOCK, &nfsdargs) < 0) {
syslog(LOG_ERR,
"can't add UDP6 socket");
nfsd_exit(1);
}
(void)close(sock);
}
}
if (rpcbreg == 1) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_udp6);
if (ecode != 0) {
syslog(LOG_ERR, "getaddrinfo udp6: %s",
gai_strerror(ecode));
nfsd_exit(1);
}
nconf_udp6 = getnetconfigent("udp6");
if (nconf_udp6 == NULL)
err(1, "getnetconfigent udp6 failed");
nb_udp6.buf = ai_udp6->ai_addr;
nb_udp6.len = nb_udp6.maxlen = ai_udp6->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_udp6, &nb_udp6)) ||
(!rpcb_set(RPCPROG_NFS, 3, nconf_udp6, &nb_udp6)))
err(1, "rpcb_set udp6 failed");
freeaddrinfo(ai_udp6);
}
}
/* Set up the socket for tcp and rpcb register it. */
if (tcpflag) {
rpcbreg = 0;
for (i = 0; i < bindhostc; i++) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (setbindhost(&ai_tcp, bindhost[i], hints) == 0) {
rpcbreg = 1;
rpcbregcnt++;
if ((tcpsock = socket(AF_INET, SOCK_STREAM,
0)) < 0) {
syslog(LOG_ERR,
"can't create tpc socket");
nfsd_exit(1);
}
if (setsockopt(tcpsock, SOL_SOCKET,
SO_REUSEADDR,
(char *)&on, sizeof(on)) < 0)
syslog(LOG_ERR,
"setsockopt SO_REUSEADDR: %m");
if (bind(tcpsock, ai_tcp->ai_addr,
ai_tcp->ai_addrlen) < 0) {
syslog(LOG_ERR,
"can't bind tcp addr %s: %m",
bindhost[i]);
nfsd_exit(1);
}
if (listen(tcpsock, 5) < 0) {
syslog(LOG_ERR, "listen failed");
nfsd_exit(1);
}
freeaddrinfo(ai_tcp);
FD_SET(tcpsock, &sockbits);
FD_SET(tcpsock, &v4bits);
maxsock = tcpsock;
connect_type_cnt++;
}
}
if (rpcbreg == 1) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
ecode = getaddrinfo(NULL, "nfs", &hints,
&ai_tcp);
if (ecode != 0) {
syslog(LOG_ERR, "getaddrinfo tcp: %s",
gai_strerror(ecode));
nfsd_exit(1);
}
nconf_tcp = getnetconfigent("tcp");
if (nconf_tcp == NULL)
err(1, "getnetconfigent tcp failed");
nb_tcp.buf = ai_tcp->ai_addr;
nb_tcp.len = nb_tcp.maxlen = ai_tcp->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp,
&nb_tcp)) || (!rpcb_set(RPCPROG_NFS, 3,
nconf_tcp, &nb_tcp)))
err(1, "rpcb_set tcp failed");
freeaddrinfo(ai_tcp);
}
}
/* Set up the socket for tcp6 and rpcb register it. */
if (tcpflag && ip6flag) {
rpcbreg = 0;
for (i = 0; i < bindhostc; i++) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (setbindhost(&ai_tcp6, bindhost[i], hints) == 0) {
rpcbreg = 1;
rpcbregcnt++;
if ((tcp6sock = socket(ai_tcp6->ai_family,
ai_tcp6->ai_socktype,
ai_tcp6->ai_protocol)) < 0) {
syslog(LOG_ERR,
"can't create tcp6 socket");
nfsd_exit(1);
}
if (setsockopt(tcp6sock, SOL_SOCKET,
SO_REUSEADDR,
(char *)&on, sizeof(on)) < 0)
syslog(LOG_ERR,
"setsockopt SO_REUSEADDR: %m");
if (setsockopt(tcp6sock, IPPROTO_IPV6,
IPV6_BINDV6ONLY, &on, sizeof on) < 0) {
syslog(LOG_ERR,
"can't set v6-only binding for tcp6 "
"socket: %m");
nfsd_exit(1);
}
if (bind(tcp6sock, ai_tcp6->ai_addr,
ai_tcp6->ai_addrlen) < 0) {
syslog(LOG_ERR,
"can't bind tcp6 addr %s: %m",
bindhost[i]);
nfsd_exit(1);
}
if (listen(tcp6sock, 5) < 0) {
syslog(LOG_ERR, "listen failed");
nfsd_exit(1);
}
freeaddrinfo(ai_tcp6);
FD_SET(tcp6sock, &sockbits);
FD_SET(tcp6sock, &v6bits);
if (maxsock < tcp6sock)
maxsock = tcp6sock;
connect_type_cnt++;
}
}
if (rpcbreg == 1) {
memset(&hints, 0, sizeof hints);
hints.ai_flags = AI_PASSIVE;
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
ecode = getaddrinfo(NULL, "nfs", &hints, &ai_tcp6);
if (ecode != 0) {
syslog(LOG_ERR, "getaddrinfo tcp6: %s",
gai_strerror(ecode));
nfsd_exit(1);
}
nconf_tcp6 = getnetconfigent("tcp6");
if (nconf_tcp6 == NULL)
err(1, "getnetconfigent tcp6 failed");
nb_tcp6.buf = ai_tcp6->ai_addr;
nb_tcp6.len = nb_tcp6.maxlen = ai_tcp6->ai_addrlen;
if ((!rpcb_set(RPCPROG_NFS, 2, nconf_tcp6, &nb_tcp6)) ||
(!rpcb_set(RPCPROG_NFS, 3, nconf_tcp6, &nb_tcp6)))
err(1, "rpcb_set tcp6 failed");
freeaddrinfo(ai_tcp6);
}
}
if (rpcbregcnt == 0) {
syslog(LOG_ERR, "rpcb_set() failed, nothing to do: %m");
nfsd_exit(1);
}
if (tcpflag && connect_type_cnt == 0) {
syslog(LOG_ERR, "tcp connects == 0, nothing to do: %m");
nfsd_exit(1);
}
setproctitle("master");
/*
* We always want a master to have a clean way to to shut nfsd down
* (with unregistration): if the master is killed, it unregisters and
* kills all children. If we run for UDP only (and so do not have to
* loop waiting waiting for accept), we instead make the parent
* a "server" too. start_server will not return.
*/
if (!tcpflag)
start_server(1);
/*
* Loop forever accepting connections and passing the sockets
* into the kernel for the mounts.
*/
for (;;) {
ready = sockbits;
if (connect_type_cnt > 1) {
if (select(maxsock + 1,
&ready, NULL, NULL, NULL) < 1) {
syslog(LOG_ERR, "select failed: %m");
nfsd_exit(1);
}
}
for (tcpsock = 0; tcpsock <= maxsock; tcpsock++) {
if (FD_ISSET(tcpsock, &ready)) {
if (FD_ISSET(tcpsock, &v4bits)) {
len = sizeof(inetpeer);
if ((msgsock = accept(tcpsock,
(struct sockaddr *)&inetpeer, &len)) < 0) {
syslog(LOG_ERR, "accept failed: %m");
nfsd_exit(1);
}
memset(inetpeer.sin_zero, 0,
sizeof(inetpeer.sin_zero));
if (setsockopt(msgsock, SOL_SOCKET,
SO_KEEPALIVE, (char *)&on, sizeof(on)) < 0)
syslog(LOG_ERR,
"setsockopt SO_KEEPALIVE: %m");
nfsdargs.sock = msgsock;
nfsdargs.name = (caddr_t)&inetpeer;
nfsdargs.namelen = len;
nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
(void)close(msgsock);
} else if (FD_ISSET(tcpsock, &v6bits)) {
len = sizeof(inet6peer);
if ((msgsock = accept(tcpsock,
(struct sockaddr *)&inet6peer,
&len)) < 0) {
syslog(LOG_ERR,
"accept failed: %m");
nfsd_exit(1);
}
if (setsockopt(msgsock, SOL_SOCKET,
SO_KEEPALIVE, (char *)&on,
sizeof(on)) < 0)
syslog(LOG_ERR, "setsockopt "
"SO_KEEPALIVE: %m");
nfsdargs.sock = msgsock;
nfsdargs.name = (caddr_t)&inet6peer;
nfsdargs.namelen = len;
nfssvc(NFSSVC_ADDSOCK, &nfsdargs);
(void)close(msgsock);
}
}
}
}
}
int
setbindhost(struct addrinfo **ai, const char *bindhost, struct addrinfo hints)
{
int ecode;
u_int32_t host_addr[4]; /* IPv4 or IPv6 */
const char *hostptr;
if (bindhost == NULL || strcmp("*", bindhost) == 0)
hostptr = NULL;
else
hostptr = bindhost;
if (hostptr != NULL) {
switch (hints.ai_family) {
case AF_INET:
if (inet_pton(AF_INET, hostptr, host_addr) == 1) {
hints.ai_flags = AI_NUMERICHOST;
} else {
if (inet_pton(AF_INET6, hostptr,
host_addr) == 1)
return (1);
}
break;
case AF_INET6:
if (inet_pton(AF_INET6, hostptr, host_addr) == 1) {
hints.ai_flags = AI_NUMERICHOST;
} else {
if (inet_pton(AF_INET, hostptr,
host_addr) == 1)
return (1);
}
break;
default:
break;
}
}
ecode = getaddrinfo(hostptr, "nfs", &hints, ai);
if (ecode != 0) {
syslog(LOG_ERR, "getaddrinfo %s: %s", bindhost,
gai_strerror(ecode));
return (1);
}
return (0);
}
void
usage()
{
(void)fprintf(stderr, "usage: nfsd %s\n", USAGE);
exit(1);
}
void
nonfs(signo)
int signo;
{
syslog(LOG_ERR, "missing system call: NFS not available");
}
void
reapchild(signo)
int signo;
{
pid_t pid;
int i;
while ((pid = wait3(NULL, WNOHANG, NULL)) > 0) {
for (i = 0; i < nfsdcnt; i++)
if (pid == children[i])
children[i] = -1;
}
}
void
unregistration()
{
if ((!rpcb_unset(RPCPROG_NFS, 2, NULL)) ||
(!rpcb_unset(RPCPROG_NFS, 3, NULL)))
syslog(LOG_ERR, "rpcb_unset failed");
}
void
killchildren()
{
int i;
for (i = 0; i < nfsdcnt; i++) {
if (children[i] > 0)
kill(children[i], SIGKILL);
}
}
/*
* Cleanup master after SIGUSR1.
*/
void
cleanup(signo)
{
nfsd_exit(0);
}
/*
* Cleanup child after SIGUSR1.
*/
void
child_cleanup(signo)
{
exit(0);
}
void
nfsd_exit(int status)
{
killchildren();
unregistration();
exit(status);
}
void
start_server(int master)
{
int status;
status = 0;
nsd.nsd_nfsd = NULL;
if (nfssvc(NFSSVC_NFSD, &nsd) < 0) {
syslog(LOG_ERR, "nfssvc: %m");
status = 1;
}
if (master)
nfsd_exit(status);
else
exit(status);
}