Les lists de contrôle d'access peuvent-elles replace les permissions sur Linux?

J'ai lutté avec ce problème sur FreeBSD récemment, mais Dieu merci pour ZFS qui l'a résolu pour moi là-bas. Cependant, je l'ai encore dans CentOS avec ext4 et je ne sais pas si il y a un moyen facile autour d'elle (ou tout autour). Ce que je veux, c'est un directory dans lequel n'importe quel user d'un certain groupe a garanti un access en lecture / écriture aux files, indépendamment des umask s des users, des mauvaises décisions de téléchargement des clients FTP, etc. J'aimerais bien me tromper. Il semble que la raison pour laquelle il n'est pas possible est que les ACL ext4 ne puissent pas replace les permissions de files, mais seulement les croiser. Par exemple:

 # mkdir bar # chmod 700 bar # getfacl bar # file: bar # owner: root # group: mygroup # flags: -s- user::rwx group::rwx #effective:--- group:mygroup:rwx #effective:--- mask::--- other::--- default:user::rwx default:group::rwx default:group:mygroup:rwx default:mask::rwx default:other::--- 

Vous pouvez voir que la list de contrôle d'access et le masque par défaut spécifient rwx pour mygroup mais les permissions de file l' rwx sur et aboutissent à --- . Malheureusement, cela signifie que si le client FTP d'un user (par exemple) télécharge des files en tant que 640, les autres membres du groupe ne pourraient pas jouer avec. Y a-t-il un moyen de contourner ceci?

Les permissions accordées par une ACL sont additives, mais peut-être vous attendez-elles à être récursives? (ils ne sont pas)

Vous pouvez presque get ce que vous voulez avec les lists de contrôle d'access. Vous devez commencer par définir l'ACL comme ci-dessus récursivement sur chaque file et directory de l'arborescence. Assurez-vous d'inclure le paramètre default:group:mygroup:rwx sur les directorys. Maintenant, tout nouveau directory recevra ces parameters automatiquement appliqués, ainsi que le nouveau file dans ces directorys.

Il y a deux fois quand cela échoue encore:

  • quand quelqu'un déplace un file ou un directory de l'extérieur de l'arborescence. Comme l'inode existe déjà, les valeurs par défaut ne sont pas définies.
  • lorsque quelqu'un extrait des files d'une archive en utilisant un programme compatible ACL qui écrase les valeurs par défaut.

Je ne connais aucun moyen de gérer ces deux autres que l'écriture d'un travail cron pour exécuter périodiquement chgrp -R mygroup DIRECTORY; chmod g+rwx -R DIRECTORY chgrp -R mygroup DIRECTORY; chmod g+rwx -R DIRECTORY . Cela peut ou peut ne pas être pratique en fonction du nombre de files dans votre directory partagé.

Voici une version légèrement modifiée d'un script que j'utilise pour corriger les ACL sur une arborescence de files. Il écrase complètement toutes les lists de contrôle d'access de n'importe quel élément de l'arborescence avec une list spécifique de groupes de lecture-écriture et de groupes en lecture seule.

 #! /usr/bin/env perl use ssortingct; use warnings; use Ssortingng::ShellQuote; use Cwd 'abs_path'; # Usage: fix-permissions.pl DIRECTORY RW_GROUP1,RW_GROUP2... RO_GROUP1,RO_GROUP2... my $dir= $ARGV[0]; my @rw_groups= split ',', $ARGV[1] if $ARGV[1]; my @ro_groups= split ',', $ARGV[2] if $ARGV[2]; -d $dir or die "No such directory'$dir'\n"; $dir= abs_path($dir); $dir =~ m|/[^/]+/| or die "Cowardly refusing to run on a top-level directory: $dir\n"; # Give all files rw-r----- and all directories rwxr-x--- # then give each rw_group read/write access, then each ro_group # read-only access to the whole tree my $dir_perm= join(',', 'u::rwx', 'g::r-x', 'o::---', 'd:u::rwx', 'd:g::r-x', 'd:o::---', ( map { "g:$_:rwx" } @rw_groups ), ( map { "d:g:$_:rwx" } @rw_groups ), ( map { "g:$_:rx" } @ro_groups ), ( map { "d:g:$_:rx" } @ro_groups ) ); my $file_perm= join(',', 'u::rwx', 'g::r-x', 'o::---', ( map { "g:$_:rw-" } @rw_groups ), ( map { "g:$_:r--" } @ro_groups ) ); for ( "find ".shell_quote($dir)." -type d -print0 | xargs -0 -r setfacl --set ".shell_quote($dir_perm), "find ".shell_quote($dir)." ! -type d -print0 | xargs -0 -r setfacl --set ".shell_quote($file_perm) ) { 0 == system($_) or die "command failed: $_\n"; }