From b4a336d0ce91c05ae48544b3fd2e56f0bcb0a8cf Mon Sep 17 00:00:00 2001 From: Sebastien Buisson Date: Wed, 31 Jan 2024 15:40:44 +0100 Subject: [PATCH] LU-17454 nodemap: allow mapping for root Allow an id mapping for root, to match what is implemented for regular users, with the following behavior: - if admin property is set, root remains root. - if admin property is not set, the idmap for '0' is taken into account. - if admin property is not set and there is no idmap for '0' and deny_unknown property is not set, root is squashed to the squash uid/gid. - if admin property is not set and there is no idmap for '0' and deny_unknown property is set, root is blocked. Note that map_mode remains ignored for root. Also, capabilities are not dropped for root when mapped, just like it is done for regular users. If admins want to drop root capabilities, root must be squashed. sanity-sec test_15 is updated to test root mapping. Signed-off-by: Sebastien Buisson Change-Id: Id2e950b99e3b3ba27179408c647e1f7b7c49e32e Reviewed-on: https://review.whamcloud.com/c/fs/lustre-release/+/53870 Tested-by: jenkins Tested-by: Maloo Reviewed-by: Andreas Dilger Reviewed-by: Patrick Farrell Reviewed-by: Oleg Drokin --- lustre/ptlrpc/nodemap_handler.c | 6 ++- lustre/tests/sanity-sec.sh | 92 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 93 insertions(+), 5 deletions(-) diff --git a/lustre/ptlrpc/nodemap_handler.c b/lustre/ptlrpc/nodemap_handler.c index 403ff50..18a77b9 100644 --- a/lustre/ptlrpc/nodemap_handler.c +++ b/lustre/ptlrpc/nodemap_handler.c @@ -662,7 +662,8 @@ EXPORT_SYMBOL(nodemap_get_from_exp); * if the nodemap_active is false, just return the passed id without mapping * * if the id to be looked up is 0, check that root access is allowed and if it - * is, return 0. Otherwise, return the squash uid or gid. + * is, return 0. Otherwise, return the mapped uid or gid if any. + * Otherwise, return the squash uid or gid. * * if the nodemap is configured to trusted the ids from the client system, just * return the passed id without mapping. @@ -691,7 +692,7 @@ __u32 nodemap_map_id(struct lu_nodemap *nodemap, if (id == 0) { if (nodemap->nmf_allow_root_access) goto out; - goto squash; + goto map; } if (id_type == NODEMAP_UID && @@ -709,6 +710,7 @@ __u32 nodemap_map_id(struct lu_nodemap *nodemap, if (nodemap->nmf_trust_client_ids) goto out; +map: if (is_default_nodemap(nodemap)) goto squash; diff --git a/lustre/tests/sanity-sec.sh b/lustre/tests/sanity-sec.sh index 2f1655d..b645369 100755 --- a/lustre/tests/sanity-sec.sh +++ b/lustre/tests/sanity-sec.sh @@ -374,6 +374,28 @@ add_idmaps() { return $rc } +add_root_idmaps() { + local i + local cmd="$LCTL nodemap_add_idmap" + local rc=0 + + echo "Start to add root idmaps ..." + for ((i = 0; i < NODEMAP_COUNT; i++)); do + local csum=${HOSTNAME_CHECKSUM}_${i} + + if ! do_facet mgs $cmd --name $csum --idtype uid \ + --idmap 0:1; then + rc=$((rc + 1)) + fi + if ! do_facet mgs $cmd --name $csum --idtype gid \ + --idmap 0:1; then + rc=$((rc + 1)) + fi + done + + return $rc +} + update_idmaps() { #LU-10040 [ "$MGS_VERSION" -lt $(version_code 2.10.55) ] && skip "Need MGS >= 2.10.55" @@ -478,6 +500,28 @@ delete_idmaps() { return $rc } +delete_root_idmaps() { + local i + local cmd="$LCTL nodemap_del_idmap" + local rc=0 + + echo "Start to delete root idmaps ..." + for ((i = 0; i < NODEMAP_COUNT; i++)); do + local csum=${HOSTNAME_CHECKSUM}_${i} + + if ! do_facet mgs $cmd --name $csum --idtype uid \ + --idmap 0:1; then + rc=$((rc + 1)) + fi + if ! do_facet mgs $cmd --name $csum --idtype gid \ + --idmap 0:1; then + rc=$((rc + 1)) + fi + done + + return $rc +} + modify_flags() { local i local proc @@ -553,8 +597,11 @@ cleanup_active() { test_idmap() { local i local cmd="$LCTL nodemap_test_id" + local do_root_idmap=true local rc=0 + (( $MDS1_VERSION >= $(version_code 2.15.60) )) || do_root_idmap=false + echo "Start to test idmaps ..." ## nodemap deactivated if ! do_facet mgs $LCTL nodemap_activate 0; then @@ -636,6 +683,25 @@ test_idmap() { fi done + if $do_root_idmap; then + ## add mapping for root + add_root_idmaps + + ## check that root allowed + for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do + nid="$SUBNET_CHECKSUM.0.${j}.100@tcp" + fs_id=$(do_facet mgs $cmd --nid $nid \ + --idtype uid --id 0) + if [ $fs_id != 0 ]; then + echo "root allowed expected 0, got $fs_id" + rc=$((rc + 1)) + fi + done + + ## delete mapping for root + delete_root_idmaps + fi + ## ensure allow_root_access is disabled for ((i = 0; i < NODEMAP_COUNT; i++)); do local csum=${HOSTNAME_CHECKSUM}_${i} @@ -652,12 +718,32 @@ test_idmap() { for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do nid="$SUBNET_CHECKSUM.0.${j}.100@tcp" fs_id=$(do_facet mgs $cmd --nid $nid --idtype uid --id 0) - if [ $fs_id != $NOBODY_UID ]; then - error "root squash expected $NOBODY_UID, got $fs_id" - rc=$((rc + 1)) + if [ $fs_id != ${NOBODY_UID:-65534} ]; then + error "root squash expect ${NOBODY_UID:-65534} got $fs_id" + rc=$((rc + 1)) fi done + if $do_root_idmap; then + ## add mapping for root + add_root_idmaps + + ## check root is mapped + for ((j = 0; j < NODEMAP_RANGE_COUNT; j++)); do + nid="$SUBNET_CHECKSUM.0.${j}.100@tcp" + fs_id=$(do_facet mgs $cmd --nid $nid \ + --idtype uid --id 0) + expected_id=1 + if [ $fs_id != $expected_id ]; then + echo "expected $expected_id, got $fs_id" + rc=$((rc + 1)) + fi + done + + ## delete mapping for root + delete_root_idmaps + fi + ## reset client trust to 0 for ((i = 0; i < NODEMAP_COUNT; i++)); do if ! do_facet mgs $LCTL nodemap_modify \ -- 1.8.3.1