来自APUE
进程的真实用户 ID 和真实组 ID 标识了我们的真实身份。这两个字段取自我们登录时在密码文件中的输入。通常,这些值在登录会话期间不会更改,尽管有多种方法可以更改 一个超级用户进程来改变它们
超级用户进程是否可以更改进程的真实用户 ID 和真实组 ID,从而使真实用户 ID 和真实组 ID 之间的关系与密码文件中的关系不匹配?例如,如果用户Tim
不是ocean
密码文件中的组成员,超级用户进程是否可以将进程的真实用户 ID 和真实组 ID 分别更改为Tim
和ocean
?
答案1
是的,超级用户进程可以将其真实用户 ID 和真实组 ID 更改为它想要的任何值。/etc/passwd
和中的值/etc/shadow
是应设置哪些值的配置,但不是对可能值的限制。
编辑#1
这意味着像这样的程序login
将从文件中读取值,因此这些文件是配置文件或输入文件。它们并不限制程序可以做什么。超级用户进程可以将任何值传递给内核,而内核不会检查任何文件。
一个程序可以调用
setgid (54321);
setuid (12345);
即使任何文件中都没有提到这两个 id,这也是可行的。
答案2
密码文件和组文件不被读取,它们仅由登录进程读取,以设置真实用户ID和真实组ID。
内核中没有任何内容提及这些文件。登录必须打开文件、处理它们并设置两个 ID。可以采用不同的编写方式从其他地方获取这些 ID。例如,来自网络数据库。
任何具有 CAP_SETUID 能力的进程都可以设置这些 ID,root 具有此能力。
Unix 中的安全模型部分在内核中实现,部分在以增强功能运行的进程中(例如作为 root)实现。
请注意,/etc/passwd
和/etc/group
也可以由和 以及任何其他需要将用户/组名称转换为用户/组 ID 或从用户/组 ID 转换的程序读取。 (他们可以通过图书馆来做到这一点,而不是知道存储这些详细信息的替代方法。)ls
ps
答案3
除其他外,其目的/etc/passwd
是翻译用户的姓名到用户的用户识别码。如果您不关心 bob 的 UID 是什么,则不需要该文件。如果您只想更改为任意 UID/GID,请使用相关的系统调用:
int setuid(uid_t uid);
int setgid(gid_t gid);
CAP_SETUID
请注意,带有和 的特权进程CAP_SETGID
能力(根进程通常具有)只能更改自己的 UID 和 GID,而不能更改其他正在运行的进程的 UID 和 GID。
答案4
我最近创建了一个 Linux 内核模块来做到这一点(https://github.com/xuancong84/chown-pid)。到目前为止,还没有用户级程序可以做到这一点。
您需要构建内核模块,cd
将其放入项目文件夹中并运行make
。如果成功,将会产生chown-pid.ko
.
然后,
insmod chown-pid.ko arg_pid=<PID> arg_gid=<UID> arg_act='set_uid' && rmmod chown-pid
insmod chown-pid.ko arg_pid=<PID> arg_gid=<GID> arg_act='set_gid' && rmmod chown-pid