Главная > Subversion > SVN and permissions

SVN and permissions

Quite often I hear people complaining “BDB sucks, it breaks here twice a day! I will use FSFS now. BDBjust sucks”. This seems true at first. But in many cases, it’s an administration error. 🙂

As the svn book and FAQ point out in many places, you need to take care of the permissions. The first important link with BDB and permissions might be the FAQ entry “Why do read-only operations still need repository write access?”. It explains why BDB requires write permission to the repository directory even for readonly operations. At this point, FSFS seems distinctly better than BDB, because FSFS only requires read permissions for readonly operations.

 For our checklist we keep in mind that a user needs write permissions for reading the repos.

Now we have to sort out the question “Who needs access to our repos?” I will discuss some common setups here.

The basic setup

$ mkdir -p /srv/svn/repositories
$ svnadmin create /srv/svn/repositories/project01
$ cd /srv/svn/repositories/project01
$ find . -ls
31320846    0 drwxr-xr-x   7 root     root           90 Apr  9 00:14 .
2272808    0 drwxr-xr-x   2 root     root            6 Apr  9 00:14 ./dav
7178361    0 drwxr-xr-x   2 root     root           39 Apr  9 00:14 ./locks
7178364    4 -rw-r--r--   1 root     root          460 Apr  9 00:14 ./locks/db.lock
7178366    4 -rw-r--r--   1 root     root          295 Apr  9 00:14 ./locks/db-logs.lock
8854953    4 drwxr-xr-x   2 root     root         4096 Apr  9 00:14 ./hooks
11228932    4 -rw-r--r--   1 root     root         2137 Apr  9 00:14 ./hooks/start-commit.tmpl
11228937    4 -rw-r--r--   1 root     root         2944 Apr  9 00:14 ./hooks/pre-commit.tmpl
11228939    4 -rw-r--r--   1 root     root         2764 Apr  9 00:14 ./hooks/pre-revprop-change.tmpl
11228940    4 -rw-r--r--   1 root     root         2016 Apr  9 00:14 ./hooks/pre-lock.tmpl
11228943    4 -rw-r--r--   1 root     root         1998 Apr  9 00:14 ./hooks/pre-unlock.tmpl
11228944    4 -rw-r--r--   1 root     root         2015 Apr  9 00:14 ./hooks/post-commit.tmpl
11228946    4 -rw-r--r--   1 root     root         1637 Apr  9 00:14 ./hooks/post-lock.tmpl
11231620    4 -rw-r--r--   1 root     root         1564 Apr  9 00:14 ./hooks/post-unlock.tmpl
11237184    4 -rw-r--r--   1 root     root         2255 Apr  9 00:14 ./hooks/post-revprop-change.tmpl
13642827    0 drwxr-xr-x   2 root     root           39 Apr  9 00:14 ./conf
13642830    4 -rw-r--r--   1 root     root         1078 Apr  9 00:14 ./conf/svnserve.conf
13642831    4 -rw-r--r--   1 root     root          311 Apr  9 00:14 ./conf/passwd
31320848    4 -rw-r--r--   1 root     root          379 Apr  9 00:14 ./README.txt
31320850    4 -r--r--r--   1 root     root            2 Apr  9 00:14 ./format
<strong>18259246    0 <u>drwxr-sr-x</u>   5 root     root          120 Apr  9 00:14 ./db</strong>
18272163    4 -rw-r--r--   1 root     root            5 Apr  9 00:14 ./db/fs-type
23169557    0 drwxr-sr-x   2 root     root           14 Apr  9 00:14 ./db/revs
23169558    4 -rw-r--r--   1 root     root          115 Apr  9 00:14 ./db/revs/0
27193648    0 drwxr-sr-x   2 root     root           14 Apr  9 00:14 ./db/revprops
27193649    4 -rw-r--r--   1 root     root           50 Apr  9 00:14 ./db/revprops/0
31320852    0 drwxr-sr-x   2 root     root            6 Apr  9 00:14 ./db/transactions
18272185    4 -rw-r--r--   1 root     root            6 Apr  9 00:14 ./db/current
18272212    0 -rw-r--r--   1 root     root            0 Apr  9 00:14 ./db/write-lock
18273153    4 -rw-r--r--   1 root     root           37 Apr  9 00:14 ./db/uuid
18273164    4 -r--r--r--   1 root     root            2 Apr  9 00:14 ./db/format

 In the output of “find” we can already see one important point: newer svn releases set the ”<a href=”http://www.gnu.org/software/coreutils/manual/html_chapter/coreutils_26.html#SEC159”>set group id” flag on the db directory. This flag makes sure that all files created in the “db” directory are owned by the same group as the “db” directory.

