6.3. Securing Your Projects
The security of your projects relies on the security of your CVS repository, the repository's computer and its environment, all the computers that contain sandboxes, your access method, your backup storage, and your developers' working environments. The security of access methods is covered in Chapter 8. General computer security is outside the scope of this book, but you should consider it when securing your repository.
Both sandbox and repository security is based on the filesystem security for the operating system that the repository is running under. The specific instructions in this section are based on traditional Unix and Linux filesystem permissions, but the principles can also be used to secure a repository running under systems with more extensive security options, such as Access Control Lists (ACLs).
Sandbox security relies on the security features installed in the filesystem that the sandbox is stored on. CVS expects to find separate user and group ownership, and separate read, write, and execute permissions for files. Fortunately, these features are available in all the systems for which CVS clients are available. Sandboxes are checked out of the repository with the username of the user who creates them (with cvs checkout). If the client's computer has a group that matches the group ownership of files in the repository, files in the sandbox are stored with that group ownership.
Read and write permissions in a sandbox depend on the settings for new files in the sandbox computer's operating system, on whether the user has the CVSREAD environment variable set, and on whether the files are being watched with the cvs watch commands. The CVSREAD environment variable is described in "Client Environment Variables," later in this chapter.
If a file is imported or added as executable, it is set as executable in the repository and the executable setting is preserved in the sandboxes.
If your project must be kept secure, ensure that the computers that the sandboxes are on are kept secure. Keep an eye on the location of any printouts your developers make, and any copies they may make outside their sandboxes. Remember that you need to track the data, not just the CVS files.
6.3.2. Repository Root Directory
Secure the repository root directory so that only the CVS owner and users who are allowed to create new projects have write access to this directory. Users who will be using existing repository projects, even though they may be creating and writing to project files, should have read access to this directory.
Securing the repository root directory usually involves creating a group for the users with the right to import projects, setting the repository root directory read-write-execute for the repository's owner and that group, and setting it read-execute for all others. It's fairly typical for write access to the repository root to be limited to the system administrator and her assistants, or to the CVS repository administrator if that person is different from the system administrator.
You may also want to set the Set Group ID (SGID) bit on the repository root directory to ensure that all projects are imported with a reasonably secure group. You'll see how to do this in the upcoming section "Project Directories."
In many cases, people who can create projects can also be trusted with the CVSROOT subdirectory, so you can set that directory read-write for those same users. Be aware, however, that these people will have access to scripts that will run arbitrary commands when CVS users check in files. See the following section for more information on the CVSROOT directory.
Example 6-1 shows a small repository and the permissions and groups set for it. The user cvs is the owner of the repository, and the group cvs is the group for people who can create new projects. The user doppel created the wowow project for the people in the group sauce, and the user jenn created the wizzard project for those in the group wizzard.
Example 6-1. Repository permissions
6.3.3. CVSROOT Directory
The permissions on the CVSROOT directory in the repository should be considered carefully. A user who can modify the files in this directory may be able to cause CVS to run arbitrary commands on the repository computer. These files are the scripting files explained in Chapter 7; they're run as the user who commits a file to CVS, and they can run any command or script. Only trusted users should have write access to this directory or most of the files in this directory.
All users who will have access to CVS should have read access to all the files in the CVSROOT directory.
Two files should be writable (as well as readable) to all users who will be running CVS commands: the history file and the val-tags file. If the history file exists, most CVS commands attempt to append to it, and fail if they can't. Many commands attempt to modify val-tags. Neither of these files trigger scripts or arbitrary commands; both are purely informational.
6.3.4. Project Directories
CVS allows you to have any number of projects in the same repository, and each project can be secured separately. Create a group for each project, and add the users who should be changing project files to that group.
It's good practice to give each project its own group, even if two projects have the same development team when the projects are created. Over the lifetime of the projects, their teams may diverge.
Group ownership of project files and directories controls project security. Ensure that each project is group-owned by a group with appropriate membership, and set the group permissions for the project files to the project's group. Also set the SGID bit, as described earlier in "Repository Root Directory."
You have only directory-level control over the security of project files. CVS sets the permissions of files stored in the repository and overwrites any read or write permissions you set when it next changes the files. When a file is changed, CVS writes a temporary version of the file, then copies the temporary file over the original file. The resulting file is owned by the person who last changed it. The group of users who change the files in a project repository must have read, write, and execute access to the project directories. Because files are overwritten when changed (during the commit process), a user changing a file needs write permission to the directory the file is in, but not to the file itself.
Users reading project files must have read and execute access to the project directories and write access to the location of the project's locksusually the project's directories. The LockDir option in the config file in the repository's CVSROOT directory can change the location of the lock files if you want to avoid giving out write permission to the repository's project directories.
To ensure that group ownership is set correctly, have your project directories automatically create the correct group permissions for new files. To do this, set each directory's SGID bit: this tells the operating system to set the group ID for new files or directories to the group ID of the directory they are created in. Use the command chmod g+s directory to set the SGID bit. The directories in Example 6-1 have their SGID bits set.
If a file is executable when it is imported or added, CVS sets it to executable in the repository. The executable bit in the repository copy of the file is preserved when the file is checked out to the sandbox. If a file should be executable but isn't, or shouldn't be but is, change the setting in the repository with chmod.
When you change the settings on a file in the repository, the file permissions of existing files in existing sandboxes are unaffected. To correct the sandbox permissions, delete the file from the sandbox and then retrieve a new copy with cvs update.
Committing a file with sandbox permissions that differ from the repository permissions does not affect the permissions in the repository version. Repository files acquire sandbox file permissions only during an add.
6.3.5. General Information on Security
If you need to set project file permissions differently from your usual file permissions, you can use the CVSUMASK environment variable, which specifies a umask setting for CVS to use. The CVS process on the repository server reads the calling user's CVSUMASK and, if this variable is present, uses the umask to set the permissions of any files or directories the CVS process creates. The format of CVSUMASK is the same as the Unix and Linux shell setting umask.
CVS normally uses the project's repository directories for lock files. Consider designating an alternate directory by using the LockDir setting in the config file in the repository's CVSROOT directory. This setting allows you to restrict users from writing to the project directories. If you use LockDir, remember to modify any scripts that you are using to freeze the repository (see "Freezing a Repository," later in this chapter). Also, when you need to remove a lock manually, be sure to look in the LockDir directory. Changing the lock directory is rarely needed, but you should be aware that it is possible.