From 28209283a67f13802cc0c1d3df07c676926810a2 Mon Sep 17 00:00:00 2001 From: Raghavendra Bhat Date: Fri, 19 Apr 2013 12:27:03 +0530 Subject: protocol/server: do not do root-squashing for trusted clients * As of now clients mounting within the storage pool using that machine's ip/hostname are trusted clients (i.e clients local to the glusterd). * Be careful when the request itself comes in as nfsnobody (ex: posix tests). So move the squashing part to protocol/server when it creates a new frame for the request, instead of auth part of rpc layer. * For nfs servers do root-squashing without checking if it is trusted client, as all the nfs servers would be running within the storage pool, hence will be trusted clients for the bricks. * Provide one more option for mounting which actually says root-squash should/should not happen. This value is given priority only for the trusted clients. For non trusted clients, the volume option takes the priority. But for trusted clients if root-squash should not happen, then they have to be mounted with root-squash=no option. (This is done because by default blocking root-squashing for the trusted clients will cause problems for smb and UFO clients for which the requests have to be squashed if the option is enabled). * For geo-replication and defrag clients do not do root-squashing. * Introduce a new option in open-behind for doing read after successful open. Change-Id: I8a8359840313dffc34824f3ea80a9c48375067f0 BUG: 954057 Signed-off-by: Raghavendra Bhat Reviewed-on: http://review.gluster.org/4863 Tested-by: Gluster Build System Reviewed-by: Vijay Bellur --- xlators/protocol/server/src/server-handshake.c | 2 + xlators/protocol/server/src/server-helpers.c | 157 +++++++++++++++++++++++++ xlators/protocol/server/src/server-helpers.h | 2 + 3 files changed, 161 insertions(+) (limited to 'xlators/protocol/server') diff --git a/xlators/protocol/server/src/server-handshake.c b/xlators/protocol/server/src/server-handshake.c index d4941011da9..708acd936d9 100644 --- a/xlators/protocol/server/src/server-handshake.c +++ b/xlators/protocol/server/src/server-handshake.c @@ -448,6 +448,8 @@ server_setvolume (rpcsvc_request_t *req) if (req->trans->xl_private != client) req->trans->xl_private = client; + auth_set_username_passwd (params, config_params, client); + ret = dict_get_int32 (params, "fops-version", &fop_version); if (ret < 0) { ret = dict_set_str (reply, "ERROR", diff --git a/xlators/protocol/server/src/server-helpers.c b/xlators/protocol/server/src/server-helpers.c index b2b6c486fe1..c11011abf9f 100644 --- a/xlators/protocol/server/src/server-helpers.c +++ b/xlators/protocol/server/src/server-helpers.c @@ -302,6 +302,11 @@ get_frame_from_request (rpcsvc_request_t *req) { call_frame_t *frame = NULL; client_t *client = NULL; + client_t *tmp_client = NULL; + xlator_t *this = NULL; + server_conf_t *priv = NULL; + clienttable_t *clienttable = NULL; + unsigned int i = 0; GF_VALIDATE_OR_GOTO ("server", req, out); @@ -315,6 +320,57 @@ get_frame_from_request (rpcsvc_request_t *req) frame->root->unique = req->xid; + client = req->trans->xl_private; + this = req->trans->xl; + priv = this->private; + clienttable = this->ctx->clienttable; + + for (i = 0; i < clienttable->max_clients; i++) { + tmp_client = clienttable->cliententries[i].client; + if (client == tmp_client) { + /* for non trusted clients username and password + would not have been set. So for non trusted clients + (i.e clients not from the same machine as the brick, + and clients from outside the storage pool) + do the root-squashing. + TODO: If any client within the storage pool (i.e + mounting within a machine from the pool but using + other machine's ip/hostname from the same pool) + is present treat it as a trusted client + */ + if (!client->auth.username && req->pid != NFS_PID) + RPC_AUTH_ROOT_SQUASH (req); + + /* Problem: If we just check whether the client is + trusted client and do not do root squashing for + them, then for smb clients and UFO clients root + squashing will never happen as they use the fuse + mounts done within the trusted pool (i.e they are + trusted clients). + Solution: To fix it, do root squashing for trusted + clients also. If one wants to have a client within + the storage pool for which root-squashing does not + happen, then the client has to be mounted with + --no-root-squash option. But for defrag client and + gsyncd client do not do root-squashing. + */ + if (client->auth.username && + req->pid != GF_CLIENT_PID_NO_ROOT_SQUASH && + req->pid != GF_CLIENT_PID_GSYNCD && + req->pid != GF_CLIENT_PID_DEFRAG) + RPC_AUTH_ROOT_SQUASH (req); + + /* For nfs clients the server processes will be running + within the trusted storage pool machines. So if we + do not do root-squashing for nfs servers, thinking + that its a trusted client, then root-squashing wont + work for nfs clients. + */ + if (req->pid == NFS_PID) + RPC_AUTH_ROOT_SQUASH (req); + } + } + frame->root->uid = req->uid; frame->root->gid = req->gid; frame->root->pid = req->pid; @@ -935,3 +991,104 @@ server_ctx_get (client_t *client, xlator_t *xlator) out: return ctx; } + +int +auth_set_username_passwd (dict_t *input_params, dict_t *config_params, + client_t *client) +{ + int ret = 0; + data_t *allow_user = NULL; + data_t *passwd_data = NULL; + char *username = NULL; + char *password = NULL; + char *brick_name = NULL; + char *searchstr = NULL; + char *username_str = NULL; + char *tmp = NULL; + char *username_cpy = NULL; + + ret = dict_get_str (input_params, "username", &username); + if (ret) { + gf_log ("auth/login", GF_LOG_DEBUG, + "username not found, returning DONT-CARE"); + /* For non trusted clients username and password + will not be there. So dont reject the client. + */ + ret = 0; + goto out; + } + + ret = dict_get_str (input_params, "password", &password); + if (ret) { + gf_log ("auth/login", GF_LOG_WARNING, + "password not found, returning DONT-CARE"); + goto out; + } + + ret = dict_get_str (input_params, "remote-subvolume", &brick_name); + if (ret) { + gf_log ("auth/login", GF_LOG_ERROR, + "remote-subvolume not specified"); + ret = -1; + goto out; + } + + ret = gf_asprintf (&searchstr, "auth.login.%s.allow", brick_name); + if (-1 == ret) { + ret = 0; + goto out; + } + + allow_user = dict_get (config_params, searchstr); + GF_FREE (searchstr); + + if (allow_user) { + username_cpy = gf_strdup (allow_user->data); + if (!username_cpy) + goto out; + + username_str = strtok_r (username_cpy, " ,", &tmp); + + while (username_str) { + if (!fnmatch (username_str, username, 0)) { + ret = gf_asprintf (&searchstr, + "auth.login.%s.password", + username); + if (-1 == ret) + goto out; + + passwd_data = dict_get (config_params, + searchstr); + GF_FREE (searchstr); + + if (!passwd_data) { + gf_log ("auth/login", GF_LOG_ERROR, + "wrong username/password " + "combination"); + ret = -1; + goto out; + } + + ret = !((strcmp (data_to_str (passwd_data), + password))?0: -1); + if (!ret) { + client->auth.username = + gf_strdup (username); + client->auth.passwd = + gf_strdup (password); + } + if (ret == -1) + gf_log ("auth/login", GF_LOG_ERROR, + "wrong password for user %s", + username); + break; + } + username_str = strtok_r (NULL, " ,", &tmp); + } + } + +out: + GF_FREE (username_cpy); + + return ret; +} diff --git a/xlators/protocol/server/src/server-helpers.h b/xlators/protocol/server/src/server-helpers.h index 93ea3585102..3c257b3bcef 100644 --- a/xlators/protocol/server/src/server-helpers.h +++ b/xlators/protocol/server/src/server-helpers.h @@ -53,6 +53,8 @@ int serialize_rsp_dirent (gf_dirent_t *entries, gfs3_readdir_rsp *rsp); int serialize_rsp_direntp (gf_dirent_t *entries, gfs3_readdirp_rsp *rsp); int readdirp_rsp_cleanup (gfs3_readdirp_rsp *rsp); int readdir_rsp_cleanup (gfs3_readdir_rsp *rsp); +int auth_set_username_passwd (dict_t *input_params, dict_t *config_params, + struct _client_t *client); server_ctx_t *server_ctx_get (client_t *client, xlator_t *xlator); -- cgit