by Steven J. Owens (unless otherwise attributed)
Most web servers are unix-flavored, which means that beyond the file system stuff you may be used to, every file has a set of values associated with it:
The user and group values actually interrelate with the nine permission flags (see the example table below), so it takes a little bit of work to describe them. There are three kinds of permissions:
And these permissions apply to three categories:
Note: To make it more complicated, often in conversation you see the term "world" used as a synonym for "other."
When you put these permissions and categories together, you get:
user | group | other | |
read | yes/no | yes/no | yes/no |
write | yes/no | yes/no | yes/no |
execute | yes/no | yes/no | yes/no |
Before I get into the commands to display and manipulate these permissions, let's nail down what I mean by read, write, execute, user, group and other:
Permission to read means quite simply permission to read the contents of the file, i.e. to execute a system command and get back the data contents of the file.
Permission to write means permission to modify the file - to overwrite exisitng data or append new data.
Permission to execute means permission to ask the operating system to treat the file as a list of commands to execute. In a single-user system with no security scheme to speak of (like good old MS-Windows; these days windows actually has some security to speak of, although it's still more full of holes than swiss cheese) this wouldn't make any sense. In a multi-user, somewhat secure system like unix, execute permission determines whether other people can run a file full of commands that you wrote.
Now let's define user, group and other.
A user is the user value for the account that owns the file.
A group is one of an arbitrarily defined list of groups to which users in the system might belong. Each file has a single group value, but users can belong to multiple groups and groups can have multiple usres. A group is essentially a group name, a unique numeric value (the group ID), and list of users that belong to it.
Note: When this article was written, it was common for users to have a primary group they belonged to (for example, dev for software developers, admin for system administrators). Any files a user created were by default in their primary group. Since then, it has become a not-uncommon practice to create a group for each user, e.g. user puff would also have group puff. This gives users lots more flexibility to manage their file permission.
And other is everybody else, i.e. anybody who is NOT the user who owns the file or a member of the same group the file belongs to.
Okay, so we have three permissions times three categories, which means each file needs nine different permission flags. Unfortunately, the way Unix actually stores these nine permissions is as three numbers. It uses a clever-but-annoying way to encode the various combinations of three different types of permissions as a single number. I'm not even going to bother to try to explain this scheme, because I haven't had to use them in over a decade. Instead, on modern unix systems the file permission command (chmod) supports using logical parameters instead of numeric parameters.
For human beings, this makes a lot more sense: I'm enabling group read permission for this file (chmod g+r filename). I'm disabling other write permission for this file (chmod o-w filename).
If you enter the command "ls -l filename
$ ls -l test -rwxrwxrwx 2 puff puff 4096 Apr 23 21:47 test
This file has all of the permission bits turned on:
user group other read r r r write w w w executable x x x
If we turn off group write permisssion with "chmod g-w test" and list it again:
$ chmod g-w test $ ls -l test -rwxr-xrwx 2 puff puff 4096 Apr 23 21:47 testuser group other read r r r write w - w executable x x x
If we also turn off other write permisssion with "chmod o-w test" and list it again:
$ chmod o-w test $ ls -l test -rwxr-xr-x 2 puff puff 4096 Apr 23 21:47 testuser group other read r r r write w - - executable x x x
By the way, we could have just turned the both off at once, by lumping together the "g" and "o" like so:
$ chmod go-w test
If you used "+" instead of "-", chmod would set those permissions to on:
$ chmod go+w test $ ls -l test -rwxr-xr-x 2 puff puff 4096 Apr 23 21:47 test
Beyond the above details, there are some gotchas to be aware of:
Normally when anybody runs an executable file, it runs "as" the user who ran it. It can do anything that user can do - so if you run a file, it can delete all your files, or email them all to somebody else, or anything you could do. It's always wise to make sure what's in what you're running before you run it.
On the flip side, when somebody else runs your file, it can't muck about with your files (unless you use special commands to make that possible - called the setGUID bit, and VERY DANGEROUS for novices to play with).
However, if you have a file writable by anybody else but you, and executable at all (by yourself or by other users), you've created a risky situation. What if somebody came along and edited some nasty commands into that file between the last time you read it and when you run it? When the file runs, it effectively has all the access you'd have, but it's running the commands that some unknown joker put in it.
In Unix, a directory is a file, with its own set of bits. Here's how they work:
The "ls" command executes the directory to list what files it contains. So if you have a directory with the "execute" permission turned off, you can't list it. Neither can the web server, so when you request that directory with your web browser, you get an error.
More of a gotcha is, let's say you have:
a file inside of a
directory named baz,
which is in turn inside of a directory named
bar,
which is in turn inside of a directory named foo,
which
is in turn inside your htdocs directory:
...htdocs/foo/bar/baz/what.html
If any of the directories in that set - foo, bar, or baz, or even htdocs or any of the directories above it - has the execute permission turned off, you won't be able to get at it via the web.
You need write permsision to edit the contents of a directory - that is, to rename or remove files. The gotcha is that once you have write permission in a directory, you can rename or remove any file, even one that doesn't belong to you.
The SetUID bit is tricky and dangerous for novices to use. Essentially, it reverses the normal situation I described above in "Executable and Writable Files". When anybody runs the file, it runs as if you ran it. This means that you need to be extra careful about security on that file (a file that is both writable AND setUID is a timebomb waiting to happen). You also have to think very carefully about the commands that are in the file, since somebody could figure out a way to feed it the wrong arguments and cause behavior you didn't anticipate. This is a huge and tricky topic to understand, and there's no way in hell I can go into it here with any level of details.
The setGID bit is like the setUID bit, only for groups - the file runs as a member of that group, even if the user running it isn't a member of that group.
A more thorough introduction to Unix permissions is at:
http://www.onlamp.com/pub/a/bsd/2000/09/06/FreeBSD_Basics.html