summaryrefslogtreecommitdiffstats
path: root/contrib/sendmail/src/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/sendmail/src/daemon.c')
-rw-r--r--contrib/sendmail/src/daemon.c120
1 files changed, 71 insertions, 49 deletions
diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c
index 88c55cd..c593901 100644
--- a/contrib/sendmail/src/daemon.c
+++ b/contrib/sendmail/src/daemon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers.
+ * Copyright (c) 1998-2004 Sendmail, Inc. and its suppliers.
* All rights reserved.
* Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
* Copyright (c) 1988, 1993
@@ -13,7 +13,7 @@
#include <sendmail.h>
-SM_RCSID("@(#)$Id: daemon.c,v 8.613.2.20 2003/11/25 19:02:24 ca Exp $")
+SM_RCSID("@(#)$Id: daemon.c,v 8.649 2004/07/14 21:57:52 ca Exp $")
#if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__)
# define USE_SOCK_STREAM 1
@@ -74,10 +74,8 @@ struct daemon
char *d_mflags; /* flags for use in macro */
char *d_name; /* user-supplied name */
#if MILTER
-# if _FFR_MILTER_PERDAEMON
char *d_inputfilterlist;
struct milter *d_inputfilters[MAXFILTERS];
-# endif /* _FFR_MILTER_PERDAEMON */
#endif /* MILTER */
};
@@ -212,7 +210,7 @@ getrequests(e)
#endif /* XDEBUG */
/* Add parent process as first item */
- proc_list_add(CurrentPid, "Sendmail daemon", PROC_DAEMON, 0, -1);
+ proc_list_add(CurrentPid, "Sendmail daemon", PROC_DAEMON, 0, -1, NULL);
if (tTd(15, 1))
{
@@ -280,6 +278,7 @@ getrequests(e)
/* May have been sleeping above, check again */
CHECK_RESTART;
+
getrequests_checkdiskspace(e);
#if XDEBUG
@@ -490,6 +489,21 @@ getrequests(e)
if (t < 0)
{
errno = save_errno;
+
+ /* let's ignore these temporary errors */
+ if (save_errno == EINTR
+#ifdef EAGAIN
+ || save_errno == EAGAIN
+#endif /* EAGAIN */
+#ifdef ECONNABORTED
+ || save_errno == ECONNABORTED
+#endif /* ECONNABORTED */
+#ifdef EWOULDBLOCK
+ || save_errno == EWOULDBLOCK
+#endif /* EWOULDBLOCK */
+ )
+ continue;
+
syserr("getrequests: accept");
/* arrange to re-open the socket next time around */
@@ -568,6 +582,16 @@ getrequests(e)
}
/*
+ ** If connection rate is exceeded here, connection shall be
+ ** refused later by a new call after fork() by the
+ ** validate_connection() function. Closing the connection
+ ** at this point violates RFC 2821.
+ ** Do NOT remove this call, its side effects are needed.
+ */
+
+ connection_rate_check(&RealHostAddr, NULL);
+
+ /*
** Create a subprocess to process the mail.
*/
@@ -594,13 +618,13 @@ getrequests(e)
#if NAMED_BIND
/*
- ** Update MX records for FallBackMX.
+ ** Update MX records for FallbackMX.
** Let's hope this is fast otherwise we screw up the
** response time.
*/
- if (FallBackMX != NULL)
- (void) getfallbackmxrr(FallBackMX);
+ if (FallbackMX != NULL)
+ (void) getfallbackmxrr(FallbackMX);
#endif /* NAMED_BIND */
if (tTd(93, 100))
@@ -655,6 +679,7 @@ getrequests(e)
ShutdownRequest = NULL;
PendingSignal = 0;
CurrentPid = getpid();
+ close_sendmail_pid();
(void) sm_releasesignal(SIGALRM);
(void) sm_releasesignal(SIGCHLD);
@@ -697,7 +722,7 @@ getrequests(e)
/* Add control socket process */
proc_list_add(CurrentPid,
"console socket child",
- PROC_CONTROL_CHILD, 0, -1);
+ PROC_CONTROL_CHILD, 0, -1, NULL);
}
else
{
@@ -708,7 +733,7 @@ getrequests(e)
/* Add parent process as first child item */
proc_list_add(CurrentPid, "daemon child",
- PROC_DAEMON_CHILD, 0, -1);
+ PROC_DAEMON_CHILD, 0, -1, NULL);
/* don't schedule queue runs if ETRN */
QueueIntvl = 0;
@@ -759,21 +784,23 @@ getrequests(e)
h_errno == TRY_AGAIN ? "TEMP" : "FAIL");
}
else
+ {
macdefine(&BlankEnvelope.e_macro, A_PERM,
- macid("{client_resolve}"), "OK");
+ macid("{client_resolve}"), "OK");
+ }
sm_setproctitle(true, e, "startup with %s", p);
markstats(e, NULL, STATS_CONNECT);
if ((inchannel = sm_io_open(SmFtStdiofd,
SM_TIME_DEFAULT,
(void *) &t,
- SM_IO_RDONLY,
+ SM_IO_RDONLY_B,
NULL)) == NULL ||
(t = dup(t)) < 0 ||
(outchannel = sm_io_open(SmFtStdiofd,
SM_TIME_DEFAULT,
(void *) &t,
- SM_IO_WRONLY,
+ SM_IO_WRONLY_B,
NULL)) == NULL)
{
syserr("cannot open SMTP server channel, fd=%d",
@@ -856,14 +883,15 @@ getrequests(e)
{
(void) sm_snprintf(status, sizeof status,
"control socket server child");
- proc_list_add(pid, status, PROC_CONTROL, 0, -1);
+ proc_list_add(pid, status, PROC_CONTROL, 0, -1, NULL);
}
else
{
(void) sm_snprintf(status, sizeof status,
"SMTP server child for %s",
anynet_ntoa(&RealHostAddr));
- proc_list_add(pid, status, PROC_DAEMON, 0, -1);
+ proc_list_add(pid, status, PROC_DAEMON, 0, -1,
+ &RealHostAddr);
}
(void) sm_releasesignal(SIGCHLD);
@@ -888,7 +916,6 @@ getrequests(e)
sm_dprintf("getreq: returning\n");
#if MILTER
-# if _FFR_MILTER_PERDAEMON
/* set the filters for this daemon */
if (Daemons[curdaemon].d_inputfilterlist != NULL)
{
@@ -902,7 +929,6 @@ getrequests(e)
if (i < MAXFILTERS)
InputFilters[i] = NULL;
}
-# endif /* _FFR_MILTER_PERDAEMON */
#endif /* MILTER */
return &Daemons[curdaemon].d_flags;
}
@@ -1465,11 +1491,9 @@ setsockaddroptions(p, d)
break;
#if MILTER
-# if _FFR_MILTER_PERDAEMON
case 'I':
d->d_inputfilterlist = v;
break;
-# endif /* _FFR_MILTER_PERDAEMON */
#endif /* MILTER */
case 'P': /* port */
@@ -1711,9 +1735,7 @@ static struct dflags DaemonFlags[] =
{ "IFNHELO", D_IFNHELO },
{ "FQMAIL", D_FQMAIL },
{ "FQRCPT", D_FQRCPT },
-#if _FFR_SMTP_SSL
{ "SMTPS", D_SMTPS },
-#endif /* _FFR_SMTP_SSL */
{ "UNQUALOK", D_UNQUALOK },
{ "NOAUTH", D_NOAUTH },
{ "NOCANON", D_NOCANON },
@@ -1738,15 +1760,13 @@ printdaemonflags(d)
if (!bitnset(df->d_flag, d->d_flags))
continue;
if (first)
- (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "<%s",
- df->d_name);
+ sm_dprintf("<%s", df->d_name);
else
- (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ",%s",
- df->d_name);
+ sm_dprintf(",%s", df->d_name);
first = false;
}
if (!first)
- (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, ">");
+ sm_dprintf(">");
}
bool
@@ -1761,10 +1781,8 @@ setdaemonoptions(p)
setsockaddroptions(p, &Daemons[NDaemons]);
#if MILTER
-# if _FFR_MILTER_PERDAEMON
if (Daemons[NDaemons].d_inputfilterlist != NULL)
Daemons[NDaemons].d_inputfilterlist = newstr(Daemons[NDaemons].d_inputfilterlist);
-# endif /* _FFR_MILTER_PERDAEMON */
#endif /* MILTER */
if (Daemons[NDaemons].d_name != NULL)
@@ -1929,7 +1947,6 @@ chkclientmodifiers(flag)
}
#if MILTER
-# if _FFR_MILTER_PERDAEMON
/*
** SETUP_DAEMON_FILTERS -- Parse per-socket filters
**
@@ -1961,7 +1978,6 @@ setup_daemon_milters()
}
}
}
-# endif /* _FFR_MILTER_PERDAEMON */
#endif /* MILTER */
/*
** MAKECONNECTION -- make a connection to an SMTP socket on a machine.
@@ -2673,11 +2689,11 @@ nextaddr:
mci->mci_out = NULL;
if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
(void *) &s,
- SM_IO_WRONLY, NULL)) == NULL ||
+ SM_IO_WRONLY_B, NULL)) == NULL ||
(s = dup(s)) < 0 ||
(mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
(void *) &s,
- SM_IO_RDONLY, NULL)) == NULL)
+ SM_IO_RDONLY_B, NULL)) == NULL)
{
save_errno = errno;
syserr("cannot open SMTP client channel, fd=%d", s);
@@ -2746,6 +2762,13 @@ nextaddr:
macdefine(&BlankEnvelope.e_macro, A_PERM,
macid("{if_family_out}"), NULL);
}
+
+#if _FFR_HELONAME
+ /* Use the configured HeloName as appropriate */
+ if (HeloName != NULL && HeloName[0] != '\0')
+ mci->mci_heloname = newstr(HeloName);
+#endif /* _FFR_HELONAME */
+
mci_setstat(mci, EX_OK, NULL, NULL);
return EX_OK;
}
@@ -2795,7 +2818,8 @@ makeconnection_ds(mux_path, mci)
if (rval != 0)
{
- syserr("makeconnection_ds: unsafe domain socket");
+ syserr("makeconnection_ds: unsafe domain socket %s",
+ mux_path);
mci_setstat(mci, EX_TEMPFAIL, "4.3.5", NULL);
errno = rval;
return EX_TEMPFAIL;
@@ -2807,7 +2831,8 @@ makeconnection_ds(mux_path, mci)
if (strlen(mux_path) >= sizeof unix_addr.sun_path)
{
- syserr("makeconnection_ds: domain socket name too long");
+ syserr("makeconnection_ds: domain socket name %s too long",
+ mux_path);
/* XXX why TEMPFAIL but 5.x.y ? */
mci_setstat(mci, EX_TEMPFAIL, "5.3.5", NULL);
@@ -2822,7 +2847,8 @@ makeconnection_ds(mux_path, mci)
if (sock == -1)
{
save_errno = errno;
- syserr("makeconnection_ds: could not create domain socket");
+ syserr("makeconnection_ds: could not create domain socket %s",
+ mux_path);
mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
errno = save_errno;
return EX_TEMPFAIL;
@@ -2843,11 +2869,11 @@ makeconnection_ds(mux_path, mci)
/* connection ok, put it into canonical form */
mci->mci_out = NULL;
if ((mci->mci_out = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
- (void *) &sock, SM_IO_WRONLY, NULL))
+ (void *) &sock, SM_IO_WRONLY_B, NULL))
== NULL
|| (sock = dup(sock)) < 0 ||
(mci->mci_in = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT,
- (void *) &sock, SM_IO_RDONLY, NULL))
+ (void *) &sock, SM_IO_RDONLY_B, NULL))
== NULL)
{
save_errno = errno;
@@ -2891,8 +2917,8 @@ shutdown_daemon()
ShutdownRequest = NULL;
PendingSignal = 0;
- if (LogLevel > 79)
- sm_syslog(LOG_DEBUG, CurEnv->e_id, "interrupt (%s)",
+ if (LogLevel > 9)
+ sm_syslog(LOG_INFO, CurEnv->e_id, "stopping daemon, reason=%s",
reason == NULL ? "implicit call" : reason);
FileName = NULL;
@@ -2964,7 +2990,6 @@ void
restart_daemon()
{
bool drop;
- int i;
int save_errno;
char *reason;
sigfunc_t ignore, oalrm, ousr1;
@@ -2996,6 +3021,9 @@ restart_daemon()
cleanup_shm(DaemonPid == getpid());
#endif /* SM_CONF_SHM */
+ /* close locked pid file */
+ close_sendmail_pid();
+
/*
** Want to drop to the user who started the process in all cases
** *but* when running as "smmsp" for the clientmqueue queue run
@@ -3016,14 +3044,7 @@ restart_daemon()
/* NOTREACHED */
}
- /* arrange for all the files to be closed */
- for (i = 3; i < DtableSize; i++)
- {
- register int j;
-
- if ((j = fcntl(i, F_GETFD, 0)) != -1)
- (void) fcntl(i, F_SETFD, j | FD_CLOEXEC);
- }
+ sm_close_on_exec(STDERR_FILENO + 1, DtableSize);
/*
** Need to allow signals before execve() to make them "harmless".
@@ -3340,6 +3361,7 @@ getauthinfo(fd, may_be_forged)
hp = sm_gethostbyname(RealHostName, family);
if (hp == NULL)
{
+ /* XXX: Could be a temporary error on forward lookup */
*may_be_forged = true;
}
else
@@ -3826,7 +3848,7 @@ host_map_lookup(map, name, av, statp)
return NULL;
if (s->s_namecanon.nc_cname == NULL)
{
- syserr("host_map_lookup(%s): bogus NULL cache entry, errno = %d, h_errno = %d",
+ syserr("host_map_lookup(%s): bogus NULL cache entry, errno=%d, h_errno=%d",
name,
s->s_namecanon.nc_errno,
s->s_namecanon.nc_herrno);
OpenPOWER on IntegriCloud