From 1cb3b1abeda53bb430bbe1490fac154337ac9994 Mon Sep 17 00:00:00 2001 From: Niels de Vos Date: Thu, 1 Jan 2015 13:15:45 +0100 Subject: nfs: more fine grained authentication for the MOUNT protocol The /etc/exports format for NFS-exports (see Change-Id I7e6aa6b) allows a more fine grained control over the authentication. This change adds the functions and structures that will be used in by Change-Id I181e8c1. BUG: 1143880 Change-Id: Ic060aac7c52d91e08519b222ba46383c94665ce7 Original-author: Shreyas Siravara CC: Richard Wareing CC: Jiffin Tony Thottan Signed-off-by: Niels de Vos Reviewed-on: http://review.gluster.org/9362 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- libglusterfs/src/common-utils.c | 69 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) (limited to 'libglusterfs/src/common-utils.c') diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index cfbf3191eef..6dcfc098dc2 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1688,6 +1688,75 @@ out: return ret; } +/** + * gf_is_ip_in_net -- Checks if an IP Address is in a network. + * A network should be specified by something like + * '10.5.153.0/24' (in CIDR notation). + * + * @result : Sets to true if the IP is in the network + * @ip_str : The IP to check + * @network: The network to check the IP against. + * + * @return: success: 0 + * failure: -EINVAL for bad args, retval of inet_pton otherwise + */ +gf_boolean_t +gf_is_ip_in_net (const char *network, const char *ip_str) +{ + unsigned long ip_buf = 0; + unsigned long net_ip_buf = 0; + unsigned long subnet_mask = 0; + int ret = -EINVAL; + char *slash = NULL; + char *net_ip = NULL; + char *subnet = NULL; + char *net_str = NULL; + int family = AF_INET; + gf_boolean_t result = _gf_false; + + GF_ASSERT (network); + GF_ASSERT (ip_str); + + if (strchr (network, ':')) + family = AF_INET6; + else if (strchr (network, '.')) + family = AF_INET; + else { + family = -1; + goto out; + } + + net_str = strdupa (network); + slash = strchr (net_str, '/'); + if (!slash) + goto out; + *slash = '\0'; + + subnet = slash + 1; + net_ip = net_str; + + /* Convert IP address to a long */ + ret = inet_pton (family, ip_str, &ip_buf); + if (ret < 0) + gf_log ("common-utils", GF_LOG_ERROR, + "inet_pton() failed with %s", strerror (errno)); + + /* Convert network IP address to a long */ + ret = inet_pton (family, net_ip, &net_ip_buf); + if (ret < 0) { + gf_log ("common-utils", GF_LOG_ERROR, + "inet_pton() failed with %s", strerror (errno)); + goto out; + } + + /* Converts /x into a mask */ + subnet_mask = (1 << atoi (subnet)) - 1; + + result = ((ip_buf & subnet_mask) == (net_ip_buf & subnet_mask)); +out: + return result; +} + char * strtail (char *str, const char *pattern) { -- cgit