Understanding file permissions and ownership on Linux

Overview

The Linux filesystem is based on a hierarchical directory structure where the root mount point is defined by the ‘/’ symbol. In fact everything is a collection of files (files, directories, partitions, pipes, sockets, and hardware devices). Directories are used as containers that list other files. Most Linux distributions follow the Filesystem Hierarchy Standard (FHS) for organizing the filesystem structure. Permissions are used to control who can read, write and execute the contents of a file, and ownership indicates to which username and group a file belongs. If you are working as a system administrator, assigning incorrect permissions or ownership can have serious consequences in terms of security. In this article I will explain the theory and show you how to manipulate them using some practical examples.

Linux file types and attributes

Linux supports seven types of files each one having a different purpose. If you are logged in text mode or have a graphical console opened you can see the type of a file by issuing the ‘ls -l‘ command followed by the file name.

From this example we can see that this file is a regular type file which is indicated by the first dash “-“ character at the beginning of the line. The below table shows the known Linux file types and their symbol association.

corresponds to a hardware device to and from which data is transferred in units of one byte

b

Block device file

corresponds to a hardware device to and from which data is transferred in blocks of more than one byte

p

Named pipe

allow communication between two processes running on the same host (FIFO files)

s

Local domain socket

is similar to a named pipe, but it permits network and bidirectional links

l

Symbolic link

contains a reference to another file or directory in the form of an absolute or relative path

The remaining 9 bits after the file type represents the file attributes which are also known as permission bits. These bits are divided in three sequential groups which define the permissions for the owner of the file, the group owners of the file, and everyone else (in this order). Each group of three bits has: a read bit, a write bit, and an execute bit. These three bits actually indicate the permissions supported by a traditional UNIX system.

Read (r) – means you have the permission to open and read the file. In case of a directory, it means you can list the contents of the directory.

Write (w) – means you can open the file and change its contents. If applied to a directory, you can add, remove, and rename files in the directory.

Execute (x) – means you have the permission to execute the file content (e.g. shell script). For directories, it allows you to access files in the directory by searching or navigating through the “cd” command.

In terms of ownership we have three categories: owner (bits 1-3), group (bits 4-6) and others (bits 7-9).

Owner – is the current owner of the file. When a user creates a new file it becomes automatically the owner of that file.

Group – indicates the group who owns the file. All users who belong to this group will have access to the file.

Others – indicates a user which isn’t the owner of the file and does not belons to the group which owns the file.

If we take into account the previous example, you can see that the owner of the file is the ‘root’ user which has read and write permissions, the group is also ‘root’ which is granted only read permissions and the others users have also only read permissions on the file.

Managing file permissions

In order to change the permissions of the file you need to use the chmod command. One thing to keep in mind is that you must be the owner of the file or the superuser in order to change its permissions. The chmod utility support two modes for modifying permissions: the symbolic mode which uses letters and some operators and the octal mode based on numerical values (0-7). When using the symbolic mode the chmod command has the following syntax:

chmod [ugoa][+-=] filename

Each letter between the first set of brackets specifies to whom to apply the permissions and have the following meanings:

u – specifies the user who owns the file (the first set of permissions)

g – specifies the group which owns the file (the second set of permissions)

o – specifies the other users which are not members of the group or owners of the file (the third set of permissions)

a – specifies all users and available on the system (all three sets of permissions).

The next 3 values between the second brackets are used as operators to manipulate permissions. They have the following meanings:

+ adds the selected permissions to the existing ones of each file

– removes the selected permissions from the file

= overwrite the existing permissions of the file and add a new one

To better understand the symbolic mode let’s take some practical examples and see how it works. Let’s assume we have a script in our current folder with the default permissions (-rw-r–r–) and we want to mark it as executable:

# chmod +x scriptfile.sh

This will make the script executable for everyone (a). Now the permission bits will look like this (-rwxr-xr-x). To restrict the execute permission to the owner only run the following command:

# chmod u+x scriptfile.sh

After this the permissions will look like this (-rwxr–r–).Another way to achieve the same result is by removing the executable bit from the group and others

# chmod go-x scriptfile.sh

To simply duplicate the permission from the owner of the file to the group we can simply run something like this:

# chmod g=u scriptfile.sh

Now the permissions will look like this (-rwxrwx—). As you can see by using the ‘=’ operator the read permission from the other users have been removed. Let have one more example. Assign read and write permissions for everybody:

# chmod ugo+rw scriptfile.sh

The permission will look like this (-rw-rw-rw-). Now let’s explain how to use the octal notation for assigning permissions.

Using the octal syntax every group of 3 bits can have a value between 0 and 7. These values are calculated by summing them from the most right bit to the left: read (4), write (2), execute (1), and no permission (0). The next table displays the eight possible combinations for each set of three bits:

Octal

Binary

Permission

Octal

Binary

Permission

