File permissions in Linux

Linux is a file-based system, it considers directories, drives, devices, etc as files. The actions you are allowed to perform on a Linux system depends on the permissions you have to these files.

The primary permissions

The three primary permissions are read, write, and execute. They have different meanings when applied to files and directories.

Files

Read Permission: Allows you to read the contents of a file. You can cat the contents of a text file to the terminal or open a file using an application.

Write Permission: Allows you to modify the contents of a file.

Execute Permission: Allows you to execute the file. This permission is relevant only for executable files, which may be binary files or script files like BASH script, Perl script, etc. For a script file execute permission is useless unless it has read permission as well since some interpreter needs to read the file.

Directories

With directories, the permissions are not as straightforward.

Read Permission: Allows you to see the contents of a directory. You can list the contents of a directory in the terminal or open the directory in a file manager. Denying read permission does not make the contents of the directory read proof. The directory is a special file that contains a list of files and subdirectories inside it. Without read permission, you cannot read the contents of this special file. But if you already know a file exists in the directory and has read permission to the file, you can read the file.

Write Permission: Allows you to create and delete files and subdirectories in the directory, provided that you also have execute permission. If a write-protected directory is empty it can be deleted as long as you have write permission to its parent directory.

Execute Permission: Without execute permission the only thing you can do with a directory is to list the names of its contents. To use the path to a directory for any other operation you need execute permission. For example, you cannot CD into the directory or view the contents of a file in the directory or remove a file from a directory since you need to use the path to the directory for these operations.

Users, groups, and others

The permission you have on a file depends on your role in relation to the file. These roles could be the following.

User: A user is effectively the owner of the file. When you create a file, by default, you will be the user of the file. This can be changed later.

Group: If a user belongs to the same group which the file belongs to, the user will have group permissions. Note: conditions apply, see below about cumulative permissions.

Other: Somebody who is neither a user or have group permission.

Permissions are not cumulative

Permissions in Linux are not cumulative and it goes in the order user, group, and then other. If you are a user you get only the permissions of the user; group permissions and other’s permissions do not apply to you. If you are not a user but a group member, you get only group permissions, you will not get other’s permissions along with it. This is usually not an issue since permissions tend to decline as we go from user to group to others, but might cause confusion in rare cases.

Viewing file permissions

Use the ls -l command to view file permissions.

av@ubuntu:~$ ls -l script.sh 
-rwxr-xr-- 1 av av 10 May 18 14:39 script.sh
Breakdown of sample ls -l output
Type of file.
rwxr-xr-- Read, write and execute permissions for owner, group, and others
1 Number of links
av User
av Group
10 Size
May 18 14:39 Date and time
script.sh Filename

File Types

The type of file can be any of the following:-

Symbol Description
Normal file
d Directory
l Link
p Named Pipe
c Character Device
b Block Device

To view permissions of a directory use the command ls -ld <directory name>

The permission string

The nine characters coming after the filetype is what represents the file permissions. The first three letters represent permissions for the user, the next three letters represent permissions for the group and the last three letters represent permissions for others (everyone else). The permissions are written in the order read, write, execute.  A dash represents a lack of that particular permission.

 

Linujx file permissiions

Changing Permissions with chmod

You can use the chmod command to change file permissions. The chmod command has two forms the numeric form and the symbolic form.

Numeric method

In the numeric method, we normally use three octal (base 8) numbers to specify permissions. A fourth leading-digit can be used to specify some special permissions but this is optional. The special permissions are discussed later in the article.

Numbers assigned to permissions
Priority Octal Binary
No Permission 0 000
Execute 1 001
Write 2 010
Read 4 100

The permissions are powers of 2 in the reverse order they are listed by the ls -l command. To learn how to use these numbers, let us start with the simplest possible example. Let us say we want to give only read permission to the user, group, and others. Here is the command:-

av@ubuntu:~$ ls -l help.txt 
-rw-rw-r-- 1 av av 0 Jun 12 16:38 help.txt
av@ubuntu:~$ chmod 444 help.txt 
av@ubuntu:~$ ls -l help.txt 
-r--r--r-- 1 av av 0 Jun 12 16:38 help.txt