Basic Concept

Note that the setgid bit doesn’t suffice to ensure correct permissions: we can only enforce the groupownership, but not enforce the permissions the new file will get—the umask of the user influences those. A typical umask value is “022”; if you create a file with this umask it will get the following permissions:

$ umask
022
$ touch file
$ ls -l file
-rw-r--r--  1 darix users 0 2005-04-09 00:41 file

As we see the group can only read the file. This is fine for FSFS, but for BDB we would need write permissions.

$ umask 007
$ touch file
$ ls -l file
-rw-rw----  1 darix users 0 2005-04-09 00:44 file

Setting the umask to “007” gives the group write permissions and removes all permissions for others. a more liberal umask would be “002” which would allow the others at least read permissions. A paranoid user would set “077” which takes permissions away from all other users (note that this umask would wreak havoc with either flavor of subversion repository). The complete magic is explained in man umask.

 

FSFS takes care of this itself. If FSFS backend creates a new file it uses the permissions of the previous revision. This permission inheritance makes sure that the group can always write the files.

 For the checklist we keep “The umask can be important!”

 

Apache2/Svnserve Only

These are for sure the easiest cases. You should run them as a non-root user!
I assume you run Apache2 as “apache:apache” and svnserve as “svn:svn”:

$ chown -R apache: /srv/svn/repositories/project01/db
$ find . -ls
31320846    0 drwxr-xr-x   7 root     root           90 Apr  9 00:14 .
2272808    0 drwxr-xr-x   2 root     root            6 Apr  9 00:14 ./dav
7178361    0 drwxr-xr-x   2 root     root           39 Apr  9 00:14 ./locks
7178364    4 -rw-r--r--   1 root     root          460 Apr  9 00:14 ./locks/db.lock
7178366    4 -rw-r--r--   1 root     root          295 Apr  9 00:14 ./locks/db-logs.lock
8854953    4 drwxr-xr-x   2 root     root         4096 Apr  9 00:14 ./hooks
11228932    4 -rw-r--r--   1 root     root         2137 Apr  9 00:14 ./hooks/start-commit.tmpl
11228937    4 -rw-r--r--   1 root     root         2944 Apr  9 00:14 ./hooks/pre-commit.tmpl
11228939    4 -rw-r--r--   1 root     root         2764 Apr  9 00:14 ./hooks/pre-revprop-change.tmpl
11228940    4 -rw-r--r--   1 root     root         2016 Apr  9 00:14 ./hooks/pre-lock.tmpl
11228943    4 -rw-r--r--   1 root     root         1998 Apr  9 00:14 ./hooks/pre-unlock.tmpl
11228944    4 -rw-r--r--   1 root     root         2015 Apr  9 00:14 ./hooks/post-commit.tmpl
11228946    4 -rw-r--r--   1 root     root         1637 Apr  9 00:14 ./hooks/post-lock.tmpl
11231620    4 -rw-r--r--   1 root     root         1564 Apr  9 00:14 ./hooks/post-unlock.tmpl
11237184    4 -rw-r--r--   1 root     root         2255 Apr  9 00:14 ./hooks/post-revprop-change.tmpl
13642827    0 drwxr-xr-x   2 root     root           39 Apr  9 00:14 ./conf
13642830    4 -rw-r--r--   1 root     root         1078 Apr  9 00:14 ./conf/svnserve.conf
13642831    4 -rw-r--r--   1 root     root          311 Apr  9 00:14 ./conf/passwd
31320848    4 -rw-r--r--   1 root     root          379 Apr  9 00:14 ./README.txt
31320850    4 -r--r--r--   1 root     root            2 Apr  9 00:14 ./format
18259246    0 drwxr-sr-x   5 apache   apache        120 Apr  9 00:14 ./db
18272163    4 -rw-r--r--   1 apache   apache          5 Apr  9 00:14 ./db/fs-type
23169557    0 drwxr-sr-x   2 apache   apache         14 Apr  9 00:14 ./db/revs
23169558    4 -rw-r--r--   1 apache   apache        115 Apr  9 00:14 ./db/revs/0
27193648    0 drwxr-sr-x   2 apache   apache         14 Apr  9 00:14 ./db/revprops
27193649    4 -rw-r--r--   1 apache   apache         50 Apr  9 00:14 ./db/revprops/0
31320852    0 drwxr-sr-x   2 apache   apache          6 Apr  9 00:14 ./db/transactions
18272185    4 -rw-r--r--   1 apache   apache          6 Apr  9 00:14 ./db/current
18272212    0 -rw-r--r--   1 apache   apache          0 Apr  9 00:14 ./db/write-lock
18273153    4 -rw-r--r--   1 apache   apache         37 Apr  9 00:14 ./db/uuid
18273164    4 -r--r--r--   1 apache   apache          2 Apr  9 00:14 ./db/format

