From: Sebastien Buisson Date: Fri, 11 Apr 2025 13:23:23 +0000 (+0200) Subject: LU-18919 nodemap: map suppgids from client X-Git-Tag: 2.16.55~68 X-Git-Url: https://git.whamcloud.com/?a=commitdiff_plain;h=16a42274449586295a2eef8ba8942fce30a525f9;p=fs%2Flustre-release.git LU-18919 nodemap: map suppgids from client Map back to the file system id space the supplementary groups received from the client. Add sanity-sec test_76 to exercise this. Signed-off-by: Sebastien Buisson Change-Id: I9d6b6e5ae2fca476b102c8a02a62c1be75379acf Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/58759 Reviewed-by: Andreas Dilger Reviewed-by: Marc Vef Reviewed-by: Oleg Drokin Tested-by: jenkins Tested-by: Maloo --- diff --git a/lustre/include/lustre_nodemap.h b/lustre/include/lustre_nodemap.h index 3f94443..02118a6 100644 --- a/lustre/include/lustre_nodemap.h +++ b/lustre/include/lustre_nodemap.h @@ -203,6 +203,7 @@ __u32 nodemap_map_id(struct lu_nodemap *nodemap, enum nodemap_tree_type tree_type, __u32 id); ssize_t nodemap_map_acl(struct lu_nodemap *nodemap, void *buf, size_t size, enum nodemap_tree_type tree_type); +int nodemap_map_suppgid(struct lu_nodemap *nodemap, int suppgid); #ifdef HAVE_SERVER_SUPPORT void nodemap_test_nid(struct lnet_nid *nid, char *name_buf, size_t name_len); #else diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index fafb607..495b04b 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -204,7 +204,7 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, __u32 perm = 0; int setuid; int setgid; - int rc = 0; + int i, rc = 0; ENTRY; LASSERT(req->rq_auth_gss); @@ -226,6 +226,9 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, NODEMAP_CLIENT_TO_FS, pud->pud_fsuid); pud->pud_fsgid = nodemap_map_id(nodemap, NODEMAP_GID, NODEMAP_CLIENT_TO_FS, pud->pud_fsgid); + for (i = 0; i < pud->pud_ngroups; i++) + pud->pud_groups[i] = nodemap_map_suppgid(nodemap, + pud->pud_groups[i]); ucred->uc_o_uid = pud->pud_uid; ucred->uc_o_gid = pud->pud_gid; @@ -244,7 +247,8 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, if (type == BODY_INIT) { struct mdt_body *body = (struct mdt_body *)buf; - ucred->uc_suppgids[0] = body->mbo_suppgid; + ucred->uc_suppgids[0] = nodemap_map_suppgid(nodemap, + body->mbo_suppgid); ucred->uc_suppgids[1] = -1; } @@ -643,7 +647,7 @@ static int old_init_ucred(struct mdt_thread_info *info, uc->uc_o_gid = uc->uc_gid = body->mbo_gid; uc->uc_o_fsuid = uc->uc_fsuid = body->mbo_fsuid; uc->uc_o_fsgid = uc->uc_fsgid = body->mbo_fsgid; - uc->uc_suppgids[0] = body->mbo_suppgid; + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, body->mbo_suppgid); uc->uc_suppgids[1] = -1; uc->uc_ginfo = NULL; uc->uc_cap = CAP_EMPTY_SET; @@ -1245,8 +1249,6 @@ static int mdt_setattr_unpack_rec(struct mdt_thread_info *info) uc->uc_fsgid = rec->sa_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->sa_cap); - uc->uc_suppgids[0] = rec->sa_suppgid; - uc->uc_suppgids[1] = -1; rr->rr_fid1 = &rec->sa_fid; la->la_valid = mdt_attr_valid_xlate(rec->sa_valid, rr, ma); @@ -1263,6 +1265,8 @@ static int mdt_setattr_unpack_rec(struct mdt_thread_info *info) NODEMAP_CLIENT_TO_FS, rec->sa_gid); la->la_projid = nodemap_map_id(nodemap, NODEMAP_PROJID, NODEMAP_CLIENT_TO_FS, rec->sa_projid); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->sa_suppgid); + uc->uc_suppgids[1] = -1; nodemap_putref(nodemap); la->la_size = rec->sa_size; @@ -1397,6 +1401,7 @@ static int mdt_create_unpack(struct mdt_thread_info *info) struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = info->mti_pill; struct md_op_spec *sp = &info->mti_spec; + struct lu_nodemap *nodemap; int rc; ENTRY; @@ -1410,8 +1415,12 @@ static int mdt_create_unpack(struct mdt_thread_info *info) uc->uc_fsgid = rec->cr_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->cr_cap); - uc->uc_suppgids[0] = rec->cr_suppgid1; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->cr_suppgid1); uc->uc_suppgids[1] = -1; + nodemap_putref(nodemap); uc->uc_umask = rec->cr_umask; rr->rr_fid1 = &rec->cr_fid1; @@ -1502,6 +1511,7 @@ static int mdt_link_unpack(struct mdt_thread_info *info) struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = info->mti_pill; + struct lu_nodemap *nodemap; int rc; ENTRY; @@ -1515,8 +1525,12 @@ static int mdt_link_unpack(struct mdt_thread_info *info) uc->uc_fsgid = rec->lk_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->lk_cap); - uc->uc_suppgids[0] = rec->lk_suppgid1; - uc->uc_suppgids[1] = rec->lk_suppgid2; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->lk_suppgid1); + uc->uc_suppgids[1] = nodemap_map_suppgid(nodemap, rec->lk_suppgid2); + nodemap_putref(nodemap); attr->la_uid = rec->lk_fsuid; attr->la_gid = rec->lk_fsgid; @@ -1546,6 +1560,7 @@ static int mdt_unlink_unpack(struct mdt_thread_info *info) struct lu_attr *attr = &info->mti_attr.ma_attr; struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = info->mti_pill; + struct lu_nodemap *nodemap; int rc; ENTRY; @@ -1559,8 +1574,12 @@ static int mdt_unlink_unpack(struct mdt_thread_info *info) uc->uc_fsgid = rec->ul_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->ul_cap); - uc->uc_suppgids[0] = rec->ul_suppgid1; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->ul_suppgid1); uc->uc_suppgids[1] = -1; + nodemap_putref(nodemap); attr->la_uid = rec->ul_fsuid; attr->la_gid = rec->ul_fsgid; @@ -1603,6 +1622,7 @@ static int mdt_rename_unpack(struct mdt_thread_info *info) struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = info->mti_pill; struct md_op_spec *spec = &info->mti_spec; + struct lu_nodemap *nodemap; int rc; ENTRY; @@ -1616,8 +1636,12 @@ static int mdt_rename_unpack(struct mdt_thread_info *info) uc->uc_fsgid = rec->rn_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->rn_cap); - uc->uc_suppgids[0] = rec->rn_suppgid1; - uc->uc_suppgids[1] = rec->rn_suppgid2; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->rn_suppgid1); + uc->uc_suppgids[1] = nodemap_map_suppgid(nodemap, rec->rn_suppgid2); + nodemap_putref(nodemap); attr->la_uid = rec->rn_fsuid; attr->la_gid = rec->rn_fsgid; @@ -1656,6 +1680,7 @@ static int mdt_migrate_unpack(struct mdt_thread_info *info) struct mdt_reint_record *rr = &info->mti_rr; struct req_capsule *pill = info->mti_pill; struct md_op_spec *spec = &info->mti_spec; + struct lu_nodemap *nodemap; int rc; ENTRY; @@ -1669,8 +1694,12 @@ static int mdt_migrate_unpack(struct mdt_thread_info *info) uc->uc_fsgid = rec->rn_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->rn_cap); - uc->uc_suppgids[0] = rec->rn_suppgid1; - uc->uc_suppgids[1] = rec->rn_suppgid2; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->rn_suppgid1); + uc->uc_suppgids[1] = nodemap_map_suppgid(nodemap, rec->rn_suppgid2); + nodemap_putref(nodemap); attr->la_uid = rec->rn_fsuid; attr->la_gid = rec->rn_fsgid; @@ -1755,6 +1784,7 @@ static int mdt_open_unpack(struct mdt_thread_info *info) struct mdt_reint_record *rr = &info->mti_rr; struct ptlrpc_request *req = mdt_info_req(info); struct md_op_spec *sp = &info->mti_spec; + struct lu_nodemap *nodemap; int rc; ENTRY; @@ -1769,8 +1799,12 @@ static int mdt_open_unpack(struct mdt_thread_info *info) uc->uc_fsgid = rec->cr_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->cr_cap); - uc->uc_suppgids[0] = rec->cr_suppgid1; - uc->uc_suppgids[1] = rec->cr_suppgid2; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->cr_suppgid1); + uc->uc_suppgids[1] = nodemap_map_suppgid(nodemap, rec->cr_suppgid2); + nodemap_putref(nodemap); uc->uc_umask = rec->cr_umask; rr->rr_fid1 = &rec->cr_fid1; @@ -1844,6 +1878,7 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) struct lu_attr *attr = &info->mti_attr.ma_attr; struct req_capsule *pill = info->mti_pill; struct mdt_rec_setxattr *rec; + struct lu_nodemap *nodemap; int rc; ENTRY; @@ -1858,8 +1893,12 @@ static int mdt_setxattr_unpack(struct mdt_thread_info *info) uc->uc_fsgid = rec->sx_fsgid; uc->uc_cap = CAP_EMPTY_SET; ll_set_capability_u32(&uc->uc_cap, rec->sx_cap); - uc->uc_suppgids[0] = rec->sx_suppgid1; + nodemap = nodemap_get_from_exp(info->mti_exp); + if (IS_ERR(nodemap)) + RETURN(PTR_ERR(nodemap)); + uc->uc_suppgids[0] = nodemap_map_suppgid(nodemap, rec->sx_suppgid1); uc->uc_suppgids[1] = -1; + nodemap_putref(nodemap); rr->rr_opcode = rec->sx_opcode; rr->rr_fid1 = &rec->sx_fid; diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index e8a70e5..f6926f2 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -1030,6 +1030,22 @@ ssize_t nodemap_map_acl(struct lu_nodemap *nodemap, void *buf, size_t size, } EXPORT_SYMBOL(nodemap_map_acl); +/** + * Map supplementary groups received from client. + * + * \param lu_nodemap nodemap + * \param id id to map + * + * \retval mapped id or -1 for invalid suppgid + */ +int nodemap_map_suppgid(struct lu_nodemap *nodemap, int suppgid) +{ + return suppgid == -1 ? suppgid : nodemap_map_id(nodemap, NODEMAP_GID, + NODEMAP_CLIENT_TO_FS, + suppgid); +} +EXPORT_SYMBOL(nodemap_map_suppgid); + static int nodemap_inherit_properties(struct lu_nodemap *dst, struct lu_nodemap *src) { diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index 5885055..f2fdf72 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -7898,6 +7898,78 @@ test_75() { } run_test 75 "check uid/gid/projid are set on OST and MDT for various RPCs" +cleanup_76() { + # unmount client + if is_mounted $MOUNT; then + umount_client $MOUNT || error "umount $MOUNT failed" + fi + + # reset and deactivate nodemaps, remount client + cleanup_local_client_nodemap + + # remount client on $MOUNT_2 + if [ "$MOUNT_2" ]; then + mount_client $MOUNT2 ${MOUNT_OPTS} || error "remount failed" + fi + wait_ssk +} + +test_76() { + local user=$(getent passwd $RUNAS_ID | cut -d: -f1) + local grp=grptest76 + local grpid=5000 + local nm=c0 + + (( $MDS1_VERSION >= $(version_code 2.16.53) )) || + skip "need MDS >= 2.16.53 for suppgroup mapping" + + do_nodes $(comma_list $(all_mdts_nodes)) \ + $LCTL set_param mdt.*.identity_upcall=NONE + + # create a specific group and add it as a supplementary group for $USER0 + groupadd -g $grpid $grp + stack_trap "groupdel $grp" EXIT + usermod -aG $grp $user + stack_trap "gpasswd -d $user $grp" EXIT + + stack_trap cleanup_76 EXIT + + # unmount client completely + umount_client $MOUNT || error "umount $MOUNT failed" + if is_mounted $MOUNT2; then + umount_client $MOUNT2 || error "umount $MOUNT2 failed" + fi + + # setup nodemap with offset + setup_local_client_nodemap $nm 1 1 + do_facet mgs $LCTL nodemap_add_offset --name $nm \ + --offset 100000 --limit 200000 || + error "nodemap_add_offset failed" + wait_nm_sync $nm offset + + # remount client to take nodemap into account + zconf_mount_clients $HOSTNAME $MOUNT $MOUNT_OPTS || + error "remount failed" + wait_ssk + + # Create directory from client part of the nodemap, as root, + # and set its group membership to $grpid. + # This is going to be mapped on server side. + $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $DIR/$tdir failed" + chgrp -v $grp $DIR/$tdir || error "chgrp $DIR/$tdir failed" + chmod -v 0770 $DIR/$tdir || error "chmod $DIR/$tdir failed" + ls -ld $DIR/$tdir + cancel_lru_locks + + # access as $USER0, should work because it has $grpid as a supp group + # and it is properly mapped on server side + $RUNAS -G$grpid ls -l $DIR/$tdir || + error "ls -l $DIR/$tdir as $user failed" + $RUNAS -G$grpid touch $DIR/$tdir/fileA || + error "touch $DIR/$tdir/fileA as $user failed" +} +run_test 76 "suppgroups and gid mapping" + log "cleanup: ======================================================" sec_unsetup() {