McGill University School of Computer Science
McGill University School of Computer Science
Views
You are here: MultiUserSVN

MultiUserSVN

From Socs Info Wiki

Multi-user Subversion via SSH


This web page provides a step by step tutorial for providing multi-user access controlled Subversion repositories via SSH. If you have a question that isn't answered here, send mail to svn@seas.upenn.edu. Thanks to Nate Foster for telling me about this technique.

Getting and generating keys

For each user of the repository you will need a SSH public key from them. If the user already has a SSH key-pair that they can use, it will most likely be found in their home directory as ~/.ssh/id_ras.pub or ~/.ssh/id_dsa.pub. If the user doesn't have a SSH key-pair, they will need to run ssh-keygen in something like the following fashion:

$ ssh-keygen -t dsa -C "<user@e-mail.address.net>"
Generating public/private dsa key pair.
Enter file in which to save the key (/home/username/.ssh/id_dsa):
Created directory '/home/username/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/username/.ssh/id_dsa.
Your public key has been saved in /home/username/.ssh/id_dsa.pub.
The key fingerprint is:
f3:31:a8:c6:82:18:c8:0f:dd:6b:fb:27:98:83:3d:3b <user@e-mail.address.net>
where the user replaces <user@e-mail.address.net> with their e-mail address. This will create a line in the file ~/.ssh/id_dsa.pub corresponding to this key; they'll want to send you that line.
Configuring repository user login

Now for each repository user, you will need to add a line to your ~/.ssh/authorized_keys file. It will look something like

command="svnserve --tunnel --tunnel-user <username> --root </path/to/repository>",no-port-forwarding,no-agent-forwarding,no-X11-forwarding,no-pty ssh-dss <user key here>

where <username> is the user-name you plan on giving the user in the repository, </path/to/repository> is the fully-qualified path of the repository, and <user key here> is the public key data the user sent you.

Configuring access control

Next, in </path/to/repository>/conf/svnserve.conf you will want to add something like

[general]
anon-access = none
auth-access = write
authz-db = authz.conf

Then, in </path/to/repository>/conf/authz.conf you will want to write an access control file that looks something like

[groups]
<a-group-name>=<user1>,<user2>,<...>
[/]
@<a-group-name>=rw

Once you start using svnserve.conf, be mindful to add yourself or any other user(s) who add access to the repository to the authz.conf file.

For more information on the format of these files, look at the Subversion book. In particular, details on the access control file can be found here.

Checking out from the repository

If everything has worked correctly, users can check out from the repository with the following incantation

 svn co svn+ssh://<username>@svn.cs.mcgill.ca/<repository>/

Here you should only give the repository name and NOT the full path to the repository as it is already set above, also <username> here is to be the one who sets up the svn repository and not the <username> that is given for the ssh keys.

Configuring anonymous access

If you would like to provide anonymous access to your repository, you will first need to generate a SSH key-pair, as described above, for the "anonymous user". It is probably best not to give this key a password. Next you create a new entry in your ~/.ssh/authorized_keys file with the public key from this key-pair, as you did for the other users. However, instead use guest for <username>. And then to users that you want to provide anonymous access, you provide the private key from this key pair.

Finally, add lines something like the following to your </path/to/repository>/conf/authz.conf file

[/]
guest=r

This document is originally from https://svn.cis.upenn.edu/multi-ssh-howto.html

How to set-up SVN hook for automatic update after every commit

The idea is to set up an svn hook that would update a directory after each commit. For example, a website stored on an svn to update every time a change is committed. This is specially useful when multiple people can contribute to the site.

This is best illustrated by an example:

When a hook excecutes, it executes under the user that ran the commit. For example, user adenau commits, however the website exists under the user mammoth. So, if svn update is run on a repository checkout own by mammoth, we have a a permission problem.

The solution is to use the setuid bit. However, when the setuid bit is set on a shell script, the OS( mainly Unix ) ignores it. The solution to this is on the subversion fact. A small C executable needs to created that does the update and also set to be setuid. Here is an example C application.


#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>

#define HOME_ENV ("HOME=/home/2005/mammoth")int main(int argc, char *argv[]) {

char *env[2] = { HOME_ENV, NULL};

execle("/usr/local/bin/svn", "svn", "update",
"/home/2005/mammoth/public_html/",
(const char *) NULL, env);
       return(EXIT_FAILURE);
}

 

The only difference between this C program and the one in the subversion faq is that the home directory was reset. SVN will not work properly under the mammoth user (after the setuid) unless its also pointing to the proper home directory.

After that, compile the C application, put it on a non-nfs location, setuid and add it to the post-commit.

Thanks goes to Alexandre Denault for his script.