access 和 faccessat 函数

    通常,当打开一个文件时,内核是以进程的有效用户 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);
                         /* 返回值:若成功,都返回 0;否则,都返回 -1 */

    其中,如果要测试文件是否已经存在,mode 就为 F_OK;否则 mode 就是下表中的常量的按位或(这些常量均位于头文件 <unistd.h>):
mode 说明
R_OK 测试读权限
W_OK 测试写权限
X_OK 测试执行权限

    faccessat 函数与 access 函数在下列两种情况下是相同的:
    1、pathname 参数为绝对路径。
    2、fd 参数为 AT_FDCWD,而 pathname 为相对路径。否则,faccessat 计算相对于打开目录(由 fd 指向)的 pathname。
    flag 参数可以用于改变 faccessat 的行为,如果 flag 设置为 AT_EACCESS,那么访问检查用的将是进程的有效用户 ID 和有效组 ID,而非实际用户 ID 和实际组 ID。
    下面是一个 access 函数示例:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

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

    执行结果:
$ ls -l accessDemo.out 
-rwxr-xr-x. 1 lei root 7194 7月   2 00:16 accessDemo.out
$ 
$ ./accessDemo.out accessDemo.out
read access OK
open for reading OK
$ 
$ ls -l /etc/shadow
-r--------. 1 root root 1297 10月  3 2016 /etc/shadow
$ 
$ ./accessDemo.out /etc/shadow
access error for /etc/shadow
open error for /etc/shadow
$ 
$ su        # 成为超级用户
密码:
# chown root accessDemo.out   # 改变用户 ID 为 root 
# chmod u+s accessDemo.out    # 打开设置用户 ID 位
# ls -l accessDemo.out
-rwsr-xr-x. 1 root root 7194 7月   2 00:16 accessDemo.out
# 
# exit     # 恢复为原来用户
exit
$ ./accessDemo.out /etc/shadow
access error for /etc/shadow
open for reading OK
$ 

    从运行结果可以看出,尽管打开了 /etc/shadow 的设置用户 ID 位(改变了进程的有效用户 ID),使 open 函数能打开该文件,但因为进程的实际用户 ID 并不等于有效 ID,所以 access 函数不能正常打开 /etc/shadow 文件。

猜你喜欢

转载自aisxyz.iteye.com/blog/2381997