Add receive:append permission for limited receive

Force receive (zfs receive -F) can rollback or destroy snapshots and
file systems that do not exist on the sending side (see zfs-receive man
page). This means an user having the receive permission can effectively
delete data on receiving side, even if such user does not have explicit
rollback or destroy permissions.

This patch adds the receive:append permission, which only permits
limited, non-forced receive. Behavior for users with full receive
permission is not changed in any way.

Fixes #16943
Reviewed-by: Ameer Hamza <ahamza@ixsystems.com>
Reviewed-by: Alexander Motin <mav@FreeBSD.org>
Signed-off-by: Gionatan Danti <g.danti@assyoma.it>
Closes #17015
This commit is contained in:
shodanshok
2025-03-13 18:54:14 +01:00
committed by Tony Hutter
parent 91656b4e2a
commit 52f3f92bbf
7 changed files with 62 additions and 4 deletions
@@ -256,6 +256,9 @@ function check_fs_perm
receive)
verify_fs_receive $user $perm $fs
;;
receive:append)
verify_fs_receive_append $user $perm $fs
;;
*)
common_perm $user $perm $fs
;;
@@ -425,6 +428,45 @@ function verify_fs_receive
return 0
}
function verify_fs_receive_append
{
typeset user=$1
typeset perm=$2
typeset fs=$3
typeset dtst
typeset stamp=${perm}.${user}.$RANDOM
typeset newfs=$fs/newfs.$stamp
typeset bak_user=$TEST_BASE_DIR/bak.$user.$stamp
log_must zfs create $newfs
typeset dtst="$newfs"
typeset dtstsnap=$dtst@snap.$stamp
log_must zfs snapshot $dtstsnap
log_must eval "zfs send $dtstsnap > $bak_user"
log_must_busy zfs destroy -rf $dtst
log_must zfs allow $user create,mount,canmount $fs
user_run $user eval "zfs receive -o canmount=off -F $dtst < $bak_user"
log_must zfs unallow $user create,mount,canmount $fs
if datasetexists $dtstsnap ; then
return 1
fi
log_must zfs allow $user create,mount,canmount $fs
user_run $user eval "zfs receive -o canmount=off $dtst < $bak_user"
log_must zfs unallow $user create,mount,canmount $fs
if ! datasetexists $dtstsnap ; then
return 1
fi
rm -rf $bak_user
return 0
}
function verify_userprop
{
typeset user=$1
@@ -86,7 +86,8 @@ set -A perms create true false \
clone true true \
promote true true \
xattr true false \
receive true false
receive true false \
receive:append true false
elif is_freebsd; then
# Results in Results in
@@ -126,6 +127,7 @@ set -A perms create true false \
rename true true \
promote true true \
receive true false \
receive:append true false \
destroy true true
else
@@ -160,6 +162,7 @@ set -A perms create true false \
zoned true false \
xattr true false \
receive true false \
receive:append true false \
destroy true true
if is_global_zone; then