As we described earlier, when we open a file, the Kernel performs its access tests based on the valid 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 cocould still want to verify that the real user can access a given file. theAccessFunction bases its tests on the real user and group IDs. (replaceValidWithRealIn the four steps at the end of section 4.5 .)
# Include <unistd. h> Int access (const char *Pathname, IntMode); |
Returns: 0 if OK, 1 on Error |
TheModeIs the bitwise or of any of the constants shown in
Figure 4.7.
Figure 4.7.Mode
ConstantsAccessFunction, 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 File |
Example
Figure 4.8 shows the use
OfAccessFunction.
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 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 thoughOpenFunction will succeed (we can still read data from the opened file, access function is only for testing which doesn't stop you from actual reading ).
Figure 4.8. Example Access Function
# Include "apue. H" # include <fcntl. h> intmain (INT argc, char * argv []) {If (argc! = 2) err_quit ("Usage:. 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 ");
// If (read (FD, Buf, 20) <0)
// Err_sys ("read data error ");
// Else
// Printf ("\" % s \ "read", Buf );
Exit (0 );}