client, and for the smtp-source and smtp-sink test programs.
Files: smtp/smtp_connect.c, smtpstone/smtp-source.c,
smtpstone/smtp-sink.c.
+
+20090114
+
+ Bugfix: VERP now uses the Postfix original recipient, if
+ available, because that is what the VERP consumer expects.
+ Files: *qmgr/qmgr_deliver.c, bounce/bounce_notify_verp.c.
+
+ Safety: extra check for broken third-party patches that
+ allow file size limit < message size limit. This can cause
+ mail to be stuck in the queue forever.
+
+ Invisible change, in preparation for multi-instance support.
+ Except for main.cf and master.cf, all files are optional
+ for non-default Postfix configuration directories. File:
+ conf/postfix-files.
Wish list:
-
- Force a panic when the VDA patch reduces the file size limit
- under the message size. They break the code that marks a
- recipient as "done", when that recipient was added late
- (e.g., "sendmail -t" or Milter SMFIR_ADDRCPT).
Set a flag when a remote SMTP client speaks before the
Postfix SMTP server sends the 220 greeting.
Make adding Date/From/Message-ID headers dependent on local
rewrite context.
+ Make adding date/from/etc. conditional. Perhaps on header
+ rewrite context? Do we need a more powerful concept than
+ local_header_rewrite_clients/remote_header_rewrite_domain?
+
Write delivery rate delay example (which _README?) and auth
failure cache example (SASL_README). Then include them in
SOHO_README.
Update attr_print/scan() so they can send/receive file
descriptors. This simplifies kludgy code in many daemons.
- Make adding date/from/etc. conditional. Perhaps on header
- rewrite context? Do we need a more powerful concept than
- local_header_rewrite_clients/remote_header_rewrite_domain?
-
Would there be a problem adding $smtpd_mumble_restrictions
and $smtpd_sender_login_maps to the default proxy_read_maps
settings?
exit 1
}
+def_config_directory=`$POSTCONF -d -h config_directory` || exit 1
test -n "$config_directory" ||
- config_directory=`$POSTCONF -d -h config_directory` || exit 1
+ config_directory="$def_config_directory"
test -d "$config_directory" || {
echo $0: Error: $config_directory is not a directory. 1>&2
case $flags in *c*) create_flag=1;; *) create_flag=;; esac
case $flags in *r*) recursive="-R";; *) recursive=;; esac
case $flags in *o*) obsolete_flag=1;; *) obsolete_flag=;; esac
+ case $flags in *[1i]*) test ! -r "$path" -a "$config_directory" != \
+ "$def_config_directory" && continue;; esac
# Flag obsolete objects. XXX Solaris 2..9 does not have "test -e".
if [ -n "$obsolete_flag" ]
then
# c=create missing directory (post-install create-missing).
# r=apply owner/group recursively (post-install set/upgrade-permissions).
# o=obsolete, no longer part of Postfix
+# 1=optional for non-default instance (config_dir != built-in default).
#
# Note: the "u" flag is for upgrading the permissions of existing files
# or directories after changes in Postfix architecture. For robustness
$sendmail_path:f:root:-:755
$newaliases_path:l:$sendmail_path
$mailq_path:l:$sendmail_path
-$config_directory/LICENSE:f:root:-:644
-$config_directory/TLS_LICENSE:f:root:-:644
-$config_directory/access:f:root:-:644:p
-$config_directory/aliases:f:root:-:644:p
-$config_directory/bounce.cf.default:f:root:-:644
-$config_directory/canonical:f:root:-:644:p
+$config_directory/LICENSE:f:root:-:644:1
+$config_directory/TLS_LICENSE:f:root:-:644:1
+$config_directory/access:f:root:-:644:p1
+$config_directory/aliases:f:root:-:644:p1
+$config_directory/bounce.cf.default:f:root:-:644:1
+$config_directory/canonical:f:root:-:644:p1
$config_directory/cidr_table:f:root:-:644:o
-$config_directory/generic:f:root:-:644:p
+$config_directory/generic:f:root:-:644:p1
$config_directory/generics:f:root:-:644:o
-$config_directory/header_checks:f:root:-:644:p
+$config_directory/header_checks:f:root:-:644:p1
$config_directory/install.cf:f:root:-:644:o
-$config_directory/main.cf.default:f:root:-:644
+$config_directory/main.cf.default:f:root:-:644:1
$config_directory/main.cf:f:root:-:644:p
-$config_directory/makedefs.out:f:root:-:644
+$config_directory/makedefs.out:f:root:-:644:1
$config_directory/master.cf:f:root:-:644:p
$config_directory/pcre_table:f:root:-:644:o
$config_directory/postfix-files:f:root:-:644:o
$config_directory/regexp_table:f:root:-:644:o
-$config_directory/relocated:f:root:-:644:p
+$config_directory/relocated:f:root:-:644:p1
$config_directory/tcp_table:f:root:-:644:o
-$config_directory/transport:f:root:-:644:p
-$config_directory/virtual:f:root:-:644:p
+$config_directory/transport:f:root:-:644:p1
+$config_directory/virtual:f:root:-:644:p1
$config_directory/postfix-script:f:root:-:755:o
$config_directory/postfix-script-sgid:f:root:-:755:o
$config_directory/postfix-script-nosgid:f:root:-:755:o
bounce_mail_free(bounce_info);
return (bounce_status);
}
-
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_TRACE_FLAGS 0
/*
* Notify the originator, subject to DSN NOTIFY restrictions.
+ *
+ * Fix 20090114: Use the Postfix original recipient, because that is
+ * what the VERP consumer expects.
*/
if (rcpt->dsn_notify != 0 /* compat */
&& (rcpt->dsn_notify & DSN_NOTIFY_FAILURE) == 0) {
bounce_status = 0;
} else {
- verp_sender(verp_buf, verp_delims, recipient, rcpt->address);
+ verp_sender(verp_buf, verp_delims, recipient, rcpt->orig_addr[0] ?
+ rcpt->orig_addr : rcpt->address);
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, STR(verp_buf),
INT_FILT_BOUNCE,
NULL_TRACE_FLAGS,
mail_connect.o: mail_proto.h
mail_connect.o: timed_ipc.h
mail_copy.o: ../../include/htable.h
+mail_copy.o: ../../include/iostuff.h
mail_copy.o: ../../include/msg.h
mail_copy.o: ../../include/safe_open.h
mail_copy.o: ../../include/stringops.h
/* System library. */
#include <sys_defs.h>
+#include <sys/stat.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <vstring.h>
#include <vstring_vstream.h>
#include <stringops.h>
+#include <iostuff.h>
/* Global library. */
time_t now;
int type;
int prev_type;
+ struct stat st;
+ off_t size_limit;
+
+ /*
+ * Workaround 20090114. This will hopefully get someone's attention. The
+ * problem with file_size_limit < message_size_limit is that mail will be
+ * delivered again and again until someone removes it from the queue by
+ * hand, because Postfix cannot mark a recipient record as "completed".
+ */
+ if (fstat(vstream_fileno(src), &st) < 0)
+ msg_fatal("fstat: %m");
+ if ((size_limit = get_file_limit()) < st.st_size)
+ msg_panic("file size limit %lu < message size %lu. This "
+ "causes large messages to be delivered repeatedly "
+ "after they were submitted with \"sendmail -t\" "
+ "or after recipients were added with the Milter "
+ "SMFIR_ADDRCPT request",
+ (unsigned long) size_limit,
+ (unsigned long) st.st_size);
/*
* Initialize.
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20090110"
+#define MAIL_RELEASE_DATE "20090114"
#define MAIL_VERSION_NUMBER "2.6"
#ifdef SNAPSHOT
* If variable envelope return path is requested, change prefix+@origin
* into prefix+user=domain@origin. Note that with VERP there is only one
* recipient per delivery.
+ *
+ * Fix 20090114: Use the Postfix original recipient, because that is what
+ * the VERP consumer expects.
*/
if (message->verp_delims == 0) {
sender = message->sender;
} else {
sender_buf = vstring_alloc(100);
verp_sender(sender_buf, message->verp_delims,
- message->sender, list.info->address);
+ message->sender, list.info->orig_addr[0] ?
+ list.info->orig_addr : list.info->address);
sender = vstring_str(sender_buf);
}
* If variable envelope return path is requested, change prefix+@origin
* into prefix+user=domain@origin. Note that with VERP there is only one
* recipient per delivery.
+ *
+ * Fix 20090114: Use the Postfix original recipient, because that is what
+ * the VERP consumer expects.
*/
if (message->verp_delims == 0) {
sender = message->sender;
} else {
sender_buf = vstring_alloc(100);
verp_sender(sender_buf, message->verp_delims,
- message->sender, list.info->address);
+ message->sender, list.info->orig_addr[0] ?
+ list.info->orig_addr : list.info->address);
sender = vstring_str(sender_buf);
}
/* At this point in the protocol, the current process controls
/* both the output file content and its temporary pathname.
/*
-/* In the second phase, the application is expected to update
-/* the output file via the \fBtmp_fp\fR member of
-/* the EDIT_FILE data structure. This phase is not implemented
-/* by the edit_file() module.
+/* In the second phase, the application opens the original
+/* file if needed, and updates the output file via the
+/* \fBtmp_fp\fR member of the EDIT_FILE data structure. This
+/* phase is not implemented by the edit_file() module.
/*
/* edit_file_close() implements the third and final phase of
/* the protocol. It flushes the output file to persistent
/* The pathname of the original file that will be replaced by
/* the output file. The temporary pathname for the output file
/* is obtained by appending the suffix defined with EDIT_FILE_SUFFIX
-/* to a copy of the specified original file pathname.
+/* to a copy of the specified original file pathname, and is
+/* made available via the \fBtmp_path\fR member of the EDIT_FILE
+/* data structure.
/* .IP output_flags
/* Flags for opening the output file. These are as with open(2),
/* except that the O_TRUNC flag is ignored. edit_file_open()
/*
/* With both functions, the global errno variable indicates
/* the nature of the problem. All errors are relative to the
-/* temporary output's pathname.
+/* temporary output's pathname. With both functions, this
+/* pathname is not available via the EDIT_FILE data structure,
+/* because that structure was already destroyed, or not created.
/* BUGS
/* In the non-error case, edit_file_open() will not return
/* until it obtains exclusive control over the output file
/*
/* When interrupted, edit_file_close() may leave behind a
/* world-readable output file under the temporary pathname.
-/* On some systems this can be used to inflict a shared-file
+/* On some systems this can be used to inflict a shared-lock
/* DOS on the protocol. Applications that are concerned about
/* maximal safety should protect the edit_file_close() call
/* with sigdelay() and sigresume() calls, but this introduces