工学1号馆

home

Unix校验当前用户对文件的访问权限

Wu Yudong    March 08, 2016     Linux/Unix   683   

我们知道内核校验文件的访问权限使用的是进程的有效用户 ID 和有效组 ID。但有时我们需要知道当前登录用户对某个文件访问权限。虽然说进程的有效用户 ID 和有效组 ID 通常分别等于当前登录用户 ID 和用户所在组 ID。例如,一个进程可能因设置用户 ID 以另一个用户权限运行,它仍可能想验证当前实际登录的用户是否能否访问一个给定的文件。

access与faccessat 函数提供了按照实际用户 ID 和实际组 ID 进行访问权限测试的功能。

#include <unistd.h>
int access(const char *pathname, int mode);
int faccessat(int fd, const char *pathname, int mode, int flag);
//Both return: 0 if OK, −1 on error

access 函数的 mode 常量,取自 <unistd.h>

mode 说明
R_OK 测试读权限
W_OK 测试写权限
X_OK 测试执行权限
F_OK 测试文件是否存在

举个例子来展示access函数的使用方法:

#include "apue.h"
#include <fcntl.h>

int
main(int argc, char **argv)
{
	if(argc != 2)
	  err_quit("usage: a.out <pathname>");
	if(access(argv[1], R_OK) < 0)
	  err_ret("access error for %s", argv[1]);
	else
	  printf("read access OK\n");
	if(open(argv[1], O_RDONLY) < 0)
	  err_ret("open error for %s", argv[1]);
	else
	  printf("open for reading OK\n");
	exit(0);
}

运行结果如下:

u@ubuntu:~/opt/Cproject/apue/cp1$ gcc error.c accessfun.c -o a.out
wu@ubuntu:~/opt/Cproject/apue/cp1$ ls -l a.out
-rwxrwxr-x 1 wu wu 8106 Mar 7 23:39 a.out
wu@ubuntu:~/opt/Cproject/apue/cp1$ ./a.out a.out
read access OK
open for reading OK
wu@ubuntu:~/opt/Cproject/apue/cp1$ ls -l /etc/shadow
-rw-r—– 1 root shadow 1057 Nov 6 03:03 /etc/shadow
wu@ubuntu:~/opt/Cproject/apue/cp1$ ./a.out /etc/shadow
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied
wu@ubuntu:~/opt/Cproject/apue/cp1$ sudo su
[sudo] password for wu:
root@ubuntu:/home/wu/opt/Cproject/apue/cp1# chown root a.out
root@ubuntu:/home/wu/opt/Cproject/apue/cp1# chmod u+s a.out
root@ubuntu:/home/wu/opt/Cproject/apue/cp1# ls -l a.out
-rwsrwxr-x 1 root wu 8106 Mar 7 23:39 a.out
root@ubuntu:/home/wu/opt/Cproject/apue/cp1# exit
exit
wu@ubuntu:~/opt/Cproject/apue/cp1$ ./a.out /etc/shadow
access error for /etc/shadow: Permission denied
open for reading OK

对运行结果解释如下:

1. 起先,文件 a.out 的所有者是 wu(当前登录用户),运行./a.out a.out时,进程的实际用户和有效用户都是wu,则 access 函数和 open 函数都能够成功。

2. 文件/etc/shadow 的所有者是 root,且其只允许 root 用户读取。此时运行./a.out /etc/shadow,进程的实际用户的有效用户都是 wu,则 access 函数和 open 函数都失败了。

3. 切换后超级用户 root,将文件 a.out 的所有者修改为超级用户root(运行命令chown root a.out ,并设置文件 a.out 的设置用户 ID 位(运行命令chmod u+s a.out )。

4. 切换后当前登录用户 wu,此时运行./a.out  /etc/shadow,进程的实际用户为 wu,但有效用户为超级用户 root(因文件a.out 的所有者为 root 且设置了设置用户 ID 位)。此时 access函数校验当前登录用户 wu 对文件/etc/shadow 读权限失败,但open 函数却能够打开文件/etc/shadow(内核用进程的有效用户 ID进行访问权限校验)。

如果文章对您有帮助,欢迎点击下方按钮打赏作者

Comments

No comments yet.
To verify that you are human, please fill in "七"(required)