Oracle Solaris ZFS 管理指南

第 8 章 使用 ACL 保护 Oracle Solaris ZFS 文件

本章介绍有关使用访问控制列表 (access control list, ACL) 保护 ZFS 文件的信息。ACL 提供的权限比标准 UNIX 权限更详尽。

本章包含以下各节:

新 Solaris ACL 模型

Solaris OS 的旧版本支持主要基于 POSIX 草案 ACL 规范的 ACL 实现。基于 POSIX 草案 ACL 用来保护 UFS 文件,并通过 NFSv4 之前的 NFS 版本进行转换。

引入 NFSv4 后,新 ACL 模型完全支持 NFSv4 在 UNIX 和非 UNIX 客户机之间提供的互操作性。如 NFSv4 规范中所定义,这一新的 ACL 实现提供了更丰富的基于 NT 样式 ACL 的语义。

新 ACL 模型的主要差别如下所列:

两种 ACL 模型均可比标准文件权限提供更精细的访问控制。与 POSIX 草案 ACL 非常相似,新 ACL 也由多个访问控制项 (Access Control Entry, ACE) 构成。

基于 POSIX 草案 ACL 使用单个项来定义允许和拒绝的权限。而新 ACL 模型包含两种类型的 ACE,用于进行访问检查: ALLOW 和 DENY。因此,不能根据任何定义一组权限的单个 ACE 来推断是否允许或拒绝该 ACE 中未定义的权限。

NFSv4 ACL 与 POSIX 草案 ACL 之间的转换如下:

有关对 ACL 和备份产品的其他限制信息,请参见使用其他备份产品保存 ZFS 数据。

ACL 设置语法的说明

基本的 ACL 格式有如下两种:

用于设置普通 ACL 的语法

ACL 很普通,因为它仅表示传统的 UNIX owner/group/other 项。

chmod [options] A[index]{+|=}owner@ |group@ |everyone@: access-permissions/...[:inheritance-flags]: deny | allow file

chmod [options] A-owner@, group@, everyone@:access-permissions /...[:inheritance-flags]:deny | allow file ...

chmod [options] A[index]- file

用于设置非普通 ACL 的语法

chmod [options] A[index]{+|=}user|group:name:access-permissions /...[:inheritance-flags]:deny | allow file

chmod [options] A-user|group:name:access-permissions /...[:inheritance-flags]:deny | allow file ...

chmod [options] A[index]- file

owner@, group@, everyone@

标识用于普通 ACL 语法的 ACL-entry-type。有关 ACL 项类型的说明,请参见表 8–1。

user|group: ACL-entry-ID(username 或 groupname)

标识用于显式 ACL 语法的 ACL-entry-type。用户和组的 ACL-entry-type 还必须包含 ACL-entry-ID、username 或 groupname。有关 ACL 项类型的说明,请参见表 8–1。

access-permissions/.../

标识授予或拒绝的访问权限。有关 ACL 访问权限的说明,请参见表 8–2。

inheritance-flags

标识一组可选的 ACL 继承标志。有关 ACL 继承标志的说明,请参见表 8–3。

deny | allow

标识授予还是拒绝访问权限。

在以下示例中,ACL-entry-ID 值无意义。


group@:write_data/append_data/execute:deny

由于 ACL 中包括特定用户 (ACL-entry-type),因此以下示例中包括 ACL-entry-ID。


0:user:gozer:list_directory/read_data/execute:allow

显示的 ACL 项与以下内容类似:


2:group@:write_data/append_data/execute:deny

本示例中的 2 为索引 ID,用于标识较大 ACL 中的 ACL 项,较大的 ACL 中可能包含对应于属主、特定 UID、组和各用户的多个项。可以使用 chmod 命令指定索引 ID,以标识 ACL 要修改的部分。例如,可将索引 ID 3 标识为 chmod 命令语法中的 A3,与以下内容类似:


chmod A3=user:venkman:read_acl:allow filename

下表介绍了 ACL 项类型,即属主、组和其他对象的 ACL 表示形式。

表 8–1 ACL 项类型

ACL 项类型 

说明 

owner@

指定授予对象属主的访问权限。 

group@

指定授予对象所属组的访问权限。 

everyone@

指定向不与其他任何 ACL 项匹配的任何用户或组授予的访问权限。 

user

通过用户名指定向对象的其他用户授予的访问权限。此项必须包括 ACL-entry-ID,其中包含 username 或 userID。如果该值不是有效的数字 UID 或 username,则该 ACL 项的类型无效。

group

通过组名指定向对象的其他组授予的访问权限。此项必须包括 ACL-entry-ID,其中包含 groupname 或 groupID。如果该值不是有效的数字 UID 或 groupname,则该 ACL 项的类型无效。

下表介绍了 ACL 访问权限。

表 8–2 ACL 访问权限

访问权限 

缩写访问权限 

说明 

add_file

w

