ZFS ACLs

ACLs


The ZFS file system uses a pure ACL model, that is compliant with the NFSv4 ACL model.  What is meant by pure ACL model, is that every file always has an ACL, unlike file systems such as UFS that have either an ACL or it has permission bits.  All access control decisions are governed by a file's ACL.  All file's still have permission bits, but they are constructed by analyzing a file's ACL.
NFSv4 ACL Overview
The ACL model in NFSv4 is similar to the Windows ACL model.  The NFSv4 ACL model supports a rich set of access permissions and inheritance controls.  An ACL in this model is composed of an array of access control entries (ACE).  Each ACE specifies the permissions, access type, inheritance flags and to whom the entry applies.  In the NFSv4 model the "who" argument of each ACE, may be either a username or groupname.  There are also a set of commonly know names, such as "owner@", "group@", "everyone@".  These abstractions are used by UNIX variant operating systems to indicate if the ACE is for the file owner, file group owner or for the world.  The everyone@ entry is not equivalent to the POSIX "other" class, it really is everyone.  The complete description of the NFSv4 ACL model is availabe in Section 5.11 of the NFSv4 protocol specification.
NFSv4 Access Permissions

Permission
Description
read_data
Permission to read the data of the file
list_data
Permission to list the contents of a directory
write_data
Permission to modify the file's data anywhere in the file's offset range.  This includes the ability to grow the file or write to an arbitrary offset.
add_file
Permission to add a new file to a directory
append_data
The ability to modify the data, but only starting at EOF.
add_subdirectory
Permission to create a subdirectory to a directory
read_xattr
The ability to read the extended attributes of a file or to do a lookup in the extended attributes directory.
write_xattr
The ability to create extended attributes or write to the extended attributes directory.
execute
Permission to execute a file
delete_child
Permission to delete a file within a directory
read_attributes
The ability to read basic attributes (non-ACLs) of a file.  Basic attributes are considered the stat(2) level attributes.
write_attributes
Permission to change the times associated with a file or directory to an arbitrary value
delete
Permission to delete a file
read_acl
Permission to read the ACL
write_acl
Permission to write a file's ACL
write_owner
Permission to change the owner or the ability to execute chown(1) or chgrp(1)
synchronize
Permission to access a file locally at the server with synchronous reads and writes.

NFSv4 Inheritance flags
Inheritance Flag
Description
file_inherit
Can be place on a directory and indicates that this ACE should be added to each new non-directory file created.
dir_inherit
Can be placed on a directory and indicates that this ACE should be added to each new directory created.
inherit_only
Placed on a directory, but does not apply to the directory itself, only to newly created files and directories.  This flag requires file_inherit and or dir_inherit to indicate what to inherit.
no_propagate
Placed on directories and indicates that ACL entries should only be inherited to one level of the tree.  This flag requires file_inherit and or dir_inherit to indicate what to inherit.
   
NFSv4 ACLs vs POSIX
The difficult part of using the NFSv4 ACL model was trying to still preserve POSIX compliance in the file system.  POSIX allows for what it calls "additonal" and "alternate" access methods.  An additional access method is defined to be layered upon the file permission bits, but they can only further restrict the standard access control mechanism.  The alternate file access control mechanism is defined to be independent of the file permission bits and which if enabled on a file may either restrict or extend the permissions of a given user.  Another major distinction between the additional and alternate access control mechanisms is that, any alternate file access control mechanism must be disabled after the file permission bits are changed with a chmod(2).  Additional mechanisms do not need to be disabled when a chmod is done.  

Most vendors that have implemented NFSv4 ACLs have taken the approach of "discarding" ACLs during a chmod(2).  This is a bit heavy handed, since a user went through the trouble of crafting a bunch of ACLs, only to have chmod(2) come through and destroy all of their hard work.  It was this single issue that was the biggest hurdle to POSIX compliance with ZFS in implementing NFSv4 ACLs.  In order to achieve this SamLisa and I spent far too long trying to come up with a model that would preserve as much of the original ACL, while still being useful.   What we came up with is a model that retains additional access methods, and disabled, but doesn't delete alternate access controls.  Sam and Lisa have filed an internet draft which has the details about the chmod(2) algorithm and how to make NFSv4 ACLs POSIX complient.

So whats cool about this
Lets assume we have the following directory /sandbox/test.dir.
Its initial ACL looks like:

    % ls -dv test.dir
    drwxr-xr-x   2 ongk     bin            2 Nov 15 14:11 test.dir
         0:owner@::deny
         1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
             /append_data/write_xattr/execute/write_attributes/write_acl
             /write_owner:allow
         2:group@:add_file/write_data/add_subdirectory/append_data:deny
         3:group@:list_directory/read_data/execute:allow
         4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
             /write_attributes/write_acl/write_owner:deny
         5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
             /read_acl/synchronize:allow



