summaryrefslogtreecommitdiffstats
path: root/rpc/rpc-lib
diff options
context:
space:
mode:
authorSantosh Kumar Pradhan <spradhan@redhat.com>2014-07-22 16:56:57 +0530
committerNiels de Vos <ndevos@redhat.com>2014-10-07 00:51:29 -0700
commitddb31110db8e1b5995d392ced988f34d2f9145d2 (patch)
tree196f7271492c76a673e3a330cb22c3e4685b0e48 /rpc/rpc-lib
parent1642ee54cf78bb2d117f7ffb2a180acf12c54ab6 (diff)
gNFS: Subdir mount does not work on UDP proto
After enabling nfs.mount-udp, mounting a subdir on a volume over NFS fails. Because mountudpproc3_mnt_3_svc() invokes nfs3_rootfh() which internally calls mnt3_mntpath_to_export() to resolve the mount path. mnt3_mntpath_to_export() just works if the mount path requested is volume itself. It is not able to resolve, if the path is a subdir inside the volume. MOUNT over TCP uses mnt3_find_export() to resolve subdir path but UDP can't use this routine because mnt3_find_export() needs the req data (of type rpcsvc_request_t) and it's available only for TCP version of RPC. FIX: (1) Use syncop_lookup() framework to resolve the MOUNT PATH by breaking it into components and resolve component-by-component. i.e. glfs_resolve_at () API from libgfapi shared object. (2) If MOUNT PATH is subdir, then make sure subdir export is not disabled. (3) Add auth mechanism to respect nfs.rpc-auth-allow/reject and subdir auth i.e. nfs.export-dir (4) Enhanced error handling for MOUNT over UDP Change-Id: I42ee69415d064b98af4f49773026562824f684d1 BUG: 1118311 Signed-off-by: Santosh Kumar Pradhan <spradhan@redhat.com> Reviewed-on: http://review.gluster.org/8346 Reviewed-by: soumya k <skoduri@redhat.com> Tested-by: Gluster Build System <jenkins@build.gluster.com> Reviewed-by: Niels de Vos <ndevos@redhat.com>
Diffstat (limited to 'rpc/rpc-lib')
-rw-r--r--rpc/rpc-lib/src/rpcsvc.c44
-rw-r--r--rpc/rpc-lib/src/rpcsvc.h5
2 files changed, 9 insertions, 40 deletions
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c
index 1238a6a1c1e..b19a905692d 100644
--- a/rpc/rpc-lib/src/rpcsvc.c
+++ b/rpc/rpc-lib/src/rpcsvc.c
@@ -2366,21 +2366,18 @@ rpcsvc_combine_allow_reject_volume_check (int allow, int reject)
}
int
-rpcsvc_auth_check (rpcsvc_t *svc, char *volname,
- rpc_transport_t *trans)
+rpcsvc_auth_check (rpcsvc_t *svc, char *volname, char *ipaddr)
{
int ret = RPCSVC_AUTH_REJECT;
int accept = RPCSVC_AUTH_REJECT;
int reject = RPCSVC_AUTH_REJECT;
char *hostname = NULL;
- char *ip = NULL;
- char client_ip[RPCSVC_PEER_STRLEN] = {0};
char *allow_str = NULL;
char *reject_str = NULL;
char *srchstr = NULL;
dict_t *options = NULL;
- if (!svc || !volname || !trans)
+ if (!svc || !volname || !ipaddr)
return ret;
/* Fetch the options from svc struct and validate */
@@ -2388,13 +2385,6 @@ rpcsvc_auth_check (rpcsvc_t *svc, char *volname,
if (!options)
return ret;
- ret = rpcsvc_transport_peername (trans, client_ip, RPCSVC_PEER_STRLEN);
- if (ret != 0) {
- gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get remote addr: "
- "%s", gai_strerror (ret));
- return RPCSVC_AUTH_REJECT;
- }
-
/* Accept if its the default case: Allow all, Reject none
* The default volfile always contains a 'allow *' rule
* for each volume. If allow rule is missing (which implies
@@ -2435,13 +2425,9 @@ rpcsvc_auth_check (rpcsvc_t *svc, char *volname,
return RPCSVC_AUTH_ACCEPT;
}
- /* Non-default rule, authenticate */
- if (!get_host_name (client_ip, &ip))
- ip = client_ip;
-
/* addr-namelookup check */
if (svc->addr_namelookup == _gf_true) {
- ret = gf_get_hostname_from_ip (ip, &hostname);
+ ret = gf_get_hostname_from_ip (ipaddr, &hostname);
if (ret) {
if (hostname)
GF_FREE (hostname);
@@ -2454,10 +2440,10 @@ rpcsvc_auth_check (rpcsvc_t *svc, char *volname,
}
accept = rpcsvc_transport_peer_check_allow (options, volname,
- ip, hostname);
+ ipaddr, hostname);
reject = rpcsvc_transport_peer_check_reject (options, volname,
- ip, hostname);
+ ipaddr, hostname);
if (hostname)
GF_FREE (hostname);
@@ -2465,32 +2451,16 @@ rpcsvc_auth_check (rpcsvc_t *svc, char *volname,
}
int
-rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname,
- rpc_transport_t *trans)
+rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname, uint16_t port)
{
- union gf_sock_union sock_union;
int ret = RPCSVC_AUTH_REJECT;
- socklen_t sinsize = sizeof (&sock_union.sin);
char *srchstr = NULL;
char *valstr = NULL;
- uint16_t port = 0;
gf_boolean_t insecure = _gf_false;
- memset (&sock_union, 0, sizeof (sock_union));
-
- if ((!svc) || (!volname) || (!trans))
+ if ((!svc) || (!volname))
return ret;
- ret = rpcsvc_transport_peeraddr (trans, NULL, 0, &sock_union.storage,
- sinsize);
- if (ret != 0) {
- gf_log (GF_RPCSVC, GF_LOG_ERROR, "Failed to get peer addr: %s",
- gai_strerror (ret));
- ret = RPCSVC_AUTH_REJECT;
- goto err;
- }
-
- port = ntohs (sock_union.sin.sin_port);
gf_log (GF_RPCSVC, GF_LOG_TRACE, "Client port: %d", (int)port);
/* If the port is already a privileged one, dont bother with checking
* options.
diff --git a/rpc/rpc-lib/src/rpcsvc.h b/rpc/rpc-lib/src/rpcsvc.h
index 911fc958cc0..2e6fd93b60a 100644
--- a/rpc/rpc-lib/src/rpcsvc.h
+++ b/rpc/rpc-lib/src/rpcsvc.h
@@ -500,11 +500,10 @@ rpcsvc_transport_peeraddr (rpc_transport_t *trans, char *addrstr, int addrlen,
struct sockaddr_storage *returnsa, socklen_t sasize);
extern int
-rpcsvc_auth_check (rpcsvc_t *svc, char *volname, rpc_transport_t *trans);
+rpcsvc_auth_check (rpcsvc_t *svc, char *volname, char *ipaddr);
extern int
-rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname,
- rpc_transport_t *trans);
+rpcsvc_transport_privport_check (rpcsvc_t *svc, char *volname, uint16_t port);
#define rpcsvc_request_seterr(req, err) (req)->rpc_err = err
#define rpcsvc_request_set_autherr(req, err) (req)->auth_err = err