如我们前面的描述,当我们打开一个文件,内核执行存取测试基于有效的用户ID和组id。there are times(有时)进程想测试基于实际用户ID和组ID.This is useful when a process is running as someone else,using either the set-user-ID or the set-group-ID feature.即使进程可以设置用户ID为root,它仍可能想要验证实际用户能否存取一个给定的文件。access 函数基于测试实际用户ID和组ID.(在4.5节最后四步用有效的替换实际的)
#include <unistd.h>
int access(const char *pathname, int mode);
returns: 0 if ok,1 on error
mode是按位或图4.7中的任意常量
figure 4.7 the mode constants for access function
mode Description
R_OK test for read permission
W_OK test for write permission
X_OK test for execute permission
F_OK test for existence of file (测试文件是否存在)
例如:
图4.8显示了access函数的使用
here is a sample session with this program:
$ ls -l a.out
-rwxrwxr-x 1 sar 15945 Nov 30 12:10 a.out
$ ./a.out a.out
read access OK
open for reading OK
$ ls -l /etc/shadow
-r-------- 1 root 1315 Jul 17 2002 /etc/shadow
$ ./a.out /etc/shadow
access error for /etc/shadow: Permission denied
open error for /etc/shadow: Permission denied
$ su become superuser
Password: enter superuser password
# chown root a.out change file's user ID to root
# chmod u+s a.out and turn on set-user-ID bit
# ls -l a.out check owner and SUID bit
-rwsrwxr-x 1 root 15945 Nov 30 12:10 a.out
# exit go back to normal user
$ ./a.out /etc/shadow
access error for /etc/shadow: Permission denied
open for reading OK
在这个例子中,set-user-ID 程序能决定实际的用户不能读文件,即使OPEN函数成功。
Figure 4.8. Example of access function
#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);
}
在前面的例子中和第八章中,我们将有时转换成超级用户,为了示范如何工作。如果你在多用户系统上并且没有超级用户权限,你就不能完成这样的例子了。