Unix File Permission Primer

Revision as of 14:42, 13 September 2016 by Phil.cs.jhu.edu (talk | contribs) (umask and chmod)

WARNING: This documentation is not yet complete.

Most of the computers available on our network run Linux, which uses the standard Unix file permission system. Understanding file permissions can help when you want to share files with others or use our webserver to host your own webpages.

The first thing to know is that you don't need to do anything special if you don't want anyone to see your files. By default, files that you create will only be accessible by you and no one else.

That said, let's get started.

Viewing File Permissions

You can view file permissions from the Unix command line with the command ls -l . That will show you something like the following:

drwx------. 2 account users    3 Sep 12 15:47 Desktop
drwx------. 4 account users    4 Aug 26  2008 Mail
-rw-------. 1 account users 4153 Apr 16  2013 README
drwx---r-x. 3 account users    4 Sep 12 15:47 public_html

The last column gives you the name of the file or directory. The first column shows the permissions. The third and fourth columns ("account" and "users" in this example) give the owning account and group, respectively. (We're going to ignore the other columns.)

The Basics

In Unix, every file (and directory) belongs to one account and one group. That gives three sets of permissions: one for the owning account (often shortened to "u", for user), one for its group ("g"), and one for everyone else ("o", for other).

There are three basic permissions in each set: read, write, and execute. For files, those are pretty straightforward: "read" lets you see the file's contents; "write" lets you change the file's contents; and "execute" lets you run the file as a program. For directories, the meanings are a little less obvious: "read" lets you see what the contents of the directory are; "write" lets you add and remove (and rename) files in the directory; and "execute" lets you access files in the directory.

Note: There are a couple of common but not necessarily obvious combinations of permissions here. First, in order to read a file, you must have read permission for the file and execute permission for the directory containing the file (and for the directory containing that directory, and so on). Second, you can have a directory that gives you execute permission but not read permission. In that case, you could access files in the directory, but only if you already knew what the files' names were, since you couldn't get a list of files in the directory.

In the output of ls -l, the permissions column is a string of ten characters that might look something like "drwx---r-x". The first character isn't really a permission--it's an indication of the type of file ("-" for a regular file, or block special file, character special file, directory, symbolic link, named pipe, socket, or a "?" for something else). The remaining characters are in three groups of three. Each group corresponds, from left to right, to the user, group, and other permission sets. Within each group, the first character is an "r" if that set contains the read permission and a "-" if it does not. The next two characters are either "w" or "-" for the write permission and "x" or "-" for the execute permission.

Putting all of that together means lets us explain these permissions: "drwx---r-x". That's a directory that gives all three permissions to the owning account, no access to members of the owning group, and read and execute permission to everyone else.

It can sometimes help to think of the permissions in terms of a matrix, like this:

read write execute
user r w x
group - - -
other r - x

Note: When the system checks permissions on a file (or directory), it first checks to see if you're the owner of the file; if so, it uses the "user" permissions. Otherwise, it checks to see if you're a member of the file's group; if so, it uses the group permissions. Otherwise, it uses the global permissions. This means that you can have a situation like the above example where members of a particular group actually have fewer permissions than people who are not members of the group.

Permission Representations

ls -l is the most common way to view file permissions. Unfortunately, when you want to change permissions, the programs for that use completely different ways of writing permissions. There are two different ways to describe permissions; most programs will accept either way and we'll cover both of them here.

Symbolic Representation

In the symbolic representation, each permission set and permission is shortened to a single character; the "r", "w", and "x" you might expect for the permissions, and "u", "g", and "o" for the "user", "group", and "other" sets. You can either specify permissions as a change from the current or default value with "+" or "-", or you can specify them exactly with "=". Different sets are separated by commas.

Here are some examples:

  • u=rwx,g=,o=rx - This specifies permissions exactly and would be shown by ls -l as "-rwx---r-x". The owning account has full permissions, members of the owning group have no permissions, and everyone else has read and execute permissions.
  • g-w,o-rwx - This is a modification of an existing set of permissions. Write permission is being removed from the "group" permission set and all permissions are being removed from the "other" set.
  • u-w,g+r - Also a modification of an existing set of permissions. The owner no longer has write access, but members of the owning group can now read the file.

Octal Representation

The symbolic representation for permissions is generally easy to read, but it can get a little long. The octal representation is the opposite: it's short, but harder to read until you get used to it.

Octal representations of the basic permissions are three digits long and look something like this: "705". The first digit represents the user permissions, the second digit is the group permissions, and the third digit shows the "other" permissions. Each digit is the sum of up to three numbers: 4 for read permission, 2 for write permission, and 1 for execute permission. The digit zero means that no permissions are given to that set.

Thus, the permissions with the octal representation "705" are the same as the symbolic representation "u=rwx,g=,o=rx" and would be shown by ls -l as "-rwx---r-x". To put that into our matrix representation:

read write execute sum
user 4 2 1 7
group 0 0 0 0
other 4 0 1 5

Here are some other example octal modes:

Octal Symbolic ls -l
000 u=,g=,o= ----------
644 u=rw,g=r,o=r -rw-r--r--
750 u=rwx,g=rx,o= -rwxr-x---

Default Permissions

On our systems, the default permissions for files are 600 (u=rw,g=,o=) and the default permissions for directories are 700 (u=rwx,g=,o=). Here's how those defaults are set (and how you can change them):

When you log in to a system, your default permissions are set by your shell's umask. The umask serves as a kind of limit on the permissions given to new files and directories. Without a umask, files would all have permissions 666 (u=rw,g=rw,o=rw) and directories would all have permissions 777 (u=rwx,g=rwx,o=rwx). In actuality, when a file or directory is created, the system starts with those values (666 for files and 777 for directories), but then applies the umask, which removes some of those starting permissions to arrive at the actual defaults.

You can view your umask with the umask command, which will show the umask in its octal representation. Many shells (but not the default shell on our systems, tcsh) also support running umask -S to show the umask in symbolic representation.

Unfortunately, the meaning of the umask is different between the octal and symbolic representation. (Unix is full of such unfortunate contradictions.) The symbolic representation works as a limit on the permissions. In symbolic terms, our default umask is u=rwx,g=,o=. The process of applying the symbolic umask is logical intersection; only permissions that are in the starting set and the umask will be applied to the file or directory being created.

For example, a file (starting permissions: u=rw,g=rw,o=rw (666)) plus a umask of u=rwx,g=rx,o= will give actual permissions of u=rw,g=r,o= (640).

The octal representation for the umask works as a list of permissions that will be taken away from the starting permissions. In octal terms, our default umask is 077. The process of applying an octal umask is logical difference; any permissions in the umask are removed from the starting permissions to arrive at the final permissions.

For example, a directory (starting permissions: 777 (u=rwx,g=rwx,o=rwx)) plus a umask of 027 will give actual permissions of 750 (u=rwx,g=rx,o=).

To change your umask, you use the umask command like this:

umask new-permissions

To make the change permanent, you'll have to add that command to your shell's initialization file. On our systems, if you haven't changed your shell, that file will be ~/.cshrc .

Warning: The default shell on our systems (tcsh) only understands octal notation for permissions. Symbolic notation will not work.

Changing Permissions

The chmod program is used to change permissions on a file or directory. Its invocation looks roughly like this:

chmod permissions file [file ...]

The "permissions" parameter can be in either octal or symbolic representation. If you use symbolic representation, you can use the "+" and "-" characters to add and remove permissions from the file without having to specify the full permissions. For example, if you just want to add execute permission to a file for yourself, and not worry about the other particular permissions on the file, you can run:

chmod u+x file

When using octal notation, you muct specify the full permissions for the file every time.

Advanced Topics

Sticky Bits

Access Control Lists