chown
该实用程序的 POSIX 规范其中提到理由部分关于chown user:group
语法(以前chown user.group
)(强调我的):
指定所有者和组的 4.3 BSD 方法包含在 POSIX.1-2008 的本卷中,因为:
- 在某些情况下,使用 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() 函数可能会失败,以及在什么系统上?
答案1
这Microsoft Interix Unix 子系统 (现已退休)因为它的 NT 内核对用户和组权限的处理与其他一些内核略有不同:
用户和组信息存储在安全访问数据库。用户和组都存储在同一个数据库中,但组和用户名必须唯一;任何组都不能拥有用户名,反之亦然。(该数据库取代了UNIX 中的
/etc/passwd
和/etc/groups
文件。)用户和组是使用适当的 Windows 方法创建的(用户管理器、Active Directory 用户和计算机或本地用户和组)或使用 Win32net user
命令。(用于创建和删除用户的示例 shell 脚本包含在目录中/usr/examples/admin
。)用户可以属于多个组。
这里有一些更具体的手册摘录:
在 Windows 中,用户或组都可以拥有对象。这与 UNIX 不同,在 UNIX 中,只有用户拥有对象。
Windows 使用安全标识符在内部识别所有用户和组(安全识别码)。哈希算法生成唯一的 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
...
指示系统调用的 POSIX 语义是否
chown(2)
有效...
显然,如果参数设置为值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
能力,其行为略有不同。
并作为你在2003年指出:
请注意,至少在 HPUX 上,您可以更改文件的所有者(
root
例如)即使您不是特权用户...
...这取决于配置setprivgroup
参数。
在任何情况下,非 root 用户可以操纵文件权限,这是可以想象的,如理由在您的问题中引用,用户可能chown
拥有该用户拥有的文件,以便该文件由另一个用户拥有。如果文件的组所有权和chown
用户的组不一致,则用户将无法再修改该文件。
在这种情况下chown
然后 chgrp
将会失败,因为用户将不再有权更改该文件的权限,而chown user:group
- 只要团体是用户自己之中的——就会成功。
有大概许多其他利基情况可能会产生类似的结果,其中可能包括目录黏和/或设置gid位、文件系统和/或特定于实现的访问控制列表。这个线程例如,很有趣。无数的排列远远超出了我自己微弱的掌握——这就是为什么这个答案被维基百科。如果您正在阅读本文,您相信它值得改进,并且您相信您知道如何 -请这样做。
还有大量关于文件权限、树遍历和符号链接的各种可能影响的文档,这些影响可能会导致递归-R
应用程序出现类似的失败chown
:
从POSIX XRAT章节标题第三和第四域:
通常,指定文件层次结构遍历选项的用户希望在单个物理层次结构上进行操作,因此可能引用层次结构之外的文件的符号链接将被忽略。例如,chownowner file 与指定了 -R 选项的同一命令是不同的操作。在此示例中,此处描述了命令的行为
chown
owner
file
,而命令的行为chown -R
所有者文件在第三和第四域中描述。...默认逻辑行走存在安全问题。历史上,命令
chown -R
用户文件对于超级用户来说是安全的,因为设定值和设置gid当文件的所有权发生更改时,位会丢失。如果遍历是合乎逻辑的,则更改所有权将不再安全,因为用户可能已插入指向树中任何文件的符号链接。同样,这将需要在执行层次结构遍历的命令中添加一个选项,以不通过符号链接间接遍历,并且执行递归遍历的历史脚本将立即成为安全问题。虽然这主要是系统管理员的问题,但最好不要为不同类别的用户设置不同的默认值。...
在 4.3 BSD 中,
chgrp
在树遍历期间更改了符号链接的组,而不是目标。 4.4 BSD 中的符号链接没有所有者、组、模式或其他标准 UNIX 系统文件属性。
来自 POSIXchgrp
正确的页面有 this 指向可能不完整的-R
递归操作,或者至少指向什么用过的成为:
System V 和 BSD 版本使用不同的退出状态代码。一些实现使用退出状态作为发生的错误数量的计数;这种做法是行不通的,因为它可能会溢出有效退出状态值的范围。标准开发人员选择通过仅指定 0 和 >0 作为退出值来屏蔽这些。
答案2
假设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 变体会违反这些假设,它们看起来相当安全。
这句话看起来像是委员会中的某个人在经过几个小时的辩论后疲惫不堪时所说的话ps
——或者秘书错误地转录了——并且在审查过程中没有人发现。毕竟,还有其他充分的理由允许自动更改用户和组,包括 POSIX 基本原理中也引用的性能原因,以及原子性(啊,如果只有一个调用来更改所有权和权限)。
假设 3 可能错误的情况是在一个系统上,进程可以获得更改文件所有者的能力,但前提是他们对文件具有写权限。虽然有些现实,但我不知道有哪个系统是这种情况。然后,chgrp
从既不作为 root 也不作为拥有该文件的用户运行的进程中的一个组可能会使该文件在以后的chown
.
对于递归调用,存在一些边缘情况:当单次传递成功时,整个传递chgrp
后跟整个传递可能会失败。chown
这不是一个很有说服力的论点,因为它涉及所有者无权遍历的目录,并且想要防止所有此类情况的应用程序无论如何都需要摆弄权限。尽管如此,它在技术上满足了这一基本原理的条件。假设正在运行的进程具有有效的用户alice
、有效的组staff
以及任意更改文件所有者的能力(不仅仅是放弃它们;一些unix变体具有这样的能力,尽管很少授予非root进程)。
$ ls -ld dir dir/file
d---rwx--- 2 charlie staff 1024 Apr 1 1970 dir
drw-rw---- 2 charlie staff 42 Apr 1 1970 file
$ chgrp -R students dir
$ chown -R bob dir
chown: dir: permission denied