Linux File Permissions

Managing permissions in Linux

File Permissions


In this section we will be looking at file permissions for users, groups and others. As we saw earlier in the course, the "ls -l" command displays all files in the extended or long form:



$ ls -l /bin/ls
-rwxr-xr-x 1 root root 104508 Nov 19 22:25 /bin/ls

After issuing the "ls -l" command for a specific file. (In this case, the binary for the ls command) we can see that in the first column of the output there are some "-"and "rwx" information. This first column is for setting the permissions and identifying whether we are dealing with a file or directory. Columns two and three indicate the owner and group.

Basically every file on a Linux system is owned by a user and a group and others.

User - The username of the person who owns the file. Normally whoever creates the file becomes the default user.

Group - The owning usergroup for a file. Users who belong to this group will have the same permissions to the file. The group setting is used to share access and deny access to users. This allows information to be easily and safely shared.

Other - This is the name given to a user who is not the owner of the file and does not belong to the group owner of the file.



3 Types of permission


There are three types of access permissions on a Linux system. These are "Read - 'r' ", "Write - 'w' " and "Execute - 'x'. These permissions are set separately for the owner, group and other users.

Read: On a regular file, the read permission means that the file can be opened and read. On a Directory, the read permission will allow you list the contents of the directory.

Write: On a regular file, this permission means that you can modify a file (write data to the file). On a Directory the Write permission means that you can add, remove and rename files within that directory.

Execute: On a regular file this setting means you can execute this file as a program or script. On a Directory the execute bit means that you can access files within the directory, however, if you wish to list the files within that directory, you will need the read permission flag set!

In the following example we can see that "mydir" is a directory. Because the first column begins with a "d". The owner of this directory is the user "landoflinux" and the group owner is "john". The first three permission bits are set to "rwx", indicating that the directory owner "landoflinux" has full access to the directory. The user "landoflinux" is able to access,view and modify files in that directory.

The next three bits "r-x" tell us that all users belonging to the group "john" have read and execute permissions to the directory. This means that they can change into the directory, execute files and view its contents. However, they do not have write permissions to make any changes to the directory content.

The final three bits "r-x" means that all users who are not "landoflinux" and do not belong to the group "john" have read and execute permissions in the directory.



drwxr-xr-x 2 landoflinux john 4096 Jan 19 11:13 mydir
-rw-r----- 1 landoflinux john  190 Jan 19 10:43 testfile1

In the example above we have a file called "testfile1". Here we find the first column begins with a "-". This indicates a regular file owned by the user "landoflinux" with a group of "john". The first three bits "rw-" indicate the owner has read and write access to that file.

The next three bits of information "r--" indicate that any user who is in the group "john" can view the file. They can not write to this file or execute this.

And finally the last three bits of information "---" indicate that no one else can access this file.

So far we have seen that the first character can be a "d" for directory or a "-" for a regular file. However, there are quite a few other indicators which you will come across whilst using a linux system. The table below illustrates this:


Identifier Description
- Regular File
d Directory
c Character Device File
b Block Device File
p fifo
s Socket
l Symbolic link

Some examples of this first bit of information in column one



drwxr-xr-x  3 root root           180 Jan 19 09:13 snd
brw-rw----+ 1 root cdrom      11,   0 Jan 19 09:13 sr0
lrwxrwxrwx  1 root root            15 Jan 19 09:13 stderr -> /proc/self/fd/2
crw-rw-rw-  1 root tty         5,   0 Jan 19 09:13 tty
srw-rw-rw-  1 root root             0 Jan 19 09:13 log

Permissions and how to set them


Before we take a look at the commands that allow you to modify permissions on files for user and groups, it would be useful to find some information about the user you are logged in with. Assuming that you have not used the "su" command to switch to another account, you are using the account that you logged in with.

whoami
The "whoami" command when issued will report information back on the current user at the shell:



john@john-desktop:~$ whoami
john

Here we can see that I am the user "john"

groups
The "groups" command when issued will indicate what groups you are a member of:



john@john-desktop:~$ groups
john adm dialout fax cdrom floppy tape dip video plugdev fuse lpadmin admin sambashare