Now if I want to give "marks" the ability to create files, but not subdirectories in this
directory then the following ACL would achieve this.

    First lets make sure "marks" can't currently create files/directories

    $ mkdir /sandbox/bucket/test.dir/dir.1
    mkdir: Failed to make directory "/sandbox/test.dir/dir.1"; Permission denied


    $ touch /sandbox/test.dir/file.1
    touch: /sandbox/test.dir/file.1 cannot create


    Now lets give marks add_file permission

    % chmod A+user:marks:add_file:allow /sandbox/test.di
    % ls -dv test.dir

    drwxr-xr-x+  2 ongk     bin            2 Nov 15 14:11 test.dir
         0:user:marks:add_file/write_data:allow
         1:owner@::deny
         2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
             /append_data/write_xattr/execute/write_attributes/write_acl
             /write_owner:allow
         3:group@:add_file/write_data/add_subdirectory/append_data:deny
         4:group@:list_directory/read_data/execute:allow
         5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
             /write_attributes/write_acl/write_owner:deny
         6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
             /read_acl/synchronize:allow


    Now lets see if it works for user "marks"

    $ id
    uid=76928(marks) gid=10(staff)

    $ touch file.1
    $ ls -v file.1
    -rw-r--r--   1 marks    staff          0 Nov 15 10:12 file.1
         0:owner@:execute:deny
         1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
             /write_acl/write_owner:allow
         2:group@:write_data/append_data/execute:deny
         3:group@:read_data:allow
         4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
             /write_acl/write_owner:deny
         5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
             :allow


    Now lets make sure "marks" can't create directories.

    $ mkdir dir.1
     mkdir: Failed to make directory "dir.1"; Permission denied

The write_owner permission is handled in a special way.  It allows for a user to "take" ownership of a file.  The following example will help illustrate this.  With the write_owner a user can only do a chown(2) to himself or to a group that he is a member of.

    We will start out with the following file.

    ls -v file.test
    -rw-r--r--   1 ongk     staff          0 Nov 15 14:22 file.test
         0:owner@:execute:deny
         1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
             /write_acl/write_owner:allow
         2:group@:write_data/append_data/execute:deny
         3:group@:read_data:allow
         4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
             /write_acl/write_owner:deny
         5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
             :allow


    Now if user "marks" tries to chown(2) the file to himself he will get an error.

     $ chown marks file.test
     chown: file.test: Not owner

     $ chgrp staff file.test
     chgrp: file.test: Not owner


     Now lets give "marks" explicit write_owner permission.

     % chmod A+user:marks:write_owner:allow file.test
     % ls -v file.test

     -rw-r--r--+  1 ongk     staff          0 Nov 15 14:22 file.test
          0:user:marks:write_owner:allow
          1:owner@:execute:deny
          2:owner@:read_data/write_data/append_data/write_xattr/write_attributes
              /write_acl/write_owner:allow
          3:group@:write_data/append_data/execute:deny
          4:group@:read_data:allow
          5:everyone@:write_data/append_data/write_xattr/execute/write_attributes
              /write_acl/write_owner:deny
          6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
              :allow

    Now lets see who "marks" can chown the file to.
   
    $ id
    uid=76928(marks) gid=10(staff)
    $ groups
    staff storage
    $ chown bin file.test
    chown: file.test: Not owner


    So "marks" can't give the file away.

    $ chown marks:staff file.test
   
Now lets look at an example to show how a user can be granted special delete permissions.  ZFS doesn't create any delete permissions when a file is created, instead it uses write_data/execute for permission to write to a directory and execute to search the directory.

    Lets first create a read-only directory and then give "marks" the ability to delete files.

    % ls -dv test.dir
    dr-xr-xr-x   2 ongk     bin            2 Nov 15 14:11 test.dir
         0:owner@:add_file/write_data/add_subdirectory/append_data:deny
         1:owner@:list_directory/read_data/write_xattr/execute/write_attributes
             /write_acl/write_owner:allow
         2:group@:add_file/write_data/add_subdirectory/append_data:deny
         3:group@:list_directory/read_data/execute:allow
         4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
             /write_attributes/write_acl/write_owner:deny
         5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
             /read_acl/synchronize:allow


    Now the directory has the following files:

    ls -l
    total 3
    -r--r--r--   1 ongk     bin            0 Nov 15 14:28 file.1
    -r--r--r--   1 ongk     bin            0 Nov 15 14:28 file.2
    -r--r--r--   1 ongk     bin            0 Nov 15 14:28 file.3


    Now lets see if "marks" can delete any of the files?

    $  rm file.1
    rm: file.1: override protection 444 (yes/no)? y
    rm: file.1 not removed: Permission denied

    Now lets give "marks" delete permission on just file.1

    chmod A+user:marks:delete:allow file.1
    ls -v file.1
    -r--r--r--+  1 ongk     bin            0 Nov 15 14:28 file.1
         0:user:marks:delete:allow
         1:owner@:write_data/append_data/execute:deny
         2:owner@:read_data/write_xattr/write_attributes/write_acl/write_owner
             :allow
         3:group@:write_data/append_data/execute:deny
         4:group@:read_data:allow
         5:everyone@:write_data/append_data/write_xattr/execute/write_attributes
             /write_acl/write_owner:deny
         6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
             :allow


    $ rm file.1
    rm: file.1: override protection 444 (yes/no)? y


