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 (c) 2012 by Delphix. All rights reserved. 30# 31 32. $STF_SUITE/tests/functional/acl/acl_common.kshlib 33 34# 35# DESCRIPTION: 36# Verify chmod have correct behaviour to directory and file not inherited 37# when filesystem has the different aclinherit setting 38# 39# STRATEGY: 40# 1. Loop 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 non-inherited directories and files have the correct access 58# control capability. 59# 60 61verify_runnable "both" 62 63function cleanup 64{ 65 typeset dir 66 67 # Cleanup basedir, compared file and dir. 68 69 if [[ -f $ofile ]]; then 70 log_must $RM -f $ofile 71 fi 72 73 for dir in $odir $basedir ; do 74 if [[ -d $dir ]]; then 75 log_must $RM -rf $dir 76 fi 77 done 78 log_must $ZFS set aclmode=discard $TESTPOOL/$TESTFS 79} 80 81log_assert "Verify chmod have correct behaviour to directory and file when " \ 82 "filesystem has the different aclinherit setting." 83log_onexit cleanup 84 85# Define inherit flag 86typeset aclinherit_flag=(discard noallow restricted passthrough) 87typeset object_flag=(file_inherit dir_inherit file_inherit/dir_inherit) 88typeset strategy_flag=("" inherit_only no_propagate inherit_only/no_propagate) 89 90typeset ace_prefix1="user:$ZFS_ACL_OTHER1" 91typeset ace_prefix2="user:$ZFS_ACL_OTHER2" 92typeset ace_discard ace_noallow ace_secure ace_passthrough 93typeset ace_secure_new 94 95# Defile the based directory and file 96basedir=$TESTDIR/basedir; ofile=$TESTDIR/ofile; odir=$TESTDIR/odir 97 98# Define the files and directories will be created after chmod 99ndir1=$basedir/ndir1; ndir2=$ndir1/ndir2; ndir3=$ndir2/ndir3 100nfile1=$basedir/nfile1; nfile2=$ndir1/nfile2; nfile3=$ndir2/nfile3 101 102# Verify all the node have expected correct access control 103allnodes="$ndir1 $ndir2 $ndir3 $nfile1 $nfile2 $nfile3" 104 105# 106# According to inherited flag, verify subdirectories and files within it has 107# correct inherited access control. 108# 109function verify_inherit #<aclinherit> <object> [strategy] 110{ 111 # Define the nodes which will be affected by inherit. 112 typeset non_inherit_nodes="" 113 typeset inherit=$1 114 typeset obj=$2 115 typeset str=$3 116 typeset inherit_type 117 typeset str1="/inherit_only/inherited:" 118 typeset str2="/inherited:" 119 120 # count: the ACE item to fetch 121 # maxnumber: predefine as 4 122 # passcnt: counter, if it achieves to maxnumber, 123 # then no additional ACE should apply. 124 # isinherit: indicate if the current target is in the inherit list. 125 126 typeset -i count=0 pass=0 passcnt=0 isinherit=0 maxnumber=4 no_propagate=0 127 128 log_must usr_exec $MKDIR -p $ndir3 129 log_must usr_exec $TOUCH $nfile1 $nfile2 $nfile3 130 131 # Get the inherit type/object_flag and non-inherited nodes. 132 if [[ $obj == *"file_inherit"* && $obj == *"dir_inherit"* ]]; then 133 inherit_type="both" 134 if [[ $str == *"no_propagate"* ]]; then 135 non_inherit_nodes= $ndir2 $ndir3 $nfile2 $nfile3 136 no_propagate=1 137 fi 138 elif [[ $obj == *"dir_inherit"* ]]; then 139 inherit_type="directory" 140 non_inherit_nodes="$nfile1 $nfile2 $nfile3" 141 if [[ $str == *"no_propagate"* ]]; then 142 non_inherit_nodes="$non_inherit_nodes $ndir2 $ndir3" 143 no_propagate=1 144 fi 145 else 146 inherit_type="file" 147 non_inherit_nodes="$ndir1 $ndir2 $ndir3" 148 if [[ $str == *"no_propagate"* ]]; then 149 non_inherit_nodes="$non_inherit_nodes $nfile2 $nfile3" 150 no_propagate=1 151 fi 152 fi 153 # Verify ACE's for all the dirs/files under $basedir 154 for node in $allnodes; do 155 if [[ " $non_inherit_nodes " == *" $node "* ]]; then 156 no_inherit=1 157 else 158 no_inherit=0 159 fi 160 i=0 161 count=0 162 passcnt=0 163 while ((i < maxnumber)); do 164 pass=0 165 eval expect1=\$acl$i 166 case $inherit in 167 noallow) 168 [[ $expect1 == *":allow" ]] && pass=1 169 ;; 170 discard) 171 passcnt=maxnumber 172 break 173 ;; 174 esac 175 if ((pass == 0 && no_inherit == 1)); then 176 aclaction=${expect1##*:} 177 acltemp=${expect1%:*} 178 # Verify ACE's for sub-directory 179 if [[ -d $node ]]; then 180 eval expect1=\$acl$i 181 acltemp=${expect1%:*} 182 if [[ $inherit_type == "directory" || \ 183 $inherit_type == "both" ]]; then 184 expect1=${acltemp}/inherited: 185 expect1=${expect1}${aclaction} 186 elif [[ $inherit_type == "file" ]]; then 187 if [[ $expect1 != \ 188 *"inherit_only"* ]]; then 189 # 190 # directory should append 191 # "inherit_only" if not have 192 # 193 expect1=${acltemp}${str1} 194 expect1=${expect1}${aclaction} 195 else 196 expect1=${acltemp}${str2} 197 expect1=${expect1}${aclaction} 198 fi 199 fi 200 aclcur=$(get_ACE $node $count) 201 aclcur=${aclcur#$count:} 202 if [[ $no_propagate == 0 ]]; then 203 if [[ $expect1 != $aclcur ]]; then 204 $LS -vd $basedir 205 $LS -vd $node 206 log_fail "$inherit $i #"\ 207 "$count ACE: $aclcur"\ 208 "expect to be $expect1" 209 fi 210 else 211 # compare if directory has basic 212 # ACL's 213 compare_acls $node $odir 214 if [[ $? -ne 0 ]]; then 215 $LS -vd $basedir 216 $LS -vd $node 217 log_fail "Unexpect acl:"\ 218 " $node, $inherit" 219 "($str)" 220 fi 221 fi 222 # Verify ACE's for nested file 223 elif [[ -f $node ]]; then 224 compare_acls $node $ofile 225 if [[ $? -ne 0 ]]; then 226 $LS -vd $basedir 227 $LS -vd $node 228 log_fail "Unexpect acl: $node," \ 229 "$inherit ($str)" 230 fi 231 232 fi 233 ((count = count + 1)) 234 fi 235 ((i = i + 1)) 236 done 237 238 # 239 # If there's no any ACE be checked, it should be identify as 240 # an normal file/dir, verify it. 241 # 242 243 if ((passcnt == maxnumber)); then 244 if [[ -d $node ]]; then 245 compare_acls $node $odir 246 elif [[ -f $node ]]; then 247 compare_acls $node $ofile 248 fi 249 250 if [[ $? -ne 0 ]]; then 251 $LS -vd $basedir 252 $LS -vd $node 253 log_fail "Unexpect acl: $node, $inherit ($str)" 254 fi 255 fi 256 done 257} 258 259typeset -i i=0 260typeset acl0 acl1 acl2 acl3 261typeset acls0 acls1 acls2 acls3 262 263# 264# Set aclmode=passthrough to make sure 265# the acl will not change during chmod. 266# A general testing should verify the combination of 267# aclmode/aclinherit works well, 268# here we just simple test them separately. 269# 270 271log_must $ZFS set aclmode=passthrough $TESTPOOL/$TESTFS 272 273for inherit in "${aclinherit_flag[@]}"; do 274 275 # 276 # Set different value of aclinherit 277 # 278 279 log_must $ZFS set aclinherit=$inherit $TESTPOOL/$TESTFS 280 281 for user in root $ZFS_ACL_STAFF1; do 282 log_must set_cur_usr $user 283 284 for obj in "${object_flag[@]}"; do 285 for str in "${strategy_flag[@]}"; do 286 typeset inh_opt=$obj 287 ((${#str} != 0)) && inh_opt=$inh_opt/$str 288 289 # 290 # Prepare 4 ACES, which should include : 291 # deny -> to verify "noallow" 292 # write_acl/write_owner -> to verify "secure" 293 # 294 295 acl0=${ace_prefix1}":read_xattr/write_acl/" 296 acl0=${acl0}"write_owner:"${inh_opt}":deny" 297 acl1="$ace_prefix2:read_xattr/write_acl/" 298 acl1=${acl1}"write_owner:$inh_opt:allow" 299 acl2="$ace_prefix1:read_xattr:$inh_opt:deny" 300 acl3="$ace_prefix2:read_xattr:$inh_opt:allow" 301 302 # 303 # The ACE filtered by write_acl/write_owner 304 # 305 306 acls0="$ace_prefix1:read_xattr:$inh_opt:deny" 307 acls1="$ace_prefix2:read_xattr:$inh_opt:allow" 308 acls2=$acl2 309 acls3=$acl3 310 # 311 # Create basedir and tmp dir/file 312 # for comparison. 313 # 314 log_note "$user: $CHMOD $acl $basedir" 315 log_must usr_exec $MKDIR $basedir 316 log_must usr_exec $MKDIR $odir 317 log_must usr_exec $TOUCH $ofile 318 319 i=3 320 while ((i >= 0)); do 321 eval acl=\$acl$i 322 323 # 324 # Place on a directory should succeed. 325 # 326 log_must usr_exec $CHMOD A+$acl $basedir 327 328 ((i = i - 1)) 329 done 330 log_note "verify_inherit $inherit $obj $str" 331 log_must verify_inherit $inherit $obj $str 332 333 log_must usr_exec $RM -rf $ofile $odir $basedir 334 done 335 done 336 done 337done 338 339log_pass "Verify chmod inherit behaviour co-op with aclinherit setting passed." 340