向目录中添加新文件的权限。 

add_subdirectory

p

在目录中创建子目录的权限。 

append_data

p

占位符。当前未实现。 

delete

d

删除文件的权限。 

delete_child

D

删除目录中的文件或目录的权限。 

execute

x

执行文件或搜索目录内容的权限。 

list_directory

r

列出目录内容的权限。 

read_acl

c

读取 ACL 的权限 (ls)。

read_attributes

a

读取文件的基本属性(非 ACL)的权限。将基本属性视为状态级别属性。允许此访问掩码位意味着该实体可以执行 ls(1) 和 stat(2)。

read_data

r

读取文件内容的权限。 

read_xattr

R

读取文件的扩展属性或在文件的扩展属性目录中执行查找的权限。 

synchronize

s

占位符。当前未实现。 

write_xattr

W

创建扩展属性或向扩展属性目录进行写入的权限。 

向用户授予此权限意味着用户可为文件创建扩展属性目录。属性文件的权限可以控制用户对属性的访问。 

write_data

w

修改或替换文件内容的权限。 

write_attributes

A

将与文件或目录关联的时间戳更改为任意值的权限。 

write_acl

C

编写 ACL 或使用 chmod 命令修改 ACL 的权限。

write_owner

o

更改文件的属主或组的权限,或者对文件执行 chown 或 chgrp 命令的能力。

获取文件拥有权的权限或将文件的组拥有权更改为由用户所属组的权限。如果要将文件或组的拥有权更改为任意用户或组,则需要 PRIV_FILE_CHOWN 权限。

ACL 继承

使用 ACL 继承的目的是使新创建的文件或目录可以继承其本来要继承的 ACL,但不忽略父目录的现有权限。

缺省情况下,不会传播 ACL。如果设置某个目录的非普通 ACL,则任何后续目录不会继承该非普通 ACL。必须对文件或目录指定 ACL 的继承。

下表介绍了可选的继承标志。

表 8–3 ACL 继承标志

继承标志 

缩写继承标志 

说明 

file_inherit

f

从父目录继承 ACL,但仅适用于该目录中的文件。 

dir_inherit

d

从父目录继承 ACL,但仅适用于该目录中的子目录。 

inherit_only

i

从父目录继承 ACL,但仅适用于新创建的文件或子目录,而不适用于该目录自身。该标志要求使用 file_inherit 标志或 dir_inherit 标志,或同时使用两者来表示要继承的内容。

no_propagate

n

仅将 ACL 从父目录继承到该目录的第一级内容,而不是第二级或后续内容。该标志要求使用 file_inherit 标志或 dir_inherit 标志,或同时使用两者来表示要继承的内容。

-

N/A 

未授予权限。 

此外,还可以使用 aclinherit 文件系统属性对文件系统设置更为严格或更为宽松的缺省 ACL 继承策略。有关更多信息,请参见下一节。

ACL 属性

ZFS 文件系统有两个与 ACL 相关的属性。

设置 ZFS 文件的 ACL

正如 ZFS 所实现的那样,ACL 由 ACL 项构成。ZFS 提供了一个纯 ACL 模型,其中所有文件都包括 ACL。通常,ACL 很普通,因为它仅表示传统的 UNIX owner/group/other 项。

如果更改文件的权限,该文件的 ACL 也会相应地更新。此外,如果删除授予用户对文件或目录的访问权限的非普通 ACL,则由于该文件或目录的权限位会将访问权限授予组或各用户,因此该用户仍可访问这一文件或目录。所有访问控制决策都由文件或目录的 ACL 中表示的权限来管理。

对于 ZFS 文件,ACL 访问权限的主要规则如下:

如果设置某个目录的非普通 ACL,则该目录的子目录不会自动继承该 ACL。如果设置了非普通 ACL 并希望目录的子目录继承该 ACL,则必须使用 ACL 继承标志。有关更多信息,请参见表 8–3 和以详细格式对 ZFS 文件设置 ACL 继承。

创建新文件时,根据 umask 值将应用类似如下的缺省的普通 ACL:


$ ls -v file.1
-rw-r--r--   1 root     root      206663 May 20 14:09 file.1
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

请注意,本例中每个用户类别 (owner@, group@, everyone@) 有两个 ACL 项。一个项用于 deny 权限,一个项用于 allow 权限。

此文件 ACL 的说明如下:

0:owner@

拒绝属主对文件的执行权限 (execute:deny)。

1:owner@

属主可以读取和修改文件的内容 (read_data/write_data/append_data)。属主还可以修改文件的属性,如时间戳、扩展属性和 ACL (write_xattr/write_attributes/write_acl)。此外,属主还可以修改文件的拥有权 (write_owner:allow)。

2:group@

拒绝组对文件的修改和执行权限 (write_data/append_data/execute:deny)。

3:group@

授予组对文件的读取权限 (read_data:allow)。

4:everyone@