From this output we can see that the user "john" is a member of several groups.

id
Another handy command to use is the "id" command, this command will display who you are, your uid (your unique id) and any group memberships that you have along with the gid (group id numbers). The command can also be used with other userids to see what groups they belong to:



john@john-desktop:~$ id
uid=1000(john) gid=1000(john) groups=1000(john),4(adm),20(dialout),21(fax),24(cdrom),25(floppy),26(tape),30(dip),44(video),46(plugdev),104(fuse),112(lpadmin),120(admin),123(sambashare)

john@john-desktop:~$ id landoflinux
uid=1002(landoflinux) gid=1002(landoflinux) groups=1002(landoflinux)

Setting Permissions


The setting of permissions on files can be carried out by the root user and the file owner. The command used for changing permissions is chmod. There are two different ways to use the "chmod" command. You can either use the symbolic method or the alternative numeric method. Both methods when used will achieve the same result.


Setting File permissions with the symbolic method


Firstly you must decide which permissions we are going to change. Do you want to set permissions for the user "u" or the group "g" or for others "o" or all three all "a".

Once you have decided what permissions you are going to set, you need to pass either a "+" to add or a "-" to remove the permission. You may wish to clear all permissions previously set by using the "=" option.

Next you will have to decide if you are going to give "read(r), write(w),execute(x) or none(-) to which section..

Have a go at creating yourself a file called testfile and then try some of the examples commands below:

The first command we will issue will be to set user,group and other fields to a value of read(r). "chmod a=r testfile"
This will give us the following result: "-r--r--r-- 1 john john 0 Jan 19 19:46 testfile"

Next we will add the execute(x) permission to groups. "chmod g+x testfile"
This will now give us: "-r--r-xr-- 1 john john 0 Jan 19 19:46 testfile"

Now lets add the write(w) and execute(x) permissions to the user section. "chmod u+wx testfile"
Now we have the following permissions set: "-rwxr-xr-- 1 john john 0 Jan 19 19:46 testfile"

Finally we remove the execute(x) permissions from the user and group section. "chmod ug-x testfile"
Now the permissions settings for the testfile should be: "-rw-r--r-- 1 john john 0 Jan 19 19:46 testfile"

An example of the above commands being applied is below. Feel free to experiment.



john@john-desktop:~/test_examples$ pwd
/home/john/test_examples
john@john-desktop:~/test_examples$ touch testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-rw-rw-r-- 1 john john 0 Jan 19 19:46 testfile
john@john-desktop:~/test_examples$ chmod a=r testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-r--r--r-- 1 john john 0 Jan 19 19:46 testfile
john@john-desktop:~/test_examples$ chmod g+x testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-r--r-xr-- 1 john john 0 Jan 19 19:46 testfile
john@john-desktop:~/test_examples$ chmod u+wx testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-rwxr-xr-- 1 john john 0 Jan 19 19:46 testfile
john@john-desktop:~/test_examples$ chmod ug-x testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-rw-r--r-- 1 john john 0 Jan 19 19:46 testfile


Setting File permissions the numerical way


As mentioned earlier there are two methods for setting file permissions using the chmod command. In the first section we looked at the symbolic method. Now we are going to use the numeric method.

As we saw earlier, we have the permissions read(r), write(w), execute(x) and none(-). With the numeric method we are going to substitute the letters with numbers ( 3 digit Octal numbers):

4 = read(r)
2 = write(w)
1 = execute(x)
0 = none(-)

To set the permissions that you desire, you need to add the numbers together to get your permission setting.

Permission Read(r) Write(w) Execute(x) Value
rwx 4 2 1 7
rw- 4 2 0 6
r-x 4 0 1 5
r-- 4 0 0 4
-wx 0 2 1 3
-w- 0 2 0 2
--x 0 0 1 1
--- 0 0 0 0


The more you use this method, the quicker and easier it gets. Lets now combine some of the permissions now for users,groups and other:

"rwxrwxrwx" is the equivalent of "User = 4 + 2 + 1 = (7)" + "Group = 4 + 2 + 1 = (7)" + "Other = 4 + 2 + 1 =(7)"
So now we can see that the permissions for user = (7), group = (7) and other =(7)

