对Linux的进程权限进行了一些总结。
本文是Linux系统下讨论。注意,Linux和Unix有很多不同的地方,并且各个不同的Unix系统也有很多不同。
本文讨论对象:
查看这几个uid有2种方式:
1. 使用ps命令:
ps -ax -o ruid -o euid -o suid -o fuid -o pid -o fname
2. 查看进程的status文件:
cat /proc/{pid}/status | grep Uid
另:
查看用户的uid、gid等,可以使用命令 id
实验1:
首先,a.out程序属于用户test1和组test.
然后,su test1,作为test1用户。
然后,执行a.out程序。
此时,使用方法1观察,可见4个uid(ruid, euid, suid, fuid)全部为test1.
然后,su test2,作为test2用户。
再执行a.out程序。
再用方法1观察,可见4个uid全部都变成了test2.
在常见情况下,这4个uid等同于执行用户的uid,而和文件的owner无关。
实验2-1:出让权限给其他用户
注意:只有root用户才能出让权限给其他用户。
首先,a.out程序属于用户test1和组test;
但是,在a.out程序中,使用系统调用setuid()将uid设置为test2的uid.
然后,让root用户来执行此程序;
使用方法1观察,会发现4个uid都是 test2 的 uid
实验2-2:
和实验2-1基本一致,不同点在于,在a.out程序中,使用seteuid()系统调用将euid设置为test2的euid.
此时,用方法1观察,会发现:
ruid=root,euid=test2,suid=root,fuid=test2
权限出让的常见场景,比如apache和mysql,启动的时候使用root用户启动,设置一些root用户才能操作的系统配置,而在创建子进程时通过setuid降级为nobody用户。
实验3:
首先,a.out属于test1用户和test用户组;
然后,以test1用户的身份来运行 chmod u+s a.out
最后,使用root用户来运行a.out
使用方法1 ps命令来查看进程情况,会发现:
ruid=root,euid=suid=fuid=test1
s权限位最经典的案例是passwd命令:
-rwsr-xr-x 1 root root 45396 may 25 2012 /usr/bin/passwd
- 由上可见,user2有权限执行passwd
- 执行时,ruid仍是user2,而euid是root. 注意,ruid总是实际执行者的uid,而目前这个case下,euid是文件所有者的uid.
- user2之所以能够改变他自己的密码,是因为passwd内部会检查ruid是否是root,若不是,则其行为会局限于修改ruid的密码
- 让euid变成root是必须的,因为密码的改变必然要求写 /etc/shadow 文件,而该文件权限位是 640,即只有root能写,所以euid必须是root.
euid和ruid什么时候不一样呢?
只有一种情况:可执行文件设置了suid位,然后由非owner用户来执行;此时,ruid为执行者,而euid为owner.
实验4:
在程序中 setfsuid({test2_uid}) , 然后调用fopen(“some file”, “a+”);
该程序执行结束后,使用 ls -l 会发现文件已经变成了属于test2的文件。