File permissions in Linux
Thursday, 29 November 2007, adz
In our “Advanced Console Tricks” series we have already covered subjects like Getting help and Processes management. Now it’s time to understand how the file permissions work. In this article we’re going to cover topics such as the basics of Linux file access rights, useful commands that allow you to manage file permissions, as well as numerical and special access modes.
From its beginnings, UNIX was multi-user environment. This feature enforced the implementation of some security mechanisms to secure data and the whole system from unauthorized access. The standard solution is DAC (Discretionary Access Control). In DAC, it is the user’s task to decide on the access rights for files. Due to operating systems development, this model become insufficient. New models were introduced, like MAC (Mandatory Access Control), ACL (Access Control List), and their implementations such as SELinux, TrustedBSD, Trusted Solaris.
2. File owner
Usually, the file owner is the user that has created the file. In UNIX-like operating systems, all files have two owners: user and group. Owners need not be a pair, user doesn’t have to be a group member. But usually it is the case that user belongs to the group that own the file. If a user is neither an owner nor the group owning the file member, it is treated as other. Each user has a designated UID number (user identification number). This enables the system to recognize the user. Root has UID=0 and the last possible number is designated for “nobody” user (for Ubuntu it is 65534, for NetBSD — 32767). Consequently, access rights are UID dependent (not user name dependent). For example, in some systems (e.g. NetBSD) we have root account with UID=0 (that is the second superuser account). Each group has a distinct GID (group identification number). To display the file owner you may use the ls command with -l option.
$ ls -l razem 1822 drwxr-xr-x 3 adam adam 120 2007-09-03 16:00 Desktop -rw-r--r-- 1 adam adam 400 2007-08-22 18:49 prog_09.py
The third and fourth column mean that the user and group own the file.
This is the command that enables changing the group of the file owner. If it is used by an ordinary user, this user must be the file owner and a member of the group he is willing to give access rights to. The interesting fact here is that the user need not to be a member of the group to actually own the file. The syntax is following: chgrp new-group files, you may use a group name or its GID here.
$ ls -l -rw-r--r-- 1 adam root 0 2007-09-03 15:33 file.txt $ chgrp users file.txt $ ls -l -rw-r--r-- 1 adam users 0 2007-09-03 15:33 file.txt
The command might be used with the -R option. It enables recursive group changes for all files and sub-directories. It acts similar to commands described earlier (rm, ls).
This command is used to change owner and group that own the file. In most systems only root can do this. This command has the following syntax: chown new user:new group files. As in the chgrp command, you may use user and group names or just simply use their UID and GID numbers. The command does not check if given numbers are correct so you can use Kids and GIDs of nonexistent users and groups.
$ ls -l -rw-r--r-- 1 adam users 0 2007-09-03 15:33 file.txt root@laptop:# chown root:root file.txt adam@laptop:~$ ls -l -rw-r--r-- 1 root root 0 2007-09-03 15:33 file.txt
Changes the group and the file owner.
root@laptop:# chown zoidberg file.txt
Changes the file owner for user named zoidberg, group is left without any changes.
# chown :futurama file.txt
Changes group for the group named futurama, owner is left without any changes. Chown enables recursive owner’s change when used with option -R.
3. Access rights
In each UNIX-like system we have three kinds of access rights: read (r), write (w) and execute (x).
|r||Read of the file content.||Display content of the directory (e.g. with the command ls).|
|w||Write to the file.||Modify the directory content.|
|x||The right to execute file.||The possibility to enter the directory using the cd command.|
When we analyze the access rights to directories we should remember that we work with files including the names of files put into them and the information about their localization on a disk. To view directory content with the ls command (without any options), it is enough to have the read rights only, but usage of ls -l needs write and execute rights, since this command enforces invisible directories change. Generally speaking, each action on a directory (except simple viewing its content) needs execution rights. Owning execution rights in the case of directories enables access to their content using file names.
drw-r--r-- 2 adam adam 96 2007-09-05 18:04 blob drwxr-xr-x 2 adam adam 176 2007-09-04 15:57 tapety -rw-r--r-- 1 adam adam 125 2007-08-29 18:31 fme.py
Access rights might be viewed using ls command with option -l. The first column shows the file type (first character) and the access rights (next 9 characters). First 3 characters are user access rights, named u after user, next 3 are the group access rights named g after group, and the last 3, other access rights, are marked as o after others.
In the example presented above, blob is a directory, the owner has the right to read and write, but is doesn’t have the right to execute (rw-), the group has the right to read (r), and others have only the right to read(r). Tapety is also a directory, to which owner has the full access right (rwx), the group has the right to read and execute (r-x), and others are able to read and execute (r-x).
It is the command for changing the access rights. Its syntax is following:
chmod access rights files
To give a command you should pick the class of users to whom we want to change access rights (ugo). There is an additional class, a (all). The next step is to pick one of three operators: + gives the right, - takes the right back, and = assigns the right. And in the last step you should give the type of access right (rwx).
$ chmod u+x skrypt.sh
The user gets execution right to the file skrypt.sh.
$ chmod go-r raport.odt
Group and other users will loose the read rights to file raport.odt.
$ chmod a=w finanse.ods
All the classes of user get write right to the file finanse.ods, if one of the classes had read and execute right it would be taken of.
$ chmod u+rwx,g+rwx,o+x trurl.py
User and group get the full access right, others get only the right to execute the file trurl.py.
3.2. Numerical access modes
To simplify the command chmod we may use numerical access rights. Each mode has the numerical value assigned. Using binary notation, it is the case that having the access right is marked as a 1 or a lack of it and is marked as 0. So the access right rwx r-x r-x would be written in binary notation as 111 101 101. Binary notation is not comfortable to use, so it is changed to an eight digit system. The access rights from our example will be written as 755, because 111 is 7 in the eight digit system, and 101 is 5. This method is not as that easy, even for an experienced user, but it is the most simple way to use chmod. You should only remember that the right to read only (r--) is 4, to write only (-w-) is 2, and to execute only (--x) is 1. Now writing down the access right it is enough to give a sum of rights for a given class.
|In symbols||In numbers|
$ chmod u=rwx,g=rwx,o=x trurl.py
would be the same as:
$ chmod 771 trurl.py
3.3. Special access modes
There were few special modes developed that enriches standard ones.
This assigns to the selected classes the right to execute for a given files if and only if this right was assigned other access classes.
$ ls -l -rwx------ 1 adam users 14 2007-09-10 21:48 skrypt.sh drwx------ 1 adam users 14 2007-09-10 21:48 tapety -rw------- 1 root users 3665 2007-09-17 17:23 wynik.txt $ chmod go+X * $ ls -l -rwxr-xr-x 1 adam users 14 2007-09-10 21:48 skrypt.sh drwxr-xr-x 1 adam users 14 2007-09-10 21:48 tapety -rw-r--r-- 1 adam users 3665 2007-09-17 17:23 wynik.txt
Without the X option the file wynik.txt would receive the execution right.
3.3.2. Sticky bit
This kind of access right, when set in the executable file case, results in storing this file in operational memory after a program has stopped working. This option is rarely used nowadays. It was designed to decrease the costs of starting popular programs. This options set for a directory enable deleting the directory contents only for a user of the directory, content file owner or root.
drwxrwxrwt 10 root root 464 2007-09-20 12:45 tmp
Sticky bit is sometimes used for the /tmp directory, which — according to the convention — should be available for all, but users should not have the right to delete files, which they do not own.
Sticky bit for a directory is set using the command chmod:
# chmod u+t test/ # ls -l drwxrwxrwt 2 adam users 48 2007-09-20 15:28 test
Or (using numbers):
# chmod 1000 test/
Setuid for executable files results in running a given program with rights of the file owner (not user, that runs the program). Some administration commands, for example sudo, might need to be set for this mode to work properly.
$ ls -l /usr/bin/ | grep sudo -rwsr-xr-x 1 root root 91508 2006-10-09 13:37 sudo
Setuid mode is set by command chmod, using symbols or numbers.
# chmod u+s program # chmod 4000 program
Setgid mode works just like setuid with one exception, it is run on the rights of file owners’ group. In case of directories the group that owns newly created file would be group owning a given directory (not the group of user that created the file). To set setgid mode the commandchmod is used.
# chmod g+s test/ # chmod 2000 test/ # ls -l drwxrwsrwt 2 adam adam 48 2007-09-20 15:28 test
The umask command is used to set default access mode for all newly created files. Its option consist of the access rights (written numerically) that will not be assigned. The access mode is set performing the binary operation:
default value AND NOT (umask value)
Simply speaking: it is enough to subtract umask value from the default mode expressed in eight digit system (default value is 666).
$ umask 0022 $ touch file $ ls -l -rw-r--r-- 2 adam adam 48 2007-09-20 15:28 file umask 0111 $ ls -l -rw-rw-rw- 1 adam adam 0 2007-09-20 17:31 file2