summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPrasanna Kumar Kalever <prasanna.kalever@redhat.com>2015-08-21 00:08:23 +0530
committerRaghavendra G <rgowdapp@redhat.com>2015-10-04 22:31:05 -0700
commit84e90b756566bc211535a8627ed16d4231110ade (patch)
tree6ba6b529ecde0769100e7e2792be19e0316b4db2
parentfc33ed37ffddee9ac90b947a038ab3a93fbcab50 (diff)
server/protocol: option for dynamic authorization of client permissions
problem: assuming gluster volume is already mounted (for gfapi: say client transport connection has already established), now if somebody change the volume permissions say *.allow | *.reject for a client, gluster should allow/terminate the client connection based on the fresh set of volume options immediately, but in existing scenario neither we have any option to set this behaviour nor we take any action until and unless we remount the volume manually solution: Introduce 'dynamic-auth' option (default: on). If 'dynamic-auth' is 'on' gluster will perform dynamic authentication to allow/terminate client transport connection immediately in response to *.allow | *.reject volume set options, thus if volume permissions have changed for a particular client (say client is added to auth.reject list), his transport connection to gluster volume will be terminated immediately. Change-Id: I6243a6db41bf1e0babbf050a8e4f8620732e00d8 BUG: 1245380 Signed-off-by: Prasanna Kumar Kalever <prasanna.kalever@redhat.com> Reviewed-on: http://review.gluster.org/12229 Tested-by: NetBSD Build System <jenkins@build.gluster.org> Reviewed-by: Raghavendra G <rgowdapp@redhat.com>
-rw-r--r--rpc/rpc-lib/src/rpc-transport.c2
-rw-r--r--rpc/rpc-lib/src/rpc-transport.h2
-rw-r--r--xlators/mgmt/glusterd/src/glusterd-volume-set.c4
-rw-r--r--xlators/protocol/server/src/server-handshake.c2
-rw-r--r--xlators/protocol/server/src/server.c55
-rw-r--r--xlators/protocol/server/src/server.h4
6 files changed, 65 insertions, 4 deletions
diff --git a/rpc/rpc-lib/src/rpc-transport.c b/rpc/rpc-lib/src/rpc-transport.c
index 197c1682027..0f1351fe91a 100644
--- a/rpc/rpc-lib/src/rpc-transport.c
+++ b/rpc/rpc-lib/src/rpc-transport.c
@@ -458,6 +458,8 @@ rpc_transport_destroy (rpc_transport_t *this)
GF_VALIDATE_OR_GOTO("rpc_transport", this, fail);
+ if (this->clnt_options)
+ dict_unref (this->clnt_options);
if (this->options)
dict_unref (this->options);
if (this->fini)
diff --git a/rpc/rpc-lib/src/rpc-transport.h b/rpc/rpc-lib/src/rpc-transport.h
index df0bab5dc43..227911a5935 100644
--- a/rpc/rpc-lib/src/rpc-transport.h
+++ b/rpc/rpc-lib/src/rpc-transport.h
@@ -210,6 +210,8 @@ struct rpc_transport {
int bind_insecure;
void *dl_handle; /* handle of dlopen() */
char *ssl_name;
+ dict_t *clnt_options; /* store options received from
+ * client */
};
struct rpc_transport_ops {
diff --git a/xlators/mgmt/glusterd/src/glusterd-volume-set.c b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
index 5b347eace9f..c18bc5d5a76 100644
--- a/xlators/mgmt/glusterd/src/glusterd-volume-set.c
+++ b/xlators/mgmt/glusterd/src/glusterd-volume-set.c
@@ -1086,6 +1086,10 @@ struct volopt_map_entry glusterd_volopt_map[] = {
.voltype = "protocol/server",
.op_version = GD_OP_VERSION_3_6_0,
},
+ { .key = "server.dynamic-auth",
+ .voltype = "protocol/server",
+ .op_version = GD_OP_VERSION_3_7_5,
+ },
{ .key = "client.send-gids",
.voltype = "protocol/client",
.type = NO_DOC,
diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c
index 40cc684e1ba..62d9368e33a 100644
--- a/xlators/protocol/server/src/server-handshake.c
+++ b/xlators/protocol/server/src/server-handshake.c
@@ -598,6 +598,8 @@ server_setvolume (rpcsvc_request_t *req)
conf->auth_modules);
if (ret == AUTH_ACCEPT) {
+ /* Store options received from client side */
+ req->trans->clnt_options = dict_ref(params);
gf_msg (this->name, GF_LOG_INFO, 0, PS_MSG_CLIENT_ACCEPTED,
"accepted client from %s (version: %s)",
diff --git a/xlators/protocol/server/src/server.c b/xlators/protocol/server/src/server.c
index a98b609da39..bcfa1f3fe0f 100644
--- a/xlators/protocol/server/src/server.c
+++ b/xlators/protocol/server/src/server.c
@@ -710,6 +710,7 @@ reconfigure (xlator_t *this, dict_t *options)
server_conf_t *conf =NULL;
rpcsvc_t *rpc_conf;
rpcsvc_listener_t *listeners;
+ rpc_transport_t *xprt = NULL;
int inode_lru_limit;
gf_boolean_t trace;
data_t *data;
@@ -778,6 +779,7 @@ reconfigure (xlator_t *this, dict_t *options)
/* logging already done in validate_auth_options function. */
goto out;
}
+
dict_foreach (this->options, _delete_auth_opt, this->options);
dict_foreach (options, _copy_auth_opt, this->options);
@@ -805,8 +807,41 @@ reconfigure (xlator_t *this, dict_t *options)
goto out;
}
- (void) rpcsvc_set_allow_insecure (rpc_conf, options);
- (void) rpcsvc_set_root_squash (rpc_conf, options);
+ ret = rpcsvc_auth_reconf (rpc_conf, options);
+ if (ret == -1) {
+ gf_log (GF_RPCSVC, GF_LOG_ERROR,
+ "Failed to reconfigure authentication");
+ goto out;
+ }
+
+ GF_OPTION_RECONF ("dynamic-auth", conf->dync_auth, options,
+ bool, out);
+
+ if (conf->dync_auth) {
+ pthread_mutex_lock (&conf->mutex);
+ {
+ list_for_each_entry (xprt, &conf->xprt_list, list) {
+ /* check for client authorization */
+ ret = gf_authenticate (xprt->clnt_options,
+ options, conf->auth_modules);
+ if (ret == AUTH_ACCEPT) {
+ gf_msg (this->name, GF_LOG_TRACE, 0,
+ PS_MSG_CLIENT_ACCEPTED,
+ "authorized client, hence we "
+ "continue with this connection");
+ } else {
+ gf_msg (this->name, GF_LOG_INFO,
+ EACCES,
+ PS_MSG_AUTHENTICATE_ERROR,
+ "unauthorized client, hence "
+ "terminating the connection %s",
+ xprt->peerinfo.identifier);
+ rpc_transport_disconnect(xprt);
+ }
+ }
+ }
+ pthread_mutex_unlock (&conf->mutex);
+ }
ret = rpcsvc_set_outstanding_rpc_limit (rpc_conf, options,
RPCSVC_DEFAULT_OUTSTANDING_RPC_LIMIT);
@@ -957,6 +992,12 @@ init (xlator_t *this)
"Failed to initialize group cache.");
goto out;
}
+ ret = dict_get_str_boolean (this->options, "dynamic-auth",
+ _gf_true);
+ if (ret == -1)
+ conf->dync_auth = _gf_true;
+ else
+ conf->dync_auth = ret;
/* RPC related */
conf->rpc = rpcsvc_init (this, this->ctx, this->options, 0);
@@ -1364,7 +1405,6 @@ struct volume_options options[] = {
"requests from a client. 0 means no limit (can "
"potentially run out of memory)"
},
-
{ .key = {"manage-gids"},
.type = GF_OPTION_TYPE_BOOL,
.default_value = "off",
@@ -1385,6 +1425,13 @@ struct volume_options options[] = {
" responses faster, depending on available processing"
" power. Range 1-32 threads."
},
-
+ { .key = {"dynamic-auth"},
+ .type = GF_OPTION_TYPE_BOOL,
+ .default_value = "on",
+ .description = "When 'on' perform dynamic authentication of volume "
+ "options in order to allow/terminate client "
+ "transport connection immediately in response to "
+ "*.allow | *.reject volume set options."
+ },
{ .key = {NULL} },
};
diff --git a/xlators/protocol/server/src/server.h b/xlators/protocol/server/src/server.h
index dd80ab75f60..ccd2b232207 100644
--- a/xlators/protocol/server/src/server.h
+++ b/xlators/protocol/server/src/server.h
@@ -68,6 +68,10 @@ struct server_conf {
* configured */
gf_boolean_t parent_up;
+ gf_boolean_t dync_auth; /* if set authenticate dynamically,
+ * in case if volume set options
+ * (say *.allow | *.reject) are
+ * tweeked */
};
typedef struct server_conf server_conf_t;