diff options
Diffstat (limited to 'gnu/libexec/uucp/libunix/access.c')
| -rw-r--r-- | gnu/libexec/uucp/libunix/access.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/gnu/libexec/uucp/libunix/access.c b/gnu/libexec/uucp/libunix/access.c new file mode 100644 index 000000000000..c2c0eef21084 --- /dev/null +++ b/gnu/libexec/uucp/libunix/access.c @@ -0,0 +1,83 @@ +/* access.c + Check access to files by the user and by the daemon. */ + +#include "uucp.h" + +#include "uudefs.h" +#include "sysdep.h" +#include "system.h" + +#include <errno.h> + +/* See if the user has access to a file, to prevent the setuid uucp + and uux programs handing out unauthorized access. */ + +boolean +fsysdep_access (zfile) + const char *zfile; +{ + if (access (zfile, R_OK) == 0) + return TRUE; + ulog (LOG_ERROR, "%s: %s", zfile, strerror (errno)); + return FALSE; +} + +/* See if the daemon has access to a file. This is called if a file + is not being transferred to the spool directory, since if the + daemon does not have access the later transfer will fail. We + assume that the daemon will have the same euid (or egid) as the one + we are running under. If our uid (gid) and euid (egid) are the + same, we assume that we have access. Note that is not important + for security, since the check will be (implicitly) done again when + the daemon tries to transfer the file. This routine should work + whether the UUCP programs are installed setuid or setgid. */ + +boolean +fsysdep_daemon_access (zfile) + const char *zfile; +{ + struct stat s; + uid_t ieuid, iuid, iegid, igid; + boolean fok; + + ieuid = geteuid (); + if (ieuid == 0) + return TRUE; + iuid = getuid (); + iegid = getegid (); + igid = getgid (); + + /* If our effective uid and gid are the same as our real uid and + gid, we assume the daemon will have access to the file. */ + if (ieuid == iuid && iegid == igid) + return TRUE; + + if (stat ((char *) zfile, &s) != 0) + { + ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno)); + return FALSE; + } + + /* If our euid is not our uid, but it is the file's uid, see if the + owner has read access. Otherwise, if our egid is not our gid, + but it is the file's gid, see if the group has read access. + Otherwise, see if the world has read access. We know from the + above check that at least one of our euid and egid are different, + so that is the only one we want to check. This check could fail + if the UUCP programs were both setuid and setgid, but why would + they be? */ + if (ieuid != iuid && ieuid == s.st_uid) + fok = (s.st_mode & S_IRUSR) != 0; + else if (iegid != igid && iegid == s.st_gid) + fok = (s.st_mode & S_IRGRP) != 0; + else + fok = (s.st_mode & S_IROTH) != 0; + + if (! fok) + { + ulog (LOG_ERROR, "%s: cannot be read by daemon", zfile); + return FALSE; + } + + return TRUE; +} |
