In this post we are going to discuss some of the Linux/Unix file system permissions. There are two basic commands for changing the ownership and permissions of a file system, namely, chmod and chown. In this post, we will be discussing one of the two – the chmod (contraction of change and mode) command.
One of the most critical jobs a system administrator has to continuously be dealing with is the permission administration. The most small carelessness with the permissions can lead to a security hole in the system.
There are three main things that have to be understood: the elements the permissions are deﬁned for, the actions that can be performed, and who can perform them.
The elements are two:
The actions are three:
- Read – Whoever is given this permission can read the content of the file
- Write – Whoever is given this permission can edit the content of the file
- Execute – Whoever is given this permission can execute (run) the file
And who can perform them are also three:
- The user that owns the ﬁle.
- The group that the user owning the ﬁle belongs to.
- Any other user that is not the owner and does not belong to the group the owner does.
To see how the permissions are organized, we can undertake a long listing of the ﬁles via the terminal:
We will see an output similar to the one shown below.
-rw-r--r-- 1 who who 0 May 4 08:20 file.txt
drwxr-xr-x 2 who who 4096 May 4 08:22 folder
The ﬁrst section, 10 characters, are which correspond to permissions. Let’s examine it:
- The ﬁrst character is for ﬁle type. – means that the ﬁle is a regular ﬁle, and d means that it is a directory.
- The following nine characters are for read (r), write (w) and execute (x) permissions for the owner, the group of the owner, and others, respectively. The first three bits (rw-) are the read, write, and execute permissions for the user. In this case, the user has no execute permissions. The next three bits are for the group. In this case, the group only has read permissions, The next three bits are for others. Just like the group, in this case, others do not also have write and execute permissions.
To change the permissions, like we discussed in the introductory part of this post, the chmod command is used. The syntax is the following:
chmod permissions file [file 2] [file n]
For example, for setting read and write permissions for the owner, read permissions for its group, and no permission for others, to a file.txt ﬁle, we would have to execute:
sudo chmod 640 file.sh
We can try to read the ﬁle with a user that is not the owner and does not belong the the owner’s group, to see what happens:
sudo -u other-user more file.sh
And we would receive an error message as shown below:
file.sh: Permission denied
But where comes that 640 from? Each digit of that number represents which permissions will have the owner, its group, and others. And each digit is the octal representation of the permission combination we want to assign. So:
- 0 for no permission.
- 1 is for execute permission.
- 2 is for write permission.
- 4 is for read permission.
The following table shows the permissions that each digit gives:
|Number||Binary||Read? (r)||Write? (w)||Execute? (x)|
From our example, therefore, we have assigned read and write permissions only to the user (6), read permission only to the group, and no permission to others.
To give all read, write, and execute permission to all users:
chmod 777 file.sh
Apart from octal representation, chmod also allows symbolic representation. In the symbolic representation, letters and arithmetic operators are used: For the users, the symbols are the following:
- u: ﬁle owner.
- g: ﬁle owner’s group
- o: other users.
- a: all users
The actions are represented with the same symbols that we have seen before:
- r: read
- w: write
- x: execute
And the operators to set the permissions are:
- =: sets the permissions as speciﬁed, overwriting any other previous permissions.
- +: adds permissions.
- -: removes permissions.
The syntax for the symbolic representation is the following:
sudo chmod who operator action,who operator action
For example, the previous example (owner: read and write; group: read; others: none) with the symbolic notation, would be the following:
sudo chmod u=rw,g=r,o-rwx file.sh
As you can see, for this example, this notation requires much more verbosity. But for other cases is more suitable. For example, if we want to maintain the current permissions, but allowing now everybody to write, we would have to type:
sudo chmod a+w file.sh
And the ﬁle would pass from these permissions:
-rw-r----- 1 who who 0 May 4 08:00 file.sh
To these ones:
-rw-rw--w- 1 who who 0 May 4 08:00 file.sh
Apart from those permissions we have seen, there are three more special permissions in Linux: the setuid (user id), the setgid (group id), and the sticky.
The setuid bit (set user ID) can be assigned to executable ﬁles, which is for, when a ﬁle is executed, allow the process acquire that ﬁle’s owner’s permissions. This is generally used to allow normal users (those without superuser privileges) to obtain root privileges for some executables. This can be seen, for example, in common binaries, such as /bin/ping. If we check its permissions, we will see that it has the setuid bit assigned:
-rwsr-xr-x 1 root root 34168 May 4 2019 /bin/ping*
Which is expressed with an ‘s’ in the place for the execution bit for the owner. If we remove the setuid bit from that executable:
sudo chmod u-s /bin/ping
A normal user won’t be able to use ping, and if he would try to use it:
The following message will be shown:
ping: icmp open socket: Operation not permitted
Of course, a user with sudo permissions could execute the command with root privileges, but, as said before, this bit is tough for users that do not have superuser privileges.
To add the setuid bit again:
sudo chmod u+s /bin/ping
If the setuid bit allows the user to acquire the permissions of the owner, the setgid (set group id) allows acquiring the permissions of the group. The bit can be set as follows with the octal notation:
sudo chmod 2777 script.sh
Which is set with the 2.
And with the symbolic notation:
sudo chmod g+s script.sh
If the setuid bit was placed in the owner’s execution bit place, in this case, is placed in the execution place of the group:
-rwxrwsrwx 1 who who 14 May 4 08:00 script.sh*
The sticky bit is used in directories, when we want a ﬁle, or folder writable for several users, but where ﬁles and folders insideitcanonlybedeletedbytheowner. This bit is used, for example, in /tmp and /var/tmp directories.
The sticky bit can be assigned the following way:
sudo chmod 1777 sticky/
Where the sticky bit is set with the leading 1, and then, the wanted permissions (which usually are 777 for this cases).
And, with the symbolic notation:
sudo chmod +t sticky/
The sticky bit is expressed with a ‘t’ in the place for the execution bit for others:
drwxrwxrwt 2 who who 4096 May 4 08:00 sticky/
We can see how it works, we can create a ﬁle in our sticky/ directory, try to modify it with the owner and other user, and also to delete it:
echo "written with owner" > file.sh
sudo -u other-user echo "written with other user" > file.sh
Which would work. But if we try to delete it with the user that is not the owner…
sudo -u other-user rm file.txt
We would see:
rm: remove write-protected regular file 'file.sh'?
We can type y to conﬁrm, but…
rm: cannot remove 'file.sh': Operation not permitted
But the owner of the ﬁle could delete it with no problem.
To remove the sticky bit:
sudo chmod -t sticky/
I hope you found it useful.