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