拒绝非文件属主或非文件所属组成员执行或修改文件内容以及修改文件任何属性的权限 (write_data/append_data/write_xattr/execute/write_attributes/write_acl/write_owner:deny)。

5:everyone@

授予非文件属主或非文件所属组成员读取文件和文件属性的权限 (read_data/read_xattr/read_attributes/read_acl/synchronize:allow)。synchronize 访问权限当前未实现。

创建新目录时,根据 umask 值将应用类似如下的缺省目录 ACL:


$ ls -dv dir.1
drwxr-xr-x   2 root     root           2 May 20 14:11 dir.1
     0:owner@::deny
     1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     2:group@:add_file/write_data/add_subdirectory/append_data:deny
     3:group@:list_directory/read_data/execute:allow
     4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

此目录 ACL 的说明如下:

0:owner@

目录的属主 deny 列表为空 (::deny)。

1:owner@

属主可以读取和修改目录内容 (list_directory/read_data/add_file/write_data/add_subdirectory/append_data),搜索内容 (execute) 以及修改时间戳、扩展属性和 ACL 等目录属性 (write_xattr/write_attributes/write_acl)。此外,属主还可以修改目录的拥有权 (write_owner:allow)。

2:group@

组不能添加或修改目录内容 ( add_file/write_data/add_subdirectory/append_data:deny)。

3:group@

组可以列出并读取目录内容。此外,组还具有搜索目录内容的执行权限 (list_directory/read_data/execute:allow)。

4:everyone@

拒绝非文件属主或非文件所属组成员添加或修改目录内容的权限 (add_file/write_data/add_subdirectory/append_data)。此外还拒绝修改目录任何属性的权限 (write_xattr/write_attributes/write_acl/write_owner:deny)。

5:everyone@

授予非文件属主或非文件所属组成员对目录内容和目录属性的读取和执行权限 (list_directory/read_data/read_xattr/execute/read_attributes/read_acl/synchronize:allow)。synchronize 访问权限当前未实现。

以详细格式设置和显示 ZFS 文件的 ACL

可以使用 chmod 命令修改 ZFS 文件的 ACL。以下用于修改 ACL 的 chmod 语法使用 acl 规范来确定 ACL 的格式。有关 acl 规范的说明,请参见ACL 设置语法的说明。

详细 ACL 信息是通过使用 ls -v 命令来显示的。


# ls -v file.1
-rw-r--r--   1 root     root      206663 May 20 14:09 file.1
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

有关使用缩写 ACL 格式的信息,请参见以缩写格式设置和显示 ZFS 文件的 ACL。


示例 8–1 修改 ZFS 文件的普通 ACL

本节提供了设置和显示普通 ACL 的示例。

在以下示例中,普通 ACL 存在于 file.1 中:


# ls -v file.1
-rw-r--r--   1 root     root      206663 May 20 15:03 file.1
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

在以下示例中,为 group@ 授予了 write_data 权限:


# chmod A2=group@:append_data/execute:deny file.1
# chmod A3=group@:read_data/write_data:allow file.1
# ls -v file.1
-rw-rw-r--   1 root     root      206663 May 20 15:03 file.1
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:append_data/execute:deny
     3:group@:read_data/write_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

在以下示例中,对 file.1 的权限重新设置为 644。


# chmod 644 file.1
# ls -v file.1
-rw-r--r--   1 root     root      206663 May 20 15:03 file.1
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow


示例 8–2 设置 ZFS 文件的非普通 ACL

本节提供了设置和显示非普通 ACL 的示例。

在以下示例中,为用户 gozer 添加了对 test.dir 目录的 read_data/execute 权限:


# chmod A+user:gozer:read_data/execute:allow test.dir
# ls -dv test.dir
drwxr-xr-x+  2 root     root           2 May 20 15:09 test.dir
     0:user:gozer:list_directory/read_data/execute:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

在以下示例中,为用户 gozer 删除了 read_data/execute 权限:


# chmod A0- test.dir
# ls -dv test.dir
drwxr-xr-x   2 root     root           2 May 20 15:09 test.dir
     0:owner@::deny
     1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     2:group@:add_file/write_data/add_subdirectory/append_data:deny
     3:group@:list_directory/read_data/execute:allow
     4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow


示例 8–3 ACL 与 ZFS 文件权限的交互关系

以下示例说明设置 ACL 和随后更改文件或目录的权限两者之间的交互关系。

在以下示例中,普通 ACL 存在于 file.2 中:


# ls -v file.2
-rw-r--r--   1 root     root        3103 May 20 15:23 file.2
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

在以下示例中,从 everyone@ 中删除了 ACL allow 权限:


# chmod A5- file.2
# ls -v file.2
-rw-r-----+  1 root     root        3103 May 20 15:23 file.2
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny

在此输出中,文件的权限从 644 重置为 640。删除 everyone@ 的 ACL allow 权限时,会有效地从文件的权限中删除 everyone@ 的读取权限。

