From 96b960fca637a0765d566591885b7d42576e723f Mon Sep 17 00:00:00 2001 From: gshapiro Date: Fri, 19 Sep 2003 23:11:30 +0000 Subject: Import sendmail 8.12.10 --- contrib/sendmail/src/README | 8 +-- contrib/sendmail/src/TRACEFLAGS | 2 +- contrib/sendmail/src/alias.c | 4 +- contrib/sendmail/src/bf.c | 4 +- contrib/sendmail/src/collect.c | 29 ++++++-- contrib/sendmail/src/conf.c | 80 +++++++++++++-------- contrib/sendmail/src/control.c | 4 +- contrib/sendmail/src/daemon.c | 37 ++-------- contrib/sendmail/src/deliver.c | 6 +- contrib/sendmail/src/domain.c | 32 ++++----- contrib/sendmail/src/headers.c | 51 ++++++++++++-- contrib/sendmail/src/main.c | 40 +++++------ contrib/sendmail/src/map.c | 16 +++-- contrib/sendmail/src/mci.c | 20 ++++-- contrib/sendmail/src/milter.c | 12 ++-- contrib/sendmail/src/mime.c | 6 +- contrib/sendmail/src/parseaddr.c | 83 ++++++++++++++-------- contrib/sendmail/src/queue.c | 142 ++++++++++++++++++++++--------------- contrib/sendmail/src/readcf.c | 81 ++++++++++++++++++++-- contrib/sendmail/src/recipient.c | 8 ++- contrib/sendmail/src/sendmail.8 | 10 +-- contrib/sendmail/src/sendmail.h | 28 ++++++-- contrib/sendmail/src/sfsasl.c | 39 +++++++++-- contrib/sendmail/src/srvrsmtp.c | 146 +++++++++++++++++++++++++++++++++++++-- contrib/sendmail/src/stab.c | 6 +- contrib/sendmail/src/udb.c | 8 +-- contrib/sendmail/src/usersmtp.c | 4 +- contrib/sendmail/src/util.c | 6 +- contrib/sendmail/src/version.c | 4 +- 29 files changed, 643 insertions(+), 273 deletions(-) (limited to 'contrib/sendmail/src') diff --git a/contrib/sendmail/src/README b/contrib/sendmail/src/README index 7686b6c..669a20c 100644 --- a/contrib/sendmail/src/README +++ b/contrib/sendmail/src/README @@ -9,7 +9,7 @@ # the sendmail distribution. # # -# $Id: README,v 8.355.2.14 2003/03/27 21:39:29 ca Exp $ +# $Id: README,v 8.355.2.15 2003/06/02 01:43:04 ca Exp $ # This directory contains the source files for sendmail(TM). @@ -125,7 +125,7 @@ MAP_REGEX Regular Expression support. You will need to use an the Free Software Foundation. DNSMAP DNS map support. Requires NAMED_BIND. PH_MAP PH map support. You will need the libphclient library from - the nph package (http://www-dev.cso.uiuc.edu/ph/nph/). + the nph package (http://www-dev.cites.uiuc.edu/ph/nph/). MAP_NSD nsd map support (IRIX 6.5 and later). >>> NOTE WELL for NEWDB support: If you want to get ndbm support, for @@ -1640,7 +1640,7 @@ OpenSSL PH PH support is provided by Mark Roth . The map is - described at http://www-dev.cso.uiuc.edu/sendmail/ . + described at http://www-dev.cites.uiuc.edu/sendmail/ . NOTE: The "spacedname" pseudo-field which was used by earlier versions of the PH map code is no longer supported! See the URL @@ -1797,4 +1797,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.355.2.14 $, last update $Date: 2003/03/27 21:39:29 $ ) +(Version $Revision: 8.355.2.15 $, last update $Date: 2003/06/02 01:43:04 $ ) diff --git a/contrib/sendmail/src/TRACEFLAGS b/contrib/sendmail/src/TRACEFLAGS index 6762d8d..1d7d28b 100644 --- a/contrib/sendmail/src/TRACEFLAGS +++ b/contrib/sendmail/src/TRACEFLAGS @@ -1,4 +1,4 @@ -# $Id: TRACEFLAGS,v 8.37.2.3 2002/09/12 02:57:36 gshapiro Exp $ +# $Id: TRACEFLAGS,v 8.37.2.4 2003/06/13 21:59:45 lijian Exp $ 0, 4 main.c main canonical name, UUCP node name, a.k.a.s 0, 15 main.c main print configuration 0, 44 util.c printav print address of each string diff --git a/contrib/sendmail/src/alias.c b/contrib/sendmail/src/alias.c index f5bd746..3ce8b0e 100644 --- a/contrib/sendmail/src/alias.c +++ b/contrib/sendmail/src/alias.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: alias.c,v 8.214 2002/05/24 20:50:16 gshapiro Exp $") +SM_RCSID("@(#)$Id: alias.c,v 8.214.2.1 2003/07/28 17:47:55 ca Exp $") #define SEPARATOR ':' # define ALIAS_SPEC_SEPARATORS " ,/:" @@ -94,7 +94,7 @@ alias(a, sendq, aliaslevel, e) if (aliaslookup(obuf, &status, a->q_host) != NULL) { if (LogLevel > 8) - syslog(LOG_WARNING, + sm_syslog(LOG_WARNING, e->e_id, "possible spam from <> to list: %s, redirected to %s\n", a->q_user, obuf); a->q_user = sm_rpool_strdup_x(e->e_rpool, obuf); diff --git a/contrib/sendmail/src/bf.c b/contrib/sendmail/src/bf.c index f678308..4e672b9 100644 --- a/contrib/sendmail/src/bf.c +++ b/contrib/sendmail/src/bf.c @@ -18,7 +18,7 @@ */ #include -SM_RCSID("@(#)$Id: bf.c,v 8.54.2.2 2002/06/21 19:58:40 gshapiro Exp $") +SM_RCSID("@(#)$Id: bf.c,v 8.54.2.3 2003/09/03 19:58:26 ca Exp $") #include #include @@ -542,7 +542,7 @@ sm_bfwrite(fp, buf, nbytes) /* Clear umask as bf_filemode are the true perms */ omask = umask(0); retval = OPEN(bfp->bf_filename, - O_RDWR | O_CREAT | O_TRUNC, + O_RDWR | O_CREAT | O_TRUNC | QF_O_EXTRA, bfp->bf_filemode, bfp->bf_flags); (void) umask(omask); diff --git a/contrib/sendmail/src/collect.c b/contrib/sendmail/src/collect.c index 0e50ca0..20a2c1c 100644 --- a/contrib/sendmail/src/collect.c +++ b/contrib/sendmail/src/collect.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: collect.c,v 8.242.2.4 2003/03/28 17:34:39 ca Exp $") +SM_RCSID("@(#)$Id: collect.c,v 8.242.2.8 2003/07/08 01:16:35 ca Exp $") static void collecttimeout __P((time_t)); static void dferror __P((SM_FILE_T *volatile, char *, ENVELOPE *)); @@ -217,7 +217,7 @@ collect_dfopen(e) syserr("@Cannot create %s", dfname); e->e_flags |= EF_NO_BODY_RETN; flush_errors(true); - finis(true, true, ExitStat); + finis(false, true, ExitStat); /* NOTREACHED */ } dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL); @@ -247,6 +247,7 @@ collect_dfopen(e) ** end of message. ** hdrp -- the location to stash the header. ** e -- the current envelope. +** rsetsize -- reset e_msgsize? ** ** Returns: ** none. @@ -281,11 +282,12 @@ static SM_EVENT *volatile CollectTimeout = NULL; #define MS_DISCARD 3 /* discarding rest of message */ void -collect(fp, smtpmode, hdrp, e) +collect(fp, smtpmode, hdrp, e, rsetsize) SM_FILE_T *fp; bool smtpmode; HDR **hdrp; register ENVELOPE *e; + bool rsetsize; { register SM_FILE_T *volatile df; volatile bool ignrdot; @@ -366,7 +368,8 @@ collect(fp, smtpmode, hdrp, e) CollectTimeout = sm_setevent(dbto, collecttimeout, dbto); } - e->e_msgsize = 0; + if (rsetsize) + e->e_msgsize = 0; for (;;) { if (tTd(30, 35)) @@ -883,7 +886,22 @@ readerr: /* collect statistics */ if (OpMode != MD_VERIFY) + { + /* + ** Recalculate e_msgpriority, it is done at in eatheader() + ** which is called (in 8.12) after the header is collected, + ** hence e_msgsize is (most likely) incorrect. + */ + + e->e_msgpriority = e->e_msgsize + - e->e_class * WkClassFact + + e->e_nrcpts * WkRecipFact; + if (tTd(90, 1)) + sm_syslog(LOG_INFO, e->e_id, + "collect: at end: msgsize=%ld, msgpriority=%ld", + e->e_msgsize, e->e_msgpriority); markstats(e, (ADDRESS *) NULL, STATS_NORMAL); + } } static void @@ -1019,6 +1037,7 @@ dferror(df, msg, e) ** ** Parameters: ** fm -- the from line. +** e -- envelope ** ** Returns: ** none. diff --git a/contrib/sendmail/src/conf.c b/contrib/sendmail/src/conf.c index be083b4..b164d29 100644 --- a/contrib/sendmail/src/conf.c +++ b/contrib/sendmail/src/conf.c @@ -13,9 +13,12 @@ #include -SM_RCSID("@(#)$Id: conf.c,v 8.972.2.35 2003/03/28 05:46:09 ca Exp $") +SM_RCSID("@(#)$Id: conf.c,v 8.972.2.50 2003/09/03 21:37:03 ca Exp $") #include +#if NEWDB +# include "sm/bdb.h" +#endif /* NEWDB */ # include # include @@ -465,6 +468,19 @@ setupmaps() register STAB *s; #if NEWDB +# if DB_VERSION_MAJOR > 1 + int major_v, minor_v, patch_v; + + (void) db_version(&major_v, &minor_v, &patch_v); + if (major_v != DB_VERSION_MAJOR || minor_v != DB_VERSION_MINOR) + { + errno = 0; + syserr("Berkeley DB version mismatch: compiled against %d.%d.%d, run-time linked against %d.%d.%d", + DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH, + major_v, minor_v, patch_v); + } +# endif /* DB_VERSION_MAJOR > 1 */ + MAPDEF("hash", ".db", MCF_ALIASOK|MCF_REBUILDABLE, map_parseargs, hash_map_open, db_map_close, db_map_lookup, db_map_store); @@ -2227,7 +2243,7 @@ refuseconnections(name, e, d, active) sm_setproctitle(true, e, R_MSG_LA, name, CurrentLA); if (LogLevel > 8) sm_syslog(LOG_NOTICE, NOQID, R_MSG_LA, name, CurrentLA); -#if _FFR_REJECT_LOG +# if _FFR_REJECT_LOG now = curtime(); if (firstrejtime[d] == 0) { @@ -2240,13 +2256,13 @@ refuseconnections(name, e, d, active) pintvl(now - firstrejtime[d], true)); nextlogtime[d] = now + RejectLogInterval; } -#endif /* _FFR_REJECT_LOG */ +# endif /* _FFR_REJECT_LOG */ return true; } -#if _FFR_REJECT_LOG +# if _FFR_REJECT_LOG else firstrejtime[d] = 0; -#endif /* _FFR_REJECT_LOG */ +# endif /* _FFR_REJECT_LOG */ if (DelayLA > 0 && CurrentLA >= DelayLA) { @@ -2428,12 +2444,12 @@ initsetproctitle(argc, argv, envp) */ align = -1; -#if _FFR_SPT_ALIGN -# ifdef SPT_ALIGN_SIZE +# if _FFR_SPT_ALIGN +# ifdef SPT_ALIGN_SIZE for (i = SPT_ALIGN_SIZE; i > 0; i >>= 1) align++; -# endif /* SPT_ALIGN_SIZE */ -#endif /* _FFR_SPT_ALIGN */ +# endif /* SPT_ALIGN_SIZE */ +# endif /* _FFR_SPT_ALIGN */ for (i = 0; i < argc; i++) { @@ -2818,25 +2834,6 @@ uname(name) return 0; } -# if 0 - /* - ** Popen is known to have security holes. - */ - - /* try uuname -l to return local name */ - if ((file = popen("uuname -l", "r")) != NULL) - { - (void) sm_io_fgets(file, SM_TIME_DEFAULT, name, - NODE_LENGTH + 1); - (void) pclose(file); - n = strchr(name, '\n'); - if (n != NULL) - *n = '\0'; - if (name->nodename[0] != '\0') - return 0; - } -# endif /* 0 */ - return -1; } #endif /* !HASUNAME */ @@ -4733,7 +4730,7 @@ load_if_names() # ifndef __hpux lifc.lifc_family = AF_UNSPEC; lifc.lifc_flags = 0; -# endif /* __hpux */ +# endif /* ! __hpux */ if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) { if (tTd(0, 4)) @@ -5678,6 +5675,9 @@ char *OsCompileOptions[] = #if ADDRCONFIG_IS_BROKEN "ADDRCONFIG_IS_BROKEN", #endif /* ADDRCONFIG_IS_BROKEN */ +#if ALLOW_255 + "ALLOW_255", +#endif /* ALLOW_255 */ #ifdef AUTO_NETINFO_HOSTS "AUTO_NETINFO_HOSTS", #endif /* AUTO_NETINFO_HOSTS */ @@ -5929,6 +5929,10 @@ char *FFRCompileOptions[] = /* Stricter checks about queue directory permissions. */ "_FFR_CHK_QUEUE", #endif /* _FFR_CHK_QUEUE */ +#if _FFR_CLIENT_SIZE + /* Don't try to send mail if its size exceeds SIZE= of server. */ + "_FFR_CLIENT_SIZE", +#endif /* _FFR_CLIENT_SIZE */ #if _FFR_CONTROL_MSTAT /* Extended daemon status. */ "_FFR_CONTROL_MSTAT", @@ -5989,6 +5993,10 @@ char *FFRCompileOptions[] = "_FFR_DROP_TRUSTUSER_WARNING", #endif /* _FFR_DROP_TRUSTUSER_WARNING */ +#if _FFR_EXTRA_MAP_CHECK + /* perform extra checks on $( $) in R lines */ + "_FFR_EXTRA_MAP_CHECK", +#endif /* _FFR_EXTRA_MAP_CHECK */ #if _FFR_FIX_DASHT /* ** If using -t, force not sending to argv recipients, even @@ -6026,6 +6034,10 @@ char *FFRCompileOptions[] = /* Use nsswitch on HP-UX */ "_FFR_HPUX_NSSWITCH", #endif /* _FFR_HPUX_NSSWITCH */ +#if _FFR_IGNORE_BOGUS_ADDR + /* Ignore addresses for which prescan() failed */ + "_FFR_IGNORE_BOGUS_ADDR", +#endif /* _FFR_IGNORE_BOGUS_ADDR */ #if _FFR_IGNORE_EXT_ON_HELO /* Ignore extensions offered in response to HELO */ "_FFR_IGNORE_EXT_ON_HELO", @@ -6049,12 +6061,16 @@ char *FFRCompileOptions[] = /* Randall S. Winchester of the University of Maryland */ "_FFR_MAX_FORWARD_ENTRIES", #endif /* _FFR_MAX_FORWARD_ENTRIES */ +#if _FFR_MAX_SLEEP_TIME + /* Limit sleep(2) time in libsm/clock.c */ + "_FFR_MAX_SLEEP_TIME", +#endif /* _FFR_MAX_SLEEP_TIME */ #if MILTER # if _FFR_MILTER_421 /* If a filter returns 421, close the SMTP connection */ "_FFR_MILTER_421", # endif /* _FFR_MILTER_421 */ -# if _FFR_MILTER_PERDAEMON +# if _FFR_MILTER_PERDAEMON /* Per DaemonPortOptions InputMailFilter lists */ "_FFR_MILTER_PERDAEMON", # endif /* _FFR_MILTER_PERDAEMON */ @@ -6144,6 +6160,10 @@ char *FFRCompileOptions[] = /* Donated code (unused). */ "_FFR_SHM_STATUS", #endif /* _FFR_SHM_STATUS */ +#if _FFR_SLEEP_USE_SELECT + /* Use select(2) in libsm/clock.c to emulate sleep(2) */ + "_FFR_SLEEP_USE_SELECT ", +#endif /* _FFR_SLEEP_USE_SELECT */ #if _FFR_SMFI_OPENSOCKET /* libmilter: smfi_opensocket() to force the socket open early */ "_FFR_SMFI_OPENSOCKET", diff --git a/contrib/sendmail/src/control.c b/contrib/sendmail/src/control.c index d36dc66..d93f0cf 100644 --- a/contrib/sendmail/src/control.c +++ b/contrib/sendmail/src/control.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -10,7 +10,7 @@ #include -SM_RCSID("@(#)$Id: control.c,v 8.118.4.3 2002/11/14 00:15:56 ca Exp $") +SM_RCSID("@(#)$Id: control.c,v 8.118.4.8 2003/06/24 17:45:27 ca Exp $") #include diff --git a/contrib/sendmail/src/daemon.c b/contrib/sendmail/src/daemon.c index d12e162..267f363 100644 --- a/contrib/sendmail/src/daemon.c +++ b/contrib/sendmail/src/daemon.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: daemon.c,v 8.613.2.14 2003/02/11 17:17:22 ca Exp $") +SM_RCSID("@(#)$Id: daemon.c,v 8.613.2.17 2003/07/30 20:17:04 ca Exp $") #if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) # define USE_SOCK_STREAM 1 @@ -235,13 +235,7 @@ getrequests(e) /* see if we are rejecting connections */ (void) sm_blocksignal(SIGALRM); - - if (ShutdownRequest != NULL) - shutdown_daemon(); - else if (RestartRequest != NULL) - restart_daemon(); - else if (RestartWorkGroup) - restart_marked_work_groups(); + CHECK_RESTART; for (idx = 0; idx < NDaemons; idx++) { @@ -283,13 +277,7 @@ getrequests(e) } /* May have been sleeping above, check again */ - if (ShutdownRequest != NULL) - shutdown_daemon(); - else if (RestartRequest != NULL) - restart_daemon(); - else if (RestartWorkGroup) - restart_marked_work_groups(); - + CHECK_RESTART; getrequests_checkdiskspace(e); #if XDEBUG @@ -335,15 +323,8 @@ getrequests(e) fd_set readfds; struct timeval timeout; - if (ShutdownRequest != NULL) - shutdown_daemon(); - else if (RestartRequest != NULL) - restart_daemon(); - else if (RestartWorkGroup) - restart_marked_work_groups(); - + CHECK_RESTART; FD_ZERO(&readfds); - for (idx = 0; idx < NDaemons; idx++) { /* wait for a connection */ @@ -380,13 +361,7 @@ getrequests(e) NULL, NULL, &timeout); /* Did someone signal while waiting? */ - if (ShutdownRequest != NULL) - shutdown_daemon(); - else if (RestartRequest != NULL) - restart_daemon(); - else if (RestartWorkGroup) - restart_marked_work_groups(); - + CHECK_RESTART; curdaemon = -1; @@ -3363,7 +3338,9 @@ getauthinfo(fd, may_be_forged) /* try to match the reverse against the forward lookup */ hp = sm_gethostbyname(RealHostName, family); if (hp == NULL) + { *may_be_forged = true; + } else { for (ha = hp->h_addr_list; *ha != NULL; ha++) diff --git a/contrib/sendmail/src/deliver.c b/contrib/sendmail/src/deliver.c index af6e41f..95149a0 100644 --- a/contrib/sendmail/src/deliver.c +++ b/contrib/sendmail/src/deliver.c @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: deliver.c,v 8.940.2.18 2003/03/28 17:34:39 ca Exp $") +SM_RCSID("@(#)$Id: deliver.c,v 8.940.2.19 2003/09/03 19:58:26 ca Exp $") #if HASSETUSERCONTEXT # include @@ -4476,7 +4476,7 @@ putbody(mci, e, separator) char *df = queuename(e, DATAFL_LETTER); e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, df, - SM_IO_RDONLY, NULL); + SM_IO_RDONLY_B, NULL); if (e->e_dfp == NULL) { char *msg = "!putbody: Cannot open %s for %s from %s"; @@ -5207,7 +5207,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e) char *df = queuename(e, DATAFL_LETTER); e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, df, - SM_IO_RDONLY, NULL); + SM_IO_RDONLY_B, NULL); if (e->e_dfp == NULL) { syserr("mailfile: Cannot open %s for %s from %s", diff --git a/contrib/sendmail/src/domain.c b/contrib/sendmail/src/domain.c index 0519907..f4a8810 100644 --- a/contrib/sendmail/src/domain.c +++ b/contrib/sendmail/src/domain.c @@ -14,9 +14,9 @@ #include #if NAMED_BIND -SM_RCSID("@(#)$Id: domain.c,v 8.181.2.6 2003/01/15 19:17:15 ca Exp $ (with name server)") +SM_RCSID("@(#)$Id: domain.c,v 8.181.2.9 2003/08/11 23:23:40 gshapiro Exp $ (with name server)") #else /* NAMED_BIND */ -SM_RCSID("@(#)$Id: domain.c,v 8.181.2.6 2003/01/15 19:17:15 ca Exp $ (without name server)") +SM_RCSID("@(#)$Id: domain.c,v 8.181.2.9 2003/08/11 23:23:40 gshapiro Exp $ (without name server)") #endif /* NAMED_BIND */ #if NAMED_BIND @@ -233,6 +233,8 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl) if (tTd(8, 2)) sm_dprintf("getmxrr(%s, droplocalhost=%d)\n", host, droplocalhost); + if (*host == '\0') + return 0; if ((fallbackMX != NULL && droplocalhost && wordinclass(fallbackMX, 'w')) || !tryfallback) @@ -778,12 +780,6 @@ bestmx_map_lookup(map, name, av, statp) ** false -- otherwise. */ -# if NETINET6 -# define SM_T_INITIAL T_AAAA -# else /* NETINET6 */ -# define SM_T_INITIAL T_A -# endif /* NETINET6 */ - bool dns_getcanonname(host, hbsize, trymx, statp, pttl) char *host; @@ -807,6 +803,7 @@ dns_getcanonname(host, hbsize, trymx, statp, pttl) bool amatch; bool gotmx = false; int qtype; + int initial; int loopcnt; char *xp; char nbuf[SM_MAX(MAXPACKET, MAXDNAME*2+2)]; @@ -898,11 +895,16 @@ cnameloop: */ mxmatch = NULL; - qtype = SM_T_INITIAL; + initial = T_A; +# if NETINET6 + if (InetMode == AF_INET6) + initial = T_AAAA; +# endif /* NETINET6 */ + qtype = initial; for (dp = searchlist; *dp != NULL; ) { - if (qtype == SM_T_INITIAL) + if (qtype == initial) gotmx = false; if (tTd(8, 5)) sm_dprintf("dns_getcanonname: trying %s.%s (%s)\n", @@ -984,7 +986,7 @@ nexttype: /* definite no -- try the next domain */ dp++; - qtype = SM_T_INITIAL; + qtype = initial; continue; } else if (tTd(8, 7)) @@ -1069,13 +1071,7 @@ nexttype: # if NETINET6 case T_AAAA: - /* Flag that a good match was found */ - amatch = true; - - /* continue in case a CNAME also exists */ - continue; # endif /* NETINET6 */ - case T_A: /* Flag that a good match was found */ amatch = true; @@ -1161,7 +1157,7 @@ nexttype: qtype = T_MX; else { - qtype = SM_T_INITIAL; + qtype = initial; dp++; } } diff --git a/contrib/sendmail/src/headers.c b/contrib/sendmail/src/headers.c index 890c280..dd871ea 100644 --- a/contrib/sendmail/src/headers.c +++ b/contrib/sendmail/src/headers.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: headers.c,v 8.266.4.5 2003/03/12 22:42:52 gshapiro Exp $") +SM_RCSID("@(#)$Id: headers.c,v 8.266.4.7 2003/09/03 21:32:20 ca Exp $") static size_t fix_mime_header __P((HDR *, ENVELOPE *)); static int priencode __P((char *)); @@ -140,7 +140,10 @@ chompheader(line, pflag, hdrp, e) mid = (unsigned char) macid(p); if (bitset(0200, mid)) + { p += strlen(macname(mid)) + 2; + SM_ASSERT(p <= q); + } else p++; @@ -315,6 +318,7 @@ hse: qval[l++] = '"'; /* - 3 to avoid problems with " at the end */ + /* should be sizeof(qval), not MAXNAME */ for (k = 0; fvalue[k] != '\0' && l < MAXNAME - 3; k++) { switch (fvalue[k]) @@ -1175,7 +1179,7 @@ crackaddr(addr, e) else if (c == ')') { /* syntax error: unmatched ) */ - if (copylev > 0 && SM_HAVE_ROOM) + if (copylev > 0 && SM_HAVE_ROOM && bp > bufhead) bp--; } @@ -1349,7 +1353,7 @@ crackaddr(addr, e) else if (SM_HAVE_ROOM) { /* syntax error: unmatched > */ - if (copylev > 0) + if (copylev > 0 && bp > bufhead) bp--; quoteit = true; continue; @@ -1693,6 +1697,12 @@ put_vanilla_header(h, v, mci) int l; l = nlp - v; + + /* + ** XXX This is broken for SPACELEFT()==0 + ** However, SPACELEFT() is always > 0 unless MAXLINE==1. + */ + if (SPACELEFT(obuf, obp) - 1 < (size_t) l) l = SPACELEFT(obuf, obp) - 1; @@ -1703,6 +1713,8 @@ put_vanilla_header(h, v, mci) if (*v != ' ' && *v != '\t') *obp++ = ' '; } + + /* XXX This is broken for SPACELEFT()==0 */ (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.*s", (int) (SPACELEFT(obuf, obp) - 1), v); putxline(obuf, strlen(obuf), mci, putflags); @@ -1737,6 +1749,7 @@ commaize(h, p, oldstyle, mci, e) int omax; bool firstone = true; int putflags = PXLF_HEADER; + char **res; char obuf[MAXLINE + 3]; /* @@ -1753,6 +1766,8 @@ commaize(h, p, oldstyle, mci, e) obp = obuf; (void) sm_snprintf(obp, SPACELEFT(obuf, obp), "%.200s: ", h->h_field); + + /* opos = strlen(obp); */ opos = strlen(h->h_field) + 2; if (opos > 202) opos = 202; @@ -1785,14 +1800,23 @@ commaize(h, p, oldstyle, mci, e) while ((isascii(*p) && isspace(*p)) || *p == ',') p++; name = p; + res = NULL; for (;;) { auto char *oldp; char pvpbuf[PSBUFSIZE]; - (void) prescan(p, oldstyle ? ' ' : ',', pvpbuf, - sizeof pvpbuf, &oldp, NULL); + res = prescan(p, oldstyle ? ' ' : ',', pvpbuf, + sizeof pvpbuf, &oldp, NULL); p = oldp; +#if _FFR_IGNORE_BOGUS_ADDR + /* ignore addresses that can't be parsed */ + if (res == NULL) + { + name = p; + continue; + } +#endif /* _FFR_IGNORE_BOGUS_ADDR */ /* look to see if we have an at sign */ while (*p != '\0' && isascii(*p) && isspace(*p)) @@ -1815,6 +1839,15 @@ commaize(h, p, oldstyle, mci, e) p--; if (++p == name) continue; + + /* + ** if prescan() failed go a bit backwards; this is a hack, + ** there should be some better error recovery. + */ + + if (res == NULL && p > name && + !((isascii(*p) && isspace(*p)) || *p == ',' || *p == '\0')) + --p; savechar = *p; *p = '\0'; @@ -1858,7 +1891,7 @@ commaize(h, p, oldstyle, mci, e) (void) sm_strlcpy(obp, ",\n", SPACELEFT(obuf, obp)); putxline(obuf, strlen(obuf), mci, putflags); obp = obuf; - (void) sm_strlcpy(obp, " ", sizeof obp); + (void) sm_strlcpy(obp, " ", sizeof obuf); opos = strlen(obp); obp += opos; opos += strlen(name); @@ -1874,7 +1907,10 @@ commaize(h, p, oldstyle, mci, e) firstone = false; *p = savechar; } - *obp = '\0'; + if (obp < &obuf[sizeof obuf]) + *obp = '\0'; + else + obuf[sizeof obuf - 1] = '\0'; putxline(obuf, strlen(obuf), mci, putflags); } /* @@ -1946,6 +1982,7 @@ fix_mime_header(h, e) return 0; /* Split on each ';' */ + /* find_character() never returns NULL */ while ((end = find_character(begin, ';')) != NULL) { char save = *end; diff --git a/contrib/sendmail/src/main.c b/contrib/sendmail/src/main.c index dbe9ce5..a56315c 100644 --- a/contrib/sendmail/src/main.c +++ b/contrib/sendmail/src/main.c @@ -25,7 +25,7 @@ SM_UNUSED(static char copyright[]) = The Regents of the University of California. All rights reserved.\n"; #endif /* ! lint */ -SM_RCSID("@(#)$Id: main.c,v 8.887.2.22 2003/03/06 18:38:08 ca Exp $") +SM_RCSID("@(#)$Id: main.c,v 8.887.2.27 2003/08/04 17:23:37 ca Exp $") #if NETINET || NETINET6 @@ -940,16 +940,18 @@ main(argc, argv, envp) *p++ = '\0'; if (*p != '\0') { - ep = sm_malloc_x(strlen(p) + 1); - cleanstrcpy(ep, p, MAXNAME); + i = strlen(p) + 1; + ep = sm_malloc_x(i); + cleanstrcpy(ep, p, i); macdefine(&BlankEnvelope.e_macro, A_HEAP, 's', ep); } } if (*optarg != '\0') { - ep = sm_malloc_x(strlen(optarg) + 1); - cleanstrcpy(ep, optarg, MAXNAME); + i = strlen(optarg) + 1; + ep = sm_malloc_x(i); + cleanstrcpy(ep, optarg, i); macdefine(&BlankEnvelope.e_macro, A_HEAP, 'r', ep); } @@ -2368,13 +2370,7 @@ main(argc, argv, envp) pid_t ret; int group; - if (ShutdownRequest != NULL) - shutdown_daemon(); - else if (RestartRequest != NULL) - restart_daemon(); - else if (RestartWorkGroup) - restart_marked_work_groups(); - + CHECK_RESTART; while ((ret = sm_wait(&status)) <= 0) continue; @@ -2392,8 +2388,9 @@ main(argc, argv, envp) "persistent queue runner=%d core dumped, signal=%d", group, WTERMSIG(status)); - /* don't restart this one */ - mark_work_group_restart(group, -1); + /* don't restart this */ + mark_work_group_restart( + group, -1); continue; } @@ -2414,7 +2411,8 @@ main(argc, argv, envp) sm_syslog(LOG_DEBUG, NOQID, "persistent queue runner=%d, exited", group); - mark_work_group_restart(group, -1); + mark_work_group_restart(group, + -1); } } finis(true, true, ExitStat); @@ -2443,13 +2441,7 @@ main(argc, argv, envp) for (;;) { (void) pause(); - if (ShutdownRequest != NULL) - shutdown_daemon(); - else if (RestartRequest != NULL) - restart_daemon(); - else if (RestartWorkGroup) - restart_marked_work_groups(); - + CHECK_RESTART; if (doqueuerun()) (void) runqueue(true, false, false, false); @@ -2643,7 +2635,7 @@ main(argc, argv, envp) /* collect body for UUCP return */ if (OpMode != MD_VERIFY) - collect(InChannel, false, NULL, &MainEnvelope); + collect(InChannel, false, NULL, &MainEnvelope, true); finis(true, true, EX_USAGE); /* NOTREACHED */ } @@ -2703,7 +2695,7 @@ main(argc, argv, envp) MainEnvelope.e_flags &= ~EF_FATALERRS; Errors = 0; buffer_errors(); - collect(InChannel, false, NULL, &MainEnvelope); + collect(InChannel, false, NULL, &MainEnvelope, true); /* header checks failed */ if (Errors > 0) diff --git a/contrib/sendmail/src/map.c b/contrib/sendmail/src/map.c index 6f9a461..8362327 100644 --- a/contrib/sendmail/src/map.c +++ b/contrib/sendmail/src/map.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1992, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: map.c,v 8.645.2.7 2002/12/03 17:01:15 ca Exp $") +SM_RCSID("@(#)$Id: map.c,v 8.645.2.10 2003/07/24 18:24:17 ca Exp $") #if LDAPMAP # include @@ -383,7 +383,7 @@ map_rewrite(map, s, slen, av) if (c != '%') { pushc: - if (--len <= 0) + if (len-- <= 1) break; *bp++ = c; continue; @@ -394,8 +394,9 @@ map_rewrite(map, s, slen, av) goto pushc; if (!(isascii(c) && isdigit(c))) { + if (len-- <= 1) + break; *bp++ = '%'; - --len; goto pushc; } for (avp = av; --c >= '0' && *avp != NULL; avp++) @@ -1173,8 +1174,7 @@ dns_map_lookup(map, name, av, statp) if (r == NULL) { result = NULL; - if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || - errno == ECONNREFUSED) + if (h_errno == TRY_AGAIN || transienterror(errno)) *statp = EX_TEMPFAIL; else *statp = EX_NOTFOUND; @@ -6944,6 +6944,10 @@ regex_map_init(map, ap) map->map_mflags |= MF_MATCHONLY; break; + case 'q': + map->map_mflags |= MF_KEEPQUOTES; + break; + case 'S': map->map_spacesub = *++p; break; diff --git a/contrib/sendmail/src/mci.c b/contrib/sendmail/src/mci.c index 033387b..b8c0de2 100644 --- a/contrib/sendmail/src/mci.c +++ b/contrib/sendmail/src/mci.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: mci.c,v 8.205.2.3 2003/01/07 03:56:19 ca Exp $") +SM_RCSID("@(#)$Id: mci.c,v 8.205.2.4 2003/03/31 17:35:27 ca Exp $") #if NETINET || NETINET6 # include @@ -548,11 +548,21 @@ mci_dump(mci, logit) } (void) sm_snprintf(p, SPACELEFT(buf, p), "flags=%lx", mci->mci_flags); p += strlen(p); + + /* + ** The following check is just for paranoia. It protects the + ** assignment in the if() clause. If there's not some minimum + ** amount of space we can stop right now. The check will not + ** trigger as long as sizeof(buf)=4000. + */ + + if (p >= buf + sizeof(buf) - 4) + goto printit; if (mci->mci_flags != 0) { struct mcifbits *f; - *p++ = '<'; + *p++ = '<'; /* protected above */ for (f = MciFlags; f->mcif_bit != 0; f++) { if (!bitset(f->mcif_bit, mci->mci_flags)) @@ -1152,7 +1162,7 @@ mci_traverse_persistent(action, pathname) if (hostptr != host) *(hostptr++) = '.'; start = end; - while (*(start - 1) != '/') + while (start > pathname && *(start - 1) != '/') start--; if (*end == '.') @@ -1162,7 +1172,7 @@ mci_traverse_persistent(action, pathname) *(hostptr++) = *scan; end = start - 2; - } while (*end == '.'); + } while (end > pathname && *end == '.'); *hostptr = '\0'; @@ -1352,7 +1362,7 @@ mci_purge_persistent(pathname, hostname) /* ** MCI_GENERATE_PERSISTENT_PATH -- generate path from hostname ** -** Given `host', convert from a.b.c to $QueueDir/.hoststat/c./b./a, +** Given `host', convert from a.b.c to $HostStatDir/c./b./a, ** putting the result into `path'. if `createflag' is set, intervening ** directories will be created as needed. ** diff --git a/contrib/sendmail/src/milter.c b/contrib/sendmail/src/milter.c index 077578b..c91ad12 100644 --- a/contrib/sendmail/src/milter.c +++ b/contrib/sendmail/src/milter.c @@ -10,7 +10,7 @@ #include -SM_RCSID("@(#)$Id: milter.c,v 8.197.2.7 2003/03/22 18:54:25 ca Exp $") +SM_RCSID("@(#)$Id: milter.c,v 8.197.2.9 2003/09/07 00:18:29 ca Exp $") #if MILTER # include @@ -1569,7 +1569,7 @@ milter_reopen_df(e) /* open writable */ if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, - SM_IO_RDWR, NULL)) == NULL) + SM_IO_RDWR_B, NULL)) == NULL) { MILTER_DF_ERROR("milter_reopen_df: sm_io_open %s: %s"); return -1; @@ -1626,7 +1626,7 @@ milter_reset_df(e) return -1; } else if ((e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, dfname, - SM_IO_RDONLY, NULL)) == NULL) + SM_IO_RDONLY_B, NULL)) == NULL) { MILTER_DF_ERROR("milter_reset_df: error reopening %s: %s"); return -1; @@ -2807,6 +2807,8 @@ milter_addrcpt(response, rlen, e) ssize_t rlen; ENVELOPE *e; { + int olderrors; + if (tTd(64, 10)) sm_dprintf("milter_addrcpt: "); @@ -2831,7 +2833,9 @@ milter_addrcpt(response, rlen, e) sm_dprintf("%s\n", response); if (MilterLogLevel > 8) sm_syslog(LOG_INFO, e->e_id, "Milter add: rcpt: %s", response); - (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); + olderrors = Errors; + (void) sendtolist(response, NULLADDR, &e->e_sendqueue, 0, e); + Errors = olderrors; return; } /* diff --git a/contrib/sendmail/src/mime.c b/contrib/sendmail/src/mime.c index 2fd36d2..62d1617 100644 --- a/contrib/sendmail/src/mime.c +++ b/contrib/sendmail/src/mime.c @@ -14,7 +14,7 @@ #include #include -SM_RCSID("@(#)$Id: mime.c,v 8.130 2002/05/21 03:39:34 ca Exp $") +SM_RCSID("@(#)$Id: mime.c,v 8.130.2.1 2003/04/15 01:05:59 ca Exp $") /* ** MIME support. @@ -317,7 +317,7 @@ mime8to7(mci, header, e, boundaries, flags) putline(buf, mci); if (tTd(43, 35)) sm_dprintf(" ...%s\n", buf); - collect(e->e_dfp, false, &hdr, e); + collect(e->e_dfp, false, &hdr, e, false); if (tTd(43, 101)) putline("+++after collect", mci); putheader(mci, hdr, e, flags); @@ -371,7 +371,7 @@ mime8to7(mci, header, e, boundaries, flags) putline("", mci); mci->mci_flags |= MCIF_INMIME; - collect(e->e_dfp, false, &hdr, e); + collect(e->e_dfp, false, &hdr, e, false); if (tTd(43, 101)) putline("+++after collect", mci); putheader(mci, hdr, e, flags); diff --git a/contrib/sendmail/src/parseaddr.c b/contrib/sendmail/src/parseaddr.c index 8128171..48ed142 100644 --- a/contrib/sendmail/src/parseaddr.c +++ b/contrib/sendmail/src/parseaddr.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: parseaddr.c,v 8.359.2.6 2003/03/27 02:39:53 ca Exp $") +SM_RCSID("@(#)$Id: parseaddr.c,v 8.359.2.9 2003/09/16 18:07:50 ca Exp $") static void allocaddr __P((ADDRESS *, int, char *, ENVELOPE *)); static int callsubr __P((char**, int, ENVELOPE *)); @@ -702,7 +702,7 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (delimptr != NULL) { if (p > addr) - p--; + --p; *delimptr = p; } CurEnv->e_to = saveto; @@ -885,9 +885,12 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) } } while (c != '\0' && (c != delim || anglecnt > 0)); *avp = NULL; - p--; if (delimptr != NULL) + { + if (p > addr) + p--; *delimptr = p; + } if (tTd(22, 12)) { sm_dprintf("prescan==>"); @@ -970,6 +973,11 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) char buf[MAXLINE]; char name[6]; + /* + ** mlp will not exceed mlist[] because readcf enforces + ** the upper limit of entries when reading rulesets. + */ + if (ruleset < 0 || ruleset >= MAXRWSETS) { syserr("554 5.3.5 rewrite: illegal ruleset number %d", ruleset); @@ -1004,6 +1012,8 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) } if (pvp == NULL) return EX_USAGE; + if (maxatom <= 0) + return EX_USAGE; /* ** Run through the list of rewrite rules, applying @@ -1291,16 +1301,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) while (pp <= m->match_last) { if (avp >= &npvp[maxatom]) - { - syserr("554 5.3.0 rewrite: expansion too long"); - if (LogLevel > 9) - sm_syslog(LOG_ERR, - e->e_id, - "rewrite: expansion too long, ruleset=%s, ruleno=%d", - rulename, - ruleno); - return EX_DATAERR; - } + goto toolong; *avp++ = *pp++; } } @@ -1407,7 +1408,7 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) char **default_rvp; char cbuf[MAXNAME + 1]; char *pvpb1[MAXATOM + 1]; - char *argvect[10]; + char *argvect[MAX_MAP_ARGS]; char pvpbuf[PSBUFSIZE]; char *nullpvp[1]; @@ -1431,13 +1432,19 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) { endtoken = LOOKUPEND; mapname = *++rvp; + if (mapname == NULL) + syserr("554 5.3.0 rewrite: missing mapname"); } map = stab(mapname, ST_MAP, ST_FIND); if (map == NULL) - syserr("554 5.3.0 rewrite: map %s not found", mapname); + syserr("554 5.3.0 rewrite: map %s not found", + mapname); /* extract the match part */ key_rvp = ++rvp; + if (key_rvp == NULL) + syserr("554 5.3.0 rewrite: missing key for map %s", + mapname); default_rvp = NULL; arg_rvp = argvect; xpvp = NULL; @@ -1446,7 +1453,8 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) { int nodetype = **rvp & 0377; - if (nodetype != CANONHOST && nodetype != CANONUSER) + if (nodetype != CANONHOST && + nodetype != CANONUSER) { rvp++; continue; @@ -1459,7 +1467,9 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) cataddr(xpvp, NULL, replac, &pvpbuf[sizeof pvpbuf] - replac, '\0'); - *++arg_rvp = replac; + if (arg_rvp < + &argvect[MAX_MAP_ARGS - 1]) + *++arg_rvp = replac; replac += strlen(replac) + 1; xpvp = NULL; } @@ -1481,9 +1491,13 @@ rewrite(pvp, ruleset, reclevel, e, maxatom) cataddr(xpvp, NULL, replac, &pvpbuf[sizeof pvpbuf] - replac, '\0'); - *++arg_rvp = replac; + if (arg_rvp < &argvect[MAX_MAP_ARGS - 1]) + *++arg_rvp = replac; } - *++arg_rvp = NULL; + if (arg_rvp >= &argvect[MAX_MAP_ARGS - 1]) + argvect[MAX_MAP_ARGS - 1] = NULL; + else + *++arg_rvp = NULL; /* save the remainder of the input string */ trsize = (int) (avp - rvp + 1) * sizeof *rvp; @@ -1672,7 +1686,7 @@ callsubr(pvp, reclevel, e) /* ** Now we need to call the ruleset specified for - ** the subroutine. we can do this inplace since + ** the subroutine. We can do this in place since ** we call the "last" subroutine first. */ @@ -1870,6 +1884,7 @@ buildaddr(tv, a, flags, e) register ENVELOPE *e; { bool tempfail = false; + int maxatom; struct mailer **mp; register struct mailer *m; register char *p; @@ -1884,6 +1899,7 @@ buildaddr(tv, a, flags, e) printav(tv); } + maxatom = MAXATOM; if (a == NULL) a = (ADDRESS *) sm_rpool_malloc_x(e->e_rpool, sizeof *a); memset((char *) a, '\0', sizeof *a); @@ -1923,14 +1939,22 @@ badaddr: return a; } mname = *++tv; + --maxatom; /* extract host and user portions */ if (*++tv != NULL && (**tv & 0377) == CANONHOST) + { hostp = ++tv; + --maxatom; + } else hostp = NULL; + --maxatom; while (*tv != NULL && (**tv & 0377) != CANONUSER) + { tv++; + --maxatom; + } if (*tv == NULL) { syserr("554 5.3.5 buildaddr: no user"); @@ -1941,6 +1965,7 @@ badaddr: else if (hostp != NULL) cataddr(hostp, tv - 1, hbuf, sizeof hbuf, '\0'); cataddr(++tv, NULL, ubuf, sizeof ubuf, ' '); + --maxatom; /* save away the host name */ if (sm_strcasecmp(mname, "error") == 0) @@ -2045,6 +2070,7 @@ badaddr: { p++; tv++; + --maxatom; a->q_flags |= QNOTREMOTE; } @@ -2075,11 +2101,11 @@ badaddr: !bitset(RF_SENDERADDR|RF_HEADERADDR, flags)) { /* sender addresses done later */ - (void) REWRITE(tv, 2, e); + (void) rewrite(tv, 2, 0, e, maxatom); if (m->m_re_rwset > 0) - (void) REWRITE(tv, m->m_re_rwset, e); + (void) rewrite(tv, m->m_re_rwset, 0, e, maxatom); } - (void) REWRITE(tv, 4, e); + (void) rewrite(tv, 4, 0, e, maxatom); /* save the result for the command line/RCPT argument */ cataddr(tv, NULL, ubuf, sizeof ubuf, '\0'); @@ -2165,7 +2191,7 @@ cataddr(pvp, evp, buf, sz, spacesub) break; } #if _FFR_CATCH_LONG_STRINGS - /* Don't silently truncate long strings */ + /* Don't silently truncate long strings; broken for evp != NULL */ if (*pvp != NULL) syserr("cataddr: string too long"); #endif /* _FFR_CATCH_LONG_STRINGS */ @@ -2458,8 +2484,7 @@ emptyaddr(a) ** ** Parameters: ** name -- the name to translate. -** m -- the mailer that we want to do rewriting relative -** to. +** m -- the mailer that we want to do rewriting relative to. ** flags -- fine tune operations. ** pstat -- pointer to status word. ** e -- the current envelope. @@ -2654,7 +2679,6 @@ maplocaluser(a, sendq, aliaslevel, e) { register char **pvp; register ADDRESS *SM_NONVOLATILE a1 = NULL; - auto char *delimptr; char pvpbuf[PSBUFSIZE]; if (tTd(29, 1)) @@ -2662,7 +2686,7 @@ maplocaluser(a, sendq, aliaslevel, e) sm_dprintf("maplocaluser: "); printaddr(a, false); } - pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, &delimptr, NULL); + pvp = prescan(a->q_user, '\0', pvpbuf, sizeof pvpbuf, NULL, NULL); if (pvp == NULL) { if (tTd(29, 9)) @@ -3108,6 +3132,7 @@ rscheck(rwset, p1, p2, e, flags, logl, host, logid) ** e -- the current envelope. ** pvp -- pointer to token vector. ** pvpbuf -- buffer space. +** size -- size of buffer space. ** ** Returns: ** EX_UNAVAILABLE -- ruleset doesn't exist. @@ -3175,7 +3200,7 @@ rscap(rwset, p1, p2, e, pvp, pvpbuf, size) QuickAbort = false; *pvp = prescan(buf, '\0', pvpbuf, size, NULL, NULL); if (*pvp != NULL) - rstat = REWRITE(*pvp, rsno, e); + rstat = rewrite(*pvp, rsno, 0, e, size); else { if (tTd(48, 2)) diff --git a/contrib/sendmail/src/queue.c b/contrib/sendmail/src/queue.c index b488b5f..6f91ed9 100644 --- a/contrib/sendmail/src/queue.c +++ b/contrib/sendmail/src/queue.c @@ -13,20 +13,23 @@ #include -SM_RCSID("@(#)$Id: queue.c,v 8.863.2.30 2003/03/20 00:20:16 ca Exp $") +SM_RCSID("@(#)$Id: queue.c,v 8.863.2.61 2003/09/03 19:58:26 ca Exp $") #include # define RELEASE_QUEUE (void) 0 # define ST_INODE(st) (st).st_ino +# define sm_file_exists(errno) ((errno) == EEXIST) + +# define TF_OPEN_FLAGS (O_CREAT|O_WRONLY|O_EXCL) /* ** Historical notes: -** QF_VERSION == 4 was sendmail 8.10/8.11 without _FFR_QUEUEDELAY -** QF_VERSION == 5 was sendmail 8.10/8.11 with _FFR_QUEUEDELAY -** QF_VERSION == 6 is sendmail 8.12 without _FFR_QUEUEDELAY -** QF_VERSION == 7 is sendmail 8.12 with _FFR_QUEUEDELAY +** QF_VERSION == 4 was sendmail 8.10/8.11 without _FFR_QUEUEDELAY +** QF_VERSION == 5 was sendmail 8.10/8.11 with _FFR_QUEUEDELAY +** QF_VERSION == 6 is sendmail 8.12 without _FFR_QUEUEDELAY +** QF_VERSION == 7 is sendmail 8.12 with _FFR_QUEUEDELAY */ #if _FFR_QUEUEDELAY @@ -67,6 +70,21 @@ typedef struct work WORK; static WORK *WorkQ; /* queue of things to be done */ static int NumWorkGroups; /* number of work groups */ +static time_t Current_LA_time = 0; + +/* Get new load average every 30 seconds. */ +#define GET_NEW_LA_TIME 30 + +#define SM_GET_LA(now) \ + do \ + { \ + now = curtime(); \ + if (Current_LA_time < now - GET_NEW_LA_TIME) \ + { \ + sm_getla(); \ + Current_LA_time = now; \ + } \ + } while (0) /* ** DoQueueRun indicates that a queue run is needed. @@ -343,14 +361,36 @@ queueup(e, announce, msync) newid = (e->e_id == NULL) || !bitset(EF_INQUEUE, e->e_flags); (void) sm_strlcpy(tf, queuename(e, NEWQFL_LETTER), sizeof tf); tfp = e->e_lockfp; - if (tfp == NULL) - newid = false; + if (tfp == NULL && newid) + { + /* + ** open qf file directly: this will give an error if the file + ** already exists and hence prevent problems if a queue-id + ** is reused (e.g., because the clock is set back). + */ + + (void) sm_strlcpy(tf, queuename(e, ANYQFL_LETTER), sizeof tf); + tfd = open(tf, TF_OPEN_FLAGS, FileMode); + if (tfd < 0 || + !lockfile(tfd, tf, NULL, LOCK_EX|LOCK_NB) || + (tfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, + (void *) &tfd, SM_IO_WRONLY_B, + NULL)) == NULL) + { + int save_errno = errno; + + printopenfds(true); + errno = save_errno; + syserr("!queueup: cannot create queue file %s, euid=%d", + tf, (int) geteuid()); + /* NOTREACHED */ + } + e->e_lockfp = tfp; + } /* if newid, write the queue file directly (instead of temp file) */ if (!newid) { - const int flags = O_CREAT|O_WRONLY|O_EXCL; - /* get a locked tf file */ for (i = 0; i < 128; i++) { @@ -360,7 +400,7 @@ queueup(e, announce, msync) if (bitset(S_IWGRP, QueueFileMode)) oldumask = umask(002); - tfd = open(tf, flags, QueueFileMode); + tfd = open(tf, TF_OPEN_FLAGS, QueueFileMode); if (bitset(S_IWGRP, QueueFileMode)) (void) umask(oldumask); @@ -399,7 +439,7 @@ queueup(e, announce, msync) (void) sleep(i % 32); } if (tfd < 0 || (tfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, - (void *) &tfd, SM_IO_WRONLY, + (void *) &tfd, SM_IO_WRONLY_B, NULL)) == NULL) { int save_errno = errno; @@ -485,11 +525,12 @@ queueup(e, announce, msync) if (bitset(S_IWGRP, QueueFileMode)) oldumask = umask(002); - dfd = open(df, O_WRONLY|O_CREAT|O_TRUNC, QueueFileMode); + dfd = open(df, O_WRONLY|O_CREAT|O_TRUNC|QF_O_EXTRA, + QueueFileMode); if (bitset(S_IWGRP, QueueFileMode)) (void) umask(oldumask); if (dfd < 0 || (dfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, - (void *) &dfd, SM_IO_WRONLY, + (void *) &dfd, SM_IO_WRONLY_B, NULL)) == NULL) syserr("!queueup: cannot create data temp file %s, uid=%d", df, (int) geteuid()); @@ -1552,9 +1593,6 @@ runqueue(forkflag, verbose, persistent, runall) ** runs things in the mail queue. */ -/* Get new load average every 30 seconds. */ -#define GET_NEW_LA_TIME 30 - static void runner_work(e, sequenceno, didfork, skip, njobs) register ENVELOPE *e; @@ -1565,9 +1603,9 @@ runner_work(e, sequenceno, didfork, skip, njobs) { int n; WORK *w; - time_t current_la_time, now; + time_t now; - current_la_time = curtime(); + SM_GET_LA(now); /* ** Here we temporarily block the second calling of the handlers. @@ -1623,13 +1661,8 @@ runner_work(e, sequenceno, didfork, skip, njobs) ** Get new load average every GET_NEW_LA_TIME seconds. */ - now = curtime(); - if (current_la_time < now - GET_NEW_LA_TIME) - { - sm_getla(); - current_la_time = now; - } - if (shouldqueue(WkRecipFact, current_la_time)) + SM_GET_LA(now); + if (shouldqueue(WkRecipFact, Current_LA_time)) { char *msg = "Aborting queue run: load average too high"; @@ -1743,7 +1776,7 @@ run_work_group(wgrp, flags) int njobs, qdir; int sequenceno = 1; int qgrp, endgrp, h, i; - time_t current_la_time, now; + time_t now; bool full, more; SM_RPOOL_T *rpool; extern void rmexpstab __P((void)); @@ -1758,11 +1791,10 @@ run_work_group(wgrp, flags) ** the queue. */ - sm_getla(); /* get load average */ - current_la_time = curtime(); + SM_GET_LA(now); if (!bitset(RWG_PERSISTENT, flags) && - shouldqueue(WkRecipFact, current_la_time)) + shouldqueue(WkRecipFact, Current_LA_time)) { char *msg = "Skipping queue run -- load average too high"; @@ -2035,7 +2067,7 @@ run_work_group(wgrp, flags) if (pid < 0) { syserr("run_work_group: cannot fork"); - return 0; + return false; } else if (pid > 0) { @@ -2216,12 +2248,8 @@ run_work_group(wgrp, flags) ** CurrentLA caused all entries in a queue to be ignored. */ - now = curtime(); - if (njobs == 0 && current_la_time < now - GET_NEW_LA_TIME) - { - sm_getla(); - current_la_time = now; - } + if (njobs == 0) + SM_GET_LA(now); rpool = sm_rpool_new_x(NULL); e = newenvelope(&QueueEnvelope, CurEnv, rpool); e->e_flags = BlankEnvelope.e_flags; @@ -2545,7 +2573,7 @@ gatherq(qgrp, qdir, doall, full, more) } /* open control file */ - cf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDONLY, + cf = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDONLY_B, NULL); if (cf == NULL && OpMode != MD_PRINT) { @@ -2686,6 +2714,8 @@ gatherq(qgrp, qdir, doall, full, more) p = strchr(&lbuf[1], ':'); if (p == NULL) p = &lbuf[1]; + else + ++p; /* skip over ':' */ } else p = &lbuf[1]; @@ -3792,7 +3822,7 @@ readqf(e, openonly) */ (void) sm_strlcpy(qf, queuename(e, ANYQFL_LETTER), sizeof qf); - qfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDWR, NULL); + qfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDWR_B, NULL); if (qfp == NULL) { int save_errno = errno; @@ -3824,6 +3854,8 @@ readqf(e, openonly) return false; } + RELEASE_QUEUE; + /* ** Prevent locking race condition. ** @@ -3850,7 +3882,6 @@ readqf(e, openonly) sm_dprintf("readqf(%s): [f]stat failure (%s)\n", qf, sm_errstring(errno)); (void) sm_io_close(qfp, SM_TIME_DEFAULT); - RELEASE_QUEUE; return false; } @@ -3873,7 +3904,6 @@ readqf(e, openonly) if (LogLevel > 19) sm_syslog(LOG_DEBUG, e->e_id, "changed"); (void) sm_io_close(qfp, SM_TIME_DEFAULT); - RELEASE_QUEUE; return false; } @@ -3939,7 +3969,6 @@ readqf(e, openonly) if (!openonly) loseqfile(e, "bogus file uid/gid in mqueue"); (void) sm_io_close(qfp, SM_TIME_DEFAULT); - RELEASE_QUEUE; return false; } @@ -3952,7 +3981,6 @@ readqf(e, openonly) (void) xunlink(queuename(e, ANYQFL_LETTER)); } (void) sm_io_close(qfp, SM_TIME_DEFAULT); - RELEASE_QUEUE; return false; } @@ -3964,7 +3992,6 @@ readqf(e, openonly) */ (void) sm_io_close(qfp, SM_TIME_DEFAULT); - RELEASE_QUEUE; return false; } @@ -4154,10 +4181,10 @@ readqf(e, openonly) /* ** count size before chompheader() destroys the line. ** this isn't accurate due to macro expansion, but - ** better than before. "+3" to skip H?? at least. + ** better than before. "-3" to skip H?? at least. */ - hdrsize += strlen(bp + 3); + hdrsize += strlen(bp) - 3; (void) chompheader(&bp[1], CHHDR_QUEUE, NULL, e); break; @@ -4199,7 +4226,6 @@ readqf(e, openonly) howlong); e->e_id = NULL; unlockqueue(e); - RELEASE_QUEUE; return false; } macdefine(&e->e_macro, A_TEMP, @@ -4274,8 +4300,13 @@ readqf(e, openonly) } else qflags |= QPRIMARY; - q = parseaddr(++p, NULLADDR, RF_COPYALL, '\0', NULL, e, - true); + macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), + "e r"); + if (*p != '\0') + q = parseaddr(++p, NULLADDR, RF_COPYALL, '\0', + NULL, e, true); + else + q = NULL; if (q != NULL) { /* make sure we keep the current qgrp */ @@ -4291,6 +4322,8 @@ readqf(e, openonly) } frcpt = NULL; orcpt = NULL; + macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), + NULL); break; case 'S': /* sender */ @@ -4372,7 +4405,6 @@ readqf(e, openonly) { errno = 0; e->e_flags |= EF_CLRQUEUE|EF_FATALERRS|EF_RESPONSE; - RELEASE_QUEUE; return true; } @@ -4381,7 +4413,6 @@ readqf(e, openonly) { syserr("readqf: %s: incomplete queue file read", qf); (void) sm_io_close(qfp, SM_TIME_DEFAULT); - RELEASE_QUEUE; return false; } @@ -4401,7 +4432,7 @@ readqf(e, openonly) */ p = queuename(e, DATAFL_LETTER); - e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, p, SM_IO_RDONLY, + e->e_dfp = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, p, SM_IO_RDONLY_B, NULL); if (e->e_dfp == NULL) { @@ -4423,7 +4454,6 @@ readqf(e, openonly) } } - RELEASE_QUEUE; return true; fail: @@ -4441,7 +4471,6 @@ readqf(e, openonly) e->e_lockfp = NULL; e->e_flags |= EF_INQUEUE; loseqfile(e, err); - RELEASE_QUEUE; return false; } /* @@ -4740,7 +4769,7 @@ print_single_queue(qgrp, qdir) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%13s", w->w_name + 2); (void) sm_strlcpyn(qf, sizeof qf, 3, qd, "/", w->w_name); - f = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDONLY, + f = sm_io_open(SmFtStdio, SM_TIME_DEFAULT, qf, SM_IO_RDONLY_B, NULL); if (f == NULL) { @@ -6591,7 +6620,7 @@ init_shm(qn, owner, hash) Pshm = sm_shmstart(ShmKey, shms, SHM_R|SHM_W, &ShmId, owner); save_errno = errno; - if (Pshm != NULL || save_errno != EEXIST) + if (Pshm != NULL || !sm_file_exists(save_errno)) break; if (++count >= 3) { @@ -6681,6 +6710,7 @@ init_shm(qn, owner, hash) } #endif /* SM_CONF_SHM */ + /* ** SETUP_QUEUES -- setup all queue groups ** @@ -8250,7 +8280,7 @@ quarantine_queue_item(qgrp, qdir, e, reason) } tempqfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &fd, - SM_IO_WRONLY, NULL); + SM_IO_WRONLY_B, NULL); if (tempqfp == NULL) { (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, diff --git a/contrib/sendmail/src/readcf.c b/contrib/sendmail/src/readcf.c index f3e72ad..2a40e82 100644 --- a/contrib/sendmail/src/readcf.c +++ b/contrib/sendmail/src/readcf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: readcf.c,v 8.607.2.8 2003/03/12 22:42:52 gshapiro Exp $") +SM_RCSID("@(#)$Id: readcf.c,v 8.607.2.11 2003/04/03 23:04:06 ca Exp $") #if NETINET || NETINET6 # include @@ -291,11 +291,19 @@ readcf(cfname, safe, e) if (rwp->r_rhs != NULL) { register char **ap; + int args, endtoken; +#if _FFR_EXTRA_MAP_CHECK + int nexttoken; +#endif /* _FFR_EXTRA_MAP_CHECK */ + bool inmap; rwp->r_rhs = copyplist(rwp->r_rhs, true, NULL); /* check no out-of-bounds replacements */ nfuzzy += '0'; + inmap = false; + args = 0; + endtoken = 0; for (ap = rwp->r_rhs; *ap != NULL; ap++) { char *botch; @@ -331,6 +339,65 @@ readcf(cfname, safe, e) botch = "$~"; break; + case CANONHOST: + if (!inmap) + break; + if (++args >= MAX_MAP_ARGS) + syserr("too many arguments for map lookup"); + break; + + case HOSTBEGIN: + endtoken = HOSTEND; + /* FALLTHROUGH */ + case LOOKUPBEGIN: + /* see above... */ + if ((**ap & 0377) == LOOKUPBEGIN) + endtoken = LOOKUPEND; + if (inmap) + syserr("cannot nest map lookups"); + inmap = true; + args = 0; +#if _FFR_EXTRA_MAP_CHECK + if (*(ap + 1) == NULL) + { + syserr("syntax error in map lookup"); + break; + } + nexttoken = **(ap + 1) & 0377; + if (nexttoken == CANONHOST || + nexttoken == CANONUSER || + nexttoken == endtoken) + { + syserr("missing map name for lookup"); + break; + } + if (*(ap + 2) == NULL) + { + syserr("syntax error in map lookup"); + break; + } + if ((**ap & 0377) == HOSTBEGIN) + break; + nexttoken = **(ap + 2) & 0377; + if (nexttoken == CANONHOST || + nexttoken == CANONUSER || + nexttoken == endtoken) + { + syserr("missing key name for lookup"); + break; + } +#endif /* _FFR_EXTRA_MAP_CHECK */ + break; + + case HOSTEND: + case LOOKUPEND: + if ((**ap & 0377) != endtoken) + break; + inmap = false; + endtoken = 0; + break; + + #if 0 /* ** This doesn't work yet as there are maps defined *after* the cf @@ -365,6 +432,8 @@ readcf(cfname, safe, e) syserr("Inappropriate use of %s on RHS", botch); } + if (inmap) + syserr("missing map closing token"); } else { @@ -863,6 +932,7 @@ fileclass(class, filename, fmt, ismap, safe, optional) *p++ = '\0'; cl = p; +#if LDAPMAP if (strcmp(cl, "LDAP") == 0) { int n; @@ -902,6 +972,7 @@ fileclass(class, filename, fmt, ismap, safe, optional) spec = buf; } else +#endif /* LDAPMAP */ { if ((spec = strchr(cl, ':')) == NULL) { @@ -2552,7 +2623,7 @@ setoption(opt, val, safe, sticky, e) break; p = newstr(ep); if (!safe) - cleanstrcpy(p, p, MAXNAME); + cleanstrcpy(p, p, strlen(p) + 1); macdefine(&CurEnv->e_macro, A_TEMP, mid, p); break; @@ -3276,13 +3347,13 @@ setoption(opt, val, safe, sticky, e) else MaxMimeFieldLength = MaxMimeHeaderLength / 2; - if (MaxMimeHeaderLength < 0) + if (MaxMimeHeaderLength <= 0) MaxMimeHeaderLength = 0; else if (MaxMimeHeaderLength < 128) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "Warning: MaxMimeHeaderLength: header length limit set lower than 128\n"); - if (MaxMimeFieldLength < 0) + if (MaxMimeFieldLength <= 0) MaxMimeFieldLength = 0; else if (MaxMimeFieldLength < 40) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, diff --git a/contrib/sendmail/src/recipient.c b/contrib/sendmail/src/recipient.c index 186c8b6..7452897 100644 --- a/contrib/sendmail/src/recipient.c +++ b/contrib/sendmail/src/recipient.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: recipient.c,v 8.330.2.1 2002/08/27 20:21:02 gshapiro Exp $") +SM_RCSID("@(#)$Id: recipient.c,v 8.330.2.2 2003/09/16 19:56:25 ca Exp $") static void includetimeout __P((void)); static ADDRESS *self_reference __P((ADDRESS *)); @@ -169,6 +169,7 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e) SM_NONVOLATILE char delimiter; /* the address delimiter */ SM_NONVOLATILE int naddrs; SM_NONVOLATILE int i; + char *endp; char *oldto = e->e_to; char *SM_NONVOLATILE bufp; char buf[MAXNAME + 1]; @@ -206,6 +207,7 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e) } else bufp = sm_malloc_x(i); + endp = bufp + i; SM_TRY { @@ -217,12 +219,16 @@ sendtolist(list, ctladdr, sendq, aliaslevel, e) auto char *delimptr; register ADDRESS *a; + SM_ASSERT(p < endp); + /* parse the address */ while ((isascii(*p) && isspace(*p)) || *p == ',') p++; + SM_ASSERT(p < endp); a = parseaddr(p, NULLADDR, RF_COPYALL, delimiter, &delimptr, e, true); p = delimptr; + SM_ASSERT(p < endp); if (a == NULL) continue; a->q_next = al; diff --git a/contrib/sendmail/src/sendmail.8 b/contrib/sendmail/src/sendmail.8 index cf473c5..eb67358 100644 --- a/contrib/sendmail/src/sendmail.8 +++ b/contrib/sendmail/src/sendmail.8 @@ -9,9 +9,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Id: sendmail.8,v 8.51 2002/05/24 15:42:13 ca Exp $ +.\" $Id: sendmail.8,v 8.51.2.1 2003/05/20 16:38:15 gshapiro Exp $ .\" -.TH SENDMAIL 8 "$Date: 2002/05/24 15:42:13 $" +.TH SENDMAIL 8 "$Date: 2003/05/20 16:38:15 $" .SH NAME sendmail \- an electronic mail transport agent @@ -295,21 +295,21 @@ Process jobs in queue group called .I name only. .TP -\fB\-q\fR[\fI!\fR]I substr +\fB\-q\fR[\fI!\fR]I\fIsubstr\fR Limit processed jobs to those containing .I substr as a substring of the queue id or not when .I ! is specified. .TP -\fB\-q\fR[\fI!\fR]R substr +\fB\-q\fR[\fI!\fR]R\fIsubstr\fR Limit processed jobs to those containing .I substr as a substring of one of the recipients or not when .I ! is specified. .TP -\fB\-q\fR[\fI!\fR]S substr +\fB\-q\fR[\fI!\fR]S\fIsubstr\fR Limit processed jobs to those containing .I substr as a substring of the sender or not when diff --git a/contrib/sendmail/src/sendmail.h b/contrib/sendmail/src/sendmail.h index 1092398..07e59bc 100644 --- a/contrib/sendmail/src/sendmail.h +++ b/contrib/sendmail/src/sendmail.h @@ -48,7 +48,7 @@ #ifdef _DEFINE # ifndef lint -SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.919.2.17 2003/03/12 22:42:52 gshapiro Exp $"; +SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.919.2.28 2003/09/03 19:58:27 ca Exp $"; # endif /* ! lint */ #endif /* _DEFINE */ @@ -186,6 +186,10 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Id: sendmail.h,v 8.919.2.17 2003/03/12 #endif /* ! INADDR_NONE */ +/* (f)open() modes for queue files */ +# define QF_O_EXTRA 0 + + /* ** An 'argument class' describes the storage allocation status ** of an object pointed to by an argument to a function. @@ -1052,6 +1056,7 @@ struct rewrite #define MATCHZERO CANONHOST #define MAXMATCH 9 /* max params per rewrite */ +#define MAX_MAP_ARGS 10 /* max arguments for map */ /* external <==> internal mapping table */ struct metamac @@ -1696,7 +1701,7 @@ EXTERN int MilterLogLevel; # if _FFR_MILTER_PERDAEMON /* functions */ -extern void setup_daemon_milters __P(()); +extern void setup_daemon_milters __P((void)); # endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ @@ -1962,7 +1967,7 @@ extern void quarantine_queue __P((char *, int)); extern char *queuename __P((ENVELOPE *, int)); extern void queueup __P((ENVELOPE *, bool, bool)); extern bool runqueue __P((bool, bool, bool, bool)); -extern int run_work_group __P((int, int)); +extern bool run_work_group __P((int, int)); extern void set_def_queueval __P((QUEUEGRP *, bool)); extern void setup_queues __P((bool)); extern bool setnewqueue __P((ENVELOPE *)); @@ -2119,6 +2124,19 @@ extern unsigned char tTdvect[100]; /* trace vector */ var = _newval; \ } while (0) +#define _CHECK_RESTART \ + do \ + { \ + if (ShutdownRequest != NULL) \ + shutdown_daemon(); \ + else if (RestartRequest != NULL) \ + restart_daemon(); \ + else if (RestartWorkGroup) \ + restart_marked_work_groups(); \ + } while (0) + +# define CHECK_RESTART _CHECK_RESTART + /* ** Global variables. */ @@ -2423,7 +2441,7 @@ extern void cleanstrcpy __P((char *, char *, int)); extern void cleanup_shm __P((bool)); #endif /* SM_CONF_SHM */ extern void clrdaemon __P((void)); -extern void collect __P((SM_FILE_T *, bool, HDR **, ENVELOPE *)); +extern void collect __P((SM_FILE_T *, bool, HDR **, ENVELOPE *, bool)); extern time_t convtime __P((char *, int)); extern char **copyplist __P((char **, bool, SM_RPOOL_T *)); extern void copy_class __P((int, int)); @@ -2502,7 +2520,7 @@ extern SIGFUNC_DECL reapchild __P((int)); extern int releasesignal __P((int)); extern void resetlimits __P((void)); extern void restart_daemon __P((void)); -extern void restart_marked_work_groups __P(()); +extern void restart_marked_work_groups __P((void)); extern bool rfc822_string __P((char *)); extern bool savemail __P((ENVELOPE *, bool)); extern void seed_random __P((void)); diff --git a/contrib/sendmail/src/sfsasl.c b/contrib/sendmail/src/sfsasl.c index 030ce74..48afb9a 100644 --- a/contrib/sendmail/src/sfsasl.c +++ b/contrib/sendmail/src/sfsasl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -9,7 +9,7 @@ */ #include -SM_RCSID("@(#)$Id: sfsasl.c,v 8.91.2.2 2002/09/12 21:07:50 ca Exp $") +SM_RCSID("@(#)$Id: sfsasl.c,v 8.91.2.5 2003/08/08 17:30:11 ca Exp $") #include #include #include @@ -101,6 +101,11 @@ sasl_open(fp, info, flags, rpool) struct sasl_info *si = (struct sasl_info *) info; so = (struct sasl_obj *) sm_malloc(sizeof(struct sasl_obj)); + if (so == NULL) + { + errno = ENOMEM; + return -1; + } so->fp = si->fp; so->conn = si->conn; @@ -139,6 +144,8 @@ sasl_close(fp) struct sasl_obj *so; so = (struct sasl_obj *) fp->f_cookie; + if (so == NULL) + return 0; if (so->fp != NULL) { sm_io_close(so->fp, SM_TIME_DEFAULT); @@ -192,6 +199,9 @@ sasl_read(fp, buf, size) ** data since it might be larger than the allowed size. ** Therefore we use a static pointer and return portions of it ** if necessary. + ** XXX Note: This function is not thread-safe nor can it be used + ** on more than one file. A correct implementation would store + ** this data in fp->f_cookie. */ # if SASL >= 20000 @@ -286,6 +296,8 @@ sasl_write(fp, buf, size) /* XXX result == 0? */ ret = sm_io_write(so->fp, SM_TIME_DEFAULT, &outbuf[total], outlen); + if (ret <= 0) + return ret; outlen -= ret; total += ret; } @@ -447,6 +459,11 @@ tls_open(fp, info, flags, rpool) struct tls_info *ti = (struct tls_info *) info; so = (struct tls_obj *) sm_malloc(sizeof(struct tls_obj)); + if (so == NULL) + { + errno = ENOMEM; + return -1; + } so->fp = ti->fp; so->con = ti->con; @@ -483,6 +500,8 @@ tls_close(fp) struct tls_obj *so; so = (struct tls_obj *) fp->f_cookie; + if (so == NULL) + return 0; if (so->fp != NULL) { sm_io_close(so->fp, SM_TIME_DEFAULT); @@ -582,7 +601,12 @@ tls_read(fp, buf, size) save_errno = (errno == 0) ? EIO : errno; again = MAX_TLS_IOS; - if (LogLevel > 7) + if (LogLevel > 9) + sm_syslog(LOG_WARNING, NOQID, + "STARTTLS: read error=%s (%d), errno=%d, get_error=%s", + err, r, errno, + ERR_error_string(ERR_get_error(), NULL)); + else if (LogLevel > 7) sm_syslog(LOG_WARNING, NOQID, "STARTTLS: read error=%s (%d)", err, r); errno = save_errno; @@ -674,7 +698,12 @@ tls_write(fp, buf, size) save_errno = (errno == 0) ? EIO : errno; again = MAX_TLS_IOS; - if (LogLevel > 7) + if (LogLevel > 9) + sm_syslog(LOG_WARNING, NOQID, + "STARTTLS: write error=%s (%d), errno=%d, get_error=%s", + err, r, errno, + ERR_error_string(ERR_get_error(), NULL)); + else if (LogLevel > 7) sm_syslog(LOG_WARNING, NOQID, "STARTTLS: write error=%s (%d)", err, r); errno = save_errno; @@ -689,7 +718,7 @@ tls_write(fp, buf, size) ** Parameters: ** fin -- data input source being replaced ** fout -- data output source being replaced -** conn -- the tls connection pointer +** con -- the tls connection pointer ** ** Returns: ** -1 on error diff --git a/contrib/sendmail/src/srvrsmtp.c b/contrib/sendmail/src/srvrsmtp.c index a7f03dd..52d47a1 100644 --- a/contrib/sendmail/src/srvrsmtp.c +++ b/contrib/sendmail/src/srvrsmtp.c @@ -16,7 +16,7 @@ # include #endif /* MILTER */ -SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.829.2.22 2003/02/19 02:45:40 ca Exp $") +SM_RCSID("@(#)$Id: srvrsmtp.c,v 8.829.2.31 2003/07/01 17:30:01 ca Exp $") #if SASL || STARTTLS # include @@ -67,6 +67,38 @@ static void printvrfyaddr __P((ADDRESS *, bool, bool)); static void rcpt_esmtp_args __P((ADDRESS *, char *, char *, ENVELOPE *)); static char *skipword __P((char *volatile, char *)); static void setup_smtpd_io __P((void)); + +#if SASL +# if SASL >= 20000 +static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, + char *_remoteip, char *_localip, + char *_auth_id, sasl_ssf_t *_ext_ssf)); + +# define RESET_SASLCONN \ + result = reset_saslconn(&conn, hostname, remoteip, localip, auth_id, \ + &ext_ssf); \ + if (result != SASL_OK) \ + { \ + /* This is pretty fatal */ \ + goto doquit; \ + } + +# else /* SASL >= 20000 */ +static int reset_saslconn __P((sasl_conn_t **_conn, char *_hostname, + struct sockaddr_in *_saddr_r, + struct sockaddr_in *_saddr_l, + sasl_external_properties_t *_ext_ssf)); +# define RESET_SASLCONN \ + result = reset_saslconn(&conn, hostname, &saddr_r, &saddr_l, &ext_ssf); \ + if (result != SASL_OK) \ + { \ + /* This is pretty fatal */ \ + goto doquit; \ + } + +# endif /* SASL >= 20000 */ +#endif /* SASL */ + extern ENVELOPE BlankEnvelope; #define SKIP_SPACE(s) while (isascii(*s) && isspace(*s)) \ @@ -367,6 +399,7 @@ smtp(nullserver, d_flags, e) volatile unsigned int n_etrn = 0; /* count of ETRN */ volatile unsigned int n_noop = 0; /* count of NOOP/VERB/etc */ volatile unsigned int n_helo = 0; /* count of HELO/EHLO */ + volatile int save_sevenbitinput; bool ok; #if _FFR_BLOCK_PROXIES || _FFR_ADAPTIVE_EOL volatile bool first; @@ -398,10 +431,13 @@ smtp(nullserver, d_flags, e) char *auth_id; const char *out; sasl_ssf_t ext_ssf; + char localip[60], remoteip[60]; # else /* SASL >= 20000 */ char *out; const char *errstr; sasl_external_properties_t ext_ssf; + struct sockaddr_in saddr_l; + struct sockaddr_in saddr_r; # endif /* SASL >= 20000 */ sasl_security_properties_t ssp; sasl_ssf_t *ssf; @@ -431,6 +467,7 @@ smtp(nullserver, d_flags, e) #endif /* PIPELINING */ volatile time_t log_delay = (time_t) 0; + save_sevenbitinput = SevenBitInput; smtp.sm_nrcpts = 0; #if MILTER smtp.sm_milterize = (nullserver == NULL); @@ -568,7 +605,6 @@ smtp(nullserver, d_flags, e) SOCKADDR_LEN_T addrsize; SOCKADDR saddr_l; SOCKADDR saddr_r; - char localip[60], remoteip[60]; addrsize = sizeof(saddr_r); if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD, @@ -607,8 +643,6 @@ smtp(nullserver, d_flags, e) if (in != NULL && strcmp(in, "inet") == 0) { SOCKADDR_LEN_T addrsize; - struct sockaddr_in saddr_l; - struct sockaddr_in saddr_r; addrsize = sizeof(struct sockaddr_in); if (getpeername(sm_io_getinfo(InChannel, SM_IO_WHAT_FD, @@ -678,6 +712,9 @@ smtp(nullserver, d_flags, e) } #endif /* SASL */ +#if STARTTLS +#endif /* STARTTLS */ + #if MILTER if (smtp.sm_milterize) { @@ -766,7 +803,10 @@ smtp(nullserver, d_flags, e) /* If this an smtps connection, start TLS now */ smtps = bitnset(D_SMTPS, d_flags); if (smtps) + { + Errors = 0; goto starttls; + } greeting: @@ -975,6 +1015,7 @@ smtp(nullserver, d_flags, e) { authenticating = SASL_NOT_AUTH; message("501 5.5.2 missing input"); + RESET_SASLCONN; continue; } # endif /* 0 */ @@ -984,6 +1025,7 @@ smtp(nullserver, d_flags, e) /* rfc 2254 4. */ message("501 5.0.0 AUTH aborted"); + RESET_SASLCONN; continue; } @@ -1006,6 +1048,7 @@ smtp(nullserver, d_flags, e) # if SASL >= 20000 sm_free(in); # endif /* SASL >= 20000 */ + RESET_SASLCONN; continue; } @@ -1160,6 +1203,7 @@ smtp(nullserver, d_flags, e) # else /* SASL >= 20000 */ errstr == NULL ? "" : errstr); # endif /* SASL >= 20000 */ + RESET_SASLCONN; authenticating = SASL_NOT_AUTH; } } @@ -1409,6 +1453,7 @@ smtp(nullserver, d_flags, e) # else /* SASL >= 20000 */ errstr); # endif /* SASL >= 20000 */ + RESET_SASLCONN; break; } auth_type = newstr(p); @@ -1436,6 +1481,7 @@ smtp(nullserver, d_flags, e) /* start over? */ authenticating = SASL_NOT_AUTH; + RESET_SASLCONN; } else { @@ -1505,6 +1551,8 @@ smtp(nullserver, d_flags, e) else if ((srv_ssl = SSL_new(srv_ctx)) == NULL) { message("454 4.3.3 TLS not available: error generating SSL handle"); + if (LogLevel > 8) + tlslogerr("server"); # if _FFR_SMTP_SSL goto tls_done; # else /* _FFR_SMTP_SSL */ @@ -1816,7 +1864,7 @@ tlsfail: ok = AllowBogusHELO; break; } - if (strchr("[].-_#", *q) == NULL) + if (strchr("[].-_#:", *q) == NULL) break; } @@ -2124,6 +2172,9 @@ tlsfail: RealUserName); } + /* reset to default value */ + SevenBitInput = save_sevenbitinput; + /* now parse ESMTP arguments */ e->e_msgsize = 0; addr = p; @@ -3003,7 +3054,7 @@ smtp_data(smtp, e) e->e_flags |= EF_NL_NOT_EOL; #endif /* _FFR_ADAPTIVE_EOL */ - collect(InChannel, true, NULL, e); + collect(InChannel, true, NULL, e, true); /* redefine message size */ (void) sm_snprintf(buf, sizeof buf, "%ld", e->e_msgsize); @@ -3962,7 +4013,7 @@ saslmechs(conn, mechlist) # if SASL >= 20000 result = sasl_listmech(conn, NULL, "", " ", "", (const char **) mechlist, - (unsigned int *)&len, (unsigned int *)&num); + (unsigned int *)&len, &num); # else /* SASL >= 20000 */ result = sasl_listmech(conn, "user", /* XXX */ "", " ", "", mechlist, @@ -4314,3 +4365,84 @@ help(topic, e) (void) sm_io_close(hf, SM_TIME_DEFAULT); } + +#if SASL +/* +** RESET_SASLCONN -- reset SASL connection data +** +** Parameters: +** conn -- SASL connection context +** hostname -- host name +** various connection data +** +** Returns: +** SASL result +*/ + +static int +reset_saslconn(sasl_conn_t ** conn, char *hostname, +# if SASL >= 20000 + char *remoteip, char *localip, + char *auth_id, sasl_ssf_t * ext_ssf) +# else /* SASL >= 20000 */ + struct sockaddr_in * saddr_r, struct sockaddr_in * saddr_l, + sasl_external_properties_t * ext_ssf) +# endif /* SASL >= 20000 */ +{ + int result; + + sasl_dispose(conn); +# if SASL >= 20000 + result = sasl_server_new("smtp", hostname, NULL, NULL, NULL, + NULL, 0, conn); +# elif SASL > 10505 + /* use empty realm: only works in SASL > 1.5.5 */ + result = sasl_server_new("smtp", hostname, "", NULL, 0, conn); +# else /* SASL >= 20000 */ + /* use no realm -> realm is set to hostname by SASL lib */ + result = sasl_server_new("smtp", hostname, NULL, NULL, 0, + conn); +# endif /* SASL >= 20000 */ + if (result != SASL_OK) + return result; + +# if SASL >= 20000 +# if NETINET || NETINET6 + if (remoteip != NULL) + result = sasl_setprop(*conn, SASL_IPREMOTEPORT, remoteip); + if (result != SASL_OK) + return result; + + if (localip != NULL) + result = sasl_setprop(*conn, SASL_IPLOCALPORT, localip); + if (result != SASL_OK) + return result; +# endif /* NETINET || NETINET6 */ + + result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf); + if (result != SASL_OK) + return result; + + result = sasl_setprop(*conn, SASL_AUTH_EXTERNAL, auth_id); + if (result != SASL_OK) + return result; +# else /* SASL >= 20000 */ +# if NETINET + if (saddr_r != NULL) + result = sasl_setprop(*conn, SASL_IP_REMOTE, saddr_r); + if (result != SASL_OK) + return result; + + if (saddr_l != NULL) + result = sasl_setprop(*conn, SASL_IP_LOCAL, saddr_l); + if (result != SASL_OK) + return result; +# endif /* NETINET */ + + result = sasl_setprop(*conn, SASL_SSF_EXTERNAL, ext_ssf); + if (result != SASL_OK) + return result; +# endif /* SASL >= 20000 */ + return SASL_OK; +} +#endif /* SASL */ diff --git a/contrib/sendmail/src/stab.c b/contrib/sendmail/src/stab.c index b2ad12d..4d1d2dd 100644 --- a/contrib/sendmail/src/stab.c +++ b/contrib/sendmail/src/stab.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2001, 2003 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: stab.c,v 8.86 2001/12/29 04:27:56 ca Exp $") +SM_RCSID("@(#)$Id: stab.c,v 8.86.4.1 2003/03/31 17:44:24 ca Exp $") /* ** STAB -- manage the symbol table @@ -279,7 +279,7 @@ queueup_macros(class, qfp, e) if (s->s_symtype == ST_CLASS && bitnset(bitidx(class), s->s_class) && - (m = macid(s->s_name)) != '\0' && + (m = macid(s->s_name)) != 0 && (p = macvalue(m, e)) != NULL) { (void) sm_io_fprintf(qfp, SM_TIME_DEFAULT, diff --git a/contrib/sendmail/src/udb.c b/contrib/sendmail/src/udb.c index b5ca724..3f218cc 100644 --- a/contrib/sendmail/src/udb.c +++ b/contrib/sendmail/src/udb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2003 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,9 +14,9 @@ #include #if USERDB -SM_RCSID("@(#)$Id: udb.c,v 8.153.4.4 2002/12/03 17:57:41 gshapiro Exp $ (with USERDB)") +SM_RCSID("@(#)$Id: udb.c,v 8.153.4.5 2003/04/03 16:31:00 ca Exp $ (with USERDB)") #else /* USERDB */ -SM_RCSID("@(#)$Id: udb.c,v 8.153.4.4 2002/12/03 17:57:41 gshapiro Exp $ (without USERDB)") +SM_RCSID("@(#)$Id: udb.c,v 8.153.4.5 2003/04/03 16:31:00 ca Exp $ (without USERDB)") #endif /* USERDB */ #if USERDB @@ -176,7 +176,7 @@ udbexpand(a, sendq, aliaslevel, e) keylen = sm_strlcpyn(keybuf, sizeof keybuf, 2, user, ":maildrop"); /* if name is too long, assume it won't match */ - if (keylen > sizeof keybuf) + if (keylen >= sizeof keybuf) return EX_OK; /* build actual database key */ diff --git a/contrib/sendmail/src/usersmtp.c b/contrib/sendmail/src/usersmtp.c index 59a23e9..e760361 100644 --- a/contrib/sendmail/src/usersmtp.c +++ b/contrib/sendmail/src/usersmtp.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: usersmtp.c,v 8.437.2.9 2003/03/15 23:57:52 gshapiro Exp $") +SM_RCSID("@(#)$Id: usersmtp.c,v 8.437.2.10 2003/05/05 23:51:47 ca Exp $") #include @@ -1088,7 +1088,7 @@ getsecret(conn, context, id, psecret) len + 1); if (*psecret == NULL) return SASL_FAIL; - (void) sm_strlcpy((*psecret)->data, authpass, len + 1); + (void) sm_strlcpy((char *) (*psecret)->data, authpass, len + 1); (*psecret)->len = (unsigned long) len; return SASL_OK; } diff --git a/contrib/sendmail/src/util.c b/contrib/sendmail/src/util.c index 27db22f..dc0b1e4 100644 --- a/contrib/sendmail/src/util.c +++ b/contrib/sendmail/src/util.c @@ -13,7 +13,7 @@ #include -SM_RCSID("@(#)$Id: util.c,v 8.363.2.5 2002/12/12 22:50:41 ca Exp $") +SM_RCSID("@(#)$Id: util.c,v 8.363.2.7 2003/06/02 03:25:39 gshapiro Exp $") #include #include @@ -390,7 +390,7 @@ truncate_at_delim(str, len, delim) *p = '\0'; if (p - str + 4 < len) { - *p++ = ':'; + *p++ = (char) delim; *p = '\0'; (void) sm_strlcat(str, "...", len); return; @@ -2414,7 +2414,7 @@ str2prt(s) ** false -- otherwise */ -int +bool path_is_dir(pathname, createflag) char *pathname; bool createflag; diff --git a/contrib/sendmail/src/version.c b/contrib/sendmail/src/version.c index da877d7..9f7eb12 100644 --- a/contrib/sendmail/src/version.c +++ b/contrib/sendmail/src/version.c @@ -13,6 +13,6 @@ #include -SM_RCSID("@(#)$Id: version.c,v 8.104.2.15 2003/03/19 21:19:53 ca Exp $") +SM_RCSID("@(#)$Id: version.c,v 8.104.2.22 2003/09/16 20:02:04 ca Exp $") -char Version[] = "8.12.9"; +char Version[] = "8.12.10"; -- cgit v1.1