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