From: Wietse Venema Date: Tue, 31 Aug 1999 05:00:00 +0000 (-0500) Subject: snapshot-19990831 X-Git-Tag: v20010228~100 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=eacbb63439db4ea224c5ce30dbb5248ca3280100;p=thirdparty%2Fpostfix.git snapshot-19990831 --- diff --git a/postfix/0README b/postfix/0README index 6f5012997..b09fc9247 100644 --- a/postfix/0README +++ b/postfix/0README @@ -106,6 +106,11 @@ Documentation: html/ HTML format man/ UNIX on-line manual page format +Example files: + + conf/ sample configuration files + examples/ chroot environments, virtual domains + Library routines: dns/ DNS client library diff --git a/postfix/BEWARE b/postfix/BEWARE new file mode 100644 index 000000000..cac1f38e9 --- /dev/null +++ b/postfix/BEWARE @@ -0,0 +1,38 @@ +LINUX SYSLOGD PERFORMANCE +========================= + +LINUX syslogd uses synchronous writes by default, which is very +expensive. For services such a mail it is recommended that you +disable synchronous logfile writes by prepending a - to the logfile +name: + + mail.* -/var/log/mail.log + +SPAM BLOCKING SOURCE ROUTED ADDRESSES +===================================== + +If you relay mail for other domains, you must prevent unauthorized +relay of addresses such as: + + user@elsewhere@the.other.domain + user%elsewhere@the.other.domain + elsewhere!user@the.other.domain + +The simplest solution is to install a regular expression filter: + + /etc/postfix/main.cf: + smtpd_recipient_restrictions = regexp:/etc/postfix/regexp_access + + /etc/postfix/regexp_access: + /[%!@].*@/ 550 Sender specified routing is not supported here. + +For the local domain, Postfix will do the right thing with: + + user@elsewhere@my.own.domain + user%elsewhere@my.own.domain + elsewhere!user@my.own.domain + +That is, it bounces the first form because "user@elsewhere" is not +a valid local user, and it accepts the second and third forms only +when user@elsewhere is a valid relay destination. + diff --git a/postfix/HISTORY b/postfix/HISTORY index 4c8056521..ef70ad097 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -2887,3 +2887,111 @@ Apologies for any names omitted. is: "prepend_delivered_header = command, file, forward". Turning off the Delivered-To: header when forwarding mail is not recommended. + +19990628 + + Feature: the postlock command now returns EX_TEMPFAIL + when the destination file is locked by another process. + +19990705 + + Workaround: in the SMTP client, move the "mail loops back + to myself test" from the 220 greeting to the HELO response. + This change does not weaken the test, and makes Postfix + more robust against broken software that greets with the + client hostname. + +19990706 + + Workaround: in the INSTALL file, use `&&' instead of `;' + in (cd path; tar ...) pipelines because some UNIX re-invented + shells don't bail out when cd fails. Matthias Andree + @dosis.uni-dortmund.de. + +19990709 + + Bugfix: $user was not set when delivering to a non-user. + Found by Vladimir Ulogov @ rohan.control.att.com when + configuring a luser_relay that contained $user. + +19990714 + + Robustness: add PATH statement to Solaris2 chroot setup + script to avoid running the ucb commands. Problem found + by Panagiotis Astithas @ ece.ntua.gr. + +19990721 + + Bugfix: don't claim a "mail loops to myself" error when + the best MX host was not found in the DNS. Found by Andrew + McNamara, connect.com.au Pty Ltd. File: smtp/smtp_addr.c. + +19990810 + + Feature: added "-c config_directory" support to the postconf + command. This probably means that "-f file" will never be + implemented. + +19990812 + + Bugfix: showq didn't print properly when listing a maildrop + file. Fix by: Andrew McNamara, connect.com.au Pty Ltd. + File: showq/showq.c. + + Feature: added SENDER to the list of parameters exported + to external commands. File: local/command.c. Code by: Lars + Hecking, National Microelectronics Research Centre, Ireland. + +19990813 + + Bugfix: sendmail -t (extract recipients from headers) did not + work when the always_bcc feature was turned on. Reported + by: Denis Shaposhnikov @ neva.vlink.ru. + +19990813 + Bugfix: "sendmail -bd" returns a bogus exit status (the child + process ID). Fix by Lamont Jones of Hewlett-Packard. File: + sendmail/sendmail.c. + +19990824 + + Bugfix: null pointer dereference while rejecting VRFY before + MAIL FROM. Found by Laurent Wacrenier @ fr.clara.net. + +19990826 + + Portability: more MacOS X Server patches; some NEXTSTEP/OPENSTEP + code that had been removed for the first public beta release; + NEXTSTEP/OPENSTEP now defaults to netinfo for the aliases + database. Submitted by Gerben Wierda. + + Portability: workaround for a FreeBSD 3.x active network + interface without IP address by Pierre Beyssac @ enst.fr. + File: inet_addr_local.c. + +19990831 + + Workaround: sendmail now prints a warning when installed + set-uid or when run by a set-uid command. Reportedly, the + linuxconf software turns on the set-uid bit, which could + open up a security loophole. File: sendmail/sendmail.c. + + Bugfix: Postfix daemons now temporarily lock DB/DBM files + while opening them, in order to avoid "invalid argument" + errors because some other process is changing the file. + Files: util/dict_db.c, util/dict_dbm.c. + + Robustness: Postfix locks queue files during delivery, to + prevent duplicate delivery when "postfix reload" is + immediately followed by "sendmail -q". This involves a + change of the deliver_request interface: delivery agents + no longer need to open and close queue files explicitly. + Files: global/deliver_request.c, pipe/pipe.c, smtp/smtp.c, + local/local.c, qmgr/qmgr_active.c, qmgr/qmgr_message.c. + + Feature: reject_unauth_destination SMTP recipient restriction + that rejects destinations not in $relay_domains. By Lamont + Jones of Hewlett-Packard. File: smtpd/smtpd_check.c. + + Robustness: postconf now validates the syntax of all main.cf + parameters. diff --git a/postfix/INSTALL b/postfix/INSTALL index b133cf5a9..9eabab10e 100644 --- a/postfix/INSTALL +++ b/postfix/INSTALL @@ -46,6 +46,7 @@ those embedded manual pages are available in the mantools directory. If your system is supported, it is one of + AIX 3.2.5 AIX 4.1.x AIX 4.2.0 BSD/OS 2.x @@ -65,16 +66,20 @@ If your system is supported, it is one of Linux RedHat 5.x Linux Slackware 3.5 Linux SuSE 5.x + Mac OS X server NEXTSTEP 3.x NetBSD 1.x OPENSTEP 4.x + OSF1.V3 (Digital UNIX) OSF1.V4 aka Digital UNIX V4 OpenBSD 2.x + Reliant UNIX 5.x + Rhapsody 5.x SunOS 4.1.x SunOS 5.4..5.7 (Solaris 2.4..7) + Ultrix 4.x -or something closely resemblant. Some platforms such as Ultrix 4 -need a bit of work because their shell is a bit brain damaged. +or something closely resemblant. If at any time in the build process you get messages like: "make: don't know how to ..." you should be able to recover by running @@ -210,7 +215,7 @@ Installing Postfix by hand takes only a few steps. - On-line manual pages: # mkdir /some/where/man - # (cd man; tar cf - .) | (cd /some/where/man; tar xvf -) + # (cd man && tar cf - .) | (cd /some/where/man && tar xvf -) Alternative: leave the manpages in the Postfix source tree. diff --git a/postfix/LICENSE b/postfix/LICENSE index 2f1ba0c2f..45b98347a 100644 --- a/postfix/LICENSE +++ b/postfix/LICENSE @@ -1,4 +1,4 @@ -IBM PUBLIC LICENSE VERSION 1.0 6/14/1999 - SECURE MAILER +IBM PUBLIC LICENSE VERSION 1.0 - SECURE MAILER THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS IBM PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE @@ -106,8 +106,8 @@ When the Program is made available in source code form: Each Contributor must include the following in a conspicuous location in the Program: - Copyright (c) {date here}, International Business Machines Corporation - and others. All Rights Reserved. + Copyright (c) 1997,1998,1999, International Business Machines + Corporation and others. All Rights Reserved. In addition, each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent diff --git a/postfix/cleanup/cleanup.c b/postfix/cleanup/cleanup.c index 2a66a5f1a..f40e27751 100644 --- a/postfix/cleanup/cleanup.c +++ b/postfix/cleanup/cleanup.c @@ -56,13 +56,15 @@ /* CONFIGURATION PARAMETERS /* .ad /* .fi -/* The following \fBmain.cf\fR parameters are especially relevant to -/* this program. See the Postfix \fBmain.cf\fR file for syntax details -/* and for default values. Use the \fBpostfix reload\fR command after -/* a configuration change. +/* The following \fBmain.cf\fR parameters are especially relevant to +/* this program. See the Postfix \fBmain.cf\fR file for syntax details +/* and for default values. Use the \fBpostfix reload\fR command after +/* a configuration change. /* .SH Miscellaneous /* .ad /* .fi +/* .IP \fBalways_bcc\fR +/* Address to send a copy of each message that enters the system. /* .IP \fBhopcount_limit\fR /* Limit the number of \fBReceived:\fR message headers. /* .SH "Address transformations" @@ -174,6 +176,7 @@ int var_dup_filter_limit; /* recipient dup filter */ char *var_empty_addr; /* destination of bounced bounces */ int var_delay_warn_time; /* delay that triggers warning */ char *var_prop_extension; /* propagate unmatched extension */ +char *var_always_bcc; /* * Mappings. @@ -400,7 +403,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv) if (*var_masq_domains) cleanup_masq_domains = argv_split(var_masq_domains, " ,\t\r\n"); if (*var_header_checks) - cleanup_header_checks = + cleanup_header_checks = maps_create(VAR_HEADER_CHECKS, var_header_checks, DICT_FLAG_LOCK); } @@ -456,6 +459,7 @@ int main(int argc, char **argv) VAR_MASQ_EXCEPTIONS, DEF_MASQ_EXCEPTIONS, &var_masq_exceptions, 0, 0, VAR_HEADER_CHECKS, DEF_HEADER_CHECKS, &var_header_checks, 0, 0, VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0, + VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0, 0, }; diff --git a/postfix/cleanup/cleanup_extracted.c b/postfix/cleanup/cleanup_extracted.c index 1057273f5..f7e2b94b9 100644 --- a/postfix/cleanup/cleanup_extracted.c +++ b/postfix/cleanup/cleanup_extracted.c @@ -118,9 +118,24 @@ void cleanup_extracted(void) /* * Optionally account for missing recipient envelope records. + * + * XXX Code duplication from cleanup_envelope.c. This should be in one + * place. */ if (cleanup_recip == 0) { rcpt = (cleanup_resent[0] ? cleanup_resent_recip : cleanup_recipients); + if (*var_always_bcc && rcpt->argv[0]) { + clean_addr = vstring_alloc(100); + cleanup_rewrite_internal(clean_addr, var_always_bcc); + if (cleanup_rcpt_canon_maps) + cleanup_map11_internal(clean_addr, cleanup_rcpt_canon_maps, + cleanup_ext_prop_mask & EXT_PROP_CANONICAL); + if (cleanup_comm_canon_maps) + cleanup_map11_internal(clean_addr, cleanup_comm_canon_maps, + cleanup_ext_prop_mask & EXT_PROP_CANONICAL); + argv_add(rcpt, STR(clean_addr), (char *) 0); + vstring_free(clean_addr); + } argv_terminate(rcpt); for (cpp = rcpt->argv; CLEANUP_OUT_OK() && *cpp; cpp++) cleanup_out_recipient(*cpp); diff --git a/postfix/conf/LICENSE b/postfix/conf/LICENSE index 2f1ba0c2f..45b98347a 100644 --- a/postfix/conf/LICENSE +++ b/postfix/conf/LICENSE @@ -1,4 +1,4 @@ -IBM PUBLIC LICENSE VERSION 1.0 6/14/1999 - SECURE MAILER +IBM PUBLIC LICENSE VERSION 1.0 - SECURE MAILER THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS IBM PUBLIC LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE @@ -106,8 +106,8 @@ When the Program is made available in source code form: Each Contributor must include the following in a conspicuous location in the Program: - Copyright (c) {date here}, International Business Machines Corporation - and others. All Rights Reserved. + Copyright (c) 1997,1998,1999, International Business Machines + Corporation and others. All Rights Reserved. In addition, each Contributor must identify itself as the originator of its Contribution, if any, in a manner that reasonably allows subsequent diff --git a/postfix/conf/aliases b/postfix/conf/aliases index fc0471f2a..a372b1655 100644 --- a/postfix/conf/aliases +++ b/postfix/conf/aliases @@ -1,30 +1,35 @@ # -# >>>>>>>>>> The program "newaliases" must be run after -# >> NOTE >> this file is updated for any changes to -# >>>>>>>>>> show through to sendmail. +# >>>>>>>>>> The program "newaliases" must be run after +# >> NOTE >> this file is updated for any changes to +# >>>>>>>>>> show through to Postfix. # # Basic system aliases -- these MUST be present -MAILER-DAEMON: postmaster -postmaster: root +MAILER-DAEMON: postmaster +postmaster: root # General redirections for pseudo accounts -bin: root -daemon: root -named: root -nobody: root -operator: root -uucp: root -www: root -ftp-bugs: root +bin: root +daemon: root +named: root +nobody: root +uucp: root +www: root +ftp-bugs: root # Put your local aliases here. -# Well-known aliases -- these should be filled in! -# root: -# manager: -# dumper: -# operator: +# Well-known aliases +manager: root +dumper: root +operator: root +abuse: postmaster + +# trap decode to catch security attacks +decode: root + +# Person who should get root's mail +#root: you #++ # NAME diff --git a/postfix/conf/main.cf b/postfix/conf/main.cf index 46e964de2..9c0e5ddcc 100644 --- a/postfix/conf/main.cf +++ b/postfix/conf/main.cf @@ -181,6 +181,7 @@ program_directory = /some/where/postfix/bin #alias_maps = dbm:/etc/aliases #alias_maps = hash:/etc/aliases #alias_maps = hash:/etc/aliases, nis:mail.aliases +#alias_maps = netinfo:/aliases # The alias_database parameter specifies the alias database(s) that # are built with "newaliases" or "sendmail -bi". This is a separate @@ -286,8 +287,10 @@ program_directory = /some/where/postfix/bin # The header_checks parameter restricts what may appear in message # headers. This requires that POSIX or PCRE regular expression support -# is built-in. Specify "/^header-name: stuff you don not want/ REJECT" -# in the pattern file. Patterns are case-insensitive by default. +# is built-in. Specify "/^header-name: stuff you do not want/ REJECT" +# in the pattern file. Patterns are case-insensitive by default. Note: +# specify only patterns ending in REJECT. Patterns ending in OK are +# a waste of cycles. # #header_checks = regexp:/etc/postfix/filename #header_checks = pcre:/etc/postfix/filename diff --git a/postfix/conf/master.cf b/postfix/conf/master.cf index adb7adebf..454a4f713 100644 --- a/postfix/conf/master.cf +++ b/postfix/conf/master.cf @@ -24,9 +24,9 @@ # Chroot: whether or not the service runs chrooted to the mail queue # directory (pathname is controlled by the queue_directory configuration # variable in the main.cf file). Presently, all Postfix daemons can run -# chrooted, except for the pipe and local daemons. The contributed -# source code from http://www.postfix.org/ describes how to set up -# a Postfix chroot environment for your type of machine. +# chrooted, except for the pipe and local daemons. The files in the +# examples/chroot-setup subdirectory describe how to set up a Postfix +# chroot environment for your type of machine. # # Wakeup time: automatically wake up the named service after the # specified number of seconds. Specify 0 for no wakeup. Presently, @@ -70,3 +70,6 @@ uucp unix - n n - - pipe flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient) ifmail unix - n n - - pipe flags=F user=ftn argv=/usr/lib/ifmail/ifmail -r $nexthop ($recipient) +bsmtp unix - n n - - pipe + flags=F user=foo argv=/usr/local/sbin/bsmtp -f $sender $nexthop $recipient + diff --git a/postfix/conf/postfix-script-nosgid b/postfix/conf/postfix-script-nosgid index 471856d1f..21392f933 100755 --- a/postfix/conf/postfix-script-nosgid +++ b/postfix/conf/postfix-script-nosgid @@ -48,7 +48,7 @@ umask 022 # LINUX by default does not synchronously update directories - # that's dangerous for mail. # -if [ -x /usr/bin/chattr ] +if [ -f /usr/bin/chattr ] then CHATTR="/usr/bin/chattr +S" else @@ -66,7 +66,7 @@ cd $daemon_directory || { $FATAL no Postfix daemon directory $daemon_directory! exit 1 } -test -x master || { +test -f master || { $FATAL no Postfix master program $daemon_directory/master! exit 1 } diff --git a/postfix/conf/postfix-script-sgid b/postfix/conf/postfix-script-sgid index 2ba58b979..337b2ade1 100755 --- a/postfix/conf/postfix-script-sgid +++ b/postfix/conf/postfix-script-sgid @@ -48,7 +48,7 @@ umask 022 # LINUX by default does not synchronously update directories - # that's dangerous for mail. # -if [ -x /usr/bin/chattr ] +if [ -f /usr/bin/chattr ] then CHATTR="/usr/bin/chattr +S" else @@ -66,7 +66,7 @@ cd $daemon_directory || { $FATAL no Postfix daemon directory $daemon_directory! exit 1 } -test -x master || { +test -f master || { $FATAL no Postfix master program $daemon_directory/master! exit 1 } diff --git a/postfix/conf/sample-misc.cf b/postfix/conf/sample-misc.cf index a0f63f203..f7a990529 100644 --- a/postfix/conf/sample-misc.cf +++ b/postfix/conf/sample-misc.cf @@ -219,8 +219,8 @@ program_directory = /usr/libexec/postfix # The queue_directory specifies the location of the Postfix queue. # This is also the root directory of Postfix daemons that run chrooted. -# The contributed source code from http://www.postfix.org/ has examples -# for setting up Postfix chroot environments on different UNIX systems. +# The files in the examples/chroot-setup subdirectory describe how +# to set up Postfix chroot environments on different UNIX systems. # queue_directory = /var/spool/postfix diff --git a/postfix/conf/sample-regexp.cf b/postfix/conf/sample-regexp.cf index 263c5509a..c4c491863 100644 --- a/postfix/conf/sample-regexp.cf +++ b/postfix/conf/sample-regexp.cf @@ -10,6 +10,10 @@ # second (if present) must not match. The first matching line wins, # terminating processing of the ruleset. +# Disallow sender-specified routing. This is a must if you relay mail +#for other domains. +/[%!@].*@/ 550 Sender-specified routing rejected + # Postmaster is OK, that way they can talk to us about how to fix their problem. /^postmaster@.*$/ OK diff --git a/postfix/conf/sample-smtpd.cf b/postfix/conf/sample-smtpd.cf index cc8c214bb..4381939fb 100644 --- a/postfix/conf/sample-smtpd.cf +++ b/postfix/conf/sample-smtpd.cf @@ -189,6 +189,7 @@ smtpd_sender_restrictions = # reject_unknown_hostname: reject HELO hostname without DNS A or MX record. # reject_unknown_sender_domain: reject sender domain without A or MX record. # check_relay_domains: permit only mail from/to domains in $relay_domains. +# reject_unauth_destination: reject mail not to domains in $relay_domains. # permit_mx_backup: accept mail for sites that list me as MX host. # reject_unknown_recipient_domain: reject domains without A or MX record. # check_recipient_access maptype:mapname diff --git a/postfix/examples/chroot-setup/Solaris2 b/postfix/examples/chroot-setup/Solaris2 index 26bf297d3..9aca6d1f7 100644 --- a/postfix/examples/chroot-setup/Solaris2 +++ b/postfix/examples/chroot-setup/Solaris2 @@ -1,5 +1,7 @@ #!/bin/sh +PATH=/usr/bin:/sbin:/usr/sbin + # Create chroot'd area under Solaris 2.5.1 for postfix. # # Dug Song diff --git a/postfix/global/Makefile.in b/postfix/global/Makefile.in index 887f2af41..25c29af3b 100644 --- a/postfix/global/Makefile.in +++ b/postfix/global/Makefile.in @@ -314,6 +314,7 @@ deliver_request.o: ../include/vbuf.h deliver_request.o: ../include/vstring.h deliver_request.o: ../include/mymalloc.h deliver_request.o: ../include/iostuff.h +deliver_request.o: ../include/myflock.h deliver_request.o: mail_queue.h deliver_request.o: mail_proto.h deliver_request.o: mail_open_ok.h diff --git a/postfix/global/deliver_request.c b/postfix/global/deliver_request.c index 0bf3319cc..ff361736e 100644 --- a/postfix/global/deliver_request.c +++ b/postfix/global/deliver_request.c @@ -8,6 +8,7 @@ /* /* typedef struct DELIVER_REQUEST { /* .in +5 +/* VSTREAM *fp; /* char *queue_name; /* char *queue_id; /* long data_offset; @@ -34,7 +35,8 @@ /* to delivery agent' protocol. In this game, the queue manager is /* the client, while the delivery agent is the server. /* -/* deliver_request_read() reads a client message delivery request. +/* deliver_request_read() reads a client message delivery request, +/* opens the queue file, and acquires a shared lock. /* A null result means that the client sent bad information or that /* it went away unexpectedly. /* @@ -46,6 +48,7 @@ /* /* deliver_request_done() reports the delivery status back to the /* client, including the optional \fIhop_status\fR information, +/* closes the queue file, /* and destroys the DELIVER_REQUEST structure. The result is /* non-zero when the status could not be reported to the client. /* DIAGNOSTICS @@ -78,6 +81,7 @@ #include #include #include +#include /* Global library. */ @@ -141,6 +145,7 @@ static int deliver_request_final(VSTREAM *stream, char *reason, int status) static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) { + char *myname = "deliver_request_get"; const char *path; struct stat st; static VSTRING *queue_name; @@ -177,6 +182,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) if (mail_open_ok(vstring_str(queue_name), vstring_str(queue_id), &st, &path) == 0) return (-1); + request->queue_name = mystrdup(vstring_str(queue_name)); request->queue_id = mystrdup(vstring_str(queue_id)); request->nexthop = mystrdup(vstring_str(nexthop)); @@ -196,6 +202,29 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request) return (-1); recipient_list_add(&request->rcpt_list, offset, vstring_str(address)); } + + /* + * Open the queue file and set a shared lock, in order to prevent + * duplicate deliveries when the queue is flushed immediately after queue + * manager restart. + * + * Opening the queue file can fail for a variety of reasons, such as the + * system running out of resources. Instead of throwing away mail, we're + * raising a fatal error which forces the mail system to back off, and + * retry later. + */ +#define DELIVER_LOCK_MODE (MYFLOCK_SHARED | MYFLOCK_NOWAIT) + + request->fp = + mail_queue_open(request->queue_name, request->queue_id, O_RDWR, 0); + if (request->fp == 0) + msg_fatal("open %s %s: %m", request->queue_name, request->queue_id); + if (msg_verbose) + msg_info("%s: file %s", myname, VSTREAM_PATH(request->fp)); + if (myflock(vstream_fileno(request->fp), DELIVER_LOCK_MODE) < 0) + msg_fatal("shared lock %s: %m", VSTREAM_PATH(request->fp)); + close_on_exec(vstream_fileno(request->fp), CLOSE_ON_EXEC); + return (0); } @@ -206,6 +235,7 @@ static DELIVER_REQUEST *deliver_request_alloc(void) DELIVER_REQUEST *request; request = (DELIVER_REQUEST *) mymalloc(sizeof(*request)); + request->fp = 0; request->queue_name = 0; request->queue_id = 0; request->nexthop = 0; @@ -223,6 +253,8 @@ static DELIVER_REQUEST *deliver_request_alloc(void) static void deliver_request_free(DELIVER_REQUEST *request) { + if (request->fp) + vstream_fclose(request->fp); if (request->queue_name) myfree(request->queue_name); if (request->queue_id) diff --git a/postfix/global/deliver_request.h b/postfix/global/deliver_request.h index 695110fdc..34ab16af9 100644 --- a/postfix/global/deliver_request.h +++ b/postfix/global/deliver_request.h @@ -26,6 +26,7 @@ * Structure of a server mail delivery request. */ typedef struct DELIVER_REQUEST { + VSTREAM *fp; /* stream, shared lock */ char *queue_name; /* message queue name */ char *queue_id; /* message queue id */ long data_offset; /* offset to message */ diff --git a/postfix/global/mail_connect.c b/postfix/global/mail_connect.c index 3de429326..61309c741 100644 --- a/postfix/global/mail_connect.c +++ b/postfix/global/mail_connect.c @@ -109,9 +109,15 @@ VSTREAM *mail_connect_wait(const char *class, const char *name) * XXX Solaris workaround for ECONNREFUSED on a busy socket. */ while ((stream = mail_connect(class, name, BLOCKING)) == 0) { - if (errno == ECONNREFUSED || errno == ENOENT) - (count++ >= 10 ? msg_fatal : msg_warn) - ("connect #%d to subsystem %s/%s: %m", count, class, name); + if (errno == ECONNREFUSED || errno == ENOENT) { + if (count++ >= 10) { + msg_fatal("connect #%d to subsystem %s/%s: %m", + count, class, name); + } else { + msg_warn("connect #%d to subsystem %s/%s: %m", + count, class, name); + } + } sleep(10); /* XXX make configurable */ } return (stream); diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h index ca210bf3c..cec982f92 100644 --- a/postfix/global/mail_params.h +++ b/postfix/global/mail_params.h @@ -342,6 +342,12 @@ abcdefghijklmnopqrstuvwxyz\ ABCDEFGHIJKLMNOPQRSTUVWXYZ" extern char *var_cmd_exp_filter; +#define VAR_FWD_EXP_FILTER "forward_expansion_filter" +#define DEF_FWD_EXP_FILTER "1234567890!@%-_=+:,.\ +abcdefghijklmnopqrstuvwxyz\ +ABCDEFGHIJKLMNOPQRSTUVWXYZ" +extern char *var_fwd_exp_filter; + #define VAR_DELIVER_HDR "prepend_delivered_header" #define DEF_DELIVER_HDR "command, file, forward" extern char *var_deliver_hdr; @@ -756,6 +762,7 @@ extern int var_non_fqdn_code; #define DEF_UNK_ADDR_CODE 450 extern int var_unk_addr_code; +#define REJECT_UNAUTH_DEST "reject_unauth_destination" #define CHECK_RELAY_DOMAINS "check_relay_domains" #define VAR_RELAY_CODE "relay_domains_reject_code" #define DEF_RELAY_CODE 554 diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h index 1533094f1..f2d3dfc06 100644 --- a/postfix/global/mail_version.h +++ b/postfix/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-19990627" +#define DEF_MAIL_VERSION "Snapshot-19990831" extern char *var_mail_version; /* LICENSE diff --git a/postfix/global/maps.c b/postfix/global/maps.c index 26e41b755..e6fd5ecc7 100644 --- a/postfix/global/maps.c +++ b/postfix/global/maps.c @@ -148,6 +148,13 @@ const char *maps_find(MAPS *maps, const char *name, int flags) const char *expansion; DICT *dict; + /* + * Temp. workaround, for buggy callers that pass zero-length keys when + * given partial addresses. + */ + if (*name == 0) + return (0); + for (map_name = maps->argv->argv; *map_name; map_name++) { if ((dict = dict_handle(*map_name)) == 0) msg_panic("%s: dictionary not found: %s", myname, *map_name); diff --git a/postfix/html/cleanup.8.html b/postfix/html/cleanup.8.html index 70c8290a9..24150028f 100644 --- a/postfix/html/cleanup.8.html +++ b/postfix/html/cleanup.8.html @@ -85,13 +85,17 @@ CLEANUP(8) CLEANUP(8) command after a configuration change. Miscellaneous + always_bcc + Address to send a copy of each message that enters + the system. + hopcount_limit Limit the number of Received: message headers. Address transformations empty_address_recipient - The destination for undeliverable mail from <>. - This substitution is done before all other address + The destination for undeliverable mail from <>. + This substitution is done before all other address rewriting. canonical_maps @@ -107,11 +111,11 @@ CLEANUP(8) CLEANUP(8) header sender addresses. masquerade_domains - List of domains that hide their subdomain struc- + List of domains that hide their subdomain struc- ture. masquerade_exceptions - List of user names that are not subject to address + List of user names that are not subject to address masquerading. virtual_maps @@ -120,11 +124,7 @@ CLEANUP(8) CLEANUP(8) Resource controls duplicate_filter_limit - Limit the number of envelope recipients that are - remembered. - - header_size_limit - Limit the amount of memory in bytes used to process + Limit the number of envelope recipients that are @@ -137,6 +137,10 @@ CLEANUP(8) CLEANUP(8) CLEANUP(8) CLEANUP(8) + remembered. + + header_size_limit + Limit the amount of memory in bytes used to process a message header. SEE ALSO @@ -151,7 +155,7 @@ CLEANUP(8) CLEANUP(8) /etc/postfix/virtual*, virtual mapping table LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -185,10 +189,6 @@ CLEANUP(8) CLEANUP(8) - - - - diff --git a/postfix/html/faq.html b/postfix/html/faq.html index d942cb7af..cd2f6d58d 100644 --- a/postfix/html/faq.html +++ b/postfix/html/faq.html @@ -30,6 +30,8 @@
  • Delivering some users locally while sending mail as user@domain +
  • Support for virus scanning +
  • Support for maildir-style mailboxes
  • Using Procmail for local delivery @@ -323,9 +325,10 @@ that are disconnected most of the time)

    - When you disable DNS lookups, you must specify a relayhost - as either a numeric IP address, or as a hostname that appears -in /etc/hosts. + When you disable DNS lookups, you must specify the +relayhost as either a numeric IP address, or as a hostname +that resolves to one or more IP addresses (Postfix does no +MX lookup).

    @@ -418,6 +421,49 @@ effective.


    +

    Support for virus scanning

    + +Would not it be great if operating systems and applications actually +worked the way they are supposed to, instead of being as fragile +as today's products? Well, we can solve only one problem at a time. + +

    + +Currently, Postfix has no hooks to let other programs inspect every +message, so the scanning has to be done before mail enters Postfix +or while mail leaves Postfix, for example at mailbox delivery time. + +

    + +

    + +
    Examples: + +
    + +
    mailbox_command = /some/program ... + +
    specifies a command that runs whenever mail is delivered to +mailbox. See the sample main.cf file for examples. In +/etc/aliases, you must specify an alias for root that +directs mail to a real person, otherwise funny things happen with +mail sent to root. + +

    + +

    mailbox_transport = foo + +
    delegates local mailbox delivery to the transport foo as +configured in /etc/postfix/master.cf. If you follow this +route you will build something around the pipe mailer. See examples +in master.cf. + +
    + +
    + +
    +

    Support for maildir-style mailboxes

    Maildir is a specific one-file-per-message organization that @@ -570,9 +616,9 @@ expression-based filter at the SMTP port:
    -
    smtpd_recipients = ... regexp:/etc/postfix/access_regexp ... +
    smtpd_recipient_restrictions = ... regexp:/etc/postfix/access_regexp ... -
    smtpd_recipients = ... pcre:/etc/postfix/access_regexp ... +
    smtpd_recipient_restrictions = ... pcre:/etc/postfix/access_regexp ...
    diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html index 11f21fcc3..2711c48ee 100644 --- a/postfix/html/local.8.html +++ b/postfix/html/local.8.html @@ -44,7 +44,11 @@ LOCAL(8) LOCAL(8) address extension), $domain (recipient domain), local (entire recipient address localpart) and $recipient_delim- iter. The forms ${name?value} and ${name:value} expand - conditionally to value when $name is (is not) defined. + conditionally to value when $name is (is not) defined. + Characters that may have special meaning to the shell or + file system are replaced by underscores. The list of + acceptable characters is specified with the forward_expan- + sion_filter configuration An alias or ~/.forward file may list any combination of external commands, destination file names, :include: @@ -55,10 +59,6 @@ LOCAL(8) LOCAL(8) When an address is found in its own alias expansion, delivery is made to the user instead. When a user is listed in the user's own ~/.forward file, delivery is made - to the user's mailbox instead. An empty ~/.forward file - means do not forward mail. - - In order to prevent the mail system from using up @@ -71,7 +71,11 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) - unreasonable amounts of memory, input records read from + to the user's mailbox instead. An empty ~/.forward file + means do not forward mail. + + In order to prevent the mail system from using up unrea- + sonable amounts of memory, input records read from :include: or from ~/.forward files are broken up into chunks of length line_length_limit. @@ -86,9 +90,10 @@ LOCAL(8) LOCAL(8) rate on-file delivery status record. In order to stop mail forwarding loops early, the software - adds a Delivered-To: header with the envelope recipient - address. If mail arrives for a recipient that is already - listed in a Delivered-To: header, the message is bounced. + adds an optional Delivered-To: header with the envelope + recipient address. If mail arrives for a recipient that is + already listed in a Delivered-To: header, the message is + bounced. MAILBOX DELIVERY The default per-user mailbox is a file in the UNIX mail @@ -120,11 +125,6 @@ LOCAL(8) LOCAL(8) In the case of UNIX-style mailbox delivery, the local dae- mon prepends a "From sender time_stamp" envelope header to - each message, prepends an optional Delivered-To: header - with the envelope recipient address, prepends a Return- - Path: header with the envelope sender address, prepends a - > character to lines beginning with "From ", and appends - an empty line. The mailbox is locked for exclusive access @@ -137,6 +137,11 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + each message, prepends an optional Delivered-To: header + with the envelope recipient address, prepends a Return- + Path: header with the envelope sender address, prepends a + > character to lines beginning with "From ", and appends + an empty line. The mailbox is locked for exclusive access while delivery is in progress. In case of problems, an attempt is made to truncate the mailbox to its original length. @@ -187,11 +192,6 @@ LOCAL(8) LOCAL(8) LOCAL The entire recipient address localpart (text to the left of the rightmost @ character). - RECIPIENT - The entire recipient address. - - The PATH environment variable is always reset to a system- - 3 @@ -203,6 +203,10 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + RECIPIENT + The entire recipient address. + + The PATH environment variable is always reset to a system- dependent default path, and the TZ (time zone) environment variable is always passed on without change. @@ -253,10 +257,6 @@ LOCAL(8) LOCAL(8) DELIVERY RIGHTS Deliveries to external files and external commands are - made with the rights of the receiving user on whose behalf - the delivery is made. In the absence of a user context, - the local daemon uses the owner rights of the :include: - file or alias database. When those files are owned by the @@ -269,6 +269,10 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + made with the rights of the receiving user on whose behalf + the delivery is made. In the absence of a user context, + the local daemon uses the owner rights of the :include: + file or alias database. When those files are owned by the superuser, delivery is made with the rights specified with the default_privs configuration parameter. @@ -318,11 +322,7 @@ LOCAL(8) LOCAL(8) local_command_shell Shell to use for external command execution (for example, /some/where/smrsh -c). When a shell is - specified, it is invoked even when the command con- - tains no shell built-in commands or meta charac- - ters. - - + specified, it is invoked even when the command @@ -335,17 +335,20 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) - prepend_delivered_header - Prepend an optional Delivered-To: header upon - external forwarding, delivery to command or file. - Specify zero or more of: command, file, forward. - Turning off Delivered-To: when forwarding mail is - not recommended. + contains no shell built-in commands or meta charac- + ters. owner_request_special Give special treatment to owner-xxx and xxx-request addresses. + prepend_delivered_header + Prepend an optional Delivered-To: header upon + external forwarding, delivery to command or file. + Specify zero or more of: command, file, forward. + Turning off Delivered-To: when forwarding mail is + not recommended. + recipient_delimiter Separator between username and address extension. @@ -387,9 +390,6 @@ LOCAL(8) LOCAL(8) Limit the number of attempts to acquire an exclu- sive lock on a mailbox or external file. - deliver_lock_delay - Time in seconds between successive attempts to - 6 @@ -401,6 +401,8 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + deliver_lock_delay + Time in seconds between successive attempts to acquire an exclusive lock. stale_lock_time @@ -447,12 +449,10 @@ LOCAL(8) LOCAL(8) Default rights for delivery to external file or command. -HISTORY - The Delivered-To: header appears in the qmail system by - Daniel Bernstein. - - The maildir structure appears in the qmail system by - Daniel Bernstein. + forward_expansion_filter + What characters are allowed to appear in $name + expansions of forward_path. Illegal characters are + replaced by underscores. @@ -467,6 +467,13 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) +HISTORY + The Delivered-To: header appears in the qmail system by + Daniel Bernstein. + + The maildir structure appears in the qmail system by + Daniel Bernstein. + SEE ALSO aliases(5) format of alias database bounce(8) non-delivery status reports @@ -509,13 +516,6 @@ LOCAL(8) LOCAL(8) - - - - - - - diff --git a/postfix/html/postalias.1.html b/postfix/html/postalias.1.html index af47d3897..76db05a8f 100644 --- a/postfix/html/postalias.1.html +++ b/postfix/html/postalias.1.html @@ -9,8 +9,8 @@ POSTALIAS(1) POSTALIAS(1) postalias - Postfix alias database maintenance SYNOPSIS - postalias [-c config_dir] [-i] [-v] [file_type:]file_name - ... + postalias [-c config_dir] [-i] [-v] [-w] + [file_type:]file_name ... DESCRIPTION The postalias command creates a new Postfix alias diff --git a/postfix/html/postconf.1.html b/postfix/html/postconf.1.html index 84f33515b..a9351d848 100644 --- a/postfix/html/postconf.1.html +++ b/postfix/html/postconf.1.html @@ -9,19 +9,24 @@ POSTCONF(1) POSTCONF(1) postconf - Postfix configuration utility SYNOPSIS - postconf [-d] [-h] [-n] [-v] [parameter ...] + postconf [-c config_dir] [-d] [-h] [-n] [-v] [parameter + ...] DESCRIPTION - The postconf command prints the actual value of parameter + The postconf command prints the actual value of parameter (all known parameters by default), one parameter per line. Options: + -c config_dir + The main.cf configuration file is in the named + directory. + -d Print default parameter settings instead of actual settings. - -h Show parameter values only, not the name = informa- - tion that normally precedes the value. + -h Show parameter values only, not the ``name ='' + label that normally precedes the value. -n Print non-default parameter settings only. @@ -30,7 +35,9 @@ POSTCONF(1) POSTCONF(1) bose. DIAGNOSTICS - Problems are reported to the standard error stream. + Problems are reported to the standard error stream. Fatal + error: out of memory, file not found, invalid main.cf + parameter syntax. LICENSE The Secure Mailer license must be distributed with this @@ -54,13 +61,6 @@ POSTCONF(1) POSTCONF(1) - - - - - - - 1 diff --git a/postfix/html/postlock.1.html b/postfix/html/postlock.1.html index 0ba4489f2..d87928ff5 100644 --- a/postfix/html/postlock.1.html +++ b/postfix/html/postlock.1.html @@ -38,13 +38,15 @@ POSTLOCK(1) POSTLOCK(1) command interpreter. DIAGNOSTICS - The result status is 255 (on some systems: -1) when post- - lock could not perform the requested operation. Other- - wise, the exit status is the exit status from the command. + The result status is 75 (EX_TEMPFAIL) when the file is + locked by another process, 255 (on some systems: -1) when + postlock could not perform the requested operation. Oth- + erwise, the exit status is the exit status from the com- + mand. BUGS - With remote file systems, the ability to acquire a lock - does not necessarily eliminate access conflicts. Avoid + With remote file systems, the ability to acquire a lock + does not necessarily eliminate access conflicts. Avoid file access by processes running on different machines. ENVIRONMENT @@ -55,10 +57,8 @@ POSTLOCK(1) POSTLOCK(1) Enable verbose logging. CONFIGURATION PARAMETERS - The following main.cf parameters are especially relevant - to this program. See the Postfix main.cf file for syntax - details and for default values. - + The following main.cf parameters are especially relevant + to this program. See the Postfix main.cf file for syntax @@ -71,13 +71,15 @@ POSTLOCK(1) POSTLOCK(1) POSTLOCK(1) POSTLOCK(1) + details and for default values. + Locking controls deliver_lock_attempts - Limit the number of attempts to acquire an exclu- + Limit the number of attempts to acquire an exclu- sive lock. deliver_lock_delay - Time in seconds between successive attempts to + Time in seconds between successive attempts to acquire an exclusive lock. stale_lock_time @@ -85,15 +87,15 @@ POSTLOCK(1) POSTLOCK(1) Resource controls fork_attempts - Number of attempts to fork() a process before giv- + Number of attempts to fork() a process before giv- ing up. fork_delay - Delay in seconds between successive fork() + Delay in seconds between successive fork() attempts. LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -123,8 +125,6 @@ POSTLOCK(1) POSTLOCK(1) - - diff --git a/postfix/html/postmap.1.html b/postfix/html/postmap.1.html index 9b01928dc..7855930a3 100644 --- a/postfix/html/postmap.1.html +++ b/postfix/html/postmap.1.html @@ -9,56 +9,56 @@ POSTMAP(1) POSTMAP(1) postmap - Postfix lookup table management SYNOPSIS - postmap [-c config_dir] [-i] [-v] [file_type:]file_name + postmap [-c config_dir] [-i] [-v] [-w] + [file_type:]file_name DESCRIPTION The postmap command creates a new Postfix lookup table, or - updates an existing one. The input and output formats are + updates an existing one. The input and output formats are expected to be compatible with: makemap file_type file_name < file_name - While the table update is in progress, signal delivery is - postponed, and an exclusive, advisory, lock is placed on + While the table update is in progress, signal delivery is + postponed, and an exclusive, advisory, lock is placed on the entire table, in order to avoid surprises in spectator programs. The format of a lookup table input file is as follows: - o Blank lines are ignored. So are lines beginning + o Blank lines are ignored. So are lines beginning with `#'. o A table entry has the form key whitespace value - o A line that starts with whitespace continues the + o A line that starts with whitespace continues the preceding line. - The key and value are processed as is, except that sur- - rounding white space is stripped off. Unlike with Postfix - alias databases, quotes cannot be used to protect lookup - keys that contain special characters such as `#' or + The key and value are processed as is, except that sur- + rounding white space is stripped off. Unlike with Postfix + alias databases, quotes cannot be used to protect lookup + keys that contain special characters such as `#' or whitespace. The key is mapped to lowercase to make mapping lookups case insensitive. Options: -c config_dir - Read the main.cf configuration file in the named + Read the main.cf configuration file in the named directory. - -i Incremental mode. Read entries from standard input + -i Incremental mode. Read entries from standard input and do not truncate an existing database. By - default, postmap creates a new database from the + default, postmap creates a new database from the entries in file_name. -v Enable verbose logging for debugging purposes. Mul- - tiple -v options make the software increasingly + tiple -v options make the software increasingly verbose. B-w Do not warn about duplicate entries; silently - ignore them. @@ -71,30 +71,32 @@ POSTMAP(1) POSTMAP(1) POSTMAP(1) POSTMAP(1) + ignore them. + Arguments: file_type The type of database to be produced. - btree The output file is a btree file, named - file_name.db. This is available only on + btree The output file is a btree file, named + file_name.db. This is available only on systems with support for db databases. - dbm The output consists of two files, named - file_name.pag and file_name.dir. This is - available only on systems with support for + dbm The output consists of two files, named + file_name.pag and file_name.dir. This is + available only on systems with support for dbm databases. - hash The output file is a hashed file, named - file_name.db. This is available only on + hash The output file is a hashed file, named + file_name.db. This is available only on systems with support for db databases. - When no file_type is specified, the software uses - the database type specified via the database_type + When no file_type is specified, the software uses + the database type specified via the database_type configuration parameter. file_name - The name of the lookup table source file when + The name of the lookup table source file when rebuilding a database. DIAGNOSTICS @@ -111,24 +113,88 @@ POSTMAP(1) POSTMAP(1) CONFIGURATION PARAMETERS database_type - Default output database type. On many UNIX sys- - tems, the default database type is either hash or + Default output database type. On many UNIX sys- + tems, the default database type is either hash or dbm. LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) Wietse Venema IBM T.J. Watson Research P.O. Box 704 + + + + 2 + + + + + +POSTMAP(1) POSTMAP(1) + + Yorktown Heights, NY 10598, USA - 2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 3 diff --git a/postfix/html/uce.html b/postfix/html/uce.html index a4654e46d..42a5ddbb1 100644 --- a/postfix/html/uce.html +++ b/postfix/html/uce.html @@ -510,6 +510,9 @@ on the client hostname or network address.
    smtpd_recipient_restrictions = permit_mynetworks, check_relay_domains +
    smtpd_recipient_restrictions = permit_mynetworks, +reject_unauth_destination +

    Restrictions: @@ -527,6 +530,16 @@ parameter specifies the response code for rejected requests (default:

    + + +

    reject_unauth_destination
    Ignore the client +hostname. Permit the request when the resolved destination address +matches $relay_domains, otherwise +reject. The relay_domains_reject_code parameter specifies +the response code for rejected requests (default: 554). + +

    +

    permit_mx_backup
    Permit the request when the local @@ -784,8 +797,10 @@ subdomain under any of the domains listed in $maps_rbl_domains.
    relay_domains
    This parameter controls the behavior of the check_relay_domains restriction -that can appear as part of a recipient address restriction list. +href="#check_relay_domains"> check_relay_domains and a +href="#reject_unauth_destination"> reject_unauth_destination +restrictions that can appear as part of a recipient address +restriction list.

    diff --git a/postfix/local/Makefile.in b/postfix/local/Makefile.in index 44ebc090a..738d12e57 100644 --- a/postfix/local/Makefile.in +++ b/postfix/local/Makefile.in @@ -201,7 +201,6 @@ forward.o: ../include/vstring_vstream.h forward.o: ../include/iostuff.h forward.o: ../include/stringops.h forward.o: ../include/mail_proto.h -forward.o: ../include/mail_queue.h forward.o: ../include/cleanup_user.h forward.o: ../include/sent.h forward.o: ../include/record.h @@ -265,7 +264,6 @@ local.o: ../include/iostuff.h local.o: ../include/name_mask.h local.o: ../include/set_eugid.h local.o: ../include/dict.h -local.o: ../include/mail_queue.h local.o: ../include/recipient_list.h local.o: ../include/deliver_request.h local.o: ../include/deliver_completed.h diff --git a/postfix/local/command.c b/postfix/local/command.c index ee1c84308..a261497b0 100644 --- a/postfix/local/command.c +++ b/postfix/local/command.c @@ -17,7 +17,7 @@ /* Duplicate commands for the same recipient are suppressed. /* A limited amount of information is exported via the environment: /* HOME, SHELL, LOGNAME, USER, EXTENSION, DOMAIN, RECIPIENT (entire -/* address) and LOCAL (just the local part). The exported +/* address) LOCAL (just the local part) and SENDER. The exported /* information is censored with var_cmd_filter. /* /* Arguments: @@ -150,6 +150,7 @@ int deliver_command(LOCAL_STATE state, USER_ATTR usr_attr, char *command) argv_add(env, "LOGNAME", state.msg_attr.user, "USER", state.msg_attr.user, + "SENDER", state.msg_attr.sender, "RECIPIENT", state.msg_attr.recipient, "LOCAL", state.msg_attr.local, ARGV_END); diff --git a/postfix/local/dotforward.c b/postfix/local/dotforward.c index 51568bbf7..b65877f86 100644 --- a/postfix/local/dotforward.c +++ b/postfix/local/dotforward.c @@ -15,7 +15,8 @@ /* listed in a recipient's .forward file(s) as specified through /* the forward_path configuration parameter. The result is /* zero when no acceptable .forward file was found, or when -/* a recipient is listed in her own .forward file. +/* a recipient is listed in her own .forward file. Expansions +/* are scrutinized with the forward_expansion_filter parameter. /* /* Arguments: /* .IP state @@ -112,7 +113,7 @@ int deliver_dotforward(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) MSG_LOG_STATE(myname, state); /* - * Skip this module if per-user forwarding is disabled. + * Skip this module if per-user forwarding is disabled. */ if (*var_forward_path == 0) return (NO); @@ -147,7 +148,7 @@ int deliver_dotforward(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) * these are the rights of root, the /file and |command delivery routines * will use unprivileged default rights instead. Better safe than sorry. */ - SET_USER_ATTR(usr_attr, mypwd, state.level); + SET_USER_ATTR(usr_attr, mypwd, state.level); /* * DELIVERY POLICY @@ -182,7 +183,8 @@ int deliver_dotforward(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) lookup_status = -1; while ((lhs = mystrtok(&next, ", \t\r\n")) != 0) { - expand_status = local_expand(path, lhs, &state, &usr_attr, (char *) 0); + expand_status = local_expand(path, lhs, &state, &usr_attr, + var_fwd_exp_filter); if ((expand_status & (MAC_PARSE_ERROR | MAC_PARSE_UNDEF)) == 0) { lookup_status = lstat_as(STR(path), &st, usr_attr.uid, usr_attr.gid); diff --git a/postfix/local/forward.c b/postfix/local/forward.c index 3d66a8cff..91f239348 100644 --- a/postfix/local/forward.c +++ b/postfix/local/forward.c @@ -70,7 +70,6 @@ /* Global library. */ #include -#include #include #include #include diff --git a/postfix/local/local.c b/postfix/local/local.c index e75c9a149..d42223b51 100644 --- a/postfix/local/local.c +++ b/postfix/local/local.c @@ -40,6 +40,9 @@ /* \fB$recipient_delimiter.\fR The forms \fI${name?value}\fR and /* \fI${name:value}\fR expand conditionally to \fIvalue\fR when /* \fI$name\fR is (is not) defined. +/* Characters that may have special meaning to the shell or file system +/* are replaced by underscores. The list of acceptable characters +/* is specified with the \fBforward_expansion_filter\fR configuration /* /* An alias or ~/.\fBforward\fR file may list any combination of external /* commands, destination file names, \fB:include:\fR directives, or @@ -69,7 +72,8 @@ /* a new message, so that each recipient has a separate on-file /* delivery status record. /* -/* In order to stop mail forwarding loops early, the software adds a +/* In order to stop mail forwarding loops early, the software adds an +/* optional /* \fBDelivered-To:\fR header with the envelope recipient address. If /* mail arrives for a recipient that is already listed in a /* \fBDelivered-To:\fR header, the message is bounced. @@ -263,14 +267,14 @@ /* /some/where/smrsh -c). /* When a shell is specified, it is invoked even when the command /* contains no shell built-in commands or meta characters. +/* .IP \fBowner_request_special\fR +/* Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +/* addresses. /* .IP \fBprepend_delivered_header\fR /* Prepend an optional \fBDelivered-To:\fR header upon external /* forwarding, delivery to command or file. Specify zero or more of: /* \fBcommand, file, forward\fR. Turning off \fBDelivered-To:\fR when /* forwarding mail is not recommended. -/* .IP \fBowner_request_special\fR -/* Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR -/* addresses. /* .IP \fBrecipient_delimiter\fR /* Separator between username and address extension. /* .SH Mailbox delivery @@ -340,6 +344,9 @@ /* mailbox_command. Illegal characters are replaced by underscores. /* .IP \fBdefault_privs\fR /* Default rights for delivery to external file or command. +/* .IP \fBforward_expansion_filter\fR +/* What characters are allowed to appear in $name expansions of +/* forward_path. Illegal characters are replaced by underscores. /* HISTORY /* .ad /* .fi @@ -390,7 +397,6 @@ /* Global library. */ -#include #include #include #include @@ -428,6 +434,7 @@ char *var_mailbox_transport; char *var_fallback_transport; char *var_forward_path; char *var_cmd_exp_filter; +char *var_fwd_exp_filter; char *var_prop_extension; int var_exp_own_alias; char *var_deliver_hdr; @@ -470,11 +477,7 @@ static int local_deliver(DELIVER_REQUEST *rqst, char *service) deliver_attr_init(&state.msg_attr); state.msg_attr.queue_name = rqst->queue_name; state.msg_attr.queue_id = rqst->queue_id; - state.msg_attr.fp = - mail_queue_open(rqst->queue_name, rqst->queue_id, O_RDWR, 0); - if (state.msg_attr.fp == 0) - msg_fatal("open file %s %s: %m", rqst->queue_name, rqst->queue_id); - close_on_exec(vstream_fileno(state.msg_attr.fp), CLOSE_ON_EXEC); + state.msg_attr.fp = rqst->fp; state.msg_attr.offset = rqst->data_offset; state.msg_attr.sender = rqst->sender; state.msg_attr.relay = service; @@ -506,7 +509,6 @@ static int local_deliver(DELIVER_REQUEST *rqst, char *service) * Clean up. */ delivered_free(state.loop_info); - vstream_fclose(state.msg_attr.fp); return (msg_stat); } @@ -607,6 +609,7 @@ int main(int argc, char **argv) VAR_MAILBOX_TRANSP, DEF_MAILBOX_TRANSP, &var_mailbox_transport, 0, 0, VAR_FALLBACK_TRANSP, DEF_FALLBACK_TRANSP, &var_fallback_transport, 0, 0, VAR_CMD_EXP_FILTER, DEF_CMD_EXP_FILTER, &var_cmd_exp_filter, 1, 0, + VAR_FWD_EXP_FILTER, DEF_FWD_EXP_FILTER, &var_fwd_exp_filter, 1, 0, VAR_PROP_EXTENSION, DEF_PROP_EXTENSION, &var_prop_extension, 0, 0, VAR_DELIVER_HDR, DEF_DELIVER_HDR, &var_deliver_hdr, 0, 0, 0, diff --git a/postfix/local/local_expand.c b/postfix/local/local_expand.c index 8800b4e0e..61806c96b 100644 --- a/postfix/local/local_expand.c +++ b/postfix/local/local_expand.c @@ -103,7 +103,7 @@ static const char *local_expand_lookup(const char *name, int mode, char *ptr) #define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0) if (STREQ(name, "user")) { - return (local->usr_attr->logname); + return (local->state->msg_attr.user); } else if (STREQ(name, "home")) { return (local->usr_attr->home); } else if (STREQ(name, "shell")) { diff --git a/postfix/makedefs b/postfix/makedefs index dbdd3b3e5..21b7b33bd 100644 --- a/postfix/makedefs +++ b/postfix/makedefs @@ -102,7 +102,7 @@ case "$SYSTEM.$RELEASE" in RANLIB=echo SYSLIBS="-lresolv -lsocket -lnsl" case $RELEASE in - 5.[0-4]) CCARGS="$CCARGS -Dusleep=doze";; + 5.[0-4]) CCARGS="$CCARGS -DMISSING_USLEEP";; *) CCARGS="$CCARGS -DHAS_POSIX_REGEXP";; esac # Avoid common types of braindamage @@ -170,7 +170,7 @@ case "$SYSTEM.$RELEASE" in ;; HP-UX.A.09.*) SYSTYPE=HPUX9 SYSLIBS=-ldbm - CCARGS="$CCARGS -Dusleep=doze" + CCARGS="$CCARGS -DMISSING_USLEEP" if [ -f /usr/lib/libdb.a ]; then CCARGS="$CCARGS -DHAS_DB" SYSLIBS="$SYSLIBS -ldb" @@ -178,7 +178,7 @@ HP-UX.A.09.*) SYSTYPE=HPUX9 ;; HP-UX.B.10.*) SYSTYPE=HPUX10 CCARGS="$CCARGS `nm /usr/lib/libc.a 2>/dev/null | - (grep usleep >/dev/null || echo '-Dusleep=doze')`" + (grep usleep >/dev/null || echo '-DMISSING_USLEEP')`" if [ -f /usr/lib/libdb.a ]; then CCARGS="$CCARGS -DHAS_DB" SYSLIBS=-ldb @@ -196,6 +196,9 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 SYSLIBS="-lresolv -lsocket -lnsl" ;; Rhapsody.5*) SYSTYPE=RHAPSODY5 + # Use the native compiler by default + : ${CC=cc} + AWK=gawk ;; ".") if [ -d /NextApps ]; then SYSTYPE=`hostinfo | sed -n \ @@ -204,6 +207,7 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543 SYSTYPE=`hostinfo | sed -n \ 's/^.*NeXT Mach 4.*$/OPENSTEP4/;/OPENSTEP4/{p;q;}'` fi + : ${CC=cc} RANLIB="sleep 5; ranlib" else echo "Unable to determine your system type." 1>&2; exit 1 @@ -226,9 +230,9 @@ case "$CC" in *) : ${OPT='-O'};; esac -: ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} +: ${CC='gcc $(WARN)'} ${OPT='-O'} ${DEBUG='-g'} ${AWK=awk} -export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG OPTS +export SYSTYPE AR ARFL RANLIB SYSLIBS CC OPT DEBUG AWK OPTS sed 's/ / /g' <sender == 0) info->sender = mystrdup(vstring_str(buf)); + if (type == REC_TYPE_RCPT) + if (info->rcpt == 0) + info->rcpt = mystrdup(vstring_str(buf)); if (type == REC_TYPE_TIME) continue; else { @@ -223,8 +227,12 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup, * Copy the message envelope segment. Allow only those records that we * expect to see in the envelope section. The envelope segment must * contain an envelope sender address. + * + * If the segment contains a recipient address, include the optional + * always_bcc recipient. */ info->sender = 0; + info->rcpt = 0; if ((status = copy_segment(qfile, cleanup, info, buf, REC_TYPE_ENVELOPE)) != 0) return (status); if (info->sender == 0) { @@ -235,8 +243,11 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup, (int) info->st.st_uid, info->sender); myfree(info->sender); - if (*var_always_bcc) - rec_fputs(cleanup, REC_TYPE_RCPT, var_always_bcc); + if (info->rcpt) { + if (*var_always_bcc) + rec_fputs(cleanup, REC_TYPE_RCPT, var_always_bcc); + myfree(info->rcpt); + } /* * Message content segment. Send a dummy message length. Prepend a diff --git a/postfix/pipe/Makefile.in b/postfix/pipe/Makefile.in index f58fbf045..aebfd7435 100644 --- a/postfix/pipe/Makefile.in +++ b/postfix/pipe/Makefile.in @@ -70,7 +70,6 @@ pipe.o: ../include/split_at.h pipe.o: ../include/stringops.h pipe.o: ../include/recipient_list.h pipe.o: ../include/deliver_request.h -pipe.o: ../include/mail_queue.h pipe.o: ../include/mail_params.h pipe.o: ../include/mail_conf.h pipe.o: ../include/bounce.h diff --git a/postfix/pipe/pipe.c b/postfix/pipe/pipe.c index 4aa7bbdbd..ed9f8af8a 100644 --- a/postfix/pipe/pipe.c +++ b/postfix/pipe/pipe.c @@ -181,7 +181,6 @@ #include #include -#include #include #include #include @@ -561,7 +560,6 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) char *myname = "deliver_message"; static PIPE_PARAMS conf; static PIPE_ATTR attr; - VSTREAM *src; RECIPIENT_LIST *rcpt_list = &request->rcpt_list; VSTRING *why = vstring_alloc(100); VSTRING *buf; @@ -603,35 +601,20 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) get_service_attr(&attr, argv); } - /* - * Open the queue file. Opening the file can fail for a variety of - * reasons, such as the system running out of resources. Instead of - * throwing away mail, we're raising a fatal error which forces the mail - * system to back off, and retry later. XXX deliver_request() should - * pre-open the queue file while it does all its sanity checks. - */ - src = mail_queue_open(request->queue_name, request->queue_id, O_RDWR, 0); - if (src == 0) - msg_fatal("%s: open %s %s: %m", myname, - request->queue_name, request->queue_id); - if (msg_verbose) - msg_info("%s: file %s", myname, VSTREAM_PATH(src)); - close_on_exec(vstream_fileno(src), CLOSE_ON_EXEC); - /* * Deliver. Set the nexthop and sender variables, and expand the command * argument vector. Recipients will be expanded on the fly. XXX Rewrite * envelope and header addresses according to transport-specific * rewriting rules. */ - if (vstream_fseek(src, request->data_offset, SEEK_SET) < 0) - msg_fatal("seek queue file %s: %m", VSTREAM_PATH(src)); + if (vstream_fseek(request->fp, request->data_offset, SEEK_SET) < 0) + msg_fatal("seek queue file %s: %m", VSTREAM_PATH(request->fp)); dict_update(PIPE_DICT_TABLE, PIPE_DICT_SENDER, request->sender); dict_update(PIPE_DICT_TABLE, PIPE_DICT_NEXTHOP, request->nexthop); expanded_argv = expand_argv(attr.command, rcpt_list); - command_status = pipe_command(src, why, + command_status = pipe_command(request->fp, why, PIPE_CMD_UID, attr.uid, PIPE_CMD_GID, attr.gid, PIPE_CMD_SENDER, request->sender, @@ -641,14 +624,11 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv) PIPE_CMD_END); deliver_status = eval_command_status(command_status, service, request, - src, vstring_str(why)); + request->fp, vstring_str(why)); /* * Clean up. */ - if (vstream_fclose(src)) - msg_warn("close %s %s: %m", request->queue_name, request->queue_id); - vstring_free(why); argv_free(expanded_argv); diff --git a/postfix/postalias/postalias.c b/postfix/postalias/postalias.c index d912c6750..a80d8262d 100644 --- a/postfix/postalias/postalias.c +++ b/postfix/postalias/postalias.c @@ -6,7 +6,7 @@ /* SYNOPSIS /* .fi /* \fBpostalias\fR [\fB-c \fIconfig_dir\fR] [\fB-i\fR] [\fB-v\fR] -/* [\fIfile_type\fR:]\fIfile_name\fR ... +/* [\fB-w\fR] [\fIfile_type\fR:]\fIfile_name\fR ... /* DESCRIPTION /* The \fBpostalias\fR command creates a new Postfix alias database, /* or updates an existing one. The input and output file formats diff --git a/postfix/postconf/Makefile.in b/postfix/postconf/Makefile.in index 187178306..7d5fba67b 100644 --- a/postfix/postconf/Makefile.in +++ b/postfix/postconf/Makefile.in @@ -36,7 +36,7 @@ update: ../bin/$(PROG) $(SAMPLES) cp $(PROG) ../bin $(MAKES): $(INC_DIR)/mail_params.h - sh extract.sh ../*/*.c + $(AWK) -f extract.awk ../*/*.c printfck: $(OBJS) $(PROG) rm -rf printfck diff --git a/postfix/postconf/extract.sh b/postfix/postconf/extract.awk similarity index 96% rename from postfix/postconf/extract.sh rename to postfix/postconf/extract.awk index 69323b484..9d3a33635 100644 --- a/postfix/postconf/extract.sh +++ b/postfix/postconf/extract.awk @@ -1,8 +1,5 @@ -#!/bin/sh - # Extract initialization tables from actual source code. -awk ' /static CONFIG_INT_TABLE/,/};/ { if ($1 ~ /VAR/) { print "int " substr($3,2,length($3)-2) ";" > "int_vars.h" @@ -21,4 +18,3 @@ awk ' print | "sort -u >bool_table.h" } } -' $* diff --git a/postfix/postconf/postconf.c b/postfix/postconf/postconf.c index e681dcea3..762f23b39 100644 --- a/postfix/postconf/postconf.c +++ b/postfix/postconf/postconf.c @@ -5,18 +5,20 @@ /* Postfix configuration utility /* SYNOPSIS /* .fi -/* \fBpostconf\fR [\fB-d\fR] [\fB-h\fR] [\fB-n\fR] [\fB-v\fR] -/* [\fIparameter ...\fR] +/* \fBpostconf\fR [\fB-c \fIconfig_dir\fR] [\fB-d\fR] [\fB-h\fR] +/* [\fB-n\fR] [\fB-v\fR] [\fIparameter ...\fR] /* DESCRIPTION /* The \fBpostconf\fR command prints the actual value of /* \fIparameter\fR (all known parameters by default), one /* parameter per line. /* /* Options: +/* .IP "\fB-c \fIconfig_dir\fR" +/* The \fBmain.cf\fR configuration file is in the named directory. /* .IP \fB-d\fR /* Print default parameter settings instead of actual settings. /* .IP \fB-h\fR -/* Show parameter values only, not the \fIname =\fR information +/* Show parameter values only, not the ``name ='' label /* that normally precedes the value. /* .IP \fB-n\fR /* Print non-default parameter settings only. @@ -25,6 +27,8 @@ /* options make the software increasingly verbose. /* DIAGNOSTICS /* Problems are reported to the standard error stream. +/* Fatal error: out of memory, file not found, invalid \fBmain.cf\fR +/* parameter syntax. /* LICENSE /* .ad /* .fi @@ -289,6 +293,8 @@ static void print_bool(int mode, CONFIG_BOOL_TABLE *cbt) show_strval(mode, cbt->name, cbt->defval ? "yes" : "no"); } else { value = dict_lookup(CONFIG_DICT, cbt->name); + if (value) + (void) get_mail_conf_bool(cbt->name, cbt->defval); if ((mode & SHOW_NONDEF) == 0) { if (value == 0) { show_strval(mode, cbt->name, cbt->defval ? "yes" : "no"); @@ -312,6 +318,8 @@ static void print_int(int mode, CONFIG_INT_TABLE *cit) show_intval(mode, cit->name, cit->defval); } else { value = dict_lookup(CONFIG_DICT, cit->name); + if (value) + (void) get_mail_conf_int(cit->name, cit->defval, cit->min, cit->max); if ((mode & SHOW_NONDEF) == 0) { if (value == 0) { show_intval(mode, cit->name, cit->defval); @@ -335,6 +343,8 @@ static void print_str(int mode, CONFIG_STR_TABLE *cst) show_strval(mode, cst->name, cst->defval); } else { value = dict_lookup(CONFIG_DICT, cst->name); + if (value) + (void) get_mail_conf_str(cst->name, cst->defval, cst->min, cst->max); if ((mode & SHOW_NONDEF) == 0) { if (value == 0) { show_strval(mode, cst->name, cst->defval); @@ -487,8 +497,12 @@ int main(int argc, char **argv) /* * Parse JCL. */ - while ((ch = GETOPT(argc, argv, "dhnv")) > 0) { + while ((ch = GETOPT(argc, argv, "c:dhnv")) > 0) { switch (ch) { + case 'c': + if (setenv(CONF_ENV_PATH, optarg, 1) < 0) + msg_fatal("out of memory"); + break; case 'd': if (mode & SHOW_NONDEF) msg_fatal("specify one of -d and -n"); @@ -506,7 +520,7 @@ int main(int argc, char **argv) msg_verbose++; break; default: - msg_fatal("usage: %s [-d (defaults)] [-h (no names)] [-n (non-defaults)] [-v] name...", argv[0]); + msg_fatal("usage: %s [-c config_directory] [-d (defaults)] [-h (no names)] [-n (non-defaults)] [-v] name...", argv[0]); } } diff --git a/postfix/postlock/postlock.c b/postfix/postlock/postlock.c index 9d728d4d4..44b2ad142 100644 --- a/postfix/postlock/postlock.c +++ b/postfix/postlock/postlock.c @@ -28,7 +28,8 @@ /* access. The command is executed directly, i.e. without /* interpretation by a shell command interpreter. /* DIAGNOSTICS -/* The result status is 255 (on some systems: -1) when \fBpostlock\fR +/* The result status is 75 (EX_TEMPFAIL) when the file is locked by +/* another process, 255 (on some systems: -1) when \fBpostlock\fR /* could not perform the requested operation. Otherwise, the /* exit status is the exit status from the command. /* BUGS @@ -84,6 +85,8 @@ #include #include #include +#include +#include /* Utility library. */ @@ -109,7 +112,7 @@ static NORETURN usage(char *myname) msg_fatal("usage: %s [-c config_dir] [-v] folder command...", myname); } -/* fatal_exit - as promised, return 255 in case of locking problems */ +/* fatal_exit - as promised, return 255 in case of unexpected problems */ static void fatal_exit(void) { @@ -195,11 +198,24 @@ int main(int argc, char **argv) close_on_exec(fd, CLOSE_ON_EXEC); why = vstring_alloc(1); #ifdef USE_DOT_LOCK - if (dot_lockfile(folder, why) < 0) + if (dot_lockfile(folder, why) < 0) { + if (errno == EEXIST) { + msg_warn("dotlock file %s: %s", folder, vstring_str(why)); + exit(EX_TEMPFAIL); + } msg_fatal("dotlock file %s: %s", folder, vstring_str(why)); + } #endif - if (deliver_flock(fd, why) < 0) + if (deliver_flock(fd, why) < 0) { + if (errno == EAGAIN) { + msg_warn("lock %s: %s", folder, vstring_str(why)); +#ifdef USE_DOT_LOCK + dot_unlockfile(folder); +#endif + exit(EX_TEMPFAIL); + } msg_fatal("lock %s: %s", folder, vstring_str(why)); + } /* * Run the command. Remove the lock after completion. diff --git a/postfix/postmap/postmap.c b/postfix/postmap/postmap.c index b50bd6c84..5227bece2 100644 --- a/postfix/postmap/postmap.c +++ b/postfix/postmap/postmap.c @@ -6,7 +6,7 @@ /* SYNOPSIS /* .fi /* \fBpostmap\fR [\fB-c \fIconfig_dir\fR] [\fB-i\fR] [\fB-v\fR] -/* [\fIfile_type\fR:]\fIfile_name\fR +/* [\fB-w\fR] [\fIfile_type\fR:]\fIfile_name\fR /* DESCRIPTION /* The \fBpostmap\fR command creates a new Postfix lookup table, /* or updates an existing one. The input and output formats are diff --git a/postfix/qmgr/qmgr.h b/postfix/qmgr/qmgr.h index 7660e4671..b8e0ae6d7 100644 --- a/postfix/qmgr/qmgr.h +++ b/postfix/qmgr/qmgr.h @@ -234,6 +234,8 @@ struct QMGR_MESSAGE { QMGR_RCPT_LIST rcpt_list; /* complete addresses */ }; +#define QMGR_MESSAGE_LOCKED ((QMGR_MESSAGE *) 1) + extern int qmgr_message_count; extern int qmgr_recipient_count; extern MAPS *qmgr_relocated; diff --git a/postfix/qmgr/qmgr_active.c b/postfix/qmgr/qmgr_active.c index bd7b17bdb..d023ae31a 100644 --- a/postfix/qmgr/qmgr_active.c +++ b/postfix/qmgr/qmgr_active.c @@ -125,6 +125,34 @@ static void qmgr_active_corrupt(const char *queue_id) } } +/* qmgr_active_defer - defer queue file */ + +static void qmgr_active_defer(QMGR_MESSAGE *message, time_t delay) +{ + char *myname = "qmgr_active_defer"; + const char *path; + struct utimbuf tbuf; + + if (msg_verbose) + msg_info("wakeup %s after %ld secs", message->queue_id, (long) delay); + + tbuf.actime = tbuf.modtime = event_time() + delay; + path = mail_queue_path((VSTRING *) 0, message->queue_name, + message->queue_id); + if (utime(path, &tbuf) < 0) + msg_fatal("%s: update %s time stamps: %m", myname, path); + if (mail_queue_rename(message->queue_id, message->queue_name, + MAIL_QUEUE_DEFERRED)) { + if (errno != ENOENT) + msg_fatal("%s: rename %s from %s to %s: %m", myname, + message->queue_id, message->queue_name, MAIL_QUEUE_DEFERRED); + msg_warn("%s: rename %s from %s to %s: %m", myname, + message->queue_id, message->queue_name, MAIL_QUEUE_DEFERRED); + } else if (msg_verbose) { + msg_info("%s: defer %s", myname, message->queue_id); + } +} + /* qmgr_active_feed - feed one message into active queue */ void qmgr_active_feed(QMGR_SCAN *scan_info, const char *queue_id) @@ -172,14 +200,6 @@ void qmgr_active_feed(QMGR_SCAN *scan_info, const char *queue_id) return; } - /* - * Reset the defer log. Leave the bounce log alone; if it is still - * around, something did not send it previously. - */ - if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT) - msg_fatal("%s: %s: remove %s %s: %m", myname, - queue_id, MAIL_QUEUE_DEFER, queue_id); - /* * Extract envelope information: sender and recipients. At this point, * mail addresses have been processed by the cleanup service so they @@ -189,11 +209,30 @@ void qmgr_active_feed(QMGR_SCAN *scan_info, const char *queue_id) * Throwing away queue files seems bad, especially when they made it this * far into the mail system. Therefore we save bad files to a separate * directory for further inspection. + * + * After queue manager restart it is possible that a queue file is still + * being delivered. In that case (the file is locked), defer delivery by + * a minimal amount of time. */ if ((message = qmgr_message_alloc(MAIL_QUEUE_ACTIVE, queue_id, scan_info->flags)) == 0) { qmgr_active_corrupt(queue_id); + } else if (message == QMGR_MESSAGE_LOCKED) { + qmgr_active_defer(message, (time_t) var_min_backoff_time); } else { + + /* + * Reset the defer log. Leave the bounce log alone; if it is still + * around, something did not send it previously. + */ + if (mail_queue_remove(MAIL_QUEUE_DEFER, queue_id) && errno != ENOENT) + msg_fatal("%s: %s: remove %s %s: %m", myname, + queue_id, MAIL_QUEUE_DEFER, queue_id); + + /* + * Special case if all recipients were already delivered. Send any + * bounces and clean up. + */ if (message->refcount == 0) qmgr_active_done(message); } @@ -206,7 +245,6 @@ void qmgr_active_done(QMGR_MESSAGE *message) char *myname = "qmgr_active_done"; struct stat st; const char *path; - struct utimbuf tbuf; time_t delay; if (msg_verbose) @@ -292,9 +330,9 @@ void qmgr_active_done(QMGR_MESSAGE *message) if (msg_verbose) msg_info("%s: sending defer warning for %s", myname, message->queue_id); if (defer_warn(BOUNCE_FLAG_KEEP, - message->queue_name, - message->queue_id, - message->errors_to) == 0) { + message->queue_name, + message->queue_id, + message->errors_to) == 0) { qmgr_message_update_warn(message); } } @@ -321,23 +359,7 @@ void qmgr_active_done(QMGR_MESSAGE *message) } else { delay = var_min_backoff_time; } - if (msg_verbose) - msg_info("wakeup %s after %ld secs", message->queue_id, delay); - tbuf.actime = tbuf.modtime = event_time() + delay; - path = mail_queue_path((VSTRING *) 0, message->queue_name, - message->queue_id); - if (utime(path, &tbuf) < 0) - msg_fatal("%s: update %s time stamps: %m", myname, path); - if (mail_queue_rename(message->queue_id, message->queue_name, - MAIL_QUEUE_DEFERRED)) { - if (errno != ENOENT) - msg_fatal("%s: rename %s from %s to %s: %m", myname, - message->queue_id, message->queue_name, MAIL_QUEUE_DEFERRED); - msg_warn("%s: rename %s from %s to %s: %m", myname, - message->queue_id, message->queue_name, MAIL_QUEUE_DEFERRED); - } else if (msg_verbose) { - msg_info("%s: defer %s", myname, message->queue_id); - } + qmgr_active_defer(message, delay); } /* diff --git a/postfix/qmgr/qmgr_message.c b/postfix/qmgr/qmgr_message.c index ec928ea80..1e6ec2e25 100644 --- a/postfix/qmgr/qmgr_message.c +++ b/postfix/qmgr/qmgr_message.c @@ -36,12 +36,13 @@ /* qmgr_message_alloc() creates an in-core message structure /* with sender and recipient information taken from the named queue /* file. A null result means the queue file could not be read or -/* that the queue file contained incorrect information. The number +/* that the queue file contained incorrect information. A result +/* QMGR_MESSAGE_LOCKED means delivery must be deferred. The number /* of recipients read from a queue file is limited by the global /* var_qmgr_rcpt_limit configuration parameter. When the limit /* is reached, the \fIrcpt_offset\fR structure member is set to /* the position where the read was terminated. Recipients are -/* ru through the resolver, and are assigned to destination +/* run through the resolver, and are assigned to destination /* queues. Recipients that cannot be assigned are deferred or /* bounced. Mail that has bounced twice is silently absorbed. /* @@ -95,6 +96,7 @@ #include #include #include +#include /* Global library. */ @@ -663,10 +665,17 @@ QMGR_MESSAGE *qmgr_message_alloc(const char *queue_name, const char *queue_id, * Extract message envelope information: time of arrival, sender address, * recipient addresses. Skip files with malformed envelope information. */ +#define QMGR_LOCK_MODE (MYFLOCK_EXCLUSIVE | MYFLOCK_NOWAIT) + if (qmgr_message_open(message) < 0) { qmgr_message_free(message); return (0); } + if (myflock(vstream_fileno(message->fp), QMGR_LOCK_MODE) < 0) { + qmgr_message_close(message); + qmgr_message_free(message); + return (QMGR_MESSAGE_LOCKED); + } if (qmgr_message_read(message) < 0) { qmgr_message_close(message); qmgr_message_free(message); diff --git a/postfix/sendmail/sendmail.c b/postfix/sendmail/sendmail.c index a6b41020e..ae44fb041 100644 --- a/postfix/sendmail/sendmail.c +++ b/postfix/sendmail/sendmail.c @@ -595,6 +595,18 @@ int main(int argc, char **argv) msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY); set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0])); + /* + * Do not set[e]uid(getuid()). This allows the real user to manipulate + * the process, which is dangerous, because some systems do not reset the + * saved set-userid unless euid == 0. + */ +#ifdef WARN_SETXID_SENDMAIL + if (geteuid() != getuid()) + msg_warn("sendmail is set-uid or is run from a set-uid process"); + if (getegid() != getgid()) + msg_warn("sendmail is set-gid or is run from a set-gid process"); +#endif + mail_conf_read(); if (chdir(var_queue_dir)) msg_fatal("chdir %s: %m", var_queue_dir); @@ -773,7 +785,7 @@ int main(int argc, char **argv) argv_add(ext_argv, "-v", (char *) 0); argv_add(ext_argv, "start", (char *) 0); argv_terminate(ext_argv); - err = mail_run_background(var_command_dir, ext_argv->argv); + err = (mail_run_background(var_command_dir, ext_argv->argv) < 0); argv_free(ext_argv); exit(err); break; diff --git a/postfix/showq/showq.c b/postfix/showq/showq.c index 1e6d1e93a..d43bccab8 100644 --- a/postfix/showq/showq.c +++ b/postfix/showq/showq.c @@ -317,7 +317,8 @@ static void showq_service(VSTREAM *client, char *unused_service, char **argv) msg_warn("close file %s %s: %m", *queue, id); } else if (strcmp(*queue, MAIL_QUEUE_MAILDROP) == 0) { queue_size += st.st_size; - vstream_fprintf(client, DATA_FORMAT, id, (long) st.st_size, + vstream_fprintf(client, DATA_FORMAT, id, ' ', + (long) st.st_size, asctime(localtime(&st.st_mtime)), "(to be determined)"); } else if (errno != ENOENT) diff --git a/postfix/smtp/Makefile.in b/postfix/smtp/Makefile.in index cd78128a3..53adda307 100644 --- a/postfix/smtp/Makefile.in +++ b/postfix/smtp/Makefile.in @@ -78,7 +78,6 @@ smtp.o: ../include/name_mask.h smtp.o: ../include/deliver_request.h smtp.o: ../include/vstring.h smtp.o: ../include/recipient_list.h -smtp.o: ../include/mail_queue.h smtp.o: ../include/mail_params.h smtp.o: ../include/mail_conf.h smtp.o: ../include/debug_peer.h diff --git a/postfix/smtp/smtp.c b/postfix/smtp/smtp.c index 2881bb99b..801d1820f 100644 --- a/postfix/smtp/smtp.c +++ b/postfix/smtp/smtp.c @@ -168,7 +168,6 @@ /* Global library. */ #include -#include #include #include #include @@ -242,20 +241,7 @@ static int deliver_message(DELIVER_REQUEST *request) why = vstring_alloc(100); state = smtp_state_alloc(); state->request = request; - - /* - * Open the queue file. Opening the file can fail for a variety of - * reasons, such as the system running out of resources. Instead of - * throwing away mail, we're raising a fatal error which forces the mail - * system to back off, and retry later. - */ - state->src = mail_queue_open(request->queue_name, request->queue_id, - O_RDWR, 0); - if (state->src == 0) - msg_fatal("%s: open %s %s: %m", myname, - request->queue_name, request->queue_id); - if (msg_verbose) - msg_info("%s: file %s", myname, VSTREAM_PATH(state->src)); + state->src = request->fp; /* * Establish an SMTP session and deliver this message to all requested @@ -287,8 +273,6 @@ static int deliver_message(DELIVER_REQUEST *request) /* * Clean up. */ - if (vstream_fclose(state->src)) - msg_warn("close %s %s: %m", request->queue_name, request->queue_id); vstring_free(why); smtp_chat_reset(state); result = state->status; diff --git a/postfix/smtp/smtp_addr.c b/postfix/smtp/smtp_addr.c index 9d32ba074..86e257268 100644 --- a/postfix/smtp/smtp_addr.c +++ b/postfix/smtp/smtp_addr.c @@ -365,6 +365,8 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why) DNS_RR *mx_names; DNS_RR *addr_list = 0; DNS_RR *self; + unsigned best_pref; + unsigned best_found; /* * Sanity check. @@ -395,14 +397,21 @@ DNS_RR *smtp_domain_addr(char *name, VSTRING *why) break; case DNS_OK: mx_names = dns_rr_sort(mx_names, smtp_compare_mx); + best_pref = (mx_names ? mx_names->pref : ~0); addr_list = smtp_addr_list(mx_names, why); dns_rr_free(mx_names); + best_found = (addr_list ? addr_list->pref : ~0); if (*var_fallback_relay) addr_list = smtp_addr_fallback(addr_list); if (msg_verbose) smtp_print_addr(name, addr_list); if ((self = smtp_find_self(addr_list)) != 0) addr_list = smtp_truncate_self(addr_list, self->pref, name, why); + if (addr_list == 0 && best_pref < best_found) { + vstring_sprintf(why, "unable to find primary mail relay for %s", + name); + smtp_errno = SMTP_RETRY; + } break; case DNS_NOTFOUND: addr_list = smtp_host_addr(name, why); diff --git a/postfix/smtp/smtp_connect.c b/postfix/smtp/smtp_connect.c index 429119ebe..104ff958f 100644 --- a/postfix/smtp/smtp_connect.c +++ b/postfix/smtp/smtp_connect.c @@ -276,7 +276,7 @@ SMTP_SESSION *smtp_connect_domain(char *name, unsigned port, VSTRING *why) break; } msg_info("%s; address %s port %d", vstring_str(why), - inet_ntoa(*((struct in_addr *) addr->data)), port); + inet_ntoa(*((struct in_addr *) addr->data)), ntohs(port)); } dns_rr_free(addr_list); return (session); diff --git a/postfix/smtp/smtp_proto.c b/postfix/smtp/smtp_proto.c index cb0080354..1e66f0c92 100644 --- a/postfix/smtp/smtp_proto.c +++ b/postfix/smtp/smtp_proto.c @@ -180,9 +180,6 @@ int smtp_helo(SMTP_STATE *state) if (n == 0 && strcasecmp(word, var_myhostname) == 0) { msg_warn("host %s greeted me with my own hostname %s", session->namaddr, var_myhostname); - return (smtp_site_fail(state, session->best ? 550 : 450, - "mail for %s loops back to myself", - request->nexthop)); } else if (strcasecmp(word, "ESMTP") == 0) state->features |= SMTP_FEATURE_ESMTP; } @@ -213,7 +210,6 @@ int smtp_helo(SMTP_STATE *state) * advertises a really huge message size limit. */ lines = resp->str; - (void) mystrtok(&lines, "\n"); while ((words = mystrtok(&lines, "\n")) != 0) { if (mystrtok(&words, "- ") && (word = mystrtok(&words, " \t")) != 0) { if (strcasecmp(word, "8BITMIME") == 0) @@ -222,6 +218,13 @@ int smtp_helo(SMTP_STATE *state) state->features |= SMTP_FEATURE_PIPELINING; else if (strcasecmp(word, "SIZE") == 0) state->features |= SMTP_FEATURE_SIZE; + else if (strcasecmp(word, var_myhostname) == 0) { + msg_warn("host %s replied to HELO/EHLO with my own hostname %s", + session->namaddr, var_myhostname); + return (smtp_site_fail(state, session->best ? 550 : 450, + "mail for %s loops back to myself", + request->nexthop)); + } } } if (msg_verbose) diff --git a/postfix/smtpd/smtpd_check.c b/postfix/smtpd/smtpd_check.c index c3ad748e3..7a091d2c6 100644 --- a/postfix/smtpd/smtpd_check.c +++ b/postfix/smtpd/smtpd_check.c @@ -124,6 +124,10 @@ /* parameter. Reject the request otherwise. /* The \fIrelay_domains_reject_code\fR configuration parameter specifies /* the reject status code (default: 554). +/* .IP reject_unauth_destination +/* Allow the request when the resolved recipient domain matches the +/* \fIrelay_domains\fR configuration parameter. Reject the request +/* otherwise. Same error code as check_relay_domains. /* .IP permit_mx_backup /* Allow the request when the local mail system is mail exchanger /* for the recipient domain (this includes the case where the local @@ -400,11 +404,22 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class, * postmaster notices, this may be the only trace left that service was * rejected. Print the request, client name/address, and response. */ - msg_info(state->recipient ? "reject: %s from %s: %s; from=<%s> to=<%s>" - : state->sender ? "reject: %s from %s: %s; from=<%s>" - : "reject: %s from %s: %s", - state->where, state->namaddr, STR(error_text), - state->sender, state->recipient); + if (state->recipient && state->sender) { + msg_info("reject: %s from %s: %s; from=<%s> to=<%s>", + state->where, state->namaddr, STR(error_text), + state->sender, state->recipient); + } else if (state->recipient) { + msg_info("reject: %s from %s: %s; to=<%s>", + state->where, state->namaddr, STR(error_text), + state->recipient); + } else if (state->sender) { + msg_info("reject: %s from %s: %s; from=<%s>", + state->where, state->namaddr, STR(error_text), + state->sender); + } else { + msg_info("reject: %s from %s: %s", + state->where, state->namaddr, STR(error_text)); + } return (SMTPD_CHECK_REJECT); } @@ -656,6 +671,45 @@ static int check_relay_domains(SMTPD_STATE *state, char *recipient, var_relay_code, reply_name, reply_class)); } +/* reject_unauth_destination - FAIL for message relaying */ + +static int reject_unauth_destination(SMTPD_STATE *state, char *recipient) +{ + char *myname = "reject_unauth_destination"; + char *domain; + + if (msg_verbose) + msg_info("%s: %s", myname, recipient); + + /* + * Resolve the address. + */ + canon_addr_internal(query, recipient); + resolve_clnt_query(STR(query), &reply); + + /* + * Permit if destination is local. XXX This must be generalized for + * per-domain user tables and for non-UNIX local delivery agents. + */ + if (STR(reply.nexthop)[0] == 0 + || (domain = strrchr(STR(reply.recipient), '@')) == 0) + return (SMTPD_CHECK_DUNNO); + domain += 1; + + /* + * Permit if the destination matches the relay_domains list. + */ + if (domain_list_match(relay_domains, domain)) + return (SMTPD_CHECK_DUNNO); + + /* + * Deny relaying between sites that both are not in relay_domains. + */ + return (smtpd_check_reject(state, MAIL_ERROR_POLICY, + "%d <%s>: Relay access denied", + var_relay_code, recipient)); +} + /* has_my_addr - see if this host name lists one of my network addresses */ static int has_my_addr(char *host) @@ -1489,6 +1543,8 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) recipient, SMTPD_NAME_RECIPIENT); } else if (strcasecmp(name, PERMIT_MX_BACKUP) == 0) { status = permit_mx_backup(state, recipient); + } else if (strcasecmp(name, REJECT_UNAUTH_DEST) == 0) { + status = reject_unauth_destination(state, recipient); } else if (strcasecmp(name, CHECK_RELAY_DOMAINS) == 0) { status = check_relay_domains(state, recipient, recipient, SMTPD_NAME_RECIPIENT); diff --git a/postfix/smtpstone/smtp-source.c b/postfix/smtpstone/smtp-source.c index 078e7f393..d6150beff 100644 --- a/postfix/smtpstone/smtp-source.c +++ b/postfix/smtpstone/smtp-source.c @@ -83,6 +83,7 @@ #include #include #include +#include /* Global library. */ @@ -261,7 +262,11 @@ static void startup(SESSION *session) if (!connect(fd, (struct sockaddr *) & sin, sizeof(sin))) break; if (session->connect_count-- > 1) +#ifdef MISSING_USLEEP + doze(10); +#else usleep(10); +#endif } session->stream = vstream_fdopen(fd, O_RDWR); smtp_timeout_setup(session->stream, var_timeout); diff --git a/postfix/util/Makefile.in b/postfix/util/Makefile.in index 9d34b33fc..1c8b7dc68 100644 --- a/postfix/util/Makefile.in +++ b/postfix/util/Makefile.in @@ -297,7 +297,6 @@ close_on_exec.o: close_on_exec.c close_on_exec.o: sys_defs.h close_on_exec.o: msg.h close_on_exec.o: iostuff.h -compat.o: compat.c concatenate.o: concatenate.c concatenate.o: sys_defs.h concatenate.o: mymalloc.h diff --git a/postfix/util/dict_db.c b/postfix/util/dict_db.c index e96e8820c..db2ed34e7 100644 --- a/postfix/util/dict_db.c +++ b/postfix/util/dict_db.c @@ -56,6 +56,7 @@ #include #endif #include +#include /* Utility library. */ @@ -345,18 +346,32 @@ static void dict_db_close(DICT *dict) /* dict_db_open - open data base */ -static DICT *dict_db_open(const char *path, int flags, int type, +static DICT *dict_db_open(const char *path, int open_flags, int type, void *tweak, int dict_flags) { DICT_DB *dict_db; struct stat st; DB *db; char *db_path; + int lock_fd = -1; db_path = concatenate(path, ".db", (char *) 0); - if ((db = dbopen(db_path, flags, 0644, type, tweak)) == 0) + + if (dict_flags & DICT_FLAG_LOCK) { + if ((lock_fd = open(db_path, open_flags, 0644)) < 0) + msg_fatal("open database %s: %m", db_path); + if (myflock(lock_fd, MYFLOCK_SHARED) < 0) + msg_fatal("shared-lock database %s for open: %m", db_path); + } + if ((db = dbopen(db_path, open_flags, 0644, type, tweak)) == 0) msg_fatal("open database %s: %m", db_path); + if (dict_flags & DICT_FLAG_LOCK) { + if (myflock(lock_fd, MYFLOCK_NONE) < 0) + msg_fatal("unlock database %s for open: %m", db_path); + if (close(lock_fd) < 0) + msg_fatal("close database %s: %m", db_path); + } dict_db = (DICT_DB *) mymalloc(sizeof(*dict_db)); dict_db->dict.lookup = dict_db_lookup; dict_db->dict.update = dict_db_update; @@ -369,7 +384,7 @@ static DICT *dict_db_open(const char *path, int flags, int type, dict_db->dict.mtime = st.st_mtime; close_on_exec(dict_db->dict.fd, CLOSE_ON_EXEC); dict_db->dict.flags = dict_flags | DICT_FLAG_FIXED; - if ((flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0) + if ((dict_flags & (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL)) == 0) dict_db->dict.flags |= (DICT_FLAG_TRY1NULL | DICT_FLAG_TRY0NULL); dict_db->db = db; dict_db->path = db_path; diff --git a/postfix/util/dict_dbm.c b/postfix/util/dict_dbm.c index 64d7d346b..46d9aea3d 100644 --- a/postfix/util/dict_dbm.c +++ b/postfix/util/dict_dbm.c @@ -39,6 +39,7 @@ #include #include #include +#include /* Utility library. */ @@ -48,6 +49,7 @@ #include "iostuff.h" #include "vstring.h" #include "myflock.h" +#include "stringops.h" #include "dict.h" #include "dict_dbm.h" @@ -349,6 +351,16 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags) DICT_DBM *dict_dbm; struct stat st; DBM *dbm; + char *dbm_path; + int lock_fd; + + if (dict_flags & DICT_FLAG_LOCK) { + dbm_path = concatenate(path, ".pag", (char *) 0); + if ((lock_fd = open(dbm_path, open_flags, 0644)) < 0) + msg_fatal("open database %s: %m", dbm_path); + if (myflock(lock_fd, MYFLOCK_SHARED) < 0) + msg_fatal("shared-lock database %s for open: %m", dbm_path); + } /* * XXX SunOS 5.x has no const in dbm_open() prototype. @@ -356,6 +368,13 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags) if ((dbm = dbm_open((char *) path, open_flags, 0644)) == 0) msg_fatal("open database %s.{dir,pag}: %m", path); + if (dict_flags & DICT_FLAG_LOCK) { + if (myflock(lock_fd, MYFLOCK_NONE) < 0) + msg_fatal("unlock database %s for open: %m", dbm_path); + if (close(lock_fd) < 0) + msg_fatal("close database %s: %m", dbm_path); + myfree(dbm_path); + } dict_dbm = (DICT_DBM *) mymalloc(sizeof(*dict_dbm)); dict_dbm->dict.lookup = dict_dbm_lookup; dict_dbm->dict.update = dict_dbm_update; @@ -366,7 +385,6 @@ DICT *dict_dbm_open(const char *path, int open_flags, int dict_flags) if (fstat(dict_dbm->dict.fd, &st) < 0) msg_fatal("dict_dbm_open: fstat: %m"); dict_dbm->dict.mtime = st.st_mtime; - close_on_exec(dict_dbm->dict.fd, CLOSE_ON_EXEC); dict_dbm->dict.flags = dict_flags | DICT_FLAG_FIXED; if ((dict_flags & (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL)) == 0) dict_dbm->dict.flags |= (DICT_FLAG_TRY0NULL | DICT_FLAG_TRY1NULL); diff --git a/postfix/util/inet_addr_local.c b/postfix/util/inet_addr_local.c index dbe02f9a5..3acc2b3b9 100644 --- a/postfix/util/inet_addr_local.c +++ b/postfix/util/inet_addr_local.c @@ -9,7 +9,7 @@ /* int inet_addr_local(list) /* INET_ADDR_LIST *list; /* DESCRIPTION -/* inet_addr_local() determines all active interface addresses +/* inet_addr_local() determines all active IP interface addresses /* of the local system. Any address found is appended to the /* specified address list. The result value is the number of /* active interfaces found. @@ -51,6 +51,21 @@ #include #include + /* + * Support for variable-length addresses. + */ +#ifdef _SIZEOF_ADDR_IFREQ +#define NEXT_INTERFACE(ifr) ((struct ifreq *) \ + ((char *) ifr + _SIZEOF_ADDR_IFREQ(*ifr))) +#else +#ifdef HAS_SA_LEN +#define NEXT_INTERFACE(ifr) ((struct ifreq *) \ + ((char *) ifr + sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len)) +#else +#define NEXT_INTERFACE(ifr) (ifr + 1) +#endif +#endif + /* inet_addr_local - find all IP addresses for this host */ int inet_addr_local(INET_ADDR_LIST *addr_list) @@ -109,16 +124,7 @@ int inet_addr_local(INET_ADDR_LIST *addr_list) &(((struct sockaddr_in *) & ifreq.ifr_addr)->sin_addr)); } } - - /* - * Support for variable-length addresses. - */ -#ifdef HAS_SA_LEN - ifr = (struct ifreq *) - ((char *) ifr + sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len); -#else - ifr++; -#endif + ifr = NEXT_INTERFACE(ifr); } vstring_free(buf); (void) close(sock); diff --git a/postfix/util/scan_dir.c b/postfix/util/scan_dir.c index 1b5680bde..3c8cc2590 100644 --- a/postfix/util/scan_dir.c +++ b/postfix/util/scan_dir.c @@ -63,7 +63,20 @@ /* System library. */ #include +#ifdef HAVE_DIRENT_H #include +#else +#define dirent direct +#ifdef HAVE_SYS_NDIR_H +#include +#endif +#ifdef HAVE_SYS_DIR_H +#include +#endif +#ifdef HAVE_NDIR_H +#include +#endif +#endif #include /* Utility library. */ diff --git a/postfix/util/split_at.c b/postfix/util/split_at.c index 2264f3083..c75e90204 100644 --- a/postfix/util/split_at.c +++ b/postfix/util/split_at.c @@ -20,6 +20,9 @@ /* /* split_at_right() looks for the rightmost delimiter /* occurrence, but is otherwise identical to split_at(). +/* DIAGNOSTICS +/* The result is a null pointer when the delimiter character +/* was not found. /* HISTORY /* .ad /* .fi diff --git a/postfix/util/sys_defs.h b/postfix/util/sys_defs.h index 70126fa8b..7a956383b 100644 --- a/postfix/util/sys_defs.h +++ b/postfix/util/sys_defs.h @@ -49,10 +49,15 @@ #if defined(RHAPSODY5) #define NORETURN void +#define HAS_NETINFO #endif #ifdef ULTRIX4 #define SUPPORTED +/* Ultrix by default has only 64 descriptors per process */ +#ifndef FD_SETSIZE +#define FD_SETSIZE 96 +#endif #include #define UNSAFE_CTYPE /* XXX verify */ #define _PATH_MAILDIR "/var/spool/mail" @@ -85,11 +90,7 @@ extern int opterr; /* Ultrix misses just S_ISSOCK, the others are there */ #define S_ISSOCK(mode) (((mode) & (S_IFMT)) == (S_IFSOCK)) #define DUP2_DUPS_CLOSE_ON_EXEC -/* Ultrix by default has only 64 descriptors per process */ -#ifndef FD_SETSIZE -#define FD_SETSIZE 100 -#endif -#define usleep doze +#define MISSING_USLEEP #endif #ifdef OSF1 @@ -316,7 +317,7 @@ extern int initgroups(const char *, int); #endif #if defined(IRIX5) -#define usleep doze +#define MISSING_USLEEP #endif #ifdef LINUX2 @@ -324,6 +325,7 @@ extern int initgroups(const char *, int); #include #define USE_PATHS_H #define USE_FLOCK_LOCK +#define USE_DOT_LOCK #define HAS_FSYNC #define HAS_DB #define DEF_DB_TYPE "hash" @@ -337,6 +339,7 @@ extern int initgroups(const char *, int); #define UNIX_DOMAIN_CONNECT_BLOCKS_FOR_ACCEPT #define PREPEND_PLUS_TO_OPTSTRING #define HAS_POSIX_REGEXP +#define WARN_SETXID_SENDMAIL #endif /* @@ -460,7 +463,7 @@ extern int h_errno; #define _PATH_STDPATH "/bin:/usr/bin:/usr/ucb" #define ROOT_PATH "/bin:/usr/bin:/usr/etc:/usr/ucb" #define DEF_DB_TYPE "dbm" -#define ALIAS_DB_MAP "dbm:/etc/sendmail/aliases" +#define ALIAS_DB_MAP "netinfo:/aliases" #include #define MISSING_POSIX_S_IS #define MISSING_POSIX_S_MODES @@ -508,7 +511,7 @@ extern int opterr; #define _PATH_STDPATH "/bin:/usr/bin:/usr/ucb" #define ROOT_PATH "/bin:/usr/bin:/usr/etc:/usr/ucb" #define DEF_DB_TYPE "dbm" -#define ALIAS_DB_MAP "dbm:/etc/sendmail/aliases" +#define ALIAS_DB_MAP "netinfo:/aliases" #include #define MISSING_POSIX_S_IS #define MISSING_POSIX_S_MODES @@ -549,7 +552,7 @@ extern int opterr; /* XXX use */ #define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin:/usr/ucb" #define USE_STATVFS #define STATVFS_IN_SYS_STATVFS_H -#define usleep doze +#define MISSING_USLEEP #endif /*