At the start, the file help.txt has rw-rw-r-- permission, then we run the chmod command. We end up with the permission r--r--r--. The first 4 in chmod gives read permission to the user, the second 4 gives read permission to the group and the last 4 gives read permission to others. This is an easy to remember order since permissions are listed in the order user, group, and then others.

One thing to note about the numeric method of chmod is that existing permissions do not matter, the command starts with a clean slate. Since we asked for only read permission we get only that, the previous permissions that used to be there are gone.

Now we need to learn how to give additional permissions. Let us say we want read and write permission for users and group and read permission for others. How are we going to do that with only three digits to specify the permissions? We just add the numbers: read + write = 4 + 2 = 6. So our permission number will be 664.

av@ubuntu:~$ chmod 664 help.txt 
av@ubuntu:~$ ls -l help.txt 
-rw-rw-r-- 1 av av 0 Jun 12 16:38 help.txt

If we have a script file and need the following permission:

user: read, write and execute = 4+ 2+ 1 = 7
group: read and execute  = 4 + 1 = 5
other: read = 4

av@ubuntu:~$ chmod 754 script.sh 
av@ubuntu:~$ ls -l script.sh 
-rwxr-xr-- 1 av av 10 Jun 12 18:34 script.sh

Symbolic method

With the symbolic method, we can tweak existing permissions. Let us see what the various symbols represent.

Symbols representing user roles
Symbol Role
a All
u User
g Group
o Other

The permissions are represented by r, w and x as you would expect, we have already seen that in the output of ls -l. The symbolic method has mainly three forms:

  • Add permissions to the existing set.
  • Remove permissions from the existing set.
  • Assing brand new permissions instead of old ones. This form is similar to the numeric method, but the symbolic method supports more fine-grained control.

To give execute permission to all users:

av@ubuntu:~$ ls -l script.sh 
-rw-r--r-- 1 av av 10 Jun 12 18:34 script.sh
av@ubuntu:~$ chmod a+x script.sh 
av@ubuntu:~$ ls -l script.sh 
-rwxr-xr-x 1 av av 10 Jun 12 18:34 script.sh

Notice the important difference between the numeric method and the symbolic method, here execute permission was given to all but the other existing permissions remained unchanged.

To give write permission to group and others:

av@ubuntu:~$ ls -l script.sh 
-rwxr-xr-x 1 av av 10 Jun 12 18:34 script.sh
av@ubuntu:~$ chmod go+w script.sh 
av@ubuntu:~$ ls -l script.sh 
-rwxrwxrwx 1 av av 10 Jun 12 18:34 script.sh

To remove write and execute permission from others:

av@ubuntu:~$ ls -l script.sh 
-rwxrwxrwx 1 av av 10 Jun 12 18:34 script.sh
av@ubuntu:~$ chmod o-wx script.sh 
av@ubuntu:~$ ls -l script.sh 
-rwxrwxr-- 1 av av 10 Jun 12 18:34 script.sh

You can also combine more than one addition or subtraction in a single command:

av@ubuntu:~$ ls -l script.sh 
-rwxrwxr-- 1 av av 10 Jun 12 18:34 script.sh
av@ubuntu:~$ chmod g-w,o+x script.sh 
av@ubuntu:~$ ls -l script.sh 
-rwxr-xr-x 1 av av 10 Jun 12 18:34 script.sh

If you want functionality similar to the numeric method, use the equals option. With equals you only get the permissions you ask for, the earlier permissions are erased.

av@ubuntu:~$ ls -l test/1.py
-rwxrwxr-- 1 av av 0 Jun 13 11:36 test/1.py
av@ubuntu:~$ chmod u=rwx,g=rx,o=rx test/1.py
av@ubuntu:~$ ls -l test/1.py
-rwxr-xr-x 1 av av 0 Jun 13 11:36 test/1.py

As with adding and removing permissions, setting absolute permissions using equals can be done for selective roles. Here the permission of others is completely replaced with a new set of permissions but the permissions of users and group remain untouched.

av@ubuntu:~$ ls -l test/1.py
-rwxr-xrwx 1 av av 0 Jun 13 11:36 test/1.py
av@ubuntu:~$ chmod o=rx test/1.py
av@ubuntu:~$ ls -l test/1.py
-rwxr-xr-x 1 av av 0 Jun 13 11:36 test/1.py

