1# 2# CDDL HEADER START 3# 4# The contents of this file are subject to the terms of the 5# Common Development and Distribution License (the "License"). 6# You may not use this file except in compliance with the License. 7# 8# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9# or https://opensource.org/licenses/CDDL-1.0. 10# See the License for the specific language governing permissions 11# and limitations under the License. 12# 13# When distributing Covered Code, include this CDDL HEADER in each 14# file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15# If applicable, add the following below this CDDL HEADER, with the 16# fields enclosed by brackets "[]" replaced with your own identifying 17# information: Portions Copyright [yyyy] [name of copyright owner] 18# 19# CDDL HEADER END 20# 21 22# 23# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24# Use is subject to license terms. 25# 26 27# 28# Copyright (c) 2013, 2016 by Delphix. All rights reserved. 29# Copyright 2016 Nexenta Systems, Inc. 30# Copyright (c) 2018 George Melikov. All Rights Reserved. 31# 32 33. $STF_SUITE/include/libtest.shlib 34. $STF_SUITE/tests/functional/delegate/delegate.cfg 35 36# 37# Cleanup exist user/group. 38# 39function cleanup_user_group 40{ 41 typeset i 42 for i in $STAFF1 $STAFF2 $OTHER1 $OTHER2 ; do 43 del_user $i 44 done 45 for i in $STAFF_GROUP $OTHER_GROUP ; do 46 del_group $i 47 done 48 49 return 0 50} 51 52# 53# Restore test file system to the original status. 54# 55function restore_root_datasets 56{ 57 destroy_dataset "$ROOT_TESTFS" "-Rf" 58 log_must zfs create $ROOT_TESTFS 59 60 if is_global_zone ; then 61 destroy_dataset "$ROOT_TESTVOL" "-Rf" 62 log_must zfs create -V $VOLSIZE $ROOT_TESTVOL 63 block_device_wait 64 fi 65 66 return 0 67} 68 69# 70# Verify the specified user have permission on the dataset 71# 72# $1 dataset 73# $2 permissions which are separated by comma(,) 74# $3-n users 75# 76function verify_perm 77{ 78 typeset dtst=$1 79 typeset permissions=$2 80 shift 2 81 82 if [[ -z $@ || -z $permissions || -z $dtst ]]; then 83 return 1 84 fi 85 86 typeset type=$(get_prop type $dtst) 87 permissions=$(echo $permissions | tr -s "," " ") 88 89 typeset user 90 for user in $@; do 91 typeset perm 92 for perm in $permissions; do 93 typeset -i ret=1 94 if [[ $type == "filesystem" ]]; then 95 check_fs_perm $user $perm $dtst 96 ret=$? 97 elif [[ $type == "volume" ]]; then 98 check_vol_perm $user $perm $dtst 99 ret=$? 100 fi 101 102 log_note "Check $type $user $perm $dtst" 103 if ((ret != 0)) ; then 104 log_note "Fail: $user should have $perm" \ 105 "on $dtst" 106 return 1 107 fi 108 done 109 done 110 111 return 0 112} 113 114# 115# Verify the specified user have no permission on the dataset 116# 117# $1 dataset 118# $2 permissions which are separated by comma(,) 119# $3-n users 120# 121function verify_noperm 122{ 123 typeset dtst=$1 124 typeset permissions=$2 125 shift 2 126 127 if [[ -z $@ || -z $permissions || -z $dtst ]]; then 128 return 1 129 fi 130 131 typeset type=$(get_prop type $dtst) 132 permissions=$(echo $permissions | tr -s "," " ") 133 134 typeset user 135 for user in $@; do 136 typeset perm 137 for perm in $permissions; do 138 typeset -i ret=1 139 if [[ $type == "filesystem" ]]; then 140 check_fs_perm $user $perm $dtst 141 ret=$? 142 elif [[ $type == "volume" ]]; then 143 check_vol_perm $user $perm $dtst 144 ret=$? 145 fi 146 147 if ((ret == 0)) ; then 148 log_note "Fail: $user should not have $perm " \ 149 "on $dtst" 150 return 1 151 fi 152 done 153 done 154 155 return 0 156} 157 158function common_perm 159{ 160 typeset user=$1 161 typeset perm=$2 162 typeset dtst=$3 163 164 case $perm in 165 send) 166 verify_send $user $perm $dtst 167 ;; 168 allow) 169 verify_allow $user $perm $dtst 170 ;; 171 userprop) 172 verify_userprop $user $perm $dtst 173 ;; 174 compression|checksum|readonly) 175 verify_ccr $user $perm $dtst 176 ;; 177 copies) 178 verify_copies $user $perm $dtst 179 ;; 180 reservation) 181 verify_reservation $user $perm $dtst 182 ;; 183 *) 184 return 1 185 ;; 186 esac 187} 188 189function check_fs_perm 190{ 191 typeset user=$1 192 typeset perm=$2 193 typeset fs=$3 194 195 case $perm in 196 create) 197 verify_fs_create $user $perm $fs 198 ;; 199 destroy) 200 verify_fs_destroy $user $perm $fs 201 ;; 202 snapshot) 203 verify_fs_snapshot $user $perm $fs 204 ;; 205 rollback) 206 verify_fs_rollback $user $perm $fs 207 ;; 208 clone) 209 verify_fs_clone $user $perm $fs 210 ;; 211 rename) 212 verify_fs_rename $user $perm $fs 213 ;; 214 mount) 215 verify_fs_mount $user $perm $fs 216 ;; 217 share) 218 verify_fs_share $user $perm $fs 219 ;; 220 mountpoint) 221 verify_fs_mountpoint $user $perm $fs 222 ;; 223 promote) 224 verify_fs_promote $user $perm $fs 225 ;; 226 canmount) 227 verify_fs_canmount $user $perm $fs 228 ;; 229 dnodesize) 230 verify_fs_dnodesize $user $perm $fs 231 ;; 232 recordsize) 233 verify_fs_recordsize $user $perm $fs 234 ;; 235 quota) 236 verify_fs_quota $user $perm $fs 237 ;; 238 aclmode) 239 verify_fs_aclmode $user $perm $fs 240 ;; 241 aclinherit) 242 verify_fs_aclinherit $user $perm $fs 243 ;; 244 snapdir) 245 verify_fs_snapdir $user $perm $fs 246 ;; 247 atime|exec|devices|setuid|xattr) 248 verify_fs_aedsx $user $perm $fs 249 ;; 250 zoned) 251 verify_fs_zoned $user $perm $fs 252 ;; 253 sharenfs) 254 verify_fs_sharenfs $user $perm $fs 255 ;; 256 receive) 257 verify_fs_receive $user $perm $fs 258 ;; 259 *) 260 common_perm $user $perm $fs 261 ;; 262 esac 263} 264 265function check_vol_perm 266{ 267 typeset user=$1 268 typeset perm=$2 269 typeset vol=$3 270 271 case $perm in 272 destroy) 273 verify_vol_destroy $user $perm $vol 274 ;; 275 snapshot) 276 verify_vol_snapshot $user $perm $vol 277 ;; 278 rollback) 279 verify_vol_rollback $user $perm $vol 280 ;; 281 clone) 282 verify_vol_clone $user $perm $vol 283 ;; 284 rename) 285 verify_vol_rename $user $perm $vol 286 ;; 287 promote) 288 verify_vol_promote $user $perm $vol 289 ;; 290 volsize) 291 verify_vol_volsize $user $perm $vol 292 ;; 293 *) 294 common_perm $user $perm $vol 295 ;; 296 esac 297} 298 299function setup_unallow_testenv 300{ 301 log_must restore_root_datasets 302 303 log_must zfs create $SUBFS 304 305 for dtst in $DATASETS ; do 306 log_must zfs allow -l $STAFF1 $LOCAL_SET $dtst 307 log_must zfs allow -d $STAFF2 $DESC_SET $dtst 308 log_must zfs allow $OTHER1 $LOCAL_DESC_SET $dtst 309 log_must zfs allow $OTHER2 $LOCAL_DESC_SET $dtst 310 311 log_must verify_perm $dtst $LOCAL_SET $STAFF1 312 log_must verify_perm $dtst $LOCAL_DESC_SET $OTHER1 313 log_must verify_perm $dtst $LOCAL_DESC_SET $OTHER2 314 if [[ $dtst == $ROOT_TESTFS ]]; then 315 log_must verify_perm $SUBFS $DESC_SET $STAFF2 316 log_must verify_perm $SUBFS $LOCAL_DESC_SET $OTHER1 317 log_must verify_perm $SUBFS $LOCAL_DESC_SET $OTHER2 318 fi 319 done 320} 321 322# 323# Verify permission send for specified user on the dataset 324# $1 user 325# $2 permission 326# $3 dataset 327# 328function verify_send 329{ 330 typeset user=$1 331 typeset perm=$2 332 typeset dtst=$3 333 334 typeset oldval 335 typeset stamp=${perm}.${user}.$RANDOM 336 typeset snap=$dtst@snap.$stamp 337 338 typeset -i ret=1 339 340 log_must zfs snapshot $snap 341 typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp 342 typeset bak_root=$TEST_BASE_DIR/bak.root.$stamp 343 344 user_run $user eval "zfs send $snap > $bak_user" 345 log_must eval "zfs send $snap > $bak_root" 346 347 if [ "$(cksum < $bak_user)" = "$(cksum < $bak_root)" ]; then 348 ret=0 349 fi 350 351 rm -rf $bak_user $bak_root 352 353 return $ret 354} 355 356function verify_fs_receive 357{ 358 typeset user=$1 359 typeset perm=$2 360 typeset fs=$3 361 362 typeset dtst 363 typeset stamp=${perm}.${user}.$RANDOM 364 typeset newfs=$fs/newfs.$stamp 365 typeset newvol=$fs/newvol.$stamp 366 typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp 367 typeset bak_root=$TEST_BASE_DIR/bak.root.$stamp 368 369 log_must zfs create $newfs 370 typeset datasets="$newfs" 371 if is_global_zone ; then 372 log_must zfs create -V $VOLSIZE $newvol 373 block_device_wait 374 datasets="$newfs $newvol" 375 fi 376 377 for dtst in $datasets ; do 378 379 typeset dtstsnap=$dtst@snap.$stamp 380 log_must zfs snapshot $dtstsnap 381 382 log_must eval "zfs send $dtstsnap > $bak_root" 383 log_must_busy zfs destroy -rf $dtst 384 385 user_run $user eval "zfs receive $dtst < $bak_root" 386 if datasetexists $dtstsnap ; then 387 return 1 388 fi 389 390 log_must zfs allow $user create $fs 391 user_run $user eval "zfs receive $dtst < $bak_root" 392 log_must zfs unallow $user create $fs 393 if datasetexists $dtstsnap ; then 394 return 1 395 fi 396 397 log_must zfs allow $user mount $fs 398 user_run $user eval "zfs receive $dtst < $bak_root" 399 log_must zfs unallow $user mount $fs 400 if datasetexists $dtstsnap ; then 401 return 1 402 fi 403 404 log_must zfs allow $user mount,create $fs 405 user_run $user eval "zfs receive $dtst < $bak_root" 406 log_must zfs unallow $user mount,create $fs 407 if ! datasetexists $dtstsnap ; then 408 return 1 409 fi 410 411 # check the data integrity 412 log_must eval "zfs send $dtstsnap > $bak_user" 413 log_must_busy zfs destroy -rf $dtst 414 log_must eval "zfs receive $dtst < $bak_root" 415 log_must eval "zfs send $dtstsnap > $bak_root" 416 log_must_busy zfs destroy -rf $dtst 417 if [ "$(cksum < $bak_user)" != "$(cksum < $bak_root)" ]; then 418 return 1 419 fi 420 421 rm -rf $bak_user $bak_root 422 423 done 424 425 return 0 426} 427 428function verify_userprop 429{ 430 typeset user=$1 431 typeset perm=$2 432 typeset dtst=$3 433 434 typeset stamp=${perm}.${user}.$RANDOM 435 436 user_run $user zfs set "$user:ts=$stamp" $dtst 437 sync_pool ${dtst%%/*} 438 if [[ $stamp != $(get_prop "$user:ts" $dtst) ]]; then 439 return 1 440 fi 441 442 return 0 443} 444 445function verify_ccr 446{ 447 typeset user=$1 448 typeset perm=$2 449 typeset dtst=$3 450 451 typeset oldval 452 453 set -A modes "on" "off" 454 oldval=$(get_prop $perm $dtst) 455 if [[ $oldval == "on" ]]; then 456 n=1 457 elif [[ $oldval == "off" ]]; then 458 n=0 459 fi 460 log_note "$user zfs set $perm=${modes[$n]} $dtst" 461 user_run $user zfs set $perm=${modes[$n]} $dtst 462 if [[ ${modes[$n]} != $(get_prop $perm $dtst) ]]; then 463 return 1 464 fi 465 466 return 0 467} 468 469function verify_copies 470{ 471 typeset user=$1 472 typeset perm=$2 473 typeset dtst=$3 474 475 typeset oldval 476 477 set -A modes 1 2 3 478 oldval=$(get_prop $perm $dtst) 479 if [[ $oldval -eq 1 ]]; then 480 n=1 481 elif [[ $oldval -eq 2 ]]; then 482 n=2 483 elif [[ $oldval -eq 3 ]]; then 484 n=0 485 fi 486 log_note "$user zfs set $perm=${modes[$n]} $dtst" 487 user_run $user zfs set $perm=${modes[$n]} $dtst 488 if [[ ${modes[$n]} != $(get_prop $perm $dtst) ]]; then 489 return 1 490 fi 491 492 return 0 493} 494 495function verify_reservation 496{ 497 typeset user=$1 498 typeset perm=$2 499 typeset dtst=$3 500 501 typeset value32m=$(( 1024 * 1024 * 32 )) 502 typeset oldval=$(get_prop reservation $dtst) 503 user_run $user zfs set reservation=$value32m $dtst 504 if [[ $value32m != $(get_prop reservation $dtst) ]]; then 505 log_must zfs set reservation=$oldval $dtst 506 return 1 507 fi 508 509 log_must zfs set reservation=$oldval $dtst 510 return 0 511} 512 513function verify_fs_create 514{ 515 typeset user=$1 516 typeset perm=$2 517 typeset fs=$3 518 519 typeset stamp=${perm}.${user}.$RANDOM 520 typeset newfs=$fs/nfs.$stamp 521 typeset newvol=$fs/nvol.$stamp 522 523 user_run $user zfs create $newfs 524 if datasetexists $newfs ; then 525 return 1 526 fi 527 528 log_must zfs allow $user mount $fs 529 user_run $user zfs create $newfs 530 log_must zfs unallow $user mount $fs 531 if ! datasetexists $newfs ; then 532 return 1 533 fi 534 535 log_must zfs destroy $newfs 536 537 if is_global_zone ; then 538 # mount permission is required for sparse volume 539 user_run $user zfs create -V 150m -s $newvol 540 block_device_wait 541 if datasetexists $newvol ; then 542 return 1 543 fi 544 545 log_must zfs allow $user mount $fs 546 user_run $user zfs create -V 150m -s $newvol 547 log_must zfs unallow $user mount $fs 548 if ! datasetexists $newvol ; then 549 return 1 550 fi 551 552 block_device_wait 553 log_must zfs destroy $newvol 554 block_device_wait 555 556 # mount and reserveration permission are 557 # required for normal volume 558 user_run $user zfs create -V 150m $newvol 559 block_device_wait 560 if datasetexists $newvol ; then 561 return 1 562 fi 563 564 log_must zfs allow $user mount $fs 565 user_run $user zfs create -V 150m $newvol 566 block_device_wait 567 log_must zfs unallow $user mount $fs 568 if datasetexists $newvol ; then 569 return 1 570 fi 571 572 log_must zfs allow $user reservation $fs 573 user_run $user zfs create -V 150m $newvol 574 block_device_wait 575 log_must zfs unallow $user reservation $fs 576 if datasetexists $newvol ; then 577 return 1 578 fi 579 580 log_must zfs allow $user refreservation $fs 581 user_run $user zfs create -V 150m $newvol 582 block_device_wait 583 log_must zfs unallow $user refreservation $fs 584 if datasetexists $newvol ; then 585 return 1 586 fi 587 588 log_must zfs allow $user mount $fs 589 log_must zfs allow $user reservation $fs 590 log_must zfs allow $user refreservation $fs 591 user_run $user zfs create -V 150m $newvol 592 log_must zfs unallow $user mount $fs 593 log_must zfs unallow $user reservation $fs 594 log_must zfs unallow $user refreservation $fs 595 if ! datasetexists $newvol ; then 596 return 1 597 fi 598 599 block_device_wait 600 log_must zfs destroy $newvol 601 block_device_wait 602 fi 603 604 return 0 605} 606 607function verify_fs_destroy 608{ 609 typeset user=$1 610 typeset perm=$2 611 typeset fs=$3 612 613 if ! ismounted $fs ; then 614 user_run $user zfs destroy $fs 615 if datasetexists $fs ; then 616 return 1 617 fi 618 fi 619 620 if ismounted $fs ; then 621 user_run $user zfs destroy $fs 622 if ! datasetexists $fs ; then 623 return 1 624 fi 625 626 # mount permission is required 627 log_must zfs allow $user mount $fs 628 user_run $user zfs destroy $fs 629 if datasetexists $fs ; then 630 return 1 631 fi 632 fi 633 634 return 0 635} 636 637# Verify that given the correct delegation, a regular user can: 638# Take a snapshot of an unmounted dataset 639# Take a snapshot of a mounted dataset 640# Create a snapshot by making a directory in the .zfs/snapshot directory 641function verify_fs_snapshot 642{ 643 typeset user=$1 644 typeset perm=$2 645 typeset fs=$3 646 647 typeset stamp=${perm}.${user}.$RANDOM 648 typeset snap=$fs@snap.$stamp 649 typeset mntpt=$(get_prop mountpoint $fs) 650 651 if [[ "yes" == $(get_prop mounted $fs) ]]; then 652 log_must zfs umount $fs 653 fi 654 655 user_run $user zfs snapshot $snap 656 if ! datasetexists $snap ; then 657 return 1 658 fi 659 log_must zfs destroy $snap 660 661 if [[ "no" == $(get_prop mounted $fs) ]]; then 662 log_must zfs mount $fs 663 fi 664 665 user_run $user zfs snapshot $snap 666 if ! datasetexists $snap ; then 667 return 1 668 fi 669 log_must zfs destroy $snap 670 671 # Creating snaps via mkdir is not supported on FreeBSD 672 if ! is_freebsd; then 673 typeset snapdir=${mntpt}/.zfs/snapshot/snap.$stamp 674 user_run $user mkdir $snapdir 675 if ! datasetexists $snap ; then 676 return 1 677 fi 678 log_must zfs destroy $snap 679 fi 680 681 return 0 682} 683 684function verify_fs_rollback 685{ 686 typeset user=$1 687 typeset perm=$2 688 typeset fs=$3 689 690 typeset oldval 691 typeset stamp=${perm}.${user}.$RANDOM 692 typeset snap=$fs@snap.$stamp 693 typeset mntpt=$(get_prop mountpoint $fs) 694 695 oldval=$(datasetcksum $fs) 696 log_must zfs snapshot $snap 697 698 if ! ismounted $fs; then 699 log_must zfs mount $fs 700 fi 701 log_must touch $mntpt/testfile.$stamp 702 703 user_run $user zfs rollback -R $snap 704 if is_global_zone ; then 705 if [[ $oldval != $(datasetcksum $fs) ]]; then 706 return 1 707 fi 708 else 709 # datasetcksum can not be used in local zone 710 if [[ -e $mntpt/testfile.$stamp ]]; then 711 return 1 712 fi 713 fi 714 715 return 0 716} 717 718function verify_fs_clone 719{ 720 typeset user=$1 721 typeset perm=$2 722 typeset fs=$3 723 724 typeset stamp=${perm}.${user}.$RANDOM 725 typeset basefs=${fs%/*} 726 typeset snap=$fs@snap.$stamp 727 typeset clone=$basefs/cfs.$stamp 728 729 log_must zfs snapshot $snap 730 user_run $user zfs clone $snap $clone 731 if datasetexists $clone ; then 732 return 1 733 fi 734 735 log_must zfs allow $user create $basefs 736 user_run $user zfs clone $snap $clone 737 log_must zfs unallow $user create $basefs 738 if datasetexists $clone ; then 739 return 1 740 fi 741 742 log_must zfs allow $user mount $basefs 743 user_run $user zfs clone $snap $clone 744 log_must zfs unallow $user mount $basefs 745 if datasetexists $clone ; then 746 return 1 747 fi 748 749 log_must zfs allow $user mount $basefs 750 log_must zfs allow $user create $basefs 751 user_run $user zfs clone $snap $clone 752 log_must zfs unallow $user create $basefs 753 log_must zfs unallow $user mount $basefs 754 if ! datasetexists $clone ; then 755 return 1 756 fi 757 758 log_must zfs destroy -R $snap 759 760 return 0 761} 762 763function verify_fs_rename 764{ 765 typeset user=$1 766 typeset perm=$2 767 typeset fs=$3 768 769 typeset stamp=${perm}.${user}.$RANDOM 770 typeset basefs=${fs%/*} 771 typeset snap=$fs@snap.$stamp 772 typeset renamefs=$basefs/nfs.$stamp 773 774 if ! ismounted $fs; then 775 log_must zfs mount $fs 776 fi 777 778 # case 1 779 user_run $user zfs rename $fs $renamefs 780 if datasetexists $renamefs ; then 781 return 1 782 fi 783 784 # case 2 785 log_must zfs allow $user create $basefs 786 user_run $user zfs rename $fs $renamefs 787 log_must zfs unallow $user create $basefs 788 if datasetexists $renamefs ; then 789 return 1 790 fi 791 792 # case 3 793 log_must zfs allow $user mount $basefs 794 user_run $user zfs rename $fs $renamefs 795 log_must zfs unallow $user mount $basefs 796 if datasetexists $renamefs ; then 797 return 1 798 fi 799 800 # case 4 801 log_must zfs allow $user mount $fs 802 user_run $user zfs rename $fs $renamefs 803 if datasetexists $renamefs ; then 804 log_must zfs unallow $user mount $renamefs 805 return 1 806 fi 807 log_must zfs unallow $user mount $fs 808 809 # case 5 810 log_must zfs allow $user create $basefs 811 log_must zfs allow $user mount $fs 812 user_run $user zfs rename $fs $renamefs 813 log_must zfs unallow $user create $basefs 814 if datasetexists $renamefs ; then 815 log_must zfs unallow $user mount $renamefs 816 return 1 817 fi 818 log_must zfs unallow $user mount $fs 819 820 # case 6 821 log_must zfs allow $user mount $basefs 822 log_must zfs allow $user mount $fs 823 user_run $user zfs rename $fs $renamefs 824 log_must zfs unallow $user mount $basefs 825 if datasetexists $renamefs ; then 826 log_must zfs unallow $user mount $renamefs 827 return 1 828 fi 829 log_must zfs unallow $user mount $fs 830 831 # case 7 832 log_must zfs allow $user create $basefs 833 log_must zfs allow $user mount $basefs 834 user_run $user zfs rename $fs $renamefs 835 log_must zfs unallow $user mount $basefs 836 log_must zfs unallow $user create $basefs 837 if ! datasetexists $renamefs ; then 838 return 1 839 fi 840 841 log_must zfs rename $renamefs $fs 842 843 return 0 844} 845 846function verify_fs_mount 847{ 848 typeset user=$1 849 typeset perm=$2 850 typeset fs=$3 851 852 typeset stamp=${perm}.${user}.$RANDOM 853 typeset mntpt=$(get_prop mountpoint $fs) 854 typeset newmntpt=$TEST_BASE_DIR/mnt.$stamp 855 856 if ismounted $fs ; then 857 user_run $user zfs unmount $fs 858 if ismounted $fs ; then 859 return 1 860 fi 861 fi 862 863 if ! ismounted $fs ; then 864 log_must zfs set -u mountpoint=$newmntpt $fs 865 log_must rm -rf $newmntpt 866 log_must mkdir $newmntpt 867 868 user_run $user zfs mount $fs 869 if ismounted $fs ; then 870 return 1 871 fi 872 873 # mountpoint's owner must be the user 874 log_must chown $user $newmntpt 875 user_run $user zfs mount $fs 876 if ! ismounted $fs ; then 877 return 1 878 fi 879 log_must zfs umount $fs 880 log_must rm -rf $newmntpt 881 log_must zfs set -u mountpoint=$mntpt $fs 882 fi 883 884 return 0 885} 886 887function verify_fs_share 888{ 889 typeset user=$1 890 typeset perm=$2 891 typeset fs=$3 892 typeset -i ret=0 893 894 svcadm enable -rs nfs/server 895 typeset stat=$(svcs -H -o STA nfs/server:default) 896 if [[ $stat != "ON" ]]; then 897 log_fail "Could not enable nfs/server" 898 fi 899 900 log_must zfs set sharenfs=on $fs 901 zfs unshare $fs 902 903 user_run $user zfs share $fs 904 if ! is_shared $fs; then 905 ret=1 906 fi 907 908 zfs unshare $fs 909 log_must zfs set sharenfs=off $fs 910 911 return $ret 912} 913 914function verify_fs_mountpoint 915{ 916 typeset user=$1 917 typeset perm=$2 918 typeset fs=$3 919 920 typeset stamp=${perm}.${user}.$RANDOM 921 typeset mntpt=$(get_prop mountpoint $fs) 922 typeset newmntpt=$TEST_BASE_DIR/mnt.$stamp 923 924 if ! ismounted $fs ; then 925 user_run $user zfs set mountpoint=$newmntpt $fs 926 if [[ $newmntpt != \ 927 $(get_prop mountpoint $fs) ]] ; then 928 return 1 929 fi 930 log_must zfs set mountpoint=$mntpt $fs 931 fi 932 933 if ismounted $fs ; then 934 user_run $user zfs set mountpoint=$newmntpt $fs 935 if [[ $mntpt != $(get_prop mountpoint $fs) ]]; then 936 return 1 937 fi 938 939 # require mount permission when fs is mounted 940 log_must zfs allow $user mount $fs 941 user_run $user zfs set mountpoint=$newmntpt $fs 942 log_must zfs unallow $user mount $fs 943 if [[ $newmntpt != \ 944 $(get_prop mountpoint $fs) ]] ; then 945 return 1 946 fi 947 log_must zfs set mountpoint=$mntpt $fs 948 fi 949 950 return 0 951} 952 953function verify_fs_promote 954{ 955 typeset user=$1 956 typeset perm=$2 957 typeset fs=$3 958 959 typeset stamp=${perm}.${user}.$RANDOM 960 typeset basefs=${fs%/*} 961 typeset snap=$fs@snap.$stamp 962 typeset clone=$basefs/cfs.$stamp 963 964 log_must zfs snapshot $snap 965 log_must zfs clone $snap $clone 966 log_must zfs promote $clone 967 968 typeset fs_orig=$(get_prop origin $fs) 969 typeset clone_orig=$(get_prop origin $clone) 970 971 user_run $user zfs promote $fs 972 # promote should fail if original fs does not have 973 # promote permission 974 if [[ $fs_orig != $(get_prop origin $fs) || \ 975 $clone_orig != $(get_prop origin $clone) ]]; then 976 return 1 977 fi 978 979 log_must zfs allow $user promote $clone 980 user_run $user zfs promote $fs 981 log_must zfs unallow $user promote $clone 982 if [[ $fs_orig != $(get_prop origin $fs) || \ 983 $clone_orig != $(get_prop origin $clone) ]]; then 984 return 1 985 fi 986 987 log_must zfs allow $user mount $fs 988 user_run $user zfs promote $fs 989 log_must zfs unallow $user mount $fs 990 if [[ $fs_orig != $(get_prop origin $fs) || \ 991 $clone_orig != $(get_prop origin $clone) ]]; then 992 return 1 993 fi 994 995 log_must zfs allow $user mount $fs 996 log_must zfs allow $user promote $clone 997 user_run $user zfs promote $fs 998 log_must zfs unallow $user promote $clone 999 log_must zfs unallow $user mount $fs 1000 if [[ $snap != $(get_prop origin $clone) || \ 1001 $clone_orig != $(get_prop origin $fs) ]]; then 1002 return 1 1003 fi 1004 1005 return 0 1006} 1007 1008function verify_fs_canmount 1009{ 1010 typeset user=$1 1011 typeset perm=$2 1012 typeset fs=$3 1013 1014 typeset oldval 1015 typeset stamp=${perm}.${user}.$RANDOM 1016 1017 if ! ismounted $fs ; then 1018 set -A modes "on" "off" 1019 oldval=$(get_prop $perm $fs) 1020 if [[ $oldval == "on" ]]; then 1021 n=1 1022 elif [[ $oldval == "off" ]]; then 1023 n=0 1024 fi 1025 log_note "$user zfs set $perm=${modes[$n]} $fs" 1026 user_run $user zfs set $perm=${modes[$n]} $fs 1027 if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then 1028 return 1 1029 fi 1030 fi 1031 1032 1033 # fs is mounted 1034 if ismounted $fs ; then 1035 # property value does not change if 1036 # no mount permission 1037 set -A modes "on" "off" 1038 oldval=$(get_prop $perm $fs) 1039 if [[ $oldval == "on" ]]; then 1040 n=1 1041 elif [[ $oldval == "off" ]]; then 1042 n=0 1043 fi 1044 log_note "$user zfs set $perm=${modes[$n]} $fs" 1045 log_must zfs allow $user mount $fs 1046 user_run $user zfs set $perm=${modes[$n]} $fs 1047 log_must zfs unallow $user mount $fs 1048 if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then 1049 return 1 1050 fi 1051 fi 1052 1053 return 0 1054} 1055 1056function verify_fs_recordsize 1057{ 1058 typeset user=$1 1059 typeset perm=$2 1060 typeset fs=$3 1061 1062 typeset value8k=$(( 1024 * 8 )) 1063 user_run $user zfs set recordsize=$value8k $fs 1064 if [[ $value8k != $(get_prop recordsize $fs) ]]; then 1065 return 1 1066 fi 1067 1068 return 0 1069} 1070 1071function verify_fs_dnodesize 1072{ 1073 typeset user=$1 1074 typeset perm=$2 1075 typeset fs=$3 1076 value="2k" 1077 1078 user_run $user zfs set dnodesize=$value $fs 1079 if [[ $value != $(get_prop dnodesize $fs) ]]; then 1080 return 1 1081 fi 1082 1083 return 0 1084} 1085 1086function verify_fs_quota 1087{ 1088 typeset user=$1 1089 typeset perm=$2 1090 typeset fs=$3 1091 1092 typeset value32m=$(( 1024 * 1024 * 32 )) 1093 user_run $user zfs set quota=$value32m $fs 1094 if [[ $value32m != $(get_prop quota $fs) ]]; then 1095 return 1 1096 fi 1097 1098 return 0 1099} 1100 1101function verify_fs_aclmode 1102{ 1103 typeset user=$1 1104 typeset perm=$2 1105 typeset fs=$3 1106 1107 typeset oldval 1108 set -A modes "discard" "groupmask" "passthrough" 1109 oldval=$(get_prop $perm $fs) 1110 if [[ $oldval == "discard" ]]; then 1111 n=1 1112 elif [[ $oldval == "groupmask" ]]; then 1113 n=2 1114 elif [[ $oldval == "passthrough" ]]; then 1115 n=0 1116 fi 1117 log_note "$user zfs set aclmode=${modes[$n]} $fs" 1118 user_run $user zfs set aclmode=${modes[$n]} $fs 1119 if [[ ${modes[$n]} != $(get_prop aclmode $fs) ]]; then 1120 return 1 1121 fi 1122 1123 return 0 1124} 1125 1126function verify_fs_aclinherit 1127{ 1128 typeset user=$1 1129 typeset perm=$2 1130 typeset fs=$3 1131 1132 # 1133 # PSARC/2008/231 change the default value of aclinherit to "restricted" 1134 # but still keep the old interface of "secure" 1135 # 1136 1137 typeset oldval 1138 set -A modes "discard" "noallow" "secure" "passthrough" 1139 oldval=$(get_prop $perm $fs) 1140 if [[ $oldval == "discard" ]]; then 1141 n=1 1142 elif [[ $oldval == "noallow" ]]; then 1143 n=2 1144 elif [[ $oldval == "secure" || $oldval == "restricted" ]]; then 1145 n=3 1146 elif [[ $oldval == "passthrough" ]]; then 1147 n=0 1148 fi 1149 log_note "$user zfs set aclinherit=${modes[$n]} $fs" 1150 user_run $user zfs set aclinherit=${modes[$n]} $fs 1151 1152 typeset newval=$(get_prop aclinherit $fs) 1153 if [[ ${modes[$n]} == "secure" && $newval == "restricted" ]]; then 1154 return 0 1155 elif [[ ${modes[$n]} != $(get_prop aclinherit $fs) ]]; then 1156 return 1 1157 fi 1158 1159 return 0 1160} 1161 1162function verify_fs_snapdir 1163{ 1164 typeset user=$1 1165 typeset perm=$2 1166 typeset fs=$3 1167 1168 typeset oldval 1169 set -A modes "visible" "hidden" 1170 oldval=$(get_prop $perm $fs) 1171 if [[ $oldval == "visible" ]]; then 1172 n=1 1173 elif [[ $oldval == "hidden" ]]; then 1174 n=0 1175 fi 1176 log_note "$user zfs set snapdir=${modes[$n]} $fs" 1177 user_run $user zfs set snapdir=${modes[$n]} $fs 1178 if [[ ${modes[$n]} != $(get_prop snapdir $fs) ]]; then 1179 return 1 1180 fi 1181 1182 return 0 1183} 1184 1185function verify_fs_aedsx 1186{ 1187 typeset user=$1 1188 typeset perm=$2 1189 typeset fs=$3 1190 1191 typeset oldval 1192 set -A modes "on" "off" 1193 oldval=$(get_prop $perm $fs) 1194 if [[ $oldval == "on" ]]; then 1195 n=1 1196 elif [[ $oldval == "off" ]]; then 1197 n=0 1198 fi 1199 log_note "$user zfs set $perm=${modes[$n]} $fs" 1200 user_run $user zfs set $perm=${modes[$n]} $fs 1201 if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then 1202 return 1 1203 fi 1204 1205 return 0 1206} 1207 1208function verify_fs_zoned 1209{ 1210 typeset user=$1 1211 typeset perm=$2 1212 typeset fs=$3 1213 1214 typeset oldval 1215 set -A modes "on" "off" 1216 oldval=$(get_prop $perm $fs) 1217 if [[ $oldval == "on" ]]; then 1218 n=1 1219 elif [[ $oldval == "off" ]]; then 1220 n=0 1221 fi 1222 log_note "$user zfs set $perm=${modes[$n]} $fs" 1223 if is_global_zone ; then 1224 if ! ismounted $fs ; then 1225 user_run $user zfs set \ 1226 $perm=${modes[$n]} $fs 1227 if [[ ${modes[$n]} != \ 1228 $(get_prop $perm $fs) ]]; then 1229 return 1 1230 fi 1231 if [[ $n -eq 0 ]]; then 1232 log_mustnot zfs mount $fs 1233 else 1234 log_must zfs mount $fs 1235 fi 1236 fi 1237 1238 if ismounted $fs; then 1239 # n always is 1 in this case 1240 user_run $user zfs set \ 1241 $perm=${modes[$n]} $fs 1242 if [[ $oldval != \ 1243 $(get_prop $perm $fs) ]]; then 1244 return 1 1245 fi 1246 1247 # mount permission is needed 1248 # to make zoned=on 1249 log_must zfs allow $user mount $fs 1250 user_run $user zfs set \ 1251 $perm=${modes[$n]} $fs 1252 log_must zfs unallow $user mount $fs 1253 if [[ ${modes[$n]} != \ 1254 $(get_prop $perm $fs) ]]; then 1255 return 1 1256 fi 1257 fi 1258 fi 1259 1260 if ! is_global_zone; then 1261 user_run $user zfs set $perm=${modes[$n]} $fs 1262 if [[ $oldval != $(get_prop $perm $fs) ]]; then 1263 return 1 1264 fi 1265 fi 1266 1267 return 0 1268} 1269 1270function verify_fs_sharenfs 1271{ 1272 typeset user=$1 1273 typeset perm=$2 1274 typeset fs=$3 1275 typeset nmode omode 1276 1277 omode=$(get_prop $perm $fs) 1278 if [[ $omode == "off" ]]; then 1279 nmode="on" 1280 else 1281 nmode="off" 1282 fi 1283 1284 log_note "$user zfs set $perm=$nmode $fs" 1285 user_run $user zfs set $perm=$nmode $fs 1286 if [[ $(get_prop $perm $fs) != $nmode ]]; then 1287 return 1 1288 fi 1289 1290 log_note "$user zfs set $perm=$omode $fs" 1291 user_run $user zfs set $perm=$omode $fs 1292 if [[ $(get_prop $perm $fs) != $omode ]]; then 1293 return 1 1294 fi 1295 1296 return 0 1297} 1298 1299function verify_vol_destroy 1300{ 1301 typeset user=$1 1302 typeset perm=$2 1303 typeset vol=$3 1304 1305 user_run $user zfs destroy $vol 1306 if ! datasetexists $vol ; then 1307 return 1 1308 fi 1309 1310 # mount permission is required 1311 log_must zfs allow $user mount $vol 1312 user_run $user zfs destroy $vol 1313 if datasetexists $vol ; then 1314 return 1 1315 fi 1316 1317 return 0 1318} 1319 1320function verify_vol_snapshot 1321{ 1322 typeset user=$1 1323 typeset perm=$2 1324 typeset vol=$3 1325 1326 typeset stamp=${perm}.${user}.$RANDOM 1327 typeset basevol=${vol%/*} 1328 typeset snap=$vol@snap.$stamp 1329 1330 user_run $user zfs snapshot $snap 1331 if datasetexists $snap ; then 1332 return 1 1333 fi 1334 1335 log_must zfs allow $user mount $vol 1336 user_run $user zfs snapshot $snap 1337 log_must zfs unallow $user mount $vol 1338 if ! datasetexists $snap ; then 1339 return 1 1340 fi 1341 1342 return 0 1343} 1344 1345function verify_vol_rollback 1346{ 1347 typeset user=$1 1348 typeset perm=$2 1349 typeset vol=$3 1350 1351 typeset stamp=${perm}.${user}.$RANDOM 1352 typeset basevol=${vol%/*} 1353 typeset snap=$vol@snap.$stamp 1354 1355 typeset oldval 1356 log_must zfs snapshot $snap 1357 oldval=$(datasetcksum $vol) 1358 1359 log_must dd if=/dev/urandom of=$ZVOL_RDEVDIR/$vol \ 1360 bs=512 count=1 1361 1362 user_run $user zfs rollback -R $snap 1363 sleep 10 1364 if [[ $oldval == $(datasetcksum $vol) ]]; then 1365 return 1 1366 fi 1367 1368 # rollback on volume has to be with mount permission 1369 log_must zfs allow $user mount $vol 1370 user_run $user zfs rollback -R $snap 1371 sleep 10 1372 log_must zfs unallow $user mount $vol 1373 if [[ $oldval != $(datasetcksum $vol) ]]; then 1374 return 1 1375 fi 1376 1377 return 0 1378} 1379 1380function verify_vol_clone 1381{ 1382 typeset user=$1 1383 typeset perm=$2 1384 typeset vol=$3 1385 1386 typeset stamp=${perm}.${user}.$RANDOM 1387 typeset basevol=${vol%/*} 1388 typeset snap=$vol@snap.$stamp 1389 typeset clone=$basevol/cvol.$stamp 1390 1391 log_must zfs snapshot $snap 1392 1393 user_run $user zfs clone $snap $clone 1394 if datasetexists $clone ; then 1395 return 1 1396 fi 1397 1398 log_must zfs allow $user create $basevol 1399 user_run $user zfs clone $snap $clone 1400 log_must zfs unallow $user create $basevol 1401 if datasetexists $clone ; then 1402 return 1 1403 fi 1404 1405 log_must zfs allow $user mount $basevol 1406 user_run $user zfs clone $snap $clone 1407 log_must zfs unallow $user mount $basevol 1408 if datasetexists $clone ; then 1409 return 1 1410 fi 1411 1412 # require create permission on parent and 1413 # mount permission on itself as well 1414 log_must zfs allow $user mount $basevol 1415 log_must zfs allow $user create $basevol 1416 user_run $user zfs clone $snap $clone 1417 log_must zfs unallow $user create $basevol 1418 log_must zfs unallow $user mount $basevol 1419 if ! datasetexists $clone ; then 1420 return 1 1421 fi 1422 1423 return 0 1424} 1425 1426function verify_vol_rename 1427{ 1428 typeset user=$1 1429 typeset perm=$2 1430 typeset vol=$3 1431 1432 typeset stamp=${perm}.${user}.$RANDOM 1433 typeset basevol=${vol%/*} 1434 typeset snap=$vol@snap.$stamp 1435 typeset clone=$basevol/cvol.$stamp 1436 typeset renamevol=$basevol/nvol.$stamp 1437 1438 user_run $user zfs rename $vol $renamevol 1439 if datasetexists $renamevol ; then 1440 return 1 1441 fi 1442 1443 log_must zfs allow $user create $basevol 1444 user_run $user zfs rename $vol $renamevol 1445 log_must zfs unallow $user create $basevol 1446 if datasetexists $renamevol ; then 1447 return 1 1448 fi 1449 1450 log_must zfs allow $user mount $basevol 1451 user_run $user zfs rename $vol $renamevol 1452 log_must zfs unallow $user mount $basevol 1453 if datasetexists $renamevol ; then 1454 return 1 1455 fi 1456 1457 # require both create permission on parent and 1458 # mount permission on parent as well 1459 log_must zfs allow $user mount $basevol 1460 log_must zfs allow $user create $basevol 1461 user_run $user zfs rename $vol $renamevol 1462 log_must zfs unallow $user mount $basevol 1463 log_must zfs unallow $user create $basevol 1464 if ! datasetexists $renamevol ; then 1465 return 1 1466 fi 1467 1468 log_must zfs rename $renamevol $vol 1469 1470 return 0 1471} 1472 1473function verify_vol_promote 1474{ 1475 typeset user=$1 1476 typeset perm=$2 1477 typeset vol=$3 1478 1479 typeset stamp=${perm}.${user}.$RANDOM 1480 typeset basevol=${vol%/*} 1481 typeset snap=$vol@snap.$stamp 1482 typeset clone=$basevol/cvol.$stamp 1483 1484 log_must zfs snapshot $snap 1485 log_must zfs clone $snap $clone 1486 log_must zfs promote $clone 1487 1488 typeset vol_orig=$(get_prop origin $vol) 1489 typeset clone_orig=$(get_prop origin $clone) 1490 1491 # promote should fail if $vol and $clone 1492 # miss either mount or promote permission 1493 # case 1 1494 user_run $user zfs promote $vol 1495 if [[ $vol_orig != $(get_prop origin $vol) || \ 1496 $clone_orig != $(get_prop origin $clone) ]]; 1497 then 1498 return 1 1499 fi 1500 1501 # promote should fail if $vol and $clone 1502 # miss either mount or promote permission 1503 # case 2 1504 log_must zfs allow $user promote $clone 1505 user_run $user zfs promote $vol 1506 log_must zfs unallow $user promote $clone 1507 if [[ $vol_orig != $(get_prop origin $vol) || \ 1508 $clone_orig != $(get_prop origin $clone) ]]; 1509 then 1510 return 1 1511 fi 1512 1513 # promote should fail if $vol and $clone 1514 # miss either mount or promote permission 1515 # case 3 1516 log_must zfs allow $user mount $vol 1517 user_run $user zfs promote $vol 1518 log_must zfs unallow $user mount $vol 1519 if [[ $vol_orig != $(get_prop origin $vol) || \ 1520 $clone_orig != $(get_prop origin $clone) ]]; 1521 then 1522 return 1 1523 fi 1524 1525 # promote should fail if $vol and $clone 1526 # miss either mount or promote permission 1527 # case 4 1528 log_must zfs allow $user mount $clone 1529 user_run $user zfs promote $vol 1530 log_must zfs unallow $user mount $clone 1531 if [[ $vol_orig != $(get_prop origin $vol) || \ 1532 $clone_orig != $(get_prop origin $clone) ]]; 1533 then 1534 return 1 1535 fi 1536 1537 # promote should fail if $vol and $clone 1538 # miss either mount or promote permission 1539 # case 5 1540 log_must zfs allow $user promote $clone 1541 log_must zfs allow $user mount $vol 1542 user_run $user zfs promote $vol 1543 log_must zfs unallow $user promote $clone 1544 log_must zfs unallow $user mount $vol 1545 if [[ $vol_orig != $(get_prop origin $vol) || \ 1546 $clone_orig != $(get_prop origin $clone) ]]; 1547 then 1548 return 1 1549 fi 1550 1551 # promote should fail if $vol and $clone 1552 # miss either mount or promote permission 1553 # case 6 1554 log_must zfs allow $user promote $clone 1555 log_must zfs allow $user mount $clone 1556 user_run $user zfs promote $vol 1557 log_must zfs unallow $user promote $clone 1558 log_must zfs unallow $user mount $vol 1559 if [[ $vol_orig != $(get_prop origin $vol) || \ 1560 $clone_orig != $(get_prop origin $clone) ]]; 1561 then 1562 return 1 1563 fi 1564 1565 # promote should fail if $vol and $clone 1566 # miss either mount or promote permission 1567 # case 7 1568 log_must zfs allow $user mount $vol 1569 log_must zfs allow $user mount $clone 1570 user_run $user zfs promote $vol 1571 log_must zfs unallow $user mount $vol 1572 log_must zfs unallow $user mount $clone 1573 if [[ $vol_orig != $(get_prop origin $vol) || \ 1574 $clone_orig != $(get_prop origin $clone) ]]; 1575 then 1576 return 1 1577 fi 1578 1579 # promote only succeeds when $vol and $clone 1580 # have both mount and promote permission 1581 # case 8 1582 log_must zfs allow $user promote $clone 1583 log_must zfs allow $user mount $vol 1584 log_must zfs allow $user mount $clone 1585 user_run $user zfs promote $vol 1586 log_must zfs unallow $user promote $clone 1587 log_must zfs unallow $user mount $vol 1588 log_must zfs unallow $user mount $clone 1589 if [[ $snap != $(get_prop origin $clone) || \ 1590 $clone_orig != $(get_prop origin $vol) ]]; then 1591 return 1 1592 fi 1593 1594 return 0 1595} 1596 1597function verify_vol_volsize 1598{ 1599 typeset user=$1 1600 typeset perm=$2 1601 typeset vol=$3 1602 1603 typeset oldval 1604 oldval=$(get_prop volsize $vol) 1605 (( newval = oldval * 2 )) 1606 1607 reserv_size=$(get_prop refreservation $vol) 1608 1609 if [[ "0" == $reserv_size ]]; then 1610 # sparse volume 1611 user_run $user zfs set volsize=$newval $vol 1612 if [[ $oldval == $(get_prop volsize $vol) ]]; 1613 then 1614 return 1 1615 fi 1616 1617 else 1618 # normal volume, reservation permission 1619 # is required 1620 user_run $user zfs set volsize=$newval $vol 1621 if [[ $newval == $(get_prop volsize $vol) ]]; 1622 then 1623 return 1 1624 fi 1625 1626 log_must zfs allow $user reservation $vol 1627 log_must zfs allow $user refreservation $vol 1628 user_run $user zfs set volsize=$newval $vol 1629 log_must zfs unallow $user reservation $vol 1630 log_must zfs unallow $user refreservation $vol 1631 if [[ $oldval == $(get_prop volsize $vol) ]]; 1632 then 1633 return 1 1634 fi 1635 fi 1636 1637 return 0 1638} 1639 1640function verify_allow 1641{ 1642 typeset user=$1 1643 typeset perm=$2 1644 typeset dtst=$3 1645 1646 typeset -i ret 1647 1648 user_run $user zfs allow $user allow $dtst && return 1 1649 1650 log_must zfs allow $user copies $dtst 1651 user_run $user zfs allow $user copies $dtst 1652 ret=$? 1653 log_must zfs unallow $user copies $dtst 1654 [ $ret -ne 1 ] 1655 1656} 1657