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.
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.
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]
24 # Copyright 2009 Sun Microsystems, Inc. All rights reserved.
25 # Use is subject to license terms.
29 # Copyright (c) 2012, 2016 by Delphix. All rights reserved.
32 .
$STF_SUITE/tests
/functional
/acl
/acl_common.kshlib
33 .
$STF_SUITE/tests
/functional
/acl
/cifs
/cifs.kshlib
37 # Verify the DOS attributes (Readonly, Hidden, Archive, System)
38 # and BSD'ish attributes (Immutable, nounlink, and appendonly)
39 # will provide the proper access limitation as expected.
41 # Readonly means that the content of a file can't be modified, but
42 # timestamps, mode and so on can.
44 # Archive - Indicates if a file should be included in the next backup
45 # of the file system. ZFS will set this bit whenever a file is
48 # Hidden and System (ZFS does nothing special with these, other than
49 # letting a user/application set them.
51 # Immutable (The data can't, change nor can mode, ACL, size and so on)
52 # The only attribute that can be updated is the access time.
54 # Nonunlink - Sort of like immutable except that a file/dir can't be
56 # This will also effect a rename operation, since that involes a
59 # Appendonly - File can only be appended to.
61 # nodump, settable, opaque (These are for the MacOS port) we will
62 # allow them to be set, but have no semantics tied to them.
65 # 1. Loop super user and non-super user to run the test case.
66 # 2. Create basedir and a set of subdirectores and files within it.
67 # 3. Set the file/dir with each kind of special attribute.
68 # 4. Verify the access limitation works as expected.
71 verify_runnable
"both"
75 if [[ -n $gobject ]]; then
76 destroy_object
$gobject
79 for fs
in $TESTPOOL/$TESTFS $TESTPOOL ; do
80 mtpt
=$
(get_prop mountpoint
$fs)
81 log_must
rm -rf $mtpt/file.
* $mtpt/dir.
*
84 [[ -f $TESTFILE ]] && rm $TESTFILE
88 # Set the special attribute to the given node
90 # $1: The given node (file/dir)
91 # $2: The special attribute to be set
93 function set_attribute
98 if [[ -z $attr ]]; then
100 if [[ -f $object ]]; then
104 chmod S
+c
${attr} $object
109 # Clear the special attribute to the given node
111 # $1: The given node (file/dir)
112 # $2: The special attribute to be cleared
114 function clear_attribute
119 if [[ -z $attr ]]; then
120 if is_global_zone
; then
122 if [[ -f $object ]]; then
130 chmod S-c
${attr} $object
135 # A wrapper function to call test function according to the given attr
137 # $1: The given node (file/dir)
138 # $2: The special attribute to be test
140 function test_wrapper
145 if [[ -z $object ||
-z $attr ]]; then
146 log_fail
"Object($object), Attr($attr) not defined."
150 R
) func
=test_readonly
152 i
) func
=test_immutable
154 u
) func
=test_nounlink
156 a
) func
=test_appendonly
160 if [[ -n $func ]]; then
166 # Invoke the function and verify whether its return code as expected
169 # $2-$n: Function and args need to be invoked
171 function verify_expect
178 "$@" > /dev
/null
2>&1
180 if [[ $status -eq 0 ]]; then
181 if ((expect
!= 0)); then
182 log_fail
"$@ unexpect return 0"
185 if ((expect
== 0)); then
186 log_fail
"$@ unexpect return $status"
192 # Unit testing function against overwrite file
194 # $1: The given file node
196 # $3: Expect value, default to be zero
198 function unit_writefile
202 typeset expect
=${3:-0}
203 if [[ -f $object ]]; then
204 verify_expect
$expect chg_usr_exec
$user \
206 verify_expect
$expect chg_usr_exec
$user \
207 "echo '$TESTSTR' > $object"
212 # Unit testing function against write new stuffs into a directory
214 # $1: The given directory node
216 # $3: Expect value, default to be zero
218 function unit_writedir
222 typeset expect
=${3:-0}
224 if [[ -d $object ]]; then
225 verify_expect
$expect chg_usr_exec
$user \
227 verify_expect
$expect chg_usr_exec
$user \
228 mkdir
-p $object/$TESTDIR
232 function unit_appenddata
236 typeset expect
=${3:-0}
238 if [[ ! -d $object ]]; then
239 verify_expect
$expect chg_usr_exec
$user \
240 "echo '$TESTSTR' >> $object"
245 # Unit testing function against delete content from a directory
247 # $1: The given node, dir
249 # $3: Expect value, default to be zero
251 function unit_deletecontent
255 typeset expect
=${3:-0}
257 if [[ -d $object ]]; then
258 for target
in $object/${TESTFILE##*/} $object/$TESTDIR ; do
259 if [[ -e $target ]]; then
260 verify_expect
$expect chg_usr_exec
$user \
261 "mv $target $target.new"
262 verify_expect
$expect chg_usr_exec
$user \
263 "echo y | rm -r $target.new"
270 # Unit testing function against delete a node
272 # $1: The given node, file/dir
274 # $3: Expect value, default to be zero
276 function unit_deletedata
280 typeset expect
=${3:-0}
282 verify_expect
$expect chg_usr_exec
$user \
283 "echo y | rm -r $object"
288 # Unit testing function against write xattr to a node
290 # $1: The given node, file/dir
292 # $3: Expect value, default to be zero
294 function unit_writexattr
298 typeset expect
=${3:-0}
300 verify_expect
$expect chg_usr_exec
$user \
301 runat
$object "cp $TESTFILE $TESTATTR"
302 verify_expect
$expect chg_usr_exec
$user \
303 "runat $object \"echo '$TESTSTR' > $TESTATTR\""
304 verify_expect
$expect chg_usr_exec
$user \
305 "runat $object \"echo '$TESTSTR' >> $TESTATTR\""
306 if [[ $expect -eq 0 ]]; then
307 verify_expect
$expect chg_usr_exec
$user \
308 runat
$object "rm -f $TESTATTR"
313 # Unit testing function against modify accesstime of a node
315 # $1: The given node, file/dir
317 # $3: Expect value, default to be zero
319 function unit_accesstime
323 typeset expect
=${3:-0}
325 if [[ -d $object ]]; then
326 verify_expect
$expect chg_usr_exec
$user ls $object
328 verify_expect
$expect chg_usr_exec
$user cat $object
333 # Unit testing function against modify updatetime of a node
335 # $1: The given node, file/dir
337 # $3: Expect value, default to be zero
339 function unit_updatetime
343 typeset expect
=${3:-0}
344 typeset immutable_expect
=${4:-$expect}
345 verify_expect
$expect chg_usr_exec
$user touch $object
346 verify_expect
$immutable_expect chg_usr_exec
$user touch -a $object
347 verify_expect
$expect chg_usr_exec
$user touch -m $object
351 # Unit testing function against write acl of a node
353 # $1: The given node, file/dir
355 # $3: Expect value, default to be zero
357 function unit_writeacl
361 typeset expect
=${3:-0}
363 verify_expect
$expect chg_usr_exec
$user chmod A
+$TESTACL $object
364 verify_expect
$expect chg_usr_exec
$user chmod A
+$TESTACL $object
365 verify_expect
$expect chg_usr_exec
$user chmod A0-
$object
366 verify_expect
$expect chg_usr_exec
$user chmod A0-
$object
367 oldmode
=$
(get_mode
$object)
368 verify_expect
$expect chg_usr_exec
$user chmod $TESTMODE $object
372 # Testing function to verify the given node is readonly
374 # $1: The given node, file/dir
376 function test_readonly
380 if [[ -z $object ]]; then
381 log_fail
"Object($object) not defined."
384 log_note
"Testing readonly of $object"
386 for user
in $ZFS_ACL_CUR_USER root
$ZFS_ACL_STAFF2; do
387 if [[ -d $object ]]; then
388 log_must usr_exec
chmod \
389 A
+user
:$user:${ace_dir}:allow
$object
391 log_must usr_exec
chmod \
392 A
+user
:$user:${ace_file}:allow
$object
395 log_must set_attribute
$object "R"
397 unit_writefile
$object $user 1
398 unit_writedir
$object $user
399 unit_appenddata
$object $user 1
401 if [[ -d $object ]]; then
402 unit_writexattr
$object $user
404 unit_writexattr
$object $user 1
407 unit_accesstime
$object $user
408 unit_updatetime
$object $user
409 unit_writeacl
$object $user
410 unit_deletecontent
$object $user
411 unit_deletedata
$object $user
413 if [[ -d $object ]] ;then
414 create_object
"dir" $object $ZFS_ACL_CUR_USER
416 create_object
"file" $object $ZFS_ACL_CUR_USER
422 # Testing function to verify the given node is immutable
424 # $1: The given node, file/dir
426 function test_immutable
430 if [[ -z $object ]]; then
431 log_fail
"Object($object) not defined."
434 log_note
"Testing immutable of $object"
436 for user
in $ZFS_ACL_CUR_USER root
$ZFS_ACL_STAFF2; do
437 if [[ -d $object ]]; then
438 log_must usr_exec
chmod \
439 A
+user
:$user:${ace_dir}:allow
$object
441 log_must usr_exec
chmod \
442 A
+user
:$user:${ace_file}:allow
$object
444 log_must set_attribute
$object "i"
446 unit_writefile
$object $user 1
447 unit_writedir
$object $user 1
448 unit_appenddata
$object $user 1
449 unit_writexattr
$object $user 1
450 unit_accesstime
$object $user
451 unit_updatetime
$object $user 1 0
452 unit_writeacl
$object $user 1
453 unit_deletecontent
$object $user 1
454 unit_deletedata
$object $user 1
456 if [[ -d $object ]] ;then
457 create_object
"dir" $object $ZFS_ACL_CUR_USER
459 create_object
"file" $object $ZFS_ACL_CUR_USER
465 # Testing function to verify the given node is nounlink
467 # $1: The given node, file/dir
469 function test_nounlink
473 if [[ -z $object ]]; then
474 log_fail
"Object($object) not defined."
477 echo "Testing nounlink of $object"
479 for user
in $ZFS_ACL_CUR_USER root
$ZFS_ACL_STAFF2; do
480 if [[ -d $object ]]; then
481 log_must usr_exec
chmod \
482 A
+user
:$user:${ace_dir}:allow
$object
484 log_must usr_exec
chmod \
485 A
+user
:$user:${ace_file}:allow
$object
487 log_must set_attribute
$object "u"
489 unit_writefile
$object $user
490 unit_writedir
$object $user
491 unit_appenddata
$object $user
492 unit_writexattr
$object $user
493 unit_accesstime
$object $user
494 unit_updatetime
$object $user
495 unit_writeacl
$object $user
496 unit_deletecontent
$object $user 1
497 unit_deletedata
$object $user 1
499 if [[ -d $object ]] ;then
500 create_object
"dir" $object $ZFS_ACL_CUR_USER
502 create_object
"file" $object $ZFS_ACL_CUR_USER
508 # Testing function to verify the given node is appendonly
510 # $1: The given node, file/dir
512 function test_appendonly
516 if [[ -z $object ]]; then
517 log_fail
"Object($object) not defined."
520 log_note
"Testing appendonly of $object"
522 for user
in $ZFS_ACL_CUR_USER root
$ZFS_ACL_STAFF2; do
523 if [[ -d $object ]]; then
524 log_must usr_exec
chmod \
525 A
+user
:$user:${ace_dir}:allow
$object
527 log_must usr_exec
chmod \
528 A
+user
:$user:${ace_file}:allow
$object
530 log_must set_attribute
$object "a"
532 unit_writefile
$object $user 1
533 unit_writedir
$object $user
534 unit_appenddata
$object $user
535 unit_writexattr
$object $user
536 unit_accesstime
$object $user
537 unit_updatetime
$object $user
538 unit_writeacl
$object $user
539 unit_deletecontent
$object $user
540 unit_deletedata
$object $user
542 if [[ -d $object ]] ;then
543 create_object
"dir" $object $ZFS_ACL_CUR_USER
545 create_object
"file" $object $ZFS_ACL_CUR_USER
550 FILES
="file.0 file.1"
552 XATTRS
="attr.0 attr.1"
553 FS
="$TESTPOOL $TESTPOOL/$TESTFS"
555 if is_global_zone
; then
564 TESTACL
=user
:$ZFS_ACL_OTHER1:write_data
:allow
566 TESTSTR
="ZFS test suites"
568 ace_file
="write_data/append_data/write_xattr/write_acl/write_attributes"
569 ace_dir
="add_file/add_subdirectory/${ace_file}"
571 log_assert
"Verify DOS & BSD'ish attributes will provide the " \
572 "access limitation as expected."
575 echo "$TESTSTR" > $TESTFILE
579 for gattr
in $ATTRS ; do
581 mtpt
=$
(get_prop mountpoint
$fs)
583 for user
in root
$ZFS_ACL_STAFF1; do
584 log_must set_cur_usr
$user
585 for file in $FILES ; do
587 create_object
"file" $gobject $ZFS_ACL_CUR_USER
588 test_wrapper
$gobject $gattr
589 destroy_object
$gobject
592 for dir
in $DIRS ; do
594 create_object
"dir" $gobject $ZFS_ACL_CUR_USER
595 test_wrapper
$gobject $gattr
596 destroy_object
$gobject
602 log_pass
"DOS & BSD'ish attributes provide the access limitation as expected."