Unix Fundamentals - Basic Topics
Unix Fundamentals - Basic Topics
Home >> Computing >> Unix Fundamentals >> Basic Topics

Contents:



What are file permissions?
[Top] [Contents]

In order to explain UNIX file permissions, a little background discussion on file ownership is required. Each file in UNIX has two owners associated with it; a user owner and a group owner. The two ownership attributes are decoupled; a file's group ownership is completely independent of the user owner and vice versa. Although a file's group owner is usually the same as the primary group of its user owner this need not be the case. An illustration of this is the following long listing of one of my files:

    -rw-r--r--   1 dhay     sysadmin     367 Sep 24 09:27 altavist.shtml
The third columns indicates that dhay is the user owner of the file and the group owner is sysadmin.

The reason for implementing a group ownership attribute is to allow file protections and permissions to be organized according to local needs. As UNIX allows users to be a member of more than one group, this mechanism allows for greater flexibility in sharing files. Files and directories can be made accessible to specific groups of users. For example, members of the mechanical design group often need to share files amongst each other. Creating a group mech for theses users enables them to set the group ownership and permissions on the files such that only members of the group have access to shared data.

This notion of file ownership is central to the concept of file protection in UNIX. Each file has a set of permissions associated with it; permissions for the file owner, for the group owner and for the entire user community (often referred to as all other users). These permissions govern what kind of file access is permitted. UNIX supports three types of file access; read (r), write (w) and execute (x). If you have read access to a file or directory (remember that directories are implemented as files in UNIX) you can view its contents. If you have write access to a file or directory, you can change the contents. If you have execute permission for a file [and it is an executable file] then you can run it. If you have execute permission for a directory, you can make it your current directory (you can cd into it).

So, looking at a long listing of a file will tell us the access permissions for the file. Revisiting our previous example:

    -rw-r--r--   1 dhay     sysadmin     367 Sep 24 09:27 altavist.shtml
The first column, a string of 10 characters, is the file mode for altavist.shtml. The first character indicates the file type. In this case the '-' indicates a plain file while a 'd' would indicate a directory; these are just two of the file types used in UNIX (advanced users will read the man pages for ls to determine what the other standard file types are). The next 9 characters are interpreted as three sets of three bits each which identify access permissions for owner, group, and world (the entire user community); these are often referred to as the mode bits. These 10 characters are interpreted in the following manner:
     
      File
    Type
      User
    Access
      Group
    Access
      Other's
    Access
      -   r   w   x   r   w   x   r   w   x
    Read Access     *   *   *
    Write Access     *   *   *
    Execute Access     *   *   *
The mode bits can be interpreted as follows: '-' indicates no permissions are given in the corresponding position, 'r' indicates that read permission is granted to the corresponding user class (owner, groupor other), 'w' indicates write permission is granted and 'x' indicates that execute permission is granted to the corresponding user class. So, from the long listing for the file altavista.shtml (above) we can deduce the following:
  • The first character, being a '-' indicates that it is a regular file.
  • The next three bits rw- indicate that the file's user owner dhay has read and write permission for this file.
  • The next three bits r-- indicate that the file's group owner sysadmin has read permission only for this file.
  • The next three bits r-- indicate that the world has read permission only for this file.
Users wishing to learn more about file permissions and modes are encouraged to consult the man pages on ls.


How do I change file permissions?
[Top] [Contents]

Changing file permissions or modes can be done using the chmod command. The general syntax of such a command would be:

    chmod [ symbolic_mode | numeric_mode ] filename(s)
A symbolic mode is a comma separated list of operations in the following form:
    [who]op[permission]
The who field can have one or more of the following values:
     
    u   modifies permissions for the user owner
    g   modifies permissions for the group owner
    o   modifies permissions for all other users
    a   modifies permissions for all users (equivalent to ugo)
