e7a346
From bceb9586b96cbf3e0f1747affa6f56cfe29ac140 Mon Sep 17 00:00:00 2001
e7a346
From: Mohammed Rafi KC <rkavunga@redhat.com>
e7a346
Date: Mon, 2 Apr 2018 12:20:47 +0530
e7a346
Subject: [PATCH 241/260] server/auth: add option for strict authentication
e7a346
e7a346
When this option is enabled, we will check for a matching
e7a346
username and password, if not found then the connection will
e7a346
be rejected. This also does a checksum validation of volfile
e7a346
e7a346
The option is invalid when SSL/TLS is in use, at which point
e7a346
the SSL/TLS certificate user name is used to validate and
e7a346
hence authorize the right user. This expects TLS allow rules
e7a346
to be setup correctly rather than the default *.
e7a346
e7a346
This option is not settable, as a result this cannot be enabled
e7a346
for volumes using the CLI. This is used with the shared storage
e7a346
volume, to restrict access to the same in non-SSL/TLS environments
e7a346
to the gluster peers only.
e7a346
e7a346
Tested:
e7a346
  ./tests/bugs/protocol/bug-1321578.t
e7a346
  ./tests/features/ssl-authz.t
e7a346
  - Ran tests on volumes with and without strict auth
e7a346
    checking (as brick vol file needed to be edited to test,
e7a346
    or rather to enable the option)
e7a346
  - Ran tests on volumes to ensure existing mounts are
e7a346
    disconnected when we enable strict checking
e7a346
e7a346
backport of upstream https://review.gluster.org/#/c/19921/
e7a346
e7a346
>Change-Id: I2ac4f0cfa5b59cc789cc5a265358389b04556b59
e7a346
>fixes: bz#1570432
e7a346
>Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e7a346
>Signed-off-by: ShyamsundarR <srangana@redhat.com>
e7a346
e7a346
Change-Id: I7fd3194b91ba22d57b851a2a042ff16b9a616a5a
e7a346
BUG: 1568969
e7a346
Signed-off-by: Mohammed Rafi KC <rkavunga@redhat.com>
e7a346
Reviewed-on: https://code.engineering.redhat.com/gerrit/136709
e7a346
Tested-by: RHGS Build Bot <nigelb@redhat.com>
e7a346
Reviewed-by: Atin Mukherjee <amukherj@redhat.com>
e7a346
---
e7a346
 xlators/mgmt/glusterd/src/glusterd-volgen.c    | 16 +++++++-
e7a346
 xlators/protocol/auth/login/src/login.c        | 51 ++++++++++++++++++++++----
e7a346
 xlators/protocol/server/src/authenticate.h     |  4 +-
e7a346
 xlators/protocol/server/src/server-handshake.c |  2 +-
e7a346
 xlators/protocol/server/src/server.c           | 18 +++++++++
e7a346
 xlators/protocol/server/src/server.h           |  2 +
e7a346
 6 files changed, 81 insertions(+), 12 deletions(-)
