access-------Linux 程序员手册 (2)

本文介绍了一个系统调用access,用于检测当前用户对特定文件的访问权限。该调用使用真实UID和GID而非有效IDs,适用于设置用户ID程序检测用户的权限。文中详细解释了参数mode的不同选项及它们如何影响权限检查。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

名字

access - 对一个文件检测当前真实用户权限

概要

#include <unistd.h>


int access(const char * pathname , int mode );

描述

access () 检测调用进程是否可以访问 pathname 指向的文件。如果 pathname 是一个符号链接,则会解引用。

mode 用来指定需要执行检测的访问模式,或者是 F_OK 。指定的模式可以是 F_OKR_OKW_OKX_OK 执行位或运算的结果。F_OK 测试文件是否存在。R_OKW_OKX_OK 测试文件存在并且保证可读、可写、可执行。

与真实地去执行一个操作(如 open (2))不一样,本系统调用检测时使用调用进程的 真实 UID 和 GID,而不是有效 IDs。这使得“设置用户 ID”程序可以简单地测试调用用户的权限。

如果调用进程具有特权(如它的真实 UID 是 0),那么对于普通文件执行 X_OK 测试时,只要这个文件的执行权限在文件所主、组或其它用户里被设置,测试总是返回成功。

返回值

成功时(所有要求的权限都得到保证),0 被返回。错误时(至少有一个在 mode 指定的权限被禁止或其它什么错误),-1 被返回,同时 errno 被设置为合适的值。

错误

access () 可能失败于:

EACCES
指定文件要求访问的权限被禁止,或 pathname 中的某个路径片段的查找权限被禁止。(参看 path_resolution (7)。)
ELOOP
在访问 pathname 时经历了太多的符号链接。
ENAMETOOLONG
pathname 太长了。
ENOENT
pathname 的目录片段不存在或是一个悬空符号链接。
ENOTDIR
pathname 里的一个片段作为一个目录使用,但是事实上它不是一个目录。
EROFS
对一个只读文件系统要求写权限。

access () 也可能失败于:

EFAULT
pathname 指向的地址不在你的可以访问的地址空间。
EINVAL
mode 指定的不正确。
EIO
发生 I/O 错误。
ENOMEM
内核可用内存不足。
ETXTBSY
对一个正在执行的可执行文件要求写权限。

遵循于

SVr4, 4.3BSD, POSIX.1-2001。

注意

警告 :如果在 open (2) 打开一个之前使用 access () 来认证一个用户将产生一个安全漏洞,因为有人可能会利用检测与打开之间的短暂时间间隔来操作它。出于这个原因,这个系统调用应该避免使用 。(在刚才描述示例中,一个更安全的方式应该是临时把有效用户ID转换到真实用户ID,然后调用 open (2)。)

access () 总是解引用符号链接。如果你需要检测符号链接本身的权限,使用带标志 AT_SYMLINK_NOFOLLOWfaccessat (2)。

在访问模式 mode 任何一个权限的禁止都会让 access () 返回错误,此时可能在 mode 里的其它权限是允许的。

如果调用进程具有特权(如是超级用户),试图测试 X_OK 时,即使指定文件执行位没有设置,POSIX.1-2001 也允许实现返回成功。Linux 没有这么做。

一个文件只有在它的路径名 pathname 里的每个前缀目录都是可查找(如执行)的时候才是可访问。如果有任何一个目录是不可查找的,access () 的调用会失败,此时不涉及那个文件自身。

只有访问位被检测,不包括文件类型或内容。所以如果一个目录测试为可写时,这只是表明可以在这个目录里创建文件,而不说这个目录可以像文件一样可以写入内容。类似的,对于一个 DOS 文件可能返回为“可执行”,但是 execve (2) 调用仍然会失败。

对于 NFS 文件系统来说,当 UID 映射启用时,access () 可能工作不正确,因为 UID 映射是针对服务器进程的,这对客户端进程不可见,而做测试的客户端进程。

错误

在内核 2.4 (和更早) 当超级用户测试 X_OK 时存在一些奇怪的事。如果一个非目录文件的所有类型的自毁长城权限都被禁止了,access () 在 mode 只设置为 X_OK 时返回 -1,而当 R_OKW_OK 也被设置在 mode 里时,access () 会返回 0。早期的 2.6 内核(包括2.6.3和更新)也有与 2.4 内核有同样的行为。

在 2.6.20 之前内核,如果 mount (2) 低级的文件系统时使用了MS_NOEXEC 标记, access () 会忽略这个标记位。自从 2.6.20 内核,access () 优先使用这个标记。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值