For svnserve, of course, you’d instead do chown -R svn: /srv/svn/repositories/project01/db.

You might argue that one should further restrict the permissions, so that others can neither read nor write the “db” directory. You’d be right. My paranoid setup looks like this:

$ chmod -R o= /srv/svn/repositories/project01
$ chgrp -R apache /srv/svn/repositories/project01
$ find . -ls
31320846    0 drwxr-x---   7 root     apache            90 Apr  9 00:14 .
2272808    0 drwxr-x---   2 root     apache             6 Apr  9 00:14 ./dav
7178361    0 drwxr-x---   2 root     apache            39 Apr  9 00:14 ./locks
7178364    4 -rw-r-----   1 root     apache           460 Apr  9 00:14 ./locks/db.lock
7178366    4 -rw-r-----   1 root     apache           295 Apr  9 00:14 ./locks/db-logs.lock
8854953    4 drwxr-x---   2 root     apache          4096 Apr  9 00:14 ./hooks
11228932    4 -rw-r-----   1 root     apache          2137 Apr  9 00:14 ./hooks/start-commit.tmpl
11228937    4 -rw-r-----   1 root     apache          2944 Apr  9 00:14 ./hooks/pre-commit.tmpl
11228939    4 -rw-r-----   1 root     apache          2764 Apr  9 00:14 ./hooks/pre-revprop-change.tmpl
11228940    4 -rw-r-----   1 root     apache          2016 Apr  9 00:14 ./hooks/pre-lock.tmpl
11228943    4 -rw-r-----   1 root     apache          1998 Apr  9 00:14 ./hooks/pre-unlock.tmpl
11228944    4 -rw-r-----   1 root     apache          2015 Apr  9 00:14 ./hooks/post-commit.tmpl
11228946    4 -rw-r-----   1 root     apache          1637 Apr  9 00:14 ./hooks/post-lock.tmpl
11231620    4 -rw-r-----   1 root     apache          1564 Apr  9 00:14 ./hooks/post-unlock.tmpl
11237184    4 -rw-r-----   1 root     apache          2255 Apr  9 00:14 ./hooks/post-revprop-change.tmpl
13642827    0 drwxr-x---   2 root     apache            39 Apr  9 00:14 ./conf
13642830    4 -rw-r-----   1 root     apache          1078 Apr  9 00:14 ./conf/svnserve.conf
13642831    4 -rw-r-----   1 root     apache           311 Apr  9 00:14 ./conf/passwd
31320848    4 -rw-r-----   1 root     apache           379 Apr  9 00:14 ./README.txt
31320850    4 -r--r-----   1 root     apache             2 Apr  9 00:14 ./format
18259246    0 drwxr-s---   5 apache   apache           120 Apr  9 00:14 ./db
18272163    4 -rw-r-----   1 apache   apache             5 Apr  9 00:14 ./db/fs-type
23169557    0 drwxr-s---   2 apache   apache            14 Apr  9 00:14 ./db/revs
23169558    4 -rw-r-----   1 apache   apache           115 Apr  9 00:14 ./db/revs/0
27193648    0 drwxr-s---   2 apache   apache            14 Apr  9 00:14 ./db/revprops
27193649    4 -rw-r-----   1 apache   apache            50 Apr  9 00:14 ./db/revprops/0
31320852    0 drwxr-s---   2 apache   apache             6 Apr  9 00:14 ./db/transactions
18272185    4 -rw-r-----   1 apache   apache             6 Apr  9 00:14 ./db/current
18272212    0 -rw-r-----   1 apache   apache             0 Apr  9 00:14 ./db/write-lock
18273153    4 -rw-r-----   1 apache   apache            37 Apr  9 00:14 ./db/uuid
18273164    4 -r--r-----   1 apache   apache             2 Apr  9 00:14 ./db/format

