From 00e247ee44067f2b3e7ca5f7e6dc2f7934c97181 Mon Sep 17 00:00:00 2001 From: Santosh Kumar Pradhan Date: Wed, 9 Apr 2014 10:19:43 +0530 Subject: gNFS: Support wildcard in RPC auth allow/reject RFE: Support wildcard in "nfs.rpc-auth-allow" and "nfs.rpc-auth-reject". e.g. *.redhat.com 192.168.1[1-5].* 192.168.1[1-5].*, *.redhat.com, 192.168.21.9 Along with wildcard, support for subnetwork or IP range e.g. 192.168.10.23/24 The option will be validated for following categories: 1) Anonymous i.e. "*" 2) Wildcard pattern i.e. string containing any ('*', '?', '[') 3) IPv4 address 4) IPv6 address 5) FQDN 6) subnetwork or IPv4 range Currently this does not support IPv6 subnetwork. Change-Id: Iac8caf5e490c8174d61111dad47fd547d4f67bf4 BUG: 1086097 Signed-off-by: Santosh Kumar Pradhan Reviewed-on: http://review.gluster.org/7485 Reviewed-by: Poornima G Reviewed-by: Harshavardhana Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- libglusterfs/src/common-utils.c | 123 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) (limited to 'libglusterfs/src/common-utils.c') diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index 80d9d2940..b7d06d925 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1858,6 +1858,70 @@ out: return ret; } +/** + * valid_ipv4_subnetwork() takes the pattern and checks if it contains + * a valid ipv4 subnetwork pattern i.e. xx.xx.xx.xx/n. IPv4 address + * part (xx.xx.xx.xx) and mask bits lengh part (n). The mask bits lengh + * must be in 0-32 range (ipv4 addr is 32 bit). The pattern must be + * in this format. + * + * Returns _gf_true if both IP addr and mask bits len are valid + * _gf_false otherwise. + */ +gf_boolean_t +valid_ipv4_subnetwork (const char *address) +{ + char *slash = NULL; + char *paddr = NULL; + char *endptr = NULL; + long prefixlen = -1; + gf_boolean_t retv = _gf_true; + + if (address == NULL) { + gf_log_callingfn (THIS->name, GF_LOG_WARNING, + "argument invalid"); + return _gf_false; + } + + paddr = gf_strdup (address); + if (paddr == NULL) /* ENOMEM */ + return _gf_false; + + /* + * INVALID: If '/' is not present OR + * Nothing specified after '/' + */ + slash = strchr(paddr, '/'); + if ((slash == NULL) || (slash[1] == '\0')) { + gf_log_callingfn (THIS->name, GF_LOG_WARNING, + "Invalid IPv4 subnetwork format"); + retv = _gf_false; + goto out; + } + + *slash = '\0'; + retv = valid_ipv4_address (paddr, strlen(paddr), _gf_false); + if (retv == _gf_false) { + gf_log_callingfn (THIS->name, GF_LOG_WARNING, + "Invalid IPv4 subnetwork address"); + goto out; + } + + prefixlen = strtol (slash + 1, &endptr, 10); + if ((errno != 0) || (*endptr != '\0') || + (prefixlen < 0) || (prefixlen > 32)) { + gf_log_callingfn (THIS->name, GF_LOG_WARNING, + "Invalid IPv4 subnetwork mask"); + retv = _gf_false; + goto out; + } + + retv = _gf_true; +out: + GF_FREE (paddr); + return retv; +} + char valid_ipv6_address (char *address, int length, gf_boolean_t wildcard_acc) { @@ -1938,6 +2002,65 @@ out: return ret; } +/** + * valid_mount_auth_address - Validate the rpc-auth.addr.allow/reject pattern + * + * @param address - Pattern to be validated + * + * @return _gf_true if "address" is "*" (anonymous) 'OR' + * if "address" is valid FQDN or valid IPv4/6 address 'OR' + * if "address" contains wildcard chars e.g. "'*' or '?' or '['" + * if "address" is valid ipv4 subnet pattern (xx.xx.xx.xx/n) + * _gf_false otherwise + * + * + * NB: If the user/admin set for wildcard pattern, then it does not have + * to be validated. Make it similar to the way exportfs (kNFS) works. + */ +gf_boolean_t +valid_mount_auth_address (char *address) +{ + int length = 0; + char *cp = NULL; + + /* 1. Check for "NULL and empty string */ + if ((address == NULL) || (address[0] == '\0')){ + gf_log_callingfn (THIS->name, + GF_LOG_WARNING, "argument invalid"); + return _gf_false; + } + + /* 2. Check for Anonymous */ + if (strcmp(address, "*") == 0) + return _gf_true; + + for (cp = address; *cp; cp++) { + /* 3. Check for wildcard pattern */ + if (*cp == '*' || *cp == '?' || *cp == '[') { + return _gf_true; + } + + /* + * 4. check for IPv4 subnetwork i.e. xx.xx.xx.xx/n + * TODO: check for IPv6 subnetwork + * NB: Wildcard must not be mixed with subnetwork. + */ + if (*cp == '/') { + return valid_ipv4_subnetwork (address); + } + } + + /* 5. Check for v4/v6 IP addr and FQDN/hostname */ + length = strlen (address); + if ((valid_ipv4_address (address, length, _gf_false)) || + (valid_ipv6_address (address, length, _gf_false)) || + (valid_host_name (address, length))) { + return _gf_true; + } + + return _gf_false; +} + /** * gf_sock_union_equal_addr - check if two given gf_sock_unions have same addr * -- cgit From a3cb38e3edf005bef73da4c9cfd958474a14d50f Mon Sep 17 00:00:00 2001 From: Harshavardhana Date: Thu, 17 Apr 2014 15:54:34 -0700 Subject: build: MacOSX Porting fixes git@forge.gluster.org:~schafdog/glusterfs-core/osx-glusterfs Working functionality on MacOSX - GlusterD (management daemon) - GlusterCLI (management cli) - GlusterFS FUSE (using OSXFUSE) - GlusterNFS (without NLM - issues with rpc.statd) Change-Id: I20193d3f8904388e47344e523b3787dbeab044ac BUG: 1089172 Signed-off-by: Harshavardhana Signed-off-by: Dennis Schafroth Tested-by: Harshavardhana Tested-by: Dennis Schafroth Reviewed-on: http://review.gluster.org/7503 Tested-by: Gluster Build System Reviewed-by: Anand Avati --- libglusterfs/src/common-utils.c | 42 +++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'libglusterfs/src/common-utils.c') diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c index b7d06d925..e63ffa142 100644 --- a/libglusterfs/src/common-utils.c +++ b/libglusterfs/src/common-utils.c @@ -1170,7 +1170,7 @@ gf_string2uint8 (const char *str, uint8_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT8_MAX) { + if (l <= UINT8_MAX) { *n = (uint8_t) l; return 0; } @@ -1189,7 +1189,7 @@ gf_string2uint16 (const char *str, uint16_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT16_MAX) { + if (l <= UINT16_MAX) { *n = (uint16_t) l; return 0; } @@ -1208,7 +1208,7 @@ gf_string2uint32 (const char *str, uint32_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT32_MAX) { + if (l <= UINT32_MAX) { *n = (uint32_t) l; return 0; } @@ -1227,7 +1227,7 @@ gf_string2uint64 (const char *str, uint64_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT64_MAX) { + if (l <= UINT64_MAX) { *n = (uint64_t) l; return 0; } @@ -1258,7 +1258,7 @@ gf_string2uint8_base10 (const char *str, uint8_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT8_MAX) { + if (l <= UINT8_MAX) { *n = (uint8_t) l; return 0; } @@ -1277,7 +1277,7 @@ gf_string2uint16_base10 (const char *str, uint16_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT16_MAX) { + if (l <= UINT16_MAX) { *n = (uint16_t) l; return 0; } @@ -1296,7 +1296,7 @@ gf_string2uint32_base10 (const char *str, uint32_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT32_MAX) { + if (l <= UINT32_MAX) { *n = (uint32_t) l; return 0; } @@ -1315,7 +1315,7 @@ gf_string2uint64_base10 (const char *str, uint64_t *n) if (rv != 0) return rv; - if (l >= 0 && l <= UINT64_MAX) { + if (l <= UINT64_MAX) { *n = (uint64_t) l; return 0; } @@ -1361,7 +1361,7 @@ err: } int -gf_string2bytesize (const char *str, uint64_t *n) +gf_string2bytesize_range (const char *str, uint64_t *n, uint64_t max) { double value = 0.0; char *tail = NULL; @@ -1410,7 +1410,7 @@ gf_string2bytesize (const char *str, uint64_t *n) return -1; } - if ((UINT64_MAX - value) < 0) { + if ((max - value) < 0) { errno = ERANGE; return -1; } @@ -1420,6 +1420,28 @@ gf_string2bytesize (const char *str, uint64_t *n) return 0; } +int +gf_string2bytesize_size (const char *str, size_t *n) +{ + uint64_t u64; + size_t max = (size_t) - 1; + int val = gf_string2bytesize_range (str, &u64, max); + *n = (size_t) u64; + return val; +} + +int +gf_string2bytesize (const char *str, uint64_t *n) +{ + return gf_string2bytesize_range(str, n, UINT64_MAX); +} + +int +gf_string2bytesize_uint64 (const char *str, uint64_t *n) +{ + return gf_string2bytesize_range(str, n, UINT64_MAX); +} + int gf_string2percent_or_bytesize (const char *str, uint64_t *n, -- cgit