Les ACL

Les ACL (Access Control Lists = Listes de Contrôle d'Accès) permettent de gérer les permissions caractérisant les autorisations d'accès à un fichier de façon beaucoup plus fine qu'avec les mécanismes Unix traditionnels.

Le mécanisme traditionnel, permettant de déterminer si un utilisateur donné possède une autorisation de type donné sur un fichier ou un répertoire, est basé sur un schéma à trois niveaux d'accès distincts, avec trois classes d'utilisateurs également distinctes, soit un codage sur 9 bits, avec en plus 3 bits spéciaux (SetUserID, SetGroupID, StickyBit; respectivement).

Les trois niveaux de permission, Read, Write et eXecute, sont codés chacun sur un bit, sont manipulables avec la commande chmod, et sont appliqués sur les trois uniques classes d'utilisateurs : User, Group, et Other. Dans ce schéma, User représente le propriétaire du fichier, Group les utilisateurs du même groupe que User, c'est-à-dire partageant les mêmes GID (group id, défini dans /etc/group), et Other, tous les autres utilisateurs, c'est-à-dire appartenant à un groupe différent.

Le masque de bits contenant les protections données par défaut à un fichier (c'est-à-dire lors de sa création) est stocké dans le fichier inode, et ce masque est initialisé par défaut avec la valeur définie dans la variable d'environnement umask. Cette variable est définie au niveau système, existe pour tout utilisateur donné et peut lui être spécifique, même si la valeur 022 (octal) est la valeur canonique. Cette valeur correspond aux protections rw,r,r pour User, Group et Other, respectivement. Comment passe-t-on de cette valeur octale à ces protections ?

Le umask, comme son nom l'indique est un masque appliqué avec un OR (somme) sur l'ensemble des bits codant les protections possibles.

Remarquez que le premier digit, c'est-à-dire les trois premiers bits (SUID, SGID, sticky), n'est jamais manipulé, et que l'accès de type execute n'est pas pris en compte dans le masque, pour des raisons de sécurité.

Voici la table décrivant les bits codant la protection de tout fichier, et si vous y appliquez un masque, en tenant compte des deux règles de protection que nous venons de voir, vous obtiendrez alors le codage effectif.

		0400	(a=rwx,u-r)	Read by owner
		0200	(a=rwx,u-w)	Write by owner
		0100	(a=rwx,u-x)	Execute (search in directory) by owner
		0040	(a=rwx,g-r)	Read by group
		0020	(a=rwx,g-w)	Write by group
		0010	(a=rwx,g-x)	Execute/search by group
		0004	(a=rwx,o-r)	Read by others
		0002	(a=rwx,o-w)	Write by others
		0001	(a=rwx,o-x)	Execute/search by others

Il est néanmoins plus simple de manipuler les valeurs que l'on veut donner à umask de façon symbolique. Cette dernière méthode remplace désormais avantageusement la technique exposée précédemment, en voie d'obsolescence rapide mais toujours en service et permettant de jeter un oeil sur les bits du système.

[root@cotentin /root]# umask u=rwx,g=rx,o=
[root@cotentin /root]# umask
027

[root@cotentin /root]# touch toto
[root@cotentin /root]# ls -l toto
-rw-r-----	1 root	root		0 mar 24 05:38 toto

[root@cotentin /root]# umask o+x
[root@cotentin /root]# umask
026

[root@cotentin /root]# touch titi
[root@cotentin /root]# ls -l titi
-rw-r-----	1 root	root		0 mar 24 05:39 titi

Une fois les codes d'accès définis par ce masque lors de la création du fichier, il est possible de les modifier au traver de la commande chmod, avec un mode de spécification des valeurs relatif ou bien absolu, et avec des valeurs de type symbolique ou bien numérique, la valeur numérique étant toujours codée en octal (regroupement par 3 bits).

[root@cotentin /root]# ls -l
total 8
drwxr-xr-x	2 root	root	4096 mar 22 18:02 DIR1/
drwxr-xr-x	2 root	root	4096 mar 22 18:02 DIR2/
-rw-r--r--	1 root	root	0 mar 22 15:53 tata
-rw-r--r--	1 root	root	0 mar 22 15:53 titi
-rw-r--r--	1 root	root	0 mar 22 15:53 toto
-rw-r--r--	1 root	root	0 mar 22 15:53 tutu

[root@cotentin /root]# chmod 777 tata
[root@cotentin /root]# chmod +x titi

[root@cotentin /root]# ls -l
total 8
drwxr-xr-x	2 root	root	4096 mar 22 18:02 DIR1/
drwxr-xr-x	2 root	root	4096 mar 22 18:02 DIR2/
-rwxrwxrwx	1 root	root	0 mar 22 15:53 tata*
-rwxr-xr-x	1 root	root	0 mar 22 15:53 titi*
-rw-r--r--	1 root	root	0 mar 22 15:53 toto
-rw-r--r--	1 root	root	0 mar 22 15:53 tutu

Ce schéma, bien qu'efficace et pouvant répondre à nombre de situations, n'offre guère de souplesse, notamment en raison de son incapacité à offrir la possibilité de spécifier un ensemble de permissions spécifiques à un utilisateur donné ou à un groupe d'utilisateurs donné, en dehors de la notion de GID dans ce dernier cas.

Les ACL offrent la possibilité de définir des droits d'accès sur des fichiers ou des répertoires au sein d'un système de fichiers ext2fs, pour des ensembles d'utilisateurs, en s'affranchissant de la notion d'identification d'utilisateur (uid), ou de groupe (gid).

Les accès consentis par une liste de contrôle d'accès vont venir enrichir, et non remplacer, les protections offertes par le schéma classique. Les trois classes d'appartenance (User, Group, Other) vont pouvoir être vues comme trois entrées (de base) dans une liste de contrôle des droits d'accès, potentiellement plus riche de caractérisations spécifiques. Cette fonctionnalité est conforme au standard Posix 1003.1e version 17, lequel définit les relations entre ces deux mécanismes de protection.

Ainsi, en allant au-delà du cadre traditionnel User / Group / Other que nous connaissons tous depuis longtemps, nous allons pouvoir effectuer des opérations permettant de définir des schémas de protection jusqu'alors considérés comme impossibles à réaliser.

De plus, il est possible de définir un ensemble d'ACL par défaut sur un répertoire, ACL qui seront automatiquement associées à chaque fichier nouvellement créé dans ce même répertoire.

En revanche, l'implémentation sous Linux étant limitée au système de fichiers ext2, il n'y a aucun moyen de bénéfichier des ACL, avec par exemple ReiserFS ou NFS, et au sein de fichiers ext2, les ACL ne s'appliquent qu'aux répertoires, fichiers, liens et tubes. La structure d'une ACL est la suivante :

entrée:[uid/gid]:permissions

Le premier paramètre, entrée, définit l'ACL comme établie pour l'utilisateur, le groupe ou les autres, ou bien comme un masque d'ACL.

Le deuxième paramètre, uid/gid, est l'identification de l'utilisateur ou du groupe, soit en valeur numérique, soit en valeur symbolique, pour l'entrée qui se trouve ici définie. Pour les définitions de masques, et les propriétaires de type other, ce champ n'est pas utilisé et donc n'est pas requis.

Le troisième paramètre, permissions, définit quant à lui les permissions associées aux fichiers, et ces permissions sont décrites comme elles le seraient dans le schéma de protection Unix classique.

Lorsque sont omis les champs optionnels uid et gid, le schéma de protection traditionnel des systèmes Unix est alors employé.

Les ACL sont manipulées par l'utilisateur en création ou en modification avec la commande setfacl(1), et sont manipulées en visualisation avec la commande getfacl(1). Ces deux commandes sont ajoutées aux commandes existant par défaut sur une machine, lors de la mise en place de l'environnement ACL.

Mais pourquoi vouloir utiliser des ACL ?

Comme nous l'avons dit précédemment, les ACL permettent de mettre en place des stratégies de sécurité qui ne seraient pas réalisables avec les mécanismes standards. Mais plutôt que de nous lancer dans de fumeuses explications théoriques, nous allons imaginer un scénario nous permettant d'aborder par la pratique la mise en oeuvre des ACL.

Exemple

Considérons une société imaginaire, utilisant un serveur Linux, ce serveur étant géré par un administrateur que nous appellerons Lewis.

Une équipe est en train de travailler sur un projet nommé Wonderland et les membres de cette équipe stockent l'ensemble des données afférentes à ce projet dans un répertoire commun qu'ils partagent, /home/wonderland/shared.

Cette équipe est composée de Pierre, Paul et Jacques, et possède un administrateur que nous appellerons Alice.

Tous les membres de l'équipe Wonderland auront accès en lecture à l'ensemble des fichiers, dans les sous-répertoires du répertoire partagé, et leur administrateur, Alice, aura bien sûr un accès total à l'ensemble des fichiers répartis dans les sous-répertoires du répertoire partagé shared.

Tous les membres de l'équipe auront un accès sans restriction aucune au répertoire partagé /home/wonderland/shared.

Les deux éléments développés en ce moment sont aero et naval. Pierre travail sur aero, tandis que Paul travail sur naval. Jacques travaille sur les deux projets, c'est-à-dire tant sur aero que sur naval.

Compte	Groupes			Fonction
Alice	research,aero,naval	Encadrement groupe
Pierre	research,aero		Dédié projet aero
Paul	research,naval		Dédié projet naval
Jacques	research,aero,naval	Sur les deux projets

La structure des répertoires après création est la suivante :

[root@cotentin wonderland]# ls -R1
.:
total 20
drwxr-xr-x	2 Alice		research	4096 mar 24 08:48 Alice/
drwxr-xr-x	2 Jacques	research	4096 mar 24 08:48 Jacques/
drwxr-xr-x	2 Paul		research	4096 mar 24 08:48 Paul/
drwxr-xr-x	2 Pierre	research	4096 mar 24 08:48 Pierre/
drwxr-xr-x	2 Alice		research	4096 mar 24 09:06 shared/

./Alice:
total 0

./Jacques:
total 0

./Paul:
total 0

./Pierre:
total 0

./shared:
total 8
drwxr-xr-x	2 Alice	aero	4096 mar 24 08:46 aero/
drwxr-xr-x	2 Alice	naval	4096 mar 24 08:46 naval/

./shared/aero:
total 0

./shared/naval:
total 0

[root@cotentin wonderland]# chmod 700 Alice/ Jacques/ Paul/ Pierre/
[root@cotentin wonderland]# chmod 750 shared/
[root@cotentin wonderland]# chmod 770 shared/aero
[root@cotentin wonderland]# chmod 770 shared/naval

[root@cotentin wonderland]# ls -R1
.:
total 20
drwx------	2 Alice		research	4096 mar 24 08:48 Alice/
drwx------	2 Jacques	research	4096 mar 24 08:48 Jacques/
drwx------	2 Paul		research	4096 mar 24 08:48 Paul/
drwx------	2 Pierre	research	4096 mar 24 08:48 Pierre/
drwxr-x---	2 Alice		research	4096 mar 24 09:06 shared/

./Alice:
total 0

./Jacques:
total 0

./Paul:
total 0

./Pierre:
total 0

./shared:
total 8
drwxrwx---	2 Alice	aero	4096 mar 24 08:46 aero/
drwxrwx---	2 Alice	naval	4096 mar 24 08:46 naval/

./shared/aero:
total 0

./shared/naval:
total 0

research::506:Alice,Pierre,Paul,Jacques
aero::507:Alice,Pierre,Jacques
naval::508:Alice,Paul,Jacques

Alice:x:502:509::/home/wonderland/Alice:/bin/bash
Pierre:x:503:510::/home/wonderland/Pierre:/bin/bash
Paul:x:504:511::/home/wonderland/Paul:/bin/bash
Jacques:x:505:512::/home/wonderland/Jacques:/bin/bash

Les deux extraits des fichiers /etc/group et /etc/passwd, respectivement, ci-dessus, nous donnent une idée précise sur la déclaration des utilisateurs et des groupes, et de la répartition des utilisateurs dans ces groupes.

Fort bien, mais que manque-t-il ?

  • Pierre n'a pas d'accès en lecture sur /home/wonderland/shared/naval
  • Paul n'a pas d'accès en lecture sur /home/wonderland/shared/aero
  • Alice n'a pas d'accès en écriture aux fichiers qui pourraient être créés par d'autres personnes dans tout répertoire sous shared.

    Les deux premiers problèmes peuvent être solutionnés de façon classique en autorisant l'accès lecture pour tous sur /home/wonderland/shared, en définissant others:read, c'est-à-dire en déprotégeant ce répertoire vis-à-vis de tout le monde. Puisque personnne, à part les membres du groupe wonderland, n'a accès à /home/wonderland, cette solution ne soulève pas de problème de sécurité particulier. En revanche, il faut faire extrêmement attention aux permissions de type other sur /home/wonderland. En effet, tout ajout ultérieur dans ce répertoire ne pourra pas être rendu lisible de tous. Les ACL offrent une bien meilleure solution.

    Le dernier point que nous avons soulevé tout à l'heure ne trouve pas de solution en dehors des ACL.

    Les sous-répertoires sous /home/wonderland/shared peuvent être rendus accessibles en lecture à wonderland, et accessibles sans restriction pour leurs utilisateurs légitimes (les groupes de projets naval et aero) respectifs. Les droits d'administrateur du groupe wonderland pour Alice nécessiteront l'emploi d'une ACL séparée. La commande suivante donne l'accès en lecture à wonderland, en plus des permissions déjà existantes pour d'autres utilisateurs et/ou groupes d'utilisateurs.

    [root@cotentin shared]# ls -l
    total 8
    drwxrwx---	2 Alice	aero	4096 mar 30 13:17 aero/
    drwxrwx---	2 Alice	naval	4096 mar 30 13:17 naval/
    
    [root@cotentin shared]# getfacl *
    # file: aero
    # owner: Alice
    # group: aero
    user::rwx
    group::rwx
    other:---
    
    # file: naval
    # owner: Alice
    # group: naval
    user::rwx
    group::rwx
    other:---
    
    [root@cotentin shared]# setfacl -m g:research:rx *
    

    Les ACL existantes sur les deux sous-répertoires contiennent maintenant les définitions suivantes :

    [root@cotentin shared]# getfacl *
    # file: aero
    # owner: Alice
    # group: aero
    user::rwx
    group::rwx
    group:research:r-x
    mask:rwx
    other:---
    
    # file: naval
    # owner: Alice
    # group: naval
    user::rwx
    group::rwx
    group:research:r-x
    mask:rwx
    other:---
    

    Lorsque des fichiers sont créés dans un des sous-répertoires de /home/wonderland/shared, le propriétaire du fichier et son groupe sont définis respectivement suivant le propriétaire et son groupe actif courant, lequel peut être modifié en utilisant la commande sg. Alice crée un fichier dans /home/wonderland/shared/aero :

    [root@cotentin shared]# su - Alice
    [Alice@cotentin Alice]$ cd /home/wonderland/shared/aero/ 
    [Alice@cotentin aero]$ umask
    022
    
    [Alice@cotentin aero]$ touch filemadebyAlice
    [Alice@cotentin aero]$ ls -l
    total 0
    -rw-r--r--	1 Alice	509	0 mar 30 13:26 filemadebyAlice
    
    [Alice@cotentin aero]$ getfacl *
    # file: filemadebyAlice
    # owner: Alice
    # group: 509
    user::rw-
    group::r--
    other:r--
    

    Remarquez les protections r-- en raison de la valeur de umask. Les caractéristiques données par les ACL ne sont pas étendues aux nouveaux fichiers, et ni research ni Jacques ne bénéficient des autorisations qu'ils devraient avoir. Cela sera rétabli en mettant en place une ACL par défaut.

    [Alice@cotentin shared]$ ls
    aero/	naval/
    
    [Alice@cotentin shared]$ /usr/local/bin/setfacl -m d:u:Jacques:rwx,d:g:research:rx *
    

    Les ACL des deux sous-répertoires contiennent désormais les informations suivantes :

    [Alice@cotentin shared]$ /usr/local/bin/getfacl *
    # file: aero
    # owner: Alice
    # group: aero
    user::rwx
    group::rwx
    group:research:r-x
    mask:rwx
    other:---
    default:user:rwx
    default:user:Jacques:rwx
    default:group:rwx
    default:group:research:r-x
    default:mask:rwx
    default:other:---
    
    # file: naval
    # owner: Alice
    # group: naval
    user::rwx
    group::rwx
    group:research:r-x
    mask:rwx
    other:---
    default:user:rwx
    default:user:Jacques:rwx
    default:group:rwx
    default:group:research:r-x
    default:mask:rwx
    default:other:---
    

    Et voici désormais le résultat de la création par Alice d'un fichier dans /home/wonderland/shared/naval. Vous remarquerez que la valeur du umask n'a plus aucune influence sur les caractéristiques du fichier.

    [Alice@cotentin shared]$ cd naval
    [Alice@cotentin naval]$ umask
    022
    
    [Alice@cotentin naval]$ touch filemadebyAlice
    [Alice@cotentin naval]$ ls -l
    total 4
    -rw-rw----	1 Alice	509	0 mar 30 13:34 filemadebyAlice
    
    [Alice@cotentin naval]$ getfacl *
    # file: filemadebyAlice
    # owner: Alice
    # group: 509
    user::rw-
    user:Jacques:rwx	# effective:rw-
    group::rwx		# effective:rw-
    group:research:r-x	# effective:r--
    mask:rw-
    other:---
    

    Structure d'une Access Control List

    Une ACL est une structure composée des données suivantes :

    
    ACL_USR_OBJ		propriétaire
    ACL_USR			utilisateur identifié
    ACL_GROUP_OBJ		groupe d'appartenance
    ACL_GROUP		groupe nommé
    ACL_MASK		droits effectifs
    ACL_OTHER		autres utilisateurs
    

    Les champs ACL_USR_OBJ, ACL_GROUP_OBJ et ACL_OTHER correspondent exactement aux structures de protection conventionnelles sur les fichiers Unix. Il y a une et une seule de chacune de ces trois structures dans une ACL.

    ACL_USER et ACL_GROUP définissent les appartenances et les droits pour les utilisateurs et les groupes et impliquent une définition dans ACL_MASK. Cette définition limite les droits portés par les deux structures précédentes, en réalisant un droit effectif, qui est la somme des droits portés par les champs USER et/ou GROUP et le masque.

    Dans le cas où la valeur définie dans le masque vient réduire l'étendue des droits définis dans les champs USER et GROUP, la valeur affichée par la commande getfacl sera suivie du champ effective, indiquant les droits réellement mis en oeuvre.

    Le caractère + peut être affiché à la suite des attributs d'un fichier suite à un ls -l si les attributs qui sont alors affichés ne décrivent pas complètement les protections associées au fichier.

    Manipulation d'une Access Control List

    Les permissions de manipulation des ACL sur un inode sont celles qui régissent les autres permissions relatives à la modification des modes d'accès. Les processes avec une autorisation search/execute peuvent lire les ACL existantes, et seul le propriétaire d'un fichier, ainsi que root (sous Linux, seul nanti du CAP_FOWNER), peuvent créer et modifier des ACL.

    Comment installer les ACL sous Linux

    Désormais convaincus de la pertinence et de l'intérêt des ACL, nous allons voir comment installer les ACL sur notre machine Linux.

    Récupération des composants

    La version courante du produit (au jour de la rédaction de cet article) est la 0.7.8, datant du 4 mars 2001, et supportant les kernels 2.2.18 et 2.4.2. A la lecture de ces lignes, vous aurez bien sûr intérêt à aller charger la version la plus récente, si une nouvelle était rendue disponible dans l'intervalle.

    Il vous faudra donc aller sur le site de Bestbits, indiqué dans les bookmars à la fin de cet article, et télécharger l'ensemble des composants. Lors du téléchargement, il vous faudra choisir la version de patchs correspondant à la version du noyau que vous désirez utiliser.

    Application des patchs et recompilation du noyau

    Munis des sources du noyau désiré, préalablement décompressées à partir d'un quelconque répertoire dans le répertoire linux, il vous faut maintenant appliquer les patchs, en commençant par le patch Extended Attributes, puis le patch ACL kernel.

    # tar xzf linux-2.2.18.tar.gz
    # cd linux
    

    Le passage des patchs se fera de la façon suivante, à la spécification des chemins d'accès près (ici, les patchs sont dans le répertoire contenant le répertoire linux).

    # gzip -cd < ../linux-9.9.9-ea-0.0.0.patch.gz | patch -p1
    # gzip -cd < ../linux-9.9.9-acl-0.0.0.patch.gz | patch -p1
    

    Les messages `patching files' doivent alors s'afficher. Un message d'erreur indiquera que vous aurez probablement tenté d'appliquer les patchs dans le désordre, ou que vous n'avez pas utilisé la bonne révision du kernel.

    Il vous faudra ensuite reconfigurer le kernel, en demandant l'invite pour les composants en développement à partir des options de maturité du code, que l'on sélectionne depuis le menu principal.

    Puis, à partir du menu filesystems, sélectionnez les options Extended Filesystem, Extended User Attributes, Posix ACLs et Extended ext2 attributes. Retournez ensuite au menu principal, et sauvegardez la configuration. Il ne vous reste plus qu'à recompiler le kernel et l'ensemble de ses modules.

    Attention, la description de cette manipulation concerne bien sûr uniquement l'adjonction au noyau des fonctionnalités ACL. Afin de retrouver un noyau comme celui que vous avez peut-être par défaut, d'autres options peuvent être à sélectionner (comme le support d'une carte SCI, ou de l'USB par exemple).

    # make menuconfig
    	... sélection des options dans les différents menus ...
    # make dep clean bzImage modules install
    

    Une fois le noyau compilé et installé dans le répertoire de boot (/boot), il ne vous reste plus qu'à aller dans ce dernier et de faire les modifications appropriées afin de créer une nouvelle entrée dans les choix de boot proposés par lilo ou par grub.

    Ce qui nous donne soit :

    # cd /boot/grub
    # vi menu.lst
    	... duplication d'une entrée
    	... modification du noyau, et optionellement de l'entrée par défaut ...
    # ./install.sh
    

    Ou soit :

    # cd /etc
    # vi lilo.conf
    	... duplication d'une entrée
    	... modification du noyau, et optionellement de l'entrée par défaut ...
    # /sbin/lilo
    

    Pour les personnes n'ayant jamais construit de noyau, la procédure est très simple, et bien que cela puisse paraître une opération insurmontable à celui qui ne s'y est jamais risqué, les difficultés sont minimes : l'obstacle est plus psychologique ou "de principe" que réel ... La preuve ? Même l'auteur y est arrivé - tout seul - ! Vous pouvez donc vous lancer sans risque, si vous faites attention au point suivant :

    L'install effectuée par le make copie le nouveau kernel dans le répertoire /boot, et redéfinit le lien symbolique vmlinuz vers ce nouveau noyau. Comme toutes les entrées identifiées par défaut par le boot manager (lilo ou grub) sont référencées à partir de vmlinuz, vous n'aurez plus accès à votre ancien noyau à partir du menu de démarrage du bootloader. Si votre noyau nouvellement compilé a un problème, les difficultés vont commencer pour vous. Aussi, prenez soin de créer manuellement une nouvelle entrée, qui pointera sur le noyau sur lequel votre machine démarrait avant votre compilation.

    Cette dernière précaution prise, il ne vous reste plus qu'à redémarrer afin de pouvoir prendre en compte ce nouveau noyau, et continuer avec la mise en oeuvre des autres composants.

    Construction des utilitaires

    Maintenant, nous allons avoir à compiler les utilitaires, en commençant tout d'abord avec le package e2fsprogs et ses patchs, qu'il faudra télécharger, décompacter, et appliquer, puis ensuite reconstruire et enfin remplacer, non sans une sauvegarde préalable, les précédents e2fsck et fsck.ext2 avec les images nouvellement générées.

    Cependant, les utilisateurs de Red Hat et Mandrake auront le plaisir de trouver sur ce site des RPM binaires directement installables sur leur machine, mais après une recompilation du noyau, une recompilation de cet environnement est une simple formalité que nous n'hésiterons pas à effectuer.

    [root@cotentin build-ACL]# ls
    acl-0.7.8.tar.gz			fileutils-4.0.41acl-0.7.8.patch.gz
    e2fsprogs-1.19/				linux/
    e2fsprogs-1.19.tar.gz			linux-2.2.18.tar.gz
    e2fsprogs-1.19ea-0.7.8.patch.gz		linux-2.2.18acl-0.7.8.patch.gz
    ea-0.7.8.tar.gz				linux-2.2.18ea-0.7.8.patch.gz
    
    [root@cotentin build-ACL]# cd e2fsprogs-1.19/
    
    [root@cotentin e2fsprogs-1.19]# gzip -cd < ../e2fsprogs-1.19ea-0.7.8.patch.gz | patch -p1
    patching file ChangeLog
    ...
    patching file version.h
    
    [root@cotentin /root]# e2fsck
    Usage: e2fsck [-panyrcdfvstFSV] [-b superblock] [-B blocksize]
    		[-I inode_buffer_blocks] [-P process_inode_size]
    		[-l|-L bad_blocks_file] [-C fd] device
    
    Emergency help:
     -p                   Automatic repair (no questions)
     -n                   Make no changes to the filesystem
     -y                   Assume "yes" to all questions
     -c                   Check for bad blocks
     -f                   Force checking even if filesystem is marked clean
     -v                   Be verbose
     -b superblock        Use alternative superblock
     -B blocksize         Force blocksize when looking for superblock
     -l bad_blocks_file   Add to badblocks list
     -L bad_blocks_file   Set badblocks list
    
    [root@cotentin e2fsprogs-1.19]# make
    ...
    
    [root@cotentin e2fsprogs-1.19]# ls /sbin/e2fsck
    /sbin/e2fsck*
    
    [root@cotentin e2fsprogs-1.19]# ls /sbin/fsck.ext2
    /sbin/fsck.ext2*
    
    [root@cotentin e2fsprogs-1.19]# file /sbin/e2fsck /sbin/fsck.ext2
    /sbin/e2fsck:    ELF 32-bit LSB executable, Intel 80386, version 1, statically linked, stripped
    /sbin/fsck.ext2: ELF 32-bit LSB executable, Intel 80386, version 1, statically linked, stripped
    
    [root@cotentin e2fsprogs-1.19]# mv /sbin/e2fsck /sbin/e2fsck.BCK
    [root@cotentin e2fsprogs-1.19]# mv /sbin/fsck.ext2 /sbin/fsck.ext2.BCK
    
    [root@cotentin e2fsprogs-1.19]# cp e2fsck/e2fsck /sbin/e2fsck
    [root@cotentin e2fsprogs-1.19]# ln /sbin/e2fsck /sbin/fsck.ext2
    
    [root@cotentin /root]# e2fsck
    Usage: e2fsck [-panyrcdfvstFSV] [-b superblock] [-B blocksize]
    		[-I inode_buffer_blocks] [-P process_inode_size]
    		[-l|-L bad_blocks_file] [-C fd] device
    
    Emergency help:
     -p                   Automatic repair (no questions)
     -n                   Make no changes to the filesystem
     -y                   Assume "yes" to all questions
     -c                   Check for bad blocks
     -f                   Force checking even if filesystem is marked clean
     -v                   Be verbose
     -b superblock        Use alternative superblock
     -B blocksize         Force blocksize when looking for superblock
     -l bad_blocks_file   Add to badblocks list
     -L bad_blocks_file   Set badblocks list
     -X                   Purge extended attribute blocks
    

    Regardez la dernière ligne (surlignée en rouge) ...

    Ensuite, le package Extended Attributes Utilities (à ne pas confondre avec le patch kernel Extended Attributes) nous permettra d'obtenir les composants aget et aset. Ces composants sont des composants expérimentaux qui ne sont pas indispensables à la manipulation des ACL et ne répondent à aucun standard.

    Les utilitaires ACL quant à eux font directement appel aux primitives système (system calls). Toutefois, ces utilitaires peuvent être très utiles en particulier pour nous aider à résoudre le problème des sauvegardes que nous aborderons plus loin.

    Les Extended Attributes sont des couples de valeurs arbitraires de la forme nom/valeur associés aux inodes des objets ciblés. Ces couples de valeurs contiennent des objets système comme les listes de contrôle d'accès elles-mêmes ou caractéristiques du système de fichiers, mais aussi des objets utilisateurs comme les types mime ou les jeux de caractères à employer.

    [root@cotentin build-ACL]# ls
    acl-0.7.8.tar.gz			fileutils-4.0.41acl-0.7.8.patch.gz
    e2fsprogs-1.19/				linux/
    e2fsprogs-1.19.tar.gz			linux-2.2.18.tar.gz
    e2fsprogs-1.19ea-0.7.8.patch.gz		linux-2.2.18acl-0.7.8.patch.gz
    ea-0.7.8.tar.gz				linux-2.2.18ea-0.7.8.patch.gz
    
    [root@cotentin build-ACL]# tar xzf ea-0.7.8.tar.gz
    [root@cotentin build-ACL]# cd ea-0.7.8
    
    [root@cotentin ea-0.7.8]# ls
    CHANGES  Makefile  TODO  src/  test/
    
    [root@cotentin ea-0.7.8]# make KERNEL_SOURCE=/home/clc/build-ACL/linux
    ...
    
    [root@cotentin ea-0.7.8]# make install
    install --strip src/aget src/aset /usr/local/bin
    
    [root@cotentin ea-0.7.8]# aset
    bash: aset: command not found
    
    [root@cotentin ea-0.7.8]# export PATH=$PATH:/usr/local/bin
    
    [root@cotentin ea-0.7.8]# aget
    Usage: aget [-n name|-d] [-sR5LPVh] [-e en] file ...
    Try `aget -h' for more information.
    
    [root@cotentin ea-0.7.8]# aget -h
    aget 0.7.8 -- get extended attributes
    Usage: aget [-n name|-d] [-sR5LPVh] [-e en] file ...
    	-n name   dump value of extended attribute `name'
    	-d        dump all extended attribute values
    	-s        include extended system attributes
    	-e en     encode values (en = text | hex | bash64)
    	-R        recurse into subdirectories (-5 = post-order)
    	-L        logical walk, follow symbolic links
    	-P        physical walk, do not follow symbolic links
    	-V        print version and exit
    	-h        this help text
    
    [root@cotentin ea-0.7.8]# aset -h
    aset 0.7.8 -- set extended attributes
    Usage: aset {-n name|-x name} [-v value] [-Vh] file ...
    	-n name    set value of extended attribute `name'
    	-x name    remove extended attribute `name'
    	-v value   value for extended attribute `name'
    	-B         restore extended attributes (inverse of `aget -sdR')
    	-V         print version and exit
    	-h         this help text
    

    Viennent ensuite les utilitaires ACL et les bibliothèques POSIX, nécessaires à la construction du package fileutils.

    [root@cotentin build-ACL]# tar xzf acl-0.7.8.tar.gz
    
    [root@cotentin build-ACL]# cd acl-0.7.8/
    
    [root@cotentin acl-0.7.8]# ls
    CHANGES  LICENSE      README  config.h.in  configure.in  doc/
    install-sh*  libcap/  src/
    CREDITS  Makefile.in  TODO    configure*   depend*       include/
    libacl/      po/      test/
    
    [root@cotentin acl-0.7.8]# ./configure
    KERNEL_SOURCE=/home/clc/build-ACL/linux
    ...
    
    [root@cotentin acl-0.7.8]# make
    ...
    
    [root@cotentin acl-0.7.8]# make install
    ...
    
    [root@cotentin acl-0.7.8]# getfacl -h
    getfacl 0.7.8 -- get file access control lists
    Usage: getfacl [-adRLPvh] file ...
    	-a, --access		display the file access control list only
    	-d, --default		display the default access control list only
    	    --omit-header	do not display the comment header
    	    --all-effective	print all effective rights
    	    --no-effective	print no effective rights
    	    --skip-base		skip files that only have the base entries
    	-R, --recursive		recurse into subdirectories
    	    --post-oder		visit subdirectories first
    	-L, --logical		logical walk, follow symbolic links
    	-P, --physical		physical walk, do not follow symbolic links
    	    --tabular		use tabular output format
    	    --absolute-names	don't strip lending '/' in pathnames
    	-v, --version		print version and exit
    	-h, --help		this help text
    
    [root@cotentin acl-0.7.8]# setfacl -h
    setfacl 0.7.8 -- set file access control lists
    Usage: setfacl [-bkndRLPvh] { -s|-S|-m|-M|-x|-X ... } ... file ...
    	-s, --set=acl		set the ACL of file(s), replacing the current ACL
    	-S, --set-file=file	read ACL entries to set from file
    	-m, --modify=acl	modify the current ACL(s) of file(s)
    	-M, --modify-file=file	read ACL entries to modify from file
    	-x, --remove=acl	remove entries from the ACL(s) of file(s)
    	-X, --remove-file=file	read ACL entries to remove from file
    	-b, --remove-all	remove all extended ACL entries
    	-k, --remove-default	remove the default ACL
    	    --mask		do recalculate the effective rights mask
    	-n, --no-mask		don't recalculate the effective rights mask
    	-d, --default		operations apply to the default ACL
    	-R, --recursive		recurse into subdirectories
    	    --post-order	visit subdirectories first
    	-L, --logical		logical walk, follow symbolic links
    	-P, --physical		physical walk, do not follow symbolic links
    	    --restore=file	restore ACLs (inverse of `getfacl -R')
    	    --test		test mode (ACLs are not modified)
    	-v, --version		print version and exit
    	-h, --help		this help text
    

    Récupérer donc le package fileutils sur ftp://alpha.gnu.org, et appliquez, une fois décompressé, le patch binaire avec xdelta. Construisez alors les nouveaux utilitaires.

    [root@cotentin build-ACL]# ls
    acl-0.7.8/                       ea-0.7.8/                             linux/
    acl-0.7.8.tar.gz                 ea-0.7.8.tar.gz                       linux-2.2.18.tar.gz
    e2fsprogs-1.19/                  fileutils-4.0.41.tar.gz               linux-2.2.18acl-0.7.8.patch.gz
    e2fsprogs-1.19.tar.gz            fileutils-4.0.41acl-0.7.8.patch.gz    linux-2.2.18ea-0.7.8.patch.gz
    e2fsprogs-1.19ea-0.7.8.patch.gz  fileutils-4.0.41acl-0.7.8.xdelta
    
    [root@cotentin build-ACL]# xdelta patch fileutils-4.0.41acl-0.7.8.xdelta fileutils-4.0.41.tar.gz fileutils-4.0.41acl-0.7.8.patch.gz
    
    [root@cotentin build-ACL]# tar xzf fileutils-4.0.41acl-0.7.8.tar.gz
    [root@cotentin build-ACL]# cd fileutils-4.0.41acl
    
    [root@cotentin build-ACL]# ./configure
    [root@cotentin build-ACL]# make
    [root@cotentin build-ACL]# make install
    

    C'est fini !!!

    Les systèmes de fichiers seront désormais montés avec le support des ACL par défaut. Vous avez toutefois la possibilité de spécifier le non support des ACL avec l'option de mount attr=noacl, ou de choisir de lancer un boot sur un kernel sans support des ACL. Les paramètres relatifs aux ACL ne sont alors pas pris en compte, et toutes les opérations relatives à la modification des paramètres de sécurité des fichiers ne seront pas répercutées sur les structures ACL, existantes mais non vues.

    Afin de vérifier tout de suite si ce que nous avons fait marche bien, nous allons taper la commande suivante, et regarder le résultat :

    [root@cotentin /root]# mkdir test
    [root@cotentin /root]# cd test
    [root@cotentin /root]# touch toto
    [root@cotentin /root]# getfacl *
    
    # file: toto
    # owner: root
    # group: root
    user::rw-
    group::r--
    other::r--
    

    Et ça marche !!!

    Utiliser les ACL

    La mise en oeuvre des ACL au quotidien, une fois toutes les étapes d'installation accomplies, c'est-à-dire de patch et de recompilation, s'avère assez simple. Les commandes utilisateur sont peu nombreuses, et les options ainsi que leurs attributs de commande sont très réduites.

    Le principe même des ACL est très facile à appréhender, et tout système Linux destiné à être partagé entre plusieurs utilisateurs dans un cadre professionnel devrait en être pourvu. Prenez bien le temps de faire le plan de l'utilisation prévue des ressources de la machine, et tout se passera sans douleur.

    Les commandes setfacl(1) et getfacl(1) vont vous permettre de définir des ACL, et de voir le contenu des ACL que vous venez de définir, respectivement.

    Tout n'étant pas encore parfait dans ce monde, les utilitaires de sauvegarde n'ont pas encore connaissance des ACL, ou même des attributs étendus. Cependant, une nouvelle spécification de format d'archive, appelé pax, est en train de voir le jour, et il y a fort à parier pour que cet environnement soit quant à lui à même de prendre en compte ces caractéristiques.

    Jusqu'à ce jour, le problème de la sauvegarde des ACL sous Linux restera, et seules des stratégies de contournement nous permettront de nous tirer d'affaire. Voici un petit exemple de ce qui peut être fait, afin de nous tirer d'affaire :

    # getfacl -sR . > acl.bck
    

    L'option s permet de ne sélectionner que les fichiers possédant des attributs étendus; quant au R, il demande une très classique opération de balayage récursif des répertoires. La restauration des ACL ainsi sauvegardées s'effectue alors comme suit :

    # setfacl - restore=./acl.bck
    

    Les attributs étendus se sauvegardent de la même façon, avec les programmes aget et aset.

    # aget -sdR -e base64 . > ea.bck
    

    L'option e spécifie la valeur d'encodage, ici en base64, mais les options text et hex sont également disponibles. Le choix de l'encodage effectué n'est réellement important qu'en fonction des utilitaires qui pourraient ensuite lire le fichier ainsi généré.

    # asset -B ea.bck
    

    Conclusion

    Si toutes les distributions des différents Unix propriétaires, ainsi que d'autres systèmes également (l'auteur a rencontré les ACL pour la première fois sur VAX/VMS en 84/85), possèdent depuis longtemps leur propre implémentation des ACL, la disponibilité de cette fonctionnalité haut de gamme n'est disponible que depuis fort récemment sous notre OS favori. Il reste encore de nombreux développements à envisager afin de parfaire et d'étendre ce qui existe déjà, mais ce qui a été réalisé mérite d'ores et déjà d'être salué et, pourquoi pas, testé en conditions réelles, afin peut-être de combler un manque déjà perçu par certains utilisateurs en environnement de production.

    Il ne reste qu'à espérer que cet environnement sera accessible dans un proche avenir sur les distributions majeures, sans obliger les personnes ayant besoin de ces fonctions à se livrer à des manipulations complexes, rébarbatives et consommatrices de temps, car si certains font de l'informatique, d'autres, beaucoup d'autres, veulent se contenter de l'utiliser dans le cadre de leurs activités. D'ailleurs, le succès de Linux dépend très largement de l'intégration la plus conviviale possible du plus grand nombre de fonctionnalités possibles, et les éditeurs de distributions Linux qui ont oeuvré dans ce sens ont vu la reconnaissance du marché se manifester au travers de la croissance de leurs parts de marché.

    Cet article ayant été réalisé à partir de divers articles existant sur le Web, les internautes ayant déjà exploré cette voie peu ou prou ne seront pas surpris de retrouver des exemples, entre autres, similaires à ceux qu'ils auraient déjà pu voir en parcourant certains articles, en particulier ceux que l'on pourra trouver à partir des liens suivants.

    Liens

    * http://acl.bestbits.at
    * http://acl.bestbits.at/download.html
    * http://e2fsprogs.sourceforge.net
    * ftp://ftp.kernel.org
    * ftp://alpha.gnu.org/gnu/fetish/

    Christophe Le Cannellier (Saint Paul Research Labs)
    Linux Magazine France n°28 - Mai 2001