1#!/usr/local/bin/ksh93 -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. $STF_SUITE/tests/acl/acl_common.kshlib 28. $STF_SUITE/tests/acl/cifs/cifs.kshlib 29 30################################################################################# 31# 32# __stc_assertion_start 33# 34# ID: zfs_acl_chmod_inherit_003_pos 35# 36# DESCRIPTION: 37# Verify chmod have correct behaviour to directory and file when 38# filesystem has the different aclinherit setting 39# 40# STRATEGY: 41# 1. Loop super user and non-super user to run the test case. 42# 2. Create basedir and a set of subdirectores and files within it. 43# 3. Separately chmod basedir with different inherite options, 44# combine with the variable setting of aclinherit: 45# "discard", "noallow", "secure" or "passthrough". 46# 4. Then create nested directories and files like the following. 47# 48# ofile 49# odir 50# chmod --> basedir -| 51# |_ nfile1 52# |_ ndir1 _ 53# |_ nfile2 54# |_ ndir2 _ 55# |_ nfile3 56# |_ ndir3 57# 58# 5. Verify each directories and files have the correct access control 59# capability. 60# 61# TESTABILITY: explicit 62# 63# TEST_AUTOMATION_LEVEL: automated 64# 65# CODING_STATUS: COMPLETED (2008-07-04) 66# 67# __stc_assertion_end 68# 69################################################################################ 70 71verify_runnable "both" 72 73function cleanup 74{ 75 typeset dir 76 77 # Cleanup basedir, compared file and dir. 78 79 if [[ -f $ofile ]]; then 80 log_must $RM -f $ofile 81 fi 82 83 for dir in $odir $basedir ; do 84 if [[ -d $dir ]]; then 85 log_must $RM -rf $dir 86 fi 87 done 88} 89 90log_assert "Verify chmod have correct behaviour to directory and file when " \ 91 "filesystem has the different aclinherit setting." 92log_onexit cleanup 93 94# Define inherit flag 95set -A aclinherit_flag discard noallow secure passthrough 96set -A object_flag "f-" "-d" "fd" 97set -A strategy_flag "--" "i-" "-n" "in" 98 99typeset ace_prefix1="owner@" 100typeset ace_prefix2="group@" 101typeset ace_prefix3="everyone@" 102typeset ace_discard ace_noallow ace_secure ace_passthrough 103typeset ace_secure_new 104 105# Defile the based directory and file 106basedir=$TESTDIR/basedir; ofile=$TESTDIR/ofile; odir=$TESTDIR/odir 107 108test_requires ZFS_ACL 109 110# Define the files and directories will be created after chmod 111ndir1=$basedir/ndir1; ndir2=$ndir1/ndir2; ndir3=$ndir2/ndir3 112nfile1=$basedir/nfile1; nfile2=$ndir1/nfile2; nfile3=$ndir2/nfile3 113 114# Verify all the node have expected correct access control 115allnodes="$ndir1 $ndir2 $ndir3 $nfile1 $nfile2 $nfile3" 116 117typeset cifs="" 118if cifs_supported ; then 119 cifs="true" 120fi 121 122# 123# According to inherited flag, verify subdirectories and files within it has 124# correct inherited access control. 125# 126function verify_inherit #<aclinherit> <object> [strategy] 127{ 128 # Define the nodes which will be affected by inherit. 129 typeset inherit_nodes 130 typeset inherit=$1 131 typeset obj=$2 132 typeset str=$3 133 134 # count: the ACE item to fetch 135 # pass: to mark if the current ACE should apply to the target 136 # maxnumber: predefine as 4 137 # passcnt: counter, if it achieves to maxnumber, 138 # then no additional ACE should apply. 139 # isinherit: indicate if the current target is in the inherit list. 140 # step: indicate if the ACE be split during inherit. 141 142 typeset -i count=0 pass=0 passcnt=0 isinherit=0 maxnumber=4 step=0 143 144 log_must usr_exec $MKDIR -p $ndir3 145 log_must usr_exec $TOUCH $nfile1 $nfile2 $nfile3 146 147 # Get the files which inherited ACE. 148 if [[ $(get_substr $obj 1 1) == f ]]; then 149 inherit_nodes="$inherit_nodes $nfile1" 150 151 if [[ $(get_substr $str 2 1) != n ]]; then 152 inherit_nodes="$inherit_nodes $nfile2 $nfile3" 153 fi 154 fi 155 # Get the directores which inherited ACE. 156 if [[ $(get_substr $obj 2 1) == d ]]; then 157 inherit_nodes="$inherit_nodes $ndir1" 158 159 if [[ $(get_substr $str 2 1) != n ]]; then 160 inherit_nodes="$inherit_nodes $ndir2 $ndir3" 161 fi 162 fi 163 164 for node in $allnodes; do 165 step=0 166 if [[ " $inherit_nodes " == *" $node "* ]]; then 167 isinherit=1 168 if [[ -d $node ]] ; then 169 step=1 170 fi 171 else 172 isinherit=0 173 fi 174 175 i=0 176 count=0 177 passcnt=0 178 while (( i < maxnumber )); do 179 pass=0 180 eval expect1=\$acl$i 181 expect2=$expect1 182 183 # 184 # aclinherit=passthrough, 185 # inherit all inheritable ACL entries without any 186 # modifications made to the ACL entries when they 187 # are inherited. 188 # 189 # aclinherit=secure, 190 # any inheritable ACL entries will remove 191 # write_acl and write_owner permissions when the ACL entry is 192 # inherited. 193 # 194 # aclinherit=noallow, 195 # only inherit inheritable ACE that specify "deny" permissions 196 # 197 # aclinherit=discard 198 # will not inherit any ACL entries 199 # 200 201 case $inherit in 202 passthrough) 203 if [[ -z $cifs ]]; then 204 break 205 fi 206 207 action=${expect1##*:} 208 expect1=${expect1%:$action} 209 expect1=${expect1%-} 210 expect1=${expect1%I} 211 expect1=${expect1}I:$action 212 ;; 213 secure) 214 eval expect2=\$acls$i 215 ;; 216 noallow) 217 if [[ $expect1 == *":allow" ]] ; then 218 pass=1 219 (( passcnt = passcnt + 1 )) 220 else 221 eval expect2=\$acls$i 222 fi 223 ;; 224 discard) 225 passcnt=maxnumber 226 break 227 ;; 228 esac 229 230 if (( pass == 0 )) ; then 231 acltemp=${expect2%:*} 232 acltemp=${acltemp%:*} 233 aclaction=${expect2##*:} 234 235 if [[ -n $cifs ]]; then 236 expect2=${acltemp}:------I:${aclaction} 237 else 238 expect2=${acltemp}:------:${aclaction} 239 fi 240 241 acltemp=${expect1%:*} 242 inh=${acltemp##*:} 243 244 if [[ -d $node ]]; then 245 if [[ $(get_substr $inh 4 1) == n ]]; then 246 247 # 248 # if no_propagate is set, 249 # then clear all inherit flags, 250 # only one ACE should left. 251 # 252 253 step=0 254 expect1="" 255 256 elif [[ $(get_substr $inh 3 1) != i ]]; then 257 258 # 259 # directory should append 260 # "inherit_only" if not have 261 # 262 acltemp=${acltemp%i*} 263 if [[ -n $cifs ]]; then 264 265 expect1=${acltemp}i---I:${aclaction} 266 else 267 expect1=${acltemp}i---:${aclaction} 268 fi 269 elif [[ -n $cifs ]]; then 270 acltemp=${acltemp%-} 271 acltemp=${acltemp%I} 272 expect1=${acltemp}I:${aclaction} 273 fi 274 275 # 276 # cleanup the first ACE if the directory 277 # not in inherit list 278 # 279 280 if (( isinherit == 0 )); then 281 expect1="" 282 fi 283 elif [[ -f $node ]] ; then 284 expect1="" 285 fi 286 287 # Get the first ACE to do comparison 288 289 aclcur=$(get_ACE $node $count compact) 290 aclcur=${aclcur#$count:} 291 if [[ -n $expect1 && $expect1 != $aclcur ]]; then 292 $LS -Vd $basedir 293 $LS -Vd $node 294 log_fail "$inherit $i #$count " \ 295 "ACE: $aclcur, expect to be " \ 296 "$expect1" 297 fi 298 299 # Get the second ACE (if should have) to do comparison 300 301 if (( step > 0 )); then 302 (( count = count + step )) 303 304 aclcur=$(get_ACE $node $count compact) 305 aclcur=${aclcur#$count:} 306 if [[ -n $expect2 && \ 307 $expect2 != $aclcur ]]; then 308 309 $LS -Vd $basedir 310 $LS -Vd $node 311 log_fail "$inherit $i #$count " \ 312 "ACE: $aclcur, expect to be " \ 313 "$expect2" 314 fi 315 fi 316 (( count = count + 1 )) 317 fi 318 (( i = i + 1 )) 319 done 320 321 # 322 # If there's no any ACE be checked, it should be identify as 323 # an normal file/dir, verify it. 324 # 325 326 if (( passcnt == maxnumber )); then 327 if [[ -d $node ]]; then 328 compare_acls $node $odir 329 elif [[ -f $node ]]; then 330 compare_acls $node $ofile 331 fi 332 333 if [[ $? -ne 0 ]]; then 334 $LS -Vd $basedir 335 $LS -Vd $node 336 log_fail "Unexpect acl: $node, $inherit ($str)" 337 fi 338 fi 339 done 340} 341 342typeset -i i=0 343typeset acl0 acl1 acl2 acl3 344typeset acls0 acls1 acls2 acls3 345 346# 347# Set aclmode=passthrough to make sure 348# the acl will not change during chmod. 349# A general testing should verify the combination of 350# aclmode/aclinherit works well, 351# here we just simple test them separately. 352# 353 354log_must $ZFS set aclmode=passthrough $TESTPOOL/$TESTFS 355 356for inherit in "${aclinherit_flag[@]}"; do 357 358 # 359 # Set different value of aclinherit 360 # 361 362 log_must $ZFS set aclinherit=$inherit $TESTPOOL/$TESTFS 363 364 for user in root $ZFS_ACL_STAFF1; do 365 log_must set_cur_usr $user 366 367 for obj in "${object_flag[@]}"; do 368 for str in "${strategy_flag[@]}"; do 369 typeset inh_opt=$obj 370 (( ${#str} != 0 )) && inh_opt=${inh_opt}${str}-- 371 372 if [[ -n $cifs ]]; then 373 inh_a=${inh_opt}- 374 inh_b=${inh_opt}I 375 else 376 inh_a=${inh_opt} 377 inh_b=${inh_opt} 378 fi 379 380 # 381 # Prepare 4 ACES, which should include : 382 # deny -> to verify "noallow" 383 # write_acl/write_owner -> to verify "secure" 384 # 385 386 acl0="$ace_prefix1:rwxp---A-W-Co-:${inh_a}:allow" 387 acl1="$ace_prefix2:rwxp---A-W-Co-:${inh_a}:deny" 388 acl2="$ace_prefix3:rwxp---A-W-Co-:${inh_a}:allow" 389 acl3="$ace_prefix1:-------A-W----:${inh_a}:deny" 390 acl4="$ace_prefix2:-------A-W----:${inh_a}:allow" 391 acl5="$ace_prefix3:-------A-W----:${inh_a}:deny" 392 393 394 # 395 # The ACE filtered by write_acl/write_owner 396 # 397 398 if [[ $inheri == "passthrough" ]]; then 399 acls0="$ace_prefix1:rwxp---A-W----:${inh_b}:allow" 400 acls1="$ace_prefix2:rwxp---A-W----:${inh_b}:deny" 401 acls2="$ace_prefix3:rwxp---A-W----:${inh_b}:allow" 402 acls3="$ace_prefix1:rwxp---A-W----:${inh_b}:deny" 403 acls4="$ace_prefix2:rwxp---A-W----:${inh_b}:allow" 404 acls5="$ace_prefix3:rwxp---A-W----:${inh_b}:deny" 405 else 406 acls0="$ace_prefix1:-------A-W----:${inh_b}:allow" 407 acls1="$ace_prefix2:-------A-W-Co-:${inh_b}:deny" 408 acls2="$ace_prefix3:-------A-W----:${inh_b}:allow" 409 acls3="$ace_prefix1:-------A-W----:${inh_b}:deny" 410 acls4="$ace_prefix2:-------A-W----:${inh_b}:allow" 411 acls5="$ace_prefix3:-------A-W----:${inh_b}:deny" 412 fi 413 414 # 415 # Create basedir and tmp dir/file 416 # for comparison. 417 # 418 419 log_note "$user: $CHMOD $acl $basedir" 420 log_must usr_exec $MKDIR $basedir 421 log_must usr_exec $MKDIR $odir 422 log_must usr_exec $TOUCH $ofile 423 424 i=5 425 while (( i >= 0 )); do 426 eval acl=\$acl$i 427 428 # 429 # Place on a directory should succeed. 430 # 431 log_must usr_exec $CHMOD A+$acl $basedir 432 433 (( i = i - 1 )) 434 done 435 436 verify_inherit $inherit $obj $str 437 438 log_must usr_exec $RM -rf $ofile $odir $basedir 439 done 440 done 441 done 442done 443 444log_pass "Verify chmod inherit behaviour co-op with aclinherit setting passed." 445