Tutorials - CGI (generic) > UNIX file permissions

Tutorials & FAQs: CGI: UNIX file permissions

In this tutorial I will explain what file permission options are available and how you can use them to protect your files and directories from access by others users either via the CGI shell or via a browser. In effect how to protect the contents of your CGI and homepages webspace.

Note 1: This tutorial is primarily aimed at the CGI server which has shell ($) access and that is where the examples come from and where the commands detailed can be used. It is possible to apply what you learn here to change the permissions of files on your homepages (www) webspace via your FTP program (used to upload the files), but in practice this is not necessary and may actually cause problems. This is because files uploaded are owned by ftp and are in group ftp and are not actually owned by you. It is recommended that you use the .htaccess/.htpasswd method to protect directories if you need to.

Note 2: All references to file apply equally to both files and directories on the system - Unix treats the two in a similar way as far as access permissions are concerned. This applies to any commands that may be specified, and where there is a difference, it will be highlighted in the text.


What file/directory permissions are available

Every file on a *nix system has an 'owner' and also belongs to a 'group' (a group is normally a list of similar users - e.g. a department in a company like sales). The owner is normally the name of the user that created the file (but not always) and the group is normally the group that the creator of the file belongs to (again not always). This owner and group is used to determine access rights to the file and directory. Any user that is not the owner or in same group as the file is classed as 'other'. This then gives us the 3 levels of file/directory protection:
  • Owner permissions - access permissions that apply to the files owner.
  • group permissions - Access permissions that apply to all users in the files group.
  • other permissions - Access permissions for any user who is not the files owner or a member of the files group.

Each level is independent and what level is applied to restrict or allow access to a file depends on the user who is trying to access the file.
  • If the user is the owner of the file then the owner permissions will be used.
  • If the user is not the owner of the file but is in the same group as the file, the group permissions will be used.
  • If the user is not the owner of the file and is not in the same group as the file then the other permissions will be used.

For each of the above (owner, group, other), UNIX has 3 types of access:
  • read (r) - read access to the file (whether you can read the file or not)
  • write (w) - write access to the file (whether you can write to the file or not)
  • execute / access (x) - For a file it means it can be executed (i.e. a shell or perl script), for a directory it means you can access(view) the files within it.


OK, lets look at some example files and explain what you are seeing:

On the CGI server, The ls -l command can be used to show various details about a file (the -l parameter specifies long format). Running ls -l on it's own will list all the files in the current directory, running ls -l <name> will show details for just the file specified or the contents of <name> if it is a directory.

The ls -l command shows the following information for each file (from left to right): permissions (e.g. -rw-rw-rw-), links, owner (tutorial), group (shellcgi), size in bytes, date, time, file/directory name. The three columns we will be focusing on in this tutorial are permissions, owner and group.

This ls -l is listing the contents of the current directory, in this case the home or root directory, because no <name> is specified:
tutorialsteam@shell2 tutorialsteam $ ls -l
total 16
-rw-r----- 1 tutorial shellcgi  2396 Feb  5 09:00 Mailbox
-rw------- 1 tutorial shellcgi    61 Jan 25 20:50 PS1
drwx--Sr-x 2 tutorial shellcgi  4096 Dec 15 23:27 cgi-bin
drwx---r-x 2 tutorial shellcgi  4096 Feb  5 23:18 stats

This ls -l is listing only the named file - Mailbox:
tutorialsteam@shell2 tutorialsteam $ ls -l Mailbox
-rw------- 1 tutorial shellcgi  2396 Feb  5 09:00 Mailbox

This ls -l is listing the contents of the stats directory:
tutorialsteam@shell2 tutorialsteam $ ls -l stats
total 144
-rw----r-- 1 tutorial shellcgi    68 Feb  5 23:18 README
-rwx------ 1 tutorial shellcgi   196 Feb  4 12:12 autostats
-rw----r-- 1 tutorial shellcgi  3753 Feb  5 09:00 index.html
-rw------- 1 tutorial shellcgi   251 Feb  4 11:46 stats.conf
-rw----r-- 1 tutorial shellcgi    33 Feb  5 23:17 stats.cron
-rw----r-- 1 tutorial shellcgi 12618 Feb  5 09:00 stats.current
-rw----r-- 1 tutorial shellcgi    33 Feb  5 09:00 stats.hist
-rw----r-- 1 tutorial shellcgi  2237 Feb  5 09:00 usage.png
-rw----r-- 1 tutorial shellcgi 82951 Feb  5 09:00 usage_200402.html
tutorialsteam@shell2 tutorialsteam $


