1d583b39bSJohn Wren Kennedy#!/bin/ksh -p 2d583b39bSJohn Wren Kennedy# 3d583b39bSJohn Wren Kennedy# CDDL HEADER START 4d583b39bSJohn Wren Kennedy# 5d583b39bSJohn Wren Kennedy# The contents of this file are subject to the terms of the 6d583b39bSJohn Wren Kennedy# Common Development and Distribution License (the "License"). 7d583b39bSJohn Wren Kennedy# You may not use this file except in compliance with the License. 8d583b39bSJohn Wren Kennedy# 9d583b39bSJohn Wren Kennedy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10d583b39bSJohn Wren Kennedy# or http://www.opensolaris.org/os/licensing. 11d583b39bSJohn Wren Kennedy# See the License for the specific language governing permissions 12d583b39bSJohn Wren Kennedy# and limitations under the License. 13d583b39bSJohn Wren Kennedy# 14d583b39bSJohn Wren Kennedy# When distributing Covered Code, include this CDDL HEADER in each 15d583b39bSJohn Wren Kennedy# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16d583b39bSJohn Wren Kennedy# If applicable, add the following below this CDDL HEADER, with the 17d583b39bSJohn Wren Kennedy# fields enclosed by brackets "[]" replaced with your own identifying 18d583b39bSJohn Wren Kennedy# information: Portions Copyright [yyyy] [name of copyright owner] 19d583b39bSJohn Wren Kennedy# 20d583b39bSJohn Wren Kennedy# CDDL HEADER END 21d583b39bSJohn Wren Kennedy# 22d583b39bSJohn Wren Kennedy 23d583b39bSJohn Wren Kennedy# 24d583b39bSJohn Wren Kennedy# Copyright 2009 Sun Microsystems, Inc. All rights reserved. 25d583b39bSJohn Wren Kennedy# Use is subject to license terms. 26d583b39bSJohn Wren Kennedy# 27d583b39bSJohn Wren Kennedy 28d583b39bSJohn Wren Kennedy# 291d32ba66SJohn Wren Kennedy# Copyright (c) 2012, 2016 by Delphix. All rights reserved. 30*6990962cSToomas Soome# Copyright 2023 RackTop Systems, Inc. 31d583b39bSJohn Wren Kennedy# 32d583b39bSJohn Wren Kennedy 33d583b39bSJohn Wren Kennedy. $STF_SUITE/tests/functional/acl/acl_common.kshlib 34d583b39bSJohn Wren Kennedy 35d583b39bSJohn Wren Kennedy# 36d583b39bSJohn Wren Kennedy# DESCRIPTION: 37d583b39bSJohn Wren Kennedy# Verify that the write_owner for 38d583b39bSJohn Wren Kennedy# owner/group/everyone are correct. 39d583b39bSJohn Wren Kennedy# 40d583b39bSJohn Wren Kennedy# STRATEGY: 41d583b39bSJohn Wren Kennedy# 1. Create file and directory in zfs filesystem 42d583b39bSJohn Wren Kennedy# 2. Set special write_owner ACE to the file and directory 43d583b39bSJohn Wren Kennedy# 3. Try to chown/chgrp of the file and directory to take owner/group 44d583b39bSJohn Wren Kennedy# 4. Verify that the owner/group are correct. Follow these rules: 45d583b39bSJohn Wren Kennedy# (1) If uid is granted the write_owner permission, then it can only do 46d583b39bSJohn Wren Kennedy# chown to its own uid, or a group that they are a member of. 47*6990962cSToomas Soome# (2) chown/chgrp will fail when write_owner not granted. 48d583b39bSJohn Wren Kennedy# (3) Superuser will always permit whatever they do. 49d583b39bSJohn Wren Kennedy# 50d583b39bSJohn Wren Kennedy 51d583b39bSJohn Wren Kennedyverify_runnable "both" 52d583b39bSJohn Wren Kennedy 53d583b39bSJohn Wren Kennedyfunction cleanup 54d583b39bSJohn Wren Kennedy{ 551d32ba66SJohn Wren Kennedy [[ -d $basedir ]] && rm -rf $basedir 561d32ba66SJohn Wren Kennedy [[ -f $TESTDIR/$ARCHIVEFILE ]] && log_must rm -f $TESTDIR/$ARCHIVEFILE 57d583b39bSJohn Wren Kennedy return 0 58d583b39bSJohn Wren Kennedy} 59d583b39bSJohn Wren Kennedy 60d583b39bSJohn Wren Kennedylog_assert "Verify that the chown/chgrp could take owner/group " \ 61d583b39bSJohn Wren Kennedy "while permission is granted." 62d583b39bSJohn Wren Kennedylog_onexit cleanup 63d583b39bSJohn Wren Kennedy 64d583b39bSJohn Wren Kennedy# 65d583b39bSJohn Wren Kennedy# Get the owner of a file/directory 66d583b39bSJohn Wren Kennedy# 67d583b39bSJohn Wren Kennedyfunction get_owner 68d583b39bSJohn Wren Kennedy{ 69d583b39bSJohn Wren Kennedy typeset node=$1 70d583b39bSJohn Wren Kennedy 71d583b39bSJohn Wren Kennedy if [[ -z $node ]]; then 72d583b39bSJohn Wren Kennedy log_fail "node are not defined." 73d583b39bSJohn Wren Kennedy fi 74d583b39bSJohn Wren Kennedy 751d32ba66SJohn Wren Kennedy echo $(ls -dl $node | awk '{print $3}') 76d583b39bSJohn Wren Kennedy} 77d583b39bSJohn Wren Kennedy 78d583b39bSJohn Wren Kennedy# 79d583b39bSJohn Wren Kennedy# Get the group of a file/directory 80d583b39bSJohn Wren Kennedy# 81d583b39bSJohn Wren Kennedyfunction get_group 82d583b39bSJohn Wren Kennedy{ 83d583b39bSJohn Wren Kennedy typeset node=$1 84d583b39bSJohn Wren Kennedy 85d583b39bSJohn Wren Kennedy if [[ -z $node ]]; then 86d583b39bSJohn Wren Kennedy log_fail "node are not defined." 87d583b39bSJohn Wren Kennedy fi 88d583b39bSJohn Wren Kennedy 891d32ba66SJohn Wren Kennedy echo $(ls -dl $node | awk '{print $4}') 90d583b39bSJohn Wren Kennedy} 91d583b39bSJohn Wren Kennedy 92d583b39bSJohn Wren Kennedy 93d583b39bSJohn Wren Kennedy# 94d583b39bSJohn Wren Kennedy# Get the group name that a UID belongs to 95d583b39bSJohn Wren Kennedy# 96d583b39bSJohn Wren Kennedyfunction get_user_group 97d583b39bSJohn Wren Kennedy{ 98d583b39bSJohn Wren Kennedy typeset uid=$1 99d583b39bSJohn Wren Kennedy typeset value 100d583b39bSJohn Wren Kennedy 101d583b39bSJohn Wren Kennedy if [[ -z $uid ]]; then 102d583b39bSJohn Wren Kennedy log_fail "UID not defined." 103d583b39bSJohn Wren Kennedy fi 104d583b39bSJohn Wren Kennedy 105d583b39bSJohn Wren Kennedy value=$(id $uid) 106d583b39bSJohn Wren Kennedy 107d583b39bSJohn Wren Kennedy if [[ $? -eq 0 ]]; then 108d583b39bSJohn Wren Kennedy value=${value##*\(} 109d583b39bSJohn Wren Kennedy value=${value%%\)*} 1101d32ba66SJohn Wren Kennedy echo $value 111d583b39bSJohn Wren Kennedy else 112d583b39bSJohn Wren Kennedy log_fail "Invalid UID (uid)." 113d583b39bSJohn Wren Kennedy fi 114d583b39bSJohn Wren Kennedy} 115d583b39bSJohn Wren Kennedy 116d583b39bSJohn Wren Kennedyfunction operate_node_owner 117d583b39bSJohn Wren Kennedy{ 118d583b39bSJohn Wren Kennedy typeset user=$1 119d583b39bSJohn Wren Kennedy typeset node=$2 120d583b39bSJohn Wren Kennedy typeset old_owner=$3 121d583b39bSJohn Wren Kennedy typeset expect_owner=$4 122d583b39bSJohn Wren Kennedy typeset ret new_owner 123d583b39bSJohn Wren Kennedy 124d583b39bSJohn Wren Kennedy if [[ $user == "" || $node == "" ]]; then 125d583b39bSJohn Wren Kennedy log_fail "user, node are not defined." 126d583b39bSJohn Wren Kennedy fi 127d583b39bSJohn Wren Kennedy 1281d32ba66SJohn Wren Kennedy su $user -c "chown $expect_owner $node" 129d583b39bSJohn Wren Kennedy ret=$? 130d583b39bSJohn Wren Kennedy new_owner=$(get_owner $node) 131d583b39bSJohn Wren Kennedy 132d583b39bSJohn Wren Kennedy if [[ $new_owner != $old_owner ]]; then 1331d32ba66SJohn Wren Kennedy tar xpf $TESTDIR/$ARCHIVEFILE 134d583b39bSJohn Wren Kennedy fi 135d583b39bSJohn Wren Kennedy 136d583b39bSJohn Wren Kennedy if [[ $ret -eq 0 ]]; then 137d583b39bSJohn Wren Kennedy if [[ $new_owner != $expect_owner ]]; then 138d583b39bSJohn Wren Kennedy log_note "Owner not changed as expected " \ 139d583b39bSJohn Wren Kennedy "($old_owner|$new_owner|$expect_owner), " \ 140d583b39bSJohn Wren Kennedy "but return code is $ret." 141d583b39bSJohn Wren Kennedy return 1 142d583b39bSJohn Wren Kennedy fi 143d583b39bSJohn Wren Kennedy elif [[ $ret -ne 0 && $new_owner != $old_owner ]]; then 144d583b39bSJohn Wren Kennedy log_note "Owner changed ($old_owner|$new_owner), " \ 145d583b39bSJohn Wren Kennedy "but return code is $ret." 146d583b39bSJohn Wren Kennedy return 2 147d583b39bSJohn Wren Kennedy fi 148d583b39bSJohn Wren Kennedy 149d583b39bSJohn Wren Kennedy return $ret 150d583b39bSJohn Wren Kennedy} 151d583b39bSJohn Wren Kennedy 152d583b39bSJohn Wren Kennedyfunction operate_node_group 153d583b39bSJohn Wren Kennedy{ 154d583b39bSJohn Wren Kennedy typeset user=$1 155d583b39bSJohn Wren Kennedy typeset node=$2 156d583b39bSJohn Wren Kennedy typeset old_group=$3 157d583b39bSJohn Wren Kennedy typeset expect_group=$4 158d583b39bSJohn Wren Kennedy typeset ret new_group 159d583b39bSJohn Wren Kennedy 160d583b39bSJohn Wren Kennedy if [[ $user == "" || $node == "" ]]; then 161d583b39bSJohn Wren Kennedy log_fail "user, node are not defined." 162d583b39bSJohn Wren Kennedy fi 163d583b39bSJohn Wren Kennedy 1641d32ba66SJohn Wren Kennedy su $user -c "chgrp $expect_group $node" 165d583b39bSJohn Wren Kennedy ret=$? 166d583b39bSJohn Wren Kennedy new_group=$(get_group $node) 167d583b39bSJohn Wren Kennedy 168d583b39bSJohn Wren Kennedy if [[ $new_group != $old_group ]]; then 1691d32ba66SJohn Wren Kennedy tar xpf $TESTDIR/$ARCHIVEFILE 170d583b39bSJohn Wren Kennedy fi 171d583b39bSJohn Wren Kennedy 172d583b39bSJohn Wren Kennedy if [[ $ret -eq 0 ]]; then 173d583b39bSJohn Wren Kennedy if [[ $new_group != $expect_group ]]; then 174d583b39bSJohn Wren Kennedy log_note "Group not changed as expected " \ 175d583b39bSJohn Wren Kennedy "($old_group|$new_group|$expect_group), " \ 176d583b39bSJohn Wren Kennedy "but return code is $ret." 177d583b39bSJohn Wren Kennedy return 1 178d583b39bSJohn Wren Kennedy fi 179d583b39bSJohn Wren Kennedy elif [[ $ret -ne 0 && $new_group != $old_group ]]; then 180d583b39bSJohn Wren Kennedy log_note "Group changed ($old_group|$new_group), " \ 181d583b39bSJohn Wren Kennedy "but return code is $ret." 182d583b39bSJohn Wren Kennedy return 2 183d583b39bSJohn Wren Kennedy fi 184d583b39bSJohn Wren Kennedy 185d583b39bSJohn Wren Kennedy return $ret 186d583b39bSJohn Wren Kennedy} 187d583b39bSJohn Wren Kennedy 188d583b39bSJohn Wren Kennedyfunction logname 189d583b39bSJohn Wren Kennedy{ 190d583b39bSJohn Wren Kennedy typeset acl_target=$1 191d583b39bSJohn Wren Kennedy typeset user=$2 192d583b39bSJohn Wren Kennedy typeset old=$3 193d583b39bSJohn Wren Kennedy typeset new=$4 194d583b39bSJohn Wren Kennedy typeset ret="log_mustnot" 195d583b39bSJohn Wren Kennedy 196d583b39bSJohn Wren Kennedy # To super user, read and write deny permission was override. 197d583b39bSJohn Wren Kennedy if [[ $user == root ]]; then 198d583b39bSJohn Wren Kennedy ret="log_must" 199d583b39bSJohn Wren Kennedy elif [[ $user == $new ]] ; then 200d583b39bSJohn Wren Kennedy if [[ $user == $old || $acl_target == *:allow ]]; then 201*6990962cSToomas Soome # with aclimplicit=on, the write_owner:deny 202*6990962cSToomas Soome # will have no effect and chown/chgrp commands 203*6990962cSToomas Soome # needs to succeed. 204*6990962cSToomas Soome if [[ $aclimplicit == on || 205*6990962cSToomas Soome $acl_target != *@:write_owner:deny ]]; then 206d583b39bSJohn Wren Kennedy ret="log_must" 207d583b39bSJohn Wren Kennedy fi 208d583b39bSJohn Wren Kennedy fi 209*6990962cSToomas Soome fi 210d583b39bSJohn Wren Kennedy 211d583b39bSJohn Wren Kennedy print $ret 212d583b39bSJohn Wren Kennedy} 213d583b39bSJohn Wren Kennedy 214d583b39bSJohn Wren Kennedyfunction check_chmod_results 215d583b39bSJohn Wren Kennedy{ 216d583b39bSJohn Wren Kennedy typeset user=$1 217d583b39bSJohn Wren Kennedy typeset node=$2 218d583b39bSJohn Wren Kennedy typeset flag=$3 219d583b39bSJohn Wren Kennedy typeset acl_target=$3:$4 220d583b39bSJohn Wren Kennedy typeset g_usr=$5 221d583b39bSJohn Wren Kennedy typeset o_usr=$6 222d583b39bSJohn Wren Kennedy typeset log old_owner old_group new_owner new_group 223d583b39bSJohn Wren Kennedy 224d583b39bSJohn Wren Kennedy old_owner=$(get_owner $node) 225d583b39bSJohn Wren Kennedy old_group=$(get_group $node) 226d583b39bSJohn Wren Kennedy 227d583b39bSJohn Wren Kennedy if [[ $flag == "owner@" || $flag == "everyone@" ]]; then 228d583b39bSJohn Wren Kennedy for new_owner in $user "nobody"; do 229d583b39bSJohn Wren Kennedy new_group=$(get_user_group $new_owner) 230d583b39bSJohn Wren Kennedy 231d583b39bSJohn Wren Kennedy log=$(logname $acl_target $user \ 232d583b39bSJohn Wren Kennedy $old_owner $new_owner) 233d583b39bSJohn Wren Kennedy 234d583b39bSJohn Wren Kennedy $log operate_node_owner $user $node \ 235d583b39bSJohn Wren Kennedy $old_owner $new_owner 236d583b39bSJohn Wren Kennedy 237d583b39bSJohn Wren Kennedy $log operate_node_group $user $node \ 238d583b39bSJohn Wren Kennedy $old_group $new_group 239d583b39bSJohn Wren Kennedy done 240d583b39bSJohn Wren Kennedy fi 241d583b39bSJohn Wren Kennedy if [[ $flag == "group@" || $flag == "everyone@" ]]; then 242d583b39bSJohn Wren Kennedy for new_owner in $g_usr "nobody"; do 243d583b39bSJohn Wren Kennedy new_group=$(get_user_group $new_owner) 244d583b39bSJohn Wren Kennedy 245d583b39bSJohn Wren Kennedy log=$(logname $acl_target $g_usr $old_owner \ 246d583b39bSJohn Wren Kennedy $new_owner) 247d583b39bSJohn Wren Kennedy 248d583b39bSJohn Wren Kennedy $log operate_node_owner $g_usr $node \ 249d583b39bSJohn Wren Kennedy $old_owner $new_owner 250d583b39bSJohn Wren Kennedy 251d583b39bSJohn Wren Kennedy $log operate_node_group $g_usr \ 252d583b39bSJohn Wren Kennedy $node $old_group $new_group 253d583b39bSJohn Wren Kennedy done 254d583b39bSJohn Wren Kennedy fi 255d583b39bSJohn Wren Kennedy if [[ $flag == "everyone@" ]]; then 256d583b39bSJohn Wren Kennedy for new_owner in $g_usr "nobody"; do 257d583b39bSJohn Wren Kennedy new_group=$(get_user_group $new_owner) 258d583b39bSJohn Wren Kennedy 259d583b39bSJohn Wren Kennedy log=$(logname $acl_target $o_usr $old_owner \ 260d583b39bSJohn Wren Kennedy $new_owner) 261d583b39bSJohn Wren Kennedy 262d583b39bSJohn Wren Kennedy $log operate_node_owner $o_usr $node \ 263d583b39bSJohn Wren Kennedy $old_owner $new_owner 264d583b39bSJohn Wren Kennedy 265d583b39bSJohn Wren Kennedy $log operate_node_group $o_usr $node \ 266d583b39bSJohn Wren Kennedy $old_group $new_group 267d583b39bSJohn Wren Kennedy done 268d583b39bSJohn Wren Kennedy fi 269d583b39bSJohn Wren Kennedy} 270d583b39bSJohn Wren Kennedy 271d583b39bSJohn Wren Kennedyfunction test_chmod_basic_access 272d583b39bSJohn Wren Kennedy{ 273d583b39bSJohn Wren Kennedy typeset user=$1 274d583b39bSJohn Wren Kennedy typeset node=${2%/} 275d583b39bSJohn Wren Kennedy typeset g_usr=$3 276d583b39bSJohn Wren Kennedy typeset o_usr=$4 277d583b39bSJohn Wren Kennedy typeset flag acl_t 278d583b39bSJohn Wren Kennedy 279d583b39bSJohn Wren Kennedy for flag in $a_flag; do 280d583b39bSJohn Wren Kennedy for acl_t in $a_access; do 2811d32ba66SJohn Wren Kennedy log_must su $user -c "chmod A+$flag:$acl_t $node" 282d583b39bSJohn Wren Kennedy 2831d32ba66SJohn Wren Kennedy tar cpf $TESTDIR/$ARCHIVEFILE basedir 284d583b39bSJohn Wren Kennedy 285d583b39bSJohn Wren Kennedy check_chmod_results $user $node $flag $acl_t $g_usr \ 286d583b39bSJohn Wren Kennedy $o_usr 287d583b39bSJohn Wren Kennedy 2881d32ba66SJohn Wren Kennedy log_must su $user -c "chmod A0- $node" 289d583b39bSJohn Wren Kennedy done 290d583b39bSJohn Wren Kennedy done 291d583b39bSJohn Wren Kennedy} 292d583b39bSJohn Wren Kennedy 293d583b39bSJohn Wren Kennedyfunction setup_test_files 294d583b39bSJohn Wren Kennedy{ 295d583b39bSJohn Wren Kennedy typeset base_node=$1 296d583b39bSJohn Wren Kennedy typeset user=$2 297d583b39bSJohn Wren Kennedy typeset group=$3 298d583b39bSJohn Wren Kennedy 2991d32ba66SJohn Wren Kennedy rm -rf $base_node 300d583b39bSJohn Wren Kennedy 3011d32ba66SJohn Wren Kennedy log_must mkdir -p $base_node 3021d32ba66SJohn Wren Kennedy log_must chown $user:$group $base_node 303d583b39bSJohn Wren Kennedy 304d583b39bSJohn Wren Kennedy # Prepare all files/sub-dirs for testing. 3051d32ba66SJohn Wren Kennedy log_must su $user -c "touch $file" 3061d32ba66SJohn Wren Kennedy log_must su $user -c "chmod 444 $file" 3071d32ba66SJohn Wren Kennedy log_must su $user -c "mkdir -p $dir" 3081d32ba66SJohn Wren Kennedy log_must su $user -c "chmod 444 $dir" 3091d32ba66SJohn Wren Kennedy log_must su $user -c "chmod 555 $base_node" 310d583b39bSJohn Wren Kennedy} 311d583b39bSJohn Wren Kennedy 312d583b39bSJohn Wren Kennedytypeset ARCHIVEFILE=archive.tar 313*6990962cSToomas Soometypeset a_prop="on off" 314d583b39bSJohn Wren Kennedytypeset a_access="write_owner:allow write_owner:deny" 315d583b39bSJohn Wren Kennedytypeset a_flag="owner@ group@ everyone@" 316d583b39bSJohn Wren Kennedytypeset basedir="$TESTDIR/basedir" 317d583b39bSJohn Wren Kennedytypeset file="$basedir/file" 318d583b39bSJohn Wren Kennedytypeset dir="$basedir/dir" 319*6990962cSToomas Soometypeset aclimplicit=$(zfs get -Ho value aclimplicit $TESTPOOL/$TESTFS) 320*6990962cSToomas Soometypeset val 321d583b39bSJohn Wren Kennedy 322d583b39bSJohn Wren Kennedycd $TESTDIR 323*6990962cSToomas Soome 324*6990962cSToomas Soomefor val in $a_prop; do 325*6990962cSToomas Soome log_must zfs set aclimplicit=$val $TESTPOOL/$TESTFS 326*6990962cSToomas Soome aclimplicit=$(zfs get -Ho value aclimplicit $TESTPOOL/$TESTFS) 327*6990962cSToomas Soome if [[ $val == off ]]; then 328*6990962cSToomas Soome # aclimplicit=off also needs aclmode=passthrough and 329*6990962cSToomas Soome # aclinherit=passthrough 330*6990962cSToomas Soome log_must zfs set aclmode=passthrough $TESTPOOL/$TESTFS 331*6990962cSToomas Soome log_must zfs set aclinherit=passthrough $TESTPOOL/$TESTFS 332*6990962cSToomas Soome fi 333*6990962cSToomas Soome 334d583b39bSJohn Wren Kennedy setup_test_files $basedir 'root' 'root' 335d583b39bSJohn Wren Kennedy test_chmod_basic_access 'root' $file $ZFS_ACL_ADMIN $ZFS_ACL_OTHER1 336d583b39bSJohn Wren Kennedy test_chmod_basic_access 'root' $dir $ZFS_ACL_ADMIN $ZFS_ACL_OTHER1 3371d32ba66SJohn Wren Kennedy rm -rf $basedir 338d583b39bSJohn Wren Kennedy 339d583b39bSJohn Wren Kennedy setup_test_files $basedir $ZFS_ACL_STAFF1 $ZFS_ACL_STAFF_GROUP 340*6990962cSToomas Soome test_chmod_basic_access $ZFS_ACL_STAFF1 $file $ZFS_ACL_STAFF2 \ 341*6990962cSToomas Soome $ZFS_ACL_OTHER1 342*6990962cSToomas Soome test_chmod_basic_access $ZFS_ACL_STAFF1 $dir $ZFS_ACL_STAFF2 \ 343*6990962cSToomas Soome $ZFS_ACL_OTHER1 3441d32ba66SJohn Wren Kennedy rm -rf $basedir 345*6990962cSToomas Soomedone 346*6990962cSToomas Soome 347*6990962cSToomas Soome# restore defaults, so next test is not affected. 348*6990962cSToomas Soomelog_must zfs inherit aclmode $TESTPOOL/$TESTFS 349*6990962cSToomas Soomelog_must zfs inherit aclinherit $TESTPOOL/$TESTFS 350*6990962cSToomas Soomelog_must zfs inherit aclimplicit $TESTPOOL/$TESTFS 351d583b39bSJohn Wren Kennedy 352d583b39bSJohn Wren Kennedylog_pass "Verify that the chown/chgrp could take owner/group " \ 353d583b39bSJohn Wren Kennedy "while permission is granted." 354