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>):
[table]
|mode|说明|
|R_OK|测试读权限|
|W_OK|测试写权限|
|X_OK|测试执行权限|
[/table]
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
$

从运行结果可以看出,尽管打开了 accessDemo.out 的设置用户 ID 位(改变了进程的有效用户 ID),使 open 函数能打开该文件,但因为进程的实际用户 ID 并不等于有效 ID,所以 access 函数不能正常打开 /etc/shadow 文件。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值