Unix File Permissions And Setuid Part 1
Posted on 08 Jul 1999
by Dean Mah (dmah)
Rated 3.74 (Ratings: 1)
- More articles in Backend
The first thing that you need to understand is that UNIX is a multi-user operating system and that every program executing is associated with a specific user. For security reason, most Web servers are executed using an under-privileged user like user 'nobody.' That way, if the Web server malfunctions or the program is corrupted in anyway, damage to the rest of the system will be minimized. When your CGI program is executed, it will usually be associated with the same under-privileged user as the one that is running the Web server. This is not always the case, however, but we'll cover that in part 2.
The next thing you'll need to know is how UNIX permissions work. There's generally two type of UNIX permissions: the basic kind that works under all versions of UNIX and the ACL kind that you'll find on AIX and Kerboros type systems. Since the basic kind works everywhere, we'll focus on it.
In basic UNIX permissions you can divide users into three groups:
user - the owner of the file.
group - users that belong to the same group as that of the file.
other - all other users.
For each group, you can set combinations of three permissions: 'read', 'write', and 'execute.' The 'execute' permission is a little odd in that when it applies to directories it allows users to enter the directory and is usually called the 'passthrough' permission.
To illustrate, let's examine what the output of ls -l mycgi.cgi might look like.
-rwxr-x--x 1 dmah staff 6707 Feb 19 08:47 mycgi.cgi
The first character will indicate what type of object that you're looking at. The '-' means it is a file. The other common one that you'll see is a 'd' which indicates that it is a directory. The next three characters represent what permissions that the owner of the file has. In this case, the owner has read, write, and execute permission on the file. The next three characters represent what permissions that anyone in the group 'staff' would have on this file. In this case, that would be read and execute permission. The final three characters are the permissions that everyone else has and the only permission assigned to these people is execute.
Let's take a look at a directory now: ls -ld public_html
drwx--x--x 6 dmah staff 1024 Jul 09 10:59 public_html
Here we see the 'd' for directory which we expect. The first three characters show us that 'dmah' has read, write, and passthrough permission on this directory. The second and third set of permissions indicate that only passthrough is allowed for users in the 'staff' group and anyone else. This means that everybody, other than the owner of the directory, will be able to enter (or cd to) the directory but will not be able to read (or ls) from or write to the directory.
Now let's combine these two pieces of information in order to get our CGI program to run. We know that usually the Web server will run as the under-privileged user 'nobody.' Also 'nobody' usually only belongs to the group 'nobody.' So the minimum set of permissions that we need to run our CGI program is 'execute' permission for everybody.
So how do we set our file permissions? For that we need to take a look at the command: chmod. Generally the command is specified as:
chmod [options] mode file(s)
There are a few options available to this command but the most useful, and the only one I'll mention, is the '-R' flag which will descend directories recursively changing the file mode or permissions of each file.
The 'mode' can be described in a couple different ways: symbolically and numerically. Symbolically, you create the 'mode' by indicating who this change applies to, what the change is, and what permissions you are changing. Who the change applies to is one of: 'u' for the user/owner, 'g' for the group, and 'o' for everybody else. There are three changes that you can make to a file: '+' add permissions, '-' take away permissions, and '=' set the permission. Finally, there's the permissions themselves which are indicated by: 'r' for read, 'w' for write, and 'x' for execute or passthrough. So let's take a look at some examples,
- chmod u-x mycgi.cgi
- Take away execute from the owner of mycgi.cgi.
- chmod o+x mycgi.cgi
- Add execute for everyone.
- chmod g+rw mycgi.cgi
- Add read and write for the group.
- chmod =rx mycgi.cgi
- Set permissions for user, group, and other to read and execute.
The last example left out the 'who' that the mode change would apply to and so it defaults to all three groups.
The numerical method can only be used to set permissions for all three groups at the same time. The 'mode' is created by using a number from 0-7 for each group so we will end up with three digits: the first digit represents the user/owner, the second the group, and the third everybody else. Next, each permission is assigned a value: 4 represents read, 2 represents write, and 1 represents execute or passthrough. To have combinations of permissions, you add the numbers up. So 0 would represent no permission while 7 would represent read, write, and execute. For example,
- chmod 210 mycgi.cgi
- Write for user, execute for group, nothing for other.
- chmod 543 mycgi.cgi
- Read/execute for user, read for group, write/execute for other.
- chmod 765 mycgi.cgi
- Read/write/execute for user, read/write for group, read/execute for other.
- chmod 755 mycgi.cgi
- Read/write/execute for user, read/execute for group/other.
The last one is typically the one that you want to assign to your CGI programs.
As long as your CGI programs are doing simple things like reading from or writing to world-accessible files or sending output to displayed on a Web page, this should be enough to get them working through the Web. However, if you are going to be reading or writing private files, you'll need to go a step further and learn about setuid which will be covered in the second half of this tutorial.