Linux的一个进程有下面几组用户ID和组ID:
real-uid/real-gid
是这个进程的拥有者(组)。getuid、getgid可以得到它们。
effective-uid/effective-gid
是Kernel用来判断资源(Message Queue,Shared Memory,Mutex等)访问权限的主要ID。在Linux系统中,这个ID不直接决定文件系统的访问权限,而是Filesystem-UID/GID来决定,但是EUID/EGID的变动直接回导致Filesystem-UID/GID的变动。所以一般可以认为euid、egid决定文件的访问权限。
它们继承于父进程的对应用户。但是如果可执行文件设置了setuid属性,那么euid、egid会设置成可执行文件的uid和gid(一般是root)。
进程中,可以使用seteuid,setreuid,setresuid等函数来修改。系统的第一个进程init的各种uid/gid都是root(0),但后续起来的程序进程会根据其需要和设计调用上面的函数来修改自己的uid/gid。
filesystem-uid/gid
决定文件系统的访问权限。访问文件时,系统会用FUID/FGID判断进程是以那种角色来访问:拥有者(user)、拥有组(group)、其他(other)。然后看这个角色是否有进程所请求的权限:读,写,执行。
这个是Linux系统特有的,一旦euid被修改fuid也会被自动修改。但可以调用setfsuid来改动,可以和euid不一样。
Supplememtary-Group-IDs
这个ID列表定义了除了gid/egid外,process还应该属于那些组。可以使用getgroups和setgroups来获取和修改他们。也影响对文件系统的访问权限。
saved-set-uid
当使用root用户或者setuid的方式启动一个进程后,其euid是root,但root的进程一般都需要能来回切换任何其他用户的ID,但是普通的euid是无法修改成root的euid的,所以设计了saved-set-uid,来记住最初的User ID,不论什么进程是什么euid都可以改回到saved-set-uid中的UID。
我们通常会这样认为:一个process的euid决定了它可以访问的文件,如果euid是访问文件的属组(group)的成员,那么process应该可以访问这个文件。这个想法是错误的。系统不会用euid来判断进程是属于哪一个组,euid只用来和文件的owner来判断,进程有egid、Supplememtary-Group-IDs信息来决定进程属于哪些组。