Advanced Programming in the UNIX Environment, Second Edition (Addison-Wesley Professional Computing Series)

4.7. access Function

As we described earlier, when we open a file, the kernel performs its access tests based on the effective user and group IDs. There are times when a process wants to test accessibility based on the real user and group IDs. This is useful when a process is running as someone else, using either the set-user-ID or the set-group-ID feature. Even though a process might be set-user-ID to root, it could still want to verify that the real user can access a given file. The access function bases its tests on the real user and group IDs. (Replace effective with real in the four steps at the end of Section 4.5.)

#include <unistd.h> int access(const char *pathname, int mode);

Returns: 0 if OK, 1 on error

The mode is the bitwise OR of any of the constants shown in Figure 4.7.

Figure 4.7. The mode constants for access function, from <unistd.h>

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

Example

Figure 4.8 shows the use of the access function.

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

In this example, the set-user-ID program can determine that the real user cannot normally read the file, even though the open function will succeed.

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); }

In the preceding example and in Chapter 8, we'll sometimes switch to become the superuser, to demonstrate how something works. If you're on a multiuser system and do not have superuser permission, you won't be able to duplicate these examples completely.

    Категории