1f38cb554SJohn Wren Kennedy#
2f38cb554SJohn Wren Kennedy# CDDL HEADER START
3f38cb554SJohn Wren Kennedy#
4f38cb554SJohn Wren Kennedy# The contents of this file are subject to the terms of the
5f38cb554SJohn Wren Kennedy# Common Development and Distribution License (the "License").
6f38cb554SJohn Wren Kennedy# You may not use this file except in compliance with the License.
7f38cb554SJohn Wren Kennedy#
8f38cb554SJohn Wren Kennedy# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9f38cb554SJohn Wren Kennedy# or http://www.opensolaris.org/os/licensing.
10f38cb554SJohn Wren Kennedy# See the License for the specific language governing permissions
11f38cb554SJohn Wren Kennedy# and limitations under the License.
12f38cb554SJohn Wren Kennedy#
13f38cb554SJohn Wren Kennedy# When distributing Covered Code, include this CDDL HEADER in each
14f38cb554SJohn Wren Kennedy# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15f38cb554SJohn Wren Kennedy# If applicable, add the following below this CDDL HEADER, with the
16f38cb554SJohn Wren Kennedy# fields enclosed by brackets "[]" replaced with your own identifying
17f38cb554SJohn Wren Kennedy# information: Portions Copyright [yyyy] [name of copyright owner]
18f38cb554SJohn Wren Kennedy#
19f38cb554SJohn Wren Kennedy# CDDL HEADER END
20f38cb554SJohn Wren Kennedy#
21f38cb554SJohn Wren Kennedy
22f38cb554SJohn Wren Kennedy#
23f38cb554SJohn Wren Kennedy# Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24f38cb554SJohn Wren Kennedy# Use is subject to license terms.
25f38cb554SJohn Wren Kennedy#
26f38cb554SJohn Wren Kennedy
27f38cb554SJohn Wren Kennedy#
28*1d32ba66SJohn Wren Kennedy# Copyright (c) 2013, 2016 by Delphix. All rights reserved.
29f38cb554SJohn Wren Kennedy#
30f38cb554SJohn Wren Kennedy
31f38cb554SJohn Wren Kennedy. $STF_SUITE/include/libtest.shlib
32f38cb554SJohn Wren Kennedy. $STF_SUITE/tests/functional/history/history.cfg
33f38cb554SJohn Wren Kennedy
34f38cb554SJohn Wren Kennedyfunction run_and_verify
35f38cb554SJohn Wren Kennedy{
36f38cb554SJohn Wren Kennedy	typeset user pool
37f38cb554SJohn Wren Kennedy	while getopts "p:u:" opt; do
38f38cb554SJohn Wren Kennedy		case $opt in
39f38cb554SJohn Wren Kennedy		p)
40f38cb554SJohn Wren Kennedy			pool=$OPTARG
41f38cb554SJohn Wren Kennedy			;;
42f38cb554SJohn Wren Kennedy		u)
43f38cb554SJohn Wren Kennedy			user=$OPTARG
44f38cb554SJohn Wren Kennedy			;;
45f38cb554SJohn Wren Kennedy		esac
46f38cb554SJohn Wren Kennedy	done
47f38cb554SJohn Wren Kennedy	shift $(($OPTIND - 1))
48f38cb554SJohn Wren Kennedy
49f38cb554SJohn Wren Kennedy	pool=${pool:-$TESTPOOL}
50f38cb554SJohn Wren Kennedy	user=${user:-"root"}
51f38cb554SJohn Wren Kennedy	fullcmd="$1"
52f38cb554SJohn Wren Kennedy	flags="$2"
53f38cb554SJohn Wren Kennedy
54*1d32ba66SJohn Wren Kennedy	histcmd=$(echo $fullcmd | sed 's/\/usr\/sbin\///g')
55*1d32ba66SJohn Wren Kennedy	cmd=$(echo $histcmd | awk '{print $1}')
56*1d32ba66SJohn Wren Kennedy	subcmd=$(echo $histcmd | awk '{print $2}')
57f38cb554SJohn Wren Kennedy
58f38cb554SJohn Wren Kennedy	# If we aren't running zpool or zfs, something is wrong
59f38cb554SJohn Wren Kennedy	[[ $cmd == "zpool" || $cmd == "zfs" ]] || \
60f38cb554SJohn Wren Kennedy	    log_fail "run_and_verify called with \"$cmd ($fullcmd)\""
61f38cb554SJohn Wren Kennedy
62f38cb554SJohn Wren Kennedy	# If this is a 'zfs receive' truncate the stdin redirect
63f38cb554SJohn Wren Kennedy	[[ $subcmd == "receive" || $subcmd == "recv" ]] && \
64f38cb554SJohn Wren Kennedy	    histcmd=${histcmd%% <*}
65f38cb554SJohn Wren Kennedy
66f38cb554SJohn Wren Kennedy	# Run the command as the specified user, and find the new history.
67*1d32ba66SJohn Wren Kennedy	zpool history $flags $pool > $OLD_HISTORY 2>/dev/null
68f38cb554SJohn Wren Kennedy	if [[ $user == "root" ]]; then
69f38cb554SJohn Wren Kennedy		log_must eval "$fullcmd"
70f38cb554SJohn Wren Kennedy	else
71*1d32ba66SJohn Wren Kennedy		log_must su $user -c "eval $fullcmd"
72f38cb554SJohn Wren Kennedy	fi
73*1d32ba66SJohn Wren Kennedy	zpool history $flags $pool > $TMP_HISTORY 2>/dev/null
74*1d32ba66SJohn Wren Kennedy	diff $OLD_HISTORY $TMP_HISTORY | grep "^> " | sed 's/^> //g' \
75f38cb554SJohn Wren Kennedy	    > $NEW_HISTORY
76f38cb554SJohn Wren Kennedy
77f38cb554SJohn Wren Kennedy	# Verify what's common to every case, regardless of zpool history flags.
78*1d32ba66SJohn Wren Kennedy	grep "$histcmd" $NEW_HISTORY >/dev/null 2>&1 || \
79f38cb554SJohn Wren Kennedy	    log_fail "Didn't find \"$histcmd\" in pool history"
80f38cb554SJohn Wren Kennedy
81f38cb554SJohn Wren Kennedy	# If 'zpool history' was called without any flags, then we're done.
82f38cb554SJohn Wren Kennedy	[[ -z $flags ]] && return
83f38cb554SJohn Wren Kennedy
84f38cb554SJohn Wren Kennedy	# Verify the new history in cases that are more interesting because
85f38cb554SJohn Wren Kennedy	# additional information is logged with -i or -l.
86f38cb554SJohn Wren Kennedy
87f38cb554SJohn Wren Kennedy	[[ $flags =~ "i" ]] && log_must verify_$subcmd "$histcmd" "$subcmd" \
88f38cb554SJohn Wren Kennedy	    "$flags"
89f38cb554SJohn Wren Kennedy	[[ $flags =~ "l" ]] && log_must verify_long "$histcmd" "$user" "$flags"
90f38cb554SJohn Wren Kennedy}
91f38cb554SJohn Wren Kennedy
92f38cb554SJohn Wren Kennedyfunction verify_long
93f38cb554SJohn Wren Kennedy{
94f38cb554SJohn Wren Kennedy	typeset cmd=$1
95f38cb554SJohn Wren Kennedy	typeset user=$2
96f38cb554SJohn Wren Kennedy	typeset flags=$3
97f38cb554SJohn Wren Kennedy
98f38cb554SJohn Wren Kennedy	[[ $flags =~ "l" ]] || return 1
99f38cb554SJohn Wren Kennedy
100*1d32ba66SJohn Wren Kennedy	typeset uid=$(id -u $user)
101*1d32ba66SJohn Wren Kennedy	typeset hname=$(hostname)
102f38cb554SJohn Wren Kennedy	if ! is_global_zone; then
103*1d32ba66SJohn Wren Kennedy		hname=$hname:$(zonename)
104f38cb554SJohn Wren Kennedy	fi
105f38cb554SJohn Wren Kennedy
106*1d32ba66SJohn Wren Kennedy	grep "$cmd \[user $uid ($user) on $hname\]" $NEW_HISTORY >/dev/null \
107f38cb554SJohn Wren Kennedy	    2>&1
108f38cb554SJohn Wren Kennedy	if [[ $? != 0 ]]; then
109f38cb554SJohn Wren Kennedy		log_note "Couldn't find long information for \"$cmd\""
110f38cb554SJohn Wren Kennedy		return 1
111f38cb554SJohn Wren Kennedy	fi
112f38cb554SJohn Wren Kennedy
113f38cb554SJohn Wren Kennedy	return 0
114f38cb554SJohn Wren Kennedy}
115f38cb554SJohn Wren Kennedy
116f38cb554SJohn Wren Kennedyfunction verify_hold
117f38cb554SJohn Wren Kennedy{
118f38cb554SJohn Wren Kennedy	typeset cmd=$1
119f38cb554SJohn Wren Kennedy	typeset subcmd=$2
120f38cb554SJohn Wren Kennedy	typeset flags=$3
121f38cb554SJohn Wren Kennedy
122f38cb554SJohn Wren Kennedy	[[ $flags =~ "i" ]] || return 1
123f38cb554SJohn Wren Kennedy
124*1d32ba66SJohn Wren Kennedy	typeset tag=$(echo $cmd | awk '{print $4}')
125f38cb554SJohn Wren Kennedy	typeset fullname=${cmd##* }
126f38cb554SJohn Wren Kennedy	typeset dsname=${fullname%%@*}
127f38cb554SJohn Wren Kennedy	typeset snapname=${fullname##*@}
128f38cb554SJohn Wren Kennedy
129f38cb554SJohn Wren Kennedy	# This works whether or not the hold was recursive
130*1d32ba66SJohn Wren Kennedy	for ds in $(zfs list -r -Ho name -t snapshot $dsname | \
131*1d32ba66SJohn Wren Kennedy	    grep "@$snapname"); do
132*1d32ba66SJohn Wren Kennedy		grep "$subcmd $ds ([0-9]*) tag=$tag" $NEW_HISTORY \
133f38cb554SJohn Wren Kennedy		    >/dev/null 2>&1
134f38cb554SJohn Wren Kennedy		if [[ $? != 0 ]]; then
135f38cb554SJohn Wren Kennedy			log_note "Didn't find hold on $ds with $tag"
136f38cb554SJohn Wren Kennedy			return 1
137f38cb554SJohn Wren Kennedy		fi
138f38cb554SJohn Wren Kennedy	done
139f38cb554SJohn Wren Kennedy
140f38cb554SJohn Wren Kennedy	return 0
141f38cb554SJohn Wren Kennedy}
142f38cb554SJohn Wren Kennedy
143f38cb554SJohn Wren Kennedyfunction verify_release
144f38cb554SJohn Wren Kennedy{
145f38cb554SJohn Wren Kennedy	# hold and release formats only differ by the subcommand name, so
146f38cb554SJohn Wren Kennedy	# simply reuse the hold function.
147f38cb554SJohn Wren Kennedy	verify_hold "$1" "release" "$3"
148f38cb554SJohn Wren Kennedy}
149f38cb554SJohn Wren Kennedy
150f38cb554SJohn Wren Kennedyfunction verify_rollback
151f38cb554SJohn Wren Kennedy{
152f38cb554SJohn Wren Kennedy	typeset cmd=$1
153f38cb554SJohn Wren Kennedy	typeset flags=$3
154f38cb554SJohn Wren Kennedy
155f38cb554SJohn Wren Kennedy	[[ $flags =~ "i" ]] || return 1
156f38cb554SJohn Wren Kennedy
157f38cb554SJohn Wren Kennedy	typeset fullname=${cmd##* }
158f38cb554SJohn Wren Kennedy	typeset dsname=${fullname%%@*}
159f38cb554SJohn Wren Kennedy	typeset parent_fs=${dsname##*/}
160f38cb554SJohn Wren Kennedy	typeset rb_fs=${dsname}/%rollback
161f38cb554SJohn Wren Kennedy	typeset snapname=${fullname##*@}
162f38cb554SJohn Wren Kennedy
163*1d32ba66SJohn Wren Kennedy	grep "clone swap $rb_fs ([0-9]*) parent=$parent_fs" $NEW_HISTORY \
164f38cb554SJohn Wren Kennedy	    >/dev/null 2>&1
165f38cb554SJohn Wren Kennedy	if [[ $? != 0 ]]; then
166f38cb554SJohn Wren Kennedy		log_note "Didn't find rollback clone swap in pool history"
167f38cb554SJohn Wren Kennedy		return 1
168f38cb554SJohn Wren Kennedy	fi
169f38cb554SJohn Wren Kennedy
170*1d32ba66SJohn Wren Kennedy	grep "destroy $rb_fs" $NEW_HISTORY >/dev/null 2>&1
171f38cb554SJohn Wren Kennedy	if [[ $? != 0 ]]; then
172f38cb554SJohn Wren Kennedy		log_note "Didn't find rollback destroy in pool history"
173f38cb554SJohn Wren Kennedy		return 1
174f38cb554SJohn Wren Kennedy	fi
175f38cb554SJohn Wren Kennedy
176f38cb554SJohn Wren Kennedy	return 0
177f38cb554SJohn Wren Kennedy}
178f38cb554SJohn Wren Kennedy
179f38cb554SJohn Wren Kennedyfunction verify_inherit
180f38cb554SJohn Wren Kennedy{
181f38cb554SJohn Wren Kennedy	typeset cmd=$1
182f38cb554SJohn Wren Kennedy	typeset flags=$3
183f38cb554SJohn Wren Kennedy
184f38cb554SJohn Wren Kennedy	[[ $flags =~ "i" ]] || return 1
185f38cb554SJohn Wren Kennedy
186f38cb554SJohn Wren Kennedy	typeset dsname=${cmd##* }
187f38cb554SJohn Wren Kennedy	typeset prop=${cmd% *}
188f38cb554SJohn Wren Kennedy	prop=${prop##* }
189f38cb554SJohn Wren Kennedy
190f38cb554SJohn Wren Kennedy	# This works whether or not the inherit was recursive
191*1d32ba66SJohn Wren Kennedy	for ds in $(zfs list -r -Ho name -t filesystem $dsname); do
192*1d32ba66SJohn Wren Kennedy		grep "$subcmd $ds ([0-9]*) ${prop}=" $NEW_HISTORY >/dev/null \
193f38cb554SJohn Wren Kennedy		    2>&1
194f38cb554SJohn Wren Kennedy		if [[ $? != 0 ]]; then
195f38cb554SJohn Wren Kennedy			log_note "Didn't find inherit history for $ds"
196f38cb554SJohn Wren Kennedy			return 1
197f38cb554SJohn Wren Kennedy		fi
198f38cb554SJohn Wren Kennedy	done
199f38cb554SJohn Wren Kennedy
200f38cb554SJohn Wren Kennedy	return 0
201f38cb554SJohn Wren Kennedy}
202f38cb554SJohn Wren Kennedy
203f38cb554SJohn Wren Kennedyfunction verify_allow
204f38cb554SJohn Wren Kennedy{
205f38cb554SJohn Wren Kennedy	typeset cmd=$1
206f38cb554SJohn Wren Kennedy	typeset subcmd=$2
207f38cb554SJohn Wren Kennedy	typeset flags=$3
208f38cb554SJohn Wren Kennedy
209f38cb554SJohn Wren Kennedy	[[ $flags =~ "i" ]] || return 1
210f38cb554SJohn Wren Kennedy	[[ $subcmd == "allow" ]] && subcmd="update"
211f38cb554SJohn Wren Kennedy	[[ $subcmd == "unallow" ]] && subcmd="remove"
212f38cb554SJohn Wren Kennedy	typeset is_set lflag dflag dsname gname gid uname uid opt str code tmp
213f38cb554SJohn Wren Kennedy
214f38cb554SJohn Wren Kennedy	#
215f38cb554SJohn Wren Kennedy	# Here, we determine three things:
216f38cb554SJohn Wren Kennedy	# - Whether we're operating on a set or an indivdual permission (which
217f38cb554SJohn Wren Kennedy	#   dictates the case of the first character in the code)
218f38cb554SJohn Wren Kennedy	# - The name of the dataset we're operating on.
219f38cb554SJohn Wren Kennedy	# - Whether the operation applies locally or to descendent datasets (or
220f38cb554SJohn Wren Kennedy	#   both)
221f38cb554SJohn Wren Kennedy	#
222*1d32ba66SJohn Wren Kennedy	echo $cmd  | awk '{i = NF - 1; print $i}' | grep '@' >/dev/null \
223f38cb554SJohn Wren Kennedy	    2>&1 && is_set=1
224f38cb554SJohn Wren Kennedy	dsname=${cmd##* }
225f38cb554SJohn Wren Kennedy	[[ $cmd =~ "-l " ]] && lflag=1
226f38cb554SJohn Wren Kennedy	[[ $cmd =~ "-d " ]] && dflag=1
227f38cb554SJohn Wren Kennedy	if [[ -z $lflag && -z $dflag ]]; then
228f38cb554SJohn Wren Kennedy		lflag=1
229f38cb554SJohn Wren Kennedy		dflag=1
230f38cb554SJohn Wren Kennedy	fi
231f38cb554SJohn Wren Kennedy
232f38cb554SJohn Wren Kennedy	#
233f38cb554SJohn Wren Kennedy	# For each of the five cases below, the operation is essentially the
234f38cb554SJohn Wren Kennedy	# same. First, use the command passed in to determine what the code at
235f38cb554SJohn Wren Kennedy	# the end of the pool history will be. The specifics of the code are
236f38cb554SJohn Wren Kennedy	# described in a block comment at the top of dsl_deleg.c. Once that's
237f38cb554SJohn Wren Kennedy	# been assembled, check for its presence in the history, and return
238f38cb554SJohn Wren Kennedy	# success or failure accordingly.
239f38cb554SJohn Wren Kennedy	#
240f38cb554SJohn Wren Kennedy	if [[ $cmd =~ "-s " ]]; then
241f38cb554SJohn Wren Kennedy		str="s-\$@"
242f38cb554SJohn Wren Kennedy		[[ -n $is_set ]] && str="S-\$@"
243f38cb554SJohn Wren Kennedy		tmp=${cmd#*@}
244f38cb554SJohn Wren Kennedy		code="$str${tmp% *}"
245*1d32ba66SJohn Wren Kennedy		grep "permission $subcmd $dsname ([0-9]*) $code" \
246f38cb554SJohn Wren Kennedy		    $NEW_HISTORY >/dev/null 2>&1
247f38cb554SJohn Wren Kennedy		if [[ $? != 0 ]]; then
248f38cb554SJohn Wren Kennedy			 log_note "Couldn't find $code in $NEW_HISTORY"
249f38cb554SJohn Wren Kennedy			 return 1
250f38cb554SJohn Wren Kennedy		 fi
251f38cb554SJohn Wren Kennedy	elif [[ $cmd =~ "-c " ]]; then
252f38cb554SJohn Wren Kennedy		str="c-\$"
253f38cb554SJohn Wren Kennedy		[[ -n $is_set ]] && str="C-\$"
254f38cb554SJohn Wren Kennedy		tmp=${cmd#*-c}
255f38cb554SJohn Wren Kennedy		code="$str${tmp% *}"
256*1d32ba66SJohn Wren Kennedy		grep "permission $subcmd $dsname ([0-9]*) $code" \
257f38cb554SJohn Wren Kennedy		    $NEW_HISTORY >/dev/null 2>&1
258f38cb554SJohn Wren Kennedy		if [ $? != 0 ]]; then
259f38cb554SJohn Wren Kennedy			 log_note "Couldn't find $code in $NEW_HISTORY"
260f38cb554SJohn Wren Kennedy			 return 1
261f38cb554SJohn Wren Kennedy		fi
262f38cb554SJohn Wren Kennedy	elif [[ $cmd =~ "-u " ]]; then
263f38cb554SJohn Wren Kennedy		str="u"
264f38cb554SJohn Wren Kennedy		[[ -n $is_set ]] && str="U"
265f38cb554SJohn Wren Kennedy		tmp=${cmd##*-u }
266*1d32ba66SJohn Wren Kennedy		opt=$(echo $tmp | awk '{print $2}')
267*1d32ba66SJohn Wren Kennedy		uid=$(id -u ${tmp%% *})
268f38cb554SJohn Wren Kennedy		if [[ -n $lflag ]]; then
269f38cb554SJohn Wren Kennedy			code="${str}l\$$uid $opt"
270*1d32ba66SJohn Wren Kennedy			grep "permission $subcmd $dsname ([0-9]*) $code" \
271f38cb554SJohn Wren Kennedy			    $NEW_HISTORY >/dev/null 2>&1
272f38cb554SJohn Wren Kennedy			if [ $? != 0 ]]; then
273f38cb554SJohn Wren Kennedy				 log_note "Couldn't find $code in $NEW_HISTORY"
274f38cb554SJohn Wren Kennedy				 return 1
275f38cb554SJohn Wren Kennedy			fi
276f38cb554SJohn Wren Kennedy		fi
277f38cb554SJohn Wren Kennedy		if [[ -n $dflag ]]; then
278f38cb554SJohn Wren Kennedy			code="${str}d\$$uid $opt"
279*1d32ba66SJohn Wren Kennedy			grep "permission $subcmd $dsname ([0-9]*) $code" \
280f38cb554SJohn Wren Kennedy			    $NEW_HISTORY >/dev/null 2>&1
281f38cb554SJohn Wren Kennedy			if [ $? != 0 ]]; then
282f38cb554SJohn Wren Kennedy				 log_note "Couldn't find $code in $NEW_HISTORY"
283f38cb554SJohn Wren Kennedy				 return 1
284f38cb554SJohn Wren Kennedy			fi
285f38cb554SJohn Wren Kennedy		fi
286f38cb554SJohn Wren Kennedy	elif [[ $cmd =~ "-g " ]]; then
287f38cb554SJohn Wren Kennedy		str="g"
288f38cb554SJohn Wren Kennedy		[[ -n $is_set ]] && str="G"
289f38cb554SJohn Wren Kennedy		tmp=${cmd##*-g }
290*1d32ba66SJohn Wren Kennedy		opt=$(echo $tmp | awk '{print $2}')
291*1d32ba66SJohn Wren Kennedy		gid=$(awk -F: "/^${tmp%% *}:/ {print \$3}" /etc/group)
292f38cb554SJohn Wren Kennedy		if [[ -n $lflag ]]; then
293f38cb554SJohn Wren Kennedy			code="${str}l\$$gid $opt"
294*1d32ba66SJohn Wren Kennedy			grep "permission $subcmd $dsname ([0-9]*) $code" \
295f38cb554SJohn Wren Kennedy			    $NEW_HISTORY >/dev/null 2>&1
296f38cb554SJohn Wren Kennedy			if [ $? != 0 ]]; then
297f38cb554SJohn Wren Kennedy				 log_note "Couldn't find $code in $NEW_HISTORY"
298f38cb554SJohn Wren Kennedy				 return 1
299f38cb554SJohn Wren Kennedy			fi
300f38cb554SJohn Wren Kennedy		fi
301f38cb554SJohn Wren Kennedy		if [[ -n $dflag ]]; then
302f38cb554SJohn Wren Kennedy			code="${str}d\$$gid $opt"
303*1d32ba66SJohn Wren Kennedy			grep "permission $subcmd $dsname ([0-9]*) $code" \
304f38cb554SJohn Wren Kennedy			    $NEW_HISTORY >/dev/null 2>&1
305f38cb554SJohn Wren Kennedy			if [ $? != 0 ]]; then
306f38cb554SJohn Wren Kennedy				 log_note "Couldn't find $code in $NEW_HISTORY"
307f38cb554SJohn Wren Kennedy				 return 1
308f38cb554SJohn Wren Kennedy			fi
309f38cb554SJohn Wren Kennedy		fi
310f38cb554SJohn Wren Kennedy	elif [[ $cmd =~ "-e " ]]; then
311f38cb554SJohn Wren Kennedy		str="e"
312f38cb554SJohn Wren Kennedy		[[ -n $is_set ]] && str="E"
313f38cb554SJohn Wren Kennedy		opt=${cmd##*-e }
314f38cb554SJohn Wren Kennedy		opt=${opt%% *}
315f38cb554SJohn Wren Kennedy		if [[ -n $lflag ]]; then
316f38cb554SJohn Wren Kennedy			code="${str}l\$ $opt"
317*1d32ba66SJohn Wren Kennedy			grep "permission $subcmd $dsname ([0-9]*) $code" \
318f38cb554SJohn Wren Kennedy			    $NEW_HISTORY >/dev/null 2>&1
319f38cb554SJohn Wren Kennedy			if [ $? != 0 ]]; then
320f38cb554SJohn Wren Kennedy				 log_note "Couldn't find $code in $NEW_HISTORY"
321f38cb554SJohn Wren Kennedy				 return 1
322f38cb554SJohn Wren Kennedy			fi
323f38cb554SJohn Wren Kennedy		fi
324f38cb554SJohn Wren Kennedy		if [[ -n $dflag ]]; then
325f38cb554SJohn Wren Kennedy			code="${str}d\$ $opt"
326*1d32ba66SJohn Wren Kennedy			grep "permission $subcmd $dsname ([0-9]*) $code" \
327f38cb554SJohn Wren Kennedy			    $NEW_HISTORY >/dev/null 2>&1
328f38cb554SJohn Wren Kennedy			if [ $? != 0 ]]; then
329f38cb554SJohn Wren Kennedy				 log_note "Couldn't find $code in $NEW_HISTORY"
330f38cb554SJohn Wren Kennedy				 return 1
331f38cb554SJohn Wren Kennedy			fi
332f38cb554SJohn Wren Kennedy		fi
333f38cb554SJohn Wren Kennedy	else
334f38cb554SJohn Wren Kennedy		log_note "Can't parse command \"$cmd\""
335f38cb554SJohn Wren Kennedy		return 1
336f38cb554SJohn Wren Kennedy	fi
337f38cb554SJohn Wren Kennedy
338f38cb554SJohn Wren Kennedy	return 0
339f38cb554SJohn Wren Kennedy}
340f38cb554SJohn Wren Kennedy
341f38cb554SJohn Wren Kennedyfunction verify_unallow
342f38cb554SJohn Wren Kennedy{
343f38cb554SJohn Wren Kennedy	#
344f38cb554SJohn Wren Kennedy	# The unallow and allow history have the same format, except the former
345f38cb554SJohn Wren Kennedy	# logs "permission removed" and the latter "permission updated" so
346f38cb554SJohn Wren Kennedy	# simply reuse the allow function.
347f38cb554SJohn Wren Kennedy	#
348f38cb554SJohn Wren Kennedy	verify_allow "$1" "unallow" "$3"
349f38cb554SJohn Wren Kennedy}
350f38cb554SJohn Wren Kennedy
351f38cb554SJohn Wren Kennedyfunction verify_destroy
352f38cb554SJohn Wren Kennedy{
353f38cb554SJohn Wren Kennedy	typeset cmd=$1
354f38cb554SJohn Wren Kennedy	typeset flags=$3
355f38cb554SJohn Wren Kennedy
356f38cb554SJohn Wren Kennedy	# This function doesn't currently verifiy the zpool command.
357f38cb554SJohn Wren Kennedy	[[ ${cmd%% *} == "zfs" ]] || return 1
358f38cb554SJohn Wren Kennedy	[[ $flags =~ "i" ]] || return 1
359f38cb554SJohn Wren Kennedy
360f38cb554SJohn Wren Kennedy	typeset dsname=${cmd##* }
361f38cb554SJohn Wren Kennedy	[[ $dsname =~ "@" ]] && typeset is_snap=1
362f38cb554SJohn Wren Kennedy
363f38cb554SJohn Wren Kennedy	if [[ -n $is_snap ]]; then
364*1d32ba66SJohn Wren Kennedy		grep "ioctl destroy_snaps" $NEW_HISTORY >/dev/null 2>&1
365f38cb554SJohn Wren Kennedy		if [[ $? != 0 ]]; then
366f38cb554SJohn Wren Kennedy			log_note "Didn't find ioctl while destroying $dsname"
367f38cb554SJohn Wren Kennedy			return 1
368f38cb554SJohn Wren Kennedy		fi
369f38cb554SJohn Wren Kennedy	fi
370f38cb554SJohn Wren Kennedy
371f38cb554SJohn Wren Kennedy	# This should be present for datasets and snapshots alike
372*1d32ba66SJohn Wren Kennedy	grep "destroy $dsname" $NEW_HISTORY >/dev/null 2>&1
373f38cb554SJohn Wren Kennedy	if [[ $? != 0 ]]; then
374f38cb554SJohn Wren Kennedy		log_note "Didn't find \"destroy\" for $dsname"
375f38cb554SJohn Wren Kennedy		return 1
376f38cb554SJohn Wren Kennedy	fi
377f38cb554SJohn Wren Kennedy
378f38cb554SJohn Wren Kennedy	return 0
379f38cb554SJohn Wren Kennedy}
380f38cb554SJohn Wren Kennedy
381f38cb554SJohn Wren Kennedyfunction verify_snapshot
382f38cb554SJohn Wren Kennedy{
383f38cb554SJohn Wren Kennedy	typeset cmd=$1
384f38cb554SJohn Wren Kennedy	typeset flags=$3
385f38cb554SJohn Wren Kennedy
386f38cb554SJohn Wren Kennedy	[[ $flags =~ "i" ]] || return 1
387f38cb554SJohn Wren Kennedy
388f38cb554SJohn Wren Kennedy	typeset fullname=${cmd##* }
389f38cb554SJohn Wren Kennedy	typeset dsname=${fullname%%@*}
390f38cb554SJohn Wren Kennedy	typeset snapname=${fullname##*@}
391f38cb554SJohn Wren Kennedy
392*1d32ba66SJohn Wren Kennedy	grep "\[txg:[0-9]*\] $subcmd $fullname ([0-9]*)" $NEW_HISTORY \
393f38cb554SJohn Wren Kennedy	    >/dev/null 2>&1
394f38cb554SJohn Wren Kennedy	if [[ $? != 0 ]]; then
395f38cb554SJohn Wren Kennedy		log_note "Didn't find snapshot command for $fullname"
396f38cb554SJohn Wren Kennedy		return 1
397f38cb554SJohn Wren Kennedy	fi
398f38cb554SJohn Wren Kennedy
399f38cb554SJohn Wren Kennedy	# This works whether or not the snapshot was recursive
400*1d32ba66SJohn Wren Kennedy	for ds in $(zfs list -r -Ho name -t snapshot $dsname | \
401*1d32ba66SJohn Wren Kennedy	    grep "@$snapname"); do
402*1d32ba66SJohn Wren Kennedy		grep "^[ ]* $ds$" $NEW_HISTORY >/dev/null 2>&1
403f38cb554SJohn Wren Kennedy		if [[ $? != 0 ]]; then
404f38cb554SJohn Wren Kennedy			log_note "Didn't find \"ioctl snapshot\" for $ds"
405f38cb554SJohn Wren Kennedy			return 1
406f38cb554SJohn Wren Kennedy		fi
407f38cb554SJohn Wren Kennedy	done
408f38cb554SJohn Wren Kennedy
409f38cb554SJohn Wren Kennedy	return 0
410f38cb554SJohn Wren Kennedy}
411