Using POSIX ACLs to complement traditional Linux permissions

Anyone who has been using Linux in a multi-user environment has been confronted to the limits of the traditional 12-bit based UNIX permission system.

For instance, you are likely to get into trouble if you have a repository (e.g. a folder containing a website) that may be modified by a set of users. Indeed, if a user (bob) has a restrictive mask (077 for instance), here is what might happen :

bob@samlaptop:/tmp $ ls -ld repository
drwxr-xr-x 2 bob repository 4096 2006-01-14 17:46 repository
bob@samlaptop:/tmp $ umask 077
bob@samlaptop:/tmp $ cd repository/
bob@samlaptop:/tmp/repository $ mkdir folder
bob@samlaptop:/tmp/repository $ ls -ld folder/
drwx—— 2 bob repository 4096 2006-01-14 17:46 folder/

As a result, the folder created by bob is not accessible by other members of the repository group. However, it is not possible nor desirable to force a set of users to keep a non-restrictive mask. Additionally, several repositories on the system might have different policies.

This is where ACLs come in. ACLS, or Access Control Lists are a new set of permissions that recent UNIXes such as Linux now support. (Windows has been supporting ACLs for quite a long time). It is now possible to define fine-grained permissions and forget the numerous hacks that everybody has been imaginating in order to survive with the current system.
This post is not a step-by-step HOWTO that explains how ACLs work under Linux, since it has already been covered by alo’s blog, or Andreas Gr├╝nbacher white paper and HOWTO. In fact, this article is only a simple introduction that shows how easy it can be to use ACLs, and was written in the hope that ugo+rwx addicts take some time to change their habits.

First of all, you need a decent distribution, such as Ubuntu Linux, that ships an ACL-enabled kernel. Most filesystems (ext3, reiserfs, …) now support ACLs, so these guidelines should work no matter which filesystem you choose. The only requirement is to mount your filesystems with the “acl” option. For instance, your /etc/fstab should look like :

/dev/hdb1 /home reiserfs defaults,acl 0 0

Once this is enabled, you can start playing with acls. One of the most interesting aspects, often under-documented, is the “default” ACL.

To introduce this concept, let’s consider that our repository should be accessible by both the samokk user and by Apache’s user www-data. Any HOWTO about ACLs will tell you that you should use the getfacl command to query the current ACLs of a filesystem object (directory / file).

samokk@bluerock:/tmp$ getfacl repository/
# file: repository
# owner: samokk
# group: samokk
user::rwx
group::r-x
other::r-x

samokk@bluerock:/tmp$ ls -ld repository/
drwxr-xr-x 2 samokk samokk 4096 2006-01-14 09:19 repository/

getfacl reports the same information as ls -l. This means that there are currently no ACLs defined, besides the traditional ugo+rwx permissions.

We want the repository to be unreadable by others, but accessible by Apache :

samokk@bluerock:/tmp$ chmod 750 repository/
samokk@bluerock:/tmp$ setfacl -m “g:www-data:rwx” repository/
samokk@bluerock:/tmp$ getfacl repository/
# file: repository
# owner: samokk
# group: samokk
user::rwx
group::r-x
group:www-data:rwx
mask::rwx
other::—

The setfacl command has been used to add ACLs to the repository object, in order to allow the www-data group (see the g: keyword) to r, w and x on the directory. getfacl’s output reflects this.

However, we still haven’t solved the mask problem we cited above. Allowing www-data to access the repository does not mean www-data will be given permission to access files that will be created in the future. Default ACLs are there to solve this issue. Default ACLs are inherited from the parent directory and can only be applied to directories (it is not possible to create files inside files…).

samokk@bluerock:/tmp$ setfacl -d -m “g:www-data:rwx” repository/
samokk@bluerock:/tmp$ umask 700
samokk@bluerock:/tmp$ >repository/file
samokk@bluerock:/tmp$ getfacl repository/
# file: repository
# owner: samokk
# group: samokk
user::rwx
group::r-x
group:www-data:rwx
mask::rwx
other::—
default:user::rwx
default:group::r-x
default:group:www-data:rwx
default:mask::rwx
default:other::—
samokk@bluerock:/tmp$ getfacl repository/file
# file: repository/file
# owner: samokk
# group: samokk
user::rw-
group::r-x #effective:r–
group:www-data:rwx #effective:rw-
mask::rw-
other::—

Wha we have just done is simple : the repository has been given a default ACLs that will be inherited by directories and that will be used to set the permission of files created inside it. An example repository/file has been created to show that the files actually inherit the permissions.

This is it ! ACLs are actually quite simple to use, so do not hesitate to ease your life !

One Response to “Using POSIX ACLs to complement traditional Linux permissions”

  1. [...] The problem with traditional permissions is that there is no decent way of specifying default permissions. So, we are going to use ACLs for that. You can find more information about them here (Using POSIX ACLs to complement traditional Linux permissions). So, this gives, for instance : # read write execute access for web user to the stats directories find /srv/data/stats -type d -exec setfacl -m “g:www-data:rwx” {} ; [...]

Leave a Reply