Project Directories

It seems that there is a question about project directories every quarter. Instead of posting the same message to the newsgroups over and over again, I have decided to create a FAQ that explains what a project directory is and how to manage it.

Creating a Project Directory?

A project directory is a common directory used by a group of users to work on a project. Let's say you need a project directory so that two users can work on a project in one place. For this example I will use my sr-test test account as one user and my normal rowland account as the other user in the group. I create the directory ~sr-test/projects and chown it so that the owner is the same but a common group is used so that sr-test and rowland can both create files, etc. in the project directory:

/n/gold/4/sr-test
% mkdir projects

/n/gold/4/sr-test
% chmod 770 projects

/n/gold/4/sr-test
% chown sr-test:staff projects

/n/gold/4/sr-test
% chmod g+s projects

/n/gold/4/sr-test
% ls -ld projects
drwxrws---   2 sr-test  staff        512 Apr  3 02:42 projects
    

What I have done here is:

  1. Created a directory that will become the project directory once the rest of the steps here are taken.
  2. Changed the permissions to 770 so that my group can manipulate files in this directory as if they owned it. This means they can create, delete, and move files in this directory. The 0 on the 770 ensures that the "other" permissions are such that no one can do anything if they are not in the group. This could be 5 to allow read and execute permissions on the project directory for "other". Do not use 5 unless you want other people to be able to access the project directory!
  3. Changed the group ownerships to my "project" group: staff. Everyone who works on this project needs to be in the staff group to have full access to this directory.
  4. Made the directory setgid. This means that any files or directories created inside of this directory will have the same group permissions as the project directory. This is standard in SVR4 UNIX. Subdirectories created in the project directory will also be mode g+s automatically so that this behavior happens recursively down from the top-level of the project directory as one would expect.

These steps are pretty standard when creating a project directory. Once this is done the group permissions on anything created within the project directory are guaranteed to belong to the project group. Any directories created in the project directory will be mode g+s to ensure that this behavior continues further down the filesystem tree. This is how project directories for classes are supposed to be created with the automated account management system.

Managing a Project Directory

Creating a project directory is not enough. You must manage your umask value when creating files in the project directory. The umask value determines the file creation mode. The umask value is an three octal digit value that is subtracted from the creation mode of the file. For example, if my umask value is 077 and I create a file with mode 777 with an open() system call, the file will end up with permissions:

  777 [ open() creation mode ]
- 077 [ umask value ]
-----
  700 [ resulting file permission ]

The octal permissions are: [ see chmod(1) ]

1 = x (execute)
2 = w (write)
4 = r (read)

4 + 2 + 1 = 7 or rwx
4 + 2     = 6 or rw-
4 + 1     = 5 or r-x

Mode 700 = rwx------
            u  g  o

u = owner
g = group
o = other
    

When you edit files they will be created with mode 666 - umask if they are normal text files. If they are executables they will be mode 777 - umask. The default setting on our system is to create files that only the user can read and write (and sometimes execute). The default umask is 077. This is a good security measure. This also means that files created in a project directory will not have any group permissions set, but is essential that group permissions are present on files for a project directory to work. You want a umask that will be most beneficial to the project group members. You can see your current umask value by simply typing "umask" with no arguments:

/n/gold/4/sr-test
% umask
77
    

Note that leading zeros are dropped. This does me little good because creating a file in the project directory it will result in a file with mode 600 permissions:

/n/gold/4/sr-test/projects
% touch file

/n/gold/4/sr-test/projects
% ls -l file
-rw-------   1 sr-test  staff          0 Apr  3 02:57 file
    

No one in my group can read or write to this file, but since the project directory is mode 770 they can delete the file (that is all). If I change my umask value to 007 then things work just the way I want:

/n/gold/4/sr-test/projects
% umask 007

/n/gold/4/sr-test/projects
% touch file

/n/gold/4/sr-test/projects
% ls -l file
-rw-rw----   1 sr-test  staff          0 Apr  3 03:00 file
    

Now my group, staff, can do whatever they like to the file including read, write, move, copy, and delete (done as rowland as opposed to the file owner sr-test):

[rowland@omega projects]$ cat file
This is a file.
[rowland@omega projects]$ echo "A new line" >>file 
[rowland@omega projects]$ cat file
This is a file.
A new line
[rowland@omega projects]$ cp file file2
[rowland@omega projects]$ ls -l
total 2
-rw-rw----   1 sr-test  staff          27 Apr  3 03:03 file
-rw-rw----   1 rowland  staff          27 Apr  3 03:04 file2
[rowland@omega projects]$ mv file file3
[rowland@omega projects]$ ls -l
total 2
-rw-rw----   1 rowland  staff          27 Apr  3 03:04 file2
-rw-rw----   1 sr-test  staff          27 Apr  3 03:03 file3
[rowland@omega projects]$ rm file2 file3
[rowland@omega projects]$ ls -l
total 0
    

I can do this because the directory is mode 770 and the file permissions were right due to sr-test using umask 007 in this directory. There are some important things to note in this situation. If you copy a file that does not belong to you then the copy will belong to you. If you move the file and it does not belong to you then the resulting file will still belong to the original owner. The actual owner of the file does not matter as long as the group permissions are correct inside the project directory. Using the correct umask value will ensure that this is the case.

Final Notes

Top-level project directories:

  1. Should be mode 770.
  2. Should have group ownership set to the project group.
  3. Should be g+s so that all files and directories in the project directory will have the project group ownership. Subdirectories created in the project directory will also be mode g+s automatically.

User file creation management:

  1. Users should set their umask to 007 inside the project directory to ensure the group has full access to the files and directories they create.
  2. When done with the project directory work (or when creating files anywhere else) change the umask back to it's original value (probably 077, and that's a safe value regardless).

The only real issue here is how to deal with this umask change/change back thing. What if you forget? The simple answer is: don't forget! Using the umask like this is essential to good project directory management. It is not a good idea to do something like "chmod -R 777 *". That is a BAD idea! Let me repeat that: that is a bad idea! An easy way to handle umask changes is to invoke a subshell, because when you leave the subshell your umask will revert:

/n/gold/4/sr-test/projects
% umask
77

/n/gold/4/sr-test/projects
% tcsh

/n/gold/4/sr-test/projects
% umask 007

/n/gold/4/sr-test/projects
% umask
7

/n/gold/4/sr-test/projects
% exit

exit

/n/gold/4/sr-test/projects
% umask
77
    

The most difficult thing is making sure people change their umask when working in the project directory, and then change their umask back when done. I suggest the subshell method as that is the easiest. Handling the umask in a project directory is vital if you want to manage it the right way. Other than that all you have to do is create the top-level project directory correctly. Through the proper project directory practices outlined here it is easy to create code repositories within the project directories that work for all of those who have access to them. Most of the problems I see with project directories center around not using the correct umask setting within the project directory.


Shaun Rowland
Last modified: Tue Apr 16 16:54:44 EDT 2002