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