Understanding Linux Solaris Permissions and Access Control Lists

Sunday, March 1, 2009

I wanted to have a definitive reference for understanding how permissions work in Unix/Linux/Solaris environments as many times I needed special privileges for some users to execute some files, then found that I can create an Access Control List (ACL) which may allow specific users to execute them, also sometimes I needed to Google for the differences between file permissions and directory permissions even though I knew them well, but when setting it, I always wanted to crosscheck.

This writing can be regarded as a quick starter for understanding how permissions work in Unix/Linux/Solaris environments and its classified into five sections, namely Permissions for Files, Permissions for Directories, Access Control Lists (Permissions at specific user or group level on files and directories), umasks and ACL masks, the first two permissions are generic, i.e its applicable for user, group and others, but the third is specific to an user or group. I have found many tutorials about UNIX permissions in the web, but this will be a little different from them because I will explain a bare minimal set of things you know about permissions from which you can easily figure out how permissions can be set for files/directories in UNIX.

Though some of these are trivial, but its always good to have a handy reference of these, at times knowing these would be fruitful to you in saving your time, also I will give a short account of how umasks and ACL masks affect effective permissions, I hope that once you read this fully, you may have some takeaways.

1. Permissions at File level
2. Permissions at Directory level
3. Permissions at Specific user or group level on files and directories (Access Control Lists)
4. umask and its effects on permissions
5. ACL Masks

Note: I am going to use octal numbers for setting permissions as its easy using octal values for chmod, for your reference 7 - Read/Write/Execute (rwx), 6 - Read/Write (rw_), 5 - Read/Execute (r_x), 4 - Read (r__).

1. Permissions at File level

This is quite simple as it goes, but you will also learn something when you introspect file permissions a little more.

With only a Read Permission on a file:

You can list the file's contents through an editor like vi or cat command, copy/move/rename files, but you can't modify the file's contents or no write/execute operations allowed on that file, so simple.

With only a Write Permission on a file:

It may sound odd having a write permission for a file without read permissions, but in fact it has its own pros and cons, you can overwrite/append contents into a file with this permission, but only using a cat command, as you don't have read permissions, you can't use an editor to change its contents, also you can rename, remove files, but you can't see the contents or your modifications on the updated file, neither copy the file's contents from one location to other, in short the write permission on a file makes sense only when you are removing/renaming a file.
-bash-3.00$ pwd
/export/home/unixuser/testdir
-bash-3.00$ ls -l
total 2
-rwxrwxrwx 1 unixuser other 12 Feb 28 19:19 file1
-bash-3.00$ chmod 222 file1
-bash-3.00$ ls -l
total 2
--w--w--w- 1 unixuser other 12 Feb 28 19:19 file1
-bash-3.00$ cat file1
cat: cannot open file1
-bash-3.00$ cat >> file1
Added a new line in file1
-bash-3.00$ mv file1 file2
-bash-3.00$ ls -l
total 2
--w--w--w- 1 unixuser other 38 Feb 28 19:24 file2
-bash-3.00$ cp file1 file2
cp: cannot open file1: Permission denied
-bash-3.00$
With only an Execute Permission on a file:

This is similar to having no permissions on a file, because with only execute permissions, you cannot do any operations on a file, as you need to read a file to execute and no write operations allowed, therefore you can't read/write/execute/rename/modify/copy a file, but still you can legally have a file with this permission.

I am sure that knowing the above facts alone can make you to understand how other permissions for files would work, for example a read/write permission on a file means you cannot execute that file and a read and execute permission means you cannot modify/overwrite the file, etc.

Default File Permission: The default file permissions are 666, (644 with a default umask 022, the user can read/write, group and other users can have only read permissions).

2. Permissions at Directory level

The permissions for a directory are little different from that of files, especially the execute permissions for directories with which you can cd into the directory and access the files in the directory with a command like ls or in an editor or browser or other file access tools. The three permissions for a directory are explained below.

With only a Read Permission on a directory:

You can list files on a directory without cd ing to that directory, but you cannot see any properties of those files like the type of that file, its size, etc, but you can see the contents of that directory, see the below example.
-bash-3.00$ pwd
/export/home/unixuser
-bash-3.00$ ls -l
total 2
drwxrwxrwx 2 unixuser other 512 Feb 28 19:35 testdir
-bash-3.00$ chmod 444 testdir/
-bash-3.00$ ls -l
total 2
dr--r--r-- 2 unixuser other 512 Feb 28 19:35 testdir
-bash-3.00$ ls -l testdir/
testdir/file1: Permission denied
total 0
-bash-3.00$
With only a Write Permission on a directory:

Its as good as having no permissions on a directory because without read permission, a write permission on a directory is rendered ineffective as you cannot cd the directory, neither access the directory contents from outside the directory, therefore no chance of creating/modifying/renaming files in the directory where you have write permissions.

With only an Execute Permission on a directory:

