ACLs podem substituir perms de arquivos no Linux?

5

Eu lutei com esse problema no FreeBSD recentemente, mas agradeço a Deus pelo ZFS, que resolveu isso para mim lá. No entanto, eu tenho isso novamente no CentOS com ext4 e não sei se há uma maneira fácil de contornar (ou qualquer maneira de contornar isso). O que eu quero é um diretório no qual qualquer usuário em um determinado grupo tenha acesso garantido de leitura / gravação aos arquivos, independentemente de usuários sem noção ' umask s, decisões ruins de upload de cliente FTP, etc. Eu não acho possível mas eu gostaria de estar errado. Parece que a razão pela qual isso não é possível é que as ACLs do ext4 não podem substituir as permissões de arquivo, apenas se interceptam com elas. Por exemplo:

# 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::---

Você pode ver que as máscaras ACL e especificam rwx para mygroup , mas as permissões de arquivo vencem e resultam em --- . Infelizmente, isso significa que, se o cliente FTP de um usuário (por exemplo) fizer o upload de arquivos como 640, outros usuários do grupo não conseguirão mexer com ele. Existe uma maneira de contornar isso?

    
por Josh 02.02.2015 / 00:00

1 resposta

4

As permissões concedidas por um ACL são aditivas, mas talvez você esteja esperando que elas sejam recursivas? (eles não são)

Você quase consegue o que deseja com as ACLs. Você precisa começar definindo a ACL como acima recursivamente em todos os arquivos e diretórios na árvore. Certifique-se de incluir a configuração default:group:mygroup:rwx nos diretórios. Agora, qualquer novo diretório obterá essas configurações automaticamente aplicadas a ele e também o novo arquivo nesses diretórios.

Existem duas ocasiões em que isso ainda falha:

  • quando alguém move um arquivo ou diretório de fora da árvore. Como o inode já existe, ele não terá os padrões definidos nele.
  • quando alguém extrai arquivos de um arquivo morto usando um programa com reconhecimento de ACL que sobrescreve os padrões.

Eu não conheço nenhuma maneira de lidar com esses dois além de escrever um cron job para executar periodicamente chgrp -R mygroup DIRECTORY; chmod g+rwx -R DIRECTORY . Isso pode ou não ser prático dependendo do número de arquivos em seu diretório compartilhado.

Aqui está uma versão ligeiramente modificada de um script que eu uso para corrigir ACLs em uma árvore de arquivos. Ele substitui completamente qualquer ACL em qualquer item da árvore com uma lista específica de grupos de leitura e gravação e grupos somente leitura.

#! /usr/bin/env perl
use strict;
use warnings;
use String::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:$_:r-x" } @ro_groups ),
  ( map { "d:g:$_:r-x" } @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";
}
    
por 02.02.2015 / 06:42