This text is a work in progress—highly subject to change—and may not accurately describe any released version of the Apache™ Subversion® software. Bookmarking or otherwise referring others to this page is probably not such a smart idea. Please visit http://www.svnbook.com/ for stable versions of this book.
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. Il est même possible de restreindre l'accès fichier par fichier.
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 cette section, nous allons expliquer ce format de fichier et comment configurer le serveur Subversion afin qu'il l'utilise pour gérer un contrôle d'accès basé sur les chemins.
Subversion permet le contrôle d'accès basé sur les chemins
avec Apache via son module
mod_authz_svn, qui doit être chargé en
utilisant la directive LoadModule
dans
httpd.conf
de la même manière que pour le
chargement du module mod_dav_svn. Pour
activer l'utilisation du module pour vos dépôts, vous devez
ajouter les directives AuthzSVNAccessFile
ou
AuthzSVNReposRelativeAccessFile
(toujours dans le fichier httpd.conf
) en les
faisant pointer vers votre propre fichier contenant les règles
de contrôle d'accès (pour une explication détaillée, consultez
la section intitulée « Contrôle d'accès par répertoire »).
Pour configurer le contrôle d'accès basé sur les chemins
avec svnserve,faites simplement pointer la
variable de configuration authz-db
(qui se trouve dans le fichier
svnserve.conf
) vers votre fichier contenant
les règles de contrôle d'accès.
Une fois que votre serveur sait où chercher les règles de contrôle d'accès, 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. En d'autres termes, sauf pour quelques
sections particulières, les noms de sections se présentent sous
deux formes : soit nom-depot:chemin
,
soit [chemin]
quand
AuthzSVNAccessFile
est utilisé. Si vous avez
configuré un contrôle d'accès aux fichiers du dépôt
via la directive
AuthzSVNReposRelativeAccessFile
, vous devriez
toujours utiliser seulement la forme [path]
.
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 cet 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é.
Note | |
---|---|
Les chemins utilisés dans les sections du fichier de
contrôle d'accès doivent être spécifiés en utilisant le
« style interne » de Subversion, ce qui veut
simplement dire qu'ils doivent être encodés en UTF-8 et
utiliser comme séparateur de répertoires la barre oblique
( |
Voici un exemple simple pour montrer à quoi ressemble
un fichier de configuration du contrôle d'accès où Sally possède
des droits en lecture seule et Harry des droits en
lecture/écriture pour le chemin
/branches/calc/bug-142
(et tous ses
enfants) dans le dépôt calc
:
[calc:/branches/calc/bug-142] harry = rw sally = r
Avertissement | |
---|---|
Avant la version 1.7, Subversion ne distinguait pas la casse des caractères pour les noms de dépôts et de chemins dans le cadre du contrôle d'accès, il convertissait le tout en minuscules avant d'effectuer la confrontation avec le contenu du fichier de contrôle d'accès. Dorénavant, il est sensible à la casse. Si vous mettez à jour un serveur vers la version 1.7 à partir d'une version antérieure, passez en revue votre fichier de contrôle d'accès pour vérifier que la casse est correcte. |
Le nom du dépôt tel qu'il est évalué par le sous-système de
contrôle d'accès dérive directement du chemin du dépôt. La
manière exacte dont se déroule cette évaluation diffère en
fonction de la valeur de deux options.
mod_dav_svn utilise seulement le nom du
dépôt figurant dans l'URL de la racine du
dépôt[71],
alors que svnserve utilise l'ensemble du
chemin relatif à partir de la racine du serveur (indiquée dans
l'option --root
(-r
) de la
ligne de commande) vers le dépôt.
Avertissement | |
---|---|
mod_dav_svn et
svnserve évaluant le nom de dépôt de deux
manières différentes, cela peut conduire à des problèmes
lorsque les deux serveurs fonctionnent simultanément sur la
machine. Naturellement, un administrateur préférerait faire
pointer les deux configurations des serveurs sur le même
fichier de contrôle d'accès. Cependant, afin que cela
fonctionne, vous devez vous assurer que la partie du nom de
dépôt qui figure dans le nom de section est compatible avec
l'idée que se fait le serveur du nom de dépôt. Par exemple,
en configurant la racine de svnserve pour
qu'elle soit la même que la valeur de la directive
|
Si vous utilisez la directive
SVNParentPath
, il est important de spécifier
les noms de dépôts dans vos sections. Si vous l'oubliez, à une
section comme [/un/repertoire]
correspondra
le chemin /un/repertoire
dans
chaque dépôt. Cependant, si vous utilisez
la directive SVNPath
, il suffit d'indiquer
les chemins dans vos sections (après tout, il n'y a qu'un seul
dépôt).
Les droits sont hérités d'un répertoire parent dans le système de fichiers. Cela veut dire que vous pouvez spécifier un sous-répertoire avec des droits différents pour Sally. Si nous continuons avec l'exemple précédent, nous pouvons autoriser Sally à écrire vers un répertoire fils de la branche où elle ne possède que des droits de lecture :
[calc:/branches/calc/bug-142] harry = rw sally = r # Sally peut écrire seulement dans 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 | |
---|---|
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. De la même manière, les sections qui spécifient un nom de
dépôt sont prioritaires sur celles qui n'en spécifient
pas : si |
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.
Notez que, bien que tous les exemples supra font référence à des répertoires, c'est simplement parce qu'il est plus commun de définir des droits d'accès sur des répertoires. Mais vous pouvez également restreindre les accès sur des fichiers.
[agenda:/projets/agenda/chef.ics] harry = rw sally = r
Le fichier des accès vous permet aussi de définir des
groupes entiers d'utilisateurs, à la façon du fichier Unix
/etc/group
. Créez donc une section
groups
dans votre fichiers d'accès et
décrivez vos groupes dans cette section : chaque nom de
variable définit le nom d'un groupe et la valeur est une liste
d'identifiants, séparés par des virgules, qui constituent les
membres de ce groupe.
[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 les droits définis pour les
groupes ne sont pas écrasés par les droits individuels. En fait,
c'est la combinaison de tous les droits qui
s'applique. Dans l'exemple précédent, Jane est membre du groupe
développeurs-paint
, qui a les droits de
lecture/écriture. Combiné avec la règle
jane = r
, cela donne toujours les droits de
lecture/écriture à Jane. Les droits pour les membres d'un groupe
ne peuvent être que étendus au delà des droits du groupe.
Restreindre les droits d'utilisateurs qui font partie d'un groupe
n'est pas possible.
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
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 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, Subversion 1.5 a introduit les alias dans la syntaxe du fichier de contrôle d'accès. Vous n'avez ainsi à taper le nom d'utilisateur complexe entier qu'une seule fois, au sein d'un paragraphe qui lui attribue un alias bien plus digeste.
Les alias sont définis dans la section
aliases
du fichier de contrôle d'accès.
Chaque nom de variable déclarée dans cette section définit un
alias et la valeur de cette variable est l'identifiant réel
Subversion qui est derrière l'alias.
[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.
À partir de Subversion 1.5, le fichier de contrôle d'accès
reconnait aussi des mots-clés « magiques » afin de
vous aider à créer des règles basées sur le statut
d'authentification de l'utilisateurs. Ainsi le mot-clé
$authenticated
est utilisé pour désigner un
utilisateur (quel qu'il soit) authentifié. Vous pouvez utiliser
ce mot-clé à la place d'un identifiant, d'un alias ou d'un nom
de groupe dans vos règles de contrôle d'accès. De la même
manière, le mot-clé $anonymous
désigne
n'importe qui qui n'est pas
authentifié.
[agenda:/projets/agenda] $anonymous = r $authenticated = rw
Un autre élément magique de la syntaxe des fichiers de
contrôle d'accès est le caractère tilde (~
)
qui est un marqueur d'exclusion. Dans vos règles de contrôle
d'accès, si vous préfixez un identifiant, un alias, un groupe
ou un mot-clé d'authentification avec le caractère tilde,
Subversion applique la règle aux utilisateurs qui
ne vérifient pas la règle. Bien que
inutilement complexe, le bloc suivant est équivalent à celui
du précédent exemple :
[agenda:/projets/agenda] ~$authenticated = r ~$anonymous = rw
Un exemple moins simpliste pourrait ressembler à :
[groups] developpeurs-calc = &harry, &sally, &joe proprios-calc = &hewlett, &packard calc = @developpeurs-calc, @proprios-calc # tous les participants à calc ont les droits de lecture/écriture ... [calc:/projets/calc] @calc = rw # ...mais seuls les propriétaires peuvent faire et modifier des étiquettes. [calc:/projets/calc/tags] ~@proprios-calc = r
Si vous utilisez Apache en tant que serveur Subversion et que vous avez rendu certains sous-répertoires de votre dépôt inaccessibles en lecture à certains utilisateurs, vous devez être au courant d'un comportement potentiellement non-optimal de la commande svn checkout.
En fonction de la bibliothèque de communication HTTP que le client Subversion utilise, il envoie potentiellement une requête au serveur pour recevoir tout le contenu de l'extraction ou de la mise à jour dans une réponse unique (dont la taille peut être assez importante). Quand le serveur reçoit la requête, c'est la seule opportunité dont dispose Apache pour demander à l'utilisateur de s'authentifier. Ceci a des effets secondaires assez étonnants. Par exemple, si un certain sous-répertoire du dépôt n'est accessible en lecture qu'à l'utilisateur Sally et que l'utilisateur Harry extrait un répertoire parent, le client répondra à la demande d'authentification initiale en tant que Harry. Au fur et à mesure que le serveur génère la réponse, il n'a aucun moyen de renvoyer un défi d'authentification quand il atteint le sous-répertoire spécial ; ainsi le sous-répertoire tout entier est omis, plutôt que de demander à l'utilisateur de se ré-authentifier en tant que Sally le moment venu.
De même, si la racine du dépôt est accessible en lecture anonymement, l'extraction se fera entièrement sans authentification, omettant, encore une fois, le répertoire non-lisible, plutôt que d'envoyer une demande d'authentification au cours de l'opération[72].
[70] Un thème récurrent dans ce livre !
[71] N'importe quel nom de dépôt,
lisible par un humain et configuré par la directive
SVNReposName
de
httpd.conf
est ignoré par le sous-système
de contrôle d'accès. Vos sections du fichier de contrôle d'accès
doivent faire référence aux dépôts par le chemin interne au
serveur comme cela a été décrit précédemment.
[72] Pour plus d'informations sur ce comportement, lisez l'article de blog Authz and Anon Authn Agony sur https://subversion.apache.org/blog/2007-03-27-authz-and-anon-authn-agony.html (article en anglais).