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