summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libglusterfs/src/common-utils.c71
-rw-r--r--libglusterfs/src/common-utils.h1
-rw-r--r--rpc/rpc-lib/src/rpcsvc.c20
-rw-r--r--xlators/nfs/server/src/mount3.c4
4 files changed, 96 insertions, 0 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 22f13861451..75b97722513 100644
--- a/libglusterfs/src/common-utils.c
+++ b/libglusterfs/src/common-utils.c
@@ -2337,3 +2337,74 @@ gf_ports_reserved (char *blocked_port, gf_boolean_t *ports)
out:
return result;
}
+
+/* Takes in client ip{v4,v6} and returns associated hostname, if any
+ * Also, allocates memory for the hostname.
+ * Returns: 0 for success, -1 for failure
+ */
+int
+gf_get_hostname_from_ip (char *client_ip, char **hostname)
+{
+ int ret = -1;
+ struct sockaddr *client_sockaddr = NULL;
+ struct sockaddr_in client_sock_in = {0};
+ struct sockaddr_in6 client_sock_in6 = {0};
+ char client_hostname[NI_MAXHOST] = {0};
+ char *client_ip_copy = NULL;
+ char *tmp = NULL;
+ char *ip = NULL;
+
+ /* if ipv4, reverse lookup the hostname to
+ * allow FQDN based rpc authentication
+ */
+ if (valid_ipv4_address (client_ip, strlen (client_ip), 0) == _gf_false) {
+ /* most times, we get a.b.c.d:port form, so check that */
+ client_ip_copy = gf_strdup (client_ip);
+ if (!client_ip_copy)
+ goto out;
+
+ ip = strtok_r (client_ip_copy, ":", &tmp);
+ } else {
+ ip = client_ip;
+ }
+
+ if (valid_ipv4_address (ip, strlen (ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *)&client_sock_in;
+ client_sock_in.sin_family = AF_INET;
+ ret = inet_pton (AF_INET, ip,
+ (void *)&client_sock_in.sin_addr.s_addr);
+
+ } else if (valid_ipv6_address (ip, strlen (ip), 0) == _gf_true) {
+ client_sockaddr = (struct sockaddr *) &client_sock_in6;
+
+ client_sock_in6.sin6_family = AF_INET6;
+ ret = inet_pton (AF_INET6, ip,
+ (void *)&client_sock_in6.sin6_addr);
+ } else {
+ goto out;
+ }
+
+ if (ret != 1) {
+ ret = -1;
+ goto out;
+ }
+
+ ret = getnameinfo (client_sockaddr,
+ sizeof (*client_sockaddr),
+ client_hostname, sizeof (client_hostname),
+ NULL, 0, 0);
+ if (ret) {
+ gf_log ("common-utils", GF_LOG_ERROR,
+ "Could not lookup hostname of %s : %s",
+ client_ip, gai_strerror (ret));
+ ret = -1;
+ goto out;
+ }
+
+ *hostname = gf_strdup ((char *)client_hostname);
+ out:
+ if (client_ip_copy)
+ GF_FREE (client_ip_copy);
+
+ return ret;
+}
diff --git a/libglusterfs/src/common-utils.h b/libglusterfs/src/common-utils.h
index b89a988c62c..bbafd1fb039 100644
--- a/libglusterfs/src/common-utils.h
+++ b/libglusterfs/src/common-utils.h
@@ -575,5 +575,6 @@ char *generate_glusterfs_ctx_id (void);
char *gf_get_reserved_ports();
int gf_process_reserved_ports (gf_boolean_t ports[]);
gf_boolean_t gf_ports_reserved (char *blocked_port, gf_boolean_t *ports);
+int gf_get_hostname_from_ip (char *client_ip, char **hostname);
#endif /* _COMMON_UTILS_H */
diff --git a/rpc/rpc-lib/src/rpcsvc.c b/rpc/rpc-lib/src/rpcsvc.c
index 7cb89db0946..c8595ee8ed1 100644
--- a/rpc/rpc-lib/src/rpcsvc.c
+++ b/rpc/rpc-lib/src/rpcsvc.c
@@ -1925,10 +1925,13 @@ rpcsvc_transport_peer_check_search (dict_t *options, char *pattern, char *clstr)
char *addrstr = NULL;
char *dup_addrstr = NULL;
char *svptr = NULL;
+ char *fqdn = NULL;
if ((!options) || (!clstr))
return -1;
+ ret = dict_get_str (options, "client.fqdn", &fqdn);
+
if (!dict_get (options, pattern))
return -1;
@@ -1956,6 +1959,17 @@ rpcsvc_transport_peer_check_search (dict_t *options, char *pattern, char *clstr)
if (ret == 0)
goto err;
+ /* compare hostnames if applicable */
+ if (fqdn) {
+#ifdef FNM_CASEFOLD
+ ret = fnmatch (addrtok, fqdn, FNM_CASEFOLD);
+#else
+ ret = fnmatch (addrtok, fqdn, 0);
+#endif
+ if (ret == 0)
+ goto err;
+ }
+
addrtok = strtok_r (NULL, ",", &svptr);
}
@@ -2174,6 +2188,7 @@ rpcsvc_transport_peer_check_name (dict_t *options, char *volname,
int aret = RPCSVC_AUTH_REJECT;
int rjret = RPCSVC_AUTH_REJECT;
char clstr[RPCSVC_PEER_STRLEN];
+ char *hostname = NULL;
if (!trans)
return ret;
@@ -2186,6 +2201,11 @@ rpcsvc_transport_peer_check_name (dict_t *options, char *volname,
goto err;
}
+ ret = gf_get_hostname_from_ip (clstr, &hostname);
+ if (!ret)
+ ret = dict_set_dynstr (options, "client.fqdn",
+ hostname);
+
aret = rpcsvc_transport_peer_check_allow (options, volname, clstr);
rjret = rpcsvc_transport_peer_check_reject (options, volname, clstr);
diff --git a/xlators/nfs/server/src/mount3.c b/xlators/nfs/server/src/mount3.c
index efd74aa58ac..255310fa800 100644
--- a/xlators/nfs/server/src/mount3.c
+++ b/xlators/nfs/server/src/mount3.c
@@ -1856,6 +1856,8 @@ rpcsvc_actor_t mnt3svc_actors[MOUNT3_PROC_COUNT] = {
/* Static init parts are assigned here, dynamic ones are done in
* mnt3svc_init and mnt3_init_state.
+ * Making MOUNT3 a synctask so that the blocking DNS calls during rpc auth
+ * gets offloaded to syncenv, keeping the main/poll thread unblocked
*/
rpcsvc_program_t mnt3prog = {
.progname = "MOUNT3",
@@ -1865,6 +1867,7 @@ rpcsvc_program_t mnt3prog = {
.actors = mnt3svc_actors,
.numactors = MOUNT3_PROC_COUNT,
.min_auth = AUTH_NULL,
+ .synctask = _gf_true,
};
@@ -1953,6 +1956,7 @@ rpcsvc_program_t mnt1prog = {
.actors = mnt1svc_actors,
.numactors = MOUNT1_PROC_COUNT,
.min_auth = AUTH_NULL,
+ .synctask = _gf_true,
};