Now for a bit more detail:

  • Owner

    The owner field shows who is the owner of the file, this is also usually the user who create it (i.e. you). Generally this should be your login name but there are exceptions to this: On the CGI server files can have an owner of 'nobody', they are actually files created by php/perl scripts which are run by the web server and the web server runs as user 'nobody'. On your homepages (www) server, all files are owned by ftp because that is the method you use to upload the files and the ftp server is running as user ftp. Permissions can be set that only apply to the owner of a file.

  • group

    All users on the system are also assigned to a group. For the CGI server this will be normally be shellcgi. Other likely ones to see are nobody (created by the web server) or ftp (on your homepages server). It is possible for members of a group to access/modify files of other members who are also in the same group. Permissions can also be use to change the group access for your files.

  • permissions

    In the examples above you will see a line of dashes and letters (-rwx---r-x). The permissions are actually the last 9 characters, the first character indicating if it is a file or directory - see below. The 9 characters are split into 3 lots of 3 permission settings. The first 3 apply to the owner, the next 3 apply to the group and the final 3 apply to other users.

    The first character is not actually part of the permissions but is an indicator of whether the information applies to a file (-) or a directory (d). In the earlier example the first ls -l shows a d indicating stats is the name of a directory not a file and later on I listed the contents of that directory. There are other possible indicators but you will not normally see them and are outside the scope of this tutorial anyway.

    Each of the positions in the 3 groups of 3 characters represents a single permission option. The first is read (r), the second is write (w) and the third is execute/access (x) for a file/directory. The existence of a letter in each position indicates that permission is allowed, and where a - is seen it indicates that permission is not allowed. The execute/access permission needs to be made clear at this point. This is basically a dual-purpose indicator. When referring to a file, it shows if the file can be executed (i.e. a shell script or perl script), when referring to a directory it indicates if the directory contents can be accessed i.e. viewed by the user doing the ls command. If this indicator shows x, it means the contents can be viewed, if it is - it means the contents cannot be viewed (you get a permission denied message if you try).

The following two examples will hopefully make the above a bit clearer:
-rw-r----- 1 tutorial shellcgi 2396 Feb 5 09:00 Mailbox

So in the above example we can split the permissions as follows

- rw- r-- ---
    - means we are looking at a file
    rw- are owner permissions. So the owner (tutorial) can read (r) and write (w) to the file but cannot execute it (-).
    r-- are the group permissions. So any user who is in the same group as shown for the file (shellcgi) can read (r) the file but cannot write (-) or execute (-) the file.
    --- are the permissions for other users (not the owner or any user in the same group). So any other user cannot read (-), write (-) or execute (-) the file.

And for a directory we have:
drwx---r-x 2 tutorial shellcgi 4096 Feb  5 23:18 stats

This shows stats is a directory (d), the owner can read (r), write (w) and access (x) the directory, the group has no access to it and other users have read (r) and access (x) only.


How do you change file/directory permissions

Permissions for files and directories can be changed using the chmod command. This allows the individual r/w/x permissions to be set/changed for the owner, group and other users. For the purpose of simplicity name below refers to both file and directory names.

Chmod has the following syntax:
chmod <permissions> <name>

chmod has two ways to represent the permissions for owner, group and other, Numeric and alphabetic.

Numeric permissions

This method uses a 3 digit octal number (e.g. 644, 755), with each digit representing the permission to set for owner (1st digit), group (2nd) and other (3rd). Each of the permissions is assigned a number and the value of the digit is the addition of the numeric value for the permission.

The permissions have the following values:

r = 4, w = 2, x = 1, - = 0

To work out the number to use to set the correct permissions see the following table:

--- = 0 (no permissions)
--x = 1 x(1) only
-w- = 2 w(2) only
-wx = 3 w(2) + x(1)
r-- = 4 r(4) only
r-x = 5 r(4) + x(1)
rw- = 6 r(4) + w(2)
rwx = 7 r(4) + w(2) + x(1)

Here are some examples to explain how the numbers are used:

chmod 100 - This sets owner --x (1), group --- (0), other --- (0) = --x------

chmod 660 - This sets owner rw- (6), group rw- (6), other --- (0) = rw-rw----

chmod 700 - This sets owner rwx (7), group --- (0), other --- (0) = rwx------

chmod 754 - This sets owner rwx (7), group r-x (5), other r-- (4) = rwx-r-xr-

Alphabetic Permissions

It is also possible to use letters instead of numbers to change/set the permissions as follows:
chmod [u g o a][+ - =][r w x X] file

  • u = user (owner), g = group, o = other, a = all (short for ugo). Any combination of ugo can be specified (u, ug, ugo, uo, go etc). If none are specified the default a is assumed.

  • + = add permission, - = remove permission, = only specified permission will be set (replacing existing permissions). Only one can be used.

  • r = read, w = write, x = execute/access, X = execute only if file is a directory or already has execute permission for some user. Any combination can be used.

chmod u+x file - this adds (+) x permission for the owner only (rw-rw-rw- becomes rwxrw-rw-).

chmod u-w file - this removes (-) w permission for the owner only (rwxr-xrwx becomes r-xr-xrwx).

chmod g+w file - this adds w permission to group (rwx---rwx becomes rwx-w-rwx).

chmod o=x file - this sets x permission only to other (rwxrwxrw- becomes rwxrwx--x).

chmod a+rx file - this sets r and x permission for owner, group and other (--------- becomes r-xr-xr-x).

You can also set different permissions for owner, group and other in the same command:

