This chapter describes how to use delegated administration to allow nonprivileged users to perform ZFS administration tasks.
The following sections are provided in this chapter:
ZFS delegated administration enables you to distribute refined permissions to specific users, groups, or everyone. Two types of delegated permissions are supported:
Individual permissions can be explicitly delegated such as create, destroy, mount, snapshot, and so on.
Groups of permissions called permission sets can be defined. A permission set can later be updated, and all of the consumers of the set automatically get the change. Permission sets begin with the @ symbol and are limited to 64 characters in length. After the @ symbol, the remaining characters in the set name have the same restrictions as normal ZFS file system names.
ZFS delegated administration provides features similar to the RBAC security model. ZFS delegation provides the following advantages for administering ZFS storage pools and file systems:
Permissions follow the ZFS storage pool whenever a pool is migrated.
Provides dynamic inheritance where you can control how the permissions propagate through the file systems.
Can be configured so that only the creator of a file system can destroy the file system.
You can delegate permissions to specific file systems. Newly created file systems can automatically pick up permissions.
Provides simple NFS administration. For example, a user with explicit permissions can create a snapshot over NFS in the appropriate .zfs/snapshot directory.
Consider using delegated administration for distributing ZFS tasks. For information about using RBAC to manage general Oracle Solaris administration tasks, see Part III, Roles, Rights Profiles, and Privileges, in System Administration Guide: Security Services.
You control the delegated administration features by using a pool's delegation property. For example:
# zpool get delegation users NAME PROPERTY VALUE SOURCE users delegation on default # zpool set delegation=off users # zpool get delegation users NAME PROPERTY VALUE SOURCE users delegation off local |
By default, the delegation property is enabled.
You can use the zfs allow command to delegate permissions on ZFS datasets to non-root users in the following ways:
Individual permissions can be delegated to a user, group, or everyone.
Groups of individual permissions can be delegated as a permission set to a user, group, or everyone.
Permissions can be delegated either locally to the current dataset only or to all descendents of the current dataset.
The following table describes the operations that can be delegated and any dependent permissions that are required to perform the delegated operations.
Permission (Subcommand) |
Description |
Dependencies |
---|---|---|
allow |
The permission to grant permissions that you have to another user. |
Must also have the permission that is being allowed. |
clone |
The permission to clone any of the dataset's snapshots. |
Must also have the create permission and the mount permission in the original file system. |
create |
The permission to create descendent datasets. |
Must also have the mount permission. |
destroy |
The permission to destroy a dataset. |
Must also have the mount permission. |
mount |
The permission to mount and unmount a dataset, and create and destroy volume device links. | |
promote |
The permission to promote a clone to a dataset. |
Must also have the mount permission and the promote permission in the original file system. |
receive |
The permission to create descendent file systems with the zfs receive command. |
Must also have the mount permission and the create permission. |
rename |
The permission to rename a dataset. |
Must also have the create permission and the mount permission in the new parent. |
rollback |
The permission to roll back a snapshot. | |
send |
The permission to send a snapshot stream. | |
share |
The permission to share and unshare a dataset. | |
snapshot |
The permission to create a snapshot of a dataset. |
You can delegate the following set of permissions but a permission might be limited to access, read, or change permission:
groupquota
groupused
userprop
userquota
userused
In addition, you can delegate administration of the following ZFS properties to non-root users:
aclinherit
aclmode
atime
canmount
casesensitivity
checksum
compression
copies
devices
exec
mountpoint
nbmand
normalization
primarycache
quota
readonly
recordsize
refreservation
reservation
secondarycache
setuid
shareiscsi
sharenfs
sharesmb
snapdir
utf8only
version
volblocksize
volsize
vscan
xattr
zoned
Some of these properties can be set only at dataset creation time. For a description of these properties, see Introducing ZFS Properties.
zfs allow -[ldugecs] everyone|user|group[,...] perm|@setname,...] filesystem| volume |
The following zfs allow syntax (in bold) identifies to whom the permissions are delegated:
zfs allow [-uge]|user|group|everyone [,...] filesystem | volume |
Multiple entities can be specified as a comma-separated list. If no -uge options are specified, then the argument is interpreted preferentially as the keyword everyone, then as a user name, and lastly, as a group name. To specify a user or group named “everyone,” use the -u or -g option. To specify a group with the same name as a user, use the -g option. The -c option delegates create-time permissions.
The following zfs allow syntax (in bold) identifies how permissions and permission sets are specified:
zfs allow [-s] ... perm|@setname [,...] filesystem | volume |
Multiple permissions can be specified as a comma-separated list. Permission names are the same as ZFS subcommands and properties. For more information, see the preceding section.
Permissions can be aggregated into permission sets and are identified by the -s option. Permission sets can be used by other zfs allow commands for the specified file system and its descendents. Permission sets are evaluated dynamically, so changes to a set are immediately updated. Permission sets follow the same naming requirements as ZFS file systems, but the name must begin with an at sign (@) and can be no more than 64 characters in length.
The following zfs allow syntax (in bold) identifies how the permissions are delegated:
zfs allow [-ld] ... ... filesystem | volume |
The -l option indicates that the permissions are allowed for the specified dataset and not its descendents, unless the -d option is also specified. The -d option indicates that the permissions are allowed for the descendent datasets and not for this dataset, unless the -l option is also specified. If neither option is specified, then the permissions are allowed for the file system or volume and all of its descendents.
You can remove previously delegated permissions with the zfs unallow command.
For example, assume that you delegated create, destroy, mount, and snapshot permissions as follows:
# zfs allow cindys create,destroy,mount,snapshot tank/cindys # zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount,snapshot ------------------------------------------------------------- |
To remove these permissions, you would use the following syntax:
# zfs unallow cindys tank/cindys # zfs allow tank/cindys |
When you delegate create and mount permissions to an individual user, you must ensure that the user has permissions on the underlying mount point.
For example, to delegate user marks create and mount permissions on the tank file system, set the permissions first:
# chmod A+user:marks:add_subdirectory:fd:allow /tank |
Then, use the zfs allow command to delegate create, destroy, and mount permissions. For example:
# zfs allow marks create,destroy,mount tank |
Now, user marks can create his own file systems in the tank file system. For example:
# su marks marks$ zfs create tank/marks marks$ ^D # su lp $ zfs create tank/lp cannot create 'tank/lp': permission denied |
The following example shows how to set up a file system so that anyone in the staff group can create and mount file systems in the tank file system, as well as destroy their own file systems. However, staff group members cannot destroy anyone else's file systems.
# zfs allow staff create,mount tank # zfs allow -c create,destroy tank # zfs allow tank ------------------------------------------------------------- Create time permissions on (tank) create,destroy Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- # su cindys cindys% zfs create tank/cindys cindys% exit # su marks marks% zfs create tank/marks/data marks% exit cindys% zfs destroy tank/marks/data cannot destroy 'tank/mark': permission denied |
Ensure that you delegate users permission at the correct file system level. For example, user marks is delegated create, destroy, and mount permissions for the local and descendent file systems. User marks is delegated local permission to snapshot the tank file system, but he is not allowed to snapshot his own file system. So, he has not been delegated the snapshot permission at the correct file system level.
# zfs allow -l marks snapshot tank # zfs allow tank ------------------------------------------------------------- Local permissions on (tank) user marks snapshot Local+Descendent permissions on (tank) user marks create,destroy,mount ------------------------------------------------------------- # su marks marks$ zfs snapshot tank/@snap1 marks$ zfs snapshot tank/marks@snap1 cannot create snapshot 'mark/marks@snap1': permission denied |
To delegate user marks permission at the descendent file system level, use the zfs allow -d option. For example:
# zfs unallow -l marks snapshot tank # zfs allow -d marks snapshot tank # zfs allow tank ------------------------------------------------------------- Descendent permissions on (tank) user marks snapshot Local+Descendent permissions on (tank) user marks create,destroy,mount ------------------------------------------------------------- # su marks $ zfs snapshot tank@snap2 cannot create snapshot 'tank@snap2': permission denied $ zfs snapshot tank/marks@snappy |
Now, user marks can only create a snapshot below the tank file system level.
You can delegate specific permissions to users or groups. For example, the following zfs allow command delegates specific permissions to the staff group. In addition, destroy and snapshot permissions are delegated after tank file systems are created.
# zfs allow staff create,mount tank # zfs allow -c destroy,snapshot tank # zfs allow tank ------------------------------------------------------------- Create time permissions on (tank) destroy,snapshot Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- |
Because user marks is a member of the staff group, he can create file systems in tank. In addition, user marks can create a snapshot of tank/marks2 because he has specific permissions to do so. For example:
# su marks $ zfs create tank/marks2 $ zfs allow tank/marks2 ------------------------------------------------------------- Local permissions on (tank/marks2) user marks destroy,snapshot ------------------------------------------------------------- Create time permissions on (tank) destroy,snapshot Local+Descendent permissions on (tank) group staff create everyone mount ------------------------------------------------------------- |
But, user marks cannot create a snapshot in tank/marks because he doesn't have specific permissions to do so. For example:
$ zfs snapshot tank/marks2@snap1 $ zfs snapshot tank/marks@snappp cannot create snapshot 'tank/marks@snappp': permission denied |
In this example, user marks has create permission in his home directory, which means he can create snapshots. This scenario is helpful when your file system is NFS mounted.
$ cd /tank/marks2 $ ls $ cd .zfs $ ls snapshot $ cd snapshot $ ls -l total 3 drwxr-xr-x 2 marks staff 2 Dec 15 13:53 snap1 $ pwd /tank/marks2/.zfs/snapshot $ mkdir snap2 $ zfs list NAME USED AVAIL REFER MOUNTPOINT tank 264K 33.2G 33.5K /tank tank/marks 24.5K 33.2G 24.5K /tank/marks tank/marks2 46K 33.2G 24.5K /tank/marks2 tank/marks2@snap1 21.5K - 24.5K - tank/marks2@snap2 0 - 24.5K - $ ls snap1 snap2 $ rmdir snap2 $ ls snap1 |
The following example shows how to create the permission set @myset and delegates the permission set and the rename permission to the group staff for the tank file system. User cindys, a staff group member, has the permission to create a file system in tank. However, user lp doesnot have permission to create a file system in tank.
# zfs allow -s @myset create,destroy,mount,snapshot,promote,clone,readonly tank # zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot ------------------------------------------------------------- # zfs allow staff @myset,rename tank # zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot Local+Descendent permissions on (tank) group staff @myset,rename # chmod A+group:staff:add_subdirectory:fd:allow tank # su cindys cindys% zfs create tank/data Cindys% zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot Local+Descendent permissions on (tank) group staff @myset,rename ------------------------------------------------------------- cindys% ls -l /tank total 15 drwxr-xr-x 2 cindys staff 2 Aug 8 14:10 data cindys% exit # su lp $ zfs create tank/lp cannot create 'tank/lp': permission denied |
You can use the following command to display permissions:
# zfs allow dataset |
This command displays permissions that are set or allowed on the specified dataset. The output contains the following components:
Permission sets
Individual permissions or create-time permissions
Local dataset
Local and descendent datasets
Descendent datasets only
The following output indicates that user cindys has create, destroy, mount, snapshot permissions on the tank/cindys file system.
# zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount,snapshot |
The output in this example indicates the following permissions on the pool/fred and pool file systems.
For the pool/fred file system:
Two permission sets are defined:
@eng (create, destroy, snapshot, mount, clone, promote, rename)
@simple (create, mount)
Create-time permissions are set for the @eng permission set and the mountpoint property. Create-time means that after a dataset set is created, the @eng permission set and the permission to set the mountpoint property are delegated.
User tom is delegated the @eng permission set, and user joe is granted create, destroy, and mount permissions for local file systems.
User fred is delegated the @basic permission set, and share and rename permissions for the local and descendent file systems.
User barney and the staff group are delegated the @basic permission set for descendent file systems only.
For the pool file system:
The permission set @simple (create, destroy, mount) is defined.
The group staff is granted the @simple permission set on the local file system.
Here is the output for this example:
$ zfs allow pool/fred ------------------------------------------------------------------------------ Permission sets on (pool/fred) @eng create,destroy,snapshot,mount,clone,promote,rename @simple create,mount Create time permissions on (pool/fred) @eng,mountpoint Local permissions on (pool/fred) user tom @eng user joe create,destroy,mount Local+Descendent permissions on (pool/fred) user fred @basic,share,rename Descendent permissions on (pool/fred) user barney @basic group staff @basic ------------------------------------------------------------------------------ Permission sets on (pool) @simple create,destroy,mount Local permissions on (pool) group staff @simple ------------------------------------------------------------------------------ |
You can use the zfs unallow command to remove delegated permissions. For example, user cindys has create, destroy, mount, and snapshot permissions on the tank/cindys file system.
# zfs allow cindys create,destroy,mount,snapshot tank/cindys # zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount,snapshot ------------------------------------------------------------- |
The following zfs unallow syntax removes user cindys's snapshot permission from the tank/cindys file system:
# zfs unallow cindys snapshot tank/cindys # zfs allow tank/cindys ------------------------------------------------------------- Local+Descendent permissions on (tank/cindys) user cindys create,destroy,mount ------------------------------------------------------------- cindys% zfs create tank/cindys/data cindys% zfs snapshot tank/cindys@today cannot create snapshot 'tank/cindys@today': permission denied |
As another example, user marks has the following permissions on the tank/marks file system:
# zfs allow tank/marks ------------------------------------------------------------- Local+Descendent permissions on (tank/marks) user marks create,destroy,mount ------------------------------------------------------------- |
The following zfs unallow syntax removes all permissions for user marks from the tank/marks file system:
# zfs unallow marks tank/marks |
The following zfs unallow syntax removes a permission set on the tank file system.
# zfs allow tank ------------------------------------------------------------- Permission sets on (tank) @myset clone,create,destroy,mount,promote,readonly,snapshot Create time permissions on (tank) create,destroy,mount Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- # zfs unallow -s @myset tank $ zfs allow tank ------------------------------------------------------------- Create time permissions on (tank) create,destroy,mount Local+Descendent permissions on (tank) group staff create,mount ------------------------------------------------------------- |