Again its like having no permissions on a directory, all you can do with an execute permission on a directory is you can only cd into that directory (but can't see any of the files in the directory), so without a basic read permission on the directory, a write or execute permission serves no purpose.
-bash-3.00$ pwd
/export/home/unixuser
-bash-3.00$ ls -l
total 2
drwxrwxrwx 2 unixuser other 512 Feb 28 18:42 testdir
-bash-3.00$ chmod 111 testdir/
-bash-3.00$ ls -l
total 2
d--x--x--x 2 unixuser other 512 Feb 28 18:42 testdir
-bash-3.00$ cd testdir/
-bash-3.00$ pwd
/export/home/user1/testdir
-bash-3.00$ ls
.: Permission denied
-bash-3.00$ cd ..
-bash-3.00$ ls -l testdir/
testdir/: Permission denied
total 2
-bash-3.00$ ./testdir/file1
-bash: ./testdir/file1: Permission denied
-bash-3.00$
Now with this basic knowledge, you can easily figure out which combination of permissions on files and the enclosing directory will make sense, experiment with different combination of permissions, that's the better way of learning, but always remember the above six permissions and its effect on files and directories, then you can easily figure out other combination of file/directory permissions.

Default Directory Permission: The default directory permissions are 777, (755 with a default umask 022, the user can read/write, cd into the directory, the group and other users can only have read permissions on the directory).

3. Permissions at Specific user or group level on files and directories (Access Control Lists)

The two commands we should know in Access Control Lists are setfacl and getfacl.

As the name says, with setfacl you can add an access control entry for a file and with getfacl, you can fetch the access control details of a file.

Well there are many options in setfacl command, you can check the man page of setfacl, whereas getfacl is simple that it takes a file name as an argument and displays the Access Control entries defined for that file. Lets come to setfacl.

setfacl options

We will see the options -m (creates or modifies ACL), -d (delete ACL), -r (recalculate ACL) and -s (substitutes an ACL, replaces an existing ACL as a whole).

3.1 Creating/modifying ACL

For example if a file with owner user1 has read/write permissions for owner and read only permissions for group and others, but for a specific UNIX user say, user2, we want to give write privileges too, then set the ACL as shown below.
-bash-3.00$ pwd
/export/home/user1
-bash-3.00$ whoami
user1
-bash-3.00$ ls -l
total 2
-rw-r--r-- 1 user1 other 12 Feb 28 23:29 file1
-bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
group::r-- #effective:r--
mask:r--
other:r--
-bash-3.00$
Now setting an ACL which will allow user2 to have write access to file1,
-bash-3.00$ setfacl -m u:user2:6 file1
-bash-3.00$ ls -l
total 2
-rw-r--r--+ 1 user1 other 12 Feb 28 23:29 file1
-bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
user:user2:rw- #effective:r--
group::r-- #effective:r--
mask:r--
other:r--
-bash-3.00$
Even though the write access was set for user2 for file1 (through the -m option with u:user2:6), since the ACL mask is read only (r--) as shown above, user2 still has an effective permission of read-only, therefore one needs to change the mask and then recalculate the ACL which is shown below (in the ACL Masks section), also note that the once a file has an ACL, a + sign in ls command for that file will indicate that as shown above.

3.2 Deleting an ACL

Deleting an ACL is quite simple, for example if you want to remove the access control entry you created above for user2, then use the setfacl -d option
-bash-3.00$ ls -l
total 2
-rw-r--r--+ 1 user1 other 12 Feb 28 23:29 file1
-bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
user:user2:rw- #effective:r--
group::r-- #effective:r--
mask:r--
other:r--
-bash-3.00$ setfacl -d u:user2 file1
-bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
group::r-- #effective:r--
mask:r--
other:r--
-bash-3.00$ ls -l
total 2
-rw-r--r-- 1 user1 other 12 Feb 28 23:29 file1
-bash-3.00$ ls -l
total 0
-rw-r--r-- 1 user1 other 0 Mar 1 23:30 file1
-bash-3.00$
3.3 Substituting/Replacing an ACL

To substitute or replace an old ACL with a new one, use the setfacl -s command, this will remove all existing ACL entries.

For example in the above ACL, we have user2 with write permissions, if we want to replace it with an ACL entry for user3 (which will remove the ACL entry for user2), then use the setfacl -s command as shown below.
bash-3.00$ ls -l
total 2
-rw-r--r-- 1 user1 other 12 Feb 28 23:29 file1
bash-3.00$ setfacl -m u:user2:6 file1
bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
user:user2:rw- #effective:r--
group::r-- #effective:r--
mask:r--
other:r--

bash-3.00$ setfacl -s u::6,g::4,o:4,m:4,u:user3:6 file1
bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
user:user3:rw- #effective:r--
group::r-- #effective:r--
mask:r--
other:r--
bash-3.00$
The important things to note when you substitute an ACL are

ACL Substitution removes all existing ACL entries (as you can see above, the ACL entry for user2 no longer exists), also you need to add all ACL entries right from owner/user, group and others for ACL substitution, if you try to substitute an ACL entry only for the specific user user3 without giving a value to owner, group and other entries, you will get a message shown below.
bash-3.00$ setfacl -s u:user3:6 file1
Missing user/group owner, other, mask entry
aclcnt 1, file file1
bash-3.00$
Also note that, you should use only one colon for setting permissions for others and mask entries,
bash-3.00$ setfacl -s u::6,g::4,o::4,m::3,u:user3:6 file1
use only 1 colon for mask and other entries.
4. umask and its effects on permissions

Setting umask affects the default permission a file can have, for example when a file is created, it will have a default permission of 666, with a default umask (022), the file's effective permission would be 644 (subtract the umask value from the default permissions), similarly for directories the default permission is 777 and the effective permission would be 755 with an umask of 022.

Lets see the effective permissions of a file with an umask 002.
bash-3.00$ pwd
/export/home/user1
bash-3.00$ ls
bash-3.00$ umask
0022
bash-3.00$ umask 002
bash-3.00$ touch file1
bash-3.00$ mkdir -p dir1
bash-3.00$ ls -l
total 2
drwxrwxr-x 2 user1 other 512 Mar 1 00:48 dir1
-rw-rw-r-- 1 user1 other 0 Mar 1 00:48 file1
bash-3.00$
As you can see with an umask of 002, the effective permissions for the new file and the directory were 664 and 775 respectively.

5. ACL Masks

ACL Masks affect the effective permissions of Access Control Lists, for example, as shown above, an user1 with access 644 for a file file1 (All but user1 can only read the file file1) grants a write access to user2 as shown below.
-bash-3.00$ pwd
/export/home/user1
-bash-3.00$ whoami
user1
-bash-3.00$ ls -l
total 2
-rw-r--r-- 1 user1 other 12 Feb 28 23:29 file1
-bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
group::r-- #effective:r--
mask:r--
other:r--
-bash-3.00$
Now setting an ACL which will allow user2 to have write access to file1,
-bash-3.00$ setfacl -m u:user2:6 file1
-bash-3.00$ ls -l
total 2
-rw-r--r--+ 1 user1 other 12 Feb 28 23:29 file1
-bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
user:user2:rw- #effective:r--
group::r-- #effective:r--
mask:r--
other:r--
-bash-3.00$
As noted above, even though the write permissions have been set for user2 for file1, the effective permission is read only as the ACL mask value is read only (r--) , therefore to change the ACL mask value to reflect the permissions we set for user2, change the mask value for the ACL and recalculate ACL mask (using -r option) with the new permission set for the user2 (using -m option) as shown below.
bash-3.00$ setfacl  -r -m  u:user2:6 file1
bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
user:user2:rw- #effective:rw-
group::r-- #effective:r--
mask:rw-
other:r--
bash-3.00$
As you have seen the recalculation of ACL mask only applies to the user2 and group in the ACL entry (the owner has read/write access by default which is determined by the umask, the ACL mask applies only to the user and groups, or only to those columns with the keyword effective), if you want to make this permission to group and others to write as well, change their permissions to include write access as shown below, their new permissions will use the latest ACL mask.
bash-3.00$ getfacl file1

# file: file1
# owner: user1
# group: other
user::rw-
user:user2:rw- #effective:rw-
group::rw- #effective:rw-
mask:rw-
other:rw-
bash-3.00$
Thats it, this is enough to get you going and changing the permissions of files/directories at will (if you are the owner of course).

5 comments:

Anonymous said...

You have a slight error in the forst paragraph of your (excellent) post.

You state that you will use octal notation and then say that 7 is rwx, 5 is rw (it is actually r_x)... 6 would give you rw_), and you correctly continue with 4 as r__.