This setup will allow apache to read all files in the repository directory but only write in the “db” directory. Other users than root or apache don’t have any access.

Allowing Svnserve and Apache2 to access the same repository

Now we get to the interesting problems: two daemons accessing the same repository. We have two possibile solutions:

  1. running both daemons as apache
  2. both daemons in a common group

running both daemons as apache

This is the easier of the two solutions. The permissions from above stay the same as above. We just need to start the svnserve as apache. On distributions with startproc it will look like:

$ startproc -u apache -g apache -e /usr/bin/svnserve -d -r /srv/svn/repositories

On systems with start-stop-daemon:

$ start-stop-daemon --start --chuid apache --group apache --exec /usr/bin/svnserve -- -d -r /srv/svn/repositories

For all other systems please refer to the manual of your os/distributon.

both daemons in a common group

For this approach we use point #2 from our checklist. First we need to decide which group we use. We can add the svn user to the group apache, or conversely we can add the apache user to the svn group. The latter has fewer possible security implications, so i will use this for my example:

# suse
$ /usr/sbin/groupmod --add-user apache svn
# freebsd
$ pw groupmod -n svn -m apache

We can set our new permissions now. Based on the paranoid example from above

$ chgrp -R svn /srv/svn/repositories/project01

Now we have to make sure both daemons run with a proper umask. The umask is usually inherited from the startup environment. Usually this can cause trouble, as root usually has “022” as its umask. If you want to make sure that the umask of the daemon is always correct, add “umask 007” in your startscript. Et voila—svnserve and apache can both access the repos just fine. 🙂

At this moment we don’t care anymore if your apache is running mod_dav_svn or viewcvs or any other repository viewer. They all work just fine and don’t wedge the repository. (At least not for permissions reasons.)

Adding file:// and svn+ssh:// to the mix

svn+ssh:// and file:// both access the repository the same way. In general we have the same problems as in the last block. We need to make sure that all accessing users have a common group and a proper umask. The easiest solution for file and svn+ssh are wrapper scripts.

file:// – access

Our wrapper script for file:// access:

#!/bin/sh
# wrapper script for svn
umask 007
exec /usr/bin/svn "$@"

You have to put this script in the path before your actual svn binary (”/usr/bin/svn”), to ensure that your users run your script. First we need to check the $PATH variable.

$ env | grep -e "^PATH=" 
PATH=/home/darix/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/games:/opt/gnome/bin:/opt/kde3/bin

On my box, ”/usr/local/bin” is in the path before ”/usr/bin/”. I save the wrapper script as ”/usr/local/bin/svn”. Any invocations of “svn” will then invoke ”/usr/local/bin/svn”. You should look at gui clients/scripts which invoke svn: sometimes they use a full path, hence bypassing our script. You’d need to adjust them, too. (This doesn’t refer to scripts like websvn—it is run in the webserver context and should have the proper umask.)

svn+ssh://

The solution for svn+ssh:// follows the same path. We have a small wrapper script again:

#!/bin/sh
# wrapper script for svnserve
umask 007
exec /usr/bin/svnserve "$@"

To find the value of $PATH from a ssh session we do:

$ ssh localhost env | grep -e "^PATH=" 
PATH=/home/darix/bin:/usr/local/bin:/usr/bin:/usr/X11R6/bin:/bin:/usr/games:/opt/gnome/bin:/opt/kde3/bin

Again, ”/usr/local/bin” seems to be a nice place for the wrapper script. We save the script as ”/usr/local/bin/svnserve”.

A note for BSD users: ”/usr/local/” is the default prefix for svn on a BSD, but put your wrapper scripts into ”/usr/bin” instead, because (at least, on my BSD box) ”/usr/bin” is in the path before ”/usr/local/bin”.

Conclusion

As shown in this short howto it is quite easy to have a proper setup with BDB without any permissions problems. So next time before you blame BDB … check your setup. From my day- by-day experience on#svn I can say 99% of the BDB wedges are permissions problems.

Sources

Original

Рубрики:Subversion
  1. Комментариев нет.
  1. Ноябрь 5, 2008 в 11:31 пп

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s

%d такие блоггеры, как: