You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
4.4 KiB
129 lines
4.4 KiB
6 years ago
|
diff -up nfs-utils-1.3.0/utils/mount/network.c.orig nfs-utils-1.3.0/utils/mount/network.c
|
||
|
--- nfs-utils-1.3.0/utils/mount/network.c.orig 2018-07-30 14:14:01.242771732 -0400
|
||
|
+++ nfs-utils-1.3.0/utils/mount/network.c 2018-07-30 14:15:36.918075978 -0400
|
||
|
@@ -44,6 +44,8 @@
|
||
|
#include <rpc/rpc.h>
|
||
|
#include <rpc/pmap_prot.h>
|
||
|
#include <rpc/pmap_clnt.h>
|
||
|
+#include <net/if.h>
|
||
|
+#include <ifaddrs.h>
|
||
|
|
||
|
#include "sockaddr.h"
|
||
|
#include "xcommon.h"
|
||
|
@@ -1736,3 +1738,48 @@ int nfs_umount_do_umnt(struct mount_opti
|
||
|
|
||
|
return EX_SUCCESS;
|
||
|
}
|
||
|
+
|
||
|
+int nfs_is_inaddr_any(struct sockaddr *nfs_saddr)
|
||
|
+{
|
||
|
+ switch (nfs_saddr->sa_family) {
|
||
|
+ case AF_INET: {
|
||
|
+ if (((struct sockaddr_in *)nfs_saddr)->sin_addr.s_addr ==
|
||
|
+ INADDR_ANY)
|
||
|
+ return 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ case AF_INET6:
|
||
|
+ if (!memcmp(&((struct sockaddr_in6 *)nfs_saddr)->sin6_addr,
|
||
|
+ &in6addr_any, sizeof(in6addr_any)))
|
||
|
+ return 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
+int nfs_addr_matches_localips(struct sockaddr *nfs_saddr)
|
||
|
+{
|
||
|
+ struct ifaddrs *myaddrs, *ifa;
|
||
|
+ int found = 0;
|
||
|
+
|
||
|
+ /* acquire exiting network interfaces */
|
||
|
+ if (getifaddrs(&myaddrs) != 0)
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ /* interate over the available interfaces and check if we
|
||
|
+ * we find a match to the supplied clientaddr value
|
||
|
+ */
|
||
|
+ for (ifa = myaddrs; ifa != NULL; ifa = ifa->ifa_next) {
|
||
|
+ if (ifa->ifa_addr == NULL)
|
||
|
+ continue;
|
||
|
+ if (!(ifa->ifa_flags & IFF_UP))
|
||
|
+ continue;
|
||
|
+ if (!memcmp(ifa->ifa_addr, nfs_saddr,
|
||
|
+ sizeof(struct sockaddr))) {
|
||
|
+ found = 1;
|
||
|
+ break;
|
||
|
+ }
|
||
|
+ }
|
||
|
+ freeifaddrs(myaddrs);
|
||
|
+ return found;
|
||
|
+}
|
||
|
diff -up nfs-utils-1.3.0/utils/mount/network.h.orig nfs-utils-1.3.0/utils/mount/network.h
|
||
|
--- nfs-utils-1.3.0/utils/mount/network.h.orig 2018-07-30 14:14:01.242771732 -0400
|
||
|
+++ nfs-utils-1.3.0/utils/mount/network.h 2018-07-30 14:15:36.918075978 -0400
|
||
|
@@ -54,6 +54,8 @@ int nfs_callback_address(const struct so
|
||
|
int clnt_ping(struct sockaddr_in *, const unsigned long,
|
||
|
const unsigned long, const unsigned int,
|
||
|
struct sockaddr_in *);
|
||
|
+int nfs_is_inaddr_any(struct sockaddr *);
|
||
|
+int nfs_addr_matches_localips(struct sockaddr *);
|
||
|
|
||
|
struct mount_options;
|
||
|
|
||
|
diff -up nfs-utils-1.3.0/utils/mount/nfs.man.orig nfs-utils-1.3.0/utils/mount/nfs.man
|
||
|
--- nfs-utils-1.3.0/utils/mount/nfs.man.orig 2018-07-30 14:14:01.240771705 -0400
|
||
|
+++ nfs-utils-1.3.0/utils/mount/nfs.man 2018-07-30 14:15:43.365163864 -0400
|
||
|
@@ -825,6 +825,9 @@ to perform NFS version 4.0 callback requ
|
||
|
files on this mount point. If the server is unable to
|
||
|
establish callback connections to clients, performance
|
||
|
may degrade, or accesses to files may temporarily hang.
|
||
|
+Can specify a value of IPv4_ANY (0.0.0.0) or equivalent
|
||
|
+IPv6 any address which will signal to the NFS server that
|
||
|
+this NFS client does not want delegations.
|
||
|
.IP
|
||
|
If this option is not specified, the
|
||
|
.BR mount (8)
|
||
|
diff -up nfs-utils-1.3.0/utils/mount/stropts.c.orig nfs-utils-1.3.0/utils/mount/stropts.c
|
||
|
--- nfs-utils-1.3.0/utils/mount/stropts.c.orig 2018-07-30 14:14:01.243771746 -0400
|
||
|
+++ nfs-utils-1.3.0/utils/mount/stropts.c 2018-07-30 14:15:36.918075978 -0400
|
||
|
@@ -229,7 +229,8 @@ static int nfs_append_addr_option(const
|
||
|
|
||
|
/*
|
||
|
* Called to discover our address and append an appropriate 'clientaddr='
|
||
|
- * option to the options string.
|
||
|
+ * option to the options string. If the supplied 'clientaddr=' value does
|
||
|
+ * not match either IPV4/IPv6 any or a local address, then fail the mount.
|
||
|
*
|
||
|
* Returns 1 if 'clientaddr=' option created successfully or if
|
||
|
* 'clientaddr=' option is already present; otherwise zero.
|
||
|
@@ -242,8 +243,27 @@ static int nfs_append_clientaddr_option(
|
||
|
struct sockaddr *my_addr = &address.sa;
|
||
|
socklen_t my_len = sizeof(address);
|
||
|
|
||
|
- if (po_contains(options, "clientaddr") == PO_FOUND)
|
||
|
+ if (po_contains(options, "clientaddr") == PO_FOUND) {
|
||
|
+ char *addr = po_get(options, "clientaddr");
|
||
|
+ union nfs_sockaddr nfs_address;
|
||
|
+ struct sockaddr *nfs_saddr = &nfs_address.sa;
|
||
|
+ socklen_t nfs_salen = sizeof(nfs_address);
|
||
|
+
|
||
|
+ /* translate the input for clientaddr to nfs_sockaddr */
|
||
|
+ if (!nfs_string_to_sockaddr(addr, nfs_saddr, &nfs_salen))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ /* check for IPV4_ANY and IPV6_ANY */
|
||
|
+ if (nfs_is_inaddr_any(nfs_saddr))
|
||
|
+ return 1;
|
||
|
+
|
||
|
+ /* check if ip matches local network addresses */
|
||
|
+ if (!nfs_addr_matches_localips(nfs_saddr))
|
||
|
+ nfs_error(_("%s: [warning] supplied clientaddr=%s "
|
||
|
+ "does not match any existing network "
|
||
|
+ "addresses"), progname, addr);
|
||
|
return 1;
|
||
|
+ }
|
||
|
|
||
|
nfs_callback_address(sap, salen, my_addr, &my_len);
|
||
|
|