diff options
Diffstat (limited to 'contrib/sendmail/src/main.c')
-rw-r--r-- | contrib/sendmail/src/main.c | 151 |
1 files changed, 99 insertions, 52 deletions
diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c index f014d83..cea9d15 100644 --- a/contrib/sendmail/src/main.c +++ b/contrib/sendmail/src/main.c @@ -19,7 +19,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.302 (Berkeley) 6/4/98"; +static char sccsid[] = "@(#)main.c 8.322 (Berkeley) 12/18/1998"; #endif /* not lint */ #define _DEFINE @@ -129,6 +129,7 @@ main(argc, argv, envp) extern char *getcfname __P((void)); extern SIGFUNC_DECL sigusr1 __P((int)); extern SIGFUNC_DECL sighup __P((int)); + extern SIGFUNC_DECL quiesce __P((int)); extern void initmacros __P((ENVELOPE *)); extern void init_md __P((int, char **)); extern int getdtsize __P((void)); @@ -304,9 +305,7 @@ main(argc, argv, envp) if (tTd(0, 101)) { printf("Version %s\n", Version); - endpwent(); - setuid(RealUid); - exit(EX_OK); + finis(FALSE, EX_OK); } /* @@ -419,8 +418,8 @@ main(argc, argv, envp) environ = emptyenviron; /* - ** restore any original TZ setting until TimeZoneSpec has been - ** determined - or early log messages may get bogus time stamps + ** restore any original TZ setting until TimeZoneSpec has been + ** determined - or early log messages may get bogus time stamps */ if ((p = getextenv("TZ")) != NULL) { @@ -549,7 +548,7 @@ main(argc, argv, envp) QueueLimitId = (QUEUE_CHAR *) NULL; /* - ** Crack argv. + ** Crack argv. */ av = argv; @@ -835,8 +834,7 @@ main(argc, argv, envp) # endif default: - ExitStat = EX_USAGE; - finis(); + finis(TRUE, EX_USAGE); break; } } @@ -971,8 +969,11 @@ main(argc, argv, envp) } /* check for permissions */ - if ((OpMode == MD_DAEMON || OpMode == MD_FGDAEMON || - OpMode == MD_PURGESTAT) && RealUid != 0) + if ((OpMode == MD_DAEMON || + OpMode == MD_FGDAEMON || + OpMode == MD_PURGESTAT) && + RealUid != 0 && + RealUid != TrustedUid) { if (LogLevel > 1) sm_syslog(LOG_ALERT, NOQID, @@ -981,7 +982,7 @@ main(argc, argv, envp) OpMode != MD_PURGESTAT ? "run daemon" : "purge host status"); usrerr("Permission denied"); - exit(EX_USAGE); + finis(FALSE, EX_USAGE); } if (MeToo) @@ -1083,6 +1084,17 @@ main(argc, argv, envp) setoption('d', "", TRUE, FALSE, CurEnv); } +#ifdef VENDOR_CODE + /* check for vendor mismatch */ + if (VendorCode != VENDOR_CODE) + { + extern char *getvendor __P((int)); + + message("Warning: .cf file vendor code mismatch: sendmail expects vendor %s, .cf file vendor is %s", + getvendor(VENDOR_CODE), getvendor(VendorCode)); + } +#endif + /* check for out of date configuration level */ if (ConfigLevel < MAXCONFIGLEVEL) { @@ -1199,6 +1211,22 @@ main(argc, argv, envp) setclass('b', "application/octet-stream"); #endif +#if _FFR_MAX_MIME_HEADER_LENGTH + /* MIME headers which have fields to check for overflow */ + setclass(macid("{checkMIMEFieldHeaders}", NULL), "content-disposition"); + setclass(macid("{checkMIMEFieldHeaders}", NULL), "content-type"); + + /* MIME headers to check for length overflow */ + setclass(macid("{checkMIMETextHeaders}", NULL), "content-description"); + + /* MIME headers to check for overflow and rebalance */ + setclass(macid("{checkMIMEHeaders}", NULL), "content-disposition"); + setclass(macid("{checkMIMEHeaders}", NULL), "content-id"); + setclass(macid("{checkMIMEHeaders}", NULL), "content-transfer-encoding"); + setclass(macid("{checkMIMEHeaders}", NULL), "content-type"); + setclass(macid("{checkMIMEHeaders}", NULL), "mime-version"); +#endif + /* operate in queue directory */ if (QueueDir == NULL) { @@ -1241,18 +1269,14 @@ main(argc, argv, envp) { /* nope, really a botch */ usrerr("You do not have permission to process the queue"); - exit (EX_NOPERM); + finis(FALSE, EX_NOPERM); } } # endif /* QUEUE */ /* if we've had errors so far, exit now */ if (ExitStat != EX_OK && OpMode != MD_TEST) - { - endpwent(); - setuid(RealUid); - exit(ExitStat); - } + finis(FALSE, ExitStat); #if XDEBUG checkfd012("before main() initmaps"); @@ -1268,31 +1292,31 @@ main(argc, argv, envp) /* print the queue */ #if QUEUE dropenvelope(CurEnv, TRUE); + signal(SIGPIPE, quiesce); printqueue(); - endpwent(); - setuid(RealUid); - exit(EX_OK); + finis(FALSE, EX_OK); #else /* QUEUE */ usrerr("No queue to print"); - finis(); + finis(FALSE, ExitStat); #endif /* QUEUE */ + break; case MD_HOSTSTAT: + signal(SIGPIPE, quiesce); mci_traverse_persistent(mci_print_persistent, NULL); - exit(EX_OK); + finis(FALSE, EX_OK); break; case MD_PURGESTAT: mci_traverse_persistent(mci_purge_persistent, NULL); - exit(EX_OK); + finis(FALSE, EX_OK); break; case MD_INITALIAS: - /* initialize alias database */ + /* initialize maps */ initmaps(TRUE, CurEnv); - endpwent(); - setuid(RealUid); - exit(ExitStat); + finis(FALSE, ExitStat); + break; case MD_SMTP: case MD_DAEMON: @@ -1301,11 +1325,11 @@ main(argc, argv, envp) CurEnv->e_envid = NULL; CurEnv->e_flags &= ~(EF_RET_PARAM|EF_NO_BODY_RETN); - /* don't open alias database -- done in srvrsmtp */ + /* don't open maps for daemon -- done below in child */ break; default: - /* open the alias database */ + /* open the maps */ initmaps(FALSE, CurEnv); break; } @@ -1359,7 +1383,7 @@ main(argc, argv, envp) printf("> "); (void) fflush(stdout); if (fgets(buf, sizeof buf, stdin) == NULL) - finis(); + finis(TRUE, ExitStat); p = strchr(buf, '\n'); if (p != NULL) *p = '\0'; @@ -1377,7 +1401,7 @@ main(argc, argv, envp) if (queuemode && OpMode != MD_DAEMON && QueueIntvl == 0) { (void) runqueue(FALSE, Verbose); - finis(); + finis(TRUE, ExitStat); } # endif /* QUEUE */ @@ -1402,7 +1426,7 @@ main(argc, argv, envp) if (i < 0) syserr("daemon: cannot fork"); if (i != 0) - exit(EX_OK); + finis(FALSE, EX_OK); /* disconnect from our controlling tty */ disconnect(2, CurEnv); @@ -1495,6 +1519,9 @@ main(argc, argv, envp) snprintf(pbuf, sizeof pbuf, "0"); define(macid("{client_port}", NULL), newstr(pbuf), &BlankEnvelope); + /* initialize maps now for check_relay ruleset */ + initmaps(FALSE, CurEnv); + if (OpMode == MD_DAEMON) { /* validate the connection */ @@ -1539,7 +1566,7 @@ main(argc, argv, envp) /* collect body for UUCP return */ if (OpMode != MD_VERIFY) collect(InChannel, FALSE, NULL, CurEnv); - finis(); + finis(TRUE, ExitStat); } /* @@ -1583,7 +1610,7 @@ main(argc, argv, envp) /* bail out if message too large */ if (bitset(EF_CLRQUEUE, CurEnv->e_flags)) { - finis(); + finis(TRUE, ExitStat); /*NOTREACHED*/ return -1; } @@ -1615,11 +1642,18 @@ main(argc, argv, envp) ** Don't send return error message if in VERIFY mode. */ - finis(); + finis(TRUE, ExitStat); /*NOTREACHED*/ return -1; } +/* ARGSUSED */ +SIGFUNC_DECL +quiesce(sig) + int sig; +{ + finis(FALSE, EX_OK); +} /* ARGSUSED */ SIGFUNC_DECL @@ -1635,7 +1669,8 @@ intindebug(sig) ** FINIS -- Clean up and exit. ** ** Parameters: -** none +** drop -- whether or not to drop CurEnv envelope +** exitstat -- exit status to use for exit() call ** ** Returns: ** never @@ -1645,14 +1680,21 @@ intindebug(sig) */ void -finis() +finis(drop, exitstat) + bool drop; + volatile int exitstat; { + extern void closemaps __P((void)); +#ifdef USERDB + extern void _udbx_close __P((void)); +#endif + if (tTd(2, 1)) { extern void printenvflags __P((ENVELOPE *)); printf("\n====finis: stat %d e_id=%s e_flags=", - ExitStat, + exitstat, CurEnv->e_id == NULL ? "NOQUEUE" : CurEnv->e_id); printenvflags(CurEnv); } @@ -1668,12 +1710,20 @@ finis() /* clean up temp files */ CurEnv->e_to = NULL; - if (CurEnv->e_id != NULL) + if (drop && CurEnv->e_id != NULL) dropenvelope(CurEnv, TRUE); /* flush any cached connections */ mci_flush(TRUE, NULL); + /* close maps belonging to this pid */ + closemaps(); + +#ifdef USERDB + /* close UserDatabase */ + _udbx_close(); +#endif + # ifdef XLA /* clean up extended load average stuff */ xla_all_end(); @@ -1685,14 +1735,14 @@ finis() sm_syslog(LOG_DEBUG, CurEnv->e_id, "finis, pid=%d", getpid()); - if (ExitStat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET) - ExitStat = EX_OK; + if (exitstat == EX_TEMPFAIL || CurEnv->e_errormode == EM_BERKNET) + exitstat = EX_OK; /* reset uid for process accounting */ endpwent(); setuid(RealUid); - exit(ExitStat); + exit(exitstat); } /* ** INTSIG -- clean up on interrupt @@ -1719,15 +1769,11 @@ intsig(sig) sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt"); FileName = NULL; unlockqueue(CurEnv); + closecontrolsocket(TRUE); #ifdef XLA xla_all_end(); #endif - - /* reset uid for process accounting */ - endpwent(); - setuid(RealUid); - - exit(EX_OK); + finis(FALSE, EX_OK); } /* ** INITMACROS -- initialize the macro system @@ -2157,23 +2203,24 @@ sighup(sig) { if (LogLevel > 3) sm_syslog(LOG_INFO, NOQID, "could not restart: need full path"); - exit(EX_OSFILE); + finis(FALSE, EX_OSFILE); } if (LogLevel > 3) sm_syslog(LOG_INFO, NOQID, "restarting %s on signal", SaveArgv[0]); alarm(0); releasesignal(SIGHUP); + closecontrolsocket(TRUE); if (drop_privileges(TRUE) != EX_OK) { if (LogLevel > 0) sm_syslog(LOG_ALERT, NOQID, "could not set[ug]id(%d, %d): %m", RunAsUid, RunAsGid); - exit(EX_OSERR); + finis(FALSE, EX_OSERR); } execve(SaveArgv[0], (ARGV_T) SaveArgv, (ARGV_T) ExternalEnviron); if (LogLevel > 0) sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %m", SaveArgv[0]); - exit(EX_OSFILE); + finis(FALSE, EX_OSFILE); } /* ** DROP_PRIVILEGES -- reduce privileges to those of the RunAsUser option |