|
|
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.