Я хотел бы клонировать все списки контроля доступа ZFS из одного файла в другой.
С помощью списков контроля доступа POSIX это можно сделать, перенаправив вывод getfacl
в setfacl
.
Есть ли простой и быстрый способ сделать это с помощью ACL в стиле NFSv4 в ZFS? Я знаю, что могу считать вывод ls -lV
и затем ввести его как часть chmod
, но я не могу найти функциональный эквивалент POSIX-способу копирования ACL.
решение1
Вместо этого ls -lV
вы можете использовать ls -lv
, который можно вставить в скрипт, чтобы преобразовать его в последовательность chmod
команд для дублирования ACL.
Например, если 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
Недавно я оказался в ситуации, когда скрипт, подобный описанному выше, был бы полезен, поэтому вот небольшой скрипт Bash, который я создал (его также можно подключить к оболочке и запустить как функцию) для вывода списка команд chmod, необходимых для копирования списков контроля доступа ZFS из одного файла в другой:
#!/bin/баш acl_as_chmods () { # вывести список команд chmod для копирования записей ACL из '$1' в '$2' [[ -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=владелец@::deny file2 chmod A1+владелец@: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=владелец@::deny $TARGET chmod A1+владелец@: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
Если мы захотим, мы даже можем оценить эти chmods напрямую, если оба файла доступны на этом хосте и мы хотим скопировать ACL сфайл1кфайл2немедленно:
~$ ls -Vd файл* #ПЕРЕД -rwx--x--x 1 пользователь пользователь 0 июн 19 04:12 файл1 владелец@:-------------:------:отказать владелец@:rwxp---AW-Co-:------:allow группа@:rw-p----------:------:отказать группа@:--x----------:------:разрешить все@:rw-p---AW-Co-:------:deny все@:--x---aRc--s:------:разрешить ---x------+ 1 пользователь пользователь 0 июн 19 04:12 file2 владелец@:--x----------:------:разрешить ~$ eval "$(acl_as_chmods файл1 файл2)" ~$ ls -Vd файл* #ПОСЛЕ -rwx--x--x 1 пользователь пользователь 0 июн 19 04:12 файл1 владелец@:-------------:------:отказать владелец@:rwxp---AW-Co-:------:allow группа@:rw-p----------:------:отказать группа@:--x----------:------:разрешить все@:rw-p---AW-Co-:------:deny все@:--x---aRc--s:------:разрешить -rwx--x--x 1 пользователь пользователь 0 июн 19 04:12 file2 владелец@:-------------:------:отказать владелец@:rwxp---AW-Co-:------:allow группа@:rw-p----------:------:отказать группа@:--x----------:------:разрешить все@:rw-p---AW-Co-:------:deny все@:--x---aRc--s:------:разрешить
решение2
Я столкнулся с такой же проблемой. Мой код здесь:
https://gist.github.com/1021032
У меня все работает как часы. Надеюсь, это пригодится, если кто-то еще столкнется с этой проблемой.
решение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_get(3SEC)
и acl_set(3SEC)
, которые можно использовать для извлечения ACL из одного файла и применения его к другому (среди прочих опций, очевидно). Они также будут, что полезно, переводить ACL из черновика POSIX в тип NFSv4; это то, что любят mv
и cp
используют системные команды.
Я написал, в свое время, команду для копирования acl из исходного в целевой файл с использованием этой техники, но в настоящее время я не могу найти исходный код. Если я его найду, я добавлю его к этому ответу.