我将用户添加到组,但文件的组权限仍然无效

tsh*_*ang 27 users permissions group

我更改了文件 ( chmod g+w testfile) 的权限并运行ls -l testfile

-rwxrwxr-x 1 user1 user1 0 2011-01-24 20:36 testfile
Run Code Online (Sandbox Code Playgroud)

然后我将一个用户添加到该组(“ /etc/group ”有user1:x:1000:user2一行),但是我无法以 user2.conf 的身份编辑该文件。为什么会这样?

Gil*_*il' 48

user2 需要注销并重新登录。组权限的工作方式如下:

  • 当您登录时,您的进程将在 中提到的主组/etc/passwd以及在 中提到您的用户的所有组中拥有组成员资格/etc/group。(更精确地,pw_gid在该领域getpw(your_uid),加上所有组,其中用户是一个显式构件。除了/etc/passwd/etc/group,该信息可以来自于其他类型的用户数据库如NIS或LDAP的。),主要组成为进程的有效组ID其他组成为其补充组 ID
  • 当进程执行需要特定组成员身份的操作时,例如访问文件,该组必须是该进程的有效组 ID 或补充组 ID 之一。

如您所见,您对用户组成员身份的更改仅在用户登录时生效。对于正在运行的进程,为时已晚。因此用户需要注销并重新登录。如果这太麻烦,用户可以登录到单独的会话(例如,在不同的控制台上,或使用ssh localhost)。

在幕后,进程只会失去特权(用户 ID、组 ID、功能)。内核启动init以 root 身份运行的进程(启动后的第一个进程),并且每个进程最终都来自该进程¹。该login进程(或sshd,或登录您的桌面管理器的一部分)仍在以 root 身份运行。它的部分工作是删除 root 权限并切换到正确的用户和组。

只有一个例外:执行setuid 或 setgid程序。该程序获得额外的权限:它可以选择在父进程成员身份的各种子集以及拥有 setxid 可执行文件的用户或组中的额外成员身份下运行。特别是,setuid root 程序具有root 权限,因此可以做任何事情²;这就是程序喜欢susudo可以完成工作的方式。

¹ 偶尔会有不是从 init (initrd, udev) 派生的进程,但原理是一样的:以 root 身份启动,随着时间的推移失去特权。
² 除非 SELinux 等多级安全框架。

  • 请注意,如果您使用的是桌面 GUI,只需注销并重新登录到终端窗口将不会重置组成员身份。我遇到了这个问题,我还需要注销我的 GUI 会话:þ (3认同)
  • @ user394 注销并重新登录会重置组成员身份。如果您只是关闭终端窗口,则不会注销。 (3认同)

jsb*_*ngs 12

您可能需要让 user2 注销并重新登录(或者只是尝试通过 ssh 登录以创建新的登录会话)。检查输出id --groups以显示用户的数字组 ID。


Cra*_*cks 6

使用 newgrp 在新的 shell 中实现临时解决方案:

newgrp可以使用该命令。它使用户能够临时(在新 shell 中)将其主要组更改为指定值。

user1组添加到user2

sudo usermod -a -G user1 user2
Run Code Online (Sandbox Code Playgroud)

作为user2调用newgrp user1

user2% newgrp user1
user2% id
uid=1001(user2) gid=1000(user1) 
groups=1000(user1),...,1001(user2)
Run Code Online (Sandbox Code Playgroud)

那么user2的主要组将立即成为user1,并且文件写入将作为user1组所有者产生。但是,中指定的主要组/etc/passwd不会更改。

当再次user2打电话时newgrp user1

user2% newgrp user2
user2% id
uid=1001(user2) gid=1001(user2) 
groups=1001(user2),...,1000(user1)

Run Code Online (Sandbox Code Playgroud)

并且user2的主组将立即被设置回原来的组user2,同时user2仍属于该组user1。这是最初预期的效果 sudo usermod -a -G user1 user2,但并没有立即发生。在这种状态下,文件写入将作为user2组所有者进行。

  • 注意:每次调用都会newgrp产生一个新的 shell。这bash会导致环境变量的值增加SHLVL1。退出 shell 后,所创建的newgrp效果会反转,没有副作用。出于这个原因,仍然可能存在需要注销/重新启动或其他解决方案的用例,因此我将之前的答案保留在下面,该答案在注销不起作用时有效,并且避免了重新启动。 然而,在实践中,我发现这newgrp足以涵盖我面临的每个用例。

注销不起作用时无需重新启动的“永久”解决方案

我发现所选答案的建议

user2 需要注销并重新登录。...内核启动以 root 身份运行的 init 进程(启动后的第一个进程),每个进程最终都是该进程的后代[因此需要通过注销来杀死它]

在 Ubuntu 20.04 中,“注销”GUI 选项不起作用,并且在注销并返回此“init”进程后,仍保留较旧的启动时间

root           1  0.0  0.1 168096 11744 ?        Ss   12:45   0:02 /sbin/init
Run Code Online (Sandbox Code Playgroud)

杀死它可能会解决这个问题,但我没有这样做,而是杀死了这个也有较旧时间戳的用户进程

craig       1790  0.0  0.0 169360  3784 ?        S    12:46   0:00 (sd-pam)
Run Code Online (Sandbox Code Playgroud)

只是因为我对“pam”是一个用于验证用户身份的模块的理解薄弱。它起作用了,然后向id自己展示了正确的组权限。

注销失败以解决问题可能(或可能不)与 相关systemd读完这篇文章后我想也许是这样。

  • @JakubKlinkovský - 但是,它与所选答案“user2 需要注销并重新登录”并非无关。而且,我不相信这只是“我的”系统;它是“我的”系统。我在其他相关问题中看到了多个评论(不仅仅是来自使用“s​​sh”的问题),抱怨注销不会更新添加的组。我的是从安装介质全新安装 20.04 的第二天,而不是更新。我想说的是,我的安装不太可能被破坏,而且很可能这是所有 20.04 正常工作的桌面安装的实际行为,其中可能有几百万个。 (2认同)

小智 5

sudo su $(whoami)

基本上与 相同的解决方法ssh localhost,但无需安装 ssh 服务器即可使用。

只要你有 root 。但是,如果您刚刚添加了一个新组并更改了权限,则可能会这样做。