The op field must have one of the following values:
     
    +   add specified permission to the existing file mode bits specified by who
    -   delete specified permission from the existing file mode bits specified by who
    =   replace the existing mode bits specified by who with the supplied permission
The permission field may be one or more of the following values:
     
    r   add or delete read permission for who
    w   add or delete write permission for who
    x   add or delete the execute file (or search directory) permission for who
For example, lets say we just wrote a Perl script called altavista.pl and we want to add appropriate permissions so that the script may be executed. A long listing of the file would be:
    -rw------- 1 dhay sysadmin 6326 Oct 16 09:56 altavista.pl
As inidicated, this file only has read and write permission for the user owner dhay. If we want to give execute permission to the file owner, we would type:
    ~/cgi-bin >>chmod u+x altavista.pl
    ~/cgi-bin >>ll altavista.pl
    -rwx------ 1 dhay sysadmin 6326 Oct 16 09:56 altavista.pl
    ~/cgi-bin >>
Now, it can be noted that the user owner of the file has execute permission. If we want to add execute permission for the group owner and the world as well, we would type:
    ~/cgi-bin >>chmod g+x,o+x altavista.pl
    ~/cgi-bin >>ll altavista.pl
    -rwx--x--x 1 dhay sysadmin 6326 Oct 16 09:56 altavista.pl
    ~/cgi-bin >>
To do this all in one step, we could have simply typed:
    chmod ugo+x altavista.pl
    or
    chmod a+x altavista.pl
Another alternative is to set the mode bits using the '=' operator. Lets say we want to give the user owner read, write and execute permission, the group owner the same and give read and execute permission only to the world. We would then type:
    chmod u=rwx,g=rwx,o=rx altavista.pl
    or
    chmod ug=rwx,o=rx altavista.pl
The long listing of the file now looks like:
    -rwxrwxr-x 1 dhay sysadmin 6326 Oct 16 09:56 altavista.pl
If we then decided to remove write permission for the group owner, we would type:
    ~/cgi-bin >>chmod g-w altavista.pl
    ~/cgi-bin >>ll altavista.pl
    -rwxr-xr-x 1 dhay sysadmin 6326 Oct 16 09:56 altavista.pl
    ~/cgi-bin >>
The above explanation of chmod only covers the basics. Adventurous readers are encouraged to read the man pages to determine the plethora of uses for the chmod command. The use of numeric_mode arguments for changing file permissions is left as an exercise for the reader (RTFM).


How do I change the group owner of a file?
[Top] [Contents]

To change the group owner of a file or directory, use the chgrp command. I will assume at this point that you have read previous items in this FAQ and you understand the notion of group ownership of a file. The general usage of this command is:

    chgrp group filename(s)
The group is a symbolic group name. One may change the group ownership on a single file or a group of files; the wildcard '*' may be used to change the group ownership of all of the files in the current working directory.

For example, the following is a list of the contents of one of my directories:

    ~/perl >>ls -al
    total 66
    drwxrwx---   2 dhay     sysadmin    1024 Nov  5 10:03 ./
    drwxr-xr-x  36 dhay     sysadmin    2048 Nov  5 09:59 ../
    -rwxr-x---   1 dhay     sysadmin    2874 Oct 24 15:27 hinfo
    -rwxr-x---   1 dhay     sysadmin    1619 Aug 29 11:17 junk.pl
    -rw-rw----   1 dhay     sysadmin   10766 Sep  9 10:03 name_list.shtml
    -rwxr-x---   1 dhay     sysadmin    2107 Sep  3 15:54 parse.old
    -rw-rw----   1 dhay     sysadmin   10766 Sep  9 10:03 templist2
