Wie klone ich ZFS-ACLs von einer Datei in eine andere?

Wie klone ich ZFS-ACLs von einer Datei in eine andere?

Ich möchte alle ZFS-ACLs von einer Datei in eine andere klonen.

getfaclMit 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 -lVund 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 -lVkönnen Sie verwenden ls -lv, was in ein Skript eingespeist werden kann, um es in eine Befehlsfolge chmodzum 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 mvund cpverwenden.

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.

verwandte Informationen