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.
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.
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]
24 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
29 # Copyright (c) 2016 by Delphix. All rights reserved.
32 .
$STF_SUITE/tests
/functional
/acl
/acl_common.kshlib
36 # chmod A{+|-|=} read_data|write_data|execute for owner@ group@ or
37 # everyone@ correctly alters mode bits .
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
47 verify_runnable
"both"
49 log_assert
"chmod A{+|-|=} read_data|write_data|execute for owner@, group@ " \
50 "or everyone@ correctly alters mode bits."
53 set -A bits
0 1 2 3 4 5 6 7
54 set -A a_flag owner group everyone
55 set -A a_access read_data write_data execute
56 set -A a_type allow deny
59 # Get a random item from an array.
63 function random_select
#array_name
68 eval typeset
-i cnt
=\
${#${arr_name}[@]}
69 (( ind
= $RANDOM % cnt
))
71 eval print \
${${arr_name}[$ind]}
75 # Create a random string according to array name, the item number and
78 # $1 array name where the function get the elements
79 # $2 the items number which you want to form the random string
80 # $3 the separated tag
82 function form_random_str
#<array_name> <count> <sep>
85 typeset
-i count
=${2:-1}
89 while (( count
> 0 )); do
90 str
="${str}$(random_select $arr_name)${sep}"
99 # According to the original bits, the input ACE access and ACE type, return the
100 # expect bits after 'chmod A0{+|=}'.
102 # $1 bits which was make up of three bit 'rwx'
103 # $2 ACE access which is read_data, write_data or execute
104 # $3 ACE type which is allow or deny
106 function cal_bits
#bits acl_access acl_type
109 typeset acl_access
=$2
115 while (( i
< 3 )); do
116 if [[ $acl_access == *"${a_access[i]}"* ]]; then
117 if [[ $acl_type == "allow" ]]; then
118 tmpbits
="$tmpbits${bit[i]}"
119 elif [[ $acl_type == "deny" ]]; then
120 tmpbits
="${tmpbits}-"
123 tmpbits
="$tmpbits${bits:$i:1}"
133 # Based on the initial node map before chmod and the ace-spec, check if chmod
134 # has the correct behaven to map bits.
136 function check_test_result
#init_mode node acl_flag acl_access a_type
141 typeset acl_access
=$4
144 typeset
-L3 u_bits
=$init_mode
145 typeset g_bits
=${init_mode:3:3}
146 typeset
-R3 o_bits
=$init_mode
148 if [[ $acl_flag == "owner" ||
$acl_flag == "everyone" ]]; then
149 u_bits
=$
(cal_bits
$u_bits $acl_access $acl_type)
151 if [[ $acl_flag == "group" ||
$acl_flag == "everyone" ]]; then
152 g_bits
=$
(cal_bits
$g_bits $acl_access $acl_type)
154 if [[ $acl_flag == "everyone" ]]; then
155 o_bits
=$
(cal_bits
$o_bits $acl_access $acl_type)
158 typeset cur_mode
=$
(get_mode
$node)
159 cur_mode
=${cur_mode:1:9}
161 if [[ $cur_mode == $u_bits$g_bits$o_bits ]]; then
162 log_note
"SUCCESS: Current map($cur_mode) == " \
163 "expected map($u_bits$g_bits$o_bits)"
165 log_fail
"FAIL: Current map($cur_mode) != " \
166 "expected map($u_bits$g_bits$o_bits)"
170 function test_chmod_map
#<node>
173 typeset init_mask acl_flag acl_access acl_type
176 if (( ${#node} == 0 )); then
177 log_fail
"FAIL: file name or directory name is not defined."
180 # Get the initial map
181 init_mask
=$
(form_random_str bits
3)
182 # Get ACL flag, access & type
183 acl_flag
=$
(form_random_str a_flag
)
184 (( cnt
= ($RANDOM % ${#a_access[@]}) + 1 ))
185 acl_access
=$
(form_random_str a_access
$cnt '/')
186 acl_access
=${acl_access%/}
187 acl_type
=$
(form_random_str a_type
)
189 typeset acl_spec
=${acl_flag}@:${acl_access}:${acl_type}
191 # Set the initial map and back the initial ACEs
192 typeset orig_ace
=/tmp
/orig_ace.$$
193 typeset cur_ace
=/tmp
/cur_ace.$$
195 for operator
in "A0+" "A0="; do
196 log_must usr_exec
chmod $init_mask $node
197 init_mode
=$
(get_mode
$node)
198 init_mode
=${init_mode:1:9}
199 log_must usr_exec
eval "ls -vd $node > $orig_ace"
201 # To "A=", firstly add one ACE which can't modify map
202 if [[ $operator == "A0=" ]]; then
203 log_must
chmod A0
+user
:$ZFS_ACL_OTHER1:execute
:deny \
206 log_must usr_exec
chmod $operator$acl_spec $node
208 $init_mode $node $acl_flag $acl_access $acl_type
211 log_must usr_exec
chmod A0-
$node
212 log_must usr_exec
eval "ls -vd $node > $cur_ace"
214 if diff $orig_ace $cur_ace; then
215 log_note
"SUCCESS: current ACEs are equal to " \
216 "original ACEs. 'chmod A-' succeeded."
218 log_fail
"FAIL: 'chmod A-' failed."
222 [[ -f $orig_ace ]] && log_must usr_exec
rm -f $orig_ace
223 [[ -f $cur_ace ]] && log_must usr_exec
rm -f $cur_ace
226 for user
in root
$ZFS_ACL_STAFF1; do
229 typeset
-i loop_cnt
=20
230 while (( loop_cnt
> 0 )); do
231 log_must usr_exec
touch $testfile
232 test_chmod_map
$testfile
233 log_must
rm -f $testfile
235 log_must usr_exec mkdir
$testdir
236 test_chmod_map
$testdir
237 log_must
rm -rf $testdir
243 log_pass
"chmod A{+|-|=} read_data|write_data|execute for owner@, group@ " \
244 "or everyone@ correctly alters mode bits passed."