e7a346
e7a346
diff --git a/xlators/mgmt/glusterd/src/glusterd-volgen.c b/xlators/mgmt/glusterd/src/glusterd-volgen.c
e7a346
index 1c43f24..3926bd3 100644
e7a346
--- a/xlators/mgmt/glusterd/src/glusterd-volgen.c
e7a346
+++ b/xlators/mgmt/glusterd/src/glusterd-volgen.c
e7a346
@@ -2341,6 +2341,7 @@ brick_graph_add_server (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
e7a346
         char            *password = NULL;
e7a346
         char            key[1024] = {0};
e7a346
         char            *ssl_user = NULL;
e7a346
+        char            *volname = NULL;
e7a346
         char            *address_family_data = NULL;
e7a346
 
e7a346
         if (!graph || !volinfo || !set_dict || !brickinfo)
e7a346
@@ -2416,6 +2417,19 @@ brick_graph_add_server (volgen_graph_t *graph, glusterd_volinfo_t *volinfo,
e7a346
         if (ret)
e7a346
                 return -1;
e7a346
 
e7a346
+        volname = volinfo->is_snap_volume ?
e7a346
+                  volinfo->parent_volname : volinfo->volname;
e7a346
+
e7a346
+
e7a346
+        if (volname && !strcmp (volname, GLUSTER_SHARED_STORAGE)) {
e7a346
+                memset (key, 0, sizeof (key));
e7a346
+                snprintf (key, sizeof (key), "strict-auth-accept");
e7a346
+
e7a346
+                ret = xlator_set_option (xl, key, "true");
e7a346
+                if (ret)
e7a346
+                        return -1;
e7a346
+        }
e7a346
+
e7a346
         if (dict_get_str (volinfo->dict, "auth.ssl-allow", &ssl_user) == 0) {
e7a346
                 memset (key, 0, sizeof (key));
e7a346
                 snprintf (key, sizeof (key), "auth.login.%s.ssl-allow",
e7a346
@@ -5841,7 +5855,7 @@ generate_client_volfiles (glusterd_volinfo_t *volinfo,
e7a346
 
e7a346
 
e7a346
         if (volname && !strcmp (volname, GLUSTER_SHARED_STORAGE) &&
e7a346
-             client_type != GF_CLIENT_TRUSTED) {
e7a346
+            client_type != GF_CLIENT_TRUSTED) {
e7a346
                 /*
e7a346
                  * shared storage volume cannot be mounted from non trusted
e7a346
                  * nodes. So we are not creating volfiles for non-trusted
e7a346
diff --git a/xlators/protocol/auth/login/src/login.c b/xlators/protocol/auth/login/src/login.c
e7a346
index e799dd2..da10d0b 100644
e7a346
--- a/xlators/protocol/auth/login/src/login.c
e7a346
+++ b/xlators/protocol/auth/login/src/login.c
e7a346
@@ -11,6 +11,16 @@
e7a346
 #include <fnmatch.h>
e7a346
 #include "authenticate.h"
e7a346
 
e7a346
+/* Note on strict_auth
e7a346
+ * - Strict auth kicks in when authentication is using the username, password
e7a346
+ *   in the volfile to login
e7a346
+ * - If enabled, auth is rejected if the username and password is not matched
e7a346
+ *   or is not present
e7a346
+ * - When using SSL names, this is automatically strict, and allows only those
e7a346
+ *   names that are present in the allow list, IOW strict auth checking has no
e7a346
+ *   implication when using SSL names
e7a346
+*/
e7a346
+
e7a346
 auth_result_t gf_auth (dict_t *input_params, dict_t *config_params)
e7a346
 {
e7a346
         auth_result_t  result  = AUTH_DONT_CARE;
e7a346
@@ -27,6 +37,7 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params)
e7a346
         char            *tmp            = NULL;
e7a346
         char            *username_cpy   = NULL;
e7a346
         gf_boolean_t    using_ssl       = _gf_false;
e7a346
+        gf_boolean_t    strict_auth     = _gf_false;
e7a346
 
e7a346
         username_data = dict_get (input_params, "ssl-name");
e7a346
         if (username_data) {
e7a346
@@ -35,16 +46,39 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params)
e7a346
                 using_ssl = _gf_true;
e7a346
         }
e7a346
         else {
e7a346
+                ret = dict_get_str_boolean (config_params, "strict-auth-accept",
e7a346
+                                            _gf_false);
e7a346
+                if (ret == -1)
e7a346
+                        strict_auth = _gf_false;
e7a346
+                else
e7a346
+                        strict_auth = ret;
e7a346
+
e7a346
                 username_data = dict_get (input_params, "username");
e7a346
                 if (!username_data) {
e7a346
-                        gf_log ("auth/login", GF_LOG_DEBUG,
e7a346
-                                "username not found, returning DONT-CARE");
e7a346
+                        if (strict_auth) {
e7a346
+                                gf_log ("auth/login", GF_LOG_DEBUG,
e7a346
+                                        "username not found, strict auth"
e7a346
+                                        " configured returning REJECT");
e7a346
+                                result = AUTH_REJECT;
e7a346
+                        } else {
e7a346
+                                gf_log ("auth/login", GF_LOG_DEBUG,
e7a346
+                                        "username not found, returning"
e7a346
+                                        " DONT-CARE");
e7a346
+                        }
e7a346
                         goto out;
e7a346
                 }
e7a346
                 password_data = dict_get (input_params, "password");
e7a346
                 if (!password_data) {
e7a346
-                        gf_log ("auth/login", GF_LOG_WARNING,
e7a346
-                                "password not found, returning DONT-CARE");
e7a346
+                        if (strict_auth) {
e7a346
+                                gf_log ("auth/login", GF_LOG_DEBUG,
e7a346
+                                        "password not found, strict auth"
e7a346
+                                        " configured returning REJECT");
e7a346
+                                result = AUTH_REJECT;
e7a346
+                        } else {
e7a346
+                                gf_log ("auth/login", GF_LOG_WARNING,
e7a346
+                                        "password not found, returning"
e7a346
+                                        " DONT-CARE");
e7a346
+                        }
e7a346
                         goto out;
e7a346
                 }
e7a346
                 password = data_to_str (password_data);
e7a346
@@ -62,9 +96,10 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params)
e7a346
         ret = gf_asprintf (&searchstr, "auth.login.%s.%s", brick_name,
e7a346
                            using_ssl ? "ssl-allow" : "allow");
e7a346
         if (-1 == ret) {
e7a346
-                gf_log ("auth/login", GF_LOG_WARNING,
e7a346
+                gf_log ("auth/login", GF_LOG_ERROR,
e7a346
                         "asprintf failed while setting search string, "
e7a346
-                        "returning DONT-CARE");
e7a346
+                        "returning REJECT");
e7a346
+                result = AUTH_REJECT;
e7a346
                 goto out;
e7a346
         }
e7a346
 
e7a346
@@ -92,8 +127,10 @@ auth_result_t gf_auth (dict_t *input_params, dict_t *config_params)
e7a346
                  * ssl-allow=* case as well) authorization is effectively
e7a346
                  * disabled, though authentication and encryption are still
e7a346
                  * active.
e7a346
+                 *
e7a346
+                 * Read NOTE on strict_auth above.
e7a346
                  */
e7a346
-                if (using_ssl) {
e7a346
+                if (using_ssl || strict_auth) {
e7a346
                         result = AUTH_REJECT;
e7a346
                 }
e7a346
                 username_cpy = gf_strdup (allow_user->data);
e7a346
diff --git a/xlators/protocol/server/src/authenticate.h b/xlators/protocol/server/src/authenticate.h
e7a346
index 3f80231..5f92183 100644
e7a346
--- a/xlators/protocol/server/src/authenticate.h
e7a346
+++ b/xlators/protocol/server/src/authenticate.h
e7a346
@@ -37,10 +37,8 @@ typedef struct {
e7a346
         volume_opt_list_t *vol_opt;
e7a346
 } auth_handle_t;
e7a346
 
e7a346
-auth_result_t gf_authenticate (dict_t *input_params,
e7a346
-                               dict_t *config_params,
e7a346
-                               dict_t *auth_modules);
e7a346
 int32_t gf_auth_init (xlator_t *xl, dict_t *auth_modules);
e7a346
 void gf_auth_fini (dict_t *auth_modules);
e7a346
+auth_result_t gf_authenticate (dict_t *, dict_t *, dict_t *);
e7a346
 
e7a346
 #endif /* _AUTHENTICATE_H */
e7a346
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
e7a346
index cbc93a3..fc63f2c 100644
e7a346
--- a/xlators/protocol/server/src/server-handshake.c
e7a346
+++ b/xlators/protocol/server/src/server-handshake.c
e7a346
@@ -747,7 +747,7 @@ server_setvolume (rpcsvc_request_t *req)
e7a346
                         ret = dict_get_str (params, "volfile-key",
e7a346
                                             &volfile_key);
e7a346
                         if (ret)
e7a346
-                                gf_msg_debug (this->name, 0, "failed to set "
e7a346
+                                gf_msg_debug (this->name, 0, "failed to get "
e7a346
                                               "'volfile-key'");
e7a346
 
e7a346
                         ret = _validate_volfile_checksum (this, volfile_key,
e7a346
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
e7a346
index eed4295..6f20a06 100644
e7a346
--- a/xlators/protocol/server/src/server.c
e7a346
+++ b/xlators/protocol/server/src/server.c
e7a346
@@ -943,6 +943,10 @@ do_rpc:
e7a346
                 goto out;
e7a346
         }
e7a346
 
e7a346
+        GF_OPTION_RECONF ("strict-auth-accept", conf->strict_auth_enabled,
e7a346
+                          options, bool, out);
e7a346
+
e7a346
+
e7a346
         GF_OPTION_RECONF ("dynamic-auth", conf->dync_auth, options,
e7a346
                         bool, out);
e7a346
 
e7a346
@@ -1183,6 +1187,14 @@ init (xlator_t *this)
e7a346
                         "Failed to initialize group cache.");
e7a346
                 goto out;
e7a346
         }
e7a346
+
e7a346
+        ret = dict_get_str_boolean (this->options, "strict-auth-accept",
e7a346
+                                    _gf_false);
e7a346
+        if (ret == -1)
e7a346
+                conf->strict_auth_enabled = _gf_false;
e7a346
+        else
e7a346
+                conf->strict_auth_enabled = ret;
e7a346
+
e7a346
         ret = dict_get_str_boolean (this->options, "dynamic-auth",
e7a346
                         _gf_true);
e7a346
         if (ret == -1)
e7a346
@@ -1840,5 +1852,11 @@ struct volume_options options[] = {
e7a346
                            "transport connection immediately in response to "
e7a346
                            "*.allow | *.reject volume set options."
e7a346
         },
e7a346
+        { .key   = {"strict-auth-accept"},
e7a346
+          .type  = GF_OPTION_TYPE_BOOL,
e7a346
+          .default_value = "off",
e7a346
+          .description   = "strict-auth-accept reject connection with out"
e7a346
+                           "a valid username and password."
e7a346
+        },
e7a346
         { .key   = {NULL} },
e7a346
 };
e7a346
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
e7a346
index af987aa..691c75b 100644
e7a346
--- a/xlators/protocol/server/src/server.h
e7a346
+++ b/xlators/protocol/server/src/server.h
e7a346
@@ -24,6 +24,7 @@
e7a346
 #include "client_t.h"
e7a346
 #include "gidcache.h"
e7a346
 #include "defaults.h"
e7a346
+#include "authenticate.h"
e7a346
 
e7a346
 #define DEFAULT_BLOCK_SIZE         4194304   /* 4MB */
e7a346
 #define DEFAULT_VOLUME_FILE_PATH   CONFDIR "/glusterfs.vol"
e7a346
@@ -109,6 +110,7 @@ struct server_conf {
e7a346
                                             * tweeked */
e7a346
         struct _child_status    *child_status;
e7a346
         gf_lock_t               itable_lock;
e7a346
+        gf_boolean_t            strict_auth_enabled;
e7a346
 };
e7a346
 typedef struct server_conf server_conf_t;
e7a346
 
e7a346
-- 
e7a346
1.8.3.1
e7a346