From 3b04d6ac1dee426cbdf507ba8d3c7e0ec593f114 Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Wed, 19 Jun 2024 16:15:43 +0200 Subject: [PATCH] LU-17961 sec: add server_upcall rbac role The purpose of the new server_upcall rbac role is to control whether clients use the server side defined identity upcall. When set, clients do comply with the server side identity upcall. When not set, clients are leveraging the special INTERNAL identity upcall, which means servers trust supplementary groups as provided by the clients. Signed-off-by: Sebastien Buisson Change-Id: I01dcedad5da0e175aa7b8d187f2affd34d933e39 Was-Change-Id: I39a69904ce4709eacf6f08173d3cfe42e247b5bd Reviewed-by: Lai Siyao Reviewed-by: Andreas Dilger Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/55475 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Oleg Drokin --- lustre/doc/lctl-nodemap-modify.8 | 5 + lustre/include/lustre_nodemap.h | 1 + lustre/include/md_object.h | 1 + lustre/include/uapi/linux/lustre/lustre_idl.h | 4 +- lustre/mdt/mdt_coordinator.c | 1 + lustre/mdt/mdt_handler.c | 1 + lustre/mdt/mdt_lib.c | 38 ++++-- lustre/mdt/mdt_restripe.c | 1 + lustre/obdecho/echo_client.c | 1 + lustre/ptlrpc/wiretest.c | 4 +- lustre/tests/sanity-sec.sh | 164 +++++++++++++++++++++++--- lustre/utils/wirecheck.c | 1 + lustre/utils/wiretest.c | 4 +- 13 files changed, 198 insertions(+), 28 deletions(-) diff --git a/lustre/doc/lctl-nodemap-modify.8 b/lustre/doc/lctl-nodemap-modify.8 index 8b96389..912998e 100644 --- a/lustre/doc/lctl-nodemap-modify.8 +++ b/lustre/doc/lctl-nodemap-modify.8 @@ -100,6 +100,11 @@ it is still possible to lock or unlock encrypted directories, as these operations only need read access to fscrypt metadata. .br - quota_ops, to allow quota modifications. +.br +- server_upcall, to define which identity upcall to use. If set, identity upcall +is defined by server side tunable. If not set, identity upcall is forced to +INTERNAL, so that servers trust supplementary groups as provided by clients. +.br Apart from all, any role not explicitly specified is forbidden. And to forbid all roles, use 'none' value. .RE diff --git a/lustre/include/lustre_nodemap.h b/lustre/include/lustre_nodemap.h index 4ec5167..f335931 100644 --- a/lustre/include/lustre_nodemap.h +++ b/lustre/include/lustre_nodemap.h @@ -32,6 +32,7 @@ static const struct nodemap_rbac_name { { NODEMAP_RBAC_BYFID_OPS, "byfid_ops" }, { NODEMAP_RBAC_CHLG_OPS, "chlg_ops" }, { NODEMAP_RBAC_FSCRYPT_ADMIN, "fscrypt_admin" }, + { NODEMAP_RBAC_SERVER_UPCALL, "server_upcall" }, }; struct nodemap_pde { diff --git a/lustre/include/md_object.h b/lustre/include/md_object.h index a1a22c6..a2cba1e 100644 --- a/lustre/include/md_object.h +++ b/lustre/include/md_object.h @@ -724,6 +724,7 @@ struct lu_ucred { int uc_rbac_byfid_ops:1; int uc_rbac_chlg_ops:1; int uc_rbac_fscrypt_admin:1; + int uc_rbac_server_upcall:1; }; struct lu_ucred *lu_ucred(const struct lu_env *env); diff --git a/lustre/include/uapi/linux/lustre/lustre_idl.h b/lustre/include/uapi/linux/lustre/lustre_idl.h index 119ae1a..f1c9f38 100644 --- a/lustre/include/uapi/linux/lustre/lustre_idl.h +++ b/lustre/include/uapi/linux/lustre/lustre_idl.h @@ -3822,12 +3822,14 @@ enum nodemap_rbac_roles { NODEMAP_RBAC_BYFID_OPS = 0x00000008, NODEMAP_RBAC_CHLG_OPS = 0x00000010, NODEMAP_RBAC_FSCRYPT_ADMIN = 0x00000020, + NODEMAP_RBAC_SERVER_UPCALL = 0x00000040, NODEMAP_RBAC_NONE = (__u32)~(NODEMAP_RBAC_FILE_PERMS | NODEMAP_RBAC_DNE_OPS | NODEMAP_RBAC_QUOTA_OPS | NODEMAP_RBAC_BYFID_OPS | NODEMAP_RBAC_CHLG_OPS | - NODEMAP_RBAC_FSCRYPT_ADMIN), + NODEMAP_RBAC_FSCRYPT_ADMIN | + NODEMAP_RBAC_SERVER_UPCALL), NODEMAP_RBAC_ALL = 0xFFFFFFFF, /* future caps ON by default */ }; diff --git a/lustre/mdt/mdt_coordinator.c b/lustre/mdt/mdt_coordinator.c index 2dce801..147dcaf 100644 --- a/lustre/mdt/mdt_coordinator.c +++ b/lustre/mdt/mdt_coordinator.c @@ -1086,6 +1086,7 @@ int hsm_init_ucred(struct lu_ucred *uc) uc->uc_rbac_byfid_ops = 1; uc->uc_rbac_chlg_ops = 1; uc->uc_rbac_fscrypt_admin = 1; + uc->uc_rbac_server_upcall = 1; RETURN(0); } diff --git a/lustre/mdt/mdt_handler.c b/lustre/mdt/mdt_handler.c index 9f13edc..07865bd 100644 --- a/lustre/mdt/mdt_handler.c +++ b/lustre/mdt/mdt_handler.c @@ -7163,6 +7163,7 @@ static int mdt_ctxt_add_dirty_flag(struct lu_env *env, mdt_ucred(info)->uc_rbac_byfid_ops = 1; mdt_ucred(info)->uc_rbac_chlg_ops = 1; mdt_ucred(info)->uc_rbac_fscrypt_admin = 1; + mdt_ucred(info)->uc_rbac_server_upcall = 1; rc = mdt_add_dirty_flag(info, mfd->mfd_object, &info->mti_attr); lu_context_exit(&ses); diff --git a/lustre/mdt/mdt_lib.c b/lustre/mdt/mdt_lib.c index 243854b..3817441c 100644 --- a/lustre/mdt/mdt_lib.c +++ b/lustre/mdt/mdt_lib.c @@ -61,10 +61,25 @@ static __u64 get_mrc_cr_flags(struct mdt_rec_create *mrc) return (__u64)(mrc->cr_flags_l) | ((__u64)mrc->cr_flags_h << 32); } +static struct upcall_cache *get_cache(struct mdt_thread_info *info) +{ + /* If nodemap does not have server_upcall role, + * use dedicated INTERNAL upcall cache, unless + * Kerberos is enforced, in which case we do not trust the client's + * provided supplementary groups. + */ + struct ptlrpc_request *req = mdt_info_req(info); + + if (SPTLRPC_FLVR_MECH(req->rq_flvr.sf_rpc) == SPTLRPC_MECH_GSS_KRB5 || + mdt_ucred(info)->uc_rbac_server_upcall) + return info->mti_mdt->mdt_identity_cache; + + return info->mti_mdt->mdt_identity_cache_int; +} + void mdt_exit_ucred(struct mdt_thread_info *info) { struct lu_ucred *uc = mdt_ucred(info); - struct mdt_device *mdt = info->mti_mdt; LASSERT(uc != NULL); if (uc->uc_valid != UCRED_INIT) { @@ -74,8 +89,7 @@ void mdt_exit_ucred(struct mdt_thread_info *info) uc->uc_ginfo = NULL; } if (uc->uc_identity) { - mdt_identity_put(mdt->mdt_identity_cache, - uc->uc_identity); + mdt_identity_put(get_cache(info), uc->uc_identity); uc->uc_identity = NULL; } uc->uc_valid = UCRED_INIT; @@ -190,6 +204,7 @@ static void ucred_set_rbac_roles(struct mdt_thread_info *info, uc->uc_rbac_byfid_ops = !!(rbac & NODEMAP_RBAC_BYFID_OPS); uc->uc_rbac_chlg_ops = !!(rbac & NODEMAP_RBAC_CHLG_OPS); uc->uc_rbac_fscrypt_admin = !!(rbac & NODEMAP_RBAC_FSCRYPT_ADMIN); + uc->uc_rbac_server_upcall = !!(rbac & NODEMAP_RBAC_SERVER_UPCALL); } static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, @@ -265,10 +280,12 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, /* deny access before we get identity ref */ GOTO(out, rc = -EACCES); + ucred_set_rbac_roles(info, ucred); + /* Fetch external identity info, if enabled */ - if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { - identity = mdt_identity_get(mdt->mdt_identity_cache, + 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 || @@ -387,7 +404,6 @@ static int new_init_ucred(struct mdt_thread_info *info, ucred_init_type_t type, ucred_set_jobid(info, ucred); ucred_set_nid(info, ucred); ucred_set_audit_enabled(info, ucred); - ucred_set_rbac_roles(info, ucred); ucred->uc_valid = UCRED_NEW; @@ -400,8 +416,7 @@ out: ucred->uc_ginfo = NULL; } if (ucred->uc_identity) { - mdt_identity_put(mdt->mdt_identity_cache, - ucred->uc_identity); + mdt_identity_put(get_cache(info), ucred->uc_identity); ucred->uc_identity = NULL; } } @@ -535,8 +550,10 @@ static int old_init_ucred_common(struct mdt_thread_info *info, /* deny access before we get identity ref */ RETURN(-EACCES); - if (!is_identity_get_disabled(mdt->mdt_identity_cache)) { - identity = mdt_identity_get(mdt->mdt_identity_cache, + ucred_set_rbac_roles(info, uc); + + if (!is_identity_get_disabled(get_cache(info))) { + identity = mdt_identity_get(get_cache(info), uc->uc_fsuid, info); if (IS_ERR(identity)) { if (unlikely(PTR_ERR(identity) == -EREMCHG || @@ -602,7 +619,6 @@ static int old_init_ucred_common(struct mdt_thread_info *info, ucred_set_jobid(info, uc); ucred_set_nid(info, uc); ucred_set_audit_enabled(info, uc); - ucred_set_rbac_roles(info, uc); uc->uc_valid = UCRED_OLD; diff --git a/lustre/mdt/mdt_restripe.c b/lustre/mdt/mdt_restripe.c index 656b5cf..bbcef6a 100644 --- a/lustre/mdt/mdt_restripe.c +++ b/lustre/mdt/mdt_restripe.c @@ -928,6 +928,7 @@ int mdt_restriper_start(struct mdt_device *mdt) uc->uc_rbac_byfid_ops = 1; uc->uc_rbac_chlg_ops = 1; uc->uc_rbac_fscrypt_admin = 1; + uc->uc_rbac_server_upcall = 1; task = kthread_create(mdt_restriper_main, info, "mdt_restriper_%03d", mdt_seq_site(mdt)->ss_node_id); diff --git a/lustre/obdecho/echo_client.c b/lustre/obdecho/echo_client.c index b8aec12..a957934 100644 --- a/lustre/obdecho/echo_client.c +++ b/lustre/obdecho/echo_client.c @@ -1839,6 +1839,7 @@ static void echo_ucred_init(struct lu_env *env) ucred->uc_rbac_byfid_ops = 1; ucred->uc_rbac_chlg_ops = 1; ucred->uc_rbac_fscrypt_admin = 1; + ucred->uc_rbac_server_upcall = 1; } static void echo_ucred_fini(struct lu_env *env) diff --git a/lustre/ptlrpc/wiretest.c b/lustre/ptlrpc/wiretest.c index ec54baa..96ca9af 100644 --- a/lustre/ptlrpc/wiretest.c +++ b/lustre/ptlrpc/wiretest.c @@ -6455,7 +6455,9 @@ void lustre_assert_wire_constants(void) (unsigned)NODEMAP_RBAC_CHLG_OPS); LASSERTF(NODEMAP_RBAC_FSCRYPT_ADMIN == 0x00000020UL, "found 0x%.8xUL\n", (unsigned)NODEMAP_RBAC_FSCRYPT_ADMIN); - LASSERTF(NODEMAP_RBAC_NONE == 0xffffffc0UL, "found 0x%.8xUL\n", + LASSERTF(NODEMAP_RBAC_SERVER_UPCALL == 0x00000040UL, "found 0x%.8xUL\n", + (unsigned)NODEMAP_RBAC_SERVER_UPCALL); + LASSERTF(NODEMAP_RBAC_NONE == 0xffffff80UL, "found 0x%.8xUL\n", (unsigned)NODEMAP_RBAC_NONE); LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n", (unsigned)NODEMAP_RBAC_ALL); diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index 97f6ef9..0bccf52 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -5866,11 +5866,15 @@ cleanup_64() { test_64a() { local testfile=$DIR/$tdir/$tfile + local srv_uc="" local rbac (( MDS1_VERSION >= $(version_code 2.15.54) )) || skip "Need MDS >= 2.15.54 for role-based controls" + (( MDS1_VERSION >= $(version_code 2.16.50) )) && + srv_uc="server_upcall" + stack_trap cleanup_64 EXIT mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" setup_64 @@ -5883,14 +5887,18 @@ test_64a() { byfid_ops \ chlg_ops \ fscrypt_admin \ + $srv_uc \ ; do [[ "$rbac" =~ "$role" ]] || error "role '$role' not in default '$rbac'" done + rbac="file_perms" + [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc" do_facet mgs $LCTL nodemap_modify --name c0 \ - --property rbac --value file_perms + --property rbac --value $rbac || + error "setting rbac $rbac failed (1)" wait_nm_sync c0 rbac touch $testfile stack_trap "set +vx" @@ -5901,7 +5909,15 @@ test_64a() { $LFS project -p 1000 $testfile || error "setting project failed" set +vx rm -f $testfile - do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none + rbac="none" + if [ -z "$srv_uc" ]; then + rbac="none" + else + rbac="$srv_uc" + fi + do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ + --value $rbac || + error "setting rbac $rbac failed (2)" wait_nm_sync c0 rbac touch $testfile set -vx @@ -5916,12 +5932,17 @@ run_test 64a "Nodemap enforces file_perms RBAC roles" test_64b() { local testdir=$DIR/$tdir/${tfile}.d local dir_restripe + local srv_uc="" + local rbac (( MDS1_VERSION >= $(version_code 2.15.54) )) || skip "Need MDS >= 2.15.54 for role-based controls" (( MDSCOUNT >= 2 )) || skip "mdt count $MDSCOUNT, skipping dne_ops role" + (( MDS1_VERSION >= $(version_code 2.16.50) )) && + srv_uc="server_upcall" + stack_trap cleanup_64 EXIT mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" setup_64 @@ -5934,8 +5955,11 @@ test_64b() { error "enabling dir_restripe failed" stack_trap "do_nodes $(comma_list $(all_mdts_nodes)) \ $LCTL set_param mdt.*.enable_dir_restripe=$dir_restripe" EXIT + rbac="dne_ops" + [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc" do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ - --value dne_ops + --value $rbac || + error "setting rbac $rbac failed (1)" wait_nm_sync c0 rbac $LFS mkdir -i 0 ${testdir}_for_migr || error "$LFS mkdir ${testdir}_for_migr failed (1)" @@ -5967,7 +5991,15 @@ test_64b() { $LFS mkdir -i 1 ${testdir}_mdt1 || error "$LFS mkdir ${testdir}_mdt1 failed (2)" - do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none + rbac="none" + if [ -z "$srv_uc" ]; then + rbac="none" + else + rbac="$srv_uc" + fi + do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ + --value $rbac || + error "setting rbac $rbac failed (2)" wait_nm_sync c0 rbac set -vx $LFS mkdir -i 1 $testdir && error "$LFS mkdir should fail (1)" @@ -5984,15 +6016,24 @@ test_64b() { run_test 64b "Nodemap enforces dne_ops RBAC roles" test_64c() { + local srv_uc="" + local rbac + (( MDS1_VERSION >= $(version_code 2.15.54) )) || skip "Need MDS >= 2.15.54 for role-based controls" + (( MDS1_VERSION >= $(version_code 2.16.50) )) && + srv_uc="server_upcall" + stack_trap cleanup_64 EXIT mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" setup_64 + rbac="quota_ops" + [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc" do_facet mgs $LCTL nodemap_modify --name c0 \ - --property rbac --value quota_ops + --property rbac --value $rbac || + error "setting rbac $rbac failed (1)" wait_nm_sync c0 rbac set -vx $LFS setquota -u $USER0 -b 307200 -B 309200 -i 10000 -I 11000 $MOUNT || @@ -6025,7 +6066,15 @@ test_64c() { $LFS setquota -p 1000 --delete $MOUNT set +vx - do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none + rbac="none" + if [ -z "$srv_uc" ]; then + rbac="none" + else + rbac="$srv_uc" + fi + do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ + --value $rbac || + error "setting rbac $rbac failed (2)" wait_nm_sync c0 rbac set -vx @@ -6060,17 +6109,25 @@ run_test 64c "Nodemap enforces quota_ops RBAC roles" test_64d() { local testfile=$DIR/$tdir/$tfile + local srv_uc="" + local rbac local fid (( MDS1_VERSION >= $(version_code 2.15.54) )) || skip "Need MDS >= 2.15.54 for role-based controls" + (( MDS1_VERSION >= $(version_code 2.16.50) )) && + srv_uc="server_upcall" + stack_trap cleanup_64 EXIT mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" setup_64 + rbac="byfid_ops" + [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc" do_facet mgs $LCTL nodemap_modify --name c0 \ - --property rbac --value byfid_ops + --property rbac --value $rbac || + error "setting rbac $rbac failed (1)" wait_nm_sync c0 rbac touch $testfile @@ -6081,7 +6138,15 @@ test_64d() { lfs rmfid $MOUNT $fid || error "lfs rmfid failed" set +vx - do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none + rbac="none" + if [ -z "$srv_uc" ]; then + rbac="none" + else + rbac="$srv_uc" + fi + do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ + --value $rbac || + error "setting rbac $rbac failed (2)" wait_nm_sync c0 rbac touch $testfile @@ -6098,10 +6163,15 @@ run_test 64d "Nodemap enforces byfid_ops RBAC roles" test_64e() { local testfile=$DIR/$tdir/$tfile local testdir=$DIR/$tdir/${tfile}.d + local srv_uc="" + local rbac (( MDS1_VERSION >= $(version_code 2.15.54) )) || skip "Need MDS >= 2.15.54 for role-based controls" + (( MDS1_VERSION >= $(version_code 2.16.50) )) && + srv_uc="server_upcall" + stack_trap cleanup_64 EXIT mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" setup_64 @@ -6117,8 +6187,11 @@ test_64e() { mkdir $testdir || error "failed to mkdir $testdir" touch $testfile || error "failed to touch $testfile" + rbac="chlg_ops" + [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc" do_facet mgs $LCTL nodemap_modify --name c0 \ - --property rbac --value chlg_ops + --property rbac --value $rbac || + error "setting rbac $rbac failed (1)" wait_nm_sync c0 rbac # access changelogs @@ -6129,7 +6202,15 @@ test_64e() { rm -rf $testdir $testfile || error "rm -rf $testdir $testfile failed" - do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value none + rbac="none" + if [ -z "$srv_uc" ]; then + rbac="none" + else + rbac="$srv_uc" + fi + do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ + --value $rbac || + error "setting rbac $rbac failed (2)" wait_nm_sync c0 rbac # do some IOs @@ -6143,7 +6224,9 @@ test_64e() { changelog_clear 0 && error "clear changelogs should fail" rm -rf $testdir $testfile - do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value all + do_facet mgs $LCTL nodemap_modify --name c0 \ + --property rbac --value all || + error "setting rbac all failed (3)" wait_nm_sync c0 rbac } run_test 64e "Nodemap enforces chlg_ops RBAC roles" @@ -6153,10 +6236,15 @@ test_64f() { local cli_enc local policy local protector + local srv_uc="" + local rbac (( MDS1_VERSION >= $(version_code 2.15.54) )) || skip "Need MDS >= 2.15.54 for role-based controls" + (( MDS1_VERSION >= $(version_code 2.16.50) )) && + srv_uc="server_upcall" + cli_enc=$($LCTL get_param mdc.*.import | grep client_encryption) [ -n "$cli_enc" ] || skip "Need enc support, skip fscrypt_admin role" which fscrypt || skip "Need fscrypt, skip fscrypt_admin role" @@ -6174,8 +6262,11 @@ test_64f() { stack_trap "rm -rf $MOUNT/.fscrypt" # file_perms is required because fscrypt uses chmod/chown + rbac="fscrypt_admin,file_perms" + [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc" do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ - --value fscrypt_admin,file_perms + --value $rbac || + error "setting rbac $rbac failed (1)" wait_nm_sync c0 rbac mkdir -p $vaultdir @@ -6194,8 +6285,11 @@ test_64f() { cancel_lru_locks # file_perms is required because fscrypt uses chmod/chown + rbac="file_perms" + [ -z "$srv_uc" ] || rbac="$rbac,$srv_uc" do_facet mgs $LCTL nodemap_modify --name c0 --property rbac \ - --value file_perms + --value $rbac || + error "setting rbac $rbac failed (2)" wait_nm_sync c0 rbac set -vx @@ -6214,7 +6308,9 @@ test_64f() { set +vx cancel_lru_locks - do_facet mgs $LCTL nodemap_modify --name c0 --property rbac --value all + do_facet mgs $LCTL nodemap_modify --name c0 \ + --property rbac --value all || + error "setting rbac all failed (3)" wait_nm_sync c0 rbac set -vx @@ -6228,6 +6324,46 @@ test_64f() { } run_test 64f "Nodemap enforces fscrypt_admin RBAC roles" +test_64g() { + local testfile=$DIR/$tdir/$tfile + + (( MDS1_VERSION >= $(version_code 2.16.50) )) || + skip "Need MDS >= 2.16.50 for role-based controls" + + # Add groups, and client to new group, on client only. + # Server is not aware. + groupadd -g 5000 grptest64g1 + stack_trap "groupdel grptest64g1" EXIT + groupadd -g 5001 grptest64g2 + stack_trap "groupdel grptest64g2" EXIT + groupadd -g 5002 grptest64g3 + stack_trap "groupdel grptest64g3" EXIT + + mkdir -p $DIR/$tdir || error "mkdir $DIR/$tdir failed" + chmod 750 $DIR/$tdir + chgrp grptest64g1 $DIR/$tdir + echo hi > $DIR/$tdir/fileA + chmod 640 $DIR/$tdir/fileA + chgrp grptest64g3 $DIR/$tdir/fileA + setfacl -m g:grptest64g2:r $DIR/$tdir/fileA + ls -lR $DIR/$tdir + + setup_64 + stack_trap cleanup_64 EXIT + + # remove server_upcall from rbac roles, + # to make this client use INTERNAL upcall + do_facet mgs $LCTL nodemap_modify --name c0 \ + --property rbac --value file_perms || + error "setting rbac file_perms failed" + wait_nm_sync c0 rbac + + $RUNAS cat $DIR/$tdir/fileA && error "cat $DIR/$tdir/fileA should fail" + $RUNAS -G 5000,5001 cat $DIR/$tdir/fileA || + error "cat $DIR/$tdir/fileA failed" +} +run_test 64g "Nodemap enforces server_upcall RBAC role" + look_for_files() { local pattern=$1 local neg=$2 diff --git a/lustre/utils/wirecheck.c b/lustre/utils/wirecheck.c index de95b71..e5a5e37 100644 --- a/lustre/utils/wirecheck.c +++ b/lustre/utils/wirecheck.c @@ -3041,6 +3041,7 @@ static void check_nodemap_key(void) CHECK_VALUE_X(NODEMAP_RBAC_BYFID_OPS); CHECK_VALUE_X(NODEMAP_RBAC_CHLG_OPS); CHECK_VALUE_X(NODEMAP_RBAC_FSCRYPT_ADMIN); + CHECK_VALUE_X(NODEMAP_RBAC_SERVER_UPCALL); CHECK_VALUE_X(NODEMAP_RBAC_NONE); CHECK_VALUE_X(NODEMAP_RBAC_ALL); } diff --git a/lustre/utils/wiretest.c b/lustre/utils/wiretest.c index 76fe5b7..846b0f2 100644 --- a/lustre/utils/wiretest.c +++ b/lustre/utils/wiretest.c @@ -6480,7 +6480,9 @@ void lustre_assert_wire_constants(void) (unsigned)NODEMAP_RBAC_CHLG_OPS); LASSERTF(NODEMAP_RBAC_FSCRYPT_ADMIN == 0x00000020UL, "found 0x%.8xUL\n", (unsigned)NODEMAP_RBAC_FSCRYPT_ADMIN); - LASSERTF(NODEMAP_RBAC_NONE == 0xffffffc0UL, "found 0x%.8xUL\n", + LASSERTF(NODEMAP_RBAC_SERVER_UPCALL == 0x00000040UL, "found 0x%.8xUL\n", + (unsigned)NODEMAP_RBAC_SERVER_UPCALL); + LASSERTF(NODEMAP_RBAC_NONE == 0xffffff80UL, "found 0x%.8xUL\n", (unsigned)NODEMAP_RBAC_NONE); LASSERTF(NODEMAP_RBAC_ALL == 0xffffffffUL, "found 0x%.8xUL\n", (unsigned)NODEMAP_RBAC_ALL); -- 1.8.3.1