xref: /386bsd/usr/src/libexec/uucp/sys6.c (revision a2142627)
1 /* sys6.unx
2    System dependent routines to deal with local file names.
3 
4    Copyright (C) 1991, 1992 Ian Lance Taylor
5 
6    This file is part of the Taylor UUCP package.
7 
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2 of the
11    License, or (at your option) any later version.
12 
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17 
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 
22    The author of the program may be contacted at ian@airs.com or
23    c/o AIRS, P.O. Box 520, Waltham, MA 02254.
24 
25    $Log: sys6.unx,v $
26    Revision 1.9  1992/02/27  19:51:55  ian
27    Added extern for stat
28 
29    Revision 1.8  1992/02/08  22:33:32  ian
30    Only get the current working directory if it's going to be needed
31 
32    Revision 1.7  1992/02/08  03:54:18  ian
33    Include <string.h> only in <uucp.h>, added 1992 copyright
34 
35    Revision 1.6  1992/02/02  20:34:36  ian
36    Niels Baggesen: must check user permissions on access to local files
37 
38    Revision 1.5  1991/12/22  22:14:19  ian
39    Monty Solomon: added HAVE_UNISTD_H configuration parameter
40 
41    Revision 1.4  1991/12/14  16:09:07  ian
42    Added -l option to uux to link files into the spool directory
43 
44    Revision 1.3  1991/12/06  22:50:01  ian
45    Franc,ois Pinard: getcwd may legitimately fail in usysdep_initialize
46 
47    Revision 1.2  1991/11/13  23:08:40  ian
48    Expand remote pathnames in uucp and uux; fix up uux special cases
49 
50    Revision 1.1  1991/09/10  19:45:50  ian
51    Initial revision
52 
53    */
54 
55 #include "uucp.h"
56 
57 #if USE_RCS_ID
58 char sys6_unx_rcsid[] = "$Id: sys6.unx,v 1.9 1992/02/27 19:51:55 ian Rel $";
59 #endif
60 
61 #include <errno.h>
62 
63 #if USE_STDIO && HAVE_UNISTD_H
64 #include <unistd.h>
65 #endif
66 
67 #include "system.h"
68 #include "sysdep.h"
69 
70 /* We need R_OK.  */
71 #ifndef R_OK
72 #define R_OK 4
73 #endif
74 
75 /* We need some mode access macros.  */
76 #ifndef S_IRUSR
77 #define S_IRUSR (0400)
78 #define S_IRGRP (0040)
79 #define S_IROTH (0004)
80 #endif /* ! defined (S_IRUSR) */
81 
82 /* External functions.  */
83 extern int access (), link (), stat ();
84 extern uid_t getuid (), getgid (), geteuid (), getegid ();
85 
86 /* See whether running this file through zsysdep_add_cwd would require
87    knowing the current working directory.  This is used to avoid
88    determining the cwd if it will not be needed.  */
89 
90 boolean
91 fsysdep_needs_cwd (zfile)
92      const char *zfile;
93 {
94   return *zfile != '/' && *zfile != '~';
95 }
96 
97 /* Add the current working directory to a file name, if no directory
98    has been specified.  We do ~ expansion here.  */
99 
100 const char *
101 zsysdep_add_cwd (zfile, flocal)
102      const char *zfile;
103      boolean flocal;
104 {
105   if (*zfile == '/')
106     return zfile;
107   if (*zfile == '~')
108     {
109       if (flocal)
110 	return zstilde_expand (&sLocalsys, zfile);
111       else
112 	return zfile;
113     }
114 
115 #if DEBUG > 0
116   if (zScwd == NULL)
117     ulog (LOG_FATAL, "zsysdep_add_cwd: No cwd");
118 #endif
119 
120   return zsappend (zScwd, zfile);
121 }
122 
123 /* Get the base name of a file name.  */
124 
125 const char *
126 zsysdep_base_name (zfile)
127      const char *zfile;
128 {
129   const char *z;
130 
131   z = strrchr (zfile, '/');
132   if (z != NULL)
133     return z + 1;
134   return zfile;
135 }
136 
137 /* See if the user has access to a file, to prevent the setuid uucp
138    and uux programs handing out unauthorized access.  */
139 
140 boolean
141 fsysdep_access (zfile)
142      const char *zfile;
143 {
144   if (access (zfile, R_OK) == 0)
145     return TRUE;
146   ulog (LOG_ERROR, "%s: %s", zfile, strerror (errno));
147   return FALSE;
148 }
149 
150 /* See if the daemon has access to a file.  This is called if a file
151    is not being transferred to the spool directory, since if the
152    daemon does not have access the later transfer will fail.  We
153    assume that the daemon will have the same euid (or egid) as the one
154    we are running under.  If our uid (gid) and euid (egid) are the
155    same, we assume that we have access.  Note that is not important
156    for security, since the check will be (implicitly) done again when
157    the daemon tries to transfer the file.  This routine should work
158    whether the UUCP programs are installed setuid or setgid.  */
159 
160 boolean
161 fsysdep_daemon_access (zfile)
162      const char *zfile;
163 {
164   struct stat s;
165   uid_t ieuid, iuid, iegid, igid;
166   boolean fok;
167 
168   ieuid = geteuid ();
169   if (ieuid == 0)
170     return TRUE;
171   iuid = getuid ();
172   iegid = getegid ();
173   igid = getgid ();
174 
175   /* If our effective uid and gid are the same as our real uid and
176      gid, we assume the daemon will have access to the file.  */
177   if (ieuid == iuid && iegid == igid)
178     return TRUE;
179 
180  if (stat (zfile, &s) != 0)
181      {
182       ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno));
183       return FALSE;
184     }
185 
186   /* If our euid is not our uid, but it is the file's uid, see if the
187      owner has read access.  Otherwise, if our egid is not our gid,
188      but it is the file's gid, see if the group has read access.
189      Otherwise, see if the world has read access.  We know from the
190      above check that at least one of our euid and egid are different,
191      so that is the only one we want to check.  This check could fail
192      if the UUCP programs were both setuid and setgid, but why would
193      they be?  */
194   if (ieuid != iuid && ieuid == s.st_uid)
195     fok = (s.st_mode & S_IRUSR) != 0;
196   else if (iegid != igid && iegid == s.st_gid)
197     fok = (s.st_mode & S_IRGRP) != 0;
198   else
199     fok = (s.st_mode & S_IROTH) != 0;
200 
201   if (! fok)
202     {
203       ulog (LOG_ERROR, "%s: cannot be read by daemon", zfile);
204       return FALSE;
205     }
206 
207   return TRUE;
208 }
209 
210 /* Link two files.  This in here because it's only called by uux.  */
211 
212 boolean
213 fsysdep_link (zfrom, zto, pfworked)
214      const char *zfrom;
215      const char *zto;
216      boolean *pfworked;
217 {
218   if (link (zfrom, zto) == 0)
219     {
220       *pfworked = TRUE;
221       return TRUE;
222     }
223   *pfworked = FALSE;
224   return errno == EXDEV;
225 }
226 
227 /*
228   Local variables:
229   mode:c
230   End:
231   */
232