So now we can construct our chmod command : "chmod 777 testfile"

Now lets try "rwxr-xr-x": First break down each section. "User = 4 + 2 + 1 = (7)" + "Group = 4 + 0 + 1 = (5)" + "Other = 4 + 0 + 1 = (5)"
So now we have User = 7 Group = 5 Other = 5

Our chmod command will now look like: "chmod 755 testfile"



john@john-desktop:~/test_examples$ ls -l
total 0
-rw-r--r-- 1 john john 0 Jan 19 19:46 testfile
john@john-desktop:~/test_examples$ chmod 777 testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-rwxrwxrwx 1 john john 0 Jan 19 19:46 testfile
john@john-desktop:~/test_examples$ chmod 755 testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-rwxr-xr-x 1 john john 0 Jan 19 19:46 testfile

Umask - File creation mask


When a file is created by a process it is automatically assigned a given permission. Files are initially created with a value of 0666, then the umask value is subtracted. This normally will reduce certain permissions.

The command used to display your umask settings is "umask". To get a none numeric view of your umask,
issue the following "umask -S". Your umask settings will now be displayed.



john@john-desktop:~/test_examples$ umask
0002
john@john-desktop:~/test_examples$ umask -S
u=rwx,g=rwx,o=rx

So on my current system my userid has a umask of 0002. To make things easier, we are going to ignore the leading "0". This gives me a value of "002". Remember we said all files are created with 666 then the umask value is subtracted. Lets take a quick look at that in action:



john@john-desktop:~/test_examples$ touch testfile
john@john-desktop:~/test_examples$ ls -l
total 0
-rw-rw-r-- 1 john john 0 Jan 19 22:05 testfile

So if the file was originally 666, it now has a value of 664!



6 6 6
0 0 2  -
-----
6 6 4

From the simple calculation, we can now see how the permissions were calculated.

Well it is not only files that have to obey the umask. Directories permissions are calculated against the umask when they are created.
The only difference is that directories start off with an initial value of 777 (rwxrwxrwx). However, once the umask has been applied this is often lowered.



john@john-desktop:~/test_examples$ mkdir testdir
john@john-desktop:~/test_examples$ ls -l
total 4
drwxrwxr-x 2 john john 4096 Jan 19 22:17 testdir

Again we can see that my umask of 002 has been subtracted from the initial value of 777.



7 7 7
0 0 2  -
-----
7 7 5

Although my umask is set to 002, another very popular value is 022. The majority of Enterprise systems I have worked on have used 022.


What are SUID, SGID and Sticky Bits?


As we have seen earlier, there are permissions that can be set for the owner, group and others on a file. However, these are not the only permission bits that can be set. There are also permission bits called the "Sticky Bit", "SUID" and "SGID".


Sticky Bit


Originally the sticky bit was an indicator that a particular program or application should remain in memory when executed. This method of marking programs and applications allowed multiple users to initialise programs faster as they were already loaded into memory. The Sticky bit originated from the early days of Unix Systems when fast disk and large amounts of memory were not available. In today's modern world of technology the sticky bit no longer really serves its original purpose. Today, the sticky bit is mainly used for modifying permissions on directories. Once a sticky bit has been set on a directory, then only the creator of files within can delete their files.

A good example of this in action is the "/tmp" directory. Here, anyone can write files to this temporary location, however, only the user that created the file can delete it. Remember that files within a directory that has the write permissions set can be deleted, even if the file doesn't have write permissions. So in the case of the "/tmp" area, the sticky bit is very useful. Below is an example of "/tmp" directory with its sticky bit set. Note the sticky bit is defined with a permission of "t":



 john@john-desktop:~$ ls -ld /tmp
drwxrwxrwt 17 root root 20480 Jan 20 11:28 /tmp

Let us now look at how we can set the sticky bit on a directory. Here we are going to use the familiar "chmod" command in both symbolic and numeric formats to create and remove the sticky bit:



