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. $STF_SUITE/tests/acl/cifs/cifs.kshlib
29
30#################################################################################
31#
32# __stc_assertion_start
33#
34# ID: zfs_acl_chmod_compact_001_pos
35#
36# DESCRIPTION:
37#	chmod A{+|-|=} could set compact ACL correctly.
38#
39# STRATEGY:
40#	1. Loop root and non-root user.
41#	2. Get the random compact ACL string.
42#	4. Separately chmod +|-|=
43#	5. Check compact ACL display as expected
44#
45# TESTABILITY: explicit
46#
47# TEST_AUTOMATION_LEVEL: automated
48#
49# CODING_STATUS: COMPLETED (2006-08-11)
50#
51# __stc_assertion_end
52#
53################################################################################
54
55verify_runnable "both"
56
57test_requires ZFS_ACL
58
59log_assert "chmod A{+|=} should set compact ACL correctly."
60log_onexit cleanup
61
62set -A a_flag owner group everyone
63set -A a_access r w x p d D a A R W c C o s
64set -A a_inherit_object f d
65set -A a_inherit_strategy i n
66set -A a_type allow deny
67
68typeset cifs=""
69
70if cifs_supported ; then
71	cifs="true"
72fi
73
74#
75# Get a random item from an array.
76#
77# $1 the base set
78#
79function random_select #array_name
80{
81	typeset arr_name=$1
82	typeset -i ind
83
84	eval typeset -i cnt=\${#${arr_name}[@]}
85	(( ind = $RANDOM % cnt ))
86
87	eval print \${${arr_name}[$ind]}
88}
89
90#
91# Create a random string according to array name, the item number and
92# separated tag.
93#
94# $1 array name where the function get the elements
95# $2 the items number which you want to form the random string
96# $3 the separated tag
97#
98function form_random_str #<array_name> <count> <sep>
99{
100	typeset arr_name=$1
101	typeset -i count=${2:-1}
102	typeset sep=${3:-""}
103
104	typeset str=""
105	while (( count > 0 )); do
106		str="${str}$(random_select $arr_name)${sep}"
107
108		(( count -= 1 ))
109	done
110
111	print $str
112}
113
114#
115# According to the input ACE access,ACE type, and inherit flags, return the
116# expect compact ACE that could be used by chmod A0{+|=}'.
117#
118# $1 ACE flag which is owner, group, or everyone
119# $2 ACE access generated by the element of a_access
120# $3 ACE inherit_object generated by the element of a_inherit_object
121# $4 ACE inherit_strategy generated by the element of a_inherit_strategy
122# $5 ACE type which is allow or deny
123#
124function cal_ace # acl_flag acl_access \
125		 # acl_inherit_object acl_inherit_strategy acl_type
126{
127	typeset acl_flag=$1
128	typeset acl_access=$2
129	typeset acl_inherit_object=$3
130	typeset acl_inherit_strategy=$4
131	typeset acl_type=$5
132
133	tmp_ace=${acl_flag}@:
134
135	for element in ${a_access[@]} ; do
136		if [[ $acl_access == *"$element"* ]]; then
137			tmp_ace="${tmp_ace}${element}"
138		else
139			tmp_ace="${tmp_ace}-"
140		fi
141	done
142	tmp_ace=${tmp_ace}:
143
144	for element in ${a_inherit_object[@]} ; do
145		if [[ $acl_inherit_object == *"$element"* ]]; then
146			tmp_ace="${tmp_ace}${element}"
147		else
148			tmp_ace="${tmp_ace}-"
149		fi
150	done
151	for element in ${a_inherit_strategy[@]} ; do
152		if [[ $acl_inherit_strategy == *"$element"* ]]; then
153			tmp_ace="${tmp_ace}${element}"
154		else
155			tmp_ace="${tmp_ace}-"
156		fi
157	done
158
159	if [[ -n $cifs ]]; then
160		tmp_ace=${tmp_ace}---:${acl_type}
161	else
162		tmp_ace=${tmp_ace}--:${acl_type}
163	fi
164
165	print "${tmp_ace}"
166}
167
168#
169# Check if chmod set the compact ACE correctly.
170#
171function check_test_result # node acl_flag acl_access \
172			   # acl_inherit_object acl_inherit_strategy acl_type
173{
174	typeset node=$1
175	typeset acl_flag=$2
176	typeset acl_access=$3
177	typeset acl_inherit_object=$4
178	typeset acl_inherit_strategy=$5
179	typeset acl_type=$6
180
181	typeset expect_ace=$(cal_ace "$acl_flag" "$acl_access" \
182		"$acl_inherit_object" "$acl_inherit_strategy" "$acl_type")
183
184	typeset cur_ace=$(get_ACE $node 0 "compact")
185
186	if [[ $cur_ace != $expect_ace ]]; then
187		log_fail "FAIL: Current map($cur_ace) !=  \
188			expected ace($expect_ace)"
189	fi
190}
191
192function test_chmod_map #<node>
193{
194	typeset node=$1
195	typeset acl_flag acl_access acl_inherit_object acl_inherit_strategy acl_type
196	typeset -i cnt
197
198	if (( ${#node} == 0 )); then
199		log_fail "FAIL: file name or directroy name is not defined."
200	fi
201
202        # Get ACL flag, access & type
203	acl_flag=$(form_random_str a_flag)
204	(( cnt = ($RANDOM % ${#a_access[@]}) + 1 ))
205	acl_access=$(form_random_str a_access $cnt)
206	acl_access=${acl_access%/}
207	acl_type=$(form_random_str a_type 1)
208
209	acl_spec=${acl_flag}@:${acl_access}
210	if [[ -d $node ]]; then
211		# Get ACL inherit_object & inherit_strategy
212		(( cnt = ($RANDOM % ${#a_inherit_object[@]}) + 1 ))
213		acl_inherit_object=$(form_random_str a_inherit_object $cnt)
214		(( cnt = ($RANDOM % ${#a_inherit_strategy[@]}) + 1 ))
215		acl_inherit_strategy=$(form_random_str a_inherit_strategy $cnt)
216		acl_spec=${acl_spec}:${acl_inherit_object}${acl_inherit_strategy}
217	fi
218	acl_spec=${acl_spec}:${acl_type}
219
220	# Set the initial map and back the initial ACEs
221	typeset orig_ace=$TMPDIR/orig_ace.${TESTCASE_ID}
222	typeset cur_ace=$TMPDIR/cur_ace.${TESTCASE_ID}
223
224	for operator in "A0+" "A0="; do
225		log_must usr_exec eval "$LS -Vd $node > $orig_ace"
226
227		# To "A=", firstly add one ACE which can't modify map
228		if [[ $operator == "A0=" ]]; then
229			log_must $CHMOD A0+user:$ZFS_ACL_OTHER1:execute:deny \
230				$node
231		fi
232		log_must usr_exec $CHMOD ${operator}${acl_spec} $node
233
234		check_test_result \
235			"$node" "$acl_flag" "$acl_access" \
236			"$acl_inherit_object" "$acl_inherit_strategy" \
237			"$acl_type"
238
239		# Check "chmod A-"
240		log_must usr_exec $CHMOD A0- $node
241		log_must usr_exec eval "$LS -Vd $node > $cur_ace"
242
243		$DIFF $orig_ace $cur_ace
244		[[ $? -ne 0 ]] && \
245			log_fail "FAIL: 'chmod A-' failed."
246	done
247
248	[[ -f $orig_ace ]] && log_must usr_exec $RM -f $orig_ace
249	[[ -f $cur_ace ]] && log_must usr_exec $RM -f $cur_ace
250}
251
252for user in root $ZFS_ACL_STAFF1; do
253	set_cur_usr $user
254
255	typeset -i loop_cnt=2
256	while (( loop_cnt > 0 )); do
257		log_must usr_exec $TOUCH $testfile
258		test_chmod_map $testfile
259		log_must $RM -f $testfile
260
261		log_must usr_exec $MKDIR $testdir
262		test_chmod_map $testdir
263		log_must $RM -rf $testdir
264
265		(( loop_cnt -= 1 ))
266	done
267done
268
269log_pass "chmod A{+|=} set compact ACL correctly."
270