
CVS Access Control List Extension Patch

http://cvsacl.sourceforge.net/
sbaris@users.sourceforge.net

CVSACL is a patch for CVS. It adds two new subcommands
(acl & racl) to cvs for access control list management. It
provides advanced ACL definitions per modules, directories,
and files on branch/tag for remote cvs repository connections.
Execution of all CVS subcommands can be controlled with eight
different permissions.
ACL definitions works for only remote connections, local users
can access and modify repository, if unix file system permissions
allow. If you want all users to make remote connections to
repository, and not allow local users to access repository, you
have to set CVSServerRunAsUser keyword in aclconfig file
(explained below).
Still local users can use acl and racl subcommands to set
permissions on directories or files if they have acl admin rights (p)
on related directories or files.
So, in order to control all access to repository with this ACL
extension, you should use CVSServerRunAsUser keyword and force all
users to make remote connections. CVS repository administrator or
project managers have to use acl and racl subcommands to manage
permissions. But there is no gui client supporting these subcommands,
so you have to use cvs client itself either locally or remotely. 




Permission Types

- no access
  Command line character: n
  If a user given n permission, it is not allowed for any action on repository. 
- read
  Command line character: r
  r permission gives only read access on repository.
  With r permission you are allowed to run cvs subcommands: annotate,
  checkout, diff, export, log, rannotate, rdiff, rlog, status. 
- write
  Command line character: w
  w permission allows only cvs commit/checkin action.
  With w permission, you are not allowed to add/remove any file to/from
  repository, other permissions should be defines for that. 
- tag
  Command line character: t
  t permission allows cvs tag and rtag subcommands to run, so you may
  control tagging and untagging operations. t permission includes r
  permission, since without reading you can not tag/untag a file.
  However t permission does not include write permission, you can not
  commit a file with only t permission. 
- create
  Command line character: c
  c permission allows cvs add and import subcommands to run. To add or
  import a file/directory to repository, you have to given a c
  permission. Again, c permission does not include write permission,
  thus you may only add or import files, but you can not modify any
  existing file. After issuing add subcommand, you have to commit the file
  to complete adding. This commit subcommand is allowed because you are
  adding file and not modifying existing one. 
- delete
  Command line character: d
  d permission allows cvs remove command to run. To remove a file/directory
  from repository, d permission have to set. It does not include write
  permission, so you can not modify contents of an existing file on repository. 
- full access except admin rights
  Command line character: a
  a permission gives all access (above permissions) to repository, but it
  can not modify permissions. Only acl admins may modify the acl definitions. 
- acl admin
  Command line character: p
  p permission means that user is an acl admin, so it is allowed to make anything on repository. 


ACL Config Keywords
The administrative file aclconfig contains miscellaneous settings which
affect the behaviour of ACL extension. Currently defined keywords are:

UseCVSACL=value 
Use ACL definitions if set to yes. If you do not want to use ACLs for
some repositories in a patched CVS server, set this keyword to no. The default is no.

UseCVSACLDefaultPermissions=value 
Value can be any combination of valid permission types (w,r,t,c,d,t,a,p).
if there is no defined ACL and default permission in access file, or no
access file at all, this permissions are used. The default is p (admin rights),
if aclconfig file is created with cvs init. 

UseCVSGroups=value 
CVS does not have a CVSROOT/passwd file. However it can be created manually
(format should be same as /etc/group). If value set to yes, CVS checks for
groups in file $CVSROOT/CVSROOT/group The default value is no.

UseSystemGroups=value 
Group memberships for users are checked in file /etc/group, if value is set
to yes. The default value is no.

CVSACLFileLocation=value 
Originally access file is put under CVSROOT/CVSROOT, if you want a different
location, set value to a valid path. The default value is $CVSROOT/CVSROOT/access.

CVSGroupsFileLocation=value 
IF UseCVSGroups is set to yes, CVS looks for a group file under $CVSROOT/CVSROOT.
To use a different location for group file set value to a valid path to group.
The default value is $CVSROOT/CVSROOT/group.

UseSeparateACLFileForEachDir=value 
If value is set to yes, a separate ACL file (access) is created for each
directory in repository. If you have a really big repository
(directories>10,000 and files>100,000), performance may drop due to a big 
acl file, access. Setting the value to yes, may increase performance. Normally,
you will not need this. The default value is no.

StopAtFirstPermissionDenied=value
If StopAtFirstPermissionDenied is set to yes
operation will stop at first permission denied message.
e.g. when you send commit command for a directory, if you dont
have write permission for just one file under the directory, 
by default you will have a warning and commit will continue
on the other files. If you set this keyword to 'no', then 
commit operation will be stopped when inaccassable file found.
Default is no.

CVSServerRunAsUser=value 
Set CVSServerRunAsUser keyword to a valid system user.
When a user make a remote connection to CVS, after successfull authentication
cvs process switch to run as that user, or defined system user in
$CVSROOT/CVSROOT/passwd. So, you also have to set unix file permissions accordingly.
A better solution:
Add a user and group such as both cvsadm.
Set CVSServerRunAsUser keyword to cvsadm.
Change unix file system permissions for your repository,
make cvsadm user and group owner, and read,write,execute permissions and setgid.
(chown cvsadm -R /path/to/your/repository)
(chgrp cvsadm -R /path/to/your/repository)
(chmod 2770 -R /path/to/your/repository)
Add yourself to cvsadm group (since you are ACL administrator).
Therefore, only users making remote connections will have access to repository
if you give rights. Local users can not access to repository via a cvs client or directly.


