1#!/bin/ksh -p 2# 3# CDDL HEADER START 4# 5# The contents of this file are subject to the terms of the 6# Common Development and Distribution License (the "License"). 7# You may not use this file except in compliance with the License. 8# 9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10# or http://www.opensolaris.org/os/licensing. 11# See the License for the specific language governing permissions 12# and limitations under the License. 13# 14# When distributing Covered Code, include this CDDL HEADER in each 15# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16# If applicable, add the following below this CDDL HEADER, with the 17# fields enclosed by brackets "[]" replaced with your own identifying 18# information: Portions Copyright [yyyy] [name of copyright owner] 19# 20# CDDL HEADER END 21# 22 23# 24# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26# 27 28# 29# Copyright 2016 Nexenta Systems, Inc. 30# Copyright 2023 RackTop Systems, Inc. 31# 32 33. $STF_SUITE/tests/functional/acl/acl_common.kshlib 34 35# DESCRIPTION: 36# Verify chmod have correct behaviour to directory and file when 37# filesystem has the different aclinherit setting 38# 39# STRATEGY: 40# 1. Use both super user and non-super user to run the test case. 41# 2. Create basedir and a set of subdirectores and files within it. 42# 3. Separately chmod basedir with different inherite options, 43# combine with the variable setting of aclinherit: 44# "discard", "noallow", "restricted" or "passthrough". 45# 4. Then create nested directories and files like the following. 46# 47# ofile 48# odir 49# chmod --> basedir -| 50# |_ nfile1 51# |_ ndir1 _ 52# |_ nfile2 53# |_ ndir2 _ 54# |_ nfile3 55# |_ ndir3 56# 57# 5. Verify each directories and files have the correct access control 58# capability. 59 60verify_runnable "both" 61 62function cleanup 63{ 64 [[ -f $ofile ]] && log_must rm -f $ofile 65 [[ -d $odir ]] && log_must rm -rf $odir 66 [[ -d $basedir ]] && log_must rm -rf $basedir 67} 68 69log_assert "Verify chmod have correct behaviour to directory and file when" \ 70 "filesystem has the different aclinherit setting" 71log_onexit cleanup 72 73# Define inherit flag 74typeset aclinherit_flag=("discard" "noallow" "restricted" "passthrough") 75typeset object_flag=("f-" "-d" "fd") 76typeset strategy_flag=("--" "i-" "-n" "in") 77 78typeset ace_prefix1="owner@" 79typeset ace_prefix2="group@" 80typeset ace_prefix3="everyone@" 81 82# Define the base directory and file 83basedir=$TESTDIR/basedir; ofile=$TESTDIR/ofile; odir=$TESTDIR/odir 84 85# Define the files and directories that will be created after chmod 86ndir1=$basedir/ndir1; ndir2=$ndir1/ndir2; ndir3=$ndir2/ndir3 87nfile1=$basedir/nfile1; nfile2=$ndir1/nfile2; nfile3=$ndir2/nfile3 88 89# Verify all nodes have expected correct access control 90allnodes="$ndir1 $ndir2 $ndir3 $nfile1 $nfile2 $nfile3" 91 92# According to inherited flag, verify subdirectories and files within it has 93# correct inherited access control. 94function verify_inherit #<aclinherit> <object> [strategy] 95{ 96 # Define the nodes which will be affected by inherit. 97 typeset inherit_nodes 98 typeset inherit=$1 99 typeset obj=$2 100 typeset str=$3 101 102 log_must usr_exec mkdir -p $ndir3 103 log_must usr_exec touch $nfile1 $nfile2 $nfile3 104 105 # Check if we have any inheritance flags set 106 if [[ $obj != "--" ]]; then 107 # Files should have inherited ACEs only if file_inherit is set 108 if [[ ${obj:0:1} == "f" ]]; then 109 inherit_nodes="$inherit_nodes $nfile1" 110 if [[ ${str:1:1} != "n" ]]; then 111 inherit_nodes="$inherit_nodes $nfile2 $nfile3" 112 fi 113 fi 114 115 # Directories should have inherited ACEs if file_inherit without 116 # no_propagate and/or dir_inherit is set 117 if [[ (${obj:0:1} == "f" && ${str:1:1} != "n") || 118 ${obj:1:1} == "d" ]]; then 119 inherit_nodes="$inherit_nodes $ndir1" 120 if [[ ${str:1:1} != "n" ]]; then 121 inherit_nodes="$inherit_nodes $ndir2 $ndir3" 122 fi 123 fi 124 fi 125 126 for node in $allnodes; do 127 typeset -i i=0 count=0 inherited=0 128 typeset expacl perm inh act 129 130 if [[ "$inherit_nodes" == *"$node"* ]]; then 131 inherited=1 132 fi 133 134 while ((i < maxaces)); do 135 # If current node isn't in inherit list, there's 136 # nothing to check, skip to checking trivial ACL 137 if ((inherited == 0)); then 138 ((count = maxaces + 1)) 139 break 140 fi 141 142 eval expacl=\$acl$i 143 case $inherit in 144 discard) 145 # Do not inherit any ACEs 146 ((count = maxaces + 1)) 147 break 148 ;; 149 noallow) 150 # Only inherit inheritable ACEs that specify 151 # "deny" permissions 152 if [[ $expacl == *":allow" ]] ; then 153 ((i = i + 1)) 154 continue 155 fi 156 ;; 157 restricted) 158 # Remove write_acl and write_owner permissions 159 # when the ACEs is inherited 160 eval expacl=\$acls$i 161 ;; 162 passthrough) 163 ;; 164 esac 165 166 perm=${expacl%:*} 167 inh=${perm##*:} 168 inh=${inh:0:2} 169 perm=${perm%:*} 170 act=${expacl##*:} 171 172 if [[ -d $node ]]; then 173 # Clear inheritance flags if no_propagate is set 174 if [[ ${str:1:1} == "n" ]]; then 175 inh="--" 176 fi 177 expacl="$perm:$inh" 178 # Set inherit_only if there's a file_inherit 179 # without dir_inherit 180 if [[ ${obj:0:1} == "f" && 181 ${obj:1:1} != "d" ]]; then 182 expacl="${expacl}i---I:$act" 183 else 184 expacl="${expacl}----I:$act" 185 fi 186 elif [[ -f $node ]] ; then 187 expacl="$perm:------I:$act" 188 fi 189 190 aclcur=$(get_ACE $node $count compact) 191 aclcur=${aclcur#$count:} 192 if [[ -n $expacl && $expacl != $aclcur ]]; then 193 ls -Vd $basedir 194 ls -Vd $node 195 log_fail "$inherit $i #$count" \ 196 "expected: $expacl, current: $aclcur" 197 fi 198 199 ((i = i + 1)) 200 ((count = count + 1)) 201 done 202 203 # There were no non-trivial ACEs to check, do the trivial ones 204 if ((count == maxaces + 1)); then 205 if [[ -d $node ]]; then 206 compare_acls $node $odir 207 elif [[ -f $node ]]; then 208 compare_acls $node $ofile 209 fi 210 211 if (( $? != 0 )); then 212 ls -Vd $basedir 213 ls -Vd $node 214 log_fail "unexpected acl: $node," \ 215 "$inherit ($str)" 216 fi 217 fi 218 219 done 220} 221 222typeset -i i=0 maxaces=6 223typeset acl0 acl1 acl2 acl3 acl4 acl5 224typeset acls0 acls1 acls2 acls3 acls4 acls5 225 226log_must zfs set aclmode=passthrough $TESTPOOL/$TESTFS 227 228for inherit in "${aclinherit_flag[@]}"; do 229 log_must zfs set aclinherit=$inherit $TESTPOOL/$TESTFS 230 231 for user in root $ZFS_ACL_STAFF1; do 232 log_must set_cur_usr $user 233 234 for obj in "${object_flag[@]}"; do 235 for str in "${strategy_flag[@]}"; do 236 typeset inh_opt=$obj 237 ((${#str} != 0)) && inh_opt="${inh_opt}${str}--" 238 239 inh_a="${inh_opt}-" 240 inh_b="${inh_opt}I" 241 242 # deny - to verify "noallow" 243 # write_acl/write_owner - to verify "restricted" 244 acl0="$ace_prefix1:rwxp---A-W-Co-:$inh_a:allow" 245 acl1="$ace_prefix2:-------A-W--o-:$inh_a:deny" 246 acl2="$ace_prefix3:-------A-W-Co-:$inh_a:allow" 247 acl3="$ace_prefix1:-------A-W----:$inh_a:deny" 248 acl4="$ace_prefix2:-------A-W----:$inh_a:allow" 249 acl5="$ace_prefix3:-------A-W----:$inh_a:deny" 250 251 # ACEs filtered by write_acl/write_owner 252 acls0="$ace_prefix1:rwxp---A-W----:$inh_b:allow" 253 acls1="$ace_prefix2:-------A-W--o-:$inh_b:deny" 254 acls2="$ace_prefix3:-------A-W----:$inh_b:allow" 255 acls3="$ace_prefix1:-------A-W----:$inh_b:deny" 256 acls4="$ace_prefix2:-------A-W----:$inh_b:allow" 257 acls5="$ace_prefix3:-------A-W----:$inh_b:deny" 258 259 log_must usr_exec mkdir $basedir 260 log_must usr_exec mkdir $odir 261 log_must usr_exec touch $ofile 262 263 ((i = maxaces - 1)) 264 while ((i >= 0)); do 265 eval acl=\$acl$i 266 log_must usr_exec chmod A+$acl $basedir 267 ((i = i - 1)) 268 done 269 270 verify_inherit $inherit $obj $str 271 272 log_must usr_exec rm -rf $ofile $odir $basedir 273 done 274 done 275 done 276done 277 278log_pass "Verify chmod inherit behaviour co-op with aclinherit setting passed" 279