1/* ufopen.c 2 Open a file with the permissions of the invoking user. 3 4 Copyright (C) 1992, 1995, 2002 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA. 21 22 The author of the program may be contacted at ian@airs.com. 23 */ 24 25#include "uucp.h" 26 27#include "uudefs.h" 28#include "sysdep.h" 29#include "system.h" 30 31#include <errno.h> 32 33#if HAVE_FCNTL_H 34#include <fcntl.h> 35#else 36#if HAVE_SYS_FILE_H 37#include <sys/file.h> 38#endif 39#endif 40 41#ifndef O_RDONLY 42#define O_RDONLY 0 43#define O_WRONLY 1 44#define O_RDWR 2 45#endif 46 47#ifndef O_NOCTTY 48#define O_NOCTTY 0 49#endif 50 51#ifndef FD_CLOEXEC 52#define FD_CLOEXEC 1 53#endif 54 55/* Open a file with the permissions of the invoking user. Ignore the 56 fbinary argument since Unix has no distinction between text and 57 binary files. */ 58 59/*ARGSUSED*/ 60openfile_t 61esysdep_user_fopen (zfile, frd, fbinary) 62 const char *zfile; 63 boolean frd; 64 boolean fbinary ATTRIBUTE_UNUSED; 65{ 66 uid_t ieuid; 67 gid_t iegid; 68 openfile_t e; 69 const char *zerr; 70 int o = 0; 71 72 if (! fsuser_perms (&ieuid, &iegid)) 73 return EFILECLOSED; 74 75 zerr = NULL; 76 77#if USE_STDIO 78 e = fopen (zfile, frd ? "r" : "w"); 79 if (e == NULL) 80 zerr = "fopen"; 81 else 82 o = fileno (e); 83#else 84 if (frd) 85 { 86 e = open ((char *) zfile, O_RDONLY | O_NOCTTY, 0); 87 zerr = "open"; 88 } 89 else 90 { 91 e = creat ((char *) zfile, IPUBLIC_FILE_MODE); 92 zerr = "creat"; 93 } 94 if (e >= 0) 95 { 96 o = e; 97 zerr = NULL; 98 } 99#endif 100 101 if (! fsuucp_perms ((long) ieuid, (long) iegid)) 102 { 103 if (ffileisopen (e)) 104 (void) ffileclose (e); 105 return EFILECLOSED; 106 } 107 108 if (zerr != NULL) 109 { 110 ulog (LOG_ERROR, "%s (%s): %s", zerr, zfile, strerror (errno)); 111#if ! HAVE_SETREUID 112 /* Are these error messages helpful or confusing? */ 113#if HAVE_SAVED_SETUID 114 if (errno == EACCES && getuid () == 0) 115 ulog (LOG_ERROR, 116 "The superuser may only transfer files that are readable by %s", 117 OWNER); 118#else 119 if (errno == EACCES) 120 ulog (LOG_ERROR, 121 "You may only transfer files that are readable by %s", OWNER); 122#endif 123#endif /* ! HAVE_SETREUID */ 124 return EFILECLOSED; 125 } 126 127 if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0) 128 { 129 ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno)); 130 (void) ffileclose (e); 131 return EFILECLOSED; 132 } 133 134 return e; 135} 136