Command Line Usage Information
acl command is used on checked out files or directories. racl command is
used on repository without a working copy. Usage information can be obtained
with standard cvs --help command.
Output of cvs --help acl and cvs --help racl: 

Usage: cvs racl [user||group:permissions] [-Rl] [-r tag]
        -R      Process directories recursively.
        -r rev  Existing revision/tag.
        -l      List defined ACLs.

Usage: cvs acl [user||group:permissions] [-Rl] [-r tag]
        -R      Process directories recursively.
        -r rev  Existing revision/tag.
        -l      List defined ACLs.

NOTICE: there is no more -d -f options for directory and file, acl/racl 
subcommands works just like other cvs subcommands.

You may directly set permissions for a user or group or add/remove
permissions with + and - signs to/from existing permissions.
If you do not give the branch/tag information, default value of HEAD
(main branch) will be used. You have to give branch/tag name with -r option.
You may type ALL for branch/tag field.

While checking for permissions, it goes thorough the list below. So the highest
significant permission is the first item in list.

- permissions assigned to username for specific directory or file. 
- permissions assigned to group name for specific directory or file. 
- permissions as defaults for specific directory or file. 
- permissions assigned to parent folders (inherits from the first parent
  which permissions are assigned).
- permissions as repository defaults. 
- permissions in aclconfig file. 




Examples
     /cvs/
      |
      |
      +--projectA/
      |	       |
      |        +---CVSROOT/
      |        |
      |        +---lib/
      |        |     |
      |        |     +---gnulib/
      |        |     |
      |        |     +---zlib/
      |        |
      |        +---src/
      |        |     |
      |        |     +---main.c
      |        |     |
      |        |     +---server.c
      |        |     |
      |        |     +---client.c
      |        |
      |        +---gui/
      |
      +--projectB/
We have above directory structure for a cvs repository, and no defined permissions.

Setting main default permissions:

$ cvs -d /cvs/projectA racl cvsadmin:p -r ALL ALL
$ cvs -d /cvs/projectA racl ALL:r -r ALL ALL
User cvsadmin will be an acl admin, and all other users will have only read
rights on all branches/tags in projectA repository. This is the default acl
definition and it overwrites default permissions in $CVSROOT/CVSROOT/aclconfig file.

$ cvs -d /cvs/projectA racl ALL:r -r ALL ALL
$ cvs -d /cvs/projectA racl ALL:n -r ALL gui
After executing these two commands, all users will have read access on all
directories and files except gui directory. Everyone will be denied to access to gui
directory becase no access, n, permissions is set.

Setting permissions directly on a file or directory:

$ cvs -d /cvs/projectA racl userX:wcd lib
$ cvs -d /cvs/projectA racl group1:w lib
First command will set write, create, and delete permissions for userX on directory
lib with branch HEAD (since no branch/tag information given, branch defaults to HEAD).
Second command will set only write permission for group1 on directory lib with branch HEAD.
Members of group1 will have only commit rights on lib directory, branch HEAD, they can
not add or remove any file, just modify existing files.
If userX is also a member of group1, userX will have write, create, and delete permissions
because it is specifically given these permissions.

$ cvs -d /cvs/projectA racl userY:wcd -r develStream lib
$ cvs -d /cvs/projectA racl userY:r -r integStream lib
These commands will give wcd permissions to userY on lib directory with tag develstream,
and r permissions on lib directory with tag integStream.

$ cvs -d /cvs/projectA racl userZ:wcd src
$ cvs -d /cvs/projectA racl userZ:r src/main.c
First command will give wcd permissions to userZ on src directory, but only read
permission on file main.c in src directory.

Using + and - signs to set permissions on a file or directory:

$ cvs -d /cvs/projectA racl userZ:+t src
$ cvs -d /cvs/projectA racl userZ:-cd src
$ cvs -d /cvs/projectA racl userZ:-wt src
Before the first command, userZ has wcd permissions on src directory, after issuing
command it will have wcdt permissions. Tag permission will be added. UserZ has wcdt
permissions, and we execute the second command to remove create and delete permissions.
So userZ has wt permissions. In the last command we also remove wt permissions, finally
userZ has no defined permissions left, and it will use the default permissions if set.

Listing permissions on a file or directory:

$ cvs -d /cvs/projectA racl -l src
$ cvs -d /cvs/projectA racl -l src
$ cvs -d /cvs/projectA racl -l src/main.c

First command will list the permissions for src directory.
Example output:
d src HEAD | userX:wcd group1:r | defaults:r
userX and group1 has assigned permissions, all other users will have default
permissions, which is only read.

Second command will list the permissions for files in src directory.
Example output:
f src/main.c HEAD | userX:wcd group1:r | defaults:r
f src/server.c HEAD | userX:wcd group1:r | defaults:r
f src/client.c HEAD | userX:wcd group1:r | defaults:r

Third command will list the permissions for main.c file in src directory.
Example output:
f src/main.c HEAD | userX:wcd group1:r | defaults:r


