While setting up a couple of things on the new monotone server, which is bascially a FreeBSD jail on a physical server kindly provided by Lapo Luchini, I stumbled upon a quite basic use case: I needed to give one user group read and write access to files created and modified by another group.
On a Linux system I’d have simply enabled POSIX ACLs for the volume and call
$ setfacl -m d:user:foo:rwx /path/to/directory $ setfacl -m d:user:bar:rwx /path/to/directory
and voila, all new files and directories underknees the path would have received the default ACLs with read and write rights for the
It turns out that on FreeBSD, which gained zfs ACL support in its 8.1 release recently, the call is quite similar – just that
NFSv4 ACLs are used instead of
POSIX ACLs, which are a bit more powerful (read more on the topic here):
$ setfacl -m user:foo:rwxp:fd:allow /path/to/directory $ setfacl -m user:bar:rwxp:fd:allow /path/to/directory
default which is used in the
fd is used, which stands for
directory_inherit and is exactly what we need. And while
POSIX ACLs are add-only, you can either specify
:deny to also explicitely deny access to a user or usergroup. Finally, you might have seen the little
p which stands for the
append_data right. This was needed for me in one case, so I added it here. It is actually one of many more rights beside the well-known
NFSv4 ACLs defines here – if you’re curious, just read more on the aforementioned link.
“So if everything works, what is the point of this blog?” you might ask. Well, unfortunately it did not all work out so nicely. One thing caused me some headaches which is actually dubbed a feature of FreeBSDs NFSv4 ACL implementation – namely that the
umask (the create mask for new files) is taken into account on file creation, which leads to an unwanted recalculation of the default (inherited) ACLs. So if you have a file foo created by user
u1 and the ACLs should also give write access to user
u2, then you might end up with something like this:
$ getfacl foo # file: foo # owner: u1 # group: users user:u1:--x-----------:------:deny user:u1:rwxp----------:------:allow user:u2:rwxp----------:------:deny user:u2:rwxp----------:------:allow owner@:--x-----------:------:deny owner@:rw-p---A-W-Co-:------:allow group@:rwxp----------:------:deny group@:--------------:------:allow everyone@:rwxp---A-W-Co-:------:deny everyone@:------a-R-c--s:------:allow
The file was created with
rw- --- --- (i.e. umask 077) which lead to a :deny rule for user
u2 and since deny rules take precendence over allow rules,
u2 gets no access to
foo. I contacted the author of FreeBSD’s NFSv4 ACL implementation, Edward Tomasz Napierała, and thankfully he drawed a way out of the mess:
Your problem is umask. When you create a file, ACL entries are inherited, and then the new ACL is modified according to some (pretty complicated) rules. You probably want to disable that, so that entries are simply inherited, without further messing and adding deny entries. To do this, set aclmode=passthrough and aclinherit=passthrough ZFS properties.
The only downside to this approach is that you cannot change these settings inside the jail, but only from the outside. Luckily, the host part is also under our control, so Lapo remounted the jail volume with the new settings, and voilá, the ACLs now work as expected.
You can learn something new every day.