1.各个进程的各种ID,称为进程凭证。如UID,GID等。具体有实际用户ID(real user ID), 实际组ID(real group ID),有效用户ID(effective user ID),有效组ID(effective group ID),保存的set-user-ID和set-group-ID,文件系统用户ID和文件系统组ID,辅助组ID。
2.实际用户id和实际组id:
这两个ID确定了进程所属的用户和组。当用户登录时,会从/etc/passwd文件中读取UID和GID作为实际用户ID和组ID,后续创建的进程都从父进程处继承real UID和real GID。
3.有效用户ID和有效组ID:
进程尝试访问各种资源时,系统会依据有效用户ID和有效组ID来确定授予该进程的权限。一般有效ID等实际ID,但会有一些操作导致这两种不一样。后面主要介绍这些操作。
4.set-user-id 和 set-group-id程序
set-user-id程序可以将进程的有效id修改为文件属主的ID,从而获得常规情况下并不具有的权限。set-group-id实现同样的功能。比如sudo就可以暂时获得root的权限。
可以使用chmod命令来设置权限位,
$ chmod u+s prog
$ chmod g+s prog
$ ls -l prog
-rwsr-sr-x
可以发现设置set-user-id后,x标志位别替换为s,当运行set-user-id进程时,内核会将该进程的UID设置为该文件属主的UID,则该进程拥有了对该文件的所有权限。同样推理可知,如果一个文件的属主为root,并且该文件可以设置set-user-id,则某个进程调用set-user-id时,内核就会将该进程的有效ID设置为0(root),则该进程暂时取得了root权限。注意修改的是进程的ID,不是文件的ID。这个功能非常强大,也带来了很大的风险,38章总结了一套良好的编程习惯,可以参考。
5.保存set-user-id 和保存set-group-id.
当set-user-id时,会发生如下步骤:
1.若可执行文件的set-user-id权限位已开,则将进程的有效用户ID设置为文件的属主ID,若没开启,则进程的有效ID保持不变。
2.保存set-user-id和保存set-group-id的值由对应的有效ID复制而来,无论正在执行的文件是否设置了set-user-id,复制都会进行。
举例说明:
假设某进程的实际id,有效id,保存的set-user-id都为1000,当其执行了root用户的拥有set-user-id的程序后,进程的ID会发生如下变化:
real=1000 effective=0 saved=0
有不少系统调用,允许将set-user-id程序的有效用户id和实际用户id来回切换,则saved就是为了保存effective的副本。
6.文件系统用户id和组id
在linux系统中,要进行诸如打开文件,改变文件属主,修改文件权限之类的文件系统操作,决定其操作权限的是文件系统用户id和组id。一般文件系统id和有效id是一致的。只有当使用linux的两个系统调用setfsuid()和setfsgid()时才会不一样。
7.获取和修改各种id的函数可以参考P140