Unix Access Control Lists

setfacl

A short primer

Want to give the www user write access to certain directories without changing ownership?

Why?

I can't chown without being root. And I want to deploy stuff as a regular user. I also don't want the www user to have write access to more than it needs to, and certainly not to the code itself!

So I use ACLs to grant access to cache dirs and log files that the web server needs to write to.

How?

Using setfacl, I do this:

setfacl -R -m u:www:write_set:fd:allow <dir>

Let's go through the parameters:

-R: apply recursively to files and subdirectories.

-m <entries>: modify the ACL. New entries will be added, and existing entries will be modified accordingly.

u:www: user:www. Can also be g for group.

write_set: Available sets are

  • full_set: all permissions
  • modify_set: all permissions except write_acl and write_owner
  • read_set: read_data, read_attributes, read_xattr and read_acl
  • write_set: write_data, append_data, write_attributes and write_xattr

fd: files and dirs will inherit the ACL, possible values are

  • f: file_inherit
  • d: dir_inherit
  • i: inherit_only
  • n: no_propagate
  • I: inherited

allow (or deny): whether to allow or deny the specified set

Caveats

The above will work on ZFS which supports NFSv4 ACLs. If you're using a traditional filesystem, you might need to use the old rwx format:

setfacl -R -m u:www:rwx <dir>

In that case, you shouldn't blindly do recursion with -R, because all the files will become executable. Do this instead:

find <dir> -type d -exec setfacl -m u:www:rwx {} \;
find <dir> -type f -exec setfacl -m u:www:rw {} \;