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