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