跳过导航链接 | |
退出打印视图 | |
![]() |
手册页第 5 部分:标准、环境和宏 Oracle Solaris 11.1 Information Library (简体中文) |
- 访问控制列表
访问控制列表 (Access control list, ACL) 是自主访问控制机制,可授予和拒绝对文件和目录的访问权限。Solaris 发行版本中支持两种不同的 ACL 模型:POSIX 样式的 ACL 和 NFSv4 ACL。
UFS 文件系统支持较早的 POSIX 样式的模型。该模型基于已撤销的从未进行标准化的 ACL POSIX 规范。POSIX 委员会后来撤销了该模型。
另一个模型基于 NFSv4 工作组的标准,是 Internet 工程任务组 (Internet Engineering Task Force, IETF) 批准的标准。ZFS 文件系统使用 NFSv4 模型,提供比 POSIX 样式的模型更丰富的语义和更精细的权限功能。
POSIX 样式的 ACL 为 Solaris 发行版中的基本 UNIX 文件权限提供备用安全机制。其目的是进一步限制对文件和目录的访问或扩展特定用户的权限。ACL 可用于更改标准所有者、组和文件模式的其他类位的权限。ACL 可为其他用户和组授予对文件的访问权限。目录还可以有一种称为缺省 ACL 的特殊 ACL,用于定义将由目录后代继承的 ACL 条目。POSIX 样式的 ACL 有一个称为掩码的 ACL 条目。该掩码定义可向其他用户和组条目授予的最大权限。每当创建文件或通过 chmod(1) 或 chmod(2) 更改其模式时,就会重新计算掩码。该掩码将重新计算为传递到 chmod(2) 的模式中定义的组权限。
POSIX 样式的 ACL 模型使用传统 UNIX 权限的标准 rwx 模型。
ACL 的表示方式如下:
acl_entry[,acl_entry]...
每个 acl_entry 都包含一个 ACL 条目。ACL 条目由两个或三个冒号分隔的 (:) 字段表示。
如果 uid 为空,则它表示文件所有者。
如果 gid 为空,则它表示所属组。
表示文件的其他类。
定义要分发的最大权限。
例如,要为用户授予 joe 读写权限,则 ACL 条目应指定为:
user:joe:rw-
NFSv4 ACL 总体上基于 Windows NT ACL 模型。NFSv4 ACL 提供比 POSIX 样式的 ACL 更丰富的 ACL 模型。
NFSv4 和 POSIX 样式的 ACL 之间的主要区别如下:
NFSv4 ACL 提供比 rwx 模型更精细的权限。
NFSv4 ACL 允许同时有 ALLOW 和 DENY 条目。
NFSv4 ACL 提供一组丰富的继承语义。POSIX ACL 也具有继承性,但使用 NFSv4 模型,您可以控制以下继承功能:
继承同时级联到文件和目录还是仅级联到文件和目录之一。
对于目录,您可以指示将继承应用于目录本身,应用于一个级别的子目录或级联到目录的所有子目录。
NFSv4 ACL 提供用于挂钩到系统的审计迹的机制。目前,Solaris 不支持此机制。
NFSv4 ACL 使管理员能够指定检查 ACL 条目的顺序。使用 POSIX 样式的 ACL 时,文件系统会按照明确定义且访问控制严格的检查顺序对 ACL 条目进行重新排序。
POSIX 样式的 ACL 语义可通过 NFSv4 ACL 来实现。但是,只有一些 NFSv4 ACL 可以转换为等效的 POSIX 样式的 ACL。
可采用三种不同 chmod ACL 格式指定权限:详细、紧凑或位置。详细格式使用字词指示用正斜杠 (/) 字符分隔权限。紧凑格式使用权限字母标识权限,位置格式使用权限字母标识权限,或使用连字符 (-) 标识没有任何权限。
详细模式的权限以及其括号中的缩写形式(紧凑和位置模式)如下所述:
读取文件数据的权限
列出目录内容的权限。
在文件的偏移范围中的任意位置修改文件数据的权限。这包括增加文件大小或写入任意偏移的能力。
向目录中添加新文件的权限。
修改文件数据的能力,但仅从 EOF 开始。当前不支持此权限。
在目录中创建子目录的权限。
读取文件的扩展属性或在扩展的属性目录中执行查找的能力。
创建扩展属性或向扩展属性目录进行写入的能力。
执行文件的权限。
读取文件的基本属性(非 ACL)的能力。基本属性将视为 stat 级别属性。允许此访问掩码位意味着实体可以执行 ls(1) 和 stat(2)。
将与文件或目录关联的时间更改为任意值的权限。
删除文件的权限。
删除目录中的文件的权限。
读取 ACL 的权限。
写入 ACL 的权限,或执行 chmod(1) 或 setfacl(1) 的能力。
在具有同步读写的服务器上本地访问文件的权限。当前不支持此权限。
NFSv4 支持以下继承标志:
继承到目录中所有新创建的文件。
继承到目录中所有新创建的目录。
放置到目录中,但不应用于目录自身,只应用于新创建的文件和目录。此标志需要 file_inherit 和/或 dir_inherit 以指示要继承的内容。
放置在目录中并指示只能继承一个树级别的 ACL 条目。此标志需要 file_inherit 和/或 dir_inherit 以指示要继承的内容。
指示在访问成功时是否应该启动报警或审计记录。与审计/报警 ACE 类型一起使用。
指示在访问失败时是否应该启动报警或审计记录。与审计/报警 ACE 类型一起使用。
继承了 ACE。
未授予权限。
使用以下语法表示 NFSv4 ACL:
acl_entry[,acl_entry]... owner@:<perms>[:inheritance flags]:<allow|deny> group@:<perms>[:inheritance flags]:<allow|deny> everyone@:<perms>[:inheritance flags]:<allow|deny> user:<username>[:inheritance flags]:<allow|deny> group:<groupname>[:inheritance flags]:<allow|deny>
文件所有者
组所有者
特定用户的权限
特定组的权限
权限和继承标志由 / 字符分隔。
ACL 规范示例:
user:fred:read_data/write_data/read_attributes:file_inherit:allow owner@:read_data:allow,group@:read_data:allow,user:tom:read_data:deny
使用紧凑 ACL 格式时,将通过使用指示权限的 14 个唯一字母来指定权限。
使用位置 ACL 格式时,将权限指定为类似于 ls -V 格式的位置参数。连字符 (-) 指示在该位置未授予任何权限,可以忽略它,只需指定必需的字母。
将按照位置表示法中指定的顺序列出上面的字母。
使用这些字母,您可以按以下等效方式指定权限。
user:fred:rw------R------:file_inherit:allow
也可以删除 - 使权限紧挨在一起。
user:fred:rwR:file_inherit:allow
还可按更紧凑的方式指定继承标志,如下所示:
user:fred:rwR:f:allow user:fred:rwR:f------:allow
Solaris 命令接口支持对 ACL 进行操作。以下 Solaris 实用程序适应两种 ACL 模型:
chmod 实用程序已得到增强,允许设置和删除 ACL。通过扩展 symbolic-mode 参数以支持 ACL 操作可实现此目的。有关详细信息,请参见 chmod(1)。
压缩文件时,与原始文件关联的任何 ACL 将与压缩文件一起保留。
缺省情况下,cp 将忽略 ACL,除非指定了 -p 选项。指定 -p 时,将保留所有者和组 ID、权限模式、修改和访问时间、ACL 和扩展属性(如果适用)。
指定 -P 选项时将保留 ACL。
指定 -acl 标志时查找包含 ACL 的文件。
缺省情况下,ls 不显示 ACL 信息。指定 -v 选项时,将显示文件的 ACL。
移动文件时,将随重命名的文件携带所有属性。跨文件系统边界移动文件时,将复制 ACL。如果不能复制 ACL 信息,移动将失败,并且不会删除源文件。
打包文件时,与原始文件关联的任何 ACL 将与打包文件一起保留。
rcp 已增强为支持复制。仅当远程主机支持 ACL 时,才保留文件的 ACL。
指定 -p 选项时将保留 ACL。
解压缩包含 ACL 的文件时,解压缩的文件会保留 ACL 信息。
在程序级别访问文件系统 ACL 所需的主要接口是 acl_get() 和 acl_set() 函数。这些函数同时支持 POSIX 样式的 ACL 和 NFSv4 ACL。
int acl_get(const char *path, int flag, acl_t **aclp); int facl_get(int fd, int flag, acl_t **aclp);
acl_get(3SEC) 和 facl_get(3SEC) 函数可在其名称由路径给定或由打开文件描述符 fd 引用的文件上检索 ACL。标志参数指定是否应检索普通 ACL。如果标志参数等于 ACL_NO_TRIVIAL,则将仅检索非普通 ACL。将在 aclp 参数中返回 ACL。
void acl_free(acl_t *aclp)s;
acl_free() 函数可释放为参数 aclp; 分配的内存。
int acl_set(const char *path, acl_t *aclp); int facl_set(int fd, acl_t *aclp);
acl_set(3SEC) 和 facl_get(3SEC) 函数用于在其名称由路径给定或由打开文件描述符 fd 引用的文件上设置 ACL。aclp 参数指定要设置的 ACL。在目标文件系统支持 NFSv4 ACL 时,acl_set(3SEC) 可将 POSIX 样式的 ACL 转换为 NFSv4 ACL。当尝试在 POSIX 样式的 ACL 支持的文件系统上设置 NFSv4 ACL 时,将不执行任何转换。
int acl_trivial(const char *path);
acl_trivial() 函数用于确定文件是否具有普通 ACL。ACL 是否普通取决于 ACL 的类型。如果 POSIX 样式的 ACL 具有的条目数多于 MIN_ACL_ENTRIES,则它是非普通的。如果 NFSv4/ZFS 样式的 ACL 具有除 owner@、group@ 和 everyone@ 之外的条目,具有继承标志集,或未按照符合 POSIX 访问控制要求的方式进行排序,则它是非普通的。
int acl_strip(const char *path, uid_t uid, gid_t gid, mode_t mode);
acl_strip() 函数可从文件中删除所有 ACL,并将其替换为基于传入的参数模式的普通 ACL。在替换 ACL 后,文件所有者和组将设置为 uid 和 gid 参数中指定的值。
int acl_fromtext(const char *path, acl_t **aclp); char *acl_totext(acl_t *aclp, int flags);
acl_text() 函数可将 aclp 指向的内部 ACL 表示形式转换为外部表示形式。有关外部表示形式的详细信息,请参见“描述”部分。
acl_fromtext() 函数可将外部表示形式转换为内部表示形式。有关外部表示形式的详细信息,请参见“描述”部分。
以下示例演示 API 如何用于对 ACL 执行基本操作。
示例 1 检索和设置某个 ACL
使用以下命令可检索某个 ACL 并在另一个文件上设置它:
error = acl_get("file", ACL_NO_TRIVIAL, &aclp); if (error == 0 && aclp != NULL) { error = acl_set("file2", aclp) acl_free(aclp); } ...
示例 2 检索和设置任何 ACL
使用以下命令可检索任何 ACL(包括普通 ACL),并在另一个文件上设置它:
error = acl_get("file3", 0, &aclp); if (error == 0) { error = acl_set("file4", aclp) acl_free(aclp); } ...
示例 3 确定文件是否具有普通 ACL
使用以下命令可确定文件是否具有普通 ACL:
istrivial = acl_trivial("file") if (istrivial == 0) printf("file %s has a trivial ACL\n", file); else printf("file %s has a NON-trivial ACL\n", file); ...
示例 4 从文件中删除所有 ACL
使用以下命令可从文件中删除所有 ACL,并设置新模式、所有者和组:
error = acl_strip("file", 10, 100, 0644); ...
chgrp(1)、chmod(1)、chown(1)、cp(1)、cpio(1)、find(1)、ls(1)、mv(1)、tar(1)、setfacl(1)、chmod(2)、acl(2),stat(2),acl_get(3SEC)、aclsort(3SEC)、acl_fromtext(3SEC)、acl_free(3SEC)、acl_strip(3SEC)、acl_trivial(3SEC)