UNIX File Permissions
Created | Updated Aug 27, 2002
Unix is a multi-user operating system, and as such needs to provide protection for user's files, to stop users from interfering with each other. Instead of simply blocking users from accessing each others files, Unix implements a simple, yet effective system, which integrates with the Unix concepts of users and groups. For those of you who don't use Unix, the unix file permissions might still be useful to know about since ftp also supports this system, and so it would be relevant to cgi programmers who need to set execute bits for scripts.
To implement the file permissions, the system attaches three fields to every file, the permission bits, the id of the owner, and the id of the group. These can be seen in the 'ls -l' output below.
-rw-r--r-- 1 bsmith users 3270905 May 28 12:57 filea
-rwsrwx--- 1 root wheel 1147005 Mar 28 15:44 fileb
In the above output the permissions form the first field of the output, and will be explained further below. We can skip the next field (that the '1') since it's not relevant, and look towards the next 2 fields, as these show the user and group of the file.
People who access files fall into three groups as far as permissions are concerned, the file's owner, members of the same group as the file, and neither of the above.
Using a numeric permissions code
Unix uses the chmod command to set permissions for files, i.e. to determine the way in which a file can be used – read, write or execute. With FTP programs and the like you'll be given a graphic interface, which is pretty explanatory by itself. From the command line, however, you'll either have to type a number like 755, or use symbolic permissions that aren't supported by all version of 'chmod'
Since this is octal1, and made only for the convenience of us humans, to understand the way it all works, you'll have to look at it from a binary angle.
You can convert the digits from 0-7 in binary yourself, or use a scientific calculator. They come out as:
0 = 000 (three zeros for the chmod)
1 = 001 (the two zeros in front of the 1 are again necessary here)
2 = 010
3 = 011
4 = 100
5 = 101
6 = 110
7 = 111
Thus the number 755 will look like 111 101 101. The first triple is the one used for the owner, the second for the group, the third for everybody else, Random User.
Then we split each of the triads, in the example of the Random User we have:
1
0
1
The first digit sets the permission to read a file, the middle one is for writing in a file, the third for executing (if it's a script or an executable). 1 stands for TRUE, i.e. permission granted, 0 is for FALSE. When we analyse the entire Random User expression, we get that everyone accessing this file can read it and execute it, but cannot alter the file by writing in it. The whole 755 will mean then that the owner can do anything with the file, while everybody else will be restricted from writing.
Some of the permission variants are, of course, rarely used, such as 577. The owner should have at least as much control as any other user.
Reading permissions in 'ls' output
Under UNIX the 'ls' command is the canonical way of listing files and their associated attributes including the permission bits. Below are two examples lines from 'ls' output.
-rw-r--r-- 1 bsmith users 3270905 May 28 12:57 filea
-rwsrwx--- 1 root wheel 1147005 Mar 28 15:44 fileb
The permission bits are represented by the series of letters and dashes at the start of each line. Each position in the field equates to a single bit (with a few exceptions) in the set of permission bits for the file. To make counting positions unnecessary each bit is represented by a letter when it is set, and a dash when it is not. Basically 'r' corresponds to read permissions, 'w' to write permission, and 'x' to execute permission.
The first bit in each line is actually not a permission bit per se, but a representation of the file's type field. This is not the files type as in 'Word document' or 'HTML page' but the underlying type of the representing inode, and is a dash for ordinary files. Its a 'p' for BSD fifos, a 'd' for directories, a 'l' for symbolic links, a 'c' for character devices and a 'b' for block devices
Following the inode type are the nine permission bits organised by the owner's permissions, then the group's permissions and the permissions for the rest of the world.
Directories and the lesser used bits
For normal files the read, write and execute permissions all have obvious meanings, but when the file is infact a directory and not a file, the execute bit fails to immediately hold any meaning. Since directories cannot be 'executed' (they may be unlinked but not executed), UNIX (never one to waste bits) subverts the execute bit to control access to the directory.
What this means it that for a directory with only the execute bit set a user cannot list the files in the directory, but they can access the files (and directories) under the directory for read, write or execute as per their individual permissions.
When only the read bit is set, a user can list the directory but they are stopped from accessing any of the files below it. This causes some rather unusual behaviour with 'ls' because although it can list what files are in the directory, it fails when trying to display the attributes for each file, since under the UNIX model these are stored in the inodes rather than the directory.
In addition to the normal permissions of read, write and execute, UNIX also has several lesser used ones. These are the sticky, setuid, and setgid bits. One property that these three bits have is that they are not grouped, like the other bits, into permissions for the owner, the group and others. Instead they specify properties that apply to everybody. Having said that in 'ls' output, ls interweaves these bits with the others with a 's' replacing the 'x' bit in the user, and group fields when the setuid or setgid bits are set respectively. The setuid bit tells the system that when the file is executed it should be run not as the invoking user but as the user who owns the file. The setgid bit does this similary for the group. For example, a game that the average user invokes might want to maintain top scores in another file. The user shouldn't be able to modify the results directly, but an executable (the game) executed by that user should be able to update the results. That is, the permissions of the owner and not the invoking user are used.
The sticky bit is a bit more complicated since it does two different things depending on whether the inode is a executable regular file or a directory. When it is set on a directory it allows only the owner of a file to delete it. Normally anyone who has write permission on a directory can remove any file under it, obviously for directories like /tmp which are world-writable this could allow users to seriously annoy each other. With the sticky bit set, users could only delete their own files from /tmp, solving the problem. The other use of the sticky bit on regular files is mainly of historical note, since modern paging operating systems tend to ignore it in favour of automatic memory management. When a file is executed which has the sticky bit set the historic behaviour was to 'lock' the file in the swap space, so that it stays in the swap for the whole uptime of the operating system. The ideal was to improve efficiency for frequently used programs.
End of finished section
Links
UNIX has the capability (so do more recent versions of Windows NT) to link files together so that the same content may be accesses via different paths in the file system. There are two ways of doing this; creating a hard link, or creating a soft link.
A soft link is a special type of file that as its content stores the path of another file. When ever a program tries to read or otherwise access on of these files, the operating system intercepts the request and forwards it onto the other file. This method has the advantage that files an be linked across file system, boundaries. In addition the linked path name can be relative path. This means that you have to be careful when issuing the 'ln -s' command. Since for example typing 'ls -s ../bin/abc /usr/bin/abc' in /lib, will not do the expected2 Symbolic links also have the advantage of allowing users to link to directories.
Hard links are the older of the two link types and are a result of the way the standard UNIX filesystem is organised. In a FAT-style filesystem like that of Dos and CP/M, the properties associated with each file such as size, owner, permissions, and links to the data blocks of the file would be stored in the directory itself. Unix instead puts this information in the file's inode (sans filename), and implements directories simply as lists of name and inode pairs. This means that conceivably a file could appear in multiple directories with different names. Unix calls this feature a hard link. In order to delete the inode only when there are no more references to file each inode countains a link counter. This can be seen as the second field in 'ls' output.
Symbolic permissions for chmod
Most modern implementations3 of 'chmod' allow one to use a symbolic string to set or modify file permissions. Most people find this a much more simple and intuitive system than working out numeric codes. It is especially useful when you need to quickly set a single bit. To illustrate the symbolic system look at the command below, which sets the permissions to 0777
chmod ugo=rwx file