linux-nfs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 1/2] Add check of clientaddr argument
@ 2018-06-05 19:29 Olga Kornievskaia
  2018-06-05 19:29 ` [PATCH v3 2/2] nfs(5): update clientaddr value options Olga Kornievskaia
  2018-06-19 16:57 ` [PATCH v3 1/2] Add check of clientaddr argument Steve Dickson
  0 siblings, 2 replies; 4+ messages in thread
From: Olga Kornievskaia @ 2018-06-05 19:29 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

If the NFS client administrator supplies the clientaddr mount
option, it should be either a special value of either IPv4/IPv6
any address or one of the machine's network addresses. Otherwise,
warn the administrator about the use of an arbitrary value for
the clientaddr value.

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
`
---
 utils/mount/network.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
 utils/mount/network.h |  2 ++
 utils/mount/stropts.c | 24 ++++++++++++++++++++++--
 3 files changed, 69 insertions(+), 2 deletions(-)

diff --git a/utils/mount/network.c b/utils/mount/network.c
index e490399..2a54f82 100644
--- a/utils/mount/network.c
+++ b/utils/mount/network.c
@@ -50,6 +50,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"
@@ -1759,3 +1761,46 @@ int nfs_umount_do_umnt(struct mount_options *options,
 
 	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;
+	}
+	case AF_INET6:
+		if (!memcmp(&((struct sockaddr_in6 *)nfs_saddr)->sin6_addr,
+				&in6addr_any, sizeof(in6addr_any)))
+			return 1;
+	}
+	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 --git a/utils/mount/network.h b/utils/mount/network.h
index ecaac33..0fc98ac 100644
--- a/utils/mount/network.h
+++ b/utils/mount/network.h
@@ -54,6 +54,8 @@ int nfs_callback_address(const struct sockaddr *, const socklen_t,
 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 --git a/utils/mount/stropts.c b/utils/mount/stropts.c
index d1b0708..4d2e37e 100644
--- a/utils/mount/stropts.c
+++ b/utils/mount/stropts.c
@@ -229,7 +229,8 @@ static int nfs_append_addr_option(const struct sockaddr *sap,
 
 /*
  * 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(const struct sockaddr *sap,
 	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);
 
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] nfs(5): update clientaddr value options
  2018-06-05 19:29 [PATCH v3 1/2] Add check of clientaddr argument Olga Kornievskaia
@ 2018-06-05 19:29 ` Olga Kornievskaia
  2018-06-19 16:57   ` Steve Dickson
  2018-06-19 16:57 ` [PATCH v3 1/2] Add check of clientaddr argument Steve Dickson
  1 sibling, 1 reply; 4+ messages in thread
From: Olga Kornievskaia @ 2018-06-05 19:29 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Document the use of IPv4/IPv6_ANY address as values to the clientaddr
as a way to tell the server that the client does not want delegations.

Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
---
 utils/mount/nfs.man | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
index bd1508c..9ee9bd9 100644
--- a/utils/mount/nfs.man
+++ b/utils/mount/nfs.man
@@ -835,6 +835,9 @@ to perform NFS version 4.0 callback requests against
 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)
-- 
1.8.3.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] Add check of clientaddr argument
  2018-06-05 19:29 [PATCH v3 1/2] Add check of clientaddr argument Olga Kornievskaia
  2018-06-05 19:29 ` [PATCH v3 2/2] nfs(5): update clientaddr value options Olga Kornievskaia
@ 2018-06-19 16:57 ` Steve Dickson
  1 sibling, 0 replies; 4+ messages in thread
From: Steve Dickson @ 2018-06-19 16:57 UTC (permalink / raw)
  To: Olga Kornievskaia; +Cc: linux-nfs



On 06/05/2018 03:29 PM, Olga Kornievskaia wrote:
> If the NFS client administrator supplies the clientaddr mount
> option, it should be either a special value of either IPv4/IPv6
> any address or one of the machine's network addresses. Otherwise,
> warn the administrator about the use of an arbitrary value for
> the clientaddr value.
> 
> Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Committed... 

steved.
> `
> ---
>  utils/mount/network.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
>  utils/mount/network.h |  2 ++
>  utils/mount/stropts.c | 24 ++++++++++++++++++++++--
>  3 files changed, 69 insertions(+), 2 deletions(-)
> 
> diff --git a/utils/mount/network.c b/utils/mount/network.c
> index e490399..2a54f82 100644
> --- a/utils/mount/network.c
> +++ b/utils/mount/network.c
> @@ -50,6 +50,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"
> @@ -1759,3 +1761,46 @@ int nfs_umount_do_umnt(struct mount_options *options,
>  
>  	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;
> +	}
> +	case AF_INET6:
> +		if (!memcmp(&((struct sockaddr_in6 *)nfs_saddr)->sin6_addr,
> +				&in6addr_any, sizeof(in6addr_any)))
> +			return 1;
> +	}
> +	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 --git a/utils/mount/network.h b/utils/mount/network.h
> index ecaac33..0fc98ac 100644
> --- a/utils/mount/network.h
> +++ b/utils/mount/network.h
> @@ -54,6 +54,8 @@ int nfs_callback_address(const struct sockaddr *, const socklen_t,
>  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 --git a/utils/mount/stropts.c b/utils/mount/stropts.c
> index d1b0708..4d2e37e 100644
> --- a/utils/mount/stropts.c
> +++ b/utils/mount/stropts.c
> @@ -229,7 +229,8 @@ static int nfs_append_addr_option(const struct sockaddr *sap,
>  
>  /*
>   * 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(const struct sockaddr *sap,
>  	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);
>  
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 2/2] nfs(5): update clientaddr value options
  2018-06-05 19:29 ` [PATCH v3 2/2] nfs(5): update clientaddr value options Olga Kornievskaia
@ 2018-06-19 16:57   ` Steve Dickson
  0 siblings, 0 replies; 4+ messages in thread
From: Steve Dickson @ 2018-06-19 16:57 UTC (permalink / raw)
  To: Olga Kornievskaia; +Cc: linux-nfs



On 06/05/2018 03:29 PM, Olga Kornievskaia wrote:
> Document the use of IPv4/IPv6_ANY address as values to the clientaddr
> as a way to tell the server that the client does not want delegations.
> 
> Signed-off-by: Olga Kornievskaia <kolga@netapp.com>
Committed... 

steved.
> ---
>  utils/mount/nfs.man | 3 +++
>  1 file changed, 3 insertions(+)
> 
> diff --git a/utils/mount/nfs.man b/utils/mount/nfs.man
> index bd1508c..9ee9bd9 100644
> --- a/utils/mount/nfs.man
> +++ b/utils/mount/nfs.man
> @@ -835,6 +835,9 @@ to perform NFS version 4.0 callback requests against
>  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)
> 

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2018-06-19 16:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-06-05 19:29 [PATCH v3 1/2] Add check of clientaddr argument Olga Kornievskaia
2018-06-05 19:29 ` [PATCH v3 2/2] nfs(5): update clientaddr value options Olga Kornievskaia
2018-06-19 16:57   ` Steve Dickson
2018-06-19 16:57 ` [PATCH v3 1/2] Add check of clientaddr argument Steve Dickson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).