Postfix version 2.0.3 brings the usual short list of corrections. - Postfix 2.0 broke relocated table lookup results with mail not rejected at the SMTP port, causing "User has moved to" text to be deleted. - A widely used maildir filename generating algorithm was broken. This affects all Postfix versions with maildir support. Instead of TIME.PID_COUNT.HOST Postfix now uses TIME.DEVICE_INODE.HOST. - Postfix 2.0 gave incorrect FILTER_README instructions for sites that wish to disable virtual alias mapping before the content filter. Prereq: "2.0.2" diff -cr /tmp/postfix-2.0.2/src/global/mail_version.h ./src/global/mail_version.h *** /tmp/postfix-2.0.2/src/global/mail_version.h Wed Jan 15 10:07:19 2003 --- ./src/global/mail_version.h Fri Jan 24 09:53:38 2003 *************** *** 20,29 **** * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ ! #define MAIL_RELEASE_DATE "20030115" #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "2.0.2" extern char *var_mail_version; /* --- 20,29 ---- * Patches change the patchlevel and the release date. Snapshots change the * release date only, unless they include the same bugfix as a patch release. */ ! #define MAIL_RELEASE_DATE "20030124" #define VAR_MAIL_VERSION "mail_version" ! #define DEF_MAIL_VERSION "2.0.3" extern char *var_mail_version; /* diff -cr /tmp/postfix-2.0.2/HISTORY ./HISTORY *** /tmp/postfix-2.0.2/HISTORY Wed Jan 15 10:12:46 2003 --- ./HISTORY Fri Jan 24 09:50:50 2003 *************** *** 7556,7562 **** Bugfix: transport_errno was not reset upon successful transport map wildcard lookup after an earlier failure. ! Reported by Victor Duchovny. File: trivial-rewrite/transport.c. Cleanup: unnecessary warnings from the proxymap client after proxymap server disconnect. File: global/dict_proxy.c. --- 7556,7562 ---- Bugfix: transport_errno was not reset upon successful transport map wildcard lookup after an earlier failure. ! Reported by Victor Duchovni. File: trivial-rewrite/transport.c. Cleanup: unnecessary warnings from the proxymap client after proxymap server disconnect. File: global/dict_proxy.c. *************** *** 7577,7582 **** --- 7577,7624 ---- stable release. "sendmail -bs" tried to access the proxymap service. It should not try to open any user/domain/uce related tables at all. File: smtpd/smtpd.c. + + 20030118 + + Typos: some hyperlinks referred to flushd, which is the + name that was used before the flush service was released. + Reported by Victor Duchovni. + + Cleanup: smtpd no longer needed to open relocated_maps. + + 20030119 + + Cleanup: bounce messages used "X-Postfix" even when mail_name + was set to something other than the default "Postfix" name. + File: bounce/bounce-notify_util.c. + + 20030120 + + Bugfix: wrong FILTER_README instructions for disabling + virtual alias mapping in the cleanup server before the + content filter. + + Bugfix: wrong FILTER_README instructions for destination-dependent + filtering, because relay_domains was specified incorrectly. + + 20030122 + + Bugfix: 20021207 (move relocated table lookup from queue + manager to trivial-rewrite server) broke relocated table + lookup results with mail not rejected at the SMTP port. + Files: *qmgr/qmgr_deliver.c, *qmgr/qmgr_message.c. + + 20030123 + + Bugfix: a widely used maildir filename algorithm was broken. + Postfix now uses TIME.DEVICE_INODE.HOST. Files: local/maildir.c, + virtual/maildir.c. + + 20030124 + + Cleanup: removed the address syntax check from the queue + manager, since a better test was implemented recently in + the trivial-rewrite server. Files: *qmgr/qmgr_message.c. Open problems: diff -cr /tmp/postfix-2.0.2/README_FILES/FILTER_README ./README_FILES/FILTER_README *** /tmp/postfix-2.0.2/README_FILES/FILTER_README Wed Jan 1 19:38:50 2003 --- ./README_FILES/FILTER_README Thu Jan 23 14:07:51 2003 *************** *** 298,303 **** --- 298,306 ---- because a lot of main.cf like information gets listed in the master.cf file. This makes the system hard to understand. + Even worse, details change as Postfix evolves and different + configuration parameters are implemented by different programs. + If you need to squeeze out more performance, it is probably simpler to run multiple Postfix instances, one before and one after the content filter. That way, each instance can have simple main.cf *************** *** 308,331 **** SMTP mail via localhost port 10025, and that submits SMTP mail back into Postfix via localhost port 10026. ! ................................... ! : Postfix : ! ----->smtpd \ : ! : -cleanup-\ /local----> ! ---->pickup / -queue- : ! : cleanup2/ | \smtp-----> ! : ^ v : ! : | v : ! : smtpd scan : ! : 10026 | : ! .......................|........... ! ^ | ! | v ! ....|............. ! : | 10025 : ! : filter : ! : : ! .................. To enable content filtering in this manner, specify in main.cf a new parameter: --- 311,334 ---- SMTP mail via localhost port 10025, and that submits SMTP mail back into Postfix via localhost port 10026. ! ....................................... ! : Postfix : ! ----->smtpd \ : ! : -pre-cleanup-\ /local----> ! ---->pickup / -queue- : ! : -cleanup-/ | \smtp-----> ! : bounces/ ^ v : ! : and locally | v : ! : forwarded smtpd scan : ! : messages 10026 | : ! ...........................|........... ! ^ | ! | v ! ....|............. ! : | 10025 : ! : filter : ! : : ! .................. To enable content filtering in this manner, specify in main.cf a new parameter: *************** *** 335,366 **** /etc/postfix/master.cf: # ! # This is the usual input "smtpd" already present in master.cf ! # ! smtp inet n - n - - smtpd # # ------------------------------------------------------------------ # # This is the cleanup daemon that handles messages in front of # the content filter. It does header_checks and body_checks (if ! # any), but does no virtual alias or canonical address mapping. # # Virtual alias or canonical address mapping happens in the second # cleanup phase after the content filter. This gives the content_filter # access to *largely* unmodified addresses for maximum flexibility. # ! # Turning off append_myorigin/append_dot_mydomain address rewriting ! # before the content filter would require two instances of the ! # trivial-rewrite daemon. If you want to go to this trouble then ! # you're clearly better off with two complete Postfix instances: one ! # in front of and one behind the content filter. ! # ! # Note that some sites may specifically want to do the opposite: ! # perform rewrites in front of the content_filter which would ! # then see only cleaned up addresses. In that case the "-o" parameter ! # settings below should be moved to the second "cleanup" instance. # ! cleanup unix n - n - 0 cleanup -o canonical_maps= -o sender_canonical_maps= -o recipient_canonical_maps= --- 338,371 ---- /etc/postfix/master.cf: # ! # These are the usual input "smtpd" and local "pickup" servers already ! # present in master.cf. We add an option to select a non-default ! # cleanup service (defined further below). ! # ! smtp inet n - n - - smtpd ! -o cleanup_service=pre-cleanup ! pickup fifo n - n 60 1 pickup ! -o cleanup_service=pre-cleanup # # ------------------------------------------------------------------ # # This is the cleanup daemon that handles messages in front of # the content filter. It does header_checks and body_checks (if ! # any), but does no virtual alias or canonical address mapping, ! # so that mail passes through your content filter with the original ! # recipient addresses mostly intact. # # Virtual alias or canonical address mapping happens in the second # cleanup phase after the content filter. This gives the content_filter # access to *largely* unmodified addresses for maximum flexibility. # ! # Some sites may specifically want to perform canonical or virtual ! # address mapping in front of the content_filter. In that case you ! # still have to enable address rewriting in the after-filter cleanup ! # instance, in order to correctly process forwarded mail or bounced ! # mail. # ! pre-cleanup unix n - n - 0 cleanup -o canonical_maps= -o sender_canonical_maps= -o recipient_canonical_maps= *************** *** 386,394 **** # parameter to avoid loops, and use a different hostname to avoid # triggering the Postfix SMTP loop detection code. # ! # This "smtpd" uses a separate cleanup that does no header or ! # body checks, but does do the various address rewrites disabled ! # in the first cleanup. # # The parameters from mynetworks onward disable all access # control other than insisting on connections from one of the IP --- 391,398 ---- # parameter to avoid loops, and use a different hostname to avoid # triggering the Postfix SMTP loop detection code. # ! # This "smtpd" uses the normal cleanup service which is also used ! # for bounces and for internally forwarded mail. # # The parameters from mynetworks onward disable all access # control other than insisting on connections from one of the IP *************** *** 401,407 **** -o myhostname=localhost.domain.tld -o local_recipient_maps= -o relay_recipient_maps= - -o cleanup_service_name=cleanup2 -o mynetworks=127.0.0.0/8 -o mynetworks_style=host -o smtpd_restriction_classes= --- 405,410 ---- *************** *** 416,433 **** # # ------------------------------------------------------------------ # ! # This is the second cleanup daemon. No header or body checks, ! # because those have already been taken care of by the cleanup instance ! # before the content filter. The second cleanup instance does all the ! # virtual alias and canonical address mapping that was disabled in ! # the first cleanup instance. ! # ! # If it is preferable to do the virtual alias and canonical address ! # mapping before the content filter, delete the "-o" lines that ! # disable canonical and virtual mappings in the above cleanup daemon ! # instance and insert them here. # ! cleanup2 unix n - n - 0 cleanup -o header_checks= -o mime_header_checks= -o nested_header_checks= --- 419,435 ---- # # ------------------------------------------------------------------ # ! # This is the normal cleanup daemon for use after content filtering. ! # No header or body checks, because those have already been taken ! # care of by the pre-cleanup service before the content filter. ! # ! # The normal cleanup instance does all the virtual alias and canonical ! # address mapping that was disabled in the pre-cleanup instance before ! # the content filter. This rewriting must be done even when you didn't ! # disable address rewriting in the pre-cleanup instance, in order to ! # correctly process bounces and locally forwarded mail. # ! cleanup unix n - n - 0 cleanup -o header_checks= -o mime_header_checks= -o nested_header_checks= *************** *** 477,508 **** # SMTP service for external users, with content filtering. 1.2.3.5:smtp inet n - n - - smtpd -o content_filter=foo:bar - - Different content filters for different MX domains - ================================================== - - This is a variant on the previous example. You configure ONE - Postfix instance with multiple SMTP server addresses. Each - SMTP server invokes a different content filter. - - /etc/postfix.master.cf: - # MX server for destinations that use the foo:bar content filter. - 1.2.3.5:smtp inet n - n - - smtpd - -o content_filter=foo:bar - -o relay_domains=/etc/postfix/foo-bar-domains - -o smtpd_recipient_restrictions=reject_unauth_destination - - # MX server for destinations that use the bar:baz content filter. - 1.2.3.6:smtp inet n - n - - smtpd - -o content_filter=bar:baz - -o relay_domains=/etc/postfix/bar-baz-domains - -o smtpd_recipient_restrictions=reject_unauth_destination - - # SMTP servers for internal users only. - 1.2.3.4:smtp inet n - n - - smtpd - -o smtpd_recipient_restrictions=permit_mynetworks,reject - 127.0.0.1:smtp inet n - n - - smtpd - -o smtpd_recipient_restrictions=permit_mynetworks,reject Getting really nasty ==================== --- 479,484 ---- diff -cr /tmp/postfix-2.0.2/README_FILES/LOCAL_RECIPIENT_README ./README_FILES/LOCAL_RECIPIENT_README *** /tmp/postfix-2.0.2/README_FILES/LOCAL_RECIPIENT_README Wed Jan 1 19:46:26 2003 --- ./README_FILES/LOCAL_RECIPIENT_README Thu Jan 23 23:07:29 2003 *************** *** 41,47 **** accounts or local aliases: /etc/postfix/main.cf: ! local_recipient_maps = unix:passwd.byname $alias_maps You need to update the local_recipient_maps setting if one of the following is true: --- 41,47 ---- accounts or local aliases: /etc/postfix/main.cf: ! local_recipient_maps = proxymap:unix:passwd.byname $alias_maps You need to update the local_recipient_maps setting if one of the following is true: diff -cr /tmp/postfix-2.0.2/conf/main.cf ./conf/main.cf *** /tmp/postfix-2.0.2/conf/main.cf Sun Jan 5 10:58:31 2003 --- ./conf/main.cf Thu Jan 23 20:42:20 2003 *************** *** 182,187 **** --- 182,189 ---- # - You use the "luser_relay", "mailbox_transport", or "fallback_transport" # feature of the Postfix local delivery agent (see sample-local.cf). # + # Details are described in the LOCAL_RECIPIENT_README file. + # # Beware: if the Postfix SMTP server runs chrooted, you probably have # to access the passwd file via the proxymap service, in order to # overcome chroot restrictions. The alternative, having a copy of diff -cr /tmp/postfix-2.0.2/conf/master.cf ./conf/master.cf *** /tmp/postfix-2.0.2/conf/master.cf Sun Jan 12 12:04:35 2003 --- ./conf/master.cf Thu Jan 16 07:44:58 2003 *************** *** 66,93 **** # DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES. # # ========================================================================== ! # service type private unpriv chroot wakeup maxproc command + args ! # (yes) (yes) (yes) (never) (100) # ========================================================================== ! smtp inet n - n - - smtpd ! #628 inet n - n - - qmqpd ! pickup fifo n - n 60 1 pickup ! cleanup unix n - n - 0 cleanup ! qmgr fifo n - n 300 1 qmgr ! #qmgr fifo n - n 300 1 nqmgr ! rewrite unix - - n - - trivial-rewrite ! bounce unix - - n - 0 bounce ! defer unix - - n - 0 bounce ! flush unix n - n 1000? 0 flush ! proxymap unix - - n - - proxymap ! smtp unix - - n - - smtp ! relay unix - - n - - smtp ! # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 ! showq unix n - n - - showq ! error unix - - n - - error ! local unix - n n - - local ! virtual unix - n n - - virtual ! lmtp unix - - n - - lmtp # # Interfaces to non-Postfix software. Be sure to examine the manual # pages of the non-Postfix software to find out what options it wants. --- 66,93 ---- # DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES. # # ========================================================================== ! # service type private unpriv chroot wakeup maxproc command + args ! # (yes) (yes) (yes) (never) (100) # ========================================================================== ! smtp inet n - n - - smtpd ! #628 inet n - n - - qmqpd ! pickup fifo n - n 60 1 pickup ! cleanup unix n - n - 0 cleanup ! qmgr fifo n - n 300 1 qmgr ! #qmgr fifo n - n 300 1 nqmgr ! rewrite unix - - n - - trivial-rewrite ! bounce unix - - n - 0 bounce ! defer unix - - n - 0 bounce ! flush unix n - n 1000? 0 flush ! proxymap unix - - n - - proxymap ! smtp unix - - n - - smtp ! relay unix - - n - - smtp ! # -o smtp_helo_timeout=5 -o smtp_connect_timeout=5 ! showq unix n - n - - showq ! error unix - - n - - error ! local unix - n n - - local ! virtual unix - n n - - virtual ! lmtp unix - - n - - lmtp # # Interfaces to non-Postfix software. Be sure to examine the manual # pages of the non-Postfix software to find out what options it wants. *************** *** 99,110 **** # # The Cyrus deliver program has changed incompatibly, multiple times. # ! old-cyrus unix - n n - - pipe flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} # Cyrus 2.1.5 (Amos Gouaux) ! cyrus unix - n n - - pipe user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} ! uucp unix - n n - - pipe flags=Fqhu 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) --- 99,110 ---- # # The Cyrus deliver program has changed incompatibly, multiple times. # ! old-cyrus unix - n n - - pipe flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user} # Cyrus 2.1.5 (Amos Gouaux) ! cyrus unix - n n - - pipe user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user} ! uucp unix - n n - - pipe flags=Fqhu 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) diff -cr /tmp/postfix-2.0.2/html/mailq.1.html ./html/mailq.1.html *** /tmp/postfix-2.0.2/html/mailq.1.html Wed Dec 18 21:18:45 2002 --- ./html/mailq.1.html Sat Jan 18 09:53:34 2003 *************** *** 197,203 **** queued for the named site. This option accepts only site names that are eligible for the "fast flush" service, and is implemented by executing the ! postqueue(1) command. See flush(8) for more infor- mation about the "fast flush" service. -qSsite --- 197,203 ---- queued for the named site. This option accepts only site names that are eligible for the "fast flush" service, and is implemented by executing the ! postqueue(1) command. See flush(8) for more infor- mation about the "fast flush" service. -qSsite *************** *** 328,334 **** postqueue(1) mail queue control qmgr(8) queue manager smtpd(8) SMTP server ! flush(8) fast flush service syslogd(8) system logging LICENSE --- 328,334 ---- postqueue(1) mail queue control qmgr(8) queue manager smtpd(8) SMTP server ! flush(8) fast flush service syslogd(8) system logging LICENSE diff -cr /tmp/postfix-2.0.2/html/newaliases.1.html ./html/newaliases.1.html *** /tmp/postfix-2.0.2/html/newaliases.1.html Wed Dec 18 21:18:45 2002 --- ./html/newaliases.1.html Sat Jan 18 09:53:34 2003 *************** *** 197,203 **** queued for the named site. This option accepts only site names that are eligible for the "fast flush" service, and is implemented by executing the ! postqueue(1) command. See flush(8) for more infor- mation about the "fast flush" service. -qSsite --- 197,203 ---- queued for the named site. This option accepts only site names that are eligible for the "fast flush" service, and is implemented by executing the ! postqueue(1) command. See flush(8) for more infor- mation about the "fast flush" service. -qSsite *************** *** 328,334 **** postqueue(1) mail queue control qmgr(8) queue manager smtpd(8) SMTP server ! flush(8) fast flush service syslogd(8) system logging LICENSE --- 328,334 ---- postqueue(1) mail queue control qmgr(8) queue manager smtpd(8) SMTP server ! flush(8) fast flush service syslogd(8) system logging LICENSE diff -cr /tmp/postfix-2.0.2/html/postqueue.1.html ./html/postqueue.1.html *** /tmp/postfix-2.0.2/html/postqueue.1.html Tue Jan 7 16:16:13 2003 --- ./html/postqueue.1.html Sat Jan 18 09:53:51 2003 *************** *** 54,64 **** -s site Schedule immediate delivery of all mail that is queued for the named site. The site must be eligi- ! ble for the "fast flush" service. See flush(8) for more information about the "fast flush" service. This option implements the traditional sendmail ! -qRsite command, by contacting the Postfix flush(8) daemon. -v Enable verbose logging for debugging purposes. Mul- --- 54,64 ---- -s site Schedule immediate delivery of all mail that is queued for the named site. The site must be eligi- ! ble for the "fast flush" service. See flush(8) for more information about the "fast flush" service. This option implements the traditional sendmail ! -qRsite command, by contacting the Postfix flush(8) daemon. -v Enable verbose logging for debugging purposes. Mul- *************** *** 115,121 **** postsuper(1) privileged queue operations qmgr(8) queue manager showq(8) list mail queue ! flush(8) fast flush service LICENSE The Secure Mailer license must be distributed with this --- 115,121 ---- postsuper(1) privileged queue operations qmgr(8) queue manager showq(8) list mail queue ! flush(8) fast flush service LICENSE The Secure Mailer license must be distributed with this diff -cr /tmp/postfix-2.0.2/html/sendmail.1.html ./html/sendmail.1.html *** /tmp/postfix-2.0.2/html/sendmail.1.html Wed Dec 18 21:18:45 2002 --- ./html/sendmail.1.html Sat Jan 18 09:53:34 2003 *************** *** 197,203 **** queued for the named site. This option accepts only site names that are eligible for the "fast flush" service, and is implemented by executing the ! postqueue(1) command. See flush(8) for more infor- mation about the "fast flush" service. -qSsite --- 197,203 ---- queued for the named site. This option accepts only site names that are eligible for the "fast flush" service, and is implemented by executing the ! postqueue(1) command. See flush(8) for more infor- mation about the "fast flush" service. -qSsite *************** *** 328,334 **** postqueue(1) mail queue control qmgr(8) queue manager smtpd(8) SMTP server ! flush(8) fast flush service syslogd(8) system logging LICENSE --- 328,334 ---- postqueue(1) mail queue control qmgr(8) queue manager smtpd(8) SMTP server ! flush(8) fast flush service syslogd(8) system logging LICENSE diff -cr /tmp/postfix-2.0.2/makedefs ./makedefs *** /tmp/postfix-2.0.2/makedefs Tue Jan 14 17:21:44 2003 --- ./makedefs Thu Jan 23 08:45:02 2003 *************** *** 204,212 **** SYSLIBS="-ldb" for name in nsl resolv $GDBM_LIBS do ! test -e /usr/lib/lib$name.a -o -e /usr/lib/lib$name.so \ ! -o -e /lib/lib$name.a -o -e /lib/lib$name.so \ ! && SYSLIBS="$SYSLIBS -l$name" done ;; IRIX*.5.*) SYSTYPE=IRIX5 --- 204,216 ---- SYSLIBS="-ldb" for name in nsl resolv $GDBM_LIBS do ! for lib in /usr/lib64 /lib64 /usr/lib /lib ! do ! test -e $lib/lib$name.a -o -e $lib/lib$name.so && { ! SYSLIBS="$SYSLIBS -l$name" ! break ! } ! done done ;; IRIX*.5.*) SYSTYPE=IRIX5 diff -cr /tmp/postfix-2.0.2/mantools/postlink ./mantools/postlink *** /tmp/postfix-2.0.2/mantools/postlink Sun Jan 12 12:44:49 2003 --- ./mantools/postlink Sat Jan 18 09:51:58 2003 *************** *** 13,19 **** s/[]*cleanup[]*(8)/&<\/a>/ s/[]*defer[]*(8)/&<\/a>/ s/[]*error[]*(8)/&<\/a>/ ! s/[]*flush[]*(8)/&<\/a>/ s/[]*local[]*(8)/&<\/a>/ s/[]*mas[-]*\n*[ ]*ter[]*(8)/&<\/a>/ s/[]*pickup[]*(8)/&<\/a>/ --- 13,19 ---- s/[]*cleanup[]*(8)/&<\/a>/ s/[]*defer[]*(8)/&<\/a>/ s/[]*error[]*(8)/&<\/a>/ ! s/[]*flush[]*(8)/&<\/a>/ s/[]*local[]*(8)/&<\/a>/ s/[]*mas[-]*\n*[ ]*ter[]*(8)/&<\/a>/ s/[]*pickup[]*(8)/&<\/a>/ diff -cr /tmp/postfix-2.0.2/src/bounce/bounce_notify_util.c ./src/bounce/bounce_notify_util.c *** /tmp/postfix-2.0.2/src/bounce/bounce_notify_util.c Sat Aug 3 10:14:31 2002 --- ./src/bounce/bounce_notify_util.c Sun Jan 19 10:29:08 2003 *************** *** 177,187 **** /* bounce_mail_alloc - initialize */ static BOUNCE_INFO *bounce_mail_alloc(const char *service, ! const char *queue_name, ! const char *queue_id, ! const char *encoding, ! int flush, ! BOUNCE_LOG *log_handle) { BOUNCE_INFO *bounce_info; int rec_type; --- 177,187 ---- /* bounce_mail_alloc - initialize */ static BOUNCE_INFO *bounce_mail_alloc(const char *service, ! const char *queue_name, ! const char *queue_id, ! const char *encoding, ! int flush, ! BOUNCE_LOG *log_handle) { BOUNCE_INFO *bounce_info; int rec_type; *************** *** 531,536 **** --- 531,538 ---- int bounce_recipient_dsn(VSTREAM *bounce, BOUNCE_INFO *bounce_info) { + char *fixed_mail_name; + post_mail_fputs(bounce, ""); #if 0 post_mail_fprintf(bounce, "Original-Recipient: rfc822; %s", "whatever"); *************** *** 540,547 **** post_mail_fprintf(bounce, "Action: %s", bounce_info->flush ? "failed" : "delayed"); post_mail_fprintf(bounce, "Status: %s", bounce_info->log_handle->status); ! bounce_print_wrap(bounce, bounce_info, "Diagnostic-Code: X-Postfix; %s", ! bounce_info->log_handle->text); #if 0 post_mail_fprintf(bounce, "Last-Attempt-Date: %s", bounce_info->log_handle->log_time); --- 542,553 ---- post_mail_fprintf(bounce, "Action: %s", bounce_info->flush ? "failed" : "delayed"); post_mail_fprintf(bounce, "Status: %s", bounce_info->log_handle->status); ! /* RFC 1894: diagnostic-type is an RFC 822 atom. */ ! fixed_mail_name = mystrdup(var_mail_name); ! translit(fixed_mail_name, " \t\r\n()<>@,;:\\\".[]", "-----------------"); ! bounce_print_wrap(bounce, bounce_info, "Diagnostic-Code: X-%s; %s", ! fixed_mail_name, bounce_info->log_handle->text); ! myfree(fixed_mail_name); #if 0 post_mail_fprintf(bounce, "Last-Attempt-Date: %s", bounce_info->log_handle->log_time); diff -cr /tmp/postfix-2.0.2/src/local/maildir.c ./src/local/maildir.c *** /tmp/postfix-2.0.2/src/local/maildir.c Mon Dec 2 13:57:44 2002 --- ./src/local/maildir.c Thu Jan 23 18:19:00 2003 *************** *** 40,46 **** --- 40,48 ---- /* System library. */ #include "sys_defs.h" + #include #include + #include #include /* Utility library. */ *************** *** 83,89 **** int mail_copy_status; int deliver_status; int copy_flags; ! static int count; /* * Make verbose logging easier to understand. --- 85,92 ---- int mail_copy_status; int deliver_status; int copy_flags; ! struct stat st; ! time_t starttime = time((time_t *) 0); /* * Make verbose logging easier to understand. *************** *** 124,143 **** * use starttime.pid_count.host, where starttime is the time that your * process started, and count is the number of messages you've * delivered." */ #define STR vstring_str set_eugid(usr_attr.uid, usr_attr.gid); ! vstring_sprintf(buf, "%ld.%d_%d.%s", (long) var_starttime, ! var_pid, count++, get_hostname()); tmpfile = concatenate(tmpdir, STR(buf), (char *) 0); ! newfile = concatenate(newdir, STR(buf), (char *) 0); if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0 && (errno != ENOENT || make_dirs(tmpdir, 0700) < 0 || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { vstring_sprintf(why, "create %s: %m", tmpfile); } else { if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why)) == 0) { if (sane_link(tmpfile, newfile) < 0 --- 127,159 ---- * use starttime.pid_count.host, where starttime is the time that your * process started, and count is the number of messages you've * delivered." + * + * Well, that stopped working on fast machines, and on operating systems + * that randomize process ID values. When creating a file in tmp/ we use + * the process ID because it still is an exclusive resource. When moving + * the file to new/ we use the device number and inode number. I do not + * care if this breaks on a remote AFS file system, because people should + * know better. */ #define STR vstring_str set_eugid(usr_attr.uid, usr_attr.gid); ! vstring_sprintf(buf, "%lu.%d.%s", ! (unsigned long) starttime, var_pid, get_hostname()); tmpfile = concatenate(tmpdir, STR(buf), (char *) 0); ! newfile = 0; if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0 && (errno != ENOENT || make_dirs(tmpdir, 0700) < 0 || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { vstring_sprintf(why, "create %s: %m", tmpfile); + } else if (fstat(vstream_fileno(dst), &st) < 0) { + vstring_sprintf(why, "create %s: %m", tmpfile); } else { + vstring_sprintf(buf, "%lu.%lu_%lu.%s", + (unsigned long) starttime, (unsigned long) st.st_dev, + (unsigned long) st.st_ino, get_hostname()); + newfile = concatenate(newdir, STR(buf), (char *) 0); if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why)) == 0) { if (sane_link(tmpfile, newfile) < 0 *************** *** 172,177 **** myfree(tmpdir); myfree(curdir); myfree(tmpfile); ! myfree(newfile); return (deliver_status); } --- 188,194 ---- myfree(tmpdir); myfree(curdir); myfree(tmpfile); ! if (newfile) ! myfree(newfile); return (deliver_status); } diff -cr /tmp/postfix-2.0.2/src/nqmgr/qmgr_deliver.c ./src/nqmgr/qmgr_deliver.c *** /tmp/postfix-2.0.2/src/nqmgr/qmgr_deliver.c Mon Oct 28 16:33:12 2002 --- ./src/nqmgr/qmgr_deliver.c Wed Jan 22 16:42:55 2003 *************** *** 154,163 **** * queue name is user@nexthop, so that we can implement per-recipient * concurrency limits. However, the delivery agent protocol expects * nexthop only, so we must strip off the recipient local part. */ flags = message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT; ! nexthop = (cp = strrchr(entry->queue->name, '@')) != 0 && cp[1] ? cp + 1 : entry->queue->name; attr_print(stream, ATTR_FLAG_MORE, ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags, --- 154,168 ---- * queue name is user@nexthop, so that we can implement per-recipient * concurrency limits. However, the delivery agent protocol expects * nexthop only, so we must strip off the recipient local part. + * + * XXX Should have separate fields for queue name and for destination, so + * that we don't have to make a special case for the error delivery agent + * (where nexthop is arbitrary text). See also: qmgr_message.c. */ flags = message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT; ! nexthop = strcmp(entry->queue->transport->name, MAIL_SERVICE_ERROR) != 0 ! && (cp = strrchr(entry->queue->name, '@')) != 0 && cp[1] ? cp + 1 : entry->queue->name; attr_print(stream, ATTR_FLAG_MORE, ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags, diff -cr /tmp/postfix-2.0.2/src/nqmgr/qmgr_message.c ./src/nqmgr/qmgr_message.c *** /tmp/postfix-2.0.2/src/nqmgr/qmgr_message.c Tue Dec 17 20:42:30 2002 --- ./src/nqmgr/qmgr_message.c Fri Jan 24 09:48:36 2003 *************** *** 638,659 **** for (recipient = list.info; recipient < list.info + list.len; recipient++) { /* - * This may be a bit late in the game, but it is the most convenient - * place to scrutinize the destination address syntax. We have a - * complete queue file, so bouncing is easy. That luxury is not - * available to the cleanup service. The main issue is that we want - * to have this test in one place, instead of having to do this in - * every front-ent program. - */ - if ((at = strrchr(recipient->address, '@')) != 0 - && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0 - && valid_hostname(at + 1, DONT_GRIPE) == 0) { - qmgr_bounce_recipient(message, recipient, - "bad host/domain syntax: \"%s\"", at + 1); - continue; - } - - /* * Resolve the destination to (transport, nexthop, address). The * result address may differ from the one specified by the sender. */ --- 638,643 ---- *************** *** 736,744 **** * on the recipient delimiter if one is defined, but doing a proper * job requires knowledge of local aliases. Yuck! I don't want to * duplicate delivery-agent specific knowledge in the queue manager. * XXX The nexthop field is overloaded to serve as destination and as * queue name. Should have separate fields for queue name and for ! * destination. */ at = strrchr(STR(reply.recipient), '@'); len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); --- 720,731 ---- * on the recipient delimiter if one is defined, but doing a proper * job requires knowledge of local aliases. Yuck! I don't want to * duplicate delivery-agent specific knowledge in the queue manager. + * * XXX The nexthop field is overloaded to serve as destination and as * queue name. Should have separate fields for queue name and for ! * destination, so that we don't have to make a special case for the ! * error delivery agent (where nexthop is arbitrary text). See also: ! * qmgr_deliver.c. */ at = strrchr(STR(reply.recipient), '@'); len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); *************** *** 753,759 **** transport = qmgr_transport_create(STR(reply.transport)); queue = 0; } ! if (transport->recipient_limit == 1) { VSTRING_SPACE(reply.nexthop, len + 2); memmove(STR(reply.nexthop) + len + 1, STR(reply.nexthop), LEN(reply.nexthop) + 1); --- 740,747 ---- transport = qmgr_transport_create(STR(reply.transport)); queue = 0; } ! if (strcmp(transport->name, MAIL_SERVICE_ERROR) != 0 ! && transport->recipient_limit == 1) { VSTRING_SPACE(reply.nexthop, len + 2); memmove(STR(reply.nexthop) + len + 1, STR(reply.nexthop), LEN(reply.nexthop) + 1); diff -cr /tmp/postfix-2.0.2/src/qmgr/qmgr_deliver.c ./src/qmgr/qmgr_deliver.c *** /tmp/postfix-2.0.2/src/qmgr/qmgr_deliver.c Mon Oct 28 16:32:58 2002 --- ./src/qmgr/qmgr_deliver.c Wed Jan 22 16:41:51 2003 *************** *** 149,158 **** * queue name is user@nexthop, so that we can implement per-recipient * concurrency limits. However, the delivery agent protocol expects * nexthop only, so we must strip off the recipient local part. */ flags = message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT; ! nexthop = (cp = strrchr(entry->queue->name, '@')) != 0 && cp[1] ? cp + 1 : entry->queue->name; attr_print(stream, ATTR_FLAG_MORE, ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags, --- 149,163 ---- * queue name is user@nexthop, so that we can implement per-recipient * concurrency limits. However, the delivery agent protocol expects * nexthop only, so we must strip off the recipient local part. + * + * XXX Should have separate fields for queue name and for destination, so + * that we don't have to make a special case for the error delivery agent + * (where nexthop is arbitrary text). See also: qmgr_message.c. */ flags = message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT; ! nexthop = strcmp(entry->queue->transport->name, MAIL_SERVICE_ERROR) != 0 ! && (cp = strrchr(entry->queue->name, '@')) != 0 && cp[1] ? cp + 1 : entry->queue->name; attr_print(stream, ATTR_FLAG_MORE, ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags, diff -cr /tmp/postfix-2.0.2/src/qmgr/qmgr_message.c ./src/qmgr/qmgr_message.c *** /tmp/postfix-2.0.2/src/qmgr/qmgr_message.c Tue Dec 17 20:42:31 2002 --- ./src/qmgr/qmgr_message.c Fri Jan 24 09:47:48 2003 *************** *** 518,539 **** for (recipient = list.info; recipient < list.info + list.len; recipient++) { /* - * This may be a bit late in the game, but it is the most convenient - * place to scrutinize the destination address syntax. We have a - * complete queue file, so bouncing is easy. That luxury is not - * available to the cleanup service. The main issue is that we want - * to have this test in one place, instead of having to do this in - * every front-ent program. - */ - if ((at = strrchr(recipient->address, '@')) != 0 - && (at + 1)[strspn(at + 1, "[]0123456789.")] != 0 - && valid_hostname(at + 1, DONT_GRIPE) == 0) { - qmgr_bounce_recipient(message, recipient, - "bad host/domain syntax: \"%s\"", at + 1); - continue; - } - - /* * Resolve the destination to (transport, nexthop, address). The * result address may differ from the one specified by the sender. */ --- 518,523 ---- *************** *** 616,624 **** * on the recipient delimiter if one is defined, but doing a proper * job requires knowledge of local aliases. Yuck! I don't want to * duplicate delivery-agent specific knowledge in the queue manager. * XXX The nexthop field is overloaded to serve as destination and as * queue name. Should have separate fields for queue name and for ! * destination. */ at = strrchr(STR(reply.recipient), '@'); len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); --- 600,611 ---- * on the recipient delimiter if one is defined, but doing a proper * job requires knowledge of local aliases. Yuck! I don't want to * duplicate delivery-agent specific knowledge in the queue manager. + * * XXX The nexthop field is overloaded to serve as destination and as * queue name. Should have separate fields for queue name and for ! * destination, so that we don't have to make a special case for the ! * error delivery agent (where nexthop is arbitrary text). See also: ! * qmgr_deliver.c. */ at = strrchr(STR(reply.recipient), '@'); len = (at ? (at - STR(reply.recipient)) : strlen(STR(reply.recipient))); *************** *** 633,639 **** transport = qmgr_transport_create(STR(reply.transport)); queue = 0; } ! if (transport->recipient_limit == 1) { VSTRING_SPACE(reply.nexthop, len + 2); memmove(STR(reply.nexthop) + len + 1, STR(reply.nexthop), LEN(reply.nexthop) + 1); --- 620,627 ---- transport = qmgr_transport_create(STR(reply.transport)); queue = 0; } ! if (strcmp(transport->name, MAIL_SERVICE_ERROR) != 0 ! && transport->recipient_limit == 1) { VSTRING_SPACE(reply.nexthop, len + 2); memmove(STR(reply.nexthop) + len + 1, STR(reply.nexthop), LEN(reply.nexthop) + 1); diff -cr /tmp/postfix-2.0.2/src/smtp/smtp_connect.c ./src/smtp/smtp_connect.c *** /tmp/postfix-2.0.2/src/smtp/smtp_connect.c Thu Nov 28 14:24:13 2002 --- ./src/smtp/smtp_connect.c Thu Jan 23 11:07:53 2003 *************** *** 371,378 **** /* * First try to deliver to the indicated destination, then try to deliver ! * to the optional fall-back relays. Each can be a list of destinations ! * by itself, with domain, host, [], numerical address, and port. */ sites = argv_alloc(1); argv_add(sites, destination, (char *) 0); --- 371,377 ---- /* * First try to deliver to the indicated destination, then try to deliver ! * to the optional fall-back relays. */ sites = argv_alloc(1); argv_add(sites, destination, (char *) 0); diff -cr /tmp/postfix-2.0.2/src/smtpd/smtpd_check.c ./src/smtpd/smtpd_check.c *** /tmp/postfix-2.0.2/src/smtpd/smtpd_check.c Mon Jan 13 08:37:39 2003 --- ./src/smtpd/smtpd_check.c Sat Jan 18 11:04:57 2003 *************** *** 356,362 **** static MAPS *relay_rcpt_maps; #ifdef TEST - static MAPS *relocated_maps; static STRING_LIST *virt_alias_doms; static STRING_LIST *virt_mailbox_doms; --- 356,361 ---- *************** *** 655,663 **** DICT_FLAG_LOCK); #ifdef TEST - relocated_maps = maps_create(VAR_RELOCATED_MAPS, var_relocated_maps, - DICT_FLAG_LOCK); - virt_alias_doms = string_list_init(MATCH_FLAG_NONE, var_virt_alias_doms); virt_mailbox_doms = string_list_init(MATCH_FLAG_NONE, var_virt_mailbox_doms); #endif --- 654,659 ---- *************** *** 3388,3394 **** char *var_virt_alias_doms; char *var_virt_mailbox_maps; char *var_virt_mailbox_doms; - char *var_relocated_maps; char *var_local_rcpt_maps; char *var_perm_mx_networks; char *var_par_dom_match; --- 3384,3389 ---- *************** *** 3426,3432 **** VAR_VIRT_ALIAS_DOMS, DEF_VIRT_ALIAS_DOMS, &var_virt_alias_doms, VAR_VIRT_MAILBOX_MAPS, DEF_VIRT_MAILBOX_MAPS, &var_virt_mailbox_maps, VAR_VIRT_MAILBOX_DOMS, DEF_VIRT_MAILBOX_DOMS, &var_virt_mailbox_doms, - VAR_RELOCATED_MAPS, DEF_RELOCATED_MAPS, &var_relocated_maps, VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, VAR_PAR_DOM_MATCH, DEF_PAR_DOM_MATCH, &var_par_dom_match, --- 3421,3426 ---- diff -cr /tmp/postfix-2.0.2/src/virtual/maildir.c ./src/virtual/maildir.c *** /tmp/postfix-2.0.2/src/virtual/maildir.c Mon Dec 2 14:02:05 2002 --- ./src/virtual/maildir.c Thu Jan 23 18:18:56 2003 *************** *** 35,40 **** --- 35,42 ---- /* System library. */ #include "sys_defs.h" + #include + #include #include #ifndef EDQUOT *************** *** 81,87 **** int mail_copy_status; int deliver_status; int copy_flags; ! static int count; /* * Make verbose logging easier to understand. --- 83,90 ---- int mail_copy_status; int deliver_status; int copy_flags; ! struct stat st; ! time_t starttime = time((time_t *) 0); /* * Make verbose logging easier to understand. *************** *** 121,140 **** * use starttime.pid_count.host, where starttime is the time that your * process started, and count is the number of messages you've * delivered." */ #define STR vstring_str set_eugid(usr_attr.uid, usr_attr.gid); ! vstring_sprintf(buf, "%ld.%d_%d.%s", (long) var_starttime, ! var_pid, count++, get_hostname()); tmpfile = concatenate(tmpdir, STR(buf), (char *) 0); ! newfile = concatenate(newdir, STR(buf), (char *) 0); if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0 && (errno != ENOENT || make_dirs(tmpdir, 0700) < 0 || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { vstring_sprintf(why, "create %s: %m", tmpfile); } else { if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why)) == 0) { if (sane_link(tmpfile, newfile) < 0 --- 124,156 ---- * use starttime.pid_count.host, where starttime is the time that your * process started, and count is the number of messages you've * delivered." + * + * Well, that stopped working on fast machines, and on operating systems + * that randomize process ID values. When creating a file in tmp/ we use + * the process ID because it still is an exclusive resource. When moving + * the file to new/ we use the device number and inode number. I do not + * care if this breaks on a remote AFS file system, because people should + * know better. */ #define STR vstring_str set_eugid(usr_attr.uid, usr_attr.gid); ! vstring_sprintf(buf, "%lu.%d.%s", ! (unsigned long) starttime, var_pid, get_hostname()); tmpfile = concatenate(tmpdir, STR(buf), (char *) 0); ! newfile = 0; if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0 && (errno != ENOENT || make_dirs(tmpdir, 0700) < 0 || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { vstring_sprintf(why, "create %s: %m", tmpfile); + } else if (fstat(vstream_fileno(dst), &st) < 0) { + vstring_sprintf(why, "create %s: %m", tmpfile); } else { + vstring_sprintf(buf, "%lu.%lu_%lu.%s", + (unsigned long) starttime, (unsigned long) st.st_dev, + (unsigned long) st.st_ino, get_hostname()); + newfile = concatenate(newdir, STR(buf), (char *) 0); if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why)) == 0) { if (sane_link(tmpfile, newfile) < 0 *************** *** 172,177 **** myfree(tmpdir); myfree(curdir); myfree(tmpfile); ! myfree(newfile); return (deliver_status); } --- 188,194 ---- myfree(tmpdir); myfree(curdir); myfree(tmpfile); ! if (newfile) ! myfree(newfile); return (deliver_status); }