diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2002-01-14 03:21:42 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2002-01-14 03:21:42 +0000 |
commit | 329cc2cc87730afac9b71e587a23dd70c8b53901 (patch) | |
tree | 82a4eac04f293758bda7297055a7c8e1236b4b76 | |
parent | 67e6877326ec09684a9203da8452b23c01cd134c (diff) |
update to sendmail-8.12.2
109 files changed, 4997 insertions, 1313 deletions
diff --git a/gnu/usr.sbin/sendmail/KNOWNBUGS b/gnu/usr.sbin/sendmail/KNOWNBUGS index f8761720226..9b94b643c76 100644 --- a/gnu/usr.sbin/sendmail/KNOWNBUGS +++ b/gnu/usr.sbin/sendmail/KNOWNBUGS @@ -3,7 +3,7 @@ K N O W N B U G S I N S E N D M A I L -The following are bugs or deficiencies in sendmail that I am aware of +The following are bugs or deficiencies in sendmail that we are aware of but which have not been fixed in the current release. You probably want to get the most up to date version of this from ftp.sendmail.org in /pub/sendmail/KNOWNBUGS. For descriptions of bugs that have been @@ -34,7 +34,7 @@ This list is not guaranteed to be complete. restructuring of the code -- for example, almost no C library support could be used to handle strings. -* Header checks are not called if header value is too long. +* Header checks are not called if header value is too long or empty. If the value of a header is longer than 1250 (MAXNAME + MAXATOM - 6) characters or it contains a single word longer than 256 (MAXNAME) @@ -46,13 +46,12 @@ This list is not guaranteed to be complete. Sometimes identical, duplicate error messages can be generated. As near as I can tell, this is rare and relatively innocuous. -* $c (hop count) macro improperly set. +* Misleading error messages. - The $c macro is supposed to contain the current hop count, for use - when calling a mailer. This macro is initialized too early, and - is always zero (or the value of the -c command line flag, if any). - This macro will probably be removed entirely in a future release; - I don't believe there are any mailers left that require it. + If an illegal address is specified on the command line together + with at least one valid address and PostmasterCopy is set, the + DSN does not contain the illegal address, but only the valid + address(es). * \231 considered harmful. @@ -120,6 +119,14 @@ This list is not guaranteed to be complete. account for the SMTP on-the-wire \r\n expansion. It probably doesn't allow for 8->7 bit MIME conversions either. +* Client ignores SIZE parameter. + + When sendmail acts as client and the server specifies a limit + for the mail size, sendmail will ignore this and try to send the + mail anyway. The server will usually reject the MAIL command + which specifies the size of the message and hence this problem + is not significant. + * Paths to programs being executed and the mode of program files are not checked. Essentially, the RunProgramInUnsafeDirPath and RunWritableProgram bits in the DontBlameSendmail option are always @@ -209,4 +216,4 @@ This list is not guaranteed to be complete. the file. This is unavoidable as sendmail must verify the file is safe to open before opening it. A file can not be locked until it is open. -$Revision: 1.5 $, Last updated $Date: 2001/09/11 19:02:47 $ +$Revision: 1.6 $, Last updated $Date: 2002/01/14 03:21:38 $ diff --git a/gnu/usr.sbin/sendmail/RELEASE_NOTES b/gnu/usr.sbin/sendmail/RELEASE_NOTES index 6adfa0d9fd0..ed791977b61 100644 --- a/gnu/usr.sbin/sendmail/RELEASE_NOTES +++ b/gnu/usr.sbin/sendmail/RELEASE_NOTES @@ -1,11 +1,166 @@ SENDMAIL RELEASE NOTES - $Sendmail: RELEASE_NOTES,v 8.1155 2001/09/30 01:07:23 ca Exp $ + $Sendmail: RELEASE_NOTES,v 8.1218 2002/01/13 18:24:15 ca Exp $ 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.12.2/8.12.2 2002/01/13 + Don't complain too much if stdin, stdout, or stderr are missing + at startup, only log an error message. + Fix potential problem if an unknown operation mode (character + following -b) has been specified. + Prevent purgestat from looping even if someone changes the + permissions or owner of hoststatus files. Problem noted + by Kari Hurtta of the Finnish Meteorological Institute. + Properly record dropped connections in persistent host status. + Problem noted by Ulrich Windl of the Universitat + Regensburg. + Remove newlines from recipients read via sendmail -t to prevent + SMTP protocol errors when sending the RCPT command. + Problem noted by William D. Colburn of the New Mexico + Institute of Mining and Technology. + Only log milter body replacements once instead of for each body + chunk sent by a filter. Problem noted by Kari Hurtta of + the Finnish Meteorological Institute. + In 8.12.0 and 8.12.1, the headers were mistakenly not included in + the message size calculation. Problem noted by Kari Hurtta + of the Finnish Meteorological Institute. + Since 8.12 no longer forks at the SMTP MAIL command, the daemon + needs to collect children status to avoid zombie processes. + Problem noted by Chris Adams of HiWAAY Informations Services. + Shut down "nullserver" and ETRN-only connections after 25 bad + commands are issued. This makes it consistent with normal + SMTP connections. + Avoid duplicate logging of milter rejections. Problem noted by + William D. Colburn of the New Mexico Institute of Mining + and Technology. + Error and delay DSNs were being sent to postmaster instead of the + message sender if the sender had used a deprecated RFC822 + source route. Problem noted by Kari Hurtta of the Finnish + Meteorological Institute. + Fix FallbackMXhost behavior for temporary errors during address + parsing. Problem noted by Jorg Bielak from Coastal Web + Online. + For systems on which stat(2) does not return a value for st_blksize + that is the "optimal blocksize for I/O" three new compile + time flags are available: SM_IO_MAX_BUF_FILE, SM_IO_MIN_BUF, + and SM_IO_MAX_BUF, which define an upper limit for + regular files, and a lower and upper limit for other file + types, respectively. + Fix a potential deadlock if two events are supposed to occur at + exactly the same time. Problem noted by Valdis Kletnieks + of Virginia Tech. + Perform envelope splitting for aliases listed directly in the + alias file, not just for include/.forward files. + Problem noted by John Beck of Sun Microsystems. + Allow selection of queue group for mailq using -qGgroup. + Based on patch by John Beck of Sun Microsystems. + Make sure cached LDAP connections used my multiple maps in the same + process are closed. Patch from Taso N. Devetzis. + If running as root, allow reading of class files in protected + directories. Patch from Alexander Talos of the University + of Vienna. + Correct a few LDAP related memory leaks. Patch from David Powell + of Sun Microsystems. + Allow specification of an empty realm via the authinfo ruleset. + This is necessary to interoperate as an SMTP AUTH client + with servers that do not support realms when using + CRAM-MD5. Problem noted by Bjoern Voigt of TU Berlin. + Avoid a potential information leak if AUTH PLAIN is used and the + server gets stuck while processing that command. Problem + noted by Chris Adams from HiWAAY Informations Services. + In addition to printing errors when parsing recipients during + command line invocations log them to make it simpler + to understand possible DSNs to postmaster. + Do not use FallbackMXhost on mailers which have the F=0 flag set. + Allow local mailers (F=l) to specify a host for TCP connections + instead of forcing localhost. + Obey ${DESTDIR} for installation of the client mail queue and + submit.cf. Patch from Peter 'Luna' Runestig. + Re-enable support for -M option which was broken in 8.12.1. Problem + noted by Neil Rickert of Northern Illinois University. + If a remote server violates the SMTP standard by unexpectedly + dropping the connection during an SMTP transaction, stop + sending commands. This prevents bogus "Bad file number" + recipient status. Problem noted by Allan E Johannesen of + Worcester Polytechnic Institute. + Do not use a size estimate of 100 for postmaster bounces, it's + almost always too small; do not guess the size at all. + New VENDOR_DEC for Compaq/DEC. Requested by James Seagraves of + Compaq Computer Corp. + Fix DaemonPortOptions IPv6 address parsing such that ::1 works + properly. Problem noted by Valdis Kletnieks of Virginia + Tech. + Portability: + Fix IPv6 network interface probing on HP-UX 11.X. Based on + patch provided by HP. + Mac OS X (aka Darwin) has a broken setreuid() call, but a + working seteuid() call. From Daniel J. Luke. + Use proper type for a 32-bit integer on SINIX. From Ganu + Sachin of Siemens. + Set SM_IO_MIN_BUF (4K) and SM_IO_MAX_BUF (8K) for HP-UX. + Reduce optimization from +O3 to +O2 on HP-UX 11. This + fixes a problem that caused additional bogus + characters to be written to the qf file. Problem + noted by Tapani Tarvainen. + Set LDA_USE_LOCKF by default for UnixWare. Problem noted + by Boyd Lynn Gerber. + Add support for HP MPE/iX. See sendmail/README for port + information. From Mark Bixby of Hewlett-Packard. + New portability defines HASNICE, HASRRESVPORT, USE_ENVIRON, + USE_DOUBLE_FORK, and NEEDLINK. See sendmail/README + for more information. From Mark Bixby of + Hewlett-Packard. + If an OS doesn't have a method of finding free disk space + (SFS_NONE), lie and say there is plenty of space. + From Mark Bixby of Hewlett-Packard. + Add support for AIX 5.1. From Valdis Kletnieks of + Virginia Tech. + Fix man page location for NeXTSTEP. From Hisanori Gogota + of the NTT/InterCommunication Center. + Do not assume that strerror() always returns a string. + Problem noted by John Beck of Sun Microsystems. + CONFIG: Add OSTYPE(freebsd5) for FreeBSD 5.X, which has removed + UUCP from the base operating system. From Mark Murray of + FreeBSD Services, Ltd. + CONFIG: Add OSTYPE(mpeix) and a generic .mc file for HP MPE/iX + systems. From Mark Bixby of Hewlett-Packard. + CONFIG: Add support for selecting a queue group for all mailers. + Based on proposal by Stephen L. Ulmer of the University of + Florida. + CONFIG: Fix error reporting for compat_check.m4. Problem noted by + Altin Waldmann. + CONFIG: Do not override user selections for confRUN_AS_USER and + confTRUSTED_USER in FEATURE(msp). From Mark Bixby of + Hewlett-Packard. + LIBMILTER: Fix bug that prevented the removal of a socket after + libmilter terminated. Problem reported by Andrey V. Pevnev + of MSFU. + LIBMILTER: Fix configuration error that required libsm for linking. + Problem noted by Kari Hurtta of the Finnish Meteorological + Institute. + LIBMILTER: Portability fix for OpenUNIX. Patch from Larry Rosenman. + LIBMILTER: Fix a theoretical memory leak and a possible attempt + to free memory twice. + LIBSM: Fix a potential segmentation violation in the I/O library. + Problem found and analyzed by John Beck and Tim Haley + of Sun Microsystems. + LIBSM: Do not clear the LDAP configuration information when + terminating the mailbox database connection in the LDAP + example code. Problem noted by Nikos Voutsinas of the + University of Athens. + New Files: + cf/cf/generic-mpeix.cf + cf/cf/generic-mpeix.mc + cf/ostype/freebsd5.m4 + cf/ostype/mpeix.m4 + devtools/OS/AIX.5.1 + devtools/OS/MPE-iX + include/sm/os/sm_os_mpeix.h + libsm/mpeix.c + 8.12.1/8.12.1 2001/10/01 SECURITY: Check whether dropping group privileges actually succeeded to avoid possible compromises of the mail system by @@ -616,7 +771,6 @@ summary of the changes in that release. confBAD_RCPT_THROTTLE BadRcptThrottle confDIRECT_SUBMISSION_MODIFIERS DirectSubmissionModifiers confMAILBOX_DATABASE MailboxDatabase - confMAIL_SUBMISSION_QUEUE MailSubmissionQueue confMAX_QUEUE_CHILDREN MaxQueueChildren confMAX_RUNNERS_PER_QUEUE MaxRunnersPerQueue confNICE_QUEUE_RUN NiceQueueRun diff --git a/gnu/usr.sbin/sendmail/cf/README b/gnu/usr.sbin/sendmail/cf/README index 55654271b8e..7ed6d7859be 100644 --- a/gnu/usr.sbin/sendmail/cf/README +++ b/gnu/usr.sbin/sendmail/cf/README @@ -76,7 +76,7 @@ Let's examine a typical .mc file: divert(-1) # - # Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + # Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -346,7 +346,10 @@ USENET_MAILER_PATH [/usr/lib/news/inews] The name of the program used to submit news. USENET_MAILER_FLAGS [rsDFMmn] The mailer flags for the usenet mailer. USENET_MAILER_ARGS [-m -h -n] The command line arguments for the - usenet mailer. + usenet mailer. NOTE: Some versions of inews + (such as those shipped with newer versions of INN) + use different flags. Double check the defaults + against the inews man page. USENET_MAILER_MAX [100000] The maximum size of messages that will be accepted by the usenet mailer. USENET_MAILER_QGRP [undefined] The queue group for the usenet mailer. @@ -406,6 +409,7 @@ POP_MAILER_PATH [/usr/lib/mh/spop] The pathname of the POP mailer. POP_MAILER_FLAGS [Penu] Flags added to POP mailer. Flags lsDFMq are always added. POP_MAILER_ARGS [pop $u] The arguments passed to the POP mailer. +POP_MAILER_QGRP [undefined] The queue group for the pop mailer. PROCMAIL_MAILER_PATH [/usr/local/bin/procmail] The path to the procmail program. This is also used by FEATURE(`local_procmail'). @@ -419,15 +423,18 @@ PROCMAIL_MAILER_ARGS [procmail -Y -m $h $f $u] The arguments passed to instead. PROCMAIL_MAILER_MAX [undefined] If set, the maximum size message that will be accepted by the procmail mailer. +PROCMAIL_MAILER_QGRP [undefined] The queue group for the procmail mailer. MAIL11_MAILER_PATH [/usr/etc/mail11] The path to the mail11 mailer. MAIL11_MAILER_FLAGS [nsFx] Flags for the mail11 mailer. MAIL11_MAILER_ARGS [mail11 $g $x $h $u] Arguments passed to the mail11 mailer. +MAIL11_MAILER_QGRP [undefined] The queue group for the mail11 mailer. PH_MAILER_PATH [/usr/local/etc/phquery] The path to the phquery program. PH_MAILER_FLAGS [ehmu] Flags for the phquery mailer. Flags nrDFM are always set. PH_MAILER_ARGS [phquery -- $u] -- arguments to the phquery mailer. +PH_MAILER_QGRP [undefined] The queue group for the ph mailer. CYRUS_MAILER_FLAGS [Ah5@/:|] The flags used by the cyrus mailer. The flags lsDFMnPq are always included. CYRUS_MAILER_PATH [/usr/cyrus/bin/deliver] The program used to deliver @@ -438,6 +445,7 @@ CYRUS_MAILER_MAX [undefined] If set, the maximum size message that will be accepted by the cyrus mailer. CYRUS_MAILER_USER [cyrus:mail] The user and group to become when running the cyrus mailer. +CYRUS_MAILER_QGRP [undefined] The queue group for the cyrus mailer. CYRUS_BB_MAILER_FLAGS [u] The flags used by the cyrusbb mailer. The flags lsDFMnP are always included. CYRUS_BB_MAILER_ARGS [deliver -e -m $u] The arguments passed @@ -452,6 +460,7 @@ QPAGE_MAILER_ARGS [qpage -l0 -m -P$u] The arguments passed to deliver qpage mail. QPAGE_MAILER_MAX [4096] If set, the maximum size message that will be accepted by the qpage mailer. +QPAGE_MAILER_QGRP [undefined] The queue group for the qpage mailer. LOCAL_PROG_QGRP [undefined] The queue group for the prog mailer. Note: to tweak Name_MAILER_FLAGS use the macro MODIFY_MAILER_FLAGS: @@ -911,8 +920,8 @@ virtusertable A domain-specific form of aliasing, allowing multiple info@foo.com foo-info info@bar.com bar-info - joe@bar.com error:nouser No such user here - jax@bar.com error:5.7.0:unavailable Address invalid + joe@bar.com error:nouser 550 No such user here + jax@bar.com error:5.7.0:550 Address invalid @baz.org jane@example.net then mail addressed to info@foo.com will be sent to the @@ -1233,10 +1242,14 @@ authinfo Provide a separate map for client side authentication hash /etc/mail/authinfo preserve_luser_host - Preserve the name of the recipient host if LUSER_RELAY - is used. Without this option, the domain part of the - recipient address will be replaced by the host specified - as LUSER_RELAY. + Preserve the name of the recipient host if LUSER_RELAY is + used. Without this option, the domain part of the + recipient address will be replaced by the host specified as + LUSER_RELAY. This feature only works if the hostname is + passed to the mailer (see mailer triple in op.me). Note + that in the default configuration the local mailer does not + receive the hostname, i.e., the mailer triple has an empty + hostname. preserve_local_plus_detail Preserve the +detail portion of the address when passing @@ -1247,9 +1260,9 @@ preserve_local_plus_detail delivery agent in use supports +detail addressing. compat_check Enable ruleset check_compat to look up pairs of addresses - sender<@>recipient in the access map. Valid values for - the RHS include - DISCARD silently discard message + with the Compat: tag -- Compat:sender<@>recipient -- in the + access map. Valid values for the RHS include + DISCARD silently discard recipient TEMP: return a temporary error ERROR: return a permanent error In the last two cases, a 4xy/5xy SMTP reply code should @@ -2078,6 +2091,13 @@ separate lines, e.g., IPv6:2002:c0a8:02c7 IPv6:2002:c0a8:51d2::23f4 host.mydomain.com + [UNIX:localhost] + +Notice: the last entry allows relaying for connections via a UNIX +socket to the MTA/MSP. This might be necessary if your configuration +doesn't allow relaying by other means in that case, e.g., by having +localhost.$m in class {R} (make sure $m is not just a top level +domain). If you use @@ -2267,7 +2287,7 @@ The value part of the map can contain: For example: - cyberspammer.com ERROR:"550 We don't accept mail from spammers" + cyberspammer.com ERROR:550 "We don't accept mail from spammers" okay.cyberspammer.com OK sendmail.org RELAY 128.32 RELAY @@ -2849,16 +2869,20 @@ If the selected mechanism provides a security layer the number of bits used for the key of the symmetric cipher is stored in the macro ${auth_ssf}. - If sendmail acts as client, it needs some information how to authenticate against another MTA. This information can be provided -by the ruleset authinfo or by the option AuthMechanisms. The +by the ruleset authinfo or by the option DefaultAuthInfo. The authinfo ruleset looks up {server_name} using the tag AuthInfo: in the access map. If no entry is found, {server_addr} is looked up in the same way and finally just the tag AuthInfo: to provide default values. -The RHS for an Auth: entry in the access map should consists of a +Notice: the default configuration file causes the option DefaultAuthInfo +to fail since the ruleset authinfo is in the .cf file. If you really +want to use DefaultAuthInfo (it is deprecated) then you have to +remove the ruleset. + +The RHS for an AuthInfo: entry in the access map should consists of a list of tokens, each of which has the form: "TDstring" (including the quotes). T is a tag which describes the item, D is a delimiter, either ':' for simple text or '=' for a base64 encoded string. @@ -2878,8 +2902,8 @@ AuthInfo:more.dom "U:user" "P=c2VjcmV0" User or authentication id must exist as well as the password. All other entries have default values. If one of user or authentication id is missing, the existing value is used for the missing item. -Realm defaults to $j and the list of mechanisms to those specified -by AuthMechanisms. +If "R:" is not specified, realm defaults to $j. The list of mechanisms +defaults to those specified by AuthMechanisms. Since this map contains sensitive information, either the access map must be unreadable by everyone but root (or the trusted user) @@ -3085,7 +3109,7 @@ something like: my.domain esmtp:host.my.domain The RHS should always be a "mailer:host" pair. The mailer is the -configuration name of a mailer (that is, an {M} line in the +configuration name of a mailer (that is, an M line in the sendmail.cf file). The "host" will be the hostname passed to that mailer. In domain-based matches (that is, those with leading dots) the "%1" may be used to interpolate the wildcarded part of @@ -3787,7 +3811,8 @@ confDEF_AUTH_INFO DefaultAuthInfo [undefined] Name of file that contains removed in future versions; it doesn't work for the MSP since it can't read the file. Use the authinfo ruleset - instead. + instead. See also the section SMTP + AUTHENTICATION. confAUTH_OPTIONS AuthOptions [undefined] If this option is 'A' then the AUTH= parameter for the MAIL FROM command is only issued @@ -3856,8 +3881,12 @@ confSHARED_MEMORY_KEY SharedMemoryKey [0] Key for shared memory. confFAST_SPLIT FastSplit [1] If set to a value greater than zero, the initial MX lookups on addresses is suppressed when they - are sorted which may result in faster - envelope splitting. + are sorted which may result in + faster envelope splitting. If the + mail is submitted directly from the + command line, then the value also + limits the number of processes to + deliver the envelopes. confMAILBOX_DATABASE MailboxDatabase [pw] Type of lookup to find information about local mailboxes. confDEQUOTE_OPTS - [empty] Additional options for the @@ -3996,7 +4025,7 @@ FEATURE(`authinfo', `DATABASE_MAP_TYPE /etc/mail/msp-authinfo') /etc/mail/msp-authinfo should contain an entry like: - AuthInfo:127.0.0.1 "U:smmsp" "P:secret" "M:DIGEST-MD5" + AuthInfo:127.0.0.1 "U:smmsp" "P:secret" "M:DIGEST-MD5" The file and the map created by makemap should be owned by smmsp, its group should be smmsp, and it should have mode 640. The database @@ -4122,7 +4151,6 @@ RULESETS (* means built in to sendmail) 96 Bottom half of Ruleset 3 (ruleset 6 in old sendmail) 97 Hook for recursive ruleset 0 call (ruleset 7 in old sendmail) 98 Local part of ruleset 0 (ruleset 8 in old sendmail) - 99 Guaranteed null (for debugging) MAILERS @@ -4209,4 +4237,4 @@ M4 DIVERSIONS 8 DNS based blacklists 9 special local rulesets (1 and 2) -$Revision: 1.10 $, Last updated $Date: 2001/10/01 17:18:28 $ +$Revision: 1.11 $, Last updated $Date: 2002/01/14 03:21:39 $ diff --git a/gnu/usr.sbin/sendmail/cf/cf/Makefile b/gnu/usr.sbin/sendmail/cf/cf/Makefile index c884d3a8d30..a9fc02bd254 100644 --- a/gnu/usr.sbin/sendmail/cf/cf/Makefile +++ b/gnu/usr.sbin/sendmail/cf/cf/Makefile @@ -1,8 +1,8 @@ -# $OpenBSD: Makefile,v 1.16 2002/01/09 23:41:13 lebel Exp $ +# $OpenBSD: Makefile,v 1.17 2002/01/14 03:21:39 millert Exp $ # # Makefile for configuration files. # -# $Sendmail: Makefile,v 8.54 2001/08/20 15:16:48 gshapiro Exp $ +# $Sendmail: Makefile,v 8.56 2001/12/13 23:56:37 gshapiro Exp $ # # @@ -149,6 +149,7 @@ M4FILES=\ ${CFDIR}/ostype/domainos.m4 \ ${CFDIR}/ostype/dynix3.2.m4 \ ${CFDIR}/ostype/freebsd4.m4 \ + ${CFDIR}/ostype/freebsd5.m4 \ ${CFDIR}/ostype/gnu.m4 \ ${CFDIR}/ostype/hpux10.m4 \ ${CFDIR}/ostype/hpux11.m4 \ @@ -160,6 +161,7 @@ M4FILES=\ ${CFDIR}/ostype/linux.m4 \ ${CFDIR}/ostype/maxion.m4 \ ${CFDIR}/ostype/mklinux.m4 \ + ${CFDIR}/ostype/mpeix.m4 \ ${CFDIR}/ostype/nextstep.m4 \ ${CFDIR}/ostype/openbsd.m4 \ ${CFDIR}/ostype/osf1.m4 \ diff --git a/gnu/usr.sbin/sendmail/cf/cf/courtesan.mc b/gnu/usr.sbin/sendmail/cf/cf/courtesan.mc index 16c8fd1b031..5e55c2d4651 100644 --- a/gnu/usr.sbin/sendmail/cf/cf/courtesan.mc +++ b/gnu/usr.sbin/sendmail/cf/cf/courtesan.mc @@ -4,7 +4,7 @@ divert(-1) # divert(0)dnl -VERSIONID(`$OpenBSD: courtesan.mc,v 1.8 2001/12/04 02:23:56 millert Exp $') +VERSIONID(`$OpenBSD: courtesan.mc,v 1.9 2002/01/14 03:21:39 millert Exp $') OSTYPE(openbsd) dnl dnl First, we override some default values @@ -44,6 +44,7 @@ dnl dnl Spam blocking features FEATURE(access_db)dnl FEATURE(blacklist_recipients)dnl +dnl FEATURE(dnsbl, `inputs.orbz.org', `Open spam relay - see http://www.orbz.org/sender.php')dnl dnl FEATURE(dnsbl, `rbl.maps.vix.com', `Rejected - see http://www.mail-abuse.org/rbl/')dnl dnl FEATURE(dnsbl, `dul.maps.vix.com', `Dialup - see http://www.mail-abuse.org/dul/')dnl dnl FEATURE(dnsbl, `relays.mail-abuse.org', `Open spam relay - see http://www.mail-abuse.org/rss/')dnl diff --git a/gnu/usr.sbin/sendmail/cf/cf/generic-mpeix.mc b/gnu/usr.sbin/sendmail/cf/cf/generic-mpeix.mc new file mode 100644 index 00000000000..53ebdef2a82 --- /dev/null +++ b/gnu/usr.sbin/sendmail/cf/cf/generic-mpeix.mc @@ -0,0 +1,25 @@ +divert(-1) +# +# Copyright (c) 2001 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +# +# This is a generic configuration file for HP MPE/iX. +# It has support for local and SMTP mail only. If you want to +# customize it, copy it to a name appropriate for your environment +# and do the modifications there. +# + +divert(0)dnl +VERSIONID(`$Sendmail: generic-mpeix.mc,v 8.1 2001/12/13 23:56:37 gshapiro Exp $') +OSTYPE(mpeix)dnl +DOMAIN(generic)dnl +define(`confFORWARD_PATH', `$z/.forward')dnl +MAILER(local)dnl +MAILER(smtp)dnl diff --git a/gnu/usr.sbin/sendmail/cf/cf/openbsd-lists.mc b/gnu/usr.sbin/sendmail/cf/cf/openbsd-lists.mc index 9aac2c325c6..332e8067ff2 100644 --- a/gnu/usr.sbin/sendmail/cf/cf/openbsd-lists.mc +++ b/gnu/usr.sbin/sendmail/cf/cf/openbsd-lists.mc @@ -6,7 +6,7 @@ divert(-1) # divert(0)dnl -VERSIONID(`$OpenBSD: openbsd-lists.mc,v 1.10 2002/01/11 00:38:39 millert Exp $') +VERSIONID(`$OpenBSD: openbsd-lists.mc,v 1.11 2002/01/14 03:21:39 millert Exp $') OSTYPE(openbsd)dnl dnl dnl Advertise ourselves as ``openbsd.org'' @@ -30,7 +30,7 @@ define(`confBIND_OPTS', `WorkAroundBrokenAAAA')dnl dnl dnl Keep host status on disk between sendmail runs in the .hoststat dir define(`confHOST_STATUS_DIRECTORY', `.hoststat')dnl -define(`confTO_HOSTSTATUS', `1h')dnl +define(`confTO_HOSTSTATUS', `30m')dnl dnl dnl Always use fully qualified domains FEATURE(always_add_domain) @@ -61,6 +61,10 @@ define(`confSERVER_KEY', `CERT_DIR/mykey.pem')dnl define(`confCLIENT_CERT', `CERT_DIR/mycert.pem')dnl define(`confCLIENT_KEY', `CERT_DIR/mykey.pem')dnl dnl +dnl Queue options for /var/spool/mqueue: +dnl Up to 7 simultaneous queue runners, max 20 recipients per envelope +QUEUE_GROUP(`mqueue', `P=/var/spool/mqueue, R=7, r=20, F=f') +dnl dnl Make mail appear to be from openbsd.org MASQUERADE_AS(openbsd.org) FEATURE(masquerade_envelope) diff --git a/gnu/usr.sbin/sendmail/cf/feature/compat_check.m4 b/gnu/usr.sbin/sendmail/cf/feature/compat_check.m4 index 8e7bf47d2bb..409c5cd88e8 100644 --- a/gnu/usr.sbin/sendmail/cf/feature/compat_check.m4 +++ b/gnu/usr.sbin/sendmail/cf/feature/compat_check.m4 @@ -9,7 +9,7 @@ divert(-1) # # divert(0) -VERSIONID(`$Sendmail: compat_check.m4,v 1.2 2001/03/13 13:41:39 ca Exp $') +VERSIONID(`$Sendmail: compat_check.m4,v 1.3 2001/11/21 18:40:06 ca Exp $') divert(-1) ifdef(`_ACCESS_TABLE_', `', `errprint(`FEATURE(`compat_check') requires FEATURE(`access_db') @@ -27,7 +27,7 @@ R$* $| $* $@ ok # it must be one of the following... anything else will be allowed.. dnl for consistency with the other two even though discard does not take an dnl reply code -R< DISCARD:$* > $#discard $: "$1 - discarded by check_compat" -R< DISCARD $* > $#discard $: "$1 - discarded by check_compat" -R< TEMP:$* > $#error $@ TEMPFAIL $: "$1 error from check_compat. try again later" -R< ERROR:$* > $#error $@ UNAVAILABLE $: "$1 error from check_compat" +R< DISCARD:$* > $#discard $: $1 " - discarded by check_compat" +R< DISCARD $* > $#discard $: $1 " - discarded by check_compat" +R< TEMP:$* > $#error $@ TEMPFAIL $: $1 " error from check_compat. Try again later" +R< ERROR:$* > $#error $@ UNAVAILABLE $: $1 " error from check_compat" diff --git a/gnu/usr.sbin/sendmail/cf/feature/dnsbl.m4 b/gnu/usr.sbin/sendmail/cf/feature/dnsbl.m4 index f008f68409c..cd869c04359 100644 --- a/gnu/usr.sbin/sendmail/cf/feature/dnsbl.m4 +++ b/gnu/usr.sbin/sendmail/cf/feature/dnsbl.m4 @@ -11,11 +11,11 @@ divert(-1) divert(0) ifdef(`_DNSBL_R_',`dnl',`dnl -VERSIONID(`$Sendmail: dnsbl.m4,v 8.25 2001/09/18 21:47:39 ca Exp $') +VERSIONID(`$Sendmail: dnsbl.m4,v 8.26 2001/11/12 16:04:14 ca Exp $') define(`_DNSBL_R_',`') LOCAL_CONFIG # map for DNS based blacklist lookups -Kdnsbl host -T<TMP>') +Kdnsbl host -T<TMP>ifdef(`DNSBL_MAP_OPT',` DNSBL_MAP_OPT')') divert(-1) define(`_DNSBL_SRV_', `ifelse(len(X`'_ARG_),`1',`blackholes.mail-abuse.org',_ARG_)')dnl define(`_DNSBL_MSG_', `ifelse(len(X`'_ARG2_),`1',`"550 Mail from " $`'&{client_addr} " refused by blackhole site '_DNSBL_SRV_`"',`_ARG2_')')dnl diff --git a/gnu/usr.sbin/sendmail/cf/feature/msp.m4 b/gnu/usr.sbin/sendmail/cf/feature/msp.m4 index e3f5f80f9bb..e793ca0bde1 100644 --- a/gnu/usr.sbin/sendmail/cf/feature/msp.m4 +++ b/gnu/usr.sbin/sendmail/cf/feature/msp.m4 @@ -10,7 +10,7 @@ divert(-1) # divert(0)dnl -VERSIONID(`$Sendmail: msp.m4,v 1.28 2001/09/22 21:46:42 ca Exp $') +VERSIONID(`$Sendmail: msp.m4,v 1.29 2001/12/13 23:56:38 gshapiro Exp $') divert(-1) define(`ALIAS_FILE', `') define(`confDELIVERY_MODE', `i') @@ -20,8 +20,8 @@ define(`confPRIVACY_FLAGS', `goaway,noetrn,restrictqrun') define(`confDONT_PROBE_INTERFACES', `True') dnl --------------------------------------------- dnl run as this user (even if called by root) -define(`confRUN_AS_USER', `smmsp') -define(`confTRUSTED_USER', confRUN_AS_USER) +ifdef(`confRUN_AS_USER',,`define(`confRUN_AS_USER', `smmsp')') +ifdef(`confTRUSTED_USER',,`define(`confTRUSTED_USER', confRUN_AS_USER)') dnl --------------------------------------------- dnl This queue directory must have the same group dnl as sendmail and it must be group-writable. diff --git a/gnu/usr.sbin/sendmail/cf/m4/proto.m4 b/gnu/usr.sbin/sendmail/cf/m4/proto.m4 index 909783c7f15..135f95fcb9b 100644 --- a/gnu/usr.sbin/sendmail/cf/m4/proto.m4 +++ b/gnu/usr.sbin/sendmail/cf/m4/proto.m4 @@ -13,7 +13,7 @@ divert(-1) # divert(0) -VERSIONID(`$Sendmail: proto.m4,v 8.624 2001/09/28 21:52:59 ca Exp $') +VERSIONID(`$Sendmail: proto.m4,v 8.628 2001/12/28 19:02:40 ca Exp $') # level CF_LEVEL config file format V`'CF_LEVEL/ifdef(`VENDOR_NAME', `VENDOR_NAME', `Berkeley') @@ -862,6 +862,11 @@ dnl but add a trailing dot to qualified hostnames so other rules will work dnl should we do this for every hostname: even unqualified? R$* CC $* $| $* < @ $+.$+ > $* $: $3 < @ $4.$5 . > $6 R$* CC $* $| $* $: $3 +ifdef(`_FFR_NOCANONIFY_HEADERS', `dnl +# do not canonify header addresses +R$* $| $* < @ $* $~P > $* $: $&{addr_type} $| $2 < @ $3 $4 > $5 +R$* h $* $| $* < @ $+.$+ > $* $: $3 < @ $4.$5 . > $6 +R$* h $* $| $* $: $3', `dnl') # pass to name server to make hostname canonical R$* $| $* < @ $* > $* $: $2 < @ $[ $3 $] > $4') dnl remove {daemon_flags} for other cases @@ -1515,6 +1520,9 @@ R<?> <[$+:$-]> <$+> <$- $-> <$*> $: $>D <[$1]> <$3> <$4 $5> <$6>') dnl not found, but subdomain: try again dnl 1 2 3 4 5 6 R<?> <$+.$+> <$+> <$- $-> <$*> $@ $>D <$2> <$3> <$4 $5> <$6> +ifdef(`_FFR_LOOKUPTAG_', `dnl lookup Tag: +dnl 1 2 3 4 +R<?> <$+> <$+> <! $-> <$*> $: < $(access $3`'_TAG_DELIM_ $: ? $) > <$1> <$2> <! $3> <$4>', `dnl') dnl not found, no subdomain: return <default> and <passthru> dnl 1 2 3 4 5 R<?> <$+> <$+> <$- $-> <$*> $@ <$2> <$5> @@ -1683,6 +1691,8 @@ dnl workspace: <result-of-lookup> (<>|<{client_addr}>) | OK R<$={Accept}> <$*> $@ $1 return value of lookup R<REJECT> <$*> $#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"') R<DISCARD> <$*> $#discard $: discard +ifdef(`_FFR_QUARANTINE', +`R<QUARANTINE:$+> <$*> $#error $@ quarantine $: $1', `dnl') dnl error tag R<ERROR:$-.$-.$-:$+> <$*> $#error $@ $1.$2.$3 $: $4 R<ERROR:$+> <$*> $#error $: $1 @@ -1828,6 +1838,8 @@ R<PERM> $* $#error $@ 5.1.8 $: "_CODE553 Domain of sender address " $&f " does ifdef(`_ACCESS_TABLE_', `dnl R<$={Accept}> $* $# $1 accept from access map R<DISCARD> $* $#discard $: discard +ifdef(`_FFR_QUARANTINE', +`R<QUARANTINE:$+> $* $#error $@ quarantine $: $1', `dnl') R<REJECT> $* $#error ifdef(`confREJECT_MSG', `$: "confREJECT_MSG"', `$@ 5.7.1 $: "550 Access denied"') dnl error tag R<ERROR:$-.$-.$-:$+> $* $#error $@ $1.$2.$3 $: $4 @@ -1965,6 +1977,8 @@ dnl maybe we should stop checks already here (if SPAM_xyx)? R<$={SpamTag}> <$*> $: @ $2 mark address as no match') R<REJECT> $* $#error $@ 5.2.1 $: confRCPTREJ_MSG R<DISCARD> $* $#discard $: discard +ifdef(`_FFR_QUARANTINE', +`R<QUARANTINE:$+> $* $#error $@ quarantine $: $1', `dnl') dnl error tag R<ERROR:$-.$-.$-:$+> $* $#error $@ $1.$2.$3 $: $4 R<ERROR:$+> $* $#error $: $1 diff --git a/gnu/usr.sbin/sendmail/cf/m4/version.m4 b/gnu/usr.sbin/sendmail/cf/m4/version.m4 index e6b37762813..c7c34127fd4 100644 --- a/gnu/usr.sbin/sendmail/cf/m4/version.m4 +++ b/gnu/usr.sbin/sendmail/cf/m4/version.m4 @@ -1,6 +1,6 @@ divert(-1) # -# Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -11,8 +11,8 @@ divert(-1) # the sendmail distribution. # # -VERSIONID(`$Sendmail: version.m4,v 8.73 2001/09/29 01:51:40 ca Exp $') +VERSIONID(`$Sendmail: version.m4,v 8.81 2002/01/13 18:23:32 ca Exp $') # divert(0) # Configuration version number -DZ8.12.1`'ifdef(`confCF_VERSION', `/confCF_VERSION') +DZ8.12.2`'ifdef(`confCF_VERSION', `/confCF_VERSION') diff --git a/gnu/usr.sbin/sendmail/cf/mailer/cyrus.m4 b/gnu/usr.sbin/sendmail/cf/mailer/cyrus.m4 index 16eed11d5e8..f2404cc0c83 100644 --- a/gnu/usr.sbin/sendmail/cf/mailer/cyrus.m4 +++ b/gnu/usr.sbin/sendmail/cf/mailer/cyrus.m4 @@ -1,6 +1,6 @@ PUSHDIVERT(-1) # -# Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set @@ -41,6 +41,7 @@ ifdef(`CYRUS_MAILER_ARGS',, `define(`CYRUS_MAILER_ARGS', `deliver -e -m $h -- $u ifdef(`CYRUS_MAILER_USER',, `define(`CYRUS_MAILER_USER', `cyrus:mail')') _DEFIFNOT(`CYRUS_BB_MAILER_FLAGS', `u') ifdef(`CYRUS_BB_MAILER_ARGS',, `define(`CYRUS_BB_MAILER_ARGS', `deliver -e -m $u')') +define(`_CYRUS_QGRP', `ifelse(defn(`CYRUS_MAILER_QGRP'),`',`', ` Q=CYRUS_MAILER_QGRP,')')dnl POPDIVERT @@ -48,12 +49,12 @@ POPDIVERT ### Cyrus Mailer specification ### ################################################## -VERSIONID(`$Sendmail: cyrus.m4,v 8.22 2000/09/02 17:46:43 ca Exp $ (Carnegie Mellon)') +VERSIONID(`$Sendmail: cyrus.m4,v 8.23 2001/11/12 23:11:34 ca Exp $ (Carnegie Mellon)') Mcyrus, P=CYRUS_MAILER_PATH, F=_MODMF_(CONCAT(`lsDFMnPq', CYRUS_MAILER_FLAGS), `CYRUS'), S=EnvFromL, R=EnvToL/HdrToL, - ifdef(`CYRUS_MAILER_MAX', `M=CYRUS_MAILER_MAX, ')U=CYRUS_MAILER_USER, T=DNS/RFC822/X-Unix, + ifdef(`CYRUS_MAILER_MAX', `M=CYRUS_MAILER_MAX, ')U=CYRUS_MAILER_USER, T=DNS/RFC822/X-Unix,_CYRUS_QGRP A=CYRUS_MAILER_ARGS Mcyrusbb, P=CYRUS_MAILER_PATH, F=_MODMF_(CONCAT(`lsDFMnP', CYRUS_BB_MAILER_FLAGS), `CYRUS'), S=EnvFromL, R=EnvToL/HdrToL, - ifdef(`CYRUS_MAILER_MAX', `M=CYRUS_MAILER_MAX, ')U=CYRUS_MAILER_USER, T=DNS/RFC822/X-Unix, + ifdef(`CYRUS_MAILER_MAX', `M=CYRUS_MAILER_MAX, ')U=CYRUS_MAILER_USER, T=DNS/RFC822/X-Unix,_CYRUS_QGRP A=CYRUS_BB_MAILER_ARGS diff --git a/gnu/usr.sbin/sendmail/cf/mailer/fax.m4 b/gnu/usr.sbin/sendmail/cf/mailer/fax.m4 index c1aecce2536..979b55d39ab 100644 --- a/gnu/usr.sbin/sendmail/cf/mailer/fax.m4 +++ b/gnu/usr.sbin/sendmail/cf/mailer/fax.m4 @@ -1,6 +1,6 @@ PUSHDIVERT(-1) # -# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998, 1999, 2001 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -22,15 +22,16 @@ ifdef(`FAX_MAILER_PATH',, `define(`FAX_MAILER_PATH', /usr/local/bin/faxmail)') ifdef(`FAX_MAILER_MAX',, `define(`FAX_MAILER_MAX', 100000)') +define(`_FAX_QGRP', `ifelse(defn(`FAX_MAILER_QGRP'),`',`', ` Q=FAX_MAILER_QGRP,')')dnl POPDIVERT #################################### ### FAX Mailer specification ### #################################### -VERSIONID(`$Sendmail: fax.m4,v 8.15 1999/10/18 04:57:53 gshapiro Exp $') +VERSIONID(`$Sendmail: fax.m4,v 8.16 2001/11/12 23:11:34 ca Exp $') Mfax, P=FAX_MAILER_PATH, F=DFMhu, S=14, R=24, - M=FAX_MAILER_MAX, T=X-Phone/X-FAX/X-Unix, + M=FAX_MAILER_MAX, T=X-Phone/X-FAX/X-Unix,_FAX_QGRP A=FAX_MAILER_ARGS LOCAL_CONFIG diff --git a/gnu/usr.sbin/sendmail/cf/mailer/mail11.m4 b/gnu/usr.sbin/sendmail/cf/mailer/mail11.m4 index a7346f78edd..d39e90c4271 100644 --- a/gnu/usr.sbin/sendmail/cf/mailer/mail11.m4 +++ b/gnu/usr.sbin/sendmail/cf/mailer/mail11.m4 @@ -24,6 +24,7 @@ _DEFIFNOT(`MAIL11_MAILER_FLAGS', `nsFx') ifdef(`MAIL11_MAILER_ARGS',, `define(`MAIL11_MAILER_ARGS', mail11 $g $x $h $u)') define(`_USE_DECNET_SYNTAX_') define(`_LOCAL_', ifdef(`confLOCAL_MAILER', confLOCAL_MAILER, `local')) +define(`_MAIL11_QGRP', `ifelse(defn(`MAIL11_MAILER_QGRP'),`',`', ` Q=MAIL11_MAILER_QGRP,')')dnl POPDIVERT @@ -41,7 +42,7 @@ POPDIVERT ### UTK-MAIL11 Mailer specification ### ########################################### -VERSIONID(`$Sendmail: mail11.m4,v 8.21 2001/07/19 00:16:16 ca Exp $') +VERSIONID(`$Sendmail: mail11.m4,v 8.22 2001/11/12 23:11:34 ca Exp $') SMail11To R$+ < @ $- .UUCP > $: $2 ! $1 back to old style @@ -56,5 +57,5 @@ R$+ $: $>Mail11To $1 preprocess R$w :: $+ $@ $w :: $1 ready to go Mmail11, P=MAIL11_MAILER_PATH, F=_MODMF_(MAIL11_MAILER_FLAGS, `MAIL11'), S=Mail11From, R=Mail11To, - T=DNS/X-DECnet/X-Unix, + T=DNS/X-DECnet/X-Unix,_MAIL11_QGRP A=MAIL11_MAILER_ARGS diff --git a/gnu/usr.sbin/sendmail/cf/mailer/phquery.m4 b/gnu/usr.sbin/sendmail/cf/mailer/phquery.m4 index 2b709d7c33a..385b5d49895 100644 --- a/gnu/usr.sbin/sendmail/cf/mailer/phquery.m4 +++ b/gnu/usr.sbin/sendmail/cf/mailer/phquery.m4 @@ -1,6 +1,6 @@ PUSHDIVERT(-1) # -# Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -17,6 +17,7 @@ PUSHDIVERT(-1) ifdef(`PH_MAILER_PATH',, `define(`PH_MAILER_PATH', /usr/local/etc/phquery)') _DEFIFNOT(`PH_MAILER_FLAGS', `ehmu') ifdef(`PH_MAILER_ARGS',, `define(`PH_MAILER_ARGS', `phquery -- $u')') +define(`_PH_QGRP', `ifelse(defn(`PH_MAILER_QGRP'),`',`', ` Q=PH_MAILER_QGRP,')')dnl POPDIVERT @@ -24,8 +25,8 @@ POPDIVERT ### PH Mailer specification ### #################################### -VERSIONID(`$Sendmail: phquery.m4,v 8.16 2000/09/02 17:46:43 ca Exp $') +VERSIONID(`$Sendmail: phquery.m4,v 8.17 2001/11/12 23:11:34 ca Exp $') Mph, P=PH_MAILER_PATH, F=_MODMF_(CONCAT(`nrDFM', PH_MAILER_FLAGS), `PH'), S=EnvFromL, R=EnvToL/HdrToL, - T=DNS/RFC822/X-Unix, + T=DNS/RFC822/X-Unix,_PH_QGRP A=PH_MAILER_ARGS diff --git a/gnu/usr.sbin/sendmail/cf/mailer/pop.m4 b/gnu/usr.sbin/sendmail/cf/mailer/pop.m4 index 16bd707eac3..b140146cdf3 100644 --- a/gnu/usr.sbin/sendmail/cf/mailer/pop.m4 +++ b/gnu/usr.sbin/sendmail/cf/mailer/pop.m4 @@ -1,6 +1,6 @@ PUSHDIVERT(-1) # -# Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -15,6 +15,7 @@ PUSHDIVERT(-1) ifdef(`POP_MAILER_PATH',, `define(`POP_MAILER_PATH', /usr/lib/mh/spop)') _DEFIFNOT(`POP_MAILER_FLAGS', `Penu') ifdef(`POP_MAILER_ARGS',, `define(`POP_MAILER_ARGS', `pop $u')') +define(`_POP_QGRP', `ifelse(defn(`POP_MAILER_QGRP'),`',`', ` Q=POP_MAILER_QGRP,')')dnl POPDIVERT @@ -22,10 +23,10 @@ POPDIVERT ### POP Mailer specification ### #################################### -VERSIONID(`$Sendmail: pop.m4,v 8.21 2000/09/02 17:46:43 ca Exp $') +VERSIONID(`$Sendmail: pop.m4,v 8.22 2001/11/12 23:11:34 ca Exp $') Mpop, P=POP_MAILER_PATH, F=_MODMF_(CONCAT(`lsDFMq', POP_MAILER_FLAGS), `POP'), S=EnvFromL, R=EnvToL/HdrToL, - T=DNS/RFC822/X-Unix, + T=DNS/RFC822/X-Unix,_POP_QGRP A=POP_MAILER_ARGS LOCAL_CONFIG diff --git a/gnu/usr.sbin/sendmail/cf/mailer/procmail.m4 b/gnu/usr.sbin/sendmail/cf/mailer/procmail.m4 index 2fd3534cc21..33b8ac53e1b 100644 --- a/gnu/usr.sbin/sendmail/cf/mailer/procmail.m4 +++ b/gnu/usr.sbin/sendmail/cf/mailer/procmail.m4 @@ -1,6 +1,6 @@ PUSHDIVERT(-1) # -# Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983 Eric P. Allman. All rights reserved. # Copyright (c) 1988, 1993 @@ -19,6 +19,7 @@ ifdef(`PROCMAIL_MAILER_PATH',, _DEFIFNOT(`PROCMAIL_MAILER_FLAGS', `SPhnu9') ifdef(`PROCMAIL_MAILER_ARGS',, `define(`PROCMAIL_MAILER_ARGS', `procmail -Y -m $h $f $u')') +define(`_PROCMAIL_QGRP', `ifelse(defn(`PROCMAIL_MAILER_QGRP'),`',`', ` Q=PROCMAIL_MAILER_QGRP,')')dnl POPDIVERT @@ -26,8 +27,8 @@ POPDIVERT ### PROCMAIL Mailer specification ### ##################*****################## -VERSIONID(`$Sendmail: procmail.m4,v 8.21 2000/09/02 17:46:43 ca Exp $') +VERSIONID(`$Sendmail: procmail.m4,v 8.22 2001/11/12 23:11:34 ca Exp $') Mprocmail, P=PROCMAIL_MAILER_PATH, F=_MODMF_(CONCAT(`DFM', PROCMAIL_MAILER_FLAGS), `PROCMAIL'), S=EnvFromSMTP/HdrFromSMTP, R=EnvToSMTP/HdrFromSMTP, - ifdef(`PROCMAIL_MAILER_MAX', `M=PROCMAIL_MAILER_MAX, ')T=DNS/RFC822/X-Unix, + ifdef(`PROCMAIL_MAILER_MAX', `M=PROCMAIL_MAILER_MAX, ')T=DNS/RFC822/X-Unix,_PROCMAIL_QGRP A=PROCMAIL_MAILER_ARGS diff --git a/gnu/usr.sbin/sendmail/cf/mailer/qpage.m4 b/gnu/usr.sbin/sendmail/cf/mailer/qpage.m4 index 4bea89e6ae0..b44529ce3fd 100644 --- a/gnu/usr.sbin/sendmail/cf/mailer/qpage.m4 +++ b/gnu/usr.sbin/sendmail/cf/mailer/qpage.m4 @@ -3,7 +3,7 @@ PUSHDIVERT(-1) # Copyright (C) 1997, Philip A. Prindeville and Enteka Enterprise Technology # Services # -# Copyright (c) 1999 Sendmail, Inc. and its suppliers. +# Copyright (c) 1999, 2001 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set @@ -16,6 +16,7 @@ ifdef(`QPAGE_MAILER_PATH', `', `define(`QPAGE_MAILER_PATH', `/usr/local/bin/qpag _DEFIFNOT(`QPAGE_MAILER_FLAGS', `mDFMs') ifdef(`QPAGE_MAILER_ARGS', `', `define(`QPAGE_MAILER_ARGS', `qpage -l0 -m -P$u')') ifdef(`QPAGE_MAILER_MAX', `', `define(`QPAGE_MAILER_MAX', `4096')') +define(`_QPAGE_QGRP', `ifelse(defn(`QPAGE_MAILER_QGRP'),`',`', ` Q=QPAGE_MAILER_QGRP,')')dnl POPDIVERT @@ -23,8 +24,8 @@ POPDIVERT ### QPAGE Mailer specification ### ###################################### -VERSIONID(`$Sendmail: qpage.m4,v 8.9 1999/11/16 03:33:04 gshapiro Exp $') +VERSIONID(`$Sendmail: qpage.m4,v 8.10 2001/11/12 23:11:34 ca Exp $') Mqpage, P=QPAGE_MAILER_PATH, F=_MODMF_(QPAGE_MAILER_FLAGS, `QPAGE'), - M=QPAGE_MAILER_MAX, T=DNS/RFC822/X-Unix, + M=QPAGE_MAILER_MAX, T=DNS/RFC822/X-Unix,_QPAGE_QGRP A=QPAGE_MAILER_ARGS diff --git a/gnu/usr.sbin/sendmail/cf/ostype/freebsd5.m4 b/gnu/usr.sbin/sendmail/cf/ostype/freebsd5.m4 new file mode 100644 index 00000000000..2804bab0adf --- /dev/null +++ b/gnu/usr.sbin/sendmail/cf/ostype/freebsd5.m4 @@ -0,0 +1,20 @@ +divert(-1) +# +# Copyright (c) 2001 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Sendmail: freebsd5.m4,v 1.1 2001/10/08 22:25:34 gshapiro Exp $') +ifdef(`STATUS_FILE',, `define(`STATUS_FILE', `/var/log/sendmail.st')')dnl +dnl turn on S flag for local mailer +MODIFY_MAILER_FLAGS(`LOCAL', `+S')dnl +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', /usr/libexec/mail.local)')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `mail $u')')dnl +ifdef(`UUCP_MAILER_PATH',, `define(`UUCP_MAILER_PATH', `/usr/local/bin/uux')')dnl +ifdef(`UUCP_MAILER_ARGS',, `define(`UUCP_MAILER_ARGS', `uux - -r -z -a$g $h!rmail ($u)')')dnl diff --git a/gnu/usr.sbin/sendmail/cf/ostype/mpeix.m4 b/gnu/usr.sbin/sendmail/cf/ostype/mpeix.m4 new file mode 100644 index 00000000000..397b6ddea43 --- /dev/null +++ b/gnu/usr.sbin/sendmail/cf/ostype/mpeix.m4 @@ -0,0 +1,22 @@ +divert(-1) +# +# Copyright (c) 2001 Sendmail, Inc. and its suppliers. +# All rights reserved. +# +# By using this file, you agree to the terms and conditions set +# forth in the LICENSE file which can be found at the top level of +# the sendmail distribution. +# +# + +divert(0) +VERSIONID(`$Sendmail: mpeix.m4,v 1.1 2001/12/13 23:56:40 gshapiro Exp $') + +ifdef(`LOCAL_MAILER_PATH',, `define(`LOCAL_MAILER_PATH', `/bin/tsmail')')dnl +_DEFIFNOT(`LOCAL_MAILER_FLAGS', `mu9')dnl +ifdef(`LOCAL_MAILER_ARGS',, `define(`LOCAL_MAILER_ARGS', `tsmail $u')')dnl +ifdef(`LOCAL_SHELL_PATH',, `define(`LOCAL_SHELL_PATH', `/bin/sh')')dnl +ifdef(`confDEF_USER_ID',, `define(`confDEF_USER_ID', `SERVER.SENDMAIL')')dnl +ifdef(`confTRUSTED_USER',, `define(`confTRUSTED_USER', `SERVER.SENDMAIL')')dnl +define(`confTIME_ZONE', `USE_TZ')dnl +define(`confDONT_BLAME_SENDMAIL', `ForwardFileInGroupWritableDirPath')dnl diff --git a/gnu/usr.sbin/sendmail/contrib/qtool.8 b/gnu/usr.sbin/sendmail/contrib/qtool.8 index 17affe5c08f..fc0c847c96b 100644 --- a/gnu/usr.sbin/sendmail/contrib/qtool.8 +++ b/gnu/usr.sbin/sendmail/contrib/qtool.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1999 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1999, 2001 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" .\" By using this file, you agree to the terms and conditions set @@ -6,18 +6,18 @@ .\" the sendmail distribution. .\" .\" -.\" $Sendmail: qtool.8,v 8.12 2000/12/15 19:53:35 gshapiro Exp $ +.\" $Sendmail: qtool.8,v 8.16 2001/11/21 19:21:20 gshapiro Exp $ .\" -.TH QTOOL 8 "$Date: 2001/09/11 19:02:48 $" +.TH QTOOL 8 "$Date: 2002/01/14 03:21:39 $" .SH NAME qtool \- manipulate sendmail queues .SH SYNOPSIS .B qtool.pl -.RB [options] +.RB [options] target_directory source [source ...] .PP -.B qtool.pl [-d|-b] +.B qtool.pl [-Q][-d|-b] .RB [options] source [source ...] .SH DESCRIPTION @@ -28,8 +28,8 @@ running. .PP With no options, .B qtool -will move any queue files as specified by \fIsource\fP into -\fItarget_directory\fP. \fISource\fP can be either an individual +will move any queue files as specified by \fIsource\fP into +\fItarget_directory\fP. \fISource\fP can be either an individual queue control file, a queue file id, or a queue directory. .PP If the -d option is specified, qtool will delete the messages specified by @@ -38,23 +38,27 @@ source instead of moving them. If the -b option is specified, the selected messages will be bounced by running sendmail with the -OTimeout.queuereturn=now option. .SS Options -.TP +.TP \fB\-b\fP Bounce all of the messages specified by source. The messages will be bounced immediately. No attempt will be made to deliver the messages. -.TP +.TP \fB\-C\fP configfile Specify the sendmail config file. Defaults to /etc/mail/sendmail.cf. .TP \fB\-d\fP Delete all of the messages specified by source. -.TP +.TP \fB\-e\fP \fIperl_expression\fP -Evalute \fIperl_expression\fP for each queue file as specified -by \fIsource\fP. If \fIperl_expression\fP evaluates to true, then that +Evalute \fIperl_expression\fP for each queue file as specified +by \fIsource\fP. If \fIperl_expression\fP evaluates to true, then that queue file is moved. See below for more detail on \fIperl_expression\fP. -.TP +.TP +\fB\-Q\fP +Operate on quarantined items +(queue control file begins with hf instead of qf). +.TP \fB\-s\fP \fIseconds\fP Move only the queue files specified by \fIsource\fP that have a modification time older than \fIseconds\fP. @@ -78,9 +82,6 @@ The last time the body was modified since the epoch in seconds. \fBbody_size\fP The size of the body file in bytes. .TP -\fBcharset\fP -Character set (for future use). -.TP \fBcontent-length\fP Content-Length: header value (Solaris sendmail only). .TP @@ -88,7 +89,7 @@ Content-Length: header value (Solaris sendmail only). The controlling user. .TP \fBcontrol_last_mod_time\fP -The last time the body was modified since the epoch in seconds. +The last time the control file was modified since the epoch in seconds. .TP \fBcontrol_size\fP The size of the control file in bytes. @@ -96,15 +97,24 @@ The size of the control file in bytes. \fBcreation_time\fP The time when the control file was created. .TP +\fBcurrent_delay\fP +Current delay for queue delay algorithm if _FFR_QUEUEDELAY is enabled. +.TP \fBdata_file_name\fP The data file name (deprecated). .TP +\fBdeliver_by\fP +Deliver by flag and deadline for DELIVERBY ESMTP extension. +.TP \fBenvid\fP Original envelope id form ESMTP. .TP \fBerror_recipient\fP The error recipient (deprecated). .TP +\fBfinal_recipient\fP +Final recipient (for DSNs). +.TP \fBflags\fP Array of characters that can be the following values: .PD 0 @@ -114,7 +124,7 @@ w warning message has been sent .TP 8 r -This is an error respone or DSN +This is an error response or DSN .TP 8 8 has 8 bit data in body @@ -157,6 +167,13 @@ Original recipient (ORCPT= parameter). \fBpriority\fP Adjusted priority of message. .TP +\fBquarantine_reason\fP +Quarantine reason for quarantined (held) envelopes if _FFR_QUARANTINE is +enabled. +.TP +\fBqueue_delay\fP +Queue delay algorithm if _FFR_QUEUEDELAY is enabled. +.TP \fBrecipient\fP Array of character flags followed by colon and recipient name. Flags: .PD 0 @@ -199,15 +216,15 @@ Moves the message with id d6CLQh100847 in queue q1 to queue q2. Moves all of the queue files that have had three attempted deliveries from queue q1 to queue q2. .SH BUGS -In sendmail 8.12, it is possible for a message's qf and df files +In sendmail 8.12, it is possible for a message's queue and data files (df) to be stored in different queues. -In this situation, you must give qtool the pathname of the qf file, -not of the df file. -To be safe, never feed qtool the pathname of a df file. +In this situation, you must give qtool the pathname of the queue file, +not of the data file (df). +To be safe, never feed qtool the pathname of a data file (df). .SH SEE ALSO sendmail(8) .SH HISTORY The .B qtool -command appeared in +command appeared in sendmail 8.10. diff --git a/gnu/usr.sbin/sendmail/contrib/qtool.pl b/gnu/usr.sbin/sendmail/contrib/qtool.pl index 0f81449a946..14211349775 100644 --- a/gnu/usr.sbin/sendmail/contrib/qtool.pl +++ b/gnu/usr.sbin/sendmail/contrib/qtool.pl @@ -1,9 +1,9 @@ #!/usr/bin/env perl ## -## Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. -## All rights reserved. +## Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. +## All rights reserved. ## -## $Sendmail: qtool.pl,v 8.20 2000/12/05 16:10:07 dmoen Exp $ +## $Sendmail: qtool.pl,v 8.26 2001/11/21 19:26:17 gshapiro Exp $ ## use strict; use File::Basename; @@ -43,7 +43,7 @@ use Getopt::Std; ## queue message. This lets you check for any value in the message ## headers or the control file. Here's an example: ## -## ./qtool.pl -e '$msg->{num_delivery_attempts} >= 2' /q1 /q2 +## ./qtool.pl -e '$msg{num_delivery_attempts} >= 2' /q1 /q2 ## ## This would move any queue files whose number of delivery attempts ## is greater than or equal to 2 from the queue 'q2' to the queue 'q1'. @@ -61,9 +61,10 @@ my $source; my $result; my $action; my $new_condition; +my $qprefix; my $conditions = new Compound(); -Getopt::Std::getopts('bC:de:s:', \%opts); +Getopt::Std::getopts('bC:de:Qs:', \%opts); sub move_action { @@ -113,6 +114,15 @@ if (defined $opts{e}) $conditions->add($new_condition); } +if (defined $opts{Q}) +{ + $qprefix = "hf"; +} +else +{ + $qprefix = "qf"; +} + if ($action == \&move_action) { $dst_name = shift(@ARGV); @@ -188,14 +198,18 @@ while (($source_name, $source) = each(%sources)) sub usage { - print("Usage: $0 [options] directory source ...\n"); - print(" $0 [-d|-b] source ...\n"); - print("options:\n"); - print(" -b Bounce the messages specified by source.\n"); - print(" -C configfile Specify sendmail config file.\n"); - print(" -d Delete the messages specified by source.\n"); - print(" -e [perl expression] Move only messages for which perl expression returns true.\n"); - print(" -s [seconds] Move only messages whose qf file is older than seconds.\n"); + print("Usage:\t$0 [options] directory source ...\n"); + print("\t$0 [-Q][-d|-b] source ...\n"); + print("Options:\n"); + print("\t-b\t\tBounce the messages specified by source.\n"); + print("\t-C configfile\tSpecify sendmail config file.\n"); + print("\t-d\t\tDelete the messages specified by source.\n"); + print("\t-e [perl expression]\n"); + print("\t\t\tMove only messages for which perl expression\n"); + print("\t\t\treturns true.\n"); + print("\t-Q\t\tOperate on quarantined files.\n"); + print("\t-s [seconds]\tMove only messages whose queue file is older\n"); + print("\t\t\tthan seconds.\n"); } ## @@ -236,10 +250,10 @@ sub add_source $data_dir_name = $source_dir_name; $source_prefix = substr($source_base_name, 0, 2); - if (!-d $source_name && $source_prefix ne 'qf' && + if (!-d $source_name && $source_prefix ne $qprefix && $source_prefix ne 'df') { - $source_base_name = "qf$source_base_name"; + $source_base_name = "$qprefix$source_base_name"; $source_name = File::Spec->catfile("$source_dir_name", "$source_base_name"); } @@ -248,7 +262,7 @@ sub add_source if (!-e $source_name) { $source_name = File::Spec->catfile("$source_dir_name", "qf", - "qf$source_id"); + "$qprefix$source_id"); if (!-e $source_name) { return "'$source_name' does not exist"; @@ -413,7 +427,7 @@ sub initialize my $queue_dir = shift; $self->{id} = shift; - $self->{file_name} = $queue_dir . '/qf' . $self->{id}; + $self->{file_name} = $queue_dir . '/' . $qprefix . $self->{id}; $self->{headers} = {}; } @@ -442,6 +456,7 @@ sub parse 'E' => 'error_recipient', 'F' => 'flags', 'H' => 'parse_header', + 'G' => 'queue_delay', 'I' => 'inode_number', 'K' => 'next_delivery_time', 'L' => 'content-length', @@ -450,11 +465,14 @@ sub parse 'P' => 'priority', 'Q' => 'original_recipient', 'R' => 'recipient', + 'q' => 'quarantine_reason', + 'r' => 'final_recipient', 'S' => 'sender', 'T' => 'creation_time', 'V' => 'version', - 'X' => 'charset', + 'Y' => 'current_delay', 'Z' => 'envid', + '!' => 'deliver_by', '$' => 'macro' ); my $line; @@ -525,7 +543,7 @@ sub parse_header if (ref($headers->{$last_header}) eq 'ARRAY') { $headers->{$last_header}[-1] = - $headers->{$last_header}[-1] . $line; + $headers->{$last_header}[-1] . $line; } else { @@ -825,7 +843,7 @@ sub move $df_dest = $destination; } - if (-e File::Spec->catfile($qf_dest, "qf$self->{id}")) + if (-e File::Spec->catfile($qf_dest, "$qprefix$self->{id}")) { $result = "There is already a queued message with id '$self->{id}' in '$destination'"; } @@ -929,7 +947,8 @@ sub initialize ## READ - Loads the queue with all of the objects that reside in it. ## ## This reads the queue's directory and creates QueuedMessage objects -## for every file in the queue that starts with 'qf'. +## for every file in the queue that starts with 'qf' or 'hf' +## (depending on the -Q option). ## sub read @@ -965,7 +984,7 @@ sub read return "Unable to open directory '$control_dir'"; } - @control_files = grep { /^qf.*/ && -f "$control_dir/$_" } readdir(QUEUE_DIR); + @control_files = grep { /^$qprefix.*/ && -f "$control_dir/$_" } readdir(QUEUE_DIR); closedir(QUEUE_DIR); foreach $file_name (@control_files) { diff --git a/gnu/usr.sbin/sendmail/doc/op/op.me b/gnu/usr.sbin/sendmail/doc/op/op.me index e3f9c6df89f..0bafcbf46a1 100644 --- a/gnu/usr.sbin/sendmail/doc/op/op.me +++ b/gnu/usr.sbin/sendmail/doc/op/op.me @@ -9,7 +9,7 @@ .\" the sendmail distribution. .\" .\" -.\" $Sendmail: op.me,v 8.575 2001/09/28 22:03:15 ca Exp $ +.\" $Sendmail: op.me,v 8.592 2001/12/26 03:44:39 ca Exp $ .\" .\" eqn op.me | pic | troff -me .\" @@ -88,7 +88,7 @@ Sendmail, Inc. .de Ve Version \\$2 .. -.Ve $Revision: 1.10 $ +.Ve $Revision: 1.11 $ .rm Ve .sp For Sendmail Version 8.12 @@ -309,43 +309,6 @@ program; for details see (This section is not yet complete. For now, see the file devtools/README for details.) See sendmail/README for various compilation flags that can be set. -.sh 3 "Notes About Some Configuration Settings" -.\"XXX -.pp -Not all configuration setting are critical to getting sendmail to run -correctly. Note that "correctly" does not directly imply highest -performance immediately. -.pp -.i Sendmail -uses the functions -.i strlcat \|(3) -and -.i strlcpy \|(3) -which, at the time of writing, are not widely available. -Further, for those systems where -these functions are available they are new enough that performance -tuning has not yet occurred. -.i Sendmail -includes in its sm library (aka -.i libsm ) -these functions with an sm_ prefix. By default sendmail uses the -.i libsm -versions of these functions as performance tuning has occurred. -A performance testing program -.i libsm/b-strl.c -can be used to evaluate which versions of the functions are faster: -.i libsm -or the system's -.i libc . -If you decide to use the -.i libc -versions then add -.(b --DSM_CONF_STRL=0 -.)b -as compile time option, see -.i $BUILDTOOLS/README -for details. .sh 3 "Tweaking the Makefile" .pp .\" .b "XXX This should all be in the Site Configuration File section." @@ -1208,6 +1171,12 @@ How to select either of these types is discussed in the appendix Persistent queue runners have the advantage that no new processes need to be spawned at certain intervals; they just sleep for a specified time after they finished a queue run. +Another advantage of persistent queue runners is that only one process +belonging to a workgroup (a workgroup is a set of queue groups) +collects the data for a queue run +and then multiple queue runner may go ahead using that data. +This can significantly reduce the disk I/O necessary to read the +queue files compared to starting multiple queue runners directly. Their disadvantage is that a new queue run is only started after all queue runners belonging to a group finished their tasks. In case one of the queue runners tries delivery to a slow recipient site @@ -2968,6 +2937,11 @@ that are group writable on the grounds that they might have been tampered with by someone other than the owner; it will even refuse to read files in group writable directories. +Also, sendmail will refuse to create a new aliases database in an +unsafe directory. You can get around this by manually creating the +database file as a trusted user ahead of time and then rebuilding the +aliases database with +.b newaliases . .pp If you are .i quite @@ -3089,6 +3063,7 @@ Allow files that are links in writable directories. .ip LinkedMapInWritableDir Allow map files that are links in writable directories. +This includes alias database files. .ip LinkedServiceSwitchFileInWritableDir Allow the service switch file to be a link even if the directory is writable. @@ -3100,6 +3075,7 @@ and .i dbm files) in unsafe directories. +This includes alias database files. .ip NonRootSafeAddr Do not mark file and program deliveries as unsafe if sendmail is not running with root privileges. @@ -3268,6 +3244,9 @@ when faced with a a broken nameservers that returns SERVFAIL (a temporary failure) on T_AAAA (IPv6) lookups during hostname canonification. +Notice: it might be necessary to apply the same (or similar) options to +.i submit.cf +too. .pp Version level 1 configurations (see the section about Configuration Version Level) @@ -4493,6 +4472,8 @@ The full name of the sender. The home directory of the recipient. .ip $_ The validated sender address. +See also +.b ${client_resolve} . .ip ${addr_type} The type of the address which is currently being rewritten. This macro contains up to three characters, the first @@ -4568,6 +4549,16 @@ FORGED forward lookup doesn't match reverse lookup TEMP temporary lookup failure .)b Defined in the SMTP server only. +.i sendmail +performs a hostname lookup on the IP address of the connecting client. +Next the IP addresses of that hostname are looked up. +If the client IP address does not appear in that list, +then the hostname is maybe forged. +This is reflected as the value FORGED for +.b ${client_resolve} +and it also shows up in +.b $_ +as "(may be forged)". .ip ${cn_issuer} The CN (common name) of the CA that signed the presented certificate (STARTTLS only). @@ -5491,11 +5482,8 @@ This mailer wants a .q Full-Name: header line. .ip X -This mailer want to use the hidden dot algorithm -as specified in RFC821; -basically, -any line beginning with a dot -will have an extra dot prepended +This mailer wants to use the hidden dot algorithm as specified in RFC821; +basically, any line beginning with a dot will have an extra dot prepended (to be stripped at the other end). This insures that lines in the message containing a dot will not terminate the message prematurely. @@ -5510,7 +5498,10 @@ that is specifically designed for delivery to a local mailbox. .ip Z Apply DialDelay (if set) to this mailer. .ip 0 -Don't look up MX records for hosts sent via SMTP. +Don't look up MX records for hosts sent via SMTP/LMTP. +Do not apply +.b FallbackMXhost +either. .ip 1 Don't send null characters ('\\0') to this mailer. .ip 2 @@ -5636,8 +5627,14 @@ M*include*, P=/dev/null, F=su, A=INCLUDE $u .pp Builtin pathnames are [FILE] and [IPC], the former is used for delivery to files, the latter for delivery via interprocess communication. -For mailers that use [IPC] as pathname the argument vector +For mailers that use [IPC] as pathname the argument vector (A=) must start with TCP or FILE for delivery via a TCP or a Unix domain socket. +If TCP is used, the second argument must be the name of the host +to contact. +Optionally a third argument can be used to specify a port, +the default is smtp (port 25). +If FILE is used, the second argument must be the name of +the Unix domain socket. .pp If the argument vector does not contain $u then .i sendmail @@ -6062,6 +6059,8 @@ with intervening white space or commas. .ta 4n A Use the AUTH= parameter for the MAIL FROM command only when authentication succeeded. + This can be used as a workaround for broken + MTAs that do not implement RFC2554 correctly. a protection from active (non-dictionary) attacks during authentication exchange. c require mechanisms which pass client credentials, @@ -6684,7 +6683,7 @@ unless the name is surrounded by square brackets. This is intended to be used by sites with poor network connectivity. Messages which are undeliverable due to temporary address failures (e.g., DNS failure) -also go to the FallbackMX host. +also go to the FallbackMXhost. .ip FastSplit [no short name] If set to a value greater than zero (the default is one), @@ -7160,9 +7159,9 @@ Second, it specifies the directory D which is the ancestor of all queue directories, and which sendmail uses as its current working directory. When sendmail dumps core, it leaves its core files in D. There are two cases. -If \fIdir\fR ends with an asterisk (eg, \fI/var/spool/mqueue/q*\fR), +If \fIdir\fR ends with an asterisk (eg, \fI/var/spool/mqueue/qd*\fR), then all of the directories or symbolic links to directories -beginning with `q' in +beginning with `qd' in .i /var/spool/mqueue will be used as queue directories of the default queue group, and @@ -7301,16 +7300,9 @@ or .b \- ) can be specified to work around some broken nameservers which return SERVFAIL (a temporary failure) on T_AAAA (IPv6) lookups. -.b N.B. -Prior to 8.7, -this option indicated that the name server be responding -in order to accept addresses. -This has been replaced by checking to see -if the -.q dns -method is listed in the service switch entry for the -.q hosts -service. +Notice: it might be necessary to apply the same (or similar) options to +.i submit.cf +too. .ip RrtImpliesDsn [R] If this option is set, a @@ -7570,7 +7562,7 @@ doubled in the code execution path for this mode. List of options for SMTP STARTTLS for the server consisting of single characters with intervening white space or commas. -The flag ``v'' disables client verification, and hence +The flag ``V'' disables client verification, and hence it is not possible to use a client certificate for relaying. Currently there are no other flags available. .ip TempFileMode=\fImode\fP @@ -9155,9 +9147,6 @@ The maximum number of items in the user environment that will be passed to subordinate mailers. .ip "MAXMXHOSTS [100]" The maximum number of MX records we will accept for any single host. -.ip "MAXALIASDB [12]" -The maximum number of alias databases that can be open at any time. -Note that there may also be an open file limit. .ip "MAXMAPSTACK [12]" The maximum number of maps that may be "stacked" in a .b sequence @@ -9794,6 +9783,14 @@ can contain several certificates of CAs. The DNs of these certificates are sent to the client during the TLS handshake (as part of the CertificateRequest) as the list of acceptable CAs. +However, do not list too many root CAs in that file, otherwise +the TLS handshake may fail; e.g., +.(b +error:14094417:SSL routines:SSL3_READ_BYTES: +sslv3 alert illegal parameter:s3_pkt.c:964:SSL alert number 47 +.)b +You should probably put only the CA cert into that file +that signed your own cert(s), or at least only those you trust. The CACERTPath directory must contain the hashes of each CA certificate as filenames (or as links to them). Symbolic links can be generated with the following @@ -10288,6 +10285,21 @@ during that session. Sometimes the xf file must be generated before a queue group has been selected; in this case, the xf file will be stored in a directory of the default queue group. +.ip Qf +A ``lost'' queue control file. +.i sendmail +renames a +.b qf +file to +.b Qf +if there is a severe (configuration) problem that cannot be solved without +human intervention. +Search the logfile for the queue file id to figure out what happened. +After you resolved the problem, you can rename the +.b Qf +file to +.b qf +and send it again. .pp The .b qf @@ -10544,7 +10556,7 @@ replace it with a blank sheet for double-sided output. .\".sz 10 .\"Eric Allman .\".sp -.\"Version $Revision: 1.10 $ +.\"Version $Revision: 1.11 $ .\".ce 0 .bp 3 .ce diff --git a/gnu/usr.sbin/sendmail/editmap/editmap.c b/gnu/usr.sbin/sendmail/editmap/editmap.c index 305826700f2..52f2ce66da3 100644 --- a/gnu/usr.sbin/sendmail/editmap/editmap.c +++ b/gnu/usr.sbin/sendmail/editmap/editmap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1992 Eric P. Allman. All rights reserved. * Copyright (c) 1992, 1993 @@ -22,7 +22,7 @@ SM_UNUSED(static char copyright[]) = #endif /* ! lint */ #ifndef lint -SM_UNUSED(static char id[]) = "@(#)$Sendmail: editmap.c,v 1.21 2001/08/27 18:09:09 gshapiro Exp $"; +SM_UNUSED(static char id[]) = "@(#)$Sendmail: editmap.c,v 1.22 2002/01/11 23:52:27 gshapiro Exp $"; #endif /* ! lint */ @@ -130,7 +130,7 @@ main(argc, argv) SMDB_MAX_USER_NAME_LEN); #define OPTIONS "C:fquxvN" - while ((opt = getopt(argc, argv, OPTIONS)) != EOF) + while ((opt = getopt(argc, argv, OPTIONS)) != -1) { switch (opt) { diff --git a/gnu/usr.sbin/sendmail/include/libmilter/mfapi.h b/gnu/usr.sbin/sendmail/include/libmilter/mfapi.h index 9258da0a32e..3c366e0633b 100644 --- a/gnu/usr.sbin/sendmail/include/libmilter/mfapi.h +++ b/gnu/usr.sbin/sendmail/include/libmilter/mfapi.h @@ -7,7 +7,7 @@ * the sendmail distribution. * * - * $Sendmail: mfapi.h,v 8.32 2001/09/13 20:38:40 ca Exp $ + * $Sendmail: mfapi.h,v 8.35 2001/10/09 19:05:24 gshapiro Exp $ */ /* @@ -306,6 +306,15 @@ LIBMILTER_API char * smfi_getsymval __P((SMFICTX *, char *)); LIBMILTER_API int smfi_setreply __P((SMFICTX *, char *, char *, char *)); +#if _FFR_MULTILINE +/* +** Alternatively, smfi_setmlreply can be called if a multi-line SMTP reply +** is needed. +*/ + +LIBMILTER_API int smfi_setmlreply __P((SMFICTX *, const char *, const char *, ...)); +#endif /* _FFR_MULTILINE */ + /* ** Set the specific reply code to be used in response to the active ** command. If not specified, a generic reply code is used. diff --git a/gnu/usr.sbin/sendmail/include/libsmdb/smdb.h b/gnu/usr.sbin/sendmail/include/libsmdb/smdb.h index 4628666b075..488b1c94ab3 100644 --- a/gnu/usr.sbin/sendmail/include/libsmdb/smdb.h +++ b/gnu/usr.sbin/sendmail/include/libsmdb/smdb.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: smdb.h,v 8.37 2001/09/11 03:08:28 gshapiro Exp $ + * $Sendmail: smdb.h,v 8.38 2001/11/19 19:30:03 gshapiro Exp $ * */ @@ -18,12 +18,6 @@ # include <sm/gen.h> # include <sm/errstring.h> -# ifndef NDBM -# ifndef NEWDB -ERROR NDBM or NEWDB must be defined. -# endif /* ! NEWDB */ -# endif /* ! NDBM */ - # ifdef NDBM # include <ndbm.h> # endif /* NDBM */ diff --git a/gnu/usr.sbin/sendmail/include/sendmail/mailstats.h b/gnu/usr.sbin/sendmail/include/sendmail/mailstats.h index 600581ec278..86650481f8b 100644 --- a/gnu/usr.sbin/sendmail/include/sendmail/mailstats.h +++ b/gnu/usr.sbin/sendmail/include/sendmail/mailstats.h @@ -10,10 +10,14 @@ * the sendmail distribution. * * - * $Sendmail: mailstats.h,v 8.17 2001/09/04 22:42:40 ca Exp $ + * $Sendmail: mailstats.h,v 8.18 2001/11/21 13:39:10 gshapiro Exp $ */ -#define STAT_VERSION 3 +#if _FFR_QUARANTINE +# define STAT_VERSION 4 +#else /* _FFR_QUARANTINE */ +# define STAT_VERSION 3 +#endif /* _FFR_QUARANTINE */ #define STAT_MAGIC 0x1B1DE /* @@ -35,4 +39,7 @@ struct statistics long stat_bt[MAXMAILERS]; /* kbytes to each mailer */ long stat_nr[MAXMAILERS]; /* # rejects by each mailer */ long stat_nd[MAXMAILERS]; /* # discards by each mailer */ +#if _FFR_QUARANTINE + long stat_nq[MAXMAILERS]; /* # quarantines by each mailer */ +#endif /* _FFR_QUARANTINE */ }; diff --git a/gnu/usr.sbin/sendmail/include/sm/conf.h b/gnu/usr.sbin/sendmail/include/sm/conf.h index 600dabeef49..67fc09e2e8c 100644 --- a/gnu/usr.sbin/sendmail/include/sm/conf.h +++ b/gnu/usr.sbin/sendmail/include/sm/conf.h @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Sendmail: conf.h,v 1.78 2001/09/23 03:13:09 ca Exp $ + * $Sendmail: conf.h,v 1.82 2001/12/20 16:14:48 ca Exp $ */ /* @@ -50,6 +50,14 @@ # define HASLSTAT 1 /* has lstat(2) call */ # endif /* ! HASLSTAT */ +# ifndef HASNICE +# define HASNICE 1 /* has nice(2) call */ +# endif /* ! HASNICE */ + +# ifndef HASRRESVPORT +# define HASRRESVPORT 1 /* has rrsevport(3) call */ +# endif /* ! HASRRESVPORT */ + /********************************************************************** ** "Hard" compilation options. ** #define these if they are available; comment them out otherwise. @@ -195,11 +203,14 @@ extern void hard_syslog(); # define LA_TYPE LA_INT # define FSHIFT 16 # define LA_AVENRUN "avenrun" -# ifndef _AIX4 +# if !defined(_AIX4) || _AIX4 < 40300 # ifndef __BIT_TYPES_DEFINED__ # define SM_INT32 int # endif /* __BIT_TYPES_DEFINED__ */ -# endif /* ! _AIX4 */ +# endif /* !defined(_AIX4) || _AIX4 < 40300 */ +# if !defined(_AIX4) || _AIX4 < 40200 +# define SM_CONF_SYSLOG 0 +# endif /* !defined(_AIX4) || _AIX4 < 40200 */ # endif /* _AIX3 */ @@ -686,7 +697,8 @@ typedef int pid_t; # define HASSETSID 1 /* has the setsid(2) POSIX syscall */ # define HASINITGROUPS 1 # define HASSETVBUF 1 -# define HASSETREUID 1 +# define HASSETREUID 0 +# define HASSETEUID 1 # define USESETEUID 1 /* has usable seteuid(2) call */ # define HASLSTAT 1 # define HASSETRLIMIT 1 @@ -1594,6 +1606,73 @@ typedef int pid_t; # endif /* apollo */ /* +** MPE-iX +** +** Requires MPE 6.0 or greater. See sendmail/README for more info. +** +** From Mark Bixby <mark_bixby@hp.com> or <mark@bixby.org>. +*/ + +# ifdef MPE + +# include <sys/sysmacros.h> +# include <fcntl.h> + +/* Sendmail stuff */ +# define HASFCHOWN 0 /* lacks fchown() */ +# define HASGETUSERSHELL 0 /* lacks getusershell() */ +# ifdef HASNICE +# undef HASNICE +# endif /* HASNICE */ +# define HASNICE 0 /* lacks nice() */ +# define HASRANDOM 0 /* lacks random() */ +# ifdef HASRRESVPORT +# undef HASRRESVPORT +# endif /* HASRRESVPORT */ +# define HASRRESVPORT 0 /* lacks rresvport() */ +# define IP_SRCROUTE 0 /* lacks IP source routing fields */ +# ifdef MATCHGECOS +# undef MATCHGECOS +# endif /* MATCHGECOS */ +# define MATCHGECOS 0 /* lacks an initialized GECOS field */ +# define NEEDFSYNC 1 /* use sendmail's fsync() */ +# define NEEDLINK 1 /* use sendmail's link() */ +# define NOFTRUNCATE 1 /* lacks ftruncate() */ +# define SFS_TYPE SFS_NONE /* can't determine disk space */ +# define SM_CONF_SYSLOG 0 /* use sendmail decl of syslog() */ +# define USE_DOUBLE_FORK 0 /* don't fork an intermediate zombie */ +# define USE_ENVIRON 1 /* use environ instead of envp */ + +/* Missing header stuff */ +# define AF_UNSPEC 0 +# define AF_MAX AF_INET +# define IFF_LOOPBACK 0x8 +# define IN_LOOPBACKNET 127 +# define MAXNAMLEN NAME_MAX +# define S_IEXEC S_IXUSR +# define S_IREAD S_IRUSR +# define S_IWRITE S_IWUSR + +/* Present header stuff that needs to be missing */ +# undef NGROUPS_MAX + +/* Shadow functions */ +# define bind sendmail_mpe_bind +# define _exit sendmail_mpe__exit +# define exit sendmail_mpe_exit +# define fcntl sendmail_mpe_fcntl +# define getegid sendmail_mpe_getegid +# define geteuid sendmail_mpe_geteuid +# define getpwnam sendmail_mpe_getpwnam +# define getpwuid sendmail_mpe_getpwuid +# define setgid sendmail_mpe_setgid +# define setuid sendmail_mpe_setuid +extern int sendmail_mpe_fcntl __P((int, int, ...)); +extern struct passwd * sendmail_mpe_getpwnam __P((const char *)); +extern struct passwd * sendmail_mpe_getpwuid __P((uid_t)); +# endif /* MPE */ + +/* ** System V Rel 5.x (a.k.a Unixware7 w/o BSD-Compatibility Libs ie. native) ** ** Contributed by Paul Gampe <paulg@apnic.net> @@ -2069,12 +2148,12 @@ typedef struct msgb mblk_t; /* ** Siemens Nixdorf Informationssysteme AG SINIX ** -** Contributed by Gerald Rinske <Gerald.Rinske@mch.sni.de> -** of Siemens Business Services VAS. +** Contributed by Gerald Rinske of Siemens Business Services VAS. */ # ifdef sinix # define HASRANDOM 0 /* has random(3) */ -# define SYSLOG_BUFSIZE 1024 +# define SYSLOG_BUFSIZE 1024 +# define SM_INT32 int /* 32bit integer */ # endif /* sinix */ /* @@ -2294,6 +2373,14 @@ typedef struct msgb mblk_t; # define SECUREWARE 0 /* assume no SecureWare C2 auditing hooks */ # endif /* ! SECUREWARE */ +# ifndef USE_DOUBLE_FORK +# define USE_DOUBLE_FORK 1 /* avoid intermediate zombies */ +# endif /* ! USE_DOUBLE_FORK */ + +# ifndef USE_ENVIRON +# define USE_ENVIRON 0 /* use main() envp instead of extern environ */ +# endif /* ! USE_ENVIRON */ + # ifndef USE_SIGLONGJMP # define USE_SIGLONGJMP 0 /* assume setjmp handles signals properly */ # endif /* ! USE_SIGLONGJMP */ diff --git a/gnu/usr.sbin/sendmail/include/sm/ldap.h b/gnu/usr.sbin/sendmail/include/sm/ldap.h index 062e957df4e..b97db5c8eaf 100644 --- a/gnu/usr.sbin/sendmail/include/sm/ldap.h +++ b/gnu/usr.sbin/sendmail/include/sm/ldap.h @@ -1,18 +1,19 @@ /* - * Copyright (c) 2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: ldap.h,v 1.4 2001/04/18 07:06:52 gshapiro Exp $ + * $Sendmail: ldap.h,v 1.9 2002/01/11 22:06:50 gshapiro Exp $ */ #ifndef SM_LDAP_H # define SM_LDAP_H # include <sm/conf.h> +# include <sm/rpool.h> # ifndef LDAPMAP_MAX_ATTR # define LDAPMAP_MAX_ATTR 64 @@ -25,6 +26,21 @@ # endif /* ! LDAPMAP_MAX_PASSWD */ # if LDAPMAP + +# if _FFR_LDAP_RECURSION + +/* Attribute types */ +# define LDAPMAP_ATTR_NORMAL 0 +# define LDAPMAP_ATTR_DN 1 +# define LDAPMAP_ATTR_FILTER 2 +# define LDAPMAP_ATTR_URL 3 +# define LDAPMAP_ATTR_FINAL 4 + +/* sm_ldap_results() flags */ +# define SM_LDAP_SINGLEMATCH 0x0001 +# define SM_LDAP_MATCHONLY 0x0002 +# endif /* _FFR_LDAP_RECURSION */ + struct sm_ldap_struct { /* needed for ldap_open or ldap_init */ @@ -49,6 +65,10 @@ struct sm_ldap_struct int ldap_scope; char *ldap_filter; char *ldap_attr[LDAPMAP_MAX_ATTR + 1]; +# if _FFR_LDAP_RECURSION + int ldap_attr_type[LDAPMAP_MAX_ATTR + 1]; + char *ldap_attr_final[LDAPMAP_MAX_ATTR + 1]; +# endif /* _FFR_LDAP_RECURSION */ bool ldap_attrsonly; /* args for ldap_result */ @@ -62,12 +82,28 @@ struct sm_ldap_struct void *ldap_next; }; -typedef struct sm_ldap_struct SM_LDAP_STRUCT; +typedef struct sm_ldap_struct SM_LDAP_STRUCT; + +# if _FFR_LDAP_RECURSION +struct sm_ldap_recurse_list +{ + char *lr_search; + int lr_type; + struct sm_ldap_recurse_list *lr_next; +}; + +typedef struct sm_ldap_recurse_list SM_LDAP_RECURSE_LIST; +# endif /* _FFR_LDAP_RECURSION */ /* functions */ extern void sm_ldap_clear __P((SM_LDAP_STRUCT *)); extern bool sm_ldap_start __P((char *, SM_LDAP_STRUCT *)); extern int sm_ldap_search __P((SM_LDAP_STRUCT *, char *)); +# if _FFR_LDAP_RECURSION +extern int sm_ldap_results __P((SM_LDAP_STRUCT *, int, int, char, + SM_RPOOL_T *, char **, + SM_LDAP_RECURSE_LIST *)); +# endif /* _FFR_LDAP_RECURSION */ extern void sm_ldap_setopts __P((LDAP *, SM_LDAP_STRUCT *)); extern int sm_ldap_geterrno __P((LDAP *)); extern void sm_ldap_close __P((SM_LDAP_STRUCT *)); diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_aix.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_aix.h index faf10acc81a..00cfa9034d1 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_aix.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_aix.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_aix.h,v 1.8 2001/10/01 15:04:26 ca Exp $ + * $Sendmail: sm_os_aix.h,v 1.9 2001/10/09 23:12:13 ca Exp $ */ /* @@ -33,8 +33,3 @@ # endif /* SM_CONF_SYSLOG */ # endif /* ! _AIX4 */ #endif /* _AIX3 */ - -/* can't set real gid */ -#ifndef SM_CONF_CANT_SETRGID -# define SM_CONF_CANT_SETRGID 1 -#endif /* SM_CONF_CANT_SETRGID */ diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_hp.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_hp.h index 6615d541570..25e52b423b4 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_hp.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_hp.h @@ -1,12 +1,12 @@ /* - * Copyright (c) 2000 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_hp.h,v 1.6 2000/12/05 19:00:47 dmoen Exp $ + * $Sendmail: sm_os_hp.h,v 1.8 2001/10/31 15:36:56 ca Exp $ */ /* @@ -24,3 +24,11 @@ #ifndef SM_CONF_MSG # define SM_CONF_MSG 1 #endif /* SM_CONF_MSG */ + +/* max/min buffer size of other than regular files */ +#ifndef SM_IO_MAX_BUF +# define SM_IO_MAX_BUF 8192 +#endif /* SM_IO_MAX_BUF */ +#ifndef SM_IO_MIN_BUF +# define SM_IO_MIN_BUF 4096 +#endif /* SM_IO_MIN_BUF */ diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_irix.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_irix.h index 0b2a9b4704d..8c5f149c080 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_irix.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_irix.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_irix.h,v 1.6 2001/09/30 16:35:29 ca Exp $ + * $Sendmail: sm_os_irix.h,v 1.7 2001/10/09 23:12:13 ca Exp $ */ /* @@ -53,8 +53,3 @@ #ifndef SM_CONF_TEST_LLONG # define SM_CONF_TEST_LLONG 0 #endif /* !SM_CONF_TEST_LLONG */ - -/* can't set real gid */ -#ifndef SM_CONF_CANT_SETRGID -# define SM_CONF_CANT_SETRGID 1 -#endif /* SM_CONF_CANT_SETRGID */ diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_linux.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_linux.h index ce7e0cc79ce..b04cdb81595 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_linux.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_linux.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_linux.h,v 1.11 2001/03/15 22:39:43 ca Exp $ + * $Sendmail: sm_os_linux.h,v 1.12 2001/10/05 01:52:41 ca Exp $ */ /* @@ -15,6 +15,9 @@ #define SM_OS_NAME "linux" +/* to get version number */ +#include <linux/version.h> + # if !defined(KERNEL_VERSION) /* not defined in 2.0.x kernel series */ # define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c)) # endif /* ! KERNEL_VERSION */ diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_mpeix.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_mpeix.h new file mode 100644 index 00000000000..7bbc351046a --- /dev/null +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_mpeix.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2001 Sendmail, Inc. and its suppliers. + * All rights reserved. + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the sendmail distribution. + * + * $Sendmail: sm_os_mpeix.h,v 1.2 2001/12/14 00:23:02 ca Exp $ + */ + +/* +** sm_os_mpeix.h -- platform definitions for HP MPE/iX +*/ + +#define SM_OS_NAME "mpeix" + +#ifndef SM_CONF_SHM +# define SM_CONF_SHM 1 +#endif /* SM_CONF_SHM */ + +#ifndef SM_CONF_SEM +# define SM_CONF_SEM 2 +#endif /* SM_CONF_SEM */ + +#ifndef SM_CONF_MSG +# define SM_CONF_MSG 1 +#endif /* SM_CONF_MSG */ + +#define SM_CONF_SETITIMER 0 + +#ifndef SM_CONF_CANT_SETRGID +# define SM_CONF_CANT_SETRGID 1 +#endif /* SM_CONF_CANT_SETRGID */ diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_openunix.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_openunix.h index 524d8aaec00..8c306320836 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_openunix.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_openunix.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_openunix.h,v 1.2 2001/09/11 23:04:15 ca Exp $ + * $Sendmail: sm_os_openunix.h,v 1.5 2001/11/11 16:32:00 ca Exp $ */ #define SM_OS_NAME "openunix" @@ -18,7 +18,7 @@ #define SM_CONF_LONGLONG 1 /* don't use flock() in mail.local.c */ -#define LDA_USE_LOCKF 1 +#define LDA_USE_LOCKF 1 #ifndef SM_CONF_SHM # define SM_CONF_SHM 1 diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_osf1.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_osf1.h index 195ec7895cd..d1dbfb68911 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_osf1.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_osf1.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_osf1.h,v 1.2 2001/10/01 14:10:45 ca Exp $ + * $Sendmail: sm_os_osf1.h,v 1.3 2001/10/09 23:12:13 ca Exp $ */ /* @@ -16,8 +16,3 @@ #define SM_OS_NAME "osf1" #define SM_CONF_SETITIMER 0 - -/* can't set real gid */ -#ifndef SM_CONF_CANT_SETRGID -# define SM_CONF_CANT_SETRGID 1 -#endif /* SM_CONF_CANT_SETRGID */ diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_ultrix.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_ultrix.h index 19bce8082f3..d5cd789148a 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_ultrix.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_ultrix.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_ultrix.h,v 1.2 2001/10/01 14:10:45 ca Exp $ + * $Sendmail: sm_os_ultrix.h,v 1.3 2001/10/09 23:12:13 ca Exp $ */ /* @@ -16,8 +16,3 @@ #define SM_OS_NAME "ultrix" #define SM_CONF_SSIZE_T 0 - -/* can't set real gid */ -#ifndef SM_CONF_CANT_SETRGID -# define SM_CONF_CANT_SETRGID 1 -#endif /* SM_CONF_CANT_SETRGID */ diff --git a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_unixware.h b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_unixware.h index 2fc571fd4f4..221bad543c4 100644 --- a/gnu/usr.sbin/sendmail/include/sm/os/sm_os_unixware.h +++ b/gnu/usr.sbin/sendmail/include/sm/os/sm_os_unixware.h @@ -6,7 +6,7 @@ * forth in the LICENSE file which can be found at the top level of * the sendmail distribution. * - * $Sendmail: sm_os_unixware.h,v 1.5 2001/09/24 20:34:36 ca Exp $ + * $Sendmail: sm_os_unixware.h,v 1.7 2001/11/11 16:32:00 ca Exp $ */ #define SM_OS_NAME "unixware" @@ -26,8 +26,7 @@ /* size_t seems to be signed */ #define SM_CONF_BROKEN_SIZE_T 1 -/* can't set real gid */ -#ifndef SM_CONF_CANT_SETRGID -# define SM_CONF_CANT_SETRGID 1 -#endif /* SM_CONF_CANT_SETRGID */ - +/* don't use flock() in mail.local.c */ +#ifndef LDA_USE_LOCKF +# define LDA_USE_LOCKF 1 +#endif /* LDA_USE_LOCKF */ diff --git a/gnu/usr.sbin/sendmail/libmilter/Makefile b/gnu/usr.sbin/sendmail/libmilter/Makefile index 3e5a650668c..759b2b45e89 100644 --- a/gnu/usr.sbin/sendmail/libmilter/Makefile +++ b/gnu/usr.sbin/sendmail/libmilter/Makefile @@ -1,9 +1,10 @@ -# $OpenBSD: Makefile,v 1.3 2001/09/11 19:02:49 millert Exp $ +# $OpenBSD: Makefile,v 1.4 2002/01/14 03:21:40 millert Exp $ LIB= milter SRCS= main.c engine.c listener.c handler.c comm.c smfi.c signal.c \ - sm_gethost.c -CPPFLAGS+= -pthread + sm_gethost.c errstring.c strl.c +CPPFLAGS+= -pthread -Dsm_snprintf=snprintf +.PATH: ${.CURDIR}/../libsm # This is not a library that gets installed so only build the .a version # In the future we may wish to install it to ease the use of external filters. diff --git a/gnu/usr.sbin/sendmail/libmilter/README b/gnu/usr.sbin/sendmail/libmilter/README index fed06305d78..39049a4c0fe 100644 --- a/gnu/usr.sbin/sendmail/libmilter/README +++ b/gnu/usr.sbin/sendmail/libmilter/README @@ -15,6 +15,22 @@ your devtools/Site/site.config.m4 file: APPENDDEF(`conf_sendmail_ENVDEF', `-DMILTER') ++----------------+ +| SECURITY HINTS | ++----------------+ + +Note: we strongly recommend not to run any milter as root. Libmilter +does not need root access to communicate with sendmail. It is a +good security practice to run a program only with root privileges +if really necessary. A milter should probably check first whether +it runs as root and refuse to start in that case. There is a +compile time option _FFR_MILTER_ROOT_UNSAFE which keeps libmilter +from unlinking a socket when running as root. It is recommended +to turn on this option: + + APPENDDEF(`conf_libmilter_ENVDEF', `-D_FFR_MILTER_ROOT_UNSAFE ') + + +-------------------+ | BUILDING A FILTER | +-------------------+ @@ -71,7 +87,7 @@ IPv4 socket on port 3333 of localhost. The current flags (F=) are: T Temporary fail connection if filter unavailable If neither F=R nor F=T is specified, the message is passed through sendmail -as if the filter were not present. +in case of filter errors as if the failing filters were not present. Finally, you can override the default timeouts used by sendmail when talking to the filters using the T= equate. There are four fields inside @@ -441,4 +457,4 @@ main(argc, argv) /* eof */ -$Revision: 1.8 $, Last updated $Date: 2001/09/11 19:02:49 $ +$Revision: 1.9 $, Last updated $Date: 2002/01/14 03:21:40 $ diff --git a/gnu/usr.sbin/sendmail/libmilter/comm.c b/gnu/usr.sbin/sendmail/libmilter/comm.c index 7f7c3e91e97..48818b13ca6 100644 --- a/gnu/usr.sbin/sendmail/libmilter/comm.c +++ b/gnu/usr.sbin/sendmail/libmilter/comm.c @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: comm.c,v 8.46 2001/09/11 04:04:44 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: comm.c,v 8.48 2001/11/07 17:43:04 ca Exp $") #include "libmilter.h" #include <sm/errstring.h> @@ -72,7 +72,9 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) *cmd = SMFIC_SELECT; return NULL; } - if ((len = MI_SOCK_READ(sd, data + i, sizeof data - i)) < 0) + + len = MI_SOCK_READ(sd, data + i, sizeof data - i); + if (MI_SOCK_READ_FAIL(len)) { smi_log(SMI_LOG_ERR, "%s, mi_rd_cmd: read returned %d: %s", @@ -136,7 +138,8 @@ mi_rd_cmd(sd, timeout, cmd, rlen, name) free(buf); return NULL; } - if ((len = MI_SOCK_READ(sd, buf + i, expl - i)) < 0) + len = MI_SOCK_READ(sd, buf + i, expl - i); + if (MI_SOCK_READ_FAIL(len)) { smi_log(SMI_LOG_ERR, "%s: mi_rd_cmd: read returned %d: %s", diff --git a/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_body.html b/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_body.html index abb8c81303b..b19e0d4913d 100644 --- a/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_body.html +++ b/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_body.html @@ -51,6 +51,12 @@ Handle a piece of a message's body. <th valign="top" align=left>NOTES</th> <td> <ul> +<li>bodyp points to a sequence of bytes. +It is <em>not</em> a C string (a sequence of characters that is terminated by '\0'). +Therefore, do not use the usual C string functions like strlen() on this byte block. +Moreover, the byte sequence may contain '\0' characters inside the block. +Hence even if a trailing '\0' is added, C string functions may still fail +to work as expected. <li>Since message bodies can be very large, defining xxfi_body can significantly impact filter performance. <li>End-of-lines are represented as received from SMTP (normally CR/LF). @@ -64,7 +70,7 @@ significantly impact filter performance. <hr size="1"> <font size="-1"> -Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. All rights reserved. <br> By using this file, you agree to the terms and conditions set diff --git a/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_connect.html b/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_connect.html index a174bf64f65..17102856ba2 100644 --- a/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_connect.html +++ b/gnu/usr.sbin/sendmail/libmilter/docs/xxfi_connect.html @@ -49,7 +49,10 @@ is passed to smfi_register(). address enclosed in square brackets (e.g. `[a.b.c.d]'). </td></tr> <tr><td>hostaddr</td> - <td>the host address, as determined by a getpeername() call on the SMTP socket. NULL if the type is not supported in the current version.</td></tr> + <td>the host address, as determined by a getpeername() call on the SMTP socket. + NULL if the type is not supported in the current version or if + the SMTP connection is made via stdin. + </td></tr> </table> </td></tr> <!----------- Return values ----------> @@ -77,7 +80,7 @@ routine, this filter's xxfi_connect() will not be called.</td> <hr size="1"> <font size="-1"> -Copyright (c) 2000 Sendmail, Inc. and its suppliers. +Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. All rights reserved. <br> By using this file, you agree to the terms and conditions set diff --git a/gnu/usr.sbin/sendmail/libmilter/engine.c b/gnu/usr.sbin/sendmail/libmilter/engine.c index 7393b2a25d7..e12f84788f1 100644 --- a/gnu/usr.sbin/sendmail/libmilter/engine.c +++ b/gnu/usr.sbin/sendmail/libmilter/engine.c @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: engine.c,v 8.97 2001/09/11 04:04:44 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: engine.c,v 8.102 2001/12/13 17:10:00 ca Exp $") #include "libmilter.h" @@ -172,6 +172,7 @@ static cmdfct cmds[] = #define _SMFIS_OPTIONS 22 #define _SMFIS_NOREPLY 23 #define _SMFIS_FAIL (-1) +#define _SMFIS_NONE (-2) /* ** MI_ENGINE -- receive commands and process them @@ -208,6 +209,7 @@ mi_engine(ctx) fi_abort = ctx->ctx_smfi->xxfi_abort; mi_clr_macros(ctx, 0); fix_stm(ctx); + r = _SMFIS_NONE; do { /* call abort only if in a mail transaction */ @@ -222,6 +224,18 @@ mi_engine(ctx) ret = MI_FAILURE; break; } + + /* + ** Notice: buf is allocated by mi_rd_cmd() and it will + ** usually be free()d after it has been used in f(). + ** However, if the function returns _SMFIS_KEEP then buf + ** contains macros and will not be free()d. + ** Hence r must be set to _SMFIS_NONE if a new buf is + ** allocated to avoid problem with housekeeping, esp. + ** if the code "break"s out of the loop. + */ + + r = _SMFIS_NONE; if ((buf = mi_rd_cmd(sd, &timeout, &cmd, &len, ctx->ctx_smfi->xxfi_name)) == NULL && cmd < SMFIC_VALIDCMD) @@ -293,7 +307,11 @@ mi_engine(ctx) curstate = ST_HELO; if (!trans_ok(curstate, newstate)) + { + free(buf); + buf = NULL; continue; + } } arg.a_len = len; arg.a_buf = buf; @@ -354,7 +372,7 @@ mi_engine(ctx) /* close must always be called */ if ((fi_close = ctx->ctx_smfi->xxfi_close) != NULL) (void) (*fi_close)(ctx); - if (buf != NULL) + if (r != _SMFIS_KEEP && buf != NULL) free(buf); mi_clr_macros(ctx, 0); return ret; @@ -1116,7 +1134,11 @@ mi_sendok(ctx, flag) { if (ctx == NULL || ctx->ctx_smfi == NULL) return false; + + /* did the milter request this operation? */ if (flag != 0 && !bitset(flag, ctx->ctx_smfi->xxfi_flags)) return false; + + /* are we in the correct state? It must be "End of Message". */ return ctx->ctx_state == ST_ENDM; } diff --git a/gnu/usr.sbin/sendmail/libmilter/handler.c b/gnu/usr.sbin/sendmail/libmilter/handler.c index 9fcf3c587b1..ab5c4f110ad 100644 --- a/gnu/usr.sbin/sendmail/libmilter/handler.c +++ b/gnu/usr.sbin/sendmail/libmilter/handler.c @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: handler.c,v 8.26 2001/09/11 04:04:45 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: handler.c,v 8.29 2001/11/15 00:17:15 msk Exp $") #include "libmilter.h" @@ -43,7 +43,7 @@ mi_handle_session(ctx) ret = mi_engine(ctx); if (ValidSocket(ctx->ctx_sd)) { - (void) close(ctx->ctx_sd); + (void) closesocket(ctx->ctx_sd); ctx->ctx_sd = INVALID_SOCKET; } if (ctx->ctx_reply != NULL) diff --git a/gnu/usr.sbin/sendmail/libmilter/libmilter.h b/gnu/usr.sbin/sendmail/libmilter/libmilter.h index f68d3d32021..207ae1f876d 100644 --- a/gnu/usr.sbin/sendmail/libmilter/libmilter.h +++ b/gnu/usr.sbin/sendmail/libmilter/libmilter.h @@ -19,7 +19,7 @@ #ifdef _DEFINE # define EXTERN # define INIT(x) = x -SM_IDSTR(MilterlId, "@(#)$Sendmail: libmilter.h,v 8.28 2001/09/11 04:04:45 gshapiro Exp $") +SM_IDSTR(MilterlId, "@(#)$Sendmail: libmilter.h,v 8.32 2001/11/29 02:21:02 ca Exp $") #else /* _DEFINE */ # define EXTERN extern # define INIT(x) @@ -33,9 +33,11 @@ SM_IDSTR(MilterlId, "@(#)$Sendmail: libmilter.h,v 8.28 2001/09/11 04:04:45 gshap #include "libmilter/milter.h" # define ValidSocket(sd) ((sd) >= 0) -# define INVALID_SOCKET -1 -# define MI_SOCK_READ(s, b, l) (read(s, b, l)) -# define MI_SOCK_WRITE(s, b, l) (write(s, b, l)) +# define INVALID_SOCKET (-1) +# define closesocket close +# define MI_SOCK_READ(s, b, l) read(s, b, l) +# define MI_SOCK_READ_FAIL(x) ((x) < 0) +# define MI_SOCK_WRITE(s, b, l) write(s, b, l) # define thread_create(ptid,wr,arg) pthread_create(ptid, NULL, wr, arg) # define sthread_get_id() pthread_self() @@ -114,4 +116,5 @@ extern char *mi_rd_cmd __P((socket_t, struct timeval *, char *, size_t *, char * extern int mi_wr_cmd __P((socket_t, struct timeval *, int, char *, size_t)); extern bool mi_sendok __P((SMFICTX_PTR, int)); + #endif /* !_LIBMILTER_H */ diff --git a/gnu/usr.sbin/sendmail/libmilter/listener.c b/gnu/usr.sbin/sendmail/libmilter/listener.c index f573c8e65d1..c81ebbaafa7 100644 --- a/gnu/usr.sbin/sendmail/libmilter/listener.c +++ b/gnu/usr.sbin/sendmail/libmilter/listener.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1999-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: listener.c,v 8.75 2001/09/11 04:04:45 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: listener.c,v 8.81 2002/01/08 23:14:23 ca Exp $") /* ** listener.c -- threaded network listener @@ -56,7 +56,7 @@ mi_milteropen(conn, backlog, socksize, family, name) { socket_t sock; int sockopt = 1; - size_t len = -1; + size_t len = 0; char *p; char *colon; char *at; @@ -386,7 +386,7 @@ mi_milteropen(conn, backlog, socksize, family, name) smi_log(SMI_LOG_ERR, "%s: Unable to setsockopt: %s", name, sm_errstring(errno)); - (void) close(sock); + (void) closesocket(sock); return INVALID_SOCKET; } @@ -395,7 +395,7 @@ mi_milteropen(conn, backlog, socksize, family, name) smi_log(SMI_LOG_ERR, "%s: Unable to bind to port %s: %s", name, conn, sm_errstring(errno)); - (void) close(sock); + (void) closesocket(sock); return INVALID_SOCKET; } @@ -404,7 +404,7 @@ mi_milteropen(conn, backlog, socksize, family, name) smi_log(SMI_LOG_ERR, "%s: listen call failed: %s", name, sm_errstring(errno)); - (void) close(sock); + (void) closesocket(sock); return INVALID_SOCKET; } @@ -415,6 +415,7 @@ mi_milteropen(conn, backlog, socksize, family, name) ** Set global variable sockpath so the UNIX socket can be ** unlink()ed at exit. */ + sockpath = (char *) malloc(len); if (sockpath != NULL) (void) sm_strlcpy(sockpath, colon, len); @@ -423,7 +424,7 @@ mi_milteropen(conn, backlog, socksize, family, name) smi_log(SMI_LOG_ERR, "%s: can't malloc(%d) for sockpath: %s", name, len, sm_errstring(errno)); - (void) close(sock); + (void) closesocket(sock); return INVALID_SOCKET; } } @@ -470,21 +471,23 @@ mi_closener() if (ValidSocket(listenfd)) { #if NETUNIX - bool removable = false; + bool removable; struct stat sockinfo; struct stat fileinfo; - if (sockpath != NULL && - fstat(listenfd, &sockinfo) == 0 && - (S_ISFIFO(sockinfo.st_mode) + removable = sockpath != NULL && +#if _FFR_MILTER_ROOT_UNSAFE + geteuid() != 0 && +#endif /* _FFR_MILTER_ROOT_UNSAFE */ + fstat(listenfd, &sockinfo) == 0 && + (S_ISFIFO(sockinfo.st_mode) # ifdef S_ISSOCK - || !S_ISSOCK(sockinfo.st_mode) + || S_ISSOCK(sockinfo.st_mode) # endif /* S_ISSOCK */ - )) - removable = true; + ); #endif /* NETUNIX */ - (void) close(listenfd); + (void) closesocket(listenfd); listenfd = INVALID_SOCKET; #if NETUNIX @@ -493,8 +496,13 @@ mi_closener() { if (removable && stat(sockpath, &fileinfo) == 0 && - fileinfo.st_dev == sockinfo.st_dev && - fileinfo.st_ino == sockinfo.st_ino && + ((fileinfo.st_dev == sockinfo.st_dev && + fileinfo.st_ino == sockinfo.st_ino) +# ifdef S_ISSOCK + || S_ISSOCK(fileinfo.st_mode) +# endif /* S_ISSOCK */ + ) + && (S_ISFIFO(fileinfo.st_mode) # ifdef S_ISSOCK || S_ISSOCK(fileinfo.st_mode) @@ -692,7 +700,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) # endif /* BSD4_4_SOCKADDR */ cliaddr.sa.sa_family != family)) { - (void) close(connfd); + (void) closesocket(connfd); connfd = INVALID_SOCKET; save_errno = EINVAL; } @@ -725,7 +733,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) } if ((ctx = (SMFICTX_PTR) malloc(sizeof *ctx)) == NULL) { - (void) close(connfd); + (void) closesocket(connfd); mcnt++; smi_log(SMI_LOG_ERR, "%s: malloc(ctx) failed (%s), %s", smfi->xxfi_name, sm_errstring(save_errno), @@ -775,7 +783,7 @@ mi_listener(conn, dbg, smfi, timeout, backlog) smfi->xxfi_name, r, tcnt >= MAX_FAILS_T ? "abort" : "try again"); MI_SLEEP(tcnt); - (void) close(connfd); + (void) closesocket(connfd); free(ctx); if (tcnt >= MAX_FAILS_T) { diff --git a/gnu/usr.sbin/sendmail/libmilter/main.c b/gnu/usr.sbin/sendmail/libmilter/main.c index 2a7f665cb81..042d1a35bad 100644 --- a/gnu/usr.sbin/sendmail/libmilter/main.c +++ b/gnu/usr.sbin/sendmail/libmilter/main.c @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: main.c,v 8.52 2001/09/11 04:04:45 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: main.c,v 8.53 2001/11/29 02:21:02 ca Exp $") #define _DEFINE 1 #include "libmilter.h" @@ -177,6 +177,7 @@ smfi_setbacklog(obacklog) return MI_SUCCESS; } + /* ** SMFI_MAIN -- setup milter connnection and start listener. ** @@ -190,6 +191,8 @@ smfi_setbacklog(obacklog) int smfi_main() { + int r; + (void) signal(SIGPIPE, SIG_IGN); if (conn == NULL) { @@ -206,10 +209,11 @@ smfi_main() smfi->xxfi_name); return MI_FAILURE; } + r = MI_SUCCESS; /* Startup the listener */ if (mi_listener(conn, dbg, smfi, timeout, backlog) != MI_SUCCESS) - return MI_FAILURE; + r = MI_FAILURE; - return MI_SUCCESS; + return r; } diff --git a/gnu/usr.sbin/sendmail/libmilter/signal.c b/gnu/usr.sbin/sendmail/libmilter/signal.c index 113f7c9a96a..5a2c49bd5ec 100644 --- a/gnu/usr.sbin/sendmail/libmilter/signal.c +++ b/gnu/usr.sbin/sendmail/libmilter/signal.c @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: signal.c,v 8.27 2001/09/11 04:04:45 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: signal.c,v 8.35 2002/01/10 01:34:55 ca Exp $") #include "libmilter.h" @@ -101,15 +101,15 @@ mi_signal_thread(name) while (true) { sig = 0; -#ifdef SOLARIS +#if defined(SOLARIS) || defined(__svr5__) if ((sig = sigwait(&set)) < 0) -#else /* SOLARIS */ +#else /* defined(SOLARIS) || defined(__svr5__) */ if (sigwait(&set, &sig) != 0) -#endif /* SOLARIS */ +#endif /* defined(SOLARIS) || defined(__svr5__) */ { smi_log(SMI_LOG_ERR, - "%s: sigwait returned error: %s", - (char *)name, strerror(errno)); + "%s: sigwait returned error: %d", + (char *)name, errno); if (++errs > MAX_FAILS_T) { mi_stop_milters(MILTER_ABRT); @@ -151,6 +151,7 @@ mi_spawn_signal_thread(name) char *name; { sthread_t tid; + int r; sigset_t set; /* Mask HUP and KILL signals */ @@ -165,11 +166,12 @@ mi_spawn_signal_thread(name) "%s: Couldn't mask HUP and KILL signals", name); return MI_FAILURE; } - if (thread_create(&tid, mi_signal_thread, - (void *)name) != MI_SUCCESS) + r = thread_create(&tid, mi_signal_thread, (void *)name); + if (r != 0) { smi_log(SMI_LOG_ERR, - "%s: Couldn't start signal thread", name); + "%s: Couldn't start signal thread: %d", + name, r); return MI_FAILURE; } return MI_SUCCESS; diff --git a/gnu/usr.sbin/sendmail/libmilter/smfi.c b/gnu/usr.sbin/sendmail/libmilter/smfi.c index 3fd3d5ce321..4a4132f083e 100644 --- a/gnu/usr.sbin/sendmail/libmilter/smfi.c +++ b/gnu/usr.sbin/sendmail/libmilter/smfi.c @@ -9,10 +9,14 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: smfi.c,v 8.46 2001/09/11 04:04:45 gshapiro Exp $") - +SM_RCSID("@(#)$Sendmail: smfi.c,v 8.57 2001/11/20 18:47:49 ca Exp $") +#include <sm/varargs.h> #include "libmilter.h" +/* for smfi_set{ml}reply, let's be generous. 256/16 should be sufficient */ +#define MAXREPLYLEN 980 /* max. length of a reply string */ +#define MAXREPLIES 32 /* max. number of reply strings */ + /* ** SMFI_ADDHEADER -- send a new header to the MTA ** @@ -234,11 +238,11 @@ smfi_quarantine(ctx, reason) return MI_FAILURE; timeout.tv_sec = ctx->ctx_timeout; timeout.tv_usec = 0; - len = strlen(reason); + len = strlen(reason) + 1; buf = malloc(len); if (buf == NULL) return MI_FAILURE; - (void) memcpy(buf, reason, len + 1); + (void) memcpy(buf, reason, len); r = mi_wr_cmd(ctx->ctx_sd, &timeout, SMFIR_QUARANTINE, buf, len); free(buf); return r; @@ -284,6 +288,7 @@ myisenhsc(s, delim) return 0; return l + h; } + /* ** SMFI_SETREPLY -- set the reply code for the next reply to the MTA ** @@ -319,20 +324,30 @@ smfi_setreply(ctx, rcode, xcode, message) !isascii(rcode[2]) || !isdigit(rcode[2])) return MI_FAILURE; if (xcode != NULL) + { + if (!myisenhsc(xcode, '\0')) + return MI_FAILURE; len += strlen(xcode) + 1; + } if (message != NULL) - len += strlen(message) + 1; + { + size_t ml; + + /* XXX check also for unprintable chars? */ + if (strpbrk(message, "\r\n") != NULL) + return MI_FAILURE; + ml = strlen(message); + if (ml > MAXREPLYLEN) + return MI_FAILURE; + len += ml + 1; + } buf = malloc(len); if (buf == NULL) return MI_FAILURE; /* oops */ (void) sm_strlcpy(buf, rcode, len); (void) sm_strlcat(buf, " ", len); if (xcode != NULL) - { - if (!myisenhsc(xcode, '\0')) - return MI_FAILURE; (void) sm_strlcat(buf, xcode, len); - } if (message != NULL) { if (xcode != NULL) @@ -344,6 +359,119 @@ smfi_setreply(ctx, rcode, xcode, message) ctx->ctx_reply = buf; return MI_SUCCESS; } + +#if _FFR_MULTILINE +/* +** SMFI_SETMLREPLY -- set multiline reply code for the next reply to the MTA +** +** Parameters: +** ctx -- Opaque context structure +** rcode -- The three-digit (RFC 821) SMTP reply code. +** xcode -- The extended (RFC 2034) reply code. +** txt, ... -- The text part of the SMTP reply, +** MUST be terminated with NULL. +** +** Returns: +** MI_SUCCESS/MI_FAILURE +*/ + +int +#if SM_VA_STD +smfi_setmlreply(SMFICTX *ctx, const char *rcode, const char *xcode, ...) +#else /* SM_VA_STD */ +smfi_setmlreply(ctx, rcode, xcode, va_alist) + SMFICTX *ctx; + const char *rcode; + const char *xcode; + va_dcl +#endif /* SM_VA_STD */ +{ + size_t len; + size_t rlen; + int args; + char *buf, *txt; + const char *xc; + char repl[16]; + SM_VA_LOCAL_DECL + + if (rcode == NULL || ctx == NULL) + return MI_FAILURE; + + /* ### <sp> */ + len = strlen(rcode) + 1; + if (len != 4) + return MI_FAILURE; + if ((rcode[0] != '4' && rcode[0] != '5') || + !isascii(rcode[1]) || !isdigit(rcode[1]) || + !isascii(rcode[2]) || !isdigit(rcode[2])) + return MI_FAILURE; + if (xcode != NULL) + { + if (!myisenhsc(xcode, '\0')) + return MI_FAILURE; + xc = xcode; + } + else + { + if (rcode[0] == '4') + xc = "4.0.0"; + else + xc = "5.0.0"; + } + + /* add trailing space */ + len += strlen(xc) + 1; + rlen = len; + args = 0; + SM_VA_START(ap, xcode); + while ((txt = SM_VA_ARG(ap, char *)) != NULL) + { + size_t tl; + + tl = strlen(txt); + if (tl > MAXREPLYLEN) + return MI_FAILURE; + + /* this text, reply codes, \r\n */ + len += tl + 2 + rlen; + if (++args > MAXREPLIES) + return MI_FAILURE; + + /* XXX check also for unprintable chars? */ + if (strpbrk(txt, "\r\n") != NULL) + return MI_FAILURE; + } + SM_VA_END(ap); + + /* trailing '\0' */ + ++len; + buf = malloc(len); + if (buf == NULL) + return MI_FAILURE; /* oops */ + (void) sm_strlcpyn(buf, len, 3, rcode, args == 1 ? " " : "-", xc); + (void) sm_strlcpyn(repl, sizeof repl, 4, rcode, args == 1 ? " " : "-", + xc, " "); + SM_VA_START(ap, xcode); + txt = SM_VA_ARG(ap, char *); + if (txt != NULL) + { + (void) sm_strlcat2(buf, " ", txt, len); + while ((txt = SM_VA_ARG(ap, char *)) != NULL) + { + if (--args <= 1) + repl[3] = ' '; + (void) sm_strlcat2(buf, "\r\n", repl, len); + (void) sm_strlcat(buf, txt, len); + } + } + if (ctx->ctx_reply != NULL) + free(ctx->ctx_reply); + ctx->ctx_reply = buf; + SM_VA_END(ap); + return MI_SUCCESS; +} +#endif /* _FFR_MULTILINE */ + /* ** SMFI_SETPRIV -- set private data ** diff --git a/gnu/usr.sbin/sendmail/libsm/README b/gnu/usr.sbin/sendmail/libsm/README index 70ba2af9a92..4d5dae44b94 100644 --- a/gnu/usr.sbin/sendmail/libsm/README +++ b/gnu/usr.sbin/sendmail/libsm/README @@ -1,11 +1,11 @@ -# Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # # By using this file, you agree to the terms and conditions set # forth in the LICENSE file which can be found at the top level of # the sendmail distribution. # -# $Sendmail: README,v 1.13 2001/08/14 18:07:18 ca Exp $ +# $Sendmail: README,v 1.20 2002/01/09 18:05:39 ca Exp $ # Libsm is a library of generally useful C abstractions. @@ -18,6 +18,10 @@ which reside in ../include/sm. The t-*.c files are regression tests. These tests are incomplete: we do not yet test all of the APIs, and we have not yet converted all tests to use the test harness. +If a test fails read the explanation it generates. Sometimes it +is sufficient to change a compile time flag, which are also listed +below. If that does not help, check the sendmail/README files for +problems on your OS. The b-*.c files are benchmarks that compare system routines with those provided by libsm. By default sendmail uses the routines @@ -28,7 +32,6 @@ versions by running the programs with the option -d (by default the programs just issue an explanation when/how to use them). The programs are: -b-strl.c tests strlcpy() and strlcat(). b-strcmp.c tests strcasecmp(). +----------------------+ @@ -66,12 +69,6 @@ SM_CONF_SYS_CDEFS_H SM_CONF_STDDEF_H Set to 0 if the header file <stddef.h> does not exist. -SM_CONF_STRL - Set to 1 if strlcpy/strlcat are available. - Then compile and run the benchmark program b-strl. - If the benchmark shows that the libsm-provided sm_strlcpy/sm_strlcat - are faster, then set SM_CONF_STRL back to 0 (the default). - SM_CONF_SETITIMER Set to 0 if the setitimer function is not available. @@ -111,3 +108,19 @@ SM_CONF_BROKEN_STRTOD SM_CONF_GETOPT Set to 1 if your operating system does not include getopt(3). + +SM_IO_MAX_BUF_FILE + Set this to a useful buffer size for regular files if stat(2) + does not return a value for st_blksize that is the + "optimal blocksize for I/O". + +SM_IO_MAX_BUF + Set this to a useful maximum buffer size for other than + regular files if stat(2) does not return a value for + st_blksize that is the "optimal blocksize for I/O". + +SM_IO_MIN_BUF + Set this to a useful minimum buffer size for other than + regular files if stat(2) does not return a value for + st_blksize that is the "optimal blocksize for I/O". + diff --git a/gnu/usr.sbin/sendmail/libsm/clock.c b/gnu/usr.sbin/sendmail/libsm/clock.c index 540512789c4..b1e4b84319d 100644 --- a/gnu/usr.sbin/sendmail/libsm/clock.c +++ b/gnu/usr.sbin/sendmail/libsm/clock.c @@ -12,7 +12,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: clock.c,v 1.33 2001/09/11 04:04:47 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: clock.c,v 1.34 2001/11/05 18:33:20 ca Exp $") #include <unistd.h> #include <time.h> #include <errno.h> @@ -117,7 +117,7 @@ sm_sigsafe_seteventm(intvl, func, arg) evp = &ev->ev_link) { #if SM_CONF_SETITIMER - if (timercmp(&(ev->ev_time), &nowi, >)) + if (timercmp(&(ev->ev_time), &nowi, >=)) #else /* SM_CONF_SETITIMER */ if (ev->ev_time >= nowi) #endif /* SM_CONF_SETITIMER */ @@ -160,6 +160,8 @@ sm_sigsafe_seteventm(intvl, func, arg) timersub(&SmEventQueue->ev_time, &now, &itime.it_value); itime.it_interval.tv_sec = 0; itime.it_interval.tv_usec = 0; + if (itime.it_value.tv_sec == 0 && itime.it_value.tv_usec == 0) + itime.it_value.tv_usec = 1000; (void) setitimer(ITIMER_REAL, &itime, NULL); # else /* SM_CONF_SETITIMER */ intvl = SmEventQueue->ev_time - now; @@ -377,7 +379,7 @@ sm_tick(sig) while ((ev = SmEventQueue) != NULL && (ev->ev_pid != mypid || #if SM_CONF_SETITIMER - timercmp(&ev->ev_time, &now, <) + timercmp(&ev->ev_time, &now, <=) #else /* SM_CONF_SETITIMER */ ev->ev_time <= now #endif /* SM_CONF_SETITIMER */ diff --git a/gnu/usr.sbin/sendmail/libsm/config.c b/gnu/usr.sbin/sendmail/libsm/config.c index 336d1a3b9d7..ea2fb0809cd 100644 --- a/gnu/usr.sbin/sendmail/libsm/config.c +++ b/gnu/usr.sbin/sendmail/libsm/config.c @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: config.c,v 1.23 2001/09/24 20:44:07 ca Exp $") +SM_RCSID("@(#)$Sendmail: config.c,v 1.26 2001/12/14 00:26:18 ca Exp $") #include <stdlib.h> #include <sm/heap.h> @@ -173,9 +173,6 @@ char *SmCompileOptions[] = #if SM_CONF_BROKEN_STRTOD "SM_CONF_BROKEN_STRTOD", #endif /* SM_CONF_BROKEN_STRTOD */ -#if SM_CONF_CANT_SETRGID - "SM_CONF_CANT_SETRGID", -#endif /* SM_CONF_CANT_SETRGID */ #if SM_CONF_GETOPT "SM_CONF_GETOPT", #endif /* SM_CONF_GETOPT */ diff --git a/gnu/usr.sbin/sendmail/libsm/errstring.c b/gnu/usr.sbin/sendmail/libsm/errstring.c index 0736ae6b6d3..484614fad25 100644 --- a/gnu/usr.sbin/sendmail/libsm/errstring.c +++ b/gnu/usr.sbin/sendmail/libsm/errstring.c @@ -11,7 +11,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: errstring.c,v 1.11 2001/09/25 21:25:00 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: errstring.c,v 1.12 2001/10/03 16:09:32 ca Exp $") #include <errno.h> #include <stdio.h> /* sys_errlist, on some platforms */ @@ -30,6 +30,11 @@ SM_RCSID("@(#)$Sendmail: errstring.c,v 1.11 2001/09/25 21:25:00 gshapiro Exp $") #endif /* LDAPMAP */ /* +** Notice: this file is used by libmilter. Please try to avoid +** using libsm specific functions. +*/ + +/* ** SM_ERRSTRING -- return string description of error code ** ** Parameters: diff --git a/gnu/usr.sbin/sendmail/libsm/exc.c b/gnu/usr.sbin/sendmail/libsm/exc.c index 8924635c527..c347b1b3d55 100644 --- a/gnu/usr.sbin/sendmail/libsm/exc.c +++ b/gnu/usr.sbin/sendmail/libsm/exc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -9,7 +9,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: exc.c,v 1.45 2001/09/11 04:04:48 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: exc.c,v 1.47 2002/01/09 18:51:43 ca Exp $") /* ** exception handling @@ -19,6 +19,7 @@ SM_RCSID("@(#)$Sendmail: exc.c,v 1.45 2001/09/11 04:04:48 gshapiro Exp $") #include <ctype.h> #include <string.h> +#include <sm/errstring.h> #include <sm/exc.h> #include <sm/heap.h> #include <sm/string.h> @@ -161,10 +162,10 @@ sm_etype_os_print(exc, stream) if (sysargs) sm_io_fprintf(stream, SM_TIME_DEFAULT, "%s: %s failed: %s", - sysargs, syscall, strerror(err)); + sysargs, syscall, sm_errstring(err)); else sm_io_fprintf(stream, SM_TIME_DEFAULT, "%s failed: %s", syscall, - strerror(err)); + sm_errstring(err)); } /* diff --git a/gnu/usr.sbin/sendmail/libsm/findfp.c b/gnu/usr.sbin/sendmail/libsm/findfp.c index 4f691795f38..587a86259fd 100644 --- a/gnu/usr.sbin/sendmail/libsm/findfp.c +++ b/gnu/usr.sbin/sendmail/libsm/findfp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -13,7 +13,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: findfp.c,v 1.60 2001/09/11 04:04:48 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: findfp.c,v 1.62 2002/01/11 16:33:03 ca Exp $") #include <stdlib.h> #include <unistd.h> #include <sys/param.h> @@ -110,6 +110,7 @@ struct sm_glue smglue = { &smuglue, 3, SmIoF }; */ static struct sm_glue *sm_moreglue_x __P((int)); +static SM_FILE_T empty; static struct sm_glue * sm_moreglue_x(n) @@ -117,7 +118,6 @@ sm_moreglue_x(n) { register struct sm_glue *g; register SM_FILE_T *p; - static SM_FILE_T empty; g = (struct sm_glue *) sm_pmalloc_x(sizeof(*g) + ALIGNBYTES + n * sizeof(SM_FILE_T)); @@ -126,11 +126,7 @@ sm_moreglue_x(n) g->gl_niobs = n; g->gl_iobs = p; while (--n >= 0) - { *p++ = empty; - p->f_type = NULL; - p->sm_magic = NULL; - } return g; } @@ -256,6 +252,10 @@ sm_init() if (Sm_IO_DidInit) /* paranoia */ return; + /* more paranoia: initialize pointers in a static variable */ + empty.f_type = NULL; + empty.sm_magic = NULL; + /* make sure we clean up on exit */ atexit(sm_cleanup); /* conservative */ Sm_IO_DidInit = true; diff --git a/gnu/usr.sbin/sendmail/libsm/fopen.c b/gnu/usr.sbin/sendmail/libsm/fopen.c index 81143d80e50..0c184b266d2 100644 --- a/gnu/usr.sbin/sendmail/libsm/fopen.c +++ b/gnu/usr.sbin/sendmail/libsm/fopen.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -13,7 +13,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: fopen.c,v 1.58 2001/09/11 04:04:48 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: fopen.c,v 1.60 2002/01/07 21:41:35 ca Exp $") #include <errno.h> #include <setjmp.h> #include <sys/time.h> @@ -117,8 +117,9 @@ sm_io_open(type, timeout, info, flags, rpool) if (ioflags == 0) { + /* must give some indication/intent */ errno = EINVAL; - return NULL; /* must give some indication/intent */ + return NULL; } if (timeout == SM_TIME_DEFAULT) diff --git a/gnu/usr.sbin/sendmail/libsm/ldap.c b/gnu/usr.sbin/sendmail/libsm/ldap.c index 2f7af53c3cd..f1eaa76d2ae 100644 --- a/gnu/usr.sbin/sendmail/libsm/ldap.c +++ b/gnu/usr.sbin/sendmail/libsm/ldap.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: ldap.c,v 1.10 2001/09/11 04:04:48 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: ldap.c,v 1.18 2002/01/11 22:06:51 gshapiro Exp $") #if LDAPMAP # include <sys/types.h> @@ -24,6 +24,7 @@ SM_RCSID("@(#)$Sendmail: ldap.c,v 1.10 2001/09/11 04:04:48 gshapiro Exp $") # include <sm/errstring.h> # include <sm/ldap.h> # include <sm/string.h> +# include <sm/sysexits.h> SM_DEBUG_T SmLDAPTrace = SM_DEBUG_INITIALIZER("sm_trace_ldap", "@(#)$Debug: sm_trace_ldap - trace LDAP operations $"); @@ -70,6 +71,10 @@ sm_ldap_clear(lmap) lmap->ldap_ld = NULL; lmap->ldap_filter = NULL; lmap->ldap_attr[0] = NULL; +#if _FFR_LDAP_RECURSION + lmap->ldap_attr_type[0] = LDAPMAP_ATTR_NORMAL; + lmap->ldap_attr_final[0] = NULL; +#endif /* _FFR_LDAP_RECURSION */ lmap->ldap_res = NULL; lmap->ldap_next = NULL; lmap->ldap_pid = 0; @@ -300,6 +305,566 @@ sm_ldap_search(lmap, key) return msgid; } +# if _FFR_LDAP_RECURSION +/* +** SM_LDAP_RESULTS -- return results from an LDAP lookup in result +** +** Parameters: +** lmap -- pointer to SM_LDAP_STRUCT in use +** msgid -- msgid returned by sm_ldap_search() +** flags -- flags for the lookup +** delim -- delimiter for result concatenation +** rpool -- memory pool for storage +** result -- return string +** recurse -- recursion list +** +** Returns: +** status (sysexit) +*/ + +# define LDAPMAP_ERROR_CLEANUP() \ +{ \ + if (lmap->ldap_res != NULL) \ + { \ + ldap_msgfree(lmap->ldap_res); \ + lmap->ldap_res = NULL; \ + } \ + (void) ldap_abandon(lmap->ldap_ld, msgid); \ +} + +static int +ldapmap_add_recurse(top, item, type, rpool) + SM_LDAP_RECURSE_LIST **top; + char *item; + int type; + SM_RPOOL_T *rpool; +{ + SM_LDAP_RECURSE_LIST *p; + SM_LDAP_RECURSE_LIST *last; + + last = NULL; + for (p = *top; p != NULL; p = p->lr_next) + { + if (strcasecmp(item, p->lr_search) == 0 && + type == p->lr_type) + { + /* already on list */ + return 1; + } + last = p; + } + + /* not on list, add it */ + p = sm_rpool_malloc_x(rpool, sizeof *p); + p->lr_search = sm_rpool_strdup_x(rpool, item); + p->lr_type = type; + p->lr_next = NULL; + if (last == NULL) + *top = p; + else + last->lr_next = p; + return 0; +} + +int +sm_ldap_results(lmap, msgid, flags, delim, rpool, result, recurse) + SM_LDAP_STRUCT *lmap; + int msgid; + int flags; + char delim; + SM_RPOOL_T *rpool; + char **result; + SM_LDAP_RECURSE_LIST *recurse; +{ + bool toplevel; + int i; + int entries = 0; + int statp; + int vsize; + int ret; + int save_errno; + char *p; + + /* Are we the top top level of the search? */ + toplevel = (recurse == NULL); + + /* Get results */ + statp = EX_NOTFOUND; + while ((ret = ldap_result(lmap->ldap_ld, msgid, 0, + (lmap->ldap_timeout.tv_sec == 0 ? NULL : + &(lmap->ldap_timeout)), + &(lmap->ldap_res))) == LDAP_RES_SEARCH_ENTRY) + { + LDAPMessage *entry; + + if (bitset(SM_LDAP_SINGLEMATCH, flags)) + { + entries += ldap_count_entries(lmap->ldap_ld, + lmap->ldap_res); + if (entries > 1) + { + LDAPMAP_ERROR_CLEANUP(); + errno = ENOENT; + return EX_NOTFOUND; + } + } + + /* If we don't want multiple values and we have one, break */ + if (delim == '\0' && *result != NULL) + break; + + /* Cycle through all entries */ + for (entry = ldap_first_entry(lmap->ldap_ld, lmap->ldap_res); + entry != NULL; + entry = ldap_next_entry(lmap->ldap_ld, lmap->ldap_res)) + { + BerElement *ber; + char *attr; + char **vals = NULL; + char *dn; + + /* + ** If matching only and found an entry, + ** no need to spin through attributes + */ + + if (statp == EX_OK && + bitset(SM_LDAP_MATCHONLY, flags)) + continue; + + /* record completed DN's to prevent loops */ + dn = ldap_get_dn(lmap->ldap_ld, entry); + if (dn == NULL) + { + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + save_errno += E_LDAPBASE; + LDAPMAP_ERROR_CLEANUP(); + errno = save_errno; + return EX_OSERR; + } + + switch (ldapmap_add_recurse(&recurse, dn, + LDAPMAP_ATTR_NORMAL, + rpool)) + { + case -1: + /* error adding */ + ldap_memfree(dn); + LDAPMAP_ERROR_CLEANUP(); + errno = ENOMEM; + return EX_OSERR; + + case 1: + /* already on list, skip it */ + ldap_memfree(dn); + continue; + } + ldap_memfree(dn); + +# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT) + /* + ** Reset value to prevent lingering + ** LDAP_DECODING_ERROR due to + ** OpenLDAP 1.X's hack (see below) + */ + + lmap->ldap_ld->ld_errno = LDAP_SUCCESS; +# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */ + + for (attr = ldap_first_attribute(lmap->ldap_ld, entry, + &ber); + attr != NULL; + attr = ldap_next_attribute(lmap->ldap_ld, entry, + ber)) + { + char *tmp, *vp_tmp; + int type; + + for (i = 0; lmap->ldap_attr[i] != NULL; i++) + { + if (sm_strcasecmp(lmap->ldap_attr[i], + attr) == 0) + { + type = lmap->ldap_attr_type[i]; + break; + } + } + if (lmap->ldap_attr[i] == NULL) + { + /* attribute not requested */ +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + LDAPMAP_ERROR_CLEANUP(); + errno = EFAULT; + return EX_SOFTWARE; + } + + if (lmap->ldap_attrsonly == LDAPMAP_FALSE) + { + vals = ldap_get_values(lmap->ldap_ld, + entry, + attr); + if (vals == NULL) + { + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + if (save_errno == LDAP_SUCCESS) + { +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + continue; + } + + /* Must be an error */ + save_errno += E_LDAPBASE; +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + LDAPMAP_ERROR_CLEANUP(); + errno = save_errno; + return EX_TEMPFAIL; + } + } + + statp = EX_OK; + +# if !defined(LDAP_VERSION_MAX) && !defined(LDAP_OPT_SIZELIMIT) + /* + ** Reset value to prevent lingering + ** LDAP_DECODING_ERROR due to + ** OpenLDAP 1.X's hack (see below) + */ + + lmap->ldap_ld->ld_errno = LDAP_SUCCESS; +# endif /* !defined(LDAP_VERSION_MAX) !defined(LDAP_OPT_SIZELIMIT) */ + + /* + ** If matching only, + ** no need to spin through entries + */ + + if (bitset(SM_LDAP_MATCHONLY, flags)) + { + if (lmap->ldap_attrsonly == LDAPMAP_FALSE) + ldap_value_free(vals); + +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + continue; + } + + /* + ** If we don't want multiple values, + ** return first found. + */ + + if (delim == '\0') + { + if (lmap->ldap_attrsonly == LDAPMAP_TRUE) + { + *result = sm_rpool_strdup_x(rpool, + attr); +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + break; + } + + if (vals[0] == NULL) + { + ldap_value_free(vals); +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + continue; + } + + vsize = strlen(vals[0]) + 1; + if (lmap->ldap_attrsep != '\0') + vsize += strlen(attr) + 1; + *result = sm_rpool_malloc_x(rpool, + vsize); + if (lmap->ldap_attrsep != '\0') + sm_snprintf(*result, vsize, + "%s%c%s", + attr, + lmap->ldap_attrsep, + vals[0]); + else + sm_strlcpy(*result, vals[0], + vsize); + ldap_value_free(vals); +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + break; + } + + /* attributes only */ + if (lmap->ldap_attrsonly == LDAPMAP_TRUE) + { + if (*result == NULL) + *result = sm_rpool_strdup_x(rpool, + attr); + else + { + vsize = strlen(*result) + + strlen(attr) + 2; + tmp = sm_rpool_malloc_x(rpool, + vsize); + (void) sm_snprintf(tmp, + vsize, "%s%c%s", + *result, delim, + attr); + *result = tmp; + } +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + continue; + } + + /* + ** If there is more than one, + ** munge then into a map_coldelim + ** separated string + */ + + vsize = 0; + for (i = 0; vals[i] != NULL; i++) + { + if (type == LDAPMAP_ATTR_DN || + type == LDAPMAP_ATTR_FILTER || + type == LDAPMAP_ATTR_URL) + { + if (ldapmap_add_recurse(&recurse, + vals[i], + type) < 0) + { + LDAPMAP_ERROR_CLEANUP(); + errno = ENOMEM; + return EX_OSERR; + } + } + if (type != LDAPMAP_ATTR_NORMAL) + { +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + continue; + } + vsize += strlen(vals[i]) + 1; + if (lmap->ldap_attrsep != '\0') + vsize += strlen(attr) + 1; + } + vp_tmp = sm_rpool_malloc_x(rpool, vsize); + *vp_tmp = '\0'; + + p = vp_tmp; + for (i = 0; vals[i] != NULL; i++) + { + if (lmap->ldap_attrsep != '\0') + { + p += sm_strlcpy(p, attr, + vsize - (p - vp_tmp)); + *p++ = lmap->ldap_attrsep; + } + p += sm_strlcpy(p, vals[i], + vsize - (p - vp_tmp)); + if (p >= vp_tmp + vsize) + { + /* Internal error: buffer too small for LDAP values */ + LDAPMAP_ERROR_CLEANUP(); + errno = ENOMEM; + return EX_OSERR; + } + if (vals[i + 1] != NULL) + *p++ = delim; + } + + ldap_value_free(vals); +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ + if (*result == NULL) + { + *result = vp_tmp; + continue; + } + vsize = strlen(*result) + strlen(vp_tmp) + 2; + tmp = sm_rpool_malloc_x(rpool, vsize); + (void) sm_snprintf(tmp, vsize, "%s%c%s", + *result, delim, vp_tmp); + *result = tmp; + } + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + + /* + ** We check save_errno != LDAP_DECODING_ERROR since + ** OpenLDAP 1.X has a very ugly *undocumented* + ** hack of returning this error code from + ** ldap_next_attribute() if the library freed the + ** ber attribute. See: + ** http://www.openldap.org/lists/openldap-devel/9901/msg00064.html + */ + + if (save_errno != LDAP_SUCCESS && + save_errno != LDAP_DECODING_ERROR) + { + /* Must be an error */ + save_errno += E_LDAPBASE; + LDAPMAP_ERROR_CLEANUP(); + errno = save_errno; + return EX_TEMPFAIL; + } + + /* We don't want multiple values and we have one */ + if (delim == '\0' && *result != NULL) + break; + } + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + if (save_errno != LDAP_SUCCESS && + save_errno != LDAP_DECODING_ERROR) + { + /* Must be an error */ + save_errno += E_LDAPBASE; + LDAPMAP_ERROR_CLEANUP(); + errno = save_errno; + return EX_TEMPFAIL; + } + ldap_msgfree(lmap->ldap_res); + lmap->ldap_res = NULL; + } + + if (ret == 0) + save_errno = ETIMEDOUT; + else + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + if (save_errno != LDAP_SUCCESS) + { + statp = EX_TEMPFAIL; + if (ret != 0) + { + switch (save_errno) + { +#ifdef LDAP_SERVER_DOWN + case LDAP_SERVER_DOWN: +#endif /* LDAP_SERVER_DOWN */ + case LDAP_TIMEOUT: + case LDAP_UNAVAILABLE: + /* server disappeared, try reopen on next search */ + statp = EX_RESTART; + break; + } + save_errno += E_LDAPBASE; + } + LDAPMAP_ERROR_CLEANUP(); + errno = save_errno; + return statp; + } + + if (lmap->ldap_res != NULL) + { + ldap_msgfree(lmap->ldap_res); + lmap->ldap_res = NULL; + } + + if (toplevel) + { + SM_LDAP_RECURSE_LIST *rl; + + /* + ** Spin through the built-up recurse list at the top + ** of the recursion. Since new items are added at the + ** end of the shared list, we actually only ever get + ** one level of recursion before things pop back to the + ** top. Any items added to the list during that recursion + ** will be expanded by the top level. + */ + + for (rl = recurse; rl != NULL; rl = rl->lr_next) + { + int sid; + int status; + + if (rl->lr_type == LDAPMAP_ATTR_NORMAL) + { + /* already expanded */ + continue; + } + else if (rl->lr_type == LDAPMAP_ATTR_DN) + { + /* do DN search */ + sid = ldap_search(lmap->ldap_ld, + rl->lr_search, + lmap->ldap_scope, + "(objectClass=*)", + lmap->ldap_attr_final, + lmap->ldap_attrsonly); + } + else if (rl->lr_type == LDAPMAP_ATTR_FILTER) + { + /* do new search */ + sid = ldap_search(lmap->ldap_ld, + lmap->ldap_base, + lmap->ldap_scope, + rl->lr_search, + lmap->ldap_attr_final, + lmap->ldap_attrsonly); + } + else if (rl->lr_type == LDAPMAP_ATTR_URL) + { + /* do new URL search */ + sid = ldap_url_search(lmap->ldap_ld, + rl->lr_search, + lmap->ldap_attrsonly); + } + else + { + /* unknown or illegal attribute type */ + errno = EFAULT; + return EX_SOFTWARE; + } + + /* Collect results */ + if (sid == -1) + { + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + statp = EX_TEMPFAIL; + switch (save_errno) + { +#ifdef LDAP_SERVER_DOWN + case LDAP_SERVER_DOWN: +#endif /* LDAP_SERVER_DOWN */ + case LDAP_TIMEOUT: + case LDAP_UNAVAILABLE: + /* server disappeared, try reopen on next search */ + statp = EX_RESTART; + break; + } + errno = save_errno + E_LDAPBASE; + return statp; + } + + status = sm_ldap_results(lmap, sid, flags, delim, + rpool, result, recurse); + save_errno = errno; + if (status != EX_OK && status != EX_NOTFOUND) + { + errno = save_errno; + return status; + } + + /* Mark as done */ + rl->lr_type = LDAPMAP_ATTR_NORMAL; + } + } + return statp; +} +#endif /* _FFR_LDAP_RECURSION */ + /* ** SM_LDAP_CLOSE -- close LDAP connection ** diff --git a/gnu/usr.sbin/sendmail/libsm/makebuf.c b/gnu/usr.sbin/sendmail/libsm/makebuf.c index 7b4efc24519..7ec258dafda 100644 --- a/gnu/usr.sbin/sendmail/libsm/makebuf.c +++ b/gnu/usr.sbin/sendmail/libsm/makebuf.c @@ -13,7 +13,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: makebuf.c,v 1.23 2001/09/11 04:04:48 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: makebuf.c,v 1.26 2001/10/31 16:04:08 ca Exp $") #include <stdlib.h> #include <unistd.h> #include <sys/types.h> @@ -111,6 +111,28 @@ sm_whatbuf(fp, bufsize, couldbetty) return SMNPT; } +#if SM_IO_MAX_BUF_FILE > 0 + if (S_ISREG(st.st_mode) && st.st_blksize > SM_IO_MAX_BUF_FILE) + st.st_blksize = SM_IO_MAX_BUF_FILE; +#endif /* SM_IO_MAX_BUF_FILE > 0 */ + +#if SM_IO_MAX_BUF > 0 || SM_IO_MIN_BUF > 0 + if (!S_ISREG(st.st_mode)) + { +# if SM_IO_MAX_BUF > 0 + if (st.st_blksize > SM_IO_MAX_BUF) + st.st_blksize = SM_IO_MAX_BUF; +# if SM_IO_MIN_BUF > 0 + else +# endif /* SM_IO_MIN_BUF > 0 */ +# endif /* SM_IO_MAX_BUF > 0 */ +# if SM_IO_MIN_BUF > 0 + if (st.st_blksize < SM_IO_MIN_BUF) + st.st_blksize = SM_IO_MIN_BUF; +# endif /* SM_IO_MIN_BUF > 0 */ + } +#endif /* SM_IO_MAX_BUF > 0 || SM_IO_MIN_BUF > 0 */ + /* ** Optimise fseek() only if it is a regular file. (The test for ** sm_std_seek is mainly paranoia.) It is safe to set _blksize diff --git a/gnu/usr.sbin/sendmail/libsm/mbdb.c b/gnu/usr.sbin/sendmail/libsm/mbdb.c index eabd6098b37..93362dcf560 100644 --- a/gnu/usr.sbin/sendmail/libsm/mbdb.c +++ b/gnu/usr.sbin/sendmail/libsm/mbdb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2001-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: mbdb.c,v 1.23 2001/09/11 04:04:48 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: mbdb.c,v 1.28 2002/01/07 23:29:43 gshapiro Exp $") #include <sys/param.h> @@ -510,7 +510,7 @@ mbdb_ldap_lookup(name, user) return EX_TEMPFAIL; } - /* Get results (all if MF_NOREWRITE, otherwise one by one) */ + /* Get results */ ret = ldap_result(LDAPLMAP.ldap_ld, msgid, 1, (LDAPLMAP.ldap_timeout.tv_sec == 0 ? NULL : &(LDAPLMAP.ldap_timeout)), @@ -567,7 +567,12 @@ mbdb_ldap_lookup(name, user) { errno = sm_ldap_geterrno(LDAPLMAP.ldap_ld); if (errno == LDAP_SUCCESS) + { +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ continue; + } /* Must be an error */ errno += E_LDAPBASE; @@ -736,13 +741,6 @@ static void mbdb_ldap_terminate() { sm_ldap_close(&LDAPLMAP); - if (LDAPLMAP.ldap_base != MBDB_DEFAULT_LDAP_BASEDN) - { - if (LDAPLMAP.ldap_host != MBDB_DEFAULT_LDAP_SERVER) - LDAPLMAP.ldap_host = NULL; - sm_free(LDAPLMAP.ldap_base); - LDAPLMAP.ldap_base = NULL; - } } # endif /* _LDAP_EXAMPLE_ */ #endif /* LDAPMAP */ diff --git a/gnu/usr.sbin/sendmail/libsm/mpeix.c b/gnu/usr.sbin/sendmail/libsm/mpeix.c new file mode 100644 index 00000000000..fbd973f28ee --- /dev/null +++ b/gnu/usr.sbin/sendmail/libsm/mpeix.c @@ -0,0 +1,646 @@ +/* + * Copyright (c) 2001 Sendmail, Inc. and its suppliers. + * All rights reserved. + * + * By using this file, you agree to the terms and conditions set + * forth in the LICENSE file which can be found at the top level of + * the sendmail distribution. + * + */ + +#include <sm/gen.h> +SM_RCSID("@(#)$Sendmail: mpeix.c,v 1.4 2001/12/14 23:54:18 gshapiro Exp $") + +#ifdef MPE +/* +** MPE lacks many common functions required across all sendmail programs +** so we define implementations for these functions here. +*/ + +# include <errno.h> +# include <fcntl.h> +# include <limits.h> +# include <mpe.h> +# include <netinet/in.h> +# include <pwd.h> +# include <sys/socket.h> +# include <sys/stat.h> +# include <unistd.h> +# include <sm/conf.h> + +/* +** CHROOT -- dummy chroot() function +** +** The MPE documentation for sendmail says that chroot-based +** functionality is not implemented because MPE lacks chroot. But +** rather than mucking around with all the sendmail calls to chroot, +** we define this dummy function to return an ENOSYS failure just in +** case a sendmail user attempts to enable chroot-based functionality. +** +** Parameters: +** path -- pathname of new root (ignored). +** +** Returns: +** -1 and errno == ENOSYS (function not implemented) +*/ + +int +chroot(path) + char *path; +{ + errno = ENOSYS; + return -1; +} + +/* +** ENDPWENT -- dummy endpwent() function +** +** Parameters: +** none +** +** Returns: +** none +*/ + +void +endpwent() +{ + return; +} + +/* +** In addition to missing functions, certain existing MPE functions have +** slightly different semantics (or bugs) compared to normal Unix OSes. +** +** Here we define wrappers for these functions to make them behave in the +** manner expected by sendmail. +*/ + +/* +** SENDMAIL_MPE_BIND -- shadow function for the standard socket bind() +** +** MPE requires GETPRIVMODE() for AF_INET sockets less than port 1024. +** +** Parameters: +** sd -- socket descriptor. +** addr -- socket address. +** addrlen -- length of socket address. +** +** Results: +** 0 -- success +** != 0 -- failure +*/ + +#undef bind +int +sendmail_mpe_bind(sd, addr, addrlen) + int sd; + void *addr; + int addrlen; +{ + bool priv = false; + int result; + extern void GETPRIVMODE __P((void)); + extern void GETUSERMODE __P((void)); + + if (addrlen == sizeof(struct sockaddr_in) && + ((struct sockaddr_in *)addr)->sin_family == AF_INET) + { + /* AF_INET */ + if (((struct sockaddr_in *)addr)->sin_port > 0 && + ((struct sockaddr_in *)addr)->sin_port < 1024) + { + priv = true; + GETPRIVMODE(); + } + ((struct sockaddr_in *)addr)->sin_addr.s_addr = 0; + result = bind(sd, addr, addrlen); + if (priv) + GETUSERMODE(); + return result; + } + + /* AF_UNIX */ + return bind(sd, addr, addrlen); +} + +/* +** SENDMAIL_MPE__EXIT -- wait for children to terminate, then _exit() +** +** Child processes cannot survive the death of their parent on MPE, so +** we must call wait() before _exit() in order to prevent this +** infanticide. +** +** Parameters: +** status -- _exit status value. +** +** Returns: +** none. +*/ + +#undef _exit +void +sendmail_mpe__exit(status) + int status; +{ + int result; + + /* Wait for all children to terminate. */ + do + { + result = wait(NULL); + } while (result > 0 || errno == EINTR); + _exit(status); +} + +/* +** SENDMAIL_MPE_EXIT -- wait for children to terminate, then exit() +** +** Child processes cannot survive the death of their parent on MPE, so +** we must call wait() before exit() in order to prevent this +** infanticide. +** +** Parameters: +** status -- exit status value. +** +** Returns: +** none. +*/ + +#undef exit +void +sendmail_mpe_exit(status) + int status; +{ + int result; + + /* Wait for all children to terminate. */ + do + { + result = wait(NULL); + } while (result > 0 || errno == EINTR); + exit(status); +} + +/* +** SENDMAIL_MPE_FCNTL -- shadow function for fcntl() +** +** MPE requires sfcntl() for sockets, and fcntl() for everything +** else. This shadow routine determines the descriptor type and +** makes the appropriate call. +** +** Parameters: +** same as fcntl(). +** +** Returns: +** same as fcntl(). +*/ + +#undef fcntl +int +sendmail_mpe_fcntl(int fildes, int cmd, ...) +{ + int len, result; + struct sockaddr sa; + + void *arg; + va_list ap; + + va_start(ap, cmd); + arg = va_arg(ap, void *); + va_end(ap); + + len = sizeof sa; + if (getsockname(fildes, &sa, &len) == -1) + { + if (errno == EAFNOSUPPORT) + { + /* AF_UNIX socket */ + return sfcntl(fildes, cmd, arg); + } + else if (errno == ENOTSOCK) + { + /* file or pipe */ + return fcntl(fildes, cmd, arg); + } + + /* unknown getsockname() failure */ + return (-1); + } + else + { + /* AF_INET socket */ + if ((result = sfcntl(fildes, cmd, arg)) != -1 && + cmd == F_GETFL) + result |= O_RDWR; /* fill in some missing flags */ + return result; + } +} + +/* +** SENDMAIL_MPE_GETPWNAM - shadow function for getpwnam() +** +** Several issues apply here: +** +** - MPE user names MUST have one '.' separator character +** - MPE user names MUST be in upper case +** - MPE does not initialize all fields in the passwd struct +** +** Parameters: +** name -- username string. +** +** Returns: +** pointer to struct passwd if found else NULL +*/ + +static char *sendmail_mpe_nullstr = ""; + +#undef getpwnam +extern struct passwd *getpwnam(const char *); + +struct passwd * +sendmail_mpe_getpwnam(name) + const char *name; +{ + int dots = 0; + int err; + int i = strlen(name); + char *upper; + struct passwd *result = NULL; + + if (i <= 0) + { + errno = EINVAL; + return result; + } + + if ((upper = (char *)malloc(i + 1)) != NULL) + { + /* upshift the username parameter and count the dots */ + while (i >= 0) + { + if (name[i] == '.') + { + dots++; + upper[i] = '.'; + } + else + upper[i] = toupper(name[i]); + i--; + } + + if (dots != 1) + { + /* prevent bug when dots == 0 */ + err = EINVAL; + } + else if ((result = getpwnam(upper)) != NULL) + { + /* init the uninitialized fields */ + result->pw_gecos = sendmail_mpe_nullstr; + result->pw_passwd = sendmail_mpe_nullstr; + result->pw_age = sendmail_mpe_nullstr; + result->pw_comment = sendmail_mpe_nullstr; + result->pw_audid = 0; + result->pw_audflg = 0; + } + err = errno; + free(upper); + } + errno = err; + return result; +} + +/* +** SENDMAIL_MPE_GETPWUID -- shadow function for getpwuid() +** +** Initializes the uninitalized fields in the passwd struct. +** +** Parameters: +** uid -- uid to obtain passwd data for +** +** Returns: +** pointer to struct passwd or NULL if not found +*/ + +#undef getpwuid +extern struct passwd *getpwuid __P((uid_t)); + +struct passwd * +sendmail_mpe_getpwuid(uid) + uid_t uid; +{ + struct passwd *result; + + if ((result = getpwuid(uid)) != NULL) + { + /* initialize the uninitialized fields */ + result->pw_gecos = sendmail_mpe_nullstr; + result->pw_passwd = sendmail_mpe_nullstr; + result->pw_age = sendmail_mpe_nullstr; + result->pw_comment = sendmail_mpe_nullstr; + result->pw_audid = 0; + result->pw_audflg = 0; + } + return result; +} + +/* +** OK boys and girls, time for some serious voodoo! +** +** MPE does not have a complete implementation of POSIX users and groups: +** +** - there is no uid 0 superuser +** - setuid/setgid file permission bits exist but have no-op functionality +** - setgid() exists, but only supports new gid == current gid (boring!) +** - setuid() forces a gid change to the new uid's primary (and only) gid +** +** ...all of which thoroughly annoys sendmail. +** +** So what to do? We can't go on an #ifdef MPE rampage throughout +** sendmail, because there are only about a zillion references to uid 0 +** and so success (and security) would probably be rather dubious by the +** time we finished. +** +** Instead we take the approach of defining wrapper functions for the +** gid/uid management functions getegid(), geteuid(), setgid(), and +** setuid() in order to implement the following model: +** +** - the sendmail program thinks it is a setuid-root (uid 0) program +** - uid 0 is recognized as being valid, but does not grant extra powers +** - MPE priv mode allows sendmail to call setuid(), not uid 0 +** - file access is still controlled by the real non-zero uid +** - the other programs (vacation, etc) have standard MPE POSIX behavior +** +** This emulation model is activated by use of the program file setgid and +** setuid mode bits which exist but are unused by MPE. If the setgid mode +** bit is on, then gid emulation will be enabled. If the setuid mode bit is +** on, then uid emulation will be enabled. So for the mail daemon, we need +** to do chmod u+s,g+s /SENDMAIL/CURRENT/SENDMAIL. +** +** The following flags determine the current emulation state: +** +** true == emulation enabled +** false == emulation disabled, use unmodified MPE semantics +*/ + +static bool sendmail_mpe_flaginit = false; +static bool sendmail_mpe_gidflag = false; +static bool sendmail_mpe_uidflag = false; + +/* +** SENDMAIL_MPE_GETMODE -- return the mode bits for the current process +** +** Parameters: +** none. +** +** Returns: +** file mode bits for the current process program file. +*/ + +mode_t +sendmail_mpe_getmode() +{ + int status = 666; + int myprogram_length; + int myprogram_syntax = 2; + char formaldesig[28]; + char myprogram[PATH_MAX + 2]; + char path[PATH_MAX + 1]; + struct stat st; + extern HPMYPROGRAM __P((int parms, char *formaldesig, int *status, + int *length, char *myprogram, + int *myprogram_length, int *myprogram_syntax)); + + myprogram_length = sizeof(myprogram); + HPMYPROGRAM(6, formaldesig, &status, NULL, myprogram, + &myprogram_length, &myprogram_syntax); + + /* should not occur, do not attempt emulation */ + if (status != 0) + return 0; + + memcpy(&path, &myprogram[1], myprogram_length - 2); + path[myprogram_length - 2] = '\0'; + + /* should not occur, do not attempt emulation */ + if (stat(path, &st) < 0) + return 0; + + return st.st_mode; +} + +/* +** SENDMAIL_MPE_EMULGID -- should we perform gid emulation? +** +** If !sendmail_mpe_flaginit then obtain the mode bits to determine +** if the setgid bit is on, we want gid emulation and so set +** sendmail_mpe_gidflag to true. Otherwise we do not want gid emulation +** and so set sendmail_mpe_gidflag to false. +** +** Parameters: +** none. +** +** Returns: +** true -- perform gid emulation +** false -- do not perform gid emulation +*/ + +bool +sendmail_mpe_emulgid() +{ + if (!sendmail_mpe_flaginit) + { + mode_t mode; + + mode = sendmail_mpe_getmode(); + sendmail_mpe_gidflag = ((mode & S_ISGID) == S_ISGID); + sendmail_mpe_uidflag = ((mode & S_ISUID) == S_ISUID); + sendmail_mpe_flaginit = true; + } + return sendmail_mpe_gidflag; +} + +/* +** SENDMAIL_MPE_EMULUID -- should we perform uid emulation? +** +** If sendmail_mpe_uidflag == -1 then obtain the mode bits to determine +** if the setuid bit is on, we want uid emulation and so set +** sendmail_mpe_uidflag to true. Otherwise we do not want uid emulation +** and so set sendmail_mpe_uidflag to false. +** +** Parameters: +** none. +** +** Returns: +** true -- perform uid emulation +** false -- do not perform uid emulation +*/ + +bool +sendmail_mpe_emuluid() +{ + if (!sendmail_mpe_flaginit) + { + mode_t mode; + + mode = sendmail_mpe_getmode(); + sendmail_mpe_gidflag = ((mode & S_ISGID) == S_ISGID); + sendmail_mpe_uidflag = ((mode & S_ISUID) == S_ISUID); + sendmail_mpe_flaginit = true; + } + return sendmail_mpe_uidflag; +} + +/* +** SENDMAIL_MPE_GETEGID -- shadow function for getegid() +** +** If emulation mode is in effect and the saved egid has been +** initialized, return the saved egid; otherwise return the value of the +** real getegid() function. +** +** Parameters: +** none. +** +** Returns: +** emulated egid if present, else true egid. +*/ + +static uid_t sendmail_mpe_egid = -1; + +#undef getegid +gid_t +sendmail_mpe_getegid() +{ + if (sendmail_mpe_emulgid() && sendmail_mpe_egid != -1) + return sendmail_mpe_egid; + return getegid(); +} + +/* +** SENDMAIL_MPE_GETEUID -- shadow function for geteuid() +** +** If emulation mode is in effect, return the saved euid; otherwise +** return the value of the real geteuid() function. +** +** Note that the initial value of the saved euid is zero, to simulate +** a setuid-root program. +** +** Parameters: +** none +** +** Returns: +** emulated euid if in emulation mode, else true euid. +*/ + +static uid_t sendmail_mpe_euid = 0; + +#undef geteuid +uid_t +sendmail_mpe_geteuid() +{ + if (sendmail_mpe_emuluid()) + return sendmail_mpe_euid; + return geteuid(); +} + +/* +** SENDMAIL_MPE_SETGID -- shadow function for setgid() +** +** Simulate a call to setgid() without actually calling the real +** function. Implement the expected uid 0 semantics. +** +** Note that sendmail will also be calling setuid() which will force an +** implicit real setgid() to the proper primary gid. So it doesn't matter +** that we don't actually alter the real gid in this shadow function. +** +** Parameters: +** gid -- desired gid. +** +** Returns: +** 0 -- emulated success +** -1 -- emulated failure +*/ + +#undef setgid +int +sendmail_mpe_setgid(gid) + gid_t gid; +{ + if (sendmail_mpe_emulgid()) + { + if (gid == getgid() || sendmail_mpe_euid == 0) + { + sendmail_mpe_egid = gid; + return 0; + } + errno = EINVAL; + return -1; + } + return setgid(gid); +} + +/* +** SENDMAIL_MPE_SETUID -- shadow function for setuid() +** +** setuid() is broken as of MPE 7.0 in that it changes the current +** working directory to be the home directory of the new uid. Thus +** we must obtain the cwd and restore it after the setuid(). +** +** Note that expected uid 0 semantics have been added, as well as +** remembering the new uid for later use by the other shadow functions. +** +** Parameters: +** uid -- desired uid. +** +** Returns: +** 0 -- success +** -1 -- failure +** +** Globals: +** sendmail_mpe_euid +*/ + +#undef setuid +int +sendmail_mpe_setuid(uid) + uid_t uid; +{ + char *cwd; + char cwd_buf[PATH_MAX+1]; + int result; + extern void GETPRIVMODE __P((void)); + extern void GETUSERMODE __P((void)); + + if (sendmail_mpe_emuluid()) + { + if (uid == 0) + { + if (sendmail_mpe_euid != 0) + { + errno = EINVAL; + return -1; + } + sendmail_mpe_euid = 0; + return 0; + } + + /* Preserve the current working directory */ + if ((cwd = getcwd(cwd_buf, PATH_MAX + 1)) == NULL) + return -1; + + GETPRIVMODE(); + result = setuid(uid); + GETUSERMODE(); + + /* Restore the current working directory */ + chdir(cwd_buf); + + if (result == 0) + sendmail_mpe_euid = uid; + + return result; + } + return setuid(uid); +} +#endif /* MPE */ diff --git a/gnu/usr.sbin/sendmail/libsm/put.c b/gnu/usr.sbin/sendmail/libsm/put.c index 309edb2ced0..ee06c5facf4 100644 --- a/gnu/usr.sbin/sendmail/libsm/put.c +++ b/gnu/usr.sbin/sendmail/libsm/put.c @@ -13,7 +13,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: put.c,v 1.26 2001/09/11 04:04:49 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: put.c,v 1.27 2001/12/19 05:19:35 ca Exp $") #include <string.h> #include <errno.h> #include <sm/io.h> @@ -71,8 +71,10 @@ void sm_perror(s) const char *s; { + int save_errno = errno; + if (s != NULL && *s != '\0') (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s: ", s); (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%s\n", - sm_errstring(errno)); + sm_errstring(save_errno)); } diff --git a/gnu/usr.sbin/sendmail/libsm/rpool.c b/gnu/usr.sbin/sendmail/libsm/rpool.c index 62bb8a04d41..9cf44f9e87d 100644 --- a/gnu/usr.sbin/sendmail/libsm/rpool.c +++ b/gnu/usr.sbin/sendmail/libsm/rpool.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: rpool.c,v 1.23 2001/09/11 04:04:49 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: rpool.c,v 1.24 2002/01/11 21:54:43 ca Exp $") /* ** resource pools @@ -108,6 +108,14 @@ sm_rpool_allocblock(rpool, size) ** ** Exceptions: ** F:sm_heap -- out of memory +** +** Notice: XXX +** if size == 0 and the rpool is new (no memory +** allocated yet) NULL is returned! +** We could solve this by +** - wasting 1 byte (size < avail) +** - checking for rpool->sm_poolptr != NULL +** - not asking for 0 sized buffer */ void * @@ -196,6 +204,14 @@ sm_rpool_malloc_x(rpool, size) ** ** Returns: ** Pointer to block, NULL on failure. +** +** Notice: XXX +** if size == 0 and the rpool is new (no memory +** allocated yet) NULL is returned! +** We could solve this by +** - wasting 1 byte (size < avail) +** - checking for rpool->sm_poolptr != NULL +** - not asking for 0 sized buffer */ void * diff --git a/gnu/usr.sbin/sendmail/libsm/shm.c b/gnu/usr.sbin/sendmail/libsm/shm.c index d108db1b940..f19fa9a8cf0 100644 --- a/gnu/usr.sbin/sendmail/libsm/shm.c +++ b/gnu/usr.sbin/sendmail/libsm/shm.c @@ -8,7 +8,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: shm.c,v 1.8 2001/09/11 04:04:49 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: shm.c,v 1.10 2001/12/14 00:22:58 ca Exp $") #if SM_CONF_SHM # include <stdlib.h> @@ -54,8 +54,7 @@ sm_shmstart(key, size, shmflg, shmid, owner) if (*shmid < 0) goto error; - shmflg = SHM_RND; - shm = shmat(*shmid, (void *) 0, shmflg); + shm = shmat(*shmid, (void *) 0, 0); if (shm == SM_SHM_NULL) goto error; diff --git a/gnu/usr.sbin/sendmail/libsm/strl.c b/gnu/usr.sbin/sendmail/libsm/strl.c index 225b156a248..21c31464131 100644 --- a/gnu/usr.sbin/sendmail/libsm/strl.c +++ b/gnu/usr.sbin/sendmail/libsm/strl.c @@ -9,11 +9,16 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: strl.c,v 1.28 2001/09/11 04:04:49 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: strl.c,v 1.29 2001/10/03 16:09:32 ca Exp $") #include <sm/config.h> #include <sm/string.h> /* +** Notice: this file is used by libmilter. Please try to avoid +** using libsm specific functions. +*/ + +/* ** XXX the type of the length parameter has been changed ** from size_t to ssize_t to avoid theoretical problems with negative ** numbers passed into these functions. diff --git a/gnu/usr.sbin/sendmail/libsm/strto.c b/gnu/usr.sbin/sendmail/libsm/strto.c index d719e100816..35b0870234f 100644 --- a/gnu/usr.sbin/sendmail/libsm/strto.c +++ b/gnu/usr.sbin/sendmail/libsm/strto.c @@ -10,13 +10,15 @@ */ #include <sm/gen.h> -SM_IDSTR(id, "@(#)$Sendmail: strto.c,v 1.16 2001/09/11 04:04:49 gshapiro Exp $") +SM_IDSTR(id, "@(#)$Sendmail: strto.c,v 1.18 2001/12/30 04:59:37 gshapiro Exp $") +#include <sys/param.h> #include <sys/types.h> #include <stdlib.h> #include <ctype.h> #include <errno.h> #include <sm/limits.h> +#include <sm/conf.h> #include <sm/string.h> /* diff --git a/gnu/usr.sbin/sendmail/libsm/t-scanf.c b/gnu/usr.sbin/sendmail/libsm/t-scanf.c index 55e7be2fd11..e4aa3773ea6 100644 --- a/gnu/usr.sbin/sendmail/libsm/t-scanf.c +++ b/gnu/usr.sbin/sendmail/libsm/t-scanf.c @@ -8,7 +8,7 @@ */ #include <sm/gen.h> -SM_IDSTR(id, "@(#)$Sendmail: t-scanf.c,v 1.4 2001/09/11 04:04:49 gshapiro Exp $") +SM_IDSTR(id, "@(#)$Sendmail: t-scanf.c,v 1.5 2001/11/13 00:51:28 ca Exp $") #include <sm/limits.h> #include <sm/io.h> @@ -26,10 +26,12 @@ main(argc, argv) char *r; sm_test_begin(argc, argv, "test scanf point stuff"); +#if !SM_CONF_BROKEN_SIZE_T (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "If tests for \"h == 2\" fail, check whether size_t is signed on your OS.\n\ If that is the case, add -DSM_CONF_BROKEN_SIZE_T to confENVDEF\n\ and start over. Otherwise contact sendmail.org.\n"); +#endif /* !SM_CONF_BROKEN_SIZE_T */ d = 2; sm_snprintf(buf, sizeof(buf), "%d", d); diff --git a/gnu/usr.sbin/sendmail/libsm/test.c b/gnu/usr.sbin/sendmail/libsm/test.c index 852e5386dc4..617ca1431c7 100644 --- a/gnu/usr.sbin/sendmail/libsm/test.c +++ b/gnu/usr.sbin/sendmail/libsm/test.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 2000-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * * By using this file, you agree to the terms and conditions set @@ -8,7 +8,7 @@ */ #include <sm/gen.h> -SM_IDSTR(Id, "@(#)$Sendmail: test.c,v 1.14 2001/09/11 04:04:49 gshapiro Exp $") +SM_IDSTR(Id, "@(#)$Sendmail: test.c,v 1.16 2002/01/08 17:54:40 ca Exp $") /* ** Abstractions for writing libsm test programs. @@ -16,8 +16,8 @@ SM_IDSTR(Id, "@(#)$Sendmail: test.c,v 1.14 2001/09/11 04:04:49 gshapiro Exp $") #include <stdlib.h> #include <unistd.h> +#include <stdio.h> #include <sm/debug.h> -#include <sm/io.h> #include <sm/test.h> extern char *optarg; @@ -80,14 +80,13 @@ sm_test_begin(argc, argv, testname) sm_debug_addsettings_x(optarg); break; case 'h': - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, Help, - argv[0], testname); + (void) fprintf(stdout, Help, argv[0], testname); exit(0); default: - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, - "Unknown command line option -%c\n", optopt); - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, Usage, - argv[0], argv[0]); + (void) fprintf(stderr, + "Unknown command line option -%c\n", + optopt); + (void) fprintf(stderr, Usage, argv[0], argv[0]); exit(1); } } @@ -115,21 +114,19 @@ sm_test(success, expr, filename, lineno) { ++SmTestIndex; if (SmTestVerbose) - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "%d..", - SmTestIndex); + (void) fprintf(stderr, "%d..", SmTestIndex); if (!success) { ++SmTestNumErrors; if (!SmTestVerbose) - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, - "%d..", SmTestIndex); - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, - "bad! %s:%d %s\n", filename, lineno, expr); + (void) fprintf(stderr, "%d..", SmTestIndex); + (void) fprintf(stderr, "bad! %s:%d %s\n", filename, lineno, + expr); } else { if (SmTestVerbose) - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "ok\n"); + (void) fprintf(stderr, "ok\n"); } return success; } @@ -147,14 +144,12 @@ sm_test(success, expr, filename, lineno) int sm_test_end() { - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, - "%d of %d tests completed successfully\n", - SmTestIndex - SmTestNumErrors, SmTestIndex); + (void) fprintf(stderr, "%d of %d tests completed successfully\n", + SmTestIndex - SmTestNumErrors, SmTestIndex); if (SmTestNumErrors != 0) - (void) sm_io_fprintf(smioerr, SM_TIME_DEFAULT, - "*** %d error%s in test! ***\n", - SmTestNumErrors, - SmTestNumErrors > 1 ? "s" : ""); + (void) fprintf(stderr, "*** %d error%s in test! ***\n", + SmTestNumErrors, + SmTestNumErrors > 1 ? "s" : ""); return SmTestNumErrors; } diff --git a/gnu/usr.sbin/sendmail/libsmdb/smdb.c b/gnu/usr.sbin/sendmail/libsmdb/smdb.c index 740f967b9c8..ed33c1e5fed 100644 --- a/gnu/usr.sbin/sendmail/libsmdb/smdb.c +++ b/gnu/usr.sbin/sendmail/libsmdb/smdb.c @@ -8,7 +8,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: smdb.c,v 8.52 2001/09/11 04:04:52 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: smdb.c,v 8.53 2001/11/19 19:31:14 gshapiro Exp $") #include <fcntl.h> #include <stdlib.h> @@ -198,7 +198,6 @@ smdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info, SMDB_USER_INFO *user_info; SMDB_DBPARAMS *params; { - int result; bool type_was_default = false; if (type == SMDB_TYPE_DEFAULT) @@ -220,6 +219,8 @@ smdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info, (strncmp(type, SMDB_TYPE_BTREE, SMDB_TYPE_BTREE_LEN) == 0)) { #ifdef NEWDB + int result; + result = smdb_db_open(database, db_name, mode, mode_mask, sff, type, user_info, params); # ifdef NDBM @@ -236,6 +237,8 @@ smdb_open_database(database, db_name, mode, mode_mask, sff, type, user_info, if (strncmp(type, SMDB_TYPE_NDBM, SMDB_TYPE_NDBM_LEN) == 0) { #ifdef NDBM + int result; + result = smdb_ndbm_open(database, db_name, mode, mode_mask, sff, type, user_info, params); return result; diff --git a/gnu/usr.sbin/sendmail/libsmutil/safefile.c b/gnu/usr.sbin/sendmail/libsmutil/safefile.c index fbddc2de527..8da12ea4193 100644 --- a/gnu/usr.sbin/sendmail/libsmutil/safefile.c +++ b/gnu/usr.sbin/sendmail/libsmutil/safefile.c @@ -15,7 +15,7 @@ #include <sm/io.h> #include <sm/errstring.h> -SM_RCSID("@(#)$Sendmail: safefile.c,v 8.118 2001/09/18 21:45:27 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: safefile.c,v 8.121 2001/10/11 21:46:13 gshapiro Exp $") /* @@ -206,6 +206,7 @@ safefile(fn, uid, gid, user, flags, mode, st) { int md = S_IWRITE|S_IEXEC; + ret = 0; if (stbuf.st_uid == uid) /* EMPTY */ ; @@ -237,9 +238,10 @@ safefile(fn, uid, gid, user, flags, mode, st) md >>= 3; } if ((stbuf.st_mode & md) != md) - errno = EACCES; + ret = errno = EACCES; } - ret = errno; + else + ret = errno; if (tTd(44, 4)) sm_dprintf("\t[final dir %s uid %d mode %lo] %s\n", dir, (int) stbuf.st_uid, diff --git a/gnu/usr.sbin/sendmail/mail.local/mail.local.c b/gnu/usr.sbin/sendmail/mail.local/mail.local.c index 2b10e2f27fc..41dc519bb28 100644 --- a/gnu/usr.sbin/sendmail/mail.local/mail.local.c +++ b/gnu/usr.sbin/sendmail/mail.local/mail.local.c @@ -18,11 +18,12 @@ SM_IDSTR(copyright, Copyright (c) 1990, 1993, 1994\n\ The Regents of the University of California. All rights reserved.\n") -SM_IDSTR(id, "@(#)$Sendmail: mail.local.c,v 8.234 2001/09/11 04:04:59 gshapiro Exp $") +SM_IDSTR(id, "@(#)$Sendmail: mail.local.c,v 8.235 2001/12/30 04:59:39 gshapiro Exp $") #include <stdlib.h> #include <sm/errstring.h> #include <sm/io.h> +#include <sm/limits.h> # include <unistd.h> # ifdef EX_OK # undef EX_OK /* unistd.h may have another use for this */ diff --git a/gnu/usr.sbin/sendmail/mailstats/mailstats.c b/gnu/usr.sbin/sendmail/mailstats/mailstats.c index 52a98b980ae..3d07d02eab0 100644 --- a/gnu/usr.sbin/sendmail/mailstats/mailstats.c +++ b/gnu/usr.sbin/sendmail/mailstats/mailstats.c @@ -20,7 +20,7 @@ SM_IDSTR(copyright, Copyright (c) 1988, 1993\n\ The Regents of the University of California. All rights reserved.\n") -SM_IDSTR(id, "@(#)$Sendmail: mailstats.c,v 8.91 2001/09/11 04:05:02 gshapiro Exp $") +SM_IDSTR(id, "@(#)$Sendmail: mailstats.c,v 8.95 2001/12/30 04:59:40 gshapiro Exp $") #include <unistd.h> #include <stddef.h> @@ -34,6 +34,7 @@ SM_IDSTR(id, "@(#)$Sendmail: mailstats.c,v 8.91 2001/09/11 04:05:02 gshapiro Exp #include <sysexits.h> #include <sm/errstring.h> +#include <sm/limits.h> #include <sendmail/sendmail.h> #include <sendmail/mailstats.h> #include <sendmail/pathnames.h> @@ -58,6 +59,9 @@ main(argc, argv) bool trunc; long frmsgs = 0, frbytes = 0, tomsgs = 0, tobytes = 0, rejmsgs = 0; long dismsgs = 0; +#if _FFR_QUARANTINE + long quarmsgs = 0; +#endif /* _FFR_QUARANTINE */ time_t now; char mtable[MAXMAILERS][MNAMELEN + 1]; char sfilebuf[MAXLINE]; @@ -279,12 +283,19 @@ main(argc, argv) "Statistics from %s", ctime(&stats.stat_itime)); (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - " M msgsfr bytes_from msgsto bytes_to msgsrej msgsdis%s\n", + " M msgsfr bytes_from msgsto bytes_to msgsrej msgsdis"); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " msgsqur"); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "%s\n", mnames ? " Mailer" : ""); } for (i = 0; i < MAXMAILERS; i++) { if (stats.stat_nf[i] || stats.stat_nt[i] || +#if _FFR_QUARANTINE + stats.stat_nq[i] || +#endif /* _FFR_QUARANTINE */ stats.stat_nr[i] || stats.stat_nd[i]) { char *format; @@ -301,6 +312,10 @@ main(argc, argv) stats.stat_bt[i], stats.stat_nr[i], stats.stat_nd[i]); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " %6ld", stats.stat_nq[i]); +#endif /* _FFR_QUARANTINE */ if (mnames) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " %s", @@ -312,14 +327,22 @@ main(argc, argv) tobytes += stats.stat_bt[i]; rejmsgs += stats.stat_nr[i]; dismsgs += stats.stat_nd[i]; +#if _FFR_QUARANTINE + quarmsgs += stats.stat_nq[i]; +#endif /* _FFR_QUARANTINE */ } } if (progmode) { (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - " T %8ld %10ld %8ld %10ld %6ld %6ld\n", + " T %8ld %10ld %8ld %10ld %6ld %6ld", frmsgs, frbytes, tomsgs, tobytes, rejmsgs, dismsgs); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " %6ld", quarmsgs); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " C %8ld %8ld %6ld\n", stats.stat_cf, stats.stat_ct, @@ -335,11 +358,20 @@ main(argc, argv) else { (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - "=============================================================\n"); + "============================================================="); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "========"); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - " T %8ld %10ldK %8ld %10ldK %6ld %6ld\n", + " T %8ld %10ldK %8ld %10ldK %6ld %6ld", frmsgs, frbytes, tomsgs, tobytes, rejmsgs, dismsgs); +#if _FFR_QUARANTINE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + " %6ld", quarmsgs); +#endif /* _FFR_QUARANTINE */ + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "\n"); (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, " C %8ld %10s %8ld %10s %6ld\n", stats.stat_cf, "", stats.stat_ct, "", diff --git a/gnu/usr.sbin/sendmail/makemap/makemap.8 b/gnu/usr.sbin/sendmail/makemap/makemap.8 index 28d1ff310cd..88f4f84e826 100644 --- a/gnu/usr.sbin/sendmail/makemap/makemap.8 +++ b/gnu/usr.sbin/sendmail/makemap/makemap.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1988, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -8,9 +8,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Sendmail: makemap.8,v 8.27 2000/12/29 18:16:55 gshapiro Exp $ +.\" $Sendmail: makemap.8,v 8.29 2001/10/10 03:23:02 ca Exp $ .\" -.Dd December 29, 2000 +.Dd October 10, 2001 .Dt MAKEMAP 8 .Os .Sh NAME @@ -77,6 +77,15 @@ Literal percents should be doubled (``%%''). Blank lines and lines beginning with ``#'' are ignored. .Pp +Notice: do +.Em not +use +.Nm +to create the aliases data base, but +.Xr newaliases 8 +which puts a special token into the data base that is required by +.Xr sendmail 8 . +.Pp If the .Li TrustedUser option is set in the sendmail configuration file and @@ -145,6 +154,7 @@ Verbosely print what it is doing. .El .Sh SEE ALSO .Xr editmap 8 , +.Xr newaliases 8 , .Xr sendmail 8 .Sh HISTORY The diff --git a/gnu/usr.sbin/sendmail/makemap/makemap.c b/gnu/usr.sbin/sendmail/makemap/makemap.c index 4637e2f4ad7..5d77f03951b 100644 --- a/gnu/usr.sbin/sendmail/makemap/makemap.c +++ b/gnu/usr.sbin/sendmail/makemap/makemap.c @@ -20,7 +20,7 @@ SM_IDSTR(copyright, Copyright (c) 1992, 1993\n\ The Regents of the University of California. All rights reserved.\n") -SM_IDSTR(id, "@(#)$Sendmail: makemap.c,v 8.173 2001/09/26 22:18:21 ca Exp $") +SM_IDSTR(id, "@(#)$Sendmail: makemap.c,v 8.175 2001/12/28 22:44:01 ca Exp $") #include <sys/types.h> @@ -56,9 +56,13 @@ static void usage(progname) char *progname; { + /* XXX break the usage output into multiple lines? it's too long */ sm_io_fprintf(smioerr, SM_TIME_DEFAULT, "Usage: %s [-C cffile] [-N] [-c cachesize] [-d] [-e] [-f] [-l] [-o] [-r] [-s] [-t delimiter] [-u] [-v] type mapname\n", progname); +#if _FFR_COMMENT_CHAR + /* add -D comment-char */ +#endif /* _FFR_COMMENT_CHAR */ exit(EX_USAGE); } @@ -77,6 +81,7 @@ main(argc, argv) bool foldcase = true; bool unmake = false; char sep = '\0'; + char comment = '#'; int exitstat; int opt; char *typename = NULL; @@ -127,8 +132,7 @@ main(argc, argv) (void) sm_strlcpy(user_info.smdbu_name, RunAsUserName, SMDB_MAX_USER_NAME_LEN); - -#define OPTIONS "C:Nc:t:deflorsuv" +#define OPTIONS "C:D:Nc:deflorst:uv" while ((opt = getopt(argc, argv, OPTIONS)) != -1) { switch (opt) @@ -157,6 +161,12 @@ main(argc, argv) foldcase = false; break; +#if _FFR_COMMENT_CHAR + case 'D': + comment = *optarg; + break; +#endif /* _FFR_COMMENT_CHAR */ + case 'l': smdb_print_available_types(); exit(EX_OK); @@ -402,7 +412,7 @@ main(argc, argv) continue; } - if (ibuf[0] == '\0' || ibuf[0] == '#') + if (ibuf[0] == '\0' || ibuf[0] == comment) continue; if (sep == '\0' && isascii(ibuf[0]) && isspace(ibuf[0])) { diff --git a/gnu/usr.sbin/sendmail/sendmail/README b/gnu/usr.sbin/sendmail/sendmail/README index 323935674bf..8b9dcfb4651 100644 --- a/gnu/usr.sbin/sendmail/sendmail/README +++ b/gnu/usr.sbin/sendmail/sendmail/README @@ -1,4 +1,4 @@ -# Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. +# Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. # All rights reserved. # Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. # Copyright (c) 1988 @@ -9,7 +9,7 @@ # the sendmail distribution. # # -# $Sendmail: README,v 8.335 2001/09/24 23:52:12 ca Exp $ +# $Sendmail: README,v 8.345 2002/01/09 18:04:30 ca Exp $ # This directory contains the source files for sendmail(TM). @@ -201,6 +201,8 @@ SYS5SIGNALS Use System V signal semantics -- the signal handler signal handler stays in force until an exec or an explicit delete. Implied by SYSTEM5. SYS5SETPGRP Use System V setpgrp() semantics. Implied by SYSTEM5. +HASNICE Define this to zero if you lack the nice(2) system call. +HASRRESVPORT Define this to zero if you lack the rresvport(3) system call. HASFCHMOD Define this to one if you have the fchmod(2) system call. This improves security. HASFCHOWN Define this to one if you have the fchown(2) system call. @@ -260,8 +262,6 @@ HASSETREGID Define this if you have setregid(2) and it can be HASSETRESGID Define this if you have setresgid(2) and it can be used to set the saved gid. Please run t_dropgid in test/ if you are not sure whether the call works. -SM_CONF_CANT_SETRGID Define this if your OS does not have a system - call that can set the real gid for a set-group-ID program. HASLSTAT Define this if you have symbolic links (and thus the lstat(2) system call). This improves security. Unlike most other options, this one is on by default, so you @@ -463,13 +463,19 @@ SO_REUSEADDR_IS_BROKEN NEEDSGETIPNODE Set this if your system supports IPv6 but doesn't include the getipnodeby{name,addr}() functions. Set automatically for Linux's glibc. -SM_CONF_STRL - By default this is on (1). This uses the sendmail versions - of strlcpy and strlcat (called sm_strlcpy and sm_strlcat - respectively). The program ../libsm/b-strl.c can be used - to determine performance of these functions if your OS - has these functions natively. PIPELINING Support SMTP PIPELINING (set by default). +USING_NETSCAPE_LDAP + Set this if LDAPMAP is set and your LDAP libraries are from + (or are derived from) Netscape's implementation, which + requires that the return value of ldap_first_attribute() + and ldap_next_attribute() be ldap_memfree()'d. +NEEDLINK Set this if your system doesn't have a link() call. It + will create a copy of the file instead of a hardlink. +USE_ENVIRON Set this to 1 to access process environment variables from + the external variable environ instead of the third + parameter of main(). +USE_DOUBLE_FORK By default this is on (1). Set it to 0 to suppress the + extra fork() used to avoid intermediate zombies. +-----------------------+ @@ -779,6 +785,23 @@ ControlSocket permissions owned directories which do not permit non-root to r/w/x through them. The long term fix is for all kernels to upgrade to 4.4BSD semantics. +HP MPE/iX + The MPE-specific code within sendmail emulates a set-user-id root + environment for the sendmail binary. But there is no root uid 0 on + MPE, nor is there any support for set-user-id programs. Even when + sendmail thinks it is running as uid 0, it will still have the file + access rights of the underlying non-zero uid, but because sendmail is + an MPE priv-mode program it will still be able to call setuid() to + successfully switch to a new uid. + + MPE setgid() semantics don't quite work the way sendmail expects, so + special emulation is done here also. + + This uid/gid emulation is enabled via the setuid/setgid file mode bits + which are not currently used by MPE. Code in libsm/mpeix.c examines + these bits and enables emulation if they have been set, i.e., + chmod u+s,g+s /SENDMAIL/CURRENT/SENDMAIL. + SunOS 4.x (Solaris 1.x) You may have to use -lresolv on SunOS. However, beware that this links in a new version of gethostbyname that does not @@ -941,13 +964,21 @@ Solaris 7 (SunOS 5.7) Solaris 8 and later (SunOS 5.8 and later) Solaris 8 and later can optionally install LDAP support. If you - have installed the Entire Distribution meta-cluster cluster, you - can use the following in devtools/Site/site.SunOS.5.8.m4 (or other + have installed the Entire Distribution meta-cluster, you can use + the following in devtools/Site/site.SunOS.5.8.m4 (or other appropriately versioned file) to enable LDAP: APPENDDEF(`confMAPDEF', `-DLDAPMAP') APPENDDEF(`confLIBS', `-lldap') +Solaris 9 and later (SunOS 5.9 and later) + Solaris 9 and later have a revised LDAP library, libldap.so.5, + which is derived from a Netscape implementation, thus requiring + that USING_NETSCAPE_LDAP be defined in conjunction with LDAPMAP: + + APPENDDEF(`confMAPDEF', `-DLDAPMAP -DUSING_NETSCAPE_LDAP') + APPENDDEF(`confLIBS', `-lldap') + Solaris If you are using dns for hostname resolution on Solaris, make sure that the 'dns' entry is last on the hosts line in @@ -1302,6 +1333,19 @@ AIX 4.X gcc -Wl,-rpath /usr/lib -Wl,-rpath /lib -Wl,-rpath /usr/local/lib +AIX 4.X If the test program t-event (and most others) in libsm fails, + check your compiler settings. It seems that the flags -qnoro or + -qnoroconst on some AIX versions trigger a compiler bug. Check + your compiler settings or use cc instead of xlc. + +AIX 4.0-4.2, maybe some AIX 4.3 versions + The AIX m4 implements a different mechanism for ifdef which is + inconsistent with other versions of m4. Therefore, it will not + work properly with the sendmail Build architecture or m4 + configuration method. To work around this problem, please use + GNU m4 from ftp://ftp.gnu.org/pub/gnu/. + The problem seems to be solved in AIX 4.3.3 at least. + AIX 4.3.3 From: Valdis.Kletnieks@vt.edu Date: Sun, 02 Jul 2000 03:58:02 -0400 @@ -1316,13 +1360,6 @@ AIX 4.3.3 2) Build against a real BIND 8.2.2 include/lib tree 3) Wait for IBM to fix it -AIX 4.X - The AIX m4 implements a different mechanism for ifdef which is - inconsistent with other versions of m4. Therefore, it will not - work properly with the sendmail Build architecture or m4 - configuration method. To work around this problem, please use - GNU m4 from ftp://ftp.gnu.org/pub/gnu/. - AIX 3.x This version of sendmail does not support MB, MG, and MR resource records, which are supported by AIX sendmail. @@ -1436,7 +1473,8 @@ UNICOS 8.0.3.4 running sendmail. Reported by Jerry G. DeLapp <jgd@acl.lanl.gov>. Mac OS X (10.0.X) - From: Mike Zimmerman <zimmy@torrentnet.com> + From Mike Zimmerman <zimmy@torrentnet.com>: + From scratch here is what Darwin users need to do to the standard 10.0.0, 10.0.1 install to get sendmail working. From http://www.macosx.com/forums/showthread.php?s=6dac0e9e1f3fd118a4870a8a9b559491&threadid=2242: @@ -1450,6 +1488,28 @@ Mac OS X (10.0.X) Remove the "&" after the sendmail command: /usr/sbin/sendmail -bd -q1h + From Carsten Klapp <carsten.klapp@home.com>: + + The easiest workaround is to remove the group-writable permission + for the root directory and the symbolic /etc inherits this + change. While this does fix sendmail, the unfortunate side-effect + is the OS X admin will no longer be able to manipulate icons in the + top level of the Startup disk unless logged into the GUI as the + superuser. + + In applying the alternate workaround, care must be taken while + swapping the symlink /etc with the directory /private/etc. In all + likelihood any admin who is concerned with this sendmail error has + enough experience to not accidentally harm anything in the process. + + a. Swap the /etc symlink with /private/etc (as superuser): + rm /etc + mv /private/etc /etc + ln -s /etc /private/etc + + b. Set / to group unwritable (as superuser): + chmod g-w / + GNU getopt I'm told that GNU getopt has a problem in that it gets confused by the double call. Use the version in conf.c instead. @@ -1675,4 +1735,4 @@ util.c Some general purpose routines used by sendmail. version.c The version number and information about this version of sendmail. -(Version $Revision: 1.10 $, last update $Date: 2001/10/01 17:18:29 $ ) +(Version $Revision: 1.11 $, last update $Date: 2002/01/14 03:21:40 $ ) diff --git a/gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS b/gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS index d21f0d1c1e3..3708f99a33a 100644 --- a/gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS +++ b/gnu/usr.sbin/sendmail/sendmail/TRACEFLAGS @@ -1,4 +1,4 @@ -# $Sendmail: TRACEFLAGS,v 8.34 2001/04/25 00:16:04 ca Exp $ +# $Sendmail: TRACEFLAGS,v 8.35 2001/11/28 01:01:25 gshapiro Exp $ 0, 1 main.c main skip background fork 0, 4 main.c main canonical name, UUCP node name, a.k.a.s 0, 15 main.c main print configuration @@ -79,6 +79,9 @@ 66 srvrsmtp.c conformance checks 67 conf.c signals 69 queue.c scheduling +#if _FFR_QUARANTINE +70 queue.c quarantining +#endif /* _FFR_QUARANTINE */ 80 content length 81 sun remote mode 91 mci.c syslogging of MCI cache information diff --git a/gnu/usr.sbin/sendmail/sendmail/alias.c b/gnu/usr.sbin/sendmail/sendmail/alias.c index 7bf287b2479..15ac964f444 100644 --- a/gnu/usr.sbin/sendmail/sendmail/alias.c +++ b/gnu/usr.sbin/sendmail/sendmail/alias.c @@ -13,15 +13,15 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: alias.c,v 8.206 2001/09/11 04:05:11 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: alias.c,v 8.211 2001/11/12 22:52:18 ca Exp $") -# define SEPARATOR ':' +#define SEPARATOR ':' # define ALIAS_SPEC_SEPARATORS " ,/:" static MAP *AliasFileMap = NULL; /* the actual aliases.files map */ static int NAliasFileMaps; /* the number of entries in AliasFileMap */ -static char *aliaslookup __P((char *, int *)); +static char *aliaslookup __P((char *, int *, char *)); /* ** ALIAS -- Compute aliases. @@ -86,11 +86,12 @@ alias(a, sendq, aliaslevel, e) ** send spam of this type to owner- of the list ** ---- to stop spam from going to mailing lists! */ + if (e->e_sender != NULL && *e->e_sender == '\0') { /* Look for owner of alias */ (void) sm_strlcpyn(obuf, sizeof obuf, 2, "owner-", a->q_user); - if (aliaslookup(obuf, &status) != NULL) + if (aliaslookup(obuf, &status, a->q_host) != NULL) { if (LogLevel > 8) syslog(LOG_WARNING, @@ -101,7 +102,7 @@ alias(a, sendq, aliaslevel, e) } #endif /* _FFR_REDIRECTEMPTY */ - p = aliaslookup(a->q_user, &status); + p = aliaslookup(a->q_user, &status, a->q_host); if (status == EX_TEMPFAIL || status == EX_UNAVAILABLE) { a->q_state = QS_QUEUEUP; @@ -154,6 +155,7 @@ alias(a, sendq, aliaslevel, e) a->q_flags |= QGOODUID|QALIAS; (void) sendtolist(p, a, sendq, aliaslevel + 1, e); + if (bitset(QSELFREF, a->q_flags) && QS_IS_EXPANDED(a->q_state)) a->q_state = QS_OK; @@ -166,7 +168,7 @@ alias(a, sendq, aliaslevel, e) (void) sm_strlcpy(obuf, "owner-owner", sizeof obuf); else (void) sm_strlcpyn(obuf, sizeof obuf, 2, "owner-", a->q_user); - owner = aliaslookup(obuf, &status); + owner = aliaslookup(obuf, &status, a->q_host); if (owner == NULL) return; @@ -189,6 +191,7 @@ alias(a, sendq, aliaslevel, e) ** Parameters: ** name -- the name to look up. ** pstat -- a pointer to a place to put the status. +** av -- argument for %1 expansion. ** ** Returns: ** the value of name. @@ -202,11 +205,16 @@ alias(a, sendq, aliaslevel, e) */ static char * -aliaslookup(name, pstat) +aliaslookup(name, pstat, av) char *name; int *pstat; + char *av; { static MAP *map = NULL; +#if _FFR_ALIAS_DETAIL + int i; + char *argv[4]; +#endif /* _FFR_ALIAS_DETAIL */ if (map == NULL) { @@ -222,7 +230,19 @@ aliaslookup(name, pstat) if (sm_strcasecmp(name, "postmaster") == 0) name = "postmaster"; +#if _FFR_ALIAS_DETAIL + i = 0; + argv[i++] = name; + argv[i++] = av; + + /* XXX '+' is hardwired here as delimiter! */ + if (av != NULL && *av == '+') + argv[i++] = av + 1; + argv[i++] = NULL; + return (*map->map_class->map_lookup)(map, name, argv, pstat); +#else /* _FFR_ALIAS_DETAIL */ return (*map->map_class->map_lookup)(map, name, NULL, pstat); +#endif /* _FFR_ALIAS_DETAIL */ } /* ** SETALIAS -- set up an alias map @@ -386,13 +406,12 @@ aliaswait(map, ext, isopen) { auto int st; unsigned int sleeptime = 2; - int loopcount = 0; + unsigned int loopcount = 0; /* only used for debugging */ time_t toolong = curtime() + SafeAlias; while (isopen && map->map_class->map_lookup(map, "@", NULL, &st) == NULL) { - loopcount++; if (curtime() > toolong) { /* we timed out */ @@ -406,8 +425,11 @@ aliaswait(map, ext, isopen) */ if (tTd(27, 2)) - sm_dprintf("aliaswait: sleeping for %u seconds (loopcount = %d)\n", + { + loopcount++; + sm_dprintf("aliaswait: sleeping for %u seconds (loopcount = %u)\n", sleeptime, loopcount); + } map->map_mflags |= MF_CLOSING; map->map_class->map_close(map); @@ -577,9 +599,9 @@ rebuildaliases(map, automatic) /* restore the old signals */ (void) sm_signal(SIGINT, oldsigint); (void) sm_signal(SIGQUIT, oldsigquit); -# ifdef SIGTSTP +#ifdef SIGTSTP (void) sm_signal(SIGTSTP, oldsigtstp); -# endif /* SIGTSTP */ +#endif /* SIGTSTP */ return success; } /* diff --git a/gnu/usr.sbin/sendmail/sendmail/aliases b/gnu/usr.sbin/sendmail/sendmail/aliases index 34db4c64452..40ac500bc9b 100644 --- a/gnu/usr.sbin/sendmail/sendmail/aliases +++ b/gnu/usr.sbin/sendmail/sendmail/aliases @@ -1,33 +1,66 @@ # -# $Sendmail: aliases,v 8.2 2000/10/16 20:20:36 gshapiro Exp $ +# $Sendmail: aliases,v 8.4 2001/12/30 04:46:23 gshapiro Exp $ # @(#)aliases 8.2 (Berkeley) 3/5/94 # # Aliases in this file will NOT be expanded in the header from -# Mail, but WILL be visible over networks or from /bin/mail. +# Mail, but WILL be visible over networks. # # >>>>>>>>>> The program "newaliases" must be run after # >> NOTE >> this file is updated for any changes to # >>>>>>>>>> show through to sendmail. # +# +# See also RFC 2142, `MAILBOX NAMES FOR COMMON SERVICES, ROLES +# AND FUNCTIONS', May 1997 + +# Pretty much everything else in this file points to "root", so +# you should forward root's email to the system administrator. +# Delivering mail to root's mailbox or reading mail as root is +# inadvisable. -# Basic system aliases -- these MUST be present. +# Uncomment and *CHANGE* this! +# root: insert-human-being-here + +# Basic system aliases -- these MUST be present MAILER-DAEMON: postmaster postmaster: root -# General redirections for pseudo accounts. +# General redirections for pseudo accounts bin: root daemon: root games: root +mailnull: postmaster +smmsp: postmaster ingres: root nobody: root system: root toor: root uucp: root -# Well-known aliases. +# Well-known aliases manager: root dumper: root operator: root -# trap decode to catch security attacks +# RFC 2142: BUSINESS-RELATED MAILBOX NAMES +# info: root +# marketing: root +# sales: root +# support: root + +# RFC 2142: NETWORK OPERATIONS MAILBOX NAMES +abuse: root +noc: root +security: root + +# RFC 2142: SUPPORT MAILBOX NAMES FOR SPECIFIC INTERNET SERVICES +hostmaster: root +usenet: root +news: usenet +webmaster: root +www: webmaster +uucp: root +ftp: root + +# Trap decode to catch security attacks decode: root diff --git a/gnu/usr.sbin/sendmail/sendmail/bf.c b/gnu/usr.sbin/sendmail/sendmail/bf.c index 638b478fd7d..b24891b7187 100644 --- a/gnu/usr.sbin/sendmail/sendmail/bf.c +++ b/gnu/usr.sbin/sendmail/sendmail/bf.c @@ -18,7 +18,7 @@ */ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: bf.c,v 8.47 2001/09/11 04:05:12 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: bf.c,v 8.48 2001/11/04 17:10:49 ca Exp $") #include <sys/types.h> #include <sys/stat.h> @@ -548,7 +548,11 @@ sm_bfwrite(fp, buf, nbytes) ** write(). */ - if (!((errno == ENOSPC) || (errno == EDQUOT))) + if (!(errno == ENOSPC +#ifdef EDQUOT + || errno == EDQUOT +#endif /* EDQUOT */ + )) errno = EIO; return -1; diff --git a/gnu/usr.sbin/sendmail/sendmail/collect.c b/gnu/usr.sbin/sendmail/sendmail/collect.c index 91b7773185e..49efb537783 100644 --- a/gnu/usr.sbin/sendmail/sendmail/collect.c +++ b/gnu/usr.sbin/sendmail/sendmail/collect.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: collect.c,v 8.232 2001/09/11 04:05:12 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: collect.c,v 8.237 2001/12/10 19:56:03 ca Exp $") static void collecttimeout __P((time_t)); static void dferror __P((SM_FILE_T *volatile, char *, ENVELOPE *)); @@ -106,7 +106,7 @@ collect_doheader(e) /* collect statistics */ if (OpMode != MD_VERIFY) - markstats(e, (ADDRESS *) NULL, false); + markstats(e, (ADDRESS *) NULL, STATS_NORMAL); /* ** If we have a Return-Receipt-To:, turn it into a DSN. @@ -221,7 +221,7 @@ collect_dfopen(e) syserr("@Cannot create %s", dfname); e->e_flags |= EF_NO_BODY_RETN; flush_errors(true); - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } dfd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL); @@ -232,7 +232,6 @@ collect_dfopen(e) e->e_dfdev = stbuf.st_dev; e->e_dfino = stbuf.st_ino; } - e->e_msgsize = 0; e->e_flags |= EF_HAS_DF; return df; } @@ -361,6 +360,7 @@ collect(fp, smtpmode, hdrp, e) CollectTimeout = sm_setevent(dbto, collecttimeout, dbto); } + e->e_msgsize = 0; for (;;) { if (tTd(30, 35)) @@ -524,6 +524,17 @@ bufferchar: if (obuf != bufbuf) sm_free(obuf); /* XXX */ } + + /* + ** XXX Notice: the logic here is broken. + ** An input to sendmail that doesn't contain a + ** header but starts immediately with the body whose + ** first line contain characters which match the + ** following "if" will cause problems: those + ** characters will NOT appear in the output... + ** Do we care? + */ + if (c >= 0200 && c <= 0237) { #if 0 /* causes complaints -- figure out something for 8.n+1 */ @@ -687,7 +698,7 @@ readerr: { dferror(df, "sm_io_flush||sm_io_error", e); flush_errors(true); - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } else if (SuperSafe != SAFE_REALLY) @@ -718,21 +729,21 @@ readerr: errno = save_errno; dferror(df, "bfcommit", e); flush_errors(true); - finis(save_errno != EEXIST, ExitStat); + finis(save_errno != EEXIST, true, ExitStat); } else if ((afd = sm_io_getinfo(df, SM_IO_WHAT_FD, NULL)) >= 0 && fsync(afd) < 0) { dferror(df, "fsync", e); flush_errors(true); - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } else if (sm_io_close(df, SM_TIME_DEFAULT) < 0) { dferror(df, "sm_io_close", e); flush_errors(true); - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } else @@ -779,7 +790,7 @@ readerr: e->e_flags &= ~EF_FATALERRS; e->e_flags |= EF_CLRQUEUE; - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } @@ -834,7 +845,7 @@ readerr: { /* we haven't acked receipt yet, so just chuck this */ syserr("@Cannot reopen %s", dfname); - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } } diff --git a/gnu/usr.sbin/sendmail/sendmail/conf.c b/gnu/usr.sbin/sendmail/sendmail/conf.c index 7d0151adfaa..992336dd78d 100644 --- a/gnu/usr.sbin/sendmail/sendmail/conf.c +++ b/gnu/usr.sbin/sendmail/sendmail/conf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: conf.c,v 8.914 2001/09/23 03:05:34 ca Exp $") +SM_RCSID("@(#)$Sendmail: conf.c,v 8.939 2002/01/09 17:26:28 gshapiro Exp $") #include <sendmail/pathnames.h> @@ -667,7 +667,7 @@ inithostmaps() } # if NAMED_BIND else if (strcmp(maptype[i], "dns") == 0 && - stab("hosts.dns", ST_MAP, ST_FIND) == NULL) + stab("hosts.dns", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "hosts.dns dns A", sizeof buf); (void) makemapentry(buf); @@ -675,7 +675,7 @@ inithostmaps() # endif /* NAMED_BIND */ # if NISPLUS else if (strcmp(maptype[i], "nisplus") == 0 && - stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL) + stab("hosts.nisplus", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "hosts.nisplus nisplus -k name -v address hosts.org_dir", sizeof buf); @@ -684,7 +684,7 @@ inithostmaps() # endif /* NISPLUS */ # if NIS else if (strcmp(maptype[i], "nis") == 0 && - stab("hosts.nis", ST_MAP, ST_FIND) == NULL) + stab("hosts.nis", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "hosts.nis nis -k 0 -v 1 hosts.byname", sizeof buf); @@ -692,8 +692,8 @@ inithostmaps() } # endif /* NIS */ # if NETINFO - else if (strcmp(maptype[i], "netinfo") == 0) && - stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL) + else if (strcmp(maptype[i], "netinfo") == 0 && + stab("hosts.netinfo", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "hosts.netinfo netinfo -v name /machines", sizeof buf); @@ -729,12 +729,12 @@ inithostmaps() stab("aliases.files", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "aliases.files null", - sizeof buf); + sizeof buf); (void) makemapentry(buf); } #if NISPLUS else if (strcmp(maptype[i], "nisplus") == 0 && - stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) + stab("aliases.nisplus", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "aliases.nisplus nisplus -kalias -vexpansion mail_aliases.org_dir", sizeof buf); @@ -743,7 +743,7 @@ inithostmaps() #endif /* NISPLUS */ #if NIS else if (strcmp(maptype[i], "nis") == 0 && - stab("aliases.nis", ST_MAP, ST_FIND) == NULL) + stab("aliases.nis", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "aliases.nis nis mail.aliases", sizeof buf); @@ -752,7 +752,7 @@ inithostmaps() #endif /* NIS */ #if NETINFO else if (strcmp(maptype[i], "netinfo") == 0 && - stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL) + stab("aliases.netinfo", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "aliases.netinfo netinfo -z, /aliases", sizeof buf); @@ -761,7 +761,7 @@ inithostmaps() #endif /* NETINFO */ #if HESIOD else if (strcmp(maptype[i], "hesiod") == 0 && - stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL) + stab("aliases.hesiod", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "aliases.hesiod hesiod aliases", sizeof buf); @@ -809,8 +809,8 @@ inithostmaps() } # endif /* NIS */ # if HESIOD - else if (strcmp(maptype[i], "hesiod") == 0) && - stab("users.hesiod", ST_MAP, ST_FIND) == NULL) + else if (strcmp(maptype[i], "hesiod") == 0 && + stab("users.hesiod", ST_MAP, ST_FIND) == NULL) { (void) sm_strlcpy(buf, "users.hesiod hesiod", sizeof buf); (void) makemapentry(buf); @@ -848,6 +848,12 @@ inithostmaps() # define _USE_SUN_NSSWITCH_ #endif /* defined(SOLARIS) || (defined(sony_news) && defined(__svr4)) */ +#if _FFR_HPUX_NSSWITCH +# ifdef __hpux +# define _USE_SUN_NSSWITCH_ +# endif /* __hpux */ +#endif /* _FFR_HPUX_NSSWITCH */ + #ifdef _USE_SUN_NSSWITCH_ # include <nsswitch.h> #endif /* _USE_SUN_NSSWITCH_ */ @@ -1925,7 +1931,7 @@ getla() { sm_syslog(LOG_ERR, NOQID, "can't open %s: %s", - _PATH_AVENRUN, strerror(errno)); + _PATH_AVENRUN, sm_errstring(errno)); return -1; } } @@ -2535,37 +2541,19 @@ int waitfor(pid) pid_t pid; { -# ifdef WAITUNION - union wait st; -# else /* WAITUNION */ - auto int st; -# endif /* WAITUNION */ + int st; pid_t i; -# if defined(ISC_UNIX) || defined(_SCO_unix_) - int savesig; -# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ do { errno = 0; -# if defined(ISC_UNIX) || defined(_SCO_unix_) - savesig = sm_releasesignal(SIGCHLD); -# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ - i = wait(&st); -# if defined(ISC_UNIX) || defined(_SCO_unix_) - if (savesig > 0) - sm_blocksignal(SIGCHLD); -# endif /* defined(ISC_UNIX) || defined(_SCO_unix_) */ + i = sm_wait(&st); if (i > 0) - (void) proc_list_drop(i, NULL, NULL); + proc_list_drop(i, st, NULL); } while ((i >= 0 || errno == EINTR) && i != pid); if (i < 0) return -1; -# ifdef WAITUNION - return st.w_status; -# else /* WAITUNION */ return st; -# endif /* WAITUNION */ } /* ** SM_WAIT -- wait @@ -2630,7 +2618,6 @@ reapchild(sig) int sig; { int m = 0; - int pld, wgrp; int save_errno = errno; int st; pid_t pid; @@ -2667,22 +2654,7 @@ reapchild(sig) # endif /* WNOHANG */ # endif /* HASWAITPID */ /* Drop PID and check if it was a control socket child */ - pld = proc_list_drop(pid, &m, &wgrp); - if (pld == PROC_CONTROL && WIFEXITED(st)) - { - /* if so, see if we need to restart or shutdown */ - if (WEXITSTATUS(st) == EX_RESTART) - RestartRequest = "control socket"; - else if (WEXITSTATUS(st) == EX_SHUTDOWN) - ShutdownRequest = "control socket"; - } - if (pld == PROC_QUEUE_CHILD && !WIFSTOPPED(st) && wgrp > -1) - { - /* restart this persistent runner */ - mark_work_group_restart(wgrp, st); - } - else if (pld == PROC_NONE) - m = 0; + proc_list_drop(pid, st, NULL); CurRunners -= m; /* Update */ } FIX_SYSV_SIGNAL(sig, reapchild); @@ -3018,9 +2990,13 @@ getopt(nargc,nargv,ostr) static char *DefaultUserShells[] = { "/bin/sh", /* standard shell */ +# ifdef MPE + "/SYS/PUB/CI", +# else /* MPE */ "/usr/bin/sh", "/bin/csh", /* C shell */ "/usr/bin/csh", +# endif /* MPE */ # ifdef __hpux # ifdef V4FS "/usr/bin/rsh", /* restricted Bourne shell */ @@ -3217,7 +3193,13 @@ freediskspace(dir, bsize) char *dir; long *bsize; { -# if SFS_TYPE != SFS_NONE +# if SFS_TYPE == SFS_NONE + if (bsize != NULL) + *bsize = 4096L; + + /* assume free space is plentiful */ + return (long) LONG_MAX; +# else /* SFS_TYPE == SFS_NONE */ # if SFS_TYPE == SFS_USTAT struct ustat fs; struct stat statbuf; @@ -3269,8 +3251,8 @@ freediskspace(dir, bsize) else return (long) fs.SFS_BAVAIL; } -# endif /* SFS_TYPE != SFS_NONE */ return -1; +# endif /* SFS_TYPE == SFS_NONE */ } /* ** ENOUGHDISKSPACE -- is there enough free space on the queue file systems? @@ -3839,7 +3821,7 @@ vendor_daemon_setup(e) if (getluid() != -1) { usrerr("Daemon cannot have LUID"); - finis(false, EX_USAGE); + finis(false, true, EX_USAGE); } #endif /* SECUREWARE */ } @@ -4454,7 +4436,7 @@ secureware_setup_secure(uid) rc, (int) uid); break; } - finis(false, EX_NOPERM); + finis(false, true, EX_NOPERM); } } #endif /* SECUREWARE */ @@ -4605,21 +4587,51 @@ void load_if_names() { # if NETINET6 && defined(SIOCGLIFCONF) +# ifdef __hpux + + /* + ** Unfortunately, HP has changed all of the structures, + ** making life difficult for implementors. + */ + +# define lifconf if_laddrconf +# define lifc_len iflc_len +# define lifc_buf iflc_buf +# define lifreq if_laddrreq +# define lifr_addr iflr_addr +# define lifr_name iflr_name +# define lifr_flags iflr_flags +# define ss_family sa_family +# undef SIOCGLIFNUM +# endif /* __hpux */ + int s; int i; + size_t len; + int numifs; + char *buf; struct lifconf lifc; +# ifdef SIOCGLIFNUM struct lifnum lifn; - int numifs; +# endif /* SIOCGLIFNUM */ s = socket(InetMode, SOCK_DGRAM, 0); if (s == -1) return; /* get the list of known IP address from the kernel */ +# ifdef __hpux + i = ioctl(s, SIOCGIFNUM, (char *) &numifs); +# endif /* __hpux */ # ifdef SIOCGLIFNUM lifn.lifn_family = AF_UNSPEC; lifn.lifn_flags = 0; - if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) + i = ioctl(s, SIOCGLIFNUM, (char *)&lifn); + numifs = lifn.lifn_count; +# endif /* SIOCGLIFNUM */ + +# if defined(__hpux) || defined(SIOCGLIFNUM) + if (i < 0) { /* can't get number of interfaces -- fall back */ if (tTd(0, 4)) @@ -4627,14 +4639,10 @@ load_if_names() sm_errstring(errno)); numifs = -1; } - else - { - numifs = lifn.lifn_count; - if (tTd(0, 42)) - sm_dprintf("system has %d interfaces\n", numifs); - } + else if (tTd(0, 42)) + sm_dprintf("system has %d interfaces\n", numifs); if (numifs < 0) -# endif /* SIOCGLIFNUM */ +# endif /* defined(__hpux) || defined(SIOCGLIFNUM) */ numifs = MAXINTERFACES; if (numifs <= 0) @@ -4642,30 +4650,36 @@ load_if_names() (void) close(s); return; } - lifc.lifc_len = numifs * sizeof (struct lifreq); - lifc.lifc_buf = xalloc(lifc.lifc_len); + + len = lifc.lifc_len = numifs * sizeof (struct lifreq); + buf = lifc.lifc_buf = xalloc(lifc.lifc_len); +# ifndef __hpux lifc.lifc_family = AF_UNSPEC; lifc.lifc_flags = 0; +# endif /* __hpux */ if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) { if (tTd(0, 4)) sm_dprintf("SIOCGLIFCONF failed: %s\n", sm_errstring(errno)); (void) close(s); - sm_free(lifc.lifc_buf); + sm_free(buf); return; } /* scan the list of IP address */ if (tTd(0, 40)) - sm_dprintf("scanning for interface specific names, lifc_len=%d\n", - lifc.lifc_len); + sm_dprintf("scanning for interface specific names, lifc_len=%ld\n", + (long) len); - for (i = 0; i < lifc.lifc_len && i >= 0; ) + for (i = 0; i < len && i >= 0; ) { - struct lifreq *ifr = (struct lifreq *)&lifc.lifc_buf[i]; + int flags; + struct lifreq *ifr = (struct lifreq *)&buf[i]; SOCKADDR *sa = (SOCKADDR *) &ifr->lifr_addr; + int af = ifr->lifr_addr.ss_family; char *addr; + char *name; struct in6_addr ia6; struct in_addr ia; # ifdef SIOCGLIFFLAGS @@ -4673,7 +4687,6 @@ load_if_names() # endif /* SIOCGLIFFLAGS */ char ip_addr[256]; char buf6[INET6_ADDRSTRLEN]; - int af = ifr->lifr_addr.ss_family; /* ** We must close and recreate the socket each time @@ -4686,7 +4699,7 @@ load_if_names() s = socket(af, SOCK_DGRAM, 0); if (s == -1) { - sm_free(lifc.lifc_buf); /* XXX */ + sm_free(buf); /* XXX */ return; } @@ -4695,7 +4708,7 @@ load_if_names() ** don't try to use it. */ - if ((lifc.lifc_len - i) < sizeof *ifr) + if ((len - i) < sizeof *ifr) break; # ifdef BSD4_4_SOCKADDR @@ -4714,7 +4727,7 @@ load_if_names() # ifdef SIOCGLIFFLAGS memset(&ifrf, '\0', sizeof(struct lifreq)); (void) sm_strlcpy(ifrf.lifr_name, ifr->lifr_name, - sizeof(ifrf.lifr_name)); + sizeof(ifrf.lifr_name)); if (ioctl(s, SIOCGLIFFLAGS, (char *) &ifrf) < 0) { if (tTd(0, 4)) @@ -4722,11 +4735,14 @@ load_if_names() sm_errstring(errno)); continue; } - else if (tTd(0, 41)) - sm_dprintf("\tflags: %lx\n", - (unsigned long) ifrf.lifr_flags); - if (!bitset(IFF_UP, ifrf.lifr_flags)) + name = ifr->lifr_name; + flags = ifrf.lifr_flags; + + if (tTd(0, 41)) + sm_dprintf("\tflags: %lx\n", (unsigned long) flags); + + if (!bitset(IFF_UP, flags)) continue; # endif /* SIOCGLIFFLAGS */ @@ -4755,8 +4771,7 @@ load_if_names() { addr = anynet_ntop(&ia6, buf6, sizeof buf6); message("WARNING: interface %s is UP with %s address", - ifr->lifr_name, - addr == NULL ? "(NULL)" : addr); + name, addr == NULL ? "(NULL)" : addr); continue; } @@ -4775,7 +4790,7 @@ load_if_names() ia.s_addr == INADDR_NONE) { message("WARNING: interface %s is UP with %s address", - ifr->lifr_name, inet_ntoa(ia)); + name, inet_ntoa(ia)); continue; } @@ -4798,12 +4813,12 @@ load_if_names() # ifdef SIOCGLIFFLAGS /* skip "loopback" interface "lo" */ if (DontProbeInterfaces == DPI_SKIPLOOPBACK && - bitset(IFF_LOOPBACK, ifrf.lifr_flags)) + bitset(IFF_LOOPBACK, flags)) continue; # endif /* SIOCGLIFFLAGS */ (void) add_hostnames(sa); } - sm_free(lifc.lifc_buf); /* XXX */ + sm_free(buf); /* XXX */ (void) close(s); # else /* NETINET6 && defined(SIOCGLIFCONF) */ # if defined(SIOCGIFCONF) && !SIOCGIFCONF_IS_BROKEN @@ -5335,6 +5350,112 @@ local_hostname_length(hostname) } #endif /* NEEDLOCAL_HOSTNAME_LENGTH */ +#if NEEDLINK +/* +** LINK -- clone a file +** +** Some OS's lacks link() and hard links. Since sendmail is using +** link() as an efficient way to clone files, this implementation +** will simply do a file copy. +** +** NOTE: This link() replacement is not a generic replacement as it +** does not handle all of the semantics of the real link(2). +** +** Parameters: +** source -- pathname of existing file. +** target -- pathname of link (clone) to be created. +** +** Returns: +** 0 -- success. +** -1 -- failure, see errno for details. +*/ + +int +link(source, target) + const char *source; + const char *target; +{ + int save_errno; + int sff; + int src = -1, dst = -1; + ssize_t readlen; + ssize_t writelen; + char buf[BUFSIZ]; + struct stat st; + + sff = SFF_REGONLY|SFF_OPENASROOT; + if (DontLockReadFiles) + sff |= SFF_NOLOCK; + + /* Open the original file */ + src = safeopen((char *)source, O_RDONLY, 0, sff); + if (src < 0) + goto fail; + + /* Obtain the size and the mode */ + if (fstat(src, &st) < 0) + goto fail; + + /* Create the duplicate copy */ + sff &= ~SFF_NOLOCK; + sff |= SFF_CREAT; + dst = safeopen((char *)target, O_CREAT|O_EXCL|O_WRONLY, + st.st_mode, sff); + if (dst < 0) + goto fail; + + /* Copy all of the bytes one buffer at a time */ + while ((readlen = read(src, &buf, sizeof(buf))) > 0) + { + ssize_t left = readlen; + char *p = buf; + + while (left > 0 && + (writelen = write(dst, p, (size_t) left)) >= 0) + { + left -= writelen; + p += writelen; + } + if (writeln < 0) + break; + } + + /* Any trouble reading? */ + if (readlen < 0 || writelen < 0) + goto fail; + + /* Close the input file */ + if (close(src) < 0) + { + src = -1; + goto fail; + } + src = -1; + + /* Close the output file */ + if (close(dst) < 0) + { + /* don't set dst = -1 here so we unlink the file */ + goto fail; + } + + /* Success */ + return 0; + + fail: + save_errno = errno; + if (src >= 0) + (void) close(src); + if (dst >= 0) + { + (void) unlink(target); + (void) close(dst); + } + errno = save_errno; + return -1; +} +#endif /* NEEDLINK */ + /* ** Compile-Time options */ @@ -5515,9 +5636,15 @@ char *OsCompileOptions[] = #if HASLSTAT "HASLSTAT", #endif /* HASLSTAT */ +#if HASNICE + "HASNICE", +#endif /* HASNICE */ #if HASRANDOM "HASRANDOM", #endif /* HASRANDOM */ +#if HASRRESVPORT + "HASRRESVPORT", +#endif /* HASRRESVPORT */ #if HASSETEGID "HASSETEGID", #endif /* HASSETEGID */ @@ -5581,6 +5708,9 @@ char *OsCompileOptions[] = #if NEEDFSYNC "NEEDFSYNC", #endif /* NEEDFSYNC */ +#if NEEDLINK + "NEEDLINK", +#endif /* NEEDLINK */ #if NEEDLOCAL_HOSTNAME_LENGTH "NEEDLOCAL_HOSTNAME_LENGTH", #endif /* NEEDLOCAL_HOSTNAME_LENGTH */ @@ -5632,6 +5762,12 @@ char *OsCompileOptions[] = #if SYSTEM5 "SYSTEM5", #endif /* SYSTEM5 */ +#if USE_DOUBLE_FORK + "USE_DOUBLE_FORK", +#endif /* USE_DOUBLE_FORK */ +#if USE_ENVIRON + "USE_ENVIRON", +#endif /* USE_ENVIRON */ #if USE_SA_SIGACTION "USE_SA_SIGACTION", #endif /* USE_SA_SIGACTION */ @@ -5672,6 +5808,7 @@ char *FFRCompileOptions[] = "_FFR_BESTMX_BETTER_TRUNCATION", #endif /* _FFR_BESTMX_BETTER_TRUNCATION */ #if _FFR_CACHE_LPC +/* Christophe Wolfhugel of France Telecom Oleane */ "_FFR_CACHE_LPC", #endif /* _FFR_CACHE_LPC */ #if _FFR_CATCH_BROKEN_MTAS @@ -5701,6 +5838,12 @@ char *FFRCompileOptions[] = #if _FFR_DONTLOCKFILESFORREAD_OPTION "_FFR_DONTLOCKFILESFORREAD_OPTION", #endif /* _FFR_DONTLOCKFILESFORREAD_OPTION */ +#if _FFR_DOTTED_USERNAMES + "_FFR_DOTTED_USERNAMES", +#endif /* _FFR_DOTTED_USERNAMES */ +#if _FFR_DROP_TRUSTUSER_WARNING + "_FFR_DROP_TRUSTUSER_WARNING", +#endif /* _FFR_DROP_TRUSTUSER_WARNING */ #if _FFR_FIX_DASHT "_FFR_FIX_DASHT", #endif /* _FFR_FIX_DASHT */ @@ -5716,10 +5859,17 @@ char *FFRCompileOptions[] = #if _FFR_HDR_TYPE "_FFR_HDR_TYPE", #endif /* _FFR_HDR_TYPE */ +#if _FFR_HPUX_NSSWITCH + "_FFR_HPUX_NSSWITCH", +#endif /* _FFR_HPUX_NSSWITCH */ #if _FFR_IGNORE_EXT_ON_HELO "_FFR_IGNORE_EXT_ON_HELO", #endif /* _FFR_IGNORE_EXT_ON_HELO */ +#if _FFR_LDAP_RECURSION + "_FFR_LDAP_RECURSION", +#endif /* _FFR_LDAP_RECURSION */ #if _FFR_MAX_FORWARD_ENTRIES +/* Randall S. Winchester of the University of Maryland */ "_FFR_MAX_FORWARD_ENTRIES", #endif /* _FFR_MAX_FORWARD_ENTRIES */ #if MILTER @@ -5728,6 +5878,7 @@ char *FFRCompileOptions[] = # endif /* _FFR_MILTER_PERDAEMON */ #endif /* MILTER */ #if _FFR_NODELAYDSN_ON_HOLD +/* Steven Pitzl */ "_FFR_NODELAYDSN_ON_HOLD", #endif /* _FFR_NODELAYDSN_ON_HOLD */ #if _FFR_NO_PIPE @@ -5754,9 +5905,6 @@ char *FFRCompileOptions[] = #if _FFR_RHS "_FFR_RHS", #endif /* _FFR_RHS */ -#if _FFR_SAVE_CHARSET - "_FFR_SAVE_CHARSET", -#endif /* _FFR_SAVE_CHARSET */ #if _FFR_SHM_STATUS "_FFR_SHM_STATUS", #endif /* _FFR_SHM_STATUS */ @@ -5772,6 +5920,9 @@ char *FFRCompileOptions[] = #if _FFR_TLS_1 "_FFR_TLS_1", #endif /* _FFR_TLS_1 */ +#if _FFR_TRUSTED_QF + "_FFR_TRUSTED_QF", +#endif /* _FFR_TRUSTED_QF */ NULL }; diff --git a/gnu/usr.sbin/sendmail/sendmail/conf.h b/gnu/usr.sbin/sendmail/sendmail/conf.h index 4b2027ae272..7af5913ef27 100644 --- a/gnu/usr.sbin/sendmail/sendmail/conf.h +++ b/gnu/usr.sbin/sendmail/sendmail/conf.h @@ -10,7 +10,7 @@ * the sendmail distribution. * * - * $Sendmail: conf.h,v 8.556 2001/09/21 23:01:46 ca Exp $ + * $Sendmail: conf.h,v 8.557 2001/10/05 03:49:41 ca Exp $ */ /* @@ -70,7 +70,6 @@ struct rusage; /* forward declaration to get gcc to shut up in wait.h */ #define MAXKEY 128 /* maximum size of a database key */ #define MEMCHUNKSIZE 1024 /* chunk size for memory allocation */ #define MAXUSERENVIRON 100 /* max envars saved, must be >= 3 */ -#define MAXALIASDB 12 /* max # of alias databases */ #define MAXMAPSTACK 12 /* max # of stacked or sequenced maps */ #if MILTER # define MAXFILTERS 25 /* max # of milter filters */ diff --git a/gnu/usr.sbin/sendmail/sendmail/control.c b/gnu/usr.sbin/sendmail/sendmail/control.c index e71bd917269..43ee851809d 100644 --- a/gnu/usr.sbin/sendmail/sendmail/control.c +++ b/gnu/usr.sbin/sendmail/sendmail/control.c @@ -10,7 +10,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: control.c,v 8.115 2001/09/21 22:20:40 ca Exp $") +SM_RCSID("@(#)$Sendmail: control.c,v 8.116 2001/12/13 21:51:38 gshapiro Exp $") /* values for cmd_code */ #define CMDERROR 0 /* bad command */ @@ -369,7 +369,9 @@ control_command(sock, e) ** precision (if bsize == 512) */ - free = (long)((double) free * ((double) bsize / 1024)); + if (free > 0) + free = (long)((double) free * + ((double) bsize / 1024)); (void) sm_io_fprintf(s, SM_TIME_DEFAULT, "%d/%d/%ld/%d\r\n", diff --git a/gnu/usr.sbin/sendmail/sendmail/daemon.c b/gnu/usr.sbin/sendmail/sendmail/daemon.c index d137c878bf6..80a88505ee0 100644 --- a/gnu/usr.sbin/sendmail/sendmail/daemon.c +++ b/gnu/usr.sbin/sendmail/sendmail/daemon.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: daemon.c,v 8.595 2001/09/25 05:03:54 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: daemon.c,v 8.603 2001/12/31 19:46:38 gshapiro Exp $") #if defined(SOCK_STREAM) || defined(__GNU_LIBRARY__) # define USE_SOCK_STREAM 1 @@ -191,7 +191,7 @@ getrequests(e) "daemon could not open control socket %s: %s", ControlSocketName, sm_errstring(errno)); - /* If there are any queue runners releated reapchild() co-ord's */ + /* If there are any queue runners released reapchild() co-ord's */ (void) sm_signal(SIGCHLD, reapchild); /* write the pid to file, command line args to syslog */ @@ -698,6 +698,9 @@ getrequests(e) { proc_list_clear(); + /* clean up background delivery children */ + (void) sm_signal(SIGCHLD, reapchild); + /* Add parent process as first child item */ proc_list_add(CurrentPid, "daemon child", PROC_DAEMON_CHILD, 0, -1); @@ -771,7 +774,7 @@ getrequests(e) { syserr("cannot open SMTP server channel, fd=%d", t); - finis(false, EX_OK); + finis(false, true, EX_OK); } sm_io_automode(inchannel, outchannel); @@ -783,7 +786,7 @@ getrequests(e) if (!xla_host_ok(RealHostName)) { message("421 4.4.5 Too many SMTP sessions for this host"); - finis(false, EX_OK); + finis(false, true, EX_OK); } #endif /* XLA */ /* find out name for interface of connection */ @@ -1017,7 +1020,8 @@ opendaemonsocket(d, firsttime) if (d->d_addr.sa.sa_family == AF_UNIX) { int rval; - long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK; + long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK|SFF_CREAT; + /* if not safe, don't use it */ rval = safefile(d->d_addr.sunix.sun_path, RunAsUid, RunAsGid, @@ -1502,15 +1506,7 @@ setsockaddroptions(p, d) break; } - /* if not safe, don't use it */ - if (safefile(addr, RunAsUid, RunAsGid, - RunAsUserName, - SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_ROOTOK|SFF_EXECOK, - S_IRUSR|S_IWUSR, NULL) != 0) - { - syserr("setsockaddroptions: unsafe domain socket"); - break; - } + /* file safety check done in opendaemonsocket() */ (void) memset(&d->d_addr.sunix.sun_path, '\0', sizeof(d->d_addr.sunix.sun_path)); (void) sm_strlcpy((char *)&d->d_addr.sunix.sun_path, @@ -1554,8 +1550,7 @@ setsockaddroptions(p, d) #if NETINET6 case AF_INET6: - if (!isascii(*addr) || !isxdigit(*addr) || - anynet_pton(AF_INET6, addr, + if (anynet_pton(AF_INET6, addr, &d->d_addr.sin6.sin6_addr) != 1) { register struct hostent *hp; @@ -2360,6 +2355,7 @@ gothostent: /* save for logging */ CurHostAddr = addr; +#if HASRRESVPORT if (bitnset(M_SECURE_PORT, mci->mci_mailer->m_flags)) { int rport = IPPORT_RESERVED - 1; @@ -2367,6 +2363,7 @@ gothostent: s = rresvport(&rport); } else +#endif /* HASRRESVPORT */ { s = socket(addr.sa.sa_family, SOCK_STREAM, 0); } @@ -2824,6 +2821,7 @@ makeconnection_ds(mux_path, mci) void shutdown_daemon() { + int i; char *reason; sm_allsignals(true); @@ -2842,7 +2840,42 @@ shutdown_daemon() xla_all_end(); #endif /* XLA */ - finis(false, EX_OK); + for (i = 0; i < NDaemons; i++) + { + if (Daemons[i].d_socket >= 0) + { + (void) close(Daemons[i].d_socket); + Daemons[i].d_socket = -1; + +#if _FFR_DAEMON_NETUNIX +# if NETUNIX + /* Remove named sockets */ + if (Daemons[i].d_addr.sa.sa_family == AF_UNIX) + { + int rval; + long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_MUSTOWN|SFF_EXECOK|SFF_CREAT; + + /* if not safe, don't use it */ + rval = safefile(Daemons[i].d_addr.sunix.sun_path, + RunAsUid, RunAsGid, + RunAsUserName, sff, + S_IRUSR|S_IWUSR, NULL); + if (rval == 0 && + unlink(Daemons[i].d_addr.sunix.sun_path) < 0) + { + sm_syslog(LOG_WARNING, NOQID, + "Could not remove daemon %s socket: %s: %s", + Daemons[i].d_name, + Daemons[i].d_addr.sunix.sun_path, + sm_errstring(errno)); + } + } +# endif /* NETUNIX */ +#endif /* _FFR_DAEMON_NETUNIX */ + } + } + + finis(false, true, EX_OK); } /* ** RESTART_DAEMON -- Performs a clean restart of the daemon @@ -2889,7 +2922,7 @@ restart_daemon() if (LogLevel > 3) sm_syslog(LOG_INFO, NOQID, "could not restart: need full path"); - finis(false, EX_OSFILE); + finis(false, true, EX_OSFILE); /* NOTREACHED */ } if (LogLevel > 3) @@ -2915,7 +2948,7 @@ restart_daemon() sm_syslog(LOG_ALERT, NOQID, "could not drop privileges: %s", sm_errstring(errno)); - finis(false, EX_OSERR); + finis(false, true, EX_OSERR); /* NOTREACHED */ } @@ -2967,7 +3000,7 @@ restart_daemon() if (LogLevel > 0) sm_syslog(LOG_ALERT, NOQID, "could not exec %s: %s", SaveArgv[0], sm_errstring(errno)); - finis(false, EX_OSFILE); + finis(false, true, EX_OSFILE); /* NOTREACHED */ } /* diff --git a/gnu/usr.sbin/sendmail/sendmail/deliver.c b/gnu/usr.sbin/sendmail/sendmail/deliver.c index 1fecda16ced..b1d33f6ad15 100644 --- a/gnu/usr.sbin/sendmail/sendmail/deliver.c +++ b/gnu/usr.sbin/sendmail/sendmail/deliver.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -14,7 +14,7 @@ #include <sendmail.h> #include <sys/time.h> -SM_RCSID("@(#)$Sendmail: deliver.c,v 8.907 2001/09/18 21:45:33 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: deliver.c,v 8.928 2002/01/10 03:23:29 gshapiro Exp $") #if HASSETUSERCONTEXT # include <login_cap.h> @@ -88,7 +88,7 @@ sendall(e, mode) logundelrcpts(e, "discarded", 9, true); else if (LogLevel > 4) sm_syslog(LOG_INFO, e->e_id, "discarded"); - markstats(e, NULL, true); + markstats(e, NULL, STATS_REJECT); return; } @@ -303,9 +303,10 @@ sendall(e, mode) if (FallBackMX != NULL && !wordinclass(FallBackMX, 'w') && mode != SM_VERIFY && + !bitnset(M_NOMX, m->m_flags) && strcmp(m->m_mailer, "[IPC]") == 0 && m->m_argv[0] != NULL && - strcmp(m->m_argv[0], "TCP")) + strcmp(m->m_argv[0], "TCP") == 0) { int len; char *p; @@ -355,12 +356,12 @@ sendall(e, mode) expensive = true; } #if _FFR_QUARANTINE - else if (QueueMode != QM_HELD && - e->e_holdmsg != NULL) + else if (QueueMode != QM_QUARANTINE && + e->e_quarmsg != NULL) { if (tTd(13, 30)) sm_dprintf(" ... quarantine: %s\n", - e->e_holdmsg); + e->e_quarmsg); q->q_state = QS_QUEUEUP; expensive = true; } @@ -413,6 +414,11 @@ sendall(e, mode) ee->e_errormode = EM_MAIL; ee->e_sibling = splitenv; ee->e_statmsg = NULL; +#if _FFR_QUARANTINE + if (e->e_quarmsg != NULL) + ee->e_quarmsg = sm_rpool_strdup_x(ee->e_rpool, + e->e_quarmsg); +#endif /* _FFR_QUARANTINE */ splitenv = ee; for (q = e->e_sendqueue; q != NULL; q = q->q_next) @@ -661,8 +667,10 @@ sendall(e, mode) /* make sure the parent doesn't own the envelope */ e->e_id = NULL; +#if USE_DOUBLE_FORK /* catch intermediate zombie */ (void) waitfor(pid); +#endif /* USE_DOUBLE_FORK */ return; } @@ -688,11 +696,13 @@ sendall(e, mode) (void) sm_signal(SIGTERM, SIG_DFL); +#if USE_DOUBLE_FORK /* double fork to avoid zombies */ pid = fork(); if (pid > 0) exit(EX_OK); save_errno = errno; +#endif /* USE_DOUBLE_FORK */ CurrentPid = getpid(); @@ -710,7 +720,7 @@ sendall(e, mode) #else /* HASFLOCK */ e->e_id = NULL; #endif /* HASFLOCK */ - finis(true, ExitStat); + finis(true, true, ExitStat); } /* be sure to give error messages in child */ @@ -746,7 +756,7 @@ sendall(e, mode) } (void) dowork(e->e_qgrp, e->e_qdir, e->e_id, false, false, e); - finis(true, ExitStat); + finis(true, true, ExitStat); #endif /* HASFLOCK */ } @@ -764,7 +774,7 @@ sendall(e, mode) Verbose = oldverbose; if (mode == SM_FORK) - finis(true, ExitStat); + finis(true, true, ExitStat); } static void @@ -837,7 +847,13 @@ sendenvelope(e, mode) oldsib = e->e_sibling; e->e_sibling = NULL; - (void) split_by_recipient(e); + if (!split_by_recipient(e) && + bitset(EF_FATALERRS, e->e_flags)) + { + if (OpMode == MD_SMTP || OpMode == MD_DAEMON) + e->e_flags |= EF_CLRQUEUE; + return; + } for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) queueup(ee, false, true); @@ -1250,6 +1266,9 @@ deliver(e, firstto) bool anyok; /* at least one address was OK */ SM_NONVOLATILE bool goodmxfound = false; /* at least one MX was OK */ bool ovr; +#if _FFR_QUARANTINE + bool quarantine; +#endif /* _FFR_QUARANTINE */ int strsize; int rcptcount; int ret; @@ -1319,7 +1338,10 @@ deliver(e, firstto) if (strlen(rpath) > MAXSHORTSTR) { rpath = shortenstring(rpath, MAXSHORTSTR); - syserr("remotename: huge return %s", rpath); + + /* avoid bogus errno */ + errno = 0; + syserr("remotename: huge return path %s", rpath); } rpath = sm_rpool_strdup_x(e->e_rpool, rpath); macdefine(&e->e_macro, A_PERM, 'g', rpath); @@ -1514,6 +1536,9 @@ deliver(e, firstto) ovr = true; /* do config file checking of compatibility */ +#if _FFR_QUARANTINE + quarantine = (e->e_quarmsg != NULL); +#endif /* _FFR_QUARANTINE */ rcode = rscheck("check_compat", e->e_from.q_paddr, to->q_paddr, e, true, true, 3, NULL, e->e_id); if (rcode == EX_OK) @@ -1532,6 +1557,20 @@ deliver(e, firstto) NULL, ctladdr, xstart, e, to); continue; } +#if _FFR_QUARANTINE + if (!quarantine && e->e_quarmsg != NULL) + { + /* + ** check_compat or checkcompat() has tried + ** to quarantine but that isn't supported. + ** Revert the attempt. + */ + + e->e_quarmsg = NULL; + macdefine(&e->e_macro, A_PERM, + macid("{quarantine}"), ""); + } +#endif /* _FFR_QUARANTINE */ if (bitset(EF_DISCARD, e->e_flags)) { if (tTd(10, 5)) @@ -1625,7 +1664,7 @@ deliver(e, firstto) } } to->q_statdate = curtime(); - markstats(e, to, false); + markstats(e, to, STATS_NORMAL); continue; } @@ -2260,6 +2299,8 @@ tryhost: struct stat stb; extern int DtableSize; + CurrentPid = getpid(); + /* clear the events to turn off SIGALRMs */ sm_clear_events(); @@ -2268,7 +2309,6 @@ tryhost: RestartWorkGroup = false; ShutdownRequest = NULL; PendingSignal = 0; - CurrentPid = getpid(); if (e->e_lockfp != NULL) (void) close(sm_io_getinfo(e->e_lockfp, @@ -2308,9 +2348,11 @@ tryhost: } # endif /* HASSETUSERCONTEXT */ +#if HASNICE /* tweak niceness */ if (m->m_nice != 0) (void) nice(m->m_nice); +#endif /* HASNICE */ /* reset group id */ if (bitnset(M_SPECIFIC_UID, m->m_flags)) @@ -2386,7 +2428,9 @@ tryhost: new_gid != getegid()) { /* Only root can change the gid */ - syserr("openmailer: insufficient privileges to change gid"); + syserr("openmailer: insufficient privileges to change gid, RunAsUid=%d, new_gid=%d, gid=%d, egid=%d", + (int) RunAsUid, (int) new_gid, + (int) getgid(), (int) getegid()); exit(EX_TEMPFAIL); } @@ -2462,7 +2506,8 @@ tryhost: if (RunAsUid != 0 && new_euid != RunAsUid) { /* Only root can change the uid */ - syserr("openmailer: insufficient privileges to change uid"); + syserr("openmailer: insufficient privileges to change uid, new_euid=%d, RunAsUid=%d", + (int) new_euid, (int) RunAsUid); exit(EX_TEMPFAIL); } @@ -3057,6 +3102,37 @@ do_transfer: mci_dump(mci, false); } +#if _FFR_CLIENT_SIZE + /* + ** See if we know the maximum size and + ** abort if the message is too big. + ** + ** NOTE: _FFR_CLIENT_SIZE is untested. + */ + + if (bitset(MCIF_SIZE, mci->mci_flags) && + mci->mci_maxsize > 0 && + e->e_msgsize > mci->mci_maxsize) + { + e->e_flags |= EF_NO_BODY_RETN; + if (bitnset(M_LOCALMAILER, m->m_flags)) + e->e_status = "5.2.3"; + else + e->e_status = "5.3.4"; + + usrerrenh(e->e_status, + "552 Message is too large; %ld bytes max", + mci->mci_maxsize); + rcode = EX_DATAERR; + + /* Need an e_message for error */ + (void) sm_snprintf(SmtpError, sizeof SmtpError, + "Message is too large; %ld bytes max", + mci->mci_maxsize); + goto give_up; + } +#endif /* _FFR_CLIENT_SIZE */ + if (mci->mci_state != MCIS_OPEN) { /* couldn't open the mailer */ @@ -3140,8 +3216,6 @@ do_transfer: e->e_id); if (i != EX_OK) { - /* avoid bogus error msg */ - errno = 0; markfailure(e, to, mci, i, false); giveresponse(i, to->q_status, m, mci, ctladdr, xstart, e, to); @@ -3156,7 +3230,8 @@ do_transfer: i = smtprcpt(to, m, mci, e, ctladdr, xstart); # if PIPELINING - if (bitset(MCIF_PIPELINED, mci->mci_flags)) + if (i == EX_OK && + bitset(MCIF_PIPELINED, mci->mci_flags)) { /* ** Add new element to list of @@ -3359,6 +3434,13 @@ do_transfer: if (tobuf[0] != '\0') { giveresponse(rcode, NULL, m, mci, ctladdr, xstart, e, tochain); +#if 0 + /* + ** This code is disabled for now because I am not + ** sure that copying status from the first recipient + ** to all non-status'ed recipients is a good idea. + */ + if (tochain->q_message != NULL && !bitnset(M_LMTP, m->m_flags) && rcode != EX_OK) { @@ -3372,9 +3454,10 @@ do_transfer: tochain->q_message); } } +#endif /* 0 */ } if (anyok) - markstats(e, tochain, false); + markstats(e, tochain, STATS_NORMAL); mci_store_persistent(mci); /* Some recipients were tempfailed, try them on the next host */ @@ -3451,6 +3534,7 @@ markfailure(e, q, mci, rcode, ovr) int rcode; bool ovr; { + int save_errno = errno; char *status = NULL; char *rstatus = NULL; @@ -3551,6 +3635,9 @@ markfailure(e, q, mci, rcode, ovr) if (CurHostName != NULL && CurHostName[0] != '\0' && mci != NULL && !bitset(M_LOCALMAILER, mci->mci_flags)) q->q_statmta = sm_rpool_strdup_x(e->e_rpool, CurHostName); + + /* restore errno */ + errno = save_errno; } /* ** ENDMAILER -- Wait for mailer to terminate. @@ -4035,6 +4122,15 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) anynet_ntoa(&CurHostAddr)); } } +#if _FFR_QUARANTINE + else if (strcmp(status, "quarantined") == 0) + { + if (e->e_quarmsg != NULL) + (void) sm_snprintf(bp, SPACELEFT(buf, bp), + ", quarantine=%s", + shortenstring(e->e_quarmsg, 40)); + } +#endif /* _FFR_QUARANTINE */ else if (strcmp(status, "queued") != 0) { p = macvalue('h', e); @@ -4173,6 +4269,15 @@ logdelivery(m, mci, dsn, status, ctladdr, xstart, e) " [%.100s]", anynet_ntoa(&CurHostAddr)); } +#if _FFR_QUARANTINE + else if (strcmp(status, "quarantined") == 0) + { + if (e->e_quarmsg != NULL) + (void) sm_snprintf(bp, SPACELEFT(buf, bp), + ", quarantine=%.100s", + e->e_quarmsg); + } +#endif /* _FFR_QUARANTINE */ else if (strcmp(status, "queued") != 0) { p = macvalue('h', e); @@ -4873,6 +4978,7 @@ mailfile(filename, mailer, ctladdr, sfflags, e) e->e_status = "5.6.3"; usrerrenh(e->e_status, "554 Cannot send 8-bit data to 7-bit destination"); + errno = 0; return EX_DATAERR; } @@ -5024,7 +5130,8 @@ mailfile(filename, mailer, ctladdr, sfflags, e) if (RunAsUid != 0 && RealUid != RunAsUid) { /* Only root can change the uid */ - syserr("mailfile: insufficient privileges to change uid"); + syserr("mailfile: insufficient privileges to change uid, RunAsUid=%d, RealUid=%d", + (int) RunAsUid, (int) RealUid); RETURN(EX_TEMPFAIL); } } @@ -5061,7 +5168,9 @@ mailfile(filename, mailer, ctladdr, sfflags, e) RealGid != getegid())) { /* Only root can change the gid */ - syserr("mailfile: insufficient privileges to change gid"); + syserr("mailfile: insufficient privileges to change gid, RealGid=%d, RunAsUid=%d, gid=%d, egid=%d", + (int) RealGid, (int) RunAsUid, + (int) getgid(), (int) getegid()); RETURN(EX_TEMPFAIL); } } @@ -5333,7 +5442,10 @@ mailfile(filename, mailer, ctladdr, sfflags, e) return EX_SOFTWARE; } if (WIFEXITED(st)) + { + errno = 0; return (WEXITSTATUS(st)); + } else { syserr("mailfile: %s: child died on signal %d", @@ -5407,7 +5519,8 @@ hostsignature(m, host) */ if (bitnset(M_LOCALMAILER, m->m_flags) && - strcmp(m->m_mailer, "[IPC]") != 0) + strcmp(m->m_mailer, "[IPC]") != 0 && + !(m->m_argv[0] != NULL && strcmp(m->m_argv[0], "TCP") == 0)) return "localhost"; /* diff --git a/gnu/usr.sbin/sendmail/sendmail/domain.c b/gnu/usr.sbin/sendmail/sendmail/domain.c index c69a838060d..5425d7c01a9 100644 --- a/gnu/usr.sbin/sendmail/sendmail/domain.c +++ b/gnu/usr.sbin/sendmail/sendmail/domain.c @@ -14,9 +14,9 @@ #include <sendmail.h> #if NAMED_BIND -SM_RCSID("@(#)$Sendmail: domain.c,v 8.176 2001/09/22 17:52:42 gshapiro Exp $ (with name server)") +SM_RCSID("@(#)$Sendmail: domain.c,v 8.177 2001/12/12 01:16:15 ca Exp $ (with name server)") #else /* NAMED_BIND */ -SM_RCSID("@(#)$Sendmail: domain.c,v 8.176 2001/09/22 17:52:42 gshapiro Exp $ (without name server)") +SM_RCSID("@(#)$Sendmail: domain.c,v 8.177 2001/12/12 01:16:15 ca Exp $ (without name server)") #endif /* NAMED_BIND */ #if NAMED_BIND @@ -307,7 +307,7 @@ getmxrr(host, mxhosts, mxprefs, droplocalhost, rcode, tryfallback, pttl) break; default: - syserr("getmxrr: res_search (%s) failed with impossible h_errno (%d)\n", + syserr("getmxrr: res_search (%s) failed with impossible h_errno (%d)", host, h_errno); *rcode = EX_OSERR; break; diff --git a/gnu/usr.sbin/sendmail/sendmail/envelope.c b/gnu/usr.sbin/sendmail/sendmail/envelope.c index 3f0c79a3e63..db014d1705b 100644 --- a/gnu/usr.sbin/sendmail/sendmail/envelope.c +++ b/gnu/usr.sbin/sendmail/sendmail/envelope.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: envelope.c,v 8.274 2001/09/17 20:39:57 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: envelope.c,v 8.279 2001/12/10 19:56:04 ca Exp $") /* ** NEWENVELOPE -- fill in a new envelope @@ -67,18 +67,18 @@ newenvelope(e, parent, rpool) { e->e_msgpriority = parent->e_msgsize; #if _FFR_QUARANTINE - if (parent->e_holdmsg == NULL) + if (parent->e_quarmsg == NULL) { - e->e_holdmsg = NULL; + e->e_quarmsg = NULL; macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), ""); + macid("{quarantine}"), ""); } else { - e->e_holdmsg = sm_rpool_strdup_x(rpool, - parent->e_holdmsg); + e->e_quarmsg = sm_rpool_strdup_x(rpool, + parent->e_quarmsg); macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), e->e_holdmsg); + macid("{quarantine}"), e->e_quarmsg); } #endif /* _FFR_QUARANTINE */ } @@ -125,7 +125,7 @@ dropenvelope(e, fulldrop, split) bool fulldrop; bool split; { - bool savedf = false; + bool panic = false; bool queueit = false; int msg_timeout = 0; bool failure_return = false; @@ -423,7 +423,7 @@ dropenvelope(e, fulldrop, split) { if (tTd(50, 8)) sm_dprintf("dropenvelope(%s): saving mail\n", id); - savedf = savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); + panic = savemail(e, !bitset(EF_NO_BODY_RETN, e->e_flags)); } /* @@ -470,12 +470,24 @@ simpledrop: e->e_id, queueit); printenvflags(e); } - if (!savedf) + if (!panic) (void) xunlink(queuename(e, DATAFL_LETTER)); +#if _FFR_QUARANTINE + if (panic && QueueMode == QM_LOST) + { + /* + ** leave the Qf file behind as + ** the delivery attempt failed. + */ + + /* EMPTY */ + } + else +#endif /* _FFR_QUARANTINE */ if (xunlink(queuename(e, ANYQFL_LETTER)) == 0) { /* add to available space in filesystem */ - updfs(e, true, !savedf); + updfs(e, true, !panic); } if (e->e_ntries > 0 && LogLevel > 9) @@ -501,7 +513,13 @@ simpledrop: oldsib = e->e_sibling; e->e_sibling = NULL; - (void) split_by_recipient(e); + if (!split_by_recipient(e) && + bitset(EF_FATALERRS, e->e_flags)) + { + syserr("!dropenvelope(%s): cannot commit data file %s, uid=%d", + e->e_id, queuename(e, DATAFL_LETTER), + geteuid()); + } for (ee = e->e_sibling; ee != NULL; ee = ee->e_sibling) queueup(ee, false, true); queueup(e, false, true); @@ -604,9 +622,8 @@ clearenvelope(e, fullclear, rpool) e->e_message = NULL; #if _FFR_QUARANTINE e->e_qfletter = '\0'; - e->e_holdmsg = NULL; - macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), ""); + e->e_quarmsg = NULL; + macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); #endif /* _FFR_QUARANTINE */ /* @@ -1088,7 +1105,7 @@ setsender(from, e, delimptr, delimchar, internal) sm_syslog(LOG_NOTICE, e->e_id, "cannot prescan from (%s)", shortenstring(from, MAXSHORTSTR)); - finis(true, ExitStat); + finis(true, true, ExitStat); } (void) REWRITE(pvp, 3, e); (void) REWRITE(pvp, 1, e); @@ -1177,6 +1194,8 @@ static struct eflags EnvelopeFlags[] = { "DONT_MIME", EF_DONT_MIME }, { "DISCARD", EF_DISCARD }, { "TOOBIG", EF_TOOBIG }, + { "SPLIT", EF_SPLIT }, + { "UNSAFE", EF_UNSAFE }, { NULL, 0 } }; diff --git a/gnu/usr.sbin/sendmail/sendmail/err.c b/gnu/usr.sbin/sendmail/sendmail/err.c index c5409e59402..03481609341 100644 --- a/gnu/usr.sbin/sendmail/sendmail/err.c +++ b/gnu/usr.sbin/sendmail/sendmail/err.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: err.c,v 8.187 2001/09/11 04:05:14 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: err.c,v 8.189 2002/01/09 18:52:30 ca Exp $") #if LDAPMAP # include <lber.h> @@ -981,6 +981,10 @@ sm_errstring(errnum) char *dnsmsg; char *bp; static char buf[MAXLINE]; +#if HASSTRERROR + char *err; + char errbuf[30]; +#endif /* HASSTRERROR */ #if !HASSTRERROR && !defined(ERRLIST_PREDEFINED) extern char *sys_errlist[]; extern int sys_nerr; @@ -999,7 +1003,14 @@ sm_errstring(errnum) case ECONNRESET: bp = buf; #if HASSTRERROR - (void) sm_strlcpy(bp, strerror(errnum), SPACELEFT(buf, bp)); + err = strerror(errnum); + if (err == NULL) + { + (void) sm_snprintf(errbuf, sizeof errbuf, + "Error %d", errnum); + err = errbuf; + } + (void) sm_strlcpy(bp, err, SPACELEFT(buf, bp)); #else /* HASSTRERROR */ if (errnum >= 0 && errnum < sys_nerr) (void) sm_strlcpy(bp, sys_errlist[errnum], @@ -1133,7 +1144,13 @@ sm_errstring(errnum) #endif /* LDAPMAP */ #if HASSTRERROR - return strerror(errnum); + err = strerror(errnum); + if (err == NULL) + { + (void) sm_snprintf(buf, sizeof buf, "Error %d", errnum); + return buf; + } + return err; #else /* HASSTRERROR */ if (errnum > 0 && errnum < sys_nerr) return sys_errlist[errnum]; diff --git a/gnu/usr.sbin/sendmail/sendmail/headers.c b/gnu/usr.sbin/sendmail/sendmail/headers.c index ab8334b974c..7f24fdd003a 100644 --- a/gnu/usr.sbin/sendmail/sendmail/headers.c +++ b/gnu/usr.sbin/sendmail/sendmail/headers.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: headers.c,v 8.265 2001/09/11 04:05:14 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: headers.c,v 8.266 2001/10/12 01:50:12 gshapiro Exp $") static size_t fix_mime_header __P((char *)); static int priencode __P((char *)); @@ -698,8 +698,8 @@ eatheader(e, full, log) int saveflags = e->e_flags; #endif /* 0 */ - (void) sendtolist(h->h_value, NULLADDR, - &e->e_sendqueue, 0, e); + (void) sendtolist(denlstring(h->h_value, true, false), + NULLADDR, &e->e_sendqueue, 0, e); #if 0 /* diff --git a/gnu/usr.sbin/sendmail/sendmail/main.c b/gnu/usr.sbin/sendmail/sendmail/main.c index 59f40350bc2..511a1e8426d 100644 --- a/gnu/usr.sbin/sendmail/sendmail/main.c +++ b/gnu/usr.sbin/sendmail/sendmail/main.c @@ -25,7 +25,7 @@ SM_UNUSED(static char copyright[]) = The Regents of the University of California. All rights reserved.\n"; #endif /* ! lint */ -SM_RCSID("@(#)$Sendmail: main.c,v 8.831 2001/09/25 22:25:58 ca Exp $") +SM_RCSID("@(#)$Sendmail: main.c,v 8.868 2001/12/29 04:54:38 ca Exp $") #if NETINET || NETINET6 @@ -158,7 +158,8 @@ main(argc, argv, envp) register int i; int j; int dp; - int save_errno; + int fill_errno; + int qgrp = NOQGRP; /* queue group to process */ bool safecf = true; BITMAP256 *p_flags = NULL; /* daemon flags */ bool warn_C_flag = false; @@ -172,11 +173,15 @@ main(argc, argv, envp) char *authinfo = NULL; char *sysloglabel = NULL; /* label for syslog */ char *conffile = NULL; /* name of .cf file */ - char *runqueuegroup = NULL; /* queue group to process */ + char *queuegroup = NULL; /* queue group to process */ +#if _FFR_QUARANTINE + char *quarantining = NULL; /* quarantine queue items? */ +#endif /* _FFR_QUARANTINE */ bool extraprivs; bool forged, negate; bool queuepersistent = false; /* queue runner process runs forever */ bool foregroundqueue = false; /* queue run in foreground */ + bool save_val; /* to save some bool var. */ int cftype; /* which cf file to use? */ static time_t starttime = 0; /* when was process started */ struct stat traf_st; /* for TrafficLog FIFO check */ @@ -198,6 +203,10 @@ main(argc, argv, envp) extern void sm_sasl_init __P((void)); #endif /* SASL */ +#if USE_ENVIRON + envp = environ; +#endif /* USE_ENVIRON */ + /* turn off profiling */ SM_PROF(0); @@ -227,22 +236,11 @@ main(argc, argv, envp) extraprivs = (RealUid != 0 && (geteuid() != getuid() || getegid() != getgid())); - /* - ** Seed the random number generator. - ** Used for queue file names, picking a queue directory, and - ** MX randomization. - */ - - seed_random(); - - /* do machine-dependent initializations */ - init_md(argc, argv); CurrentPid = getpid(); /* get whatever .cf file is right for the opmode */ cftype = SM_GET_RIGHT_CF; - /* in 4.4BSD, the table can be huge; impose a reasonable limit */ DtableSize = getdtsize(); if (DtableSize > 256) @@ -253,17 +251,17 @@ main(argc, argv, envp) ** But also be sure that 0, 1, & 2 are open. */ - /* reset errno and save_errno; the latter is used down below */ - errno = save_errno = 0; + /* reset errno and fill_errno; the latter is used way down below */ + errno = fill_errno = 0; fill_fd(STDIN_FILENO, NULL); if (errno != 0) - save_errno = errno; + fill_errno = errno; fill_fd(STDOUT_FILENO, NULL); if (errno != 0) - save_errno = errno; + fill_errno = errno; fill_fd(STDERR_FILENO, NULL); if (errno != 0) - save_errno = errno; + fill_errno = errno; i = DtableSize; while (--i > 0) @@ -285,48 +283,19 @@ main(argc, argv, envp) # endif /* LOG_MAIL */ #endif /* LOG */ - SyslogPrefixLen = PIDLEN + (MAXQFNAME - 3) + SL_FUDGE + SLDLL; - if (MissingFds != 0) - { - bool err = false; - char mbuf[MAXLINE]; + /* + ** Seed the random number generator. + ** Used for queue file names, picking a queue directory, and + ** MX randomization. + */ - mbuf[0] = '\0'; - if (bitset(1 << STDIN_FILENO, MissingFds)) - { - err = true; - (void) sm_strlcat(mbuf, ", stdin", sizeof mbuf); - } - if (bitset(1 << STDOUT_FILENO, MissingFds)) - { - err = true; - (void) sm_strlcat(mbuf, ", stdout", sizeof mbuf); - } - if (bitset(1 << STDERR_FILENO, MissingFds)) - (void) sm_strlcat(mbuf, ", stderr", sizeof mbuf); + seed_random(); - /* - ** hack for syserr(), otherwise nothing is logged because - ** LogLevel is set later on (setdefaults()). - ** XXX should this really be syserr()? - ** For example, arpwatch closes std{in,out,err} as daemon - ** and only reassigns stdin to the file it wants to mail. - ** This causes "bogus" syserrors and dumpfd output without - ** any explanation why this happened. - */ + /* do machine-dependent initializations */ + init_md(argc, argv); - errno = save_errno; - if (err) - { - LogLevel = 1; - syserr("File descriptors missing on startup: %s", - &mbuf[2]); - } - else - sm_syslog(LOG_WARNING, NOQID, - "File descriptors missing on startup: %s", - &mbuf[2]); - } + + SyslogPrefixLen = PIDLEN + (MAXQFNAME - 3) + SL_FUDGE + SLDLL; /* reset status from syserr() calls for missing file descriptors */ Errors = 0; @@ -357,8 +326,7 @@ main(argc, argv, envp) #ifdef SIGUSR1 /* Only allow root (or non-set-*-ID binaries) to use SIGUSR1 */ - if (getuid() == 0 || - (getuid() == geteuid() && getgid() == getegid())) + if (extraprivs) { /* arrange to dump state on user-1 signal */ (void) sm_signal(SIGUSR1, sigusr1); @@ -393,15 +361,28 @@ main(argc, argv, envp) else if (strcmp(p, "purgestat") == 0) OpMode = MD_PURGESTAT; -#if defined(__osf__) || defined(_AIX3) -# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:x" -#endif /* defined(__osf__) || defined(_AIX3) */ -#if defined(sony_news) -# define OPTIONS "A:B:b:C:cd:E:e:F:f:Gh:IiJ:L:M:mN:nO:o:p:q:R:r:sTtV:vX:" -#endif /* defined(sony_news) */ -#ifndef OPTIONS -# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:" -#endif /* ! OPTIONS */ +#if _FFR_QUARANTINE +# if defined(__osf__) || defined(_AIX3) +# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:xQ:" +# endif /* defined(__osf__) || defined(_AIX3) */ +# if defined(sony_news) +# define OPTIONS "A:B:b:C:cd:E:e:F:f:Gh:IiJ:L:M:mN:nO:o:p:q:R:r:sTtV:vX:Q:" +# endif /* defined(sony_news) */ +# ifndef OPTIONS +# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:Q:" +# endif /* ! OPTIONS */ +#else /* _FFR_QUARANTINE */ +# if defined(__osf__) || defined(_AIX3) +# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:x" +# endif /* defined(__osf__) || defined(_AIX3) */ +# if defined(sony_news) +# define OPTIONS "A:B:b:C:cd:E:e:F:f:Gh:IiJ:L:M:mN:nO:o:p:q:R:r:sTtV:vX:" +# endif /* defined(sony_news) */ +# ifndef OPTIONS +# define OPTIONS "A:B:b:C:cd:e:F:f:Gh:IiL:M:mN:nO:o:p:q:R:r:sTtV:vX:" +# endif /* ! OPTIONS */ +#endif /* _FFR_QUARANTINE */ + opterr = 0; while ((j = getopt(argc, argv, OPTIONS)) != -1) { @@ -426,14 +407,15 @@ main(argc, argv, envp) break; case MD_FREEZE: - usrerr("Frozen configurations unsupported"); - ExitStat = EX_USAGE; - break; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Frozen configurations unsupported\n"); + return EX_USAGE; default: - usrerr("Invalid operation mode %c", j); - ExitStat = EX_USAGE; - break; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Invalid operation mode %c\n", + j); + return EX_USAGE; } break; @@ -457,6 +439,9 @@ main(argc, argv, envp) SL_FUDGE + j; break; +#if _FFR_QUARANTINE + case 'Q': +#endif /* _FFR_QUARANTINE */ case 'q': /* just check if it is there */ queuerun = true; @@ -523,7 +508,7 @@ main(argc, argv, envp) if (tTd(0, 101)) { sm_dprintf("Version %s\n", Version); - finis(false, EX_OK); + finis(false, true, EX_OK); /* NOTREACHED */ } @@ -811,7 +796,7 @@ main(argc, argv, envp) QueueLimitSender = (QUEUE_CHAR *) NULL; QueueLimitId = (QUEUE_CHAR *) NULL; #if _FFR_QUARANTINE - QueueLimitReason = (QUEUE_CHAR *) NULL; + QueueLimitQuarantine = (QUEUE_CHAR *) NULL; #endif /* _FFR_QUARANTINE */ /* @@ -956,6 +941,26 @@ main(argc, argv, envp) } break; +#if _FFR_QUARANTINE + case 'Q': /* change quarantining on queued items */ + /* sanity check */ + if (OpMode != MD_DELIVER && + OpMode != MD_QUEUERUN) + { + usrerr("Can not use -Q with -b%c", OpMode); + ExitStat = EX_USAGE; + break; + } + + if (OpMode == MD_DELIVER) + set_op_mode(MD_QUEUERUN); + + FullName = NULL; + + quarantining = newstr(optarg); + break; +#endif /* _FFR_QUARANTINE */ + case 'q': /* run queue files at intervals */ /* sanity check */ if (OpMode != MD_DELIVER && @@ -991,7 +996,13 @@ main(argc, argv, envp) ExitStat = EX_USAGE; break; } - runqueuegroup = newstr(&optarg[1]); + if (queuegroup != NULL) + { + usrerr("Can not use multiple -qG options"); + ExitStat = EX_USAGE; + break; + } + queuegroup = newstr(&optarg[1]); break; case 'I': /* Limit by ID */ @@ -1023,16 +1034,16 @@ main(argc, argv, envp) break; #if _FFR_QUARANTINE - case 'H': /* Limit by recipient */ + case 'Q': /* Limit by quarantine message */ if (optarg[1] != '\0') { new = (QUEUE_CHAR *) xalloc(sizeof *new); new->queue_match = newstr(&optarg[1]); new->queue_negate = negate; - new->queue_next = QueueLimitReason; - QueueLimitReason = new; + new->queue_next = QueueLimitQuarantine; + QueueLimitQuarantine = new; } - QueueMode = QM_HELD; + QueueMode = QM_QUARANTINE; break; case 'L': /* act on lost items */ @@ -1160,7 +1171,7 @@ main(argc, argv, envp) #endif /* defined(sony_news) */ default: - finis(true, EX_USAGE); + finis(true, true, EX_USAGE); /* NOTREACHED */ break; } @@ -1170,7 +1181,7 @@ main(argc, argv, envp) if ((ExitStat != EX_OK && OpMode != MD_TEST) || ExitStat == EX_OSERR) { - finis(false, ExitStat); + finis(false, true, ExitStat); /* NOTREACHED */ } @@ -1204,6 +1215,25 @@ main(argc, argv, envp) #endif /* !defined(_USE_SUN_NSSWITCH_) && !defined(_USE_DEC_SVC_CONF_) */ vendor_post_defaults(&BlankEnvelope); + /* now we can complain about missing fds */ + if (MissingFds != 0 && LogLevel > 8) + { + char mbuf[MAXLINE]; + + mbuf[0] = '\0'; + if (bitset(1 << STDIN_FILENO, MissingFds)) + (void) sm_strlcat(mbuf, ", stdin", sizeof mbuf); + if (bitset(1 << STDOUT_FILENO, MissingFds)) + (void) sm_strlcat(mbuf, ", stdout", sizeof mbuf); + if (bitset(1 << STDERR_FILENO, MissingFds)) + (void) sm_strlcat(mbuf, ", stderr", sizeof mbuf); + + /* Notice: fill_errno is from high above: fill_fd() */ + sm_syslog(LOG_WARNING, NOQID, + "File descriptors missing on startup: %s; %s", + &mbuf[2], sm_errstring(fill_errno)); + } + /* Remove the ability for a normal user to send signals */ if (RealUid != 0 && RealUid != geteuid()) { @@ -1225,7 +1255,7 @@ main(argc, argv, envp) { syserr("main: setreuid(%d, %d) failed", (int) new_uid, (int) geteuid()); - finis(false, EX_OSERR); + finis(false, true, EX_OSERR); /* NOTREACHED */ } if (tTd(47, 10)) @@ -1242,7 +1272,7 @@ main(argc, argv, envp) if (setuid(new_uid) < 0) { syserr("main: setuid(%d) failed", (int) new_uid); - finis(false, EX_OSERR); + finis(false, true, EX_OSERR); /* NOTREACHED */ } if (tTd(47, 10)) @@ -1265,12 +1295,12 @@ main(argc, argv, envp) if (UseMSP && (OpMode == MD_DAEMON || OpMode == MD_FGDAEMON)) { usrerr("Mail submission program cannot be used as daemon"); - finis(false, EX_USAGE); + finis(false, true, EX_USAGE); } - if (OpMode == MD_DELIVER || OpMode == MD_SMTP || OpMode == MD_ARPAFTP || - OpMode == MD_DAEMON || OpMode == MD_FGDAEMON || - OpMode == MD_QUEUERUN) + if (OpMode == MD_DELIVER || OpMode == MD_SMTP || + OpMode == MD_QUEUERUN || OpMode == MD_ARPAFTP || + OpMode == MD_DAEMON || OpMode == MD_FGDAEMON) makeworkgroups(); /* set up the basic signal handlers */ @@ -1305,7 +1335,7 @@ main(argc, argv, envp) dp = drop_privileges(true); if (dp != EX_OK) { - finis(false, dp); + finis(false, true, dp); /* NOTREACHED */ } } @@ -1317,7 +1347,7 @@ main(argc, argv, envp) if (dp == EX_OK && UseMSP && (geteuid() == 0 || getuid() == 0)) { usrerr("Mail submission program must have RunAsUser set to non root user"); - finis(false, EX_CONFIG); + finis(false, true, EX_CONFIG); /* NOTREACHED */ } } @@ -1351,8 +1381,7 @@ main(argc, argv, envp) { /* Now we know which .cf file we use */ sm_dprintf(" Conf file:\t%s (selected)\n", - getcfname(OpMode, SubmitMode, SM_GET_RIGHT_CF, - conffile)); + getcfname(OpMode, SubmitMode, cftype, conffile)); sm_dprintf(" Pid file:\t%s (selected)\n", PidFile); } @@ -1389,15 +1418,13 @@ main(argc, argv, envp) /* check body type for legality */ i = check_bodytype(BlankEnvelope.e_bodytype); - if (i == BODYTYPE_NONE) - /* EMPTY */ - /* nothing */ ; - else if (i == BODYTYPE_ILLEGAL) + if (i == BODYTYPE_ILLEGAL) { usrerr("Illegal body type %s", BlankEnvelope.e_bodytype); BlankEnvelope.e_bodytype = NULL; } - else SevenBitInput = (i == BODYTYPE_7BIT); + else if (i != BODYTYPE_NONE) + SevenBitInput = (i == BODYTYPE_7BIT); /* tweak default DSN notifications */ if (DefaultNotify == 0) @@ -1439,6 +1466,11 @@ main(argc, argv, envp) switch (OpMode) { case MD_QUEUERUN: +#if _FFR_QUARANTINE + if (quarantining != NULL) + action = "quarantine jobs"; + else +#endif /* _FFR_QUARANTINE */ /* Normal users can do a single queue run */ if (QueueIntvl == 0) break; @@ -1466,8 +1498,9 @@ main(argc, argv, envp) sm_syslog(LOG_ALERT, NOQID, "user %d attempted to %s", (int) RealUid, action); + HoldErrs = false; usrerr("Permission denied (real uid not trusted)"); - finis(false, EX_USAGE); + finis(false, true, EX_USAGE); /* NOTREACHED */ break; @@ -1498,7 +1531,7 @@ main(argc, argv, envp) sm_dprintf("Failed to drop privs for user %d attempt to expand, exiting\n", (int) RealUid); CurEnv->e_id = NULL; - finis(true, dp); + finis(true, true, dp); /* NOTREACHED */ } } @@ -1522,15 +1555,17 @@ main(argc, argv, envp) sm_syslog(LOG_ALERT, NOQID, "user %d attempted to rebuild the alias map", (int) RealUid); + HoldErrs = false; usrerr("Permission denied (real uid not trusted)"); - finis(false, EX_USAGE); + finis(false, true, EX_USAGE); /* NOTREACHED */ } if (UseMSP) { + HoldErrs = false; usrerr("User %d cannot rebuild aliases in mail submission program", (int) RealUid); - finis(false, EX_USAGE); + finis(false, true, EX_USAGE); /* NOTREACHED */ } /* FALLTHROUGH */ @@ -1824,9 +1859,9 @@ main(argc, argv, envp) if (HostStatDir != NULL && !path_is_dir(HostStatDir, false)) { /* cannot use this value */ - if (tTd(0, 2)) - sm_dprintf("Cannot use HostStatusDirectory = %s: %s\n", - HostStatDir, sm_errstring(errno)); + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Warning: Cannot use HostStatusDirectory = %s: %s\n", + HostStatDir, sm_errstring(errno)); HostStatDir = NULL; } @@ -1841,8 +1876,9 @@ main(argc, argv, envp) if (stbuf.st_uid != RealUid) { /* nope, really a botch */ + HoldErrs = false; usrerr("You do not have permission to process the queue"); - finis(false, EX_NOPERM); + finis(false, true, EX_NOPERM); /* NOTREACHED */ } } @@ -1858,10 +1894,23 @@ main(argc, argv, envp) } #endif /* MILTER */ + /* Convert queuegroup string to qgrp number */ + if (queuegroup != NULL) + { + qgrp = name2qid(queuegroup); + if (qgrp == NOQGRP) + { + HoldErrs = false; + usrerr("Queue group %s unknown", queuegroup); + finis(false, true, ExitStat); + /* NOTREACHED */ + } + } + /* if we've had errors so far, exit now */ if (ExitStat != EX_OK && OpMode != MD_TEST) { - finis(false, ExitStat); + finis(false, true, ExitStat); /* NOTREACHED */ } @@ -1882,10 +1931,25 @@ main(argc, argv, envp) { case MD_PRINT: /* print the queue */ + HoldErrs = false; dropenvelope(&BlankEnvelope, true, false); (void) sm_signal(SIGPIPE, sigpipe); + if (qgrp != NOQGRP) + { + int j; + + /* Selecting a particular queue group to run */ + for (j = 0; j < Queue[qgrp]->qg_numqueues; j++) + { + if (StopRequest) + stop_sendmail(); + (void) print_single_queue(qgrp, j); + } + finis(false, true, EX_OK); + /* NOTREACHED */ + } printqueue(); - finis(false, EX_OK); + finis(false, true, EX_OK); /* NOTREACHED */ break; @@ -1894,27 +1958,47 @@ main(argc, argv, envp) dropenvelope(&BlankEnvelope, true, false); (void) sm_signal(SIGPIPE, sigpipe); printnqe(smioout, NULL); - finis(false, EX_OK); + finis(false, true, EX_OK); /* NOTREACHED */ break; +#if _FFR_QUARANTINE + case MD_QUEUERUN: + /* only handle quarantining here */ + if (quarantining == NULL) + break; + + if (QueueMode != QM_QUARANTINE && + QueueMode != QM_NORMAL) + { + HoldErrs = false; + usrerr("Can not use -Q with -q%c", QueueMode); + ExitStat = EX_USAGE; + finis(false, true, ExitStat); + /* NOTREACHED */ + } + quarantine_queue(quarantining, qgrp); + finis(false, true, EX_OK); + break; +#endif /* _FFR_QUARANTINE */ + case MD_HOSTSTAT: (void) sm_signal(SIGPIPE, sigpipe); (void) mci_traverse_persistent(mci_print_persistent, NULL); - finis(false, EX_OK); + finis(false, true, EX_OK); /* NOTREACHED */ break; case MD_PURGESTAT: (void) mci_traverse_persistent(mci_purge_persistent, NULL); - finis(false, EX_OK); + finis(false, true, EX_OK); /* NOTREACHED */ break; case MD_INITALIAS: /* initialize maps */ initmaps(); - finis(false, ExitStat); + finis(false, true, ExitStat); /* NOTREACHED */ break; @@ -1971,11 +2055,14 @@ main(argc, argv, envp) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "Enter <ruleset> <address>\n"); } + macdefine(&(MainEnvelope.e_macro), A_PERM, + macid("{addr_type}"), "e r"); for (;;) { SM_TRY { (void) sm_signal(SIGINT, intindebug); + (void) sm_releasesignal(SIGINT); if (Verbose == 2) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, @@ -2047,7 +2134,6 @@ main(argc, argv, envp) if (OpMode == MD_QUEUERUN && QueueIntvl == 0) { - int qgrp = NOQGRP; pid_t pid = -1; #if STARTTLS @@ -2055,19 +2141,6 @@ main(argc, argv, envp) (void) initclttls(tls_ok); #endif /* STARTTLS */ - if (runqueuegroup != NULL) - { - /* Selecting a particular queue group to run */ - qgrp = name2qid(runqueuegroup); - if (qgrp == NOQGRP) - { - usrerr("Queue group %s unknown", - runqueuegroup); - finis(true, ExitStat); - /* NOTREACHED */ - } - } - /* ** The parent process of the caller of runqueue() needs ** to stay around for a possible SIGTERM. The SIGTERM will @@ -2130,10 +2203,10 @@ main(argc, argv, envp) if (WIFSTOPPED(status)) continue; - (void) proc_list_drop(ret, NULL, NULL); + proc_list_drop(ret, status, NULL); } } - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } @@ -2148,6 +2221,15 @@ main(argc, argv, envp) } # endif /* SASL */ + if (OpMode == MD_SMTP) + { + proc_list_add(CurrentPid, "Sendmail SMTP Agent", + PROC_DAEMON, 0, -1); + + /* clean up background delivery children */ + (void) sm_signal(SIGCHLD, reapchild); + } + /* ** If a daemon, wait for a request. ** getrequests will always return in a child. @@ -2169,7 +2251,7 @@ main(argc, argv, envp) syserr("daemon: cannot fork"); if (i != 0) { - finis(false, EX_OK); + finis(false, true, EX_OK); /* NOTREACHED */ } @@ -2264,8 +2346,7 @@ main(argc, argv, envp) continue; /* Probe only on a child status */ - (void) proc_list_drop(ret, NULL, - &group); + proc_list_drop(ret, status, &group); if (WIFSIGNALED(status)) { @@ -2276,6 +2357,7 @@ main(argc, argv, envp) group, WTERMSIG(status)); /* don't restart this one */ + mark_work_group_restart(group, -1); continue; } @@ -2296,13 +2378,10 @@ main(argc, argv, envp) sm_syslog(LOG_DEBUG, NOQID, "persistent queue runner=%d, exited", group); - continue; + mark_work_group_restart(group, -1); } - - /* restart this persistent runner */ - mark_work_group_restart(group, status); } - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } @@ -2528,7 +2607,7 @@ main(argc, argv, envp) /* collect body for UUCP return */ if (OpMode != MD_VERIFY) collect(InChannel, false, NULL, &MainEnvelope); - finis(true, EX_USAGE); + finis(true, true, EX_USAGE); /* NOTREACHED */ } @@ -2536,7 +2615,10 @@ main(argc, argv, envp) ** Scan argv and deliver the message to everyone. */ + save_val = LogUsrErrs; + LogUsrErrs = true; sendtoargv(av, &MainEnvelope); + LogUsrErrs = save_val; /* if we have had errors sofar, arrange a meaningful exit stat */ if (Errors > 0 && ExitStat == EX_OK) @@ -2564,9 +2646,22 @@ main(argc, argv, envp) MainEnvelope.e_to = NULL; if (OpMode != MD_VERIFY || GrabTo) { - int savederrors = Errors; - long savedflags = MainEnvelope.e_flags & EF_FATALERRS; + int savederrors; + unsigned long savedflags; + /* + ** workaround for compiler warning on Irix: + ** do not initialize variable in the definition, but + ** later on: + ** warning(1548): transfer of control bypasses + ** initialization of: + ** variable "savederrors" (declared at line 2570) + ** variable "savedflags" (declared at line 2571) + ** goto giveup; + */ + + savederrors = Errors; + savedflags = MainEnvelope.e_flags & EF_FATALERRS; MainEnvelope.e_flags |= EF_GLOBALERRS; MainEnvelope.e_flags &= ~EF_FATALERRS; Errors = 0; @@ -2576,6 +2671,7 @@ main(argc, argv, envp) /* header checks failed */ if (Errors > 0) { + giveup: if (!GrabTo) { /* Log who the mail would have gone to */ @@ -2584,7 +2680,7 @@ main(argc, argv, envp) 8, false); } flush_errors(true); - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ return -1; } @@ -2592,7 +2688,8 @@ main(argc, argv, envp) /* bail out if message too large */ if (bitset(EF_CLRQUEUE, MainEnvelope.e_flags)) { - finis(true, ExitStat != EX_OK ? ExitStat : EX_DATAERR); + finis(true, true, ExitStat != EX_OK ? ExitStat + : EX_DATAERR); /* NOTREACHED */ return -1; } @@ -2605,13 +2702,23 @@ main(argc, argv, envp) sm_dprintf("From person = \"%s\"\n", MainEnvelope.e_from.q_paddr); +#if _FFR_QUARANTINE + /* Check if quarantining stats should be updated */ + if (MainEnvelope.e_quarmsg != NULL) + markstats(&MainEnvelope, NULL, STATS_QUARANTINE); +#endif /* _FFR_QUARANTINE */ + /* ** Actually send everything. ** If verifying, just ack. */ if (Errors == 0) - split_by_recipient(&MainEnvelope); + { + if (!split_by_recipient(&MainEnvelope) && + bitset(EF_FATALERRS, MainEnvelope.e_flags)) + goto giveup; + } /* make sure we deliver at least the first envelope */ i = FastSplit > 0 ? 0 : -1; @@ -2645,7 +2752,7 @@ main(argc, argv, envp) ** Don't send return error message if in VERIFY mode. */ - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ return ExitStat; } @@ -2675,6 +2782,7 @@ stop_sendmail() ** ** Parameters: ** drop -- whether or not to drop CurEnv envelope +** cleanup -- call exit() or _exit()? ** exitstat -- exit status to use for exit() call ** ** Returns: @@ -2685,8 +2793,9 @@ stop_sendmail() */ void -finis(drop, exitstat) +finis(drop, cleanup, exitstat) bool drop; + bool cleanup; volatile int exitstat; { /* Still want to process new timeouts added below */ @@ -2772,7 +2881,10 @@ finis(drop, exitstat) #endif /* SM_HEAP_CHECK */ if (sm_debug_active(&SmXtrapReport, 1)) sm_dprintf("xtrap count = %d\n", SmXtrapCount); - exit(exitstat); + if (cleanup) + exit(exitstat); + else + _exit(exitstat); SM_END_TRY } /* @@ -2974,7 +3086,7 @@ intsig(sig) unlockqueue(CurEnv); } - finis(drop, EX_OK); + finis(drop, false, EX_OK); /* NOTREACHED */ } /* @@ -3113,6 +3225,18 @@ obsolete(argv) if (ap[0] != '-' || ap[1] == '-') return; +#if _FFR_QUARANTINE + /* Don't allow users to use "-Q." or "-Q ." */ + if ((ap[1] == 'Q' && ap[2] == '.') || + (ap[1] == 'Q' && argv[1] != NULL && + argv[1][0] == '.' && argv[1][1] == '\0')) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Can not use -Q.\n"); + exit(EX_USAGE); + } +#endif /* _FFR_QUARANTINE */ + /* skip over options that do have a value */ op = strchr(OPTIONS, ap[1]); if (op != NULL && *++op == ':' && ap[2] == '\0' && @@ -3139,6 +3263,12 @@ obsolete(argv) if (ap[1] == 'q' && ap[2] == '\0') *argv = "-q0"; +#if _FFR_QUARANTINE + /* If -Q doesn't have an argument, disable quarantining */ + if (ap[1] == 'Q' && ap[2] == '\0') + *argv = "-Q."; +#endif /* _FFR_QUARANTINE */ + /* if -d doesn't have an argument, use 0-99.1 */ if (ap[1] == 'd' && ap[2] == '\0') *argv = "-d0-99.1"; @@ -3433,9 +3563,10 @@ drop_privileges(to_real_uid) } /* reset primary group id */ - if (to_real_uid || RunAsGid != 0) + if (to_real_uid) { /* + ** Drop gid to real gid. ** On some OS we must reset the effective[/real[/saved]] gid, ** and then use setgid() to finally drop all group privileges. ** Later on we check whether we can get back the @@ -3449,7 +3580,6 @@ drop_privileges(to_real_uid) (int) RunAsGid); rval = EX_OSERR; } - else #else /* HASSETEGID */ # if HASSETREGID if (setregid(RunAsGid, RunAsGid) < 0) @@ -3458,7 +3588,6 @@ drop_privileges(to_real_uid) (int) RunAsGid, (int) RunAsGid); rval = EX_OSERR; } - else # else /* HASSETREGID */ # if HASSETRESGID if (setresgid(RunAsGid, RunAsGid, RunAsGid) < 0) @@ -3467,32 +3596,44 @@ drop_privileges(to_real_uid) (int) RunAsGid, (int) RunAsGid, (int) RunAsGid); rval = EX_OSERR; } - else # endif /* HASSETRESGID */ # endif /* HASSETREGID */ #endif /* HASSETEGID */ - if (setgid(RunAsGid) < 0) + } + if (rval == EX_OK && (to_real_uid || RunAsGid != 0)) + { + if (setgid(RunAsGid) < 0 && (!UseMSP || getegid() != RunAsGid)) { syserr("drop_privileges: setgid(%d) failed", (int) RunAsGid); rval = EX_OSERR; } - else if (getegid() != RunAsGid -#if !SM_CONF_CANT_SETRGID - || getgid() != RunAsGid -#endif /* !SM_CONF_CANT_SETRGID */ - ) + errno = 0; + if (rval == EX_OK && getegid() != RunAsGid) { - syserr("drop_privileges: Unable to drop set-group-ID privileges"); + syserr("drop_privileges: Unable to set effective gid=%d to RunAsGid=%d", + (int) getegid(), (int) RunAsGid); rval = EX_OSERR; } } + + /* fiddle with uid */ if (to_real_uid || RunAsUid != 0) { uid_t euid = geteuid(); + /* + ** Try to setuid(RunAsUid). + ** euid must be RunAsUid, + ** ruid must be RunAsUid unless it's the MSP and the euid + ** wasn't 0 and we didn't have to drop privileges to the + ** real uid. + */ + if (setuid(RunAsUid) < 0 || - getuid() != RunAsUid || geteuid() != RunAsUid) + (getuid() != RunAsUid && + (!UseMSP || euid == 0 || to_real_uid )) || + geteuid() != RunAsUid) { #if HASSETREUID /* @@ -3687,8 +3828,6 @@ testmodeline(line, e) char exbuf[MAXLINE]; extern unsigned char TokTypeNoC[]; - macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e r"); - /* skip leading spaces */ while (*line == ' ') line++; @@ -3878,7 +4017,7 @@ testmodeline(line, e) if (sm_strcasecmp(&line[1], "quit") == 0) { CurEnv->e_id = NULL; - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ } if (sm_strcasecmp(&line[1], "mx") == 0) @@ -4153,7 +4292,7 @@ dump_class(s, id) register STAB *s; int id; { - if (s->s_type != ST_CLASS) + if (s->s_symtype != ST_CLASS) return; if (bitnset(bitidx(id), s->s_class)) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, diff --git a/gnu/usr.sbin/sendmail/sendmail/map.c b/gnu/usr.sbin/sendmail/sendmail/map.c index 615d4073484..3a16de7ddd8 100644 --- a/gnu/usr.sbin/sendmail/sendmail/map.c +++ b/gnu/usr.sbin/sendmail/sendmail/map.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1992, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1992, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: map.c,v 8.606 2001/09/25 18:32:36 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: map.c,v 8.618 2002/01/11 22:06:52 gshapiro Exp $") #if LDAPMAP # include <sm/ldap.h> @@ -465,7 +465,7 @@ map_init(s, unused) register MAP *map; /* has to be a map */ - if (s->s_type != ST_MAP) + if (s->s_symtype != ST_MAP) return; map = &s->s_map; @@ -620,7 +620,7 @@ map_close(s, bogus) MAP *map; extern MAPCLASS BogusMapClass; - if (s->s_type != ST_MAP) + if (s->s_symtype != ST_MAP) return; map = &s->s_map; @@ -3303,6 +3303,7 @@ ldapmap_open(map, mode) { /* Already have a connection open to this LDAP server */ lmap->ldap_ld = ((SM_LDAP_STRUCT *)s->s_lmap->map_db1)->ldap_ld; + lmap->ldap_pid = ((SM_LDAP_STRUCT *)s->s_lmap->map_db1)->ldap_pid; /* Add this map as head of linked list */ lmap->ldap_next = s->s_lmap; @@ -3448,6 +3449,7 @@ ldapmap_lookup(map, name, av, statp) int entries = 0; int msgid; int ret; + int save_errno; int vsize; char *vp, *p; char *result = NULL; @@ -3475,8 +3477,6 @@ ldapmap_lookup(map, name, av, statp) msgid = sm_ldap_search(lmap, keybuf); if (msgid == -1) { - int save_errno; - errno = sm_ldap_geterrno(lmap->ldap_ld) + E_LDAPBASE; save_errno = errno; if (!bitset(MF_OPTIONAL, map->map_mflags)) @@ -3489,8 +3489,7 @@ ldapmap_lookup(map, name, av, statp) keybuf, map->map_mname); } *statp = EX_TEMPFAIL; - errno = save_errno - E_LDAPBASE; - switch (errno) + switch (save_errno - E_LDAPBASE) { #ifdef LDAP_SERVER_DOWN case LDAP_SERVER_DOWN: @@ -3508,9 +3507,58 @@ ldapmap_lookup(map, name, av, statp) *statp = EX_NOTFOUND; vp = NULL; - /* Get results (all if MF_NOREWRITE, otherwise one by one) */ - while ((ret = ldap_result(lmap->ldap_ld, msgid, - bitset(MF_NOREWRITE, map->map_mflags), +# if _FFR_LDAP_RECURSION + { + int flags; + SM_RPOOL_T *rpool; + + flags = 0; + if (bitset(MF_SINGLEMATCH, map->map_mflags)) + flags |= SM_LDAP_SINGLEMATCH; + if (bitset(MF_MATCHONLY, map->map_mflags)) + flags |= SM_LDAP_MATCHONLY; + + /* Create an rpool for search related memory usage */ + rpool = sm_rpool_new_x(NULL); + + p = NULL; + *statp = sm_ldap_results(lmap, msgid, flags, map->map_coldelim, + rpool, &p, NULL); + save_errno = errno; + + /* Copy result so rpool can be freed */ + if (*statp == EX_OK && p != NULL) + vp = newstr(p); + sm_rpool_free(rpool); + + /* need to restart LDAP connection? */ + if (*statp == EX_RESTART) + { + *statp = EX_TEMPFAIL; + ldapmap_close(map); + } + + errno = save_errno; + if (*statp != EX_OK && *statp != EX_NOTFOUND) + { + if (!bitset(MF_OPTIONAL, map->map_mflags)) + { + if (bitset(MF_NODEFER, map->map_mflags)) + syserr("Error getting LDAP results in map %s", + map->map_mname); + else + syserr("421 4.0.0 Error getting LDAP results in map %s", + map->map_mname); + } + errno = save_errno; + return NULL; + } + goto finishlookup; + } +# endif /* _FFR_LDAP_RECURSION */ + + /* Get results */ + while ((ret = ldap_result(lmap->ldap_ld, msgid, 0, (lmap->ldap_timeout.tv_sec == 0 ? NULL : &(lmap->ldap_timeout)), &(lmap->ldap_res))) == LDAP_RES_SEARCH_ENTRY) @@ -3585,15 +3633,21 @@ ldapmap_lookup(map, name, av, statp) attr); if (vals == NULL) { - errno = sm_ldap_geterrno(lmap->ldap_ld); - if (errno == LDAP_SUCCESS) + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + if (save_errno == LDAP_SUCCESS) + { +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ continue; + } /* Must be an error */ - errno += E_LDAPBASE; + save_errno += E_LDAPBASE; if (!bitset(MF_OPTIONAL, map->map_mflags)) { + errno = save_errno; if (bitset(MF_NODEFER, map->map_mflags)) syserr("Error getting LDAP values in map %s", @@ -3615,6 +3669,7 @@ ldapmap_lookup(map, name, av, statp) msgid); if (vp != NULL) sm_free(vp); /* XXX */ + errno = save_errno; return NULL; } } @@ -3637,7 +3692,15 @@ ldapmap_lookup(map, name, av, statp) */ if (bitset(MF_MATCHONLY, map->map_mflags)) + { + if (lmap->ldap_attrsonly == LDAPMAP_FALSE) + ldap_value_free(vals); + +# if USING_NETSCAPE_LDAP + ldap_memfree(attr); +# endif /* USING_NETSCAPE_LDAP */ continue; + } /* ** If we don't want multiple values, @@ -3757,7 +3820,7 @@ ldapmap_lookup(map, name, av, statp) sm_free(vp_tmp); /* XXX */ vp = tmp; } - errno = sm_ldap_geterrno(lmap->ldap_ld); + save_errno = sm_ldap_geterrno(lmap->ldap_ld); /* ** We check errno != LDAP_DECODING_ERROR since @@ -3768,13 +3831,14 @@ ldapmap_lookup(map, name, av, statp) ** http://www.openldap.org/lists/openldap-devel/9901/msg00064.html */ - if (errno != LDAP_SUCCESS && - errno != LDAP_DECODING_ERROR) + if (save_errno != LDAP_SUCCESS && + save_errno != LDAP_DECODING_ERROR) { /* Must be an error */ - errno += E_LDAPBASE; + save_errno += E_LDAPBASE; if (!bitset(MF_OPTIONAL, map->map_mflags)) { + errno = save_errno; if (bitset(MF_NODEFER, map->map_mflags)) syserr("Error getting LDAP attributes in map %s", map->map_mname); @@ -3791,6 +3855,7 @@ ldapmap_lookup(map, name, av, statp) (void) ldap_abandon(lmap->ldap_ld, msgid); if (vp != NULL) sm_free(vp); /* XXX */ + errno = save_errno; return NULL; } @@ -3798,13 +3863,15 @@ ldapmap_lookup(map, name, av, statp) if (map->map_coldelim == '\0' && vp != NULL) break; } - errno = sm_ldap_geterrno(lmap->ldap_ld); - if (errno != LDAP_SUCCESS && errno != LDAP_DECODING_ERROR) + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + if (save_errno != LDAP_SUCCESS && + save_errno != LDAP_DECODING_ERROR) { /* Must be an error */ - errno += E_LDAPBASE; + save_errno += E_LDAPBASE; if (!bitset(MF_OPTIONAL, map->map_mflags)) { + errno = save_errno; if (bitset(MF_NODEFER, map->map_mflags)) syserr("Error getting LDAP entries in map %s", map->map_mname); @@ -3821,50 +3888,25 @@ ldapmap_lookup(map, name, av, statp) (void) ldap_abandon(lmap->ldap_ld, msgid); if (vp != NULL) sm_free(vp); /* XXX */ + errno = save_errno; return NULL; } ldap_msgfree(lmap->ldap_res); lmap->ldap_res = NULL; } - /* - ** If grabbing all results at once for MF_NOREWRITE and - ** only want a single match, make sure that's all we have - */ - - if (ret == LDAP_RES_SEARCH_RESULT && - bitset(MF_NOREWRITE|MF_SINGLEMATCH, map->map_mflags)) - { - entries += ldap_count_entries(lmap->ldap_ld, lmap->ldap_res); - if (entries > 1) - { - *statp = EX_NOTFOUND; - if (lmap->ldap_res != NULL) - { - ldap_msgfree(lmap->ldap_res); - lmap->ldap_res = NULL; - } - if (vp != NULL) - sm_free(vp); /* XXX */ - return NULL; - } - *statp = EX_OK; - } - if (ret == 0) - errno = ETIMEDOUT; + save_errno = ETIMEDOUT; else - errno = sm_ldap_geterrno(lmap->ldap_ld); - if (errno != LDAP_SUCCESS) + save_errno = sm_ldap_geterrno(lmap->ldap_ld); + if (save_errno != LDAP_SUCCESS) { - int save_errno; - if (ret != 0) - errno += E_LDAPBASE; - save_errno = errno; + save_errno += E_LDAPBASE; if (!bitset(MF_OPTIONAL, map->map_mflags)) { + errno = save_errno; if (bitset(MF_NODEFER, map->map_mflags)) syserr("Error getting LDAP results in map %s", map->map_mname); @@ -3876,8 +3918,7 @@ ldapmap_lookup(map, name, av, statp) if (vp != NULL) sm_free(vp); /* XXX */ - errno = save_errno - E_LDAPBASE; - switch (errno) + switch (save_errno - E_LDAPBASE) { #ifdef LDAP_SERVER_DOWN case LDAP_SERVER_DOWN: @@ -3892,20 +3933,9 @@ ldapmap_lookup(map, name, av, statp) return NULL; } - /* - ** If MF_NOREWRITE, we are special map which doesn't - ** actually return a map value. Instead, we don't free - ** ldap_res and let the calling function process the LDAP - ** results. The caller should ldap_msgfree(lmap->ldap_res). - */ - - if (bitset(MF_NOREWRITE, map->map_mflags)) - { - if (vp != NULL) - sm_free(vp); /* XXX */ - *statp = EX_OK; - return ""; - } +# if _FFR_LDAP_RECURSION +finishlookup: +# endif /* _FFR_LDAP_RECURSION */ /* Did we match anything? */ if (vp == NULL && !bitset(MF_MATCHONLY, map->map_mflags)) @@ -4209,7 +4239,7 @@ ldapmap_parseargs(map, args) # ifdef LDAP_REFERRALS lmap->ldap_options &= ~LDAP_OPT_REFERRALS; # else /* LDAP_REFERRALS */ - syserr("compile with -DLDAP_REFERRALS for referral support\n"); + syserr("compile with -DLDAP_REFERRALS for referral support"); # endif /* LDAP_REFERRALS */ break; @@ -4534,6 +4564,11 @@ ldapmap_parseargs(map, args) if (lmap->ldap_attr[0] != NULL) { +#if _FFR_LDAP_RECURSION + bool recurse = false; + int final = 0; +#endif /* _FFR_LDAP_RECURSION */ + i = 0; p = ldapmap_dequote(lmap->ldap_attr[0]); lmap->ldap_attr[0] = NULL; @@ -4558,11 +4593,80 @@ ldapmap_parseargs(map, args) return false; } if (*v != '\0') - lmap->ldap_attr[i++] = newstr(v); + { +#if _FFR_LDAP_RECURSION + char *type; + + type = strchr(v, ':'); + if (type != NULL) + *type++ = '\0'; +#endif /* _FFR_LDAP_RECURSION */ + + lmap->ldap_attr[i] = newstr(v); + +#if _FFR_LDAP_RECURSION + if (type != NULL) + { + if (sm_strcasecmp(type, "normal") == 0) + { + lmap->ldap_attr_type[i] = LDAPMAP_ATTR_NORMAL; + } + else if (sm_strcasecmp(type, "dn") == 0) + { + recurse = true; + lmap->ldap_attr_type[i] = LDAPMAP_ATTR_DN; + } + else if (sm_strcasecmp(type, "filter") == 0) + { + recurse = true; + lmap->ldap_attr_type[i] = LDAPMAP_ATTR_FILTER; + } + else if (sm_strcasecmp(type, "url") == 0) + { + recurse = true; + lmap->ldap_attr_type[i] = LDAPMAP_ATTR_URL; + } + else if (sm_strcasecmp(type, "final") == 0) + { + lmap->ldap_attr_type[i] = LDAPMAP_ATTR_FINAL; + if (final >= LDAPMAP_MAX_ATTR) + { + syserr("Too many FINAL attributes in %s (max %d)", + map->map_mname, LDAPMAP_MAX_ATTR); + return false; + } + lmap->ldap_attr_final[final++] = lmap->ldap_attr[i]; + } + else + { + syserr("Unknown attribute type (%s) in %s", + type, map->map_mname); + return false; + } + } + else + lmap->ldap_attr_type[i] = LDAPMAP_ATTR_NORMAL; +#endif /* _FFR_LDAP_RECURSION */ + i++; + } } lmap->ldap_attr[i] = NULL; +#if _FFR_LDAP_RECURSION + lmap->ldap_attr_final[final] = NULL; + if (recurse && lmap->ldap_attr_final[0] == NULL) + { + syserr("LDAP recursion requested in %s but no FINAL attribute given", + map->map_mname); + return false; + } + if (recurse && lmap->ldap_attrsonly == LDAPMAP_TRUE) + { + syserr("LDAP recursion requested in %s can not be used with -n", + map->map_mname); + return false; + } +#endif /* _FFR_LDAP_RECURSION */ } - map->map_db1 = (ARBPTR_T) lmap; return true; } @@ -4758,7 +4862,7 @@ ph_map_parseargs(map, args) break; default: - syserr("ph_map_parseargs: unknown option -%c\n", *p); + syserr("ph_map_parseargs: unknown option -%c", *p); } /* try to account for quoted strings */ @@ -5146,7 +5250,7 @@ syslog_map_parseargs(map, args) else #endif /* LOG_DEBUG */ { - syserr("syslog_map_parseargs: Unknown priority %s\n", + syserr("syslog_map_parseargs: Unknown priority %s", priority); return false; } @@ -6140,7 +6244,7 @@ prog_map_lookup(map, name, av, statp) i = read(fd, buf, sizeof buf - 1); if (i < 0) { - syserr("prog_map_lookup(%s): read error %s\n", + syserr("prog_map_lookup(%s): read error %s", map->map_mname, sm_errstring(errno)); rval = NULL; } @@ -6178,7 +6282,7 @@ prog_map_lookup(map, name, av, statp) if (status == -1) { - syserr("prog_map_lookup(%s): wait error %s\n", + syserr("prog_map_lookup(%s): wait error %s", map->map_mname, sm_errstring(errno)); *statp = EX_SOFTWARE; rval = NULL; @@ -6604,7 +6708,7 @@ parse_fields(s, ibuf, blen, nr_substrings) } else { - syserr("too many fields, %d max\n", blen); + syserr("too many fields, %d max", blen); return -1; } s = ++cp; diff --git a/gnu/usr.sbin/sendmail/sendmail/mci.c b/gnu/usr.sbin/sendmail/sendmail/mci.c index 5b5629b9567..fc51a4bcaf4 100644 --- a/gnu/usr.sbin/sendmail/sendmail/mci.c +++ b/gnu/usr.sbin/sendmail/sendmail/mci.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: mci.c,v 8.200 2001/09/21 20:01:42 ca Exp $") +SM_RCSID("@(#)$Sendmail: mci.c,v 8.202 2001/11/05 22:12:17 ca Exp $") #if NETINET || NETINET6 # include <arpa/inet.h> @@ -867,7 +867,6 @@ mci_read_persistent(fp, mci) { sm_dprintf("mci_read_persistent: fp=%lx, mci=", (unsigned long) fp); - mci_dump(mci, false); } SM_FREE_CLR(mci->mci_status); @@ -916,6 +915,8 @@ mci_read_persistent(fp, mci) break; case '.': /* end of file */ + if (tTd(56, 93)) + mci_dump(mci, false); return 0; default: @@ -928,6 +929,8 @@ mci_read_persistent(fp, mci) } } LineNumber = saveLineNumber; + if (tTd(56, 93)) + sm_dprintf("incomplete (missing dot for EOF)\n"); if (ver < 0) return -1; return 0; @@ -1313,11 +1316,17 @@ mci_purge_persistent(pathname, hostname) if (hostname != NULL) { /* remove the file */ - if (unlink(pathname) < 0) + ret = unlink(pathname); + if (ret < 0) { + if (LogLevel > 8) + sm_syslog(LOG_ERR, NOQID, + "mci_purge_persistent: failed to unlink %s: %s", + pathname, sm_errstring(errno)); if (tTd(56, 2)) sm_dprintf("mci_purge_persistent: failed to unlink %s: %s\n", pathname, sm_errstring(errno)); + return ret; } } else @@ -1329,13 +1338,14 @@ mci_purge_persistent(pathname, hostname) if (tTd(56, 1)) sm_dprintf("mci_purge_persistent: dpurge %s\n", pathname); - if (rmdir(pathname) < 0) + ret = rmdir(pathname); + if (ret < 0) { if (tTd(56, 2)) sm_dprintf("mci_purge_persistent: rmdir %s: %s\n", pathname, sm_errstring(errno)); + return ret; } - } return 0; diff --git a/gnu/usr.sbin/sendmail/sendmail/milter.c b/gnu/usr.sbin/sendmail/sendmail/milter.c index d1606540f70..8e780089c42 100644 --- a/gnu/usr.sbin/sendmail/sendmail/milter.c +++ b/gnu/usr.sbin/sendmail/sendmail/milter.c @@ -10,7 +10,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: milter.c,v 8.180 2001/09/17 20:39:57 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: milter.c,v 8.185 2001/11/21 02:21:15 gshapiro Exp $") #if MILTER # include <libmilter/mfapi.h> @@ -1803,6 +1803,7 @@ milter_send_command(m, command, data, sz, e, state) char rcmd; ssize_t rlen; unsigned long skipflag; + char *action; char *defresponse; char *response; @@ -1815,36 +1816,43 @@ milter_send_command(m, command, data, sz, e, state) { case SMFIC_CONNECT: skipflag = SMFIP_NOCONNECT; + action = "connect"; defresponse = "554 Command rejected"; break; case SMFIC_HELO: skipflag = SMFIP_NOHELO; + action = "helo"; defresponse = "550 Command rejected"; break; case SMFIC_MAIL: skipflag = SMFIP_NOMAIL; + action = "mail"; defresponse = "550 5.7.1 Command rejected"; break; case SMFIC_RCPT: skipflag = SMFIP_NORCPT; + action = "rcpt"; defresponse = "550 5.7.1 Command rejected"; break; case SMFIC_HEADER: skipflag = SMFIP_NOHDRS; + action = "header"; defresponse = "550 5.7.1 Command rejected"; break; case SMFIC_BODY: skipflag = SMFIP_NOBODY; + action = "body"; defresponse = "554 5.7.1 Command rejected"; break; case SMFIC_EOH: skipflag = SMFIP_NOEOH; + action = "eoh"; defresponse = "550 5.7.1 Command rejected"; break; @@ -1858,6 +1866,7 @@ milter_send_command(m, command, data, sz, e, state) default: skipflag = 0; + action = "default"; defresponse = "550 5.7.1 Command rejected"; break; } @@ -1893,14 +1902,30 @@ milter_send_command(m, command, data, sz, e, state) { case SMFIR_REPLYCODE: MILTER_CHECK_REPLYCODE(defresponse); - if (MilterLogLevel > 8) - sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s", - m->mf_name, response); - /* FALLTHROUGH */ + if (MilterLogLevel > 10) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject=%s", + m->mf_name, action, response); + *state = rcmd; + break; case SMFIR_REJECT: + if (MilterLogLevel > 10) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, reject", + m->mf_name, action); + *state = rcmd; + break; + case SMFIR_DISCARD: + if (MilterLogLevel > 10) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, discard", + m->mf_name, action); + *state = rcmd; + break; + case SMFIR_TEMPFAIL: + if (MilterLogLevel > 10) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, tempfail", + m->mf_name, action); *state = rcmd; break; @@ -1911,23 +1936,26 @@ milter_send_command(m, command, data, sz, e, state) m->mf_state = SMFS_CLOSABLE; else m->mf_state = SMFS_DONE; - if (MilterLogLevel > 8) - sm_syslog(LOG_INFO, e->e_id, "Milter (%s): accepted", - m->mf_name); + if (MilterLogLevel > 10) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, accepted", + m->mf_name, action); break; case SMFIR_CONTINUE: /* if MAIL command is ok, filter is in message state */ if (command == SMFIC_MAIL) m->mf_state = SMFS_INMSG; + if (MilterLogLevel > 12) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, action=%s, continue", + m->mf_name, action); break; default: /* Invalid response to command */ if (MilterLogLevel > 0) sm_syslog(LOG_ERR, e->e_id, - "milter_send_command(%s): returned bogus response %c", - m->mf_name, rcmd); + "milter_send_command(%s): action=%s returned bogus response %c", + m->mf_name, action, rcmd); milter_error(m, e); break; } @@ -2685,7 +2713,13 @@ milter_changeheader(response, rlen, e) if (h != sysheader && h->h_value != NULL) { - e->e_msgsize -= strlen(h->h_value); + size_t l; + + l = strlen(h->h_value); + if (l > e->e_msgsize) + e->e_msgsize = 0; + else + e->e_msgsize -= l; /* rpool, don't free: sm_free(h->h_value); XXX */ } @@ -2693,7 +2727,15 @@ milter_changeheader(response, rlen, e) { /* Remove "Field: " from message size */ if (h != sysheader) - e->e_msgsize -= strlen(h->h_field) + 2; + { + size_t l; + + l = strlen(h->h_field) + 2; + if (l > e->e_msgsize) + e->e_msgsize = 0; + else + e->e_msgsize -= l; + } h->h_value = NULL; } else @@ -2890,7 +2932,7 @@ milter_replbody(response, rlen, newfilter, e) e->e_msgsize -= prevsize; } - if (MilterLogLevel > 8) + if (newfilter && MilterLogLevel > 8) sm_syslog(LOG_INFO, e->e_id, "Milter message: body replaced"); if (response == NULL) @@ -2998,7 +3040,7 @@ milter_init(e, state) m->mf_sock < 0 ? "open" : "negotiate"); if (MilterLogLevel > 0) - sm_syslog(LOG_INFO, e->e_id, + sm_syslog(LOG_ERR, e->e_id, "Milter (%s): init failed to %s", m->mf_name, m->mf_sock < 0 ? "open" : @@ -3132,7 +3174,7 @@ milter_connect(hostname, addr, e, state) if (*state != SMFIR_CONTINUE) { - if (MilterLogLevel > 7) + if (MilterLogLevel > 9) sm_syslog(LOG_INFO, e->e_id, "Milter: connect, ending"); milter_quit(e); } @@ -3534,7 +3576,7 @@ milter_data(e, state) { case SMFIR_REPLYCODE: MILTER_CHECK_REPLYCODE("554 5.7.1 Command rejected"); - if (MilterLogLevel > 8) + if (MilterLogLevel > 12) sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject=%s", m->mf_name, response); *state = rcmd; @@ -3542,8 +3584,25 @@ milter_data(e, state) break; case SMFIR_REJECT: /* log msg at end of function */ + if (MilterLogLevel > 12) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, reject", + m->mf_name); + *state = rcmd; + m->mf_state = SMFS_DONE; + break; + case SMFIR_DISCARD: + if (MilterLogLevel > 12) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, discard", + m->mf_name); + *state = rcmd; + m->mf_state = SMFS_DONE; + break; + case SMFIR_TEMPFAIL: + if (MilterLogLevel > 12) + sm_syslog(LOG_INFO, e->e_id, "milter=%s, tempfail", + m->mf_name); *state = rcmd; m->mf_state = SMFS_DONE; break; @@ -3572,14 +3631,14 @@ milter_data(e, state) } if (response == NULL) response = newstr(""); - if (MilterLogLevel > 8) + if (MilterLogLevel > 3) sm_syslog(LOG_INFO, e->e_id, - "Milter: quarantine: %s", - response); - e->e_holdmsg = sm_rpool_strdup_x(e->e_rpool, + "milter=%s, quarantine=%s", + m->mf_name, response); + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, response); macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), e->e_holdmsg); + macid("{quarantine}"), e->e_quarmsg); break; # endif /* _FFR_QUARANTINE */ diff --git a/gnu/usr.sbin/sendmail/sendmail/newaliases.8 b/gnu/usr.sbin/sendmail/sendmail/newaliases.8 index ef49f960106..3bc64072766 100644 --- a/gnu/usr.sbin/sendmail/sendmail/newaliases.8 +++ b/gnu/usr.sbin/sendmail/sendmail/newaliases.8 @@ -1,4 +1,4 @@ -.\" Copyright (c) 1998-2000 Sendmail, Inc. and its suppliers. +.\" Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. .\" All rights reserved. .\" Copyright (c) 1983, 1997 Eric P. Allman. All rights reserved. .\" Copyright (c) 1985, 1990, 1993 @@ -9,9 +9,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Sendmail: newaliases.1,v 8.17 2001/04/03 01:53:18 gshapiro Exp $ +.\" $Sendmail: newaliases.1,v 8.19 2001/10/10 03:23:17 ca Exp $ .\" -.Dd April 3, 2001 +.Dd October 10, 2001 .Dt NEWALIASES 8 .Os .Sh NAME @@ -33,6 +33,15 @@ is identical to The .Nm newaliases utility exits 0 on success, and >0 if an error occurs. +.Pp +Notice: do +.Em not +use +.Xr makemap 8 +to create the aliases data base, because +.Nm +puts a special token into the data base that is required by +.Xr sendmail 8 . .Sh FILES .Bl -tag -width /etc/mail/aliases -compact .It Pa /etc/mail/aliases @@ -41,6 +50,7 @@ The mail aliases file .Sh SEE ALSO .Xr aliases 5 , .Xr mailer.conf 5 , +.Xr makemap 8 , .Xr sendmail 8 .Sh HISTORY The diff --git a/gnu/usr.sbin/sendmail/sendmail/parseaddr.c b/gnu/usr.sbin/sendmail/sendmail/parseaddr.c index 83dd3080067..0398f916763 100644 --- a/gnu/usr.sbin/sendmail/sendmail/parseaddr.c +++ b/gnu/usr.sbin/sendmail/sendmail/parseaddr.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: parseaddr.c,v 8.344 2001/09/20 23:08:06 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: parseaddr.c,v 8.349 2001/12/12 02:50:22 gshapiro Exp $") static void allocaddr __P((ADDRESS *, int, char *, ENVELOPE *)); static int callsubr __P((char**, int, ENVELOPE *)); @@ -803,7 +803,8 @@ prescan(addr, delim, pvpbuf, pvpbsize, delimptr, toktab) if (isascii(c) && isprint(c)) usrerr("553 Illegal character %c", c); else - usrerr("553 Illegal character 0x%02x", c); + usrerr("553 Illegal character 0x%02x", + c & 0x0ff); } if (bitset(M, newstate)) c = NOCHAR; @@ -2923,17 +2924,17 @@ rscheck(rwset, p1, p2, e, rmcomm, cnt, logl, host, logid) if (pvp[4] == NULL || (pvp[4][0] & 0377) != CANONUSER || pvp[5] == NULL) - e->e_holdmsg = sm_rpool_strdup_x(e->e_rpool, + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, rwset); else { cataddr(&(pvp[5]), NULL, ubuf, sizeof ubuf, ' '); - e->e_holdmsg = sm_rpool_strdup_x(e->e_rpool, + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, ubuf); } macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), e->e_holdmsg); + macid("{quarantine}"), e->e_quarmsg); quarantine = true; } #endif /* _FFR_QUARANTINE */ @@ -2952,7 +2953,7 @@ rscheck(rwset, p1, p2, e, rmcomm, cnt, logl, host, logid) if (!logged) { if (cnt) - markstats(e, &a1, true); + markstats(e, &a1, STATS_REJECT); logged = true; } } @@ -3011,6 +3012,9 @@ rscheck(rwset, p1, p2, e, rmcomm, cnt, logl, host, logid) SM_END_TRY setstat(rstat); + + /* rulesets don't set errno */ + errno = 0; if (rstat != EX_OK && QuickAbort) sm_exc_raisenew_x(&EtypeQuickAbort, 2); return rstat; diff --git a/gnu/usr.sbin/sendmail/sendmail/queue.c b/gnu/usr.sbin/sendmail/sendmail/queue.c index c042dc37995..5e4f51d1d5e 100644 --- a/gnu/usr.sbin/sendmail/sendmail/queue.c +++ b/gnu/usr.sbin/sendmail/sendmail/queue.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: queue.c,v 8.788 2001/09/30 16:32:47 ca Exp $") +SM_RCSID("@(#)$Sendmail: queue.c,v 8.834 2002/01/08 23:04:58 ca Exp $") #include <dirent.h> @@ -40,7 +40,10 @@ static time_t queuedelay __P((ENVELOPE *)); # define queuedelay(e) MinQueueAge #define queuedelay_qfver_unsupported(qfver) ((qfver) == 5 || (qfver) == 7) #endif /* _FFR_QUEUEDELAY */ - +#if _FFR_QUARANTINE +static char queue_letter __P((ENVELOPE *, int)); +static bool quarantine_queue_item __P((int, int, ENVELOPE *, char *)); +#endif /* _FFR_QUARANTINE */ /* Naming convention: qgrp: index of queue group, qg: QUEUEGROUP */ @@ -118,8 +121,7 @@ static int multiqueue_cache __P((char *, int, QUEUEGRP *, int, unsigned int *)); static int gatherq __P((int, int, bool, bool *, bool *)); static int sortq __P((int)); static void printctladdr __P((ADDRESS *, SM_FILE_T *)); -static int print_single_queue __P((int, int)); -static bool readqf __P((ENVELOPE *)); +static bool readqf __P((ENVELOPE *, bool)); static void restart_work_group __P((int)); static void runner_work __P((ENVELOPE *, int, bool, int, int)); static void schedule_queue_runs __P((bool, int)); @@ -276,7 +278,6 @@ hash_q(p, h) ** E error recipient ** F flag bits ** G queue delay algorithm (_FFR_QUEUEDELAY) -** h hold reason (_FFR_QUARANTINE) ** H header ** I data file's inode number ** K time of last delivery attempt @@ -284,6 +285,7 @@ hash_q(p, h) ** M message (obsolete) ** N number of delivery attempts ** P message priority +** q quarantine reason (_FFR_QUARANTINE) ** Q original recipient (ORCPT=) ** r final recipient (Final-Recipient: DSN field) ** R recipient @@ -320,7 +322,6 @@ queueup(e, announce, msync) bool announce; bool msync; { - char *qf; register SM_FILE_T *tfp; register HDR *h; register ADDRESS *q; @@ -330,8 +331,9 @@ queueup(e, announce, msync) register char *p; MAILER nullmailer; MCI mcibuf; + char qf[MAXPATHLEN]; char tf[MAXPATHLEN]; - char dfname[MAXPATHLEN]; + char df[MAXPATHLEN]; char buf[MAXLINE]; /* @@ -440,16 +442,17 @@ queueup(e, announce, msync) ** If there is no data file yet, create one. */ - (void) sm_strlcpy(dfname, queuename(e, DATAFL_LETTER), sizeof dfname); + (void) sm_strlcpy(df, queuename(e, DATAFL_LETTER), sizeof df); if (bitset(EF_HAS_DF, e->e_flags)) { if (e->e_dfp != NULL && SuperSafe != SAFE_REALLY && sm_io_setinfo(e->e_dfp, SM_BF_COMMIT, NULL) < 0 && errno != EINVAL) + { syserr("!queueup: cannot commit data file %s, uid=%d", - queuename(e, DATAFL_LETTER), geteuid()); - + queuename(e, DATAFL_LETTER), geteuid()); + } if (e->e_dfp != NULL && SuperSafe == SAFE_INTERACTIVE && msync) { @@ -462,10 +465,10 @@ queueup(e, announce, msync) { if (newid) syserr("!552 Error writing data file %s", - dfname); + df); else syserr("!452 Error writing data file %s", - dfname); + df); } } } @@ -482,14 +485,14 @@ queueup(e, announce, msync) if (bitset(S_IWGRP, QueueFileMode)) oldumask = umask(002); - dfd = open(dfname, O_WRONLY|O_CREAT|O_TRUNC, QueueFileMode); + dfd = open(df, O_WRONLY|O_CREAT|O_TRUNC, QueueFileMode); if (bitset(S_IWGRP, QueueFileMode)) (void) umask(oldumask); if (dfd < 0 || (dfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &dfd, SM_IO_WRONLY, NULL)) == NULL) syserr("!queueup: cannot create data temp file %s, uid=%d", - dfname, geteuid()); + df, geteuid()); if (fstat(dfd, &stbuf) < 0) e->e_dfino = -1; else @@ -514,23 +517,23 @@ queueup(e, announce, msync) { if (newid) syserr("!552 Error writing data file %s", - dfname); + df); else syserr("!452 Error writing data file %s", - dfname); + df); } } if (sm_io_close(dfp, SM_TIME_DEFAULT) < 0) syserr("!queueup: cannot save data temp file %s, uid=%d", - dfname, geteuid()); + df, geteuid()); e->e_putbody = putbody; } /* ** Output future work requests. ** Priority and creation time should be first, since - ** they are required by orderq. + ** they are required by gatherq. */ /* output queue version number (must be first!) */ @@ -586,9 +589,9 @@ queueup(e, announce, msync) #if _FFR_QUARANTINE /* quarantine reason */ - if (e->e_holdmsg != NULL) - (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "h%s\n", - denlstring(e->e_holdmsg, true, false)); + if (e->e_quarmsg != NULL) + (void) sm_io_fprintf(tfp, SM_TIME_DEFAULT, "q%s\n", + denlstring(e->e_quarmsg, true, false)); #endif /* _FFR_QUARANTINE */ /* message from envelope, if it exists */ @@ -681,11 +684,18 @@ queueup(e, announce, msync) denlstring(q->q_paddr, true, false)); if (announce) { + char *tag = "queued"; + +#if _FFR_QUARANTINE + if (e->e_quarmsg != NULL) + tag = "quarantined"; +#endif /* _FFR_QUARANTINE */ + e->e_to = q->q_paddr; - message("queued"); + message(tag); if (LogLevel > 8) logdelivery(q->q_mailer, NULL, q->q_status, - "queued", NULL, (time_t) 0, e); + tag, NULL, (time_t) 0, e); e->e_to = NULL; } if (tTd(40, 1)) @@ -814,40 +824,46 @@ queueup(e, announce, msync) if (!newid) { +#if _FFR_QUARANTINE + char new = queue_letter(e, ANYQFL_LETTER); +#endif /* _FFR_QUARANTINE */ + /* rename (locked) tf to be (locked) [qh]f */ - qf = queuename(e, ANYQFL_LETTER); + (void) sm_strlcpy(qf, queuename(e, ANYQFL_LETTER), + sizeof qf); if (rename(tf, qf) < 0) syserr("cannot rename(%s, %s), uid=%d", tf, qf, geteuid()); - # if _FFR_QUARANTINE - /* Check if type has changed */ - if (e->e_qfletter != '\0' && - e->e_qfletter != qf[0]) + else { - char new = qf[0]; + /* + ** Check if type has changed and only + ** remove the old item if the rename above + ** succeeded. + */ - /* If it has changed, remove the old item */ - if (tTd(40, 5)) + if (e->e_qfletter != '\0' && + e->e_qfletter != new) { - sm_dprintf("type changed from %c to %c\n", - e->e_qfletter, new); - if (tTd(40, 101)) - pause(); - } + if (tTd(40, 5)) + { + sm_dprintf("type changed from %c to %c\n", + e->e_qfletter, new); + } - qf[0] = e->e_qfletter; - if (unlink(qf) < 0) - { - /* XXX: something more drastic? */ - if (LogLevel > 0) - sm_syslog(LOG_ERR, e->e_id, - "queueup: unlink(%s) failed: %s", - qf, sm_errstring(errno)); + if (unlink(queuename(e, e->e_qfletter)) < 0) + { + /* XXX: something more drastic? */ + if (LogLevel > 0) + sm_syslog(LOG_ERR, e->e_id, + "queueup: unlink(%s) failed: %s", + queuename(e, e->e_qfletter), + sm_errstring(errno)); + } } - qf[0] = new; } - e->e_qfletter = qf[0]; + e->e_qfletter = new; # endif /* _FFR_QUARANTINE */ /* @@ -871,22 +887,25 @@ queueup(e, announce, msync) if (e->e_lockfp != NULL) (void) sm_io_close(e->e_lockfp, SM_TIME_DEFAULT); e->e_lockfp = tfp; + + /* save log info */ + if (LogLevel > 79) + sm_syslog(LOG_DEBUG, e->e_id, "queueup %s", qf); } else { - qf = tf; + /* save log info */ + if (LogLevel > 79) + sm_syslog(LOG_DEBUG, e->e_id, "queueup %s", tf); + #if _FFR_QUARANTINE - e->e_qfletter = qf[0]; + e->e_qfletter = queue_letter(e, ANYQFL_LETTER); #endif /* _FFR_QUARANTINE */ } errno = 0; e->e_flags |= EF_INQUEUE; - /* save log info */ - if (LogLevel > 79) - sm_syslog(LOG_DEBUG, e->e_id, "queueup %s", qf); - if (tTd(40, 1)) sm_dprintf("<<<<< done queueing %s <<<<<\n\n", e->e_id); return; @@ -967,7 +986,7 @@ printctladdr(a, tfp) ** ** This propagates the signal to the child processes that are queue ** runners. This is for a queue runner "cleanup". After all of the -** child queue runner processees are signaled (it should be SIGTERM +** child queue runner processes are signaled (it should be SIGTERM ** being the sig) then the old signal handler (Oldsh) is called ** to handle any cleanup set for this process (provided it is not ** SIG_DFL or SIG_IGN). The signal may not be handled immediately @@ -1028,7 +1047,7 @@ runners_sigterm(sig) ** ** This propagates the signal to the child processes that are queue ** runners. This is for a queue runner "cleanup". After all of the -** child queue runner processees are signaled (it should be SIGHUP +** child queue runner processes are signaled (it should be SIGHUP ** being the sig) then the old signal handler (Oldsh) is called to ** handle any cleanup set for this process (provided it is not SIG_DFL ** or SIG_IGN). The signal may not be handled immediately if the @@ -1082,13 +1101,13 @@ runners_sighup(sig) ** ** Parameters: ** wgrp -- the work group id to restart. -** reason -- why (signal?). +** reason -- why (signal?), -1 to turn off restart ** ** Returns: ** none. ** ** Side effects: -** Sets global RestartWorkGroup to true. +** May set global RestartWorkGroup to true. ** ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE @@ -1104,7 +1123,8 @@ mark_work_group_restart(wgrp, reason) return; WorkGrp[wgrp].wg_restart = reason; - RestartWorkGroup = true; + if (reason >= 0) + RestartWorkGroup = true; } /* ** RESTART_MARKED_WORK_GROUPS -- restart work groups marked as needing restart @@ -1304,7 +1324,7 @@ runqueue(forkflag, verbose, persistent, runall) /* queue run has been started, don't do any more this time */ clrbitn(NumQueue, DoQueueRun); - /* more then one queue or more then one directory per queue */ + /* more than one queue or more than one directory per queue */ if (!forkflag && !verbose && (WorkGrp[0].wg_qgs[0]->qg_numqueues > 1 || NumWorkGroups > 1 || WorkGrp[0].wg_numqgrp > 1)) @@ -1767,7 +1787,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) if (QueueLimitId != NULL || QueueLimitSender != NULL || #if _FFR_QUARANTINE - QueueLimitReason != NULL || + QueueLimitQuarantine != NULL || #endif /* _FFR_QUARANTINE */ QueueLimitRecipient != NULL) { @@ -1805,7 +1825,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) { e->e_id = NULL; if (forkflag) - finis(true, ExitStat); + finis(true, true, ExitStat); return true; /* we're done */ } } @@ -1819,9 +1839,11 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) WorkGrp[wgrp].wg_curqgrp, WorkGrp[wgrp].wg_numqgrp); #endif /* _FFR_QUEUE_SCHED_DBG */ +#if HASNICE /* tweak niceness of queue runs */ if (Queue[qgrp]->qg_nice > 0) (void) nice(Queue[qgrp]->qg_nice); +#endif /* HASNICE */ /* XXX running queue group... */ sm_setproctitle(true, CurEnv, "running queue: %s", @@ -1919,7 +1941,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) } else { - /* Reset global flags */ + /* child -- Reset global flags */ RestartRequest = NULL; RestartWorkGroup = false; ShutdownRequest = NULL; @@ -1934,7 +1956,24 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) */ sm_exc_newthread(fatal_error); - if (MaxQueueChildren > 0) + + /* + ** SMTP processes (whether -bd or -bs) set + ** SIGCHLD to reapchild to collect + ** children status. However, at delivery + ** time, that status must be collected + ** by sm_wait() to be dealt with properly + ** (check success of delivery based + ** on status code, etc). Therefore, if we + ** are an SMTP process, reset SIGCHLD + ** back to the default so reapchild + ** doesn't collect status before + ** sm_wait(). + */ + + if (OpMode == MD_SMTP || + OpMode == MD_DAEMON || + MaxQueueChildren > 0) { proc_list_clear(); sm_releasesignal(SIGCHLD); @@ -1945,7 +1984,9 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) QuickAbort = OnlyOneError = false; runner_work(e, sequenceno, true, maxrunners, njobs); - finis(true, ExitStat); /* This child is done */ + + /* This child is done */ + finis(true, true, ExitStat); /* NOTREACHED */ } } @@ -1968,7 +2009,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) while ((ret = sm_wait(&status)) <= 0) continue; - (void) proc_list_drop(ret, NULL, NULL); + proc_list_drop(ret, status, NULL); } } else @@ -2060,7 +2101,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) /* ** Get the LA outside the WorkQ loop if necessary. ** In a persistent queue runner the code is repeated over - ** and over but orderq() may ignore entries due to + ** and over but gatherq() may ignore entries due to ** shouldqueue() (do we really have to do this twice?). ** Hence the queue runners would just idle around when once ** CurrentLA caused all entries in a queue to be ignored. @@ -2081,7 +2122,7 @@ run_work_group(wgrp, forkflag, verbose, persistent, runall) /* exit without the usual cleanup */ e->e_id = NULL; if (forkflag) - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ return true; } @@ -2181,14 +2222,14 @@ runqueueevent(qgrp) ** prepares available work into WorkList */ -#define NEED_P 001 /* 'P': priority */ -#define NEED_T 002 /* 'T': time */ -#define NEED_R 004 /* 'R': recipient */ -#define NEED_S 010 /* 'S': sender */ -#define NEED_H 020 /* host */ +#define NEED_P 0001 /* 'P': priority */ +#define NEED_T 0002 /* 'T': time */ +#define NEED_R 0004 /* 'R': recipient */ +#define NEED_S 0010 /* 'S': sender */ +#define NEED_H 0020 /* host */ #if _FFR_QUARANTINE -# define HAS_HOLD 040 /* has an unexpected 'h' line */ -# define NEED_HOLD 100 /* 'h': reason */ +# define HAS_QUARANTINE 0040 /* has an unexpected 'q' line */ +# define NEED_QUARANTINE 0100 /* 'q': reason */ #endif /* _FFR_QUARANTINE */ static WORK *WorkList = NULL; /* list of unsort work */ @@ -2226,7 +2267,7 @@ gatherq(qgrp, qdir, doall, full, more) if (tTd(41, 1)) { - sm_dprintf("orderq:\n"); + sm_dprintf("gatherq:\n"); check = QueueLimitId; while (check != NULL) @@ -2256,12 +2297,12 @@ gatherq(qgrp, qdir, doall, full, more) } #if _FFR_QUARANTINE - if (QueueMode == QM_HELD) + if (QueueMode == QM_QUARANTINE) { - check = QueueLimitReason; + check = QueueLimitQuarantine; while (check != NULL) { - sm_dprintf("\tQueueLimitReason = %s%s\n", + sm_dprintf("\tQueueLimitQuarantine = %s%s\n", check->queue_negate ? "!" : "", check->queue_match); check = check->queue_next; @@ -2274,7 +2315,7 @@ gatherq(qgrp, qdir, doall, full, more) f = opendir(qd); if (f == NULL) { - syserr("orderq: cannot open \"%s\"", + syserr("gatherq: cannot open \"%s\"", qid_printqueue(qgrp, qdir)); if (full != NULL) *full = WorkListCount >= MaxQueueRun && MaxQueueRun > 0; @@ -2295,14 +2336,14 @@ gatherq(qgrp, qdir, doall, full, more) struct stat sbuf; if (tTd(41, 50)) - sm_dprintf("orderq: checking %s..", d->d_name); + sm_dprintf("gatherq: checking %s..", d->d_name); /* is this an interesting entry? */ #if _FFR_QUARANTINE if (!(((QueueMode == QM_NORMAL && d->d_name[0] == NORMQF_LETTER) || - (QueueMode == QM_HELD && - d->d_name[0] == HELDQF_LETTER) || + (QueueMode == QM_QUARANTINE && + d->d_name[0] == QUARQF_LETTER) || (QueueMode == QM_LOST && d->d_name[0] == LOSEQF_LETTER)) && d->d_name[1] == 'f')) @@ -2321,11 +2362,11 @@ gatherq(qgrp, qdir, doall, full, more) { if (Verbose) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - "orderq: %s too long, %d max characters\n", + "gatherq: %s too long, %d max characters\n", d->d_name, MAXQFNAME); if (LogLevel > 0) sm_syslog(LOG_ALERT, NOQID, - "orderq: %s too long, %d max characters", + "gatherq: %s too long, %d max characters", d->d_name, MAXQFNAME); continue; } @@ -2333,8 +2374,8 @@ gatherq(qgrp, qdir, doall, full, more) check = QueueLimitId; while (check != NULL) { - if (strcontainedin(check->queue_match, d->d_name) != - check->queue_negate) + if (strcontainedin(true, check->queue_match, + d->d_name) != check->queue_negate) break; else check = check->queue_next; @@ -2368,7 +2409,7 @@ gatherq(qgrp, qdir, doall, full, more) { if (errno != ENOENT) sm_syslog(LOG_INFO, NOQID, - "orderq: can't stat %s/%s", + "gatherq: can't stat %s/%s", qid_printqueue(qgrp, qdir), d->d_name); wn--; @@ -2380,12 +2421,12 @@ gatherq(qgrp, qdir, doall, full, more) if (!((d->d_name[0] == DATAFL_LETTER || d->d_name[0] == NORMQF_LETTER || #if _FFR_QUARANTINE - d->d_name[0] == HELDQF_LETTER || + d->d_name[0] == QUARQF_LETTER || d->d_name[0] == LOSEQF_LETTER || #endif /* _FFR_QUARANTINE */ d->d_name[0] == XSCRPT_LETTER) && d->d_name[1] == 'f' && d->d_name[2] == '\0')) - syserr("orderq: %s/%s is not a regular file", + syserr("gatherq: %s/%s is not a regular file", qid_printqueue(qgrp, qdir), d->d_name); wn--; continue; @@ -2396,7 +2437,7 @@ gatherq(qgrp, qdir, doall, full, more) QueueSortOrder == QSO_BYMODTIME || QueueSortOrder == QSO_RANDOM) && #if _FFR_QUARANTINE - QueueLimitReason == NULL && + QueueLimitQuarantine == NULL && #endif /* _FFR_QUARANTINE */ QueueLimitSender == NULL && QueueLimitRecipient == NULL) @@ -2420,7 +2461,7 @@ gatherq(qgrp, qdir, doall, full, more) { /* this may be some random person sending hir msgs */ if (tTd(41, 2)) - sm_dprintf("orderq: cannot open %s: %s\n", + sm_dprintf("gatherq: cannot open %s: %s\n", d->d_name, sm_errstring(errno)); errno = 0; wn--; @@ -2460,8 +2501,8 @@ gatherq(qgrp, qdir, doall, full, more) if (QueueLimitRecipient != NULL) i |= NEED_R; #if _FFR_QUARANTINE - if (QueueLimitReason != NULL) - i |= NEED_HOLD; + if (QueueLimitQuarantine != NULL) + i |= NEED_QUARANTINE; #endif /* _FFR_QUARANTINE */ while (cf != NULL && i != 0 && sm_io_fgets(cf, SM_TIME_DEFAULT, lbuf, @@ -2498,27 +2539,28 @@ gatherq(qgrp, qdir, doall, full, more) break; #if _FFR_QUARANTINE - case 'h': - if (QueueMode != QM_HELD && + case 'q': + if (QueueMode != QM_QUARANTINE && QueueMode != QM_LOST) { if (tTd(41, 49)) - sm_dprintf("%s not marked as held but has an 'h' line\n", + sm_dprintf("%s not marked as quarantined but has a 'q' line\n", w->w_name); - i |= HAS_HOLD; + i |= HAS_QUARANTINE; } - else if (QueueMode == QM_HELD) + else if (QueueMode == QM_QUARANTINE) { - if (QueueLimitReason == NULL) + if (QueueLimitQuarantine == NULL) { - i &= ~NEED_HOLD; + i &= ~NEED_QUARANTINE; break; } p = &lbuf[1]; - check = QueueLimitReason; + check = QueueLimitQuarantine; while (check != NULL) { - if (strcontainedin(check->queue_match, + if (strcontainedin(false, + check->queue_match, p) != check->queue_negate) break; @@ -2526,7 +2568,7 @@ gatherq(qgrp, qdir, doall, full, more) check = check->queue_next; } if (check != NULL) - i &= ~NEED_HOLD; + i &= ~NEED_QUARANTINE; } break; #endif /* _FFR_QUARANTINE */ @@ -2560,7 +2602,8 @@ gatherq(qgrp, qdir, doall, full, more) check = QueueLimitRecipient; while (check != NULL) { - if (strcontainedin(check->queue_match, + if (strcontainedin(true, + check->queue_match, p) != check->queue_negate) break; @@ -2575,7 +2618,8 @@ gatherq(qgrp, qdir, doall, full, more) check = QueueLimitSender; while (check != NULL) { - if (strcontainedin(check->queue_match, + if (strcontainedin(true, + check->queue_match, &lbuf[1]) != check->queue_negate) break; @@ -2615,8 +2659,8 @@ gatherq(qgrp, qdir, doall, full, more) if ((!doall && shouldqueue(w->w_pri, w->w_ctime)) || #if _FFR_QUARANTINE - bitset(HAS_HOLD, i) || - bitset(NEED_HOLD, i) || + bitset(HAS_QUARANTINE, i) || + bitset(NEED_QUARANTINE, i) || #endif /* _FFR_QUARANTINE */ bitset(NEED_R|NEED_S, i)) { @@ -2771,7 +2815,7 @@ sortq(max) { /* ** Sort randomly. - ** workcmpf5() retuns a random 1 or -1. + ** workcmpf5() returns a random 1 or -1. ** As long as nobody does a verification pass over the ** sorted list, we should be golden. */ @@ -3311,7 +3355,14 @@ dowork(qgrp, qdir, id, forkflag, requeueflag, e) PendingSignal = 0; CurrentPid = getpid(); sm_exc_newthread(fatal_error); - if (MaxQueueChildren > 0) + + /* + ** See note above about SMTP processes and SIGCHLD. + */ + + if (OpMode == MD_SMTP || + OpMode == MD_DAEMON || + MaxQueueChildren > 0) { proc_list_clear(); sm_releasesignal(SIGCHLD); @@ -3373,14 +3424,14 @@ dowork(qgrp, qdir, id, forkflag, requeueflag, e) e->e_header = NULL; /* read the queue control file -- return if locked */ - if (!readqf(e)) + if (!readqf(e, false)) { if (tTd(40, 4) && e->e_id != NULL) sm_dprintf("readqf(%s) failed\n", qid_printname(e)); e->e_id = NULL; if (forkflag) - finis(false, EX_OK); + finis(false, true, EX_OK); else { /* adding this frees 8 bytes */ @@ -3404,7 +3455,7 @@ dowork(qgrp, qdir, id, forkflag, requeueflag, e) /* finish up and exit */ if (forkflag) - finis(true, ExitStat); + finis(true, true, ExitStat); else { dropenvelope(e, true, false); @@ -3490,7 +3541,14 @@ doworklist(el, forkflag, requeueflag) PendingSignal = 0; CurrentPid = getpid(); sm_exc_newthread(fatal_error); - if (MaxQueueChildren > 0) + + /* + ** See note above about SMTP processes and SIGCHLD. + */ + + if (OpMode == MD_SMTP || + OpMode == MD_DAEMON || + MaxQueueChildren > 0) { proc_list_clear(); sm_releasesignal(SIGCHLD); @@ -3548,8 +3606,8 @@ doworklist(el, forkflag, requeueflag) if (WILL_BE_QUEUED(ei->e_sendmode)) continue; #if _FFR_QUARANTINE - else if (QueueMode != QM_HELD && - ei->e_holdmsg != NULL) + else if (QueueMode != QM_QUARANTINE && + ei->e_quarmsg != NULL) continue; #endif /* _FFR_QUARANTINE */ @@ -3569,7 +3627,7 @@ doworklist(el, forkflag, requeueflag) CurEnv = &e; /* read the queue control file -- return if locked */ - if (readqf(&e)) + if (readqf(&e, false)) { e.e_flags |= EF_INQUEUE; eatheader(&e, requeueflag, true); @@ -3596,7 +3654,7 @@ doworklist(el, forkflag, requeueflag) /* finish up and exit */ if (forkflag) - finis(true, ExitStat); + finis(true, true, ExitStat); return 0; } /* @@ -3604,6 +3662,7 @@ doworklist(el, forkflag, requeueflag) ** ** Parameters: ** e -- the envelope of the job to run. +** openonly -- only open the qf (returned as e_lockfp) ** ** Returns: ** true if it successfully read the queue file. @@ -3614,8 +3673,9 @@ doworklist(el, forkflag, requeueflag) */ static bool -readqf(e) +readqf(e, openonly) register ENVELOPE *e; + bool openonly; { register SM_FILE_T *qfp; ADDRESS *ctladdr; @@ -3781,7 +3841,8 @@ readqf(e) if (tTd(40, 8)) sm_dprintf("readqf(%s): bogus file\n", qf); e->e_flags |= EF_INQUEUE; - loseqfile(e, "bogus file uid/gid in mqueue"); + if (!openonly) + loseqfile(e, "bogus file uid/gid in mqueue"); (void) sm_io_close(qfp, SM_TIME_DEFAULT); RELEASE_QUEUE; return false; @@ -3790,7 +3851,7 @@ readqf(e) if (st.st_size == 0) { /* must be a bogus file -- if also old, just remove it */ - if (st.st_ctime + 10 * 60 < curtime()) + if (!openonly && st.st_ctime + 10 * 60 < curtime()) { (void) xunlink(queuename(e, DATAFL_LETTER)); (void) xunlink(queuename(e, ANYQFL_LETTER)); @@ -3812,13 +3873,28 @@ readqf(e) return false; } +#if _FFR_TRUSTED_QF + /* + ** If we don't own the file mark it as unsafe. + ** However, allow TrustedUser to own it as well + ** in case TrustedUser manipulates the queue. + */ + + if (st.st_uid != geteuid() && st.st_uid != TrustedUid) + e->e_flags |= EF_UNSAFE; +#else /* _FFR_TRUSTED_QF */ /* If we don't own the file mark it as unsafe */ if (st.st_uid != geteuid()) e->e_flags |= EF_UNSAFE; +#endif /* _FFR_TRUSTED_QF */ /* good file -- save this lock */ e->e_lockfp = qfp; + /* Just wanted the open file */ + if (openonly) + return true; + /* do basic system initialization */ initsys(e); macdefine(&e->e_macro, A_PERM, 'i', e->e_id); @@ -3828,7 +3904,7 @@ readqf(e) set_op_mode(MD_QUEUERUN); ctladdr = NULL; #if _FFR_QUARANTINE - e->e_qfletter = qf[0]; + e->e_qfletter = queue_letter(e, ANYQFL_LETTER); #endif /* _FFR_QUARANTINE */ e->e_dfqgrp = e->e_qgrp; e->e_dfqdir = e->e_qdir; @@ -3979,10 +4055,10 @@ readqf(e) #endif /* _FFR_QUEUEDELAY */ #if _FFR_QUARANTINE - case 'h': /* hold message */ - e->e_holdmsg = sm_rpool_strdup_x(e->e_rpool, &bp[1]); + case 'q': /* quarantine reason */ + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, &bp[1]); macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), &bp[1]); + macid("{quarantine}"), e->e_quarmsg); break; #endif /* _FFR_QUARANTINE */ @@ -4207,6 +4283,15 @@ readqf(e) return true; } + /* Check to make sure we have a complete queue file read */ + if (!nomore) + { + syserr("readqf: %s: incomplete queue file read", qf); + (void) sm_io_close(qfp, SM_TIME_DEFAULT); + RELEASE_QUEUE; + return false; + } + /* possibly set ${dsn_ret} macro */ if (bitset(EF_RET_PARAM, e->e_flags)) { @@ -4263,7 +4348,7 @@ prtstr(s, ml) char *s; int ml; { - char c; + int c; if (s == NULL) return; @@ -4414,13 +4499,13 @@ printqueue() ** qdir -- the queue directory. ** ** Returns: -** none. +** number of requests in mail queue. ** ** Side Effects: ** Prints a listing of the mail queue on the standard output. */ -static int +int print_single_queue(qgrp, qdir) int qgrp; int qdir; @@ -4528,7 +4613,7 @@ print_single_queue(qgrp, qdir) int flags = 0; int qfver; #if _FFR_QUARANTINE - char holdmsg[MAXLINE]; + char quarmsg[MAXLINE]; #endif /* _FFR_QUARANTINE */ char statmsg[MAXLINE]; char bodytype[MAXNAME + 1]; @@ -4576,7 +4661,7 @@ print_single_queue(qgrp, qdir) e.e_qgrp = qgrp; e.e_qdir = qdir; dfsize = -1; - if (readqf(&e)) + if (readqf(&e, false)) { char *df = queuename(&e, DATAFL_LETTER); if (stat(df, &st) >= 0) @@ -4590,14 +4675,12 @@ print_single_queue(qgrp, qdir) clearenvelope(&e, false, e.e_rpool); sm_rpool_free(e.e_rpool); } + if (w->w_lock) + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "*"); #if _FFR_QUARANTINE - if (QueueMode == QM_LOST) + else if (QueueMode == QM_LOST) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "?"); - else if (QueueMode == QM_HELD) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "!"); #endif /* _FFR_QUARANTINE */ - if (w->w_lock) - (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "*"); else if (w->w_tooyoung) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "-"); else if (shouldqueue(w->w_pri, w->w_ctime)) @@ -4608,7 +4691,7 @@ print_single_queue(qgrp, qdir) errno = 0; #if _FFR_QUARANTINE - holdmsg[0] = '\0'; + quarmsg[0] = '\0'; #endif /* _FFR_QUARANTINE */ statmsg[0] = bodytype[0] = '\0'; qfver = 0; @@ -4635,11 +4718,11 @@ print_single_queue(qgrp, qdir) break; #if _FFR_QUARANTINE - case 'h': /* hold message */ - if ((i = strlen(&buf[1])) >= sizeof holdmsg) - i = sizeof holdmsg - 1; - memmove(holdmsg, &buf[1], i); - holdmsg[i] = '\0'; + case 'q': /* quarantine reason */ + if ((i = strlen(&buf[1])) >= sizeof quarmsg) + i = sizeof quarmsg - 1; + memmove(quarmsg, &buf[1], i); + quarmsg[i] = '\0'; break; #endif /* _FFR_QUARANTINE */ @@ -4673,14 +4756,14 @@ print_single_queue(qgrp, qdir) prtstr(&buf[1], 39); } #if _FFR_QUARANTINE - if (holdmsg[0] != '\0') + if (quarmsg[0] != '\0') { (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, - "\n ON HOLD: (%.*s)", + "\n QUARANTINE: %.*s", Verbose ? 100 : 60, - holdmsg); - holdmsg[0] = '\0'; + quarmsg); + quarmsg[0] = '\0'; } #endif /* _FFR_QUARANTINE */ if (statmsg[0] != '\0' || bodytype[0] != '\0') @@ -4764,8 +4847,10 @@ print_single_queue(qgrp, qdir) } return nrequests; } + +#if _FFR_QUARANTINE /* -** QUEUENAME -- build a file name in the queue directory for this envelope. +** QUEUE_LETTER -- get the proper queue letter for the current QueueMode. ** ** Parameters: ** e -- envelope to build it in/from. @@ -4773,34 +4858,19 @@ print_single_queue(qgrp, qdir) ** of the file name. ** ** Returns: -** a pointer to the queue name (in a static buffer). -** -** Side Effects: -** If no id code is already assigned, queuename() will -** assign an id code with assign_queueid(). If no queue -** directory is assigned, one will be set with setnewqueue(). +** the letter to use */ -char * -queuename(e, type) - register ENVELOPE *e; +static char +queue_letter(e, type) + ENVELOPE *e; int type; { - int qd, qg; - char *sub = "/"; - char pref[3]; - static char buf[MAXPATHLEN]; - - /* Assign an ID if needed */ - if (e->e_id == NULL) - assign_queueid(e); - -#if _FFR_QUARANTINE /* Change type according to QueueMode */ if (type == ANYQFL_LETTER) { - if (e->e_holdmsg != NULL) - type = HELDQF_LETTER; + if (e->e_quarmsg != NULL) + type = QUARQF_LETTER; else { switch (QueueMode) @@ -4809,8 +4879,8 @@ queuename(e, type) type = NORMQF_LETTER; break; - case QM_HELD: - type = HELDQF_LETTER; + case QM_QUARANTINE: + type = QUARQF_LETTER; break; case QM_LOST: @@ -4824,6 +4894,43 @@ queuename(e, type) } } } + return type; +} +#endif /* _FFR_QUARANTINE */ + +/* +** QUEUENAME -- build a file name in the queue directory for this envelope. +** +** Parameters: +** e -- envelope to build it in/from. +** type -- the file type, used as the first character +** of the file name. +** +** Returns: +** a pointer to the queue name (in a static buffer). +** +** Side Effects: +** If no id code is already assigned, queuename() will +** assign an id code with assign_queueid(). If no queue +** directory is assigned, one will be set with setnewqueue(). +*/ + +char * +queuename(e, type) + register ENVELOPE *e; + int type; +{ + int qd, qg; + char *sub = "/"; + char pref[3]; + static char buf[MAXPATHLEN]; + + /* Assign an ID if needed */ + if (e->e_id == NULL) + assign_queueid(e); + +#if _FFR_QUARANTINE + type = queue_letter(e, type); #endif /* _FFR_QUARANTINE */ /* begin of filename */ @@ -4832,7 +4939,7 @@ queuename(e, type) pref[2] = '\0'; /* Assign a queue group/directory if needed */ - if (type == XSCRPT_LETTER) + if (type == XSCRPT_LETTER) { /* ** We don't want to call setnewqueue() if we are fetching @@ -4892,7 +4999,7 @@ queuename(e, type) break; #if _FFR_QUARANTINE - case HELDQF_LETTER: + case QUARQF_LETTER: #endif /* _FFR_QUARANTINE */ case TEMPQF_LETTER: case NEWQFL_LETTER: @@ -6725,6 +6832,15 @@ makequeue(line, qdef) p = delimptr; } +#if !HASNICE + if (qg->qg_nice != NiceQueueRun) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Q%s: Warning: N= set on system that doesn't support nice()\n", + qg->qg_name); + } +#endif /* !HASNICE */ + /* do some rationality checking */ if (NumQueue >= MAXQUEUEGROUPS) { @@ -7073,7 +7189,7 @@ makeworkgroups() ** ** Side Effects: ** On success, the new data file is created. -** On failure, EF_FATALERRS is set in new->e_flags. +** On fatal failure, EF_FATALERRS is set in old->e_flags. */ static bool dup_df __P((ENVELOPE *, ENVELOPE *)); @@ -7100,7 +7216,7 @@ dup_df(old, new) if (r < 0 && errno != EINVAL) { syserr("@can't commit %s", opath); - new->e_flags |= EF_FATALERRS; + old->e_flags |= EF_FATALERRS; return false; } } @@ -7111,12 +7227,6 @@ dup_df(old, new) ** ** Don't waste time attempting a hard link unless old and new ** are on the same file system. - ** - ** We unlink the new file if it previously existed. This protects - ** us from abandoned data files left behind as a result of - ** a prior system crash. The envelope ids of these old files - ** can conflict with the envelope ids we are generating right now - ** if the clock was set back. */ ofs = Queue[old->e_qgrp]->qg_qpaths[old->e_qdir].qp_fsysidx; @@ -7129,21 +7239,7 @@ dup_df(old, new) SYNC_DIR(npath, true); return true; } - if (errno == EEXIST) - { - if (unlink(npath) < 0) - { - syserr("@can't unlink %s", npath); - new->e_flags |= EF_FATALERRS; - return false; - } - if (link(opath, npath) == 0) - { - new->e_flags |= EF_HAS_DF; - SYNC_DIR(npath, true); - return true; - } - } + goto error; } /* @@ -7161,23 +7257,12 @@ dup_df(old, new) SYNC_DIR(npath, true); return true; } - if (errno == EEXIST) - { - if (unlink(npath) < 0) - { - syserr("@can't unlink %s", npath); - new->e_flags |= EF_FATALERRS; - return false; - } - if (link(opath, npath) == 0) - { - new->e_flags |= EF_HAS_DF; - SYNC_DIR(npath, true); - return true; - } - } - syserr("@can't link %s to %s", opath, npath); - new->e_flags |= EF_FATALERRS; + + error: + if (LogLevel > 0) + sm_syslog(LOG_ERR, old->e_id, + "dup_df: can't link %s to %s, error=%s, envelope splitting failed", + opath, npath, sm_errstring(errno)); return false; } @@ -7224,6 +7309,11 @@ split_env(e, sendqueue, qgrp, qdir) ee->e_qdir = ee->e_dfqdir = qdir; ee->e_errormode = EM_MAIL; ee->e_statmsg = NULL; +#if _FFR_QUARANTINE + if (e->e_quarmsg != NULL) + ee->e_quarmsg = sm_rpool_strdup_x(ee->e_rpool, + e->e_quarmsg); +#endif /* _FFR_QUARANTINE */ /* ** XXX Not sure if this copying is necessary. @@ -7263,8 +7353,7 @@ split_env(e, sendqueue, qgrp, qdir) ** additional envelopes, and the associated data files exist ** on disk. But the queue files are not created. ** -** On failure, e->e_flags & EF_FATALERRS is set. -** e->e_sibling is not changed. +** On failure, e->e_sibling is not changed. ** The order of recipients in e->e_sendqueue is permuted. ** Abandoned data files for additional envelopes that failed ** to be created may exist on disk. @@ -7422,7 +7511,10 @@ split_across_queue_groups(e) /* create data files for each additional envelope */ if (!dup_df(e, splits[0])) + { + i = 0; goto failure; + } for (i = 1; i < nsplits; ++i) { /* copy or link to the previous data file */ @@ -7441,7 +7533,13 @@ split_across_queue_groups(e) /* failure: clean up */ failure: - e->e_flags |= EF_FATALERRS; + if (i > 0) + { + int j; + + for (j = 0; j < i; j++) + (void) unlink(queuename(splits[j], DATAFL_LETTER)); + } e->e_sendqueue = addrs[0]; for (i = 0; i < naddrs - 1; ++i) addrs[i]->q_next = addrs[i + 1]; @@ -7573,6 +7671,14 @@ split_within_queue(e) ee = split_env(e, addrs[i], e->e_qgrp, e->e_qdir); if (!dup_df(e, ee)) { + + ee = firstsibling; + while (ee != NULL) + { + (void) unlink(queuename(ee, DATAFL_LETTER)); + ee = ee->e_sibling; + } + /* Error. Restore e's sibling & recipient lists. */ e->e_sibling = firstsibling; for (i = 0; i < nrcpt - 1; ++i) @@ -7724,3 +7830,478 @@ split_by_recipient(e) e->e_flags |= EF_SPLIT; return split; } + +#if _FFR_QUARANTINE +/* +** QUARANTINE_QUEUE_ITEM -- {un,}quarantine a single envelope +** +** Add/remove quarantine reason and requeue appropriately. +** +** Parameters: +** qgrp -- queue group for the item +** qdir -- queue directory in the given queue group +** e -- envelope information for the item +** reason -- quarantine reason, NULL means unquarantine. +** +** Results: +** true if item changed, false otherwise +** +** Side Effects: +** Changes quarantine tag in queue file and renames it. +*/ + +static bool +quarantine_queue_item(qgrp, qdir, e, reason) + int qgrp; + int qdir; + ENVELOPE *e; + char *reason; +{ + bool dirty = false; + bool failing = false; + bool foundq = false; + bool finished = false; + int fd; + int flags; + int oldtype; + int newtype; + int save_errno; + MODE_T oldumask = 0; + SM_FILE_T *oldqfp, *tempqfp; + char *bp; + char oldqf[MAXPATHLEN]; + char tempqf[MAXPATHLEN]; + char newqf[MAXPATHLEN]; + char buf[MAXLINE]; + + oldtype = queue_letter(e, ANYQFL_LETTER); + (void) sm_strlcpy(oldqf, queuename(e, ANYQFL_LETTER), sizeof oldqf); + (void) sm_strlcpy(tempqf, queuename(e, NEWQFL_LETTER), sizeof tempqf); + + /* + ** Instead of duplicating all the open + ** and lock code here, tell readqf() to + ** do that work and return the open + ** file pointer in e_lockfp. Note that + ** we must release the locks properly when + ** we are done. + */ + + if (!readqf(e, true)) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Skipping %s\n", qid_printname(e)); + return false; + } + oldqfp = e->e_lockfp; + + /* open the new queue file */ + flags = O_CREAT|O_WRONLY|O_EXCL; + if (bitset(S_IWGRP, QueueFileMode)) + oldumask = umask(002); + fd = open(tempqf, flags, QueueFileMode); + if (bitset(S_IWGRP, QueueFileMode)) + (void) umask(oldumask); + RELEASE_QUEUE; + + if (fd < 0) + { + save_errno = errno; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Skipping %s: Could not open %s: %s\n", + qid_printname(e), tempqf, + sm_errstring(save_errno)); + (void) sm_io_close(oldqfp, SM_TIME_DEFAULT); + return false; + } + if (!lockfile(fd, tempqf, NULL, LOCK_EX|LOCK_NB)) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Skipping %s: Could not lock %s\n", + qid_printname(e), tempqf); + (void) close(fd); + (void) sm_io_close(oldqfp, SM_TIME_DEFAULT); + return false; + } + + tempqfp = sm_io_open(SmFtStdiofd, SM_TIME_DEFAULT, (void *) &fd, + SM_IO_WRONLY, NULL); + if (tempqfp == NULL) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Skipping %s: Could not lock %s\n", + qid_printname(e), tempqf); + (void) close(fd); + (void) sm_io_close(oldqfp, SM_TIME_DEFAULT); + return false; + } + + /* Copy the data over, changing the quarantine reason */ + while ((bp = fgetfolded(buf, sizeof buf, oldqfp)) != NULL) + { + if (tTd(40, 4)) + sm_dprintf("+++++ %s\n", bp); + switch (bp[0]) + { + case 'q': /* quarantine reason */ + foundq = true; + if (reason == NULL) + { + if (Verbose) + { + (void) sm_io_fprintf(smioout, + SM_TIME_DEFAULT, + "%s: Removed quarantine of \"%s\"\n", + e->e_id, &bp[1]); + } + sm_syslog(LOG_INFO, e->e_id, "unquarantine"); + dirty = true; + continue; + } + else if (strcmp(reason, &bp[1]) == 0) + { + if (Verbose) + { + (void) sm_io_fprintf(smioout, + SM_TIME_DEFAULT, + "%s: Already quarantined with \"%s\"\n", + e->e_id, reason); + } + (void) sm_io_fprintf(tempqfp, SM_TIME_DEFAULT, + "q%s\n", reason); + } + else + { + if (Verbose) + { + (void) sm_io_fprintf(smioout, + SM_TIME_DEFAULT, + "%s: Quarantine changed from \"%s\" to \"%s\"\n", + e->e_id, &bp[1], + reason); + } + (void) sm_io_fprintf(tempqfp, SM_TIME_DEFAULT, + "q%s\n", reason); + sm_syslog(LOG_INFO, e->e_id, "quarantine=%s", + reason); + dirty = true; + } + break; + + case 'R': + /* + ** If we are quarantining an unquarantined item, + ** need to put in a new 'q' line before it's + ** too late. + */ + + if (!foundq && reason != NULL) + { + if (Verbose) + { + (void) sm_io_fprintf(smioout, + SM_TIME_DEFAULT, + "%s: Quarantined with \"%s\"\n", + e->e_id, reason); + } + (void) sm_io_fprintf(tempqfp, SM_TIME_DEFAULT, + "q%s\n", reason); + sm_syslog(LOG_INFO, e->e_id, "quarantine=%s", + reason); + foundq = true; + dirty = true; + } + + /* Copy the line to the new file */ + (void) sm_io_fprintf(tempqfp, SM_TIME_DEFAULT, + "%s\n", bp); + break; + + case '.': + finished = true; + /* FALLTHROUGH */ + + default: + /* Copy the line to the new file */ + (void) sm_io_fprintf(tempqfp, SM_TIME_DEFAULT, + "%s\n", bp); + break; + } + } + + /* Make sure we read the whole old file */ + errno = sm_io_error(tempqfp); + if (errno != 0 && errno != SM_IO_EOF) + { + save_errno = errno; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Skipping %s: Error reading %s: %s\n", + qid_printname(e), oldqf, + sm_errstring(save_errno)); + failing = true; + } + + if (!failing && !finished) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Skipping %s: Incomplete file: %s\n", + qid_printname(e), oldqf); + failing = true; + } + + /* Check if we actually changed anything or we can just bail now */ + if (!dirty) + { + /* pretend we failed, even though we technically didn't */ + failing = true; + } + + /* Make sure we wrote things out safely */ + if (!failing && + (sm_io_flush(tempqfp, SM_TIME_DEFAULT) != 0 || + ((SuperSafe == SAFE_REALLY || SuperSafe == SAFE_INTERACTIVE) && + fsync(sm_io_getinfo(tempqfp, SM_IO_WHAT_FD, NULL)) < 0) || + ((errno = sm_io_error(tempqfp)) != 0))) + { + save_errno = errno; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Skipping %s: Error writing %s: %s\n", + qid_printname(e), tempqf, + sm_errstring(save_errno)); + failing = true; + } + + + /* Figure out the new filename */ + newtype = (reason == NULL ? NORMQF_LETTER : QUARQF_LETTER); + if (oldtype == newtype) + { + /* going to rename tempqf to oldqf */ + (void) sm_strlcpy(newqf, oldqf, sizeof newqf); + } + else + { + /* going to rename tempqf to new name based on newtype */ + (void) sm_strlcpy(newqf, queuename(e, newtype), sizeof newqf); + } + + save_errno = 0; + + /* rename tempqf to newqf */ + if (!failing && + rename(tempqf, newqf) < 0) + save_errno = (errno == 0) ? EINVAL : errno; + + /* Check rename() success */ + if (!failing && save_errno != 0) + { + sm_syslog(LOG_DEBUG, e->e_id, + "quarantine_queue_item: rename(%s, %s): %s", + tempqf, newqf, sm_errstring(save_errno)); + + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Error renaming %s to %s: %s\n", + tempqf, newqf, + sm_errstring(save_errno)); + if (oldtype == newtype) + { + /* + ** Bail here since we don't know the state of + ** the filesystem and may need to keep tempqf + ** for the user to rescue us. + */ + + RELEASE_QUEUE; + errno = save_errno; + syserr("!452 Error renaming control file %s", tempqf); + /* NOTREACHED */ + } + else + { + /* remove new file (if rename() half completed) */ + if (xunlink(newqf) < 0) + { + save_errno = errno; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Error removing %s: %s\n", + newqf, + sm_errstring(save_errno)); + } + + /* tempqf removed below */ + failing = true; + } + + } + + /* If changing file types, need to remove old type */ + if (!failing && oldtype != newtype) + { + if (xunlink(oldqf) < 0) + { + save_errno = errno; + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Error removing %s: %s\n", + oldqf, sm_errstring(save_errno)); + } + } + + /* see if anything above failed */ + if (failing) + { + /* Something failed: remove new file, old file still there */ + (void) xunlink(tempqf); + } + + /* + ** fsync() after file operations to make sure metadata is + ** written to disk on filesystems in which renames are + ** not guaranteed. It's ok if they fail, mail won't be lost. + */ + + if (SuperSafe != SAFE_NO) + { + /* for soft-updates */ + (void) fsync(sm_io_getinfo(tempqfp, + SM_IO_WHAT_FD, NULL)); + + if (!failing) + { + /* for soft-updates */ + (void) fsync(sm_io_getinfo(oldqfp, + SM_IO_WHAT_FD, NULL)); + } + + /* for other odd filesystems */ + SYNC_DIR(tempqf, false); + } + + /* Close up shop */ + RELEASE_QUEUE; + if (tempqfp != NULL) + (void) sm_io_close(tempqfp, SM_TIME_DEFAULT); + if (oldqfp != NULL) + (void) sm_io_close(oldqfp, SM_TIME_DEFAULT); + + /* All went well */ + return !failing; +} + +/* +** QUARANTINE_QUEUE -- {un,}quarantine matching items in the queue +** +** Read all matching queue items, add/remove quarantine +** reason, and requeue appropriately. +** +** Parameters: +** reason -- quarantine reason, "." means unquarantine. +** qgrplimit -- limit to single queue group unless NOQGRP +** +** Results: +** none. +** +** Side Effects: +** Lots of changes to the queue. +*/ + +void +quarantine_queue(reason, qgrplimit) + char *reason; + int qgrplimit; +{ + int changed = 0; + int qgrp; + + /* Convert internal representation of unquarantine */ + if (reason != NULL && reason[0] == '.' && reason[1] == '\0') + reason = NULL; + + if (reason != NULL) + { + /* clean it */ + reason = newstr(denlstring(reason, true, true)); + } + + for (qgrp = 0; qgrp < NumQueue && Queue[qgrp] != NULL; qgrp++) + { + int qdir; + + if (qgrplimit != NOQGRP && qgrplimit != qgrp) + continue; + + for (qdir = 0; qdir < Queue[qgrp]->qg_numqueues; qdir++) + { + int i; + int nrequests; + + if (StopRequest) + stop_sendmail(); + + nrequests = gatherq(qgrp, qdir, true, NULL, NULL); + + /* first see if there is anything */ + if (nrequests <= 0) + { + if (Verbose) + { + (void) sm_io_fprintf(smioout, + SM_TIME_DEFAULT, "%s: no matches\n", + qid_printqueue(qgrp, qdir)); + } + continue; + } + + if (Verbose) + { + (void) sm_io_fprintf(smioout, + SM_TIME_DEFAULT, "Processing %s:\n", + qid_printqueue(qgrp, qdir)); + } + + for (i = 0; i < WorkListCount; i++) + { + ENVELOPE e; + + if (StopRequest) + stop_sendmail(); + + /* setup envelope */ + clearenvelope(&e, true, sm_rpool_new_x(NULL)); + e.e_id = WorkList[i].w_name + 2; + e.e_qgrp = qgrp; + e.e_qdir = qdir; + + if (tTd(70, 101)) + { + sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Would do %s\n", e.e_id); + changed++; + } + else if (quarantine_queue_item(qgrp, qdir, + &e, reason)) + changed++; + + /* clean up */ + sm_rpool_free(e.e_rpool); + e.e_rpool = NULL; + } + if (WorkList != NULL) + sm_free(WorkList); /* XXX */ + WorkList = NULL; + WorkListSize = 0; + WorkListCount = 0; + } + } + if (Verbose) + { + if (changed == 0) + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "No changes\n"); + else + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "%d change%s\n", + changed, + changed == 1 ? "" : "s"); + } +} +#endif /* _FFR_QUARANTINE */ diff --git a/gnu/usr.sbin/sendmail/sendmail/readcf.c b/gnu/usr.sbin/sendmail/sendmail/readcf.c index 0309821a089..6609b4a6881 100644 --- a/gnu/usr.sbin/sendmail/sendmail/readcf.c +++ b/gnu/usr.sbin/sendmail/sendmail/readcf.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: readcf.c,v 8.587 2001/09/22 20:48:35 ca Exp $") +SM_RCSID("@(#)$Sendmail: readcf.c,v 8.594 2001/12/14 00:43:17 gshapiro Exp $") #if NETINET || NETINET6 # include <arpa/inet.h> @@ -115,19 +115,19 @@ readcf(cfname, safe, e) if (cf == NULL) { syserr("cannot open"); - finis(false, EX_OSFILE); + finis(false, true, EX_OSFILE); } if (fstat(sm_io_getinfo(cf, SM_IO_WHAT_FD, NULL), &statb) < 0) { syserr("cannot fstat"); - finis(false, EX_OSFILE); + finis(false, true, EX_OSFILE); } if (!S_ISREG(statb.st_mode)) { syserr("not a plain file"); - finis(false, EX_OSFILE); + finis(false, true, EX_OSFILE); } if (OpMode != MD_TEST && bitset(S_IWGRP|S_IWOTH, statb.st_mode)) @@ -613,7 +613,7 @@ readcf(cfname, safe, e) if (sm_io_error(cf)) { syserr("I/O read error"); - finis(false, EX_OSFILE); + finis(false, true, EX_OSFILE); } (void) sm_io_close(cf, SM_TIME_DEFAULT); FileName = NULL; @@ -977,6 +977,8 @@ fileclass(class, filename, fmt, safe, optional) sff |= SFF_NOWLINK; if (safe) sff |= SFF_OPENASROOT; + else if (RealUid == 0) + sff |= SFF_ROOTOK; if (DontLockReadFiles) sff |= SFF_NOLOCK; f = safefopen(filename, O_RDONLY, 0, sff); @@ -1344,6 +1346,24 @@ makemailer(line) p = delimptr; } +#if !HASRRESVPORT + if (bitnset(M_SECURE_PORT, m->m_flags)) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "M%s: Warning: F=%c set on system that doesn't support rresvport()\n", + m->m_name, M_SECURE_PORT); + } +#endif /* !HASRRESVPORT */ + +#if !HASNICE + if (m->m_nice != 0) + { + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "M%s: Warning: N= set on system that doesn't support nice()\n", + m->m_name); + } +#endif /* !HASNICE */ + /* do some rationality checking */ if (m->m_argv == NULL) { @@ -1376,8 +1396,7 @@ makemailer(line) if (strcmp(m->m_mailer, "[TCP]") == 0) { - syserr("M%s: P=[TCP] must be replaced by P=[IPC]\n", - m->m_name); + syserr("M%s: P=[TCP] must be replaced by P=[IPC]", m->m_name); return; } @@ -1838,6 +1857,9 @@ static struct optioninfo { "TempFileMode", 'F', OI_NONE }, { "SaveFromLine", 'f', OI_NONE }, { "MatchGECOS", 'G', OI_NONE }, + + /* no long name, just here to avoid problems in setoption */ + { "", 'g', OI_NONE }, { "HelpFile", 'H', OI_NONE }, { "MaxHopCount", 'h', OI_NONE }, { "ResolverOptions", 'I', OI_NONE }, @@ -1849,6 +1871,9 @@ static struct optioninfo { "UseErrorsTo", 'l', OI_NONE }, { "LogLevel", 'L', OI_SAFE }, { "MeToo", 'm', OI_SAFE }, + + /* no long name, just here to avoid problems in setoption */ + { "", 'M', OI_NONE }, { "CheckAliases", 'n', OI_NONE }, { "OldStyleHeaders", 'o', OI_SAFE }, { "DaemonPortOptions", 'O', OI_NONE }, @@ -2255,7 +2280,7 @@ setoption(opt, val, safe, sticky, e) default: syserr("Unknown 8-bit mode %c", *val); - finis(false, EX_USAGE); + finis(false, true, EX_USAGE); } #else /* MIME8TO7 */ (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, @@ -2323,7 +2348,7 @@ setoption(opt, val, safe, sticky, e) default: syserr("Unknown delivery mode %c", *val); - finis(false, EX_USAGE); + finis(false, true, EX_USAGE); } break; @@ -2611,7 +2636,11 @@ setoption(opt, val, safe, sticky, e) case 'u': /* set default uid */ for (p = val; *p != '\0'; p++) { +#if _FFR_DOTTED_USERNAMES + if (*p == '/' || *p == ':') +#else /* _FFR_DOTTED_USERNAMES */ if (*p == '.' || *p == '/' || *p == ':') +#endif /* _FFR_DOTTED_USERNAMES */ { *p++ = '\0'; break; @@ -2848,6 +2877,10 @@ setoption(opt, val, safe, sticky, e) break; case O_NICEQUEUERUN: /* nice queue runs */ +#if !HASNICE + (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, + "Warning: NiceQueueRun set on system that doesn't support nice()\n"); +#endif /* !HASNICE */ /* XXX do we want to check the range? > 0 ? */ NiceQueueRun = atoi(val); @@ -2943,7 +2976,11 @@ setoption(opt, val, safe, sticky, e) case O_RUNASUSER: /* run bulk of code as this user */ for (p = val; *p != '\0'; p++) { +#if _FFR_DOTTED_USERNAMES + if (*p == '/' || *p == ':') +#else /* _FFR_DOTTED_USERNAMES */ if (*p == '.' || *p == '/' || *p == ':') +#endif /* _FFR_DOTTED_USERNAMES */ { *p++ = '\0'; break; @@ -3127,11 +3164,11 @@ setoption(opt, val, safe, sticky, e) break; case O_TRUSTUSER: -# if !HASFCHOWN +# if !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) if (!UseMSP) (void) sm_io_fprintf(smioout, SM_TIME_DEFAULT, "readcf: option TrustedUser may cause problems on systems\n which do not support fchown() if UseMSP is not set.\n"); -# endif /* !HASFCHOWN */ +# endif /* !HASFCHOWN && !defined(_FFR_DROP_TRUSTUSER_WARNING) */ if (isascii(*val) && isdigit(*val)) TrustedUid = atoi(val); else diff --git a/gnu/usr.sbin/sendmail/sendmail/recipient.c b/gnu/usr.sbin/sendmail/sendmail/recipient.c index fc21bb54762..71987aab4dd 100644 --- a/gnu/usr.sbin/sendmail/sendmail/recipient.c +++ b/gnu/usr.sbin/sendmail/sendmail/recipient.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: recipient.c,v 8.325 2001/09/11 04:05:16 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: recipient.c,v 8.327 2001/11/20 13:59:53 ca Exp $") static void includetimeout __P((void)); static ADDRESS *self_reference __P((ADDRESS *)); @@ -151,9 +151,6 @@ sortbysignature(xx, yy) ** ** Returns: ** The number of addresses actually on the list. -** -** Side Effects: -** none. */ /* q_flags bits inherited from ctladdr */ @@ -785,6 +782,9 @@ recipient(new, sendq, aliaslevel, e) *pq = new; } + /* added a new address: clear split flag */ + e->e_flags &= ~EF_SPLIT; + /* ** Alias the name and handle special mailer types. */ @@ -1399,7 +1399,6 @@ include(fname, forwarding, ctladdr, sendq, aliaslevel, e) register char *p; bool safechown = false; volatile bool safedir = false; - bool oldsplit; struct stat st; char buf[MAXLINE]; @@ -1784,8 +1783,6 @@ resetuid: LineNumber = 0; ctladdr->q_flags &= ~QSELFREF; nincludes = 0; - oldsplit = bitset(EF_SPLIT, e->e_flags); - e->e_flags &= ~EF_SPLIT; while (sm_io_fgets(fp, SM_TIME_DEFAULT, buf, sizeof buf) != NULL && !maxreached) { @@ -1833,7 +1830,7 @@ resetuid: ctladdr->q_state = QS_DONTSEND; #endif /* 0 */ - syserr("Attempt to forward to more then %d addresses (in %s)!", + syserr("Attempt to forward to more than %d addresses (in %s)!", MaxForwardEntries,fname); maxreached = true; } @@ -1851,10 +1848,6 @@ resetuid: ctladdr->q_state = QS_DONTSEND; } - /* if nothing included: restore old split flag */ - if (nincludes <= 0 && oldsplit) - e->e_flags |= EF_SPLIT; - (void) sm_io_close(fp, SM_TIME_DEFAULT); FileName = oldfilename; LineNumber = oldlinenumber; diff --git a/gnu/usr.sbin/sendmail/sendmail/savemail.c b/gnu/usr.sbin/sendmail/sendmail/savemail.c index 8240a98347f..34e5c84b547 100644 --- a/gnu/usr.sbin/sendmail/sendmail/savemail.c +++ b/gnu/usr.sbin/sendmail/sendmail/savemail.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: savemail.c,v 8.291 2001/09/11 04:05:16 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: savemail.c,v 8.297 2001/12/28 22:32:19 ca Exp $") static void errbody __P((MCI *, ENVELOPE *, char *)); static bool pruneroute __P((char *)); @@ -32,7 +32,8 @@ static bool pruneroute __P((char *)); ** message; otherwise just send the header. ** ** Returns: -** true if the data file should be preserved by dropenvelope() +** true if savemail panic'ed, (i.e., the data file should +** be preserved by dropenvelope()) ** ** Side Effects: ** Saves the letter, by writing or mailing it back to the @@ -56,7 +57,7 @@ savemail(e, sendbody) bool sendbody; { register SM_FILE_T *fp; - bool savedf = false; + bool panic = false; int state; auto ADDRESS *q = NULL; register char *p; @@ -78,7 +79,7 @@ savemail(e, sendbody) if (e->e_id == NULL) { /* can't return a message with no id */ - return savedf; + return panic; } /* @@ -94,7 +95,7 @@ savemail(e, sendbody) '\0', NULL, e, false) == NULL) { syserr("553 5.3.5 Cannot parse Postmaster!"); - finis(true, EX_SOFTWARE); + finis(true, true, EX_SOFTWARE); } } e->e_to = NULL; @@ -134,10 +135,10 @@ savemail(e, sendbody) case EM_QUIET: /* no need to return anything at all */ - return savedf; + return panic; default: - syserr("554 5.3.0 savemail: bogus errormode x%x\n", + syserr("554 5.3.0 savemail: bogus errormode x%x", e->e_errormode); state = ESM_MAIL; break; @@ -150,7 +151,7 @@ savemail(e, sendbody) bitset(EF_RESPONSE, e->e_parent->e_flags)) { /* got an error sending a response -- can it */ - return savedf; + return panic; } state = ESM_POSTMASTER; } @@ -250,17 +251,9 @@ savemail(e, sendbody) break; } - if (!DontPruneRoutes && pruneroute(from)) - { - ADDRESS *a; - - for (a = e->e_errorqueue; a != NULL; - a = a->q_next) - { - if (sameaddr(a, &e->e_from)) - a->q_state = QS_DUPLICATE; - } - } + if (!DontPruneRoutes) + (void) pruneroute(from); + (void) sendtolist(from, NULLADDR, &e->e_errorqueue, 0, e); } @@ -467,14 +460,14 @@ savemail(e, sendbody) case ESM_PANIC: /* leave the locked queue & transcript files around */ loseqfile(e, "savemail panic"); - savedf = true; + panic = true; errno = 0; syserr("554 savemail: cannot save rejected email anywhere"); state = ESM_DONE; break; } } - return savedf; + return panic; } /* ** RETURNTOSENDER -- return a message to the sender with an error. @@ -497,7 +490,7 @@ savemail(e, sendbody) */ #define MAXRETURNS 6 /* max depth of returning messages */ -#define ERRORFUDGE 100 /* nominal size of error message text */ +#define ERRORFUDGE 1024 /* nominal size of error message text */ int returntosender(msg, returnq, flags, e) @@ -591,10 +584,10 @@ returntosender(msg, returnq, flags, e) } ee->e_sendqueue = returnq; - ee->e_msgsize = ERRORFUDGE; + ee->e_msgsize = 0; if (bitset(RTSF_SEND_BODY, flags) && !bitset(PRIV_NOBODYRETN, PrivacyFlags)) - ee->e_msgsize += e->e_msgsize; + ee->e_msgsize = ERRORFUDGE + e->e_msgsize; else ee->e_flags |= EF_NO_BODY_RETN; @@ -717,7 +710,7 @@ returntosender(msg, returnq, flags, e) eatheader(ee, true, true); /* mark statistics */ - markstats(ee, NULLADDR, false); + markstats(ee, NULLADDR, STATS_NORMAL); /* actually deliver the error message */ sendall(ee, SM_DELIVER); diff --git a/gnu/usr.sbin/sendmail/sendmail/sendmail.h b/gnu/usr.sbin/sendmail/sendmail/sendmail.h index 4d0ba670cbe..27d86e5fa1f 100644 --- a/gnu/usr.sbin/sendmail/sendmail/sendmail.h +++ b/gnu/usr.sbin/sendmail/sendmail/sendmail.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -48,7 +48,7 @@ #ifdef _DEFINE # ifndef lint -SM_UNUSED(static char SmailId[]) = "@(#)$Sendmail: sendmail.h,v 8.883 2001/09/25 18:59:53 ca Exp $"; +SM_UNUSED(static char SmailId[]) = "@(#)$Sendmail: sendmail.h,v 8.902 2002/01/09 00:10:11 ca Exp $"; # endif /* ! lint */ #endif /* _DEFINE */ @@ -65,6 +65,7 @@ SM_UNUSED(static char SmailId[]) = "@(#)$Sendmail: sendmail.h,v 8.883 2001/09/25 #include <sm/mbdb.h> #include <sm/errstring.h> #include <sm/sysexits.h> +#include <sm/shm.h> #ifdef LOG # include <syslog.h> @@ -857,7 +858,7 @@ struct envelope * readonly. NULL or allocated from * e_rpool. */ #if _FFR_QUARANTINE - char *e_holdmsg; /* why envelope is quarantined */ + char *e_quarmsg; /* why envelope is quarantined */ char e_qfletter; /* queue file letter on disk */ #endif /* _FFR_QUARANTINE */ char *e_msgboundary; /* MIME-style message part boundary */ @@ -1173,14 +1174,14 @@ MAP #define MF_ALIASWAIT 0x00000800 /* alias map in aliaswait state */ #define MF_IMPL_HASH 0x00001000 /* implicit: underlying hash database */ #define MF_IMPL_NDBM 0x00002000 /* implicit: underlying NDBM database */ -#define MF_UNSAFEDB 0x00004000 /* this map is world writable */ +/* 0x00004000 */ #define MF_APPEND 0x00008000 /* append new entry on rebuild */ #define MF_KEEPQUOTES 0x00010000 /* don't dequote key before lookup */ #define MF_NODEFER 0x00020000 /* don't defer if map lookup fails */ #define MF_REGEX_NOT 0x00040000 /* regular expression negation */ #define MF_DEFER 0x00080000 /* don't lookup map in defer mode */ #define MF_SINGLEMATCH 0x00100000 /* successful only if match one key */ -#define MF_NOREWRITE 0x00200000 /* don't rewrite result, return as-is */ +/* 0x00200000 available for use */ #define MF_FILECLASS 0x00400000 /* this is a file class map */ #define MF_OPENBOGUS 0x00800000 /* open failed, don't call map_close */ #define MF_CLOSING 0x01000000 /* map is being closed */ @@ -1322,7 +1323,7 @@ typedef struct ph_map_struct PH_MAP_STRUCT; extern void proc_list_add __P((pid_t, char *, int, int, int)); extern void proc_list_clear __P((void)); extern void proc_list_display __P((SM_FILE_T *, char *)); -extern int proc_list_drop __P((pid_t, int *, int *)); +extern void proc_list_drop __P((pid_t, int, int *)); extern void proc_list_probe __P((void)); extern void proc_list_set __P((pid_t, char *)); extern void proc_list_signal __P((int, int)); @@ -1334,8 +1335,7 @@ extern void proc_list_signal __P((int, int)); struct symtab { char *s_name; /* name to be entered */ - short s_type; /* general type (see below) */ - short s_len; /* length of this entry */ + short s_symtype; /* general type (see below) */ struct symtab *s_next; /* pointer to next in chain */ union { @@ -1682,6 +1682,7 @@ typedef SM_INT32 mi_int32; #define VENDOR_HP 3 /* Hewlett-Packard specific config syntax */ #define VENDOR_IBM 4 /* IBM specific config syntax */ #define VENDOR_SENDMAIL 5 /* Sendmail, Inc. specific config syntax */ +#define VENDOR_DEC 6 /* Compaq, DEC, Digital */ /* prototypes for vendor-specific hook routines */ extern void vendor_daemon_setup __P((ENVELOPE *)); @@ -1809,7 +1810,7 @@ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ /* queue file names */ #if _FFR_QUARANTINE # define ANYQFL_LETTER '?' -# define HELDQF_LETTER 'h' +# define QUARQF_LETTER 'h' #else /* _FFR_QUARANTINE */ /* Before quarantining, ANYQF == NORMQF */ # define ANYQFL_LETTER 'q' @@ -1857,9 +1858,9 @@ EXTERN unsigned long TLS_Srv_Opts; /* TLS server options */ #if _FFR_QUARANTINE /* QueueMode bits */ -# define QM_NORMAL 0x0001 -# define QM_HELD 0x0002 -# define QM_LOST 0x0004 +# define QM_NORMAL ' ' +# define QM_QUARANTINE 'Q' +# define QM_LOST 'L' #endif /* _FFR_QUARANTINE */ /* Queue Run Limitations */ @@ -1893,7 +1894,7 @@ EXTERN time_t QueueMaxDelay; /* maximum queue delay */ #endif /* _FFR_QUEUEDELAY */ EXTERN QUEUE_CHAR *QueueLimitId; /* limit queue run to id */ #if _FFR_QUARANTINE -EXTERN QUEUE_CHAR *QueueLimitReason; /* limit queue run to rcpt */ +EXTERN QUEUE_CHAR *QueueLimitQuarantine; /* limit queue run to quarantine reason */ #endif /* _FFR_QUARANTINE */ EXTERN QUEUE_CHAR *QueueLimitRecipient; /* limit queue run to rcpt */ EXTERN QUEUE_CHAR *QueueLimitSender; /* limit queue run to sender */ @@ -1909,6 +1910,9 @@ extern void loseqfile __P((ENVELOPE *, char *)); extern int name2qid __P((char *)); extern char *qid_printname __P((ENVELOPE *)); extern char *qid_printqueue __P((int, int)); +#if _FFR_QUARANTINE +extern void quarantine_queue __P((char *, int)); +#endif /* _FFR_QUARANTINE */ extern char *queuename __P((ENVELOPE *, int)); extern void queueup __P((ENVELOPE *, bool, bool)); extern bool runqueue __P((bool, bool, bool, bool)); @@ -1918,6 +1922,7 @@ extern void setup_queues __P((bool)); extern bool setnewqueue __P((ENVELOPE *)); extern bool shouldqueue __P((long, time_t)); extern void sync_queue_time __P((void)); +extern int print_single_queue __P((int, int)); #if REQUIRES_DIR_FSYNC # define SYNC_DIR(path, panic) sync_dir(path, panic) extern void sync_dir __P((char *, bool)); @@ -1997,6 +2002,7 @@ extern void inittimeouts __P((char *, bool)); /* variables */ extern unsigned char tTdvect[100]; /* trace vector */ + /* ** Miscellaneous information. */ @@ -2302,7 +2308,13 @@ extern int mailfile __P((char *volatile, MAILER *volatile, ADDRESS *, volatile l extern void sendall __P((ENVELOPE *, int)); /* stats */ -extern void markstats __P((ENVELOPE *, ADDRESS *, bool)); +#define STATS_NORMAL 'n' +#if _FFR_QUARANTINE +# define STATS_QUARANTINE 'q' +#endif /* _FFR_QUARANTINE */ +#define STATS_REJECT 'r' + +extern void markstats __P((ENVELOPE *, ADDRESS *, int)); extern void clearstats __P((void)); extern void poststats __P((char *)); @@ -2376,7 +2388,7 @@ extern char *fgetfolded __P((char *, int, SM_FILE_T *)); extern void fill_fd __P((int, char *)); extern char *find_character __P((char *, int)); extern int finduser __P((char *, bool *, SM_MBDB_T *)); -extern void finis __P((bool, volatile int)); +extern void finis __P((bool, bool, volatile int)); extern void fixcrlf __P((char *, bool)); extern long freediskspace __P((char *, long *)); #if NETINET6 && NEEDSGETIPNODE @@ -2459,7 +2471,7 @@ extern pid_t sm_wait __P((int *)); extern bool split_by_recipient __P((ENVELOPE *e)); extern void stop_sendmail __P((void)); extern char *str2prt __P((char *)); -extern bool strcontainedin __P((char *, char *)); +extern bool strcontainedin __P((bool, char *, char *)); extern int switch_map_find __P((char *, char *[], short [])); extern bool transienterror __P((int)); #if _FFR_BESTMX_BETTER_TRUNCATION || _FFR_DNSMAP_MULTI diff --git a/gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c b/gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c index b29b3912f7e..9249a509c84 100644 --- a/gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c +++ b/gnu/usr.sbin/sendmail/sendmail/srvrsmtp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -16,7 +16,7 @@ # include <libmilter/mfdef.h> #endif /* MILTER */ -SM_RCSID("@(#)$Sendmail: srvrsmtp.c,v 8.795 2001/09/25 19:57:10 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: srvrsmtp.c,v 8.814 2002/01/08 00:56:22 ca Exp $") #if SASL || STARTTLS # include <sys/time.h> @@ -197,8 +197,9 @@ static SM_DEBUG_T DebugLeakSmtp = SM_DEBUG_INITIALIZER("leak_smtp", typedef struct { bool sm_gotmail; /* mail command received */ - unsigned int sm_nrcpts; /* number of RCPT commands */ + unsigned int sm_nrcpts; /* number of successful RCPT commands */ #if _FFR_ADAPTIVE_EOL +WARNING: do NOT use this FFR, it is most likely broken bool sm_crlf; /* input in CRLF form? */ #endif /* _FFR_ADAPTIVE_EOL */ bool sm_discard; @@ -207,7 +208,7 @@ typedef struct bool sm_milterlist; /* any filters in the list? */ #endif /* MILTER */ #if _FFR_QUARANTINE - char *sm_holdmsg; /* carry quarantining across messages */ + char *sm_quarmsg; /* carry quarantining across messages */ #endif /* _FFR_QUARANTINE */ } SMTP_T; @@ -353,7 +354,6 @@ smtp(nullserver, d_flags, e) volatile unsigned int n_etrn = 0; /* count of ETRN */ volatile unsigned int n_noop = 0; /* count of NOOP/VERB/etc */ volatile unsigned int n_helo = 0; /* count of HELO/EHLO */ - volatile unsigned int delay = 1; /* timeout for bad commands */ bool ok; #if _FFR_ADAPTIVE_EOL volatile bool first; @@ -497,6 +497,8 @@ smtp(nullserver, d_flags, e) } hostname = macvalue('j', e); + + #if SASL sasl_ok = bitset(SRV_OFFER_AUTH, features); n_mechs = 0; @@ -609,12 +611,18 @@ smtp(nullserver, d_flags, e) switch (state) { case SMFIR_REJECT: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: inititalization failed, rejecting commands"); greetcode = "554"; nullserver = "Command rejected"; smtp.sm_milterize = false; break; case SMFIR_TEMPFAIL: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: inititalization failed, temp failing commands"); tempfail = true; smtp.sm_milterize = false; break; @@ -633,17 +641,28 @@ smtp(nullserver, d_flags, e) { case SMFIR_REPLYCODE: /* REPLYCODE shouldn't happen */ case SMFIR_REJECT: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: connect: host=%s, addr=%s, rejecting commands", + peerhostname, + anynet_ntoa(&RealHostAddr)); greetcode = "554"; nullserver = "Command rejected"; smtp.sm_milterize = false; break; case SMFIR_TEMPFAIL: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: connect: host=%s, addr=%s, temp failing commands", + peerhostname, + anynet_ntoa(&RealHostAddr)); tempfail = true; smtp.sm_milterize = false; break; } if (response != NULL) + sm_free(response); /* XXX */ } #endif /* MILTER */ @@ -703,10 +722,10 @@ smtp(nullserver, d_flags, e) #if _FFR_QUARANTINE /* If quarantining by a connect/ehlo action, save between messages */ - if (e->e_holdmsg == NULL) - smtp.sm_holdmsg = NULL; + if (e->e_quarmsg == NULL) + smtp.sm_quarmsg = NULL; else - smtp.sm_holdmsg = newstr(e->e_holdmsg); + smtp.sm_quarmsg = newstr(e->e_quarmsg); #endif /* _FFR_QUARANTINE */ /* sendinghost's storage must outlive the current envelope */ @@ -1005,14 +1024,6 @@ smtp(nullserver, d_flags, e) if (LogLevel > 14) sm_syslog(LOG_INFO, e->e_id, "<-- %s", inp); - if (e->e_id == NULL) - sm_setproctitle(true, e, "%s: %.80s", - CurSmtpClient, inp); - else - sm_setproctitle(true, e, "%s %s: %.80s", - qid_printname(e), - CurSmtpClient, inp); - /* break off command */ for (p = inp; isascii(*p) && isspace(*p); p++) continue; @@ -1039,13 +1050,32 @@ smtp(nullserver, d_flags, e) /* check whether a "non-null" command has been used */ switch (c->cmd_code) { +#if SASL + case CMDAUTH: + /* avoid information leak; take first two words? */ + q = "AUTH"; + break; +#endif /* SASL */ + case CMDMAIL: case CMDEXPN: case CMDVRFY: case CMDETRN: lognullconnection = false; + /* FALLTHROUGH */ + default: + q = inp; + break; } + if (e->e_id == NULL) + sm_setproctitle(true, e, "%s: %.80s", + CurSmtpClient, q); + else + sm_setproctitle(true, e, "%s %s: %.80s", + qid_printname(e), + CurSmtpClient, q); + /* ** Process command. ** @@ -1075,12 +1105,15 @@ smtp(nullserver, d_flags, e) default: #if MAXBADCOMMANDS > 0 /* theoretically this could overflow */ - if (++n_badcmds > MAXBADCOMMANDS) + if (nullserver != NULL && + ++n_badcmds > MAXBADCOMMANDS) { - delay *= 2; - if (delay >= MAXTIMEOUT) - delay = MAXTIMEOUT; - (void) sleep(delay); + message("421 4.7.0 %s Too many bad commands; closing connection", + MyHostName); + + /* arrange to ignore send list */ + e->e_sendqueue = NULL; + goto doquit; } #endif /* MAXBADCOMMANDS > 0 */ if (nullserver != NULL) @@ -1598,19 +1631,19 @@ smtp(nullserver, d_flags, e) #if _FFR_QUARANTINE /* restore connection quarantining */ - if (smtp.sm_holdmsg == NULL) + if (smtp.sm_quarmsg == NULL) { - e->e_holdmsg = NULL; + e->e_quarmsg = NULL; macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), ""); + macid("{quarantine}"), ""); } else { - e->e_holdmsg = sm_rpool_strdup_x(e->e_rpool, - smtp.sm_holdmsg); + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, + smtp.sm_quarmsg); macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), - e->e_holdmsg); + macid("{quarantine}"), + e->e_quarmsg); } #endif /* _FFR_QUARANTINE */ } @@ -1626,16 +1659,28 @@ smtp(nullserver, d_flags, e) switch (state) { case SMFIR_REPLYCODE: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: helo=%s, reject=%s", + p, response); nullserver = newstr(response); smtp.sm_milterize = false; break; case SMFIR_REJECT: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: helo=%s, reject=Command rejected", + p); nullserver = "Command rejected"; smtp.sm_milterize = false; break; case SMFIR_TEMPFAIL: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: helo=%s, reject=%s", + p, MSG_TEMPFAIL); tempfail = true; smtp.sm_milterize = false; break; @@ -1649,9 +1694,9 @@ smtp(nullserver, d_flags, e) ** save between messages */ - if (smtp.sm_holdmsg == NULL && - e->e_holdmsg != NULL) - smtp.sm_holdmsg = newstr(e->e_holdmsg); + if (smtp.sm_quarmsg == NULL && + e->e_quarmsg != NULL) + smtp.sm_quarmsg = newstr(e->e_quarmsg); #endif /* _FFR_QUARANTINE */ } #endif /* MILTER */ @@ -1916,6 +1961,26 @@ smtp(nullserver, d_flags, e) if (Errors > 0) sm_exc_raisenew_x(&EtypeQuickAbort, 1); +#if SASL +# if _FFR_AUTH_PASSING + /* set the default AUTH= if the sender didn't */ + if (e->e_auth_param == NULL) + { + /* XXX only do this for an MSA? */ + e->e_auth_param = macvalue(macid("{auth_authen}"), + e); + if (e->e_auth_param == NULL) + e->e_auth_param = "<>"; + + /* + ** XXX should we invoke Strust_auth now? + ** authorizing as the client that just + ** authenticated, so we'll trust implicitly + */ + } +# endif /* _FFR_AUTH_PASSING */ +#endif /* SASL */ + /* do config file checking of the sender */ macdefine(&e->e_macro, A_PERM, macid("{addr_type}"), "e s"); @@ -2242,18 +2307,18 @@ smtp(nullserver, d_flags, e) CLEAR_STATE(cmdbuf); #if _FFR_QUARANTINE /* restore connection quarantining */ - if (smtp.sm_holdmsg == NULL) + if (smtp.sm_quarmsg == NULL) { - e->e_holdmsg = NULL; + e->e_quarmsg = NULL; macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), ""); + macid("{quarantine}"), ""); } else { - e->e_holdmsg = sm_rpool_strdup_x(e->e_rpool, - smtp.sm_holdmsg); + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, + smtp.sm_quarmsg); macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), e->e_holdmsg); + macid("{quarantine}"), e->e_quarmsg); } #endif /* _FFR_QUARANTINE */ break; @@ -2542,7 +2607,7 @@ doquit: #if PROFILING return; #endif /* PROFILING */ - finis(true, ExitStat); + finis(true, true, ExitStat); /* NOTREACHED */ case CMDVERB: /* set verbose mode */ @@ -2733,24 +2798,35 @@ smtp_data(smtp, e) switch (state) { case SMFIR_REPLYCODE: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: data, reject=%s", + response); milteraccept = false; usrerr(response); break; case SMFIR_REJECT: milteraccept = false; - if (MilterLogLevel > 8) + if (MilterLogLevel > 3) sm_syslog(LOG_INFO, e->e_id, - "Milter: reject, message data"); + "Milter: data, reject=554 5.7.1 Command rejected"); usrerr("554 5.7.1 Command rejected"); break; case SMFIR_DISCARD: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: data, discard"); milteraccept = false; e->e_flags |= EF_DISCARD; break; case SMFIR_TEMPFAIL: + if (MilterLogLevel > 3) + sm_syslog(LOG_INFO, e->e_id, + "Milter: data, reject=%s", + MSG_TEMPFAIL); milteraccept = false; usrerr(MSG_TEMPFAIL); break; @@ -2772,6 +2848,12 @@ smtp_data(smtp, e) } #endif /* MILTER */ +#if _FFR_QUARANTINE + /* Check if quarantining stats should be updated */ + if (e->e_quarmsg != NULL) + markstats(e, NULL, STATS_QUARANTINE); +#endif /* _FFR_QUARANTINE */ + /* ** If a header/body check (header checks or milter) ** set EF_DISCARD, don't queueup the message -- @@ -2783,13 +2865,12 @@ smtp_data(smtp, e) doublequeue = false; aborting = Errors > 0; - if (!aborting) - { + if (!aborting && #if _FFR_QUARANTINE - if (QueueMode == QM_HELD || e->e_holdmsg == NULL) + (QueueMode == QM_QUARANTINE || e->e_quarmsg == NULL) && #endif /* _FFR_QUARANTINE */ - aborting = !split_by_recipient(e); - } + !split_by_recipient(e)) + aborting = bitset(EF_FATALERRS, e->e_flags); if (aborting) { @@ -2854,14 +2935,6 @@ smtp_data(smtp, e) /* make sure it is in the queue */ queueup(ee, false, true); } -#if _FFR_QUARANTINE - else if (QueueMode != QM_HELD && - ee->e_holdmsg != NULL) - { - /* make sure it is in the queue */ - queueup(ee, false, true); - } -#endif /* _FFR_QUARANTINE */ else { /* send to all recipients */ @@ -2889,8 +2962,8 @@ smtp_data(smtp, e) continue; } #if _FFR_QUARANTINE - else if (QueueMode != QM_HELD && - ee->e_holdmsg != NULL) + else if (QueueMode != QM_QUARANTINE && + ee->e_quarmsg != NULL) { ee->e_sendmode = SM_QUEUE; continue; @@ -2942,8 +3015,8 @@ smtp_data(smtp, e) { #if _FFR_QUARANTINE if (!doublequeue && - QueueMode != QM_HELD && - ee->e_holdmsg != NULL) + QueueMode != QM_QUARANTINE && + ee->e_quarmsg != NULL) { dropenvelope(ee, true, false); continue; @@ -2968,16 +3041,16 @@ smtp_data(smtp, e) #if _FFR_QUARANTINE /* restore connection quarantining */ - if (smtp->sm_holdmsg == NULL) + if (smtp->sm_quarmsg == NULL) { - e->e_holdmsg = NULL; - macdefine(&e->e_macro, A_PERM, macid("{holdmsg}"), ""); + e->e_quarmsg = NULL; + macdefine(&e->e_macro, A_PERM, macid("{quarantine}"), ""); } else { - e->e_holdmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_holdmsg); + e->e_quarmsg = sm_rpool_strdup_x(e->e_rpool, smtp->sm_quarmsg); macdefine(&e->e_macro, A_PERM, - macid("{holdmsg}"), e->e_holdmsg); + macid("{quarantine}"), e->e_quarmsg); } #endif /* _FFR_QUARANTINE */ } @@ -3231,12 +3304,18 @@ mail_esmtp_args(kp, vp, e) /* NOTREACHED */ } macdefine(&e->e_macro, A_TEMP, macid("{msg_size}"), vp); + errno = 0; e->e_msgsize = strtol(vp, (char **) NULL, 10); if (e->e_msgsize == LONG_MAX && errno == ERANGE) { usrerr("552 5.2.3 Message size exceeds maximum value"); /* NOTREACHED */ } + if (e->e_msgsize < 0) + { + usrerr("552 5.2.3 Message size invalid"); + /* NOTREACHED */ + } } else if (sm_strcasecmp(kp, "body") == 0) { @@ -3376,6 +3455,10 @@ mail_esmtp_args(kp, vp, e) /* not trusted */ e->e_auth_param = "<>"; +# if _FFR_AUTH_PASSING + macdefine(&BlankEnvelope.e_macro, A_PERM, + macid("{auth_author}"), NULL); +# endif /* _FFR_AUTH_PASSING */ } else { @@ -3409,6 +3492,7 @@ mail_esmtp_args(kp, vp, e) usrerr("501 5.5.2 BY= requires a value"); /* NOTREACHED */ } + errno = 0; e->e_deliver_by = strtol(vp, &s, 10); if (e->e_deliver_by == LONG_MIN || e->e_deliver_by == LONG_MAX || @@ -3660,7 +3744,12 @@ saslmechs(conn, mechlist) *mechlist = intersect(AuthMechanisms, *mechlist, NULL); } else + { *mechlist = NULL; /* be paranoid... */ + if (result == SASL_OK && LogLevel > 9) + sm_syslog(LOG_WARNING, NOQID, + "AUTH warning: no mechanisms"); + } return num; } /* diff --git a/gnu/usr.sbin/sendmail/sendmail/stab.c b/gnu/usr.sbin/sendmail/sendmail/stab.c index 603c1a9a29e..753d34f179c 100644 --- a/gnu/usr.sbin/sendmail/sendmail/stab.c +++ b/gnu/usr.sbin/sendmail/sendmail/stab.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: stab.c,v 8.84 2001/09/11 04:05:17 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: stab.c,v 8.86 2001/12/29 04:27:56 ca Exp $") /* ** STAB -- manage the symbol table @@ -68,13 +68,13 @@ stab(name, type, op) if (type == ST_MACRO || type == ST_RULESET) { while ((s = *ps) != NULL && - (s->s_type != type || strcmp(name, s->s_name))) + (s->s_symtype != type || strcmp(name, s->s_name))) ps = &s->s_next; } else { while ((s = *ps) != NULL && - (s->s_type != type || sm_strcasecmp(name, s->s_name))) + (s->s_symtype != type || sm_strcasecmp(name, s->s_name))) ps = &s->s_next; } @@ -93,7 +93,7 @@ stab(name, type, op) long *lp = (long *) s->s_class; sm_dprintf("type %d val %lx %lx %lx %lx\n", - s->s_type, lp[0], lp[1], lp[2], lp[3]); + s->s_symtype, lp[0], lp[1], lp[2], lp[3]); } } return s; @@ -200,8 +200,7 @@ stab(name, type, op) s = (STAB *) sm_pmalloc_x(len); memset((char *) s, '\0', len); s->s_name = sm_pstrdup_x(name); - s->s_type = type; - s->s_len = len; + s->s_symtype = type; /* link it in */ *ps = s; @@ -238,7 +237,7 @@ stabapply(func, arg) { if (tTd(36, 90)) sm_dprintf("stabapply: trying %d/%s\n", - s->s_type, s->s_name); + s->s_symtype, s->s_name); func(s, arg); } } @@ -278,7 +277,7 @@ queueup_macros(class, qfp, e) int m; char *p; - if (s->s_type == ST_CLASS && + if (s->s_symtype == ST_CLASS && bitnset(bitidx(class), s->s_class) && (m = macid(s->s_name)) != '\0' && (p = macvalue(m, e)) != NULL) @@ -317,7 +316,7 @@ copy_class(src, dst) { for (s = *shead; s != NULL; s = s->s_next) { - if (s->s_type == ST_CLASS && + if (s->s_symtype == ST_CLASS && bitnset(src, s->s_class)) setbitn(dst, s->s_class); } @@ -366,7 +365,7 @@ rmexpstab() s = SymTab[i]; while (s != NULL) { - switch (s->s_type) + switch (s->s_symtype) { case ST_HOSTSIG: if (s->s_hostsig.hs_exp >= now) @@ -381,7 +380,7 @@ rmexpstab() break; default: - if (s->s_type >= ST_MCI) + if (s->s_symtype >= ST_MCI) { /* call mci_uncache? */ SM_STAB_FREE(s->s_mci.mci_status); @@ -448,7 +447,7 @@ dumpstab() while (s != NULL) { ++total; - t = s->s_type; + t = s->s_symtype; if (t > MAXSTTYPES - 1) t = MAXSTTYPES - 1; types[t]++; diff --git a/gnu/usr.sbin/sendmail/sendmail/stats.c b/gnu/usr.sbin/sendmail/sendmail/stats.c index 98069b6a4e1..c90a353ab13 100644 --- a/gnu/usr.sbin/sendmail/sendmail/stats.c +++ b/gnu/usr.sbin/sendmail/sendmail/stats.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: stats.c,v 8.50 2001/09/11 04:05:17 gshapiro Exp $") +SM_RCSID("@(#)$Sendmail: stats.c,v 8.52 2001/11/21 13:39:14 gshapiro Exp $") #include <sendmail/mailstats.h> @@ -30,7 +30,7 @@ static bool GotStats = false; /* set when we have stats to merge */ ** Parameters: ** e -- the envelope. ** to -- to address. -** reject -- whether this is a rejection. +** type -- type of stats this represents. ** ** Returns: ** none. @@ -40,13 +40,21 @@ static bool GotStats = false; /* set when we have stats to merge */ */ void -markstats(e, to, reject) +markstats(e, to, type) register ENVELOPE *e; register ADDRESS *to; - bool reject; + int type; { - if (reject) + switch (type) { +#if _FFR_QUARANTINE + case STATS_QUARANTINE: + if (e->e_from.q_mailer != NULL) + Stat.stat_nq[e->e_from.q_mailer->m_mno]++; + break; +#endif /* _FFR_QUARANTINE */ + + case STATS_REJECT: if (e->e_from.q_mailer != NULL) { if (bitset(EF_DISCARD, e->e_flags)) @@ -55,22 +63,30 @@ markstats(e, to, reject) Stat.stat_nr[e->e_from.q_mailer->m_mno]++; } Stat.stat_cr++; - } - else if (to == NULL) - { - Stat.stat_cf++; - if (e->e_from.q_mailer != NULL) + break; + + case STATS_NORMAL: + if (to == NULL) { - Stat.stat_nf[e->e_from.q_mailer->m_mno]++; - Stat.stat_bf[e->e_from.q_mailer->m_mno] += - KBYTES(e->e_msgsize); + Stat.stat_cf++; + if (e->e_from.q_mailer != NULL) + { + Stat.stat_nf[e->e_from.q_mailer->m_mno]++; + Stat.stat_bf[e->e_from.q_mailer->m_mno] += + KBYTES(e->e_msgsize); + } } - } - else - { - Stat.stat_ct++; - Stat.stat_nt[to->q_mailer->m_mno]++; - Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize); + else + { + Stat.stat_ct++; + Stat.stat_nt[to->q_mailer->m_mno]++; + Stat.stat_bt[to->q_mailer->m_mno] += KBYTES(e->e_msgsize); + } + break; + + default: + /* Silently ignore bogus call */ + return; } @@ -159,6 +175,9 @@ poststats(sfile) stats.stat_bt[i] += Stat.stat_bt[i]; stats.stat_nr[i] += Stat.stat_nr[i]; stats.stat_nd[i] += Stat.stat_nd[i]; +#if _FFR_QUARANTINE + stats.stat_nq[i] += Stat.stat_nq[i]; +#endif /* _FFR_QUARANTINE */ } stats.stat_cr += Stat.stat_cr; stats.stat_ct += Stat.stat_ct; diff --git a/gnu/usr.sbin/sendmail/sendmail/usersmtp.c b/gnu/usr.sbin/sendmail/sendmail/usersmtp.c index 4294f131c03..f6fabdc44a7 100644 --- a/gnu/usr.sbin/sendmail/sendmail/usersmtp.c +++ b/gnu/usr.sbin/sendmail/sendmail/usersmtp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: usersmtp.c,v 8.423 2001/09/24 14:16:54 ca Exp $") +SM_RCSID("@(#)$Sendmail: usersmtp.c,v 8.428 2002/01/08 00:56:23 ca Exp $") #include <sysexits.h> @@ -245,17 +245,12 @@ tryhelo: /* got a 421 error code during startup */ tempfail1: - if (mci->mci_errno == 0) - mci->mci_errno = errno; mci_setstat(mci, EX_TEMPFAIL, ENHSCN(enhsc, "4.4.2"), NULL); if (mci->mci_state != MCIS_CLOSED) smtpquit(m, mci, e); return; tempfail2: - if (mci->mci_errno == 0) - mci->mci_errno = errno; - /* XXX should use code from other end iff ENHANCEDSTATUSCODES */ mci_setstat(mci, EX_TEMPFAIL, ENHSCN(enhsc, "4.5.0"), SmtpReplyBuffer); @@ -264,7 +259,6 @@ tryhelo: return; unavailable: - mci->mci_errno = errno; mci_setstat(mci, EX_UNAVAILABLE, "5.5.0", SmtpReplyBuffer); smtpquit(m, mci, e); return; @@ -1029,27 +1023,45 @@ getsimple(context, id, result, len) /* XXX maybe other mechanisms too?! */ addrealm = (*sai)[SASL_MECH] != NULL && sm_strcasecmp((*sai)[SASL_MECH], "CRAM-MD5") == 0; + + /* + ** Add realm to authentication id unless authid contains + ** '@' (i.e., a realm) or the default realm is empty. + */ + if (addrealm && h != NULL && strchr(h, '@') == NULL) { + /* has this been done before? */ if ((*sai)[SASL_ID_REALM] == NULL) { char *realm; realm = (*sai)[SASL_DEFREALM]; - l = strlen(h) + strlen(realm) + 2; - /* should use rpool, but how to get it? */ - authid = sm_sasl_malloc(l); - if (authid != NULL) + /* do not add an empty realm */ + if (*realm == '\0') { - (void) sm_snprintf(authid, l, "%s@%s", - h, realm); - (*sai)[SASL_ID_REALM] = authid; + authid = h; + (*sai)[SASL_ID_REALM] = NULL; } else { - authid = h; - (*sai)[SASL_ID_REALM] = NULL; + l = strlen(h) + strlen(realm) + 2; + + /* should use rpool, but from where? */ + authid = sm_sasl_malloc(l); + if (authid != NULL) + { + (void) sm_snprintf(authid, l, + "%s@%s", + h, realm); + (*sai)[SASL_ID_REALM] = authid; + } + else + { + authid = h; + (*sai)[SASL_ID_REALM] = NULL; + } } } else @@ -1655,8 +1667,7 @@ smtpauth(m, mci, e) #endif /* 0 */ /* set default value for realm */ - if ((mci->mci_sai)[SASL_DEFREALM] == NULL || - *(mci->mci_sai)[SASL_DEFREALM] == '\0') + if ((mci->mci_sai)[SASL_DEFREALM] == NULL) (mci->mci_sai)[SASL_DEFREALM] = sm_rpool_strdup_x(e->e_rpool, macvalue('j', CurEnv)); @@ -1721,6 +1732,18 @@ smtpmailfrom(m, mci, e) sm_dprintf("smtpmailfrom: CurHost=%s\n", CurHostName); enhsc = NULL; + /* + ** Check if connection is gone, if so + ** it's a tempfail and we use mci_errno + ** for the reason. + */ + + if (mci->mci_state == MCIS_CLOSED) + { + errno = mci->mci_errno; + return EX_TEMPFAIL; + } + /* set up appropriate options to include */ if (bitset(MCIF_SIZE, mci->mci_flags) && e->e_msgsize > 0) { @@ -1879,7 +1902,6 @@ smtpmailfrom(m, mci, e) if (r < 0) { /* communications failure */ - mci->mci_errno = errno; mci_setstat(mci, EX_TEMPFAIL, "4.4.2", NULL); smtpquit(m, mci, e); return EX_TEMPFAIL; @@ -1997,6 +2019,18 @@ smtprcpt(to, m, mci, e, ctladdr, xstart) } #endif /* PIPELINING */ + /* + ** Check if connection is gone, if so + ** it's a tempfail and we use mci_errno + ** for the reason. + */ + + if (mci->mci_state == MCIS_CLOSED) + { + errno = mci->mci_errno; + return EX_TEMPFAIL; + } + optbuf[0] = '\0'; bufp = optbuf; @@ -2104,10 +2138,24 @@ smtprcptstat(to, m, mci, e) register ENVELOPE *e; { int r; + int save_errno; char *enhsc; + /* + ** Check if connection is gone, if so + ** it's a tempfail and we use mci_errno + ** for the reason. + */ + + if (mci->mci_state == MCIS_CLOSED) + { + errno = mci->mci_errno; + return EX_TEMPFAIL; + } + enhsc = NULL; r = reply(m, mci, e, TimeOuts.to_rcpt, NULL, &enhsc); + save_errno = errno; to->q_rstatus = sm_rpool_strdup_x(e->e_rpool, SmtpReplyBuffer); to->q_status = ENHSCN_RPOOL(enhsc, smtptodsn(r), e->e_rpool); if (!bitnset(M_LMTP, m->m_flags)) @@ -2115,6 +2163,7 @@ smtprcptstat(to, m, mci, e) if (r < 0 || REPLYTYPE(r) == 4) { mci->mci_retryrcpt = true; + errno = save_errno; return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 2) @@ -2197,6 +2246,18 @@ smtpdata(m, mci, e, ctladdr, xstart) time_t timeout; char *enhsc; + /* + ** Check if connection is gone, if so + ** it's a tempfail and we use mci_errno + ** for the reason. + */ + + if (mci->mci_state == MCIS_CLOSED) + { + errno = mci->mci_errno; + return EX_TEMPFAIL; + } + enhsc = NULL; /* @@ -2247,6 +2308,7 @@ smtpdata(m, mci, e, ctladdr, xstart) if (r < 0 || REPLYTYPE(r) == 4) { smtpquit(m, mci, e); + errno = mci->mci_errno; return EX_TEMPFAIL; } else if (REPLYTYPE(r) == 5) @@ -2651,6 +2713,18 @@ smtprset(m, mci, e) mci->mci_okrcpts = 0; #endif /* PIPELINING */ + /* + ** Check if connection is gone, if so + ** it's a tempfail and we use mci_errno + ** for the reason. + */ + + if (mci->mci_state == MCIS_CLOSED) + { + errno = mci->mci_errno; + return; + } + SmtpPhase = "client RSET"; smtpmessage("RSET", m, mci); r = reply(m, mci, e, TimeOuts.to_rset, NULL, NULL); @@ -2774,6 +2848,15 @@ reply(m, mci, e, timeout, pfunc, enhstat) if (mci->mci_state == MCIS_CLOSED) return SMTPCLOSING; + /* don't try to read from a non-existant fd */ + if (mci->mci_in == NULL) + { + if (mci->mci_errno == 0) + mci->mci_errno = EBADF; + errno = mci->mci_errno; + return -1; + } + if (mci->mci_out != NULL) (void) sm_io_flush(mci->mci_out, SM_TIME_DEFAULT); @@ -2790,11 +2873,17 @@ reply(m, mci, e, timeout, pfunc, enhstat) /* if the remote end closed early, fake an error */ errno = save_errno; if (errno == 0) + { + (void) sm_snprintf(SmtpReplyBuffer, + sizeof SmtpReplyBuffer, + "421 4.4.1 Connection reset by %s", + CURHOSTNAME); #ifdef ECONNRESET errno = ECONNRESET; #else /* ECONNRESET */ errno = EPIPE; #endif /* ECONNRESET */ + } mci->mci_errno = errno; oldholderrs = HoldErrs; diff --git a/gnu/usr.sbin/sendmail/sendmail/util.c b/gnu/usr.sbin/sendmail/sendmail/util.c index 786893b739a..9a7345a3905 100644 --- a/gnu/usr.sbin/sendmail/sendmail/util.c +++ b/gnu/usr.sbin/sendmail/sendmail/util.c @@ -13,7 +13,7 @@ #include <sendmail.h> -SM_RCSID("@(#)$Sendmail: util.c,v 8.352 2001/09/26 14:56:58 ca Exp $") +SM_RCSID("@(#)$Sendmail: util.c,v 8.357 2001/11/28 19:19:27 gshapiro Exp $") #include <sysexits.h> #include <sm/xtrap.h> @@ -311,7 +311,7 @@ find_character(string, character) ** ** Returns: ** BODYTYPE_* according to parameter -** +** */ int @@ -1147,16 +1147,19 @@ xunlink(f) char *f; { register int i; + int save_errno; if (LogLevel > 98) sm_syslog(LOG_DEBUG, CurEnv->e_id, "unlink %s", f); i = unlink(f); + save_errno = errno; if (i < 0 && LogLevel > 97) sm_syslog(LOG_DEBUG, CurEnv->e_id, "%s: unlink-fail %d", f, errno); if (i >= 0) SYNC_DIR(f, false); + errno = save_errno; return i; } /* @@ -1469,6 +1472,7 @@ bitzerop(map) ** STRCONTAINEDIN -- tell if one string is contained in another ** ** Parameters: +** icase -- ignore case? ** a -- possible substring. ** b -- possible superstring. ** @@ -1478,7 +1482,8 @@ bitzerop(map) */ bool -strcontainedin(a, b) +strcontainedin(icase, a, b) + bool icase; register char *a; register char *b; { @@ -1489,14 +1494,25 @@ strcontainedin(a, b) la = strlen(a); lb = strlen(b); c = *a; - if (isascii(c) && isupper(c)) + if (icase && isascii(c) && isupper(c)) c = tolower(c); for (; lb-- >= la; b++) { - if (*b != c && isascii(*b) && isupper(*b) && tolower(*b) != c) - continue; - if (sm_strncasecmp(a, b, la) == 0) - return true; + if (icase) + { + if (*b != c && + isascii(*b) && isupper(*b) && tolower(*b) != c) + continue; + if (sm_strncasecmp(a, b, la) == 0) + return true; + } + else + { + if (*b != c) + continue; + if (strncmp(a, b, la) == 0) + return true; + } } return false; } @@ -2292,6 +2308,13 @@ str2prt(s) break; default: (void) sm_snprintf(h, l, "%03o", (int) c); + + /* + ** XXX since l is unsigned this may + ** wrap around if the calculation is screwed + ** up... + */ + l -= 2; h += 3; break; @@ -2480,24 +2503,25 @@ proc_list_set(pid, task) ** ** Parameters: ** pid -- pid to drop -** count -- pointer to number of processes (return). +** st -- process status ** other -- storage for proc_other (return). ** ** Returns: -** type of process +** none. ** ** Side Effects: -** May decrease CurChildren. +** May decrease CurChildren, CurRunners, or +** set RestartRequest or ShutdownRequest. ** ** NOTE: THIS CAN BE CALLED FROM A SIGNAL HANDLER. DO NOT ADD ** ANYTHING TO THIS ROUTINE UNLESS YOU KNOW WHAT YOU ARE ** DOING. */ -int -proc_list_drop(pid, count, other) +void +proc_list_drop(pid, st, other) pid_t pid; - int *count; + int st; int *other; { int i; @@ -2509,8 +2533,6 @@ proc_list_drop(pid, count, other) { ProcListVec[i].proc_pid = NO_PID; type = ProcListVec[i].proc_type; - if (count != NULL) - *count = ProcListVec[i].proc_count; if (other != NULL) *other = ProcListVec[i].proc_other; break; @@ -2520,7 +2542,22 @@ proc_list_drop(pid, count, other) CurChildren--; - return type; + if (type == PROC_CONTROL && WIFEXITED(st)) + { + /* if so, see if we need to restart or shutdown */ + if (WEXITSTATUS(st) == EX_RESTART) + RestartRequest = "control socket"; + else if (WEXITSTATUS(st) == EX_SHUTDOWN) + ShutdownRequest = "control socket"; + } + else if (type == PROC_QUEUE_CHILD && !WIFSTOPPED(st) && + ProcListVec[i].proc_other > -1) + { + /* restart this persistent runner */ + mark_work_group_restart(ProcListVec[i].proc_other, st); + } + else if (type == PROC_QUEUE) + CurRunners -= ProcListVec[i].proc_count; } /* ** PROC_LIST_CLEAR -- clear the process list diff --git a/gnu/usr.sbin/sendmail/sendmail/version.c b/gnu/usr.sbin/sendmail/sendmail/version.c index c7387b84f64..04b4c3ba65b 100644 --- a/gnu/usr.sbin/sendmail/sendmail/version.c +++ b/gnu/usr.sbin/sendmail/sendmail/version.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998-2001 Sendmail, Inc. and its suppliers. + * Copyright (c) 1998-2002 Sendmail, Inc. and its suppliers. * All rights reserved. * Copyright (c) 1983 Eric P. Allman. All rights reserved. * Copyright (c) 1988, 1993 @@ -13,6 +13,6 @@ #include <sm/gen.h> -SM_RCSID("@(#)$Sendmail: version.c,v 8.83 2001/09/29 01:47:38 ca Exp $") +SM_RCSID("@(#)$Sendmail: version.c,v 8.91 2002/01/13 18:23:00 ca Exp $") -char Version[] = "8.12.1"; +char Version[] = "8.12.2"; diff --git a/gnu/usr.sbin/sendmail/vacation/vacation.1 b/gnu/usr.sbin/sendmail/vacation/vacation.1 index de3e0244275..66e9fe3b905 100644 --- a/gnu/usr.sbin/sendmail/vacation/vacation.1 +++ b/gnu/usr.sbin/sendmail/vacation/vacation.1 @@ -9,9 +9,9 @@ .\" the sendmail distribution. .\" .\" -.\" $Sendmail: vacation.1,v 8.25 2001/07/13 21:35:35 gshapiro Exp $ +.\" $Sendmail: vacation.1,v 8.26 2001/11/21 04:21:35 gshapiro Exp $ .\" -.TH VACATION 1 "$Date: 2001/09/11 19:02:51 $" +.TH VACATION 1 "$Date: 2002/01/14 03:21:41 $" .SH NAME vacation \- return ``I am not here'' indication @@ -85,7 +85,9 @@ syslog(8). Use .I filename as name of the database instead of -.IR ~/.vacation.db . +.IR ~/.vacation.db +or +.IR ~/.vacation.{dir,pag} . Unless the .I filename starts with / it is relative to ~. @@ -186,8 +188,12 @@ or line is included in the mail headers. The people who have sent you messages are maintained as a db(3) +or +dbm(3) database in the file .I .vacation.db +or +.I .vacation.{dir,pag} in your home directory. .PP .B Vacation @@ -220,7 +226,10 @@ line automatically. .SH FILES .TP 1.8i ~/.vacation.db -default database file +default database file for db(3) +.TP 1.8i +~/.vacation.{dir,pag} +default database file for dbm(3) .TP ~/.vacation.msg default message to send diff --git a/gnu/usr.sbin/sendmail/vacation/vacation.c b/gnu/usr.sbin/sendmail/vacation/vacation.c index 25ea7f6b9b3..50f5c0280a9 100644 --- a/gnu/usr.sbin/sendmail/vacation/vacation.c +++ b/gnu/usr.sbin/sendmail/vacation/vacation.c @@ -20,7 +20,7 @@ SM_IDSTR(copyright, The Regents of the University of California. All rights reserved.\n\ Copyright (c) 1983 Eric P. Allman. All rights reserved.\n") -SM_IDSTR(id, "@(#)$Sendmail: vacation.c,v 8.130 2001/09/18 21:45:35 gshapiro Exp $") +SM_IDSTR(id, "@(#)$Sendmail: vacation.c,v 8.131 2001/12/12 00:02:42 gshapiro Exp $") #include <ctype.h> @@ -118,7 +118,7 @@ main(argc, argv) int argc; char **argv; { - bool iflag, emptysender, exclude; + bool iflag, exclude; bool runasuser = false; bool lflag = false; int mfail = 0, ufail = 0; @@ -132,6 +132,7 @@ main(argc, argv) char *msgfilename = NULL; char *cfpath = NULL; char *name; + char *returnaddr = NULL; SMDB_USER_INFO user_info; static char rnamebuf[MAXNAME]; extern int optind, opterr; @@ -141,7 +142,7 @@ main(argc, argv) extern int readheaders __P((void)); extern bool recent __P((void)); extern void setreply __P((char *, time_t)); - extern void sendmessage __P((char *, char *, bool)); + extern void sendmessage __P((char *, char *, char *)); extern void xclude __P((SM_FILE_T *)); /* Vars needed to link with smutil */ @@ -168,12 +169,16 @@ main(argc, argv) opterr = 0; iflag = false; - emptysender = false; exclude = false; interval = INTERVAL_UNDEF; *From = '\0'; -#define OPTIONS "a:C:df:Iilm:r:s:t:Uxz" + +#if _FFR_RETURN_ADDR +# define OPTIONS "a:C:df:Iilm:R:r:s:t:Uxz" +#else /* _FFR_RETURN_ADDR */ +# define OPTIONS "a:C:df:Iilm:r:s:t:Uxz" +#endif /* _FFR_RETURN_ADDR */ while (mfail == 0 && ufail == 0 && (ch = getopt(argc, argv, OPTIONS)) != -1) @@ -217,6 +222,12 @@ main(argc, argv) msgfilename = optarg; break; +#if _FFR_RETURN_ADDR + case 'R': + returnaddr = optarg; + break; +#endif /* _FFR_RETURN_ADDR */ + case 'r': if (isascii(*optarg) && isdigit(*optarg)) { @@ -244,7 +255,7 @@ main(argc, argv) break; case 'z': - emptysender = true; + returnaddr = "<>"; break; case '?': @@ -413,7 +424,7 @@ main(argc, argv) (void) time(&now); setreply(From, now); (void) Db->smdb_close(Db); - sendmessage(name, msgfilename, emptysender); + sendmessage(name, msgfilename, returnaddr); } else (void) Db->smdb_close(Db); @@ -929,7 +940,7 @@ xclude(f) ** Parameters: ** myname -- user name. ** msgfn -- name of file with vacation message. -** emptysender -- use <> as sender address? +** sender -- use as sender address ** ** Returns: ** nothing. @@ -939,10 +950,10 @@ xclude(f) */ void -sendmessage(myname, msgfn, emptysender) +sendmessage(myname, msgfn, sender) char *myname; char *msgfn; - bool emptysender; + char *sender; { SM_FILE_T *mfp, *sfp; int i; @@ -968,8 +979,8 @@ sendmessage(myname, msgfn, emptysender) pv[0] = "sendmail"; pv[1] = "-oi"; pv[2] = "-f"; - if (emptysender) - pv[3] = "<>"; + if (sender != NULL) + pv[3] = sender; else pv[3] = myname; pv[4] = "--"; @@ -1017,9 +1028,17 @@ sendmessage(myname, msgfn, emptysender) void usage() { + char *retusage; + +#if _FFR_RETURN_ADDR + retusage = "[-R returnaddr] "; +#else /* _FFR_RETURN_ADDR */ + retusage = ""; +#endif /* _FFR_RETURN_ADDR */ + msglog(LOG_NOTICE, - "uid %u: usage: vacation [-a alias] [-C cfpath] [-d] [-f db] [-i] [-l] [-m msg] [-r interval] [-s sender] [-t time] [-U] [-x] [-z] login\n", - getuid()); + "uid %u: usage: vacation [-a alias] [-C cfpath] [-d] [-f db] [-i] [-l] [-m msg] %s[-r interval] [-s sender] [-t time] [-U] [-x] [-z] login\n", + getuid(), retusage); exit(EX_USAGE); } |