|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.