To change the group ownership of the file junk.pl the the mech group, one would type:
    ~/perl >>chgrp mech junk.pl 
    ~/perl >>ls -al
    total 66
    drwx------   2 dhay     sysadmin    1024 Nov  5 10:03 ./
    drwxr-xr-x  36 dhay     sysadmin    2048 Nov  5 09:59 ../
    -rwxr-x---   1 dhay     sysadmin    2874 Oct 24 15:27 hinfo
    -rwxr-x---   1 dhay     mech        1619 Aug 29 11:17 junk.pl
    -rw-rw----   1 dhay     sysadmin   10766 Sep  9 10:03 name_list.shtml
    -rwxr-x---   1 dhay     sysadmin    2107 Sep  3 15:54 parse.old
    -rw-rw----   1 dhay     sysadmin   10766 Sep  9 10:03 templist2
Presto chango the group owner of junk.pl is now mech! Now, if we want to change the group owner of the files parse.old and templist2 to the group swdevel, we would type the following:
    ~/perl >>chgrp swdevel parse.old templist2 
    ~/perl >>ls -al
    total 66
    drwx------   2 dhay     sysadmin    1024 Nov  5 10:03 ./
    drwxr-xr-x  36 dhay     sysadmin    2048 Nov  5 09:59 ../
    -rwxr-x---   1 dhay     sysadmin    2874 Oct 24 15:27 hinfo
    -rwxr-x---   1 dhay     mech        1619 Aug 29 11:17 junk.pl
    -rw-rw----   1 dhay     sysadmin   10766 Sep  9 10:03 name_list.shtml
    -rwxr-x---   1 dhay     swdevel     2107 Sep  3 15:54 parse.old
    -rw-rw----   1 dhay     swdevel    10766 Sep  9 10:03 templist2
But, if we decide we want to change the group ownership of every file in the directory to www we would type the following:
    ~/perl >>chgrp www *
    ~/perl >>ls -al
    total 66
    drwx------   2 dhay     sysadmin    1024 Nov  5 10:03 ./
    drwxr-xr-x  36 dhay     sysadmin    2048 Nov  5 09:59 ../
    -rwxr-x---   1 dhay     www         2874 Oct 24 15:27 hinfo
    -rwxr-x---   1 dhay     www         1619 Aug 29 11:17 junk.pl
    -rw-rw----   1 dhay     www        10766 Sep  9 10:03 name_list.shtml
    -rwxr-x---   1 dhay     www         2107 Sep  3 15:54 parse.old
Notice that the group ownership of the directory itself (denoted by the entry ./) was not changed. To change the group owner of the directory, we would need to do so explicitly:
    ~/perl >>chgrp www .
    ~/perl >>ls -al
    total 66
    drwx------   2 dhay     www         1024 Nov  5 10:03 ./
    drwxr-xr-x  36 dhay     sysadmin    2048 Nov  5 09:59 ../
    -rwxr-x---   1 dhay     www         2874 Oct 24 15:27 hinfo
    -rwxr-x---   1 dhay     www         1619 Aug 29 11:17 junk.pl
    -rw-rw----   1 dhay     www        10766 Sep  9 10:03 name_list.shtml
    -rwxr-x---   1 dhay     www         2107 Sep  3 15:54 parse.old
    -rw-rw----   1 dhay     www        10766 Sep  9 10:03 templist2
The chgrp command also supports a recursive option similar to that of chmod. Users are encouraged to the read the man pages to determine the semantics of this feature.


What the heck is my gid and how do I change it?
[Top] [Contents]

However, if you're still curious about this topic, then read on... In UNIX, each user has a user_id and a group_id. Your user_id is just your login name; this is assigned when the friendly system administrator creates your account. Your user_id is static; it cannot be changed without intervention from the afformentioned sys admin (and even then this is not recommended). Your group_id is also assigned when your account is created but a user may be a member of more than one group.

To determine your current group_id, use the id command.

    ~ >>id
    uid=531(dhay) gid=50(sysadmin)
