设置用户ID位
先摆出 main.c 文件, 回头再看.
#include "apue.h"
#include <fcntl.h>
int main(int argc, const char * argv[]) {
if(argc != 2){
err_quit("示例: ./a.out <filePath>");
}
const char * file_path = argv[1];
//access函数以进程的 实际用户ID 为基础执行访问权限测试
if(access(file_path, R_OK) < 0){
err_ret("实际用户读权限检测失败!\n");
}else{
printf("实际用户读权限 is OK.\n");
}
//内核以进程的 有效用户ID 为基础执行访问权限测试
if(open(file_path, O_RDONLY) < 0){
err_ret("有效用户读权限检测失败!\n");
}else{
printf("有效用户读权限 is OK.\n");
}
exit(0);
}
测试目录下的文件
total 56
drwxr-xr-x 6 cbd staff 204 8 21 16:44 ./
drwxr-xr-x 4 cbd staff 136 8 21 15:58 ../
-rwsr-xr-x 1 root staff 13644 8 21 16:42 a.out*
-rw-r--r--@ 1 cbd staff 674 8 21 16:08 main.c
-rw-r--r-- 1 cbd staff 25 8 21 16:44 ordinary.txt
-r-------- 1 root staff 25 8 21 16:44 super.txt
在这里先只讨论用户组ID.
一个进程关联的用户ID可以有 实际用户ID
和 有效用户ID
和保存的设置用户ID(exec函数调用,暂不讨论).
通常,实际用户ID在登陆系统的时候就确定了,有效用户ID大部分时候和实际用户ID一致.
可以用’who am i’查看实际用户, 用whoami
查看有效用户.
用户以user1身份登陆,whoami
和who am i
都是user1.
当用su切换到root之后,whoami
为root, who am i
还是user1.
(OSX默认root没有密码, 需要先sudo passwd root
给root一个密码后才能su
.)
内核以进程的有效用户ID
为基础执行访问权限测试.
回到该目录, 重点看a.out
文件, 它属于root用户.
super.txt属于root,而且只允许root用户读.
有没有办法在不改变super.txt文件属性的前提下,让一般用户使用a.out有读super.txt的权限呢?
这个例子就来自/etc/passwd
的问题,它是敏感文件,只许root用户操作,但一般用户又需要passwd命令修改自己的密码.
解决办法就是在运行a.out
的时候,把有效用户ID临时切换到root,也就是a.out
的所属者.这个操作成为设置用户ID位
.
Baodong-MBP:access_open cbd$ ll
total 56
drwxr-xr-x 6 cbd staff 204 8 21 17:01 ./
drwxr-xr-x 4 cbd staff 136 8 21 15:58 ../
-rwsr-xr-x 1 root staff 13644 8 21 16:42 a.out*
-rw-r--r--@ 1 cbd staff 828 8 21 17:01 main.c
-rw-r--r-- 1 cbd staff 25 8 21 16:44 ordinary.txt
-r-------- 1 root staff 25 8 21 16:44 super.txt
Baodong-MBP:access_open cbd$ ./a.out super.txt
实际用户读权限检测失败!
: Permission denied
有效用户读权限 is OK.
我们用cbd身份运行a.out, 该进程的实际用户ID为cbd.
看到rws
中的s表示已经设置用户ID位,所以该进程的有效用户ID为该文件a.out的所有者也就是root.
内核在检查身份时以有效用户ID为准,所以有效ID为root的进程来查看只允许root用户查看的super.txt也就合法了.
另, rws
表示只读+只写+执行+设置用户ID位; rwS
表示只读+只写+设置用户ID位,没有执行权限.
另, rws------
对应的数字mod为4700,---rwS------
对应的数字mod为2060.(1为粘着位)
另, 在shell中可以这样设定 chmod u+s a.out
, 注意s的对象为a.out这个可执行文件而不是想保护的那个文件.super.txt的权限设置永远不要改动.
权力越大责任越大,使用需谨慎.
总结
类型 | shell | 确定 | 检测 |
---|---|---|---|
实际用户ID位 | who am i | tty时确定 | access() |
有效用户ID位 | whoami | su可变 | system call |