This document is released under the terms of the OpenContent License, Version 1.0. See http://opencontent.org/opl.shtml for details.
If you don't get Unix security right, then
This tutorial will enable you to
The basic execution unit in Unix is the process. Here are some statements about processes:
-rw-r--r-- 1 root root 0 Jul 7 1995 /etc/motd
This file belongs to owner root, and group root. Owner root is allowed
to read and write, group root is allowed to read, and everybody else is
allowed to read.
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
file
$ 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.
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.
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.
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.
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:
/etc/passwd:
user:x:500:500:Joe User:/home/user:/bin/bash
/etc/group:
floppy:x:19:user
user:x:500:
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?
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.
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
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.
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.
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
Filesystems:
$ ls -ld /dev/null /dev/zero /tmp
crw-rw-rw- 1 root root 1, 3 May 6 1998 /dev/null
crw-rw-rw- 1 root root 1, 5 May 6 1998 /dev/zero
drwxrwxrwt 15 root root 93184 Jun 1 15:02 /tmp
For processes:
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.