Access Control Lists

Access control lists are used to grant privileges on a more fine-grained basis than standard permissions allow. Standard permissions can only be granted to the owner of the file/directory, its group and  everybody else. But what if we need to grant privileges to users or groups that do not own the file? That’s when ACLs come to the rescue. Unless the Linux OS we are using is really old or extremely minimalistic, ACLs should be supported. We can make sure of that with the command:

root:~> rpm -­qa | grep acl
libacl­2.2.51­12.el7.x86_64       → the libacl should be there
acl­2.2.51­12.el7.x86_64          → as well as the acl commands

If we need to use ACLs the first thing we need to do is to check whether the file system where we intend to use them supports them or not.

root:~> mount | grep /var
/dev/mapper/vg­var on /var type xfs (rw,relatime,seclabel,attr2,inode64,noquota)

Even though ACLs do not appear explicitly enabled in the output above, XFS allows ACLs even when mounted explicitly with the noacl option (feature or bug?). The ext4 file system also allows them by default but they can be disabled:

root:~> mount | grep /data1
/dev/mapper/vgdata1 on /data1 type ext4 (rw,relatime,seclabel,acl,stripe=512,data=ordered)
.
root:~> mount -­o remount,noacl  /data1
.
root:~> mount | grep /data1
/dev/mapper/vgdata1 on /data1 type ext4 (rw,relatime,seclabel,noacl,stripe=512,data=ordered)

Unlike ext4 file systems, ext2 & ext3 file systems do not enable ACLs by default. If we need them we will have to explicitate the acl option in the mount command and add it to /etc/fstab:

root:~> cat /etc/fstab | grep /var
/dev/mapper/vgmint/lvvar      /var     ext4      acl,errors=remount­rw    0   1

If we do not want ACLs in an ext4 file system, then we will also have to use the noacl option in /etc/fstab.
Let’s start using ACLs to see how they work…

marc:~> umask
0002
marc:~> touch /tmp/test1
marc:~> ls ­-l /tmp/test1
-rw-­rw-­r–­­. 1 marc marc 0 Mar 31 08:44 /tmp/test1

We have created a file as user marc with the default umask derived permissions. At first sight, the permissions on the file should be 775 given the umask 002. But we should remember 3 things:

1- in RHEL7 the default umask for users whose UID < 200 (system users) is 0002

2- for those users with a higher UID it is set to 0022

3- regardless of the umask, execution permissions are never given by default

So even though the umask is 002, the permissions will never be higher than 666. Therefore, the real permissions on the file are 664 or rw-rw-r–.

Now let’s start doing useful things: we will give read permission to the user lucy.

root:~> setfacl -­m u:lucy:r /tmp/test1
root:~> ls ­-l /tmp/test1
-rw-­rw-­r–­­+ 1 marc marc 0 Mar 31 08:44 /tmp/test1          (the “+” sign indicates ACLs!)
root:~> getfacl /tmp/test1
# file: test1
# owner: marc
# group: marc
user::rw­
user:lucy:r­­
group::rw­
mask::rw­
other::r­­
root:~> setfacl -­m g:dba:r /tmp/test1
root:~> getfacl /tmp/test1
# file: test1
# owner: marc
# group: marc
user::rw­
user:lucy:r­­
group::rw­
group:dba:r­­
mask::rw­
other::r­­

As we can see in the examples above, to give extra permissions to 3rd party users or groups we use the syntax:

setfacl ­-m ­[ugmo]:user_or_group_name_or_id:permissions  <file or directory>

The initial “-m” flag indicates that we intend to modify or add an ACL.

The ugmo flags indicate whether the ACL applies to a user, group, the mask or others.

Even though we can use ACLs to manipulate permissions for the owner of the file and for others, we will rarely do that as chmod is less hassle.

The ACL mask sets the maximum permissions for all users and groups that do not own the file/directory.

Let’s see it in action:

root:~> setfacl ­-m u:lucy:rwx /tmp/test1
root:~> getfacl test1
# file: test1
# owner: marc
# group: marc
user::rw­
user:lucy:rwx
group::rw­
group:dba:r­­
mask::rwx
other::r­­
root:~> setfacl -­m m:rx test1
root:~> getfacl test1
# file: test1
# owner: marc
# group: marc
user::rw­
user:lucy:rwx                      #effective:r­x
group::rw­                          #effective:r­­
group:dba:r­­
mask::r­x
other::r­­

We have given rwx permissions to user lucy and using getfacl we can see that those are indeed the effective permissions. But after setting the ACL mask to rx, we can see that the already implemented permissions for user lucy and group dba are curtailed to rx and x respectively.

Imagine a company with a large number of sysadmins managing thousands of systems. If we want to prevent an “accidental” granting of excessive permissions to users/groups through ACLs, using the mask can help to achieve that. Nothing stops a sysadmin from changing the mask itself, but it would have to be an explicit change so it would not be so “accidental”.

How do we delete ACLs? We can delete specific rules or all ACLs in a file/directory. If user Lucy does not longer need read access to test1, we can remove just this rule with the command:

root:~> setfacl -­x u:lucy /tmp/test1
root:~> getfacl test1
# file: test1
# owner: marc
# group: marc
user::rw­
group::rw­
group:accounting:r­­
mask::rw­
other::r­­

The “-x” option deletes specific rules. The “-b” option on the other hand deletes all the ACLs for a file or directory.

root:~> setfacl -­b /tmp/test1
root:~> getfacl /tmp/test1
getfacl: Removing leading ‘/’ from absolute path names
# file: tmp/test1
# owner: marc
# group: marc
user::rw­
group::rw­
other::r­­

What about ACLs for directories? They work the same way but with 2 further options.

We can use the “-R” flag to mean recursive. So the ACL will apply to the target directory plus all subdirectories and files.

root:~> setfacl ­-Rm u:marc:rwx /opt/oracle   →  applied to /opt/oracle and everything underneath!

We can also use the “-d” flag to mean default. So the ACL will be applied to files and directories created later on.

root:~> setfacl ­-Rdm u:marc:rwx /opt/oracle
root:~> touch /opt/oracle/test1
root:~> getfacl /opt/oracle/test1
getfacl: Removing leading ‘/’ from absolute path names
# file: opt/oracle/test1
# owner: marc
# group: marc
user::rw­
user:oracle:rwx
#effective:rw­
group::rwx
#effective:rw­
mask::rw­
other::r­­

We can see that a file created after the ACL was assigned will inherit the ACL permissions as expected.

We can copy ACLs from one file onto another with the command:

root:~> getfacl file1 | setfacl --set­-file=-­ file2

And we can copy ACLs from one directory onto another with the command:

root:~> getfacl ­­--access dir1 | setfacl ­-M-­ dir

As a last thought to close this ACL overview, we should remember that to archive files withholding ACL settings we can use the tar or star commands.

 

<< sudo command          Pluggable Authentication Modules >>