What are access control lists (ACLs)?

In a nutshell, access control lists (ACLs) allow you to assign permissions to many different users and groups on individual files or directories.

WARNING
Not all Linux distributions have ACLs enable by default. However simply installing the acl package from your software repository will enable this functionality

In this post we will take a look at recognising ACLs, then we'll see how to utilise them.

In the following example, both the file owner and another user alex can still read this file. Why?

[martin@church1e]$ chmod 770 myfile
[martin@church1e]$ ls -l myfile
-rwx-rwx---+ 1 martin martin 0 Nov 15 07:38 myfile

Note that there is extra character (a + sign) at the end of the permissions field. This indicates that beside the standard Linux permissions, there is also an ACL active on the file.

If we use the stat command, we see that it is unaware of any ACL associated with the file:

[martin@church1e]$ stat myfile
  File: myfile
  Size: 0               Blocks: 0          IO Block: 4096   regular empty file
Device: 8,3     Inode: 2760390     Links: 1
Access: (0770/-rwxrwx---)  Uid: ( 1000/  martin)   Gid: ( 1000/  martin)
Access: 2015-11-05 07:38:49.538153926 +0000
Modify: 2015-11-05 07:38:49.538153926 +0000
Change: 2015-11-05 07:38:54.782247580 +0000
 Birth: 2015-11-05 07:38:49.538153926 +0000

However, using the getfacl command we can display the ACL information.

[martin@church1e]$ getfacl myfile
# file: myfile
# owner: martin
# group: martin
user::rwx
user:alex:r-x
group::rwx
group:testers:r-x
mask::rwx
other::---

In the above output, we see that both user alex and members of the testers group can read and execute the file.

The setfacl cmmand allows us to set ACLs on files and directories. In the following example, we will give read/write/execute (rwx) to user rosie:

[martin@church1e]$ echo test > testfile
[martin@church1e]$ ls -l testfile
-rw-r----- 1 martin martin 5 Nov  5 08:11 testfile
[martin@church1e]$ setfacl -m u:rosie:7 testfile
[martin@church1e]$ getfacl testfile | grep rosie
user:rosie:rwx

The -m option allows you to modify an ACL, which means existing entries will remain. Even if we do a chmod 770 testfile, user rosie will still have access to the file, as we see in this example:

[martin@church1e]$ chmod 770 testfile
[martin@church1e]$ su - rosie
Password:
[rosie@church1e]$ cat ~martin/testfile
test

We can also set all rwx permissions and ACL entries in one command by using the setfacl --set command.

NOTE This command will erase all existing ACL entries before applying the new permissions
[martin@church1e]$ setfacl --set u::7,g::7,u:rosie:r,o::-,g:testers:7 mydir
[martin@church1e]$ getfacl mydir
# file: mydir
# owner: martin
# group: martin
user::rwx
user:rosie:r--
group::rwx
group:testers:rwx
mask::rwx
other::---

The above example is equal to running:

[martin@churchie]$ chmod 770 mydir
[martin@church1e]$ setfacl -m u:rosie:r,g:testers:7 mydir

Finally, we can also set a default acl on a directory, which means that all files and sub-directories automatically inherite the ACL. We simply mark the ACL as default using the -d option. For example:

[martin@church1e]$ mkdir testdir
[martin@church1e]$ chown martin:testers testdir
[martin@church1e]$ setfacl -d --set u::7,g::7,o::-,g:testers:7,u:rosie:5 testdir
[martin@church1e]$ mkdir testdir/dir2
[martin@church1e]$ getfacl testdir/dir2
# file: testdir/dir2
# owner: martin
# group: martin
user::rwx
user:rosie:r-x
group::rwx
group:testers:rwx
mask::rwx
other::---
default:user::rwx
default:user:rosie:r-x
default:group::rwx
default:group:testers:rwx
default:mask::rwx
default:other::---