Project Collaboration at CSLab and Unix Permissions

This document explains how Unix file permissions work, and how you can use them to collaborate on research projects.

  1. File permissions: The Basics
    1. Users, Groups, and Other
    2. Read, Write, and Execute Permissions
    3. Finding out the Permissions for a File
    4. Setting or Changing the Permissions on a file
    5. The Default Permissions: umask
  2. Using Unix File Permissions to your Advantage
    1. Whom do You Trust?
    2. Using Customized Groups
    3. The chgrp Command, and the setgid Flag
    4. Managing Your umask
    5. Manual or Periodic Corrections

File permissions: The Basics

Users, Groups, and Other

Every user's account belongs to one or more Unix groups. At CSLab, most users belong to a group named for the researcher who sponsors his or her account.

You can use the groups command to find out what groups you are a member of.

Every file on the system has associated with it a set of permissions which determine who is allowed to access the file, and what types of access are permitted.

There are three sets of permission flags for each file. Which set of flags is used depends on who is attempting to access the file, and which groups he or she belongs to.

The first set of flags (the "user" permissions) applies if, and only if, you are the owner of the file.

The second set of flags (the "group" permissions) applies if you are not the owner of the file, but the group that the file belongs to is among the groups that your account belongs to. (Note that a user can belong to several groups, but a file always belongs to exactly one group.)

If neither the first nor the second set of flags applies, then the third and final set of flags ("other," or "world," permissions) is used.

Read, Write, and Execute Permissions

Each of the three sets defined above (user, group, and other) consists of three flags, called "read," "write," and "execute" (abbreviated "r", "w", and "x" respectively).

When you are trying to access a file:

  • To open a file for reading, the read flag for that file must be turned on.
  • To overwrite an existing file (or to append to it), the write flag must be turned on. (However, note that the write flag does not usually control whether or not you can delete the file.)
  • To execute a program file, the execute flag must be turned on.

The flags are also meaningful for directories, but their meaning is slightly different:

  • To list the contents of a directory (e.g., with the "ls" command), both the read and execute flags must be turned on.
  • To create a new file in a directory, or to delete or rename an existing file in that directory, both the write and execute flags must be turned on.
  • If the execute flag is turned on for a directory, but the read flag is turned off, you won't be able to list the contents of the directory; however, if you know the name of a file in the directory, you can still read from, write to, or execute the file (if the permissions on the file allow this).
  • If the execute flag is turned off for a directory, you cannot read from, write to, or execute any files in or under the directory even if you know their names.

Finding out the Permissions for a File

To list the permissions for all of the files in the current directory, use this command:

ls -l

The -l option tells ls to show the permissions on the file.

(There are other options you can supply to the ls command as well; see the man page for details.)

When you run the command above, you should your files and directories listed in a form similar to the following:

-rwxr-x--x   1 you      yourgrp      8221 Mar 23 12:01 a.out
-rw-r--r--   1 you      yourgrp     12923 Mar 23 04:18 homepage.html
drwx------   2 you      yourgrp       512 Mar  2 13:36 mail
drwxr-x--x   2 you      yourgrp      1024 Apr  8  1999 my-subdirectory

The last column shows the name of the file. The third and fourth columns show, respectively, the owner of the file, and the group to which the file belongs.

For now, let's concentrate on the first column of the listing. It's ten characters wide; the first character tells you what type of file it is. A dash "-" in the first column means it's a regular file; a "d" means it's a directory; an "l" means it's a symbolic link.

The next nine characters represent the three sets of three permissions flags I talked about in the section above: first the three "user" flags, then the three "group" flags, and finally the three "other" (or "world") flags.

Within each set of three characters, you'll see an "r" if the read flag is turned on for the file or directory, or a dash "-" if it's turned off; next, you'll see a "w" or a "-" telling you whether the write flag is turned on; finally, you'll see "x" or "-" for the execute permission.

(On some directories, you may see an "s" or "t" instead of an "x". Don't worry about this for now; we'll get to that later.)

Let's take another look at one of those entries from our directory listing:

-rwxr-x--x   1 you      yourgrp      8221 Mar 23 12:01 a.out

We see from the "-" in the first column that a.out is a regular file (not a directory).

The next three characters, "rwx", show that the user who owns the file (user you) is allowed to read the file, overwrite or append to the file, or execute it as a program.

