summaryrefslogtreecommitdiff
path: root/usr.sbin/sendmail/src/daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/sendmail/src/daemon.c')
-rw-r--r--usr.sbin/sendmail/src/daemon.c153
1 files changed, 87 insertions, 66 deletions
diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c
index 9a11969bf2c2..aead4ffb28bc 100644
--- a/usr.sbin/sendmail/src/daemon.c
+++ b/usr.sbin/sendmail/src/daemon.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1983, 1995 Eric P. Allman
+ * Copyright (c) 1983, 1995, 1996 Eric P. Allman
* Copyright (c) 1988, 1993
* The Regents of the University of California. All rights reserved.
*
@@ -37,9 +37,9 @@
#ifndef lint
#ifdef DAEMON
-static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (with daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (with daemon mode)";
#else
-static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemon mode)";
+static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (without daemon mode)";
#endif
#endif /* not lint */
@@ -70,7 +70,7 @@ static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemo
** thing yourself, I recommend chucking the entire file
** and starting from scratch. Basic semantics are:
**
-** getrequests()
+** getrequests(e)
** Opens a port and initiates a connection.
** Returns in a child. Must set InChannel and
** OutChannel appropriately.
@@ -80,7 +80,7 @@ static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemo
** etc., to avoid having extra file descriptors during
** the queue run and to avoid confusing the network
** code (if it cares).
-** makeconnection(host, port, outfile, infile, usesecureport)
+** makeconnection(host, port, outfile, infile, e)
** Make a connection to the named host on the given
** port. Set *outfile and *infile to the files
** appropriate for communication. Returns zero on
@@ -93,10 +93,12 @@ static char sccsid[] = "@(#)daemon.c 8.119.1.2 (Berkeley) 9/16/96 (without daemo
** GETREQUESTS -- open mail IPC port and get requests.
**
** Parameters:
-** none.
+** e -- the current envelope.
**
** Returns:
-** none.
+** TRUE -- if a "null server" should be used -- that is, one
+** that rejects all commands.
+** FALSE -- to use a normal server.
**
** Side Effects:
** Waits until some interesting activity occurs. When
@@ -113,8 +115,9 @@ int ListenQueueSize = 10; /* size of listen queue */
int TcpRcvBufferSize = 0; /* size of TCP receive buffer */
int TcpSndBufferSize = 0; /* size of TCP send buffer */
-void
-getrequests()
+bool
+getrequests(e)
+ ENVELOPE *e;
{
int t;
bool refusingconnections = TRUE;
@@ -124,6 +127,7 @@ getrequests()
bool j_has_dot;
#endif
extern void reapchild();
+ extern int opendaemonsocket __P((bool));
/*
** Set up the address for the mailer.
@@ -166,7 +170,7 @@ getrequests()
extern char *CommandLineArgs;
/* write the process id on line 1 */
- fprintf(pidf, "%d\n", getpid());
+ fprintf(pidf, "%ld\n", (long) getpid());
/* line 2 contains all command line flags */
fprintf(pidf, "%s\n", CommandLineArgs);
@@ -179,7 +183,7 @@ getrequests()
{
char jbuf[MAXHOSTNAMELEN];
- expand("\201j", jbuf, sizeof jbuf, CurEnv);
+ expand("\201j", jbuf, sizeof jbuf, e);
j_has_dot = strchr(jbuf, '.') != NULL;
}
#endif
@@ -195,8 +199,7 @@ getrequests()
extern int getla();
/* see if we are rejecting connections */
- CurrentLA = getla();
- if (refuseconnections())
+ if (refuseconnections(ntohs(DaemonAddr.sin.sin_port)))
{
if (DaemonSocket >= 0)
{
@@ -220,8 +223,9 @@ getrequests()
/* check for disaster */
{
char jbuf[MAXHOSTNAMELEN];
+ extern void dumpstate __P((char *));
- expand("\201j", jbuf, sizeof jbuf, CurEnv);
+ expand("\201j", jbuf, sizeof jbuf, e);
if (!wordinclass(jbuf, 'w'))
{
dumpstate("daemon lost $j");
@@ -238,7 +242,8 @@ getrequests()
#endif
/* wait for a connection */
- setproctitle("accepting connections");
+ setproctitle("accepting connections on port %d",
+ ntohs(DaemonAddr.sin.sin_port));
do
{
errno = 0;
@@ -277,9 +282,9 @@ getrequests()
if (pid == 0)
{
char *p;
- extern char *hostnamebyanyaddr();
extern void intsig();
FILE *inchannel, *outchannel;
+ bool nullconn;
/*
** CHILD -- return to caller.
@@ -296,7 +301,7 @@ getrequests()
/* determine host name */
p = hostnamebyanyaddr(&RealHostAddr);
- if (strlen(p) > MAXNAME)
+ if (strlen(p) > (SIZE_T) MAXNAME)
p[MAXNAME] = '\0';
RealHostName = newstr(p);
setproctitle("startup with %s", p);
@@ -313,7 +318,13 @@ getrequests()
OutChannel = outchannel;
DisConnected = FALSE;
- /* should we check for illegal connection here? XXX */
+ /* validate the connection */
+ HoldErrs = TRUE;
+ nullconn = !validate_connection(&RealHostAddr, RealHostName, e);
+ HoldErrs = FALSE;
+ if (nullconn)
+ break;
+
#ifdef XLA
if (!xla_host_ok(RealHostName))
{
@@ -323,16 +334,19 @@ getrequests()
#endif
if (tTd(15, 2))
- printf("getreq: returning\n");
- return;
+ printf("getreq: returning (normal server)\n");
+ return FALSE;
}
- CurChildren++;
+ /* parent -- keep track of children */
+ proc_list_add(pid);
/* close the port so that others will hang (for a while) */
(void) close(t);
}
- /*NOTREACHED*/
+ if (tTd(15, 2))
+ printf("getreq: returning (null server)\n");
+ return TRUE;
}
/*
** OPENDAEMONSOCKET -- open the SMTP socket
@@ -446,6 +460,7 @@ opendaemonsocket(firsttime)
} while (ntries++ < MAXOPENTRIES && transienterror(saveerrno));
syserr("!opendaemonsocket: server SMTP socket wedged: exiting");
finis();
+ return -1; /* avoid compiler warning on IRIX */
}
/*
** CLRDAEMON -- reset the daemon connection
@@ -536,16 +551,16 @@ setdaemonoptions(p)
#if NETINET
case AF_INET:
if (isascii(*v) && isdigit(*v))
- DaemonAddr.sin.sin_addr.s_addr = htonl(inet_network(v));
+ DaemonAddr.sin.sin_addr.s_addr = inet_addr(v);
else
{
- register struct netent *np;
+ register struct hostent *hp;
- np = getnetbyname(v);
- if (np == NULL)
- syserr("554 network \"%s\" unknown", v);
+ hp = sm_gethostbyname(v);
+ if (hp == NULL)
+ syserr("554 host \"%s\" unknown", v);
else
- DaemonAddr.sin.sin_addr.s_addr = np->n_net;
+ bcopy(hp->h_addr, &DaemonAddr.sin.sin_addr, INADDRSZ);
}
break;
#endif
@@ -630,8 +645,7 @@ setdaemonoptions(p)
** port -- the port number to connect to.
** mci -- a pointer to the mail connection information
** structure to be filled in.
-** usesecureport -- if set, use a low numbered (reserved)
-** port to provide some rudimentary authentication.
+** e -- the current envelope.
**
** Returns:
** An exit code telling whether the connection could be
@@ -653,11 +667,11 @@ connecttimeout()
SOCKADDR CurHostAddr; /* address of current host */
int
-makeconnection(host, port, mci, usesecureport)
+makeconnection(host, port, mci, e)
char *host;
u_short port;
register MCI *mci;
- bool usesecureport;
+ ENVELOPE *e;
{
register int i = 0;
register int s;
@@ -691,7 +705,7 @@ makeconnection(host, port, mci, usesecureport)
*p = '\0';
#if NETINET
hid = inet_addr(&host[1]);
- if (hid == -1)
+ if (hid == INADDR_NONE)
#endif
{
/* try it as a host name (avoid MX lookup) */
@@ -717,8 +731,11 @@ makeconnection(host, port, mci, usesecureport)
}
if (p == NULL)
{
+ extern char MsgBuf[];
+
usrerr("553 Invalid numeric domain spec \"%s\"", host);
mci->mci_status = "5.1.2";
+ mci->mci_rstatus = newstr(MsgBuf);
return (EX_NOHOST);
}
#if NETINET
@@ -728,22 +745,25 @@ makeconnection(host, port, mci, usesecureport)
}
else
{
- register char *p = &host[strlen(host) - 1];
-
- hp = sm_gethostbyname(host);
- if (hp == NULL && *p == '.')
+ /* contortion to get around SGI cc complaints */
{
+ register char *p = &host[strlen(host) - 1];
+
+ hp = sm_gethostbyname(host);
+ if (hp == NULL && *p == '.')
+ {
#if NAMED_BIND
- int oldopts = _res.options;
+ int oldopts = _res.options;
- _res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
+ _res.options &= ~(RES_DEFNAMES|RES_DNSRCH);
#endif
- *p = '\0';
- hp = sm_gethostbyname(host);
- *p = '.';
+ *p = '\0';
+ hp = sm_gethostbyname(host);
+ *p = '.';
#if NAMED_BIND
- _res.options = oldopts;
+ _res.options = oldopts;
#endif
+ }
}
gothostent:
if (hp == NULL)
@@ -754,6 +774,7 @@ gothostent:
(errno == ECONNREFUSED && UseNameServer))
{
mci->mci_status = "4.4.3";
+ mci->mci_rstatus = NULL;
return (EX_TEMPFAIL);
}
#endif
@@ -841,7 +862,7 @@ gothostent:
/* save for logging */
CurHostAddr = addr;
- if (usesecureport)
+ if (bitnset(M_SECURE_PORT, mci->mci_mailer->m_flags))
{
int rport = IPPORT_RESERVED - 1;
@@ -878,8 +899,8 @@ gothostent:
(void) setsockopt(s, SOL_SOCKET, SO_DEBUG,
(char *)&on, sizeof on);
}
- if (CurEnv->e_xfp != NULL)
- (void) fflush(CurEnv->e_xfp); /* for debugging */
+ if (e->e_xfp != NULL)
+ (void) fflush(e->e_xfp); /* for debugging */
errno = 0; /* for debugging */
/*
@@ -889,10 +910,12 @@ gothostent:
if (setjmp(CtxConnectTimeout) == 0)
{
- if (TimeOuts.to_connect == 0)
- ev = NULL;
- else
+ if (e->e_ntries <= 0 && TimeOuts.to_iconnect != 0)
+ ev = setevent(TimeOuts.to_iconnect, connecttimeout, 0);
+ else if (TimeOuts.to_connect != 0)
ev = setevent(TimeOuts.to_connect, connecttimeout, 0);
+ else
+ ev = NULL;
if (connect(s, (struct sockaddr *) &addr, addrlen) >= 0)
{
if (ev != NULL)
@@ -986,7 +1009,6 @@ myhostname(hostbuf, size)
int size;
{
register struct hostent *hp;
- extern bool getcanonname();
if (gethostname(hostbuf, size) < 0)
{
@@ -1087,7 +1109,6 @@ getauthinfo(fd)
int nleft;
char ibuf[MAXNAME + 1];
static char hbuf[MAXNAME * 2 + 2];
- extern char *hostnamebyanyaddr();
falen = sizeof RealHostAddr;
if (isatty(fd) || getpeername(fd, &RealHostAddr.sa, &falen) < 0 ||
@@ -1104,6 +1125,8 @@ getauthinfo(fd)
{
/* translate that to a host name */
RealHostName = newstr(hostnamebyanyaddr(&RealHostAddr));
+ if (strlen(RealHostName) > MAXNAME)
+ RealHostName[MAXNAME - 1] = '\0';
}
if (TimeOuts.to_ident == 0)
@@ -1170,6 +1193,9 @@ getauthinfo(fd)
{
p += i;
nleft -= i;
+ *p = '\0';
+ if (strchr(ibuf, '\n') != NULL)
+ break;
}
(void) close(s);
clrevent(ev);
@@ -1207,14 +1233,6 @@ getauthinfo(fd)
}
/* p now points to the OSTYPE field */
- while (isascii(*p) && isspace(*p))
- p++;
- if (strncasecmp(p, "other", 5) == 0 &&
- (p[5] == ':' || p[5] == ' ' || p[5] == ',' || p[5] == '\0'))
- {
- /* not useful information */
- goto noident;
- }
p = strchr(p, ':');
if (p == NULL)
{
@@ -1432,25 +1450,28 @@ host_map_lookup(map, name, av, statp)
if (*name != '[')
{
- extern bool getcanonname();
-
if (tTd(9, 1))
printf("host_map_lookup(%s) => ", name);
s->s_namecanon.nc_flags |= NCF_VALID; /* will be soon */
- if (strlen(name) < sizeof hbuf)
snprintf(hbuf, sizeof hbuf, "%s", name);
if (getcanonname(hbuf, sizeof hbuf - 1, !HasWildcardMX))
{
if (tTd(9, 1))
printf("%s\n", hbuf);
- cp = map_rewrite(map, hbuf, strlen(hbuf), av);
- s->s_namecanon.nc_cname = newstr(cp);
+ if (bitset(MF_MATCHONLY, map->map_mflags))
+ {
+ cp = map_rewrite(map, name, strlen(name), av);
+ s->s_namecanon.nc_cname = newstr(hbuf);
+ }
+ else
+ {
+ cp = map_rewrite(map, hbuf, strlen(hbuf), av);
+ s->s_namecanon.nc_cname = newstr(cp);
+ }
return cp;
}
else
{
- register struct hostent *hp;
-
s->s_namecanon.nc_errno = errno;
#if NAMED_BIND
s->s_namecanon.nc_herrno = h_errno;