diff options
Diffstat (limited to 'contrib/sendmail/src')
26 files changed, 1136 insertions, 515 deletions
diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README index fe9f308..e4e62a1 100644 --- a/contrib/sendmail/src/README +++ b/contrib/sendmail/src/README @@ -9,7 +9,7 @@ # the sendmail distribution. # # -# $Id: README,v 8.263.2.1.2.21 2000/09/27 16:36:26 ca Exp $ +# $Id: README,v 8.263.2.1.2.27 2000/12/16 16:46:02 gshapiro Exp $ # This directory contains the source files for sendmail(TM). @@ -593,9 +593,8 @@ SFIO Uses sfio instead of stdio. sfio is available from AT&T stdio.h must be installed in a subdirectory called sfio, i.e., if you install sfio in /usr/local, stdio.h should be in /usr/local/include/sfio, and libsfio.a should be in - /usr/local/lib. Notice: you may run into problems if - you use sfio2000 (the body of a message is lost). Use - sfio1999 instead. + /usr/local/lib. Notice: read the sfio section in + OPERATING SYSTEM AND COMPILE QUIRKS. +---------------------+ @@ -629,6 +628,12 @@ different version of the database internally that does not include wildcard MX records that match your domain. ANYTHING ELSE WILL GIVE YOU HEADACHES! +When attempting to canonify a hostname, some broken name servers will +return SERVFAIL (a temporary failure) on T_AAAA (IPv6) lookups. If you +want to excuse this behavior, compile sendmail with +-D_FFR_WORKAROUND_BROKEN_NAMESERVERS. However, instead, we recommend catching +the problem and reporting it to the name server administrator so we can rid +the world of broken name servers. +----------------------------------------+ | STARTTLS COMPILATION AND CONFIGURATION | @@ -918,6 +923,25 @@ Solaris 7 (SunOS 5.7) to ldap_set_option for LDAP_OPT_REFERRALS in ldapmap_setopts if LDAP support is compiled in sendmail. +Solaris + If you are using dns for hostname resolution on Solaris, make sure + that the 'dns' entry is last on the hosts line in + '/etc/nsswitch.conf'. For example, use: + + hosts: nisplus files dns + + Do not use: + + host: nisplus dns [NOTFOUND=return] files + + Note that 'nisplus' above is an illustration. The same comment + applies no matter what naming services you are using. If you have + anything other than dns last, even after "[NOTFOUND=return]", + sendmail may not be able to determine whether an error was + temporary or permanent. The error returned by the solaris + gethostbyname() is the error for the last lookup used, and other + naming services do not have the same concept of temporary failure. + Ultrix By default, the IDENT protocol is turned off on Ultrix. If you are running Ultrix 4.4 or later, or if you have included patch @@ -1247,7 +1271,7 @@ AIX 4.3.3 2) Build against a real Bind 8.2.2 include/lib tree 3) Wait for IBM to fix it -AIX 4.2 +AIX 4.X The AIX m4 implements a different mechanism for ifdef which is inconsistent with other versions of m4. Therefore, it will not work properly with the sendmail Build architecture or m4 @@ -1470,9 +1494,30 @@ OpenSSL Do not use 0.9.3, but OpenSSL 0.9.5a or later if compatible with 0.9.5a. +sfio + You may run into problems if you use sfio2000 (the body of a + message is lost). Use sfio1999 instead; however, it also has + a bug that can cause sendmail to fail. A patch has been provided + by Petr Lampa of Brno University of Technology, which is given here: + +diff -rc ../../../../sfio/src/lib/sfio/sfputr.c ./sfputr.c +*** ../../../../sfio/src/lib/sfio/sfputr.c Tue May 16 18:25:49 2000 +--- ./sfputr.c Wed Sep 20 09:06:01 2000 +*************** +*** 24,29 **** +--- 24,30 ---- + for(w = 0; (*s || rc >= 0); ) + { SFWPEEK(f,ps,p); + ++ if(p == -1) return -1; /* PL */ + if(p == 0 || (f->flags&SF_WHOLE) ) + { n = strlen(s); + if(p >= (n + (rc < 0 ? 0 : 1)) ) + + PH PH support is provided by Mark Roth <roth@uiuc.edu>. The map is - described at http://www-wsg.cso.uiuc.edu/sendmail/patches/ . + described at http://www-dev.cso.uiuc.edu/sendmail/ . Please contact Mark Roth for support and questions regarding the map. @@ -1623,4 +1668,4 @@ util.c Some general purpose routines used by sendmail. version.c The version number and information about this version of sendmail. -(Version $Revision: 8.263.2.1.2.21 $, last update $Date: 2000/09/27 16:36:26 $ ) +(Version $Revision: 8.263.2.1.2.27 $, last update $Date: 2000/12/16 16:46:02 $ ) diff --git a/contrib/sendmail/src/alias.c b/contrib/sendmail/src/alias.c index 6a0b17c..4c6a174 100644 --- a/contrib/sendmail/src/alias.c +++ b/contrib/sendmail/src/alias.c @@ -13,7 +13,7 @@ #include <sendmail.h> #ifndef lint -static char id[] = "@(#)$Id: alias.c,v 8.142.4.3 2000/09/21 21:52:16 ca Exp $"; +static char id[] = "@(#)$Id: alias.c,v 8.142.4.9 2000/11/08 20:58:42 geir Exp $"; #endif /* ! lint */ # define SEPARATOR ':' @@ -279,7 +279,7 @@ setalias(spec) map = &s->s_map; memset(map, '\0', sizeof *map); map->map_mname = s->s_name; - p = strpbrk(p,ALIAS_SPEC_SEPARATORS); + p = strpbrk(p, ALIAS_SPEC_SEPARATORS); if (p != NULL && *p == SEPARATOR) { /* map name */ @@ -732,7 +732,7 @@ readaliases(map, af, announcestats, logstats) register char *nlp; nlp = &p[strlen(p)]; - if (nlp[-1] == '\n') + if (nlp > p && nlp[-1] == '\n') *--nlp = '\0'; if (CheckAliases) diff --git a/contrib/sendmail/src/aliases b/contrib/sendmail/src/aliases index 85e62a9..1b19f41 100644 --- a/contrib/sendmail/src/aliases +++ b/contrib/sendmail/src/aliases @@ -1,5 +1,5 @@ # -# $Id: aliases,v 8.1 1999/02/06 18:44:07 gshapiro Exp $ +# $Id: aliases,v 8.1.36.1 2000/10/16 20:18:39 gshapiro Exp $ # @(#)aliases 8.2 (Berkeley) 3/5/94 # # Aliases in this file will NOT be expanded in the header from @@ -31,24 +31,3 @@ operator: root # trap decode to catch security attacks decode: root - -# OFFICIAL CSRG/BUG ADDRESSES - -# Ftp maintainer. -ftp: ftp-bugs -ftp-bugs: bigbug@cs.berkeley.edu - -# Distribution office. -bsd-dist: bsd-dist@cs.berkeley.edu - -# Fortune maintainer. -fortune: fortune@cs.berkeley.edu - -# Termcap maintainer. -termcap: termcap@cs.berkeley.edu - -# General bug address. -ucb-fixes: bigbug@cs.berkeley.edu -ucb-fixes-request: bigbug@cs.berkeley.edu -bugs: bugs@cs.berkeley.edu -# END OFFICIAL BUG ADDRESSES diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c index f6ba02c..c6c5f78 100644 --- a/contrib/sendmail/src/collect.c +++ b/contrib/sendmail/src/collect.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: collect.c,v 8.136.4.6 2000/09/21 21:52:16 ca Exp $"; +static char id[] = "@(#)$Id: collect.c,v 8.136.4.8 2000/10/09 00:50:04 gshapiro Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -436,7 +436,7 @@ nextstate: dprintf("collect: rscheck(\"check_eoh\", \"%s $| %s\")\n", hnum, hsize); rstat = rscheck("check_eoh", hnum, hsize, e, FALSE, - TRUE, 4); + TRUE, 4, NULL); bp = buf; @@ -854,6 +854,11 @@ eatfrom(fm, e) p++; while (*p == ' ') p++; + if (strlen(p) < 17) + { + /* no room for the date */ + return; + } if (!(isascii(*p) && isupper(*p)) || p[3] != ' ' || p[13] != ':' || p[16] != ':') continue; @@ -866,8 +871,10 @@ eatfrom(fm, e) continue; for (dt = MonthList; *dt != NULL; dt++) + { if (strncmp(*dt, &p[4], 3) == 0) break; + } if (*dt != NULL) break; } diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c index 7865b0e..dda2761 100644 --- a/contrib/sendmail/src/control.c +++ b/contrib/sendmail/src/control.c @@ -9,7 +9,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: control.c,v 8.44.14.8 2000/09/17 17:04:26 gshapiro Exp $"; +static char id[] = "@(#)$Id: control.c,v 8.44.14.13 2000/12/28 21:25:52 gshapiro Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -77,16 +77,26 @@ opencontrolsocket() return -1; } - if (geteuid() == 0 && TrustedUid != 0) + if (geteuid() == 0) { - if (chown(ControlSocketName, TrustedUid, -1) < 0) + uid_t u = 0; + + if (RunAsUid != 0) + u = RunAsUid; + else if (TrustedUid != 0) + u = TrustedUid; + + if (u != 0 && + chown(ControlSocketName, u, -1) < 0) { save_errno = errno; sm_syslog(LOG_ALERT, NOQID, - "ownership change on %s failed: %s", - ControlSocketName, errstring(save_errno)); - message("050 ownership change on %s failed: %s", - ControlSocketName, errstring(save_errno)); + "ownership change on %s to uid %d failed: %s", + ControlSocketName, (int) u, + errstring(save_errno)); + message("050 ownership change on %s to uid %d failed: %s", + ControlSocketName, (int) u, + errstring(save_errno)); closecontrolsocket(TRUE); errno = save_errno; return -1; @@ -141,8 +151,8 @@ closecontrolsocket(fullclose) ControlSocket = -1; } - rval = safefile(ControlSocketName, RunAsUid, RunAsGid, RunAsUserName, - sff, S_IRUSR|S_IWUSR, NULL); + rval = safefile(ControlSocketName, RunAsUid, RunAsGid, + RunAsUserName, sff, S_IRUSR|S_IWUSR, NULL); /* if not safe, don't unlink */ if (rval != 0) diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c index 6ef2b2f..e29d774 100644 --- a/contrib/sendmail/src/daemon.c +++ b/contrib/sendmail/src/daemon.c @@ -16,9 +16,9 @@ #ifndef lint # ifdef DAEMON -static char id[] = "@(#)$Id: daemon.c,v 8.401.4.18 2000/09/21 21:52:16 ca Exp $ (with daemon mode)"; +static char id[] = "@(#)$Id: daemon.c,v 8.401.4.41 2000/12/28 23:46:43 gshapiro Exp $ (with daemon mode)"; # else /* DAEMON */ -static char id[] = "@(#)$Id: daemon.c,v 8.401.4.18 2000/09/21 21:52:16 ca Exp $ (without daemon mode)"; +static char id[] = "@(#)$Id: daemon.c,v 8.401.4.41 2000/12/28 23:46:43 gshapiro Exp $ (without daemon mode)"; # endif /* DAEMON */ #endif /* ! lint */ @@ -162,8 +162,6 @@ getrequests(e) # endif /* NETUNIX */ extern ENVELOPE BlankEnvelope; -#define D(x,idx) x[idx] - for (idx = 0; idx < ndaemons; idx++) { @@ -171,6 +169,7 @@ getrequests(e) Daemons[idx].d_firsttime = TRUE; Daemons[idx].d_refuse_connections_until = (time_t) 0; } + /* ** Try to actually open the connection. */ @@ -178,9 +177,11 @@ getrequests(e) if (tTd(15, 1)) { for (idx = 0; idx < ndaemons; idx++) + { dprintf("getrequests: daemon %s: port %d\n", Daemons[idx].d_name, ntohs(Daemons[idx].d_port)); + } } /* get a socket for the SMTP connection */ @@ -225,72 +226,124 @@ getrequests(e) bool control = FALSE; int save_errno; int pipefd[2]; + time_t timenow; # if STARTTLS long seed; - time_t timenow; # endif /* STARTTLS */ + extern bool refuseconnections __P((char *, ENVELOPE *, int)); /* see if we are rejecting connections */ (void) blocksignal(SIGALRM); + timenow = curtime(); + + /* + ** Use ConnRateThrottle only if the + ** last pass was for a connection + */ + + if (ConnRateThrottle > 0 && curdaemon >= 0) + { + static int conncnt = 0; + static time_t lastconn = 0; + + if (timenow != lastconn) + { + lastconn = timenow; + conncnt = 1; + } + else if (++conncnt > ConnRateThrottle) + { + /* sleep to flatten out connection load */ + sm_setproctitle(TRUE, e, + "deferring connections: %d per second", + ConnRateThrottle); + if (LogLevel >= 9) + sm_syslog(LOG_INFO, NOQID, + "deferring connections: %d per second", + ConnRateThrottle); + (void) sleep(1); + } + } + for (idx = 0; idx < ndaemons; idx++) { - if (curtime() < Daemons[idx].d_refuse_connections_until) + if (timenow < Daemons[idx].d_refuse_connections_until) continue; if (refuseconnections(Daemons[idx].d_name, e, idx)) { if (Daemons[idx].d_socket >= 0) { - /* close socket so peer fails quickly */ - (void) close(Daemons[idx].d_socket); - Daemons[idx].d_socket = -1; + /* close socket so peer fails quickly */ + (void) close(Daemons[idx].d_socket); + Daemons[idx].d_socket = -1; } /* refuse connections for next 15 seconds */ - Daemons[idx].d_refuse_connections_until = curtime() + 15; + Daemons[idx].d_refuse_connections_until = timenow + 15; } else if (Daemons[idx].d_socket < 0 || Daemons[idx].d_firsttime) { - if (!Daemons[idx].d_firsttime && LogLevel >= 9) - sm_syslog(LOG_INFO, NOQID, - "accepting connections again for daemon %s", - Daemons[idx].d_name); - - /* arrange to (re)open the socket if needed */ - (void) opendaemonsocket(&Daemons[idx], FALSE); - Daemons[idx].d_firsttime = FALSE; + if (!Daemons[idx].d_firsttime && LogLevel >= 9) + sm_syslog(LOG_INFO, NOQID, + "accepting connections again for daemon %s", + Daemons[idx].d_name); + + /* arrange to (re)open the socket if needed */ + (void) opendaemonsocket(&Daemons[idx], FALSE); + Daemons[idx].d_firsttime = FALSE; } } - if (curtime() >= last_disk_space_check) + if (timenow >= last_disk_space_check) { + bool logged = FALSE; + if (!enoughdiskspace(MinBlocksFree + 1, FALSE)) { - if (!bitnset(D_ETRNONLY, Daemons[idx].d_flags)) + for (idx = 0; idx < ndaemons; idx++) { - /* log only if not logged before */ - if (LogLevel >= 9) - sm_syslog(LOG_INFO, NOQID, - "rejecting new messages: min free: %ld", - MinBlocksFree); - sm_setproctitle(TRUE, e, - "rejecting new messages: min free: %ld", - MinBlocksFree); - setbitn(D_ETRNONLY, Daemons[idx].d_flags); + if (!bitnset(D_ETRNONLY, Daemons[idx].d_flags)) + { + /* log only if not logged before */ + if (!logged) + { + if (LogLevel >= 9) + sm_syslog(LOG_INFO, NOQID, + "rejecting new messages: min free: %ld", + MinBlocksFree); + logged = TRUE; + sm_setproctitle(TRUE, e, + "rejecting new messages: min free: %ld", + MinBlocksFree); + } + setbitn(D_ETRNONLY, Daemons[idx].d_flags); + } } } - else if (bitnset(D_ETRNONLY, Daemons[idx].d_flags)) + else { - /* log only if not logged before */ - if (LogLevel >= 9) - sm_syslog(LOG_INFO, NOQID, - "accepting new messages (again)"); - /* title will be set below */ - clrbitn(D_ETRNONLY, Daemons[idx].d_flags); + for (idx = 0; idx < ndaemons; idx++) + { + if (bitnset(D_ETRNONLY, Daemons[idx].d_flags)) + { + /* log only if not logged before */ + if (!logged) + { + if (LogLevel >= 9) + sm_syslog(LOG_INFO, NOQID, + "accepting new messages (again)"); + logged = TRUE; + } + + /* title will be set below */ + clrbitn(D_ETRNONLY, Daemons[idx].d_flags); + } + } } /* only check disk space once a minute */ - last_disk_space_check = curtime() + 60; + last_disk_space_check = timenow + 60; } # if XDEBUG @@ -331,6 +384,7 @@ getrequests(e) for (;;) { + bool setproc = FALSE; int highest = -1; fd_set readfds; struct timeval timeout; @@ -342,10 +396,13 @@ getrequests(e) /* wait for a connection */ if (Daemons[idx].d_socket >= 0) { - if (!bitnset(D_ETRNONLY, Daemons[idx].d_flags)) + if (!setproc && + !bitnset(D_ETRNONLY, + Daemons[idx].d_flags)) { sm_setproctitle(TRUE, e, "accepting connections"); + setproc = TRUE; } if (Daemons[idx].d_socket > highest) highest = Daemons[idx].d_socket; @@ -367,6 +424,7 @@ getrequests(e) ** to 5 seconds (so it might get reopened soon), ** otherwise (all sockets open) 60. */ + idx = 0; while (idx < ndaemons && Daemons[idx].d_socket >= 0) idx++; @@ -379,8 +437,12 @@ getrequests(e) t = select(highest + 1, FDSET_CAST &readfds, NULL, NULL, &timeout); + + if (DoQueueRun) (void) runqueue(TRUE, FALSE); + + curdaemon = -1; if (t <= 0) { timedout = TRUE; @@ -389,7 +451,6 @@ getrequests(e) control = FALSE; errno = 0; - curdaemon = -1; /* look "round-robin" for an active socket */ if ((idx = olddaemon + 1) >= ndaemons) @@ -411,7 +472,7 @@ getrequests(e) } # if NETUNIX if (curdaemon == -1 && ControlSocket >= 0 && - FD_ISSET(ControlSocket, &readfds)) + FD_ISSET(ControlSocket, &readfds)) { struct sockaddr_un sa_un; @@ -421,6 +482,12 @@ getrequests(e) &lotherend); control = TRUE; } +# else /* NETUNIX */ + if (curdaemon == -1) + { + /* No daemon to service */ + continue; + } # endif /* NETUNIX */ if (t >= 0 || errno != EINTR) break; @@ -431,6 +498,7 @@ getrequests(e) continue; } save_errno = errno; + timenow = curtime(); (void) blocksignal(SIGALRM); if (t < 0) { @@ -447,7 +515,7 @@ getrequests(e) ** force accept() to fail on affected systems. */ - Daemons[curdaemon].d_refuse_connections_until = curtime() + 15; + Daemons[curdaemon].d_refuse_connections_until = timenow + 15; # endif /* SO_REUSEADDR_IS_BROKEN */ continue; } @@ -521,13 +589,13 @@ getrequests(e) seed = get_random(); RAND_seed((void *) &last_disk_space_check, sizeof last_disk_space_check); - timenow = curtime(); RAND_seed((void *) &timenow, sizeof timenow); RAND_seed((void *) &seed, sizeof seed); # else /* STARTTLS */ (void) get_random(); # endif /* STARTTLS */ +#ifndef DEBUG_NO_FORK /* ** Create a pipe to keep the child from writing to the ** socket until after the parent has closed it. Otherwise @@ -552,6 +620,9 @@ getrequests(e) (void) close(t); continue; } +#else /* ! DEBUG_NO_FORK */ + pid = 0; +#endif /* ! DEBUG_NO_FORK */ if (pid == 0) { @@ -608,6 +679,7 @@ getrequests(e) anynet_ntoa(&RealHostAddr)); } +#ifndef DEBUG_NO_FORK if (pipefd[0] != -1) { auto char c; @@ -629,6 +701,7 @@ getrequests(e) continue; (void) close(pipefd[0]); } +#endif /* ! DEBUG_NO_FORK */ /* control socket processing */ if (control) @@ -1045,10 +1118,12 @@ setsockaddroptions(p, d) struct daemon *d; { # if NETISO - short port; + short portno; # endif /* NETISO */ int l; char *h, *flags; + char *port = NULL; + char *addr = NULL; # if NETINET if (d->d_addr.sa.sa_family == AF_UNSPEC) @@ -1107,152 +1182,11 @@ setsockaddroptions(p, d) break; case 'A': /* address */ - switch (d->d_addr.sa.sa_family) - { -# if NETINET - case AF_INET: - if (!isascii(*v) || !isdigit(*v) || - ((d->d_addr.sin.sin_addr.s_addr = inet_addr(v)) == INADDR_NONE)) - { - register struct hostent *hp; - - hp = sm_gethostbyname(v, AF_INET); - if (hp == NULL) - syserr("554 5.3.0 host \"%s\" unknown", - v); - else - { - while (*(hp->h_addr_list) && - hp->h_addrtype != AF_INET) - hp->h_addr_list++; - if (*(hp->h_addr_list) == NULL) - syserr("554 5.3.0 host \"%s\" unknown", - v); - else - memmove(&d->d_addr.sin.sin_addr, - *(hp->h_addr_list), - INADDRSZ); - } - } - break; -# endif /* NETINET */ - -# if NETINET6 - case AF_INET6: - if (!isascii(*v) || !isxdigit(*v) || - inet_pton(AF_INET6, v, - &d->d_addr.sin6.sin6_addr) != 1) - { - register struct hostent *hp; - - hp = sm_gethostbyname(v, AF_INET6); - if (hp == NULL) - syserr("554 5.3.0 host \"%s\" unknown", - v); - else - { - while (*(hp->h_addr_list) && - hp->h_addrtype != AF_INET6) - hp->h_addr_list++; - if (*(hp->h_addr_list) == NULL) - syserr("554 5.3.0 host \"%s\" unknown", - v); - else - memmove(&d->d_addr.sin6.sin6_addr, - *(hp->h_addr_list), - IN6ADDRSZ); - } - } - break; -# endif /* NETINET6 */ - - default: - syserr("554 5.3.5 address= option unsupported for family %d", - d->d_addr.sa.sa_family); - break; - } + addr = v; break; case 'P': /* port */ - switch (d->d_addr.sa.sa_family) - { -# if NETINET - case AF_INET: - if (isascii(*v) && isdigit(*v)) - d->d_addr.sin.sin_port = htons((u_short)atoi((const char *)v)); - else - { -# ifdef NO_GETSERVBYNAME - syserr("554 5.3.5 invalid port number: %s", - v); -# else /* NO_GETSERVBYNAME */ - register struct servent *sp; - - sp = getservbyname(v, "tcp"); - if (sp == NULL) - syserr("554 5.3.5 service \"%s\" unknown", - v); - else - d->d_addr.sin.sin_port = sp->s_port; -# endif /* NO_GETSERVBYNAME */ - } - break; -# endif /* NETINET */ - -# if NETINET6 - case AF_INET6: - if (isascii(*v) && isdigit(*v)) - d->d_addr.sin6.sin6_port = htons((u_short)atoi(v)); - else - { -# ifdef NO_GETSERVBYNAME - syserr("554 5.3.5 invalid port number: %s", - v); -# else /* NO_GETSERVBYNAME */ - register struct servent *sp; - - sp = getservbyname(v, "tcp"); - if (sp == NULL) - syserr("554 5.3.5 service \"%s\" unknown", - v); - else - d->d_addr.sin6.sin6_port = sp->s_port; -# endif /* NO_GETSERVBYNAME */ - } - break; -# endif /* NETINET6 */ - -# if NETISO - case AF_ISO: - /* assume two byte transport selector */ - if (isascii(*v) && isdigit(*v)) - port = htons((u_short)atoi(v)); - else - { -# ifdef NO_GETSERVBYNAME - syserr("554 5.3.5 invalid port number: %s", - v); -# else /* NO_GETSERVBYNAME */ - register struct servent *sp; - - sp = getservbyname(v, "tcp"); - if (sp == NULL) - syserr("554 5.3.5 service \"%s\" unknown", - v); - else - port = sp->s_port; -# endif /* NO_GETSERVBYNAME */ - } - memmove(TSEL(&d->d_addr.siso), - (char *) &port, 2); - break; -# endif /* NETISO */ - - default: - syserr("554 5.3.5 Port= option unsupported for family %d", - d->d_addr.sa.sa_family); - break; - } + port = v; break; case 'L': /* listen queue size */ @@ -1278,7 +1212,7 @@ setsockaddroptions(p, d) *flags++ = '\0'; for (; *v != '\0'; v++) if (!(isascii(*v) && isspace(*v))) - setbitn(*v, d->d_flags); + setbitn(bitidx(*v), d->d_flags); break; case 'S': /* send buffer size */ @@ -1298,6 +1232,167 @@ setsockaddroptions(p, d) f); } } + + /* Check addr and port after finding family */ + if (addr != NULL) + { + switch (d->d_addr.sa.sa_family) + { +# if NETINET + case AF_INET: + if (!isascii(*addr) || !isdigit(*addr) || + ((d->d_addr.sin.sin_addr.s_addr = inet_addr(addr)) == INADDR_NONE)) + { + register struct hostent *hp; + + hp = sm_gethostbyname(addr, AF_INET); + if (hp == NULL) + syserr("554 5.3.0 host \"%s\" unknown", + addr); + else + { + while (*(hp->h_addr_list) != NULL && + hp->h_addrtype != AF_INET) + hp->h_addr_list++; + if (*(hp->h_addr_list) == NULL) + syserr("554 5.3.0 host \"%s\" unknown", + addr); + else + memmove(&d->d_addr.sin.sin_addr, + *(hp->h_addr_list), + INADDRSZ); +# if _FFR_FREEHOSTENT && NETINET6 + freehostent(hp); + hp = NULL; +# endif /* _FFR_FREEHOSTENT && NETINET6 */ + } + } + break; +# endif /* NETINET */ + +# if NETINET6 + case AF_INET6: + if (!isascii(*addr) || + (!isxdigit(*addr) && *addr != ':') || + inet_pton(AF_INET6, addr, + &d->d_addr.sin6.sin6_addr) != 1) + { + register struct hostent *hp; + + hp = sm_gethostbyname(addr, AF_INET6); + if (hp == NULL) + syserr("554 5.3.0 host \"%s\" unknown", + addr); + else + { + while (*(hp->h_addr_list) != NULL && + hp->h_addrtype != AF_INET6) + hp->h_addr_list++; + if (*(hp->h_addr_list) == NULL) + syserr("554 5.3.0 host \"%s\" unknown", + addr); + else + memmove(&d->d_addr.sin6.sin6_addr, + *(hp->h_addr_list), + IN6ADDRSZ); +# if _FFR_FREEHOSTENT + freehostent(hp); + hp = NULL; +# endif /* _FFR_FREEHOSTENT */ + } + } + break; +# endif /* NETINET6 */ + + default: + syserr("554 5.3.5 address= option unsupported for family %d", + d->d_addr.sa.sa_family); + break; + } + } + + if (port != NULL) + { + switch (d->d_addr.sa.sa_family) + { +# if NETINET + case AF_INET: + if (isascii(*port) && isdigit(*port)) + d->d_addr.sin.sin_port = htons((u_short)atoi((const char *)port)); + else + { +# ifdef NO_GETSERVBYNAME + syserr("554 5.3.5 invalid port number: %s", + port); +# else /* NO_GETSERVBYNAME */ + register struct servent *sp; + + sp = getservbyname(port, "tcp"); + if (sp == NULL) + syserr("554 5.3.5 service \"%s\" unknown", + port); + else + d->d_addr.sin.sin_port = sp->s_port; +# endif /* NO_GETSERVBYNAME */ + } + break; +# endif /* NETINET */ + +# if NETINET6 + case AF_INET6: + if (isascii(*port) && isdigit(*port)) + d->d_addr.sin6.sin6_port = htons((u_short)atoi(port)); + else + { +# ifdef NO_GETSERVBYNAME + syserr("554 5.3.5 invalid port number: %s", + port); +# else /* NO_GETSERVBYNAME */ + register struct servent *sp; + + sp = getservbyname(port, "tcp"); + if (sp == NULL) + syserr("554 5.3.5 service \"%s\" unknown", + port); + else + d->d_addr.sin6.sin6_port = sp->s_port; +# endif /* NO_GETSERVBYNAME */ + } + break; +# endif /* NETINET6 */ + +# if NETISO + case AF_ISO: + /* assume two byte transport selector */ + if (isascii(*port) && isdigit(*port)) + portno = htons((u_short)atoi(port)); + else + { +# ifdef NO_GETSERVBYNAME + syserr("554 5.3.5 invalid port number: %s", + port); +# else /* NO_GETSERVBYNAME */ + register struct servent *sp; + + sp = getservbyname(port, "tcp"); + if (sp == NULL) + syserr("554 5.3.5 service \"%s\" unknown", + port); + else + portno = sp->s_port; +# endif /* NO_GETSERVBYNAME */ + } + memmove(TSEL(&d->d_addr.siso), + (char *) &portno, 2); + break; +# endif /* NETISO */ + + default: + syserr("554 5.3.5 Port= option unsupported for family %d", + d->d_addr.sa.sa_family); + break; + } + } } /* ** SETDAEMONOPTIONS -- set options for running the MTA daemon @@ -1494,7 +1589,7 @@ makeconnection(host, port, mci, e) for (; *p != '\0'; p++) { if (!(isascii(*p) && isspace(*p))) - setbitn(*p, d_flags); + setbitn(bitidx(*p), d_flags); } } @@ -1506,7 +1601,7 @@ makeconnection(host, port, mci, e) /* look for just this one flag */ if (*p == D_IFNHELO) { - setbitn(*p, d_flags); + setbitn(bitidx(*p), d_flags); break; } } @@ -1846,6 +1941,10 @@ gothostent: syserr("Can't connect to address family %d", addr.sa.sa_family); mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); errno = EINVAL; +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return EX_NOHOST; } @@ -1856,7 +1955,13 @@ gothostent: # ifdef XLA /* if too many connections, don't bother trying */ if (!xla_noqueue_ok(host)) + { +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return EX_TEMPFAIL; + } # endif /* XLA */ firstconnect = TRUE; @@ -1887,6 +1992,10 @@ gothostent: xla_host_end(host); # endif /* XLA */ mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ errno = save_errno; return EX_TEMPFAIL; } @@ -1960,6 +2069,10 @@ gothostent: errno = save_errno; syserr("makeconnection: cannot bind socket [%s]", anynet_ntoa(&clt_addr)); +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ errno = save_errno; return EX_TEMPFAIL; } @@ -2068,6 +2181,13 @@ gothostent: errstring(save_errno)); v6found = TRUE; family = AF_INET; +# if _FFR_FREEHOSTENT + if (hp != NULL) + { + freehostent(hp); + hp = NULL; + } +# endif /* _FFR_FREEHOSTENT */ goto v4retry; } v6tempfail: @@ -2084,10 +2204,22 @@ gothostent: xla_host_end(host); # endif /* XLA */ mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ errno = save_errno; return EX_TEMPFAIL; } +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + { + freehostent(hp); + hp = NULL; + } +# endif /* _FFR_FREEHOSTENT && NETINET6 */ + /* connection ok, put it into canonical form */ mci->mci_out = NULL; if ((mci->mci_out = fdopen(s, "w")) == NULL || @@ -2449,7 +2581,7 @@ getauthinfo(fd, may_be_forged) errno = 0; } (void) snprintf(hbuf, sizeof hbuf, "%s@localhost", - RealUserName); + RealUserName); if (tTd(9, 1)) dprintf("getauthinfo: %s\n", hbuf); return hbuf; @@ -2487,6 +2619,10 @@ getauthinfo(fd, may_be_forged) if (addrcmp(hp, *ha, &RealHostAddr) == 0) break; *may_be_forged = *ha == NULL; +# if _FFR_FREEHOSTENT && NETINET6 + freehostent(hp); + hp = NULL; +# endif /* _FFR_FREEHOSTENT && NETINET6 */ } } @@ -2971,7 +3107,11 @@ host_map_lookup(map, name, av, statp) else { if ((cp = strchr(name, ']')) == NULL) + { + if (tTd(9, 1)) + dprintf("FAILED\n"); return NULL; + } *cp = '\0'; hp = NULL; @@ -2992,6 +3132,10 @@ host_map_lookup(map, name, av, statp) { /* found a match -- copy out */ ans = denlstring((char *) hp->h_name, TRUE, TRUE); +# if _FFR_FREEHOSTENT && NETINET6 + freehostent(hp); + hp = NULL; +# endif /* _FFR_FREEHOSTENT && NETINET6 */ } } @@ -3006,6 +3150,8 @@ host_map_lookup(map, name, av, statp) cp = map_rewrite(map, name, strlen(name), NULL); else cp = map_rewrite(map, ans, strlen(ans), av); + if (tTd(9, 1)) + dprintf("FOUND %s\n", ans); return cp; } @@ -3176,6 +3322,9 @@ host_map_lookup(map, name, avp, statp) cp = map_rewrite(map, name, strlen(name), NULL); else cp = map_rewrite(map, hp->h_name, strlen(hp->h_name), avp); +# if _FFR_FREEHOSTENT && NETINET6 + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return cp; } @@ -3428,8 +3577,35 @@ hostnamebyanyaddr(sap) && inet_addr(hp->h_name) == INADDR_NONE # endif /* NETINET */ ) - return denlstring((char *) hp->h_name, TRUE, TRUE); + { + char *name; + + name = denlstring((char *) hp->h_name, TRUE, TRUE); + +# if _FFR_FREEHOSTENT && NETINET6 + if (name == hp->h_name) + { + static char n[MAXNAME + 1]; + + /* Copy the string, hp->h_name is about to disappear */ + strlcpy(n, name, sizeof n); + name = n; + } + + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ + return name; + } # endif /* NETINET || NETINET6 */ + +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + { + freehostent(hp); + hp = NULL; + } +# endif /* _FFR_FREEHOSTENT && NETINET6 */ + # if NETUNIX if (sap->sa.sa_family == AF_UNIX && sap->sunix.sun_path[0] == '\0') return "localhost"; diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c index 35a4505..440b1db 100644 --- a/contrib/sendmail/src/deliver.c +++ b/contrib/sendmail/src/deliver.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: deliver.c,v 8.600.2.1.2.44 2000/09/21 21:52:17 ca Exp $"; +static char id[] = "@(#)$Id: deliver.c,v 8.600.2.1.2.56 2000/12/19 01:16:12 gshapiro Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -463,17 +463,19 @@ sendall(e, mode) if (!somedeliveries && mode != SM_QUEUE && mode != SM_DEFER && mode != SM_VERIFY) { + time_t now = curtime(); + if (tTd(13, 29)) dprintf("No deliveries: auto-queuing\n"); mode = SM_QUEUE; /* treat this as a delivery in terms of counting tries */ - e->e_dtime = curtime(); + e->e_dtime = now; if (!expensive) e->e_ntries++; for (ee = splitenv; ee != NULL; ee = ee->e_sibling) { - ee->e_dtime = curtime(); + ee->e_dtime = now; if (!expensive) ee->e_ntries++; } @@ -1239,7 +1241,7 @@ deliver(e, firstto) ovr = TRUE; /* do config file checking of compatibility */ rcode = rscheck("check_compat", e->e_from.q_paddr, to->q_paddr, - e, TRUE, TRUE, 4); + e, TRUE, TRUE, 4, NULL); if (rcode == EX_OK) { /* do in-code checking if not discarding */ @@ -2238,21 +2240,17 @@ tryhost: #if SMTP if (clever && mci->mci_state != MCIS_CLOSED) { - static u_short again; # if SASL && SFIO -# define DONE_TLS_B 0x01 -# define DONE_TLS bitset(DONE_TLS_B, again) +# define DONE_AUTH(f) bitset(MCIF_AUTHACT, f) # endif /* SASL && SFIO */ # if STARTTLS -# define DONE_STARTTLS_B 0x02 -# define DONE_STARTTLS bitset(DONE_STARTTLS_B, again) +# define DONE_STARTTLS(f) bitset(MCIF_TLSACT, f) # endif /* STARTTLS */ -# define ONLY_HELO_B 0x04 -# define ONLY_HELO bitset(ONLY_HELO_B, again) -# define SET_HELO again |= ONLY_HELO_B -# define CLR_HELO again &= ~ONLY_HELO_B +# define ONLY_HELO(f) bitset(MCIF_ONLY_EHLO, f) +# define SET_HELO(f) f |= MCIF_ONLY_EHLO +# define CLR_HELO(f) f &= ~MCIF_ONLY_EHLO + - again = 0; # if STARTTLS || (SASL && SFIO) reconnect: /* after switching to an authenticated connection */ # endif /* STARTTLS || (SASL && SFIO) */ @@ -2260,18 +2258,20 @@ reconnect: /* after switching to an authenticated connection */ # if SASL mci->mci_saslcap = NULL; # endif /* SASL */ - smtpinit(m, mci, e, ONLY_HELO); - CLR_HELO; + smtpinit(m, mci, e, ONLY_HELO(mci->mci_flags)); + CLR_HELO(mci->mci_flags); # if STARTTLS /* first TLS then AUTH to provide a security layer */ - if (mci->mci_state != MCIS_CLOSED && !DONE_STARTTLS) + if (mci->mci_state != MCIS_CLOSED && + !DONE_STARTTLS(mci->mci_flags)) { int olderrors; bool hasdot; bool usetls; bool saveQuickAbort = QuickAbort; bool saveSuprErrs = SuprErrs; + char *host = NULL; # if _FFR_TLS_CLT1 char *p; # endif /* _FFR_TLS_CLT1 */ @@ -2306,20 +2306,22 @@ reconnect: /* after switching to an authenticated connection */ newstr(anynet_ntoa(&CurHostAddr)), e); else define(macid("{server_addr}", NULL), NULL, e); -# if _FFR_TLS_O_T if (usetls) { + host = macvalue(macid("{server_name}", NULL), + e); +# if _FFR_TLS_O_T olderrors = Errors; QuickAbort = FALSE; SuprErrs = TRUE; if (rscheck("try_tls", CurHostName, NULL, - e, TRUE, FALSE, 8) != EX_OK + e, TRUE, FALSE, 8, host) != EX_OK || Errors > olderrors) usetls = FALSE; SuprErrs = saveSuprErrs; QuickAbort = saveQuickAbort; - } # endif /* _FFR_TLS_O_T */ + } /* undo change of CurHostName */ if (hasdot) @@ -2329,7 +2331,6 @@ reconnect: /* after switching to an authenticated connection */ if ((rcode = starttls(m, mci, e)) == EX_OK) { /* start again without STARTTLS */ - again |= DONE_STARTTLS_B; mci->mci_flags |= MCIF_TLSACT; } else @@ -2367,6 +2368,12 @@ reconnect: /* after switching to an authenticated connection */ newstr(s), e); } } + else if (mci->mci_ssl != NULL) + { + /* active TLS connection, use that data */ + (void) tls_get_info(mci->mci_ssl, e, FALSE, + mci->mci_host, FALSE); + } else define(macid("{verify}", NULL), "NONE", e); olderrors = Errors; @@ -2383,7 +2390,7 @@ reconnect: /* after switching to an authenticated connection */ */ if (rscheck("tls_server", macvalue(macid("{verify}", NULL), e), - NULL, e, TRUE, TRUE, 6) != EX_OK || + NULL, e, TRUE, TRUE, 6, host) != EX_OK || Errors > olderrors || rcode == EX_SOFTWARE) { @@ -2422,6 +2429,9 @@ reconnect: /* after switching to an authenticated connection */ smtpquit(m, mci, e); } + /* avoid bogus error msg */ + mci->mci_errno = 0; + /* temp or permanent failure? */ rcode = (*p == '4') ? EX_TEMPFAIL : EX_UNAVAILABLE; @@ -2435,20 +2445,27 @@ reconnect: /* after switching to an authenticated connection */ } QuickAbort = saveQuickAbort; SuprErrs = saveSuprErrs; - if (DONE_STARTTLS && mci->mci_state != MCIS_CLOSED) + if (DONE_STARTTLS(mci->mci_flags) && + mci->mci_state != MCIS_CLOSED) { - SET_HELO; + SET_HELO(mci->mci_flags); mci->mci_flags &= ~MCIF_EXTENS; goto reconnect; } } + else if (mci->mci_ssl != NULL) + { + /* active TLS connection, use that data */ + (void) tls_get_info(mci->mci_ssl, e, FALSE, + mci->mci_host, FALSE); + } # endif /* STARTTLS */ # if SASL /* if other server supports authentication let's authenticate */ if (mci->mci_state != MCIS_CLOSED && mci->mci_saslcap != NULL && # if SFIO - !DONE_TLS && + !DONE_AUTH(mci->mci_flags) && # endif /* SFIO */ SASLInfo != NULL) { @@ -2490,8 +2507,7 @@ reconnect: /* after switching to an authenticated connection */ if (sfdcsasl(mci->mci_in, mci->mci_out, mci->mci_conn) == 0) { - again |= DONE_TLS_B; - SET_HELO; + SET_HELO(mci->mci_flags); mci->mci_flags &= ~MCIF_EXTENS; mci->mci_flags |= MCIF_AUTHACT; goto reconnect; @@ -2609,9 +2625,11 @@ do_transfer: # if STARTTLS # if _FFR_TLS_RCPT i = rscheck("tls_rcpt", to->q_user, NULL, e, - TRUE, TRUE, 4); + TRUE, TRUE, 4, mci->mci_host); if (i != EX_OK) { + /* avoid bogus error msg */ + errno = 0; markfailure(e, to, mci, i, FALSE); giveresponse(i, to->q_status, m, mci, ctladdr, xstart, e); @@ -3368,6 +3386,7 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) register char *bp; register char *p; int l; + time_t now; char buf[1024]; #if (SYSLOG_BUFSIZE) >= 256 @@ -3388,14 +3407,15 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) } /* delay & xdelay: max 41 bytes */ + now = curtime(); snprintf(bp, SPACELEFT(buf, bp), ", delay=%s", - pintvl(curtime() - e->e_ctime, TRUE)); + pintvl(now - e->e_ctime, TRUE)); bp += strlen(bp); if (xstart != (time_t) 0) { snprintf(bp, SPACELEFT(buf, bp), ", xdelay=%s", - pintvl(curtime() - xstart, TRUE)); + pintvl(now - xstart, TRUE)); bp += strlen(bp); } @@ -3553,12 +3573,12 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) } bp = buf; snprintf(bp, SPACELEFT(buf, bp), "delay=%s", - pintvl(curtime() - e->e_ctime, TRUE)); + pintvl(now - e->e_ctime, TRUE)); bp += strlen(bp); if (xstart != (time_t) 0) { snprintf(bp, SPACELEFT(buf, bp), ", xdelay=%s", - pintvl(curtime() - xstart, TRUE)); + pintvl(now - xstart, TRUE)); bp += strlen(bp); } @@ -3901,6 +3921,11 @@ putbody(mci, e, separator) dead = TRUE; continue; } + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } pos++; } for (xp = buf; xp < bp; xp++) @@ -3911,9 +3936,11 @@ putbody(mci, e, separator) dead = TRUE; break; } - - /* record progress for DATA timeout */ - DataProgress = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } } if (dead) continue; @@ -3922,6 +3949,11 @@ putbody(mci, e, separator) if (fputs(mci->mci_mailer->m_eol, mci->mci_out) == EOF) break; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } pos = 0; } else @@ -3931,8 +3963,6 @@ putbody(mci, e, separator) *pbp++ = c; } - /* record progress for DATA timeout */ - DataProgress = TRUE; bp = buf; /* determine next state */ @@ -3951,9 +3981,11 @@ putbody(mci, e, separator) if (fputs(mci->mci_mailer->m_eol, mci->mci_out) == EOF) continue; - - /* record progress for DATA timeout */ - DataProgress = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) { @@ -4005,6 +4037,11 @@ putch: dead = TRUE; continue; } + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } pos++; continue; } @@ -4016,9 +4053,11 @@ putch: dead = TRUE; continue; } - - /* record progress for DATA timeout */ - DataProgress = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) { @@ -4037,6 +4076,11 @@ putch: if (fputs(mci->mci_mailer->m_eol, mci->mci_out) == EOF) continue; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } pos = 0; ostate = OS_HEAD; } @@ -4051,12 +4095,14 @@ putch: dead = TRUE; continue; } + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } pos++; ostate = OS_INLINE; } - - /* record progress for DATA timeout */ - DataProgress = TRUE; break; } } @@ -4078,9 +4124,11 @@ putch: dead = TRUE; break; } - - /* record progress for DATA timeout */ - DataProgress = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } } pos += bp - buf; } @@ -4398,12 +4446,21 @@ mailfile(filename, mailer, ctladdr, sfflags, e) } else if (bitset(S_ISGID, mode)) RealGid = stb.st_gid; - else if (ctladdr != NULL && ctladdr->q_uid != 0) - RealGid = ctladdr->q_gid; else if (ctladdr != NULL && ctladdr->q_uid == DefUid && ctladdr->q_gid == 0) + { + /* + ** Special case: This means it is an + ** alias and we should act as DefaultUser. + ** See alias()'s comments. + */ + RealGid = DefGid; + RealUserName = DefUser; + } + else if (ctladdr != NULL && ctladdr->q_uid != 0) + RealGid = ctladdr->q_gid; else if (mailer != NULL && mailer->m_gid != 0) RealGid = mailer->m_gid; else @@ -4698,6 +4755,7 @@ hostsignature(m, host) int len; int nmx; int hl; + time_t now; char *hp; char *endp; int oldoptions = _res.options; @@ -4756,6 +4814,7 @@ hostsignature(m, host) if (ConfigLevel < 2) _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */ + now = curtime(); for (hp = host; hp != NULL; hp = endp) { #if NETINET6 @@ -4795,7 +4854,7 @@ hostsignature(m, host) mci = mci_get(hp, m); mci->mci_errno = errno; mci->mci_herrno = h_errno; - mci->mci_lastuse = curtime(); + mci->mci_lastuse = now; if (rcode == EX_NOHOST) mci_setstat(mci, rcode, "5.1.2", "550 Host unknown"); @@ -5113,7 +5172,7 @@ starttls(m, mci, e) return EX_SOFTWARE; } mci->mci_ssl = clt_ssl; - result = tls_get_info(clt_ssl, e, FALSE, mci->mci_host); + result = tls_get_info(clt_ssl, e, FALSE, mci->mci_host, TRUE); /* switch to use SSL... */ #if SFIO diff --git a/contrib/sendmail/src/domain.c b/contrib/sendmail/src/domain.c index 8f5c8e2..39126dd 100644 --- a/contrib/sendmail/src/domain.c +++ b/contrib/sendmail/src/domain.c @@ -15,9 +15,9 @@ #ifndef lint # if NAMED_BIND -static char id[] = "@(#)$Id: domain.c,v 8.114.6.1.2.3 2000/06/13 18:00:08 gshapiro Exp $ (with name server)"; +static char id[] = "@(#)$Id: domain.c,v 8.114.6.1.2.6 2000/12/19 02:50:33 gshapiro Exp $ (with name server)"; # else /* NAMED_BIND */ -static char id[] = "@(#)$Id: domain.c,v 8.114.6.1.2.3 2000/06/13 18:00:08 gshapiro Exp $ (without name server)"; +static char id[] = "@(#)$Id: domain.c,v 8.114.6.1.2.6 2000/12/19 02:50:33 gshapiro Exp $ (without name server)"; # endif /* NAMED_BIND */ #endif /* ! lint */ @@ -393,6 +393,10 @@ punt: host, MyHostName); return -1; } +# if _FFR_FREEHOSTENT && NETINET6 + freehostent(h); + hp = NULL; +# endif /* _FFR_FREEHOSTENT && NETINET6 */ } if (strlen(host) >= (SIZE_T) sizeof MXHostBuf) { @@ -640,6 +644,8 @@ dns_getcanonname(host, hbsize, trymx, statp) return FALSE; } + *statp = EX_OK; + /* ** Initialize domain search list. If there is at least one ** dot in the name, search the unmodified name first so we @@ -730,6 +736,7 @@ cnameloop: qtype == T_A ? "A" : qtype == T_MX ? "MX" : "???"); + errno = 0; ret = res_querydomain(host, *dp, C_IN, qtype, answer.qb2, sizeof(answer.qb2)); if (ret <= 0) @@ -740,7 +747,11 @@ cnameloop: if (errno == ECONNREFUSED || h_errno == TRY_AGAIN) { - /* the name server seems to be down */ + /* + ** the name server seems to be down or + ** broken. + */ + h_errno = TRY_AGAIN; *statp = EX_TEMPFAIL; @@ -757,8 +768,23 @@ cnameloop: ** the cache so this isn't dangerous. */ +#if _FFR_WORKAROUND_BROKEN_NAMESERVERS + /* + ** Only return if not TRY_AGAIN as an + ** attempt with a different qtype may + ** succeed (res_querydomain() calls + ** res_query() calls res_send() which + ** sets errno to ETIMEDOUT if the + ** nameservers could be contacted but + ** didn't give an answer). + */ + + if (qtype != T_ANY && errno != ETIMEDOUT) + return FALSE; +#else /* _FFR_WORKAROUND_BROKEN_NAMESERVERS */ if (qtype != T_ANY) return FALSE; +#endif /* _FFR_WORKAROUND_BROKEN_NAMESERVERS */ } if (h_errno != HOST_NOT_FOUND) @@ -976,7 +1002,8 @@ cnameloop: /* if nothing was found, we are done */ if (mxmatch == NULL) { - *statp = EX_NOHOST; + if (*statp == EX_OK) + *statp = EX_NOHOST; return FALSE; } diff --git a/contrib/sendmail/src/envelope.c b/contrib/sendmail/src/envelope.c index 1a6136e..a708589 100644 --- a/contrib/sendmail/src/envelope.c +++ b/contrib/sendmail/src/envelope.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: envelope.c,v 8.180.14.4 2000/08/22 18:22:39 gshapiro Exp $"; +static char id[] = "@(#)$Id: envelope.c,v 8.180.14.6 2000/11/30 00:39:46 gshapiro Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -91,6 +91,7 @@ dropenvelope(e, fulldrop) bool done = FALSE; register ADDRESS *q; char *id = e->e_id; + time_t now; char buf[MAXLINE]; if (tTd(50, 1)) @@ -130,7 +131,8 @@ dropenvelope(e, fulldrop) ** Extract state information from dregs of send list. */ - if (curtime() > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) + now = curtime(); + if (now > e->e_ctime + TimeOuts.to_q_return[e->e_timeoutclass]) message_timeout = TRUE; if (TimeOuts.to_q_return[e->e_timeoutclass] == NOW && @@ -208,7 +210,7 @@ dropenvelope(e, fulldrop) } } else if (TimeOuts.to_q_warning[e->e_timeoutclass] > 0 && - curtime() > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) + now > e->e_ctime + TimeOuts.to_q_warning[e->e_timeoutclass]) { if (!bitset(EF_WARNING|EF_RESPONSE, e->e_flags) && e->e_class >= 0 && @@ -965,7 +967,7 @@ static struct eflags EnvelopeFlags[] = { "HAS_DF", EF_HAS_DF }, { "IS_MIME", EF_IS_MIME }, { "DONT_MIME", EF_DONT_MIME }, - { NULL } + { NULL, 0 } }; void diff --git a/contrib/sendmail/src/macro.c b/contrib/sendmail/src/macro.c index 007a6eb..1a32182 100644 --- a/contrib/sendmail/src/macro.c +++ b/contrib/sendmail/src/macro.c @@ -12,14 +12,17 @@ */ #ifndef lint -static char id[] = "@(#)$Id: macro.c,v 8.40.16.2 2000/09/17 17:04:26 gshapiro Exp $"; +static char id[] = "@(#)$Id: macro.c,v 8.40.16.7 2000/10/09 15:49:06 gshapiro Exp $"; #endif /* ! lint */ #include <sendmail.h> -char *MacroName[256]; /* macro id to name table */ -int NextMacroId = 0240; /* codes for long named macros */ +#if MAXMACROID != (BITMAPBITS - 1) + ERROR Read the comment in conf.h +#endif /* MAXMACROID != (BITMAPBITS - 1) */ +char *MacroName[MAXMACROID + 1]; /* macro id to name table */ +int NextMacroId = 0240; /* codes for long named macros */ /* ** EXPAND -- macro expand a string using $x escapes. @@ -111,7 +114,7 @@ expand(s, buf, bufsize, e) continue; case MACROEXPAND: /* macro interpolation */ - c = *++s & 0377; + c = bitidx(*++s); if (c != '\0') q = macvalue(c, e); else @@ -247,7 +250,7 @@ define(n, v, e) { int m; - m = n & 0377; + m = bitidx(n); if (tTd(35, 9)) { dprintf("%sdefine(%s as ", @@ -285,7 +288,7 @@ macvalue(n, e) int n; register ENVELOPE *e; { - n &= 0377; + n = bitidx(n); while (e != NULL) { register char *p = e->e_macro[n]; @@ -315,7 +318,7 @@ macname(n) { static char mbuf[2]; - n &= 0377; + n = bitidx(n); if (bitset(0200, n)) { char *p = MacroName[n]; @@ -368,7 +371,7 @@ macid(p, ep) *ep = p; if (tTd(35, 14)) dprintf("NULL\n"); - return '\0'; + return 0; } if (*p != '{') { @@ -376,8 +379,8 @@ macid(p, ep) if (ep != NULL) *ep = p + 1; if (tTd(35, 14)) - dprintf("%c\n", *p); - return *p; + dprintf("%c\n", bitidx(*p)); + return bitidx(*p); } bp = mbuf; while (*++p != '\0' && *p != '}' && bp < &mbuf[sizeof mbuf - 1]) @@ -401,7 +404,7 @@ macid(p, ep) else if (mbuf[1] == '\0') { /* ${x} == $x */ - mid = mbuf[0]; + mid = bitidx(mbuf[0]); p++; } else @@ -428,6 +431,13 @@ macid(p, ep) } if (ep != NULL) *ep = p; + if (mid < 0 || mid > MAXMACROID) + { + syserr("Unable to assign macro/class ID (mid = 0x%x)", mid); + if (tTd(35, 14)) + dprintf("NULL\n"); + return 0; + } if (tTd(35, 14)) dprintf("0x%x\n", mid); return mid; @@ -452,5 +462,5 @@ wordinclass(str, cl) register STAB *s; s = stab(str, ST_CLASS, ST_FIND); - return s != NULL && bitnset(cl & 0xff, s->s_class); + return s != NULL && bitnset(bitidx(cl), s->s_class); } diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c index 58f49c4..5097b58 100644 --- a/contrib/sendmail/src/main.c +++ b/contrib/sendmail/src/main.c @@ -21,7 +21,7 @@ static char copyright[] = #endif /* ! lint */ #ifndef lint -static char id[] = "@(#)$Id: main.c,v 8.485.4.27 2000/09/26 01:30:38 gshapiro Exp $"; +static char id[] = "@(#)$Id: main.c,v 8.485.4.38 2000/12/19 02:50:33 gshapiro Exp $"; #endif /* ! lint */ #define _DEFINE @@ -624,6 +624,10 @@ main(argc, argv, envp) setclass('w', ipbuf); } #endif /* NETINET || NETINET6 */ +#if _FFR_FREEHOSTENT && NETINET6 + freehostent(hp); + hp = NULL; +#endif /* _FFR_FREEHOSTENT && NETINET6 */ } /* current time */ @@ -1540,6 +1544,15 @@ main(argc, argv, envp) { char buf[MAXLINE]; +#if _FFR_TESTMODE_DROP_PRIVS + dp = drop_privileges(TRUE); + if (dp != EX_OK) + { + CurEnv->e_id = NULL; + finis(TRUE, dp); + } +#endif /* _FFR_TESTMODE_DROP_PRIVS */ + if (isatty(fileno(stdin))) Verbose = 2; @@ -1608,6 +1621,16 @@ main(argc, argv, envp) } #endif /* QUEUE */ +# if SASL + if (OpMode == MD_SMTP || OpMode == MD_DAEMON) + { + /* give a syserr or just disable AUTH ? */ + if ((i = sasl_server_init(srvcallbacks, "Sendmail")) != SASL_OK) + syserr("!sasl_server_init failed! [%s]", + sasl_errstring(i, NULL, NULL)); + } +# endif /* SASL */ + /* ** If a daemon, wait for a request. ** getrequests will always return in a child. @@ -1760,13 +1783,6 @@ main(argc, argv, envp) define(macid("{client_port}", NULL), newstr(pbuf), &BlankEnvelope); -#if SASL - /* give a syserr or just disable AUTH ? */ - if ((i = sasl_server_init(srvcallbacks, "Sendmail")) != SASL_OK) - syserr("!sasl_server_init failed! [%s]", - sasl_errstring(i, NULL, NULL)); -#endif /* SASL */ - if (OpMode == MD_DAEMON) { /* validate the connection */ @@ -1784,6 +1800,8 @@ main(argc, argv, envp) if (OpMode == MD_SMTP) (void) initsrvtls(); # endif /* STARTTLS */ + + smtp(nullserver, *p_flags, CurEnv); } #endif /* SMTP */ @@ -2167,7 +2185,7 @@ struct metamac MetaMacros[] = /* miscellaneous control characters */ { '&', MACRODEXPAND }, - { '\0' } + { '\0', '\0' } }; #define MACBINDING(name, mid) \ @@ -2181,7 +2199,7 @@ initmacros(e) register struct metamac *m; register int c; char buf[5]; - extern char *MacroName[256]; + extern char *MacroName[MAXMACROID + 1]; for (m = MetaMacros; m->metaname != '\0'; m++) { @@ -2388,7 +2406,18 @@ auth_warning(e, msg, va_alist) static char hostbuf[48]; if (hostbuf[0] == '\0') - (void) myhostname(hostbuf, sizeof hostbuf); + { + struct hostent *hp; + + hp = myhostname(hostbuf, sizeof hostbuf); +#if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + { + freehostent(hp); + hp = NULL; + } +#endif /* _FFR_FREEHOSTENT && NETINET6 */ + } (void) snprintf(buf, sizeof buf, "%s: ", hostbuf); p = &buf[strlen(buf)]; @@ -2782,7 +2811,7 @@ testmodeline(line, e) { case 'D': mid = macid(&line[2], &delimptr); - if (mid == '\0') + if (mid == 0) return; translate_dollars(delimptr); define(mid, newstr(delimptr), e); @@ -2793,7 +2822,7 @@ testmodeline(line, e) return; mid = macid(&line[2], &delimptr); - if (mid == '\0') + if (mid == 0) return; translate_dollars(delimptr); expand(delimptr, exbuf, sizeof exbuf, e); @@ -2899,12 +2928,12 @@ testmodeline(line, e) if (line[1] == '=') { mid = macid(&line[2], NULL); - if (mid != '\0') + if (mid != 0) stabapply(dump_class, mid); return; } mid = macid(&line[1], NULL); - if (mid == '\0') + if (mid == 0) return; p = macvalue(mid, e); if (p == NULL) @@ -3169,6 +3198,6 @@ dump_class(s, id) { if (s->s_type != ST_CLASS) return; - if (bitnset(id & 0xff, s->s_class)) + if (bitnset(bitidx(id), s->s_class)) printf("%s\n", s->s_name); } diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c index 3676d44..8fb0cfd 100644 --- a/contrib/sendmail/src/map.c +++ b/contrib/sendmail/src/map.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: map.c,v 8.414.4.24 2000/09/27 04:11:29 gshapiro Exp $"; +static char id[] = "@(#)$Id: map.c,v 8.414.4.34 2000/12/18 18:00:43 ca Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -2895,6 +2895,7 @@ ldapmap_start(map) # if USE_LDAP_INIT ld = ldap_init(lmap->ldap_host, lmap->ldap_port); + save_errno = errno; # else /* USE_LDAP_INIT */ /* ** If using ldap_open(), the actual connection to the server @@ -3574,7 +3575,7 @@ ldapmap_lookup(map, name, av, statp) } /* Did we match anything? */ - if (vp == NULL) + if (vp == NULL && !bitset(MF_MATCHONLY, map->map_mflags)) return NULL; /* @@ -3586,22 +3587,26 @@ ldapmap_lookup(map, name, av, statp) if (bitset(MF_NOREWRITE, map->map_mflags)) { - /* vp != NULL due to test above */ - free(vp); + if (vp != NULL) + free(vp); return ""; } if (*statp == EX_OK) { - /* vp != NULL due to test above */ if (LogLevel > 9) sm_syslog(LOG_INFO, CurEnv->e_id, - "ldap %.100s => %s", name, vp); + "ldap %.100s => %s", name, + vp == NULL ? "<NULL>" : vp); if (bitset(MF_MATCHONLY, map->map_mflags)) result = map_rewrite(map, name, strlen(name), NULL); else + { + /* vp != NULL according to test above */ result = map_rewrite(map, vp, strlen(vp), av); - free(vp); + } + if (vp != NULL) + free(vp); } return result; } @@ -4238,7 +4243,7 @@ ldapmap_parseargs(map, args) if (p != NULL) *p++ = '\0'; - if (i == LDAPMAP_MAX_ATTR) + if (i >= LDAPMAP_MAX_ATTR) { syserr("Too many return attributes in %s (max %d)", map->map_mname, LDAPMAP_MAX_ATTR); @@ -4631,7 +4636,7 @@ ph_map_open(map, mode) { if (tTd(9, 1)) dprintf("ph_map_open(%s) => DEFERRED\n", - map->map_mname); + map->map_mname); /* ** Unset MF_DEFER here so that map_lookup() returns @@ -6719,7 +6724,7 @@ macro_map_lookup(map, name, av, statp) struct regex_map { - regex_t regex_pattern_buf; /* xalloc it */ + regex_t *regex_pattern_buf; /* xalloc it */ int *regex_subfields; /* move to type MAP */ char *regex_delim; /* move to type MAP */ }; @@ -6796,6 +6801,7 @@ regex_map_init(map, ap) p = ap; map_p = (struct regex_map *) xnalloc(sizeof *map_p); + map_p->regex_pattern_buf = (regex_t *)xnalloc(sizeof(regex_t)); for (;;) { @@ -6852,14 +6858,15 @@ regex_map_init(map, ap) if (tTd(38, 3)) dprintf("regex_map_init: compile '%s' 0x%x\n", p, pflags); - if ((regerr = regcomp(&(map_p->regex_pattern_buf), p, pflags)) != 0) + if ((regerr = regcomp(map_p->regex_pattern_buf, p, pflags)) != 0) { /* Errorhandling */ char errbuf[ERRBUF_SIZE]; - (void) regerror(regerr, &(map_p->regex_pattern_buf), + (void) regerror(regerr, map_p->regex_pattern_buf, errbuf, ERRBUF_SIZE); syserr("pattern-compile-error: %s\n", errbuf); + free(map_p->regex_pattern_buf); free(map_p); return FALSE; } @@ -6877,7 +6884,7 @@ regex_map_init(map, ap) int substrings; int *fields = (int *) xalloc(sizeof(int) * (MAX_MATCH + 1)); - substrings = map_p->regex_pattern_buf.re_nsub + 1; + substrings = map_p->regex_pattern_buf->re_nsub + 1; if (tTd(38, 3)) dprintf("regex_map_init: nr of substrings %d\n", @@ -6886,6 +6893,7 @@ regex_map_init(map, ap) if (substrings >= MAX_MATCH) { syserr("too many substrings, %d max\n", MAX_MATCH); + free(map_p->regex_pattern_buf); free(map_p); return FALSE; } @@ -6955,7 +6963,7 @@ regex_map_lookup(map, name, av, statp) } map_p = (struct regex_map *)(map->map_db1); - reg_res = regexec(&(map_p->regex_pattern_buf), + reg_res = regexec(map_p->regex_pattern_buf, name, MAX_MATCH, pmatch, 0); if (bitset(MF_REGEX_NOT, map->map_mflags)) @@ -6987,7 +6995,7 @@ regex_map_lookup(map, name, av, statp) if (av[1] != NULL) { if (parse_fields(av[1], fields, MAX_MATCH + 1, - (int) map_p->regex_pattern_buf.re_nsub + 1) == -1) + (int) map_p->regex_pattern_buf->re_nsub + 1) == -1) { *statp = EX_CONFIG; return NULL; @@ -7011,7 +7019,8 @@ regex_map_lookup(map, name, av, statp) first = FALSE; - if (pmatch[*ip].rm_so < 0 || pmatch[*ip].rm_eo < 0) + if (*ip >= MAX_MATCH || + pmatch[*ip].rm_so < 0 || pmatch[*ip].rm_eo < 0) continue; sp = name + pmatch[*ip].rm_so; @@ -7128,7 +7137,7 @@ nsd_map_lookup(map, name, av, statp) char **av; int *statp; { - int buflen; + int buflen, r; char *p; ns_map_t *ns_map; char keybuf[MAXNAME + 1]; @@ -7150,12 +7159,27 @@ nsd_map_lookup(map, name, av, statp) { if (tTd(38, 20)) dprintf("nsd_map_t_find failed\n"); + *statp = EX_UNAVAILABLE; return NULL; } - - if (ns_lookup(ns_map, NULL, map->map_file, - keybuf, NULL, buf, MAXLINE) == NULL) + r = ns_lookup(ns_map, NULL, map->map_file, keybuf, NULL, buf, MAXLINE); + if (r == NS_UNAVAIL || r == NS_TRYAGAIN) + { + *statp = EX_TEMPFAIL; return NULL; + } + if (r == NS_BADREQ || r == NS_NOPERM) + { + *statp = EX_CONFIG; + return NULL; + } + if (r != NS_SUCCESS) + { + *statp = EX_NOTFOUND; + return NULL; + } + + *statp = EX_OK; /* Null out trailing \n */ if ((p = strchr(buf, '\n')) != NULL) diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c index 248cba7..a248090 100644 --- a/contrib/sendmail/src/milter.c +++ b/contrib/sendmail/src/milter.c @@ -9,7 +9,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: milter.c,v 8.50.4.33 2000/09/19 19:40:15 gshapiro Exp $"; +static char id[] = "@(#)$Id: milter.c,v 8.50.4.41 2000/12/27 21:35:32 gshapiro Exp $"; #endif /* ! lint */ #if _FFR_MILTER @@ -22,6 +22,9 @@ static char id[] = "@(#)$Id: milter.c,v 8.50.4.33 2000/09/19 19:40:15 gshapiro E # include <arpa/inet.h> # endif /* NETINET || NETINET6 */ +# define SM_FD_SET FD_SET +# define SM_FD_ISSET FD_ISSET +# define SM_FD_SETSIZE FD_SETSIZE static void milter_error __P((struct milter *)); static int milter_open __P((struct milter *, bool, ENVELOPE *)); @@ -113,29 +116,28 @@ static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1]; ** Assumes 'm' is a milter structure for the current socket. */ - -# define MILTER_TIMEOUT(routine, secs, write) \ +# define MILTER_TIMEOUT(routine, secs, write) \ { \ int ret; \ int save_errno; \ fd_set fds; \ struct timeval tv; \ \ - if (m->mf_sock >= FD_SETSIZE) \ + if (SM_FD_SETSIZE != 0 && m->mf_sock >= SM_FD_SETSIZE) \ { \ if (tTd(64, 5)) \ dprintf("%s(%s): socket %d is larger than FD_SETSIZE %d\n", \ - routine, m->mf_name, m->mf_sock, FD_SETSIZE); \ + routine, m->mf_name, m->mf_sock, SM_FD_SETSIZE); \ if (LogLevel > 0) \ sm_syslog(LOG_ERR, e->e_id, \ "%s(%s): socket %d is larger than FD_SETSIZE %d\n", \ - routine, m->mf_name, m->mf_sock, FD_SETSIZE); \ + routine, m->mf_name, m->mf_sock, SM_FD_SETSIZE); \ milter_error(m); \ return NULL; \ } \ \ FD_ZERO(&fds); \ - FD_SET(m->mf_sock, &fds); \ + SM_FD_SET(m->mf_sock, &fds); \ tv.tv_sec = secs; \ tv.tv_usec = 0; \ ret = select(m->mf_sock + 1, \ @@ -167,7 +169,7 @@ static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1]; return NULL; \ \ default: \ - if (FD_ISSET(m->mf_sock, &fds)) \ + if (SM_FD_ISSET(m->mf_sock, &fds)) \ break; \ if (tTd(64, 5)) \ dprintf("%s(%s): socket not ready\n", \ @@ -181,7 +183,6 @@ static char *MilterEnvRcptMacros[MAXFILTERMACROS + 1]; } \ } - /* ** Low level functions */ @@ -879,6 +880,9 @@ milter_open(m, parseonly, e) m->mf_name, at, hp->h_addrtype); milter_error(m); +# if _FFR_FREEHOSTENT && NETINET6 + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return -1; } } @@ -901,6 +905,10 @@ milter_open(m, parseonly, e) if (parseonly) { m->mf_state = SMFS_READY; +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return 0; } @@ -913,6 +921,10 @@ milter_open(m, parseonly, e) dprintf("milter_open(%s): Trying to open filter in state %c\n", m->mf_name, (char) m->mf_state); milter_error(m); +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return -1; } @@ -931,6 +943,10 @@ milter_open(m, parseonly, e) "X%s: error creating socket: %s", m->mf_name, errstring(save_errno)); milter_error(m); +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return -1; } @@ -983,6 +999,9 @@ milter_open(m, parseonly, e) m->mf_name, at, hp->h_addrtype); milter_error(m); +# if _FFR_FREEHOSTENT && NETINET6 + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return -1; } continue; @@ -995,9 +1014,20 @@ milter_open(m, parseonly, e) "X%s: error connecting to filter", m->mf_name); milter_error(m); +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + freehostent(hp); +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return -1; } m->mf_state = SMFS_OPEN; +# if _FFR_FREEHOSTENT && NETINET6 + if (hp != NULL) + { + freehostent(hp); + hp = NULL; + } +# endif /* _FFR_FREEHOSTENT && NETINET6 */ return sock; } /* @@ -1078,7 +1108,7 @@ milter_setup(line) for (; *p != '\0'; p++) { if (!(isascii(*p) && isspace(*p))) - setbitn(*p, m->mf_flags); + setbitn(bitidx(*p), m->mf_flags); } break; @@ -1549,8 +1579,11 @@ milter_quit_filter(m, e) (void) milter_write(m, SMFIC_QUIT, (char *) NULL, 0, m->mf_timeout[SMFTO_WRITE], e); - (void) close(m->mf_sock); - m->mf_sock = -1; + if (m->mf_sock >= 0) + { + (void) close(m->mf_sock); + m->mf_sock = -1; + } if (m->mf_state != SMFS_ERROR) m->mf_state = SMFS_CLOSED; } @@ -1617,7 +1650,7 @@ milter_send_macros(m, macros, cmd, e) for (i = 0; macros[i] != NULL; i++) { mid = macid(macros[i], NULL); - if (mid == '\0') + if (mid == 0) continue; v = macvalue(mid, e); if (v == NULL) @@ -1631,7 +1664,7 @@ milter_send_macros(m, macros, cmd, e) for (i = 0; macros[i] != NULL; i++) { mid = macid(macros[i], NULL); - if (mid == '\0') + if (mid == 0) continue; v = macvalue(mid, e); if (v == NULL) @@ -1841,6 +1874,13 @@ milter_command(command, data, sz, macros, e, state) { struct milter *m = InputFilters[i]; + /* previous problem? */ + if (m->mf_state == SMFS_ERROR) + { + MILTER_CHECK_ERROR(continue); + break; + } + /* sanity check */ if (m->mf_sock < 0 || (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) @@ -2282,6 +2322,7 @@ milter_addheader(response, rlen, e) ENVELOPE *e; { char *val; + HDR *h; if (tTd(64, 10)) dprintf("milter_addheader: "); @@ -2319,13 +2360,31 @@ milter_addheader(response, rlen, e) return; } + for (h = e->e_header; h != NULL; h = h->h_link) + { + if (strcasecmp(h->h_field, response) == 0 && + !bitset(H_USER, h->h_flags) && + !bitset(H_TRACE, h->h_flags)) + break; + } + /* add to e_msgsize */ e->e_msgsize += strlen(response) + 2 + strlen(val); - if (tTd(64, 10)) - dprintf("Add %s: %s\n", response, val); - - addheader(newstr(response), val, H_USER, &e->e_header); + if (h != NULL) + { + if (tTd(64, 10)) + dprintf("Replace default header %s value with %s\n", + h->h_field, val); + h->h_value = newstr(val); + h->h_flags |= H_USER; + } + else + { + if (tTd(64, 10)) + dprintf("Add %s: %s\n", response, val); + addheader(newstr(response), val, H_USER, &e->e_header); + } } /* ** MILTER_CHANGEHEADER -- Change the supplied header in the message @@ -2347,7 +2406,7 @@ milter_changeheader(response, rlen, e) { mi_int32 i, index; char *field, *val; - HDR *h; + HDR *h, *sysheader; if (tTd(64, 10)) dprintf("milter_changeheader: "); @@ -2389,14 +2448,36 @@ milter_changeheader(response, rlen, e) return; } + sysheader = NULL; for (h = e->e_header; h != NULL; h = h->h_link) { - if (bitset(H_USER, h->h_flags) && - strcasecmp(h->h_field, field) == 0 && - --index <= 0) - break; + if (strcasecmp(h->h_field, field) == 0) + { + if (bitset(H_USER, h->h_flags) && + --index <= 0) + { + sysheader = NULL; + break; + } + else if (!bitset(H_USER, h->h_flags) && + !bitset(H_TRACE, h->h_flags)) + { + /* + ** DRUMS msg-fmt draft says can only have + ** multiple occurences of trace fields, + ** so make sure we replace any non-trace, + ** non-user field. + */ + + sysheader = h; + } + } } + /* if not found as user-provided header at index, use sysheader */ + if (h == NULL) + h = sysheader; + if (h == NULL) { if (*val == '\0') @@ -2419,19 +2500,22 @@ milter_changeheader(response, rlen, e) { if (*val == '\0') { - dprintf("Delete %s: %s\n", field, + dprintf("Delete%s %s: %s\n", + h == sysheader ? " (default header)" : "", + field, h->h_value == NULL ? "<NULL>" : h->h_value); } else { - dprintf("Change %s: from %s to %s\n", + dprintf("Change%s %s: from %s to %s\n", + h == sysheader ? " (default header)" : "", field, h->h_value == NULL ? "<NULL>" : h->h_value, val); } } - if (h->h_value != NULL) + if (h != sysheader && h->h_value != NULL) { e->e_msgsize -= strlen(h->h_value); free(h->h_value); @@ -2440,12 +2524,14 @@ milter_changeheader(response, rlen, e) if (*val == '\0') { /* Remove "Field: " from message size */ - e->e_msgsize -= strlen(h->h_field) + 2; + if (h != sysheader) + e->e_msgsize -= strlen(h->h_field) + 2; h->h_value = NULL; } else { h->h_value = newstr(val); + h->h_flags |= H_USER; e->e_msgsize += strlen(h->h_value); } } @@ -2693,17 +2779,8 @@ milter_init(e, state) m->mf_sock < 0 ? "open" : "negotiate"); /* if negotation failure, close socket */ - if (m->mf_sock >= 0) - { - (void) close(m->mf_sock); - m->mf_sock = -1; - } milter_error(m); - if (m->mf_state == SMFS_ERROR) - { - MILTER_CHECK_ERROR(continue); - break; - } + MILTER_CHECK_ERROR(continue); } } @@ -3087,6 +3164,13 @@ milter_data(e, state) *state = SMFIR_CONTINUE; newfilter = TRUE; + /* previous problem? */ + if (m->mf_state == SMFS_ERROR) + { + MILTER_CHECK_ERROR(continue); + break; + } + /* sanity checks */ if (m->mf_sock < 0 || (m->mf_state != SMFS_OPEN && m->mf_state != SMFS_INMSG)) diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c index e92f615..2ba078f 100644 --- a/contrib/sendmail/src/mime.c +++ b/contrib/sendmail/src/mime.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1994, 1996-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1994 @@ -15,7 +15,7 @@ #include <string.h> #ifndef lint -static char id[] = "@(#)$Id: mime.c,v 8.94 1999/10/17 17:35:58 ca Exp $"; +static char id[] = "@(#)$Id: mime.c,v 8.94.16.3 2000/10/09 02:46:10 gshapiro Exp $"; #endif /* ! lint */ static int isboundary __P((char *, char **)); @@ -277,8 +277,10 @@ mime8to7(mci, header, e, boundaries, flags) if (tTd(43, 1)) dprintf("mime8to7: multipart boundary \"%s\"\n", bbuf); for (i = 0; i < MAXMIMENESTING; i++) + { if (boundaries[i] == NULL) break; + } if (i >= MAXMIMENESTING) { usrerr("mime8to7: multipart nesting boundary too deep"); @@ -621,7 +623,7 @@ mime8to7(mci, header, e, boundaries, flags) linelen++; } } - if (bitnset(c1 & 0xff, badchars)) + if (bitnset(bitidx(c1), badchars)) { *bp++ = '='; *bp++ = Base16Code[(c1 >> 4) & 0x0f]; @@ -828,11 +830,11 @@ mimeboundary(line, boundaries) if (line[0] != '-' || line[1] != '-' || boundaries == NULL) return MBT_NOTSEP; i = strlen(line); - if (line[i - 1] == '\n') + if (i > 0 && line[i - 1] == '\n') i--; /* strip off trailing whitespace */ - while (line[i - 1] == ' ' || line[i - 1] == '\t') + while (i > 0 && (line[i - 1] == ' ' || line[i - 1] == '\t')) i--; savec = line[i]; line[i] = '\0'; @@ -904,7 +906,7 @@ isboundary(line, boundaries) { register int i; - for (i = 0; boundaries[i] != NULL; i++) + for (i = 0; i <= MAXMIMENESTING && boundaries[i] != NULL; i++) { if (strcmp(line, boundaries[i]) == 0) return i; diff --git a/contrib/sendmail/src/newaliases.1 b/contrib/sendmail/src/newaliases.1 index dffa4ce..5a7c916 100644 --- a/contrib/sendmail/src/newaliases.1 +++ b/contrib/sendmail/src/newaliases.1 @@ -9,11 +9,11 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: newaliases.1,v 8.15 1999/06/22 20:41:34 tony Exp $ +.\" $Id: newaliases.1,v 8.15.28.1 2000/12/14 23:08:15 gshapiro Exp $ .\" -.TH NEWALIASES 1 "$Date: 1999/06/22 20:41:34 $" +.TH NEWALIASES 1 "$Date: 2000/12/14 23:08:15 $" .SH NAME -.B newaliases +newaliases \- rebuild the data base for the mail aliases file .SH SYNOPSIS .B newaliases diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c index eb63223..fd4f34b 100644 --- a/contrib/sendmail/src/parseaddr.c +++ b/contrib/sendmail/src/parseaddr.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: parseaddr.c,v 8.234.4.5 2000/09/25 07:53:29 gshapiro Exp $"; +static char id[] = "@(#)$Id: parseaddr.c,v 8.234.4.9 2000/10/09 03:14:48 gshapiro Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -2054,7 +2054,7 @@ static struct qflags AddressFlags[] = { "QDELAYED", QDELAYED }, { "QTHISPASS", QTHISPASS }, { "QRCPTOK", QRCPTOK }, - { NULL } + { NULL, 0 } }; void @@ -2644,6 +2644,7 @@ dequote_map(map, name, av, statp) ** rmcomm -- remove comments? ** cnt -- count rejections (statistics)? ** logl -- logging level +** host -- NULL or relay host. ** ** Returns: ** EX_OK -- if the rwset doesn't resolve to $#error @@ -2651,13 +2652,14 @@ dequote_map(map, name, av, statp) */ int -rscheck(rwset, p1, p2, e, rmcomm, cnt, logl) +rscheck(rwset, p1, p2, e, rmcomm, cnt, logl, host) char *rwset; char *p1; char *p2; ENVELOPE *e; bool rmcomm, cnt; int logl; + char *host; { char *buf; int bufsize; @@ -2775,7 +2777,12 @@ rscheck(rwset, p1, p2, e, rmcomm, cnt, logl) p2); p += strlen(p); } - if ((relay = macvalue('_', e)) != NULL) + + if (host != NULL) + relay = host; + else + relay = macvalue('_', e); + if (relay != NULL) { snprintf(p, SPACELEFT(lbuf, p), ", relay=%s", relay); diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c index a91a988..590aed9 100644 --- a/contrib/sendmail/src/queue.c +++ b/contrib/sendmail/src/queue.c @@ -16,9 +16,9 @@ #ifndef lint # if QUEUE -static char id[] = "@(#)$Id: queue.c,v 8.343.4.17 2000/09/15 03:34:51 gshapiro Exp $ (with queueing)"; +static char id[] = "@(#)$Id: queue.c,v 8.343.4.38 2000/12/08 14:33:02 ca Exp $ (with queueing)"; # else /* QUEUE */ -static char id[] = "@(#)$Id: queue.c,v 8.343.4.17 2000/09/15 03:34:51 gshapiro Exp $ (without queueing)"; +static char id[] = "@(#)$Id: queue.c,v 8.343.4.38 2000/12/08 14:33:02 ca Exp $ (without queueing)"; # endif /* QUEUE */ #endif /* ! lint */ @@ -84,6 +84,7 @@ static int workcmpf4(); */ # define TEMPQF_LETTER 'T' +# define LOSEQF_LETTER 'Q' void queueup(e, announce) @@ -384,6 +385,9 @@ queueup(e, announce) (void) putc('F', tfp); if (bitset(QPINGONDELAY, q->q_flags)) (void) putc('D', tfp); + if (q->q_alias != NULL && + bitset(QALIAS, q->q_alias->q_flags)) + (void) putc('A', tfp); (void) putc(':', tfp); (void) fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE)); if (announce) @@ -447,7 +451,7 @@ queueup(e, announce) { if (bitset(0200, h->h_macro)) fprintf(tfp, "${%s}", - macname(h->h_macro & 0377)); + macname(bitidx(h->h_macro))); else fprintf(tfp, "$%c", h->h_macro); } @@ -520,7 +524,6 @@ queueup(e, announce) if (rename(tf, qf) < 0) syserr("cannot rename(%s, %s), uid=%d", tf, qf, geteuid()); - /* ** fsync() after renaming to make sure ** metadata is written to disk on @@ -529,8 +532,7 @@ queueup(e, announce) */ if (tfd >= 0 && SuperSafe && fsync(tfd) < 0) - syserr("!queueup: cannot fsync queue temp file %s", - tf); + syserr("!queueup: cannot fsync queue temp file %s", tf); /* close and unlock old (locked) qf */ if (e->e_lockfp != NULL) @@ -653,6 +655,9 @@ runqueue(forkflag, verbose) bool ret = TRUE; static int curnum = 0; + DoQueueRun = FALSE; + + if (!forkflag && NumQueues > 1 && !verbose) forkflag = TRUE; @@ -710,11 +715,9 @@ run_single_queue(queuedir, forkflag, verbose) register ENVELOPE *e; int njobs; int sequenceno = 0; - time_t current_la_time; + time_t current_la_time, now; extern ENVELOPE BlankEnvelope; - DoQueueRun = FALSE; - /* ** If no work will ever be selected, don't even bother reading ** the queue. @@ -877,10 +880,11 @@ run_single_queue(queuedir, forkflag, verbose) ** Get new load average every 30 seconds. */ - if (current_la_time < curtime() - 30) + now = curtime(); + if (current_la_time < now - 30) { CurrentLA = sm_getla(e); - current_la_time = curtime(); + current_la_time = now; } if (shouldqueue(WkRecipFact, current_la_time)) { @@ -993,6 +997,7 @@ runqueueevent() # define NEED_T 002 # define NEED_R 004 # define NEED_S 010 +# define NEED_H 020 static WORK *WorkList = NULL; static int WorkListSize = 0; @@ -1163,6 +1168,7 @@ orderq(queuedir, doall) /* open control file */ cf = fopen(qf, "r"); + if (cf == NULL) { /* this may be some random person sending hir msgs */ @@ -1185,6 +1191,11 @@ orderq(queuedir, doall) /* extract useful information */ i = NEED_P | NEED_T; + if (QueueSortOrder == QSO_BYHOST) + { + /* need w_host set for host sort order */ + i |= NEED_H; + } if (QueueLimitSender != NULL) i |= NEED_S; if (QueueLimitRecipient != NULL) @@ -1226,6 +1237,7 @@ orderq(queuedir, doall) { w->w_host = strrev(&p[1]); makelower(w->w_host); + i &= ~NEED_H; } if (QueueLimitRecipient == NULL) { @@ -1952,6 +1964,7 @@ readqf(e) u_long qflags; ADDRESS *q; int mid; + time_t now; auto char *ep; if (tTd(40, 4)) @@ -2013,6 +2026,11 @@ readqf(e) case 'P': qflags |= QPRIMARY; break; + + case 'A': + if (ctladdr != NULL) + ctladdr->q_flags |= QALIAS; + break; } } } @@ -2088,12 +2106,13 @@ readqf(e) e->e_ntries = atoi(&buf[1]); /* if this has been tried recently, let it be */ - if (e->e_ntries > 0 && e->e_dtime <= curtime() && - curtime() < e->e_dtime + queuedelay(e)) + now = curtime(); + if (e->e_ntries > 0 && e->e_dtime <= now && + now < e->e_dtime + queuedelay(e)) { char *howlong; - howlong = pintvl(curtime() - e->e_dtime, TRUE); + howlong = pintvl(now - e->e_dtime, TRUE); if (Verbose) printf("%s: too young (%s)\n", e->e_id, howlong); @@ -2183,6 +2202,9 @@ readqf(e) char *p; mid = macid(&bp[1], &ep); + if (mid == 0) + break; + p = newstr(ep); define(mid, p, e); @@ -2339,7 +2361,7 @@ printqueue() ** queuedir -- queue directory ** ** Returns: -** none. +** number of entries ** ** Side Effects: ** Prints a listing of the mail queue on the standard output. @@ -2618,9 +2640,9 @@ queuename(e, type) sub = "/df"; break; - case 'T': + case TEMPQF_LETTER: case 't': - case 'Q': + case LOSEQF_LETTER: case 'q': if (bitset(QP_SUBQF, QPaths[e->e_queuedir].qp_subdirs)) sub = "/qf"; @@ -2873,8 +2895,6 @@ setctluser(user, qfver) ** none. */ -# define LOSEQF_LETTER 'Q' - void loseqfile(e, why) register ENVELOPE *e; @@ -3138,7 +3158,7 @@ multiqueue_cache() syserr("QueueDirectory: can not wildcard relative path"); if (tTd(41, 2)) dprintf("multiqueue_cache: \"%s\": Can not wildcard relative path.\n", - QueueDir); + qpath); ExitStat = EX_CONFIG; return; } diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c index 8235883..942ca5b 100644 --- a/contrib/sendmail/src/readcf.c +++ b/contrib/sendmail/src/readcf.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: readcf.c,v 8.382.4.27 2000/09/28 01:31:16 gshapiro Exp $"; +static char id[] = "@(#)$Id: readcf.c,v 8.382.4.31 2000/12/18 18:00:43 ca Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -356,6 +356,8 @@ readcf(cfname, safe, e) case 'D': /* macro definition */ mid = macid(&bp[1], &ep); + if (mid == 0) + break; p = munchstring(ep, NULL, '\0'); define(mid, newstr(p), e); break; @@ -369,6 +371,8 @@ readcf(cfname, safe, e) if (bp[0] == 'C') { mid = macid(&bp[1], &ep); + if (mid == 0) + break; expand(ep, exbuf, sizeof exbuf, e); p = exbuf; } @@ -397,6 +401,8 @@ readcf(cfname, safe, e) case 'F': /* word class from file */ mid = macid(&bp[1], &ep); + if (mid == 0) + break; for (p = ep; isascii(*p) && isspace(*p); ) p++; if (p[0] == '-' && p[1] == 'o') @@ -869,7 +875,10 @@ makemailer(line) if (*p != '\0') *p++ = '\0'; if (line[0] == '\0') + { syserr("name required for mailer"); + return; + } m->m_name = newstr(line); /* now scan through and assign info from the fields */ @@ -901,13 +910,14 @@ makemailer(line) case 'P': /* pathname */ if (*p == '\0') syserr("mailer %s: empty path name", m->m_name); - m->m_mailer = newstr(p); + else + m->m_mailer = newstr(p); break; case 'F': /* flags */ for (; *p != '\0'; p++) if (!(isascii(*p) && isspace(*p))) - setbitn(*p, m->m_flags); + setbitn(bitidx(*p), m->m_flags); break; case 'S': /* sender rewriting ruleset */ @@ -937,14 +947,16 @@ makemailer(line) if (*p == '\0') syserr("mailer %s: null end-of-line string", m->m_name); - m->m_eol = newstr(p); + else + m->m_eol = newstr(p); break; case 'A': /* argument vector */ if (*p == '\0') syserr("mailer %s: null argument vector", m->m_name); - m->m_argv = makeargv(p); + else + m->m_argv = makeargv(p); break; case 'M': /* maximum message size */ @@ -975,13 +987,15 @@ makemailer(line) if (*p == '\0') syserr("mailer %s: null working directory", m->m_name); - m->m_execdir = newstr(p); + else + m->m_execdir = newstr(p); break; case 'C': /* default charset */ if (*p == '\0') syserr("mailer %s: null charset", m->m_name); - m->m_defcharset = newstr(p); + else + m->m_defcharset = newstr(p); break; case 'T': /* MTA-Name/Address/Diagnostic types */ @@ -1030,11 +1044,17 @@ makemailer(line) if (*p != '\0') *p++ = '\0'; if (*q == '\0') + { syserr("mailer %s: null user name", m->m_name); + break; + } pw = sm_getpwnam(q); if (pw == NULL) + { syserr("readcf: mailer U= flag: unknown user %s", q); + break; + } else { m->m_uid = pw->pw_uid; @@ -1065,11 +1085,17 @@ makemailer(line) p++; *p++ = '\0'; if (*q == '\0') + { syserr("mailer %s: null group name", m->m_name); + break; + } gr = getgrnam(q); if (gr == NULL) + { syserr("readcf: mailer U= flag: unknown group %s", q); + break; + } else m->m_gid = gr->gr_gid; } @@ -1137,6 +1163,7 @@ makemailer(line) #if _FFR_REMOVE_TCP_MAILER_PATH syserr("M%s: P=[TCP] is deprecated, use P=[IPC] instead\n", m->m_name); + return; #else /* _FFR_REMOVE_TCP_MAILER_PATH */ printf("M%s: Warning: P=[TCP] is deprecated, use P=[IPC] instead\n", m->m_name); @@ -1155,6 +1182,7 @@ makemailer(line) { syserr("M%s: too few parameters for %s mailer", m->m_name, m->m_mailer); + return; } if (strcmp(m->m_argv[0], "TCP") != 0 #if NETUNIX @@ -1186,11 +1214,13 @@ makemailer(line) m->m_name, (m->m_argv[0] == NULL || m->m_argv[1] == NULL) ? "few" : "many"); + return; } else if (strcmp(m->m_argv[0], "FILE") != 0) { syserr("M%s: first argument in [FILE] mailer must be FILE", m->m_name); + return; } } @@ -1956,6 +1986,7 @@ setoption(opt, val, safe, sticky, e) case SM_DEFER: /* queue only and defer map lookups */ #if !QUEUE syserr("need QUEUE to set -odqueue or -oddefer"); + break; #endif /* !QUEUE */ /* FALLTHROUGH */ @@ -2115,12 +2146,14 @@ setoption(opt, val, safe, sticky, e) break; case 'M': /* define macro */ + sticky = FALSE; mid = macid(val, &ep); + if (mid == 0) + break; p = newstr(ep); if (!safe) cleanstrcpy(p, p, MAXNAME); define(mid, p, CurEnv); - sticky = FALSE; break; case 'm': /* send to me too */ @@ -2136,9 +2169,7 @@ setoption(opt, val, safe, sticky, e) case 'O': /* daemon options */ #if DAEMON if (!setdaemonoptions(val)) - { syserr("too many daemons defined (%d max)", MAXDAEMONS); - } #else /* DAEMON */ syserr("DaemonPortOptions (O option) set but DAEMON not compiled in"); #endif /* DAEMON */ @@ -2175,7 +2206,8 @@ setoption(opt, val, safe, sticky, e) } if (pv->pv_name == NULL) syserr("readcf: Op line: %s unrecognized", val); - PrivacyFlags |= pv->pv_flag; + else + PrivacyFlags |= pv->pv_flag; } sticky = FALSE; break; @@ -2262,7 +2294,10 @@ setoption(opt, val, safe, sticky, e) DefUid = -1; pw = sm_getpwnam(val); if (pw == NULL) + { syserr("readcf: option u: unknown user %s", val); + break; + } else { DefUid = pw->pw_uid; @@ -2275,7 +2310,8 @@ setoption(opt, val, safe, sticky, e) if (DefUid > UID_MAX) { syserr("readcf: option u: uid value (%ld) > UID_MAX (%ld); ignored", - DefUid, UID_MAX); + (long) DefUid, (long) UID_MAX); + break; } #endif /* UID_MAX */ @@ -2540,7 +2576,10 @@ setoption(opt, val, safe, sticky, e) pw = sm_getpwnam(val); if (pw == NULL) + { syserr("readcf: option RunAsUser: unknown user %s", val); + break; + } else if (can_setuid) { if (*p == '\0') @@ -2553,7 +2592,8 @@ setoption(opt, val, safe, sticky, e) if (RunAsUid > UID_MAX) { syserr("readcf: option RunAsUser: uid value (%ld) > UID_MAX (%ld); ignored", - RunAsUid, UID_MAX); + (long) RunAsUid, (long) UID_MAX); + break; } #endif /* UID_MAX */ if (*p != '\0') @@ -2679,7 +2719,10 @@ setoption(opt, val, safe, sticky, e) TrustedUid = 0; pw = sm_getpwnam(val); if (pw == NULL) + { syserr("readcf: option TrustedUser: unknown user %s", val); + break; + } else TrustedUid = pw->pw_uid; } @@ -2688,7 +2731,7 @@ setoption(opt, val, safe, sticky, e) if (TrustedUid > UID_MAX) { syserr("readcf: option TrustedUser: uid value (%ld) > UID_MAX (%ld)", - TrustedUid, UID_MAX); + (long) TrustedUid, (long) UID_MAX); TrustedUid = 0; } # endif /* UID_MAX */ @@ -2997,7 +3040,7 @@ setclass(class, str) str++; mid = macid(str, NULL); - if (mid == '\0') + if (mid == 0) return; if (tTd(37, 8)) @@ -3011,7 +3054,7 @@ setclass(class, str) dprintf("setclass(%s, %s)\n", macname(class), str); s = stab(str, ST_CLASS, ST_ENTER); - setbitn(class, s->s_class); + setbitn(bitidx(class), s->s_class); } } /* @@ -3209,7 +3252,7 @@ strtorwset(p, endp, stabmode) { s->s_ruleset = ruleset; } - if (stabmode == ST_ENTER) + if (stabmode == ST_ENTER && ruleset >= 0) { char *h = NULL; @@ -3334,7 +3377,11 @@ settimeout(name, val, sticky) } if (to->to_name == NULL) + { + errno = 0; /* avoid bogus error text */ syserr("settimeout: invalid timeout %s", name); + return; + } /* ** See if this option is preset for us. diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h index 1748a73..9a6698a 100644 --- a/contrib/sendmail/src/sendmail.h +++ b/contrib/sendmail/src/sendmail.h @@ -20,7 +20,7 @@ #ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.37 2000/09/25 07:53:29 gshapiro Exp $"; +static char SmailId[] = "@(#)$Id: sendmail.h,v 8.517.4.45 2000/12/28 23:46:44 gshapiro Exp $"; # endif /* ! lint */ #else /* _DEFINE */ # define EXTERN extern @@ -226,14 +226,14 @@ typedef struct address ADDRESS; #define QS_QUEUEUP 3 /* save address in queue */ #define QS_VERIFIED 4 /* verified, but not expanded */ #define QS_DONTSEND 5 /* don't send to this address */ -#define QS_EXPANDED 6 /* expanded */ -#define QS_SENDER 7 /* message sender (MeToo) */ -#define QS_CLONED 8 /* addr cloned to a split envelope */ -#define QS_DISCARDED 9 /* recipient discarded (EF_DISCARD) */ -#define QS_REPLACED 10 /* maplocaluser()/UserDB replaced */ -#define QS_REMOVED 11 /* removed (removefromlist()) */ -#define QS_DUPLICATE 12 /* duplicate suppressed */ -#define QS_INCLUDED 13 /* :include: delivery */ +#define QS_EXPANDED 6 /* QS_DONTSEND: expanded */ +#define QS_SENDER 7 /* QS_DONTSEND: message sender (MeToo) */ +#define QS_CLONED 8 /* QS_DONTSEND: addr cloned to split envelope */ +#define QS_DISCARDED 9 /* QS_DONTSEND: rcpt discarded (EF_DISCARD) */ +#define QS_REPLACED 10 /* QS_DONTSEND: maplocaluser()/UserDB replaced */ +#define QS_REMOVED 11 /* QS_DONTSEND: removed (removefromlist()) */ +#define QS_DUPLICATE 12 /* QS_DONTSEND: duplicate suppressed */ +#define QS_INCLUDED 13 /* QS_DONTSEND: :include: delivery */ /* address state testing primitives */ #define QS_IS_OK(s) ((s) == QS_OK) @@ -459,6 +459,8 @@ MCI #else /* STARTTLS */ #define MCIF_EXTENS (MCIF_EXPN | MCIF_SIZE | MCIF_8BITMIME | MCIF_DSN | MCIF_8BITOK | MCIF_AUTH | MCIF_ENHSTAT) #endif /* STARTTLS */ +#define MCIF_ONLY_EHLO 0x10000000 /* use only EHLO in smtpinit */ + /* states */ #define MCIS_CLOSED 0 /* no traffic on this connection */ @@ -627,7 +629,7 @@ struct envelope int e_ntries; /* number of delivery attempts */ dev_t e_dfdev; /* df file's device, for crash recov */ ino_t e_dfino; /* df file's ino, for crash recovery */ - char *e_macro[256]; /* macro definitions */ + char *e_macro[MAXMACROID + 1]; /* macro definitions */ char *e_if_macros[2]; /* HACK: incoming interface info */ char *e_auth_param; TIMERS e_timers; /* per job timers */ @@ -776,7 +778,7 @@ extern void expand __P((char *, char *, size_t, ENVELOPE *)); extern int macid __P((char *, char **)); extern char *macname __P((int)); extern char *macvalue __P((int, ENVELOPE *)); -extern int rscheck __P((char *, char *, char *, ENVELOPE *, bool, bool, int)); +extern int rscheck __P((char *, char *, char *, ENVELOPE *, bool, bool, int, char *)); extern void setclass __P((int, char *)); extern int strtorwset __P((char *, char **, int)); extern void translate_dollars __P((char *)); @@ -1870,7 +1872,7 @@ extern void apps_ssl_info_cb __P((SSL *, int , int)); extern bool inittls __P((SSL_CTX **, u_long, bool, char *, char *, char *, char *, char *)); extern bool initclttls __P((void)); extern bool initsrvtls __P((void)); -extern int tls_get_info __P((SSL *, ENVELOPE *, bool, char *)); +extern int tls_get_info __P((SSL *, ENVELOPE *, bool, char *, bool)); extern int endtls __P((SSL *, char *)); extern int endtlsclt __P((MCI *)); extern void tlslogerr __P((void)); @@ -2044,7 +2046,6 @@ extern void queueup_macros __P((int, FILE *, ENVELOPE *)); extern SIGFUNC_DECL quiesce __P((int)); extern void readcf __P((char *, bool, ENVELOPE *)); extern SIGFUNC_DECL reapchild __P((int)); -extern bool refuseconnections __P((char *, ENVELOPE *, int)); extern int releasesignal __P((int)); extern void resetlimits __P((void)); extern bool rfc822_string __P((char *)); diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c index 582a064..c09e4e8 100644 --- a/contrib/sendmail/src/sfsasl.c +++ b/contrib/sendmail/src/sfsasl.c @@ -9,7 +9,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: sfsasl.c,v 8.17.4.8 2000/09/14 00:14:13 ca Exp $"; +static char id[] = "@(#)$Id: sfsasl.c,v 8.17.4.13 2000/11/03 00:24:49 gshapiro Exp $"; #endif /* ! lint */ #if SFIO @@ -27,6 +27,9 @@ static char id[] = "@(#)$Id: sfsasl.c,v 8.17.4.8 2000/09/14 00:14:13 ca Exp $"; # include <sasl.h> # include "sfsasl.h" +/* how to deallocate a buffer allocated by SASL */ +# define SASL_DEALLOC(b) free(b) + static ssize_t sasl_read(f, buf, size, disc) Sfio_t *f; @@ -35,29 +38,61 @@ sasl_read(f, buf, size, disc) Sfdisc_t *disc; { int len, result; - char *outbuf; - unsigned int outlen; + static char *outbuf = NULL; + static unsigned int outlen = 0; + static unsigned int offset = 0; Sasldisc_t *sd = (Sasldisc_t *) disc; - len = sfrd(f, buf, size, disc); - - if (len <= 0) - return len; - - result = sasl_decode(sd->conn, buf, len, &outbuf, &outlen); + /* + ** sasl_decode() may require more data than a single read() returns. + ** Hence we have to put a loop around the decoding. + ** This also requires that we may have to split up the returned + ** data since it might be larger than the allowed size. + ** Therefore we use a static pointer and return portions of it + ** if necessary. + */ - if (result != SASL_OK) + while (outbuf == NULL && outlen == 0) { - /* eventually, we'll want an exception here */ - return -1; + len = sfrd(f, buf, size, disc); + if (len <= 0) + return len; + result = sasl_decode(sd->conn, buf, len, &outbuf, &outlen); + if (result != SASL_OK) + { + outbuf = NULL; + offset = 0; + outlen = 0; + return -1; + } } if (outbuf != NULL) { - (void)memcpy(buf, outbuf, outlen); - free(outbuf); + if (outlen - offset > size) + { + /* return another part of the buffer */ + (void) memcpy(buf, outbuf + offset, (size_t) size); + offset += size; + result = size; + } + else + { + /* return the rest of the buffer */ + result = outlen - offset; + (void) memcpy(buf, outbuf + offset, (size_t) result); + SASL_DEALLOC(outbuf); + outbuf = NULL; + offset = 0; + outlen = 0; + } } - return outlen; + else + { + /* be paranoid: outbuf == NULL but outlen != 0 */ + syserr("!sasl_read failure: outbuf == NULL but outlen != 0"); + } + return result; } static ssize_t @@ -75,15 +110,12 @@ sasl_write(f, buf, size, disc) result = sasl_encode(sd->conn, buf, size, &outbuf, &outlen); if (result != SASL_OK) - { - /* eventually, we'll want an exception here */ return -1; - } if (outbuf != NULL) { sfwr(f, outbuf, outlen, disc); - free(outbuf); + SASL_DEALLOC(outbuf); } return size; } diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c index 9989c75..78443a8 100644 --- a/contrib/sendmail/src/srvrsmtp.c +++ b/contrib/sendmail/src/srvrsmtp.c @@ -16,9 +16,9 @@ #ifndef lint # if SMTP -static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.58 2000/09/21 21:52:18 ca Exp $ (with SMTP)"; +static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.66 2000/12/18 18:00:44 ca Exp $ (with SMTP)"; # else /* SMTP */ -static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.58 2000/09/21 21:52:18 ca Exp $ (without SMTP)"; +static char id[] = "@(#)$Id: srvrsmtp.c,v 8.471.2.2.2.66 2000/12/18 18:00:44 ca Exp $ (without SMTP)"; # endif /* SMTP */ #endif /* ! lint */ @@ -376,8 +376,8 @@ smtp(nullserver, d_flags, e) saveSuprErrs = SuprErrs; SuprErrs = TRUE; QuickAbort = FALSE; - if (rscheck("offer_tls", CurSmtpClient, "", e, TRUE, FALSE, 8) != EX_OK - || Errors > 0) + if (rscheck("offer_tls", CurSmtpClient, "", e, TRUE, FALSE, 8, + NULL) != EX_OK || Errors > 0) usetls = FALSE; QuickAbort = saveQuickAbort; SuprErrs = saveSuprErrs; @@ -1054,7 +1054,7 @@ smtp(nullserver, d_flags, e) /* ignore return code for now, it's in {verify} */ (void) tls_get_info(srv_ssl, &BlankEnvelope, TRUE, - CurSmtpClient); + CurSmtpClient, TRUE); /* ** call Stls_client to find out whether @@ -1067,8 +1067,8 @@ smtp(nullserver, d_flags, e) QuickAbort = FALSE; if (rscheck("tls_client", macvalue(macid("{verify}", NULL), e), - "STARTTLS", e, TRUE, TRUE, 6) != EX_OK || - Errors > 0) + "STARTTLS", e, TRUE, TRUE, 6, NULL) != + EX_OK || Errors > 0) { extern char MsgBuf[]; @@ -1520,7 +1520,7 @@ smtp(nullserver, d_flags, e) /* do config file checking of the sender */ if (rscheck("check_mail", addr, - NULL, e, TRUE, TRUE, 4) != EX_OK || + NULL, e, TRUE, TRUE, 4, NULL) != EX_OK || Errors > 0) goto undo_subproc_no_pm; @@ -1715,7 +1715,7 @@ smtp(nullserver, d_flags, e) /* do config file checking of the recipient */ if (rscheck("check_rcpt", addr, - NULL, e, TRUE, TRUE, 4) != EX_OK || + NULL, e, TRUE, TRUE, 4, NULL) != EX_OK || Errors > 0) break; @@ -2074,13 +2074,19 @@ smtp(nullserver, d_flags, e) { /* do config file checking of the address */ if (rscheck(vrfy ? "check_vrfy" : "check_expn", - p, NULL, e, TRUE, FALSE, 4) + p, NULL, e, TRUE, FALSE, 4, NULL) != EX_OK || Errors > 0) goto undo_subproc; (void) sendtolist(p, NULLADDR, &vrfyqueue, 0, e); } if (wt > 0) - (void) sleep(wt - (curtime() - previous)); + { + time_t t; + + t = wt - (curtime() - previous); + if (t > 0) + (void) sleep(t); + } if (Errors > 0) goto undo_subproc; if (vrfyqueue == NULL) @@ -2141,8 +2147,8 @@ smtp(nullserver, d_flags, e) "ETRN", e); /* do config file checking of the parameter */ - if (rscheck("check_etrn", p, NULL, e, TRUE, FALSE, 4) - != EX_OK || Errors > 0) + if (rscheck("check_etrn", p, NULL, e, TRUE, FALSE, 4, + NULL) != EX_OK || Errors > 0) break; if (LogLevel > 5) @@ -2330,7 +2336,7 @@ doquit: ** e -- the current envelope. ** ** Returns: -** none. +** time to wait. ** ** Side Effects: ** Slows down if we seem to be under attack. @@ -2448,7 +2454,7 @@ mail_esmtp_args(kp, vp, e) /* NOTREACHED */ } define(macid("{msg_size}", NULL), newstr(vp), e); - e->e_msgsize = strtol(vp, (char **) NULL, 10); + e->e_msgsize = strtol(vp, (char **) NULL, 10); if (e->e_msgsize == LONG_MAX && errno == ERANGE) { usrerr("552 5.2.3 Message size exceeds maximum value"); @@ -2580,8 +2586,8 @@ mail_esmtp_args(kp, vp, e) SuprErrs = TRUE; QuickAbort = FALSE; if (strcmp(auth_param, "<>") != 0 && - (rscheck("trust_auth", pbuf, NULL, e, TRUE, FALSE, 10) - != EX_OK || Errors > 0)) + (rscheck("trust_auth", pbuf, NULL, e, TRUE, FALSE, 10, + NULL) != EX_OK || Errors > 0)) { if (tTd(95, 8)) { @@ -2800,6 +2806,7 @@ runinchild(label, e) (void) blocksignal(SIGCHLD); + childpid = dofork(); if (childpid < 0) { @@ -2889,6 +2896,7 @@ saslmechs(conn, mechlist) sm_syslog(LOG_WARNING, NOQID, "SASL error: listmech=%d, num=%d", result, num); + num = 0; } return num; } @@ -3812,6 +3820,7 @@ initsrvtls() ** e -- current envelope ** srv -- server or client ** host -- hostname of other side +** log -- log connection information? ** ** Returns: ** result of authentication. @@ -3822,11 +3831,12 @@ initsrvtls() */ int -tls_get_info(ssl, e, srv, host) +tls_get_info(ssl, e, srv, host, log) SSL *ssl; ENVELOPE *e; bool srv; char *host; + bool log; { SSL_CIPHER *c; int b, r; @@ -3849,7 +3859,7 @@ tls_get_info(ssl, e, srv, host) define(macid("{tls_version}", NULL), newstr(s), e); cert = SSL_get_peer_certificate(ssl); - if (LogLevel >= 14) + if (log && LogLevel >= 14) sm_syslog(LOG_INFO, e->e_id, "TLS: get_verify in %s: %ld get_peer: 0x%lx", srv ? "srv" : "clt", @@ -3910,7 +3920,7 @@ tls_get_info(ssl, e, srv, host) X509_free(cert); /* do some logging */ - if (LogLevel > 9) + if (log && LogLevel > 9) { char *vers, *s1, *s2, *bits; diff --git a/contrib/sendmail/src/stab.c b/contrib/sendmail/src/stab.c index 2177ae6..1249f9d 100644 --- a/contrib/sendmail/src/stab.c +++ b/contrib/sendmail/src/stab.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: stab.c,v 8.40.16.2 2000/06/05 21:46:59 gshapiro Exp $"; +static char id[] = "@(#)$Id: stab.c,v 8.40.16.3 2000/10/09 02:46:12 gshapiro Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -268,6 +268,7 @@ queueup_macros(class, qfp, e) if (e == NULL) return; + class = bitidx(class); for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) { for (s = *shead; s != NULL; s = s->s_next) @@ -276,7 +277,7 @@ queueup_macros(class, qfp, e) char *p; if (s->s_type == ST_CLASS && - bitnset(class & 0xff, s->s_class) && + bitnset(class, s->s_class) && (m = macid(s->s_name, NULL)) != '\0' && (p = macvalue(m, e)) != NULL) { @@ -326,12 +327,14 @@ copy_class(src, dst) register STAB **shead; register STAB *s; + src = bitidx(src); + dst = bitidx(dst); for (shead = SymTab; shead < &SymTab[STABSIZE]; shead++) { for (s = *shead; s != NULL; s = s->s_next) { if (s->s_type == ST_CLASS && - bitnset(src & 0xff, s->s_class)) + bitnset(src, s->s_class)) setbitn(dst, s->s_class); } } diff --git a/contrib/sendmail/src/timers.c b/contrib/sendmail/src/timers.c index 74d0ccf..acd774c 100644 --- a/contrib/sendmail/src/timers.c +++ b/contrib/sendmail/src/timers.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2000 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -11,7 +11,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: timers.c,v 8.13 1999/11/23 07:22:28 gshapiro Exp $"; +static char id[] = "@(#)$Id: timers.c,v 8.13.16.1 2000/10/09 01:06:45 gshapiro Exp $"; #endif /* ! lint */ #if _FFR_TIMERS @@ -204,8 +204,11 @@ poptimer(ptimer) /* pop back to this timer */ for (i = 0; i < NTimers; i++) + { if (TimerStack[i] == ptimer) break; + } + if (i != NTimers - 1) warntimer("poptimer: odd pop (timer=0x%lx, index=%d, NTimers=%d)", (u_long) ptimer, i, NTimers); diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c index 0a9c287..bfce56a 100644 --- a/contrib/sendmail/src/usersmtp.c +++ b/contrib/sendmail/src/usersmtp.c @@ -15,9 +15,9 @@ #ifndef lint # if SMTP -static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.13 2000/09/26 00:46:21 gshapiro Exp $ (with SMTP)"; +static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.18 2000/12/20 16:36:11 ca Exp $ (with SMTP)"; # else /* SMTP */ -static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.13 2000/09/26 00:46:21 gshapiro Exp $ (without SMTP)"; +static char id[] = "@(#)$Id: usersmtp.c,v 8.245.4.18 2000/12/20 16:36:11 ca Exp $ (without SMTP)"; # endif /* SMTP */ #endif /* ! lint */ @@ -1187,7 +1187,7 @@ attemptauth(m, mci, e, mechused) return EX_TEMPFAIL; addrsize = sizeof(struct sockaddr_in); if (getsockname(fileno(mci->mci_out), - (struct sockaddr *) &saddr_l, &addrsize) != 0) + (struct sockaddr *) &saddr_l, &addrsize) == 0) { if (sasl_setprop(mci->mci_conn, SASL_IP_LOCAL, &saddr_l) != SASL_OK) @@ -1298,7 +1298,7 @@ attemptauth(m, mci, e, mechused) } else in64[0] = '\0'; - smtpmessage(in64, m, mci); + smtpmessage("%s", m, mci, in64); smtpresult = reply(m, mci, e, TimeOuts.to_datafinal, getsasldata, NULL); /* which timeout? XXX */ @@ -1542,7 +1542,7 @@ smtpmailfrom(m, mci, e) smtpquit(m, mci, e); return EX_TEMPFAIL; } - else if (r == 421) + else if (r == SMTPCLOSING) { /* service shutting down */ mci_setstat(mci, EX_TEMPFAIL, ENHSCN(enhsc, "4.5.0"), @@ -2106,7 +2106,7 @@ smtpquit(m, mci, e) /* look for naughty mailers */ sm_syslog(LOG_ERR, e->e_id, - "smtpquit: mailer%s%s exited with exit value %d\n", + "smtpquit: mailer%s%s exited with exit value %d", mailer == NULL ? "" : " ", mailer == NULL ? "" : mailer, rcode); @@ -2141,9 +2141,13 @@ smtprset(m, mci, e) ** Any response is deemed to be acceptable. ** The standard does not state the proper action ** to take when a value other than 250 is received. + ** + ** However, if 421 is returned for the RSET, leave + ** mci_state as MCIS_SSD (set in reply()). */ - mci->mci_state = MCIS_OPEN; + if (mci->mci_state != MCIS_SSD) + mci->mci_state = MCIS_OPEN; return; } smtpquit(m, mci, e); diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c index fa0f74a..e71627f 100644 --- a/contrib/sendmail/src/util.c +++ b/contrib/sendmail/src/util.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: util.c,v 8.225.2.1.2.8 2000/07/03 18:28:56 geir Exp $"; +static char id[] = "@(#)$Id: util.c,v 8.225.2.1.2.15 2000/10/18 23:46:07 ca Exp $"; #endif /* ! lint */ #include <sendmail.h> @@ -209,6 +209,7 @@ shorten_rfc822_string(string, length) ** If have to rebalance an already short enough string, ** need to do it within allocated space. */ + slen = strlen(string); if (length == 0 || slen < length) length = slen; @@ -500,10 +501,13 @@ log_sendmail_pid(e) } else { + long pid; extern char *CommandLineArgs; + pid = (long) getpid(); + /* write the process id on line 1 */ - fprintf(pidf, "%ld\n", (long) getpid()); + fprintf(pidf, "%ld\n", pid); /* line 2 contains all command line flags */ fprintf(pidf, "%s\n", CommandLineArgs); @@ -640,7 +644,7 @@ xputs(s) if (strchr("=~&?", *s) != NULL) (void) putchar(*s++); if (bitset(0200, *s)) - printf("{%s}", macname(*s++ & 0377)); + printf("{%s}", macname(bitidx(*s++))); else printf("%c", *s++); continue; @@ -918,6 +922,11 @@ putxline(l, len, mci, pxflags) { if (putc('.', mci->mci_out) == EOF) dead = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) (void) putc('.', TrafficLogFile); } @@ -928,6 +937,11 @@ putxline(l, len, mci, pxflags) { if (putc('>', mci->mci_out) == EOF) dead = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) (void) putc('>', TrafficLogFile); } @@ -942,9 +956,11 @@ putxline(l, len, mci, pxflags) dead = TRUE; break; } - - /* record progress for DATA timeout */ - DataProgress = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } } if (dead) break; @@ -957,10 +973,11 @@ putxline(l, len, mci, pxflags) dead = TRUE; break; } - - /* record progress for DATA timeout */ - DataProgress = TRUE; - + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) { for (l = l_base; l < q; l++) @@ -981,6 +998,11 @@ putxline(l, len, mci, pxflags) { if (putc('.', mci->mci_out) == EOF) break; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) (void) putc('.', TrafficLogFile); } @@ -991,6 +1013,11 @@ putxline(l, len, mci, pxflags) { if (putc('>', mci->mci_out) == EOF) break; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) (void) putc('>', TrafficLogFile); } @@ -1003,9 +1030,11 @@ putxline(l, len, mci, pxflags) dead = TRUE; break; } - - /* record progress for DATA timeout */ - DataProgress = TRUE; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } } if (dead) break; @@ -1014,6 +1043,11 @@ putxline(l, len, mci, pxflags) (void) putc('\n', TrafficLogFile); if (fputs(mci->mci_mailer->m_eol, mci->mci_out) == EOF) break; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (l < end && *l == '\n') { if (*++l != ' ' && *l != '\t' && *l != '\0' && @@ -1021,13 +1055,15 @@ putxline(l, len, mci, pxflags) { if (putc(' ', mci->mci_out) == EOF) break; + else + { + /* record progress for DATA timeout */ + DataProgress = TRUE; + } if (TrafficLogFile != NULL) (void) putc(' ', TrafficLogFile); } } - - /* record progress for DATA timeout */ - DataProgress = TRUE; } while (l < end); } /* @@ -1347,8 +1383,10 @@ bitintersect(a, b) int i; for (i = BITMAPBYTES / sizeof (int); --i >= 0; ) + { if ((a[i] & b[i]) != 0) return TRUE; + } return FALSE; } /* @@ -1372,8 +1410,10 @@ bitzerop(map) int i; for (i = BITMAPBYTES / sizeof (int); --i >= 0; ) + { if (map[i] != 0) return FALSE; + } return TRUE; } /* @@ -1485,8 +1525,8 @@ checkfds(where) static BITMAP256 baseline; extern int DtableSize; - if (DtableSize > 256) - maxfd = 256; + if (DtableSize > BITMAPBITS) + maxfd = BITMAPBITS; else maxfd = DtableSize; if (where == NULL) diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c index f3a25f4..2499b10 100644 --- a/contrib/sendmail/src/version.c +++ b/contrib/sendmail/src/version.c @@ -12,7 +12,7 @@ */ #ifndef lint -static char id[] = "@(#)$Id: version.c,v 8.43.4.16 2000/09/21 04:12:23 geir Exp $"; +static char id[] = "@(#)$Id: version.c,v 8.43.4.25 2000/12/29 18:22:18 gshapiro Exp $"; #endif /* ! lint */ -char Version[] = "8.11.1"; +char Version[] = "8.11.2"; |