core: Feature added to accept CidrIp in auth.allow

Added functionality to gluster volume set auth.allow command to
accept CIDR IP addresses. Modified few functions to isolate cidr
feature so that it prevents other gluster commands such as peer
probe to use cidr format ip. The functions are modified in such
a way that they have an option to enable accepting of cidr
format for other gluster commands if required in furture.

updates: bz#1138841

Change-Id: Ie6734002a7078f1820e5df42d404411cce945e8b
Credits: Mohit Agrawal
Signed-off-by: Rinku Kothiya <rkothiya@redhat.com>
This commit is contained in:
Rinku Kothiya 2019-01-01 21:06:05 +05:30 committed by Amar Tumballi
parent ebaf09a2a3
commit 0687b0beb5
8 changed files with 79 additions and 15 deletions

View File

@ -144,7 +144,7 @@ cli_cmd_bricks_parse(const char **words, int wordcount, int brick_index,
GF_FREE(tmp_host);
goto out;
}
if (!valid_internet_address(host_name, _gf_false)) {
if (!valid_internet_address(host_name, _gf_false, _gf_false)) {
cli_err(
"internet address '%s' does not conform to "
"standards",
@ -3615,7 +3615,7 @@ cli_cmd_volume_statedump_options_parse(const char **words, int wordcount,
}
ip_addr = strtok(tmp, ":");
pid = strtok(NULL, ":");
if (valid_internet_address(ip_addr, _gf_true) && pid &&
if (valid_internet_address(ip_addr, _gf_true, _gf_false) && pid &&
gf_valid_pid(pid, strlen(pid))) {
ret = gf_asprintf(&option_str, "%s %s %s", words[3], ip_addr, pid);
if (ret < 0) {
@ -3809,7 +3809,7 @@ extract_hostname_path_from_token(const char *tmp_words, char **hostname,
ret = -1;
goto out;
}
if (!valid_internet_address(host_name, _gf_false)) {
if (!valid_internet_address(host_name, _gf_false, _gf_false)) {
cli_err(
"internet address '%s' does not conform to "
"standards",

View File

@ -60,7 +60,7 @@ cli_cmd_peer_probe_cbk(struct cli_state *state, struct cli_cmd_word *word,
if (ret)
goto out;
ret = valid_internet_address((char *)words[2], _gf_false);
ret = valid_internet_address((char *)words[2], _gf_false, _gf_false);
if (ret == 1) {
ret = 0;
} else {

View File

@ -2090,7 +2090,7 @@ out:
* @ip_str : The IP to check
* @network: The network to check the IP against.
*
* @return: success: 0
* @return: success: _gf_true
* failure: -EINVAL for bad args, retval of inet_pton otherwise
*/
gf_boolean_t
@ -2457,6 +2457,31 @@ out:
return ret;
}
char
valid_cidr_address(char *cidr_address, gf_boolean_t wildcard_acc)
{
unsigned int net_mask = 0, len = 0;
char *temp = NULL, *cidr_str = NULL, ret = 1;
cidr_str = strdupa(cidr_address);
temp = strstr(cidr_str, "/");
if (temp == NULL)
return 0; /* Since Invalid cidr ip address we return 0 */
*temp = '\0';
temp++;
net_mask = (unsigned int)atoi(temp);
if (net_mask > 32 || net_mask < 1)
return 0; /* Since Invalid cidr ip address we return 0*/
len = strlen(cidr_str);
ret = valid_ipv4_address(cidr_str, len, wildcard_acc);
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
@ -2593,7 +2618,8 @@ out:
}
char
valid_internet_address(char *address, gf_boolean_t wildcard_acc)
valid_internet_address(char *address, gf_boolean_t wildcard_acc,
gf_boolean_t cidr)
{
char ret = 0;
int length = 0;
@ -2608,6 +2634,10 @@ valid_internet_address(char *address, gf_boolean_t wildcard_acc)
if (length == 0)
goto out;
if (cidr && valid_cidr_address(address, wildcard_acc)) {
ret = 1;
}
if (valid_ipv4_address(address, length, wildcard_acc) ||
valid_ipv6_address(address, length, wildcard_acc) ||
valid_host_name(address, length))

View File

@ -875,7 +875,8 @@ valid_ipv4_address(char *address, int length, gf_boolean_t wildcard_acc);
char
valid_ipv6_address(char *address, int length, gf_boolean_t wildcard_acc);
char
valid_internet_address(char *address, gf_boolean_t wildcard_acc);
valid_internet_address(char *address, gf_boolean_t wildcard_acc,
gf_boolean_t cidr);
gf_boolean_t
valid_mount_auth_address(char *address);
gf_boolean_t

View File

@ -551,7 +551,7 @@ xlator_option_validate_addr(xlator_t *xl, const char *key, const char *value,
int ret = -1;
char errstr[256];
if (!valid_internet_address((char *)value, _gf_false)) {
if (!valid_internet_address((char *)value, _gf_false, _gf_false)) {
snprintf(errstr, 256, "option %s %s: Can not parse %s address", key,
value, value);
gf_msg(xl->name, GF_LOG_ERROR, 0, LG_MSG_INVALID_ENTRY, "%s", errstr);
@ -592,7 +592,7 @@ xlator_option_validate_addr_list(xlator_t *xl, const char *key,
/* Possible old format, handle it for back-ward compatibility */
addr_tok = strtok_r(dup_val, ",", &save_ptr);
while (addr_tok) {
if (!valid_internet_address(addr_tok, _gf_true))
if (!valid_internet_address(addr_tok, _gf_true, _gf_true))
goto out;
addr_tok = strtok_r(NULL, ",", &save_ptr);
@ -627,7 +627,7 @@ xlator_option_validate_addr_list(xlator_t *xl, const char *key,
if (addr_tok == NULL)
goto out;
while (addr_tok) {
if (!valid_internet_address(addr_tok, _gf_true))
if (!valid_internet_address(addr_tok, _gf_true, _gf_true))
goto out;
addr_tok = strtok_r(NULL, "|", &save_ptr);

25
tests/bugs/bug-1138841.t Normal file
View File

@ -0,0 +1,25 @@
#!/bin/bash
. $(dirname $0)/../include.rc
. $(dirname $0)/../volume.rc
. $(dirname $0)/../dht.rc
cleanup;
TEST glusterd
TEST pidof glusterd
## Create a volume and set auth.allow using cidr format ip
TEST $CLI volume create $V0 $H0:$B0/${V0}{0,1}
TEST $CLI volume set $V0 auth.allow 127.0.0.1/20
TEST $CLI volume start $V0
## mount the volume and create a file on the mount point
TEST $GFS --volfile-server=$H0 --volfile-id=$V0 $M0
TEST touch $M0/tmp1
## Stop the volume and do the cleanup
TEST $CLI volume stop $V0
cleanup

View File

@ -95,7 +95,7 @@ gf_quiesce_populate_failover_hosts(xlator_t *this, quiesce_priv_t *priv,
__gf_quiesce_cleanup_failover_hosts(this, priv);
addr_tok = strtok_r(dup_val, ",", &save_ptr);
while (addr_tok) {
if (!valid_internet_address(addr_tok, _gf_true)) {
if (!valid_internet_address(addr_tok, _gf_true, _gf_false)) {
gf_msg(this->name, GF_LOG_INFO, 0, QUIESCE_MSG_INVAL_HOST,
"Specified "
"invalid internet address:%s",

View File

@ -65,10 +65,18 @@ compare_addr_and_update(char *option_str, char *peer_addr, char *subvol,
goto out;
}
} else {
match = fnmatch(addr_str, peer_addr, 0);
if (negate ? match : !match) {
*result = status;
goto out;
if (strstr(addr_str, "/")) {
match = gf_is_ip_in_net(addr_str, peer_addr);
if (negate ? !match : match) {
*result = status;
goto out;
}
} else {
match = fnmatch(addr_str, peer_addr, 0);
if (negate ? match : !match) {
*result = status;
goto out;
}
}
}