How UNIX file permissions work
This is a subject which bamboozles lots of people new to UNIX (or at least, new to the command-line), but it’s useful to know.
It’s easy to get confused by the likes of drwxr-xr-x when you do a ls -l, but it’s not as complicated and arcane as it might first appear.
Part 1: The basics
First of all, let’s look at user accounts. Every user account has two pieces of important information associated with it: the numeric user and group ID. As far as the innards of your operating system are concerned, these are just numbers, assigned to you by the system administrator (or they let a program assign them automatically), but they uniquely identify you. For example, my user and primary group ID on my Mac are “502” and “12” respectively. There’s nothing particularly special about these numbers, but only I am “502” on my Mac and only people in the same group as me have “12” as a group ID.
Users also may have a set of supplementary groups: we’ll see why this are important later.
Like users, files usually have a user ID and group ID associated with them. These are called the “owner” and the “group” of the file. You don’t usually see the actual IDs, because utilities that show you the owner and group of files (like ls) show you the names of the users and groups which have those IDs assigned with them.
Normally, when you create a file, the file takes on your user and primary group ID. So, when I create a file on my Mac, it will have an owner ID of 502 and a group ID of 12. Thus, I “own” that file. As well as these IDs, files have what’s called a mode, which is basically 16 bits of flags indicating what kind of file it is, who can access it (and how), as well as some options.
The access bits are what most people think of when you talk about UNIX permissions. They are made up of three sets of bits which specify what the owner of the file, the group of the file, and everyone else can do to it. For each of the these three sets, there’s a flag which says whether that set of people can read, write and execute the file. Read and write are probably obvious, but the meaning of execute depends on the kind of file we’re talking about.
By convention, we express these permissions in two ways: a number, written in octal (base-8), or a string of letters and dashes. You see the string of letters and dashes more often than the octal form, so we’ll start with that.
A file that is readable, writeable and executable only by the owner will have a set of permissions written as -rwx———. If it’s also readable and executable by people in the file’s group, it’ll be -rwx-r-x—-. Hopefully, you can guess what it’d be if it was readable, writeable and executable by everybody (it’s -rwxrwxrwx).
So far so good. You’ll have probably figured out that you can use this system to set some silly permissions, such as “this file is only readable by people who aren’t the owner or member of the file’s group” (———-r—), but that only tends to happen by accident.
That dash at the start of the string tells you what sort of file it is: “file” in UNIX parlance can mean lots of different things: for example, a directory is a type of “file”. If the first character of the permissions string is “d”, this tells you that it’s a directory. If it’s “c”, it’s a character device (for example, a terminal or a serial port). If it’s a “b”, it’s a block device (usually a disk of some kind). There are others, too, but you probably don’t need to know about them just yet.
For files, the “executable” bit tells you whether you can run the file as a program. Unlike DOS and Windows, it’s not the file extension which tells the operating system whether it can run it; instead, it’s the executable bit. If the executable bit isn’t set, you can’t run it. If it is, the behaviour depends upon what’s inside it: if it’s a binary file containing a compiled program, the operating system will just execute it; otherwise, the it will be executed as a script (that is, a text file which is fed into another program to execute).
For directories, the “executable” bit tells you whether you can actually change to that directory or not: a directory without the executable bit is near-useless, but it can be occasionally useful to make directories temporarily non-executable to lock them down for some reason.
For other types of file, the executable bit is generally ignored.
So, if you see drwxr-xr-x, you know that it’s a directory, readable, writeable and executable by the owner, and just readable and executable by everybody else, including those in the file’s group.
Permissions in octal are written quite similarly to the letters and dashes form. Instead of three sets of flags, we use a digit for each of owner, group, and “world” (i.e., everybody else). You work out the octal digit by adding up 1, if the file is executable, 2, if the file is writeable, and 4 if the file is readable. Because files aren’t executable by default unless they’re directories, the usual octal permissions are “644” for normal files (-rw-r—r—) and “755” for directories (drwxr-xr-x). Scripts and executable programs are usually also specified as “755”.
You’ll note that there isn’t an octal value for the “d”, and that’s because in the situations where you set permissions (which is where you’re most likely to see the octal value), you simply don’t have the ability to specify that it’s a directory or an ordinary file—that’s defined by how the file was created in the first place.
If you do an ls -l and see the following:
drwxr-xr-x 29 mo everyone 986 2009-07-20 10:44 Tools -rw-r----- 1 mo everyone 1394 2009-08-11 17:39 sqlnet.log
…the columns, in order, are “mode”, “number of links”, “owner”, “group”, “size”, “last modification time” and “name”. The number of links is a whole other topic, as is precisely what units are used for the file size, but you should be able to fathom the rest of it now. If you want to find out the numeric ID of a user, you can do id <name>, which in my case will tell you:
uid=502(mo) gid=12(everyone) groups=12(everyone),104(com.apple.sharepoint.group.4),101(com.apple.sharepoint.group.1),102(com.apple.sharepoint.group.2),103(com.apple.sharepoint.group.3),20(staff)
…which tells you that my user ID is 502, my primary group ID is 12, and also that I’m supplementary groups with IDs 104, 101, 102, 103 and 20.
In Part 2, I’ll run through how to change permissions, and what supplementary groups are for.