Linux ACLs and sticky Users

Sticky and suid bits are quite helpfull tools when it comes to keeping the correct permissions throughout a set of folders and files. But what if you want to do more then just a fixed group or an execute-as user option?

Problem: get /var/www/ to be editable by a bunch of users (group:editors), without messing up the following permission schema: www-data:editors:others r-w:rwx:---.

folder: /var/www/ 
owner: www-data
group: editors 

New files will be created with permissions set to owner: creator, group: editors, when they should be:

r-x for www-data (owner)
rws for editors (group+sticky)
--- non for others

However, since new files belong to the creating user (e.g creator) www-data is out of the picture which means that apache can’t access the file unless others have r-x permissions.

Linux Permissions

Here we have our testfolder, it belongs to www-data:editors and has the suid (s) and the sticky-bit (T) set.

drwxrws--T  3 www-data editors   32 Nov 19 16:06 .
drwxr-xr-x 20 fmohr    fmohr   4,0K Nov 19 15:56 ..
-rw-r--r--  1 fmohr    editors    0 Nov 19 16:06 test01
drwxr-sr-x  2 www-data editors    6 Nov 19 16:05 test02

This however only let’s us achieve fixed group ownership. As you can see in test01, this file was created by fmohr, not www-data.


Enter ACLs, the Linux integrated Access Control List permission system.
At first sight, ACL might look a little bit frustrating, but it’s actually quite easy to use.

First we create a new folder, in this case one belonging to root:root

$ ll
total 0
drwxr-xr-x 3 root root 17 Nov 19 16:26 .
drwxr-xr-x 3 root root 16 Nov 19 16:26 ..
drwxr-xr-x 2 root root  6 Nov 19 16:26 test

Of course we can’t do anything in this folder without using sudo, so let’s change that.

$ touch test/myfile
touch: cannot touch `test/myfile': Permission denied

First, install acl or check if it’s already installed with sudo apt-get install acl

You also need to check your filesystem and mounts for acl support. EXT3+4 and XFS should have it enabled by default, others might have to be remounted. For more info on how to enable ACL, check out this blog:

To see if your kernel supports ACL, run the following command and check for your current filesystem.

$ grep _ACL /boot/config-*

Now set the user, that should from now on own the folder and all files and folders in it.

$ sudo setfacl -m d:u:www-data:r-x test/		 # set for parent-dir
$ sudo setfacl -m u:www-data:r-x test			# set for *
$ ls -ld test/
drwxr-xr-x+ 2 root root 6 Nov 19 16:26 test/

As you can might have noticed the owner and group haven’t changed, but if you look a bit closer you can see the + sign behind the last execution bit x. This indicates, that ACL rules are already in place and working.

We can’t create files yet since we are neither www-data nor root. Even if we where www-data, we would only have read and execute permissions.

To fix that, we need to set the group permissions.

$ sudo setfacl -m d:g:editors:rwx test/
$ sudo setfacl -m g:editors:rwx test/
$ ll
total 4,0K
drwxr-xr-x  3 root root 17 Nov 19 16:26 .
drwxr-xr-x  3 root root 16 Nov 19 16:26 ..
drwxrwxr-x+ 2 root root 17 Nov 19 17:03 test
$ touch test/filetest
$ ll test/filetest
-rw-rw-r--+ 1 fmohr CM_T_OPS_Team 0 Nov 19 17:07 test/filetes

The folder still displays root:root, but we can see the current ACL permissions by running getfacl.

$ ll test/
drwxrwxr-x+ 2 root  root          21 Nov 19 17:10 .

$ getfacl test/
# file: test/
# owner: root
# group: root

The new file automatically inherited the primary group and user of its creator, which is not what we want. The ACL rules tell us something different.

$ ll test/
-rw-rw-r--+ 1 fmohr fmohr  0 Nov 19 17:07 filetest

$ getfacl test/filetest
# file: test/filetest
# owner: fmohr
# group: fmohr
user:www-data:r-x               #effective:r--
user:fmohr:rwx                  #effective:rw-
group::r-x                      #effective:r--
group:editors:rwx  			 #effective:rw-

They show us, which owner and group are set by the linux permission system but also which users and groups are granted access by the ACL rules.

To expand on that a little bit:

$ getfacl test/filetest
# file: test/filetest
# owner: fmohr
# group: fmohr
user::rw-			# owner: fmohr 	(from default linux permissions)
user:www-data:r-x	# www-data 		(from ACL rule)
user:fmohr:rwx   	# fmohr			(from ACL rule)
group::r-x       	# group: fmohr	(from default linux permissions)
group:editors:rwx	# editors		(from ACL rule)
mask::rw-			# maximum permissions for any users (automatic ACL)
other::r--			# other			(from default linux permissions)

As a good example, I will change the owner of filetest to root:root and set permissions to 000, which would mean no one can access the file.

$ sudo chown root:root filetest
$ sudo chmod 000 filetest
$ ll
----------+ 1 root root  0 Nov 19 17:07 filetest
$ cat filetest
cat: filetest: Permission denied

As you can see, as user fmohr I can’t access the file. This is due to mask being changed by the chmod command as well.

$ getfacl filetest
# file: filetest
# owner: root
# group: root
user:www-data:r-x               #effective:---
user:fmohr:rwx                  #effective:---
group::r-x                      #effective:---
group:application_treetool:rwx  #effective:---

If we were to set mask back to the maximum permission ACL is allowed to grant, we would get access to the file by our ACL rules.

$ sudo setfacl -m mask:rwx filetest
$ echo "test" > filetest
$ cat filetest

As a final note, ACLs are inherited onto new files but won’t be applied to existing files automatically. This means, that you have to manually apply them to your existing files and folders. After that, you’re set to work with a detailed permission system, featuring permissions for multiple groups and users regardless of the original owner of the files.

Thanks to Daniel Lawson over at serverfault for a great answer!