diff options
| author | Santosh Kumar Pradhan <spradhan@redhat.com> | 2014-06-06 12:22:04 +0530 | 
|---|---|---|
| committer | Niels de Vos <ndevos@redhat.com> | 2014-06-25 00:41:52 -0700 | 
| commit | d3f0de90d0c5166e63f5764d2f21703fd29ce976 (patch) | |
| tree | bdfc1b91f4d34ce7a29a8ad9774ad513d24a8730 /rpc | |
| parent | 5740fd404827a70e6318b6fff5773a9d9234d704 (diff) | |
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.<volname>.allow"
   and "NFS subdir auth code" to remove code duplication.
Change-Id: I26b0def52c22cda35ca11766afca3df5fd4360bf
BUG: 1102293
Signed-off-by: Santosh Kumar Pradhan <spradhan@redhat.com>
Reviewed-on: http://review.gluster.org/8048
Reviewed-by: Rajesh Joseph <rjoseph@redhat.com>
Tested-by: Gluster Build System <jenkins@build.gluster.com>
Reviewed-by: Niels de Vos <ndevos@redhat.com>
Diffstat (limited to 'rpc')
| -rw-r--r-- | rpc/rpc-lib/src/rpcsvc.c | 45 | 
1 files changed, 18 insertions, 27 deletions
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c index 5241a265ce8..814af05f7b6 100644 --- a/rpc/rpc-lib/src/rpcsvc.c +++ b/rpc/rpc-lib/src/rpcsvc.c @@ -61,7 +61,7 @@ rpcsvc_notify (rpc_transport_t *trans, void *mydata,                 rpc_transport_event_t event, void *data, ...);  static int -match_subnet_v4 (const char *addrtok, const char *ipaddr); +rpcsvc_match_subnet_v4 (const char *addrtok, const char *ipaddr);  rpcsvc_notify_wrapper_t *  rpcsvc_notify_wrapper_alloc (void) @@ -2265,9 +2265,9 @@ rpcsvc_transport_peer_check_search (dict_t *options, char *pattern,                                  goto err;                  } -                /* Compare IPv4 subnetwork */ +                /* Compare IPv4 subnetwork, TODO: IPv6 subnet support */                  if (strchr (addrtok, '/')) { -                        ret = match_subnet_v4 (addrtok, ip); +                        ret = rpcsvc_match_subnet_v4 (addrtok, ip);                          if (ret == 0)                                  goto err;                  } @@ -2565,9 +2565,9 @@ out:  }  /* - * match_subnet_v4() takes subnetwork address pattern and checks - * if the target IPv4 address has the same network address with - * the help of network mask. + * rpcsvc_match_subnet_v4() takes subnetwork address pattern and checks + * if the target IPv4 address has the same network address with the help + * of network mask.   *   * Returns 0 for SUCCESS and -1 otherwise.   * @@ -2575,12 +2575,12 @@ out:   *     as it's already being done at the time of CLI SET.   */  static int -match_subnet_v4 (const char *addrtok, const char *ipaddr) +rpcsvc_match_subnet_v4 (const char *addrtok, const char *ipaddr)  {          char                 *slash     = NULL;          char                 *netaddr   = NULL; -        long                  prefixlen = -1;          int                   ret       = -1; +        uint32_t              prefixlen = 0;          uint32_t              shift     = 0;          struct sockaddr_in    sin1      = {0, };          struct sockaddr_in    sin2      = {0, }; @@ -2602,28 +2602,19 @@ match_subnet_v4 (const char *addrtok, const char *ipaddr)                  goto out;          /* -         * Find the network mask in network byte order. -         * NB: 32 : Max len of IPv4 address. +         * Find the IPv4 network mask in network byte order. +         * IMP: String slash+1 is already validated, it cant have value +         * more than IPv4_ADDR_SIZE (32).           */ -        prefixlen = atoi (slash + 1); -        shift = 32 - (uint32_t)prefixlen; +        prefixlen = (uint32_t) atoi (slash + 1); +        shift = IPv4_ADDR_SIZE - prefixlen;          mask.sin_addr.s_addr = htonl ((uint32_t)~0 << shift); -        /* -         * Check if both have same network address. -         * Extract the network address from the IP addr by applying the -         * network mask. If they match, return SUCCESS. i.e. -         * -         * (x == y) <=> (x ^ y == 0) -         * (x & y) ^ (x & z) <=> x & (y ^ z) -         * -         * ((ip1 & mask) == (ip2 & mask)) <=> ((mask & (ip1 ^ ip2)) == 0) -         */ -        if (((mask.sin_addr.s_addr) & -             (sin1.sin_addr.s_addr ^ sin2.sin_addr.s_addr)) != 0) -                goto out; - -        ret = 0; /* SUCCESS */ +        if (mask_match (sin1.sin_addr.s_addr, +                        sin2.sin_addr.s_addr, +                        mask.sin_addr.s_addr)) { +                ret = 0; /* SUCCESS */ +        }  out:          GF_FREE (netaddr);          return ret;  | 
