UNIX环境编程学习笔记(8)——文件I/O之校验当前登录用户对文件的访问权限
2014-09-03 20:53
537 查看
lienhua34
2014-09-03
通过前面一篇随笔(文件访问权限与进程访问控制),我们知道内核校验文件的访问权限使用的是进程的有效用户 ID 和有效组 ID。但有时我们需要知道当前登录用户对某个文件访问权限。虽然说进程的有效用户 ID 和有效组 ID 通常分别等于当前登录用户 ID 和用户所在组 ID。例如,一个进程可能因设置用户 ID 以另一个用户权限运行,它仍可能想验证当前实际登录的用户是否能否访问一个给定的文件。
access 函数提供了按照实际用户 ID 和实际组 ID 进行访问权限测试的功能。其校验步骤跟之前说的内核校验步骤一致,只是将“有效”改成了“实际”。
#include <unistd.h>
int access(const char *pathname, int mode);
返回值:若成功则返回0,若出错则返回-1.
其中,mode 是表 1 中所列常量的按位或。
表 1: access 函数的 mode 常量,取自 <unistd.h>
例子:
下面程序测试当前登录用户对命令行第一个参数是否具有读权限,然后以只读的方式打开该文件。
编译该程序,生成 accessdemo,然后运行该程序,
我们来分析一下上面的运行命令序列及其结果。
1. 起先,文件 accessdemo 的所有者是 lienhua34(当前登录用户),运行./accessdemo acessdemo 时,进程的实际用户和有效用户都是lienhua34,则 access 函数和 open 函数都能够成功。(第1到6行)
2. 文件/etc/shadow 的所有者是 root,且其只允许 root 用户读取。此时运行./accessdemo /etc/shadow,进程的实际用户的有效用户都是 lienhua34,则 access 函数和 open 函数都失败了。(第7到11行)
3. 切换后超级用户 root,将文件 accessdemo 的所有者修改为超级用户root(运行命令chown root accessdemo,并设置文件 accessdemo 的设置用户 ID 位(运行命令chmod u+s accessdemo)。(第12到18行)
4. 切换后当前登录用户 lienhua34,此时运行./accessdemo /etc/shadow,进程的实际用户为 lienhua34,但有效用户为超级用户 root(因文件accessdemo 的所有者为 root 且设置了设置用户 ID 位)。此时 access函数校验当前登录用户 lienhua34 对文件/etc/shadow 读权限失败,但open 函数却能够打开文件/etc/shadow(内核用进程的有效用户 ID进行访问权限校验)。(第19到21行)
(done)
2014-09-03
通过前面一篇随笔(文件访问权限与进程访问控制),我们知道内核校验文件的访问权限使用的是进程的有效用户 ID 和有效组 ID。但有时我们需要知道当前登录用户对某个文件访问权限。虽然说进程的有效用户 ID 和有效组 ID 通常分别等于当前登录用户 ID 和用户所在组 ID。例如,一个进程可能因设置用户 ID 以另一个用户权限运行,它仍可能想验证当前实际登录的用户是否能否访问一个给定的文件。
access 函数提供了按照实际用户 ID 和实际组 ID 进行访问权限测试的功能。其校验步骤跟之前说的内核校验步骤一致,只是将“有效”改成了“实际”。
#include <unistd.h>
int access(const char *pathname, int mode);
返回值:若成功则返回0,若出错则返回-1.
其中,mode 是表 1 中所列常量的按位或。
mode | 说明 |
R_OK | 测试读权限 |
W_OK | 测试写权限 |
X_OK | 测试执行权限 |
F_OK | 测试文件是否存在 |
下面程序测试当前登录用户对命令行第一个参数是否具有读权限,然后以只读的方式打开该文件。
#include <stdlib.h> #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: accessdemo <pathname>"); exit(-1); } if (access(argv[1], R_OK) < 0) { printf("access error for %s: %s\n", argv[1], strerror(errno)); } else { printf("read access OK\n"); } if (open(argv[1], O_RDONLY) < 0) { printf("open error for %s: %s\n", argv[1], strerror(errno)); } else { printf("open for reading OK\n"); } exit(0); }
编译该程序,生成 accessdemo,然后运行该程序,
lienhua34:demo$ gcc -o accessdemo accessdemo.c lienhua34:demo$ ls -l accessdemo -rwxrwxr-x 1 lienhua34 lienhua34 7400 9月 1 21:29 accessdemo lienhua34:demo$ ./accessdemo accessdemo read access OK open for reading OK lienhua34:demo$ ls -l /etc/shadow -rw-r----- 1 root shadow 1143 4月 6 19:27 /etc/shadow lienhua34:demo$ ./accessdemo /etc/shadow access error for /etc/shadow: Permission denied open error for /etc/shadow: Permission denied lienhua34:demo$ su # chown root accessdemo # chmod u+s accessdemo # ls -l accessdemo -rwsrwxr-x 1 root lienhua34 7400 9月 1 21:29 accessdemo # exit exit lienhua34:demo$ ./accessdemo /etc/shadow access error for /etc/shadow: Permission denied open for reading OK
我们来分析一下上面的运行命令序列及其结果。
1. 起先,文件 accessdemo 的所有者是 lienhua34(当前登录用户),运行./accessdemo acessdemo 时,进程的实际用户和有效用户都是lienhua34,则 access 函数和 open 函数都能够成功。(第1到6行)
2. 文件/etc/shadow 的所有者是 root,且其只允许 root 用户读取。此时运行./accessdemo /etc/shadow,进程的实际用户的有效用户都是 lienhua34,则 access 函数和 open 函数都失败了。(第7到11行)
3. 切换后超级用户 root,将文件 accessdemo 的所有者修改为超级用户root(运行命令chown root accessdemo,并设置文件 accessdemo 的设置用户 ID 位(运行命令chmod u+s accessdemo)。(第12到18行)
4. 切换后当前登录用户 lienhua34,此时运行./accessdemo /etc/shadow,进程的实际用户为 lienhua34,但有效用户为超级用户 root(因文件accessdemo 的所有者为 root 且设置了设置用户 ID 位)。此时 access函数校验当前登录用户 lienhua34 对文件/etc/shadow 读权限失败,但open 函数却能够打开文件/etc/shadow(内核用进程的有效用户 ID进行访问权限校验)。(第19到21行)
(done)
相关文章推荐
- UNIX环境编程学习笔记(8)——文件I/O之校验当前登录用户对文件的访问权限
- UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改
- UNIX环境编程学习笔记(9)——文件I/O之文件访问权限的屏蔽和更改
- UNIX环境编程学习笔记(7)——文件I/O之文件访问权限与进程访问控制
- UNIX环境编程学习笔记(5)——文件I/O之fcntl函数访问已打开文件的性质
- UNIX环境编程学习笔记(5)——文件I/O之fcntl函数访问已打开文件的性质
- UNIX环境高级编程学习笔记(七)系统数据文件和信息
- Unix环境编程学习笔记------查看系统调用号文件
- UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符
- UNIX环境编程学习笔记(6)——文件I/O之判断文件类型
- UNIX环境编程学习笔记—文件I/O之标准I/O流
- UNIX环境编程学习笔记(11)——文件I/O之文件时间以及 utime 函数
- UNIX环境编程学习笔记(14)——文件I/O之临时文件
- UNIX环境编程学习笔记(2)——文件I/O之不带缓冲的 I/O
- UNIX环境编程学习笔记(4)——文件I/O之dup复制文件描述符
- UNIX环境高级编程学习之第六章系统数据文件和信息 用链表的形式读出一个服务器的远程用户登入登出信息
- UNIX环境编程学习笔记(12)——文件I/O之目录操作
- UNIX环境编程学习笔记(13)——文件I/O之标准I/O流
- UNIX环境编程学习笔记(2)——文件I/O之不带缓冲的 I/O
- UNIX环境编程学习笔记(3)——文件I/O之内核 I/O 数据结构