From 5f3e6db5f88c0a94b69acb674e2c801bd3897aa2 Mon Sep 17 00:00:00 2001 From: Aurelien Degremont Date: Wed, 6 Mar 2024 15:04:41 +0100 Subject: [PATCH] LU-17566 mdt: improve new_init_ucred() for refactoring In order to merge new_init_ucred() and old_init_ucred() code eventually, move new_init_ucred() code around for it to look even closer to old_init_ucred(). - Fill generic ucred fields at the beginning (similar to what old_init_ucred() is doing. - Move code for the bottom part to be closer to old_init_ucred_common(). This code path is not used on most of lustre deployments, so I'm enabling kerberos testing to ensure some tests will go through this code path. Lustre-change: https://review.whamcloud.com/55025 Lustre-commit: 2752ac20422b681649e7a1c9ab0b6cf0f93d9e27 Test-Parameters: kerberos=true testlist=sanity-krb5 Change-Id: I113fca6a104c1db66d9e0defd6fd91e378d7208c Signed-off-by: Aurelien Degremont Reviewed-by: Sebastien Buisson Reviewed-by: Andreas Dilger Reviewed-on: https://review.whamcloud.com/c/ex/lustre-release/+/55376 Tested-by: jenkins Tested-by: Maloo --- lustre/mdt/mdt_lib.c | 53 +++++++++++++++++++++++++++++----------------------- 1 file changed, 30 insertions(+), 23 deletions(-) diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index a0ca65b..9a223a4 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -215,6 +215,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, struct lu_ucred *ucred = mdt_ucred(info); struct lu_nodemap *nodemap; lnet_nid_t peernid = req->rq_peer.nid; + struct md_identity *identity = NULL; __u32 perm = 0; int setuid; int setgid; @@ -247,6 +248,15 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred->uc_o_fsuid = pud->pud_fsuid; ucred->uc_o_fsgid = pud->pud_fsgid; + ucred->uc_uid = pud->pud_uid; + ucred->uc_gid = pud->pud_gid; + + ucred->uc_fsuid = pud->pud_fsuid; + ucred->uc_fsgid = pud->pud_fsgid; + + ucred->uc_cap = CAP_EMPTY_SET; + ll_set_capability_u32(&ucred->uc_cap, pud->pud_cap); + if (type == BODY_INIT) { struct mdt_body *body = (struct mdt_body *)buf; @@ -254,6 +264,8 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred->uc_suppgids[1] = -1; } + /* Perm checks before fetching external identity */ + if (!flvr_is_rootonly(req->rq_flvr.sf_rpc) && req->rq_auth_uid != pud->pud_uid) { CDEBUG(D_SEC, "local client %s: auth uid %u " @@ -271,31 +283,32 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred_set_rbac_roles(info, ucred); - if (is_identity_get_disabled(get_cache(info))) { - ucred->uc_identity = NULL; - perm = CFS_SETUID_PERM | CFS_SETGID_PERM | CFS_SETGRP_PERM; - } else { - struct md_identity *identity; + /* Fetch external identity info, if enabled */ + if (!is_identity_get_disabled(get_cache(info))) { identity = mdt_identity_get(get_cache(info), pud->pud_uid, info); if (IS_ERR(identity)) { - if (unlikely(PTR_ERR(identity) == -EREMCHG)) { - ucred->uc_identity = NULL; - perm = CFS_SETUID_PERM | CFS_SETGID_PERM | - CFS_SETGRP_PERM; + if (unlikely(PTR_ERR(identity) == -EREMCHG || + cap_raised(ucred->uc_cap, + CAP_DAC_READ_SEARCH))) { + identity = NULL; } else { CDEBUG(D_SEC, "Deny access without identity: uid %u\n", pud->pud_uid); GOTO(out_nodemap, rc = -EACCES); } - } else { - ucred->uc_identity = identity; - perm = mdt_identity_get_perm(ucred->uc_identity, - peernid); } } + ucred->uc_identity = identity; + + /* Perm checks that needs external identity */ + + if (ucred->uc_identity) + perm = mdt_identity_get_perm(ucred->uc_identity, peernid); + else + perm = CFS_SETUID_PERM | CFS_SETGID_PERM | CFS_SETGRP_PERM; /* find out the setuid/setgid attempt */ setuid = (pud->pud_uid != pud->pud_fsuid); @@ -338,14 +351,6 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred->uc_ginfo = NULL; } - ll_set_capability_u32(&ucred->uc_cap, pud->pud_cap); - - ucred->uc_uid = pud->pud_uid; - ucred->uc_gid = pud->pud_gid; - - ucred->uc_fsuid = pud->pud_fsuid; - ucred->uc_fsgid = pud->pud_fsgid; - /* clear suppgids if uid or gid was squashed. */ if (nodemap && (ucred->uc_o_uid == nodemap->nm_squash_uid || @@ -397,11 +402,12 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, } } - ucred->uc_valid = UCRED_NEW; ucred_set_jobid(info, ucred); ucred_set_nid(info, ucred); ucred_set_audit_enabled(info, ucred); + ucred->uc_valid = UCRED_NEW; + EXIT; out: @@ -608,11 +614,12 @@ static int old_init_ucred_common(struct mdt_thread_info *info, uc->uc_suppgids[1] = -1; } - uc->uc_valid = UCRED_OLD; ucred_set_jobid(info, uc); ucred_set_nid(info, uc); ucred_set_audit_enabled(info, uc); + uc->uc_valid = UCRED_OLD; + EXIT; return 0; } -- 1.8.3.1