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