ZFS now supports the ability to delegate zfs(1M) administrative tasks to ordinary users.
Two styles of delegated permissions are supported. First the individual permission(s) can be explicitly specified, or the administrator can define a permission set. A permission set can then later be updated and all of the consumers of the set will automatically pick up the change. Permission sets all begin with the letter @ and are limited to 64 characters in length. Characters after the @ sign in a set name have the same restrictions as normal ZFS file system names.
Granting permissions
Permissions are delegated with the allow
subcommand to ZFS(1M).zfs allow [-l] [-d] <"everyone"|user|group>[,<"everyone" |user|group>] \
<perm>|@<setname>[,<perm>|@<setname>...] <filesystem|volume>
zfs allow [-l] [-d] -u <user> <perm>|@<setname>[,<perm>|@<setname>...] <filesystem|volume>
zfs allow [-l] [-d] -g <group> <perm>|@<setname>[,<perm>|@<setname>...] <filesystem|volume>
zfs allow [-l] [-d] -e <perm>|@<setname>[,<perm>|@<setname>...]<filesystem|volume>
zfs allow -c <perm>|@<setname>[,<perm>|@<setname>...] <filesystem|volume>
zfs allow -s @setname <perm>|@<setname>[,<perm>...] <filesystem|volume>
If no flags are used, the permission(s) will be allowed for the specified
dataset and all of its descendents.
-l "Local" means that the permission is allowed for the
specified dataset, and not its descendents (unless -d is also
specified).
-d "Descendents" means that the permission is allowed for
descendent datasets, and not for this dataset (unless -l is also
specified).
-c "Create" means that the permission will be granted (Locally) to the
creator on any newly-created descendent file systems.
-s "Permission set" means that the listed permission(s) will act as a
set. Changing the permissions in a set will immediately change
what is allowed wherever the set is used.
Permissions
The actual permissions are pretty much self explanatory, but here is the list and what they allow you to do.
| create | create descendent datasets. (Must also have 'mount' permission) |
| destroy | destroy dataset |
| snapshot | take snapshots. (Must also have 'mount' permission) |
| rollback |
rollback dataset. (Must also have mount) |
| clone | create clone of any of the dataset's snaps. (must also have 'create' permission in clone's parent) |
| promote | promote dataset. (must also have 'promote' permission in origin fs) |
| rename | rename a dataset. (must also have 'create' and 'mount' permission in new parent) |
| mount | mount and unmount the dataset |
| share | share and unshare this dataset |
| send | send any of the dataset's snapshots |
| receive | create a descendent with zfs receive. (must also have 'create' permission) |
| allow | Allows users to grant permissions they have to another user. |
| quota | modify quotas |
| reservation | set reservations |
| volsize | set volsize property |
| recordsize | set recordsize property |
| mountpoint | set mountpoint property |
| sharenfs | set sharenfs property |
| checksum | set checksum property |
| compression | set compressions property |
| atime | set atime property |
| devices | set devices property |
| exec | set exec property |
| setuid | set setuid property |
| readonly | set readonly property |
| snapdir | set snapdir property |
| aclmode | set aclmode property |
| aclinherit | set aclinherit property |
| copies | set copies property |
| canmount | set canmount property |
| xattr | set xattr property |
| userprop | allow user properties to be modified |
| shareiscsi | set shareiscsi property |
Permission Revoking
For removing permissions the unallow zfs(1M) subcommand is used.
zfs unallow [-r] [-l] [-d] <"everyone"|user|group>[,<"everyone"|user|group>...] \
[<perm>|@<setname>[,<perm>|@<setname>...]] <filesystem|volume>
zfs unallow [-r][-l][-d] -u user [<perm>|@<setname>[,<perm>|@<setname>...]] <filesystem|volume>
zfs unallow [-r][-l][-d] -g group [<perm>|@<setname>[,<perm>|@<setname>...]] <filesystem|volume>
zfs unallow [-r][-l][-d] -e [<perm>|@<setname>[,<perm>|@<setname>...]] <filesystem|volume>
zfs unallow [-r] -c <perm>|@<setname>[,<perm>|@<setname>...] <filesystem|volume>
zfs unallow [-r] -s @<setname> [<perm>|@<setname>[,<perm>|@<setname>...]] <filesystem|volume>
Displaying Permissions
$ zfs allow <filesystem|volume>
Examples
First lets create just a simple setup where anybody in group "staff" can
create and mount file systems anywhere in the pool.
# zpool create sandbox c0t1d0
The individual users still need permission to create the mountpoints, so
lets just create a sticky directory.
# chmod 1777 /sandbox
# zfs allow staff create,mount sandbox
$ zfs allow sandbox
-------------------------------------------------------------
Local+Descendent permissions on (sandbox)
group staff create,mount
-------------------------------------------------------------
marks$ zfs create sandbox/marks
user "marks" can't destroy this file system, since we didn't hand out destroy permission.
$ zfs destroy sandbox/marks
cannot destroy 'sandbox/marks': permission denied
Permission set example:
Permission sets need to be defined before they can be used.
# zfs allow -s @set1 create,mount,snapshot,clone,promote sandbox
Now lets assign this to the previosly created sandbox/marks file system.
# zfs allow marks @set1 sandbox/marks
# zfs allow sandbox/marks
-------------------------------------------------------------
Local+Descendent permissions on (sandbox/marks)
user marks @set1
-------------------------------------------------------------
Permission sets on (sandbox)
@set1 clone,create,mount,promote,snapshot
Local+Descendent permissions on (sandbox)
group staff create,mount
-------------------------------------------------------------
Now lets see if "marks" can take a snpshot
marks$ zfs snapshot sandbox/marks@snap1
Lets make sure nobody else can.
tester$ zfs snapshot sandbox/marks@snap2
cannot create snapshot 'sandbox/marks@snap2': permission denied