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 j 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 (( j = i + 1 )) 120 tmpbits="$tmpbits$(get_substr $bits $j 1)" 121 fi 122 123 (( i += 1 )) 124 done 125 126 echo "$tmpbits" 127} 128 129# 130# Based on the initial node map before chmod and the ace-spec, check if chmod 131# has the correct behaven to map bits. 132# 133function check_test_result #init_mode node acl_flag acl_access a_type 134{ 135 typeset init_mode=$1 136 typeset node=$2 137 typeset acl_flag=$3 138 typeset acl_access=$4 139 typeset acl_type=$5 140 141 typeset -3L u_bits=$init_mode 142 typeset g_bits=$(get_substr $init_mode 4 3) 143 typeset -3R o_bits=$init_mode 144 145 if [[ $acl_flag == "owner" || $acl_flag == "everyone" ]]; then 146 u_bits=$(cal_bits $u_bits $acl_access $acl_type) 147 fi 148 if [[ $acl_flag == "group" || $acl_flag == "everyone" ]]; then 149 g_bits=$(cal_bits $g_bits $acl_access $acl_type) 150 fi 151 if [[ $acl_flag == "everyone" ]]; then 152 o_bits=$(cal_bits $o_bits $acl_access $acl_type) 153 fi 154 155 typeset cur_mode=$(get_mode $node) 156 cur_mode=$(get_substr $cur_mode 2 9) 157 158 if [[ $cur_mode == $u_bits$g_bits$o_bits ]]; then 159 log_note "SUCCESS: Current map($cur_mode) ==" \ 160 "expected map($u_bits$g_bits$o_bits)" 161 else 162 log_fail "FAIL: Current map($cur_mode) != " \ 163 "expected map($u_bits$g_bits$o_bits)" 164 fi 165} 166 167function test_chmod_map #<node> 168{ 169 typeset node=$1 170 typeset init_mask acl_flag acl_access acl_type 171 typeset -i cnt 172 173 if (( ${#node} == 0 )); then 174 log_fail "FAIL: file name or directroy name is not defined." 175 fi 176 177 # Get the initial map 178 init_mask=$(form_random_str bits 3) 179 # Get ACL flag, access & type 180 acl_flag=$(form_random_str a_flag) 181 (( cnt = ($RANDOM % ${#a_access[@]}) + 1 )) 182 acl_access=$(form_random_str a_access $cnt '/') 183 acl_access=${acl_access%/} 184 acl_type=$(form_random_str a_type) 185 186 typeset acl_spec=${acl_flag}@:${acl_access}:${acl_type} 187 188 # Set the initial map and back the initial ACEs 189 typeset orig_ace=/tmp/orig_ace.$$ 190 typeset cur_ace=/tmp/cur_ace.$$ 191 192 for operator in "A0+" "A0="; do 193 log_must usr_exec $CHMOD $init_mask $node 194 init_mode=$(get_mode $node) 195 init_mode=$(get_substr $init_mode 2 9) 196 log_must usr_exec eval "$LS -vd $node > $orig_ace" 197 198 # To "A=", firstly add one ACE which can't modify map 199 if [[ $operator == "A0=" ]]; then 200 log_must $CHMOD A0+user:$ZFS_ACL_OTHER1:execute:deny \ 201 $node 202 fi 203 log_must usr_exec $CHMOD $operator$acl_spec $node 204 check_test_result \ 205 $init_mode $node $acl_flag $acl_access $acl_type 206 207 # Check "chmod A-" 208 log_must usr_exec $CHMOD A0- $node 209 log_must usr_exec eval "$LS -vd $node > $cur_ace" 210 211 if $DIFF $orig_ace $cur_ace; then 212 log_note "SUCCESS: original ACEs equivalence the " \ 213 "current ACEs. 'chmod A-' succeeded." 214 else 215 log_fail "FAIL: 'chmod A-' failed." 216 fi 217 done 218 219 [[ -f $orig_ace ]] && log_must usr_exec $RM -f $orig_ace 220 [[ -f $cur_ace ]] && log_must usr_exec $RM -f $cur_ace 221} 222 223for user in root $ZFS_ACL_STAFF1; do 224 set_cur_usr $user 225 226 typeset -i loop_cnt=20 227 while (( loop_cnt > 0 )); do 228 log_must usr_exec $TOUCH $testfile 229 test_chmod_map $testfile 230 log_must $RM -f $testfile 231 232 log_must usr_exec $MKDIR $testdir 233 test_chmod_map $testdir 234 log_must $RM -rf $testdir 235 236 (( loop_cnt -= 1 )) 237 done 238done 239 240log_pass "chmod A{+|-|=} read_data|write_data|execute for owner@, group@ " \ 241 "oreveryone@ correctly alters mode bits passed." 242