对于内核来讲,只有User Identifier,它是一个整数,存储在进程信息中。内核不关心用户名。用户名是文件系统中的一个文件映射UID到到一个字符串实现。
Real UID,也即UID,是运行进程的用户,Effective user ID,也即EUID,内核使用EUID来检查大部分权限。当父进程fork子进程时,子进程继承父进程的UID和EUID。
UID为0的用户是root用户。
文件系统有读、写和执行权限,这个大家都知道。
内核的权限很多都是根据文件的权限来确定权限的。比如root用户挂载了一个usb磁盘,如果里面有一个char dev文件,权限为777的话,那么所有人都可以访问对应的设备。
文件还有一个setuid bit,如果设置了这个位,那么执行这个可执行文件的EUID将是这个文件的owner。而不是父进程。
1 2 | $ ls -l /usr/bin/sudo -rwsr-xr-x 1 root root 157192 Oct 11 02:29 /usr/bin/sudo |
可以看到sudo可执行文件的user的可执行位置为s,表示设置了setuid位,而且sudo可执行文件的owner为root,这表示sudo执行的时候,具有root权限。这也是sudo实现的原理。
因此我们挂载可移动磁盘时,应该挂载为忽略setuid选项。否则会很危险。
setuid()系统调用可以设置EUID,如果当前用户有权限,它也会设置Real UID。显然非ROOT用户,没有权限直接使用setuid来设置自己为ROOT用户。
使用
1 | chmod u+s |
来设置setuid bit。
类似的还有setgid bit。使用
chmod g+s
来设置setgid bit
文件设置了这个位,表示只有这个文件的owner才能删除这个文件,其它用户(当然不包括ROOT用户)即使有写权限,也不能删除它。
使用
1 | chmod +t |
来设置sticky bit。
参考资料:
https://www.geeksforgeeks.org/setuid-setgid-and-sticky-bits-in-linux-file-permissions/
https://en.wikipedia.org/wiki/User_identifier