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