当前位置:嗨网首页>书籍在线阅读

22-用户和组

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

5.6 用户和组

正如本章前面和第1章中所讨论过的,进程是与用户和组相关联的。用户ID和组ID分别用C语言的uid_t和gid_t这两个类型表示。映射表示数值和可读字符串之间的关系(例如root用户的uid是0),是通过文件/etc/passwd 和/etc/group在用户空间完成的。内核只处理数值形式。

在Linux系统中,一个进程的用户ID和组ID代表这个进程可以执行哪些操作。进程必须以合适的用户和组运行。许多进程是以root用户运行。然而,在软件开发中,最好采取“最小权限”原则,表示进程要尽可能以最小权限来运行。这个要求是动态变化的:如果进程在前期需要以root用户的权限运行,而在后面不需要root权限了,那么它就应该在后期尽可能地放弃root权限。由于这个原因,很多进程——特别是那些需要root权限来执行特定操作的进程——经常需要操作自己的用户ID或组ID。

在具体了解如何实现之前,首先需要探索用户ID和组ID的一些复杂方面。

实际用户ID/组ID、有效用户ID /组ID和保留的用户ID /组ID

下面会重点讨论用户ID,组ID与之类似。

实际上,与进程相关的用户ID有4个而不是一个,它们是:实际用户ID(real user ID)、有效用户ID(effective user ID)、保留的用户ID(saved user ID)和文件系统用户ID(filesystem user ID)。实际用户ID是指运行这个进程的用户uid。这个用户uid会被设置为父进程的实际用户ID,并且在exec系统调用中都不会发生改变。一般情况下,登录进程会将用户登录的那个shell的实际用户ID设置为登录用户的uid,并且这个用户所有进程的实际用户ID都会继承这个值。超级用户(root)可能会把实际用户ID修改为任意值,但是其他用户不能改变这个值。

有效用户ID是当前进程所使用的用户ID。权限验证一般是使用这个值。初始时,这个ID等于实际用户ID。因为创建进程时,子进程会继承父进程的有效用户ID。此外,exec系统调用不会改变有效用户ID。但是在exec调用过程中,实际用户ID和有效用户ID开始存在区别:通过执行setuid (suid),进程可以改变自己的有效用户ID。准确地说,有效用户ID被设置为程序文件所有者的用户ID。比如,/usr/bin/passwd是一个setuid文件,它的所有者是root用户。当一个普通用户创建一个进程来运行它时,不论谁运行了它,这个进程的有效用户ID都是root用户ID。

因此,没有特殊权限的用户只能把有效用户ID设置成实际用户ID或保留的用户ID。超级用户可以把有效用户ID设置成任意值。

保留的用户ID是进程原先的有效用户ID。当创建进程时,子进程会从父进程继承保留的用户ID。对于exec系统调用来说,内核会把保留的用户ID设置为有效用户ID,从而在exex系统调用过程中保存了一份有效用户ID的记录。没有特殊权限的用户不能改变保留的用户ID的值,超级用户可以把它设置为实际用户ID的值。

为什么要有这么多的ID呢?有效用户ID的作用是:它是在检查进程权限过程中使用的用户ID。实际用户ID和保留的用户ID是作为代理或潜在用户ID值,其作用是允许非root进程在这些用户ID之间相互切换。实际用户ID是真正运行程序的有效用户id。保留的用户ID是在执行suid程序前的有效用户id。