在以下示例中,现有 ACL 将替换为 everyone@ 的 read_data/write_data 权限:


# chmod A=everyone@:read_data/write_data:allow file.3
# ls -v file.3
-rw-rw-rw-+  1 root     root        6986 May 20 15:25 file.3
     0:everyone@:read_data/write_data:allow

在此输出中,chmod 语法有效地将现有 ACL 中的 read_data/write_data:allow 权限替换为对属主、组和 everyone@ 的读取/写入权限。在此模型中,everyone@ 用于指定对任何用户或组的访问权限。由于不存在用以覆盖属主和组的权限的 owner@ 或 group@ ACL 项,因此权限设置为 666。

在以下示例中,现有 ACL 将替换为用户 gozer 的读取权限:


# chmod A=user:gozer:read_data:allow file.3
# ls -v file.3
----------+  1 root     root        6986 May 20 15:25 file.3
     0:user:gozer:read_data:allow

在此输出中,文件权限计算结果为 000,这是因为不存在对应 owner@、group@ 或 everyone@ 的 ACL 项,这些项用于表示文件的传统权限组成部分。文件属主可通过重置权限(和 ACL)来解决此问题,如下所示:


# chmod 655 file.3
# ls -v file.3
-rw-r-xr-x+  1 root     root        6986 May 20 15:25 file.3
     0:user:gozer::deny
     1:user:gozer:read_data:allow
     2:owner@:execute:deny
     3:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     4:group@:write_data/append_data:deny
     5:group@:read_data/execute:allow
     6:everyone@:write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:deny
     7:everyone@:read_data/read_xattr/execute/read_attributes/read_acl
         /synchronize:allow


示例 8–4 恢复 ZFS 文件的普通 ACL

可以使用 chmod 命令来删除文件或目录的所有非普通 ACL,从而恢复文件或目录的普通 ACL。

在以下示例中,test5.dir 中存在两个非普通 ACE:


# ls -dv test5.dir
drwxr-xr-x+  2 root     root           2 May 20 15:32 test5.dir
     0:user:lp:read_data:file_inherit:deny
     1:user:gozer:read_data:file_inherit:deny
     2:owner@::deny
     3:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     4:group@:add_file/write_data/add_subdirectory/append_data:deny
     5:group@:list_directory/read_data/execute:allow
     6:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     7:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

在以下示例中,删除了用户 gozer 和 lp 的非普通 ACL。剩余的 ACL 包含用于 owner@、group@ 和 everyone@ 的六个缺省值。


# chmod A- test5.dir
# ls -dv test5.dir
drwxr-xr-x   2 root     root           2 May 20 15:32 test5.dir
     0:owner@::deny
     1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     2:group@:add_file/write_data/add_subdirectory/append_data:deny
     3:group@:list_directory/read_data/execute:allow
     4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

以详细格式对 ZFS 文件设置 ACL 继承

可以指定文件和目录是否及如何继承 ACL。缺省情况下,不会传播 ACL。如果设置某个目录的非普通 ACL,则任何后续目录都不会继承该 ACL。必须对文件或目录指定 ACL 的继承。

此外,可对文件系统全局设置两个 ACL 属性:aclinherit 和 aclmode。缺省情况下,aclinherit 设置为 restricted,aclmode 设置为 groupmask。

有关更多信息,请参见ACL 继承。


示例 8–5 授予缺省 ACL 继承

缺省情况下,ACL 不通过目录结构传播。

在以下示例中,为用户 gozer 应用了针对 test.dir 目录的非普通 ACE read_data/write_data/execute:


# chmod A+user:gozer:read_data/write_data/execute:allow test.dir
# ls -dv test.dir
drwxr-xr-x+  2 root     root           2 May 20 15:41 test.dir
     0:user:gozer:list_directory/read_data/add_file/write_data/execute:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

如果创建了 test.dir 子目录,则不会传播用户 gozer 的 ACE。如果对子目录的权限授予用户 gozer 作为文件属主、组成员或 everyone@ 进行访问的权限,则该用户只能访问子目录。例如:


# mkdir test.dir/sub.dir
# ls -dv test.dir/sub.dir
drwxr-xr-x   2 root     root           2 May 20 15:42 test.dir/sub.dir
     0:owner@::deny
     1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     2:group@:add_file/write_data/add_subdirectory/append_data:deny
     3:group@:list_directory/read_data/execute:allow
     4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow


示例 8–6 对文件和目录授予 ACL 继承

以下示例标识了设置 file_inherit 标志时应用的文件和目录的 ACE。

在本例中,为用户 gozer 添加了对 test2.dir 目录中的文件的 read_data/write_data 权限,以便该用户对于任何新创建的文件都具有读取访问权限:


