本人对Unix下的进程的实际用户ID和有效用户ID一直都比较迷惑,没有彻底搞清楚。最近温习APUE(《高级UNIX环境编程》),终于对这两个概念有了一个清晰的认识,看来经典著做绝对须要温习多遍,才能领略其中的奥秘。编程
在Unix进程中涉及多个用户ID和用户组ID,包括以下:测试
一、实际用户ID和实际用户组ID:标识我是谁(听说这是一个变态的哲学问题,难死一片哲学家)。也就是登陆用户的uid和gid,好比个人Linux以simon登陆,在Linux运行的全部的命令的实际用户ID都是simon的uid,实际用户组ID都是simon的gid(能够用id命令查看)。
二、有效用户ID和有效用户组ID:进程用来决定咱们对资源的访问权限。通常状况下,有效用户ID等于实际用户ID,有效用户组ID等于实际用户组ID。当设置-用户-ID(SUID)位设置,则有效用户ID等于文件的全部者的uid,而不是实际用户ID;一样,若是设置了设置-用户组-ID(SGID)位,则有效用户组ID等于文件全部者的gid,而不是实际用户组ID。 ui
Unix系统经过进程的有效用户ID和有效用户组ID来决定进程对系统资源的访问权限。spa
以上这些概念仍是比较的抽象,那么我就动手验证一下就很是清楚了。用户以下代码写一个小的测试程序:.net
#include <sys/types.h> #include <unistd.h> #include <stdio.h>int main(void) { printf("uid = %d, gid = %d, euid = %d, egid = %d\n", getuid(), getgid(), geteuid(), getegid()); }
这个程序很是简单没有什么好说的。咱们编译这个程序生成a.out程序。 unix
经过上图,咱们能够看到:经过id命令看到当前登陆用户为simon,uid=1000,gid=1000。经过ls命令咱们能够看出a.out程序没有设置SUID和SGID(能够参考个人博文Linux的特殊文件权限,来明确怎样经过ls查看SUID和SGID位的设置状况),全部者是simon,全部者阻也是simon。执行a.out咱们发现有效用户ID等于实际用户ID(1000),有效用户组ID等于实际用户组ID(1000)。code
你可能注意到a.out的全部者simon,组也是simon,和实际用户,实际用户组是同样的,这样测试下来上面的结果说服力不够。下一步咱们修改一下a.out全部者和组,再看结果。进程
发现结果和上面同样,a.out进程的有效用户ID等于实际用户ID(1000),有效用户组ID等于实际用户组ID(1000)。资源
下面咱们给a.out程序设置SUID,看看会有什么结果。get
咱们发现设置a.out程序的SUID位以后,a.out进程的有效用户ID等于文件全部者的UID(root的uid为0),有效用户组ID仍是等于实际用户组ID(1000)。这样程序就能够访问只有root才能访问的资源了。注意这样的程序很危险,编写这样的程序必定要当心。
下面咱们设置a.out的SGID,看看会有什么结果。
咱们发现设置a.out的SGID以后,a.out进程的有效用户ID等于实际用户ID(1000),有效用户组ID等于文件全部者的用户组ID(root组gid等于0)。这样a.out进程就能够访问root组能够访问的全部的资源了。
通过上面的描述想必你们对实际用户ID和有效用户ID有了一个比较清晰的认识。请你们自行分析passwd命令的实际用户ID和有效用户ID(passwd须要访问root权限的资源/etc/passwd等),能够参考Linux的特殊文件权限。
来源:http://my.unix-center.net/~Simon_fu/?p=607