Changing Permissions of multiple files

The chmod -R option can be used to change permissions on multiple files.

To give read permission to all files and directories in the test directory to others:

chmod -R o+r test/

You can also use the find command to find the files you want and then run chmod on them. To give execute permission to the user to all py files in the test directory: 

find test/ -iname "*.py" -exec chmod u+x {} \+

Numeric method vs Symbolic method

If you know the full set of permissions that a file must have then the numeric method is a very concise way to specify that. For small tweaks to existing permission, the symbolic method is easier. To tweak existing permissions on a large number of files, the symbolic method is required. For example, to give others read permission to all files in a directory without touching other existing permissions, you need the symbolic method.

Special permissions

We have already seen read, write, and execute permissions. Now let us look at setuid, setgid, and the sticky bit. These permissions are not commonly used but are useful in some situations.

Special permissions work as intended only if execute permission is also set.

Setuid

Setuid is a risky addition to execute permission for users. To understand this permission let us look at a use case. You can use the passwd command to change your password. This command does not require root privileges, but the passwords are stored in /etc/shadow file which does require root privileges, as you would expect.

av@ubuntu:~$ ls -l /etc/shadow
-rw-r----- 1 root shadow 1163 Mar 21 18:02 /etc/shadow

So how did a user process manage to change a file belonging to the root? Setuid is the answer; see the permissions for the passwd executable file.

av@ubuntu:~$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 59640 Mar 23  2019 /usr/bin/passwd

The file belongs to the root, but it has an s where user execute permission would normally be. This allows the file to be executed by any user with privileges of the owner, root in this case. Needless to say, this option should be used with extreme caution.

Why setuid?

So why is it okay for passwd to use setuid? It is because the passwd program has a narrow, clearly defined scope. It does not allow ordinary users to perform unsafe operations. If you use setuid on something like mv or rm there would be absolute chaos. What benefit do we get from using setuid for passwd? The user needs access to a root file where the password is stored. The only alternative is to force the user to acquire root privileges temporarily. This is unnecessary and counter-productive for an otherwise safe command like passwd.

How to give setuid permission

Use the following command to allow setuid permission.

av@ubuntu:~/test$ chmod u+s hello.py
av@ubuntu:~/test$ ls -l hello.py
-rwsrw-r-- 1 av av 0 Jun 13 11:36 hello.py

Setgid

Setgid is similar to setuid, the only difference is that in setgid the program runs with group permissions instead of user permissions.  To give setgid permission to a file, use the following command:

av@ubuntu:~/test$ chmod g+s hello.py
av@ubuntu:~/test$ ls -l hello.py
-rwxrwsr-- 1 av av 0 Jun 13 11:36 hello.py

Notice that the output of ls -l command has an s where group-execute permission would normally be.

Sticky Bit

The sticky bit is a special permission that is applicable to directories. It is useful for shared directories where everyone must have write access. The problem with such a directory is that anyone who can write to the directory can also delete files from it. So a user can delete files belonging to other users even if they have no permission to the file itself. The sticky bit can solve this problem. If sticky bit is set on the directory, users can delete only those files which they own. To set the sticky bit use the following command:

av@ubuntu:~$ chmod +t test/
av@ubuntu:~$ ls -ld test
drwxrwxrwt 4 av av 4096 Jun 13 12:39 test

Notice that, in the output of ls -l there is a t where group-execute permission would normally be.

If a special permission is set without corresponding execute permission, the s and t symbols would be capitalized in the ls -l output.

Numeric method for special permissions

As mentioned earlier, the numeric method of chmod has an optional leading digit to represent special permissions. The numbers representing special permissions are as follows.

Special Permissions
Number Permission
1 Sticky Bit
2 Setgid
4 Setuid

To set the sticky bit on a directory, use the following command

av@ubuntu:~$ chmod 1777 test/
av@ubuntu:~$ ls -ld test/
drwxrwxrwt 4 av av 4096 Jun 13 12:39 test/

As earlier, you can combine permissions by adding the numbers.

Leave a Comment

Your email address will not be published. Required fields are marked *