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