7290 ZFS test suite needs to control what utilities it can run
[unleashed.git] / usr / src / test / zfs-tests / tests / functional / acl / cifs / cifs_attr_003_pos.ksh
bloba47ad0277bf80dfafc2c84faa8e4eea00591627f
1 #!/bin/ksh -p
3 # CDDL HEADER START
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]
20 # CDDL HEADER END
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
36 # DESCRIPTION:
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
46 # modified.
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
55 # removed.
56 # This will also effect a rename operation, since that involes a
57 # remove.
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.
64 # STRATEGY:
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"
73 function cleanup
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.*
82 done
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
95 typeset object=$1
96 typeset attr=$2
98 if [[ -z $attr ]]; then
99 attr="AHRSadimu"
100 if [[ -f $object ]]; then
101 attr="${attr}q"
104 chmod S+c${attr} $object
105 return $?
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
116 typeset object=$1
117 typeset attr=$2
119 if [[ -z $attr ]]; then
120 if is_global_zone ; then
121 attr="AHRSadimu"
122 if [[ -f $object ]]; then
123 attr="${attr}q"
125 else
126 attr="AHRS"
130 chmod S-c${attr} $object
131 return $?
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
142 typeset object=$1
143 typeset attr=$2
145 if [[ -z $object || -z $attr ]]; then
146 log_fail "Object($object), Attr($attr) not defined."
149 case $attr in
150 R) func=test_readonly
152 i) func=test_immutable
154 u) func=test_nounlink
156 a) func=test_appendonly
158 esac
160 if [[ -n $func ]]; then
161 $func $object
166 # Invoke the function and verify whether its return code as expected
168 # $1: Expect value
169 # $2-$n: Function and args need to be invoked
171 function verify_expect
173 typeset -i expect=$1
174 typeset status
176 shift
178 "$@" > /dev/null 2>&1
179 status=$?
180 if [[ $status -eq 0 ]]; then
181 if ((expect != 0)); then
182 log_fail "$@ unexpect return 0"
184 else
185 if ((expect == 0)); then
186 log_fail "$@ unexpect return $status"
192 # Unit testing function against overwrite file
194 # $1: The given file node
195 # $2: Execute user
196 # $3: Expect value, default to be zero
198 function unit_writefile
200 typeset object=$1
201 typeset user=$2
202 typeset expect=${3:-0}
203 if [[ -f $object ]]; then
204 verify_expect $expect chg_usr_exec $user \
205 cp $TESTFILE $object
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
215 # $2: Execute user
216 # $3: Expect value, default to be zero
218 function unit_writedir
220 typeset object=$1
221 typeset user=$2
222 typeset expect=${3:-0}
224 if [[ -d $object ]]; then
225 verify_expect $expect chg_usr_exec $user \
226 cp $TESTFILE $object
227 verify_expect $expect chg_usr_exec $user \
228 mkdir -p $object/$TESTDIR
232 function unit_appenddata
234 typeset object=$1
235 typeset user=$2
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
248 # $2: Execute user
249 # $3: Expect value, default to be zero
251 function unit_deletecontent
253 typeset object=$1
254 typeset user=$2
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"
265 done
270 # Unit testing function against delete a node
272 # $1: The given node, file/dir
273 # $2: Execute user
274 # $3: Expect value, default to be zero
276 function unit_deletedata
278 typeset object=$1
279 typeset user=$2
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
291 # $2: Execute user
292 # $3: Expect value, default to be zero
294 function unit_writexattr
296 typeset object=$1
297 typeset user=$2
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
316 # $2: Execute user
317 # $3: Expect value, default to be zero
319 function unit_accesstime
321 typeset object=$1
322 typeset user=$2
323 typeset expect=${3:-0}
325 if [[ -d $object ]]; then
326 verify_expect $expect chg_usr_exec $user ls $object
327 else
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
336 # $2: Execute user
337 # $3: Expect value, default to be zero
339 function unit_updatetime
341 typeset object=$1
342 typeset user=$2
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
354 # $2: Execute user
355 # $3: Expect value, default to be zero
357 function unit_writeacl
359 typeset object=$1
360 typeset user=$2
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
378 typeset object=$1
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
390 else
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
403 else
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
415 else
416 create_object "file" $object $ZFS_ACL_CUR_USER
418 done
422 # Testing function to verify the given node is immutable
424 # $1: The given node, file/dir
426 function test_immutable
428 typeset object=$1
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
440 else
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
458 else
459 create_object "file" $object $ZFS_ACL_CUR_USER
461 done
465 # Testing function to verify the given node is nounlink
467 # $1: The given node, file/dir
469 function test_nounlink
471 typeset object=$1
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
483 else
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
501 else
502 create_object "file" $object $ZFS_ACL_CUR_USER
504 done
508 # Testing function to verify the given node is appendonly
510 # $1: The given node, file/dir
512 function test_appendonly
514 typeset object=$1
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
526 else
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
544 else
545 create_object "file" $object $ZFS_ACL_CUR_USER
547 done
550 FILES="file.0 file.1"
551 DIRS="dir.0 dir.1"
552 XATTRS="attr.0 attr.1"
553 FS="$TESTPOOL $TESTPOOL/$TESTFS"
555 if is_global_zone ; then
556 ATTRS="R i u a"
557 else
558 ATTRS="R"
561 TESTFILE=/tmp/tfile
562 TESTDIR=tdir
563 TESTATTR=tattr
564 TESTACL=user:$ZFS_ACL_OTHER1:write_data:allow
565 TESTMODE=777
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."
573 log_onexit cleanup
575 echo "$TESTSTR" > $TESTFILE
577 typeset gobject
578 typeset gattr
579 for gattr in $ATTRS ; do
580 for fs in $FS ; do
581 mtpt=$(get_prop mountpoint $fs)
582 chmod 777 $mtpt
583 for user in root $ZFS_ACL_STAFF1; do
584 log_must set_cur_usr $user
585 for file in $FILES ; do
586 gobject=$mtpt/$file
587 create_object "file" $gobject $ZFS_ACL_CUR_USER
588 test_wrapper $gobject $gattr
589 destroy_object $gobject
590 done
592 for dir in $DIRS ; do
593 gobject=$mtpt/$dir
594 create_object "dir" $gobject $ZFS_ACL_CUR_USER
595 test_wrapper $gobject $gattr
596 destroy_object $gobject
597 done
598 done
599 done
600 done
602 log_pass "DOS & BSD'ish attributes provide the access limitation as expected."