1.8 用户标识
1.用户ID
口令文件登录项中的用户ID(user ID)是一个数值,它向系统标识各个不同的用户。系统管理员在确定一个用户的登录名的同时,确定其用户ID。用户不能更改其用户ID。通常每个用户有一个唯一的用户ID。下面将介绍内核如何使用用户ID来检验该用户是否有执行某些操作的权限。
用户ID为0的用户为根用户(root)或超级用户(superuser)。在口令文件中,通常有一个登录项,其登录名为root,我们称这种用户的特权为超级用户特权。我们将在第4章中看到,如果一个进程具有超级用户特权,则大多数文件权限检查都不再进行。某些操作系统功能只向超级用户提供,超级用户对系统有自由的支配权。
2.组ID
口令文件登录项也包括用户的组ID(group ID),它是一个数值。组ID也是由系统管理员在指定用户登录名时分配的。一般来说,在口令文件中有多个登录项具有相同的组ID。组被用于将若干用户集合到项目或部门中去。这种机制允许同组的各个成员之间共享资源(如文件)。4.5节将介绍可以通过设置文件的权限使组内所有成员都能访问该文件,而组外用户不能访问。
组文件将组名映射为数值的组ID。组文件通常是/etc/group。
使用数值的用户ID和数值的组ID设置权限是历史上形成的。对于磁盘上的每个文件,文件系统都存储该文件所有者的用户ID和组ID。存储这两个值只需4个字节(假定每个都以双字节的整型值存放)。如果使用完整ASCII登录名和组名,则需更多的磁盘空间。另外,在检验权限期间,比较字符串较之比较整型数更消耗时间。
但是对于用户而言,使用名字比使用数值方便,所以口令文件包含了登录名和用户ID之间的映射关系,而组文件则包含了组名和组ID之间的映射关系。例如,ls -l命令使用口令文件将数值的用户ID映射为登录名,从而打印出文件所有者的登录名。
早期的UNIX系统使用16位整型数表示用户ID和组ID。现今的UNIX系统使用32位整型数表示用户ID和组ID。
实例
图1-9程序用于打印用户ID和组ID。
#include "apue.h"
int
main(void)
{
printf("uid = %d, gid = %d\n", getuid(), getgid());
exit(0);
}
图1-9 打印用户ID和组ID
程序调用getuid和getgid以返回用户ID和组ID。运行该程序的结果如下:
$ ./a.out
uid = 205, gid = 105
3.附属组ID
除了在口令文件中对一个登录名指定一个组ID外,大多数 UNIX系统版本还允许一个用户属于另外一些组。这一功能是从4.2BSD开始的,它允许一个用户属于多至16个其他的组。登录时,读文件/etc/group,寻找列有该用户作为其成员的前16个记录项就可以得到该用户的附属组ID(supplementary group ID)。在下一章将说明,POSIX要求系统至少应支持8个附属组,实际上大多数系统至少支持16个附属组。