diff options
Diffstat (limited to 'usr.sbin/sendmail/src/daemon.c')
-rw-r--r-- | usr.sbin/sendmail/src/daemon.c | 153 |
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; |