summaryrefslogtreecommitdiffstats
path: root/libglusterfs/src/common-utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'libglusterfs/src/common-utils.c')
-rw-r--r--libglusterfs/src/common-utils.c165
1 files changed, 155 insertions, 10 deletions
diff --git a/libglusterfs/src/common-utils.c b/libglusterfs/src/common-utils.c
index 80d9d29..e63ffa1 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;
}
@@ -1421,6 +1421,28 @@ gf_string2bytesize (const char *str, uint64_t *n)
}
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,
gf_boolean_t *is_percent)
@@ -1858,6 +1880,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)
{
@@ -1939,6 +2025,65 @@ out:
}
/**
+ * 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
*
* @param a - first sock union