Example of Setting Linux File Permissions

A recent exercise I gave ITS335 IT Security students was to create some users in Linux and explore the storage of passwords and basic access control mechanisms (i.e. permissions). In this article I demonstrate a possible solution. It includes examples of basic user management and permission commands such as:

Examples of files /etc/passwd, /etc/shadow and /etc/group are also given.

The focus of this article is showing example of the commands and output. I don't attempt to explain the details of each command. If you've never used the commands, the most of them are well-explained in their man pages. On the terminal type: man command. Alternatively you can watch some of YouTube screencasts on Linux File Permissions:

This demo is performed on a virtnet node called node1. The default user, which has sudo access, is called network. The Linux distribution release and Linux kernel version are shown using the commands lsb_release and uname, respectively.

network@node1:~$ lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 12.04.3 LTS
Release:	12.04
Codename:	precise
network@node1:~$ uname -a
Linux node1 3.8.0-29-generic #42~precise1-Ubuntu SMP Wed Aug 14 15:31:16 UTC 2013 i686 i686 i386 GNU/Linux

The first task is to add some users. I'll add three users called steve, thanaruk and cholwich. The command used is adduser, which creates the user and their home directory and prompts for information about the new user, including password.

network@node1:~$ sudo adduser steve
Adding user `steve' ...
Adding new group `steve' (1001) ...
Adding new user `steve' (1001) with group `steve' ...
Creating home directory `/home/steve' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for steve
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n] 
network@node1:~$ sudo adduser thanaruk
Adding user `thanaruk' ...
...
Is the information correct? [Y/n] 
network@node1:~$ sudo adduser cholwich
Adding user `cholwich' ...
...
Is the information correct? [Y/n] 

User information is stored in two configuration files: /etc/passwd and /etc/shadow. Lets first look at /etc/passwd. On a Ubuntu system there are many system users already. Rather than showing the details of system users I want to see the details of the 3 newly created users. So we can use tail to show the last 3 lines of the file /etc/passwd. (If you want to see the entire file, use cat /etc/passwd).

network@node1:~$ tail -3 /etc/passwd
steve:x:1001:1001:,,,:/home/steve:/bin/bash
thanaruk:x:1002:1002:,,,:/home/thanaruk:/bin/bash
cholwich:x:1003:1003:,,,:/home/cholwich:/bin/bash

Each line contains information about a single user, with fields separate by a colon (:). The first field is the username. The second field we see an 'x'. This field is for the password, but the value 'x' is a special value that indicates password information is stored in a separate file /etc/shadow. We'll see that file shortly. The third field is the user ID. In Linux, users are in fact identified by this ID. The username is just a more friendly identified of the user. The fourth field is the group ID for this user. We see the group and user IDs are identical in this example, but it doesn't have to be. We'll see the group names shortly. The field with three commads (,,,) normally stores the users full name, office, phone number etc. But when I created the users I left this information blank. The sixth field is the users home directory and the last field is the shell program that is run when the user logs in.

Further explanation of the structure of the /etc/passwd file can be found by reading the man page: man -S5 passwd.

The special value of 'x' in the password field in /etc/passwd indicates password information is stored in /etc/shadow. Below we see the password information for our 3 new users.

network@node1:~$ sudo tail -3 /etc/shadow
steve:$6$9TX8CxpR$GTaHPOnAseQHIDrpV2bm5kOZ5wf1G/rjXI5o/AtfBN6Ts.WdQlwnxDpXTnWV5ynXFhIkP5hfUdj4pWI2Y8A9M0:16075:0:99999:7:::
thanaruk:$6$FLJBCaNe$l0MS4aMPJtZ6wMajKKP9lKNqTqkccyGiABPF5pePOnvbvdSBcr.uM8hMSVPN5Q1l3YfCHtpG.JG6W7DqnPr4F0:16075:0:99999:7:::
cholwich:$6$by3fbvXY$D5H2ZGgz0m2vCXVzWhQxr4ZqeSeboj8IeTCExF37F/5uHO168K/0AdzucVTaAY9WqyBp8nUs0V/7gJPjwZ/Ay/:16075:0:99999:7:::

The structure of the /etc/shadow file is explained in the man page: man -S5 shadow. Let's focus on the second field, which is in fact split into three sub-fields separated by dollar signs ($). Take for example the value for steve.

For an explanation on why the hash of a salted password is stored, see my article on passwords, hashes and rainbow tables. For details on the format of these fields, including the list of hash algorithms, see the man page: man crypt (the relevant information is in the Notes under Glibc notes).

Now lets create a new group called instructors using the addgroup command. The group name and group ID is stored in the file /etc/group.

network@node1:~$ sudo addgroup instructors
Adding group `instructors' (GID 1004) ...
Done.
network@node1:~$ tail -4 /etc/group
steve:x:1001:
thanaruk:x:1002:
cholwich:x:1003:
instructors:x:1004:

Recall the /etc/passwd file lists a users primary group ID. For example, steve is in the group 1001; the file above shows the name of group 1001 is steve (the group name and user name do not have to be the same; its just the default in Ubuntu). In addition, others may be in a group. Lets add steve and cholwich to the group instructors using the command adduser.

network@node1:~$ sudo adduser steve instructors
Adding user `steve' to group `instructors' ...
Adding user steve to group instructors
Done.
network@node1:~$ sudo adduser cholwich instructors
Adding user `cholwich' to group `instructors' ...
Adding user cholwich to group instructors
Done.
network@node1:~$ tail -4 /etc/group
steve:x:1001:
thanaruk:x:1002:
cholwich:x:1003:
instructors:x:1004:steve,cholwich

We now see in the file /etc/group that instructors contains steve and cholwich.

We now have three users, each in their own group, as well as two of those users in another group. To demonstrate access control in Linux (i.e. permissions), we first need some files and directories. The following shows the creation of some dummy files and directories for each user. We will set the permissions later. The command su is used to switch to another user (of course you need that users password). There are many ways to create files: I created simple text files by echoing a string into a file.

network@node1:~$ su thanaruk
Password: 
thanaruk@node1:/home/network$ cd
thanaruk@node1:~$ mkdir teaching
thanaruk@node1:~$ mkdir private
thanaruk@node1:~$ echo "notes" > notes.txt
thanaruk@node1:~$ echo "exam" > teaching/exam.txt
thanaruk@node1:~$ echo "personal" > private/personal.txt
thanaruk@node1:~$ exit
exit
network@node1:~$ su steve
Password: 
steve@node1:/home/network$ cd
steve@node1:~$ mkdir lab
steve@node1:~$ mkdir its335
steve@node1:~$ echo "papers" > papers.txt
steve@node1:~$ echo "manual" > lab/manual.txt
steve@node1:~$ echo "quiz" > its335/quiz.txt
steve@node1:~$ exit
exit
network@node1:~$ su cholwich
Password: 
cholwich@node1:/home/network$ cd
cholwich@node1:~$ mkdir lecture
cholwich@node1:~$ echo "week1" > lecture/week1.txt
cholwich@node1:~$ echo "schedule" > schedule.txt
cholwich@node1:~$ exit
exit

Now we will look at and when necessary change the permissions for each user.

The access control requirements for thanaruk is that no-one else can access his files or directories. First lets switch to user thanaruk, cd into his home directory, and then list all files/directories recursively (i.e. list the files/directories in his home, then the files/directories in those directories, and so on).

network@node1:~$ su thanaruk
Password: 
thanaruk@node1:/home/network$ cd
thanaruk@node1:~$ ls -lR
.:
total 12
-rw-rw-r-- 1 thanaruk thanaruk    6 Jan  5 09:44 notes.txt
drwxrwxr-x 2 thanaruk thanaruk 4096 Jan  5 09:45 private
drwxrwxr-x 2 thanaruk thanaruk 4096 Jan  5 09:45 teaching

./private:
total 4
-rw-rw-r-- 1 thanaruk thanaruk 9 Jan  5 09:45 personal.txt

./teaching:
total 4
-rw-rw-r-- 1 thanaruk thanaruk 5 Jan  5 09:45 exam.txt

I will not explain permissions here, i.e. I assume knowledge of what rwx means and users, groups and others. There are many explanations of Linux (Unix) permissions online. You can see my slides that summarise Linux File Permissions, my YouTube lecture (starting about 38 minutes in) explaining Linux permissions using those slides, or my more detailed series of six YouTube screencasts, each 10 to 20 minutes, covering Linux permissions. To read about Linux permissions, you can use the info documentation (which is often more detailed than man pages) by typing: info coreutils 'file permissions'. It contains quite a good and complete description of file permissions.

From the listing of the files by thanaruk we see the default permissions are:

Recall that the default group contains only the user. In summary, thanaruk can read and write files, other users can only read his files. We want to prevent others from being able to read his files. There are different ways this can be achieved. We will use just one approach (whether or not its the best approach depends on what may happen on the system in the future, e.g. will new users be added? will we want to allow them access to some of Thanaruk's files?).

First note the permissions on each users home directory.

thanaruk@node1:~$ ls -l /home/
total 16
drwxr-xr-x 3 cholwich cholwich 4096 Jan  5 09:49 cholwich
drwxr-xr-x 7 network  network  4096 Dec 28 15:23 network
drwxr-xr-x 4 steve    steve    4096 Jan  5 09:48 steve
drwxr-xr-x 4 thanaruk thanaruk 4096 Jan  5 09:45 thanaruk

By default, each users home directory is readable and executable by other users. That is, other users can list the files/directories in Thanaruk's home, and they can also cd into his home directory (due to the execute permission). A quick way to block access for other users on all of Thanaruk's files is to remove the read/execute permissions on his home directory using chmod (note that '.' refers to the current directory, which is Thanaruk's home directory).

thanaruk@node1:~$ chmod o-rx .
thanaruk@node1:~$ ls -l /home/
total 16
drwxr-xr-x 3 cholwich cholwich 4096 Jan  5 09:49 cholwich
drwxr-xr-x 7 network  network  4096 Dec 28 15:23 network
drwxr-xr-x 4 steve    steve    4096 Jan  5 09:48 steve
drwxr-x--- 4 thanaruk thanaruk 4096 Jan  5 09:45 thanaruk

Other users no longer have read or execute permissions on /home/thanaruk. If you cannot change into a directory, then it also applies all sub-directories (irrespective of their permissions). Lets check by switching to user steve and trying to list/access some directories and files.

thanaruk@node1:~$ su steve
Password: 
steve@node1:/home/thanaruk$ ls
ls: cannot open directory .: Permission denied
steve@node1:/home/thanaruk$ ls private
ls: cannot access private: Permission denied
steve@node1:/home/thanaruk$ cd private
bash: cd: private: Permission denied
steve@node1:/home/thanaruk$ cat notes.txt
cat: notes.txt: Permission denied
steve@node1:/home/thanaruk$ cat teaching/exam.txt
cat: teaching/exam.txt: Permission denied
steve@node1:/home/thanaruk$ exit
exit
thanaruk@node1:~$ exit
exit

The above simple test shows steve cannot access anything in Thanaruk's home directory (even if he knows the file names). We achieved our requirement for Thanaruk.

Now lets consider steve. The access control requirements are that no-one can access his files, except one directory (lab) can be accessed and modified by users in the instructors group. Again, there are different ways to implement this. We'll look at just one approach.

network@node1:~$ su steve
Password: 
steve@node1:/home/network$ cd
steve@node1:~$ ls -lR
.:
total 12
drwxrwxr-x 2 steve steve 4096 Jan  5 09:48 its335
drwxrwxr-x 2 steve steve 4096 Jan  5 09:47 lab
-rw-rw-r-- 1 steve steve    7 Jan  5 09:47 papers.txt

./its335:
total 4
-rw-rw-r-- 1 steve steve 5 Jan  5 09:48 quiz.txt

./lab:
total 4
-rw-rw-r-- 1 steve steve 7 Jan  5 09:47 manual.txt

By default, the group owner of the lab directory is the same as the user, i.e. steve. Lets change the group owner to instructors using chown. We will do it recursively (-R) to also change ownership of existing files inside the directory.

steve@node1:~$ chown -R steve.instructors lab
steve@node1:~$ ls -lR
.:
total 12
drwxrwxr-x 2 steve steve       4096 Jan  5 09:48 its335
drwxrwxr-x 2 steve instructors 4096 Jan  5 09:47 lab
-rw-rw-r-- 1 steve steve          7 Jan  5 09:47 papers.txt

./its335:
total 4
-rw-rw-r-- 1 steve steve 5 Jan  5 09:48 quiz.txt

./lab:
total 4
-rw-rw-r-- 1 steve instructors 7 Jan  5 09:47 manual.txt

Now that the instructors group owns the lab directory, we need to make it (and the files inside it) writable by the group. We also want to make all files and directories inaccessible to others.

steve@node1:~$ chmod -R g+w lab/
steve@node1:~$ chmod go-rwx papers.txt its335/ its335/quiz.txt 
steve@node1:~$ chmod -R o-rwx lab/
steve@node1:~$ ls -lR
.:
total 12
drwx------ 2 steve steve       4096 Jan  5 09:48 its335
drwxrwx--- 2 steve instructors 4096 Jan  5 09:47 lab
-rw------- 1 steve steve          7 Jan  5 09:47 papers.txt

./its335:
total 4
-rw------- 1 steve steve 5 Jan  5 09:48 quiz.txt

./lab:
total 4
-rw-rw---- 1 steve instructors 7 Jan  5 09:47 manual.txt

Now do some simple tests, first as user thanaruk who is not in the instructors group (as can be seen by using the groups command).

steve@node1:~$ su thanaruk
Password: 
thanaruk@node1:/home/steve$ groups
thanaruk
thanaruk@node1:/home/steve$ cd lab
bash: cd: lab: Permission denied
thanaruk@node1:/home/steve$ ls its335/
ls: cannot open directory its335/: Permission denied
thanaruk@node1:/home/steve$ exit
exit

Thanaruk cannot access any of Steve's files. Now try for cholwich who is in the instructors group.

steve@node1:~$ su cholwich
Password: 
cholwich@node1:/home/steve$ groups
cholwich instructors
cholwich@node1:/home/steve$ ls its335/
ls: cannot open directory its335/: Permission denied
cholwich@node1:/home/steve$ cd lab/
cholwich@node1:/home/steve/lab$ ls -l
total 4
-rw-rw---- 1 steve instructors 7 Jan  5 09:47 manual.txt
cholwich@node1:/home/steve/lab$ echo "more" >> manual.txt 
cholwich@node1:/home/steve/lab$ echo "new" > new.txt
cholwich@node1:/home/steve/lab$ ls -l
total 8
-rw-rw---- 1 steve    instructors 12 Jan  5 10:14 manual.txt
-rw-rw-r-- 1 cholwich cholwich     4 Jan  5 10:14 new.txt
cholwich@node1:/home/steve/lab$ exit
exit
steve@node1:~$ exit
exit

Cholwich can view and edit the files inside the lab directory. He adds the word "more" to manual.txt and creates a new file called new.txt.

Finally, the requirements for user cholwich is that all other users can read his files.

network@node1:~$ su cholwich
Password: 
cholwich@node1:/home/network$ cd
cholwich@node1:~$ ls -lR
.:
total 8
drwxrwxr-x 2 cholwich cholwich 4096 Jan  5 09:49 lecture
-rw-rw-r-- 1 cholwich cholwich    9 Jan  5 09:49 schedule.txt

./lecture:
total 4
-rw-rw-r-- 1 cholwich cholwich 6 Jan  5 09:49 week1.txt

The default permissions are sufficient: Cholwich can read/write his own files, other users can read his files. A quick test by switching to user thanaruk.

cholwich@node1:~$ su thanaruk
Password: 
thanaruk@node1:/home/cholwich$ cat schedule.txt 
schedule
thanaruk@node1:/home/cholwich$ echo "edit" >> schedule.txt 
bash: schedule.txt: Permission denied
thanaruk@node1:/home/cholwich$ cd lecture/
thanaruk@node1:/home/cholwich/lecture$ cat week1.txt 
week1
thanaruk@node1:/home/cholwich/lecture$ exit
exit
cholwich@node1:~$ exit
exit

So we have some examples of using chown and chmod to change the ownership and permissions to implement access control in Linux. However note that there are different ways to implement the access control requirements - we have considered just one approach. You may want to consider others, and the tradeoffs between them. Other things to consider include:

For completness, the listing all three users files/directories is below.

network@node1:~$ sudo ls -lR /home/thanaruk/ /home/steve/ /home/cholwich/
[sudo] password for network: 
/home/cholwich/:
total 8
drwxrwxr-x 2 cholwich cholwich 4096 Jan  5 09:49 lecture
-rw-rw-r-- 1 cholwich cholwich    9 Jan  5 09:49 schedule.txt

/home/cholwich/lecture:
total 4
-rw-rw-r-- 1 cholwich cholwich 6 Jan  5 09:49 week1.txt

/home/steve/:
total 12
drwx------ 2 steve steve       4096 Jan  5 09:48 its335
drwxrwx--- 2 steve instructors 4096 Jan  5 10:14 lab
-rw------- 1 steve steve          7 Jan  5 09:47 papers.txt

/home/steve/its335:
total 4
-rw------- 1 steve steve 5 Jan  5 09:48 quiz.txt

/home/steve/lab:
total 8
-rw-rw---- 1 steve    instructors 12 Jan  5 10:14 manual.txt
-rw-rw-r-- 1 cholwich cholwich     4 Jan  5 10:14 new.txt

/home/thanaruk/:
total 12
-rw-rw-r-- 1 thanaruk thanaruk    6 Jan  5 09:44 notes.txt
drwxrwxr-x 2 thanaruk thanaruk 4096 Jan  5 09:45 private
drwxrwxr-x 2 thanaruk thanaruk 4096 Jan  5 09:45 teaching

/home/thanaruk/private:
total 4
-rw-rw-r-- 1 thanaruk thanaruk 9 Jan  5 09:45 personal.txt

/home/thanaruk/teaching:
total 4
-rw-rw-r-- 1 thanaruk thanaruk 5 Jan  5 09:45 exam.txt