# chmod A+user:gozer:read_data/write_data:file_inherit:allow test2.dir
# ls -dv test2.dir
drwxr-xr-x+  2 root     root           2 May 20 15:50 test2.dir
     0:user:gozer:read_data/write_data:file_inherit:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

在本例中,用户 gozer 的权限应用于新创建的 test2.dir/file.2 文件。授予 ACL 继承 read_data:file_inherit:allow 意味着用户 gozer 可以读取任何新创建的文件的内容。


# touch test2.dir/file.2
# ls -v test2.dir/file.2
-rw-r--r--+  1 root     root           0 May 20 15:51 test2.dir/file.2
     0:user:gozer:write_data:deny
     1:user:gozer:read_data/write_data:allow
     2:owner@:execute:deny
     3:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     4:group@:write_data/append_data/execute:deny
     5:group@:read_data:allow
     6:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     7:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

由于此文件的 aclmode 属性设置为缺省值 groupmask,因此用户 gozer 对 file.2 不具有 write_data 权限,这是因为该文件的组权限不允许使用此权限。

设置 file_inherit 或 dir_inherit 标志时所应用的 inherit_only 权限用来通过目录结构传播 ACL。因此,除非用户 gozer 是文件的属主或文件所属组的成员,否则仅授予或拒绝该用户 everyone@ 权限中的权限。例如:


# mkdir test2.dir/subdir.2
# ls -dv test2.dir/subdir.2
drwxr-xr-x+  2 root     root           2 May 20 15:52 test2.dir/subdir.2
     0:user:gozer:list_directory/read_data/add_file/write_data:file_inherit
         /inherit_only:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

以下示例标识了同时设置 file_inherit 和 dir_inherit 标志时所应用的文件和目录的 ACL。

在本例中,向用户 gozer 授予了继承用于新创建的文件和目录的读取、写入和执行权限:


# chmod A+user:gozer:read_data/write_data/execute:file_inherit/dir_inherit:allow 
test3.dir
# ls -dv test3.dir
drwxr-xr-x+  2 root     root           2 May 20 15:53 test3.dir
     0:user:gozer:list_directory/read_data/add_file/write_data/execute
         :file_inherit/dir_inherit:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

# touch test3.dir/file.3
# ls -v test3.dir/file.3
-rw-r--r--+  1 root     root           0 May 20 15:58 test3.dir/file.3
     0:user:gozer:write_data/execute:deny
     1:user:gozer:read_data/write_data/execute:allow
     2:owner@:execute:deny
     3:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     4:group@:write_data/append_data/execute:deny
     5:group@:read_data:allow
     6:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     7:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

# mkdir test3.dir/subdir.1
# ls -dv test3.dir/subdir.1
drwxr-xr-x+  2 root     root           2 May 20 15:59 test3.dir/subdir.1
     0:user:gozer:list_directory/read_data/add_file/write_data/execute
         :file_inherit/dir_inherit/inherit_only:allow
     1:user:gozer:add_file/write_data:deny
     2:user:gozer:list_directory/read_data/add_file/write_data/execute:allow
     3:owner@::deny
     4:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     5:group@:add_file/write_data/add_subdirectory/append_data:deny
     6:group@:list_directory/read_data/execute:allow
     7:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     8:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

在以下示例中,由于 group@ 和 everyone@ 的父目录的权限拒绝写入和执行权限,因此拒绝了用户 gozer 的写入和执行权限。缺省的 aclinherit 属性为 restricted,这意味着未继承 write_data 和 execute 权限。

在本例中,向用户 gozer 授予了继承用于新创建的文件的读取、写入和执行权限。但是,这些权限不会传播给该目录的后续内容。


# chmod A+user:gozer:read_data/write_data/execute:file_inherit/no_propagate:allow 
test4.dir
# ls -dv test4.dir
drwxr-xr-x+  2 root     root           2 May 20 16:02 test4.dir
     0:user:gozer:list_directory/read_data/add_file/write_data/execute
         :file_inherit/no_propagate:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

如以下示例所示,创建新子目录时,用户 gozer 对文件的 read_data/write_data/execute 权限不会传播给新的 sub4.dir 目录:


mkdir test4.dir/sub4.dir
# ls -dv test4.dir/sub4.dir
drwxr-xr-x   2 root     root           2 May 20 16:03 test4.dir/sub4.dir
     0:owner@::deny
     1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     2:group@:add_file/write_data/add_subdirectory/append_data:deny
     3:group@:list_directory/read_data/execute:allow
     4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     5:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

如以下示例所示,用户 gozer 对文件的 read_data/write_data/execute 权限将传播给新创建的文件:


# touch test4.dir/file.4
# ls -v test4.dir/file.4
-rw-r--r--+  1 root     root           0 May 20 16:04 test4.dir/file.4
     0:user:gozer:write_data/execute:deny
     1:user:gozer:read_data/write_data/execute:allow
     2:owner@:execute:deny
     3:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     4:group@:write_data/append_data/execute:deny
     5:group@:read_data:allow
     6:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     7:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow


