The Unix Permission System

Ken Yap

5th June 1999

1. License

This document is released under the terms of the OpenContent License, Version 1.0. See for details.

2. Scope of this tutorial

If you don't get Unix security right, then

This tutorial will enable you to

3. Processes

The basic execution unit in Unix is the process. Here are some statements about processes:

4. Permissions

5. Directories

For directories, the meaning is different.

What is the difference between list and search? List means you can see what the directory contains, e.g. ls, file completion. Search means you can access to what's there. See these examples:

$ ls -ld folder
drw------- 32 user user 4096 May 31 12:33 folder
$ ls folder
$ ls -l folder/file
ls: folder/file: Permission denied

You can see what files are in folder but if you try to open one then you will get permission denied, even though you can see the names, which seems strange.

$ ls -ld folder
d-wx------ 32 user user 4096 May 31 12:33 folder
$ ls folder
ls: folder: Permission denied
$ ls -l folder/file
-rw-r-----  1 user user    0 Jun  1 14:17 folder/file

You cannot see what is inside folder, but if you know the name of a file inside, you can use it.

6. Other filesystem objects

For symlinks, the permissions and ownership are irrelevant.

For devices and named pipes, permissions work more or less as for files, except that execute has no meaning.

7. Octal notation

Each of the categories: owner, group and world use 3 bits, so permissions are conveniently represented by a 3 digit octal number. In each digit, read=4, write=2 and execute=1. For example, in:

-rw-r--r-- 1 root root 0 Jul 7 1995 /etc/motd

the octal permission is 644. Either of these do the same thing:

chmod 644 /etc/motd
chmod u=rw,g=r,o=r /etc/motd

To get:

drwxr-xr-x 32 user user 4096 May 31 12:33 folder

you do either of

chmod 755 folder
chmod u=rwx,g=rx,o=rx folder

Experienced Unix users know some octal numbers by heart. Also check out the +, - and a options of chmod.

8. Hierarchy

Access is determined not just by the permissions on the object but by all directories on the path from the root directory. To access a filesystem object, the process must be able to search all directories in the path.

For example, say you are an ordinary user faced with this:

/       drwxr-xr-x root root
 etc    drwxr-xr-x root root
  motd  -rw-r--r-- root root

Are you allowed to read /etc/motd?

For symlinks, just do a textual substitution of the link and continue to check for access rights. For example:

lrwxrwxrwx 1 root root 3 Feb 6 1998 /dev/cdrom -> /dev/hdc

The directories traversed are: /, /dev, then substitute the symbolic link for the whole path to get /dev/hdc, which is then traversed as /, /dev, and finally the permissions on hdc are checked. Another example:

lrwxrwxrwx 1 root root 29 May 4 1998 /etc/X11/X -> ../../usr/X11R6/bin/XF86_SVGA

Sequence: /, /etc, /etc/X11, substitute for X, /etc, /, /usr, /usr/X11R6, /usr/X11R6/bin/, and finally the permissions on XF86_SVGA are checked.

9. Groups

How does one belong to a group?

When a shell is established for a user, the owner and group IDs are taken from the /etc/passwd file, or equivalent thereof.

There are two schemes in common use: Assign all ordinary users into one big group, say "users"; or assign each user into their own group. The latter allows finer grain control.

In addition to the group in /etc/passwd, users also belong to any groups they are listed in /etc/group, or equivalent thereof. For example:

user:x:500:500:Joe User:/home/user:/bin/bash


means that user is in group floppy and for the purposes of checking group permission, his group IDs are user and floppy. The groups command shows what groups the current process is in. NB: additional group IDs are read once on logging in. So if you have changed /etc/group, you need to logout and login again for the addition to take effect.

brw-rw---- 1 root floppy 2, 0  May 6 1998 /dev/fd0
brw----rw- 1 root floppy 2, 28 May 6 1998 /dev/fd0H1440

If user is in group floppy, what are user's rights on /dev/fd0 and /dev/fd0H1440?

10. Setuid bit

There are other bits in the permissions, the set user ID bit (setuid bit) and the set group ID bit.

---s--x--x 1 root root 274516 May 7 1998 /usr/bin/sudo

For the execution of this program, the effective user ID of the program is that of the owner, in this case root. Setuid programs must be very, very careful to do only permitted things, and nothing else. Not just root, but any user can write setuid programs to allow other people controlled access to their files, e.g. to update a games score file.

Do not give setuid root permissions to binary executables if you can use alternatives like sudo, and never setuid scripts, those are very vulnerable. Even experienced programmers have to work hard to eliminate all holes from setuid root programs like sudo.

