Suppose you want to host virtual repository in `/repos1' directory.
First you have to create system group called `repos1'. Then create two system accounts for this repository. Let us call them `repos1user' and `repos1admin'. Make sure both users have the `repos1' group as a primary group.
Create the `/repos1' directory itself and make sure it is owned by `repos1admin' user and `repos1' group. This directory should have read-write access to user, read-only access to group and no access to the other world (i.e., `0750').
The filesystem containing the repository should support BSD-style semantics for assigning group ownership (i.e. newly created files and directories are owned by the same group that owns their parent directory). Some systems support this by default, some (i. e., Linux) have either `bsdgroups' mount option or the `/repos1' directory should have setgid bit on (i.e., `2750').
Init the repository with `cvs init':
$ cvs -d :local:/repos1 init
Make sure that `/repos1/CVSROOT/' and all files within it are owned by user `repos1admin', group `repos1'. `/repos1/CVSROOT' has access rights of `0750' and all files within it should be `0640'.
There are two special files: `/repos1/CVSROOT/history' should have access rights of `0660' because every user's actions have to be logged in this file. `/repos1/CVSROOT/cvspasswd' contains sensitive passwords (although crypted) and should be `0600'.
Create directories for each module in this repository (there seems to be no way of creating these remotely) and make them belong to `repos1user' user and `repos1' group. These directories have access rights of `0770'.
Almost every virtual user for this repository will work under the single system account `repos1user' and system group `repos1'. This means that the corresponding field in `cvspasswd' should contain `repos1user:repos1', See section passwd--manage the `CVSROOT/cvspasswd' file.
This configuration is the most simple and seems to cover most installations. There are several ways to handle more complex virtual repositories.
The most flexible and natural solution is adding ACL (access control lists) to CVS-server. This project is currently under development. If you would like to positively influence this process, contact me: firstname.lastname@example.org.
If your operating system supports file-level ACLs, you may use these. Note that administrator of such a repository would have a shell account on CVS-server machine to fiddle with this.
Otherwise you may create additional system groups and make various module directories in repository owned by the appropriate groups. Also assign every virtual CVS-user an appropriate system group, using `cvs passwd' command. In this case administrator of such kind of repository would have an account each time she wants to create a new system group (assigning of this groups to virtual users could be made remotely).
To repeat, CVS ACLs seems to be the best solution: remotely manageable, extremely (almost unmanageably) flexible, more fine-grained than filesystem-level ACLs (i.e. working on the level of CVS operations).
To install CVS-server with virtual domains support edit your `/etc/inetd.conf' and add the following line (formatted to fit the screen):
2401 stream tcp nowait root /usr/local/bin/cvs-pserver cvs-pserver /repos1 /repos2 -- /usr/local/bin/cvschkpw /usr/local/bin/cvs pserver
inetd wants a symbolic service name
instead of a raw port number, then put this in
cvspserver instead of
inetd or make it to re-read its
Here `/usr/local/bin/cvs-pserver' is the path to
/repos2 etc. (until the "
--" string) are
the names of repositories where users are allowed to
login over the network. `/usr/local/bin/cvschkpw'
is authentication binary that conforms to
checkpassword interface described at
`/usr/local/bin/cvs' is the path to CVS
binary that will be executed if the user will
Go to the first, previous, next, last section, table of contents.