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

1.1       root        1: /* init.c
                      2:    Initialize the system dependent routines.
                      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 [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 "uuconf.h"
                     30: #include "system.h"
                     31: #include "sysdep.h"
                     32: 
                     33: #include <errno.h>
                     34: #include <pwd.h>
                     35: 
                     36: #if HAVE_FCNTL_H
                     37: #include <fcntl.h>
                     38: #else
                     39: #if HAVE_SYS_FILE_H
                     40: #include <sys/file.h>
                     41: #endif
                     42: #endif
                     43: 
                     44: #ifndef O_RDONLY
                     45: #define O_RDONLY 0
                     46: #define O_WRONLY 1
                     47: #define O_RDWR 2
                     48: #endif
                     49: 
                     50: #if ! HAVE_GETHOSTNAME && HAVE_UNAME
                     51: #include <sys/utsname.h>
                     52: #endif
                     53: 
                     54: /* Use getcwd in preference to getwd; if we have neither, we will be
                     55:    using a getcwd replacement.  */
                     56: #if HAVE_GETCWD
                     57: #undef HAVE_GETWD
                     58: #define HAVE_GETWD 0
                     59: #else /* ! HAVE_GETCWD */
                     60: #if ! HAVE_GETWD
                     61: #undef HAVE_GETCWD
                     62: #define HAVE_GETCWD 1
                     63: #endif /* ! HAVE_GETWD */
                     64: #endif /* ! HAVE_GETCWD */
                     65: 
                     66: #if HAVE_GETWD
                     67: /* Get a value for MAXPATHLEN.  */
                     68: #if HAVE_SYS_PARAMS_H
                     69: #include <sys/params.h>
                     70: #endif
                     71: 
                     72: #if HAVE_LIMITS_H
                     73: #include <limits.h>
                     74: #endif
                     75: 
                     76: #ifndef MAXPATHLEN
                     77: #ifdef PATH_MAX
                     78: #define MAXPATHLEN PATH_MAX
                     79: #else /* ! defined (PATH_MAX) */
                     80: #define MAXPATHLEN 1024
                     81: #endif /* ! defined (PATH_MAX) */
                     82: #endif /* ! defined (MAXPATHLEN) */
                     83: #endif /* HAVE_GETWD */
                     84: 
                     85: /* External functions.  */
                     86: #ifndef getlogin
                     87: extern char *getlogin ();
                     88: #endif
                     89: #if GETPWNAM_DECLARATION_OK
                     90: #ifndef getpwnam
                     91: extern struct passwd *getpwnam ();
                     92: #endif
                     93: #endif
                     94: #if GETPWUID_DECLARATION_OK
                     95: #ifndef getpwuid
                     96: extern struct passwd *getpwuid ();
                     97: #endif
                     98: #endif
                     99: #if HAVE_GETCWD
                    100: #ifndef getcwd
                    101: extern char *getcwd ();
                    102: #endif
                    103: #endif
                    104: #if HAVE_GETWD
                    105: #ifndef getwd
                    106: extern char *getwd ();
                    107: #endif
                    108: #endif
                    109: #if HAVE_SYSCONF
                    110: #ifndef sysconf
                    111: extern long sysconf ();
                    112: #endif
                    113: #endif
                    114: 
                    115: /* Initialize the system dependent routines.  We will probably be running
                    116:    suid to uucp, so we make sure that nothing is obviously wrong.  We
                    117:    save the login name since we will be losing the real uid.  */
                    118: static char *zSlogin;
                    119: 
                    120: /* The UUCP spool directory.  */
                    121: const char *zSspooldir;
                    122: 
                    123: /* The UUCP lock directory.  */
                    124: const char *zSlockdir;
                    125: 
                    126: /* The local UUCP name.  */
                    127: const char *zSlocalname;
                    128: 
                    129: /* We save the current directory since we will do a chdir to the
                    130:    spool directory.  */
                    131: char *zScwd;
                    132: 
                    133: /* The maximum length of a system name is controlled by the type of spool
                    134:    directory we use.  */
                    135: #if SPOOLDIR_V2 || SPOOLDIR_BSD42 || SPOOLDIR_BSD43 || SPOOLDIR_ULTRIX
                    136: size_t cSysdep_max_name_len = 7;
                    137: #endif
                    138: #if SPOOLDIR_HDB || SPOOLDIR_SVR4
                    139: size_t cSysdep_max_name_len = 14;
                    140: #endif
                    141: #if SPOOLDIR_TAYLOR
                    142: #if HAVE_LONG_FILE_NAMES
                    143: size_t cSysdep_max_name_len = 255;
                    144: #else /* ! HAVE_LONG_FILE_NAMES */
                    145: size_t cSysdep_max_name_len = 14;
                    146: #endif /* ! HAVE_LONG_FILE_NAMES */
                    147: #endif /* SPOOLDIR_TAYLOR */
                    148: 
                    149: /* Initialize the system dependent routines.  */
                    150: 
                    151: void
                    152: usysdep_initialize (puuconf,iflags)
                    153:      pointer puuconf;
                    154:      int iflags;
                    155: {
                    156:   int cdescs;
                    157:   int o;
                    158:   int iuuconf;
                    159:   char *z;
                    160:   struct passwd *q;
                    161: 
                    162:   ulog_id (getpid ());
                    163: 
                    164:   /* Close everything but stdin, stdout and stderr.  */
                    165: #if HAVE_GETDTABLESIZE
                    166:   cdescs = getdtablesize ();
                    167: #else
                    168: #if HAVE_SYSCONF
                    169:   cdescs = sysconf (_SC_OPEN_MAX);
                    170: #else
                    171: #ifdef OPEN_MAX
                    172:   cdescs = OPEN_MAX;
                    173: #else
                    174: #ifdef NOFILE
                    175:   cdescs = NOFILE;
                    176: #else
                    177:   cdescs = 20;
                    178: #endif /* ! defined (NOFILE) */
                    179: #endif /* ! defined (OPEN_MAX) */
                    180: #endif /* ! HAVE_SYSCONF */
                    181: #endif /* ! HAVE_GETDTABLESIZE */
                    182: 
                    183:   for (o = 3; o < cdescs; o++)
                    184:     (void) close (o);
                    185: 
                    186:   /* Make sure stdin, stdout and stderr are open.  */
                    187:   if (fcntl (0, F_GETFD, 0) < 0
                    188:       && open ((char *) "/dev/null", O_RDONLY, 0) != 0)
                    189:     exit (EXIT_FAILURE);
                    190:   if (fcntl (1, F_GETFD, 0) < 0
                    191:       && open ((char *) "/dev/null", O_WRONLY, 0) != 1)
                    192:     exit (EXIT_FAILURE);
                    193:   if (fcntl (2, F_GETFD, 0) < 0
                    194:       && open ((char *) "/dev/null", O_WRONLY, 0) != 2)
                    195:     exit (EXIT_FAILURE);
                    196: 
                    197:   iuuconf = uuconf_spooldir (puuconf, &zSspooldir);
                    198:   if (iuuconf != UUCONF_SUCCESS)
                    199:     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
                    200: 
                    201:   iuuconf = uuconf_lockdir (puuconf, &zSlockdir);
                    202:   if (iuuconf != UUCONF_SUCCESS)
                    203:     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
                    204: 
                    205:   iuuconf = uuconf_localname (puuconf, &zSlocalname);
                    206:   if (iuuconf == UUCONF_NOT_FOUND)
                    207:     {
                    208: #if HAVE_GETHOSTNAME
                    209:       char ab[256];
                    210: 
                    211:       if (gethostname (ab, sizeof ab - 1) < 0)
                    212:        ulog (LOG_FATAL, "gethostname: %s", strerror (errno));
                    213:       ab[sizeof ab - 1] = '\0';
                    214:       ab[strcspn (ab, ".")] = '\0';
                    215:       zSlocalname = zbufcpy (ab);
                    216: #else /* ! HAVE_GETHOSTNAME */
                    217: #if HAVE_UNAME
                    218:       struct utsname s;
                    219: 
                    220:       if (uname (&s) < 0)
                    221:        ulog (LOG_FATAL, "uname: %s", strerror (errno));
                    222:       zSlocalname = zbufcpy (s.nodename);
                    223: #else /* ! HAVE_UNAME */
                    224:       ulog (LOG_FATAL, "Don't know how to get local node name");
                    225: #endif /* ! HAVE_UNAME */
                    226: #endif /* ! HAVE_GETHOSTNAME */
                    227:     }
                    228:   else if (iuuconf != UUCONF_SUCCESS)
                    229:     ulog_uuconf (LOG_FATAL, puuconf, iuuconf);
                    230: 
                    231:   /* We always set our file modes to exactly what we want.  */
                    232:   umask (0);
                    233: 
                    234:   /* Get the login name, making sure that it matches the uid.  Many
                    235:      systems truncate the getlogin return value to 8 characters, but
                    236:      keep the full name in the password file, so we prefer the name in
                    237:      the password file.  */
                    238:   z = getenv ("LOGNAME");
                    239:   if (z == NULL)
                    240:     z = getenv ("USER");
                    241:   if (z == NULL)
                    242:     z = getlogin ();
                    243:   if (z == NULL)
                    244:     q = NULL;
                    245:   else
                    246:     {
                    247:       q = getpwnam (z);
                    248:       if (q != NULL)
                    249:        z = q->pw_name;
                    250:     }
                    251:   if (q == NULL || q->pw_uid != getuid ())
                    252:     {
                    253:       q = getpwuid (getuid ());
                    254:       if (q == NULL)
                    255:        z = NULL;
                    256:       else
                    257:        z = q->pw_name;
                    258:     }
                    259:   if (z != NULL)
                    260:     zSlogin = zbufcpy (z);
                    261: 
                    262:   /* On some old systems, an suid program run by root is started with
                    263:      an euid of 0.  If this happens, we look up the uid we should have
                    264:      and set ourselves to it manually.  This means that on such a
                    265:      system root will not be able to uucp or uux files that are not
                    266:      readable by uucp.  */
                    267:   if ((iflags & INIT_SUID) != 0
                    268:       && geteuid () == 0)
                    269:     {
                    270:       q = getpwnam (OWNER);
                    271:       if (q != NULL)
                    272:        setuid (q->pw_uid);
                    273:     }
                    274: 
                    275:   if ((iflags & INIT_GETCWD) != 0)
                    276:     {
                    277:       const char *zenv;
                    278:       struct stat senv, sdot;
                    279: 
                    280:       /* Get the current working directory.  We have to get it now,
                    281:         since we're about to do a chdir.  We use PWD if it's defined
                    282:         and if it really names the working directory, since if it's
                    283:         not the same as whatever getcwd returns it's probably more
                    284:         appropriate.  */
                    285:       zenv = getenv ("PWD");
                    286:       if (zenv != NULL
                    287:          && stat ((char *) zenv, &senv) == 0
                    288:          && stat ((char *) ".", &sdot) == 0
                    289:          && senv.st_ino == sdot.st_ino
                    290:          && senv.st_dev == sdot.st_dev)
                    291:        zScwd = zbufcpy (zenv);
                    292:       else
                    293:        {
                    294: 
                    295: #if HAVE_GETCWD
                    296:          {
                    297:            size_t c;
                    298: 
                    299:            c = 128;
                    300:            while (TRUE)
                    301:              {
                    302:                zScwd = (char *) xmalloc (c);
                    303:                if (getcwd (zScwd, c) != NULL)
                    304:                  break;
                    305:                xfree ((pointer) zScwd);
                    306:                zScwd = NULL;
                    307:                if (errno != ERANGE)
                    308:                  break;
                    309:                c <<= 1;
                    310:              }
                    311:          }
                    312: #endif /* HAVE_GETCWD */
                    313: 
                    314: #if HAVE_GETWD
                    315:          zScwd = (char *) xmalloc (MAXPATHLEN);
                    316:          if (getwd (zScwd) == NULL)
                    317:            {
                    318:              xfree ((pointer) zScwd);
                    319:              zScwd = NULL;
                    320:            }
                    321: #endif /* HAVE_GETWD */
                    322: 
                    323:          if (zScwd != NULL)
                    324:            zScwd = (char *) xrealloc ((pointer) zScwd,
                    325:                                       strlen (zScwd) + 1);
                    326:        }
                    327:     }
                    328: 
                    329:   if ((iflags & INIT_NOCHDIR) == 0)
                    330:     {
                    331:       /* Connect to the spool directory, and create it if it doesn't
                    332:         exist.  */
                    333:       if (chdir (zSspooldir) < 0)
                    334:        {
                    335:          if (errno == ENOENT
                    336:              && mkdir ((char *) zSspooldir, IDIRECTORY_MODE) < 0)
                    337:            ulog (LOG_FATAL, "mkdir (%s): %s", zSspooldir,
                    338:                  strerror (errno));
                    339:          if (chdir (zSspooldir) < 0)
                    340:            ulog (LOG_FATAL, "chdir (%s): %s", zSspooldir,
                    341:                  strerror (errno));
                    342:        }
                    343:     }
                    344: }
                    345: 
                    346: /* Exit the program.  */
                    347: 
                    348: void
                    349: usysdep_exit (fsuccess)
                    350:      boolean fsuccess;
                    351: {
                    352:   exit (fsuccess ? EXIT_SUCCESS : EXIT_FAILURE);
                    353: }
                    354: 
                    355: /* This is called when a non-standard configuration file is used, to
                    356:    make sure the program doesn't hand out privileged file access.
                    357:    This means that to test non-standard configuration files, you
                    358:    should be logged in as uucp.  This is called before
                    359:    usysdep_initialize.  It ensures that someone can't simply use an
                    360:    alternate configuration file to steal UUCP transfers from other
                    361:    systems.  This will still permit people to set up their own
                    362:    configuration file and pretend to be whatever system they choose.
                    363:    The only real security is to use a high level of protection on the
                    364:    modem ports.  */
                    365: 
                    366: /*ARGSUSED*/
                    367: boolean fsysdep_other_config (z)
                    368:      const char *z;
                    369: {
                    370:   (void) setuid (getuid ());
                    371:   (void) setgid (getgid ());
                    372:   return TRUE;
                    373: }
                    374: 
                    375: /* Get the node name to use if it was not specified in the configuration
                    376:    file.  */
                    377: 
                    378: const char *
                    379: zsysdep_localname ()
                    380: {
                    381:   return zSlocalname;
                    382: }
                    383: 
                    384: /* Get the login name.  We actually get the login name in
                    385:    usysdep_initialize, because after that we may switch away from the
                    386:    real uid.  */
                    387: 
                    388: const char *
                    389: zsysdep_login_name ()
                    390: {
                    391:   if (zSlogin == NULL)
                    392:     ulog (LOG_FATAL, "Can't get login name");
                    393:   return zSlogin;
                    394: }

unix.superglobalmegacorp.com

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