Annotation of coherent/g/usr/lib/uucp/tay104/unix/ufopen.c, revision 1.1.1.1

1.1       root        1: /* ufopen.c
                      2:    Open a file with the permissions of the invoking user.
                      3: 
                      4:    Copyright (C) 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 [email protected] or
                     23:    c/o Infinity Development Systems, P.O. Box 520, Waltham, MA 02254.
                     24:    */
                     25: 
                     26: #include "uucp.h"
                     27: 
                     28: #include "uudefs.h"
                     29: #include "sysdep.h"
                     30: #include "system.h"
                     31: 
                     32: #include <errno.h>
                     33: 
                     34: #if HAVE_FCNTL_H
                     35: #include <fcntl.h>
                     36: #else
                     37: #if HAVE_SYS_FILE_H
                     38: #include <sys/file.h>
                     39: #endif
                     40: #endif
                     41: 
                     42: #ifndef O_RDONLY
                     43: #define O_RDONLY 0
                     44: #define O_WRONLY 1
                     45: #define O_RDWR 2
                     46: #endif
                     47: 
                     48: #ifndef O_NOCTTY
                     49: #define O_NOCTTY 0
                     50: #endif
                     51: 
                     52: #ifndef FD_CLOEXEC
                     53: #define FD_CLOEXEC 1
                     54: #endif
                     55: 
                     56: /* Local functions.  */
                     57: 
                     58: static boolean fsuser_perms P((uid_t *pieuid));
                     59: static boolean fsuucp_perms P((long ieuid));
                     60: 
                     61: /* Switch to permissions of the invoking user.  */
                     62: 
                     63: static boolean
                     64: fsuser_perms (pieuid)
                     65:      uid_t *pieuid;
                     66: {
                     67:   uid_t ieuid, iuid;
                     68: 
                     69:   ieuid = geteuid ();
                     70:   iuid = getuid ();
                     71:   if (pieuid != NULL)
                     72:     *pieuid = ieuid;
                     73: 
                     74: #if HAVE_SETREUID
                     75:   /* Swap the effective user id and the real user id.  We can then
                     76:      swap them back again when we want to return to the uucp user's
                     77:      permissions.  */
                     78:   if (setreuid (ieuid, iuid) < 0)
                     79:     {
                     80:       ulog (LOG_ERROR, "setreuid (%ld, %ld): %s",
                     81:            (long) ieuid, (long) iuid, strerror (errno));
                     82:       return FALSE;
                     83:     }
                     84: #else /* ! HAVE_SETREUID */
                     85: #if HAVE_SAVED_SETUID
                     86:   /* Set the effective user id to the real user id.  Since the
                     87:      effective user id is saved (it's the saved setuid) we will able
                     88:      to set back to it later.  If the real user id is root we will not
                     89:      be able to switch back and forth, so don't even try.  */
                     90:   if (iuid != 0)
                     91:     {
                     92:       if (setuid (iuid) < 0)
                     93:        {
                     94:          ulog (LOG_ERROR, "setuid (%ld): %s", (long) iuid, strerror (errno));
                     95:          return FALSE;
                     96:        }
                     97:     }
                     98: #else /* ! HAVE_SAVED_SETUID */
                     99:   /* There's no way to switch between real permissions and effective
                    100:      permissions.  Just try to open the file with the uucp
                    101:      permissions.  */
                    102: #endif /* ! HAVE_SAVED_SETUID */
                    103: #endif /* ! HAVE_SETREUID */
                    104: 
                    105:   return TRUE;
                    106: }
                    107: 
                    108: /* Restore the uucp permissions.  */
                    109: 
                    110: /*ARGSUSED*/
                    111: static boolean
                    112: fsuucp_perms (ieuid)
                    113:      long ieuid;
                    114: {
                    115: #if HAVE_SETREUID
                    116:   /* Swap effective and real user id's back to what they were.  */
                    117:   if (! fsuser_perms ((uid_t *) NULL))
                    118:     return FALSE;
                    119: #else /* ! HAVE_SETREUID */
                    120: #if HAVE_SAVED_SETUID
                    121:   /* Set ourselves back to our original effective user id.  */
                    122:   if (setuid ((uid_t) ieuid) < 0)
                    123:     {
                    124:       ulog (LOG_ERROR, "setuid (%ld): %s", (long) ieuid, strerror (errno));
                    125:       /* Is this error message helpful or confusing?  */
                    126:       if (errno == EPERM)
                    127:        ulog (LOG_ERROR,
                    128:              "Probably HAVE_SAVED_SETUID in policy.h should be set to 0");
                    129:       return FALSE;
                    130:     }
                    131: #else /* ! HAVE_SAVED_SETUID */
                    132:   /* We didn't switch, no need to switch back.  */
                    133: #endif /* ! HAVE_SAVED_SETUID */
                    134: #endif /* ! HAVE_SETREUID */
                    135: 
                    136:   return TRUE;
                    137: }
                    138: 
                    139: /* Open a file with the permissions of the invoking user.  Ignore the
                    140:    fbinary argument since Unix has no distinction between text and
                    141:    binary files.  */
                    142: 
                    143: /*ARGSUSED*/
                    144: openfile_t
                    145: esysdep_user_fopen (zfile, frd, fbinary)
                    146:      const char *zfile;
                    147:      boolean frd;
                    148:      boolean fbinary;
                    149: {
                    150:   uid_t ieuid;
                    151:   openfile_t e;
                    152:   const char *zerr;
                    153:   int o = 0;
                    154: 
                    155:   if (! fsuser_perms (&ieuid))
                    156:     return EFILECLOSED;
                    157: 
                    158:   zerr = NULL;
                    159: 
                    160: #if USE_STDIO
                    161:   e = fopen (zfile, frd ? "r" : "w");
                    162:   if (e == NULL)
                    163:     zerr = "fopen";
                    164:   else
                    165:     o = fileno (e);
                    166: #else
                    167:   if (frd)
                    168:     {
                    169:       e = open ((char *) zfile, O_RDONLY | O_NOCTTY, 0);
                    170:       zerr = "open";
                    171:     }
                    172:   else
                    173:     {
                    174:       e = creat ((char *) zfile, IPUBLIC_FILE_MODE);
                    175:       zerr = "creat";
                    176:     }
                    177:   if (e >= 0)
                    178:     {
                    179:       o = e;
                    180:       zerr = NULL;
                    181:     }
                    182: #endif
                    183: 
                    184:   if (! fsuucp_perms ((long) ieuid))
                    185:     {
                    186:       if (ffileisopen (e))
                    187:        (void) ffileclose (e);
                    188:       return EFILECLOSED;
                    189:     }
                    190: 
                    191:   if (zerr != NULL)
                    192:     {
                    193:       ulog (LOG_ERROR, "%s (%s): %s", zerr, zfile, strerror (errno));
                    194: #if ! HAVE_SETREUID
                    195:       /* Are these error messages helpful or confusing?  */
                    196: #if HAVE_SAVED_SETUID
                    197:       if (errno == EACCES && getuid () == 0)
                    198:        ulog (LOG_ERROR,
                    199:              "The superuser may only transfer files that are readable by %s",
                    200:              OWNER);
                    201: #else
                    202:       if (errno == EACCES)
                    203:        ulog (LOG_ERROR,
                    204:              "You may only transfer files that are readable by %s", OWNER);
                    205: #endif
                    206: #endif /* ! HAVE_SETREUID */
                    207:       return EFILECLOSED;
                    208:     }
                    209: 
                    210:   if (fcntl (o, F_SETFD, fcntl (o, F_GETFD, 0) | FD_CLOEXEC) < 0)
                    211:     {
                    212:       ulog (LOG_ERROR, "fcntl (FD_CLOEXEC): %s", strerror (errno));
                    213:       (void) ffileclose (e);
                    214:       return EFILECLOSED;
                    215:     }
                    216: 
                    217:   return e;
                    218: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.