Lets see what a chmod(1) that changes the mode would do to a file with a ZFS ACL.
We will start out with the following ACL which gives user bin read_data and write_data permission.

    ls -v file.1
    -rw-r--r--+  1 marks    staff          0 Nov 15 10:12 file.1
         0:user:bin:read_data/write_data:allow
         1:owner@:execute:deny
         2:owner@:read_data/write_data/append_data/write_xattr/write_attributes
             /write_acl/write_owner:allow
         3:group@:write_data/append_data/execute:deny
         4:group@:read_data:allow
         5:everyone@:write_data/append_data/write_xattr/execute/write_attributes
             /write_acl/write_owner:deny
         6:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
             :allow


   
chmod 640 file.1
    $ ls -v file.1
    -rw-r-----+  1 marks    staff          0 Nov 15 10:12 file.1
         0:user:bin:write_data:deny
         1:user:bin:read_data/write_data:allow
         2:owner@:execute:deny
         3:owner@:read_data/write_data/append_data/write_xattr/write_attributes
             /write_acl/write_owner:allow
         4:group@:write_data/append_data/execute:deny
         5:group@:read_data:allow
         6:everyone@:read_data/write_data/append_data/write_xattr/execute
             /write_attributes/write_acl/write_owner:deny
         7:everyone@:read_xattr/read_attributes/read_acl/synchronize:allow


    In this example ZFS has prepended a deny ACE to take away write_data permission.  This
    is an example of disabling "alternate" access methods.  More details about
    how ACEs are disabled are described in internet draft.
 
The ZFS admin guide and the chmod(1) manpages have many more examples of setting ACLs and how the inheritance model works.

With the ZFS ACL model access control is no longer limited to the simple "rwx" model that UNIX has used since its inception.


   
Comments:

Thank you for a very nice worked example. I'll be teaching NFS v4 ACLs soon, and \*was\* full of fear....

Posted by kidari on October 05, 2006 at 07:37 PM MDT #

Nice article and examples.. I have a doubt reg. write_acl. NFSv4ACLs introduces multiple access masks like ACE4_WRITE_NAMED_ATTRS & ACE4_WRITE_ATTRIBUTES. Do they play a role in granting ACE4_WRITE_ACL? What other permission needs to checked before granted a user write_acl access? Thanks!

Posted by Suresh on November 14, 2006 at 06:25 PM MST #

During a restore of a zone in a zfs filesystem ACL's were added from the zone directory down. I have tried to use chmod to remove the ACL's but can't. There is a duplicate system that I am trying to use as a model for permissions. It looks like this: drwxr-xr-x 12 root root 1024 Dec 22 10:01 dev 0:user::rwx 1:group::r-x #effective:r-x 2:mask:r-x 3:other:r-x Below is the server with the problem. drwxr-xr-x 12 root root 54 Jan 3 15:49 dev 0:owner@::deny 1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory /append_data/write_xattr/execute/write_attributes/write_acl /write_owner:allow 2:group@:add_file/write_data/add_subdirectory/append_data:deny 3:group@:list_directory/read_data/execute:allow 4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr /write_attributes/write_acl/write_owner:deny 5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes /read_acl/synchronize:allow How can I fix this?

Posted by Linda Walton on January 24, 2007 at 07:29 AM MST #

I wanted to change the permissons on a ZFS folder so that any files created in this folder will have an effective permisson of 600 - ie only the owner can read or write. I could do this on a non zfs file system using the command

# setfacl -s u::rwx,g::r--,o:---,d:u::rw-,d:g::r--,d:o:---,d:m:--- directory_name

I am having a tough time to come up with the equivalent chmod command on a ZFS file system.

Can you take a stab at this ?

Posted by Dominic Kailath on January 12, 2011 at 03:40 AM MST #

Post a Comment:
  • HTML Syntax: NOT allowed
About

marks

Search

Categories
Archives
« April 2014
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today
Bookmarks
Feeds