ZFS ACL をあるファイルから別のファイルに複製するにはどうすればよいですか?

ZFS ACL をあるファイルから別のファイルに複製するにはどうすればよいですか?

すべての ZFS ACL を 1 つのファイルから別のファイルに複製したいと思います。

getfaclPOSIX ACL では、の出力を にパイプすることでこれを実行できますsetfacl

ZFS の NFSv4 スタイルの ACL を使用して、これを簡単かつ迅速に実行する方法はありますか? の出力を読み取ってls -lV、それを の一部として入力できることchmodはわかっていますが、ACL をコピーする POSIX の方法と機能的に同等なものが見つからないようです。

答え1

を使用する代わりに、スクリプトに入力してACL を複製する一連のコマンドに変換することがls -lVできます。ls -lvchmod

たとえば、ACl が次のようになっている場合:

$ 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

次のコマンドシーケンスに変換する必要があります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

最近、上記のようなスクリプトが役に立つ状況に遭遇したので、ZFS ACL をあるファイルから別のファイルにコピーするために必要な chmod コマンドのリストを出力する、私が作成した小さな Bash スクリプト (シェルにソースして関数として実行することもできます) を以下に示します。

#!/bin/bash

acl_as_chmods() {
# ACL エントリを '$1' から '$2' にコピーする chmod コマンドのリストを出力します
 [[ -a "$1" ]] 2>/dev/null || {
   echo "有効な参照ファイルが必要です。" >&2
   戻り値 1
 }
 ls -vd "$1" | {
   読み取り # 最初の行は ACL 情報ではないため、バイパスします
   ACL_entry を読む
     echo -n "chmod A=${ACL_entry#*:}"
   # '$2' としてターゲットファイルが指定されていない場合は、実行時に 'TARGET' 変数を使用します
   ACL_entry を読み取り中 || { echo " ${2-\$TARGET}"; false; }
   する
     [[ "$ACL_entry" == [0-9]*:* ]] && \
       echo -en " ${2-\$TARGET}\nchmod A${ACL_entry%%:*}+${ACL_entry#*:}" || \
       echo -n "$ACL_entry"
   終わり
 }
}

## スクリプトとして実行するか、シェルに関数をソースしますか?
__acl_as_chmods() {
 [[ "${FUNCNAME[1]}" == "ソース" ]] || acl_as_chmods "$@"
}

__acl_as_chmods "$@"

以下に使用例とその出力をいくつか示します。ファイル1上から:

~$ ./acl_as_chmods.sh ファイル1 ファイル2
chmod A=所有者@::拒否ファイル2
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

~$ ソース acl_as_chmods.sh
~$ acl_as_chmods ファイル1
chmod A=owner@::deny $TARGET
chmod A1+owner@:read_data/write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:allow $TARGET
chmod A2+group@:read_data/write_data/append_data:deny $TARGET
chmod A3+group@:execute:allow $TARGET
chmod A4+everyone@:read_data/write_data/append_data/write_xattr/write_attributes/write_acl/write_owner:deny $TARGET
chmod A5+everyone@:read_xattr/execute/read_attributes/read_acl/synchronize:allow $TARGET

両方のファイルがこのホスト上でアクセス可能で、ACLをコピーしたい場合は、これらのchmodを直接評価することもできます。ファイル1ファイル2すぐに:

~$ ls -Vd ファイル* #BEFORE
-rwx--x--x 1 ユーザー ユーザー 0 6月19日 04:12 ファイル1
            所有者@:--------------:------:拒否
            所有者@:rwxp---AW-Co-:------:allow
            グループ@:rw-p----------:------:拒否
            グループ@:--x-----------:------:許可
         みんな@:rw-p---AW-Co-:------:拒否
         みんな@:--x---aRc--s:------:許可
---x------+ 1 ユーザー ユーザー 0 6月19日 04:12 ファイル2
            所有者@:--x-----------:------:許可

~$ eval "$(acl_as_chmods ファイル1 ファイル2)"

~$ ls -Vd ファイル* #後
-rwx--x--x 1 ユーザー ユーザー 0 6月19日 04:12 ファイル1
            所有者@:--------------:------:拒否
            所有者@:rwxp---AW-Co-:------:allow
            グループ@:rw-p----------:------:拒否
            グループ@:--x-----------:------:許可
         みんな@:rw-p---AW-Co-:------:拒否
         みんな@:--x---aRc--s:------:許可
-rwx--x--x 1 ユーザー ユーザー 0 6月19日 04:12 ファイル2
            所有者@:--------------:------:拒否
            所有者@:rwxp---AW-Co-:------:allow
            グループ@:rw-p----------:------:拒否
            グループ@:--x-----------:------:許可
         みんな@:rw-p---AW-Co-:------:拒否
         みんな@:--x---aRc--s:------:許可

答え2

私も同じ問題に遭遇しました。私のコードは次のとおりです:

出典: github.com

私にとってはうまくいきました。他の誰かがこの問題に遭遇したときにも役立つことを願っています。

答え3

何を取るかマーティン提案に少し Perl を適用すると、次のようなものが得られるかもしれません:

#!/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: $?";
}

system(@out) 行のコメントを解除する前に試してください。

答え4

残念なことに、これはシェル レベルでは適切に公開されていないようです。C には、あるファイルから ACL を取得して別のファイルに適用するために使用できる関数とがありますacl_get(3SEC)(acl_set(3SEC)もちろん、他のオプションもあります)。また、便利なことに、これらの関数は ACL を POSIX ドラフトから NFSv4 タイプに変換します。これは、システム コマンドが好んmvcp使用するものです。

かつて、この手法を使用して、ソース ファイルから宛先ファイルに ACL をコピーするコマンドを作成しましたが、現在ソース コードが見つかりません。見つかったら、この回答に追加します。

関連情報