0

000

—

4

100

r–

1

001

–x

5

101

r-x

2

010

-w-

6

110

rw-

3

011

-wx

7

111

rwx

For example the “rwx” permission is calculated by adding the individual values for each bit (4+2+1 =7). Using the octal notation you can only specify an absolute value for the permission bits unlike the symbolic mode which can modify bits individually. Let’s use some practical examples for better understanding.

# chmod 644 scriptfile.sh

After running this the permission bits will have these values (-rw-r–r–). Let’s have another example which enables read and write access for all users. Type the following:

# chmod 666 scriptfile.sh

The permission bits will look like this (-rw-rw-rw-). One last example, let’s give full permissions to the owner of the file:

# chmod 700 scriptfile.sh

The permission bits will look like this (-rwx——). By running the chmod utility without any parameter you apply the chnages to only a single file or directory. If you wish to apply changes recursively to multiple file and directories you must use the chmod command with the ‘-R’ option.

# chmod -R 644 /mnt

In this example the permissions will be applied recursively to all file and folders below the /mnt mountpoint. You can also pass the ‘-v’ parameter to display the changes made on the screen.

Managing ownership

Ownership refers to the user and group to which owns a file or directory. Linux offers the chown command for managing ownership. Remember that you must be the owner of the file or the superuser in order to change its owners. The syntax for the chown command is pretty simple.

chown [options] [owner][:group] filename

The owner and group must be valid usernames and groups existent on the affected system. Let’s have some practical examples.

# chown cioby:users scriptfile.sh

In this example the owner of the file is the username ‘cioby’ and the group is ‘users’. As you can see the owner and the group are delimited by a colon ‘:’, but the chown command also accepts a dot ‘.’ as a delimiter for compatibility with older systems.

You can also specify only the owner or the group to be changed individually. For example to change only the group to we would type the following:

# chown :ftpusers scriptfile.sh

In this example only the group is specified preceded by a colon ‘:’. The chown command also provides a ‘-R’ option which is used to apply changes recursively.

# chown -R cioby:users /myfolder

Linux also provides the chgrp command which basically does the same thing as the chown command when is used to change the group owner.

Linux special permissions

Besides the permissions already discussed Linux offers also some special permissions which are used in some particular cases. These are described below:

SUID (SetUID bit) – is used only for executable files and has no effect on directories. Normally when a user launches a program it owns it. When the SUID bit is applied it tells us that the program will run with the file owner’s privileges instead of the user who executes it. One such program is the passwd utility which allows a normal user to run it with root privileges. The SUID bit is indicated by the ‘s’ letter which appears on the owner’s execute bit position (-rwsr-xr-x) and has a value of 4.

SGID (SetUID bit) – this is similar with the SUID bit but it sets the process group owner to the file’s group. When it’s applied to a directory all the new files inside that directory will inherit the group ownership of the directory. For example if directory /home/cioby has the group owner admins and the SGID bit is enabled, then all the files under this directory are will be owned by the admins group regardless of the creator’s group. The SGID bit is also indicated by the ‘s’ letter which appear on the group execute bit position (-rwxr-sr-x) and has a value of 2.

Sticky bit – is used for shared directories to protect files from being deleted by those who don�t own the files. When this bit is set on a directory only the file owner, the directory owner, and root can rename or delete files. When used in a shared environment, the sticky bit allows groups to create and modify files but allows only file owners the privilege of deleting or renaming them. One such example is the /tmp directory which has by default the sticky bit set. The sticky bit is indicated by the ‘t’ letter which appears in the world execute bit position (-rwxr-xr-t) and has a value of 1.

Let’s put in practice this theory through some practical examples. These bits can be set using either symbolic mode or the numerical mode. To set the SUID bit on a file with the default permissions (-rwxr-xr-x) run one of the following commands:

# chmod u+s scriptfile.sh

# chmod 4755 scriptfile.sh

To set the SGID bit on a directory with the default permissions (-rwxr-xr-x) run one of the following commands:

# chmod g+s /myfolder

# chmod 2755 /myfolder

To set the sticky bit on a directory with the default permissions (-rwxr-xr-x) run one of the following commands:

# chmod o+t /tmp

# chmod 1777 /tmp

To simply remove one of this bits using the numerical notation place a ‘0’ before the 9 permission bits like this 0755 to remove the SUID bit,SGID bit and the sticky bit. To remove them individually you can use the symbolic notation with the ‘-‘ operator. Also sometimes you may see that these bits are represented with caps letters (S or T) in the permissions bits. This is due to the fact that execute bit is not set for the corresponding permissions set.

Summary

When working as a system administrator it’s essential to know how Linux manages permissions for maintaining the security of the system. Beyond these permissions discussed here Linux supports some extended file attributes and ACL’s (access control lists) for security management. For more details about permissions you can consult the man pages for the chmod and chown commands.