Enjoy Better Flexibility in Granting File System Permissions with Access Control Lists (ACLs)
ACLs provide additional and more flexible permissions for file systems. They give better control over who can read, write and execute a file or any disk resource.
Standard Linux file permissions are satisfactory for most situations but they have their limitations. Permissions can be set to restrict access to a file to only the file owner, to members of a single group, or to everyone else. It may not be appropriate for the process (a running program) to be a member of the group owning the files, and even less desirable to grant permission to everyone.
ACLs allow fine-grained permissions to be allocated to a file. Named users or named groups, as well as users and groups identified by a UID or GUID, can be granted permissions, in addition to the standard file owner, group owner and other file permissions. The same permission flags apply: r – read, w – write, and x – execute (on files, search for directories).
The file owner can set ACLs on individual files or directories. New files and sub-directories can automatically inherit ACL settings from the parent directory’s default ACLs, if they are set. Just like normal file access rules, the parent directory hierarchy will need at least the other execute permission set to enable named users and named groups to have access.
The file system mount option
The file system needs to be mounted with ACL support enabled. XFS file systems have built-in ACL support. Ext4 file systems created on Red Hat Enterprise Linux 7 (RHEL 7) have the ACL option enabled by default, but ext4 file systems created in earlier versions of RHEL may need the ACL option
included with the mount request, or set in the superblock.
Viewing and interpreting ACL permissions
The ls-l command only outputs minimal setting details.
The + at the end of a 10-character permission string indicates that there are ACL settings associated with this file. You can interpret the user, group and other rwx flags as follows.
User: Shows the user ACL settings, which are the same as standard user file settings; rwx.
Group: Shows the current ACL mask settings, not the group owner settings; rw.
Other: Shows the other ACL settings, which are the same as other standard file settings; no access.
Note: Changing group permissions on a file with an ACL by using chmod does not change the group owner permissions and does not change the ACL mask. Use the setfacl –m g::perms file if the intent is to update the file group owner permissions.
Viewing the ACLs
To display ACL settings on a file, use getfacl file name (Figure 2).
Each section of the example given in Figure 2 indicates the following.
Opening comment entries: The first three lines are comments that identify the file name, owner (student) and group owner (controller). If there are any additional file flags, for example, setuid or setgid, then a fourth comment line will appear showing which flags are set.
1. File owner permission is rwx.
2. The named user is ram and abc permissions are rwx.
1. Group owner permissions are rw-.
2. Named group permissions. One entry for the group pqr shows permission to be rwx.
Viewing directory ACLs
To display ACL settings on a directory, you can use getfacl / directory (Figure 3).
Each section of the example given in Figure 3 indicates the following.
Opening comment entries: The first three lines of comments identify the directory name, the owner (student), and group owner (controller). If there are any additional directory flags (setuid, setgid, sticky), then a fourth comment line will appear showing the set flags—in this case, setgid.
Standard ACL entries which are shown below the comment lines are the ACL permissions on this directory. They are the same as the file example mentioned earlier, but apply to the directory. The key difference is the inclusion of the execute permission on these entries (when appropriate) to allow directory search permission.
The ACL mask
The ACL mask defines the maximum permissions that can be generated for named users, the group owner and named groups. It does not restrict the permissions of the file owner or other users. All files and directories that implement ACLs will have an ACL mask.
The mask can be viewed with getfacl and can be explicitly set with setfacl. It will be calculated and added automatically if it is not explicitly set, but it could also be inherited from a parent directory’s default mask setting. By default, the mask is recalculated whenever any of the affected ACLs are added, modified or deleted.
ACL permission precedence
When determining whether a process (a running program) can access a file, file permissions and ACLs are applied as follows:
If a process is running as the user that owns the file, then the file’s user ACL permissions apply.
If the process is running as a user that is listed in a named user ACL entry, then the named user ACL permissions apply (as long as it is permitted by the mask).
If the process is running as a group that matches the group owner of the file or as a group with an explicit name group ACL entry, then the matching ACL permissions apply (as long as it is permitted by the mask).
Otherwise, the file’s other ACL permissions apply.
Securing files with ACLs
Changing ACL file permissions: Use setfacl to add, modify or remove standard ACLs on files and directories. ACLs use the normal file system representation r for read permission, w for write permission, and x for execute permission. A ‘-’ (dash) indicates that the relevant permission is absent. When (recursively) setting ACLs, an upper-case X can be used to indicate that execute permissions should only be set on directories and not regular files, unless the file already has the relevant execute permissions. This is the same behaviour as chmod.
Adding or modifying an ACL: ACLs can be set via the command line using –m or passed via a file using –M (use
‘-’ (dash) instead of a file name for stdin). These two are the modify options; they add new ACL entries or replace specific existing ACL entries on a file or directory. Any other existing ACL entries on the file or directory remain untouched. To add or modify a user or named user ACL, use the following command:
# setfacl –m u:name:rX file
If a name is left blank, then it applies to the file owner; otherwise, the name can be a user name or UID value. In this example, the permissions granted are read-only and if already set, execute (unless the file was a directory, in which case the directory gets the execute permissions set to allow directory search).
ACL file owner and standard file owner permissions are equivalent; consequently, using chmod on the file owner permissions is equivalent to using setfacl on them. chmod has no effect on named users.
To add or modify a group or named group ACL, use the following command:
# setfacl –m g:name:rw file
This follows the same pattern for adding or modifying a user ACL. If the name is left blank, then it applies to the group owner. Otherwise, specify a group name or GID value for a named group. The permissions are read and write in this example. chmod has no effect on any group permissions for files with ACL settings, but it updates the ACL mask.
To add or modify the other ACL, use the following command:
#setfacl –m o::- file
Other only accepts permission settings. It is common for permissions to be set to ‘-’ (dash), which specifies that other users have no permissions, but any of the standard permissions can be specified.
ACL other and standard other permissions are equivalent, so using chmod on the other permissions is equivalent to using setfacl on them. Add multiple entries using the same command, and comma-separate each of the entries, as follows:
# setfacl –m u::rwx, g:sodor:rX,o::- file
This will set the file owner to read, write and execute; set the named group sodor to read-only and conditional execute, and restrict all other users to no permissions. The group owner will maintain the existing file or ACL permissions and other named entries will remain unchanged.
Using getfacl as input
The output from getfacl can be used as input to setfacl: # getfacl file-A | setfacl --set-file=- file-B
-set-file accepts input from a file or stdin and the ‘-’ (dash) specifies the use of stdin. In this case, File B will have the same ACL settings as File A.
Setting an explicit ACL mask
An ACL mask can be explicitly set on a file or directory to limit the maximum effective permissions for named users, the group owner, and named groups. This restricts any existing permissions that exceed the mask, but does nothing to permissions that are less permissive than the mask.
# setfacl –m m: :r file
This adds a mask value that restricts any named users, the group owner and any named groups to read-only permission, regardless of their existing settings. The file owner and other users are not impacted by the mask setting. getfacl will show an ‘effective’ comment beside entries that are being restricted by a mask setting.
Note: By default, the ACL mask is recalculated each time one of the impacted ACL settings (named users, group owner, or named groups) is modified or deleted, potentially resetting a previous explicit mask setting. To avoid mask recalculations, use –n or include a mask setting (-m m::perms) with any setfacl operation that modifies maskaffected ACL settings.
Recursive ACL modifications
When setting an ACL on a directory, it is common to want to apply the ACL recursively to the directory structure and files. Use the –R option to do this. The X (upper case X) permission is often used with recursion, so that files with the execute permissions set retain the setting, and directories get the execute permissions set to allow directory search. It is considered good practice to also use the uppercase X when non-recursively setting ACLs, as it prevents an administrator from accidentally adding execute permissions to a regular file.
# setfacl –x u:name, g:name file
This only removes the named user and the named group from the list of file or directory ACLs. Any other existing ACLs remain active.
It is possible to use the delete (-x) and modify (-m) operations in the same setfacl operation.
The mask can only be deleted if there are no other ACLs set (excluding the base ACLs which cannot be deleted), so it must be deleted last. The file will no longer have ACLs and ls-l will not show the ‘+’ symbol next to the permissions string. Alternatively, to delete all ACLs on a file or directory (including default ACLs on directories), use the following command: # setfacl –b file
Controlling default ACL file permissions
A directory can have default ACLs set on it that are automatically inherited by all new files and new subdirectories. There can be default ACL permissions set for each of the standard ACL settings, including a default mask.
A directory still requires standard ACLs for access control because default ACLs do not implement access control for the directory—they only provide ACL permission inheritance support.
Here is an example:
# setfacl –m d:u:name:rx directory
This adds a default named user (d:u:name) with read-only permission and execute permission on sub-directories.
The setfacl command for adding a default ACL for each of the ACL types is exactly the same as for standard ACLs, but prefaced with d:. Alternatively, use the –d option on the command line.
Important: When setting default ACLs on a directory, ensure that users will be able to access the contents of new sub-directories created in it by including the execute permissions on the default ACL. Users will not automatically get the execute permissions set on newly created regular files because, unlike new directories, the ACL mask of a new regular file is rw-.
Note: New files and new directories continue to get their owner UID and primary group GID values set from the creating user, except when the parent directory setgid flag is enabled, in which case the primary group GID will be the same as the parent directory GID.
Deleting default ACLs
The process for deleting a default ACL is also the same as for deleting a standard ACL; again, preface with d: or use the –d option.
# setfacl –x d:u:name directory
This removes the default ACL that has been added in the previous example. To delete all default ACLs on a directory, use setfacl –k /directory. To delete all ACLs on a directory, use setfacl –b /directory.
Figure 2: ACL settings on the file osfy.txt
Figure 3: ACL on a directory
Figure 1: The ‘+’ indicates the presence of ACL