diff options
| author | Peter Wemm <peter@FreeBSD.org> | 1997-06-27 14:53:01 +0000 |
|---|---|---|
| committer | Peter Wemm <peter@FreeBSD.org> | 1997-06-27 14:53:01 +0000 |
| commit | f3a1fc342b4423150f71e23e50f24d073a6d238b (patch) | |
| tree | a5e7dee2f9ff41f2d43580f859a6e8970722fa7d /usr.sbin/sendmail/src/main.c | |
| parent | 52c4d6f5d6bb1ffd8b30c0429fc18d371856a062 (diff) | |
Notes
Diffstat (limited to 'usr.sbin/sendmail/src/main.c')
| -rw-r--r-- | usr.sbin/sendmail/src/main.c | 193 |
1 files changed, 116 insertions, 77 deletions
diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c index 3c30fb3e6173..880b181ca25f 100644 --- a/usr.sbin/sendmail/src/main.c +++ b/usr.sbin/sendmail/src/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1983, 1995, 1996 Eric P. Allman + * Copyright (c) 1983, 1995-1997 Eric P. Allman * Copyright (c) 1988, 1993 * The Regents of the University of California. All rights reserved. * @@ -39,7 +39,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.230 (Berkeley) 1/17/97"; +static char sccsid[] = "@(#)main.c 8.246 (Berkeley) 6/11/97"; #endif /* not lint */ #define _DEFINE @@ -62,13 +62,8 @@ char edata, end; ** turn calls a bunch of mail servers that do the real work of ** delivering the mail. ** -** Sendmail is driven by tables read in from /usr/lib/sendmail.cf -** (read by readcf.c). Some more static configuration info, -** including some code that you may want to tailor for your -** installation, is in conf.c. You may also want to touch -** daemon.c (if you have some other IPC mechanism), acct.c -** (to change your accounting), names.c (to adjust the name -** server mechanism). +** Sendmail is driven by settings read in from /etc/sendmail.cf +** (read by readcf.c). ** ** Usage: ** /usr/lib/sendmail [flags] addr ... @@ -82,7 +77,7 @@ char edata, end; ** International Computer Science Institute ** (11/88 - 9/89). ** UCB/Mammoth Project (10/89 - 7/95). -** InReference, Inc. (8/95 - present). +** InReference, Inc. (8/95 - 1/97). ** The support of the my employers is gratefully acknowledged. ** Few of them (Britton-Lee in particular) have had ** anything to gain from my involvement in this project. @@ -99,6 +94,10 @@ char *CommandLineArgs; /* command line args for pid file */ bool Warn_Q_option = FALSE; /* warn about Q option use */ char **SaveArgv; /* argument vector for re-execing */ +#ifdef NGROUPS_MAX +GIDSET_T InitialGidSet[NGROUPS_MAX]; +#endif + static void obsolete(); extern void printmailer __P((MAILER *)); extern void tTflag __P((char *)); @@ -219,7 +218,7 @@ main(argc, argv, envp) } errno = 0; -#ifdef LOG +#if LOG # ifdef LOG_MAIL openlog("sendmail", LOG_PID, LOG_MAIL); # else @@ -229,6 +228,15 @@ main(argc, argv, envp) tTsetup(tTdvect, sizeof tTdvect, "0-99.1"); +#ifdef NGROUPS_MAX + /* save initial group set for future checks */ + i = getgroups(NGROUPS_MAX, InitialGidSet); + if (i == 0) + InitialGidSet[0] = (GID_T) -1; + while (i < NGROUPS_MAX) + InitialGidSet[i++] = InitialGidSet[0]; +#endif + /* drop group id privileges (RunAsUser not yet set) */ drop_privileges(); @@ -489,9 +497,6 @@ main(argc, argv, envp) #endif } - /* probe interfaces and locate any additional names */ - load_if_names(); - /* current time */ define('b', arpadate((char *) NULL), CurEnv); @@ -828,6 +833,10 @@ main(argc, argv, envp) expand("\201m", jbuf, sizeof jbuf, CurEnv); setclass('m', jbuf); + /* probe interfaces and locate any additional names */ + if (!DontProbeInterfaces) + load_if_names(); + if (tTd(0, 1)) { printf("\n============ SYSTEM IDENTITY (after readcf) ============"); @@ -880,6 +889,10 @@ main(argc, argv, envp) setuserenv("TZ", NULL); tzset(); + /* be sure we don't pick up bogus HOSTALIASES environment variable */ + if (queuemode && RealUid != 0) + (void) unsetenv("HOSTALIASES"); + /* check for sane configuration level */ if (ConfigLevel > MAXCONFIGLEVEL) { @@ -904,13 +917,12 @@ main(argc, argv, envp) /* check for permissions */ if ((OpMode == MD_DAEMON || OpMode == MD_PURGESTAT) && RealUid != 0) { -#ifdef LOG if (LogLevel > 1) - syslog(LOG_ALERT, "user %d attempted to %s", + sm_syslog(LOG_ALERT, NOQID, + "user %d attempted to %s", RealUid, OpMode == MD_DAEMON ? "run daemon" : "purge host status"); -#endif usrerr("Permission denied"); exit(EX_USAGE); } @@ -923,6 +935,8 @@ main(argc, argv, envp) case MD_TEST: /* don't have persistent host status in test mode */ HostStatDir = NULL; + Verbose = 2; + CurEnv->e_errormode = EM_PRINT; break; case MD_FGDAEMON: @@ -938,10 +952,9 @@ main(argc, argv, envp) GrabTo = FALSE; /* arrange to restart on hangup signal */ -#ifdef LOG if (SaveArgv[0] == NULL || SaveArgv[0][0] != '/') - syslog(LOG_WARNING, "daemon invoked without full pathname; kill -1 won't work"); -#endif + sm_syslog(LOG_WARNING, NOQID, + "daemon invoked without full pathname; kill -1 won't work"); setsignal(SIGHUP, sighup); /* workaround: can't seem to release the signal in the parent */ @@ -949,7 +962,8 @@ main(argc, argv, envp) break; case MD_INITALIAS: - Verbose = TRUE; + Verbose = 2; + CurEnv->e_errormode = EM_PRINT; /* fall through... */ case MD_PRINT: @@ -1088,17 +1102,23 @@ main(argc, argv, envp) #endif /* operate in queue directory */ - if (OpMode == MD_TEST) - /* nothing -- just avoid further if clauses */ ; - else if (QueueDir == NULL) + if (QueueDir == NULL) { - syserr("QueueDirectory (Q) option must be set"); - ExitStat = EX_CONFIG; + if (OpMode != MD_TEST) + { + syserr("QueueDirectory (Q) option must be set"); + ExitStat = EX_CONFIG; + } } - else if (chdir(QueueDir) < 0) + else { - syserr("cannot chdir(%s)", QueueDir); - ExitStat = EX_CONFIG; + /* test path to get warning messages */ + (void) safedirpath(QueueDir, (uid_t) 0, (gid_t) 0, NULL, SFF_ANYFILE); + if (OpMode != MD_TEST && chdir(QueueDir) < 0) + { + syserr("cannot chdir(%s)", QueueDir); + ExitStat = EX_CONFIG; + } } /* check host status directory for validity */ @@ -1226,7 +1246,7 @@ main(argc, argv, envp) SIGFUNC_DECL intindebug __P((int)); if (isatty(fileno(stdin))) - Verbose = TRUE; + Verbose = 2; if (Verbose) { @@ -1261,7 +1281,6 @@ main(argc, argv, envp) if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0) { - (void) unsetenv("HOSTALIASES"); (void) runqueue(FALSE, Verbose); finis(); } @@ -1305,9 +1324,8 @@ main(argc, argv, envp) if (tTd(0, 1)) strcat(dtype, "+debugging"); -#ifdef LOG - syslog(LOG_INFO, "starting daemon (%s): %s", Version, dtype + 1); -#endif + sm_syslog(LOG_INFO, NOQID, + "starting daemon (%s): %s", Version, dtype + 1); #ifdef XLA xla_create_file(); #endif @@ -1317,8 +1335,14 @@ main(argc, argv, envp) { (void) runqueue(TRUE, FALSE); if (OpMode != MD_DAEMON) + { for (;;) + { pause(); + if (DoQueueRun) + (void) runqueue(TRUE, FALSE); + } + } } # endif /* QUEUE */ dropenvelope(CurEnv, TRUE); @@ -1402,7 +1426,7 @@ main(argc, argv, envp) /* collect body for UUCP return */ if (OpMode != MD_VERIFY) - collect(InChannel, FALSE, FALSE, NULL, CurEnv); + collect(InChannel, FALSE, NULL, CurEnv); finis(); } @@ -1423,8 +1447,21 @@ main(argc, argv, envp) CurEnv->e_to = NULL; if (OpMode != MD_VERIFY || GrabTo) { + long savedflags = CurEnv->e_flags & EF_FATALERRS; + CurEnv->e_flags |= EF_GLOBALERRS; - collect(InChannel, FALSE, FALSE, NULL, CurEnv); + CurEnv->e_flags &= ~EF_FATALERRS; + collect(InChannel, FALSE, NULL, CurEnv); + + /* bail out if there were fatal errors in collect */ + if (OpMode != MD_VERIFY && bitset(EF_FATALERRS, CurEnv->e_flags)) + { + CurEnv->e_flags |= EF_CLRQUEUE; + finis(); + /*NOTREACHED*/ + return -1; + } + CurEnv->e_flags |= savedflags; } errno = 0; @@ -1443,6 +1480,7 @@ main(argc, argv, envp) printaddr(&CurEnv->e_from, FALSE); } CurEnv->e_to = NULL; + CurrentLA = getla(); sendall(CurEnv, SM_DEFAULT); /* @@ -1493,6 +1531,13 @@ finis() if (tTd(2, 9)) printopenfds(FALSE); + /* if we fail in finis(), just exit */ + if (setjmp(TopFrame) != 0) + { + /* failed -- just give it up */ + goto forceexit; + } + /* clean up temp files */ CurEnv->e_to = NULL; if (CurEnv->e_id != NULL) @@ -1507,10 +1552,11 @@ finis() # endif /* and exit */ -# ifdef LOG + forceexit: if (LogLevel > 78) - syslog(LOG_DEBUG, "finis, pid=%d", getpid()); -# endif /* LOG */ + sm_syslog(LOG_DEBUG, CurEnv->e_id, + "finis, pid=%d", + getpid()); if (ExitStat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET) ExitStat = EX_OK; @@ -1540,11 +1586,8 @@ SIGFUNC_DECL intsig(sig) int sig; { -#ifdef LOG if (LogLevel > 79) - syslog(LOG_DEBUG, "%s: interrupt", - CurEnv->e_id == NULL ? "[NOQUEUE]" : CurEnv->e_id); -#endif + sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt"); FileName = NULL; unlockqueue(CurEnv); #ifdef XLA @@ -1665,11 +1708,10 @@ disconnect(droplev, e) printf("don't\n"); return; } -#ifdef LOG if (LogLevel > 93) - syslog(LOG_DEBUG, "%s: disconnect level %d", - e->e_id == NULL ? "[NOQUEUE]" : e->e_id, droplev); -#endif + sm_syslog(LOG_DEBUG, e->e_id, + "disconnect level %d", + droplev); /* be sure we don't get nasty signals */ (void) setsignal(SIGINT, SIG_IGN); @@ -1678,7 +1720,7 @@ disconnect(droplev, e) /* we can't communicate with our caller, so.... */ HoldErrs = TRUE; CurEnv->e_errormode = EM_MAIL; - Verbose = FALSE; + Verbose = 0; DisConnected = TRUE; /* all input from /dev/null */ @@ -1719,10 +1761,10 @@ disconnect(droplev, e) checkfd012("disconnect"); #endif -# ifdef LOG if (LogLevel > 71) - syslog(LOG_DEBUG, "in background, pid=%d", getpid()); -# endif /* LOG */ + sm_syslog(LOG_DEBUG, e->e_id, + "in background, pid=%d", + getpid()); errno = 0; } @@ -1822,11 +1864,10 @@ auth_warning(e, msg, va_alist) vsnprintf(p, SPACELEFT(buf, p), msg, ap); VA_END; addheader("X-Authentication-Warning", buf, &e->e_header); -#ifdef LOG if (LogLevel > 3) - syslog(LOG_INFO, "%s: Authentication-Warning: %.400s", - e->e_id == NULL ? "[NOQUEUE]" : e->e_id, buf); -#endif + sm_syslog(LOG_INFO, e->e_id, + "Authentication-Warning: %.400s", + buf); } } /* @@ -1916,22 +1957,23 @@ void dumpstate(when) char *when; { -#ifdef LOG register char *j = macvalue('j', CurEnv); int rs; - syslog(LOG_DEBUG, "--- dumping state on %s: $j = %s ---", + sm_syslog(LOG_DEBUG, CurEnv->e_id, + "--- dumping state on %s: $j = %s ---", when, j == NULL ? "<NULL>" : j); if (j != NULL) { if (!wordinclass(j, 'w')) - syslog(LOG_DEBUG, "*** $j not in $=w ***"); + sm_syslog(LOG_DEBUG, CurEnv->e_id, + "*** $j not in $=w ***"); } - syslog(LOG_DEBUG, "CurChildren = %d", CurChildren); - syslog(LOG_DEBUG, "--- open file descriptors: ---"); + sm_syslog(LOG_DEBUG, CurEnv->e_id, "CurChildren = %d", CurChildren); + sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- open file descriptors: ---"); printopenfds(TRUE); - syslog(LOG_DEBUG, "--- connection cache: ---"); + sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- connection cache: ---"); mci_dump_all(TRUE); rs = strtorwset("debug_dumpstate", NULL, ST_FIND); if (rs > 0) @@ -1942,14 +1984,13 @@ dumpstate(when) pv[0] = NULL; stat = rewrite(pv, rs, 0, CurEnv); - syslog(LOG_DEBUG, + sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- ruleset debug_dumpstate returns stat %d, pv: ---", stat); for (pvp = pv; *pvp != NULL; pvp++) - syslog(LOG_DEBUG, "%s", *pvp); + sm_syslog(LOG_DEBUG, CurEnv->e_id, "%s", *pvp); } - syslog(LOG_DEBUG, "--- end of state dump ---"); -#endif + sm_syslog(LOG_DEBUG, CurEnv->e_id, "--- end of state dump ---"); } @@ -1968,31 +2009,24 @@ sighup(sig) { if (SaveArgv[0][0] != '/') { -#ifdef LOG if (LogLevel > 3) - syslog(LOG_INFO, "could not restart: need full path"); -#endif + sm_syslog(LOG_INFO, NOQID, "could not restart: need full path"); exit(EX_OSFILE); } -#ifdef LOG if (LogLevel > 3) - syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]); -#endif + sm_syslog(LOG_INFO, NOQID, "restarting %s on signal", SaveArgv[0]); + alarm(0); releasesignal(SIGHUP); if (setgid(RealGid) < 0 || setuid(RealUid) < 0) { -#ifdef LOG if (LogLevel > 0) - syslog(LOG_ALERT, "could not set[ug]id(%d, %d): %m", + sm_syslog(LOG_ALERT, NOQID, "could not set[ug]id(%d, %d): %m", RealUid, RealGid); -#endif exit(EX_OSERR); } execv(SaveArgv[0], (ARGV_T) SaveArgv); -#ifdef LOG if (LogLevel > 0) - syslog(LOG_ALERT, "could not exec %s: %m", SaveArgv[0]); -#endif + sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %m", SaveArgv[0]); exit(EX_OSFILE); } /* @@ -2285,6 +2319,11 @@ testmodeline(line, e) printf("Map named \"%s\" not found\n", p); return; } + if (!bitset(MF_OPEN, map->s_map.map_mflags)) + { + printf("Map named \"%s\" not open\n", p); + return; + } printf("map_lookup: %s (%s) ", p, q); p = (*map->s_map.map_class->map_lookup) (&map->s_map, q, NULL, &rcode); |
