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.
128 lines
4.4 KiB
128 lines
4.4 KiB
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); |
|
|
|
|