bash 如何将用户组传递给子进程?

bash 如何将用户组传递给子进程?

众所周知,如果我将自己添加到一个新组,则直到我注销并重新登录后,该更改才会反映出来:

$ sudo adduser me newgroup
$ groups
me sudo
$ groups me
me sudo newgroup
$

这种奇怪的行为是因为groups由 shell 解释并且不显示新的组成员身份。但groups me实际上是引用/etc/group,因此显示了新的成员资格。

但我觉得奇怪的是,新的 shell 没有注意到这个变化:

$ bash
$ groups
me sudo

据我所知,反映新组成员资格的方法是 (1)newgrpsgsu(2) 注销并重新登录。

因此bash必须以某种方式将组列表传递给其子级。它不在环境中(我尝试过printenv),也不在内核的task_struct中(只有gid、egid、sgid和fsgid)。

我不知道怎么办。

答案1

组由进程从其父进程继承。 Bash 在这件事上别无选择。以 root 身份运行的进程可以根据请求获取新的补充组;不以 root 身份运行的进程只能放弃补充组。

不带参数的命令groups返回它自己的组列表(从其父级继承):真实组、有效组和补充组。该命令在用户和组数据库中group SOMEUSER查找关联的组。SOMEUSER

登录时,在登录过程从根用户切换到目标用户之前,作为登录过程的一部分,根据用户和组数据库分配组。命令newgrpsusg能够在运行时获取额外的组,因为它是设定值根;他们的代码是以这样的方式编写的:他们只会授予用户在登录时将被授予的组(除了 root 可以获得它想要的任何组)。

在Linux内核中,进程的UID和GID被记录在struct cred。补充组位于group_info指向一个的字段中struct group_info其中包含一个组 ID 数组。

答案2

这些组是在登录期间在删除权限之前分配的。你的 shell 不能简单地为自己分配新的组,否则它作为一个安全系统将毫无用处;进程所属的组由内核维护。查看cat /proc/$$/status示例的输出并查看 Groups: 行;这是您的 shell 所在组的明确列表($$ 是 shell 进程 ID 的快捷方式)。

groups username命令将查看 /etc/groups (如您所说)并仅显示用户配置所属的组。如果没有用户名,groups 命令仅显示 /proc/$$/status 组列表,即进程所属的实际当前组。

相关内容