How ACL Masks Let You Fine-Tune File Permissions in Linux
Key Takeaways
- Access Control List (ACL) masks ensure compatibility with programs that aren’t ACL-aware, translating ACL entries into POSIX permissions.
- ACL masks represent the maximum allowed permissions for any user or group object that isn’t the owning user, group, or “other” class.
- When adding new ACL entries, the mask automatically adjusts to reflect the maximum permissions allowed for all named users or groups.
Are you using Access Control Lists (ACLs) but are confused about the concept of masks? You’re not alone. Let’s dive into this important concept by taking a look at what they are and how they interact with Linux file system permissions.
What Are ACL Masks?
ACL masks are a way to ensure permissions interoperability with programs and utilities that aren’t ACL-aware.
An ACL mask on a file or directory equates to the maximum permissions allowed to any user or group object that isn’t the owning user, group, or “other” class of the user/group/other class paradigm. To put it another way, it translates ACL entries into POSIX permissions for the sake of backward compatibility.
Let’s take a look at a newly created file we’ll be working with in this article, mysupersecretfile.txt:
ls -l mysupersecretfile.txt
Pretty straightforward permissions for such a sensitive document, right?
Notice the dot (.) after the permissions set. This indicates an SELinux context, which is unrelated to ACLs or ACL masks.
For clarity, let’s also examine the ACL entries for the file, using the getfacl command:
getfacl mysupersecretfile.txt
The current ACL entries for owning user and group entries map directly to the actual POSIX owning user and owning group of the file. This is normal for any file that doesn’t have extended ACL entries, and is called “minimal ACLs”.
Let’s say we received a request to add a user called manager as an ACL entry to this file, with read permissions. We’ll accomplish this with the setfacl command. Then, let’s examine the new ACL permissions using the ls and getfacl commands:
setfacl -m u:manager:r mysupersecretfile.txt
ls -l mysupersecretfile.txt
getfacl mysupersecretfile.txt
You’ll now notice the “+” sign alongside the permissions entries in the ls command, indicating that there are ACL entries associated with the file.
Do you see the mask line in the output of the getfacl command now? In addition to the manager user’s extended ACL entry, this mask entry has been automatically assigned. This is necessary; it represents the maximum permissions allowed for any named user or group object (again, besides the owner user and owning group objects). Right now, the read permission equates to the read permission of the existing mask.
Now let’s add another user from a second request, contractor, to the ACL of our file. This time, however, we need to give them read and write permissions. Let’s see how that affects the mask:
setfacl -m u:contractor:rw mysupersecretfile.txt
getfacl mysupersecretfile.txt
Now, in addition to the manager (r) ACL entry, we also see the contractor (rw) entry. But why did the mask entry change to read and write?
When we added the contractor user with read and write permissions, it affected the ACL mask because, as I mentioned above, the mask relates to the maximum allowed permissions of ACL users and group entries. Since we added write permissions to the contractor user’s ACL entry, the mask also gets the write permission.
When working with ACLs, you’ll see that the role of the group class permissions (such as with the output of the ls -l command) is re-purposed to reflect the ACL mask. Don’t worry though, the group owner permissions are still reflected as the ‘owning group’ ACL entry.
Keep in mind that if you add another user with fewer permissions, for example read-only, they do not inherit the mask permissions—just like the manager user didn’t get the write permission when we added the contractor user’s ACL entry.
Effective Permissions
We can set the mask entry permissions manually by using the setfacl command. This will allow us to filter any named user and/or group permissions set on the file at the same time, or for existing users’ ACL entries of the file, to the lowest common denominator. This is called effective permissions.
Let’s set the mask on our file to read-only, and then take a fresh look at the ACL entries:
setfacl -m m::r mysupersecretfile.txt
getfacl mysupersecretfile.txt
The comment showing the contractor user’s effective permissions lets us know that, even though they were granted read and write permissions, in reality, they only have read permission. Modifying the mask caused this. If we look at the file again with ls -l, we’ll see the group class permissions (which again is re-purposed to reflect the mask) have changed:
ls -l mysupersecretfile.txt
If you want to add a named user or group ACL entry, but don’t want to recalculate the mask, you can use -n alongside setfacl. This will restrict the ACL you’re adding to the maximum permissions allowed by the mask (shown by the effective permissions of the entry). This isn’t the default, though; keep in mind that the mask isn’t a form of mandatory access control. Let’s try that below:
setfacl -n -m u:milton:rwx mysupersecretfile.txt
getfacl mysupersecretfile.txt
Default Masks
When you’re working with ACLs, the concept of default masks is very similar to default ACL entries. For example, when you add a default mask to a directory, all newly created files and subdirectories inside of it will inherit that same mask (as well as the default mask entry). Just use the -d parameter with the setfacl command to apply a default mask:
mkdir mysupersecretdirectory
setfacl -d -m m::rX mysupersecretdirectory/
getfacl mysupersecretdirectory/
mkdir mysupersecretdirectory/mysupersecretsubdirectory/
getfacl mysupersecretdirectory/mysupersecretsubdirectory/
Default masks, and default ACL entries for that matter, are only applicable to directories since they’re the only objects that can contain files and/or other directories inside of them to apply these inheritable entries to.
ACL masks are a way to ensure the security of ACLs is handled properly, regardless of the capabilities of the program that’s manipulating them.
As technology, software, and security concepts continue to rapidly evolve, it’s important to remember that backward compatibility is paramount for many of us, and must be honored alongside new advancements. Of course, that doesn’t mean you can’t have new bells and whistles, it just means that those new bells and whistles should adhere to existing standards.