Cleanup: don't hyperlink text that is already hyperlinked.
File: mantools/postlink.
+
+20211002
+
+ Bugfix (introduced: Postfix 3.3): the header_from_format
+ feature was not implemented for From: headers from the
+ bounce daemon, and for Postfix SMTP server and client
+ postmaster notifications. Reported by Vladimir Mishonov.
+ Files: bounce/bounce.c, bounce/bounce_notify_util_tester.c,
+ bounce/bounce_service.h, bounce/bounce_template.c,
+ bounce/bounce_template.h, bounce/bounce_templates.c,
+ cleanup/cleanup.h, cleanup/cleanup_init.c,
+ cleanup/cleanup_message.c, smtp/lmtp_params.c, smtp/smtp.c,
+ smtp/smtp.h, smtp/smtp_chat.c, smtp/smtp_params.c,
+ smtpd/smtpd.c, smtpd/smtpd.h, smtpd/smtpd_chat.c, and test
+ data.
to the original message by including a References: and
In-Reply-To: header with the original Message-ID value.
+ Available in Postfix 3.7 and later:
+
+ <b>header_from_format (standard)</b>
+ The format of the Postfix-generated <b>From:</b> header.
+
<b>FILES</b>
/var/spool/postfix/bounce/* non-delivery records
/var/spool/postfix/defer/* non-delivery records
after applying <a href="header_checks.5.html"><b>header_checks</b>(5)</a> and before invoking Milter
applications.
+ <b>header_from_format (standard)</b>
+ The format of the Postfix-generated <b>From:</b> header.
+
<b>BUILT-IN CONTENT FILTERING CONTROLS</b>
Postfix built-in content filtering is meant to stop a flood of worms or
viruses. It is not a general content filter.
to the original message by including a References: and
In-Reply-To: header with the original Message-ID value.
+ Available in Postfix 3.7 and later:
+
+ <b>header_from_format (standard)</b>
+ The format of the Postfix-generated <b>From:</b> header.
+
<b>FILES</b>
/var/spool/postfix/bounce/* non-delivery records
/var/spool/postfix/defer/* non-delivery records
DATA requests, when deadlines are enabled with
<a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a>.
+ <b>header_from_format (standard)</b>
+ The format of the Postfix-generated <b>From:</b> header.
+
<b>MIME PROCESSING CONTROLS</b>
Available in Postfix version 2.0 and later:
DATA requests, when deadlines are enabled with
<a href="postconf.5.html#smtp_per_request_deadline">smtp_per_request_deadline</a>.
+ <b>header_from_format (standard)</b>
+ The format of the Postfix-generated <b>From:</b> header.
+
<b>MIME PROCESSING CONTROLS</b>
Available in Postfix version 2.0 and later:
DATA and BDAT requests, when deadlines are enabled with
<a href="postconf.5.html#smtpd_per_request_deadline">smtpd_per_request_deadline</a>.
+ <b>header_from_format (standard)</b>
+ The format of the Postfix-generated <b>From:</b> header.
+
<b>TARPIT CONTROLS</b>
When a remote SMTP client makes errors, the Postfix SMTP server can
insert delays before responding. This can help to slow down run-away
to the original message by including a References: and
In-Reply-To: header with the original Message-ID value.
+ Available in Postfix 3.7 and later:
+
+ <b>header_from_format (standard)</b>
+ The format of the Postfix-generated <b>From:</b> header.
+
<b>FILES</b>
/var/spool/postfix/bounce/* non-delivery records
/var/spool/postfix/defer/* non-delivery records
Enable non\-delivery, success, and delay notifications that link
to the original message by including a References: and In\-Reply\-To:
header with the original Message\-ID value.
+.PP
+Available in Postfix 3.7 and later:
+.IP "\fBheader_from_format (standard)\fR"
+The format of the Postfix\-generated \fBFrom:\fR header.
.SH "FILES"
.na
.nf
.IP "\fBmessage_drop_headers (bcc, content\-length, resent\-bcc, return\-path)\fR"
Names of message headers that the \fBcleanup\fR(8) daemon will remove
after applying \fBheader_checks\fR(5) and before invoking Milter applications.
+.IP "\fBheader_from_format (standard)\fR"
+The format of the Postfix\-generated \fBFrom:\fR header.
.SH "BUILT-IN CONTENT FILTERING CONTROLS"
.na
.nf
.IP "\fBsmtp_min_data_rate (500)\fR"
The minimum plaintext data transfer rate in bytes/second for
DATA requests, when deadlines are enabled with smtp_per_request_deadline.
+.IP "\fBheader_from_format (standard)\fR"
+The format of the Postfix\-generated \fBFrom:\fR header.
.SH "MIME PROCESSING CONTROLS"
.na
.nf
The minimum plaintext data transfer rate in bytes/second for
DATA and BDAT requests, when deadlines are enabled with
smtpd_per_request_deadline.
+.IP "\fBheader_from_format (standard)\fR"
+The format of the Postfix\-generated \fBFrom:\fR header.
.SH "TARPIT CONTROLS"
.na
.nf
failure_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
Postmaster-Subject: Postmaster Copy: Undelivered Mail
delay_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Delayed Mail (still being retried)
Postmaster-Subject: Postmaster Warning: Delayed Mail
success_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Successful Mail Delivery Report
This is the mail system at host $myhostname.
verify_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Mail Delivery Status Report
This is the mail system at host $myhostname.
EOF
failure_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
Postmaster-Subject: Postmaster Copy: Undelivered Mail
delay_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Delayed Mail (still being retried)
Postmaster-Subject: Postmaster Warning: Delayed Mail
success_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Successful Mail Delivery Report
This is the mail system at host $myhostname.
verify_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Mail Delivery Status Report
This is the mail system at host $myhostname.
test: $(TESTPROG)
-tests: update template_test 2template_test \
+tests: update template_test obs_template_test 2template_test \
with-msgid-with-long-line_test \
with-msgid-with-eoh-event_test \
with-msgid-no-eoh-event_test \
template_test: $(PROG) template_test.ref
echo queue_directory=. >main.cf
echo myhostname=example.com >>main.cf
+ echo header_from_format=standard >>main.cf
touch -t 197101010000 main.cf
MAIL_CONFIG=. ./$(PROG) -SVzndump_templates >template_test.tmp
diff template_test.ref template_test.tmp
diff template_test.ref template_test.tmp
rm -f template_test.tmp main.cf
+obs_template_test: $(PROG) obs_template_test.ref
+ echo queue_directory=. >main.cf
+ echo myhostname=example.com >>main.cf
+ echo header_from_format=obsolete >>main.cf
+ touch -t 197101010000 main.cf
+ MAIL_CONFIG=. ./$(PROG) -SVzndump_templates >template_test.tmp
+ diff obs_template_test.ref template_test.tmp
+ rm -f template_test.tmp main.cf
+
2template_test: $(PROG) template_test.ref 2template_test.in
echo queue_directory=. >main.cf
echo myhostname=example.com >>main.cf
bounce.o: ../../include/dsb_scan.h
bounce.o: ../../include/dsn.h
bounce.o: ../../include/dsn_buf.h
+bounce.o: ../../include/hfrom_format.h
bounce.o: ../../include/htable.h
bounce.o: ../../include/iostuff.h
bounce.o: ../../include/load_file.h
bounce_notify_util_tester.o: ../../include/dsn.h
bounce_notify_util_tester.o: ../../include/dsn_buf.h
bounce_notify_util_tester.o: ../../include/dsn_mask.h
+bounce_notify_util_tester.o: ../../include/hfrom_format.h
bounce_notify_util_tester.o: ../../include/htable.h
bounce_notify_util_tester.o: ../../include/mail_conf.h
bounce_notify_util_tester.o: ../../include/mail_params.h
bounce_one_service.o: bounce_service.h
bounce_one_service.o: bounce_template.h
bounce_template.o: ../../include/attr.h
+bounce_template.o: ../../include/bounce_log.h
bounce_template.o: ../../include/check_arg.h
+bounce_template.o: ../../include/dsn.h
+bounce_template.o: ../../include/dsn_buf.h
+bounce_template.o: ../../include/hfrom_format.h
bounce_template.o: ../../include/htable.h
bounce_template.o: ../../include/iostuff.h
bounce_template.o: ../../include/is_header.h
bounce_template.o: ../../include/msg.h
bounce_template.o: ../../include/mymalloc.h
bounce_template.o: ../../include/nvtable.h
+bounce_template.o: ../../include/rcpt_buf.h
+bounce_template.o: ../../include/recipient_list.h
bounce_template.o: ../../include/split_at.h
bounce_template.o: ../../include/stringops.h
bounce_template.o: ../../include/sys_defs.h
bounce_template.o: ../../include/vbuf.h
bounce_template.o: ../../include/vstream.h
bounce_template.o: ../../include/vstring.h
+bounce_template.o: bounce_service.h
bounce_template.o: bounce_template.c
bounce_template.o: bounce_template.h
bounce_templates.o: ../../include/attr.h
/* Enable non-delivery, success, and delay notifications that link
/* to the original message by including a References: and In-Reply-To:
/* header with the original Message-ID value.
+/* .PP
+/* Available in Postfix 3.7 and later:
+/* .IP "\fBheader_from_format (standard)\fR"
+/* The format of the Postfix-generated \fBFrom:\fR header.
/* FILES
/* /var/spool/postfix/bounce/* non-delivery records
/* /var/spool/postfix/defer/* non-delivery records
#include <mail_addr.h>
#include <rcpt_buf.h>
#include <dsb_scan.h>
+#include <hfrom_format.h>
/* Single-threaded server skeleton. */
char *var_delay_rcpt;
char *var_bounce_tmpl;
bool var_threaded_bounce;
+char *var_hfrom_format; /* header_from_format */
/*
* We're single threaded, so we can avoid some memory allocation overhead.
*/
BOUNCE_TEMPLATES *bounce_templates;
+ /*
+ * From: header format.
+ */
+int bounce_hfrom_format;
+
#define STR vstring_str
#define VS_NEUTER(s) printable(vstring_str(s), '?')
static void post_jail_init(char *service_name, char **unused_argv)
{
+ bounce_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format);
/*
* Special case: dump bounce templates. This is not part of the master(5)
VAR_2BOUNCE_RCPT, DEF_2BOUNCE_RCPT, &var_2bounce_rcpt, 1, 0,
VAR_DELAY_RCPT, DEF_DELAY_RCPT, &var_delay_rcpt, 1, 0,
VAR_BOUNCE_TMPL, DEF_BOUNCE_TMPL, &var_bounce_tmpl, 0, 0,
+ VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
0,
};
static const CONFIG_NBOOL_TABLE nbool_table[] = {
#include <mail_params.h>
#include <record.h>
#include <rec_type.h>
+#include <hfrom_format.h>
/*
* Bounce service.
if (chdir(var_queue_dir) < 0)
msg_fatal("chdir %s: %m", var_queue_dir);
+ bounce_hfrom_format =
+ hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format);
+
/*
* Write one message to VSTRING.
*/
char *var_delay_rcpt;
char *var_bounce_tmpl;
bool var_threaded_bounce;
+char *var_hfrom_format; /* header_from_format */
+
+int bounce_hfrom_format;
int main(int argc, char **argv)
{
VAR_2BOUNCE_RCPT, DEF_2BOUNCE_RCPT, &var_2bounce_rcpt, 1, 0,
VAR_DELAY_RCPT, DEF_DELAY_RCPT, &var_delay_rcpt, 1, 0,
VAR_BOUNCE_TMPL, DEF_BOUNCE_TMPL, &var_bounce_tmpl, 0, 0,
+ VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
0,
};
static const CONFIG_NBOOL_TABLE nbool_table[] = {
*/
#include <bounce_template.h>
+ /*
+ * bounce_service.c
+ */
+extern int bounce_hfrom_format;
+
/*
* bounce_append_service.c
*/
#include <mail_proto.h>
#include <mail_conf.h>
#include <is_header.h>
+#include <hfrom_format.h>
/* Application-specific. */
#include <bounce_template.h>
+#include <bounce_service.h>
/*
* The following tables implement support for bounce template expansions of
if (strcasecmp("charset", cp) == 0) {
tp->mime_charset = hval;
} else if (strcasecmp("from", cp) == 0) {
- tp->from = hval;
+ tp->std_from = tp->obs_from = hval;
} else if (strcasecmp("subject", cp) == 0) {
tp->subject = hval;
} else if (strcasecmp("postmaster-subject", cp) == 0) {
if (tp->flags & BOUNCE_TMPL_FLAG_NEW_BUFFER)
bounce_template_parse_buffer(tp);
- out_fn(fp, "From: %s", tp->from);
+ out_fn(fp, "From: %s", bounce_hfrom_format == HFROM_FORMAT_CODE_STD ?
+ tp->std_from : tp->obs_from);
out_fn(fp, "Subject: %s", tp->postmaster_subject && postmaster_copy ?
tp->postmaster_subject : tp->subject);
out_fn(fp, "To: %s", rcpt);
bounce_template_parse_buffer(tp);
vstream_fprintf(fp, "Charset: %s\n", tp->mime_charset);
- vstream_fprintf(fp, "From: %s\n", tp->from);
+ vstream_fprintf(fp, "From: %s\n", bounce_hfrom_format == HFROM_FORMAT_CODE_STD ?
+ tp->std_from : tp->obs_from);
vstream_fprintf(fp, "Subject: %s\n", tp->subject);
if (tp->postmaster_subject)
vstream_fprintf(fp, "Postmaster-Subject: %s\n",
const char *origin; /* built-in or pathname */
const char *mime_charset; /* character set (configurable) */
const char *mime_encoding; /* 7bit or 8bit (derived) */
- const char *from; /* originator (configurable) */
+ const char *obs_from; /* originator (configurable) */
+ const char *std_from; /* originator (configurable) */
const char *subject; /* general subject (configurable) */
const char *postmaster_subject; /* postmaster subject (configurable) */
const char **message_text; /* message text (configurable) */
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
"us-ascii",
MAIL_ATTR_ENC_7BIT,
MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">",
"Undelivered Mail Returned to Sender",
"Postmaster Copy: Undelivered Mail",
def_bounce_failure_body,
"# THIS IS A WARNING ONLY. YOU DO NOT NEED TO RESEND YOUR MESSAGE. #",
"####################################################################",
"",
- "Your message could not be delivered for more than $delay_warning_time_hours hour(s)."
- ,
+ "Your message could not be delivered for more than $delay_warning_time_hours hour(s).",
"It will be retried until it is $maximal_queue_lifetime_days day(s) old.",
"",
"For further assistance, please send mail to " MAIL_ADDR_POSTMASTER ".",
"us-ascii",
MAIL_ATTR_ENC_7BIT,
MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">",
"Delayed Mail (still being retried)",
"Postmaster Warning: Delayed Mail",
def_bounce_delay_body,
"us-ascii",
MAIL_ATTR_ENC_7BIT,
MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">",
"Successful Mail Delivery Report",
0,
def_bounce_success_body,
"us-ascii",
MAIL_ATTR_ENC_7BIT,
MAIL_ADDR_MAIL_DAEMON " (Mail Delivery System)",
+ "Mail Delivery System <" MAIL_ADDR_MAIL_DAEMON ">",
"Mail Delivery Status Report",
0,
def_bounce_verify_body,
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
--- /dev/null
+failure_template = <<EOF
+Charset: us-ascii
+From: MAILER-DAEMON (Mail Delivery System)
+Subject: Undelivered Mail Returned to Sender
+Postmaster-Subject: Postmaster Copy: Undelivered Mail
+
+This is the mail system at host $myhostname.
+
+I'm sorry to have to inform you that your message could not
+be delivered to one or more recipients. It's attached below.
+
+For further assistance, please send mail to postmaster.
+
+If you do so, please include this problem report. You can
+delete your own text from the attached returned message.
+
+ The mail system
+EOF
+
+delay_template = <<EOF
+Charset: us-ascii
+From: MAILER-DAEMON (Mail Delivery System)
+Subject: Delayed Mail (still being retried)
+Postmaster-Subject: Postmaster Warning: Delayed Mail
+
+This is the mail system at host $myhostname.
+
+####################################################################
+# THIS IS A WARNING ONLY. YOU DO NOT NEED TO RESEND YOUR MESSAGE. #
+####################################################################
+
+Your message could not be delivered for more than $delay_warning_time_hours hour(s).
+It will be retried until it is $maximal_queue_lifetime_days day(s) old.
+
+For further assistance, please send mail to postmaster.
+
+If you do so, please include this problem report. You can
+delete your own text from the attached returned message.
+
+ The mail system
+EOF
+
+success_template = <<EOF
+Charset: us-ascii
+From: MAILER-DAEMON (Mail Delivery System)
+Subject: Successful Mail Delivery Report
+
+This is the mail system at host $myhostname.
+
+Your message was successfully delivered to the destination(s)
+listed below. If the message was delivered to mailbox you will
+receive no further notifications. Otherwise you may still receive
+notifications of mail delivery errors from other systems.
+
+ The mail system
+EOF
+
+verify_template = <<EOF
+Charset: us-ascii
+From: MAILER-DAEMON (Mail Delivery System)
+Subject: Mail Delivery Status Report
+
+This is the mail system at host $myhostname.
+
+Enclosed is the mail delivery report that you requested.
+
+ The mail system
+EOF
failure_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
Postmaster-Subject: Postmaster Copy: Undelivered Mail
delay_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Delayed Mail (still being retried)
Postmaster-Subject: Postmaster Warning: Delayed Mail
success_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Successful Mail Delivery Report
This is the mail system at host $myhostname.
verify_template = <<EOF
Charset: us-ascii
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Mail Delivery Status Report
This is the mail system at host $myhostname.
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
References: <12345@mta-name.example>
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
References: <12345@mta-name.example>
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
References: <12345@mta-name.example>
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
Auto-Submitted: auto-replied
-From: MAILER-DAEMON (Mail Delivery System)
+From: Mail Delivery System <MAILER-DAEMON>
Subject: Undelivered Mail Returned to Sender
To: test-recipient
References: <12345@mta-name.example>
cleanup_init.o: ../../include/flush_clnt.h
cleanup_init.o: ../../include/header_body_checks.h
cleanup_init.o: ../../include/header_opts.h
+cleanup_init.o: ../../include/hfrom_format.h
cleanup_init.o: ../../include/htable.h
cleanup_init.o: ../../include/iostuff.h
cleanup_init.o: ../../include/mail_addr.h
cleanup_message.o: ../../include/ext_prop.h
cleanup_message.o: ../../include/header_body_checks.h
cleanup_message.o: ../../include/header_opts.h
+cleanup_message.o: ../../include/hfrom_format.h
cleanup_message.o: ../../include/htable.h
cleanup_message.o: ../../include/info_log_addr_form.h
cleanup_message.o: ../../include/iostuff.h
/* .IP "\fBmessage_drop_headers (bcc, content-length, resent-bcc, return-path)\fR"
/* Names of message headers that the \fBcleanup\fR(8) daemon will remove
/* after applying \fBheader_checks\fR(5) and before invoking Milter applications.
+/* .IP "\fBheader_from_format (standard)\fR"
+/* The format of the Postfix-generated \fBFrom:\fR header.
/* BUILT-IN CONTENT FILTERING CONTROLS
/* .ad
/* .fi
/*
* From: header formatting.
*/
-#define HFROM_FORMAT_CODE_STD 0
-#define HFROM_FORMAT_CODE_OBS 1
-extern int hfrom_format_code;
+extern int cleanup_hfrom_format;
/* LICENSE
/* .ad
#include <mail_version.h> /* milter_macro_v */
#include <ext_prop.h>
#include <flush_clnt.h>
+#include <hfrom_format.h>
/* Application-specific. */
/*
* From: header format.
*/
-int hfrom_format_code;
+int cleanup_hfrom_format;
/* cleanup_all - callback for the runtime error handler */
void cleanup_post_jail(char *unused_name, char **unused_argv)
{
- static const NAME_CODE hfrom_format_table[] = {
- HFROM_FORMAT_NAME_STD, HFROM_FORMAT_CODE_STD,
- HFROM_FORMAT_NAME_OBS, HFROM_FORMAT_CODE_OBS,
- 0, -1,
- };
/*
* Optionally set the file size resource limit. XXX This limits the
/*
* From: header formatting.
*/
- if ((hfrom_format_code = name_code(hfrom_format_table,
- NAME_CODE_FLAG_NONE, var_hfrom_format)) < 0)
- msg_fatal("invalid setting: %s = %s",
- VAR_HFROM_FORMAT, var_hfrom_format);
+ cleanup_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format);
}
#include <dsn_util.h>
#include <conv_time.h>
#include <info_log_addr_form.h>
+#include <hfrom_format.h>
/* Application-specific. */
|| (cp = strchr(state->fullname, '\n')) != 0)
*cp = ' ';
- switch (hfrom_format_code) {
-
- /*
- * "From: phrase <route-addr>". Quote the phrase if it
- * contains specials or the "%!" legacy address operators.
- */
- case HFROM_FORMAT_CODE_STD:
+ /*
+ * "From: phrase <route-addr>". Quote the phrase if it contains
+ * specials or the "%!" legacy address operators.
+ */
+ if (cleanup_hfrom_format == HFROM_FORMAT_CODE_STD) {
vstring_sprintf(state->temp2, "%sFrom: ", state->resent);
if (state->fullname[strcspn(state->fullname,
"%!" LEX_822_SPECIALS)] == 0) {
}
vstring_sprintf_append(state->temp2, "<%s>",
vstring_str(state->temp1));
- break;
+ }
- /*
- * "From: addr-spec (ctext)". This is the obsolete form.
- */
- case HFROM_FORMAT_CODE_OBS:
+ /*
+ * "From: addr-spec (ctext)". This is the obsolete form.
+ */
+ else {
vstring_sprintf(state->temp2, "%sFrom: %s ",
state->resent, vstring_str(state->temp1));
vstring_sprintf(state->temp1, "(%s)", state->fullname);
token = tok822_parse(vstring_str(state->temp1));
tok822_externalize(state->temp2, token, TOK822_STR_NONE);
tok822_free_tree(token);
- break;
- default:
- msg_panic("%s: unknown header format %d",
- myname, hfrom_format_code);
}
}
mail_addr_form.c quote_flags.c maillog_client.c \
normalize_mailhost_addr.c map_search.c reject_deliver_request.c \
info_log_addr_form.c sasl_mech_filter.c login_sender_match.c \
- test_main.c compat_level.c config_known_tcp_ports.c
+ test_main.c compat_level.c config_known_tcp_ports.c \
+ hfrom_format.c
OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
$(NON_PLUGIN_MAP_OBJ) mail_addr_form.o quote_flags.o maillog_client.o \
normalize_mailhost_addr.o map_search.o reject_deliver_request.o \
info_log_addr_form.o sasl_mech_filter.o login_sender_match.o \
- test_main.o compat_level.o config_known_tcp_ports.o
+ test_main.o compat_level.o config_known_tcp_ports.o \
+ hfrom_format.o
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these maps, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros.
attr_override.h mail_parm_split.h midna_adomain.h mail_addr_form.h \
maillog_client.h normalize_mailhost_addr.h map_search.h \
info_log_addr_form.h sasl_mech_filter.h login_sender_match.h \
- test_main.h compat_level.h config_known_tcp_ports.h
+ test_main.h compat_level.h config_known_tcp_ports.h \
+ hfrom_format.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
mail_version mail_dict server_acl uxtext mail_parm_split \
fold_addr smtp_reply_footer mail_addr_map normalize_mailhost_addr \
haproxy_srvr map_search delivered_hdr login_sender_match \
- compat_level config_known_tcp_ports
+ compat_level config_known_tcp_ports hfrom_format
LIBS = ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
LIB_DIR = ../../lib
compat_level: compat_level.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+hfrom_format: hfrom_format.c $(LIB) $(LIBS)
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
config_known_tcp_ports: config_known_tcp_ports.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
mail_addr_find_test mail_addr_map_test quote_822_local_test \
normalize_mailhost_addr_test haproxy_srvr_test map_search_test \
delivered_hdr_test login_sender_match_test compat_level_test \
- config_known_tcp_ports_test
+ config_known_tcp_ports_test hfrom_format_test
mime_tests: mime_test mime_nest mime_8bit mime_dom mime_trunc mime_cvt \
mime_cvt2 mime_cvt3 mime_garb1 mime_garb2 mime_garb3 mime_garb4
diff config_known_tcp_ports.ref config_known_tcp_ports.tmp
rm -f config_known_tcp_ports.tmp
+hfrom_format_test: update hfrom_format \
+ hfrom_format.ref
+ -$(SHLIB_ENV) $(VALGRIND) ./hfrom_format \
+ >hfrom_format.tmp 2>&1
+ diff hfrom_format.ref hfrom_format.tmp
+ rm -f hfrom_format.tmp
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
header_token.o: header_token.c
header_token.o: header_token.h
header_token.o: lex_822.h
+hfrom_format.o: ../../include/msg.h
+hfrom_format.o: ../../include/name_code.h
+hfrom_format.o: ../../include/sys_defs.h
+hfrom_format.o: hfrom_format.c
+hfrom_format.o: hfrom_format.h
+hfrom_format.o: mail_params.h
info_log_addr_form.o: ../../include/check_arg.h
info_log_addr_form.o: ../../include/msg.h
info_log_addr_form.o: ../../include/name_code.h
--- /dev/null
+/*++
+/* NAME
+/* hfrom_format 3
+/* SUMMARY
+/* Parse a header_from_format setting
+/* SYNOPSIS
+/* #include <hfrom_format.h>
+/*
+/* int hfrom_format_parse(
+/* const char *name,
+/* const char *value)
+/*
+/* const char *str_hfrom_format_code(int code)
+/* DESCRIPTION
+/* hfrom_format_parse() takes a parameter name (used for
+/* diagnostics) and value, and maps it to the corresponding
+/* code: HFROM_FORMAT_NAME_STD maps to HFROM_FORMAT_CODE_STD,
+/* and HFROM_FORMAT_NAME_OBS maps to HFROM_FORMAT_CODE_OBS.
+/*
+/* str_hfrom_format_code() does the reverse mapping.
+/* DIAGNOSTICS
+/* All input errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+ /*
+ * System library.
+ */
+#include <sys_defs.h>
+
+ /*
+ * Utility library.
+ */
+#include <name_code.h>
+#include <msg.h>
+
+ /*
+ * Global library.
+ */
+#include <mail_params.h>
+
+ /*
+ * Application-specific.
+ */
+#include <hfrom_format.h>
+
+ /*
+ * Primitive dependency injection.
+ */
+#ifdef TEST
+extern NORETURN PRINTFLIKE(1, 2) test_msg_fatal(const char *,...);
+
+#define msg_fatal test_msg_fatal
+#endif
+
+ /*
+ * The name-to-code mapping.
+ */
+static const NAME_CODE hfrom_format_table[] = {
+ HFROM_FORMAT_NAME_STD, HFROM_FORMAT_CODE_STD,
+ HFROM_FORMAT_NAME_OBS, HFROM_FORMAT_CODE_OBS,
+ 0, -1,
+};
+
+/* hfrom_format_parse - parse header_from_format setting */
+
+int hfrom_format_parse(const char *name, const char *value)
+{
+ int code;
+
+ if ((code = name_code(hfrom_format_table, NAME_CODE_FLAG_NONE, value)) < 0)
+ msg_fatal("invalid setting: \"%s = %s\"", name, value);
+ return (code);
+}
+
+/* str_hfrom_format_code - convert code to string */
+
+const char *str_hfrom_format_code(int code)
+{
+ const char *name;
+
+ if ((name = str_name_code(hfrom_format_table, code)) == 0)
+ msg_fatal("invalid header format code: %d", code);
+ return (name);
+}
+
+#ifdef TEST
+#include <stdlib.h>
+#include <setjmp.h>
+#include <string.h>
+
+#include <vstream.h>
+#include <vstring.h>
+#include <msg_vstream.h>
+
+#define STR(x) vstring_str(x)
+
+ /*
+ * TODO(wietse) make this a proper VSTREAM interface. Instead of temporarily
+ * swapping streams, we could temporarily swap the stream's write function.
+ */
+
+/* vstream_swap - kludge to capture output for testing */
+
+static void vstream_swap(VSTREAM *one, VSTREAM *two)
+{
+ VSTREAM save;
+
+ save = *one;
+ *one = *two;
+ *two = save;
+}
+
+jmp_buf test_fatal_jbuf;
+
+#undef msg_fatal
+
+/* test_msg_fatal - does not return, and does not terminate */
+
+void test_msg_fatal(const char *fmt,...)
+{
+ va_list ap;
+
+ va_start(ap, fmt);
+ vmsg_warn(fmt, ap);
+ va_end(ap);
+ longjmp(test_fatal_jbuf, 1);
+}
+
+struct name_test_case {
+ const char *label; /* identifies test case */
+ const char *config; /* configuration under test */
+ const char *exp_warning; /* expected warning or empty */
+ const int exp_code; /* expected code */
+};
+
+static struct name_test_case name_test_cases[] = {
+ {"hfrom_format_parse good-standard",
+ /* config */ HFROM_FORMAT_NAME_STD,
+ /* warning */ "",
+ /* exp_code */ HFROM_FORMAT_CODE_STD
+ },
+ {"hfrom_format_parse good-obsolete",
+ /* config */ HFROM_FORMAT_NAME_OBS,
+ /* warning */ "",
+ /* exp_code */ HFROM_FORMAT_CODE_OBS
+ },
+ {"hfrom_format_parse bad",
+ /* config */ "does-not-exist",
+ /* warning */ "hfrom_format: warning: invalid setting: \"hfrom_format_parse bad = does-not-exist\"\n",
+ /* code */ 0,
+ },
+ {"hfrom_format_parse empty",
+ /* config */ "",
+ /* warning */ "hfrom_format: warning: invalid setting: \"hfrom_format_parse empty = \"\n",
+ /* code */ 0,
+ },
+ 0,
+};
+
+struct code_test_case {
+ const char *label; /* identifies test case */
+ int code; /* code under test */
+ const char *exp_warning; /* expected warning or empty */
+ const char *exp_name; /* expected namme */
+};
+
+static struct code_test_case code_test_cases[] = {
+ {"str_hfrom_format_code good-standard",
+ /* code */ HFROM_FORMAT_CODE_STD,
+ /* warning */ "",
+ /* exp_name */ HFROM_FORMAT_NAME_STD
+ },
+ {"str_hfrom_format_code good-obsolete",
+ /* code */ HFROM_FORMAT_CODE_OBS,
+ /* warning */ "",
+ /* exp_name */ HFROM_FORMAT_NAME_OBS
+ },
+ {"str_hfrom_format_code bad",
+ /* config */ 12345,
+ /* warning */ "hfrom_format: warning: invalid header format code: 12345\n",
+ /* exp_name */ 0
+ },
+ 0,
+};
+
+int main(int argc, char **argv)
+{
+ struct name_test_case *np;
+ int code;
+ struct code_test_case *cp;
+ const char *name;
+ int pass = 0;
+ int fail = 0;
+ int test_failed;
+ VSTRING *msg_buf;
+ VSTREAM *memory_stream;
+
+ msg_vstream_init("hfrom_format", VSTREAM_ERR);
+ msg_buf = vstring_alloc(100);
+
+ for (np = name_test_cases; np->label != 0; np++) {
+ VSTRING_RESET(msg_buf);
+ VSTRING_TERMINATE(msg_buf);
+ test_failed = 0;
+ if ((memory_stream = vstream_memopen(msg_buf, O_WRONLY)) == 0)
+ msg_fatal("open memory stream: %m");
+ vstream_swap(VSTREAM_ERR, memory_stream);
+ if (setjmp(test_fatal_jbuf) == 0)
+ code = hfrom_format_parse(np->label, np->config);
+ vstream_swap(memory_stream, VSTREAM_ERR);
+ if (vstream_fclose(memory_stream))
+ msg_fatal("close memory stream: %m");
+ if (strcmp(STR(msg_buf), np->exp_warning) != 0) {
+ msg_warn("test case %s: got error: \"%s\", want: \"%s\"",
+ np->label, STR(msg_buf), np->exp_warning);
+ test_failed = 1;
+ }
+ if (*np->exp_warning == 0) {
+ if (code != np->exp_code) {
+ msg_warn("test case %s: got code: \"%d\", want: \"%d\"(%s)",
+ np->label, code, np->exp_code,
+ str_hfrom_format_code(np->exp_code));
+ test_failed = 1;
+ }
+ }
+ if (test_failed) {
+ msg_info("%s: FAIL", np->label);
+ fail++;
+ } else {
+ msg_info("%s: PASS", np->label);
+ pass++;
+ }
+ }
+
+ for (cp = code_test_cases; cp->label != 0; cp++) {
+ VSTRING_RESET(msg_buf);
+ VSTRING_TERMINATE(msg_buf);
+ test_failed = 0;
+ if ((memory_stream = vstream_memopen(msg_buf, O_WRONLY)) == 0)
+ msg_fatal("open memory stream: %m");
+ vstream_swap(VSTREAM_ERR, memory_stream);
+ if (setjmp(test_fatal_jbuf) == 0)
+ name = str_hfrom_format_code(cp->code);
+ vstream_swap(memory_stream, VSTREAM_ERR);
+ if (vstream_fclose(memory_stream))
+ msg_fatal("close memory stream: %m");
+ if (strcmp(STR(msg_buf), cp->exp_warning) != 0) {
+ msg_warn("test case %s: got error: \"%s\", want: \"%s\"",
+ cp->label, STR(msg_buf), cp->exp_warning);
+ test_failed = 1;
+ } else if (*cp->exp_warning == 0) {
+ if (strcmp(name, cp->exp_name)) {
+ msg_warn("test case %s: got name: \"%s\", want: \"%s\"",
+ cp->label, name, cp->exp_name);
+ test_failed = 1;
+ }
+ }
+ if (test_failed) {
+ msg_info("%s: FAIL", cp->label);
+ fail++;
+ } else {
+ msg_info("%s: PASS", cp->label);
+ pass++;
+ }
+ }
+
+ msg_info("PASS=%d FAIL=%d", pass, fail);
+ vstring_free(msg_buf);
+ exit(fail != 0);
+}
+
+#endif
--- /dev/null
+#ifndef _HFROM_FORMAT_INCLUDED_
+#define _HFROM_FORMAT_INCLUDED_
+
+/*++
+/* NAME
+/* hfrom_format 3h
+/* SUMMARY
+/* Parse a header_from_format setting
+/* SYNOPSIS
+/* #include <hfrom_format.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External interface.
+ */
+#define HFROM_FORMAT_CODE_OBS 0 /* Obsolete */
+#define HFROM_FORMAT_CODE_STD 1 /* Standard */
+
+extern int hfrom_format_parse(const char *, const char *);
+extern const char *str_hfrom_format_code(int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*--*/
+
+#endif
--- /dev/null
+hfrom_format: hfrom_format_parse good-standard: PASS
+hfrom_format: hfrom_format_parse good-obsolete: PASS
+hfrom_format: hfrom_format_parse bad: PASS
+hfrom_format: hfrom_format_parse empty: PASS
+hfrom_format: str_hfrom_format_code good-standard: PASS
+hfrom_format: str_hfrom_format_code good-obsolete: PASS
+hfrom_format: str_hfrom_format_code bad: PASS
+hfrom_format: PASS=7 FAIL=0
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20210926"
+#define MAIL_RELEASE_DATE "20211002"
#define MAIL_VERSION_NUMBER "3.7"
#ifdef SNAPSHOT
smtp.o: ../../include/fold_addr.h
smtp.o: ../../include/header_body_checks.h
smtp.o: ../../include/header_opts.h
+smtp.o: ../../include/hfrom_format.h
smtp.o: ../../include/htable.h
smtp.o: ../../include/iostuff.h
smtp.o: ../../include/mail_conf.h
smtp_chat.o: ../../include/dsn_util.h
smtp_chat.o: ../../include/header_body_checks.h
smtp_chat.o: ../../include/header_opts.h
+smtp_chat.o: ../../include/hfrom_format.h
smtp_chat.o: ../../include/htable.h
smtp_chat.o: ../../include/int_filt.h
smtp_chat.o: ../../include/iostuff.h
VAR_LMTP_DSN_FILTER, DEF_LMTP_DSN_FILTER, &var_smtp_dsn_filter, 0, 0,
VAR_LMTP_DNS_RE_FILTER, DEF_LMTP_DNS_RE_FILTER, &var_smtp_dns_re_filter, 0, 0,
VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0,
+ VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
0,
};
static const CONFIG_TIME_TABLE lmtp_time_table[] = {
VAR_LMTP_BALANCE_INET_PROTO, DEF_LMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto,
0,
};
- static const CONFIG_NBOOL_TABLE lmtp_nbool_table[] = {
+ static const CONFIG_NBOOL_TABLE lmtp_nbool_table[] = {
VAR_LMTP_REQ_DEADLINE, DEF_LMTP_REQ_DEADLINE, &var_smtp_req_deadline,
0,
- };
+ };
/* .IP "\fBsmtp_min_data_rate (500)\fR"
/* The minimum plaintext data transfer rate in bytes/second for
/* DATA requests, when deadlines are enabled with smtp_per_request_deadline.
+/* .IP "\fBheader_from_format (standard)\fR"
+/* The format of the Postfix-generated \fBFrom:\fR header.
/* MIME PROCESSING CONTROLS
/* .ad
/* .fi
#include <string_list.h>
#include <maps.h>
#include <ext_prop.h>
+#include <hfrom_format.h>
/* DNS library. */
int var_smtp_sasl_auth_cache_time;
bool var_smtp_sasl_auth_soft_bounce;
+char *var_hfrom_format;
+
/*
* Global variables.
*/
HBC_CHECKS *smtp_header_checks; /* limited header checks */
HBC_CHECKS *smtp_body_checks; /* limited body checks */
SMTP_CLI_ATTR smtp_cli_attr; /* parsed command-line */
+int smtp_hfrom_format; /* postmaster notifications */
#ifdef USE_TLS
* the process lifetime.
*/
get_cli_attr(&smtp_cli_attr, argv);
+
+ /*
+ * header_from format, for postmaster notifications.
+ */
+ smtp_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format);
}
/* pre_init - pre-jail initialization */
CA_MAIL_SERVER_BOOL_TABLE(smtp_mode ?
smtp_bool_table : lmtp_bool_table),
CA_MAIL_SERVER_NBOOL_TABLE(smtp_mode ?
- smtp_nbool_table : lmtp_nbool_table),
+ smtp_nbool_table : lmtp_nbool_table),
CA_MAIL_SERVER_PRE_INIT(pre_init),
CA_MAIL_SERVER_POST_INIT(post_init),
CA_MAIL_SERVER_PRE_ACCEPT(pre_accept),
extern void smtp_quote_822_address_flags(VSTRING *, const char *, int);
extern void smtp_quote_821_address(VSTRING *, const char *);
+ /*
+ * header_from_format support, for postmaster notifications.
+ */
+extern int smtp_hfrom_format;
+
/* LICENSE
/* .ad
/* .fi
#include <post_mail.h>
#include <mail_error.h>
#include <dsn_util.h>
+#include <hfrom_format.h>
/* Application-specific. */
msg_warn("postmaster notify: %m");
return;
}
- post_mail_fprintf(notice, "From: %s (Mail Delivery System)",
- mail_addr_mail_daemon());
- post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt);
+ if (smtp_hfrom_format == HFROM_FORMAT_CODE_STD) {
+ post_mail_fprintf(notice, "From: Mail Delivery System <%s>",
+ mail_addr_mail_daemon());
+ post_mail_fprintf(notice, "To: Postmaster <%s>", var_error_rcpt);
+ } else {
+ post_mail_fprintf(notice, "From: %s (Mail Delivery System)",
+ mail_addr_mail_daemon());
+ post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt);
+ }
post_mail_fprintf(notice, "Subject: %s %s client: errors from %s",
var_mail_name, smtp_mode ? "SMTP" : "LMTP",
session->namaddrport);
VAR_SMTP_DSN_FILTER, DEF_SMTP_DSN_FILTER, &var_smtp_dsn_filter, 0, 0,
VAR_SMTP_DNS_RE_FILTER, DEF_SMTP_DNS_RE_FILTER, &var_smtp_dns_re_filter, 0, 0,
VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0,
+ VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
0,
};
static const CONFIG_TIME_TABLE smtp_time_table[] = {
VAR_SMTP_BALANCE_INET_PROTO, DEF_SMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto,
0,
};
- static const CONFIG_NBOOL_TABLE smtp_nbool_table[] = {
+ static const CONFIG_NBOOL_TABLE smtp_nbool_table[] = {
VAR_SMTP_REQ_DEADLINE, DEF_SMTP_REQ_DEADLINE, &var_smtp_req_deadline,
0,
- };
+ };
smtpd.o: ../../include/ehlo_mask.h
smtpd.o: ../../include/events.h
smtpd.o: ../../include/flush_clnt.h
+smtpd.o: ../../include/hfrom_format.h
smtpd.o: ../../include/htable.h
smtpd.o: ../../include/inet_proto.h
smtpd.o: ../../include/info_log_addr_form.h
smtpd_chat.o: ../../include/cleanup_user.h
smtpd_chat.o: ../../include/dict.h
smtpd_chat.o: ../../include/dns.h
+smtpd_chat.o: ../../include/hfrom_format.h
smtpd_chat.o: ../../include/htable.h
smtpd_chat.o: ../../include/int_filt.h
smtpd_chat.o: ../../include/iostuff.h
/* The minimum plaintext data transfer rate in bytes/second for
/* DATA and BDAT requests, when deadlines are enabled with
/* smtpd_per_request_deadline.
+/* .IP "\fBheader_from_format (standard)\fR"
+/* The format of the Postfix-generated \fBFrom:\fR header.
/* TARPIT CONTROLS
/* .ad
/* .fi
#include <match_parent_style.h>
#include <normalize_mailhost_addr.h>
#include <info_log_addr_form.h>
+#include <hfrom_format.h>
/* Single-threaded server skeleton. */
bool var_relay_before_rcpt_checks;
bool var_smtpd_req_deadline;
int var_smtpd_min_data_rate;
+char *var_hfrom_format;
/*
* Silly little macros.
*/
static DICT *smtpd_cmd_filter;
+ /*
+ * Parsed header_from_format setting.
+ */
+int smtpd_hfrom_format;
+
#ifdef USE_SASL_AUTH
/*
|| var_smtpd_cmail_limit || var_smtpd_crcpt_limit
|| var_smtpd_cntls_limit || var_smtpd_cauth_limit)
anvil_clnt = anvil_clnt_create();
+
+ /*
+ * header_from_format support, for postmaster notifications.
+ */
+ smtpd_hfrom_format = hfrom_format_parse(VAR_HFROM_FORMAT, var_hfrom_format);
}
MAIL_VERSION_STAMP_DECLARE;
VAR_SMTPD_POLICY_CONTEXT, DEF_SMTPD_POLICY_CONTEXT, &var_smtpd_policy_context, 0, 0,
VAR_SMTPD_DNS_RE_FILTER, DEF_SMTPD_DNS_RE_FILTER, &var_smtpd_dns_re_filter, 0, 0,
VAR_SMTPD_REJ_FTR_MAPS, DEF_SMTPD_REJ_FTR_MAPS, &var_smtpd_rej_ftr_maps, 0, 0,
+ VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
0,
};
static const CONFIG_RAW_TABLE raw_table[] = {
*/
extern double smtpd_space_multf;
+ /*
+ * header_from_format support.
+ */
+extern int smtpd_hfrom_format;
+
/* LICENSE
/* .ad
/* .fi
#include <post_mail.h>
#include <mail_error.h>
#include <smtp_reply_footer.h>
+#include <hfrom_format.h>
/* Application-specific. */
msg_warn("postmaster notify: %m");
return;
}
- post_mail_fprintf(notice, "From: %s (Mail Delivery System)",
- mail_addr_mail_daemon());
- post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt);
+ if (smtpd_hfrom_format == HFROM_FORMAT_CODE_STD) {
+ post_mail_fprintf(notice, "From: Mail Delivery System <%s>",
+ mail_addr_mail_daemon());
+ post_mail_fprintf(notice, "To: Postmaster <%s>", var_error_rcpt);
+ } else {
+ post_mail_fprintf(notice, "From: %s (Mail Delivery System)",
+ mail_addr_mail_daemon());
+ post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt);
+ }
post_mail_fprintf(notice, "Subject: %s SMTP server: errors from %s",
var_mail_name, state->namaddr);
post_mail_fputs(notice, "");