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