Contrôle d'accès basé sur les chemins

Apache et svnserve sont tous deux capables d'accorder ou de refuser l'accès aux utilisateurs. Généralement c'est géré globalement au niveau du dépôt : un utilisateur peut accéder (ou pas) au dépôt en lecture et il peut accéder (ou pas) au dépôt en écriture. Il est pourtant aussi possible de définir des règles d'accès possédant une granularité plus fine. Un ensemble d'utilisateurs peut alors obtenir le droit d'écrire dans certains répertoires du dépôt mais pas dans d'autres ; parallèlement, un autre répertoire peut très bien ne pas être accessible en lecture pour la majorité des utilisateurs.

Les deux types de serveurs utilisent un format de fichier commun pour décrire les règles d'accès basées sur les chemins. Dans le cas d'Apache, il faut charger le module mod_authz_svn puis ajouter la directive AuthzSVNAccessFile (dans le fichier httpd.conf) pointant vers votre propre fichier de règles (pour l'explication complète, voir la section intitulée « Contrôle d'accès par répertoire »). Si vous utilisez svnserve, vous devez faire pointer la variable authz-db (dans le fichier svnserve.conf) vers votre fichier de règles.

Une fois que votre serveur sait où trouver votre fichier de règles, il est temps de définir ces règles.

