235 lines
6.1 KiB
Plaintext
235 lines
6.1 KiB
Plaintext
|
/* 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:
|
|||
|
*/
|