john@john-desktop:~/test_examples$ ls -l
total 4
drwxr-xrwx 2 john john 4096 Jan 20 11:46 testdir
john@john-desktop:~/test_examples$ chmod o+t testdir
john@john-desktop:~/test_examples$ ls -l
total 4
drwxr-xrwt 2 john john 4096 Jan 20 11:46 testdir
john@john-desktop:~/test_examples$ chmod o-t testdir
john@john-desktop:~/test_examples$ ls -l
total 4
drwxr-xrwx 2 john john 4096 Jan 20 11:46 testdir
john@john-desktop:~/test_examples$ chmod +t testdir
john@john-desktop:~/test_examples$ ls -l
total 4
drwxr-xrwt 2 john john 4096 Jan 20 11:46 testdir
john@john-desktop:~/test_examples$ chmod -t testdir
john@john-desktop:~/test_examples$ ls -l
total 4
drwxr-xrwx 2 john john 4096 Jan 20 11:46 testdir
john@john-desktop:~/test_examples$ chmod 1757 testdir
john@john-desktop:~/test_examples$ ls -l
total 4
drwxr-xrwt 2 john john 4096 Jan 20 11:46 testdir

SUID


On Linux systems we use the "SUID" bit to allow executables and scripts to be executed with special permissions. For instance the executable program "passwd" is owned by root, however, any user can run this to change their password and update the passwd file. Let us locate the "passwd" file and take a look at its permissions:



john@john-desktop:~$ whereis passwd
passwd: /usr/bin/passwd /etc/passwd /usr/bin/X11/passwd /usr/share/man/man5/passwd.5.gz /usr/share/man/man1/passwd.1ssl.gz /usr/share/man/man1/passwd.1.gz
john@john-desktop:~$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 41284 Sep 12 23:29 /usr/bin/passwd
john@john-desktop:~$ ls -l /etc/passwd
-rw-r--r-- 1 root root 1905 Jan 17 20:15 /etc/passwd
john@john-desktop:~$ ls -l /etc/shadow
-rw-r----- 1 root shadow 1352 Jan 17 20:16 /etc/shadow

If we look at the output from the "ls -l /usr/bin/passwd" file, we can see that this program has the "suid" set. Once this sticky bit has been set under the user section "rwsr-xr-x", this will allow any user to run the "passwd" command as root. The reason for the sticky bit is to allow users to update the /etc/passwd and /etc/shadow files which normally only the root user can do. If the sticky bit was not set, then users would not be able to change their passwords as they would not be able to update the passwd/shadow files.


Setting the SUID


To set the "suid" permission on an executable we will use the "chmod" command. Permissions can be set in the normal manner using chmod:
"chmod u+s testfile" would set the suid bit on the file testfile. You can also use the numeric equivalent of "chmod 4775 testfile"



john@john-desktop:~/test_examples$ ls -l
total 0 -rwxrwxr-x 1 john john 0 Jan 20 12:45 test.sh john@john-desktop:~/test_examples$ chmod u+s test.sh john@john-desktop:~/test_examples$ ls -l total 0 -rwsrwxr-x 1 john john 0 Jan 20 12:45 test.sh john@john-desktop:~/test_examples$ chmod -s test.sh john@john-desktop:~/test_examples$ ls -l total 0 -rwxrwxr-x 1 john john 0 Jan 20 12:45 test.sh john@john-desktop:~/test_examples$ chmod 4775 test.sh john@john-desktop:~/test_examples$ ls -l total 0 -rwsrwxr-x 1 john john 0 Jan 20 12:45 test.sh

Setting the SGID on Directories


If a directory has the sgid set then any filesystem objects will inherit the group of the directory. This functionality can be very useful when you have different users creating files in one location. Consider the following:



root@john-desktop:~# mkdir /home/shared
root@john-desktop:~# chgrp marketing /home/shared
root@john-desktop:~# chmod g+s /home/shared

The above structure will allow users who are in the group "marketing" to create files and directories within the directory "/home/shared". This files will automatically be assigned a group ownership of "marketing" as well. You may need to consider a users umask setting with this setup. New filesystem objects may or may not be readable, writeable or executable by other members of the group marketing. Whenever you create new directories and permissions, it is always wise to fully understand what you are trying to achieve before you start rolling out any solutions!