示例 8–7 aclmode 属性设置为 passthrough 时的 ACL 继承

如以下示例所示,当 tank/cindys 文件系统的 aclmode 属性设置为 passthrough 时,用户 gozer 新创建的 file.4 继承应用于 test4.dir 目录的 ACL:


# zfs set aclmode=passthrough tank/cindys
# touch test4.dir/file.4
# ls -v test4.dir/file.4
-rw-r--r--+  1 root     root           0 May 20 16:08 test4.dir/file.4
     0:user:gozer:write_data/execute:deny
     1:user:gozer:read_data/write_data/execute:allow
     2:owner@:execute:deny
     3:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     4:group@:write_data/append_data/execute:deny
     5:group@:read_data:allow
     6:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     7:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

此输出说明对父目录 test4.dir 设置的 read_data/write_data/execute:allow:file_inherit/dir_inherit ACL 会传递给用户 gozer。



示例 8–8 aclmode 属性设置为 discard 时的 ACL 继承

如果将文件系统的 aclmode 属性设置为 discard,则目录的权限更改时,可能会废弃 ACL。例如:


# zfs set aclmode=discard tank/cindys
# chmod A+user:gozer:read_data/write_data/execute:dir_inherit:allow test5.dir
# ls -dv test5.dir
drwxr-xr-x+  2 root     root           2 May 20 16:09 test5.dir
     0:user:gozer:list_directory/read_data/add_file/write_data/execute
         :dir_inherit:allow
     1:owner@::deny
     2:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     3:group@:add_file/write_data/add_subdirectory/append_data:deny
     4:group@:list_directory/read_data/execute:allow
     5:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     6:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

如果以后决定要加强目录的权限,则会废弃非普通 ACL。例如:


# chmod 744 test5.dir
# ls -dv test5.dir
drwxr--r--   2 root     root           2 May 20 16:09 test5.dir
     0:owner@::deny
     1:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     2:group@:add_file/write_data/add_subdirectory/append_data/execute:deny
     3:group@:list_directory/read_data:allow
     4:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /execute/write_attributes/write_acl/write_owner:deny
     5:everyone@:list_directory/read_data/read_xattr/read_attributes/read_acl
         /synchronize:allow


示例 8–9 aclinherit 属性设置为 noallow 时的 ACL 继承

在以下示例中,设置了两个包含文件继承的非普通 ACL。一个 ACL 允许 read_data 权限,一个 ACL 拒绝 read_data 权限。此示例还说明了如何可在同一 chmod 命令中指定两个 ACE。


# zfs set aclinherit=noallow tank/cindys
# chmod A+user:gozer:read_data:file_inherit:deny,user:lp:read_data:file_inherit:allow 
test6.dir
# ls -dv test6.dir
drwxr-xr-x+  2 root     root           2 May 20 16:11 test6.dir
     0:user:gozer:read_data:file_inherit:deny
     1:user:lp:read_data:file_inherit:allow
     2:owner@::deny
     3:owner@:list_directory/read_data/add_file/write_data/add_subdirectory
         /append_data/write_xattr/execute/write_attributes/write_acl
         /write_owner:allow
     4:group@:add_file/write_data/add_subdirectory/append_data:deny
     5:group@:list_directory/read_data/execute:allow
     6:everyone@:add_file/write_data/add_subdirectory/append_data/write_xattr
         /write_attributes/write_acl/write_owner:deny
     7:everyone@:list_directory/read_data/read_xattr/execute/read_attributes
         /read_acl/synchronize:allow

如以下示例所示,创建新文件时,将废弃允许 read_data 权限的 ACL。


# touch test6.dir/file.6
# ls -v test6.dir/file.6
-rw-r--r--   1 root     root           0 May 20 16:13 test6.dir/file.6
     0:owner@:execute:deny
     1:owner@:read_data/write_data/append_data/write_xattr/write_attributes
         /write_acl/write_owner:allow
     2:group@:write_data/append_data/execute:deny
     3:group@:read_data:allow
     4:everyone@:write_data/append_data/write_xattr/execute/write_attributes
         /write_acl/write_owner:deny
     5:everyone@:read_data/read_xattr/read_attributes/read_acl/synchronize
         :allow

以缩写格式设置和显示 ZFS 文件的 ACL

可通过使用 14 个唯一字母表示权限的缩写格式来设置和显示 ZFS 文件的权限。表 8–2 和 表 8–3 列出了表示缩写权限的字母。

可以使用 ls -V 命令显示用于文件和目录的缩写 ACL 列表。例如:


# ls -V file.1
-rw-r--r--   1 root     root      206663 Jun 17 10:07 file.1
            owner@:--x-----------:------:deny
            owner@:rw-p---A-W-Co-:------:allow
            group@:-wxp----------:------:deny
            group@:r-------------:------:allow
         everyone@:-wxp---A-W-Co-:------:deny
         everyone@:r-----a-R-c--s:------:allow

