diff options
author | peter <peter@FreeBSD.org> | 1996-11-18 02:26:51 +0000 |
---|---|---|
committer | peter <peter@FreeBSD.org> | 1996-11-18 02:26:51 +0000 |
commit | 8e0d5faaa77159b266e4ab922edf43a79f52e0c0 (patch) | |
tree | dc9912f7544cf0388bda667e714af24cd2fc24f8 | |
parent | c25f71c7e501b060767f7d67d9448d649a801c95 (diff) | |
download | FreeBSD-src-8e0d5faaa77159b266e4ab922edf43a79f52e0c0.zip FreeBSD-src-8e0d5faaa77159b266e4ab922edf43a79f52e0c0.tar.gz |
Import sendmail-8.8.3 - this contains the official fix to replace the
previous workaround patch that I used.
Obtained from: Eric Allman <eric@sendmail.org>
33 files changed, 1706 insertions, 660 deletions
diff --git a/usr.sbin/sendmail/RELEASE_NOTES b/usr.sbin/sendmail/RELEASE_NOTES index 0eb9e61..203b61a 100644 --- a/usr.sbin/sendmail/RELEASE_NOTES +++ b/usr.sbin/sendmail/RELEASE_NOTES @@ -1,12 +1,125 @@ SENDMAIL RELEASE NOTES - @(#)RELEASE_NOTES 8.8.2.1 (Berkeley) 10/18/96 + @(#)RELEASE_NOTES 8.8.3.2 (Berkeley) 11/16/96 This listing shows the version of the sendmail binary, the version of the sendmail configuration files, the date of release, and a summary of the changes in that release. -8.8.2/8.8.2 96/11/18 +8.8.3/8.8.3 96/11/17 + SECURITY: it was possible to get a root shell by lying to sendmail + about argv[0] and then sending it a signal. Problem noted + by Leshka Zakharoff <leshka@leshka.chuvashia.su> on the + best-of-security list. + Log sendmail binary version number in "Warning: .cf version level + (%d) exceeds program functionality (%d) message" -- this + should make it clearer to people that they are running + the wrong binary. + Fix a problem that occurs when you open an SMTP connection and then + do one or more ETRN commands followed by a MAIL command; at + the end of the DATA phase sendmail would incorrectly report + "451 SMTP-MAIL: lost child: No child processes". Problem + noted by Eric Bishop of Virginia Tech. + When doing text-based host canonification (typically /etc/hosts + lookup), a null host name would match any /etc/hosts entry + with space at the end of the line. Problem noted by Steve + Hubert of the University of Washington, Seattle. + 7 to 8 bit BASE64 MIME conversions could duplicate bits of text. + Problem reported by Tom Smith of Digital Equipment Corp. + Increase the size of the DNS answer buffer -- the standard UDP packet + size PACKETSZ (512) is not sufficient for some nameserver + answers containing very many resource records. The resolver + may also switch to TCP and retry if it detects UDP packet + overflow. Also, allow for the fact that the resolver + routines res_query and res_search return the size of the + *un*truncated answer in case the supplied answer buffer it + not big enough to accommodate the entire answer. Patch from + Eric Wassenaar. + Improvements to MaxDaemonChildren code. If you think you have too + many children, probe the ones you have to verify that they + are still around. Suggested by Jared Mauch of CICnet, Inc. + Also, do this probe before growing the vector of children + pids; this previously caused the vector to grow indefinitely + due to a race condition. Problem reported by Kyle Jones of + UUNET. + On some architectures, <db.h> (from the Berkeley DB library) defines + O_EXLOCK to zero; this fools the map compilation code into + thinking that it can avoid race conditions by locking on open. + Change it to check for O_EXLOCK non-zero. Problem noted by + Leif Erlingsson of Data Lege. + Always call res_init() on startup (if compiled in, of course) to + allow the sendmail.cf file to tweak resolver flags; without + it, flag tweaks in ResolverOptions are ignored. Patch from + Andrew Sun of Merrill Lynch. + Improvements to host status printing code. Suggested by Steve Hubert + of the University of Washington, Seattle. + Change MinQueueAge option processing to do the check for the job age + when reading the queue file, rather than at the end; this + avoids parsing the addresses, which can do DNS lookups. + Problem noted by John Beck of InReference, Inc. + When MIME was being 7->8 bit decoded, "From " lines weren't being + properly escaped. Problem noted by Peter Nilsson of the + University of Linkoping. + In some cases, sendmail would retain root permissions during queue + runs even if RunAsUser was set. Problem noted by Mark + Thomas of Mark G. Thomas Consulting. + If the F=l flag was set on an SMTP mailer to indicate that it is + actually local delivery, and NOTIFY=SUCCESS is specified in + the envelope, and the receiving SMTP server speaks DSN, then + the DSN would be both generated locally and propogated to the + other end. + The U= mailer field didn't correctly extract the group id if the + user id was numeric. Problem noted by Kenneth Herron of + MCI Telecommunications Communications. + If a message exceeded the fixed maximum size on input, the body of + the message was included in the bounce. Note that this did + not occur if it exceeded the maximum _output_ size. Problem + reported by Kyle Jones of UUNET. + PORTABILITY FIXES: + AIX4: 4.1 does't have a working setreuid(2); change the + AIX4 defines to use seteuid(2) instead, which + works on 4.1 as well as 4.2. Problem noted by + Håkan Lindholm of interAF, Sweden. + AIX4: use tzname[] vector to determine time zone name. + Patch from NAKAMURA Motonori of Kyoto University. + MkLinux: add Makefile.Linux.ppc and OSTYPE(mklinux) support. + Contributed by Paul DeBois <dubois@primate.wisc.edu>. + Solaris: kstat(3k) support for retrieving the load average. + This adds the LA_KSTAT definition for LA_TYPE. + The outline of the implementation was contributed + by Michael Tokarev of Telecom Service, JSC, Moscow. + HP-UX 10.0 gripes about the (perfectly legal!) forward + declaration of struct rusage at the top of conf.h; + change it to only be included if you are using gcc, + which is apparently the only compiler that requires + it in the first place. Problem noted by Jeff + Earickson of Colby College. + IRIX: don't default to using gcc. IRIX is a civilized + operating system that comes with a decent compiler + by default. Problem noted by Barry Bouwsma and + Kari Hurtta. + CONFIG: specify F=9 as default in FEATURE(local_procmail) for + consistency with other local mailers. Inconsistency + pointed out by Teddy Hogeborn <teddy@fukt.hk-r.se>. + CONFIG: if the "limited best mx" feature is used (to reduce DNS + overhead) as part of the bestmx_is_local feature, the + domain part was dropped from the name. Patch from Steve + Hubert of the University of Washington, Seattle. + CONFIG: catch addresses of the form "user@.dom.ain"; these could + end up being translated to the null host name, which would + return any entry in /etc/hosts that had a space at the end + of the line. Problem noted by Steve Hubert of the + University of Washington, Seattle. + CONFIG: add OSTYPE(aix4). From Michael Sofka of Rensselaer + Polytechnic Institute. + MAKEMAP: tweak hash and btree parameters for better performance. + Patch from Matt Dillon of Best Internet Communications. + NEW FILES: + src/Makefiles/Makefile.Linux.ppc + cf/ostype/aix4.m4 + cf/ostype/mklinux.m4 + +8.8.2/8.8.2 96/10/18 SECURITY: fix a botch in the 7-bit MIME patch; the previous patch changed the code but didn't fix the problem. PORTABILITY FIXES: @@ -1089,7 +1202,7 @@ summary of the changes in that release. Syntax errors such as unbalanced parentheses in the configuration file could be omitted if you had "Oem" prior to the syntax error in the config file. Change to always print - the error message. It was especially wierd because it + the error message. It was especially weird because it would cause a "warning" message to be sent to the Postmaster for every message sent (but with no transcript). Problem noted by Gregory Paris of Motorola. @@ -1823,7 +1936,7 @@ summary of the changes in that release. only works on adjacent preferences, so an MX list that had A=5, B=10, A=15 would leave both As, but one that had A=5, A=10, B=15 would reduce to A, B. This is intentional, - just in case there is something wierd I haven't thought of. + just in case there is something weird I haven't thought of. Suggested by Barry Shein of Software Tool & Die. SECURITY: .forward files cannot be symbolic links. If they are, a bad guy can read your private files. @@ -2420,7 +2533,7 @@ summary of the changes in that release. fixed by Michael Corrigan and Christophe Wolfhugel. 8.6.7/8.6.6 94/03/14 - SECURITY: it was possible to get root access by using wierd + SECURITY: it was possible to get root access by using weird values to the -d flag. Thanks to Alain Durand of INRIA for forwarding me the notice from the bugtraq list. @@ -2558,7 +2671,7 @@ summary of the changes in that release. CNAME loops caused an error message to be generated, but also re-queued the message. Changed to just re-queue the message (it's really hard to just bounce it because - of the wierd way the name server works in the presence + of the weird way the name server works in the presence of CNAME loops). Problem noted by James M.R.Matheson of Cambridge University. Avoid giving ``warning: foo owned process doing -bs'' messages @@ -2823,7 +2936,7 @@ summary of the changes in that release. Make sure that route-addrs always have <angle brackets> around them in non-SMTP envelopes (SMTP envelopes already do this properly). - Avoid wierd headers on unbalanced punctuation of the form: + Avoid weird headers on unbalanced punctuation of the form: ``Joe User <user)'' -- this caused reference to the null macro. Fix from Rick McCarty of IO.COM. Fix a problem that caused an alias "user: user@local.host" to @@ -3488,7 +3601,7 @@ summary of the changes in that release. the "to" address). Problem noted by John Myers. Fix dfopen to return NULL if the open failed; I was depending on fdopen(-1) returning NULL, which isn't the case. This - isn't serious, but does result in wierd error diagnoses. + isn't serious, but does result in weird error diagnoses. From Michael Corrigan. CONFIG: add UUCP_MAX_SIZE M4 macro to set the maximum size of messages sent through UUCP-family mailers. Suggested @@ -3524,7 +3637,7 @@ summary of the changes in that release. Changes from Eric Wassenaar. Open /dev/null for the transcript if the create of the xf file failed; this avoids at least one possible null pointer - reference in very wierd cases. From Eric Wassenaar. + reference in very weird cases. From Eric Wassenaar. Clean up statistics gathering; it was over-reporting because of forks. From Eric Wassenaar. Fix problem that causes old Return-Path: line to override new @@ -3775,7 +3888,7 @@ summary of the changes in that release. PRALIASES: support for printing NEWDB databases. From Michael J. Corrigan of U.C. San Diego. CONFIG: don't pass pseudo-domains to $[ ... $] (if you have - a wildcard MX it can have wierd results). From + a wildcard MX it can have weird results). From Christophe Wolfhugel. CONFIG: dot terminate relay hostnames in S0. From Christophe Wolfhugel. @@ -3888,7 +4001,7 @@ summary of the changes in that release. Don't try to flock non-regular files when mailing to a file. In particular, this was a problem if you tried to send to /dev/null. - Fix a wierd bug that can cause senders to be queued as + Fix a weird bug that can cause senders to be queued as recipients if the name server is down when the mail is initially sent. This hack just ignores sender deletion (essentially, it sets the MeToo flag) if there @@ -4222,7 +4335,7 @@ summary of the changes in that release. file to have an F line, and the format of the T option to accept take the format "return/warn" (both intervals). Don't force all local names to lower case -- this was left over - from the wierd handling of case mapping on aliases. It + from the weird handling of case mapping on aliases. It is now driven (as expected) by the "u" mailer flag. Problem noted by P{r Emanuelsson. Fix problem that caused headers on returned email to be trashed; @@ -4325,7 +4438,7 @@ summary of the changes in that release. mailer. Additional debug printing in getcanonname (show query type). Don't add the e_fromdomain on sender addresses -- this interacts - wierdly with the owner- code. + weirdly with the owner- code. Improve delivery logging to not log obvious or meaningless stuff. Include numeric IP address in Received: lines per RFC 1123 section 5.2.8. @@ -4407,7 +4520,7 @@ summary of the changes in that release. Config extensions for Sam Leffler's FlexFAX software. 6.31/6.10 93/02/28 - Fix some more bugs in alias owner code -- there were some wierd + Fix some more bugs in alias owner code -- there were some weird cases where an error in a non-aliased name would override the return info in an aliased name with an owner. Changes from WIDE Project, forwarded to me by Motonori Nakamura: diff --git a/usr.sbin/sendmail/cf/README b/usr.sbin/sendmail/cf/README index de57253..d71ffd2 100644 --- a/usr.sbin/sendmail/cf/README +++ b/usr.sbin/sendmail/cf/README @@ -4,7 +4,7 @@ Eric Allman <eric@CS.Berkeley.EDU> - @(#)README 8.106 (Berkeley) 10/12/96 + @(#)README 8.108 (Berkeley) 11/16/96 This document describes the sendmail configuration files being used @@ -128,7 +128,7 @@ Let's examine a typical .mc file: divert(0) The divert(-1) will delete the crud in the resulting output file. -The copyright notice can be replace by whatever your lawyers require; +The copyright notice can be replaced by whatever your lawyers require; our lawyers require the one that I've included in my files. A copyleft is a copyright by another name. The divert(0) restores regular output. @@ -587,8 +587,10 @@ uucpdomain Similar feature for UUCP hosts. The default map definition always_add_domain Include the local host domain even on locally delivered - mail. Normally it is not added unless it is already - present. + mail. Normally it is not added on unqualified names. + However, if you use a shared message store but do not use + the same user name space everywhere, you may need the host + name on local names. allmasquerade If masquerading is enabled (using MASQUERADE_AS), this feature will cause recipient addresses to also masquerade @@ -940,8 +942,8 @@ You can have your host masquerade as another using MASQUERADE_AS(host.domain) This causes mail being sent to be labeled as coming from the -indicated domain, rather than $j. One normally masquerades as one -of one's own subdomains (for example, it's unlikely that I would +indicated host.domain, rather than $j. One normally masquerades as +one of one's own subdomains (for example, it's unlikely that I would choose to masquerade as an MIT site). This behaviour is modified by a plethora of FEATUREs; in particular, see masquerade_envelope, allmasquerade, limited_masquerade, and masquerade_entire_domain. @@ -1217,6 +1219,11 @@ Plussed users If that is not found, the alias "root+*" will be tried, then "root". +LDAP + For notes on use LDAP in sendmail, see + http://www-leland.stanford.edu/~bbense/Inst.html + + +----------------+ | SECURITY NOTES | diff --git a/usr.sbin/sendmail/cf/cf/Makefile.dist b/usr.sbin/sendmail/cf/cf/Makefile.dist index 074529e..7dc55d9 100644 --- a/usr.sbin/sendmail/cf/cf/Makefile.dist +++ b/usr.sbin/sendmail/cf/cf/Makefile.dist @@ -1,10 +1,19 @@ # # Makefile for configuration files. # -# @(#)Makefile.dist 8.1 (Berkeley) 8/25/93 +# @(#)Makefile.dist 8.9 (Berkeley) 9/12/95 +# + +# +# Configuration files are created using "m4 file.mc > file.cf"; +# this may be easier than tweaking the Makefile. You do need to +# have a fairly modern M4 available (GNU m4 works). On SunOS, use +# /usr/5bin/m4. +# M4= m4 #M4= /usr/src/usr.bin/m4/obj/m4 +CFDIR= .. CHMOD= chmod ROMODE= 444 RM= rm -f @@ -13,18 +22,16 @@ RM= rm -f .mc.cf: $(RM) $@ - $(M4) $*.mc > $@ + $(M4) ${CFDIR}/m4/cf.m4 $*.mc > $@ $(CHMOD) $(ROMODE) $@ -ALL= cs-hidden.cf cs-exposed.cf \ - hpux-cs-exposed.cf hpux-cs-hidden.cf \ - sunos3.5-cs-exposed.cf sunos3.5-cs-hidden.cf \ - sunos4.1-cs-exposed.cf sunos4.1-cs-hidden.cf \ - ultrix4.1-cs-exposed.cf ultrix4.1-cs-hidden.cf \ - mail.cs.cf mail.eecs.cf ucbvax.cf vangogh.cf \ - chez.cf knecht.cf cogsci.cf alpha.cf s2k.cf auspex.cf \ - python.cf \ - clientproto.cf tcpproto.cf uucpproto.cf +ALL= generic-bsd4.4.cf generic-hpux9.cf generic-hpux10.cf \ + generic-osf1.cf generic-solaris2.cf \ + cs-hpux9.cf cs-osf1.cf cs-solaris2.cf \ + cs-sunos4.1.cf cs-ultrix4.cf \ + s2k-osf1.cf s2k-ultrix4.cf \ + chez.cs.cf huginn.cs.cf mail.cs.cf mail.eecs.cf mailspool.cs.cf \ + python.cs.cf ucbarpa.cf ucbvax.cf vangogh.cs.cf all: $(ALL) @@ -35,51 +42,67 @@ depend install: # this is overkill, but.... M4FILES=\ - ../domain/Berkeley.m4 \ - ../domain/cs.exposed.m4 \ - ../domain/cs.hidden.m4 \ - ../domain/eecs.hidden.m4 \ - ../domain/s2k.m4 \ - ../feature/allmasquerade.m4 \ - ../feature/always_add_domain.m4 \ - ../feature/bitdomain.m4 \ - ../feature/domaintable.m4 \ - ../feature/mailertable.m4 \ - ../feature/nocanonify.m4 \ - ../feature/nodns.m4 \ - ../feature/notsticky.m4 \ - ../feature/nouucp.m4 \ - ../feature/nullclient.m4 \ - ../feature/redirect.m4 \ - ../feature/use_cw_file.m4 \ - ../feature/uucpdomain.m4 \ - ../hack/cssubdomain.m4 \ - ../m4/cf.m4 \ - ../m4/nullrelay.m4 \ - ../m4/proto.m4 \ - ../m4/version.m4 \ - ../mailer/fax.m4 \ - ../mailer/local.m4 \ - ../mailer/smtp.m4 \ - ../mailer/usenet.m4 \ - ../mailer/uucp.m4 \ - ../ostype/aix3.m4 \ - ../ostype/bsd4.3.m4 \ - ../ostype/bsd4.4.m4 \ - ../ostype/hpux.m4 \ - ../ostype/irix.m4 \ - ../ostype/linux.m4 \ - ../ostype/nextstep.m4 \ - ../ostype/osf1.m4 \ - ../ostype/riscos4.5.m4 \ - ../ostype/solaris2.m4 \ - ../ostype/sunos3.5.m4 \ - ../ostype/sunos4.1.m4 \ - ../ostype/svr4.m4 \ - ../ostype/ultrix4.1.m4 \ - ../siteconfig/uucp.cogsci.m4 \ - ../siteconfig/uucp.old.arpa.m4 \ - ../siteconfig/uucp.ucbarpa.m4 \ - ../siteconfig/uucp.ucbvax.m4 \ + ${CFDIR}/domain/Berkeley.EDU.m4 \ + ${CFDIR}/domain/CS.Berkeley.EDU.m4 \ + ${CFDIR}/domain/EECS.Berkeley.EDU.m4 \ + ${CFDIR}/domain/S2K.Berkeley.EDU.m4 \ + ${CFDIR}/feature/allmasquerade.m4 \ + ${CFDIR}/feature/always_add_domain.m4 \ + ${CFDIR}/feature/bestmx_is_local.m4 \ + ${CFDIR}/feature/bitdomain.m4 \ + ${CFDIR}/feature/domaintable.m4 \ + ${CFDIR}/feature/local_procmail.m4 \ + ${CFDIR}/feature/mailertable.m4 \ + ${CFDIR}/feature/nocanonify.m4 \ + ${CFDIR}/feature/nodns.m4 \ + ${CFDIR}/feature/notsticky.m4 \ + ${CFDIR}/feature/nouucp.m4 \ + ${CFDIR}/feature/nullclient.m4 \ + ${CFDIR}/feature/redirect.m4 \ + ${CFDIR}/feature/smrsh.m4 \ + ${CFDIR}/feature/stickyhost.m4 \ + ${CFDIR}/feature/use_cw_file.m4 \ + ${CFDIR}/feature/uucpdomain.m4 \ + ${CFDIR}/hack/cssubdomain.m4 \ + ${CFDIR}/m4/cf.m4 \ + ${CFDIR}/m4/nullrelay.m4 \ + ${CFDIR}/m4/proto.m4 \ + ${CFDIR}/m4/version.m4 \ + ${CFDIR}/mailer/cyrus.m4 \ + ${CFDIR}/mailer/fax.m4 \ + ${CFDIR}/mailer/local.m4 \ + ${CFDIR}/mailer/mail11.m4 \ + ${CFDIR}/mailer/pop.m4 \ + ${CFDIR}/mailer/procmail.m4 \ + ${CFDIR}/mailer/smtp.m4 \ + ${CFDIR}/mailer/usenet.m4 \ + ${CFDIR}/mailer/uucp.m4 \ + ${CFDIR}/ostype/aix3.m4 \ + ${CFDIR}/ostype/amdahl-uts.m4 \ + ${CFDIR}/ostype/aux.m4 \ + ${CFDIR}/ostype/bsd4.3.m4 \ + ${CFDIR}/ostype/bsd4.4.m4 \ + ${CFDIR}/ostype/bsdi1.0.m4 \ + ${CFDIR}/ostype/dgux.m4 \ + ${CFDIR}/ostype/domainos.m4 \ + ${CFDIR}/ostype/dynix3.2.m4 \ + ${CFDIR}/ostype/hpux9.m4 \ + ${CFDIR}/ostype/irix4.m4 \ + ${CFDIR}/ostype/irix5.m4 \ + ${CFDIR}/ostype/linux.m4 \ + ${CFDIR}/ostype/nextstep.m4 \ + ${CFDIR}/ostype/osf1.m4 \ + ${CFDIR}/ostype/ptx2.m4 \ + ${CFDIR}/ostype/riscos4.5.m4 \ + ${CFDIR}/ostype/sco3.2.m4 \ + ${CFDIR}/ostype/solaris2.m4 \ + ${CFDIR}/ostype/sunos3.5.m4 \ + ${CFDIR}/ostype/sunos4.1.m4 \ + ${CFDIR}/ostype/svr4.m4 \ + ${CFDIR}/ostype/ultrix4.m4 \ + ${CFDIR}/siteconfig/uucp.cogsci.m4 \ + ${CFDIR}/siteconfig/uucp.old.arpa.m4 \ + ${CFDIR}/siteconfig/uucp.ucbarpa.m4 \ + ${CFDIR}/siteconfig/uucp.ucbvax.m4 \ $(ALL): $(M4FILES) diff --git a/usr.sbin/sendmail/cf/feature/bestmx_is_local.m4 b/usr.sbin/sendmail/cf/feature/bestmx_is_local.m4 index 80c0ebb..1b96aa1 100644 --- a/usr.sbin/sendmail/cf/feature/bestmx_is_local.m4 +++ b/usr.sbin/sendmail/cf/feature/bestmx_is_local.m4 @@ -34,7 +34,7 @@ divert(-1) # divert(0) -VERSIONID(`@(#)bestmx_is_local.m4 8.3 (Berkeley) 5/11/96') +VERSIONID(`@(#)bestmx_is_local.m4 8.4 (Berkeley) 10/23/96') divert(-1) LOCAL_CONFIG @@ -60,7 +60,7 @@ LOCAL_NET_CONFIG ifelse(_ARG_, `', `', `#')dnl unlimited bestmx R$* < @ $* > $* $: $1 < @ $2 @@ $(bestmx $2 $) > $3 ifelse(_ARG_, `', `#', `')dnl limit bestmx to $=B -R$* < @ $* $=B > $* $: $1 < @ $2 @@ $(bestmx $2 $3 $) > $4 +R$* < @ $* $=B > $* $: $1 < @ $2 $3 @@ $(bestmx $2 $3 $) > $4 R$* $=O $* < @ $* @@ $=w . > $* $@ $>97 $1 $2 $3 R$* < @ $* @@ $=w . > $* $#local $: $1 R$* < @ $* @@ $* > $* $: $1 < @ $2 > $4 diff --git a/usr.sbin/sendmail/cf/feature/local_procmail.m4 b/usr.sbin/sendmail/cf/feature/local_procmail.m4 index ba194bd..db0cc87 100644 --- a/usr.sbin/sendmail/cf/feature/local_procmail.m4 +++ b/usr.sbin/sendmail/cf/feature/local_procmail.m4 @@ -34,7 +34,7 @@ divert(-1) # divert(0) -VERSIONID(`@(#)local_procmail.m4 8.5 (Berkeley) 2/12/96') +VERSIONID(`@(#)local_procmail.m4 8.6 (Berkeley) 10/20/96') divert(-1) define(`LOCAL_MAILER_PATH', @@ -43,5 +43,5 @@ define(`LOCAL_MAILER_PATH', PROCMAIL_MAILER_PATH, `/usr/local/bin/procmail'), _ARG_)) -define(`LOCAL_MAILER_FLAGS', `SPfhn') +define(`LOCAL_MAILER_FLAGS', `SPfhn9') define(`LOCAL_MAILER_ARGS', `procmail -Y -a $h -d $u') diff --git a/usr.sbin/sendmail/cf/m4/proto.m4 b/usr.sbin/sendmail/cf/m4/proto.m4 index 1dc457c..474dc7d 100644 --- a/usr.sbin/sendmail/cf/m4/proto.m4 +++ b/usr.sbin/sendmail/cf/m4/proto.m4 @@ -34,7 +34,7 @@ divert(-1) # divert(0) -VERSIONID(`@(#)proto.m4 8.134 (Berkeley) 10/13/96') +VERSIONID(`@(#)proto.m4 8.135 (Berkeley) 10/26/96') MAILER(local)dnl @@ -662,7 +662,7 @@ R$* $: <> $1 R<> $* < @ [ $+ ] > $* $1 < @ [ $2 ] > $3 R<> $* <$* : $* > $* $#error $@ 5.1.1 $: "colon illegal in host name part" R<> $* $1 -R$* < @ . > $* $#error $@ 5.1.2 $: "invalid host name" +R$* < @ . $* > $* $#error $@ 5.1.2 $: "invalid host name" ifdef(`_MAILER_smtp_', `# handle numeric address spec diff --git a/usr.sbin/sendmail/cf/m4/version.m4 b/usr.sbin/sendmail/cf/m4/version.m4 index db8f365..0fe40a9 100644 --- a/usr.sbin/sendmail/cf/m4/version.m4 +++ b/usr.sbin/sendmail/cf/m4/version.m4 @@ -32,8 +32,8 @@ divert(-1) # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -VERSIONID(`@(#)version.m4 8.8.2.1 (Berkeley) 10/18/96') +VERSIONID(`@(#)version.m4 8.8.3.1 (Berkeley) 11/16/96') # divert(0) # Configuration version number -DZ8.8.2`'ifdef(`confCF_VERSION', `/confCF_VERSION') +DZ8.8.3`'ifdef(`confCF_VERSION', `/confCF_VERSION') diff --git a/usr.sbin/sendmail/cf/ostype/aix4.m4 b/usr.sbin/sendmail/cf/ostype/aix4.m4 new file mode 100644 index 0000000..4dc3387 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/aix4.m4 @@ -0,0 +1,41 @@ +divert(-1) +# +# Copyright (c) 1996 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# + +divert(0) +VERSIONID(`@(#)aix4.m4 8.1 (Berkeley) 11/13/96') +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /bin/bellmail)')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', mail -F $g $u)')dnl +ifdef(`LOCAL_MAILER_FLAGS',, `define(`LOCAL_MAILER_FLAGS', `mn9')')dnl +define(`confTIME_ZONE', `USE_TZ')dnl diff --git a/usr.sbin/sendmail/cf/ostype/mklinux.m4 b/usr.sbin/sendmail/cf/ostype/mklinux.m4 new file mode 100644 index 0000000..1da5928 --- /dev/null +++ b/usr.sbin/sendmail/cf/ostype/mklinux.m4 @@ -0,0 +1,44 @@ +divert(-1) +# +# Copyright (c) 1983 Eric P. Allman +# Copyright (c) 1988, 1993 +# The Regents of the University of California. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. All advertising materials mentioning features or use of this software +# must display the following acknowledgement: +# This product includes software developed by the University of +# California, Berkeley and its contributors. +# 4. Neither the name of the University nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# MkLinux support contributed by Paul DeBois <dubois@primate.wisc.edu> +# + +divert(0) +VERSIONID(`@(#)mklinux.m4 8.1 (Berkeley) 10/30/96') +ifdef(`STATUS_FILE',, + `define(`STATUS_FILE', /var/log/sendmail.st)') +ifdef(`PROCMAIL_MAILER_PATH',, + define(`PROCMAIL_MAILER_PATH', `/usr/bin/procmail')) +FEATURE(local_procmail) diff --git a/usr.sbin/sendmail/contrib/mailprio b/usr.sbin/sendmail/contrib/mailprio index cdbc3b0..58feba7 100644 --- a/usr.sbin/sendmail/contrib/mailprio +++ b/usr.sbin/sendmail/contrib/mailprio @@ -1,280 +1,540 @@ -Message-Id: <199412081919.NAA23234@austin.BSDI.COM> -To: Eric Allman <eric@cs.berkeley.edu> -Subject: Re: sorting mailings lists with fastest delivery users first -In-reply-to: Your message of Thu, 08 Dec 1994 06:08:33 PST. -References: <199412081408.GAA06210@mastodon.CS.Berkeley.EDU> -From: Tony Sanders <sanders@bsdi.com> +Received: from austin.bsdi.com (root{9l9gVDC7v8t3dlv0OtXTlby6X1zBWd56}@austin.BSDI.COM [205.230.224.49]) by knecht.Sendmail.ORG (8.8.2/8.8.2) with ESMTP id JAA05023 for <eric@sendmail.org>; Thu, 31 Oct 1996 09:29:47 -0800 (PST) +Received: from austin.bsdi.com (localhost [127.0.0.1]) by austin.bsdi.com (8.7.4/8.7.3) with ESMTP id KAA19250; Thu, 31 Oct 1996 10:28:18 -0700 (MST) +Message-Id: <199610311728.KAA19250@austin.bsdi.com> +To: Eric Allman <eric@sendmail.org> +cc: marc@xfree86.org +Subject: Updated mailprio_0_93.shar +From: Tony Sanders <sanders@earth.com> Organization: Berkeley Software Design, Inc. -Date: Thu, 08 Dec 1994 13:19:39 -0600 -Sender: sanders@austin.BSDI.COM +Date: Thu, 31 Oct 1996 10:28:14 -0700 +Sender: sanders@austin.bsdi.com -Eric Allman writes: -> Nope, that's a new one, so far as I know. Any interest in -> contributing it? For small lists it seems overkill, but for -> large lists it could be a major win. +Eric, please update contrib/mailprio in the sendmail distribution +to this version at your convenience. Thanks. -Sure, I will contribute it; after I sent you mail last night I went ahead -and finished up what I thought needed to be done. I would like to get -some feedback from you on a few items, if you have time. +I've also made this available in: + ftp://ftp.earth.com/pub/postmaster/ -There are two programs, mailprio_mkdb and mailprio (source below). +mailprio_0_93.shar follows... -mailprio_mkdb reads maillog files and creates a DB file of address vs. -delay. I'm not too happy with how it does the averages right now but this -is just a quick hack. However, it should at least order sites that take -days vs. those that deliver on the first pass through. One thing that -would make this information a lot more accurate is if sendmail could log -a "transaction delay" (on failures also), as well as total delivery delay. -Perhaps, as an option, it could maintain the DB file itself? - -mailprio then simply reads a list of addresses from stdin (the mailing -list), and tries to prioritize them according to the info the database. -It collects comment lines and other junk at the top of the file; all -mailprio does is reorder lines, the actual text of the file should -be unchanged to the extent that you can verify it with: - sort sorted_list > checkit; sort mailing-list | diff - checkit -Users with no delay information are put next. The prioritized list is last. -Of course, this function could also be built-into sendmail (eventually). - -Putting "new account" info at the top with the current averaging function -probably adversly affects the prioritized list (at least in the short -term), but putting it at the bottom would not really give the new accounts -a fair chance. I suspect this isn't that big of a problem. I'm running -this here on a list with 461 accounts and about 10 messages per day so -I'll see how it goes. I'll keep some stats on delay times and see what -happens. - -Another thing that would help this situation, is if sendmail had the queue -ordered by site (but you already know this). If you ever get to do per -site queuing you should consider "blocking" a queue for some short period -of time if a connection fails to that site [sendmail does this inside a -single process on a per account basis now right?]; this would allow multiple -sendmails to quickly skip over those sites for people like me that run: - - for i in 1 2 3 4 5 6 7 8 ; do daemon sendmail -q; done - -to flush a queue that has gotten behind. You could also do this inside -sendmail with a parallelism option (when it is time to run the queue, how -many processes to start). - -#! /bin/sh -# This is a shell archive. Remove anything before this line, then unpack -# it by saving it into a file and typing "sh file". To overwrite existing -# files, type "sh file -c". You can also feed this as standard input via -# unshar, or by typing "sh <file", e.g.. If this archive is complete, you -# will see the following message at the end: -# "End of shell archive." -# Contents: mailprio mailprio_mkdb -# Wrapped by sanders@austin.BSDI.COM on Fri Dec 9 18:07:02 1994 -PATH=/bin:/usr/bin:/usr/ucb ; export PATH -if test -f 'mailprio' -a "${1}" != "-c" ; then - echo shar: Will not clobber existing file \"'mailprio'\" +#!/bin/sh +# This is a shell archive (produced by GNU sharutils 4.1). +# To extract the files from this archive, save it to some FILE, remove +# everything before the `!/bin/sh' line above, then type `sh FILE'. +# +# Made on 1996-10-31 10:07 MST by <sanders@earth.com>. +# +# Existing files will *not* be overwritten unless `-c' is specified. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 8260 -rwxr-xr-x mailprio +# 3402 -rw-r--r-- mailprio.README +# 4182 -rwxr-xr-x mailprio_mkdb +# +touch -am 1231235999 $$.touch >/dev/null 2>&1 +if test ! -f 1231235999 && test -f $$.touch; then + shar_touch=touch else -echo shar: Extracting \"'mailprio'\" \(3093 characters\) -sed "s/^X//" >'mailprio' <<'END_OF_FILE' -X#!/usr/bin/perl -X# -X# mailprio -- setup mail priorities for a mailing list -X# -X# Sort mailing list by mailprio database: -X# mailprio < mailing-list > sorted_list -X# Double check against orig: -X# sort sorted_list > checkit; sort mailing-list | diff - checkit -X# If it checks out, install it. -X# -X# TODO: -X# option to process mqueue files so we can reorder files in the queue! -X$usage = "Usage: mailprio [-p priodb]\n"; -X$home = "/home/sanders/lists"; -X$priodb = "$home/mailprio"; -X -Xif ($main'ARGV[0] =~ /^-/) { -X $args = shift; -X if ($args =~ m/\?/) { print $usage; exit 0; } -X if ($args =~ m/p/) { -X $priodb = shift || die $usage, "-p requires argument\n"; } -X} -X -X# In shell script, it goes something like this: -X# old_mailprio > /tmp/a -X# fgrep -f lists/inet-access /tmp/a | sed -e 's/^.......//' > /tmp/b -X# ; /tmp/b contains list of known users, faster delivery first -X# fgrep -v -f /tmp/b lists/inet-access > /tmp/c -X# ; put all unknown stuff at the top of new list for now -X# echo '# -----' >> /tmp/c -X# cat /tmp/b >> /tmp/c -X -X# Setup %list and @list -Xlocal($addr, $canon); -Xwhile ($addr = <STDIN>) { -X chop $addr; -X next if $addr =~ /^# ----- /; # that's our line -X push(@list, $addr), next if $addr =~ /^\s*#/; # save comments -X $canon = &canonicalize((&simplify_address($addr))[0]); -X unless (defined $canon) { -X warn "no address found: $addr\n"; -X push(@list, $addr); # save it anyway -X next; + shar_touch=: + echo + echo 'WARNING: not restoring timestamps. Consider getting and' + echo "installing GNU \`touch', distributed in GNU File Utilities..." + echo +fi +rm -f 1231235999 $$.touch +# +# ============= mailprio ============== +if test -f 'mailprio' && test X"$1" != X"-c"; then + echo 'x - skipping mailprio (file already exists)' +else + echo 'x - extracting mailprio (text)' + sed 's/^X//' << 'SHAR_EOF' > 'mailprio' && +#!/usr/bin/perl +# +# mailprio,v 1.4 1996/10/31 17:03:52 sanders Exp +# Version 0.93 -- Thu Oct 31 09:42:25 MST 1996 +# +# mailprio -- setup mail priorities for a mailing list +# +# Copyright 1994, 1996, Tony Sanders <sanders@earth.com> +# Rights are hereby granted to download, use, modify, sell, copy, and +# redistribute this software so long as the original copyright notice +# and this list of conditions remain intact and modified versions are +# noted as such. +# +# I would also very much appreciate it if you could send me a copy of +# any changes you make so I can possibly integrate them into my version. +# +# Options: +# -p priority_database -- Specify database to use if not default +# -q -- Process sendmail V8.8.X queue format files +# +# Sort mailing lists or sendmail queue files by mailprio database. +# Files listed on the command line are locked and then sorted in place, in +# the absence of any file arguments it will read STDIN and write STDOUT. +# +# Examples: +# mailprio < mailing-list > sorted_list +# mailprio mailing-list1 mailing-list2 mailing-list3 ... +# mailprio -q /var/spool/mqueue/qf* +# To double check results: +# sort sorted_list > checkit; sort orig-mailing-list | diff - checkit +# +# To get the maximum value from a transaction delay based priority +# function you need to reorder the distribution list (and the mail +# queue files for that matter) fairly often; you could even have +# your mailing list software reorder the list before each outgoing +# message. +# +$usage = "Usage: mailprio [-p priodb] [-q] [mailinglists ...]\n"; +$home = "/home/sanders/lists"; +$priodb = "$home/mailprio"; +$locking = "flock"; # "flock" or "fcntl" +X +# In shell, it would go more or less like this: +# old_mailprio > /tmp/a +# fgrep -f lists/inet-access /tmp/a | sed -e 's/^.......//' > /tmp/b +# ; /tmp/b contains list of known users, faster delivery first +# fgrep -v -f /tmp/b lists/inet-access > /tmp/c +# ; put all unknown stuff at the top of new list for now +# echo '# -----' >> /tmp/c +# cat /tmp/b >> /tmp/c +X +$qflag = 0; +while ($main'ARGV[0] =~ /^-/) { +X $args = shift; +X if ($args =~ m/\?/) { print $usage; exit 0; } +X if ($args =~ m/q/) { $qflag = 1; } +X if ($args =~ m/p/) { +X $priodb = shift || die $usage, "-p requires argument\n"; } +} +X +push(@main'ARGV, '-') if ($#ARGV < 0); +while ($file = shift @ARGV) { +X if ($file eq "-") { +X $source = "main'STDIN"; +X $sink = "main'STDOUT"; +X } else { +X $sink = $source = "FH"; +X open($source, "+< $file") || do { warn "$file: $!\n"; next; }; +X if (!defined &seize($source, &LOCK_EX | &LOCK_NB)) { +X # couldn't get lock, just skip it +X close($source); +X next; +X } X } -X if (defined $list{$canon}) { -X warn "duplicate: ``$addr -> $canon''\n"; -X push(@list, $addr); # save it anyway -X next; +X +X local(*list); +X &process($source, *list); +X +X # setup to write output +X if ($file ne "-") { +X # zero the file (FH is hardcoded because truncate requires it, sigh) +X seek(FH, 0, 0) || die "$file: seek: $!\n"; +X truncate(FH, 0) || die "$file: truncate: $!\n"; +X } +X +X # do the dirty work +X &output($sink, *list); +X +X close($sink) || warn "$file: $!\n"; # close clears the lock +X close($source); +} +X +sub process { +X # Setup %list and @list +X local($source, *list) = @_; +X local($addr, $canon); +X while ($addr = <$source>) { +X chop $addr; +X next if $addr =~ /^# ----- /; # that's our line +X push(@list, $addr), next if $addr =~ /^\s*#/; # save comments +X if ($qflag) { +X next if $addr =~ m/^\./; +X push(@list, $addr), next if !($addr =~ s/^(R[^:]*:)//); +X $Rflags = $1; +X } +X $canon = &canonicalize((&simplify_address($addr))[0]); +X unless (defined $canon) { +X warn "$file: no address found: $addr\n"; +X push(@list, ($qflag?$Rflags:'') . $addr); # save it as is +X next; +X } +X if (defined $list{$canon}) { +X warn "$file: duplicate: ``$addr -> $canon''\n"; +X push(@list, ($qflag?$Rflags:'') . $addr); # save it as is +X next; +X } +X $list{$canon} = $addr; X } -X $list{$canon} = $addr; -X} -X -Xlocal(*prio); -Xdbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n"; -Xforeach $to (keys %list) { -X if (defined $prio{$to}) { -X # add to list of found users (%userprio) and remove from %list -X # so that we know what users were not yet prioritized -X $userprio{$to} = $prio{$to}; # priority -X $useracct{$to} = $list{$to}; # string -X delete $list{$to}; +} +X +sub output { +X local($sink, *list) = @_; +X +X local($to, *prio, *userprio, *useracct); +X dbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n"; +X foreach $to (keys %list) { +X if (defined $prio{$to}) { +X # add to list of found users (%userprio) and remove from %list +X # so that we know what users were not yet prioritized +X $userprio{$to} = $prio{$to}; # priority +X $useracct{$to} = $list{$to}; # string +X delete $list{$to}; +X } X } -X} -Xdbmclose(%prio); +X dbmclose(%prio); +X +X # Put all the junk we found at the very top +X # (this might not always be a feature) +X print $sink join("\n", @list), "\n" if int(@list); X -X# Put all the junk we found at the very top -X# (this might not always be a feature) -Xprint join("\n", @list), "\n"; +X # prioritized list of users +X if (int(keys %userprio)) { +X print $sink '# ----- prioritized users', "\n" unless $qflag; +X foreach $to (sort by_userprio keys %userprio) { +X die "Opps! Something is seriously wrong with useracct: $to\n" +X unless defined $useracct{$to}; +X print $sink 'RFD:' if $qflag; +X print $sink $useracct{$to}, "\n"; +X } +X } X -X# unprioritized users go next, slow accounts will get moved down quickly -Xprint '# ----- unprioritized users', "\n"; -Xforeach $to (keys %list) { print $list{$to}, "\n"; } +X # unprioritized users go last, fast accounts will get moved up eventually +X # XXX: should go before the "really slow" prioritized users? +X if (int(keys %list)) { +X print $sink '# ----- unprioritized users', "\n" unless $qflag; +X foreach $to (keys %list) { +X print $sink 'RFD:' if $qflag; +X print $sink $list{$to}, "\n"; +X } +X } X -X# finally, our prioritized list of users -Xprint '# ----- prioritized users', "\n"; -Xforeach $to (sort { $userprio{$a} <=> $userprio{$b}; } keys %userprio) { -X die "Opps! Something is seriously wrong with useracct: $to\n" -X unless defined $useracct{$to}; -X print $useracct{$to}, "\n"; -X} +X print $sink ".\n" if $qflag; +} X -Xexit(0); +sub by_userprio { +X # sort first by priority, then by key. +X $userprio{$a} <=> $userprio{$b} || $a cmp $b; +} X -X# REPL-LIB --------------------------------------------------------------- +# REPL-LIB --------------------------------------------------------------- X -Xsub canonicalize { +sub canonicalize { X local($addr) = @_; X # lowercase, strip leading/trailing whitespace X $addr =~ y/A-Z/a-z/; $addr =~ s/^\s+//; $addr =~ s/\s+$//; $addr; -X} +} X -X# @addrs = simplify_address($addr); -Xsub simplify_address { +# @addrs = simplify_address($addr); +sub simplify_address { X local($_) = shift; -X 1 while s/\([^\(\)]*\)//g; # strip comments -X 1 while s/"[^"]*"//g; # strip comments -X split(/,/); # split into parts +X 1 while s/\([^\(\)]*\)//g; # strip comments +X 1 while s/"[^"]*"//g; # strip comments +X split(/,/); # split into parts X foreach (@_) { -X 1 while s/.*<(.*)>.*/\1/; -X s/^\s+//; -X s/\s+$//; +X 1 while s/.*<(.*)>.*/\1/; +X s/^\s+//; +X s/\s+$//; X } X @_; -X} -END_OF_FILE -if test 3093 -ne `wc -c <'mailprio'`; then - echo shar: \"'mailprio'\" unpacked with wrong size! +} +X +### ---- ### +# +# Error codes +# +do 'errno.ph'; +eval 'sub ENOENT {2;}' unless defined &ENOENT; +eval 'sub EINTR {4;}' unless defined &EINTR; +eval 'sub EINVAL {22;}' unless defined &EINVAL; +X +# +# File locking +# +do 'sys/unistd.ph'; +eval 'sub SEEK_SET {0;}' unless defined &SEEK_SET; +X +do 'sys/file.ph'; +eval 'sub LOCK_SH {0x01;}' unless defined &LOCK_SH; +eval 'sub LOCK_EX {0x02;}' unless defined &LOCK_EX; +eval 'sub LOCK_NB {0x04;}' unless defined &LOCK_NB; +eval 'sub LOCK_UN {0x08;}' unless defined &LOCK_UN; +X +do 'fcntl.ph'; +eval 'sub F_GETFD {1;}' unless defined &F_GETFD; +eval 'sub F_SETFD {2;}' unless defined &F_SETFD; +eval 'sub F_GETFL {3;}' unless defined &F_GETFL; +eval 'sub F_SETFL {4;}' unless defined &F_SETFL; +eval 'sub O_NONBLOCK {0x0004;}' unless defined &O_NONBLOCK; +eval 'sub F_SETLK {8;}' unless defined &F_SETLK; # nonblocking +eval 'sub F_SETLKW {9;}' unless defined &F_SETLKW; # lockwait +eval 'sub F_RDLCK {1;}' unless defined &F_RDLCK; +eval 'sub F_UNLCK {2;}' unless defined &F_UNLCK; +eval 'sub F_WRLCK {3;}' unless defined &F_WRLCK; +$s_flock = "sslll"; # struct flock {type, whence, start, len, pid} +X +# return undef on failure +sub seize { +X local ($FH, $lock) = @_; +X local ($ret); +X if ($locking eq "flock") { +X $ret = flock($FH, $lock); +X return ($ret == 0 ? undef : 1); +X } else { +X local ($flock, $type) = 0; +X if ($lock & &LOCK_SH) { $type = &F_RDLCK; } +X elsif ($lock & &LOCK_EX) { $type = &F_WRLCK; } +X elsif ($lock & &LOCK_UN) { $type = &F_UNLCK; } +X else { $! = &EINVAL; return undef; } +X $flock = pack($s_flock, $type, &SEEK_SET, 0, 0, 0); +X $ret = fcntl($FH, ($lock & &LOCK_NB) ? &F_SETLK : &F_SETLKW, $flock); +X return ($ret == -1 ? undef : 1); +X } +} +SHAR_EOF + $shar_touch -am 1031100396 'mailprio' && + chmod 0755 'mailprio' || + echo 'restore of mailprio failed' + shar_count="`wc -c < 'mailprio'`" + test 8260 -eq "$shar_count" || + echo "mailprio: original size 8260, current size $shar_count" fi -chmod +x 'mailprio' -# end of 'mailprio' +# ============= mailprio.README ============== +if test -f 'mailprio.README' && test X"$1" != X"-c"; then + echo 'x - skipping mailprio.README (file already exists)' +else + echo 'x - extracting mailprio.README (text)' + sed 's/^X//' << 'SHAR_EOF' > 'mailprio.README' && +mailprio README +X +mailprio.README,v 1.2 1996/10/31 17:03:54 sanders Exp +Version 0.93 -- Thu Oct 31 09:42:25 MST 1996 +X +Copyright 1994, 1996, Tony Sanders <sanders@earth.com> +Rights are hereby granted to download, use, modify, sell, copy, and +redistribute this software so long as the original copyright notice +and this list of conditions remain intact and modified versions are +noted as such. +X +I would also very much appreciate it if you could send me a copy of +any changes you make so I can possibly integrate them into my version. +X +The current version of this and other related mail tools are available in: +X ftp://ftp.earth.com/pub/postmaster/ +X +Even with the new persistent host status in sendmail V8.8.X this +function can still reduce the lag time distributing mail to a large +group of people. It also makes it a little more likely that everyone +will get mailing list mail in the order sent which can help reduce +duplicate postings. Basically, the goal is to put slow hosts at +the bottom of the list so that as many fast hosts are delivered +as quickly as possible. +X +CONTENTS +======== +X +X mailprio.README -- simple docs +X mailprio -- the address sorter +X mailprio_mkdb -- builds the database for the sorter +X +X +CHANGES +======= +X Version 0.92 +X Initial public release. +X +X Version 0.93 +X Updated to make use of the (somewhat) new xdelay statistic. +X Changed -q flag to support new sendmail queue file format (RFD:<addr>). +X Fixed argument parsing bug. +X Fixed bug with database getting "garbage" in it. +X +X +CONFIGURATION +============= +X +X You need to edit each script and ensure proper configuration. +X +X In mailprio check: #!perl path, $home, $priodb, $locking +X +X In mailprio_mkdb check: #!perl path, $home, $priodb, $maillog +X +X +USAGE: mailprio +=============== +X +X Usage: mailprio [-p priodb] [-q] [mailinglists ...] +X -p priority_database -- Specify database to use if not default +X -q -- Process sendmail queue format files +X [USE WITH CAUTION] +X +X Sort mailing lists or sendmail V8 queue files by mailprio database. +X Files listed on the command line are locked and then sorted in place, in +X the absence of any file arguments it will read STDIN and write STDOUT. +X +X Examples: +X mailprio < mailing-list > sorted_list +X mailprio mailing-list1 mailing-list2 mailing-list3 ... +X mailprio -q /var/spool/mqueue/qf* [not recommended] +X To double check results: +X sort sorted_list > checkit; sort orig-mailing-list | diff - checkit +X +X NOTE: +X To get the maximum value from a transaction delay based priority +X function you need to reorder the distribution list (and the mail +X queue files for that matter) fairly often; you could even have +X your mailing list software reorder the list before each outgoing +X message. +X +X +USAGE: mailprio_mkdb +==================== +X +X Usage: mailprio_mkdb [-l maillog] [-p priodb] +X -l maillog -- Specify maillog to process if not default +X -p priority_database -- Specify database to use if not default +X +X Builds the mail priority database using information from the maillog. +X +X Run at least nightly before you rotate the maillog. If you are +X going to run mailprio more often than that then you will need to +X load the current maillog information before that will do any good +X (and to keep from reloading the same information you will need +X some kind of incremental maillog information to load from). +SHAR_EOF + $shar_touch -am 1031100396 'mailprio.README' && + chmod 0644 'mailprio.README' || + echo 'restore of mailprio.README failed' + shar_count="`wc -c < 'mailprio.README'`" + test 3402 -eq "$shar_count" || + echo "mailprio.README: original size 3402, current size $shar_count" fi -if test -f 'mailprio_mkdb' -a "${1}" != "-c" ; then - echo shar: Will not clobber existing file \"'mailprio_mkdb'\" +# ============= mailprio_mkdb ============== +if test -f 'mailprio_mkdb' && test X"$1" != X"-c"; then + echo 'x - skipping mailprio_mkdb (file already exists)' else -echo shar: Extracting \"'mailprio_mkdb'\" \(3504 characters\) -sed "s/^X//" >'mailprio_mkdb' <<'END_OF_FILE' -X#!/usr/bin/perl -X# -X# mailprio_mkdb -- make mail priority database based on delay times -X# -X$usage = "Usage: mailprio_mkdb [-l maillog] [-p priodb]\n"; -X$home = "/home/sanders/lists"; -X$maillog = "/var/log/maillog"; -X$priodb = "$home/mailprio"; -X -Xif ($main'ARGV[0] =~ /^-/) { + echo 'x - extracting mailprio_mkdb (text)' + sed 's/^X//' << 'SHAR_EOF' > 'mailprio_mkdb' && +#!/usr/bin/perl +# +# mailprio_mkdb,v 1.5 1996/10/31 17:03:53 sanders Exp +# Version 0.93 -- Thu Oct 31 09:42:25 MST 1996 +# +# mailprio_mkdb -- make mail priority database based on delay times +# +# Copyright 1994, 1996, Tony Sanders <sanders@earth.com> +# Rights are hereby granted to download, use, modify, sell, copy, and +# redistribute this software so long as the original copyright notice +# and this list of conditions remain intact and modified versions are +# noted as such. +# +# I would also very much appreciate it if you could send me a copy of +# any changes you make so I can possibly integrate them into my version. +# +# The average function moves the value around quite rapidly (half-steps) +# which may or may not be a feature. This version uses the new xdelay +# statistic (new as of sendmail V8) which is per transaction. We also +# weight the result based on the overall delay. +# +# Something that might be worth doing for systems that don't support +# xdelay would be to compute an approximation of the transaction delay +# by sorting by messages-id and delay then computing the difference +# between adjacent delay values. +# +# To get the maximum value from a transaction delay based priority +# function you need to reorder the distribution list (and the mail +# queue files for that matter) fairly often; you could even have +# your mailing list software reorder the list before each outgoing +# message. +X +$usage = "Usage: mailprio_mkdb [-l maillog] [-p priodb]\n"; +$home = "/home/sanders/lists"; +$maillog = "/var/log/maillog"; +$priodb = "$home/mailprio"; +X +while ($ARGV[0] =~ /^-/) { X $args = shift; X if ($args =~ m/\?/) { print $usage; exit 0; } X if ($args =~ m/l/) { X $maillog = shift || die $usage, "-l requires argument\n"; } X if ($args =~ m/p/) { X $priodb = shift || die $usage, "-p requires argument\n"; } -X} -X -Xlocal(*prio); -X# We'll merge with existing information if it's already there. -Xdbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n"; -X&getlog_stats($maillog, *prio); -X# foreach $addr (sort { $prio{$a} <=> $prio{$b}; } keys %prio) { -X# printf("%06d %s\n", $prio{$addr}, $addr); } -Xdbmclose(%prio); -Xexit(0); -X -Xsub getlog_stats { +} +X +$SIG{'PIPE'} = 'handle_pipe'; +X +# will merge with existing information +dbmopen(%prio, $priodb, 0644) || die "$priodb: $!\n"; +&getlog_stats($maillog, *prio); +dbmclose(%prio); +exit(0); +X +sub handle_pipe { +X dbmclose(%prio); +} +X +sub getlog_stats { X local($maillog, *stats) = @_; X local($to, $delay); X local($h, $m, $s); X open(MAILLOG, "< $maillog") || die "$maillog: $!\n"; X while (<MAILLOG>) { -X ($delay) = (m/, delay=([^,]*), /); -X $delay || next; -X ($h, $m, $s) = split(/:/, $delay); -X $delay = ($h * 60 * 60) + ($m * 60) + $s; -X -X # deleting everything after ", " seems safe enough, though -X # it is possible that it was inside "..."'s and that we will -X # miss some addresses because of it. However, I'm not willing -X # to do full parsing just for that case. If this bothers you -X # you could do something like: s/, (delay|ctladdr)=.*//; -X # but you have to make sure you catch all the possible names. -X $to = $_; $to =~ s/^.* to=//; $to =~ s/, .*//; +X next unless / to=/ && / stat=/; +X next if / stat=queued/; +X if (/ stat=sent/i) { +X # read delay and xdelay and convert to seconds +X ($delay) = (m/ delay=([^,]*),/); +X next unless $delay; +X ($h, $m, $s) = split(/:/, $delay); +X $delay = ($h * 60 * 60) + ($m * 60) + $s; +X +X ($xdelay) = (m/ xdelay=([^,]*),/); +X next unless $xdelay; +X ($h, $m, $s) = split(/:/, $xdelay); +X $xdelay = ($h * 60 * 60) + ($m * 60) + $s; +X +X # Now weight the delay factor by the transaction delay (xdelay). +X $xdelay /= 300; # [0 - 1(@5 min)] +X $xdelay += 0.5; # [0.5 - 1.5] +X $xdelay = 1.5 if $xdelay > 1.5; # clamp +X $delay *= $xdelay; # weight delay by xdelay +X } +X elsif (/, stat=/) { +X # delivery failure of some sort (i.e. bad) +X $delay = 432000; # force 5 days +X } +X $delay = 1000000 if $delay > 1000000; +X +X # filter the address(es); isn't perfect but is "good enough" +X $to = $_; $to =~ s/^.* to=//; +X 1 while $to =~ s/\([^\(\)]*\)//g; # strip comments +X 1 while $to =~ s/"[^"]*"//g; # strip comments +X $to =~ s/, .*//; # remove other stat info X foreach $addr (&simplify_address($to)) { X next unless $addr; X $addr = &canonicalize($addr); -X # print $delay, " ", $addr, "\n"; X $stats{$addr} = $delay unless defined $stats{$addr}; # init -X -X # This average function moves the value around quite rapidly -X # which may or may not be a feature. -X # -X # This has at least one odd behavior because we currently only -X # use the delay information from maillog which is only logged -X # on actual delivery. This works backwards from what we really -X # want to happen when a fast host goes down for a while and then -X # comes back up. -X # -X # I spoke with Eric and he suggested adding an xdelay statistic -X # for a per transaction delay which would help that situation -X # a lot. What I believe you want in that cases something like: -X # delay fast, xdelay fast: smokin', these hosts go first -X # delay slow, xdelay fast: put host high on the list (back up?) -X # delay fast, xdelay slow: host is down/having problems/slow -X # delay slow, xdelay slow: poorly connected sites, very last -X # Of course, you have to reorder the distribution list fairly -X # often for that to help. Come to think of it, you should -X # also reorder /var/spool/mqueue files also (if they aren't -X # locked of course). Hmmm.... +X # pseudo-average in the new delay (half-steps) +X # simple, moving average X $stats{$addr} = int(($stats{$addr} + $delay) / 2); X } X } X close(MAILLOG); -X} +} X -X# REPL-LIB --------------------------------------------------------------- +# REPL-LIB --------------------------------------------------------------- X -Xsub canonicalize { +sub canonicalize { X local($addr) = @_; X # lowercase, strip leading/trailing whitespace X $addr =~ y/A-Z/a-z/; $addr =~ s/^\s+//; $addr =~ s/\s+$//; $addr; -X} +} X -X# @addrs = simplify_address($addr); -Xsub simplify_address { +# @addrs = simplify_address($addr); +sub simplify_address { X local($_) = shift; X 1 while s/\([^\(\)]*\)//g; # strip comments X 1 while s/"[^"]*"//g; # strip comments @@ -285,13 +545,13 @@ X s/^\s+//; X s/\s+$//; X } X @_; -X} -END_OF_FILE -if test 3504 -ne `wc -c <'mailprio_mkdb'`; then - echo shar: \"'mailprio_mkdb'\" unpacked with wrong size! -fi -chmod +x 'mailprio_mkdb' -# end of 'mailprio_mkdb' +} +SHAR_EOF + $shar_touch -am 1031100396 'mailprio_mkdb' && + chmod 0755 'mailprio_mkdb' || + echo 'restore of mailprio_mkdb failed' + shar_count="`wc -c < 'mailprio_mkdb'`" + test 4182 -eq "$shar_count" || + echo "mailprio_mkdb: original size 4182, current size $shar_count" fi -echo shar: End of shell archive. exit 0 diff --git a/usr.sbin/sendmail/doc/op/op.me b/usr.sbin/sendmail/doc/op/op.me index 1009ba1..4bbcf88 100644 --- a/usr.sbin/sendmail/doc/op/op.me +++ b/usr.sbin/sendmail/doc/op/op.me @@ -30,7 +30,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.\" @(#)op.me 8.97 (Berkeley) 10/17/96 +.\" @(#)op.me 8.98 (Berkeley) 11/16/96 .\" .\" eqn op.me | pic | troff -me .eh 'SMM:08-%''Sendmail Installation and Operation Guide' @@ -68,7 +68,7 @@ Eric Allman InReference, Inc. eric@Sendmail.ORG .sp -Version 8.97 +Version 8.98 .sp For Sendmail Version 8.8 .)l @@ -3561,6 +3561,25 @@ The full name of the sender. The home directory of the recipient. .ip $_ The validated sender address. +.ip ${bodytype} +The message body type +(7BIT or 8BITMIME), +as determined from the envelope. +.ip ${client_addr} +The IP address of the SMTP client. +Defined in the SMTP server only. +.ip ${client_name} +The host name of the SMTP client. +Defined in the SMTP server only. +.ip ${client_port} +The port number of the SMTP client. +Defined in the SMTP server only. +.ip ${envid} +The envelope id passed to sendmail as part of the envelope. +.ip ${opMode} +The current operation mode (from the +.b \-b +flag). .pp There are three types of dates that can be used. The @@ -3758,10 +3777,12 @@ and the receiver has the IDENT protocol turned on, it will include the user name on that host. .pp The -.b ${client_name} +.b ${client_name} , +.b ${client_addr} , and -.b ${client_addr} -are set to the name and address of the SMTP client +.b ${client_port} +macros +are set to the name, address, and port number of the SMTP client who is invoking .i sendmail as a server. @@ -8129,7 +8150,7 @@ A transcript of the current session. .\"Eric Allman .\"InReference, Inc. .\".sp -.\"Version 8.97 +.\"Version 8.98 .\".ce 0 .bp 2 .rs diff --git a/usr.sbin/sendmail/mail.local/mail.local.c b/usr.sbin/sendmail/mail.local/mail.local.c index 8604867..1f28229 100644 --- a/usr.sbin/sendmail/mail.local/mail.local.c +++ b/usr.sbin/sendmail/mail.local/mail.local.c @@ -38,7 +38,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)mail.local.c 8.30 (Berkeley) 10/9/96"; +static char sccsid[] = "@(#)mail.local.c 8.33 (Berkeley) 11/13/96"; #endif /* not lint */ /* diff --git a/usr.sbin/sendmail/makemap/makemap.c b/usr.sbin/sendmail/makemap/makemap.c index ac1fb1a..5ac2df6 100644 --- a/usr.sbin/sendmail/makemap/makemap.c +++ b/usr.sbin/sendmail/makemap/makemap.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)makemap.c 8.17 (Berkeley) 9/25/96"; +static char sccsid[] = "@(#)makemap.c 8.18 (Berkeley) 11/13/96"; #endif /* not lint */ #include <stdio.h> @@ -97,6 +97,7 @@ main(argc, argv) int st; int mode; int putflags; + long dbcachesize = 1024 * 1024; enum type type; int fd; union @@ -112,6 +113,7 @@ main(argc, argv) union dbent key, val; #ifdef NEWDB BTREEINFO bti; + HASHINFO hinfo; #endif char ibuf[BUFSIZE]; char fbuf[MAXNAME]; @@ -122,7 +124,12 @@ main(argc, argv) progname = argv[0]; - while ((opt = getopt(argc, argv, "Ndforv")) != EOF) +#ifdef FFR_CFLAG +#define OPTIONS "Nc:dforv" +#else +#define OPTIONS "Ndforv" +#endif + while ((opt = getopt(argc, argv, OPTIONS)) != EOF) { switch (opt) { @@ -130,6 +137,12 @@ main(argc, argv) inclnull = TRUE; break; +#ifdef FFR_CFLAG + case 'c': + dbcachesize = atol(optarg); + break; +#endif + case 'd': allowdups = TRUE; break; @@ -189,7 +202,11 @@ main(argc, argv) switch (type) { case T_ERR: +#ifdef FFR_CFLAG + fprintf(stderr, "Usage: %s [-N] [-c cachesize] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname); +#else fprintf(stderr, "Usage: %s [-N] [-d] [-f] [-o] [-r] [-v] type mapname\n", progname); +#endif exit(EX_USAGE); case T_UNKNOWN: @@ -294,7 +311,11 @@ main(argc, argv) #ifdef NEWDB case T_HASH: - dbp.db = dbopen(mapname, mode, 0644, DB_HASH, NULL); + /* tweak some parameters for performance */ + hinfo.nelem = 4096; + hinfo.cachesize = dbcachesize; + + dbp.db = dbopen(mapname, mode, 0644, DB_HASH, &hinfo); if (dbp.db != NULL) { # if OLD_NEWDB @@ -306,6 +327,9 @@ main(argc, argv) break; case T_BTREE: + /* tweak some parameters for performance */ + bti.cachesize = dbcachesize; + dbp.db = dbopen(mapname, mode, 0644, DB_BTREE, &bti); if (dbp.db != NULL) { diff --git a/usr.sbin/sendmail/src/READ_ME b/usr.sbin/sendmail/src/READ_ME index 779f828..afeac1b 100644 --- a/usr.sbin/sendmail/src/READ_ME +++ b/usr.sbin/sendmail/src/READ_ME @@ -30,7 +30,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# @(#)READ_ME 8.125 (Berkeley) 10/18/96 +# @(#)READ_ME 8.130 (Berkeley) 11/10/96 # This directory contains the source files for sendmail. @@ -168,7 +168,7 @@ LDAPMAP Lightweight Directory Lookup Protocol support. You will this flag. >>> NOTE WELL for NEWDB support: it is CRITICAL that you remove ndbm.o ->>> from libdb.a and ndbm.h from the appropriate include directories if +>>> from libdb.a before you install it and DO NOT install ndbm.h if >>> you want to get ndbm support. If you don't delete these, there is >>> absolutely no point to including -DNDBM, since it will just get you >>> another (inferior) API to the same format database. These files @@ -355,11 +355,20 @@ LA_TYPE The type of load average your kernel supports. These the dg_sys_info system call. LA_HPUX (10) is an HP-UX specific version that uses the pstat_getdynamic system call. + LA_IRIX6 (11) is an IRIX 6.x specific version that adapts + to 32 or 64 bit kernels; it is otherwise very similar + to LA_INT. + LA_KSTAT (12) uses the (Solaris-specific) kstat(3k) + implementation. + LA_DEVSHORT (13) reads a short from a system file (default: + /dev/table/avenrun) and scales it in the same manner + as LA_SHORT. LA_INT, LA_SHORT, LA_FLOAT, and LA_READKSYM have several other parameters that they try to divine: the name of your kernel, the name of the variable in the kernel to examine, the number of bits of precision in a fixed point load average, - and so forth. + and so forth. LA_DEVSHORT uses _PATH_AVENRUN to find the + device to be read to find the load average. In desperation, use LA_ZERO. The actual code is in conf.c -- it can be tweaked if you are brave. FSHIFT For LA_INT, LA_SHORT, and LA_READKSYM, this is the number @@ -809,6 +818,26 @@ IRIX the developers' option in order to get the necessary include files. + If you compile with -lmalloc (the fast memory allocator), you may + get warning messages such as the following: + + ld32: WARNING 85: definition of _calloc in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _malloc in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _realloc in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _free in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + ld32: WARNING 85: definition of _cfree in /usr/lib32/libmalloc.so + preempts that definition in /usr/lib32/mips3/libc.so. + + These are unavoidable and innocuous -- just ignore them. + + According to Dave Sill <de5@ornl.gov>, there is a version of the + Berkeley db library patched to run on Irix 6.2 available from + http://reality.sgi.com/ariel/db-1.85-irix.tar.Z . + NeXT or NEXTSTEP NEXTSTEP 3.3 and earlier ship with the old DBM library. You will need to acquire the new Berkeley DB from ftp.cs.berkeley.edu. @@ -1348,4 +1377,4 @@ version.c The version number and information about this Eric Allman -(Version 8.125, last update 10/18/96 07:32:40) +(Version 8.130, last update 11/10/96 11:15:30) diff --git a/usr.sbin/sendmail/src/collect.c b/usr.sbin/sendmail/src/collect.c index 233c247..48b5b89 100644 --- a/usr.sbin/sendmail/src/collect.c +++ b/usr.sbin/sendmail/src/collect.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)collect.c 8.58 (Berkeley) 9/18/96"; +static char sccsid[] = "@(#)collect.c 8.60 (Berkeley) 11/15/96"; #endif /* not lint */ # include <errno.h> @@ -488,7 +488,7 @@ readerr: ** Examples are who is the from person & the date. */ - eatheader(e, !requeueflag); + eatheader(e, TRUE); if (GrabTo && e->e_sendqueue == NULL) usrerr("No recipient addresses found in header"); @@ -557,6 +557,7 @@ readerr: /* check for message too large */ if (MaxMessageSize > 0 && e->e_msgsize > MaxMessageSize) { + e->e_flags |= EF_NO_BODY_RETN; e->e_status = "5.2.3"; usrerr("552 Message exceeds maximum fixed size (%ld)", MaxMessageSize); diff --git a/usr.sbin/sendmail/src/conf.c b/usr.sbin/sendmail/src/conf.c index 0799047..6f3fd95 100644 --- a/usr.sbin/sendmail/src/conf.c +++ b/usr.sbin/sendmail/src/conf.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)conf.c 8.312 (Berkeley) 10/17/96"; +static char sccsid[] = "@(#)conf.c 8.315 (Berkeley) 11/10/96"; #endif /* not lint */ # include "sendmail.h" @@ -1188,8 +1188,19 @@ init_md(argc, argv) /* keep gethostby*() from stripping the local domain name */ set_domain_trim_off(); #endif -#if SECUREWARE +#if SECUREWARE || defined(_SCO_unix_) set_auth_parameters(argc, argv); + +# ifdef _SCO_unix_ + /* + ** This is required for highest security levels (the kernel + ** won't let it call set*uid() or run setuid binaries without + ** it). It may be necessary on other SECUREWARE systems. + */ + + if (getluid() == -1) + setluid(0); +# endif #endif #ifdef VENDOR_DEFAULT @@ -1245,6 +1256,8 @@ init_vendor_macros(e) #define LA_DGUX 9 /* special DGUX implementation */ #define LA_HPUX 10 /* special HPUX implementation */ #define LA_IRIX6 11 /* special IRIX 6.2 implementation */ +#define LA_KSTAT 12 /* special Solaris kstat(3k) implementation */ +#define LA_DEVSHORT 13 /* read short from a device */ /* do guesses based on general OS type */ #ifndef LA_TYPE @@ -1780,8 +1793,100 @@ int getla(void) } #endif +#if LA_TYPE == LA_KSTAT + +#include <kstat.h> + +int +getla() +{ + kstat_ctl_t *kc; + kstat_t *ksp; + kstat_named_t *ksn; + int la; + + kc = kstat_open(); + if (kc == NULL) + { + if (tTd(3, 1)) + printf("getla: kstat_open(): %s\n", + errstring(errno)); + return -1; + } + ksp = kstat_lookup(kc, "unix", 0, "system_misc"); /* NULL on error */ + if (ksp == NULL) + { + if (tTd(3, 1)) + printf("getla: kstat_lookup(): %s\n", + errstring(errno); + return -1; + } + if (kstat_read(kc, ksp, NULL) < 0) + { + if (tTd(3, 1)) + printf("getla: kstat_read(): %s\n", + errstring(errno); + return -1; + } + ksn = (kstat_named_t *) kstat_data_lookup(ksp, "avenrun_1min"); + la = (ksn->value.ul + FSCALE/2) >> FSHIFT; + kstat_close(kc); + return la; +} + +#endif /* LA_TYPE == LA_KSTAT */ + +#if LA_TYPE == LA_DEVSHORT + +/* +** Read /dev/table/avenrun for the load average. This should contain +** three shorts for the 1, 5, and 15 minute loads. We only read the +** first, since that's all we care about. +** +** Intended for SCO OpenServer 5. +*/ + +# ifndef _PATH_AVENRUN +# define _PATH_AVENRUN "/dev/table/avenrun" +# endif + +int +getla() +{ + static int afd = -1; + short avenrun; + int loadav; + int r; + + errno = EBADF; + + if (afd == -1 || lseek(afd, 0L, SEEK_SET) == -1) + { + if (errno != EBADF) + return -1; + afd = open(_PATH_AVENRUN, O_RDONLY|O_SYNC); + if (afd < 0) + { + syslog(LOG_ERR, "can't open %s: %m", _PATH_AVENRUN); + return -1; + } + } + + r = read(afd, &avenrun, sizeof avenrun); + + if (tTd(3, 5)) + printf("getla: avenrun = %d\n", avenrun); + loadav = (int) (avenrun + FSCALE/2) >> FSHIFT; + if (tTd(3, 1)) + printf("getla: %d\n", loadav); + return loadav; +} + +#endif /* LA_TYPE == LA_DEVSHORT */ + #if LA_TYPE == LA_ZERO +int getla() { if (tTd(3, 1)) @@ -1941,8 +2046,10 @@ refuseconnections(port) syslog(LOG_INFO, "rejecting connections on port %d: load average: %d", port, CurrentLA); #endif + return TRUE; } - else if (!enoughdiskspace(MinBlocksFree + 1)) + + if (!enoughdiskspace(MinBlocksFree + 1)) { setproctitle("rejecting connections on port %d: min free: %d", port, MinBlocksFree); @@ -1951,20 +2058,26 @@ refuseconnections(port) syslog(LOG_INFO, "rejecting connections on port %d: min free: %d", port, MinBlocksFree); #endif + return TRUE; } - else if (MaxChildren > 0 && CurChildren >= MaxChildren) + + if (MaxChildren > 0 && CurChildren >= MaxChildren) { - setproctitle("rejecting connections on port %d: %d children, max %d", - port, CurChildren, MaxChildren); -#ifdef LOG - if (LogLevel >= 14) - syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d", + proc_list_probe(); + if (CurChildren >= MaxChildren) + { + setproctitle("rejecting connections on port %d: %d children, max %d", port, CurChildren, MaxChildren); +#ifdef LOG + if (LogLevel >= 14) + syslog(LOG_INFO, "rejecting connections on port %d: %d children, max %d", + port, CurChildren, MaxChildren); #endif + return TRUE; + } } - else - return FALSE; - return TRUE; + + return FALSE; } /* ** SETPROCTITLE -- set process title for ps diff --git a/usr.sbin/sendmail/src/conf.h b/usr.sbin/sendmail/src/conf.h index 69558c2..cf7cbe5 100644 --- a/usr.sbin/sendmail/src/conf.h +++ b/usr.sbin/sendmail/src/conf.h @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)conf.h 8.267 (Berkeley) 10/17/96 + * @(#)conf.h 8.272 (Berkeley) 11/16/96 */ /* @@ -41,7 +41,9 @@ ** included in the next release. */ +#ifdef __GNUC__ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ +#endif # include <sys/param.h> # include <sys/types.h> @@ -216,7 +218,11 @@ extern void hard_syslog(int, char *, ...); #ifdef _AIX4 # define _AIX3 1 /* pull in AIX3 stuff */ -# define HASSETREUID 1 /* setreuid(2) works */ +# define USESETEUID 1 /* seteuid(2) works */ +# define TZ_TYPE TZ_NAME /* use tzname[] vector */ +# if _AIX4 >= 40200 +# define HASSETREUID 1 /* setreuid(2) works as of AIX 4.2 */ +# endif #endif @@ -409,6 +415,9 @@ typedef int pid_t; # define snprintf __snprintf /* but names it oddly in 2.5 */ # define vsnprintf __vsnprintf # endif +# ifndef LA_TYPE +# define LA_TYPE LA_KSTAT /* use kstat(3k) -- may work in < 2.5 */ +# endif # endif # ifndef HASGETUSERSHELL # define HASGETUSERSHELL 0 /* getusershell(3) causes core dumps */ @@ -588,6 +597,7 @@ extern long dgux_inet_addr(); # define WAITUNION 1 /* use "union wait" as wait argument type */ # define UID_T int /* compiler gripes on uid_t */ # define GID_T int /* ditto for gid_t */ +# define MODE_T int /* and mode_t */ # define sleep sleepX # define setpgid setpgrp # ifndef LA_TYPE @@ -791,31 +801,43 @@ extern int errno; ** The third is for SCO UNIX 3.2v4.0/Open Desktop 2.0 and earlier. */ +/* SCO OpenServer 5 */ #if _SCO_DS >= 1 # include <paths.h> # define _SCO_unix_4_2 -# define HASSNPRINTF 1 /* has snprintf() call */ -# define HASFCHMOD 1 /* has fchmod() call */ -# define HASSETRLIMIT 1 /* has setrlimit() call */ +# define HASSNPRINTF 1 /* has snprintf(3) call */ +# define HASFCHMOD 1 /* has fchmod(2) call */ +# define HASSETRLIMIT 1 /* has setrlimit(2) call */ +# define USESETEUID 1 /* has seteuid(2) call */ +# define HASINITGROUPS 1 /* has initgroups(3) call */ +# define HASGETDTABLESIZE 1 /* has getdtablesize(2) call */ # define RLIMIT_NEEDS_SYS_TIME_H 1 +# ifndef LA_TYPE +# define LA_TYPE LA_DEVSHORT +# endif +# define _PATH_AVENRUN "/dev/table/avenrun" #endif - +/* SCO UNIX 3.2v4.2/Open Desktop 3.0 */ #ifdef _SCO_unix_4_2 # define _SCO_unix_ # define HASSETREUID 1 /* has setreuid(2) call */ #endif +/* SCO UNIX 3.2v4.0 Open Desktop 2.0 and earlier */ #ifdef _SCO_unix_ # include <sys/stream.h> /* needed for IP_SRCROUTE */ # define SYSTEM5 1 /* include all the System V defines */ # define HASGETUSERSHELL 0 /* does not have getusershell(3) call */ +# define NOFTRUNCATE 0 /* has (simulated) ftruncate call */ # define MAXPATHLEN PATHSIZE -# define LA_TYPE LA_SHORT # define SFS_TYPE SFS_4ARGS /* use <sys/statfs.h> 4-arg impl */ # define SFS_BAVAIL f_bfree /* alternate field name */ # define SPT_TYPE SPT_SCO /* write kernel u. area */ # define TZ_TYPE TZ_TM_NAME /* use tm->tm_name */ +# define UID_T uid_t +# define GID_T gid_t +# define GIDSET_T gid_t # define _PATH_UNIX "/unix" # define _PATH_VENDOR_CF "/usr/lib/sendmail.cf" # ifndef _PATH_SENDMAILPID @@ -828,9 +850,10 @@ extern int errno; # endif # ifndef _SCO_DS -# define NOFTRUNCATE 0 /* does not have ftruncate(3) call */ +# define ftruncate chsize /* use chsize(2) to emulate ftruncate */ # define NEEDFSYNC 1 /* needs the fsync(2) call stub */ # define NETUNIX 0 /* no unix domain socket support */ +# define LA_TYPE LA_SHORT # endif #endif @@ -1850,6 +1873,10 @@ extern int errno; # define SIZE_T size_t #endif +#ifndef MODE_T +# define MODE_T mode_t +#endif + #ifndef ARGV_T # define ARGV_T char ** #endif diff --git a/usr.sbin/sendmail/src/daemon.c b/usr.sbin/sendmail/src/daemon.c index aead4ff..283d7e4 100644 --- a/usr.sbin/sendmail/src/daemon.c +++ b/usr.sbin/sendmail/src/daemon.c @@ -37,9 +37,9 @@ #ifndef lint #ifdef DAEMON -static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (with daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (with daemon mode)"; #else -static char sccsid[] = "@(#)daemon.c 8.145 (Berkeley) 10/12/96 (without daemon mode)"; +static char sccsid[] = "@(#)daemon.c 8.148 (Berkeley) 11/8/96 (without daemon mode)"; #endif #endif /* not lint */ @@ -193,7 +193,7 @@ getrequests(e) for (;;) { - register int pid; + register pid_t pid; auto int lotherend; extern bool refuseconnections(); extern int getla(); @@ -244,6 +244,16 @@ getrequests(e) /* wait for a connection */ setproctitle("accepting connections on port %d", ntohs(DaemonAddr.sin.sin_port)); +#if 0 + /* + ** Andrew Sun <asun@ieps-sun.ml.com> claims that this will + ** fix the SVr4 problem. But it seems to have gone away, + ** so is it worth doing this? + */ + + if (SetNonBlocking(DaemonSocket, FALSE) < 0) + log an error here; +#endif do { errno = 0; @@ -734,9 +744,8 @@ makeconnection(host, port, mci, e) extern char MsgBuf[]; usrerr("553 Invalid numeric domain spec \"%s\"", host); - mci->mci_status = "5.1.2"; - mci->mci_rstatus = newstr(MsgBuf); - return (EX_NOHOST); + mci_setstat(mci, EX_NOHOST, "5.1.2", MsgBuf); + return EX_NOHOST; } #if NETINET addr.sin.sin_family = AF_INET; /*XXX*/ @@ -773,11 +782,11 @@ gothostent: if (errno == ETIMEDOUT || h_errno == TRY_AGAIN || (errno == ECONNREFUSED && UseNameServer)) { - mci->mci_status = "4.4.3"; - mci->mci_rstatus = NULL; - return (EX_TEMPFAIL); + mci_setstat(mci, EX_TEMPFAIL, "4.4.3", NULL); + return EX_TEMPFAIL; } #endif + mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); return (EX_NOHOST); } addr.sa.sa_family = hp->h_addrtype; @@ -839,6 +848,7 @@ gothostent: default: syserr("Can't connect to address family %d", addr.sa.sa_family); + mci_setstat(mci, EX_NOHOST, "5.1.2", NULL); return (EX_NOHOST); } @@ -876,7 +886,11 @@ gothostent: { sav_errno = errno; syserr("makeconnection: cannot create socket"); - goto failure; +#ifdef XLA + xla_host_end(host); +#endif + mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); + return EX_TEMPFAIL; } #ifdef SO_SNDBUF @@ -964,18 +978,12 @@ gothostent: continue; } - /* failure, decide if temporary or not */ - failure: + /* couldn't open connection */ #ifdef XLA xla_host_end(host); #endif - if (transienterror(sav_errno)) - return EX_TEMPFAIL; - else - { - message("%s", errstring(sav_errno)); - return (EX_UNAVAILABLE); - } + mci_setstat(mci, EX_TEMPFAIL, "4.4.1", NULL); + return EX_TEMPFAIL; } /* connection ok, put it into canonical form */ @@ -984,9 +992,11 @@ gothostent: (mci->mci_in = fdopen(s, "r")) == NULL) { syserr("cannot open SMTP client channel, fd=%d", s); + mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); return EX_TEMPFAIL; } + mci_setstat(mci, EX_OK, NULL, NULL); return (EX_OK); } /* diff --git a/usr.sbin/sendmail/src/deliver.c b/usr.sbin/sendmail/src/deliver.c index f446f53..c019d2b 100644 --- a/usr.sbin/sendmail/src/deliver.c +++ b/usr.sbin/sendmail/src/deliver.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)deliver.c 8.246 (Berkeley) 10/17/96"; +static char sccsid[] = "@(#)deliver.c 8.251 (Berkeley) 11/11/96"; #endif /* not lint */ #include "sendmail.h" @@ -78,7 +78,7 @@ sendall(e, mode) ENVELOPE *splitenv = NULL; bool oldverbose = Verbose; bool somedeliveries = FALSE; - int pid; + pid_t pid; extern void sendenvelope(); /* @@ -760,7 +760,7 @@ sendenvelope(e, mode) int dofork() { - register int pid = -1; + register pid_t pid = -1; DOFORK(fork); return (pid); @@ -813,11 +813,12 @@ deliver(e, firstto) ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */ int rcode; /* response code */ char *firstsig; /* signature of firstto */ - int pid = -1; + pid_t pid = -1; char *volatile curhost; register volatile u_short port = 0; time_t xstart; bool suidwarn; + bool anyok; /* at least one address was OK */ int mpvect[2]; int rpvect[2]; char *pv[MAXPV+1]; @@ -1314,7 +1315,7 @@ tryhost: if (mci_lock_host(mci) != EX_OK) { - mci->mci_exitstat = EX_TEMPFAIL; + mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL); continue; } @@ -1840,6 +1841,7 @@ tryhost: extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *)); extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *)); extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *)); + extern int smtpgetstat __P((MAILER *, MCI *, ENVELOPE *)); /* ** Send the MAIL FROM: protocol @@ -1883,10 +1885,6 @@ tryhost: e->e_to = tobuf + 1; rcode = smtpdata(m, mci, e); } - - /* now close the connection */ - if (!bitset(MCIF_CACHED, mci->mci_flags)) - smtpquit(m, mci, e); } if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0') { @@ -1917,11 +1915,17 @@ tryhost: */ give_up: - if (tobuf[0] != '\0') - giveresponse(rcode, m, mci, ctladdr, xstart, e); - if (rcode == EX_OK) - markstats(e, tochain); - mci_store_persistent(mci); +#ifdef SMTP +# if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + { + tobuf[0] = '\0'; + anyok = FALSE; + } + else +# endif +#endif + anyok = rcode == EX_OK; for (to = tochain; to != NULL; to = to->q_tchain) { @@ -1929,11 +1933,37 @@ tryhost: if (bitset(QBADADDR|QQUEUEUP, to->q_flags)) continue; - /* mark bad addresses */ - if (rcode != EX_OK) +#ifdef SMTP +# if FFR_LMTP + /* if running LMTP, get the status for each address */ + if (bitnset(M_LMTP, m->m_flags)) { - markfailure(e, to, mci, rcode); - continue; + rcode = smtpgetstat(m, mci, e); + if (rcode == EX_OK) + { + strcat(tobuf, ","); + strcat(tobuf, to->q_paddr); + anyok = TRUE; + } + else + { + e->e_to = to->q_paddr; + markfailure(e, to, mci, rcode); + giveresponse(rcode, m, mci, ctladdr, xstart, e); + e->e_to = tobuf + 1; + continue; + } + } + else +# endif +#endif + { + /* mark bad addresses */ + if (rcode != EX_OK) + { + markfailure(e, to, mci, rcode); + continue; + } } /* successful delivery */ @@ -1958,6 +1988,38 @@ tryhost: } } +#ifdef SMTP +# if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + { + /* + ** Global information applies to the last recipient only; + ** clear it out to avoid bogus errors. + */ + + rcode = EX_OK; + e->e_statmsg = NULL; + + /* reset the mci state for the next transaction */ + if (mci->mci_state == MCIS_ACTIVE) + mci->mci_state = MCIS_OPEN; + } +# endif +#endif + + if (tobuf[0] != '\0') + giveresponse(rcode, m, mci, ctladdr, xstart, e); + if (anyok) + markstats(e, tochain); + mci_store_persistent(mci); + +#ifdef SMTP + /* now close the connection */ + if (clever && mci->mci_state != MCIS_CLOSED && + !bitset(MCIF_CACHED, mci->mci_flags)) + smtpquit(m, mci, e); +#endif + /* ** Restore state and return. */ @@ -2142,7 +2204,7 @@ endmailer(mci, e, pv) st = waitfor(mci->mci_pid); if (st == -1) { - syserr("endmailer %s: wait", pv[0]); + syserr("endmailer %s: wait", mci->mci_mailer->m_name); return (EX_SOFTWARE); } @@ -2951,7 +3013,7 @@ mailfile(filename, ctladdr, sfflags, e) register ENVELOPE *e; { register FILE *f; - register int pid = -1; + register pid_t pid = -1; int mode; bool suidwarn = geteuid() == 0; @@ -3146,9 +3208,9 @@ mailfile(filename, ctladdr, sfflags, e) /* reset ISUID & ISGID bits for paranoid systems */ #if HASFCHMOD - (void) fchmod(fileno(f), (int) stb.st_mode); + (void) fchmod(fileno(f), (MODE_T) stb.st_mode); #else - (void) chmod(filename, (int) stb.st_mode); + (void) chmod(filename, (MODE_T) stb.st_mode); #endif (void) xfclose(f, "mailfile", filename); (void) fflush(stdout); @@ -3259,10 +3321,10 @@ hostsignature(m, host, e) /* update the connection info for this host */ mci = mci_get(hp, m); - mci->mci_lastuse = curtime(); - mci->mci_exitstat = rcode; mci->mci_errno = errno; mci->mci_herrno = h_errno; + mci->mci_lastuse = curtime(); + mci_setstat(mci, rcode, NULL, NULL); /* use the original host name as signature */ nmx = 1; diff --git a/usr.sbin/sendmail/src/domain.c b/usr.sbin/sendmail/src/domain.c index a494baf..9203651 100644 --- a/usr.sbin/sendmail/src/domain.c +++ b/usr.sbin/sendmail/src/domain.c @@ -36,9 +36,9 @@ #ifndef lint #if NAMED_BIND -static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (with name server)"; +static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (with name server)"; #else -static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name server)"; +static char sccsid[] = "@(#)domain.c 8.64 (Berkeley) 10/30/96 (without name server)"; #endif #endif /* not lint */ @@ -48,10 +48,23 @@ static char sccsid[] = "@(#)domain.c 8.63 (Berkeley) 9/15/96 (without name serve #include <resolv.h> #include <arpa/inet.h> +/* +** The standard udp packet size PACKETSZ (512) is not sufficient for some +** nameserver answers containing very many resource records. The resolver +** may switch to tcp and retry if it detects udp packet overflow. +** Also note that the resolver routines res_query and res_search return +** the size of the *un*truncated answer in case the supplied answer buffer +** it not big enough to accommodate the entire answer. +*/ + +#ifndef MAXPACKET +# define MAXPACKET 8192 /* max packet size used internally by BIND */ +#endif + typedef union { HEADER qb1; - u_char qb2[PACKETSZ]; + u_char qb2[MAXPACKET]; } querybuf; #ifndef MXHOSTBUFSIZE @@ -206,6 +219,10 @@ getmxrr(host, mxhosts, droplocalhost, rcode) return (-1); } + /* avoid problems after truncation in tcp packets */ + if (n > sizeof(answer)) + n = sizeof(answer); + /* find first satisfactory answer */ hp = (HEADER *)&answer; cp = (u_char *)&answer + HFIXEDSZ; @@ -515,7 +532,7 @@ dns_getcanonname(host, hbsize, trymx, statp) int qtype; int loopcnt; char *xp; - char nbuf[MAX(PACKETSZ, MAXDNAME*2+2)]; + char nbuf[MAX(MAXPACKET, MAXDNAME*2+2)]; char *searchlist[MAXDNSRCH+2]; extern char *gethostalias(); @@ -648,6 +665,10 @@ cnameloop: else if (tTd(8, 7)) printf("\tYES\n"); + /* avoid problems after truncation in tcp packets */ + if (ret > sizeof(answer)) + ret = sizeof(answer); + /* ** Appear to have a match. Confirm it by searching for A or ** CNAME records. If we don't have a local domain diff --git a/usr.sbin/sendmail/src/envelope.c b/usr.sbin/sendmail/src/envelope.c index 66b9773..80e5ce6 100644 --- a/usr.sbin/sendmail/src/envelope.c +++ b/usr.sbin/sendmail/src/envelope.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)envelope.c 8.93 (Berkeley) 9/26/96"; +static char sccsid[] = "@(#)envelope.c 8.96 (Berkeley) 11/11/96"; #endif /* not lint */ #include "sendmail.h" @@ -153,9 +153,24 @@ dropenvelope(e, fulldrop) e->e_flags &= ~EF_QUEUERUN; for (q = e->e_sendqueue; q != NULL; q = q->q_next) { - if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags) || - bitset(QQUEUEUP, q->q_flags)) + if (bitset(QQUEUEUP, q->q_flags) && + bitset(QDONTSEND, q->q_flags)) + { + /* I'm not sure how this happens..... */ + if (tTd(50, 2)) + { + printf("Bogus flags: "); + printaddr(q, FALSE); + } + q->q_flags &= ~QDONTSEND; + } + if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) queueit = TRUE; +#if XDEBUG + else if (bitset(QQUEUEUP, q->q_flags)) + syslog(LOG_DEBUG, "%s: q_flags = %x", + e->e_id, q->q_flags); +#endif /* see if a notification is needed */ if (bitset(QPINGONFAILURE, q->q_flags) && @@ -203,8 +218,7 @@ dropenvelope(e, fulldrop) fprintf(e->e_xfp, "Message will be deleted from queue\n"); for (q = e->e_sendqueue; q != NULL; q = q->q_next) { - if (bitset(QQUEUEUP, q->q_flags) || - !bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) + if (!bitset(QBADADDR|QDONTSEND|QSENT, q->q_flags)) { q->q_flags |= QBADADDR; q->q_status = "4.4.7"; diff --git a/usr.sbin/sendmail/src/main.c b/usr.sbin/sendmail/src/main.c index 8947d11..29b5ac1 100644 --- a/usr.sbin/sendmail/src/main.c +++ b/usr.sbin/sendmail/src/main.c @@ -39,7 +39,7 @@ static char copyright[] = #endif /* not lint */ #ifndef lint -static char sccsid[] = "@(#)main.c 8.211 (Berkeley) 10/12/96"; +static char sccsid[] = "@(#)main.c 8.215 (Berkeley) 11/16/96"; #endif /* not lint */ #define _DEFINE @@ -387,12 +387,18 @@ main(argc, argv, envp) OpMode = MD_DELIVER; FullName = getextenv("NAME"); + /* + ** Initialize name server if it is going to be used. + */ + #if NAMED_BIND - if (tTd(8, 8)) - { + if (!bitset(RES_INIT, _res.options)) res_init(); + if (tTd(8, 8)) _res.options |= RES_DEBUG; - } +# ifdef RES_NOALIASES + _res.options |= RES_NOALIASES; +# endif #endif errno = 0; @@ -513,15 +519,7 @@ main(argc, argv, envp) { case MD_DAEMON: case MD_FGDAEMON: -# ifdef DAEMON - if (RealUid != 0) - { - usrerr("Permission denied"); - exit(EX_USAGE); - } - vendor_daemon_setup(CurEnv); - /* fall through ... */ -# else +# ifndef DAEMON usrerr("Daemon mode not implemented"); ExitStat = EX_USAGE; break; @@ -534,8 +532,6 @@ main(argc, argv, envp) # endif /* SMTP */ case MD_INITALIAS: - /* fall through ... */ - case MD_DELIVER: case MD_VERIFY: case MD_TEST: @@ -845,18 +841,6 @@ main(argc, argv, envp) } /* - ** Initialize name server if it is going to be used. - */ - -#if NAMED_BIND - if (UseNameServer && !bitset(RES_INIT, _res.options)) - res_init(); -# ifdef RES_NOALIASES - _res.options |= RES_NOALIASES; -# endif -#endif - - /* ** Do more command line checking -- these are things that ** have to modify the results of reading the config file. */ @@ -897,8 +881,8 @@ main(argc, argv, envp) /* check for sane configuration level */ if (ConfigLevel > MAXCONFIGLEVEL) { - syserr("Warning: .cf version level (%d) exceeds program functionality (%d)", - ConfigLevel, MAXCONFIGLEVEL); + syserr("Warning: .cf version level (%d) exceeds sendmail version %s functionality (%d)", + ConfigLevel, Version, MAXCONFIGLEVEL); } /* need MCI cache to have persistence */ @@ -931,6 +915,19 @@ main(argc, argv, envp) /* fall through ... */ case MD_DAEMON: + /* check for permissions */ + if (RealUid != 0) + { +#ifdef LOG + if (LogLevel > 1) + syslog(LOG_ALERT, "user %d attempted to run daemon", + RealUid); +#endif + usrerr("Permission denied"); + exit(EX_USAGE); + } + vendor_daemon_setup(CurEnv); + /* remove things that don't make sense in daemon mode */ FullName = NULL; GrabTo = FALSE; @@ -1964,6 +1961,15 @@ sighup() syslog(LOG_INFO, "restarting %s on signal", SaveArgv[0]); #endif releasesignal(SIGHUP); + if (setgid(RealGid) < 0 || setuid(RealUid) < 0) + { +#ifdef LOG + if (LogLevel > 0) + syslog(LOG_ALERT, "could not set[ug]id(%d, %d): %m", + RealUid, RealGid); +#endif + exit(EX_OSERR); + } execv(SaveArgv[0], (ARGV_T) SaveArgv); #ifdef LOG if (LogLevel > 0) diff --git a/usr.sbin/sendmail/src/map.c b/usr.sbin/sendmail/src/map.c index 796e472..34e6fce 100644 --- a/usr.sbin/sendmail/src/map.c +++ b/usr.sbin/sendmail/src/map.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96"; +static char sccsid[] = "@(#)map.c 8.144 (Berkeley) 11/16/96"; #endif /* not lint */ #include "sendmail.h" @@ -107,7 +107,7 @@ static char sccsid[] = "@(#)map.c 8.140 (Berkeley) 10/12/96"; extern bool aliaswait __P((MAP *, char *, int)); extern bool extract_canonname __P((char *, char *, char[], int)); -#if defined(O_EXLOCK) && HASFLOCK +#if O_EXLOCK && HASFLOCK # define LOCK_ON_OPEN 1 /* we can open/create a locked file */ #else # define LOCK_ON_OPEN 0 /* no such luck -- bend over backwards */ @@ -690,6 +690,8 @@ extract_canonname(name, line, cbuf, cbuflen) p = get_column(line, i, '\0', nbuf, sizeof nbuf); if (p == NULL) break; + if (*p == '\0') + continue; if (cbuf[0] == '\0' || (strchr(cbuf, '.') == NULL && strchr(p, '.') != NULL)) { @@ -1034,17 +1036,30 @@ ndbm_map_close(map) ** be pokey about it. That's hard to do. */ -extern bool db_map_open __P((MAP *, int, DBTYPE)); +extern bool db_map_open __P((MAP *, int, DBTYPE, const void *)); + +/* these should be K line arguments */ +#ifndef DB_CACHE_SIZE +# define DB_CACHE_SIZE (1024 * 1024) /* database memory cache size */ +#endif +#ifndef DB_HASH_NELEM +# define DB_HASH_NELEM 4096 /* (starting) size of hash table */ +#endif bool bt_map_open(map, mode) MAP *map; int mode; { + BTREEINFO btinfo; + if (tTd(38, 2)) printf("bt_map_open(%s, %s, %d)\n", map->map_mname, map->map_file, mode); - return db_map_open(map, mode, DB_BTREE); + + bzero(&btinfo, sizeof btinfo); + btinfo.cachesize = DB_CACHE_SIZE; + return db_map_open(map, mode, DB_BTREE, &btinfo); } bool @@ -1052,17 +1067,24 @@ hash_map_open(map, mode) MAP *map; int mode; { + HASHINFO hinfo; + if (tTd(38, 2)) printf("hash_map_open(%s, %s, %d)\n", map->map_mname, map->map_file, mode); - return db_map_open(map, mode, DB_HASH); + + bzero(&hinfo, sizeof hinfo); + hinfo.nelem = DB_HASH_NELEM; + hinfo.cachesize = DB_CACHE_SIZE; + return db_map_open(map, mode, DB_HASH, &hinfo); } bool -db_map_open(map, mode, dbtype) +db_map_open(map, mode, dbtype, openinfo) MAP *map; int mode; DBTYPE dbtype; + const void *openinfo; { DB *db; int i; @@ -1113,7 +1135,7 @@ db_map_open(map, mode, dbtype) omode |= O_TRUNC; #endif - db = dbopen(buf, omode, DBMMODE, dbtype, NULL); + db = dbopen(buf, omode, DBMMODE, dbtype, openinfo); saveerrno = errno; #if !LOCK_ON_OPEN diff --git a/usr.sbin/sendmail/src/mci.c b/usr.sbin/sendmail/src/mci.c index f901ea8..18e951a 100644 --- a/usr.sbin/sendmail/src/mci.c +++ b/usr.sbin/sendmail/src/mci.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)mci.c 8.44 (Berkeley) 10/9/96"; +static char sccsid[] = "@(#)mci.c 8.46 (Berkeley) 11/3/96"; #endif /* not lint */ #include "sendmail.h" @@ -362,6 +362,7 @@ mci_get(host, m) ** ** Parameters: ** mci -- the MCI structure to set. +** xstat -- the exit status code. ** dstat -- the DSN status code. ** rstat -- the SMTP status code. ** @@ -370,18 +371,19 @@ mci_get(host, m) */ void -mci_setstat(mci, dstat, rstat) +mci_setstat(mci, xstat, dstat, rstat) MCI *mci; + int xstat; char *dstat; char *rstat; { + mci->mci_exitstat = xstat; mci->mci_status = dstat; + if (mci->mci_rstatus != NULL) + free(mci->mci_rstatus); if (rstat != NULL) - { - if (mci->mci_rstatus != NULL) - free(mci->mci_rstatus); - mci->mci_rstatus = newstr(rstat); - } + rstat = newstr(rstat); + mci->mci_rstatus = rstat; } /* ** MCI_DUMP -- dump the contents of an MCI structure. @@ -1032,6 +1034,7 @@ mci_print_persistent(pathname, hostname) int status; int width = Verbose ? 78 : 25; bool locked; + char *p; MCI mcib; if (!initflag) @@ -1061,16 +1064,34 @@ mci_print_persistent(pathname, hostname) locked = !lockfile(fileno(fp), pathname, "", LOCK_EX|LOCK_NB); fclose(fp); - if (mcib.mci_rstatus == NULL) - printf("%c%-39s %12s %.*s\n", - locked ? '*' : ' ', hostname, - pintvl(curtime() - mcib.mci_lastuse, TRUE), - width, errstring(mcib.mci_errno)); + printf("%c%-39s %12s ", + locked ? '*' : ' ', hostname, + pintvl(curtime() - mcib.mci_lastuse, TRUE)); + if (mcib.mci_rstatus != NULL) + printf("%.*s\n", width, mcib.mci_rstatus); + else if (mcib.mci_exitstat == EX_TEMPFAIL && mcib.mci_errno != 0) + printf("Deferred: %.*s\n", width - 10, errstring(mcib.mci_errno)); + else if (mcib.mci_exitstat != 0) + { + int i = mcib.mci_exitstat - EX__BASE; + extern int N_SysEx; + extern char *SysExMsg[]; + + if (i < 0 || i > N_SysEx) + { + char buf[80]; + + snprintf(buf, sizeof buf, "Unknown mailer error %d", + mcib.mci_exitstat); + printf("%.*s\n", width, buf); + } + else + printf("%.*s\n", width, &(SysExMsg[i])[5]); + } + else if (mcib.mci_errno == 0) + printf("OK\n"); else - printf("%c%-39s %12s %.*s\n", - locked ? '*' : ' ', hostname, - pintvl(curtime() - mcib.mci_lastuse, TRUE), - width, mcib.mci_rstatus); + printf("OK: %.*s\n", width - 4, errstring(mcib.mci_errno)); return 0; } diff --git a/usr.sbin/sendmail/src/mime.c b/usr.sbin/sendmail/src/mime.c index 670a6cd..9ee726a 100644 --- a/usr.sbin/sendmail/src/mime.c +++ b/usr.sbin/sendmail/src/mime.c @@ -36,7 +36,7 @@ # include <string.h> #ifndef lint -static char sccsid[] = "@(#)mime.c 8.48 (Berkeley) 10/18/96"; +static char sccsid[] = "@(#)mime.c 8.49 (Berkeley) 10/30/96"; #endif /* not lint */ /* @@ -932,9 +932,23 @@ isboundary(line, boundaries) ** none. */ -extern void mime_from64 __P((u_char *, u_char *, int)); extern int mime_fromqp __P((u_char *, u_char **, int, int)); +static char index_64[128] = +{ + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, + -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, + 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, + -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, + 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, + -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, + 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 +}; + +#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) + + void mime7to8(mci, header, e) register MCI *mci; @@ -996,29 +1010,82 @@ mime7to8(mci, header, e) if (strcasecmp(cte, "base64") == 0) { + int nchar = 0; + int c1, c2, c3, c4; + fbufp = fbuf; - while (fgets(buf, sizeof buf, e->e_dfp) != NULL) + while ((c1 = fgetc(e->e_dfp)) != EOF) { - obufp = obuf; - mime_from64((u_char *) buf, obuf, MAXLINE); - while ((ch = *obufp++) != '\0') + if (isascii(c1) && isspace(c1)) + continue; + + do { - *fbufp++ = ch; - if (ch == '\n' || fbufp >= &fbuf[MAXLINE]) - { - *fbufp = '\0'; - putline((char *) fbuf, mci); - fbufp = fbuf; - } - } + c2 = fgetc(e->e_dfp); + } while (isascii(c2) && isspace(c2)); + if (c2 == EOF) + break; - /* force out partial last line */ - if (fbufp > fbuf) + do { + c3 = fgetc(e->e_dfp); + } while (isascii(c3) && isspace(c3)); + if (c3 == EOF) + break; + + do + { + c4 = fgetc(e->e_dfp); + } while (isascii(c4) && isspace(c4)); + if (c4 == EOF) + break; + + if (c1 == '=' || c2 == '=') + continue; + c1 = CHAR64(c1); + c2 = CHAR64(c2); + + *fbufp = (c1 << 2) | ((c2 & 0x30) >> 4); + if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE]) + { + if (*--fbufp != '\n' || *--fbufp != '\r') + fbufp++; + *fbufp = '\0'; + putline((char *) fbuf, mci); + fbufp = fbuf; + } + if (c3 == '=') + continue; + c3 = CHAR64(c3); + *fbufp = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); + if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE]) + { + if (*--fbufp != '\n' || *--fbufp != '\r') + fbufp++; + *fbufp = '\0'; + putline((char *) fbuf, mci); + fbufp = fbuf; + } + if (c4 == '=') + continue; + c4 = CHAR64(c4); + *fbufp = ((c3 & 0x03) << 6) | c4; + if (*fbufp++ == '\n' || fbuf >= &fbuf[MAXLINE]) + { + if (*--fbufp != '\n' || *--fbufp != '\r') + fbufp++; *fbufp = '\0'; putline((char *) fbuf, mci); + fbufp = fbuf; } } + + /* force out partial last line */ + if (fbufp > fbuf) + { + *fbufp = '\0'; + putline((char *) fbuf, mci); + } } else { @@ -1113,89 +1180,5 @@ mime_fromqp(infile, outfile, state, maxlen) return 1; } -static char index_64[128] = -{ - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, - -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63, - 52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1,-1,-1,-1, - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14, - 15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1, - -1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40, - 41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1 -}; - -#define CHAR64(c) (((c) < 0 || (c) > 127) ? -1 : index_64[(c)]) - -void -mime_from64(infile, outfile, maxlen) - u_char *infile; - u_char *outfile; - int maxlen; -{ - int nchar = 0; - int c1, c2, c3, c4; - - while ((c1 = *infile++) != '\0') - { - if (isascii(c1) && isspace(c1)) - continue; - - do - { - c2 = *infile++; - } while (isascii(c2) && isspace(c2)); - if (c2 == '\0') - break; - - do - { - c3 = *infile++; - } while (isascii(c3) && isspace(c3)); - if (c3 == '\0') - break; - - do - { - c4 = *infile++; - } while (isascii(c4) && isspace(c4)); - if (c4 == '\0') - break; - - if (c1 == '=' || c2 == '=') - { - continue; - } - c1 = CHAR64(c1); - c2 = CHAR64(c2); - - if (++nchar > maxlen) - break; - - *outfile++ = (c1 << 2) | ((c2 & 0x30) >> 4); - - if (c3 != '=') - { - c3 = CHAR64(c3); - - if (++nchar > maxlen) - break; - - *outfile++ = ((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2); - if (c4 != '=') - { - c4 = CHAR64(c4); - - if (++nchar > maxlen) - break; - - *outfile++ = ((c3 & 0x03) << 6) | c4; - } - } - } - - *outfile = '\0'; - return; -} #endif /* MIME7TO8 */ diff --git a/usr.sbin/sendmail/src/queue.c b/usr.sbin/sendmail/src/queue.c index 75263b7..299a016 100644 --- a/usr.sbin/sendmail/src/queue.c +++ b/usr.sbin/sendmail/src/queue.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef QUEUE -static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (with queueing)"; +static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (with queueing)"; #else -static char sccsid[] = "@(#)queue.c 8.125 (Berkeley) 10/12/96 (without queueing)"; +static char sccsid[] = "@(#)queue.c 8.131 (Berkeley) 11/8/96 (without queueing)"; #endif #endif /* not lint */ @@ -296,40 +296,45 @@ queueup(e, announce) printctladdr(NULL, NULL); for (q = e->e_sendqueue; q != NULL; q = q->q_next) { - if (bitset(QQUEUEUP, q->q_flags) || - !bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags)) + if (bitset(QDONTSEND|QBADADDR|QSENT, q->q_flags)) { - printctladdr(q, tfp); - if (q->q_orcpt != NULL) - fprintf(tfp, "Q%s\n", - denlstring(q->q_orcpt, TRUE, FALSE)); - putc('R', tfp); - if (bitset(QPRIMARY, q->q_flags)) - putc('P', tfp); - if (bitset(QHASNOTIFY, q->q_flags)) - putc('N', tfp); - if (bitset(QPINGONSUCCESS, q->q_flags)) - putc('S', tfp); - if (bitset(QPINGONFAILURE, q->q_flags)) - putc('F', tfp); - if (bitset(QPINGONDELAY, q->q_flags)) - putc('D', tfp); - putc(':', tfp); - fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE)); - if (announce) - { - e->e_to = q->q_paddr; - message("queued"); - if (LogLevel > 8) - logdelivery(q->q_mailer, NULL, "queued", - NULL, (time_t) 0, e); - e->e_to = NULL; - } - if (tTd(40, 1)) - { - printf("queueing "); - printaddr(q, FALSE); - } +#if XDEBUG + if (bitset(QQUEUEUP, q->q_flags)) + syslog(LOG_DEBUG, "%s: q_flags = %x", + e->e_id, q->q_flags); +#endif + continue; + } + printctladdr(q, tfp); + if (q->q_orcpt != NULL) + fprintf(tfp, "Q%s\n", + denlstring(q->q_orcpt, TRUE, FALSE)); + putc('R', tfp); + if (bitset(QPRIMARY, q->q_flags)) + putc('P', tfp); + if (bitset(QHASNOTIFY, q->q_flags)) + putc('N', tfp); + if (bitset(QPINGONSUCCESS, q->q_flags)) + putc('S', tfp); + if (bitset(QPINGONFAILURE, q->q_flags)) + putc('F', tfp); + if (bitset(QPINGONDELAY, q->q_flags)) + putc('D', tfp); + putc(':', tfp); + fprintf(tfp, "%s\n", denlstring(q->q_paddr, TRUE, FALSE)); + if (announce) + { + e->e_to = q->q_paddr; + message("queued"); + if (LogLevel > 8) + logdelivery(q->q_mailer, NULL, "queued", + NULL, (time_t) 0, e); + e->e_to = NULL; + } + if (tTd(40, 1)) + { + printf("queueing "); + printaddr(q, FALSE); } } @@ -574,7 +579,7 @@ runqueue(forkflag) if (forkflag) { - int pid; + pid_t pid; extern void intsig(); #ifdef SIGCHLD extern void reapchild(); @@ -625,6 +630,15 @@ runqueue(forkflag) /* force it to run expensive jobs */ NoConnect = FALSE; + /* drop privileges */ + if (geteuid() == (uid_t) 0) + { + if (RunAsGid != (gid_t) 0) + (void) setgid(RunAsGid); + if (RunAsUid != (uid_t) 0) + (void) setuid(RunAsUid); + } + /* ** Create ourselves an envelope */ @@ -1387,6 +1401,7 @@ readqf(e) struct stat st; char *bp; int qfver = 0; + long hdrsize = 0; register char *p; char *orcpt = NULL; bool nomore = FALSE; @@ -1579,6 +1594,7 @@ readqf(e) case 'H': /* header */ (void) chompheader(&bp[1], FALSE, NULL, e); + hdrsize += strlen(&bp[1]); break; case 'M': /* message */ @@ -1611,6 +1627,26 @@ readqf(e) case 'N': /* number of delivery attempts */ e->e_ntries = atoi(&buf[1]); + + /* if this has been tried recently, let it be */ + if (e->e_ntries > 0 && + (curtime() - e->e_dtime) < MinQueueAge) + { + char *howlong = pintvl(curtime() - e->e_dtime, TRUE); + extern void unlockqueue(); + + if (Verbose || tTd(40, 8)) + printf("%s: too young (%s)\n", + e->e_id, howlong); +#ifdef LOG + if (LogLevel > 19) + syslog(LOG_DEBUG, "%s: too young (%s)", + e->e_id, howlong); +#endif + e->e_id = NULL; + unlockqueue(e); + return FALSE; + } break; case 'P': /* message priority */ @@ -1694,25 +1730,6 @@ readqf(e) return TRUE; } - /* if this has been tried recently, let it be */ - if (e->e_ntries > 0 && (curtime() - e->e_dtime) < MinQueueAge) - { - char *howlong = pintvl(curtime() - e->e_dtime, TRUE); - extern void unlockqueue(); - - if (Verbose || tTd(40, 8)) - printf("%s: too young (%s)\n", - e->e_id, howlong); -#ifdef LOG - if (LogLevel > 19) - syslog(LOG_DEBUG, "%s: too young (%s)", - e->e_id, howlong); -#endif - e->e_id = NULL; - unlockqueue(e); - return FALSE; - } - /* ** Arrange to read the data file. */ @@ -1728,7 +1745,7 @@ readqf(e) e->e_flags |= EF_HAS_DF; if (fstat(fileno(e->e_dfp), &st) >= 0) { - e->e_msgsize = st.st_size; + e->e_msgsize = st.st_size + hdrsize; e->e_dfdev = st.st_dev; e->e_dfino = st.st_ino; } @@ -1971,7 +1988,7 @@ queuename(e, type) register ENVELOPE *e; int type; { - static int pid = -1; + static pid_t pid = -1; static char c0; static char c1; static char c2; diff --git a/usr.sbin/sendmail/src/readcf.c b/usr.sbin/sendmail/src/readcf.c index e3cb3a1..c95a6f3 100644 --- a/usr.sbin/sendmail/src/readcf.c +++ b/usr.sbin/sendmail/src/readcf.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)readcf.c 8.174 (Berkeley) 10/9/96"; +static char sccsid[] = "@(#)readcf.c 8.176 (Berkeley) 11/10/96"; #endif /* not lint */ # include "sendmail.h" @@ -715,7 +715,7 @@ fileclass(class, filename, fmt, safe, optional) { FILE *f; int sff; - int pid; + pid_t pid; register char *p; char buf[MAXLINE]; @@ -1024,6 +1024,10 @@ makemailer(line) m->m_uid = strtol(p, &q, 0); p = q; + while (isascii(*p) && isspace(*p)) + p++; + if (*p != '\0') + p++; } while (isascii(*p) && isspace(*p)) p++; diff --git a/usr.sbin/sendmail/src/sendmail.h b/usr.sbin/sendmail/src/sendmail.h index 62b0bb9..2dc30e4 100644 --- a/usr.sbin/sendmail/src/sendmail.h +++ b/usr.sbin/sendmail/src/sendmail.h @@ -31,7 +31,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * @(#)sendmail.h 8.206 (Berkeley) 10/17/96 + * @(#)sendmail.h 8.209 (Berkeley) 11/8/96 */ /* @@ -41,7 +41,7 @@ # ifdef _DEFINE # define EXTERN # ifndef lint -static char SmailSccsId[] = "@(#)sendmail.h 8.206 10/17/96"; +static char SmailSccsId[] = "@(#)sendmail.h 8.209 11/8/96"; # endif # else /* _DEFINE */ # define EXTERN extern @@ -275,6 +275,7 @@ struct mailer # define M_HASPWENT 'w' /* check for /etc/passwd entry */ /* 'x' CF: include Full-Name: */ # define M_XDOT 'X' /* use hidden-dot algorithm */ +# define M_LMTP 'z' /* run Local Mail Transport Protocol */ # define M_NOMX '0' /* turn off MX lookups */ # define M_EBCDIC '3' /* extend Q-P encoding for EBCDIC */ # define M_TRYRULESET5 '5' /* use ruleset 5 after local aliasing */ @@ -310,7 +311,7 @@ MCI long mci_maxsize; /* max size this server will accept */ FILE *mci_in; /* input side of connection */ FILE *mci_out; /* output side of connection */ - int mci_pid; /* process id of subordinate proc */ + pid_t mci_pid; /* process id of subordinate proc */ char *mci_phase; /* SMTP phase string */ struct mailer *mci_mailer; /* ptr to the mailer for this conn */ char *mci_host; /* host name */ @@ -1095,7 +1096,7 @@ EXTERN gid_t RealGid; /* real gid of caller */ EXTERN uid_t DefUid; /* default uid to run as */ EXTERN gid_t DefGid; /* default gid to run as */ EXTERN char *DefUser; /* default user to run as (from DefUid) */ -EXTERN int OldUmask; /* umask when sendmail starts up */ +EXTERN MODE_T OldUmask; /* umask when sendmail starts up */ EXTERN int Errors; /* set if errors (local to single pass) */ EXTERN int ExitStat; /* exit status code */ EXTERN int LineNumber; /* line number in current input */ @@ -1303,7 +1304,7 @@ extern void inittimeouts __P((char *)); extern void logdelivery __P((MAILER *, MCI *, const char *, ADDRESS *, time_t, ENVELOPE *)); extern void giveresponse __P((int, MAILER *, MCI *, ADDRESS *, time_t, ENVELOPE *)); extern void buildfname __P((char *, char *, char *, int)); -extern void mci_setstat __P((MCI *, char *, char *)); +extern void mci_setstat __P((MCI *, int, char *, char *)); extern char *smtptodsn __P((int)); extern int rscheck __P((char *, char *, char *, ENVELOPE *e)); extern void mime7to8 __P((MCI *, HDR *, ENVELOPE *)); diff --git a/usr.sbin/sendmail/src/srvrsmtp.c b/usr.sbin/sendmail/src/srvrsmtp.c index cda3ca8..062acde 100644 --- a/usr.sbin/sendmail/src/srvrsmtp.c +++ b/usr.sbin/sendmail/src/srvrsmtp.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (with SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (with SMTP)"; #else -static char sccsid[] = "@(#)srvrsmtp.c 8.123 (Berkeley) 10/12/96 (without SMTP)"; +static char sccsid[] = "@(#)srvrsmtp.c 8.125 (Berkeley) 11/8/96 (without SMTP)"; #endif #endif /* not lint */ @@ -1270,10 +1270,20 @@ runinchild(label, e) char *label; register ENVELOPE *e; { - int childpid; + pid_t childpid; + sigfunc_t chldsig; if (!OneXact) { + /* + ** Disable child process reaping, in case ETRN has preceeded + ** MAIL command. + */ + +#ifdef SIGCHLD + chldsig = setsignal(SIGCHLD, SIG_IGN); +#endif + childpid = dofork(); if (childpid < 0) { @@ -1300,6 +1310,11 @@ runinchild(label, e) finis(); } +#ifdef SIGCHLD + /* restore the child signal */ + (void) setsignal(SIGCHLD, chldsig); +#endif + return (1); } else diff --git a/usr.sbin/sendmail/src/usersmtp.c b/usr.sbin/sendmail/src/usersmtp.c index 1b684fb..1be0d84 100644 --- a/usr.sbin/sendmail/src/usersmtp.c +++ b/usr.sbin/sendmail/src/usersmtp.c @@ -36,9 +36,9 @@ #ifndef lint #ifdef SMTP -static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (with SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (with SMTP)"; #else -static char sccsid[] = "@(#)usersmtp.c 8.72 (Berkeley) 9/15/96 (without SMTP)"; +static char sccsid[] = "@(#)usersmtp.c 8.75 (Berkeley) 11/6/96 (without SMTP)"; #endif #endif /* not lint */ @@ -143,8 +143,10 @@ smtpinit(m, mci, e) SmtpPhase = mci->mci_phase = "client greeting"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); r = reply(m, mci, e, TimeOuts.to_initial, esmtp_check); - if (r < 0 || REPLYTYPE(r) == 4) + if (r < 0) goto tempfail1; + if (REPLYTYPE(r) == 4) + goto tempfail2; if (REPLYTYPE(r) != 2) goto unavailable; @@ -153,11 +155,24 @@ smtpinit(m, mci, e) ** My mother taught me to always introduce myself. */ +#if FFR_LMTP + if (bitnset(M_ESMTP, m->m_flags) || bitnset(M_LMTP, m->m_flags)) +#else if (bitnset(M_ESMTP, m->m_flags)) +#endif mci->mci_flags |= MCIF_ESMTP; tryhelo: +#if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + { + smtpmessage("LHLO %s", m, mci, MyHostName); + SmtpPhase = mci->mci_phase = "client LHLO"; + } + else if (bitset(MCIF_ESMTP, mci->mci_flags)) +#else if (bitset(MCIF_ESMTP, mci->mci_flags)) +#endif { smtpmessage("EHLO %s", m, mci, MyHostName); SmtpPhase = mci->mci_phase = "client EHLO"; @@ -173,7 +188,12 @@ tryhelo: goto tempfail1; else if (REPLYTYPE(r) == 5) { +#if FFR_LMTP + if (bitset(MCIF_ESMTP, mci->mci_flags) && + !bitnset(M_LMTP, m->m_flags)) +#else if (bitset(MCIF_ESMTP, mci->mci_flags)) +#endif { /* try old SMTP instead */ mci->mci_flags &= ~MCIF_ESMTP; @@ -182,7 +202,7 @@ tryhelo: goto unavailable; } else if (REPLYTYPE(r) != 2) - goto tempfail1; + goto tempfail2; /* ** Check to see if we actually ended up talking to ourself. @@ -194,11 +214,14 @@ tryhelo: if (p != NULL) *p = '\0'; if (!bitnset(M_NOLOOPCHECK, m->m_flags) && +#if FFR_LMTP + !bitnset(M_LMTP, m->m_flags) && +#endif strcasecmp(&SmtpReplyBuffer[4], MyHostName) == 0) { syserr("553 %s config error: mail loops back to me (MX problem?)", mci->mci_host); - mci->mci_exitstat = EX_CONFIG; + mci_setstat(mci, EX_CONFIG, NULL, NULL); mci->mci_errno = 0; smtpquit(m, mci, e); return; @@ -215,7 +238,7 @@ tryhelo: smtpmessage("VERB", m, mci); r = reply(m, mci, e, TimeOuts.to_miscshort, NULL); if (r < 0) - goto tempfail2; + goto tempfail1; } if (mci->mci_state != MCIS_CLOSED) @@ -227,17 +250,25 @@ tryhelo: /* got a 421 error code during startup */ tempfail1: + if (mci->mci_errno == 0) + mci->mci_errno = errno; + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); + if (mci->mci_state != MCIS_CLOSED) + smtpquit(m, mci, e); + return; + tempfail2: - mci->mci_exitstat = EX_TEMPFAIL; if (mci->mci_errno == 0) mci->mci_errno = errno; + /* XXX should use code from other end iff ENHANCEDSTATUSCODES */ + mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer); if (mci->mci_state != MCIS_CLOSED) smtpquit(m, mci, e); return; unavailable: - mci->mci_exitstat = EX_UNAVAILABLE; mci->mci_errno = errno; + mci_setstat(mci, EX_UNAVAILABLE, "5.5.0", SmtpReplyBuffer); smtpquit(m, mci, e); return; } @@ -387,7 +418,7 @@ smtpmailfrom(m, mci, e) extern char MsgBuf[]; usrerr("%s does not support 8BITMIME", mci->mci_host); - mci_setstat(mci, "5.6.3", MsgBuf); + mci_setstat(mci, EX_DATAERR, "5.6.3", MsgBuf); return EX_DATAERR; } @@ -447,17 +478,24 @@ smtpmailfrom(m, mci, e) SmtpPhase = mci->mci_phase = "client MAIL"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); r = reply(m, mci, e, TimeOuts.to_mail, NULL); - if (r < 0 || r == 421) + if (r < 0) { - /* communications failure/service shutting down */ - mci->mci_exitstat = EX_TEMPFAIL; + /* communications failure */ mci->mci_errno = errno; + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + else if (r == 421) + { + /* service shutting down */ + mci_setstat(mci, EX_TEMPFAIL, "4.5.0", SmtpReplyBuffer); smtpquit(m, mci, e); return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 4) { - mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer); + mci_setstat(mci, EX_TEMPFAIL, smtptodsn(r), SmtpReplyBuffer); return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 2) @@ -467,25 +505,25 @@ smtpmailfrom(m, mci, e) else if (r == 501) { /* syntax error in arguments */ - mci_setstat(mci, "5.5.2", SmtpReplyBuffer); + mci_setstat(mci, EX_DATAERR, "5.5.2", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 553) { /* mailbox name not allowed */ - mci_setstat(mci, "5.1.3", SmtpReplyBuffer); + mci_setstat(mci, EX_DATAERR, "5.1.3", SmtpReplyBuffer); return EX_DATAERR; } else if (r == 552) { /* exceeded storage allocation */ - mci_setstat(mci, "5.2.2", SmtpReplyBuffer); + mci_setstat(mci, EX_UNAVAILABLE, "5.2.2", SmtpReplyBuffer); return EX_UNAVAILABLE; } else if (REPLYTYPE(r) == 5) { /* unknown error */ - mci_setstat(mci, "5.0.0", SmtpReplyBuffer); + mci_setstat(mci, EX_UNAVAILABLE, "5.0.0", SmtpReplyBuffer); return EX_UNAVAILABLE; } @@ -499,7 +537,7 @@ smtpmailfrom(m, mci, e) #endif /* protocol error -- close up */ - mci_setstat(mci, "5.5.1", SmtpReplyBuffer); + mci_setstat(mci, EX_PROTOCOL, "5.5.1", SmtpReplyBuffer); smtpquit(m, mci, e); return EX_PROTOCOL; } @@ -536,7 +574,8 @@ smtprcpt(to, m, mci, e) { /* NOTIFY= parameter */ if (bitset(QHASNOTIFY, to->q_flags) && - bitset(QPRIMARY, to->q_flags)) + bitset(QPRIMARY, to->q_flags) && + !bitnset(M_LOCALMAILER, m->m_flags)) { bool firstone = TRUE; @@ -622,6 +661,7 @@ smtprcpt(to, m, mci, e) ** ** Parameters: ** m -- mailer being sent to. +** mci -- the mailer connection information. ** e -- the envelope for this message. ** ** Returns: @@ -642,6 +682,7 @@ smtpdata(m, mci, e) { register int r; register EVENT *ev; + int rstat; time_t timeout; /* @@ -690,8 +731,8 @@ smtpdata(m, mci, e) if (setjmp(CtxDataTimeout) != 0) { mci->mci_errno = errno; - mci->mci_exitstat = EX_TEMPFAIL; mci->mci_state = MCIS_ERROR; + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); syserr("451 timeout writing message to %s", mci->mci_host); smtpquit(m, mci, e); return EX_TEMPFAIL; @@ -720,8 +761,8 @@ smtpdata(m, mci, e) { /* error during processing -- don't send the dot */ mci->mci_errno = EIO; - mci->mci_exitstat = EX_IOERR; mci->mci_state = MCIS_ERROR; + mci_setstat(mci, EX_IOERR, "4.4.2", NULL); smtpquit(m, mci, e); return EX_IOERR; } @@ -734,8 +775,12 @@ smtpdata(m, mci, e) nmessage(">>> ."); /* check for the results of the transaction */ - SmtpPhase = mci->mci_phase = "client DATA 250"; + SmtpPhase = mci->mci_phase = "client DATA status"; setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase); +#if FFR_LMTP + if (bitnset(M_LMTP, m->m_flags)) + return EX_OK; +#endif r = reply(m, mci, e, TimeOuts.to_datafinal, NULL); if (r < 0) { @@ -743,16 +788,22 @@ smtpdata(m, mci, e) return EX_TEMPFAIL; } mci->mci_state = MCIS_OPEN; - mci_setstat(mci, smtptodsn(r), SmtpReplyBuffer); - e->e_statmsg = newstr(&SmtpReplyBuffer[4]); if (REPLYTYPE(r) == 4) - return EX_TEMPFAIL; + rstat = EX_TEMPFAIL; else if (REPLYCLASS(r) != 5) - /* fall through */ ; + rstat = EX_PROTOCOL; else if (REPLYTYPE(r) == 2) - return EX_OK; + rstat = EX_OK; else if (REPLYTYPE(r) == 5) - return EX_UNAVAILABLE; + rstat = EX_UNAVAILABLE; + else + rstat = EX_PROTOCOL; + mci_setstat(mci, rstat, smtptodsn(r), SmtpReplyBuffer); + if (e->e_statmsg != NULL) + free(e->e_statmsg); + e->e_statmsg = newstr(&SmtpReplyBuffer[4]); + if (rstat != EX_PROTOCOL) + return rstat; #ifdef LOG if (LogLevel > 1) { @@ -761,7 +812,7 @@ smtpdata(m, mci, e) shortenstring(SmtpReplyBuffer, 403)); } #endif - return EX_PROTOCOL; + return rstat; } @@ -771,10 +822,66 @@ datatimeout() longjmp(CtxDataTimeout, 1); } /* +** SMTPGETSTAT -- get status code from DATA in LMTP +** +** Parameters: +** m -- the mailer to which we are sending the message. +** mci -- the mailer connection structure. +** e -- the current envelope. +** +** Returns: +** The exit status corresponding to the reply code. +*/ + +#if FFR_LMTP + +int +smtpgetstat(m, mci, e) + MAILER *m; + MCI *mci; + ENVELOPE *e; +{ + int r; + int stat; + + /* check for the results of the transaction */ + r = reply(m, mci, e, TimeOuts.to_datafinal, NULL); + if (r < 0) + { + smtpquit(m, mci, e); + return EX_TEMPFAIL; + } + if (e->e_statmsg != NULL) + free(e->e_statmsg); + e->e_statmsg = newstr(&SmtpReplyBuffer[4]); + if (REPLYTYPE(r) == 4) + stat = EX_TEMPFAIL; + else if (REPLYCLASS(r) != 5) + stat = EX_PROTOCOL; + else if (REPLYTYPE(r) == 2) + stat = EX_OK; + else if (REPLYTYPE(r) == 5) + stat = EX_UNAVAILABLE; + mci_setstat(mci, stat, smtptodsn(r), SmtpReplyBuffer); +#ifdef LOG + if (LogLevel > 1 && stat == EX_PROTOCOL) + { + syslog(LOG_CRIT, "%s: %.100s: SMTP DATA-3 protocol error: %s", + e->e_id, mci->mci_host, + shortenstring(SmtpReplyBuffer, 403)); + } +#endif + return stat; +} + +#endif +/* ** SMTPQUIT -- close the SMTP connection. ** ** Parameters: ** m -- a pointer to the mailer. +** mci -- the mailer connection information. +** e -- the current envelope. ** ** Returns: ** none. @@ -927,6 +1034,7 @@ reply(m, mci, e, timeout, pfunc) if (p == NULL) { bool oldholderrs; + extern char MsgBuf[]; /* if the remote end closed early, fake an error */ if (errno == 0) @@ -937,10 +1045,10 @@ reply(m, mci, e, timeout, pfunc) # endif /* ECONNRESET */ mci->mci_errno = errno; - mci->mci_exitstat = EX_TEMPFAIL; oldholderrs = HoldErrs; HoldErrs = TRUE; usrerr("451 reply: read error from %s", mci->mci_host); + mci_setstat(mci, EX_TEMPFAIL, "4.4.2", MsgBuf); /* if debugging, pause so we can see state */ if (tTd(18, 100)) diff --git a/usr.sbin/sendmail/src/util.c b/usr.sbin/sendmail/src/util.c index 49d2a65..822aaf35 100644 --- a/usr.sbin/sendmail/src/util.c +++ b/usr.sbin/sendmail/src/util.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)util.c 8.105 (Berkeley) 10/12/96"; +static char sccsid[] = "@(#)util.c 8.109 (Berkeley) 11/16/96"; #endif /* not lint */ # include "sendmail.h" @@ -1012,6 +1012,15 @@ putxline(l, mci, pxflags) if (TrafficLogFile != NULL) (void) putc('.', TrafficLogFile); } + else if (l[0] == 'F' && slop == 0 && + bitset(PXLF_MAPFROM, pxflags) && + strncmp(l, "From ", 5) == 0 && + bitnset(M_ESCFROM, mci->mci_mailer->m_flags)) + { + (void) putc('>', mci->mci_out); + if (TrafficLogFile != NULL) + (void) putc('>', TrafficLogFile); + } if (TrafficLogFile != NULL) fprintf(TrafficLogFile, "%.*s\n", p - l, l); for ( ; l < p; ++l) @@ -2197,6 +2206,7 @@ proc_list_add(pid) pid_t pid; { int i; + extern void proc_list_probe __P((void)); for (i = 0; i < ProcListSize; i++) { @@ -2205,6 +2215,18 @@ proc_list_add(pid) } if (i >= ProcListSize) { + /* probe the existing vector to avoid growing infinitely */ + proc_list_probe(); + + /* now scan again */ + for (i = 0; i < ProcListSize; i++) + { + if (ProcListVec[i] == NO_PID) + break; + } + } + if (i >= ProcListSize) + { /* grow process list */ pid_t *npv; @@ -2244,8 +2266,42 @@ proc_list_drop(pid) if (ProcListVec[i] == pid) { ProcListVec[i] = NO_PID; - CurChildren--; break; } } + if (CurChildren > 0) + CurChildren--; +} +/* +** PROC_LIST_PROBE -- probe processes in the list to see if they still exist +** +** Parameters: +** none +** +** Returns: +** none +*/ + +void +proc_list_probe() +{ + int i; + + for (i = 0; i < ProcListSize; i++) + { + if (ProcListVec[i] == NO_PID) + continue; + if (kill(ProcListVec[i], 0) < 0) + { +#ifdef LOG + if (LogLevel > 3) + syslog(LOG_DEBUG, "proc_list_probe: lost pid %d", + ProcListVec[i]); +#endif + ProcListVec[i] = NO_PID; + CurChildren--; + } + } + if (CurChildren < 0) + CurChildren = 0; } diff --git a/usr.sbin/sendmail/src/version.c b/usr.sbin/sendmail/src/version.c index 7544a9a..8a53f29 100644 --- a/usr.sbin/sendmail/src/version.c +++ b/usr.sbin/sendmail/src/version.c @@ -33,7 +33,7 @@ */ #ifndef lint -static char sccsid[] = "@(#)version.c 8.8.2.1 (Berkeley) 10/18/96"; +static char sccsid[] = "@(#)version.c 8.8.3.2 (Berkeley) 11/16/96"; #endif /* not lint */ -char Version[] = "8.8.2"; +char Version[] = "8.8.3"; diff --git a/usr.sbin/sendmail/test/Results b/usr.sbin/sendmail/test/Results index 31a6771..9645d73 100644 --- a/usr.sbin/sendmail/test/Results +++ b/usr.sbin/sendmail/test/Results @@ -39,6 +39,7 @@ AIX 3.1.5 FAIL 93.08.07 David J. N. Begley AIX 3.2.3e FAIL 93.07.26 Steve Bauer <sbauer@silver.sdsmt.edu> AIX 3.2.4 FAIL 93.10.07 David J. N. Begley AIX 3.2.5 FAIL 94.05.17 Steve Bauer <sbauer@hpcmmib.hpc.sdsmt.edu> +AIX 4.1 FAIL 96.10.21 Hakan Lindholm <hakan@af.lu.se> AIX 4.2 OK 96.10.16 Steve Bauer <sbauer@krypton.hpc.sdsmt.edu> IRIX 4.0.4 OK 93.09.25 Robert Elz @@ -78,6 +79,8 @@ Solaris 2.5 OK 96.02.29 Carson Gaspar <carson@lehman.com> Linux 1.2.13 FAIL 95.11.02 Sven Neuhaus <sven@ping.de> Linux 2.0.17 FAIL 96.09.03 Horst von Brand <vonbrand@sleipnir.valparaiso.cl> +AIX 4.1 OK 96.10.21 Hakan Lindholm <hakan@af.lu.se> + IRIX 5.2 OK 95.12.01 Mark Andrews <mandrews@aw.sgi.com> IRIX 5.3 OK 95.12.01 Mark Andrews <mandrews@aw.sgi.com> IRIX 6.2 OK 96.09.16 Kari E. Hurtta <Kari.Hurtta@ozone.FMI.FI> |