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