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