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 2009 Sun Microsystems, Inc. All rights reserved. 27# Use is subject to license terms. 28# 29# ident "@(#)cifs_attr_003_pos.ksh 1.4 09/05/19 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_003_pos 40# 41# DESCRIPTION: 42# Verify the DOS attributes (Readonly, Hidden, Archive, System) 43# and BSD'ish attributes (Immutable, nounlink, and appendonly) 44# will provide the proper access limitation as expected. 45# 46# Readonly means that the content of a file can't be modified, but 47# timestamps, mode and so on can. 48# 49# Archive - Indicates if a file should be included in the next backup 50# of the file system. ZFS will set this bit whenever a file is 51# modified. 52# 53# Hidden and System (ZFS does nothing special with these, other than 54# letting a user/application set them. 55# 56# Immutable (The data can't, change nor can mode, ACL, size and so on) 57# The only attribute that can be updated is the access time. 58# 59# Nonunlink - Sort of like immutable except that a file/dir can't be 60# removed. 61# This will also effect a rename operation, since that involes a 62# remove. 63# 64# Appendonly - File can only be appended to. 65# 66# nodump, settable, opaque (These are for the MacOS port) we will 67# allow them to be set, but have no semantics tied to them. 68# 69# STRATEGY: 70# 1. Loop super user and non-super user to run the test case. 71# 2. Create basedir and a set of subdirectores and files within it. 72# 3. Set the file/dir with each kind of special attribute. 73# 4. Verify the access limitation works as expected. 74# 75# TESTABILITY: explicit 76# 77# TEST_AUTOMATION_LEVEL: automated 78# 79# CODING_STATUS: COMPLETED (2007-11-05) 80# 81# __stc_assertion_end 82# 83################################################################################ 84 85verify_runnable "both" 86 87if ! cifs_supported ; then 88 log_unsupported "CIFS not supported on current system." 89fi 90 91test_requires ZFS_ACL ZFS_XATTR 92 93function cleanup 94{ 95 if [[ -n $gobject ]]; then 96 destroy_object $gobject 97 fi 98 99 for fs in $TESTPOOL/$TESTFS $TESTPOOL ; do 100 mtpt=$(get_prop mountpoint $fs) 101 log_must $RM -rf $mtpt/file.* $mtpt/dir.* 102 done 103} 104 105# 106# Set the special attribute to the given node 107# 108# $1: The given node (file/dir) 109# $2: The special attribute to be set 110# 111function set_attribute 112{ 113 typeset object=$1 114 typeset attr=$2 115 116 if [[ -z $attr ]]; then 117 attr="AHRSadimu" 118 if [[ -f $object ]]; then 119 attr="${attr}q" 120 fi 121 fi 122 123 $CHMOD S+c${attr} $object 124 return $? 125} 126 127# 128# Clear the special attribute to the given node 129# 130# $1: The given node (file/dir) 131# $2: The special attribute to be cleared 132# 133function clear_attribute 134{ 135 typeset object=$1 136 typeset attr=$2 137 138 if [[ -z $attr ]]; then 139 if is_global_zone ; then 140 attr="AHRSadimu" 141 if [[ -f $object ]]; then 142 attr="${attr}q" 143 fi 144 else 145 attr="AHRS" 146 fi 147 fi 148 149 $CHMOD S-c${attr} $object 150 return $? 151} 152 153# 154# A wrapper function to call test function according to the given attr 155# 156# $1: The given node (file/dir) 157# $2: The special attribute to be test 158# 159function test_wrapper 160{ 161 typeset object=$1 162 typeset attr=$2 163 164 if [[ -z $object || -z $attr ]]; then 165 log_fail "Object($object), Attr($attr) not defined." 166 fi 167 168 case $attr in 169 R) func=test_readonly 170 ;; 171 i) func=test_immutable 172 ;; 173 u) func=test_nounlink 174 ;; 175 a) func=test_appendonly 176 ;; 177 esac 178 179 if [[ -n $func ]]; then 180 $func $object 181 fi 182} 183 184# 185# Invoke the function and verify whether its return code as expected 186# 187# $1: Expect value 188# $2-$n: Function and args need to be invoked 189# 190function verify_expect 191{ 192 typeset -i expect=$1 193 typeset status 194 195 shift 196 197 "$@" > /dev/null 2>&1 198 status=$? 199 if [[ $status -eq 0 ]]; then 200 if (( expect != 0 )); then 201 log_fail "$@ unexpect return 0" 202 fi 203 else 204 if (( expect == 0 )); then 205 log_fail "$@ unexpect return $status" 206 fi 207 fi 208} 209 210# 211# Unit testing function against overwrite file 212# 213# $1: The given file node 214# $2: Execute user 215# $3: Expect value, default to be zero 216# 217function unit_writefile 218{ 219 typeset object=$1 220 typeset user=$2 221 typeset expect=${3:-0} 222 223 if [[ -f $object ]]; then 224 verify_expect $expect $CHG_USR_EXEC $user \ 225 $CP $TESTFILE $object 226 verify_expect $expect $CHG_USR_EXEC $user \ 227 $EVAL "$ECHO '$TESTSTR' > $object" 228 fi 229} 230 231# 232# Unit testing function against write new stuffs into a directory 233# 234# $1: The given directory node 235# $2: Execute user 236# $3: Expect value, default to be zero 237# 238function unit_writedir 239{ 240 typeset object=$1 241 typeset user=$2 242 typeset expect=${3:-0} 243 244 if [[ -d $object ]]; then 245 verify_expect $expect $CHG_USR_EXEC $user \ 246 $CP $TESTFILE $object 247 verify_expect $expect $CHG_USR_EXEC $user \ 248 $MKDIR -p $object/$TESTDIR 249 fi 250} 251 252function unit_appenddata 253{ 254 typeset object=$1 255 typeset user=$2 256 typeset expect=${3:-0} 257 258 if [[ ! -d $object ]]; then 259 verify_expect $expect $CHG_USR_EXEC $user \ 260 $EVAL "$ECHO '$TESTSTR' >> $object" 261 fi 262} 263 264# 265# Unit testing function against delete content from a directory 266# 267# $1: The given node, dir 268# $2: Execute user 269# $3: Expect value, default to be zero 270# 271function unit_deletecontent 272{ 273 typeset object=$1 274 typeset user=$2 275 typeset expect=${3:-0} 276 277 if [[ -d $object ]]; then 278 for target in $object/${TESTFILE##*/} $object/$TESTDIR ; do 279 if [[ -e $target ]]; then 280 verify_expect $expect $CHG_USR_EXEC $user \ 281 $EVAL "$MV $target $target.new" 282 verify_expect $expect $CHG_USR_EXEC $user \ 283 $EVAL "$ECHO y | $RM -r $target.new" 284 fi 285 done 286 fi 287} 288 289# 290# Unit testing function against delete a node 291# 292# $1: The given node, file/dir 293# $2: Execute user 294# $3: Expect value, default to be zero 295# 296function unit_deletedata 297{ 298 typeset object=$1 299 typeset user=$2 300 typeset expect=${3:-0} 301 302 verify_expect $expect $CHG_USR_EXEC $user \ 303 $EVAL "$ECHO y | $RM -r $object" 304 305} 306 307# 308# Unit testing function against write xattr to a node 309# 310# $1: The given node, file/dir 311# $2: Execute user 312# $3: Expect value, default to be zero 313# 314function unit_writexattr 315{ 316 typeset object=$1 317 typeset user=$2 318 typeset expect=${3:-0} 319 320 verify_expect $expect $CHG_USR_EXEC $user \ 321 $RUNAT $object "$CP $TESTFILE $TESTATTR" 322 verify_expect $expect $CHG_USR_EXEC $user \ 323 $EVAL "$RUNAT $object \"$ECHO '$TESTSTR' > $TESTATTR\"" 324 verify_expect $expect $CHG_USR_EXEC $user \ 325 $EVAL "$RUNAT $object \"$ECHO '$TESTSTR' >> $TESTATTR\"" 326 if [[ $expect -eq 0 ]]; then 327 verify_expect $expect $CHG_USR_EXEC $user \ 328 $RUNAT $object "$RM -f $TESTATTR" 329 fi 330} 331 332# 333# Unit testing function against modify accesstime of a node 334# 335# $1: The given node, file/dir 336# $2: Execute user 337# $3: Expect value, default to be zero 338# 339function unit_accesstime 340{ 341 typeset object=$1 342 typeset user=$2 343 typeset expect=${3:-0} 344 345 if [[ -d $object ]]; then 346 verify_expect $expect $CHG_USR_EXEC $user $LS $object 347 else 348 verify_expect $expect $CHG_USR_EXEC $user $CAT $object 349 fi 350} 351 352# 353# Unit testing function against modify updatetime of a node 354# 355# $1: The given node, file/dir 356# $2: Execute user 357# $3: Expect value, default to be zero 358# 359function unit_updatetime 360{ 361 typeset object=$1 362 typeset user=$2 363 typeset expect=${3:-0} 364 365 verify_expect $expect $CHG_USR_EXEC $user $TOUCH $object 366 verify_expect $expect $CHG_USR_EXEC $user $TOUCH -a $object 367 verify_expect $expect $CHG_USR_EXEC $user $TOUCH -m $object 368} 369 370# 371# Unit testing function against write acl of a node 372# 373# $1: The given node, file/dir 374# $2: Execute user 375# $3: Expect value, default to be zero 376# 377function unit_writeacl 378{ 379 typeset object=$1 380 typeset user=$2 381 typeset expect=${3:-0} 382 383 verify_expect $expect $CHG_USR_EXEC $user chmod A+$TESTACL $object 384 verify_expect $expect $CHG_USR_EXEC $user chmod A+$TESTACL $object 385 verify_expect $expect $CHG_USR_EXEC $user chmod A0- $object 386 verify_expect $expect $CHG_USR_EXEC $user chmod A0- $object 387 oldmode=$(get_mode $object) 388 verify_expect $expect $CHG_USR_EXEC $user chmod $TESTMODE $object 389} 390 391# 392# Testing function to verify the given node is readonly 393# 394# $1: The given node, file/dir 395# 396function test_readonly 397{ 398 typeset object=$1 399 400 if [[ -z $object ]]; then 401 log_fail "Object($object) not defined." 402 fi 403 404 log_note "Testing readonly of $object" 405 406 for user in $ZFS_ACL_CUR_USER root $ZFS_ACL_STAFF2; do 407 if [[ -d $object ]]; then 408 log_must usr_exec chmod \ 409 A+user:$user:${ace_dir}:allow $object 410 else 411 log_must usr_exec chmod \ 412 A+user:$user:${ace_file}:allow $object 413 fi 414 415 log_must set_attribute $object "R" 416 417 unit_writefile $object $user 1 418 unit_writedir $object $user 419 unit_appenddata $object $user 1 420 421 if [[ -d $object ]]; then 422 unit_writexattr $object $user 423 else 424 unit_writexattr $object $user 1 425 fi 426 427 unit_accesstime $object $user 428 unit_updatetime $object $user 429 unit_writeacl $object $user 430 unit_deletecontent $object $user 431 unit_deletedata $object $user 432 433 if [[ -d $object ]] ;then 434 create_object "dir" $object $ZFS_ACL_CUR_USER 435 else 436 create_object "file" $object $ZFS_ACL_CUR_USER 437 fi 438 done 439} 440 441# 442# Testing function to verify the given node is immutable 443# 444# $1: The given node, file/dir 445# 446function test_immutable 447{ 448 typeset object=$1 449 450 if [[ -z $object ]]; then 451 log_fail "Object($object) not defined." 452 fi 453 454 log_note "Testing immutable of $object" 455 456 for user in $ZFS_ACL_CUR_USER root $ZFS_ACL_STAFF2; do 457 if [[ -d $object ]]; then 458 log_must usr_exec chmod \ 459 A+user:$user:${ace_dir}:allow $object 460 else 461 log_must usr_exec chmod \ 462 A+user:$user:${ace_file}:allow $object 463 fi 464 log_must set_attribute $object "i" 465 466 unit_writefile $object $user 1 467 unit_writedir $object $user 1 468 unit_appenddata $object $user 1 469 unit_writexattr $object $user 1 470 unit_accesstime $object $user 471 unit_updatetime $object $user 1 472 unit_writeacl $object $user 1 473 unit_deletecontent $object $user 1 474 unit_deletedata $object $user 1 475 476 if [[ -d $object ]] ;then 477 create_object "dir" $object $ZFS_ACL_CUR_USER 478 else 479 create_object "file" $object $ZFS_ACL_CUR_USER 480 fi 481 done 482} 483 484# 485# Testing function to verify the given node is nounlink 486# 487# $1: The given node, file/dir 488# 489function test_nounlink 490{ 491 typeset object=$1 492 493 if [[ -z $object ]]; then 494 log_fail "Object($object) not defined." 495 fi 496 497 $ECHO "Testing nounlink of $object" 498 499 for user in $ZFS_ACL_CUR_USER root $ZFS_ACL_STAFF2; do 500 if [[ -d $object ]]; then 501 log_must usr_exec chmod \ 502 A+user:$user:${ace_dir}:allow $object 503 else 504 log_must usr_exec chmod \ 505 A+user:$user:${ace_file}:allow $object 506 fi 507 log_must set_attribute $object "u" 508 509 unit_writefile $object $user 510 unit_writedir $object $user 511 unit_appenddata $object $user 512 unit_writexattr $object $user 513 unit_accesstime $object $user 514 unit_updatetime $object $user 515 unit_writeacl $object $user 516 unit_deletecontent $object $user 1 517 unit_deletedata $object $user 1 518 519 if [[ -d $object ]] ;then 520 create_object "dir" $object $ZFS_ACL_CUR_USER 521 else 522 create_object "file" $object $ZFS_ACL_CUR_USER 523 fi 524 done 525} 526 527# 528# Testing function to verify the given node is appendonly 529# 530# $1: The given node, file/dir 531# 532function test_appendonly 533{ 534 typeset object=$1 535 536 if [[ -z $object ]]; then 537 log_fail "Object($object) not defined." 538 fi 539 540 log_note "Testing appendonly of $object" 541 542 for user in $ZFS_ACL_CUR_USER root $ZFS_ACL_STAFF2; do 543 if [[ -d $object ]]; then 544 log_must usr_exec chmod \ 545 A+user:$user:${ace_dir}:allow $object 546 else 547 log_must usr_exec chmod \ 548 A+user:$user:${ace_file}:allow $object 549 fi 550 log_must set_attribute $object "a" 551 552 unit_writefile $object $user 1 553 unit_writedir $object $user 554 unit_appenddata $object $user 555 unit_writexattr $object $user 556 unit_accesstime $object $user 557 unit_updatetime $object $user 558 unit_writeacl $object $user 559 unit_deletecontent $object $user 560 unit_deletedata $object $user 561 562 if [[ -d $object ]] ;then 563 create_object "dir" $object $ZFS_ACL_CUR_USER 564 else 565 create_object "file" $object $ZFS_ACL_CUR_USER 566 fi 567 done 568} 569 570FILES="file.0 file.1" 571DIRS="dir.0 dir.1" 572XATTRS="attr.0 attr.1" 573FS="$TESTPOOL $TESTPOOL/$TESTFS" 574 575if is_global_zone ; then 576 ATTRS="R i u a" 577else 578 ATTRS="R" 579fi 580 581TESTFILE=$TMPDIR/tfile 582TESTDIR=tdir 583TESTATTR=tattr 584TESTACL=user:$ZFS_ACL_OTHER1:write_data:allow 585TESTMODE=777 586TESTSTR="ZFS test suites" 587 588ace_file="write_data/append_data/write_xattr/write_acl/write_attributes" 589ace_dir="add_file/add_subdirectory/${ace_file}" 590 591log_assert "Verify DOS & BSD'ish attributes will provide the " \ 592 "access limitation as expected." 593log_onexit cleanup 594 595$ECHO "$TESTSTR" > $TESTFILE 596 597typeset gobject 598typeset gattr 599for gattr in $ATTRS ; do 600 for fs in $FS ; do 601 mtpt=$(get_prop mountpoint $fs) 602 $CHMOD 777 $mtpt 603 for user in root $ZFS_ACL_STAFF1; do 604 log_must set_cur_usr $user 605 for file in $FILES ; do 606 gobject=$mtpt/$file 607 create_object "file" $gobject $ZFS_ACL_CUR_USER 608 test_wrapper $gobject $gattr 609 destroy_object $gobject 610 done 611 612 for dir in $DIRS ; do 613 gobject=$mtpt/$dir 614 create_object "dir" $gobject $ZFS_ACL_CUR_USER 615 test_wrapper $gobject $gattr 616 destroy_object $gobject 617 done 618 done 619 done 620done 621 622log_pass "DOS & BSD'ish attributes provide the access limitation as expected." 623