11. Setgid bit

The setgid bit sets the group ID of the process to be that of the group owner for the execution of the program. Here is an example:

-rwxr-sr-x 1 root man 31756 Sep 5 1998 man

The man program has permission on anything owned by group man (presumably for writing catN files). Setgid is useful for grouping resources and then giving limited permission to them, if no system services requiring superuser ID are involved. An example was /bin/ps on some Unixes, this had setgid kmem so that it could read the kernel memory space.

Setgid programs are not so dangerous as setuid root programs, but be careful of the groups you use them with. For example if you give a program rights to a group that has access to disk or memory, it can be a hole.

With BSD semantics, the setgid bit on directories forces any objects created under that directory to be owned by the directory's group ID, rather than the group of the creating process. This is useful for ensuring that all objects in a subtree belong to a particular group, e.g. CVS archives.

$ mkdir folder
$ chgrp geeks folder
$ chmod g+s folder
$ touch folder/file
$ ls -ld folder folder/file
drwxr-sr-x 2 user geeks 1024 Jun 3 13:51 folder
-rw-r--r-- 1 user geeks    0 Jun 3 13:51 folder/file

12. Sticky bit

The sticky bit or the t bit is no longer relevant for files. For directories it means that even if the permissions allow users to remove objects from the directory, only the owner may do so. For example:

drwxrwxrwt 15 root root 93184 May 31 17:28 /tmp

This ensures that only the creator of files in /tmp may remove them. Otherwise others could tamper with temporary files. The t bit does not prevent users from filling up the partition, that comes under quota management.

13. Umask

The umask is a per-process mask that is used to control default permissions on objects that are created. Suppose you usually don't want to give world write permission on files and directories, a wise move. This is done with a umask.

The umask is 3 octal digits. The bits that are on in the umask remove those bits in the resulting object. For example:

$ umask 000
$ touch foo
$ ls -l foo
-rw-rw-rw- 1 user user 0 May 31 23:14 foo
$ umask 002
$ touch bar
$ ls -l bar
-rw-rw-r-- 1 user user 0 May 31 23:14 bar

The permission of 666 for foo is masked against 002 to remove the world write bit. If the system assigns you to your own group, a common umask is 002, but if all normal users are in the same group, a good umask is 022. If you are very paranoid, the appropriate umask would be 077.

Umasks can be set by the program, in the example above the shell. The initial umask is inherited from the parent process.

14. An example

FAQ: I put index.html in ~user/public_html but the Web server gives permission denied?

$ egrep '^User|^Group' /etc/httpd/conf/httpd.conf
User nobody
Group nobody
$ ls -ld ~user ~user/public_html ~user/public_html/index.html
drwxr-x--- 31 user user 8192 Jun  1 14:37 /home/user
drwxr-xr-x  3 user user 8192 May 12 12:02 /home/user/public_html
-rw-r--r--  1 user user  566 May 12 12:02 /home/user/public_html/index.html

Can you see the problem? What if we had

$ ls -ld ~user
drwxr-x--x 31 user user 8192 Jun  1 14:37 /home/user

How about

$ ls -ld ~user/public_html
drwxr-x--x 31 user user 8192 Jun  1 14:37 /home/user/public_html

15. Rules of thumb


For processes:

16. A case study

You are running a ftp server and you want contributors to be able to deposit files in a incoming directory for action by a reviewer. Recall that anonymous ftp users run as ftp when logged in. You create a directory called incoming under ~ftp:

drwxr-xr-x 18 ftp ftp 8192 Jun 2 16:03 incoming

People can put files there, but they can also read and remove them at will. Second try:

d-wxr-xr-x 18 ftp ftp 8192 Jun 2 16:03 incoming

People to deposit files but not see what's there, so to remove a file, the existence and name of a file would have to be guessed. But hackers can still use your directory to store warez.

Configure the ftp server so that the files are owned by another ID, say john, when uploaded, and set the permissions to prohibit reading by the ftp group, e.g. 600, so even if warez is put there, they can't be read.

d-wxrwxr-x 18  ftp ftp 8192 Jun 2 16:03 incoming
-rw-------  1 john ftp  654 Jun 2 16:05 incoming/file

John, who is in group ftp, could move the files elsewhere later.

d-wxrwxr-t 18 ftp ftp 8192 Jun 2 16:03 incoming

Turning on the t bit prevents people for removing the file once created.

man ftpaccess, under the upload command, will give you the gory details.