Proper access rights with SSH+SVN

July 13, 2009 - Joeri - ssh - access - svn - Software

We want to use SSH+SVN. We do!

However, access rights can be a pain with this protocol since we cannot use SVN's built-in access management. We want to achieve the following:

User "user1" can access repositories "project_a" and "project_b". User "user2" can only access repository "project_b". Now, "user1" and "user2" do not have the same primary group. The first has "staff" as a primary group and the latter, group "users".

In order to do this, we will create a group for every repository. This way we can assign different users to different groups and therefore to different repositories. To give an overview:

svnadm: svn-users
user1: staff, svn-users, svn-project-a, svn-project-b
user2: users, svn-users, svn-project-b

Since both users need to access one or more repositories, they are all part of group "svn-users". There is a sort of super-user called "svnadm", which is not really important for this explanation.

Let's set up our directory structure and keep in mind that all groups have write permission (g+wr):

/var/svn                        svnadm  svn-users
/var/svn/project_a              user1   svn-project-a
/var/svn/project_b              user2   svn-project-b

The whole "project_a" directory and all it's children have "svn-project-a" as group. The same goes for "project_b" that has "svn-project-b" as group.

The problem

Theres one problem though: If a user commits a change to a repository, his primary group is used for some repository administration files (in repo/db) which renders the repository inaccessible to others that are not in the same group. Thus, if "user1" commits to "project_b", some files will have group "staff" and "user2" cannot access them.

Suddenly you might have this:

/var/svn                        svnadm  svn-users
/var/svn/project_a              user1   svn-project-a
/var/svn/project_b              user2   svn-project-b
/var/svn/project_b/db/current   user1   staff


The solution

The solution is something I haven't found that clear on the internet, so here it is:

find /var/svn/project_a/db -type d -exec chmod g+s '{}' \;
find /var/svn/project_b/db -type d -exec chmod g+s '{}' \;

What this does is simple. We give a g+s-bit to all repo/db directories. Setting directories g+s makes all new files created in said directory have their group set to the directory's group. You should do this for every repository.

If you also set your default umask to 002 you're done. This allows users and groups to write and can be set in your ~/.bashrc file or set as default in /etc/login.defs (on some Linux distributions).

Have fun!

Latest Tweets