NetBSD/gnu/libexec/uucp/sys6.unx

235 lines
6.1 KiB
Plaintext
Raw Normal View History

1993-03-21 12:45:37 +03:00
/* sys6.unx
System dependent routines to deal with local file names.
Copyright (C) 1991, 1992 Ian Lance Taylor
This file is part of the Taylor UUCP package.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
The author of the program may be contacted at ian@airs.com or
c/o AIRS, P.O. Box 520, Waltham, MA 02254.
$Log: sys6.unx,v $
Revision 1.1.1.1 1993/03/21 09:45:37 cgd
initial import of 386bsd-0.1 sources
Revision 1.9 1992/02/27 19:51:55 ian
Added extern for stat
Revision 1.8 1992/02/08 22:33:32 ian
Only get the current working directory if it's going to be needed
Revision 1.7 1992/02/08 03:54:18 ian
Include <string.h> only in <uucp.h>, added 1992 copyright
Revision 1.6 1992/02/02 20:34:36 ian
Niels Baggesen: must check user permissions on access to local files
Revision 1.5 1991/12/22 22:14:19 ian
Monty Solomon: added HAVE_UNISTD_H configuration parameter
Revision 1.4 1991/12/14 16:09:07 ian
Added -l option to uux to link files into the spool directory
Revision 1.3 1991/12/06 22:50:01 ian
Franc,ois Pinard: getcwd may legitimately fail in usysdep_initialize
Revision 1.2 1991/11/13 23:08:40 ian
Expand remote pathnames in uucp and uux; fix up uux special cases
Revision 1.1 1991/09/10 19:45:50 ian
Initial revision
*/
#include "uucp.h"
#if USE_RCS_ID
char sys6_unx_rcsid[] = "$Id: sys6.unx,v 1.1.1.1 1993/03/21 09:45:37 cgd Exp $";
#endif
#include <errno.h>
#if USE_STDIO && HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "system.h"
#include "sysdep.h"
/* We need R_OK. */
#ifndef R_OK
#define R_OK 4
#endif
/* We need some mode access macros. */
#ifndef S_IRUSR
#define S_IRUSR (0400)
#define S_IRGRP (0040)
#define S_IROTH (0004)
#endif /* ! defined (S_IRUSR) */
/* External functions. */
extern int access (), link (), stat ();
extern uid_t getuid (), getgid (), geteuid (), getegid ();
/* See whether running this file through zsysdep_add_cwd would require
knowing the current working directory. This is used to avoid
determining the cwd if it will not be needed. */
boolean
fsysdep_needs_cwd (zfile)
const char *zfile;
{
return *zfile != '/' && *zfile != '~';
}
/* Add the current working directory to a file name, if no directory
has been specified. We do ~ expansion here. */
const char *
zsysdep_add_cwd (zfile, flocal)
const char *zfile;
boolean flocal;
{
if (*zfile == '/')
return zfile;
if (*zfile == '~')
{
if (flocal)
return zstilde_expand (&sLocalsys, zfile);
else
return zfile;
}
#if DEBUG > 0
if (zScwd == NULL)
ulog (LOG_FATAL, "zsysdep_add_cwd: No cwd");
#endif
return zsappend (zScwd, zfile);
}
/* Get the base name of a file name. */
const char *
zsysdep_base_name (zfile)
const char *zfile;
{
const char *z;
z = strrchr (zfile, '/');
if (z != NULL)
return z + 1;
return zfile;
}
/* 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 (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;
}
/* Link two files. This in here because it's only called by uux. */
boolean
fsysdep_link (zfrom, zto, pfworked)
const char *zfrom;
const char *zto;
boolean *pfworked;
{
if (link (zfrom, zto) == 0)
{
*pfworked = TRUE;
return TRUE;
}
*pfworked = FALSE;
return errno == EXDEV;
}
/*
Local variables:
mode:c
End:
*/