该chown
实用程序的 POSIX 规范在其基本原理部分中提到了有关chown user:group
语法(以前的chown user.group
)(强调我的):
POSIX.1-2008 的这一卷中包含了 4.3 BSD 指定所有者和组的方法,因为:
- 在某些情况下,使用 chgrp 和 chown(仅更改用户 ID)实用程序无法实现所需的结束条件。(如果当前所有者不是所需组的成员,并且所需所有者不是当前组的成员,则除非所有者和组同时更改,否则 chown() 函数可能会失败。)
我认为user:group
语法是一个方便的东西。现在,上述暗示有事情可以做chown user:group
,你不能用chgrp group; chown user
现在那个文本对我来说没有意义。在 4.3BSD 中,只有 root 可以更改文件的所有者,因此在任何情况下他都可以做什么没有限制。
SysV 和其他一些系统允许(或曾经允许)文件的所有者将文件的用户和组更改为任何内容,但即使在这些系统中,上面的文本对我来说也没有意义。好的,如果有人做了 a chown someone-else the-file
,chgrp something-else the-file
之后就不能再做,因为他不再是文件的所有者,但是没有什么可以阻止他/她做第chgrp
一个(保持文件的所有者)和chown
之后的事情,这不是上面的文字正是说。
我不明白什么和所需的所有者不是当前组的成员与问题有什么关系。
那么在什么情况下chown() 函数可能会失败,除非所有者和组同时更改,以及在什么系统上?
在微软的Interix的Unix子系统 (现已退休),其NT内核的处理方式略有不同与用户和组权限比其他一些事情:
用户和组信息存储在安全访问数据库中。用户和组都存储在同一个数据库中,但组和用户名必须是唯一的;任何组都不能有用户名,反之亦然。(此数据库取代了UNIX 中的
/etc/passwd
和/etc/groups
文件。)使用适当的 Windows 方法(用户管理器、Active Directory 用户和计算机或本地用户和组)或使用 Win32net user
命令创建用户和组。(用于创建和删除用户的示例 shell 脚本包含在目录中/usr/examples/admin
。)用户可以属于多个组。
以下是一些更具体的手册摘录:
在 Windows 中,用户或组都可以拥有一个对象。这与 UNIX 不同,在 UNIX 中只有用户拥有一个对象。
Windows 通过使用安全标识符(SID) 在内部识别所有用户和组。散列算法生成唯一的 SID 值;没有两个用户或组具有相同的 SID。
有权访问对象的用户和组由其 SID 标识。Windows 可以保护的所有对象都有一个自由访问控制列表 (DACL),它由称为访问控制条目 (ACE) 的单独条目组成。ACE 包括两条重要信息:用户或组 SID,以及单个用户或组对对象的访问权限的描述。
...更改文件的组 ID ...调用 chgrp(1) 的用户必须属于指定的组并且是文件的所有者,或者具有适当的权限。
...所有者和组操作数都是可选的;但是,必须指定一个。如果指定了组操作数,则它前面必须有一个冒号 (:)。
所有者可以通过数字用户 ID 或用户名指定。如果用户名也是数字用户 ID,则将操作数用作用户名。组可以是数字组 ID 或组名称。如果组名也是数字组 ID,则操作数用作组名。
出于安全原因,文件的所有权只能由具有适当权限的进程更改。
正如我所读到的,这意味着如果您的用户帐户属于具有足够权限来修改该组拥有的文件权限的 Windows 组,则可以有效地chgrp
将该文件超出您的用户帐户的控制范围。与使用chown
显式user:group
参数相比,这意味着更少的控制。在没有申报的可能性,这方面user:
和 :group
你永远无法达到相同的结果并非如此。
这是一个详细介绍 Interix 如何与 Windows ACL 交互的链接,重点介绍这些知识如何应用于其他 Unix 变体上的 Samba 文件系统。
这是一个现在已过时的Solaris 文档的链接,该文档描述了该可调参数rstchown
...
指示
chown(2)
系统调用的 POSIX 语义是否有效...
显然,如果参数设置为0
...
...关闭 POSIX 语义会打开各种安全漏洞的可能性。它还打开了用户将文件的所有权更改为另一个用户并且在没有用户或系统管理员干预的情况下无法取回文件的可能性。
这样的选项不会使 Solaris 的POSIX 一致性失效。仅仅因为它是一个选项,它就符合标准:
尽管符合 POSIX.1-2008 的所有实现都支持下面描述的所有功能,但可能存在系统相关或文件系统相关的配置过程,可以删除或修改 这些功能中的任何或全部。如果需要严格遵守,则不应进行此类配置。
以下符号常量应定义为 -1 以外的值。如果常量定义为零,则应用程序应使用
sysconf()
、pathconf()
、 或fpathconf()
函数或getconf
实用程序来确定当时系统上存在哪些功能或相关的特定路径名。_POSIX_CHOWN_RESTRICTED
的使用
chown()
仅限于具有适当权限的进程,并且只能将文件的组 ID 更改为进程的有效组 ID 或其补充组 ID 之一。
该chown()
系统的功能-这是记录的系统调用由双方提出chown
和chgrp
shell实用程序-被指定失败的原因很多。他们之中:
EACCES
对路径前缀的组件拒绝搜索权限。
ELOOP
在解析路径参数期间遇到的符号链接中存在循环。
EPERM
有效的用户 ID 与文件的所有者不匹配,或者调用进程没有适当的权限并且_POSIX_CHOWN_RESTRICTED表示需要此类权限。
然而,向非 root 用户授予权限修改权限的行为从来都不是 Solaris 独有的。有非常出色的-如果有些过时-在UNIX文件权限覆盖该论坛的帖子中,作者指出:
最初,Unix 允许文件所有者赠送文件。文件的所有者可以将所有者更改为其他人。非 root 用户无法撤消此操作... BSD [后来]
chown
从非 root 用户中删除...[部分原因是]...它实现了磁盘配额,可以限制多少磁盘空间用户可以在文件系统中...顽皮的用户可以放弃大文件以偷偷超过配额。今天,很难说非 root 用户是否可以
chown
创建文件。许多版本的 Unix 都允许这两种行为......
另一个不错的 - 并且是最近的 -邮件列表帖子引用了这一点并继续:
大多数操作系统的默认设置
chown
仅限于 root。并且大家一致认为,出于安全考虑,它应该保持这种状态。如果非 root 用户确实更改了文件的所有者并且任何执行位打开,则必须清除SUID
和SGID
位。这可能会发生,也可能不会发生root
。我认为最后一段说得很好。
那篇文章还提到
CAP_CHOWN
在 Linux 上控制该设施(应该只影响POSIX_CHOWN_RESTRICTED
行为)。还有CAP_FOWNER
能力,这在行为上有点不同。
请注意,至少在 HPUX 上,即使您不是特权用户,您也可以更改文件的所有者(
root
例如) ...
...这取决于配置setprivgroup
参数。
在非 root 用户可以操作文件权限的任何情况下,如您的问题中引用的基本原理所述,可以想象用户可能chown
拥有该用户拥有的文件,因此该文件归另一个用户所有。如果文件的组所有权和chown
ing 用户的组不一致,则用户将无法再修改该文件。
在这种情况下chown
,然后 chgrp
将失败,因为用户将不再有权限修改该文件的权限,而chown user:group
-只要组是其中用户自己-会成功。
还有可能是许多其他小众的情况下可能导致类似的,其中可能包括目录粘性和/或setgid的位,文件系统和/或实现特定的访问控制列表。例如,这个线程很有趣。无数的排列远远超出了我自己无力的掌握 - 这就是为什么这个答案被维基。如果您正在阅读本文,您就会相信它值得改进,并且您相信自己知道如何做——请这样做。
还有关于文件权限、树遍历和符号链接的各种可能影响的大量文档,这些影响可能会在此处对-R
递归chown
应用程序造成类似的失败:
从POSIX XRAT部分标题为第三和第四域:
通常,指定文件层次遍历选项的用户希望在单个物理层次上进行操作,因此忽略可能引用层次外文件的符号链接。例如,chown owner file 与指定了 -R 选项的同一命令是不同的操作。在这个例子中,命令的行为在
chown
owner
file
这里描述,而命令chown -R
所有者文件的行为在第三和第四域中描述。...默认为逻辑行走存在安全问题。从历史上看,命令
chown -R
用户文件对超级用户来说是安全的,因为当文件的所有权更改时setuid和setgid位丢失了。如果遍历是合乎逻辑的,更改所有权将不再安全,因为用户可能已插入指向树中任何文件的符号链接。同样,这将需要在执行层次遍历的命令中添加一个选项,而不是通过符号链接进行间接遍历,并且执行递归遍历的历史脚本将立即成为安全问题。虽然这主要是系统管理员的问题,但最好不要为不同类别的用户设置不同的默认值。...
在 4.3 BSD 中,
chgrp
在树遍历期间更改了符号链接的组,而不是目标。4.4 BSD 中的符号链接没有所有者、组、模式或其他标准 UNIX 系统文件属性。
从chgrp
正确的 POSIX页面中可以看出,这表明可能存在不完整的-R
递归操作,或者至少指出了过去的情况:
System V 和 BSD 版本使用不同的退出状态代码。一些实现使用退出状态作为发生错误数量的计数;这种做法是行不通的,因为它可能会溢出有效退出状态值的范围。标准开发人员选择通过仅指定 0 和 >0 作为退出值来屏蔽这些。
假设1:判断是否成功的规则chown
独立地检查目标用户和组部分,即它们的形式user_condition(target_uid, other_environment_parameters) && group_condition(target_gid, other_environment_parameters)
。
假设2:chown(file, -1, -1)
成功。
假设3:判断是否成功的规则与chown
文件当前属于哪个组无关。
推论:如果chown(file, uid, gid)
会成功,那么也会成功chown(file, -1, gid) && chown(file, uid, -1)
。
我不知道有哪个 Unix 变体会违反这些假设,它们看起来相当安全。
\n\n这句话看起来像是委员会中的某个人在经过几个小时的辩论后疲倦时所说的话ps
\xe2\x80\x94 或秘书错误转录\xc2\xa0\xe2\ x80\x94 并且在审查期间没有人发现。毕竟,还有其他充分的理由允许自动更改用户和组,包括 POSIX 基本原理中也引用的性能原因,以及原子性(啊,如果只有一个调用来更改所有权和权限)。
假设 3 可能错误的情况是在一个系统上,进程可以获得更改文件所有者的能力,但前提是他们对文件具有写权限。虽然有些现实,但我不知道有哪个系统是这种情况。然后,chgrp
从既不作为 root 也不作为拥有该文件的用户运行的进程中的一个组可能会使该文件在以后的chown
.
对于递归调用,存在一些边缘情况:当单次传递成功时,整个chgrp
传递 后跟整个传递可能会失败。chown
这不是一个很有说服力的论点,因为它涉及所有者无权遍历的目录,并且想要防止所有此类情况的应用程序无论如何都需要摆弄权限。尽管如此,它在技术上满足了这一基本原理的条件。假设正在运行的进程具有有效的用户alice
、有效的组staff
以及任意更改文件所有者的能力(不仅仅是放弃它们;一些unix变体具有这样的能力,尽管很少授予非根进程)。
$ ls -ld dir dir/file\nd---rwx--- 2 charlie staff 1024 Apr 1 1970 dir\ndrw-rw---- 2 charlie staff 42 Apr 1 1970 file\n$ chgrp -R students dir\n$ chown -R bob dir\nchown: dir: permission denied\n
Run Code Online (Sandbox Code Playgroud)\n