Pages

Thursday, October 4, 2012

Linux ACL's

That root can do everything with the files and directories user created will be slightly ignored in this article. Another thing I am doing different here is the prompt of each user. In normal cases I use the # for the root prompt and $ for the user prompt. In this article I will use ajolie$ for the prompt for the user ajolie and so on. The command will be done with the user that stand in front of the $.

Preperations:

To start with ACL in Linux I have created three users:

# getent passwd
...
ajolie:x:1001:100:ajolie:/home/ajolie:/bin/bash
sneill:x:1002:100:sneill:/home/sneill:/bin/bash
jmoris:x:1003:100:jmoris:/home/jmoris:/bin/bash

All these users are in the same group 100 (users). The default umask ist 0022, that means that every time a user creates a file it will have read/write access for the creator, read access for all users in the group 100 and also read access for everybody else (644).

Set ACL for a file:

First let the user ajolie create a file and set the access rights to 600:

ajolie$ cd /local/pub
ajolie$ touch foo
ajolie$ chmod 600 foo
ajolie$ ls -la foo
-rw------- 1 ajolie users    0 Sep 11 22:03 foo

In this case only the user ajolie can read/write the file foo - nobody else:

jmoris$ cd /local/pub
jmoris$ cat foo
cat: foo: Permission denied

sneill$ cd /local/pub
sneill$ cat foo
cat: foo: Permission denied

With ACL you can set the rights that the user sneill can read the file, but not jmoris. The command to set an ACL is setfacl. The option -m is for modify, the u indicates a user followed by a valid username (sneill) and the rights you want to grant. As rights you can use r (read), w (write) and x (execute):

ajolie$ setfacl -m u:sneill:r-- foo

The user sneill can read the file now, but not jmoris:

sneill$ cat foo
...
jmoris$ cat foo
cat: foo: Permission denied

Instead of using r-- to grant the rights you can only use r. But I will use the rwx notation in this entire artice.
If you take a look at the rights of the file then you will notice a change:

ajolie$ ls -la foo
-rw-r-----+ 1 ajolie users 0 Sep 11 22:07 foo

The Posix rights schema indicates that the file foo has rw access for the owner of the file and read access for the group - which is not quiet right. Just note the + at the rights which is new. If you see a file with a + at the end of rights then you know that the file was modified with ACL's. To list the ACL's of a file you can use the command getfacl. Even a     user that does not have any rights to a file can get the ACL's of it:

jmoris$ getfacl foo
# file: foo
# owner: ajolie
# group: users
user::rw-
user:sneill:r--
group::---
mask::r--
other::---

You can repeat the above setfacl command for each user you want to grant read access to the file foo. You can set multiple ACL's to multiple users by comma seperating them, eg:

ajolie$ setfacl -m u:sneill:r--,u:jmoris:rw- foo
ajolie$ getfacl foo
# file: foo
# owner: ajolie
# group: users
user::rw-
user:sneill:r--
user:jmoris:rw-
group::r--
mask::rw-
other::r--

But sometimes you need to remove a user from the ACL list eg. sneill this time:

ajolie$ getfacl foo
...
user:sneill:r--
user:jmoris:r--
...

To remove the user sneill from the user list use the setfacl command with the -x option:

ajolie$ setfacl -x u:sneill foo
ajolie$ getfacl foo
...
user:jmoris:r--
...

In the above example it makes no sense to remove only a single right because the user has only one right so you can remove the user directly. But sometimes you need to remove only a single right, in this case you don't remove the right, you need to define a new ACL eg:

ajolie$ getfacl foo
...
user:sneill:rw-
user:jmoris:rw-
...

Both users have the same same rights (read/write). To remove the write right for the user sneill just define a new ACL:

ajolie$ setfacl -m u:sneill:r-- foo
ajolie$ getfacl foo
...
user:sneill:r--
user:jmoris:rw-
...

Of course you can set ACL's for a group on a file:

ajolie$ touch foo
ajolie$ setfacl -m g:apache:rw- foo
ajolie$ getfacl foo
# file: foo
# owner: ajolie
# group: users
user::rw-
group::r--
group:apache:rw-
mask::rw-
other::r--

Or for everybody else:

ajolie$ touch foo
ajolie$ setfacl -m o::rw- foo
ajolie$ getfacl foo
# file: foo
# owner: ajolie
# group: users
user::rw-
group::r--
other::rw-

The above examples displaying the ACL's after the file foo was newly created.
One more thing: if you just create a new file and take a look at the ACL's (without setting any ACL) then you will get someting like this:

ajolie$ touch foo
ajolie$ getfacl foo
# file: foo
# owner: ajolie
# group: users
user::rw-
group::r--
other::r--

The ACL's that are displayed are the same as your usual rights, the empty group that is displayed represent the initial group for the user who created the file:

ajolie$ ls -la foo
-rw-r--r-- 1 ajolie users 0 Sep 12 22:47 foo

The rights depend on the umask that is set for the user.

Set ACL for a directory:

First let the user ajolie create a file and set the access rights to 600:

ajolie$ cd /local/pub
ajolie$ mkdir foo
ajolie$ chmod 700 foo
ajolie$ ls -la foo
-rw------- 1 ajolie users    0 Sep 11 22:03 foo

In this case only the user ajolie can change into the directory foo - nobody else:

jmoris$ cd /local/pub
jmoris$ cd foo
-su: cd: foo: Permission denied

sneill$ cd /local/pub
sneill$ cd foo
-su: cd: foo: Permission denied

Just like files the user ajolie must grant access to the directory foo for another user:

ajolie$ setfacl -m u:sneill:r-x foo

Now the user sneill can change into the directory foo but the user jmoris still not. When you do an ls again notice the plus at the end of the permissions again:

ajolie$ ls -la
...
drwxr-x---+ 2 ajolie users 4096 Oct  4 23:00 foo/
...

The rights are very similar to the above sample with the file. The create has rwx access, the initial group of the creator has r-x access (with is not quiet right again) and everybody else has no rights. And just like files you can look at an ACL for a directory:

ajolie$ getfacl foo
# file: foo
# owner: ajolie
# group: users
user::rwx
user:sneill:r-x
group::---
mask::r-x
other::---

The rest is very the same as above, you can add ACL's, remove ACL's and modify ACL's. Just one thing: a user can add ACL's recursively. This may have some impact on existing files and directories. Imagine the following situation: the user ajolie has create a directory foo and within this directory a file foo. The directory rights are set to 700 (rwx for the creator only) and the file rights are set to 600 (rw- for the creator only):

ajolie$ mkdir foo
ajolie$ chmod 700 foo
ajolie$ touch foo/foo
ajolie$ chmod 600 foo/foo

The user ajolie can set the following ACL to grant access for the user sneill:

ajolie$ setfacl -R -m u:sneill:r-x foo

With -R switch the ACL's are set recursively for each directory and file - this will make the file foo executable for the user sneill which is probably a bad idea:

getfacl foo/foo
# file: foo/foo
# owner: ajolie
# group: users
user::rw-
user:sneill:r-x
group::---
mask::r-x
other::---

Some other useful options:

If you need to remove the complete ACL from a file/directory then you can use the -b option in the setfacl command:

ajolie$ ls -la foo
-rw-rw-r--+ 1 ajolie users 0 Sep 12 22:47 foo
ajolie$ setfacl -b foo
ajolie$ ls -la foo
-rw-r--r-- 1 ajolie users 0 Sep 12 22:47 foo

This works also recursively with -R switch (in this case foo is a directory):

ajolie$ setfacl -R -b foo