diff options
| -rw-r--r-- | libglusterfs/src/common-utils.c | 71 | ||||
| -rw-r--r-- | libglusterfs/src/common-utils.h | 1 | ||||
| -rw-r--r-- | rpc/rpc-lib/src/rpcsvc.c | 20 | ||||
| -rw-r--r-- | xlators/nfs/server/src/mount3.c | 4 | 
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,  };  | 