The three characters after that, "r-x," are the group permissions; they show that any user (other than yourself) who is in the group yourgrp is allowed to read the file or execute it as a program, but is not allowed to change its contents.

The last three characters, "--x," show that anyone who isn't a member of group yourgrp is allowed to execute the file as a program, but cannot read or change the contents of the file.

Setting or Changing the Permissions on a file

The chmod command can be used to explicitly set the permissions on a file or directory. Only the owner of a file or directory is allowed to set the permissions for it.

Read the man page for chmod for complete details, but here are some examples of how to turn permissions for a file on or off:

chmod o-r filename

Turns off read permission for "world"

chmod g+w filename

Turns on write permission for the group to which the file belongs

chmod go-rwx filename

Turns off all permissions (read, write, and execute) for group and world (i.e., everyone but the file's owner)

chmod o=rx filename

Turns on read and execute permission, and turns off write permission, for "world"

chmod g=u filename

Sets permissions for "group" to be the same as they currently are for "user"

chmod u=rw,g=r,o= filename

Sets permissions to rw-r-----

chmod 640 filename

Also sets permissions to rw-r----- (see below)

The last entry requires some explanation. Unix internally represents the permissions on a file as an integer. You can specify that integer in octal (base 8) to the chmod command instead of using letters for the user, group, and other groups and for read, write and execute permission. This way of specifying permissions is more concise, but less intuitive to read.

Since a digit in octal consists of three bits, the number you use in the chmod command to set the nine permission bits is a three-digit octal number. The three digits represent the user, group, and other permissions respectively. Each digit is the sum of:

  • 4, to turn on read permission, or 0 to turn it off;
  • 2, to turn on write permission, or 0 to turn it off;
  • 1, to turn on execute permission, or 0 to turn it off.

So, for example:

  • chmod 775 directory is the same as chmod ug=rwx,o=rx directory, and will set the permissions on directory to rwxrwxr-x
  • chmod 640 filename is the same as chmod u=rw,g=r,o= filename, and will set the permissions on filename to rw-r-----
  • chmod 600 filename is the same as chmod u=rw,go= filename, and will set the permissions on filename to rw-------

The Default Permissions: umask

How does the system decide which permissions get set when a file gets created?

Well, in general, it's up to the program that's creating the file. A text editor, for example, will probably create the file readable and writable, but not executable. A compiler, on the other hand, would probably make the program files it creates executable.

However, you probably don't want every file you create to be writable by every user on the system. That's why there's a mechanism called the file mode creation mask, commonly known as the umask.

The umask is an integer, generally specified in octal, similar to the integer you can pass to the chmod command the way we did at the end of the previous section. However, the umask specifies the permission bits we want turned off by default.

The umask is set using the umask command. Normally, this command appears in your .cshrc file in your home directory, so it gets set for your shell every time you log in.

At CSLab, the default umask is set to 022. We saw in the previous section that the octal digit 2 represents write permission, so 022 turns off write permission for "group" and "other."

Here are some other useful settings for your umask, and what they mean:

  • umask 022 removes write permission for group and other
  • umask 002 removes write permission for other only
  • umask 077 removes read, write, and execute permission for group and other
  • umask 007 removes read, write, and execute permission for other
  • umask 027 removes write permission for group, and read, write, and execute permission for other

Using Unix File Permissions to your Advantage

Whom do You Trust?

In some cases, the easiest way to collaborate on a project may be to simply make all of the files and directories involved world-readable and world-writable. This means that any user with a CSLab account can see all of the project files, and make any changes they want to them.

However, opening up the permissions this way requires you to implicitly trust every one of the hundreds of users who has an account on the machine not to tamper with your project.

If all of the people who are collaborating on the project are users whose accounts are sponsored by the same researcher, it may make sense to use your default group for your collaboration. You can make the files and directories readable and writable by user and group, but not writable (and perhaps not readable) by other. In other words, you would set the permissions for your files to rw-rw-r-- (or rw-rw----), and set the permissions for your directories to rwxrwxr-x (or rwxrwx---).

To make these permissions the default, use the command umask 002 (or umask 007).

Since every file or directory you create belongs to your default group, this will give access to those files to your account sponsor and all other accounts sponsored by that researcher.

Using Customized Groups

Sometimes, the people collaborating on a project are not all working for the same researcher; or perhaps they are, but the project is sensitive enough that not all of the people whose accounts are sponsored by that researcher should have the ability to see or modify the files.

If this is the case, the project leader can ask your Point of Contact (PoC) to create a new group for his or her project.

When asking for a new group, you should tell us:

  • the name for the new group; this name must consist entirely of two to eight lowercase letters or digits, must begin with a lowercase letter, and cannot be the same name as any other group or any user on the system.
  • the list of CSLab users who should be made members of the new group.

Remember, users can belong to more than one group. When you're added to a new project group, you're still a member of the default group associated with your account sponsor. That default group is also called your primary group; any other groups you're added to, such as project groups, are called supplementary groups.

However, also remember that files only belong to one group. Under normal circumstances, any file you create belongs to your primary group; in order to use your project group to collaborate, we need to change that.

The chgrp Command, and the setgid Flag

If you belong to more than one group, you can use the chgrp command to change which group a file belongs to. As with the chmod command, you have to own the file. In addition, you have to be a member of the group you're putting the file into.

Let's suppose your primary group is yourgrp, but you've been made a member of the group projgrp for the purpose of collaborating on a project whose files are going to reside in the directory /cs/htdocs/project/.

hostname.cs> cd /cs/htdocs/project
hostname.cs> umask 007
hostname.cs> mkdir projfiles
hostname.cs> ls -ld projfiles
drwxrwx---   2 you      yourgrp       512 Mar 23 17:47 projfiles
hostname.cs>

We want this new directory to belong to the project group, so we do this:

hostname.cs> chgrp projgrp projfiles
hostname.cs> ls -ld projfiles
drwxrwx---   2 you      projgrp       512 Mar 23 17:47 projfiles
hostname.cs>

The directory now belongs to the correct group, so any member of the projgrp group can now read or write files in this directory.

However, as it stands, any files that get created in this directory will belong to the primary group of whoever created the file; you would need to use the chgrp command to correct the group membership of every single file or directory you created here.

hostname.cs> cd projfiles
hostname.cs> echo "hello" > newfile
hostname.cs> ls -l
-rw-rw----   1 you      yourgrp       512 Mar 23 17:48 newfile
hostname.cs> chgrp projgrp newfile
hostname.cs> ls -l
-rw-rw----   1 you      projgrp       512 Mar 23 17:48 newfile
hostname.cs>

Fortunately, there is a mechanism which can help us with this problem. In addition to the permissions flags we've already seen, there is a special flag called the set-group-id (or setgid) flag, which you can turn on with the command chmod g+s directory. When this flag is turned on for a directory, any file created in the directory will inherit the group membership of the directory, instead of the primary group of the user who created the file.

hostname.cs> pwd
/cs/htdocs/project/projgrp
hostname.cs> ls -l .
drwxrwx---   2 you      projgrp       512 Mar 23 17:48 projfiles
hostname.cs> chmod g+s .
hostname.cs> ls -l .
drwxrws---   2 you      projgrp       512 Mar 23 17:48 projfiles
hostname.cs> echo "hello" > newfile2
hostname.cs> ls -l
-rw-rw----   1 you      projgrp       512 Mar 23 17:48 newfile
-rw-rw----   1 you      projgrp       512 Mar 23 17:49 newfile2
hostname.cs>

(Note how newfile2 immediately belongs to group projgrp when it's created; we didn't have to use the chgrp command to change its group membership.)

Managing Your umask

As explained earlier, the default permissions that are given to a new file are controlled by your umask. The umask isn't associated with a directory; if you've set your umask to 077 so that files under your home directory stay private, then any files you create in the project directory won't be group readable or writable unless you type umask 007 before creating them.

Manual or Periodic Corrections

Another way to deal with permissions in a project directory is to run a command to set them explicitly for all of your files in the project directory.

The following command will search the directory /cs/htdocs/project/projfiles) for files and directories which belong to you and are in the project group, and make sure that they have the same permissions for "group" as for "user," and aren't accessible by "other":

hostname.cs> gnufind /cs/htdocs/project/projfiles \
? -user $USER -group projgrp '!' -type l -print0 | \
? gnuxargs -0 chmod g=u,o=

You could run this command manually after each editing session, or set up a crontab file to run it automatically (e.g., once a day), so that if you've inadvertently left any files in the project directory without group write permission, they'll get fixed.