From 37db778f48f952747575e323cb341ed663852fff Mon Sep 17 00:00:00 2001 From: Kit Westneat Date: Fri, 14 Apr 2017 11:06:02 -0400 Subject: [PATCH] LU-9145 nodemap: new_init_ucred doesn't do nodemapping The new_init_ucred path was missed in the original nodemap implementation. This patch adds the mapping calls to new_init_ucred. WIP: There are some issues/questions: - some of the new_init_ucred code should be merged with old_init_ucred_common. - Why does new_init check for setuid/setgid/setgrp, but not old_init? - What is ptlrpc_user_desc and should it interact with nodemap? Signed-off-by: Kit Westneat Change-Id: Ia0e07078f32c43ec319be5a4cea753667056d645 Reviewed-on: https://review.whamcloud.com/26624 Reviewed-by: Fan Yong Tested-by: Jenkins Tested-by: Maloo Reviewed-by: Emoly Liu Reviewed-by: Oleg Drokin --- lustre/mdt/mdt_lib.c | 81 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index a6c7fa5..744b5e2 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -144,30 +144,59 @@ static void ucred_set_jobid(struct mdt_thread_info *info, struct lu_ucred *uc) static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, void *buf, bool drop_fs_cap) { - struct ptlrpc_request *req = mdt_info_req(info); - struct mdt_device *mdt = info->mti_mdt; - struct ptlrpc_user_desc *pud = req->rq_user_desc; - struct lu_ucred *ucred = mdt_ucred(info); - lnet_nid_t peernid = req->rq_peer.nid; - __u32 perm = 0; - int setuid; - int setgid; - int rc = 0; + struct ptlrpc_request *req = mdt_info_req(info); + struct mdt_device *mdt = info->mti_mdt; + struct ptlrpc_user_desc *pud = req->rq_user_desc; + struct lu_ucred *ucred = mdt_ucred(info); + struct lu_nodemap *nodemap; + lnet_nid_t peernid = req->rq_peer.nid; + __u32 perm = 0; + int setuid; + int setgid; + int rc = 0; - ENTRY; + ENTRY; - LASSERT(req->rq_auth_gss); - LASSERT(!req->rq_auth_usr_mdt); - LASSERT(req->rq_user_desc); + LASSERT(req->rq_auth_gss); + LASSERT(!req->rq_auth_usr_mdt); + LASSERT(req->rq_user_desc); LASSERT(ucred != NULL); ucred->uc_valid = UCRED_INVALID; - ucred->uc_o_uid = pud->pud_uid; - ucred->uc_o_gid = pud->pud_gid; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + + pud->pud_uid = nodemap_map_id(nodemap, NODEMAP_UID, + NODEMAP_CLIENT_TO_FS, pud->pud_uid); + pud->pud_gid = nodemap_map_id(nodemap, NODEMAP_GID, + NODEMAP_CLIENT_TO_FS, pud->pud_gid); + pud->pud_fsuid = nodemap_map_id(nodemap, NODEMAP_UID, + NODEMAP_CLIENT_TO_FS, pud->pud_fsuid); + pud->pud_fsgid = nodemap_map_id(nodemap, NODEMAP_GID, + NODEMAP_CLIENT_TO_FS, pud->pud_fsgid); + + ucred->uc_o_uid = pud->pud_uid; + ucred->uc_o_gid = pud->pud_gid; ucred->uc_o_fsuid = pud->pud_fsuid; ucred->uc_o_fsgid = pud->pud_fsgid; + if (nodemap && ucred->uc_o_uid == nodemap->nm_squash_uid) { + /* deny access before we get identity ref */ + if (nodemap->nmf_deny_unknown) { + nodemap_putref(nodemap); + RETURN(-EACCES); + } + + ucred->uc_fsuid = nodemap->nm_squash_uid; + ucred->uc_fsgid = nodemap->nm_squash_gid; + ucred->uc_cap = 0; + ucred->uc_suppgids[0] = -1; + ucred->uc_suppgids[1] = -1; + } + nodemap_putref(nodemap); + if (type == BODY_INIT) { struct mdt_body *body = (struct mdt_body *)buf; @@ -217,21 +246,21 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, (ucred->uc_identity && (pud->pud_gid != ucred->uc_identity->mi_gid))); - /* check permission of setuid */ - if (setuid && !(perm & CFS_SETUID_PERM)) { - CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n", - pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid)); - GOTO(out, rc = -EACCES); - } + /* check permission of setuid */ + if (setuid && !(perm & CFS_SETUID_PERM)) { + CDEBUG(D_SEC, "mdt blocked setuid attempt (%u -> %u) from %s\n", + pud->pud_uid, pud->pud_fsuid, libcfs_nid2str(peernid)); + GOTO(out, rc = -EACCES); + } - /* check permission of setgid */ - if (setgid && !(perm & CFS_SETGID_PERM)) { + /* check permission of setgid */ + if (setgid && !(perm & CFS_SETGID_PERM)) { CDEBUG(D_SEC, "mdt blocked setgid attempt (%u:%u/%u:%u -> %u) " "from %s\n", pud->pud_uid, pud->pud_gid, pud->pud_fsuid, pud->pud_fsgid, ucred->uc_identity->mi_gid, libcfs_nid2str(peernid)); GOTO(out, rc = -EACCES); - } + } if (perm & CFS_SETGRP_PERM) { if (pud->pud_ngroups) { @@ -255,8 +284,8 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred->uc_ginfo = NULL; } - ucred->uc_uid = pud->pud_uid; - ucred->uc_gid = pud->pud_gid; + ucred->uc_uid = pud->pud_uid; + ucred->uc_gid = pud->pud_gid; ucred->uc_fsuid = pud->pud_fsuid; ucred->uc_fsgid = pud->pud_fsgid; -- 1.8.3.1