我注意到access(2)系统调用使用真实且无效的用户ID进行访问控制检查的困难方式。虽然这与access(2)手册页在Linux上所说的一致,但对我来说仍然没有意义......
例如,setuid root程序将在root的有效UID和运行程序的任何人的真实UID下运行..现在,程序将能够以open(2)打开/etc/shadow
,但是使用access("/etc/shadow", R_OK);
EACCESS
会失败
任何人都可以教导我为什么访问(2)以它的方式工作?
答案 0 :(得分:4)
最简单的答案是 access()按照the standard所说的方式工作:
access()函数应根据amode中包含的位模式检查由path参数指向的路径名指定的文件,使用真实用户ID代替有效用户ID和实际组ID取代有效的群组ID。
该标准还描述了一个不同的函数 faccessat(),它有一个使用有效UID的选项:
AT_EACCESS
使用有效的用户和组ID而不是访问()调用中所需的真实用户和组ID来执行可访问性检查。
您还可以在某些系统上找到nonstandard function eaccess() or euidaccess(),并使用EUID进行检查。该标准谈到了这个功能,以及为什么它不是标准的一部分。
至于为什么 access()是原创设计,考虑到典型的程序实际上并不经常需要 access()。如果您想知道是否可以打开文件,可能是因为您要打开它。所以,试着打开它,看它是否有效。很少需要测试你是否可以做某事而不实际做。
标准页面的基本原理暗示 access()的原始目的:
超级用户可以完全访问系统上的所有文件。因此,超级用户启动并切换到权限较低的有效用户ID的程序无法使用access()来测试其文件访问权限。
access()的最初目的是让setuid程序测试用户是否可以在不考虑程序提升访问权限的情况下执行操作。这允许setuid程序在不放弃其升高状态的情况下限制其所做的范围。
答案 1 :(得分:0)
根据Linux手册页,"这允许set-user-ID程序轻松确定调用用户的权限。"
我认为这实际上是功能的关键。任何程序都可以尝试所需的访问类型,并在发生时处理失败。大部分都做。只有在您关心答案是否与您从“"尝试查看"”中获得的答案不同时,您才需要单独检查访问权限。方法