Access Control Lists

Access control list
(ACL) provides an additional, more flexible permission mechanism for
file systems
. It is designed to assist with UNIX file permissions. ACL allows you to give permissions for any user or group to any disk resource.
Installation
The
acl
package is a dependency of
systemd
, it should already be installed.
Enable ACL
To enable ACL, the filesystem must be mounted with the
acl
option. You can use
fstab
entries to make it permanent on your system.
There is a possibility that the
acl
option is already active as one of the default mount options on the filesystem.
Btrfs
and Ext2/
3
/
4
filesystems are affected by this. Use the following command to check ext2/3/4 formatted partitions for the option:
# tune2fs -l /dev/sd
XY
| grep "Default mount options:"
Default mount options:    user_xattr
acl
Also check that the default mount options are not overridden, in such case you will see
noacl
in
/proc/mounts
in the relevant line.
You can set the default mount options of a filesystem using the
tune2fs -o
option
partition
command, for example:
# tune2fs -o acl /dev/sd
XY
Using the default mount options instead of an entry in
/etc/fstab
is very useful for external drives, such partition will be mounted with
acl
option also on other Linux machines. There is no need to edit
/etc/fstab
on every machine.
Note
acl
is specified as a default mount option when creating an ext2/3/4 filesystem. This is configured in
/etc/mke2fs.conf
.
The default mount options are not listed in
/proc/mounts
.
Usage
Set ACL
The ACL can be modified using the
setfacl
command.
Tip
You can list file/directory permission changes without modifying the permissions (i.e. dry-run) by appending the
--test
flag.
To apply operations to all files and directories recursively, append the
-R
/
--recursive
argument.
To set permissions for a user (
user
is either the user name or ID):
# setfacl -m "u:
user:permissions
" <file/dir>
To set permissions for a group (
group
is either the group name or ID):
# setfacl -m "g:
group:permissions
" <file/dir>
To set permissions for others:
# setfacl -m "other:
permissions
" <file/dir>
To allow all
newly created
files or directories to inherit entries from the parent directory (this will not affect files which will be
moved
into the directory):
# setfacl -dm "
entry
" <dir>
To remove a specific entry:
# setfacl -x "
entry
" <file/dir>
To remove the default entries:
# setfacl -k <file/dir>
To remove all entries (entries of the owner, group and others are retained):
# setfacl -b <file/dir>
Note
By default,
setfacl
automatically recalculates the ACL mask entry unless the
-n (--no-mask)
option is used. The mask entry defines the maximum effective permissions for all named users, named groups, and the owning group (but not the file owner or others). When recalculated, the mask is set to the union (bitwise OR) of all permissions from these entries — ensuring that each retains its requested permissions.
The mask then acts as a limiting filter: each affected entry's effective permissions are the intersection (bitwise AND) of its own permissions and the mask.
For example, if
user:bob
is granted
rwx
and the mask is
r-x
, Bob’s effective permissions will be limited to
r-x
.
This behavior ensures consistent access semantics, especially when sharing files across systems that do or do not support ACLs.
The example below helps clarify two distinct steps in how the ACL mask works in
setfacl
, especially in the context of the
--no-mask
and default behavior:
Recalculation of the mask (bitwise OR / "union")
Applying the mask (bitwise AND / limiting)
user:bob: rw-
group:dev: r--
group:: r-x
→ mask: rwx (union)

Effective rights:
bob: rw-
dev: r--
group:: r-x
The 2003 USENIX document
POSIX Access Control Lists on Linux
has more information.
Show ACL
To show permissions, use:
# getfacl <file/dir>
Examples
Set all permissions for user
johnny
to file named
abc
:
# setfacl -m "u:johnny:rwx" abc
Check permissions:
# getfacl abc
# file: abc
# owner: someone
# group: someone
user::rw-
user:johnny:rwx
group::r--
mask::rwx
other::r--
Change permissions for user
johnny
:
# setfacl -m "u:johnny:r-x" abc
Check permissions:
# getfacl abc
# file: abc
# owner: someone
# group: someone
user::rw-
user:johnny:r-x
group::r--
mask::r-x
other::r--
Remove all ACL entries:
# setfacl -b abc
Check permissions:
# getfacl abc
# file: abc
# owner: someone
# group: someone
user::rw-
group::r--
other::r--
Output of ls command
You will notice that there is an ACL for a given file because it will exhibit a
+
(plus sign) after its Unix permissions in the output of
ls -l
.
$ ls -l /dev/audio
crw-rw----+ 1 root audio 14, 4 nov.   9 12:49 /dev/audio
$ getfacl /dev/audio
getfacl: Removing leading '/' from absolute path names
# file: dev/audio
# owner: root
# group: audio
user::rw-
user:solstice:rw-
group::rw-
mask::rw-
other::---
Execution permissions for private files
The following technique describes how a process like a
web server
can be granted access to files that reside in a user's home directory, without compromising security by giving the whole world access.
In the following we assume that the web server runs as the user
http
and grant it access to
geoffrey
's home directory
/home/geoffrey
.
The first step is granting execution permissions for the user
http
:
# setfacl -m "u:http:--x" /home/geoffrey
Note
Execution permissions to a directory are necessary for a process to list the directory's content.
Since the user
http
is now able to access files in
/home/geoffrey
, others no longer need access:
# chmod o-rx /home/geoffrey
Use
getfacl
to verify the changes:
$ getfacl /home/geoffrey
getfacl: Removing leading '/' from absolute path names
# file: home/geoffrey
# owner: geoffrey
# group: geoffrey
user::rwx
user:http:--x
group::r-x
mask::r-x
other::---
As the above output shows,
other
's no longer have any permissions, but the user
http
is still able to access the files, thus security might be considered increased.
If you need to give write access for the user
http
on specific directories and/or files, run:
# setfacl -dm "u:http:rwx" /home/geoffrey/project1/cache
See also
getfacl(1)
setfacl(1)
POSIX Access Control Lists on Linux
How to set default file permissions for all folders/files in a directory?