Access Control Lists - ArchWiki

Jump to content

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/sdXY | 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/sdXY

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 copied 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>

The factual accuracy of this article or section is disputed.

Reason: The original note about the `--mask` option (which was taken from setfacl(1)) was determined as inaccurate, but the new note does not seem correct either. See the talk page for details. (Discuss in Talk:Access Control Lists#ACL mask entry)
Note: The default behavior of setfacl is to recalculate the ACL mask entry, unless a `--mask` entry was explicitly given. The mask entry indicates the maximum permissions allowed for users (other than the owner) and for groups. Unless explicitly set, this will match the permissions of the default group. To clarify what this means, suppose the group owning a directory has `r-x` permissions. If you add an ACL user or group with `rwx` permissions, the effective permissions of this user or group will be `r-x`. The reason for this is so that there are no surprises when a file from a system which does not support ACLs is made available on a system which does..

### 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?

Category:

- Access control

Hidden category:

- Pages or sections flagged with Template:Accuracy