Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add receive:append permission for limited receive #17015

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
@@ -5292,6 +5292,7 @@ zfs_do_receive(int argc, char **argv)
#define ZFS_DELEG_PERM_SHARE "share"
#define ZFS_DELEG_PERM_SEND "send"
#define ZFS_DELEG_PERM_RECEIVE "receive"
#define ZFS_DELEG_PERM_RECEIVE_APPEND "receive:append"
#define ZFS_DELEG_PERM_ALLOW "allow"
#define ZFS_DELEG_PERM_USERPROP "userprop"
#define ZFS_DELEG_PERM_VSCAN "vscan" /* ??? */
1 change: 1 addition & 0 deletions include/sys/dsl_deleg.h
Original file line number Diff line number Diff line change
@@ -46,6 +46,7 @@ extern "C" {
#define ZFS_DELEG_PERM_SHARE "share"
#define ZFS_DELEG_PERM_SEND "send"
#define ZFS_DELEG_PERM_RECEIVE "receive"
#define ZFS_DELEG_PERM_RECEIVE_APPEND "receive:append"
#define ZFS_DELEG_PERM_ALLOW "allow"
#define ZFS_DELEG_PERM_USERPROP "userprop"
#define ZFS_DELEG_PERM_VSCAN "vscan"
3 changes: 2 additions & 1 deletion man/man8/zfs-allow.8
Original file line number Diff line number Diff line change
@@ -207,14 +207,15 @@ load-key subcommand Allows loading and unloading of encryption key (see \fBzfs l
change-key subcommand Allows changing an encryption key via \fBzfs change-key\fR.
mount subcommand Allows mounting/umounting ZFS datasets
promote subcommand Must also have the \fBmount\fR and \fBpromote\fR ability in the origin file system
receive subcommand Must also have the \fBmount\fR and \fBcreate\fR ability
receive subcommand Must also have the \fBmount\fR and \fBcreate\fR ability, required for \fBzfs receive -F\fR (see also \fBreceive:append\fR for limited, non forced receive)
release subcommand Allows releasing a user hold which might destroy the snapshot
rename subcommand Must also have the \fBmount\fR and \fBcreate\fR ability in the new parent
rollback subcommand Must also have the \fBmount\fR ability
send subcommand
share subcommand Allows sharing file systems over NFS or SMB protocols
snapshot subcommand Must also have the \fBmount\fR ability

receive:append other Must also have the \fBmount\fR and \fBcreate\fR ability, limited receive ability (can not do receive -F)
groupquota other Allows accessing any \fBgroupquota@\fI…\fR property
groupobjquota other Allows accessing any \fBgroupobjquota@\fI…\fR property
groupused other Allows reading any \fBgroupused@\fI…\fR property
1 change: 1 addition & 0 deletions module/zcommon/zfs_deleg.c
Original file line number Diff line number Diff line change
@@ -52,6 +52,7 @@ const zfs_deleg_perm_tab_t zfs_deleg_perm_tab[] = {
{ZFS_DELEG_PERM_MOUNT},
{ZFS_DELEG_PERM_PROMOTE},
{ZFS_DELEG_PERM_RECEIVE},
{ZFS_DELEG_PERM_RECEIVE_APPEND},
{ZFS_DELEG_PERM_RENAME},
{ZFS_DELEG_PERM_ROLLBACK},
{ZFS_DELEG_PERM_SNAPSHOT},
13 changes: 11 additions & 2 deletions module/zfs/zfs_ioctl.c
Original file line number Diff line number Diff line change
@@ -900,9 +900,18 @@ zfs_secpolicy_recv(zfs_cmd_t *zc, nvlist_t *innvl, cred_t *cr)
(void) innvl;
int error;

/*
* zfs receive -F requires full receive permission,
* otherwise receive:append permission is enough
*/
if ((error = zfs_secpolicy_write_perms(zc->zc_name,
ZFS_DELEG_PERM_RECEIVE, cr)) != 0)
return (error);
ZFS_DELEG_PERM_RECEIVE, cr)) != 0) {
if (zc->zc_guid || nvlist_exists(innvl, "force"))
return (error);
if ((error = zfs_secpolicy_write_perms(zc->zc_name,
ZFS_DELEG_PERM_RECEIVE_APPEND, cr)) != 0)
return (error);
}

if ((error = zfs_secpolicy_write_perms(zc->zc_name,
ZFS_DELEG_PERM_MOUNT, cr)) != 0)
42 changes: 42 additions & 0 deletions tests/zfs-tests/tests/functional/delegate/delegate_common.kshlib
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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