chmod u+x,g-x,o+r file - this adds x permission to owner, removes x permission for group and adds r permission to other (rw-rwx--- becomes rwxrw-r--).

An additional option to the chmod command is -R. This causes the chmod command to also recursively search all directories within the current directory and changes the permission of any matching files. This is useful when you have a lot of files in multiple sub-directories that you want the same permissions to be set without having to perform the chmod command in each one separately.

chmod -R o+x *.php - this will perform a recursive search of all files in all directories starting from the current directory changing any file that matches *.php to add owner execute permission. (e.g. rw-rw-rw- becomes rwxrw-rw-)

chmod -R o+X * - this will perform the same recursive search as above but all files and directories will have owner execute permission set.


Using the above information to control access to files/directories

Because access to the CGI and homepages webspace is different, different methods must be employed to protect your files. I will first explain what you can do on the CGI platform then explain why it is different on the homepages platform.

Protecting files on CGI

Because of the way users are created on PlusNet's CGI systems, all users have a unique owner name but are effectively in the same group (shellcgi). This means in order to protect files and directories you must restrict access to users that fall into the 'group' and 'other' areas.

To protect the whole of your home directory and sub-directories on your CGI webspace you should use the following command:
$ cd
$ chmod 700 .
$ ls -ld .
drwx------ 4 tutorial shellcgi 4096 Feb 10 13:28 .

The cd command makes sure you are in your home or root directory. The chmod command will set the permissions on your current directory (.) to rwx------ meaning only you can read, write, execute (or access for directory) any files or directories that exist in your home directory. The ls -ld will print the long format (l) details for the current directory (.) only (d) to verify your setting. Once you have done this, access to any files or directories in your CGI webspace is limited to you only so you don't have to set the permissions on individual directories that exist within your home directory. Anyone else trying to access anywhere in your webspace will get permission denied error back. Note: this will also mean the webserver cannot access your files either and thus your website. You must have at least 5 (r-x) for 'other' (e.g. 705 rwx---r-x) to give the webserver access to your website.


Another example is the following, which should be run from your root directory:
$ chmod -R u+rwX,g-rwx,o+rX *

This ensures sensible permissions are applied to directories (which would automatically be given the all-important "x"), and for files to which someone has execute (indicating they probably are executables), the execute permission will be given, but not otherwise. This also removes all permissions for group.

Also where you want to allow group or other access to directories it is sensible to also have r permission as well as x (r-x or 5)

It is recommended that you leave the permissions on the special directory cgi-bin as they are. If you do happen to change them the following command will restore the default settings (rwx-Sr-x):
$ chmod 705 cgi-bin
$ chmod g+s cgi-bin

The S in the group permissions is a special setting for the directory. What this means can be found in the manual page for chmod - details of how to view this is at the end of the tutorial. As this is not something normal users set it is not covered here (and would be difficult to explain to new Linux users anyway).

Any scripts like perl or php or even shell scripts must have execute (x) permission for at least 'other' and to be safe for 'group' as well. This is because the web server runs as user 'nobody' in group 'nobody' and it does not exist in the same group as a normal user. The command for that is:
chmod 755 <filename> or chmod 705 <filename>

which sets rwxr-xr-x or rwx---r-x for <filename>

If you want to protect .htaccess and .htpasswd, set the permissions to 644 (rw-r-r--) so only you can overwrite/update the file. It must have at least read permission for 'other' so the web server can read the file. There is no problem with having read access because the passwords are stored encrypted.

If you have a script that you want to execute, use chmod 755 (rwxr-xr-x).

If you have a number of files you want to set the same permissions on you can use wildcards for the filename or a common extension:
$ chmod 755 *.php

will set all files with an extension of php to rwxr-xr-x.

As an alternative to the -R recursive option on chmod, the following command will also do a recursive search to change the permissions on matching files but will not touch any directories:
$ find . -type f -depth -print -name "*.php" -exec chmod 755 {} \;

This will do a recursive search through all directories from your current directory changing all files with an extension .php to 755 rwxr-xr-x.

A word of warning: Be very careful when using * to represent all files in a chmod command when you also have directories within your current directory. This may cause the directories to be set to the permissions as well as the files and could result in the directory being unreadable due to permission problems. If you do manage to change a directories permission, just use chmod +x <dirname> to restore the correct access permissions.

Protecting files on your homepages (www)

As I explained earlier, all files on your homepages are owned by ftp and are in group ftp. Because you are not the owner of the file, changing file permissions is not recommended. Instead you should use the .htaccess / .htpasswd method to protect areas of your website directory structure you don't want people to access. Please follow the instructions in the .htaccess tutorial.



Additional information

Additional information can be found about what has been described in this tutorial and additional options in the manual page for chmod. You can view the manual page for any command on the CGI server by using the following syntax: man <command> e.g.:
$ man chmod
$ man ls


When viewing a man page, use space to move forward a page, b to move back a page and q to quit and return to the $ prompt.

That completes this tutorial. If you have any questions or comments regarding the contents of this document please PM me (petervaughan) or one of the other tutorials team members.
Original Article by: petervaughan - Edited by: csogilvie