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