From d3f0de90d0c5166e63f5764d2f21703fd29ce976 Mon Sep 17 00:00:00 2001 From: Santosh Kumar Pradhan Date: Fri, 6 Jun 2014 12:22:04 +0530 Subject: gNFS: Fix multi-homed m/c issue in NFS subdir auth NFS subdir authentication doesn't correctly handle multi-homed (host with multiple NIC having multiple IP addr) OR multi-protocol (IPv4 and IPv6) network addresses. When user/admin sets HOSTNAME in gluster CLI for NFS subdir auth, mnt3_verify_auth() routine does not iterate over all the resolved n/w addrs returned by getaddrinfo() n/w API. Instead, it just tests with the one returned first. 1. Iterate over all the n/w addrs (linked list) returned by getaddrinfo(). 2. Move the n/w mask calculation part to mnt3_export_fill_hostspec() instead of doing it in mnt3_verify_auth() i.e. calculating for each mount request. It does not change for MOUNT req. 3. Integrate "subnet support code rpc-auth.addr..allow" and "NFS subdir auth code" to remove code duplication. Change-Id: I26b0def52c22cda35ca11766afca3df5fd4360bf BUG: 1102293 Signed-off-by: Santosh Kumar Pradhan Reviewed-on: http://review.gluster.org/8048 Reviewed-by: Rajesh Joseph Tested-by: Gluster Build System Reviewed-by: Niels de Vos --- libglusterfs/src/common-utils.c | 19 ++++++++++++++++++- libglusterfs/src/common-utils.h | 3 +++ 2 files changed, 21 insertions(+), 1 deletion(-) (limited to 'libglusterfs') diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 9fe1b6a4463..6ba5223da0b 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1936,7 +1936,7 @@ valid_ipv4_subnetwork (const char *address) prefixlen = strtol (slash + 1, &endptr, 10); if ((errno != 0) || (*endptr != '\0') || - (prefixlen < 0) || (prefixlen > 32)) { + (prefixlen < 0) || (prefixlen > IPv4_ADDR_SIZE)) { gf_log_callingfn (THIS->name, GF_LOG_WARNING, "Invalid IPv4 subnetwork mask"); retv = _gf_false; @@ -2132,6 +2132,23 @@ gf_sock_union_equal_addr (union gf_sock_union *a, return _gf_false; } +/* + * Check if both have same network address. + * Extract the network address from the sockaddr(s) addr by applying the + * network mask. If they match, return boolean _gf_true, _gf_false otherwise. + * + * (x == y) <=> (x ^ y == 0) + * (x & y) ^ (x & z) <=> x & (y ^ z) + * + * ((ip1 & mask) == (ip2 & mask)) <=> ((mask & (ip1 ^ ip2)) == 0) + */ +gf_boolean_t +mask_match(const uint32_t a, const uint32_t b, const uint32_t m) +{ + return (((a ^ b) & m) == 0); +} + + /*Thread safe conversion function*/ char * uuid_utoa (uuid_t uuid) diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h index 61da39767a2..86848df452d 100644 --- a/libglusterfs/src/common-utils.h +++ b/libglusterfs/src/common-utils.h @@ -50,6 +50,8 @@ void trap (void); #define roof(a,b) ((((a)+(b)-1)/((b)?(b):1))*(b)) #define floor(a,b) (((a)/((b)?(b):1))*(b)) +#define IPv4_ADDR_SIZE 32 + #define GF_UNIT_KB 1024ULL #define GF_UNIT_MB 1048576ULL @@ -582,6 +584,7 @@ void skip_word (char **str); /* returns a new string with nth word of given string. n>=1 */ char *get_nth_word (const char *str, int n); +gf_boolean_t mask_match (const uint32_t a, const uint32_t b, const uint32_t m); char valid_host_name (char *address, int length); char valid_ipv4_address (char *address, int length, gf_boolean_t wildcard_acc); char valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc); -- cgit