| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
After glibc 2.3.3, getifaddrs(3) can return AF_INET6 addresses for
local network interfaces. Using the library call is easier than
trying to update the open code in from_local(), and means we have
less to maintain in nfs-utils going forward.
And, since from_local() can now support IPv6, change its synopsis to
take a "struct sockaddr *" .
Note that the original code discovers local addresses once. These
days, with wifi, DHCP, and NetworkManager, the local network
configuration can change dynamically over time. So, call getifaddrs()
more often to ensure from_local() has up-to-date network configuration
information.
This implementation refreshes the list if from_local() has not been
called in the last second. This is actually not terribly honerous.
check_default() invokes from_local() only when the remote host is not
in its access cache, or the access/deny files have changed.
So new hosts will cause a refresh, but previously seen hosts
(including localhost) should not.
On the other hand, it still may not be often enough. After the first
call, if only previously seen hosts attempt to access our daemons,
from_local() would never be called, and the local list would never be
updated. This might be possible during steady-state operation with
a small number of servers and clients.
It would also be nice if we could free the local interface address
list at shutdown time, but that would be a lot of trouble for little
gain.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Clean up: Replace calls to syslog(2) and perror(3) in from_local.c
with calls to xlog(). The problems displayed by the perror(3) calls
especially should be reported. Currently they are never seen in the
system log.
As part of a build test, I defined TEST, and found a couple of
problems with main(), which are also addressed in this patch.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
| |
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Expand and clarify the explanation of NSM operation on Linux, and
provide the same text in both man pages.
Update descriptions of the command line options to match the operation
of the current implementation.
Introduce sections discussing security and operational issues, and
IPv6 operation.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If TI-RPC is available, use it to create statd's svc listener. If
not, use the old function, rpc_init(), to create statd's listener.
IPv6 can be supported if TI-RPC is available. In this case,
/etc/netconfig is searched to determine which transports to advertise.
Add the new listener creation API in libnfs.a since other components
of nfs-utils (such as rpc.mountd) will eventually want to share it.
A little re-arrangement of when the statd listener is created is done
to make unregistration of the statd service more reliable. As it is
now, the statd service is never unregistered when it exits. After it
is gone, other programs usually hang when trying to access statd or
see if it's running, since the registration is still there but statd
itself does not respond.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
I'm about to switch the order of listener creation and dropping root
privileges. rpc.statd will drop privileges first, then create its
listeners. The reason for the new ordering is explained in a
subsequent patch.
However, for non-TI-RPC builds, rpc_init() needs to use a privileged
port to do pmap registrations. For both TI-RPC and non-TI-RPC builds,
CAP_NET_BIND is required in case the admin requests a privileged
listener port on the statd command line.
So that these requirements are met, nsm_drop_privileges() will now
retain CAP_NET_BIND while dropping root.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Clean up: The contents of NL_ADDR are fixed: they are always the IPv4
loopback address. Some time ago, the use of NL_ADDR() was stubbed out
of the NLM downcall forward path, replaced with a constant IPv4
loopback address.
Stub it out of the reply path as well, and then remove NL_ADDR
entirely.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
| |
SM_STAT is usually not used by most contemporary NSM implementations,
but for consistency, it gets the same treatment as sm_mon_1_svc(),
since both should use the same logic to determine whether a mon_name
is able to be monitored.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
| |
Replace deprecated gethostbyname(3) and gethostbyaddr(3) calls in
monitor.c, and address a couple of memory leaks.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
| |
Provide a shared function to generate canonical names that statd
uses to index its on-disk monitor list. This function can resolve
DNS hostnames, and IPv4 and IPv6 presentation addresses.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To support IPv6, statd must support multi-homed remote peers. For our
purposes, "multi-homed peer" means that more than one unique IP
address maps to the one canonical host name for that peer.
An SM_MON request from the local lockd has a "mon_name" argument that
statd reverse maps to a canonical hostname (ie the A record for that
host). statd assumes the canonical hostname is unique enough that
it stores the callback data for this mon_name in a file named after
that canonical hostname.
Because lockd can't distinguish between two unique IP addresses that
may be from the same physical host, the kernel can hand statd a
mon_name that maps to the same canonical hostname as some previous
mon_name. So that the kernel can keep this instance of the mon_name
unique, it creates a fresh priv cookie for each new address.
Note that a mon_name can be a presentation address string, or the
caller_name string sent in each NLMPROC_LOCK request. There's
nothing that requires the caller_name to be a fully-qualified
hostname, thus it's uniqueness is not guaranteed. The current
design of statd assumes that canonical hostnames will be unique
enough.
When a mon_name for a fresh SM_MON request maps to the same canonical
hostname as an existing monitored peer, but the priv cookie is new,
statd will try to write the information for the fresh request into an
existing monitor record file, wiping out the contents of the file.
This is because the mon_name/cookie combination won't match any record
statd already has.
Currently, statd doesn't check if a record file already exists before
writing into it. statd's logic assumes that the svc routine has
already checked that no matching record exists in the in-core monitor
list. And, it doesn't use O_EXCL when opening the record file. Not
only is the old data in that file wiped out, but statd's in-core
monitor list will no longer match what's in the on-disk monitor list.
Note that IPv6 isn't needed to exercise multi-homed peer support.
Any IPv4 peer that has multiple addresses that map to its canonical
hostname will trigger this behavior. However, this scenario will
become quite common when all hosts on a network automatically get both
an IPv4 address and an IPv6 address.
I can think of a few ways to address this:
1. Replace the current on-disk format with a database that has a
uniqueness constraint on the monitor records
2. Create a new file naming scheme; eg. one that uses a truly
unique name such as a hash generated from the mon_name, my_name, and
priv cookie
3. Support multiple lines in each monitor record file
Since statd's on-disk format constitutes a formal API, options 1 and 2
are right out. This patch implements option 3. There are two parts:
adding a new line to an existing file; and deleting a line from a file
with more than one line. Interestingly, the existing code already
supports reading more than one line from these files, so we don't need
to add extra code here to do that.
One file may contain a line for every unique mon_name / priv cookie
where the mon_name reverse maps to the same canonical hostname. We
use the atomic write facility added by a previous patch to ensure the
on-disk monitor record list is updated atomically.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
We're about to use the same logic (mktemp, write, rename) for
other new purposes, so pull it out into its own function.
This change also addresses a latent bug: O_TRUNC is now used when
creating the temporary file. This eliminates the possibility of
getting stale data in the temp file, if somehow a previous "atomic
write" was interrupted and didn't remove the temporary file.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
| |
Currently sm-notify does not use the mon_name and my_name strings
passed to smn_get_host(). Very soon we're going to need the mon_name
and my_name strings, so add code to store those strings in struct
nsm_host, and free them when each host is forgotten.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
| |
Ensure that SM_SIMU_CRASH does not allow non-AF_INET callers to
bypass the localhost check.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For the time being, statd is not going to support receiving SM_MON
calls from the local lockd via IPv6.
However, the upcalls (SM_MON, etc.) from the local lockd arrive on the
same socket that receives calls from remote peers. Thus
caller_is_localhost() at least has to be smart enough to notice that
the caller is not AF_INET, and to display non-AF_INET addresses
appropriately.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
| |
We have all the pieces in place, so update sm_notify_1_svc() to handle
SM_NOTIFY requests sent from IPv6 remotes.
This also eliminates a memory leak: the strdup'd memory containing the
callers' presentation address was never freed.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Add an API to convert a socket address to a presentation address
string. This is used for displaying error messages and the like.
We prefer getnameinfo(3) over inet_?to?(3) as it supports IPv6 scope
IDs. Since statd has to continue to build correctly on systems whose
glibc does not have getnameinfo(3), an inet_?to?(3) version is also
provided.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
For the near future, statd will support IPv6 but exportfs will not.
Thus statd will need a version of matchhostname() that can deal
properly with IPv6 remotes. To reduce the risk of breaking exportfs,
introduce a separate version of matchhostname() for statd to use while
exportfs continues to use the existing AF_INET-only implementation.
Note that statd will never send matchhostname() a hostname string
containing export wildcards, so is_hostame() is not needed in the
statd version of matchhostname(). This saves some computational
expense when comparing hostnames.
A separate statd-specific implementation of matchhostname() allows
some flexibility in the long term, as well. We might want to enrich
the matching heuristics of our SM_NOTIFY, for example, or replace
them entirely with a heuristic that is not dependent upon DNS.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Introduce generic helpers for managing socket addresses. These are
general enough that they are useful for pretty much any component of
nfs-utils.
We also include the definition of nfs_sockaddr here, so it can be
shared. See:
https://bugzilla.redhat.com/show_bug.cgi?id=448743
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
| |
When IPV6_SUPPORTED is enabled and the local system has IPv6 support,
request AF_INET6 and AF_INET addresses from the DNS resolver.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
This patch updates the "bind to a user-specified port" arm of
smn_create_socket() so it can deal with IPv6 bind addresses.
A single getaddrinfo(3) call can convert a user-specified bind address
or hostname to a socket address, optionally plant a provided port
number, or whip up an appropriate wildcard address for use as the main
socket's bind address.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
| |
This patch updates the "bind to an arbitrary privileged port" arm of
smn_create_socket() so it can deal with IPv6 bind addresses.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Socket creation is unfortunately complicated by the need to handle the
case where sm-notify is built with IPv6 support, but the local system
has disabled it entirely at run-time (ie, socket(3) returns
EAFNOSUPPORT when we try to create an AF_INET6 socket).
The run-time address family setting is made available in the global
variable nsm_family. This setting can control the family of the
socket's bind address and what kind of addresses we want returned by
smn_lookup(). Support for that is added in subsequent patches.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
The top half of the notify() function creates the main socket that
sm-notify uses to do its job. To make adding IPv6 support simpler,
refactor that piece into a separate function.
The logic is modified slightly so that exit(3) is invoked only in
main(). This is not required, but it makes the code slightly easier
to understand and maintain.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
| |
Replace the open code to construct NLM downcalls and PMAP_GETPORT RPC
requests with calls to our new library routines.
This clean up removes redundant code in rmtcall.c, and enables the
possibility of making NLM downcalls via IPv6 transports. We won't
support that for a long while, however.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Replace the open code to construct SM_NOTIFY and PMAP_GETPORT RPC
requests with calls to our new library routines that support
IPv6 and RPCB_GETADDR as well.
This change allows sm-notify to send RPCB_GETADDR, but it won't do
that until the main sm-notify socket supports PF_INET6 and the DNS
resolution logic is updated to return IPv6 addresses.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
To manage concurrency, both statd and sm-notify construct raw RPC
requests in socket buffers, and use a minimal request scheduler
to send these requests and manage replies. Both statd and sm-notify
open code the RPC request construction.
Introduce helper functions that can construct and send raw
NSMPROC_NOTIFY, NLM downcalls, and portmapper calls over a datagram
socket, and receive and parse their replies. Support for IPv6 and
RPCB_GETADDR is featured. This code (and the IPv6 support it
introduces) can now be shared by statd and sm-notify, eliminating
code and bug duplication.
This implementation is based on what's in utils/statd/rmtcall.c now,
but is wrapped up in a nice API and includes extra error checking.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This partially reverts commit ec637de16210c1c6fcb3a0df34d7889592f577dc.
Only NFSv4 clients will actually want to see referall points--others are
better off just seeing an empty directory, that they can manually (or
with automount) mount the appropriate filesystem on.
So we want the kernel to automatically traverse only in the v4 case (as
recent kernels do).
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
We've hidden v4root exports from get_exportlist (hence from the
showmount command), but not from other mountd operations--allowing
clients to attempt to mount exports when they should be getting an
immediate error.
Symptoms observed on a linux client were that a mount that previously
would have returned an error immediately now hung. This restores the
previous behavior.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
|
|
|
|
| |
Move more of v4root_set into a helper function.
Also, check the return value from strdup. (We don't really handle the
error well yet--we'll end up giving negative replies to export upcalls
when we should be giving the kernel exports, resulting in spurious
-ENOENTs or -ESTALE's--but that's better than crashing with a NULL
dereference.)
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
| |
We're adding new entries, but not deleting them, so we don't need to do
the usual double-counter trick here.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Since we're adding new exports as we traverse the export list, it's
possible we may find ourselves revisiting an export we just added. It's
harmless to reprocess those exports, as we're currently doing. But it's
also pointless.
(Actually, the current code appears to always add new export entries at
the head of each list, so we shouldn't hit this case. It still may be a
good idea to keep this check, though, as insulation against future
changes to that data structure.)
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
| |
Only exportfs uses m_mayexport; mountd always populates the export list
with auth_reload(), which always sets m_mayexport on the entries it
creates.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
| |
Common exit code.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
| |
Move newcache case into its own function.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
| |
Break up another big function.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
| |
Consolidate duplicated initialization code.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
| |
Use standard indentation, move warnings to helper function.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
| |
Comment clarification, minor style cleanup.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
|
|
|
|
| |
I needed to understand get_exportlist() recently, and it gave me
trouble.
Move detail work into helper functions to make the basic logic clear,
and to remove need for excessive nesting (and fix inconsistent
indentation levels). Also remove unnecessary casts of void returns from
xmalloc().
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
| |
If a pseudo root is not defined in the export file, the
v4root_needed global variable will be set, signaling
v4root_set() create the dynamic pseudo root.
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
|
|
|
|
|
| |
Don't show pseudo exports when clients ask to see what
is exported via the showmount mount command.
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
If paths A and A/B are both exported, then we have a choice of exports
to return for A (or under A but still above A/B): we could return A
itself, or we could return a V4ROOT export leading to B.
For now, we will always prefer the non-V4ROOT export, whenever that is
an option. This will allow clients to reach A/B as long as
adminstrators keep to the rule that the security on a parent permits the
union of the access permitted on any descendant.
In the future we may support more complicated arrangements.
(Note: this can't be avoided by simply not creating v4root exports with
the same domain and path, because different domains may have some
overlap.)
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
|
| |
Create v4root exports for each directory that is a parent of an explicit
export. Give each the minimal security required to traverse to any of
its children.
Signed-off-by: Steve Dickson <steved@redhat.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
| |
Signed-off-by: Steve Dickson <steved@redhat.com>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Currently,
mount --bind /path /path
where /path is a subdirectory of a crossmnt export, can cause client
hangs, since the kernel detects that as a mountpoint, but nfs-util's
is_mountpoint() function does not.
I don't see any sure-fire way to detect such mountpoints. But that's
OK: it's harmless to allow this upcall to succeed even when the
directory is not a mountpoint, so let's just remove this check.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
| |
More trivial cleanup (no change in functionality) to group logical
operations together into a single function.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
|
|
|
| |
Move this main loop to a separate function, to make it a little easier
to follow the logic of the caller.
Also, instead of waiting till we find an export to do the dns
resolution, do it at the start; it will normally be needed anyway, and
this simplifies the control flow.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
|
|
| |
Query the kernel to ask which flavors vary by pseudoflavor, and use that
instead of a fixed constant. To allow the possibility of more flags
varying by pseudoflavor, use the set/clear_flags functions for all
options instead of setting some by hand.
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|
|
|
|
|
|
|
| |
Move this into a helper function. (We'll be adding a little more code
here.)
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
|