The output consists of your current user_id (which shouldn't change- the really keen UNIX users will read the man pages on su) and your group_id (which may be changed). Your current group_id plays a part in determining which access permissions you have. For example, I often find it necessary to wander about the system performing various administrative tasks. I usually do so as myself (not root) and sometimes I am denied access to a directory as my default group_id (sysadmin) does not match the group owner of that directory.
    ~ >>cd /net/nwdch071/disk4
    /net/nwdch071/disk4
    /net/nwdch071/disk4 >>cd tiger
    tiger: Permission denied.
    /net/nwdch071/disk4 >>
    
    
Note that I can access the /net/nwdch071/disk4 directory but I am denied access to the tiger sub-directory. To determine why this occured, let's look at the long listing for the tiger directory:
    /net/nwdch071/disk4 >>ls -al | grep tiger
    drwxrwx---  33 root     mech        1024 Oct 10 10:16 tiger/
As can be noted, the tiger directory has rwx permission for the user owner root and for the group owner mech but there are no permissions for other (if you are confused, follow this link). Hence, the tiger directory may only be accessed by members of the group mech. To be able to gain access to this directory, I must change my current group_id from sysadmin to mech. This can be done using the newgrp command as follows:
    /net/nwdch071/disk4 >>newgrp mech
    /net/nwdch071/disk4 >>id
    uid=531(dhay) gid=61(mech) groups=50(sysadmin)
It should be noted that to change your group_id, you must be a member of the target group (more on this later). Now, with my current group_id set to mech, I can enter the tiger directory.
    /net/nwdch071/disk4 >>cd tiger
    /net/nwdch071/disk4/tiger
    /net/nwdch071/disk4/tiger >>pwd
    /tmp_mnt/net/nwdch071/disk4/tiger

How do I find out which group(s) I am in?
[Top] [Contents]

Use the groups command. This command enables one to determine which UNIX groups they are members of. Each user is assigned a defualt primary group when their account is created. Users may also be members of many other groups though.

The general usage syntax of the groups command is as follows:

    groups [user_id]
For example, to find out which groups I am a member of, I would type the following:
    ~ >>groups dhay
    mech pcb pv pvvee swdevel sysadmin www
If I want to determine the group membership of another user:
    ~ >>groups dstack
    Exchange mech pcb pv pvvee swdevel sysadmin www
The man pages suggest the the user_id is optional; the output will be the group membership of the invoking user (yourself). However, it seems that when no user_id is specified, only the invoking user's primary group (from the password file) is
returned.


What is my search path and how do I change it?
[Top] [Contents]

Your path or search path is used by the OS to locate the executable image for commands entered at the shell prompt. A search path is simply an ordered list of directories in which to look for commands. Your search path is typically set in your startup scripts. Your search path is stored in the PATH environment variable. To view your path, type the following:

    ~ >>echo $PATH
    .:/net/nwdch014/lv_disk1/users/dhay/bin:/bin:/usr/bin:/usr/bin/X11:/usr/dt/bin:
    /usr/local/bin:/usr/local/bin.hp:/bnr/tools/bin:/bnr/contrib/bin:/opt/corp/tools/bin:
    /opt/corp/tools/makersgml-5.1/bin:/net/nwdch001/data7/ntcad/bin:
    /net/nwdch001/data3/apps/Pixel2/bin:/net/nwdch085/opt/java/bin:
    /usr/local/gnu/bin:/net/zwdcn001/home/dstack/bin:/usr/sbin:/usr/admin/bin
Often, we need to change our search path as new applications become available on the network. The most robust way to achieve this is to edit your .cshrc.user file; the changes to the path variable will take effect every time you invoke a new shell. To add to your path, look for the following line in your .cshrc.user file:
    set path = ( $path /usr/local/gnu/bin)
If we wanted to add the directory /usr/admin/bin to our search path, we would modify the above line to look like:
    set path = ( $path /usr/local/gnu/bin /usr/admin/bin)
In this fashion, one can add as many additional directories to their search path as is deemed necessary. Excercise caution though; some programs react poorly if the search path is too long!!

Copyright © Dan Hay
Last update: Tuesday, 29-Mar-2005 19:06:27 UTC