Linux进程权限

对Linux的进程权限进行了一些总结。

本文是Linux系统下讨论。注意,Linux和Unix有很多不同的地方,并且各个不同的Unix系统也有很多不同。

本文讨论对象:

  • ruid: real user id,即实际用户,也即当前登录的用户
  • euid: effective user id, 即有效用户,也即以哪个用户身份来执行脚本
  • suid: saved user id, 保存用户
  • fuid: file system user id, 即文件系统用户
  • s权限位: 即 set user ID bit,即除了rwx之外的那个s标志位

查看这几个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

普通场景下的uid情况

实验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.

结论1

在常见情况下,这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

结论2

  1. setuid和seteuid是有区别的:
    setuid是永久放弃了root用户权限,转让给非root用户后,无法再收回;
    seteuid只是临时放弃root用户权限,将来可通过seteuid(0)再回到root权限;
  2. seteuid会同时改变euid和fuid都为所设置的euid的值;
  3. 只有root用户才能出让权限,即只有root用户才能调用setuid.

权限出让的常见场景,比如apache和mysql,启动的时候使用root用户启动,设置一些root用户才能操作的系统配置,而在创建子进程时通过setuid降级为nobody用户。

s权限位对进程权限的影响

实验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.

结论3

euid和ruid什么时候不一样呢?
只有一种情况:可执行文件设置了suid位,然后由非owner用户来执行;此时,ruid为执行者,而euid为owner.

对用户文件权限的影响

实验4:
在程序中 setfsuid({test2_uid}) , 然后调用fopen(“some file”, “a+”);
该程序执行结束后,使用 ls -l 会发现文件已经变成了属于test2的文件。

结论4

  • 影响用户文件权限的是fuid,不是euid.
  • fuid是Linux特有的属性,Unix系统是靠euid来判定用户权限。

进程权限的继承

结论5

  • 当使用fork子进程的时候,子进程全部继承父进程4个uid
  • 当使用exec系列函数时候,会把suid置为euid

参考文献

  • http://blog.chinaunix.net/uid-27105712-id-3349522.html
  • http://blog.csdn.net/nirendao/article/details/55549515

你可能感兴趣的:(技术综合,Linux,Linux编程)