summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tests/bugs/bug-1109741-auth-mgmt-handshake.t50
-rwxr-xr-xtests/cluster.rc12
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-handshake.c49
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.c14
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-utils.h3
5 files changed, 124 insertions, 4 deletions
diff --git a/tests/bugs/bug-1109741-auth-mgmt-handshake.t b/tests/bugs/bug-1109741-auth-mgmt-handshake.t
new file mode 100644
index 00000000000..42a8eb3ed82
--- /dev/null
+++ b/tests/bugs/bug-1109741-auth-mgmt-handshake.t
@@ -0,0 +1,50 @@
+#! /bin/bash
+
+. $(dirname $0)/../include.rc
+. $(dirname $0)/../cluster.rc
+
+# The test will attempt to verify that management handshake requests to
+# GlusterD are authenticated before being allowed to change a GlusterD's
+# op-version
+#
+# 1. Launch 3 glusterds
+# 2. Probe 2 of them to form a cluster. This should succeed.
+# 3. Probe either of the first two GlusterD's from the 3rd GlusterD. This should fail.
+# 4. a. Reduce the op-version of 3rd GlusterD and restart it.
+# b. Probe either of the first two GlusterD's from the 3rd GlusterD. This should fail.
+# 5. Check current op-version of first two GlusterDs. It shouldn't have changed.
+# 6. Probe third GlusterD from the cluster. This should succeed.
+
+
+cleanup
+
+TEST launch_cluster 3
+
+TEST $CLI_1 peer probe $H2
+
+TEST ! $CLI_3 peer probe $H1
+
+GD1_WD=$($CLI_1 system getwd)
+OP_VERS_ORIG=$(grep 'operating-version' ${GD1_WD}/glusterd.info | cut -d '=' -f 2)
+
+TEST $CLI_3 system uuid get # Needed for glusterd.info to be created
+
+GD3_WD=$($CLI_3 system getwd)
+TEST sed -rnie "'s/(operating-version=)\w+/\130600/gip'" ${GD3_WD}/glusterd.info
+
+TEST kill_glusterd 3
+TEST start_glusterd 3
+
+TEST ! $CLI_3 peer probe $H1
+
+OP_VERS_NEW=$(grep 'operating-version' ${GD1_WD}/glusterd.info | cut -d '=' -f 2)
+TEST [[ $OP_VERS_ORIG == $OP_VERS_NEW ]]
+
+TEST $CLI_1 peer probe $H3
+
+kill_node 1
+kill_node 2
+kill_node 3
+
+cleanup;
+
diff --git a/tests/cluster.rc b/tests/cluster.rc
index 42f3ad24434..5c821776156 100755
--- a/tests/cluster.rc
+++ b/tests/cluster.rc
@@ -61,13 +61,17 @@ function define_glusterds() {
done
}
+function start_glusterd() {
+ local g
+ local index=$1
-function start_glusterds() {
- local g;
+ g="glusterd_${index}"
+ ${!g}
+}
+function start_glusterds() {
for i in `seq 1 $CLUSTER_COUNT`; do
- g="glusterd_$i";
- ${!g};
+ start_glusterd $i
done
}
diff --git a/xlators/mgmt/glusterd/src/glusterd-handshake.c b/xlators/mgmt/glusterd/src/glusterd-handshake.c
index da3a01c99f8..7971f12bdac 100644
--- a/xlators/mgmt/glusterd/src/glusterd-handshake.c
+++ b/xlators/mgmt/glusterd/src/glusterd-handshake.c
@@ -881,6 +881,43 @@ out:
return ret;
}
+/* Validate if glusterd can serve the management handshake request
+ *
+ * Requests are allowed if,
+ * - glusterd has no peers, or
+ * - the request came from a known peer
+ */
+gf_boolean_t
+gd_validate_mgmt_hndsk_req (rpcsvc_request_t *req)
+{
+ int ret = -1;
+ char hostname[UNIX_PATH_MAX + 1] = {0,};
+ glusterd_peerinfo_t *peer = NULL;
+ xlator_t *this = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+
+ if (!glusterd_have_peers ())
+ return _gf_true;
+
+ /* If you cannot get the hostname, you cannot authenticate */
+ ret = glusterd_remote_hostname_get (req, hostname, sizeof (hostname));
+ if (ret)
+ return _gf_false;
+
+ peer = glusterd_peerinfo_find (NULL, hostname);
+ if (peer == NULL) {
+ ret = -1;
+ gf_log (this->name, GF_LOG_ERROR, "Rejecting management "
+ "handshake request from unknown peer %s",
+ req->trans->peerinfo.identifier);
+ return _gf_false;
+ }
+
+ return _gf_true;
+}
+
int
__glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req)
{
@@ -895,6 +932,12 @@ __glusterd_mgmt_hndsk_versions (rpcsvc_request_t *req)
this = THIS;
conf = this->private;
+ /* Check if we can service the request */
+ if (!gd_validate_mgmt_hndsk_req (req)) {
+ ret = -1;
+ goto out;
+ }
+
ret = xdr_to_generic (req->msg[0], &args,
(xdrproc_t)xdr_gf_mgmt_hndsk_req);
if (ret < 0) {
@@ -979,6 +1022,12 @@ __glusterd_mgmt_hndsk_versions_ack (rpcsvc_request_t *req)
this = THIS;
conf = this->private;
+ /* Check if we can service the request */
+ if (!gd_validate_mgmt_hndsk_req (req)) {
+ ret = -1;
+ goto out;
+ }
+
ret = xdr_to_generic (req->msg[0], &args,
(xdrproc_t)xdr_gf_mgmt_hndsk_req);
if (ret < 0) {
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.c b/xlators/mgmt/glusterd/src/glusterd-utils.c
index 375e58e3e87..34d59e1d225 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.c
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.c
@@ -13944,3 +13944,17 @@ glusterd_check_client_op_version_support (char *volname, uint32_t op_version,
}
return 0;
}
+
+gf_boolean_t
+glusterd_have_peers ()
+{
+ xlator_t *this = NULL;
+ glusterd_conf_t *conf = NULL;
+
+ this = THIS;
+ GF_ASSERT (this);
+ conf = this->private;
+ GF_ASSERT (conf);
+
+ return !list_empty (&conf->peers);
+}
diff --git a/xlators/mgmt/glusterd/src/glusterd-utils.h b/xlators/mgmt/glusterd/src/glusterd-utils.h
index 887e89661f4..605d7e05124 100644
--- a/xlators/mgmt/glusterd/src/glusterd-utils.h
+++ b/xlators/mgmt/glusterd/src/glusterd-utils.h
@@ -912,4 +912,7 @@ glusterd_get_default_val_for_volopt (dict_t *dict, gf_boolean_t all_opts,
int
glusterd_check_client_op_version_support (char *volname, uint32_t op_version,
char **op_errstr);
+
+gf_boolean_t
+glusterd_have_peers ();
#endif