| # |
| # CDDL HEADER START |
| # |
| # The contents of this file are subject to the terms of the |
| # Common Development and Distribution License (the "License"). |
| # You may not use this file except in compliance with the License. |
| # |
| # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
| # or http://www.opensolaris.org/os/licensing. |
| # See the License for the specific language governing permissions |
| # and limitations under the License. |
| # |
| # When distributing Covered Code, include this CDDL HEADER in each |
| # file and include the License file at usr/src/OPENSOLARIS.LICENSE. |
| # If applicable, add the following below this CDDL HEADER, with the |
| # fields enclosed by brackets "[]" replaced with your own identifying |
| # information: Portions Copyright [yyyy] [name of copyright owner] |
| # |
| # CDDL HEADER END |
| # |
| |
| # |
| # Copyright 2008 Sun Microsystems, Inc. All rights reserved. |
| # Use is subject to license terms. |
| # |
| |
| # |
| # Copyright (c) 2013, 2016 by Delphix. All rights reserved. |
| # Copyright 2016 Nexenta Systems, Inc. |
| # Copyright (c) 2018 George Melikov. All Rights Reserved. |
| # |
| |
| . $STF_SUITE/include/libtest.shlib |
| . $STF_SUITE/tests/functional/delegate/delegate.cfg |
| |
| # |
| # Cleanup exist user/group. |
| # |
| function cleanup_user_group |
| { |
| typeset i |
| for i in $STAFF1 $STAFF2 $OTHER1 $OTHER2 ; do |
| del_user $i |
| done |
| for i in $STAFF_GROUP $OTHER_GROUP ; do |
| del_group $i |
| done |
| |
| return 0 |
| } |
| |
| # |
| # Restore test file system to the original status. |
| # |
| function restore_root_datasets |
| { |
| destroy_dataset "$ROOT_TESTFS" "-Rf" |
| log_must zfs create $ROOT_TESTFS |
| |
| if is_global_zone ; then |
| destroy_dataset "$ROOT_TESTVOL" "-Rf" |
| log_must zfs create -V $VOLSIZE $ROOT_TESTVOL |
| block_device_wait |
| fi |
| |
| return 0 |
| } |
| |
| # |
| # Verify the specified user have permission on the dataset |
| # |
| # $1 dataset |
| # $2 permissions which are separated by comma(,) |
| # $3-n users |
| # |
| function verify_perm |
| { |
| typeset dtst=$1 |
| typeset permissions=$2 |
| shift 2 |
| |
| if [[ -z $@ || -z $permissions || -z $dtst ]]; then |
| return 1 |
| fi |
| |
| typeset type=$(get_prop type $dtst) |
| permissions=$(echo $permissions | tr -s "," " ") |
| |
| typeset user |
| for user in $@; do |
| typeset perm |
| for perm in $permissions; do |
| typeset -i ret=1 |
| if [[ $type == "filesystem" ]]; then |
| check_fs_perm $user $perm $dtst |
| ret=$? |
| elif [[ $type == "volume" ]]; then |
| check_vol_perm $user $perm $dtst |
| ret=$? |
| fi |
| |
| log_note "Check $type $user $perm $dtst" |
| if ((ret != 0)) ; then |
| log_note "Fail: $user should have $perm " \ |
| "on $dtst" |
| return 1 |
| fi |
| done |
| done |
| |
| return 0 |
| } |
| |
| # |
| # Verify the specified user have no permission on the dataset |
| # |
| # $1 dataset |
| # $2 permissions which are separated by comma(,) |
| # $3-n users |
| # |
| function verify_noperm |
| { |
| typeset dtst=$1 |
| typeset permissions=$2 |
| shift 2 |
| |
| if [[ -z $@ || -z $permissions || -z $dtst ]]; then |
| return 1 |
| fi |
| |
| typeset type=$(get_prop type $dtst) |
| permissions=$(echo $permissions | tr -s "," " ") |
| |
| typeset user |
| for user in $@; do |
| typeset perm |
| for perm in $permissions; do |
| typeset -i ret=1 |
| if [[ $type == "filesystem" ]]; then |
| check_fs_perm $user $perm $dtst |
| ret=$? |
| elif [[ $type == "volume" ]]; then |
| check_vol_perm $user $perm $dtst |
| ret=$? |
| fi |
| |
| if ((ret == 0)) ; then |
| log_note "Fail: $user should not have $perm " \ |
| "on $dtst" |
| return 1 |
| fi |
| done |
| done |
| |
| return 0 |
| } |
| |
| function common_perm |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset dtst=$3 |
| |
| typeset -i ret=1 |
| case $perm in |
| send) |
| verify_send $user $perm $dtst |
| ret=$? |
| ;; |
| allow) |
| verify_allow $user $perm $dtst |
| ret=$? |
| ;; |
| userprop) |
| verify_userprop $user $perm $dtst |
| ret=$? |
| ;; |
| compression|checksum|readonly) |
| verify_ccr $user $perm $dtst |
| ret=$? |
| ;; |
| copies) |
| verify_copies $user $perm $dtst |
| ret=$? |
| ;; |
| reservation) |
| verify_reservation $user $perm $dtst |
| ret=$? |
| ;; |
| *) |
| ret=1 |
| ;; |
| esac |
| |
| return $ret |
| } |
| |
| function check_fs_perm |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset -i ret=1 |
| case $perm in |
| create) |
| verify_fs_create $user $perm $fs |
| ret=$? |
| ;; |
| destroy) |
| verify_fs_destroy $user $perm $fs |
| ret=$? |
| ;; |
| snapshot) |
| verify_fs_snapshot $user $perm $fs |
| ret=$? |
| ;; |
| rollback) |
| verify_fs_rollback $user $perm $fs |
| ret=$? |
| ;; |
| clone) |
| verify_fs_clone $user $perm $fs |
| ret=$? |
| ;; |
| rename) |
| verify_fs_rename $user $perm $fs |
| ret=$? |
| ;; |
| mount) |
| verify_fs_mount $user $perm $fs |
| ret=$? |
| ;; |
| share) |
| verify_fs_share $user $perm $fs |
| ret=$? |
| ;; |
| mountpoint) |
| verify_fs_mountpoint $user $perm $fs |
| ret=$? |
| ;; |
| promote) |
| verify_fs_promote $user $perm $fs |
| ret=$? |
| ;; |
| canmount) |
| verify_fs_canmount $user $perm $fs |
| ret=$? |
| ;; |
| dnodesize) |
| verify_fs_dnodesize $user $perm $fs |
| ret=$? |
| ;; |
| recordsize) |
| verify_fs_recordsize $user $perm $fs |
| ret=$? |
| ;; |
| quota) |
| verify_fs_quota $user $perm $fs |
| ret=$? |
| ;; |
| aclmode) |
| verify_fs_aclmode $user $perm $fs |
| ret=$? |
| ;; |
| aclinherit) |
| verify_fs_aclinherit $user $perm $fs |
| ret=$? |
| ;; |
| snapdir) |
| verify_fs_snapdir $user $perm $fs |
| ret=$? |
| ;; |
| atime|exec|devices|setuid|xattr) |
| verify_fs_aedsx $user $perm $fs |
| ret=$? |
| ;; |
| zoned) |
| verify_fs_zoned $user $perm $fs |
| ret=$? |
| ;; |
| sharenfs) |
| verify_fs_sharenfs $user $perm $fs |
| ret=$? |
| ;; |
| receive) |
| verify_fs_receive $user $perm $fs |
| ret=$? |
| ;; |
| *) |
| common_perm $user $perm $fs |
| ret=$? |
| ;; |
| esac |
| |
| return $ret |
| } |
| |
| function check_vol_perm |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| typeset -i ret=1 |
| case $perm in |
| destroy) |
| verify_vol_destroy $user $perm $vol |
| ret=$? |
| ;; |
| snapshot) |
| verify_vol_snapshot $user $perm $vol |
| ret=$? |
| ;; |
| rollback) |
| verify_vol_rollback $user $perm $vol |
| ret=$? |
| ;; |
| clone) |
| verify_vol_clone $user $perm $vol |
| ret=$? |
| ;; |
| rename) |
| verify_vol_rename $user $perm $vol |
| ret=$? |
| ;; |
| promote) |
| verify_vol_promote $user $perm $vol |
| ret=$? |
| ;; |
| volsize) |
| verify_vol_volsize $user $perm $vol |
| ret=$? |
| ;; |
| *) |
| common_perm $user $perm $vol |
| ret=$? |
| ;; |
| esac |
| |
| return $ret |
| } |
| |
| function setup_unallow_testenv |
| { |
| log_must restore_root_datasets |
| |
| log_must zfs create $SUBFS |
| |
| for dtst in $DATASETS ; do |
| log_must zfs allow -l $STAFF1 $LOCAL_SET $dtst |
| log_must zfs allow -d $STAFF2 $DESC_SET $dtst |
| log_must zfs allow $OTHER1 $LOCAL_DESC_SET $dtst |
| log_must zfs allow $OTHER2 $LOCAL_DESC_SET $dtst |
| |
| log_must verify_perm $dtst $LOCAL_SET $STAFF1 |
| log_must verify_perm $dtst $LOCAL_DESC_SET $OTHER1 |
| log_must verify_perm $dtst $LOCAL_DESC_SET $OTHER2 |
| if [[ $dtst == $ROOT_TESTFS ]]; then |
| log_must verify_perm $SUBFS $DESC_SET $STAFF2 |
| log_must verify_perm $SUBFS $LOCAL_DESC_SET $OTHER1 |
| log_must verify_perm $SUBFS $LOCAL_DESC_SET $OTHER2 |
| fi |
| done |
| |
| return 0 |
| } |
| |
| # |
| # Verify permission send for specified user on the dataset |
| # $1 user |
| # $2 permission |
| # $3 dataset |
| # |
| function verify_send |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset dtst=$3 |
| |
| typeset oldval |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset snap=$dtst@snap.$stamp |
| |
| typeset -i ret=1 |
| |
| log_must zfs snapshot $snap |
| typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp |
| typeset bak_root=$TEST_BASE_DIR/bak.root.$stamp |
| |
| user_run $user eval "zfs send $snap > $bak_user" |
| log_must eval "zfs send $snap > $bak_root" |
| |
| if [[ $(checksum $bak_user) == $(checksum $bak_root) ]]; then |
| ret=0 |
| fi |
| |
| rm -rf $bak_user > /dev/null |
| rm -rf $bak_root > /dev/null |
| |
| return $ret |
| } |
| |
| function verify_fs_receive |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset dtst |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset newfs=$fs/newfs.$stamp |
| typeset newvol=$fs/newvol.$stamp |
| typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp |
| typeset bak_root=$TEST_BASE_DIR/bak.root.$stamp |
| |
| log_must zfs create $newfs |
| typeset datasets="$newfs" |
| if is_global_zone ; then |
| log_must zfs create -V $VOLSIZE $newvol |
| block_device_wait |
| datasets="$newfs $newvol" |
| fi |
| |
| for dtst in $datasets ; do |
| |
| typeset dtstsnap=$dtst@snap.$stamp |
| log_must zfs snapshot $dtstsnap |
| |
| log_must eval "zfs send $dtstsnap > $bak_root" |
| log_must_busy zfs destroy -rf $dtst |
| |
| user_run $user eval "zfs receive $dtst < $bak_root" |
| if datasetexists $dtstsnap ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user create $fs |
| user_run $user eval "zfs receive $dtst < $bak_root" |
| log_must zfs unallow $user create $fs |
| if datasetexists $dtstsnap ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $fs |
| user_run $user eval "zfs receive $dtst < $bak_root" |
| log_must zfs unallow $user mount $fs |
| if datasetexists $dtstsnap ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount,create $fs |
| user_run $user eval "zfs receive $dtst < $bak_root" |
| log_must zfs unallow $user mount,create $fs |
| if ! datasetexists $dtstsnap ; then |
| return 1 |
| fi |
| |
| # check the data integrity |
| log_must eval "zfs send $dtstsnap > $bak_user" |
| log_must_busy zfs destroy -rf $dtst |
| log_must eval "zfs receive $dtst < $bak_root" |
| log_must eval "zfs send $dtstsnap > $bak_root" |
| log_must_busy zfs destroy -rf $dtst |
| if [[ $(checksum $bak_user) != $(checksum $bak_root) ]]; then |
| return 1 |
| fi |
| |
| rm -rf $bak_user > /dev/null |
| rm -rf $bak_root > /dev/null |
| |
| done |
| |
| return 0 |
| } |
| |
| function verify_userprop |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset dtst=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| |
| user_run $user zfs set "$user:ts=$stamp" $dtst |
| if [[ $stamp != $(get_prop "$user:ts" $dtst) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_ccr |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset dtst=$3 |
| |
| typeset oldval |
| |
| set -A modes "on" "off" |
| oldval=$(get_prop $perm $dtst) |
| if [[ $oldval == "on" ]]; then |
| n=1 |
| elif [[ $oldval == "off" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set $perm=${modes[$n]} $dtst" |
| user_run $user zfs set $perm=${modes[$n]} $dtst |
| if [[ ${modes[$n]} != $(get_prop $perm $dtst) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_copies |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset dtst=$3 |
| |
| typeset oldval |
| |
| set -A modes 1 2 3 |
| oldval=$(get_prop $perm $dtst) |
| if [[ $oldval -eq 1 ]]; then |
| n=1 |
| elif [[ $oldval -eq 2 ]]; then |
| n=2 |
| elif [[ $oldval -eq 3 ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set $perm=${modes[$n]} $dtst" |
| user_run $user zfs set $perm=${modes[$n]} $dtst |
| if [[ ${modes[$n]} != $(get_prop $perm $dtst) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_reservation |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset dtst=$3 |
| |
| typeset value32m=$(( 1024 * 1024 * 32 )) |
| typeset oldval=$(get_prop reservation $dtst) |
| user_run $user zfs set reservation=$value32m $dtst |
| if [[ $value32m != $(get_prop reservation $dtst) ]]; then |
| log_must zfs set reservation=$oldval $dtst |
| return 1 |
| fi |
| |
| log_must zfs set reservation=$oldval $dtst |
| return 0 |
| } |
| |
| function verify_fs_create |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset newfs=$fs/nfs.$stamp |
| typeset newvol=$fs/nvol.$stamp |
| |
| user_run $user zfs create $newfs |
| if datasetexists $newfs ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $fs |
| user_run $user zfs create $newfs |
| log_must zfs unallow $user mount $fs |
| if ! datasetexists $newfs ; then |
| return 1 |
| fi |
| |
| log_must zfs destroy $newfs |
| |
| if is_global_zone ; then |
| # mount permission is required for sparse volume |
| user_run $user zfs create -V 150m -s $newvol |
| block_device_wait |
| if datasetexists $newvol ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $fs |
| user_run $user zfs create -V 150m -s $newvol |
| log_must zfs unallow $user mount $fs |
| if ! datasetexists $newvol ; then |
| return 1 |
| fi |
| |
| block_device_wait |
| log_must zfs destroy $newvol |
| block_device_wait |
| |
| # mount and reserveration permission are |
| # required for normal volume |
| user_run $user zfs create -V 150m $newvol |
| block_device_wait |
| if datasetexists $newvol ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $fs |
| user_run $user zfs create -V 150m $newvol |
| block_device_wait |
| log_must zfs unallow $user mount $fs |
| if datasetexists $newvol ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user reservation $fs |
| user_run $user zfs create -V 150m $newvol |
| block_device_wait |
| log_must zfs unallow $user reservation $fs |
| if datasetexists $newvol ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user refreservation $fs |
| user_run $user zfs create -V 150m $newvol |
| block_device_wait |
| log_must zfs unallow $user refreservation $fs |
| if datasetexists $newvol ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $fs |
| log_must zfs allow $user reservation $fs |
| log_must zfs allow $user refreservation $fs |
| user_run $user zfs create -V 150m $newvol |
| log_must zfs unallow $user mount $fs |
| log_must zfs unallow $user reservation $fs |
| log_must zfs unallow $user refreservation $fs |
| if ! datasetexists $newvol ; then |
| return 1 |
| fi |
| |
| block_device_wait |
| log_must zfs destroy $newvol |
| block_device_wait |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_destroy |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| if ! ismounted $fs ; then |
| user_run $user zfs destroy $fs |
| if datasetexists $fs ; then |
| return 1 |
| fi |
| fi |
| |
| if ismounted $fs ; then |
| user_run $user zfs destroy $fs |
| if ! datasetexists $fs ; then |
| return 1 |
| fi |
| |
| # mount permission is required |
| log_must zfs allow $user mount $fs |
| user_run $user zfs destroy $fs |
| if datasetexists $fs ; then |
| return 1 |
| fi |
| fi |
| |
| return 0 |
| } |
| |
| # Verify that given the correct delegation, a regular user can: |
| # Take a snapshot of an unmounted dataset |
| # Take a snapshot of an mounted dataset |
| # Create a snapshot by making a directory in the .zfs/snapshot directory |
| function verify_fs_snapshot |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset snap=$fs@snap.$stamp |
| typeset mntpt=$(get_prop mountpoint $fs) |
| |
| if [[ "yes" == $(get_prop mounted $fs) ]]; then |
| log_must zfs umount $fs |
| fi |
| |
| user_run $user zfs snapshot $snap |
| if ! datasetexists $snap ; then |
| return 1 |
| fi |
| log_must zfs destroy $snap |
| |
| if [[ "no" == $(get_prop mounted $fs) ]]; then |
| log_must zfs mount $fs |
| fi |
| |
| user_run $user zfs snapshot $snap |
| if ! datasetexists $snap ; then |
| return 1 |
| fi |
| log_must zfs destroy $snap |
| |
| typeset snapdir=${mntpt}/.zfs/snapshot/snap.$stamp |
| user_run $user mkdir $snapdir |
| if ! datasetexists $snap ; then |
| return 1 |
| fi |
| log_must zfs destroy $snap |
| |
| return 0 |
| } |
| |
| function verify_fs_rollback |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset oldval |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset snap=$fs@snap.$stamp |
| typeset mntpt=$(get_prop mountpoint $fs) |
| |
| oldval=$(datasetcksum $fs) |
| log_must zfs snapshot $snap |
| |
| if ! ismounted $fs; then |
| log_must zfs mount $fs |
| fi |
| log_must touch $mntpt/testfile.$stamp |
| |
| user_run $user zfs rollback -R $snap |
| if is_global_zone ; then |
| if [[ $oldval != $(datasetcksum $fs) ]]; then |
| return 1 |
| fi |
| else |
| # datasetcksum can not be used in local zone |
| if [[ -e $mntpt/testfile.$stamp ]]; then |
| return 1 |
| fi |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_clone |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset basefs=${fs%/*} |
| typeset snap=$fs@snap.$stamp |
| typeset clone=$basefs/cfs.$stamp |
| |
| log_must zfs snapshot $snap |
| user_run $user zfs clone $snap $clone |
| if datasetexists $clone ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user create $basefs |
| user_run $user zfs clone $snap $clone |
| log_must zfs unallow $user create $basefs |
| if datasetexists $clone ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $basefs |
| user_run $user zfs clone $snap $clone |
| log_must zfs unallow $user mount $basefs |
| if datasetexists $clone ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $basefs |
| log_must zfs allow $user create $basefs |
| user_run $user zfs clone $snap $clone |
| log_must zfs unallow $user create $basefs |
| log_must zfs unallow $user mount $basefs |
| if ! datasetexists $clone ; then |
| return 1 |
| fi |
| |
| log_must zfs destroy -R $snap |
| |
| return 0 |
| } |
| |
| function verify_fs_rename |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset basefs=${fs%/*} |
| typeset snap=$fs@snap.$stamp |
| typeset renamefs=$basefs/nfs.$stamp |
| |
| if ! ismounted $fs; then |
| log_must zfs mount $fs |
| fi |
| |
| # case 1 |
| user_run $user zfs rename $fs $renamefs |
| if datasetexists $renamefs ; then |
| return 1 |
| fi |
| |
| # case 2 |
| log_must zfs allow $user create $basefs |
| user_run $user zfs rename $fs $renamefs |
| log_must zfs unallow $user create $basefs |
| if datasetexists $renamefs ; then |
| return 1 |
| fi |
| |
| # case 3 |
| log_must zfs allow $user mount $basefs |
| user_run $user zfs rename $fs $renamefs |
| log_must zfs unallow $user mount $basefs |
| if datasetexists $renamefs ; then |
| return 1 |
| fi |
| |
| # case 4 |
| log_must zfs allow $user mount $fs |
| user_run $user zfs rename $fs $renamefs |
| if datasetexists $renamefs ; then |
| log_must zfs unallow $user mount $renamefs |
| return 1 |
| fi |
| log_must zfs unallow $user mount $fs |
| |
| # case 5 |
| log_must zfs allow $user create $basefs |
| log_must zfs allow $user mount $fs |
| user_run $user zfs rename $fs $renamefs |
| log_must zfs unallow $user create $basefs |
| if datasetexists $renamefs ; then |
| log_must zfs unallow $user mount $renamefs |
| return 1 |
| fi |
| log_must zfs unallow $user mount $fs |
| |
| # case 6 |
| log_must zfs allow $user mount $basefs |
| log_must zfs allow $user mount $fs |
| user_run $user zfs rename $fs $renamefs |
| log_must zfs unallow $user mount $basefs |
| if datasetexists $renamefs ; then |
| log_must zfs unallow $user mount $renamefs |
| return 1 |
| fi |
| log_must zfs unallow $user mount $fs |
| |
| # case 7 |
| log_must zfs allow $user create $basefs |
| log_must zfs allow $user mount $basefs |
| user_run $user zfs rename $fs $renamefs |
| log_must zfs unallow $user mount $basefs |
| log_must zfs unallow $user create $basefs |
| if ! datasetexists $renamefs ; then |
| return 1 |
| fi |
| |
| log_must zfs rename $renamefs $fs |
| |
| return 0 |
| } |
| |
| function verify_fs_mount |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset mntpt=$(get_prop mountpoint $fs) |
| typeset newmntpt=$TEST_BASE_DIR/mnt.$stamp |
| |
| if ismounted $fs ; then |
| user_run $user zfs unmount $fs |
| if ismounted $fs ; then |
| return 1 |
| fi |
| fi |
| |
| if ! ismounted $fs ; then |
| log_must zfs set mountpoint=$newmntpt $fs |
| log_must rm -rf $newmntpt |
| log_must mkdir $newmntpt |
| |
| user_run $user zfs mount $fs |
| if ismounted $fs ; then |
| return 1 |
| fi |
| |
| # mountpoint's owner must be the user |
| log_must chown $user $newmntpt |
| user_run $user zfs mount $fs |
| if ! ismounted $fs ; then |
| return 1 |
| fi |
| log_must zfs umount $fs |
| log_must rm -rf $newmntpt |
| log_must zfs set mountpoint=$mntpt $fs |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_share |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| typeset -i ret=0 |
| |
| svcadm enable -rs nfs/server |
| typeset stat=$(svcs -H -o STA nfs/server:default) |
| if [[ $stat != "ON" ]]; then |
| log_fail "Could not enable nfs/server" |
| fi |
| |
| log_must zfs set sharenfs=on $fs |
| zfs unshare $fs |
| |
| user_run $user zfs share $fs |
| if ! is_shared $fs; then |
| ret=1 |
| fi |
| |
| zfs unshare $fs |
| log_must zfs set sharenfs=off $fs |
| |
| return $ret |
| } |
| |
| function verify_fs_mountpoint |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset mntpt=$(get_prop mountpoint $fs) |
| typeset newmntpt=$TEST_BASE_DIR/mnt.$stamp |
| |
| if ! ismounted $fs ; then |
| user_run $user zfs set mountpoint=$newmntpt $fs |
| if [[ $newmntpt != \ |
| $(get_prop mountpoint $fs) ]] ; then |
| return 1 |
| fi |
| log_must zfs set mountpoint=$mntpt $fs |
| fi |
| |
| if ismounted $fs ; then |
| user_run $user zfs set mountpoint=$newmntpt $fs |
| if [[ $mntpt != $(get_prop mountpoint $fs) ]]; then |
| return 1 |
| fi |
| |
| # require mount permission when fs is mounted |
| log_must zfs allow $user mount $fs |
| user_run $user zfs set mountpoint=$newmntpt $fs |
| log_must zfs unallow $user mount $fs |
| if [[ $newmntpt != \ |
| $(get_prop mountpoint $fs) ]] ; then |
| return 1 |
| fi |
| log_must zfs set mountpoint=$mntpt $fs |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_promote |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset basefs=${fs%/*} |
| typeset snap=$fs@snap.$stamp |
| typeset clone=$basefs/cfs.$stamp |
| |
| log_must zfs snapshot $snap |
| log_must zfs clone $snap $clone |
| log_must zfs promote $clone |
| |
| typeset fs_orig=$(get_prop origin $fs) |
| typeset clone_orig=$(get_prop origin $clone) |
| |
| user_run $user zfs promote $fs |
| # promote should fail if original fs does not have |
| # promote permission |
| if [[ $fs_orig != $(get_prop origin $fs) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user promote $clone |
| user_run $user zfs promote $fs |
| log_must zfs unallow $user promote $clone |
| if [[ $fs_orig != $(get_prop origin $fs) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $fs |
| user_run $user zfs promote $fs |
| log_must zfs unallow $user mount $fs |
| if [[ $fs_orig != $(get_prop origin $fs) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $fs |
| log_must zfs allow $user promote $clone |
| user_run $user zfs promote $fs |
| log_must zfs unallow $user promote $clone |
| log_must zfs unallow $user mount $fs |
| if [[ $snap != $(get_prop origin $clone) || \ |
| $clone_orig != $(get_prop origin $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_canmount |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset oldval |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| |
| if ! ismounted $fs ; then |
| set -A modes "on" "off" |
| oldval=$(get_prop $perm $fs) |
| if [[ $oldval == "on" ]]; then |
| n=1 |
| elif [[ $oldval == "off" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set $perm=${modes[$n]} $fs" |
| user_run $user zfs set $perm=${modes[$n]} $fs |
| if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then |
| return 1 |
| fi |
| fi |
| |
| |
| # fs is mounted |
| if ismounted $fs ; then |
| # property value does not change if |
| # no mount permission |
| set -A modes "on" "off" |
| oldval=$(get_prop $perm $fs) |
| if [[ $oldval == "on" ]]; then |
| n=1 |
| elif [[ $oldval == "off" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set $perm=${modes[$n]} $fs" |
| log_must zfs allow $user mount $fs |
| user_run $user zfs set $perm=${modes[$n]} $fs |
| log_must zfs unallow $user mount $fs |
| if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then |
| return 1 |
| fi |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_recordsize |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset value8k=$(( 1024 * 8 )) |
| user_run $user zfs set recordsize=$value8k $fs |
| if [[ $value8k != $(get_prop recordsize $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_dnodesize |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| value="2k" |
| |
| user_run $user zfs set dnodesize=$value $fs |
| if [[ $value != $(get_prop dnodesize $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_quota |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset value32m=$(( 1024 * 1024 * 32 )) |
| user_run $user zfs set quota=$value32m $fs |
| if [[ $value32m != $(get_prop quota $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_aclmode |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset oldval |
| set -A modes "discard" "groupmask" "passthrough" |
| oldval=$(get_prop $perm $fs) |
| if [[ $oldval == "discard" ]]; then |
| n=1 |
| elif [[ $oldval == "groupmask" ]]; then |
| n=2 |
| elif [[ $oldval == "passthrough" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set aclmode=${modes[$n]} $fs" |
| user_run $user zfs set aclmode=${modes[$n]} $fs |
| if [[ ${modes[$n]} != $(get_prop aclmode $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_aclinherit |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| # |
| # PSARC/2008/231 change the default value of aclinherit to "restricted" |
| # but still keep the old interface of "secure" |
| # |
| |
| typeset oldval |
| set -A modes "discard" "noallow" "secure" "passthrough" |
| oldval=$(get_prop $perm $fs) |
| if [[ $oldval == "discard" ]]; then |
| n=1 |
| elif [[ $oldval == "noallow" ]]; then |
| n=2 |
| elif [[ $oldval == "secure" || $oldval == "restricted" ]]; then |
| n=3 |
| elif [[ $oldval == "passthrough" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set aclinherit=${modes[$n]} $fs" |
| user_run $user zfs set aclinherit=${modes[$n]} $fs |
| |
| typeset newval=$(get_prop aclinherit $fs) |
| if [[ ${modes[$n]} == "secure" && $newval == "restricted" ]]; then |
| return 0 |
| elif [[ ${modes[$n]} != $(get_prop aclinherit $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_snapdir |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset oldval |
| set -A modes "visible" "hidden" |
| oldval=$(get_prop $perm $fs) |
| if [[ $oldval == "visible" ]]; then |
| n=1 |
| elif [[ $oldval == "hidden" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set snapdir=${modes[$n]} $fs" |
| user_run $user zfs set snapdir=${modes[$n]} $fs |
| if [[ ${modes[$n]} != $(get_prop snapdir $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_aedsx |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset oldval |
| set -A modes "on" "off" |
| oldval=$(get_prop $perm $fs) |
| if [[ $oldval == "on" ]]; then |
| n=1 |
| elif [[ $oldval == "off" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set $perm=${modes[$n]} $fs" |
| user_run $user zfs set $perm=${modes[$n]} $fs |
| if [[ ${modes[$n]} != $(get_prop $perm $fs) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_zoned |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| |
| typeset oldval |
| set -A modes "on" "off" |
| oldval=$(get_prop $perm $fs) |
| if [[ $oldval == "on" ]]; then |
| n=1 |
| elif [[ $oldval == "off" ]]; then |
| n=0 |
| fi |
| log_note "$user zfs set $perm=${modes[$n]} $fs" |
| if is_global_zone ; then |
| if ! ismounted $fs ; then |
| user_run $user zfs set \ |
| $perm=${modes[$n]} $fs |
| if [[ ${modes[$n]} != \ |
| $(get_prop $perm $fs) ]]; then |
| return 1 |
| fi |
| if [[ $n -eq 0 ]]; then |
| log_mustnot zfs mount $fs |
| else |
| log_must zfs mount $fs |
| fi |
| fi |
| |
| if ismounted $fs; then |
| # n always is 1 in this case |
| user_run $user zfs set \ |
| $perm=${modes[$n]} $fs |
| if [[ $oldval != \ |
| $(get_prop $perm $fs) ]]; then |
| return 1 |
| fi |
| |
| # mount permission is needed |
| # to make zoned=on |
| log_must zfs allow $user mount $fs |
| user_run $user zfs set \ |
| $perm=${modes[$n]} $fs |
| log_must zfs unallow $user mount $fs |
| if [[ ${modes[$n]} != \ |
| $(get_prop $perm $fs) ]]; then |
| return 1 |
| fi |
| fi |
| fi |
| |
| if ! is_global_zone; then |
| user_run $user zfs set $perm=${modes[$n]} $fs |
| if [[ $oldval != $(get_prop $perm $fs) ]]; then |
| return 1 |
| fi |
| fi |
| |
| return 0 |
| } |
| |
| function verify_fs_sharenfs |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset fs=$3 |
| typeset nmode omode |
| |
| omode=$(get_prop $perm $fs) |
| if [[ $omode == "off" ]]; then |
| nmode="on" |
| else |
| nmode="off" |
| fi |
| |
| log_note "$user zfs set $perm=$nmode $fs" |
| user_run $user zfs set $perm=$nmode $fs |
| if [[ $(get_prop $perm $fs) != $nmode ]]; then |
| return 1 |
| fi |
| |
| log_note "$user zfs set $perm=$omode $fs" |
| user_run $user zfs set $perm=$omode $fs |
| if [[ $(get_prop $perm $fs) != $omode ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_vol_destroy |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| user_run $user zfs destroy $vol |
| if ! datasetexists $vol ; then |
| return 1 |
| fi |
| |
| # mount permission is required |
| log_must zfs allow $user mount $vol |
| user_run $user zfs destroy $vol |
| if datasetexists $vol ; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_vol_snapshot |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| typeset stamp=${perm}.${user}.$(date +'%F-%T-%N') |
| typeset basevol=${vol%/*} |
| typeset snap=$vol@snap.$stamp |
| |
| user_run $user zfs snapshot $snap |
| if datasetexists $snap ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $vol |
| user_run $user zfs snapshot $snap |
| log_must zfs unallow $user mount $vol |
| if ! datasetexists $snap ; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_vol_rollback |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| typeset stamp=${perm}.${user}.$(date+'%F-%T-%N') |
| typeset basevol=${vol%/*} |
| typeset snap=$vol@snap.$stamp |
| |
| typeset oldval |
| log_must zfs snapshot $snap |
| oldval=$(datasetcksum $vol) |
| |
| log_must dd if=/dev/urandom of=$ZVOL_RDEVDIR/$vol \ |
| bs=512 count=1 |
| |
| user_run $user zfs rollback -R $snap |
| sleep 10 |
| if [[ $oldval == $(datasetcksum $vol) ]]; then |
| return 1 |
| fi |
| |
| # rollback on volume has to be with mount permission |
| log_must zfs allow $user mount $vol |
| user_run $user zfs rollback -R $snap |
| sleep 10 |
| log_must zfs unallow $user mount $vol |
| if [[ $oldval != $(datasetcksum $vol) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_vol_clone |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| typeset stamp=${perm}.${user}.$(date+'%F-%T-%N') |
| typeset basevol=${vol%/*} |
| typeset snap=$vol@snap.$stamp |
| typeset clone=$basevol/cvol.$stamp |
| |
| log_must zfs snapshot $snap |
| |
| user_run $user zfs clone $snap $clone |
| if datasetexists $clone ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user create $basevol |
| user_run $user zfs clone $snap $clone |
| log_must zfs unallow $user create $basevol |
| if datasetexists $clone ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $basevol |
| user_run $user zfs clone $snap $clone |
| log_must zfs unallow $user mount $basevol |
| if datasetexists $clone ; then |
| return 1 |
| fi |
| |
| # require create permission on parent and |
| # mount permission on itself as well |
| log_must zfs allow $user mount $basevol |
| log_must zfs allow $user create $basevol |
| user_run $user zfs clone $snap $clone |
| log_must zfs unallow $user create $basevol |
| log_must zfs unallow $user mount $basevol |
| if ! datasetexists $clone ; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_vol_rename |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| typeset stamp=${perm}.${user}.$(date+'%F-%T-%N') |
| typeset basevol=${vol%/*} |
| typeset snap=$vol@snap.$stamp |
| typeset clone=$basevol/cvol.$stamp |
| typeset renamevol=$basevol/nvol.$stamp |
| |
| user_run $user zfs rename $vol $renamevol |
| if datasetexists $renamevol ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user create $basevol |
| user_run $user zfs rename $vol $renamevol |
| log_must zfs unallow $user create $basevol |
| if datasetexists $renamevol ; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user mount $basevol |
| user_run $user zfs rename $vol $renamevol |
| log_must zfs unallow $user mount $basevol |
| if datasetexists $renamevol ; then |
| return 1 |
| fi |
| |
| # require both create permission on parent and |
| # mount permission on parent as well |
| log_must zfs allow $user mount $basevol |
| log_must zfs allow $user create $basevol |
| user_run $user zfs rename $vol $renamevol |
| log_must zfs unallow $user mount $basevol |
| log_must zfs unallow $user create $basevol |
| if ! datasetexists $renamevol ; then |
| return 1 |
| fi |
| |
| log_must zfs rename $renamevol $vol |
| |
| return 0 |
| } |
| |
| function verify_vol_promote |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| typeset stamp=${perm}.${user}.$(date+'%F-%T-%N') |
| typeset basevol=${vol%/*} |
| typeset snap=$vol@snap.$stamp |
| typeset clone=$basevol/cvol.$stamp |
| |
| log_must zfs snapshot $snap |
| log_must zfs clone $snap $clone |
| log_must zfs promote $clone |
| |
| typeset vol_orig=$(get_prop origin $vol) |
| typeset clone_orig=$(get_prop origin $clone) |
| |
| # promote should fail if $vol and $clone |
| # miss either mount or promote permission |
| # case 1 |
| user_run $user zfs promote $vol |
| if [[ $vol_orig != $(get_prop origin $vol) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; |
| then |
| return 1 |
| fi |
| |
| # promote should fail if $vol and $clone |
| # miss either mount or promote permission |
| # case 2 |
| log_must zfs allow $user promote $clone |
| user_run $user zfs promote $vol |
| log_must zfs unallow $user promote $clone |
| if [[ $vol_orig != $(get_prop origin $vol) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; |
| then |
| return 1 |
| fi |
| |
| # promote should fail if $vol and $clone |
| # miss either mount or promote permission |
| # case 3 |
| log_must zfs allow $user mount $vol |
| user_run $user zfs promote $vol |
| log_must zfs unallow $user mount $vol |
| if [[ $vol_orig != $(get_prop origin $vol) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; |
| then |
| return 1 |
| fi |
| |
| # promote should fail if $vol and $clone |
| # miss either mount or promote permission |
| # case 4 |
| log_must zfs allow $user mount $clone |
| user_run $user zfs promote $vol |
| log_must zfs unallow $user mount $clone |
| if [[ $vol_orig != $(get_prop origin $vol) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; |
| then |
| return 1 |
| fi |
| |
| # promote should fail if $vol and $clone |
| # miss either mount or promote permission |
| # case 5 |
| log_must zfs allow $user promote $clone |
| log_must zfs allow $user mount $vol |
| user_run $user zfs promote $vol |
| log_must zfs unallow $user promote $clone |
| log_must zfs unallow $user mount $vol |
| if [[ $vol_orig != $(get_prop origin $vol) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; |
| then |
| return 1 |
| fi |
| |
| # promote should fail if $vol and $clone |
| # miss either mount or promote permission |
| # case 6 |
| log_must zfs allow $user promote $clone |
| log_must zfs allow $user mount $clone |
| user_run $user zfs promote $vol |
| log_must zfs unallow $user promote $clone |
| log_must zfs unallow $user mount $vol |
| if [[ $vol_orig != $(get_prop origin $vol) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; |
| then |
| return 1 |
| fi |
| |
| # promote should fail if $vol and $clone |
| # miss either mount or promote permission |
| # case 7 |
| log_must zfs allow $user mount $vol |
| log_must zfs allow $user mount $clone |
| user_run $user zfs promote $vol |
| log_must zfs unallow $user mount $vol |
| log_must zfs unallow $user mount $clone |
| if [[ $vol_orig != $(get_prop origin $vol) || \ |
| $clone_orig != $(get_prop origin $clone) ]]; |
| then |
| return 1 |
| fi |
| |
| # promote only succeeds when $vol and $clone |
| # have both mount and promote permission |
| # case 8 |
| log_must zfs allow $user promote $clone |
| log_must zfs allow $user mount $vol |
| log_must zfs allow $user mount $clone |
| user_run $user zfs promote $vol |
| log_must zfs unallow $user promote $clone |
| log_must zfs unallow $user mount $vol |
| log_must zfs unallow $user mount $clone |
| if [[ $snap != $(get_prop origin $clone) || \ |
| $clone_orig != $(get_prop origin $vol) ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| } |
| |
| function verify_vol_volsize |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset vol=$3 |
| |
| typeset oldval |
| oldval=$(get_prop volsize $vol) |
| (( newval = oldval * 2 )) |
| |
| reserv_size=$(get_prop refreservation $vol) |
| |
| if [[ "0" == $reserv_size ]]; then |
| # sparse volume |
| user_run $user zfs set volsize=$newval $vol |
| if [[ $oldval == $(get_prop volsize $vol) ]]; |
| then |
| return 1 |
| fi |
| |
| else |
| # normal volume, reservation permission |
| # is required |
| user_run $user zfs set volsize=$newval $vol |
| if [[ $newval == $(get_prop volsize $vol) ]]; |
| then |
| return 1 |
| fi |
| |
| log_must zfs allow $user reservation $vol |
| log_must zfs allow $user refreservation $vol |
| user_run $user zfs set volsize=$newval $vol |
| log_must zfs unallow $user reservation $vol |
| log_must zfs unallow $user refreservation $vol |
| if [[ $oldval == $(get_prop volsize $vol) ]]; |
| then |
| return 1 |
| fi |
| fi |
| |
| return 0 |
| } |
| |
| function verify_allow |
| { |
| typeset user=$1 |
| typeset perm=$2 |
| typeset dtst=$3 |
| |
| typeset -i ret |
| |
| user_run $user zfs allow $user allow $dtst |
| ret=$? |
| if [[ $ret -eq 0 ]]; then |
| return 1 |
| fi |
| |
| log_must zfs allow $user copies $dtst |
| user_run $user zfs allow $user copies $dtst |
| ret=$? |
| log_must zfs unallow $user copies $dtst |
| if [[ $ret -eq 1 ]]; then |
| return 1 |
| fi |
| |
| return 0 |
| |
| } |