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