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 2008 Sun Microsystems, Inc.  All rights reserved.
27# Use is subject to license terms.
28#
29# ident	"@(#)cifs_attr_002_pos.ksh	1.1	08/02/27 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: cifs_attr_002_pos
40#
41# DESCRIPTION:
42#	Verify the user with PRIV_FILE_FLAG_SET/PRIV_FILE_FLAG_CLEAR
43#	could set/clear BSD'ish attributes.
44#	(Immutable, nounlink, and appendonly)
45#
46# STRATEGY:
47#	1. Loop super user and non-super user to run the test case.
48#	2. Create basedir and a set of subdirectores and files within it.
49#	3. Grant user has PRIV_FILE_FLAG_SET/PRIV_FILE_FLAG_CLEAR separately.
50#	4. Verify set/clear BSD'ish attributes should succeed.
51#
52# TESTABILITY: explicit
53#
54# TEST_AUTOMATION_LEVEL: automated
55#
56# CODING_STATUS: COMPLETED (2007-11-05)
57#
58# __stc_assertion_end
59#
60################################################################################
61
62verify_runnable "global"
63
64if ! cifs_supported ; then
65	log_unsupported "CIFS not supported on current system."
66fi
67
68test_requires ZFS_ACL ZFS_XATTR
69
70function cleanup
71{
72	if [[ -n $gobject ]]; then
73		destroy_object $gobject
74	fi
75
76	for fs in $TESTPOOL/$TESTFS $TESTPOOL ; do
77		mtpt=$(get_prop mountpoint $fs)
78		log_must $RM -rf $mtpt/file.* $mtpt/dir.*
79	done
80}
81
82#
83# Set the special attribute to the given node
84#
85# $1: The given node (file/dir)
86# $2: The special attribute to be set
87# $3: Execute username
88#
89function set_attribute
90{
91	typeset object=$1
92	typeset attr=$2
93	typeset user=$3
94	typeset ret=0
95
96	if [[ -z $object ]]; then
97		log_fail "Object not defined."
98	fi
99
100	if [[ -z $attr ]]; then
101		attr="uiadm"
102		if [[ -f $object ]]; then
103			attr="${attr}q"
104		fi
105	fi
106
107	if [[ -n $user ]]; then
108		$RUNWATTR -u $user -p =basic${priv_mod} \
109			"$CHMOD S+c${attr} $object"
110		ret=$?
111	else
112		$CHMOD S+c${attr} $object
113		ret=$?
114	fi
115
116	return $ret
117}
118
119#
120# Clear the special attribute to the given node
121#
122# $1: The given node (file/dir)
123# $2: The special attribute to be cleared
124# $3: Execute username
125#
126function clear_attribute
127{
128	typeset object=$1
129	typeset attr=$2
130	typeset user=$3
131	typeset ret=0
132
133	if [[ -z $object ]]; then
134		log_fail "Object($object) not defined."
135	fi
136
137	if [[ -z $attr ]]; then
138		attr="uiadm"
139		if [[ -f $object ]]; then
140			attr="${attr}q"
141		fi
142	fi
143
144	if [[ -n $user ]]; then
145		$RUNWATTR -u $user -p =basic${priv_mod} \
146			"$CHMOD S-c${attr} $object"
147		ret=$?
148	else
149		$CHMOD S-c${attr} $object
150		ret=$?
151	fi
152
153	return $ret
154}
155
156#
157# Grant the privset to the given user
158#
159# $1: The given user
160# $2: The given privset
161#
162function grant_priv
163{
164	typeset user=$1
165	typeset priv=$2
166
167	if [[ -z $user || -z $priv ]]; then
168		log_fail "User($user), Priv($priv) not defined."
169	fi
170	priv_mod=",$priv"
171	return $?
172}
173
174#
175# Revoke the all additional privset from the given user
176#
177# $1: The given user
178#
179function revoke_priv
180{
181	typeset user=$1
182
183	if [[ -z $user ]]; then
184		log_fail "User not defined."
185	fi
186	priv_mod=
187	return $?
188}
189
190#
191# Invoke the function and verify whether its return code as expected
192#
193# $1: Function be invoked
194# $2: The given node (file/dir)
195# $3: Execute user
196# $4: Option
197#
198function verify_op
199{
200	typeset func=$1
201	typeset object=$2
202	typeset opt=$3
203	typeset user=$4
204	typeset expect="log_mustnot"
205
206	if [[ -z $func || -z $object ]]; then
207		log_fail "Func($func), Object($object) not defined."
208	fi
209
210	# If user has PRIV_FILE_FLAG_SET, it could permit to set_attribute,
211	# And If has PRIV_FILE_FLAG_CLEAR, it could permit to clear_attribute,
212	# otherwise log_mustnot.
213	if [[ -z $user || $user == "root" ]] || \
214		[[ $priv_mod == *"file_flag_set"* ]] || \
215		[[ $priv_mod == *"all"* ]] ; then
216			expect="log_must"
217	fi
218	if [[ -d $object ]] && \
219		[[ $opt == *"q"* ]] ; then
220		expect="log_mustnot"
221	fi
222
223	if [[ $func == clear_attribute ]]; then
224		if [[ $expect == "log_mustnot" ]]; then
225			expect="log_must"
226		elif [[ -z $user || $user == "root" ]] || \
227			[[ $priv_mod == *"all"* ]] ; then
228			expect="log_must"
229		else
230			expect="log_mustnot"
231		fi
232	fi
233
234	$expect $func $object $opt $user
235}
236
237log_assert "Verify set/clear BSD'ish attributes will succeed while user has " \
238	"PRIV_FILE_FLAG_SET/PRIV_FILE_FLAG_CLEAR privilege"
239log_onexit cleanup
240
241file="file.0"
242dir="dir.0"
243FLAGOPTIONS="u i a d q m"
244
245typeset gobject
246for fs in $TESTPOOL $TESTPOOL/$TESTFS ; do
247	mtpt=$(get_prop mountpoint $fs)
248	for owner in root $ZFS_ACL_STAFF1 ; do
249
250		create_object "file" $mtpt/$file $owner
251		create_object "dir" $mtpt/$dir $owner
252
253		for object in $mtpt/$file $mtpt/$dir ; do
254			gobject=$object
255			for user in root $ZFS_ACL_STAFF2 ; do
256				log_must grant_priv $user file_flag_set
257				for opt in $FLAGOPTIONS ; do
258					verify_op set_attribute \
259						$object $opt $user
260					verify_op clear_attribute \
261						$object $opt $user
262				done
263				log_must revoke_priv $user
264
265				log_must grant_priv $user all
266				for opt in $FLAGOPTIONS ; do
267					verify_op set_attribute \
268						$object $opt $user
269					verify_op clear_attribute \
270						$object $opt $user
271				done
272				log_must revoke_priv $user
273			done
274		done
275		destroy_object $mtpt/$file $mtpt/$dir
276	done
277done
278
279log_pass "Set/Clear BSD'ish attributes succeed while user has " \
280	"PRIV_FILE_FLAG_SET/PRIV_FILE_FLAG_CLEAR privilege"
281