Nice article though

Prasanna Seshadri said...

Hi,

Thanks a ton for pointing that out, now its corrected, appreciate your time.

Anonymous said...

The details of the directory permissions are off a bit. The execute bit allows listing the details of an entry by name "ls -l testdir/file1" for example would work as expected. Execute and write together is enough to allow you to copy files into a directory and delete files from the directory, so it's doesn't actually "serve no purpose", it just requires that you know the names of the files already.

Prasanna Seshadri said...

Hi,

Good point, the reason why I mentioned like that is because without a read permission, an user has no chance to figure out that a file in fact exists in a directory and in that sense I mentioned that without read (unless its hard coded in his memory), there is practically no way you can do any operations on a directory without knowing the files, even tab completion won't work of course with write or execute or both permissions.

You are right, execute and write has some value, but again without read you can't get any hint of the files there though you can move your files into the directory.

Probably I will add your point which is valid of course if the user has knowledge of the files in the directory, will update it accordingly.

venkat said...

Hello sir,
I am confused with your file permissions explainations. Suppose a user is in his home directory /export/home/unixuser, even if he has read permission, he can copy a file. is it not?


Copyright © 2016 Prasanna Seshadri, www.prasannatech.net, All Rights Reserved.
No part of the content or this site may be reproduced without prior written permission of the author.