Precedence of ACLS when a user belongs to multiple groups

aclgrouppermissions

If a file has ACL entries for two groups, giving them different permissions, like this:

group:admin:rw-
group:staff:r--

what permissions does a user have if he belongs to both groups? Which entry takes precedence? Experiment seems to show that the most restrictive permissions apply. If so, what's the best way to deal with situations where I really want members of one group to have elevated privileges, even if they belong to other, more restricted groups too?

Best Answer

From the standard:

In words, Common Access Determination Algorithm is to be interpreted as follows (this description is a loose paraphrase of the common access determination algorithm which is specified in detailed pseudocode in ACL Managers ):

  • Match (in the sense defined in the pseudocode in ACL Managers ) the incoming PAC against the ACL's access ACLEs (in the top-to-bottom order shown, namely: UO, U, FU, GO/G/FG, O, FO, AO), stopping at the first such match (except that all matches are considered "simultaneously" in the case of the indicated group-like ACLEs), and note the permissions granted by the matched ACLE (or, in the case of the group-like ACLEs, the union of the permissions granted by all the matched ACLEs).

  • Mask (that is, intersect) the acquired permissions against the permissions in the ACL's mask ACLEs, as necessary (namely, mask with MASK_OBJ permissions if the match occurred in the center column1, and/or mask with UNAUTHENTICATED permissions if the PAC is unauthenticated). (If the ACL Manager doesn't support these two mask ACLEs, this step is a null operation.)

(emphasis in original, footnote added)

That is, if there is a file with user and group root and permissions 0600 called acl-test, containing the single line read possible, then:

$ getfacl acl-test
# file acl-test
# owner: root
# group: root
user::rw-
group::---
other::---

Now if I (as user fox) attempt to cat this:

$ cat acl-test
cat: acl-test: Permission denied

Group permissions are unioned

I happen to be in the groups users and wheel, so we can add specific ACLs for these groups:

# setfacl -m g:users:--- -m g:wheel:r-- acl-test
$ cat acl-test
read possible

This is because the group entries (considered simultaneously) allow read permission to one of my groups. These can be combined:

# setfacl -m g:users:-w- acl-test
$ getfacl acl-test
# file: acl-test
# owner: root
# group: root
user::rw-
group::---
group:wheel:r--
group:users:-w-
mask::rw-
other::---
$ printf '%s\n' 'write possible' >> acl-test
$ cat acl-test
read possible
write possible

So now I can both read and write the file, even though the groups that allow these permissions are not the same group.

User-specific permissions override all groups

Since user rules apply before group rules, we can still restrict a given user from reading and/or writing contents:

# setfacl -m u:fox:--- acl-test
$ getfacl acl-test
# file: acl-test
# owner: root
# group: root
user::rw-
user:fox:---
group::---
group:wheel:r--
group:users:-w-
mask::rw-
other::---
$ cat acl-test
cat: acl-test: Permission denied

A mask, if set, overrides almost everything

If a file is meant to be truly read-only to anyone but the owner:

# setfacl -x u:fox -m g::rw- -m m:r-- acl-test
$ getfacl acl-test
# file: acl-test
# owner: root
# group: root
user::rw-
group::rw-          #effective:r--
group:wheel:r--
group:users:-w-     #effective:---
mask::r--
other::---
$ printf '%s\n' 'now writing is impossible' >> acl-test
bash: acl-test: Permission denied
# printf '%s\n' 'owner can still write' >> acl-test

Amusingly, the mask does not override the others permissions, so:

# setfacl -x g:users -x g:wheel -m o:rw- -n acl-test
$ getfacl acl-test
# file: acl-test
# owner: root
# group: root
user::rw-
group::rw-          #effective:r--
mask::r--
other::rw-
$ printf '%s\n' 'others can write now' >> acl-test
# chown :users acl-test
$ printf '%s\n' 'but not members of the owning group' >> acl-test
bash: acl-test: Permission denied

1 The "center column" refers to this image and contains everything except UO and O, so the owning user and others are unaffected by a mask. All groups and non-owning users with defined rules are affected.

Related Question