以下介绍此缩写 ACL 输出:

owner@

拒绝属主对文件的执行权限 (x=execute)。

owner@

属主可以读取和修改文件的内容 (rw=read_data/write_data、p=append_data)。属主还可以修改文件的属性,如时间戳、扩展属性和 ACL (A=write_xattr、W=write_attributes 和 C=write_acl)。此外,属主还可以修改文件的拥有权 (o=write_owner)。

group@

拒绝组对文件的修改和执行权限 (write_data、p=append_data 和 x=execute)。

group@

授予组对文件的读取权限 (r=read_data)。

everyone@

拒绝非文件属主或非文件所属组成员执行或修改文件内容以及修改文件任何属性的权限(w=write_data、x=execute、p=append_data、A=write_xattr、W=write_attributes、C=write_acl 和 o=write_owner)。

everyone@

授予非文件属主或非文件所属组成员读取文件和文件属性的权限 (r=read_data、a=append_data、R=read_xattr、c=read_acl 和 s=synchronize)。synchronize 访问权限当前未实现。

与详细 ACL 格式相比,缩写 ACL 格式具有以下优点:

有关使用详细 ACL 格式的信息,请参见以详细格式设置和显示 ZFS 文件的 ACL。


示例 8–10 以缩写格式设置和显示 ACL

在以下示例中,普通 ACL 存在于 file.1 中:


# ls -V file.1
-rw-r--r--   1 root     root      206663 Jun 17 10:07 file.1
            owner@:--x-----------:------:deny
            owner@:rw-p---A-W-Co-:------:allow
            group@:-wxp----------:------:deny
            group@:r-------------:------:allow
         everyone@:-wxp---A-W-Co-:------:deny
         everyone@:r-----a-R-c--s:------:allow

在以下示例中,为用户 gozer 添加了对 file.1 的 read_data/execute 权限。


# chmod A+user:gozer:rx:allow file.1
# ls -V file.1
-rw-r--r--+  1 root     root      206663 Jun 17 10:07 file.1
        user:gozer:r-x-----------:------:allow
            owner@:--x-----------:------:deny
            owner@:rw-p---A-W-Co-:------:allow
            group@:-wxp----------:------:deny
            group@:r-------------:------:allow
         everyone@:-wxp---A-W-Co-:------:deny
         everyone@:r-----a-R-c--s:------:allow

为用户 gozer 添加相同权限的另一种方法是在特定位置(例如 4)插入新 ACL 项。这样,位于位置 4-6 的现有 ACL 将被下推。例如:


# chmod A4+user:gozer:rx:allow file.1
# ls -V file.1
-rw-r--r--+  1 root     root      206663 Jun 17 10:16 file.1
            owner@:--x-----------:------:deny
            owner@:rw-p---A-W-Co-:------:allow
            group@:-wxp----------:------:deny
            group@:r-------------:------:allow
        user:gozer:r-x-----------:------:allow
         everyone@:-wxp---A-W-Co-:------:deny
         everyone@:r-----a-R-c--s:------:allow

在以下示例中,向用户 gozer 授予了继承用于新创建的文件和目录的读取、写入和执行权限。


# chmod A+user:gozer:rwx:fd:allow dir.2
# ls -dV dir.2
drwxr-xr-x+  2 root     root           2 Jun 17 10:19 dir.2
        user:gozer:rwx-----------:fd----:allow
            owner@:--------------:------:deny
            owner@:rwxp---A-W-Co-:------:allow
            group@:-w-p----------:------:deny
            group@:r-x-----------:------:allow
         everyone@:-w-p---A-W-Co-:------:deny
         everyone@:r-x---a-R-c--s:------:allow

另外,还可以剪切 ls -V 输出中的权限和继承标志并将其粘贴到缩写的 chmod 格式中。例如,要将用户 gozer 对 dir.2 的权限和继承标志复制给用户 cindys,可将权限和继承标志 (rwx-----------:fd-----:allow) 复制并粘贴到 chmod 命令中,如下所示:


# chmod A+user:cindys:rwx-----------:fd----:allow dir.2
# ls -dV dir.2
drwxr-xr-x+  2 root     root           2 Jun 17 10:19 dir.2
       user:cindys:rwx-----------:fd----:allow
        user:gozer:rwx-----------:fd----:allow
            owner@:--------------:------:deny
            owner@:rwxp---A-W-Co-:------:allow
            group@:-w-p----------:------:deny
            group@:r-x-----------:------:allow
         everyone@:-w-p---A-W-Co-:------:deny
         everyone@:r-x---a-R-c--s:------:allow


示例 8–11 aclinherit 属性设置为 passthrough 时的 ACL 继承

