9.2 Permissions

Permissions are the other important part of the multiuser aspects of the filesystem. With these, you can change who can read, write, and execute files.

The permission information is stored as four octal digits, each specifying a different set of permissions. There are owner permissions, group permissions, and world permissions. The fourth octal digit is used to store special information such as set user ID, set group ID, and the sticky bit. The octal values assigned to the permission modes are (they also have letters associated with them that are displayed by programs such as ls and can be used by chmod):

Table 9-1. Octal Permission Values

Permission Type Octal Value Letter Value
“sticky” bit 1 t
set user ID 4 s
set group ID 2 s
read 4 r
write 2 w
execute 1 x

You add the octal values for each permission group. For example, if you want the group permissions to be “read” and “write”, you would use “6” in the group portion of the permission information.

bash's default permissions are:

% ls -l /bin/bash
-rwxr-xr-x   1 root     bin  477692 Mar 21 19:57 /bin/bash

The first dash would be replaced with a “d” if this was a directory. The three permission groups (owner, group, and world) are displayed next. We see that the owner has read, write, and execute permissions (rwx). The group has only read and execute (r-x). And everyone else has only read and execute (r-x).

How would we set permissions on another file to resemble bash's? First, let's make an example file:

% touch /tmp/example
% ls -l /tmp/example
-rw-rw-r---  1 david    users    0 Apr 19 11:21 /tmp/example

We will use chmod(1) (which means “change mode”) to set the permissions on the example file. Add the octal numbers for the permissions you want. For the owner to have read, write, and execute, we would have a value of 7. Read and execute would have 5. Run those together and pass them to chmod like this:

% chmod 755 /tmp/example
% ls -l /tmp/example
-rwxr-xr-x   1 david    users    0 Apr 19 11:21 /tmp/example

Now you may be thinking, “Why didn't it just create a file with those permissions in the first place?” Well the answer is simple. bash includes a nice little built-in called umask. This is included with most Unix shells as well, and controls what file permissions are assigned to newly created files. We discussed bash built-ins to some degree in Section 8.3.1. umask takes a little getting used to. It works very similar to chmod, only in reverse. You specify the octal values you do not wish to have present in newly created files. The default umask value is 0022.

% umask
0022
% umask 0077
% touch tempfile
% ls -l tempfile
-rw--------  1 david    users    0 Apr 19 11:21 tempfile

See the man page for bash for more information.

To set special permissions with chmod, add the numbers together and place them in the first column. For example, to make it set user ID and set group ID, we use 6 as the first column:

% chmod 6755 /tmp/example
% ls -l /tmp/example
-rwsr-sr-x   1 david    users    0 Apr 19 11:21 /tmp/example

If the octal values confuse you, you can use letters with chmod. The permission groups are represented as:

Owner u
Group g
World o
All of the above a

To do the above, we would have to use several command lines:

% chmod a+rx /tmp/example
% chmod u+w /tmp/example
% chmod ug+s /tmp/example

Some people prefer the letters over the numbers. Either way will result in the same set of permissions.

The octal format is often faster, and the one you see most often used in shell scripts. Sometimes the letters are more powerful however. For example, there's no easy way to change one group of permissions while preserving the other groups on files and directories when using the octal format. This is trivial with the letters.

% ls -l /tmp/
-rwxr-xr-x   1 alan    users    0 Apr 19 11:21 /tmp/example0
-rwxr-x---   1 alan    users    0 Apr 19 11:21 /tmp/example1
----r-xr-x   1 alan    users    0 Apr 19 11:21 /tmp/example2
% chmod g-rwx /tmp/example?
-rwx---r-x   1 alan    users    0 Apr 19 11:21 /tmp/example0
-rwx------   1 alan    users    0 Apr 19 11:21 /tmp/example1
-------r-x   1 alan    users    0 Apr 19 11:21 /tmp/example2

We mentioned set user ID and set group ID permissions in several places above. You may be wondering what this is. Normally when you run a program, it is operating under your user account. That is, it has all the permissions that you as a user have. The same is true for the group. When you run a program, it executes under your current group. With set user ID permissions, you can force the program to always run as the program owner (such as “root”). Set group ID is the same, but for the group.

Be careful with this, set user ID and set group ID programs can open major security holes on your system. If you frequently set user ID programs that are owned by root, you are allowing anyone to run that program and run it as root. Since root has no restrictions on the system, you can see how this would pose a major security problem. In short, it's not bad to use set user ID and set group ID permissions, just use common sense.