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 2009 Sun Microsystems, Inc. All rights reserved. 25# Use is subject to license terms. 26 27. $STF_SUITE/tests/acl/acl_common.kshlib 28 29################################################################################# 30# 31# __stc_assertion_start 32# 33# ID: zfs_acl_chmod_rwx_002_pos 34# 35# DESCRIPTION: 36# chmod A{+|-|=} read_data|write_data|execute for owner@ group@ or everyone@ 37# correctly alters mode bits . 38# 39# STRATEGY: 40# 1. Loop root and non-root user. 41# 2. Get the random initial map. 42# 3. Get the random ACL string. 43# 4. Separately chmod +|-|= read_data|write_data|execute 44# 5. Check map bits 45# 46# TESTABILITY: explicit 47# 48# TEST_AUTOMATION_LEVEL: automated 49# 50# CODING_STATUS: COMPLETED (2005-10-05) 51# 52# __stc_assertion_end 53# 54################################################################################ 55 56verify_runnable "both" 57 58log_assert "chmod A{+|-|=} read_data|write_data|execute for owner@, group@ " \ 59 "or everyone@ correctly alters mode bits." 60log_onexit cleanup 61 62set -A bits 0 1 2 3 4 5 6 7 63set -A a_flag owner group everyone 64set -A a_access read_data write_data execute 65set -A a_type allow deny 66 67# 68# Get a random item from an array. 69# 70# $1 the base set 71# 72function random_select #array_name 73{ 74 typeset arr_name=$1 75 typeset -i ind 76 77 eval typeset -i cnt=\${#${arr_name}[@]} 78 (( ind = $RANDOM % cnt )) 79 80 eval print \${${arr_name}[$ind]} 81} 82 83# 84# Create a random string according to array name, the item number and 85# separated tag. 86# 87# $1 array name where the function get the elements 88# $2 the items number which you want to form the random string 89# $3 the separated tag 90# 91function form_random_str #<array_name> <count> <sep> 92{ 93 typeset arr_name=$1 94 typeset -i count=${2:-1} 95 typeset sep=${3:-""} 96 97 typeset str="" 98 while (( count > 0 )); do 99 str="${str}$(random_select $arr_name)${sep}" 100 101 (( count -= 1 )) 102 done 103 104 print $str 105} 106 107# 108# According to the original bits, the input ACE access and ACE type, return the 109# expect bits after 'chmod A0{+|=}'. 110# 111# $1 bits which was make up of three bit 'rwx' 112# $2 ACE access which is read_data, write_data or execute 113# $3 ACE type which is allow or deny 114# 115function cal_bits #bits acl_access acl_type 116{ 117 typeset bits=$1 118 typeset acl_access=$2 119 typeset acl_type=$3 120 set -A bit r w x 121 122 typeset tmpbits="" 123 typeset -i i=0 j 124 while (( i < 3 )); do 125 if [[ $acl_access == *"${a_access[i]}"* ]]; then 126 if [[ $acl_type == "allow" ]]; then 127 tmpbits="$tmpbits${bit[i]}" 128 elif [[ $acl_type == "deny" ]]; then 129 tmpbits="${tmpbits}-" 130 fi 131 else 132 (( j = i + 1 )) 133 tmpbits="$tmpbits$(get_substr $bits $j 1)" 134 fi 135 136 (( i += 1 )) 137 done 138 139 print "$tmpbits" 140} 141 142# 143# Based on the initial node map before chmod and the ace-spec, check if chmod 144# has the correct behaven to map bits. 145# 146function check_test_result #init_mode node acl_flag acl_access a_type 147{ 148 typeset init_mode=$1 149 typeset node=$2 150 typeset acl_flag=$3 151 typeset acl_access=$4 152 typeset acl_type=$5 153 154 typeset -3L u_bits=$init_mode 155 typeset g_bits=$(get_substr $init_mode 4 3) 156 typeset -3R o_bits=$init_mode 157 158 if [[ $acl_flag == "owner" || $acl_flag == "everyone" ]]; then 159 u_bits=$(cal_bits $u_bits $acl_access $acl_type) 160 fi 161 if [[ $acl_flag == "group" || $acl_flag == "everyone" ]]; then 162 g_bits=$(cal_bits $g_bits $acl_access $acl_type) 163 fi 164 if [[ $acl_flag == "everyone" ]]; then 165 o_bits=$(cal_bits $o_bits $acl_access $acl_type) 166 fi 167 168 typeset cur_mode=$(get_mode $node) 169 cur_mode=$(get_substr $cur_mode 2 9) 170 171 if [[ $cur_mode == $u_bits$g_bits$o_bits ]]; then 172 log_note "SUCCESS: Current map($cur_mode) ==" \ 173 "expected map($u_bits$g_bits$o_bits)" 174 else 175 log_fail "FAIL: Current map($cur_mode) != " \ 176 "expected map($u_bits$g_bits$o_bits)" 177 fi 178} 179 180function test_chmod_map #<node> 181{ 182 typeset node=$1 183 typeset init_mask acl_flag acl_access acl_type 184 typeset -i cnt 185 186 if (( ${#node} == 0 )); then 187 log_fail "FAIL: file name or directroy name is not defined." 188 fi 189 190 # Get the initial map 191 init_mask=$(form_random_str bits 3) 192 # Get ACL flag, access & type 193 acl_flag=$(form_random_str a_flag) 194 (( cnt = ($RANDOM % ${#a_access[@]}) + 1 )) 195 acl_access=$(form_random_str a_access $cnt '/') 196 acl_access=${acl_access%/} 197 acl_type=$(form_random_str a_type) 198 199 typeset acl_spec=${acl_flag}@:${acl_access}:${acl_type} 200 201 # Set the initial map and back the initial ACEs 202 typeset orig_ace=$TMPDIR/orig_ace.${TESTCASE_ID} 203 typeset cur_ace=$TMPDIR/cur_ace.${TESTCASE_ID} 204 205 for operator in "A0+" "A0="; do 206 log_must usr_exec $CHMOD $init_mask $node 207 init_mode=$(get_mode $node) 208 init_mode=$(get_substr $init_mode 2 9) 209 log_must usr_exec eval "$LS -vd $node > $orig_ace" 210 211 # To "A=", firstly add one ACE which can't modify map 212 if [[ $operator == "A0=" ]]; then 213 log_must $CHMOD A0+user:$ZFS_ACL_OTHER1:execute:deny \ 214 $node 215 fi 216 log_must usr_exec $CHMOD $operator$acl_spec $node 217 check_test_result \ 218 $init_mode $node $acl_flag $acl_access $acl_type 219 220 # Check "chmod A-" 221 log_must usr_exec $CHMOD A0- $node 222 log_must usr_exec eval "$LS -vd $node > $cur_ace" 223 224 if $DIFF $orig_ace $cur_ace; then 225 log_note "SUCCESS: original ACEs equivalence the " \ 226 "current ACEs. 'chmod A-' succeeded." 227 else 228 log_fail "FAIL: 'chmod A-' failed." 229 fi 230 done 231 232 [[ -f $orig_ace ]] && log_must usr_exec $RM -f $orig_ace 233 [[ -f $cur_ace ]] && log_must usr_exec $RM -f $cur_ace 234} 235 236test_requires ZFS_ACL 237 238for user in root $ZFS_ACL_STAFF1; do 239 set_cur_usr $user 240 241 typeset -i loop_cnt=20 242 while (( loop_cnt > 0 )); do 243 log_must usr_exec $TOUCH $testfile 244 test_chmod_map $testfile 245 log_must $RM -f $testfile 246 247 log_must usr_exec $MKDIR $testdir 248 test_chmod_map $testdir 249 log_must $RM -rf $testdir 250 251 (( loop_cnt -= 1 )) 252 done 253done 254 255log_pass "chmod A{+|-|=} read_data|write_data|execute for owner@, group@ " \ 256 "oreveryone@ correctly alters mode bits passed." 257