将 aclinherit 属性设置为 passthrough 的文件系统会继承所有可继承 ACL 项,并且继承 ACL 项时不会对其进行任何修改。当此属性设置为 passthrough 时,会使用由可继承 ACE 确定的权限来创建文件。如果不存在影响权限的可继承 ACE,则会根据应用程序要求的权限设置权限。

以下示例使用缩写 ACL 语法来说明如何通过将 aclinherit 属性设置为 passthrough 来继承权限。

在本示例中,对 test1.dir 目录设置了 ACL 以强制继承。该语法会为新创建的文件创建 owner@、group@ 和 everyone@ ACL 项。新创建的目录会继承 @owner、group@ 和 everyone@ ACL 项。此外,目录会继承六个其他将 ACE 传播至新创建的目录和文件的 ACE。


# zfs set aclinherit=passthrough tank/cindys
# pwd
/tank/cindys
# mkdir test1.dir

# chmod A=owner@:rwxpcCosRrWaAdD:fd:allow,group@:rwxp:fd:allow,everyone@::fd:allow 
test1.dir
# ls -Vd test1.dir
drwxrwx---+  2 root     root           2 Jun 17 10:37 test1.dir
            owner@:rwxpdDaARWcCos:fd----:allow
            group@:rwxp----------:fd----:allow
         everyone@:--------------:fd----:allow

在此示例中,新创建的文件会继承指定由新创建的文件继承的 ACL。


# cd test1.dir
# touch file.1
# ls -V file.1
-rwxrwx---+  1 root     root           0 Jun 17 10:38 file.1
            owner@:rwxpdDaARWcCos:------:allow
            group@:rwxp----------:------:allow
         everyone@:--------------:------:allow

在本示例中,新创建的目录会继承用于控制对此目录访问权限的 ACE 以及用于将来传播到新创建目录的子级的 ACE。


# mkdir subdir.1
# ls -dV subdir.1
drwxrwx---+  2 root     root           2 Jun 17 10:39 subdir.1
            owner@:rwxpdDaARWcCos:fdi---:allow
            owner@:rwxpdDaARWcCos:------:allow
            group@:rwxp----------:fdi---:allow
            group@:rwxp----------:------:allow
         everyone@:--------------:fdi---:allow
         everyone@:--------------:------:allow

-di-- 和 f-i--- 项用于传播继承,在访问控制期间不会被考虑。在本示例中,会使用继承 ACE 不存在的另一目录中的普通 ACL 创建文件。


# cd /tank/cindys
# mkdir test2.dir
# cd test2.dir
# touch file.2
# ls -V file.2
-rw-r--r--   1 root     root           0 Jun 17 10:40 file.2
            owner@:--x-----------:------:deny
            owner@:rw-p---A-W-Co-:------:allow
            group@:-wxp----------:------:deny
            group@:r-------------:------:allow
         everyone@:-wxp---A-W-Co-:------:deny
         everyone@:r-----a-R-c--s:------:allow


示例 8–12 aclinherit 属性设置为 passthrough-x 时的 ACL 继承

当 aclinherit 属性设置为 passthrough-x 时,对于 owner@、group@ 或 everyone@ 设置,将使用执行 (x) 权限创建文件,但前提是在文件创建模式以及影响该模式的可继承 ACE 中设置了执行权限。

以下示例说明如何通过将 aclinherit 属性设置为 passthrough-x 来继承执行权限。


# zfs set aclinherit=passthrough-x tank/cindys

对 /tank/cindys/test1.dir 设置以下 ACL,以便针对 owner@、group@ 和 everyone@ 设置为文件提供可执行 ACL 继承。


# chmod A=owner@:rwxpcCosRrWaAdD:fd:allow,group@:rwxp:fd:allow,everyone@::fd:allow test1.dir
# ls -Vd test1.dir
drwxrwx---+  2 root     root           2 Jun 17 10:41 test1.dir
            owner@:rwxpdDaARWcCos:fd----:allow
            group@:rwxp----------:fd----:allow
         everyone@:--------------:fd----:allow

使用请求的权限 0666 创建文件 (file1),但生成的权限为 0660。没有继承执行权限的原因是,创建模式未请求该权限。


# touch test1.dir/file1
# ls -V test1.dir/file1
-rw-rw----+  1 root     root           0 Jun 17 10:42 test1.dir/file1
            owner@:rw-pdDaARWcCos:------:allow
            group@:rw-p----------:------:allow
         everyone@:--------------:------:allow

接下来,在 testdir 目录下使用 cc 编译器来生成名为 t 的可执行文件。


# cc -o t t.c
# ls -V t
-rwxrwx---+  1 root     root        7396 Jun 17 10:50 t
                 owner@:rwxpdDaARWcCos:------:allow
                 group@:rwxp----------:------:allow
              everyone@:--------------:------:allow

生成的权限为 0770,这是因为 cc 请求了权限 0777,这导致从 owner@、group@ 和 everyone@ 条目继承了执行权限。