Ich möchte alle ZFS-ACLs von einer Datei in eine andere klonen.
getfacl
Mit POSIX-ACLs kann dies durch Weiterleiten der Ausgabe von an erfolgen setfacl
.
Gibt es eine einfache und schnelle Möglichkeit, dies mit den ACLs im NFSv4-Stil in ZFS zu tun? Ich weiß, dass ich die Ausgabe von auslesen ls -lV
und dann als Teil eines eingeben kann chmod
, aber ich kann anscheinend kein funktionales Äquivalent zur POSIX-Methode zum Kopieren von ACLs finden.
Antwort1
Anstelle von ls -lV
können Sie verwenden ls -lv
, was in ein Skript eingespeist werden kann, um es in eine Befehlsfolge chmod
zum Duplizieren der ACLs umzuwandeln.
Wenn der ACl beispielsweise so aussieht:
$ 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
Es sollte in die folgende Befehlsfolge umgewandelt werden chmod
:
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
Ich befand mich kürzlich in einer Situation, in der ein Skript wie das oben beschriebene nützlich gewesen wäre. Hier ist also ein kleines Bash-Skript, das ich erstellt habe (kann auch in die Shell geladen und als Funktion ausgeführt werden), um die Liste der chmod-Befehle auszudrucken, die zum Kopieren der ZFS-ACLs von einer Datei in eine andere erforderlich sind:
#!/bin/bash acl_as_chmods () { # Liste der chmod-Befehle drucken, um die ACL-Einträge von „$1“ nach „$2“ zu kopieren [[ -a "$1" ]] 2>/dev/null || { echo "Gültige Referenzdatei erforderlich." >&2 Rückgabe 1 } ls -vd "$1" | { lesen # erste Zeile enthält keine ACL-Informationen; umgehen ACL-Eintrag lesen echo -n "chmod A=${ACL_entry#*:}" # wenn keine Zieldatei als „$2“ angegeben wurde, verwende zur Laufzeit die Variable „TARGET“ während ACL-Eintrag gelesen wird || { echo " ${2-\$TARGET}"; false; } Tun [[ "$ACL_entry" == [0-9]*:* ]] && \ echo -en " ${2-\$TARGET}\nchmod A${ACL_entry%%:*}+${ACL_entry#*:}" || \ echo -n "$ACL_eintrag" Erledigt } } ## Als Skript oder Quellfunktion in der Shell ausführen? __acl_as_chmods () { [[ "${FUNCNAME[1]}" == "Quelle" ]] || acl_as_chmods "$@" } __acl_as_chmods "$@"
Hier sind ein paar Anwendungsbeispiele und deren Ausgabe fürDatei1von oben:
~$ ./acl_as_chmods.sh Datei1 Datei2 chmod A=Besitzer@::deny file2 chmod A1+owner@:Daten lesen/Daten schreiben/Daten anhängen/xattr schreiben/ausführen/Attribute schreiben/ACL schreiben/Eigentümer schreiben:Datei2 zulassen chmod A2+group@:Daten lesen/Daten schreiben/Daten anhängen:Datei2 verweigern chmod A3+group@:execute:allow file2 chmod A4+jeder@:Daten lesen/Daten schreiben/Daten anhängen/xattr schreiben/Attribute schreiben/ACL schreiben/Eigentümer schreiben:Datei2 verweigern chmod A5+everyone@:read_xattr/ausführen/read_attributes/read_acl/synchronisieren:file2 zulassen ~$ Quelle acl_as_chmods.sh ~$ acl_as_chmods Datei1 chmod A=Besitzer@::deny $TARGET chmod A1+owner@:Daten lesen/Daten schreiben/Daten anhängen/xattr schreiben/ausführen/Attribute schreiben/ACL schreiben/Eigentümer schreiben:$TARGET zulassen chmod A2+group@:Daten lesen/Daten schreiben/Daten anhängen:deny $TARGET chmod A3+group@:execute:allow $TARGET chmod A4+jeder@:Daten lesen/Daten schreiben/Daten anhängen/xattr schreiben/Attribute schreiben/ACL schreiben/Eigentümer schreiben:deny $TARGET chmod A5+jeder@:read_xattr/ausführen/read_attributes/read_acl/synchronisieren:zulassen $TARGET
Wenn wir möchten, können wir diese chmods sogar direkt auswerten, wenn beide Dateien auf diesem Host erreichbar sind und wir die ACLs kopieren möchten vonDatei1ZuDatei2sofort:
~$ ls -Vd Datei* #VORHER -rwx--x--x 1 Benutzer Benutzer 0 Jun 19 04:12 Datei1 Besitzer@:--------------:------:verweigern Besitzer@:rwxp---AW-Co-:------:erlauben Gruppe@:rw-p----------:------:verweigern Gruppe@:--x-----------:------:erlauben jeder@:rw-p---AW-Co-:------:verweigern jeder@:--x---aRc--s:------:erlauben ---x------+ 1 Benutzer Benutzer 0 Jun 19 04:12 Datei2 Besitzer@:--x-----------:------:erlauben ~$ eval "$(acl_as_chmods Datei1 Datei2)" ~$ ls -Vd Datei* #NACH -rwx--x--x 1 Benutzer Benutzer 0 Jun 19 04:12 Datei1 Besitzer@:--------------:------:verweigern Besitzer@:rwxp---AW-Co-:------:erlauben Gruppe@:rw-p----------:------:verweigern Gruppe@:--x-----------:------:erlauben jeder@:rw-p---AW-Co-:------:verweigern jeder@:--x---aRc--s:------:erlauben -rwx--x--x 1 Benutzer Benutzer 0 Jun 19 04:12 Datei2 Besitzer@:--------------:------:verweigern Besitzer@:rwxp---AW-Co-:------:erlauben Gruppe@:rw-p----------:------:verweigern Gruppe@:--x-----------:------:erlauben jeder@:rw-p---AW-Co-:------:verweigern jeder@:--x---aRc--s:------:erlauben
Antwort2
Ich bin auf dasselbe Problem gestoßen. Mein Code ist hier:
https://gist.github.com/1021032
Funktioniert bei mir einwandfrei. Ich hoffe, es ist praktisch, falls jemand anders da draußen jemals auf dieses Problem stößt.
Antwort3
Was nehmenMartinschlägt vor und wenn Sie ein bisschen Perl anwenden, erhalten Sie möglicherweise etwa Folgendes:
#!/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: $?";
}
Versuchen Sie es, bevor Sie die Systemzeilen (@out) auskommentieren.
Antwort4
Ärgerlicherweise scheint dies auf Shell-Ebene nicht richtig dargestellt zu werden. In C gibt es Funktionen acl_get(3SEC)
und , acl_set(3SEC)
mit denen man die ACL aus einer Datei nehmen und auf eine andere anwenden kann (neben anderen Optionen natürlich). Sie übersetzen auch nützlicherweise eine ACL vom POSIX-Entwurf in den NFSv4-Typ; das ist es, was Systembefehle mögen mv
und cp
verwenden.
Ich habe einmal einen Befehl geschrieben, um mit dieser Technik eine ACL von einer Quell- in eine Zieldatei zu kopieren, kann den Quellcode derzeit aber nicht finden. Sollte ich ihn finden, hänge ich ihn an diese Antwort an.