从https://unix.stackexchange.com/a/18290/674
内核视图
从概念上讲,进程属于三组组。每组都是下一组的子集。
- 作为进程默认组的单个组,该进程创建的文件将属于该组。
- 被检查的组的集合当组需要打开文件的权限时。
- 组的集合以额外权限运行的进程可以利用。
由于历史原因,这些集合分别是:
- 这有效组ID (如);
- 有效组 ID 加上补充组 ID;
- 以上所有加上真实组ID 和已保存的集合组 ID。
问题:
第 3 点中的“以进程可以利用的额外权限运行的进程”是什么情况?
这种情况与第2点中的“当组需要打开文件的权限时”的情况不同吗?
一般情况下和第 2 点中的“补充组 ID”是否分别包括主要组 ID?
通过“一般”,我的意思是我注意到的输出
id
包括以下主要组和补充组groups=
,而 https://unix.stackexchange.com/a/18203/674说“每个用户可以属于多个补充组 - 这些组列在id
输出的末尾。”那么我想知道主组也是辅助组吗?
谢谢。
答案1
特别是在 Linux 中,如今,“以进程可以利用的额外权限运行的进程”是这样的进程:
CAP_SETGID
“在其用户命名空间中具有该功能”。请注意,这三点的介绍指出“每个集合都是下一个集合的子集”,因此,是的,第 3 点中描述的集合在概念上与第 2 点中描述的集合不同。
id
打印有效的群体,而非主要群体;您可以使用 更改您的有效组newgrp
。主要组是默认的真实/有效组。在 Linux 上,getgroups
' 联机帮助页提到“未指定返回列表中是否包含调用进程的有效组ID”,因此补充组不一定包含主组。
还是专门考虑Linux,值得一读联机credentials
帮助页。
答案2
鉴于不同概念的数量,我发现通过实际示例更容易学习它们。
像用户空间 NFS 服务器这样的程序代表通过网络连接的特定用户。例如,当代表特定用户打开文件时,他们会临时更改其有效用户和组 ID。他们能够切换回来,因为他们在“保存集”或“真实”UID 和 GID 中仍然拥有特权 UID 和 GID。
我最近了解到这fusermount
是执行此操作的程序的另一个示例。它必须是 set-uid root 才能挂载文件系统,但它希望以原始用户身份执行权限检查,例如在读取配置文件时,以及到达作为挂载点传递的目录时。至少,它必须像这样改变它的UID。如果这个程序也被set-gid,那么它也必须改变它的GID。 fusermount
不需要安装为 set-gid,但代码无论如何都会更改其有效 GID。它不需要更多的代码,至少我希望它不会引起任何问题:-)。
页面man
提到setfsgid()
这个例子时说
对 setfsuid() 和 setfsgid() 的显式调用通常仅由诸如 Linux NFS 服务器之类的程序使用,这些程序需要更改用于文件访问的用户和组 ID,而无需相应更改真实有效的用户和组 ID
[...]
添加文件系统用户 ID 属性是为了允许进程出于文件权限检查的目的更改其用户 ID,同时又不会容易接收不需要的信号。自 Linux 2.0 起,信号权限处理有所不同(请参阅kill(2)),因此进程更改可以更改其有效用户 ID,而不会容易受到来自不需要的进程的信号的影响。因此,现在不需要 setfsuid(),在新应用程序中应该避免使用(setfsgid(2) 也是如此)。
即这些程序的当前版本将使用 setresuid() 和 setresgid() 暂时更改其有效 UID 和 GID。