La syntaxe du fichier est la même syntaxe que celle utilisée dans svnserve.conf et dans les fichiers de configuration. Les lignes commençant par un dièse (#) sont ignorées. Dans la forme la plus simple, chaque section désigne un dépôt et un chemin à l'intérieur de celui-ci et les noms d'utilisateurs authentifiés sont les noms des options à l'intérieur de chaque section. La valeur de chaque option décrit le niveau d'accès de l'utilisateur au chemin du dépôt : soit r (lecture seule), soit rw (lecture/écriture). Si l'utilisateur ne figure pas dans la section, l'accès n'est pas autorisé.

Plus précisément, la valeur des noms de section est soit de la forme [nom-du-depot:chemin], soit de la forme [chemin]. Si vous utilisez la directive SVNParentPath, il est important de spécifier les noms des dépôts dans vos sections. Si vous les omettez, une section telle que [/un/repertoire] correspondra au chemin /un/repertoire de tous les dépôts. Cependant, si vous utilisez la directive SVNPath, ne définir que des chemins dans vos sections est acceptable — après tout, il n'y a qu'un seul dépôt.

[calc:/branches/calc/bogue-142]
harry = rw
sally = r

Dans ce premier exemple, l'utilisateur harry a les droits d'accès complets en lecture/écriture au répertoire /branches/calc/bogue-142 du dépôt calc, alors que l'utilisateur sally n'a que l'accès en lecture. Tous les autres utilisateurs sont bloqués et ne peuvent pas accéder à ce répertoire.

Bien évidemment, les droits d'accès sont hérités d'un répertoire parent à ses fils. Ce qui signifie que nous pouvons spécifier un sous-répertoire avec une politique d'accès différente pour Sally :

[calc:/branches/calc/bogue-142]
harry = rw
sally = r

# donne à sally les droits d'écriture sur le sous-répertoire "test"
[calc:/branches/calc/bogue-142/test]
sally = rw

Maintenant Sally peut écrire dans le sous-répertoire test de la branche, mais ne peut toujours que lire les autres parties. Harry, en attendant, continue à avoir les droits d'accès complets en lecture écriture sur toute la branche.

Il est aussi possible d'interdire explicitement l'accès à quelqu'un grâce aux règles d'héritage, en attribuant la valeur vide à un nom d'utilisateur :

[calc:/branches/calc/bogue-142]
harry = rw
sally = r

[calc:/branches/calc/bogue-142/secret]
harry =

Dans cet exemple, Harry a les droits de lecture/écriture sur l'arborescence bogue-142 toute entière, mais n'a absolument pas accès au répertoire secret contenu dans celle-ci.

[Astuce] Astuce

Ce qu'il faut retenir est que le chemin le plus spécifique est choisi en premier. Le serveur tente de trouver une correspondance avec le chemin lui-même, puis avec son chemin parent, puis avec le parent du parent, etc. Le résultat est que tout chemin spécifié dans le fichier des accès prendra le pas sur les droits hérités de ses répertoires parents.

Par défaut, personne n'a accès au dépôt. Cela signifie que si vous démarrez avec un fichier vide, vous voudrez probablement au moins donner les droits de lecture sur la racine du dépôt à tous les utilisateurs. Vous pouvez accomplir ceci en utilisant la variable astérisque (*), qui désigne « tous les utilisateurs » :

[/]
* = r

C'est une configuration très répandue ; notez qu'aucun nom de dépôt n'est mentionné dans le nom de la section. Ceci rend tous les dépôts accessibles en lecture à tous les utilisateurs. Une fois que tous les utilisateurs ont l'accès en lecture aux dépôts, vous pouvez accorder des droits d'écriture (rw) explicites à certains utilisateurs sur des sous-répertoires spécifiques à l'intérieur de dépôts spécifiques.

La variable astérisque (*) a aussi ceci de spécial qu'elle est le seul symbole qui puisse correspondre à un utilisateur anonyme. Si vous avez configuré votre serveur pour qu'il autorise un mélange d'accès anonymes et authentifiés, tous les utilisateurs peuvent commencer à y accéder anonymement. Le serveur cherche une valeur * définie pour le chemin d'accès demandé ; s'il n'en trouve pas, il demande au client de s'authentifier.

Le fichier des accès vous permet aussi de définir des groupes entiers d'utilisateurs, à la façon du fichier Unix /etc/group :

[groups]
developpeurs-calc = harry, sally, joe
developpeurs-paint = frank, sally, jane
tout-le-monde = harry, sally, joe, frank, sally, jane

Les droits d'accès peuvent être accordés aux groupes de la même façon qu'à de simples utilisateurs. Il faut juste les mettre en évidence par le préfixe « at » (@) :

[calc:/projets/calc]
@developpeurs-calc = rw

[paint:/projets/paint]
jane = r
@developpeurs-paint = rw

Un autre fait notable est que la première règle vérifiée est celle qui sera appliquée à l'utilisateur. Dans l'exemple précédent, même si jane est membre du groupe développeurs-paint (qui a les droits de lecture/écriture), la règle jane = r sera lue et vérifiée avant la règle du groupe, refusant ainsi à Jane l'accès en écriture.

Les groupes peuvent aussi contenir d'autres groupes :

[groups]
developpeurs-calc = harry, sally, joe
developpeurs-paint = frank, sally, jane
tout-le-monde = @developpeurs-calc, @developpeurs-paint

Subversion 1.5 introduit une autre fonctionnalité utile pour la syntaxe du fichier des accès : les alias. Certains systèmes d'authentification attendent et utilisent des noms d'utilisateurs relativement courts tels que ceux que nous avons décrits ici — harry, sally, joe, etc. Mais d'autres systèmes d'authentification, comme par exemple ceux qui utilisent des bases LDAP ou des certificats clients SSL, peuvent utiliser des noms d'utilisateurs beaucoup plus complexes. Par exemple, le nom d'utilisateur d'Harry dans un système protégé par LDAP pourrait très bien être : CN=Harold Hacker,OU=Engineers,DC=red-bean,DC=com. Avec des noms d'utilisateurs de ce type, le fichier des accès devient rapidement illisible, avec des noms d'utilisateurs longs ou obscurs qui peuvent facilement être mal orthographiés. Heureusement, les alias vous permettent de n'avoir à taper le nom d'utilisateur complexe entier qu'une seule fois, au sein d'un paragraphe qui lui attribue un alias bien plus digeste.

[aliases]
harry = CN=Harold Hacker,OU=Engineers,DC=red-bean,DC=com
sally = CN=Sally Swatterbug,OU=Engineers,DC=red-bean,DC=com
joe = CN=Gerald I. Joseph,OU=Engineers,DC=red-bean,DC=com
…

Une fois défini votre ensemble d'alias, vous pouvez faire référence à ces utilisateurs en d'autres endroits du fichier par leurs alias, partout là où vous auriez sinon entré leur véritables noms d'utilisateurs. Il faut juste ajouter une esperluette (&) juste avant l'alias pour le distinguer des noms d'utilisateurs classiques :

[groups]
developpeurs-calc = &harry, &sally, &joe
developpeurs-paint = &frank, &sally, &jane
tout-le-monde = @developpeurs-calc, @developpeurs-paint

Vous pouvez aussi choisir d'utiliser des alias si les noms de vos utilisateurs changent souvent. Ainsi vous n'aurez que la table des alias à mettre à jour quand des modifications de noms d'utilisateurs auront lieu, au lieu d'avoir à effectuer des opérations de recherches-et-remplacements-globaux sur la totalité du fichier.



[50] Un thème récurrent dans ce livre !