Me gustaría clonar todas las ACL de ZFS de un archivo a otro.
Con las ACL POSIX, esto se puede hacer canalizando la salida de getfacl
a setfacl
.
¿Existe una manera fácil y rápida de hacer esto con las ACL de estilo NFSv4 en ZFS? Sé que puedo leer el resultado ls -lV
y luego ingresarlo como parte de a chmod
, pero parece que no puedo encontrar un equivalente funcional a la forma POSIX de copiar ACL.
Respuesta1
En lugar de usar, ls -lV
puede usar ls -lv
el cual se puede introducir en un script para convertirlo en una secuencia de chmod
comandos para duplicar las ACL.
Por ejemplo, si el ACl tiene este aspecto:
$ ls -lv file1
0:owner@::deny
1:owner@:read_data/write_data/append_data/write_xattr/execute
/write_attributes/write_acl/write_owner:allow
2:group@:read_data/write_data/append_data:deny
3:group@:execute:allow
4:everyone@:read_data/write_data/append_data/write_xattr
/write_attributes/write_acl/write_owner:deny
5:everyone@:read_xattr/execute/read_attributes/read_acl/synchronize:allow
Debe entregarse a la siguiente secuencia de chmod
comandos:
chmod A0=owner@::deny file2
chmod A1=owner@:read_data/write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:allow file2
chmod A2=group@:read_data/write_data/append_data:deny file2
chmod A3=group@:execute:allow file2
chmod A4=everyone@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner:deny file2
chmod A5=everyone@:read_xattr/execute/read_attributes/read_acl/synchronize:allow file2
Recientemente me encontré en una situación en la que un script como el descrito anteriormente habría sido útil, así que aquí hay un pequeño script Bash que hice (también puede obtenerse en el shell y ejecutarse como una función) para imprimir la lista de comandos chmod necesarios. para copiar las ACL de ZFS de un archivo a otro:
#!/bin/bash acl_as_chmods () { # imprimir la lista de comandos chmod para copiar las entradas de ACL de '$1' a '$2' [[ -a "$1" ]] 2>/dev/null || { echo "Se requiere un archivo de referencia válido". >&2 regresar 1 } ls -vd "$1" | { leer # la primera línea no es información de ACL; derivación leer ACL_entry echo -n "chmod A=${ACL_entry#*:}" # si no se especificó ningún archivo de destino como '$2', use la variable 'TARGET' en tiempo de ejecución mientras se lee ACL_entry || { echo " ${2-\$TARGET}"; FALSO; } hacer [[ "$ACL_entry" == [0-9]*:* ]] && \ echo -en " ${2-\$TARGET}\nchmod A${ACL_entry%%:*}+${ACL_entry#*:}" || \ echo -n "$ACL_entrada" hecho } } ## ¿ejecutar como script o función fuente al shell? __acl_as_chmods () { [[ "${FUNCNAME[1]}" == "fuente" ]] || acl_as_chmods "$@" } __acl_as_chmods "$@"
Aquí hay un par de usos de ejemplo y su resultado paraarchivo1desde arriba:
~$ ./acl_as_chmods.sh archivo1 archivo2 chmod A=propietario@::denegar archivo2 chmod A1+propietario@:read_data/write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:permitir archivo2 chmod A2+grupo@:read_data/write_data/append_data:denegar archivo2 chmod A3+grupo@:ejecutar:permitir archivo2 chmod A4+todos@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner:denegar archivo2 chmod A5+todos@:read_xattr/execute/read_attributes/read_acl/synchronize:permitir archivo2 ~$ fuente acl_as_chmods.sh ~$ acl_as_chmods archivo1 chmod A=propietario@::denegar $OBJETIVO chmod A1+propietario@:read_data/write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:permitir $OBJETIVO chmod A2+grupo@:read_data/write_data/append_data:deny $OBJETIVO chmod A3+grupo@:ejecutar:permitir $OBJETIVO chmod A4+todos@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner:deny $OBJETIVO chmod A5+todos@:read_xattr/execute/read_attributes/read_acl/synchronize:allow $OBJETIVO
Si lo deseamos, incluso podemos evaluar estos chmods directamente, si ambos archivos son accesibles en este host y deseamos copiar las ACL dearchivo1aarchivo2inmediatamente:
~$ ls -Vd archivo* #ANTES -rwx--x--x 1 usuario usuario 0 19 de junio 04:12 archivo1 propietario@:--------------:------:negar propietario@:rwxp---AW-Co-:------:permitir grupo@:rw-p----------:--------------:denegar grupo@:--x-----------:------:permitir todos@:rw-p---AW-Co-:------:negar todos@:--x---aRc--s:------:permitir ---x------+ 1 usuario usuario 0 19 de junio 04:12 archivo2 propietario@:--x-----------:------:permitir ~$ eval "$(acl_as_chmods archivo1 archivo2)" ~$ ls -Vd archivo* #DESPUÉS -rwx--x--x 1 usuario usuario 0 19 de junio 04:12 archivo1 propietario@:--------------:------:negar propietario@:rwxp---AW-Co-:------:permitir grupo@:rw-p----------:--------------:denegar grupo@:--x-----------:------:permitir todos@:rw-p---AW-Co-:------:negar todos@:--x---aRc--s:------:permitir -rwx--x--x 1 usuario usuario 0 19 de junio 04:12 archivo2 propietario@:--------------:------:negar propietario@:rwxp---AW-Co-:------:permitir grupo@:rw-p----------:--------------:denegar grupo@:--x-----------:------:permitir todos@:rw-p---AW-Co-:------:negar todos@:--x---aRc--s:------:permitir
Respuesta2
Me encontré con este mismo problema. Mi código está aquí:
https://gist.github.com/1021032
Funciona como un encanto para mí. Espero que sea útil si alguien más alguna vez se encuentra con este problema.
Respuesta3
tomando lo queMartínsugiere y aplicando un poco de perl podrías obtener algo como:
#!/usr/bin/perl
use warnings;
use strict;
my $state = 0;
if ($#ARGV < 1 || $#ARGV > 2) {
print "\n\tUsage: $0 srcFile destFile\n";
}
my $acl=`ls -lv "${ARGV[0]}"`;
my @out="chmod", "arg", $ARGV[1];
foreach my $line ($acl) {
chomp $line;
if ($line =~ m/^\s+(\d+):(.*)$/) {
if ($state > 0) {
print join(" ",@out)."\n";
#system(@out) or die "system @args failed: $?";
}
$state = 1;
$out[1] = "A$1=$2";
} else {
$line =~ m/^\s+(.*)$/;
$state = 2;
$out[1] .= $1;
}
}
if ($state > 0) {
print join(" ",@out)."\n";
#system(@out) or die "system @args failed: $?";
}
Pruébelo antes de descomentar las líneas del sistema (@out).
Respuesta4
Es molesto que esto no parezca estar expuesto adecuadamente a nivel del caparazón. En C existen funciones acl_get(3SEC)
y acl_set(3SEC)
que se pueden usar para tomar la ACL de un archivo y aplicarla a otro (entre otras opciones, obviamente). También traducirán, de manera útil, una ACL del borrador POSIX al tipo NFSv4; esto es lo que les gusta mv
y cp
usan los comandos del sistema.
En un momento, escribí un comando para copiar una ACL de un archivo de origen a un archivo de destino usando esta técnica, pero actualmente no puedo encontrar el código fuente. Si lo encuentro, lo agregaré a esta respuesta.