有进程相关的id:
实际用户id,有效用户id,设置用户id
及相应组id;
一般情况下,有效用户id等于实际用户id;
特殊情况下,执行一个可执行文件,进程有效用户id可以设置为可执行文件的所有者id;
代码如下:
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
int main(int argc, char *argv[])
{
if (argc < 2)
{
printf("usage: test <pathname>\n");
return -1;
}
if (access(argv[1], R_OK) < 0)
{
printf("acess error for %s:", argv[1]);
printf("%s\n", strerror(errno));
}
else
{
printf("read access OK\n");
}
if (open(argv[1], O_RDONLY) < 0)
{
printf("open error for %s:", argv[1]);
printf("%s\n", strerror(errno));
}
else
{
printf("open for Reading OK\n");
}
return 0;
}
编译生成可执行文件test
[lanyang@localhost work]$ gcc test_access.c -o test
[lanyang@localhost work]$ ll
total 12
-rwxrwxr-x. 1 lanyang lanyang 7373 Jul 30 11:41 test
当前用户lanyang
测试文件/etc/passwd
[lanyang@localhost work]$ ll /etc/passwd
-rw-r--r--. 1 root root 1844 Jul 25 04:21 /etc/passwd
[lanyang@localhost work]$ ./test /etc/passwd
read access OK
open for Reading OK
测试文件/etc/shadow
[lanyang@localhost work]$ ll /etc/shadow
----------. 1 root root 1129 Jul 25 04:21 /etc/shadow
[lanyang@localhost work]$ ./test /etc/shadow
acess error for /etc/shadow:Permission denied
open error for /etc/shadow:Permission denied
切换到root用户
[lanyang@localhost work]$ su root
Password:
设置文件所有者为root
[root@localhost work]# chown root test
设置set-user-id位
[root@localhost work]# chmod u+s test
查看test文件属性
[root@localhost work]# ll
total 12
-rwsrwxr-x. 1 root lanyang 7373 Jul 30 11:50 test
退出root用户
[root@localhost work]# exit
exit
现在用户是lanyang
再次测试/etc/shadow
[lanyang@localhost work]$ ./test /etc/shadow
acess error for /etc/shadow:Permission denied
open for Reading OK
结论:
可以看到access测试失败,而open测试通过;
原因:
access的测试是按照进程实际用户ID(在这里是lanyang)进行权限测试,文件所有者为root,无法通过权限测试;
open以有效用户ID进行测试,由于test文件设置set-user-id位,当用户lanyang执行test时,进程的有效用户ID被设置成文件所有者ID,也就是root,通过权限测试;