2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 21:55:20 +00:00

postfix-1.1.9-20020512

This commit is contained in:
Wietse Venema
2002-05-12 00:00:00 -05:00
committed by Viktor Dukhovni
parent 78a1cda2a7
commit 8b55eed2be
64 changed files with 848 additions and 228 deletions

View File

@@ -6383,10 +6383,41 @@ Apologies for any names omitted.
multiple Postfix instances. Text by Victor Duchovny, Morgan
Stanley. File: README_FILES/FILTER_README.
Open problems:
20020510
Low: smtpd should reply with the original recipient address,
or it should at least externalize it.
Feature: header/body filters now log the origin of the
message that is being rejected. Files: smtpd/smtpd.c,
qmqpd/qmqpd.c, pickup/pickup.c, cleanup/cleanup_envelope.c,
cleanup/cleanup_message.c. Requested by Craig Sanders, if
I remember correctly.
Feature: the Postfix SMTP client now passes on MIME body
type information (8bit, 7bit) received via SMTP, via MIME
headers, or via the sendmail command line. Files:
global/deliver_request.c, smtpd/smtpd.c, sendmail/sendmail.c,
cleanup/cleanup_envelope.c, cleanup/cleanup_message.c,
cleanup/cleanup_extracted.c, *qmgr/qmgr_message.c,
*qmgr/qmgr_deliver.c, smtp/smtp_proto.c, lmtp/lmtp_proto.c.
20020511
Feature: bounces now specify the proper MIME encoding (8bit,
7bit), depending on the MIME body type information received
via SMTP, via MIME headers, or via the sendmail command
line. Files: global/bounce.c, global/defer.c, global/abounce.c,
bounce/bounce_service.c, bounce/bounce_notify_util.c.
20020512
Cleanup: the SMTP client logged and bounced the CNAME
expanded recipient address, and thereby complicated trouble
shooting. File: src/smtp_proto.c.
Bugfix: the SMTP and LMTP clients bounced the quoted
recipient address, resulting in too much quoting in bounce
reports. Files: src/smtp_proto.c, lmtp/lmtp_proto.c.
Open problems:
Low: all table lookups should consistently use internalized
(unquoted) or externalized (quoted) forms as lookup keys.

View File

@@ -12,6 +12,38 @@ snapshot release). Patches change the patchlevel and the release
date. Snapshots change only the release date, unless they include
the same bugfixes as a patch release.
Incompatible changes with Postfix snapshot 1.1.9-20020512
=========================================================
The Postfix SMTP client no longer uses the CNAME expanded recipient
address when logging delivery or when bouncing mail. This makes
trouble shooting somewhat easier.
Postfix snapshot 1.1.9-20020512 queue files contain records that
are incompatible with "postqueue -r" on all Postfix versions prior
to 1.1 and release candidates. This happens whenever the sender
specifies MIME body type information via the SMTP `MAIL FROM'
command, via the `sendmail -B' command line option, or via the
Content-Transfer-Encoding: message header.
Postfix snapshot 1.1.9-20020512 queue files may contain records
that are incompatible with "postqueue -r" on previous 1.1 Postfix
versions and release candidates. This happens whenever the sender
specifies the MIME body type only via the Content-Transfer-Encoding:
message header, and not via `MAIL FROM' or `sendmail -B'.
Major changes with Postfix snapshot 1.1.9-20020512
==================================================
The Postfix SMTP and LMTP clients now properly pass on the MIME
body type information (7BIT or 8BITMIME), provided that the sender
properly specifies MIME body type information via the SMTP MAIL
FROM command, via the sendmail -B command line option, or via MIME
message headers. This includes mail that is returned as undeliverable.
Implementing MIME body type propagation was a low priority because
qmail didn't implement this, either. However, Postfix will not
convert 8BITMIME content into 7BIT, and probably never will.
Incompatible changes with Postfix snapshot 1.1.9-20020509
=========================================================
@@ -22,11 +54,11 @@ catch-all patterns.
The appearance of user@domain1@domain2 addresses has changed. In
mail headers, such addresses are now properly quoted as
"user@domain1"@domain2. This quoted form is now also expected on
the left-hand side of virtual and canonical lookup tables, but only
by some of the Postfix components. For now, it is better not to
use user@domain1@domain2 address forms on the left-hand side of
lookup tables.
"user@domain1"@domain2. As a side effect, this quoted form is now
also expected on the left-hand side of virtual and canonical lookup
tables, but only by some of the Postfix components. For now, it
is better not to use user@domain1@domain2 address forms on the
left-hand side of lookup tables.
Incompatible changes with Postfix snapshot 1.1.8-20020508
=========================================================

View File

@@ -1,5 +1,4 @@
<html> <head> </head> <body> <pre>
BOUNCE(8) BOUNCE(8)
<b>NAME</b>
@@ -38,6 +37,7 @@ BOUNCE(8) BOUNCE(8)
<b>STANDARDS</b>
<a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
<a href="http://www.faqs.org/rfcs/rfc1894.html">RFC 1894</a> (Delivery Status Notifications)
<a href="http://www.faqs.org/rfcs/rfc2045.html">RFC 2045</a> (Format of Internet Message Bodies)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8).
@@ -90,6 +90,5 @@ BOUNCE(8) BOUNCE(8)
P.O. Box 704
Yorktown Heights, NY 10598, USA
1
BOUNCE(8)
</pre> </body> </html>

View File

@@ -1,5 +1,4 @@
<html> <head> </head> <body> <pre>
LMTP(8) LMTP(8)
<b>NAME</b>
@@ -56,6 +55,7 @@ LMTP(8) LMTP(8)
<b>STANDARDS</b>
<a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
<a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
<a href="http://www.faqs.org/rfcs/rfc1652.html">RFC 1652</a> (8bit-MIME transport)
<a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
<a href="http://www.faqs.org/rfcs/rfc2033.html">RFC 2033</a> (LMTP protocol)
<a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining)
@@ -265,6 +265,5 @@ LMTP(8) LMTP(8)
P.O. Box 830688, MC34
Richardson, TX 75083, USA
1
LMTP(8)
</pre> </body> </html>

View File

@@ -57,92 +57,91 @@ SENDMAIL(1) SENDMAIL(1)
The following options are recognized:
<b>-B</b> <i>body_type</i> (ignored)
The message body MIME type. Currently, Postfix
implements <b>just-send-eight</b>.
<b>-B</b> <i>body_type</i>
The message body MIME type: <b>7BIT</b> or <b>8BITMIME</b>.
<b>-C</b> <i>config_file</i> (ignored :-)
The path name of the <b>sendmail.cf</b> file. Postfix con-
figuration files are kept in <b>/etc/postfix</b>.
<b>-F</b> <i>full_name</i>
Set the sender full name. This is used only with
Set the sender full name. This is used only with
messages that have no <b>From:</b> message header.
<b>-G</b> (ignored)
Gateway (relay) submission, as opposed to initial
Gateway (relay) submission, as opposed to initial
user submission.
<b>-I</b> Initialize alias database. See the <b>newaliases</b> com-
<b>-I</b> Initialize alias database. See the <b>newaliases</b> com-
mand above.
<b>-L</b> <i>label</i> (ignored)
The logging label. Use the <b>syslog</b><i>_</i><b>name</b> configura-
The logging label. Use the <b>syslog</b><i>_</i><b>name</b> configura-
tion parameter instead.
<b>-N</b> <i>dsn</i> (ignored)
Delivery status notification control. Currently,
Delivery status notification control. Currently,
Postfix does not implement <b>DSN</b>.
<b>-R</b> <i>return_limit</i> (ignored)
Limit the size of bounced mail. Use the
<b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b> configuration parameter instead.
Limit the size of bounced mail. Use the
<b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b> configuration parameter instead.
<b>-X</b> <i>log_file</i> (ignored)
Log mailer traffic. Use the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> and
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> configuration parameters instead.
Log mailer traffic. Use the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> and
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> configuration parameters instead.
<b>-U</b> (ignored)
Initial user submission.
<b>-V</b> Variable Envelope Return Path. Given an envelope
sender address of the form <i>owner-listname</i>@<i>origin</i>,
each recipient <i>user</i>@<i>domain</i> receives mail with a
<b>-V</b> Variable Envelope Return Path. Given an envelope
sender address of the form <i>owner-listname</i>@<i>origin</i>,
each recipient <i>user</i>@<i>domain</i> receives mail with a
personalized envelope sender address.
By default, the personalized envelope sender
address is <i>owner-listname</i><b>+</b><i>user</i><b>=</b><i>domain</i>@<i>origin</i>. The
default <b>+</b> and <b>=</b> characters are configurable with
the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b> configuration parame-
ter.
<b>-V</b><i>xy</i> As <b>-V</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter char-
acters, instead of the characters specified with
By default, the personalized envelope sender
address is <i>owner-listname</i><b>+</b><i>user</i><b>=</b><i>domain</i>@<i>origin</i>. The
default <b>+</b> and <b>=</b> characters are configurable with
the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b> configuration parame-
ter.
<b>-bd</b> Go into daemon mode. This mode of operation is
<b>-V</b><i>xy</i> As <b>-V</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter char-
acters, instead of the characters specified with
the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b> configuration parame-
ter.
<b>-bd</b> Go into daemon mode. This mode of operation is
implemented by executing the <b>postfix</b> <b>start</b> command.
<b>-bi</b> Initialize alias database. See the <b>newaliases</b> com-
<b>-bi</b> Initialize alias database. See the <b>newaliases</b> com-
mand above.
<b>-bm</b> Read mail from standard input and arrange for
<b>-bm</b> Read mail from standard input and arrange for
delivery. This is the default mode of operation.
<b>-bp</b> List the mail queue. See the <b>mailq</b> command above.
<b>-bs</b> Stand-alone SMTP server mode. Read SMTP commands
from standard input, and write responses to stan-
dard output. In stand-alone SMTP server mode, UCE
restrictions and access controls are disabled by
default. To enable them, run the process as the
<b>-bs</b> Stand-alone SMTP server mode. Read SMTP commands
from standard input, and write responses to stan-
dard output. In stand-alone SMTP server mode, UCE
restrictions and access controls are disabled by
default. To enable them, run the process as the
<b>mail</b><i>_</i><b>owner</b> user.
This mode of operation is implemented by running
This mode of operation is implemented by running
the <a href="smtpd.8.html"><b>smtpd</b>(8)</a> daemon.
<b>-f</b> <i>sender</i>
Set the envelope sender address. This is the
address where delivery problems are sent to, unless
the message contains an <b>Errors-To:</b> message header.
the message contains an <b>Errors-To:</b> message header.
<b>-h</b> <i>hop_count</i> (ignored)
Hop count limit. Use the <b>hopcount</b><i>_</i><b>limit</b> configura-
Hop count limit. Use the <b>hopcount</b><i>_</i><b>limit</b> configura-
tion parameter instead.
<b>-i</b> When reading a message from standard input, don't
treat a line with only a <b>.</b> character as the end of
<b>-i</b> When reading a message from standard input, don't
treat a line with only a <b>.</b> character as the end of
input.
<b>-m</b> (ignored)
@@ -152,67 +151,67 @@ SENDMAIL(1) SENDMAIL(1)
Backwards compatibility.
<b>-oA</b><i>alias_database</i>
Non-default alias database. Specify <i>pathname</i> or
Non-default alias database. Specify <i>pathname</i> or
<i>type</i>:<i>pathname</i>. See <a href="postalias.1.html"><b>postalias</b>(1)</a> for details.
<b>-o7</b> (ignored)
<b>-o8</b> (ignored)
The message body type. Currently, Postfix imple-
The message body type. Currently, Postfix imple-
ments <b>just-send-eight</b>.
<b>-oi</b> When reading a message from standard input, don't
treat a line with only a <b>.</b> character as the end of
<b>-oi</b> When reading a message from standard input, don't
treat a line with only a <b>.</b> character as the end of
input.
<b>-om</b> (ignored)
The sender is never eliminated from alias etc.
The sender is never eliminated from alias etc.
expansions.
<b>-o</b> <i>x</i> <i>value</i> (ignored)
Set option <i>x</i> to <i>value</i>. Use the equivalent configu-
Set option <i>x</i> to <i>value</i>. Use the equivalent configu-
ration parameter in <b>main.cf</b> instead.
<b>-r</b> <i>sender</i>
Set the envelope sender address. This is the
address where delivery problems are sent to, unless
the message contains an <b>Errors-To:</b> message header.
the message contains an <b>Errors-To:</b> message header.
<b>-q</b> Attempt to deliver all queued mail. This is imple-
<b>-q</b> Attempt to deliver all queued mail. This is imple-
mented by executing the <a href="postqueue.1.html"><b>postqueue</b>(1)</a> command.
<b>-q</b><i>interval</i> (ignored)
The interval between queue runs. Use the
The interval between queue runs. Use the
<b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b> configuration parameter instead.
<b>-qR</b><i>site</i>
Schedule immediate delivery of all mail that is
Schedule immediate delivery of all mail that is
queued for the named <i>site</i>. This option accepts only
<i>site</i> names that are eligible for the "fast flush"
service, and is implemented by executing the
<i>site</i> names that are eligible for the "fast flush"
service, and is implemented by executing the
<a href="postqueue.1.html"><b>postqueue</b>(1)</a> command. See <a href="flushd.8.html"><b>flush</b>(8)</a> for more infor-
mation about the "fast flush" service.
<b>-qS</b><i>site</i>
This command is not implemented. Use the slower
This command is not implemented. Use the slower
<b>sendmail</b> <b>-q</b> command instead.
<b>-t</b> Extract recipients from message headers. This
requires that no recipients be specified on the
<b>-t</b> Extract recipients from message headers. This
requires that no recipients be specified on the
command line.
<b>-v</b> Enable verbose logging for debugging purposes. Mul-
tiple <b>-v</b> options make the software increasingly
tiple <b>-v</b> options make the software increasingly
verbose.
<b>SECURITY</b>
By design, this program is not set-user (or group) id.
However, it must handle data from untrusted users or
untrusted machines. Thus, the usual precautions need to
By design, this program is not set-user (or group) id.
However, it must handle data from untrusted users or
untrusted machines. Thus, the usual precautions need to
be taken against malicious inputs.
<b>DIAGNOSTICS</b>
Problems are logged to <b>syslogd</b>(8) and to the standard
Problems are logged to <b>syslogd</b>(8) and to the standard
error stream.
<b>ENVIRONMENT</b>
@@ -224,7 +223,7 @@ SENDMAIL(1) SENDMAIL(1)
<b>MAIL</b><i>_</i><b>DEBUG</b>
Enable debugging with an external command, as spec-
ified with the <b>debugger</b><i>_</i><b>command</b> configuration
ified with the <b>debugger</b><i>_</i><b>command</b> configuration
parameter.
<b>FILES</b>
@@ -232,13 +231,13 @@ SENDMAIL(1) SENDMAIL(1)
/etc/postfix, configuration files
<b>CONFIGURATION</b> <b>PARAMETERS</b>
See the Postfix <b>main.cf</b> file for syntax details and for
default values. Use the <b>postfix</b> <b>reload</b> command after a
See the Postfix <b>main.cf</b> file for syntax details and for
default values. Use the <b>postfix</b> <b>reload</b> command after a
configuration change.
<b>alias</b><i>_</i><b>database</b>
Default alias database(s) for <b>newaliases</b>. The
default value for this parameter is system-spe-
Default alias database(s) for <b>newaliases</b>. The
default value for this parameter is system-spe-
cific.
<b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b>
@@ -254,62 +253,62 @@ SENDMAIL(1) SENDMAIL(1)
initialized.
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
Increment in verbose logging level when a remote
Increment in verbose logging level when a remote
host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
parameter.
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
List of domain or network patterns. When a remote
host matches a pattern, increase the verbose log-
ging level by the amount specified in the
List of domain or network patterns. When a remote
host matches a pattern, increase the verbose log-
ging level by the amount specified in the
<b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
<b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>
The VERP delimiter characters that are used when
the <b>-V</b> command line option is specified without
The VERP delimiter characters that are used when
the <b>-V</b> command line option is specified without
delimiter characters.
<b>fast</b><i>_</i><b>flush</b><i>_</i><b>domains</b>
List of domains that will receive "fast flush" ser-
vice (default: all domains that this system is
willing to relay mail to). This list specifies the
domains that Postfix accepts in the SMTP <b>ETRN</b>
vice (default: all domains that this system is
willing to relay mail to). This list specifies the
domains that Postfix accepts in the SMTP <b>ETRN</b>
request and in the <b>sendmail</b> <b>-qR</b> command.
<b>fork</b><i>_</i><b>attempts</b>
Number of attempts to <b>fork</b>() a process before giv-
Number of attempts to <b>fork</b>() a process before giv-
ing up.
<b>fork</b><i>_</i><b>delay</b>
Delay in seconds between successive <b>fork</b>()
Delay in seconds between successive <b>fork</b>()
attempts.
<b>hopcount</b><i>_</i><b>limit</b>
Limit the number of <b>Received:</b> message headers.
<b>mail</b><i>_</i><b>owner</b>
The owner of the mail queue and of most Postfix
The owner of the mail queue and of most Postfix
processes.
<b>command</b><i>_</i><b>directory</b>
Directory with Postfix support commands (default:
Directory with Postfix support commands (default:
<b>$program</b><i>_</i><b>directory</b>).
<b>daemon</b><i>_</i><b>directory</b>
Directory with Postfix daemon programs (default:
Directory with Postfix daemon programs (default:
<b>$program</b><i>_</i><b>directory</b>).
<b>queue</b><i>_</i><b>directory</b>
Top-level directory of the Postfix queue. This is
Top-level directory of the Postfix queue. This is
also the root directory of Postfix daemons that run
chrooted.
<b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
The time between successive scans of the deferred
The time between successive scans of the deferred
queue.
<b>verp</b><i>_</i><b>delimiter</b><i>_</i><b>filter</b>
The characters that Postfix accepts as VERP delim-
The characters that Postfix accepts as VERP delim-
iter characters.
<b>SEE</b> <b>ALSO</b>
@@ -324,7 +323,7 @@ SENDMAIL(1) SENDMAIL(1)
syslogd(8) system logging
<b>LICENSE</b>
The Secure Mailer license must be distributed with this
The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>

View File

@@ -43,6 +43,7 @@ SMTP(8) SMTP(8)
<b>STANDARDS</b>
<a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a> (SMTP protocol)
<a href="http://www.faqs.org/rfcs/rfc1651.html">RFC 1651</a> (SMTP service extensions)
<a href="http://www.faqs.org/rfcs/rfc1652.html">RFC 1652</a> (8bit-MIME transport)
<a href="http://www.faqs.org/rfcs/rfc1870.html">RFC 1870</a> (Message Size Declaration)
<a href="http://www.faqs.org/rfcs/rfc2197.html">RFC 2197</a> (Pipelining)
<a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a> (AUTH command)

View File

@@ -55,9 +55,8 @@ appropriate combination of command-line options. Some features are
controlled by parameters in the \fBmain.cf\fR configuration file.
The following options are recognized:
.IP "\fB-B \fIbody_type\fR (ignored)"
The message body MIME type. Currently, Postfix implements
\fBjust-send-eight\fR.
.IP "\fB-B \fIbody_type\fR"
The message body MIME type: \fB7BIT\fR or \fB8BITMIME\fR.
.IP "\fB-C \fIconfig_file\fR (ignored :-)"
The path name of the \fBsendmail.cf\fR file. Postfix configuration
files are kept in \fB/etc/postfix\fR.

View File

@@ -41,6 +41,7 @@ themselves, and that depend on retry logic in their own client.
.nf
RFC 822 (ARPA Internet Text Messages)
RFC 1894 (Delivery Status Notifications)
RFC 2045 (Format of Internet Message Bodies)
.SH DIAGNOSTICS
.ad
.fi

View File

@@ -56,6 +56,7 @@ run chrooted at fixed low privilege.
.nf
RFC 821 (SMTP protocol)
RFC 1651 (SMTP service extensions)
RFC 1652 (8bit-MIME transport)
RFC 1870 (Message Size Declaration)
RFC 2033 (LMTP protocol)
RFC 2197 (Pipelining)

View File

@@ -48,6 +48,7 @@ run chrooted at fixed low privilege.
.nf
RFC 821 (SMTP protocol)
RFC 1651 (SMTP service extensions)
RFC 1652 (8bit-MIME transport)
RFC 1870 (Message Size Declaration)
RFC 2197 (Pipelining)
RFC 2554 (AUTH command)

View File

@@ -136,6 +136,9 @@ bounce_notify_util.o: ../../include/mail_error.h
bounce_notify_util.o: ../../include/name_mask.h
bounce_notify_util.o: ../../include/bounce_log.h
bounce_notify_util.o: ../../include/mail_date.h
bounce_notify_util.o: ../../include/mail_proto.h
bounce_notify_util.o: ../../include/iostuff.h
bounce_notify_util.o: ../../include/attr.h
bounce_notify_util.o: bounce_service.h
bounce_notify_verp.o: bounce_notify_verp.c
bounce_notify_verp.o: ../../include/sys_defs.h

View File

@@ -33,6 +33,7 @@
/* STANDARDS
/* RFC 822 (ARPA Internet Text Messages)
/* RFC 1894 (Delivery Status Notifications)
/* RFC 2045 (Format of Internet Message Bodies)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* BUGS
@@ -127,6 +128,7 @@ char *var_delay_rcpt;
static VSTRING *queue_id;
static VSTRING *queue_name;
static VSTRING *recipient;
static VSTRING *encoding;
static VSTRING *sender;
static VSTRING *verp_delims;
static VSTRING *why;
@@ -186,8 +188,9 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, int flush)
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_END) != 4) {
ATTR_TYPE_END) != 5) {
msg_warn("malformed request");
return (-1);
}
@@ -200,8 +203,9 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, int flush)
return (-1);
}
if (msg_verbose)
msg_info("bounce_notify_proto: service=%s queue=%s id=%s sender=%s",
service_name, STR(queue_name), STR(queue_id), STR(sender));
msg_info("bounce_notify_proto: service=%s queue=%s id=%s encoding=%s sender=%s",
service_name, STR(queue_name), STR(queue_id),
STR(encoding), STR(sender));
/*
* On request by the client, set up a trap to delete the log file in case
@@ -214,7 +218,8 @@ static int bounce_notify_proto(char *service_name, VSTREAM *client, int flush)
* Execute the request.
*/
return (bounce_notify_service(service_name, STR(queue_name),
STR(queue_id), STR(sender), flush));
STR(queue_id), STR(encoding),
STR(sender), flush));
}
/* bounce_verp_proto - bounce_notify server protocol, VERP style */
@@ -228,12 +233,13 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client, int flush)
* Read and validate the client request.
*/
if (mail_command_server(client,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
ATTR_TYPE_END) != 5) {
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
ATTR_TYPE_END) != 6) {
msg_warn("malformed request");
return (-1);
}
@@ -251,9 +257,9 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client, int flush)
return (-1);
}
if (msg_verbose)
msg_info("%s: service=%s queue=%s id=%s sender=%s delim=%s",
msg_info("%s: service=%s queue=%s id=%s encoding=%s sender=%s delim=%s",
myname, service_name, STR(queue_name), STR(queue_id),
STR(sender), STR(verp_delims));
STR(encoding), STR(sender), STR(verp_delims));
/*
* On request by the client, set up a trap to delete the log file in case
@@ -269,11 +275,12 @@ static int bounce_verp_proto(char *service_name, VSTREAM *client, int flush)
if (!*STR(sender) || !strcasecmp(STR(sender), mail_addr_double_bounce())) {
msg_warn("request to send VERP-style notification of bounced mail");
return (bounce_notify_service(service_name, STR(queue_name),
STR(queue_id), STR(sender), flush));
STR(queue_id), STR(encoding),
STR(sender), flush));
} else
return (bounce_notify_verp(service_name, STR(queue_name),
STR(queue_id), STR(sender),
STR(verp_delims), flush));
STR(queue_id), STR(encoding),
STR(sender), STR(verp_delims), flush));
}
/* bounce_service - parse bounce command type and delegate */
@@ -349,6 +356,7 @@ static void post_jail_init(char *unused_name, char **unused_argv)
queue_id = vstring_alloc(10);
queue_name = vstring_alloc(10);
recipient = vstring_alloc(10);
encoding = vstring_alloc(10);
sender = vstring_alloc(10);
verp_delims = vstring_alloc(10);
why = vstring_alloc(10);

View File

@@ -6,9 +6,11 @@
/* SYNOPSIS
/* #include "bounce_service.h"
/*
/* int bounce_notify_service(queue_name, queue_id, sender, flush)
/* int bounce_notify_service(queue_name, queue_id, encoding,
/* sender, flush)
/* char *queue_name;
/* char *queue_id;
/* char *encoding;
/* char *sender;
/* int flush;
/* DESCRIPTION
@@ -78,7 +80,8 @@
/* bounce_notify_service - send a bounce */
int bounce_notify_service(char *service, char *queue_name,
char *queue_id, char *recipient, int flush)
char *queue_id, char *encoding,
char *recipient, int flush)
{
BOUNCE_INFO *bounce_info;
int bounce_status = 1;
@@ -91,7 +94,8 @@ int bounce_notify_service(char *service, char *queue_name,
/*
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id, flush);
bounce_info = bounce_mail_init(service, queue_name, queue_id,
encoding, flush);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_CLEANUP_FLAGS 0

View File

@@ -12,10 +12,12 @@
/* .in -4
/* } BOUNCE_INFO;
/*
/* BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id, flush)
/* BOUNCE_INFO *bounce_mail_init(service, queue_name, queue_id,
/* encoding, flush)
/* const char *service;
/* const char *queue_name;
/* const char *queue_id;
/* const char *encoding;
/* int flush;
/*
/* void bounce_mail_free(bounce_info)
@@ -152,6 +154,7 @@
#include <mail_error.h>
#include <bounce_log.h>
#include <mail_date.h>
#include <mail_proto.h>
/* Application-specific. */
@@ -162,7 +165,8 @@
/* bounce_mail_init - initialize */
BOUNCE_INFO *bounce_mail_init(const char *service, const char *queue_name,
const char *queue_id, int flush)
const char *queue_id,
const char *encoding, int flush)
{
BOUNCE_INFO *bounce_info;
int rec_type;
@@ -175,6 +179,16 @@ BOUNCE_INFO *bounce_mail_init(const char *service, const char *queue_name,
bounce_info->service = service;
bounce_info->queue_name = queue_name;
bounce_info->queue_id = queue_id;
if (strcmp(encoding, MAIL_ATTR_ENC_8BIT) == 0) {
bounce_info->mime_encoding = "8bit";
} else if (strcmp(encoding, MAIL_ATTR_ENC_7BIT) == 0) {
bounce_info->mime_encoding = "7bit";
} else {
if (strcmp(encoding, MAIL_ATTR_ENC_NONE) != 0)
msg_warn("%s: unknown encoding: %.200s",
bounce_info->queue_id, encoding);
bounce_info->mime_encoding = 0;
}
bounce_info->flush = flush;
bounce_info->buf = vstring_alloc(100);
bounce_info->arrival_time = 0;
@@ -298,6 +312,9 @@ int bounce_header(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
post_mail_fprintf(bounce, "Content-Type: %s; report-type=%s;",
"multipart/report", "delivery-status");
post_mail_fprintf(bounce, "\tboundary=\"%s\"", bounce_info->mime_boundary);
if (bounce_info->mime_encoding)
post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
bounce_info->mime_encoding);
post_mail_fputs(bounce, "");
post_mail_fputs(bounce, "This is a MIME-encapsulated message.");
@@ -522,6 +539,9 @@ int bounce_original(VSTREAM *bounce, BOUNCE_INFO *bounce_info,
"Undelivered Message Headers" : "Undelivered Message");
post_mail_fprintf(bounce, "Content-Type: %s", headers_only ?
"text/rfc822-headers" : "message/rfc822");
if (bounce_info->mime_encoding)
post_mail_fprintf(bounce, "Content-Transfer-Encoding: %s",
bounce_info->mime_encoding);
post_mail_fputs(bounce, "");
/*

View File

@@ -80,7 +80,8 @@
/* bounce_notify_verp - send a bounce */
int bounce_notify_verp(char *service, char *queue_name,
char *queue_id, char *recipient,
char *queue_id, char *encoding,
char *recipient,
char *verp_delims, int flush)
{
char *myname = "bounce_notify_verp";
@@ -105,7 +106,8 @@ int bounce_notify_verp(char *service, char *queue_name,
/*
* Initialize. Open queue file, bounce log, etc.
*/
bounce_info = bounce_mail_init(service, queue_name, queue_id, flush);
bounce_info = bounce_mail_init(service, queue_name, queue_id,
encoding, flush);
#define NULL_SENDER MAIL_ADDR_EMPTY /* special address */
#define NULL_CLEANUP_FLAGS 0

View File

@@ -26,12 +26,12 @@ extern int bounce_append_service(char *, char *, char *, char *);
/*
* bounce_notify_service.c
*/
extern int bounce_notify_service(char *, char *, char *, char *, int);
extern int bounce_notify_service(char *, char *, char *, char *, char *, int);
/*
* bounce_notify_verp.c
*/
extern int bounce_notify_verp(char *, char *, char *, char *, char *, int);
extern int bounce_notify_verp(char *, char *, char *, char *, char *, char *, int);
/*
* bounce_cleanup.c
@@ -50,6 +50,7 @@ typedef struct {
const char *service; /* bounce or defer */
const char *queue_name; /* incoming, etc. */
const char *queue_id; /* base name */
const char *mime_encoding; /* null or encoding */
const char *mime_boundary; /* for MIME */
int flush; /* 0=defer, other=bounce */
VSTRING *buf; /* scratch pad */
@@ -59,7 +60,7 @@ typedef struct {
BOUNCE_LOG *log_handle; /* open logfile */
} BOUNCE_INFO;
extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, int);
extern BOUNCE_INFO *bounce_mail_init(const char *, const char *, const char *, const char *, int);
extern void bounce_mail_free(BOUNCE_INFO *);
extern int bounce_header(VSTREAM *, BOUNCE_INFO *, const char *);
extern int bounce_boilerplate(VSTREAM *, BOUNCE_INFO *);

View File

@@ -78,6 +78,9 @@ cleanup.o: ../../include/record.h
cleanup.o: ../../include/rec_type.h
cleanup.o: ../../include/mail_server.h
cleanup.o: cleanup.h
cleanup.o: ../../include/nvtable.h
cleanup.o: ../../include/htable.h
cleanup.o: ../../include/mymalloc.h
cleanup.o: ../../include/maps.h
cleanup.o: ../../include/tok822.h
cleanup.o: ../../include/resolve_clnt.h
@@ -100,6 +103,8 @@ cleanup_api.o: ../../include/mail_params.h
cleanup_api.o: ../../include/mail_stream.h
cleanup_api.o: cleanup.h
cleanup_api.o: ../../include/argv.h
cleanup_api.o: ../../include/nvtable.h
cleanup_api.o: ../../include/htable.h
cleanup_api.o: ../../include/maps.h
cleanup_api.o: ../../include/dict.h
cleanup_api.o: ../../include/tok822.h
@@ -113,6 +118,9 @@ cleanup_envelope.o: ../../include/vstring.h
cleanup_envelope.o: ../../include/vbuf.h
cleanup_envelope.o: ../../include/vstream.h
cleanup_envelope.o: ../../include/mymalloc.h
cleanup_envelope.o: ../../include/stringops.h
cleanup_envelope.o: ../../include/nvtable.h
cleanup_envelope.o: ../../include/htable.h
cleanup_envelope.o: ../../include/record.h
cleanup_envelope.o: ../../include/rec_type.h
cleanup_envelope.o: ../../include/cleanup_user.h
@@ -138,11 +146,16 @@ cleanup_extracted.o: ../../include/vbuf.h
cleanup_extracted.o: ../../include/vstream.h
cleanup_extracted.o: ../../include/argv.h
cleanup_extracted.o: ../../include/mymalloc.h
cleanup_extracted.o: ../../include/nvtable.h
cleanup_extracted.o: ../../include/htable.h
cleanup_extracted.o: ../../include/cleanup_user.h
cleanup_extracted.o: ../../include/record.h
cleanup_extracted.o: ../../include/rec_type.h
cleanup_extracted.o: ../../include/mail_params.h
cleanup_extracted.o: ../../include/ext_prop.h
cleanup_extracted.o: ../../include/mail_proto.h
cleanup_extracted.o: ../../include/iostuff.h
cleanup_extracted.o: ../../include/attr.h
cleanup_extracted.o: cleanup.h
cleanup_extracted.o: ../../include/maps.h
cleanup_extracted.o: ../../include/dict.h
@@ -164,6 +177,9 @@ cleanup_init.o: ../../include/vstring.h
cleanup_init.o: ../../include/vbuf.h
cleanup_init.o: ../../include/vstream.h
cleanup_init.o: ../../include/argv.h
cleanup_init.o: ../../include/nvtable.h
cleanup_init.o: ../../include/htable.h
cleanup_init.o: ../../include/mymalloc.h
cleanup_init.o: ../../include/maps.h
cleanup_init.o: ../../include/dict.h
cleanup_init.o: ../../include/tok822.h
@@ -186,6 +202,8 @@ cleanup_map11.o: ../../include/maps.h
cleanup_map11.o: ../../include/quote_822_local.h
cleanup_map11.o: ../../include/quote_flags.h
cleanup_map11.o: cleanup.h
cleanup_map11.o: ../../include/nvtable.h
cleanup_map11.o: ../../include/htable.h
cleanup_map11.o: ../../include/tok822.h
cleanup_map11.o: ../../include/resolve_clnt.h
cleanup_map11.o: ../../include/been_here.h
@@ -207,6 +225,8 @@ cleanup_map1n.o: ../../include/quote_822_local.h
cleanup_map1n.o: ../../include/quote_flags.h
cleanup_map1n.o: ../../include/been_here.h
cleanup_map1n.o: cleanup.h
cleanup_map1n.o: ../../include/nvtable.h
cleanup_map1n.o: ../../include/htable.h
cleanup_map1n.o: ../../include/tok822.h
cleanup_map1n.o: ../../include/resolve_clnt.h
cleanup_map1n.o: ../../include/mail_stream.h
@@ -227,6 +247,7 @@ cleanup_masquerade.o: ../../include/quote_822_local.h
cleanup_masquerade.o: ../../include/quote_flags.h
cleanup_masquerade.o: cleanup.h
cleanup_masquerade.o: ../../include/vstream.h
cleanup_masquerade.o: ../../include/nvtable.h
cleanup_masquerade.o: ../../include/maps.h
cleanup_masquerade.o: ../../include/dict.h
cleanup_masquerade.o: ../../include/been_here.h
@@ -241,6 +262,9 @@ cleanup_message.o: ../../include/vstream.h
cleanup_message.o: ../../include/argv.h
cleanup_message.o: ../../include/split_at.h
cleanup_message.o: ../../include/mymalloc.h
cleanup_message.o: ../../include/stringops.h
cleanup_message.o: ../../include/nvtable.h
cleanup_message.o: ../../include/htable.h
cleanup_message.o: ../../include/record.h
cleanup_message.o: ../../include/rec_type.h
cleanup_message.o: ../../include/cleanup_user.h
@@ -254,6 +278,9 @@ cleanup_message.o: ../../include/mail_date.h
cleanup_message.o: ../../include/mail_addr.h
cleanup_message.o: ../../include/is_header.h
cleanup_message.o: ../../include/ext_prop.h
cleanup_message.o: ../../include/mail_proto.h
cleanup_message.o: ../../include/iostuff.h
cleanup_message.o: ../../include/attr.h
cleanup_message.o: cleanup.h
cleanup_message.o: ../../include/maps.h
cleanup_message.o: ../../include/dict.h
@@ -272,6 +299,9 @@ cleanup_out.o: ../../include/cleanup_user.h
cleanup_out.o: ../../include/mail_params.h
cleanup_out.o: cleanup.h
cleanup_out.o: ../../include/argv.h
cleanup_out.o: ../../include/nvtable.h
cleanup_out.o: ../../include/htable.h
cleanup_out.o: ../../include/mymalloc.h
cleanup_out.o: ../../include/maps.h
cleanup_out.o: ../../include/dict.h
cleanup_out.o: ../../include/tok822.h
@@ -290,6 +320,9 @@ cleanup_out_recipient.o: cleanup.h
cleanup_out_recipient.o: ../../include/vstring.h
cleanup_out_recipient.o: ../../include/vbuf.h
cleanup_out_recipient.o: ../../include/vstream.h
cleanup_out_recipient.o: ../../include/nvtable.h
cleanup_out_recipient.o: ../../include/htable.h
cleanup_out_recipient.o: ../../include/mymalloc.h
cleanup_out_recipient.o: ../../include/maps.h
cleanup_out_recipient.o: ../../include/dict.h
cleanup_out_recipient.o: ../../include/tok822.h
@@ -309,6 +342,9 @@ cleanup_rewrite.o: ../../include/quote_flags.h
cleanup_rewrite.o: cleanup.h
cleanup_rewrite.o: ../../include/vstream.h
cleanup_rewrite.o: ../../include/argv.h
cleanup_rewrite.o: ../../include/nvtable.h
cleanup_rewrite.o: ../../include/htable.h
cleanup_rewrite.o: ../../include/mymalloc.h
cleanup_rewrite.o: ../../include/maps.h
cleanup_rewrite.o: ../../include/dict.h
cleanup_rewrite.o: ../../include/been_here.h
@@ -320,10 +356,12 @@ cleanup_state.o: ../../include/mymalloc.h
cleanup_state.o: ../../include/vstring.h
cleanup_state.o: ../../include/vbuf.h
cleanup_state.o: ../../include/argv.h
cleanup_state.o: ../../include/htable.h
cleanup_state.o: ../../include/been_here.h
cleanup_state.o: ../../include/mail_params.h
cleanup_state.o: cleanup.h
cleanup_state.o: ../../include/vstream.h
cleanup_state.o: ../../include/nvtable.h
cleanup_state.o: ../../include/maps.h
cleanup_state.o: ../../include/dict.h
cleanup_state.o: ../../include/tok822.h

View File

@@ -14,6 +14,7 @@
#include <vstring.h>
#include <vstream.h>
#include <argv.h>
#include <nvtable.h>
/*
* Global library.
@@ -61,6 +62,7 @@ typedef struct CLEANUP_STATE {
int end_seen; /* REC_TYPE_END seen */
int rcpt_count; /* recipient count */
char *reason; /* failure reason */
NVTABLE *attr; /* queue file attribute list */
} CLEANUP_STATE;
/*

View File

@@ -38,11 +38,11 @@
/* These flags control the handling of data errors, and must be set
/* before processing the first message record.
/* .IP CLEANUP_FLAG_BOUNCE
/* The cleanup server is responsible for returning undeliverable
/* The cleanup server is responsible for returning undeliverable
/* mail (too many hops, message too large) to the sender.
/* .IP CLEANUP_FLAG_FILTER
/* Enable header/body filtering. This should be enabled only with mail
/* that enters Postfix, not with locally forwarded mail or with bounce
/* Enable header/body filtering. This should be enabled only with mail
/* that enters Postfix, not with locally forwarded mail or with bounce
/* messages.
/* .IP CLEANUP_FLAG_EXTRACT
/* Extract recipients from message headers when no recipients are
@@ -125,7 +125,7 @@ CLEANUP_STATE *cleanup_open(void)
* that the runtime error handler can clean up in case of problems.
*/
state->handle = mail_stream_file(MAIL_QUEUE_INCOMING,
MAIL_CLASS_PUBLIC, var_queue_service, 0);
MAIL_CLASS_PUBLIC, var_queue_service, 0);
state->dst = state->handle->stream;
cleanup_path = mystrdup(VSTREAM_PATH(state->dst));
state->queue_id = mystrdup(state->handle->id);
@@ -176,6 +176,7 @@ int cleanup_flush(CLEANUP_STATE *state)
{
char *junk;
int status;
char *encoding;
/*
* Ignore recipient extraction alarms if (a) we did (not need to) extract
@@ -235,7 +236,10 @@ int cleanup_flush(CLEANUP_STATE *state)
"%s", state->reason ? state->reason :
cleanup_strerror(state->errs)) == 0
&& bounce_flush(BOUNCE_FLAG_CLEAN, MAIL_QUEUE_INCOMING,
state->queue_id, state->sender) == 0) {
state->queue_id,
(encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) ?
encoding : MAIL_ATTR_ENC_NONE,
state->sender) == 0) {
state->errs = 0;
} else {
if (var_soft_bounce == 0) {

View File

@@ -56,6 +56,8 @@
#include <vstring.h>
#include <vstream.h>
#include <mymalloc.h>
#include <stringops.h>
#include <nvtable.h>
/* Global library. */
@@ -104,6 +106,10 @@ void cleanup_envelope(CLEANUP_STATE *state, int type, char *str, int len)
static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf, int len)
{
char *attr_name;
char *attr_value;
const char *error_text;
if (type == REC_TYPE_MESG) {
if (state->sender == 0 || state->time == 0) {
msg_warn("%s: missing sender or time envelope record",
@@ -196,6 +202,21 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
state->errs |= CLEANUP_STAT_BAD;
return;
}
} else if (type == REC_TYPE_ATTR) {
if (state->attr->used >= var_qattr_count_limit) {
msg_warn("%s: queue file attribute count exceeds safety limit: %d",
state->queue_id, var_qattr_count_limit);
state->errs |= CLEANUP_STAT_BAD;
return;
}
cleanup_out(state, type, buf, len);
if ((error_text = split_nameval(buf, &attr_name, &attr_value)) != 0) {
msg_warn("%s: malformed attribute: %s: %.100s",
state->queue_id, error_text, buf);
state->errs |= CLEANUP_STAT_BAD;
return;
}
nvtable_update(state->attr, attr_name, attr_value);
} else {
cleanup_out(state, type, buf, len);
}

View File

@@ -51,6 +51,7 @@
#include <vstream.h>
#include <argv.h>
#include <mymalloc.h>
#include <nvtable.h>
/* Global library. */
@@ -59,6 +60,7 @@
#include <rec_type.h>
#include <mail_params.h>
#include <ext_prop.h>
#include <mail_proto.h>
/* Application-specific. */
@@ -72,12 +74,23 @@ static void cleanup_extracted_process(CLEANUP_STATE *, int, char *, int);
void cleanup_extracted(CLEANUP_STATE *state, int type, char *buf, int len)
{
const char *encoding;
/*
* Start the extracted segment.
*/
cleanup_out_string(state, REC_TYPE_XTRA, "");
/*
* Older Postfix versions didn't emit encoding information, so this
* record can only be optional. Putting this before the mandatory
* Return-Receipt-To and Errors-To ensures that the queue manager will
* pick up the content encoding before starting deliveries.
*/
if ((encoding = nvtable_find(state->attr, MAIL_ATTR_ENCODING)) != 0)
cleanup_out_format(state, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ENCODING, encoding);
/*
* Always emit Return-Receipt-To and Errors-To records, and always emit
* them ahead of extracted recipients, so that the queue manager does not

View File

@@ -108,12 +108,14 @@ char *var_always_bcc; /* big brother */
int var_extra_rcpt_limit; /* recipient extract limit */
char *var_rcpt_witheld; /* recipients not disclosed */
char *var_masq_classes; /* what to masquerade */
int var_qattr_count_limit; /* named attribute limit */
CONFIG_INT_TABLE cleanup_int_table[] = {
VAR_HOPCOUNT_LIMIT, DEF_HOPCOUNT_LIMIT, &var_hopcount_limit, 1, 0,
VAR_HEADER_LIMIT, DEF_HEADER_LIMIT, &var_header_limit, 1, 0,
VAR_DUP_FILTER_LIMIT, DEF_DUP_FILTER_LIMIT, &var_dup_filter_limit, 0, 0,
VAR_EXTRA_RCPT_LIMIT, DEF_EXTRA_RCPT_LIMIT, &var_extra_rcpt_limit, 0, 0,
VAR_QATTR_COUNT_LIMIT, DEF_QATTR_COUNT_LIMIT, &var_qattr_count_limit, 1, 0,
0,
};

View File

@@ -61,6 +61,8 @@
#include <argv.h>
#include <split_at.h>
#include <mymalloc.h>
#include <stringops.h>
#include <nvtable.h>
/* Global library. */
@@ -75,6 +77,7 @@
#include <mail_addr.h>
#include <is_header.h>
#include <ext_prop.h>
#include <mail_proto.h>
/* Application-specific. */
@@ -263,6 +266,7 @@ static int cleanup_act(CLEANUP_STATE *state, char *context, char *buf,
{
const char *optional_text = value + strcspn(value, " \t");
int command_len = optional_text - value;
const char *origin;
while (*optional_text && ISSPACE(*optional_text))
optional_text++;
@@ -276,8 +280,10 @@ static int cleanup_act(CLEANUP_STATE *state, char *context, char *buf,
state->reason = mystrdup(*optional_text ? optional_text :
cleanup_strerror(CLEANUP_STAT_CONT));
state->errs |= CLEANUP_STAT_CONT;
msg_info("%s: reject: %s %.200s; from=<%s> to=<%s>: %s",
state->queue_id, context, buf, state->sender,
if ((origin = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
origin = MAIL_ATTR_ORG_NONE;
msg_info("%s: reject: %s %.200s from %s; from=<%s> to=<%s>: %s",
state->queue_id, context, buf, origin, state->sender,
state->recip ? state->recip : "unknown",
state->reason);
return (CLEANUP_ACT_KEEP);
@@ -310,6 +316,20 @@ static void cleanup_header(CLEANUP_STATE *state)
{
char *myname = "cleanup_header";
HEADER_OPTS *hdr_opts;
char *hdrval;
struct code_map {
const char *name;
const char *encoding;
};
static struct code_map code_map[] = { /* RFC 2045 */
"7bit", MAIL_ATTR_ENC_7BIT,
"8bit", MAIL_ATTR_ENC_8BIT,
"binary", MAIL_ATTR_ENC_8BIT, /* XXX Violation */
"quoted-printable", MAIL_ATTR_ENC_7BIT,
"base64", MAIL_ATTR_ENC_7BIT,
0,
};
struct code_map *cmp;
if (msg_verbose)
msg_info("%s: '%s'", myname, vstring_str(state->header_buf));
@@ -365,15 +385,28 @@ static void cleanup_header(CLEANUP_STATE *state)
*/
else {
state->headers_seen |= (1 << hdr_opts->type);
hdrval = vstring_str(state->header_buf) + strlen(hdr_opts->name) + 2;
while (ISSPACE(*hdrval))
hdrval++;
trimblanks(hdrval, 0);
if (hdr_opts->type == HDR_MESSAGE_ID)
msg_info("%s: message-id=%s", state->queue_id,
vstring_str(state->header_buf) + strlen(hdr_opts->name) + 2);
msg_info("%s: message-id=%s", state->queue_id, hdrval);
if (hdr_opts->type == HDR_RESENT_MESSAGE_ID)
msg_info("%s: resent-message-id=%s", state->queue_id,
vstring_str(state->header_buf) + strlen(hdr_opts->name) + 2);
msg_info("%s: resent-message-id=%s", state->queue_id, hdrval);
if (hdr_opts->type == HDR_RECEIVED)
if (++state->hop_count >= var_hopcount_limit)
state->errs |= CLEANUP_STAT_HOPS;
if (hdr_opts->type == HDR_CONTENT_TRANSFER_ENCODING) {
if (nvtable_find(state->attr, MAIL_ATTR_ENCODING) == 0) {
for (cmp = code_map; cmp->name != 0; cmp++) {
if (strcasecmp(hdrval, cmp->name) == 0) {
nvtable_update(state->attr, MAIL_ATTR_ENCODING,
cmp->encoding);
break;
}
}
}
}
if (CLEANUP_OUT_OK(state)) {
if (hdr_opts->flags & HDR_OPT_RR)
state->resent = "Resent-";

View File

@@ -38,6 +38,7 @@
#include <mymalloc.h>
#include <vstring.h>
#include <argv.h>
#include <htable.h>
/* Global library. */
@@ -86,6 +87,7 @@ CLEANUP_STATE *cleanup_state_alloc(void)
state->end_seen = 0;
state->rcpt_count = 0;
state->reason = 0;
state->attr = nvtable_create(10);
return (state);
}
@@ -117,5 +119,6 @@ void cleanup_state_free(CLEANUP_STATE *state)
been_here_free(state->dups);
if (state->reason)
myfree(state->reason);
nvtable_free(state->attr);
myfree((char *) state);
}

View File

@@ -6,44 +6,49 @@
/* SYNOPSIS
/* #include <abounce.h>
/*
/* void abounce_flush(flags, queue, id, sender, callback, context)
/* void abounce_flush(flags, queue, id, encoding, sender, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/* void (*callback)(int status, char *context);
/* char *context;
/*
/* void abounce_flush_verp(flags, queue, id, sender, verp, callback, context)
/* void abounce_flush_verp(flags, queue, id, encoding, sender, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/* const char *verp;
/* void (*callback)(int status, char *context);
/* char *context;
/*
/* void adefer_flush(flags, queue, id, sender, callback, context)
/* void adefer_flush(flags, queue, id, encoding, sender, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/* void (*callback)(int status, char *context);
/* char *context;
/*
/* void adefer_flush_verp(flags, queue, id, sender, verp, callback, context)
/* void adefer_flush_verp(flags, queue, id, encoding, sender, verp, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/* const char *verp;
/* void (*callback)(int status, char *context);
/* char *context;
/*
/* void adefer_warn(flags, queue, id, sender, callback, context)
/* void adefer_warn(flags, queue, id, encoding, sender, callback, context)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/* void (*callback)(int status, char *context);
/* char *context;
@@ -86,6 +91,8 @@
/* .IP id
/* The message queue id if the original message file. The bounce log
/* file has the same name as the original message file.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
/* .IP sender
/* The sender envelope address.
/* .IP verp
@@ -182,7 +189,9 @@ static void abounce_event(int unused_event, char *context)
static void abounce_request_verp(const char *class, const char *service,
int command, int flags,
const char *queue, const char *id,
const char *sender, const char *verp,
const char *encoding,
const char *sender,
const char *verp,
ABOUNCE_FN callback,
char *context)
{
@@ -205,6 +214,7 @@ static void abounce_request_verp(const char *class, const char *service,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp,
ATTR_TYPE_END) == 0
@@ -218,23 +228,25 @@ static void abounce_request_verp(const char *class, const char *service,
/* abounce_flush_verp - asynchronous bounce flush */
void abounce_flush_verp(int flags, const char *queue, const char *id,
const char *sender, const char *verp,
ABOUNCE_FN callback, char *context)
const char *encoding, const char *sender,
const char *verp, ABOUNCE_FN callback,
char *context)
{
abounce_request_verp(MAIL_CLASS_PRIVATE, var_bounce_service,
BOUNCE_CMD_VERP, flags, queue, id, sender, verp,
callback, context);
BOUNCE_CMD_VERP, flags, queue, id, encoding,
sender, verp, callback, context);
}
/* adefer_flush_verp - asynchronous defer flush */
void adefer_flush_verp(int flags, const char *queue, const char *id,
const char *sender, const char *verp,
ABOUNCE_FN callback, char *context)
const char *encoding, const char *sender,
const char *verp, ABOUNCE_FN callback,
char *context)
{
abounce_request_verp(MAIL_CLASS_PRIVATE, var_defer_service,
BOUNCE_CMD_VERP, flags, queue, id, sender, verp,
callback, context);
BOUNCE_CMD_VERP, flags, queue, id, encoding,
sender, verp, callback, context);
}
/* abounce_request - suspend pseudo thread until server reply event */
@@ -242,9 +254,8 @@ void adefer_flush_verp(int flags, const char *queue, const char *id,
static void abounce_request(const char *class, const char *service,
int command, int flags,
const char *queue, const char *id,
const char *sender,
ABOUNCE_FN callback,
char *context)
const char *encoding, const char *sender,
ABOUNCE_FN callback, char *context)
{
ABOUNCE *ap;
@@ -265,6 +276,7 @@ static void abounce_request(const char *class, const char *service,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_END) == 0
&& vstream_fflush(ap->fp) == 0) {
@@ -277,26 +289,29 @@ static void abounce_request(const char *class, const char *service,
/* abounce_flush - asynchronous bounce flush */
void abounce_flush(int flags, const char *queue, const char *id,
const char *sender, ABOUNCE_FN callback, char *context)
const char *encoding, const char *sender,
ABOUNCE_FN callback, char *context)
{
abounce_request(MAIL_CLASS_PRIVATE, var_bounce_service, BOUNCE_CMD_FLUSH,
flags, queue, id, sender, callback, context);
flags, queue, id, encoding, sender, callback, context);
}
/* adefer_flush - asynchronous defer flush */
void adefer_flush(int flags, const char *queue, const char *id,
const char *sender, ABOUNCE_FN callback, char *context)
const char *encoding, const char *sender,
ABOUNCE_FN callback, char *context)
{
abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_FLUSH,
flags, queue, id, sender, callback, context);
flags, queue, id, encoding, sender, callback, context);
}
/* adefer_warn - send copy of defer log to sender as warning bounce */
void adefer_warn(int flags, const char *queue, const char *id,
const char *sender, ABOUNCE_FN callback, char *context)
const char *encoding, const char *sender,
ABOUNCE_FN callback, char *context)
{
abounce_request(MAIL_CLASS_PRIVATE, var_defer_service, BOUNCE_CMD_WARN,
flags, queue, id, sender, callback, context);
flags, queue, id, encoding, sender, callback, context);
}

View File

@@ -21,12 +21,12 @@
*/
typedef void (*ABOUNCE_FN) (int, char *);
extern void abounce_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void adefer_flush(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void adefer_warn(int, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void abounce_flush(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void adefer_flush(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void adefer_warn(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void abounce_flush_verp(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void adefer_flush_verp(int, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void abounce_flush_verp(int, const char *, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
extern void adefer_flush_verp(int, const char *, const char *, const char *, const char *, const char *, ABOUNCE_FN, char *);
/* LICENSE
/* .ad

View File

@@ -23,10 +23,11 @@
/* const char *format;
/* va_list ap;
/*
/* int bounce_flush(flags, queue, id, sender)
/* int bounce_flush(flags, queue, id, encoding, sender)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/* DESCRIPTION
/* This module implements the client interface to the message
@@ -56,6 +57,8 @@
/* .IP id
/* The message queue id if the original message file. The bounce log
/* file has the same name as the original message file.
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
/* .IP sender
/* The sender envelope address.
/* .IP relay
@@ -168,7 +171,7 @@ int vbounce_append(int flags, const char *id, const char *recipient,
/* bounce_flush - flush the bounce log and deliver to the sender */
int bounce_flush(int flags, const char *queue, const char *id,
const char *sender)
const char *encoding, const char *sender)
{
/*
@@ -182,6 +185,7 @@ int bounce_flush(int flags, const char *queue, const char *id,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_END) == 0) {
return (0);

View File

@@ -25,7 +25,7 @@ extern int PRINTFLIKE(6, 7) bounce_append(int, const char *, const char *,
const char *,...);
extern int vbounce_append(int, const char *, const char *, const char *,
time_t, const char *, va_list);
extern int bounce_flush(int, const char *, const char *, const char *);
extern int bounce_flush(int, const char *, const char *, const char *, const char *);
extern int PRINTFLIKE(8, 9) bounce_recip(int, const char *, const char *,
const char *, const char *,

View File

@@ -23,10 +23,11 @@
/* const char *format;
/* va_list ap;
/*
/* int defer_flush(flags, queue, id, sender)
/* int defer_flush(flags, queue, id, encoding, sender)
/* int flags;
/* const char *queue;
/* const char *id;
/* const char *encoding;
/* const char *sender;
/*
/* int defer_warn(flags, queue, id, sender)
@@ -70,6 +71,8 @@
/* .IP recipient
/* A recipient address that is being deferred. The domain part
/* of the address is marked dead (for a limited amount of time).
/* .IP encoding
/* The body content encoding: MAIL_ATTR_ENC_{7BIT,8BIT,NONE}.
/* .IP sender
/* The sender envelope address.
/* .IP relay
@@ -178,15 +181,16 @@ int vdefer_append(int flags, const char *id, const char *recipient,
/* defer_flush - flush the defer log and deliver to the sender */
int defer_flush(int flags, const char *queue, const char *id,
const char *sender)
const char *encoding, const char *sender)
{
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_END) == 0) {
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_END) == 0) {
return (0);
} else {
return (-1);
@@ -200,12 +204,12 @@ int defer_warn(int flags, const char *queue, const char *id,
const char *sender)
{
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_WARN,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_END) == 0) {
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_WARN,
ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_END) == 0) {
return (0);
} else {
return (-1);

View File

@@ -29,7 +29,7 @@ extern int PRINTFLIKE(6, 7) defer_append(int, const char *, const char *,
const char *, time_t, const char *,...);
extern int vdefer_append(int, const char *, const char *, const char *,
time_t, const char *, va_list);
extern int defer_flush(int, const char *, const char *, const char *);
extern int defer_flush(int, const char *, const char *, const char *, const char *);
extern int defer_warn(int, const char *, const char *, const char *);

View File

@@ -15,6 +15,7 @@
/* long data_offset;
/* long data_size;
/* char *nexthop;
/* char *encoding;
/* char *sender;
/* char *errors_to;
/* char *return_receipt;
@@ -169,6 +170,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
static VSTRING *queue_name;
static VSTRING *queue_id;
static VSTRING *nexthop;
static VSTRING *encoding;
static VSTRING *address;
static VSTRING *errors_to;
static VSTRING *return_receipt;
@@ -183,6 +185,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
queue_name = vstring_alloc(10);
queue_id = vstring_alloc(10);
nexthop = vstring_alloc(10);
encoding = vstring_alloc(10);
address = vstring_alloc(10);
errors_to = vstring_alloc(10);
return_receipt = vstring_alloc(10);
@@ -199,11 +202,12 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &request->data_offset,
ATTR_TYPE_LONG, MAIL_ATTR_SIZE, &request->data_size,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, address,
ATTR_TYPE_STR, MAIL_ATTR_ERRTO, errors_to,
ATTR_TYPE_STR, MAIL_ATTR_RRCPT, return_receipt,
ATTR_TYPE_LONG, MAIL_ATTR_TIME, &request->arrival_time,
ATTR_TYPE_END) != 10)
ATTR_TYPE_END) != 11)
return (-1);
if (mail_open_ok(vstring_str(queue_name),
vstring_str(queue_id), &st, &path) == 0)
@@ -212,6 +216,7 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
request->queue_name = mystrdup(vstring_str(queue_name));
request->queue_id = mystrdup(vstring_str(queue_id));
request->nexthop = mystrdup(vstring_str(nexthop));
request->encoding = mystrdup(vstring_str(encoding));
request->sender = mystrdup(vstring_str(address));
request->errors_to = mystrdup(vstring_str(errors_to));
request->return_receipt = mystrdup(vstring_str(return_receipt));
@@ -274,6 +279,7 @@ static DELIVER_REQUEST *deliver_request_alloc(void)
request->queue_name = 0;
request->queue_id = 0;
request->nexthop = 0;
request->encoding = 0;
request->sender = 0;
request->errors_to = 0;
request->return_receipt = 0;
@@ -296,6 +302,8 @@ static void deliver_request_free(DELIVER_REQUEST *request)
myfree(request->queue_id);
if (request->nexthop)
myfree(request->nexthop);
if (request->encoding)
myfree(request->encoding);
if (request->sender)
myfree(request->sender);
if (request->errors_to)

View File

@@ -33,6 +33,7 @@ typedef struct DELIVER_REQUEST {
long data_offset; /* offset to message */
long data_size; /* message size */
char *nexthop; /* next hop name */
char *encoding; /* content encoding */
char *sender; /* envelope sender */
char *errors_to; /* error report address */
char *return_receipt; /* confirm receipt address */

View File

@@ -51,6 +51,7 @@ static HEADER_OPTS header_opts[] = {
"Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP,
"Bcc", HDR_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP,
"Cc", HDR_CC, HDR_OPT_XRECIP,
"Content-Transfer-Encoding", HDR_CONTENT_TRANSFER_ENCODING, 0,
"Content-Length", HDR_CONTENT_LENGTH, HDR_OPT_DROP,
"Delivered-To", HDR_DELIVERED_TO, 0,
"Date", HDR_DATE, 0,

View File

@@ -1486,6 +1486,13 @@ extern int var_db_create_buf;
#define DEF_DB_READ_BUF (128 *1024)
extern int var_db_read_buf;
/*
* Named queue file attributes.
*/
#define VAR_QATTR_COUNT_LIMIT "queue_file_attribute_count_limit"
#define DEF_QATTR_COUNT_LIMIT 100
extern int var_qattr_count_limit;
/* LICENSE
/* .ad
/* .fi

View File

@@ -98,6 +98,21 @@ extern char *mail_pathname(const char *, const char *);
#define MAIL_ATTR_TRANSPORT "transport"
#define MAIL_ATTR_NEXTHOP "nexthop"
/*
* The following attribute names are stored in queue files. Changing this
* means lots of work to maintain backwards compatibility with queued mail.
*/
#define MAIL_ATTR_ENCODING "encoding" /* internal encoding */
#define MAIL_ATTR_ENC_8BIT "8bit" /* 8BITMIME equivalent */
#define MAIL_ATTR_ENC_7BIT "7bit" /* 7BIT equivalent */
#define MAIL_ATTR_ENC_NONE "" /* encoding unknown */
#define MAIL_ATTR_CLIENT_NAME "client_name" /* client hostname */
#define MAIL_ATTR_CLIENT_ADDR "client_address" /* client address */
#define MAIL_ATTR_HELO_NAME "helo_name" /* SMTP helo name */
#define MAIL_ATTR_ORIGIN "message_origin" /* hostname[address] */
#define MAIL_ATTR_ORG_NONE "unknown" /* origin unknown */
#define MAIL_ATTR_ORG_LOCAL "local" /* local submission */
/* LICENSE
/* .ad
/* .fi

View File

@@ -20,7 +20,7 @@
* 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 "20020509"
#define MAIL_RELEASE_DATE "20020512"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "1.1.9-" MAIL_RELEASE_DATE

View File

@@ -152,6 +152,8 @@ static void post_mail_init(VSTREAM *stream, const char *sender,
* size record.
*/
rec_fprintf(stream, REC_TYPE_TIME, "%ld", (long) now);
rec_fprintf(stream, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ORIGIN, MAIL_ATTR_ORG_LOCAL);
rec_fputs(stream, REC_TYPE_FROM, sender);
rec_fputs(stream, REC_TYPE_RCPT, recipient);
rec_fputs(stream, REC_TYPE_MESG, "");

View File

@@ -55,10 +55,16 @@
* The types of records that I expect to see while processing different
* record groups. The first member in each set is the record type that
* indicates the end of that record group.
*
* XXX A records in the extracted segment are generated only by the cleanup
* server, and are not supposed to be present in locally submitted mail, as
* this is "postfix internal" information. However, the pickup server has to
* allow for the presence of A records in the extracted segment, because it
* can be requested to re-process already queued mail with `postsuper -r'.
*/
#define REC_TYPE_ENVELOPE "MCTFILSDROWVA"
#define REC_TYPE_CONTENT "XLN"
#define REC_TYPE_EXTRACT "EDROPre" /* NOT A */
#define REC_TYPE_EXTRACT "EDROPreA"
#define REC_TYPE_NOEXTRACT "E"
/*

View File

@@ -163,6 +163,9 @@ lmtp_proto.o: ../../include/off_cvt.h
lmtp_proto.o: ../../include/mark_corrupt.h
lmtp_proto.o: ../../include/quote_821_local.h
lmtp_proto.o: ../../include/quote_flags.h
lmtp_proto.o: ../../include/mail_proto.h
lmtp_proto.o: ../../include/iostuff.h
lmtp_proto.o: ../../include/attr.h
lmtp_proto.o: lmtp.h
lmtp_proto.o: ../../include/argv.h
lmtp_proto.o: lmtp_sasl.h

View File

@@ -46,6 +46,7 @@
/* STANDARDS
/* RFC 821 (SMTP protocol)
/* RFC 1651 (SMTP service extensions)
/* RFC 1652 (8bit-MIME transport)
/* RFC 1870 (Message Size Declaration)
/* RFC 2033 (LMTP protocol)
/* RFC 2197 (Pipelining)

View File

@@ -117,6 +117,7 @@
#include <off_cvt.h>
#include <mark_corrupt.h>
#include <quote_821_local.h>
#include <mail_proto.h>
/* Application-specific. */
@@ -294,12 +295,12 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
* Macros for readability. XXX Aren't LMTP addresses supposed to be case
* insensitive?
*/
#define REWRITE_ADDRESS(addr) do { \
if (*(addr)) { \
quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
myfree(addr); \
addr = mystrdup(vstring_str(state->scratch)); \
lowercase(addr); \
#define REWRITE_ADDRESS(dst, src) do { \
if (*(src)) { \
quote_821_local(dst, src, QUOTE_FLAG_8BITCLEAN); \
lowercase(vstring_str(dst)); \
} else { \
vstring_strcpy(dst, src); \
} \
} while (0)
@@ -357,12 +358,21 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
* Build the MAIL FROM command.
*/
case LMTP_STATE_MAIL:
if (*request->sender)
REWRITE_ADDRESS(request->sender);
vstring_sprintf(next_command, "MAIL FROM:<%s>", request->sender);
if (state->features & LMTP_FEATURE_SIZE)
REWRITE_ADDRESS(state->scratch, request->sender);
vstring_sprintf(next_command, "MAIL FROM:<%s>",
vstring_str(state->scratch));
if (state->features & LMTP_FEATURE_SIZE) /* RFC 1652 */
vstring_sprintf_append(next_command, " SIZE=%lu",
request->data_size);
if (state->features & LMTP_FEATURE_8BITMIME) {
if (strcmp(request->encoding, MAIL_ATTR_ENC_8BIT) == 0)
vstring_strcat(next_command, " BODY=8BITMIME");
else if (strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) == 0)
vstring_strcat(next_command, " BODY=7BIT");
else if (strcmp(request->encoding, MAIL_ATTR_ENC_NONE) != 0)
msg_warn("%s: unknown content encoding: %s",
request->queue_id, request->encoding);
}
next_state = LMTP_STATE_RCPT;
break;
@@ -372,8 +382,9 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
*/
case LMTP_STATE_RCPT:
rcpt = request->rcpt_list.info + send_rcpt;
REWRITE_ADDRESS(rcpt->address);
vstring_sprintf(next_command, "RCPT TO:<%s>", rcpt->address);
REWRITE_ADDRESS(state->scratch, rcpt->address);
vstring_sprintf(next_command, "RCPT TO:<%s>",
vstring_str(state->scratch));
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
next_state = LMTP_STATE_DATA;
break;

View File

@@ -209,6 +209,9 @@ qmgr_message.o: ../../include/maps.h
qmgr_message.o: ../../include/opened.h
qmgr_message.o: ../../include/resolve_local.h
qmgr_message.o: ../../include/verp_sender.h
qmgr_message.o: ../../include/mail_proto.h
qmgr_message.o: ../../include/iostuff.h
qmgr_message.o: ../../include/attr.h
qmgr_message.o: ../../include/resolve_clnt.h
qmgr_message.o: qmgr.h
qmgr_message.o: ../../include/scan_dir.h

View File

@@ -266,6 +266,7 @@ struct QMGR_MESSAGE {
long data_offset; /* data seek offset */
char *queue_name; /* queue name */
char *queue_id; /* queue file */
char *encoding; /* content encoding */
char *sender; /* complete address */
char *verp_delims; /* VERP delimiters */
char *errors_to; /* error report address */

View File

@@ -283,6 +283,7 @@ void qmgr_active_done(QMGR_MESSAGE *message)
abounce_flush(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
qmgr_active_done_2_bounce_flush,
(char *) message);
@@ -290,6 +291,7 @@ void qmgr_active_done(QMGR_MESSAGE *message)
abounce_flush_verp(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
message->verp_delims,
qmgr_active_done_2_bounce_flush,
@@ -370,6 +372,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
adefer_flush(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
qmgr_active_done_3_defer_flush,
(char *) message);
@@ -377,6 +380,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
adefer_flush_verp(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
message->verp_delims,
qmgr_active_done_3_defer_flush,
@@ -389,6 +393,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
adefer_warn(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
qmgr_active_done_3_defer_warn,
(char *) message);

View File

@@ -166,6 +166,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->data_size,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, message->encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_ERRTO, message->errors_to,
ATTR_TYPE_STR, MAIL_ATTR_RRCPT, message->return_receipt,

View File

@@ -122,6 +122,7 @@
#include <opened.h>
#include <resolve_local.h>
#include <verp_sender.h>
#include <mail_proto.h>
/* Client stubs. */
@@ -153,6 +154,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
message->data_offset = 0;
message->queue_id = mystrdup(queue_id);
message->queue_name = mystrdup(queue_name);
message->encoding = 0;
message->sender = 0;
message->errors_to = 0;
message->return_receipt = 0;
@@ -283,6 +285,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
long save_offset = message->rcpt_offset; /* save a flag */
char *start;
int recipient_limit;
const char *error_text;
char *name;
char *value;
/*
* Initialize. No early returns or we have a memory leak.
@@ -404,6 +409,15 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
break;
}
}
} else if (rec_type == REC_TYPE_ATTR) {
if ((error_text = split_nameval(start, &name, &value)) != 0) {
msg_warn("%s: bad attribute: %s: %.200s",
message->queue_id, error_text, start);
break;
}
if (strcmp(name, MAIL_ATTR_ENCODING) == 0)
if (message->encoding == 0)
message->encoding = mystrdup(value);
} else if (rec_type == REC_TYPE_ERTO) {
if (message->errors_to == 0) {
message->errors_to = mystrdup(start);
@@ -447,6 +461,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
message->errors_to = mystrdup("");
if (message->return_receipt == 0)
message->return_receipt = mystrdup("");
if (message->encoding == 0)
message->encoding = mystrdup(MAIL_ATTR_ENC_NONE);
/*
* Clean up.
@@ -926,6 +942,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
qmgr_job_free(job);
myfree(message->queue_id);
myfree(message->queue_name);
if (message->encoding)
myfree(message->encoding);
if (message->sender)
myfree(message->sender);
if (message->verp_delims)

View File

@@ -62,6 +62,7 @@ pickup.o: ../../include/vbuf.h
pickup.o: ../../include/vstream.h
pickup.o: ../../include/set_ugid.h
pickup.o: ../../include/safe_open.h
pickup.o: ../../include/stringops.h
pickup.o: ../../include/mail_queue.h
pickup.o: ../../include/mail_open_ok.h
pickup.o: ../../include/mymalloc.h

View File

@@ -92,6 +92,7 @@
#include <vstream.h>
#include <set_ugid.h>
#include <safe_open.h>
#include <stringops.h>
/* Global library. */
@@ -159,13 +160,21 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
{
int type;
int check_first = (*expected == REC_TYPE_CONTENT[0]);
const char *error_text;
char *attr_name;
char *attr_value;
/*
* Limit the input record size. All front-end programs should protect the
* mail system against unreasonable inputs. This also requires that we
* limit the size of envelope records written by the local posting agent.
*
* As time stamp we use the scrutinized queue file modification time, and
* ignore the time stamp embedded in the queue file.
*
* Allow attribute records if the queue file is owned by the mail system
* (postsuper -r) or if the attribute specifies the MIME body type
* (sendmail -B).
*/
for (;;) {
if ((type = rec_get(qfile, buf, var_line_limit)) < 0
@@ -181,6 +190,28 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
info->rcpt = mystrdup(vstring_str(buf));
if (type == REC_TYPE_TIME)
continue;
if (type == REC_TYPE_ATTR) {
if ((error_text = split_nameval(vstring_str(buf), &attr_name,
&attr_value)) != 0) {
msg_warn("uid=%ld: malformed attribute record: %s: %.200s",
(long) info->st.st_uid, error_text, vstring_str(buf));
continue;
}
#define STREQ(x,y) (strcmp(x,y) == 0)
if (info->st.st_uid == var_owner_uid
|| (STREQ(attr_name, MAIL_ATTR_ENCODING)
&& (STREQ(attr_value, MAIL_ATTR_ENC_7BIT)
|| STREQ(attr_value, MAIL_ATTR_ENC_8BIT)
|| STREQ(attr_value, MAIL_ATTR_ENC_NONE)))) {
rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
attr_name, attr_value);
continue;
}
msg_warn("uid=%ld: ignoring attribute record: %.200s=%.200s",
(long) info->st.st_uid, attr_name, attr_value);
continue;
}
if (type == REC_TYPE_FILT && *expected == REC_TYPE_ENVELOPE[0])
continue;
else {
@@ -239,6 +270,12 @@ static int pickup_copy(VSTREAM *qfile, VSTREAM *cleanup,
if (*var_filter_xport)
rec_fprintf(cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
/*
* Origin is local.
*/
rec_fprintf(cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ORIGIN, MAIL_ATTR_ORG_LOCAL);
/*
* Copy the message envelope segment. Allow only those records that we
* expect to see in the envelope section. The envelope segment must
@@ -322,7 +359,6 @@ static int pickup_file(PICKUP_INFO *info)
int status;
VSTREAM *qfile;
VSTREAM *cleanup;
int fd;
/*
* Open the submitted file. If we cannot open it, and we're not having a
@@ -331,8 +367,8 @@ static int pickup_file(PICKUP_INFO *info)
* Perhaps we should save "bad" files elsewhere for further inspection.
* XXX How can we delete a file when open() fails with ENOENT?
*/
qfile = safe_open(info->path, O_RDONLY | O_NONBLOCK, 0,
(struct stat *) 0, -1, -1, buf);
qfile = safe_open(info->path, O_RDONLY | O_NONBLOCK, 0,
(struct stat *) 0, -1, -1, buf);
if (qfile == 0) {
if (errno != ENOENT)
msg_warn("open input file %s: %s", info->path, vstring_str(buf));

View File

@@ -193,6 +193,9 @@ qmgr_message.o: ../../include/maps.h
qmgr_message.o: ../../include/opened.h
qmgr_message.o: ../../include/resolve_local.h
qmgr_message.o: ../../include/verp_sender.h
qmgr_message.o: ../../include/mail_proto.h
qmgr_message.o: ../../include/iostuff.h
qmgr_message.o: ../../include/attr.h
qmgr_message.o: ../../include/resolve_clnt.h
qmgr_message.o: qmgr.h
qmgr_message.o: ../../include/scan_dir.h

View File

@@ -226,6 +226,7 @@ struct QMGR_MESSAGE {
long data_offset; /* data seek offset */
char *queue_name; /* queue name */
char *queue_id; /* queue file */
char *encoding; /* content encoding */
char *sender; /* complete address */
char *verp_delims; /* VERP delimiters */
char *errors_to; /* error report address */

View File

@@ -283,6 +283,7 @@ void qmgr_active_done(QMGR_MESSAGE *message)
abounce_flush(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
qmgr_active_done_2_bounce_flush,
(char *) message);
@@ -290,6 +291,7 @@ void qmgr_active_done(QMGR_MESSAGE *message)
abounce_flush_verp(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
message->verp_delims,
qmgr_active_done_2_bounce_flush,
@@ -370,6 +372,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
adefer_flush(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
qmgr_active_done_3_defer_flush,
(char *) message);
@@ -377,6 +380,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
adefer_flush_verp(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
message->verp_delims,
qmgr_active_done_3_defer_flush,
@@ -389,6 +393,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message)
adefer_warn(BOUNCE_FLAG_KEEP,
message->queue_name,
message->queue_id,
message->encoding,
message->errors_to,
qmgr_active_done_3_defer_warn,
(char *) message);

View File

@@ -161,6 +161,7 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
ATTR_TYPE_LONG, MAIL_ATTR_SIZE, message->data_size,
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, nexthop,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, message->encoding,
ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
ATTR_TYPE_STR, MAIL_ATTR_ERRTO, message->errors_to,
ATTR_TYPE_STR, MAIL_ATTR_RRCPT, message->return_receipt,

View File

@@ -113,6 +113,7 @@
#include <opened.h>
#include <resolve_local.h>
#include <verp_sender.h>
#include <mail_proto.h>
/* Client stubs. */
@@ -143,6 +144,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
message->data_offset = 0;
message->queue_id = mystrdup(queue_id);
message->queue_name = mystrdup(queue_name);
message->encoding = 0;
message->sender = 0;
message->errors_to = 0;
message->return_receipt = 0;
@@ -203,6 +205,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
char *start;
struct stat st;
int nrcpt = 0;
const char *error_text;
char *name;
char *value;
/*
* Initialize. No early returns or we have a memory leak.
@@ -294,6 +299,15 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
}
if (vstream_fseek(message->fp, extra_offset, SEEK_SET) < 0)
msg_fatal("seek file %s: %m", VSTREAM_PATH(message->fp));
} else if (rec_type == REC_TYPE_ATTR) {
if ((error_text = split_nameval(start, &name, &value)) != 0) {
msg_warn("%s: bad attribute: %s: %.200s",
message->queue_id, error_text, start);
break;
}
if (strcmp(name, MAIL_ATTR_ENCODING) == 0)
if (message->encoding == 0)
message->encoding = mystrdup(value);
} else if (rec_type == REC_TYPE_ERTO) {
if (message->errors_to == 0)
message->errors_to = mystrdup(start);
@@ -336,6 +350,8 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
message->errors_to = mystrdup("");
if (message->return_receipt == 0)
message->return_receipt = mystrdup("");
if (message->encoding == 0)
message->encoding = mystrdup(MAIL_ATTR_ENC_NONE);
/*
* Clean up.
@@ -761,6 +777,8 @@ void qmgr_message_free(QMGR_MESSAGE *message)
msg_panic("qmgr_message_free: queue file is open");
myfree(message->queue_id);
myfree(message->queue_name);
if (message->encoding)
myfree(message->encoding);
if (message->sender)
myfree(message->sender);
if (message->verp_delims)

View File

@@ -245,6 +245,18 @@ static void qmqpd_copy_sender(QMQPD_STATE *state)
state->sender = mystrndup(STR(state->buf), LEN(state->buf));
}
/* qmqpd_write_attributes - save session attributes */
static void qmqpd_write_attributes(QMQPD_STATE *state)
{
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_CLIENT_NAME, state->name);
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_CLIENT_ADDR, state->addr);
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ORIGIN, state->namaddr);
}
/* qmqpd_copy_recipients - copy message recipients */
static void qmqpd_copy_recipients(QMQPD_STATE *state)
@@ -503,6 +515,11 @@ static void qmqpd_receive(QMQPD_STATE *state)
*/
qmqpd_copy_sender(state);
/*
* Record some session attributes.
*/
qmqpd_write_attributes(state);
/*
* Read and write the envelope recipients, including the optional big
* brother recipient.

View File

@@ -49,9 +49,8 @@
/* controlled by parameters in the \fBmain.cf\fR configuration file.
/*
/* The following options are recognized:
/* .IP "\fB-B \fIbody_type\fR (ignored)"
/* The message body MIME type. Currently, Postfix implements
/* \fBjust-send-eight\fR.
/* .IP "\fB-B \fIbody_type\fR"
/* The message body MIME type: \fB7BIT\fR or \fB8BITMIME\fR.
/* .IP "\fB-C \fIconfig_file\fR (ignored :-)"
/* The path name of the \fBsendmail.cf\fR file. Postfix configuration
/* files are kept in \fB/etc/postfix\fR.
@@ -347,8 +346,8 @@ char *verp_delims;
/* enqueue - post one message */
static void enqueue(const int flags, const char *sender, const char *full_name,
char **recipients)
static void enqueue(const int flags, const char *encoding, const char *sender,
const char *full_name, char **recipients)
{
VSTRING *buf;
VSTREAM *dst;
@@ -428,6 +427,8 @@ static void enqueue(const int flags, const char *sender, const char *full_name,
rec_fputs(dst, REC_TYPE_FROM, saved_sender);
if (verp_delims && *saved_sender == 0)
msg_fatal("-V option requires non-null sender address");
if (encoding)
rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_ENCODING, encoding);
if (verp_delims)
rec_fputs(dst, REC_TYPE_VERP, verp_delims);
if (recipients) {
@@ -538,6 +539,7 @@ int main(int argc, char **argv)
int n;
int flags = SM_FLAG_DEFAULT;
char *site_to_flush = 0;
char *encoding = 0;
/*
* Be consistent with file permissions.
@@ -664,6 +666,14 @@ int main(int argc, char **argv)
break;
case 'n':
msg_fatal_status(EX_USAGE, "-%c option not supported", c);
case 'B':
if (strcmp(optarg, "8BITMIME") == 0)/* RFC 1652 */
encoding = MAIL_ATTR_ENC_8BIT;
else if (strcmp(optarg, "7BIT") == 0) /* RFC 1652 */
encoding = MAIL_ATTR_ENC_7BIT;
else
msg_fatal_status(EX_USAGE, "-B option needs 8BITMIME or 7BIT");
break;
case 'F': /* full name */
full_name = optarg;
break;
@@ -779,7 +789,7 @@ int main(int argc, char **argv)
/* NOTREACHED */
case SM_MODE_ENQUEUE:
if (site_to_flush == 0) {
enqueue(flags, sender, full_name, argv + OPTIND);
enqueue(flags, encoding, sender, full_name, argv + OPTIND);
exit(0);
}
if (argv[OPTIND])

View File

@@ -167,6 +167,8 @@ smtp_proto.o: ../../include/off_cvt.h
smtp_proto.o: ../../include/mark_corrupt.h
smtp_proto.o: ../../include/quote_821_local.h
smtp_proto.o: ../../include/quote_flags.h
smtp_proto.o: ../../include/mail_proto.h
smtp_proto.o: ../../include/attr.h
smtp_proto.o: smtp.h
smtp_proto.o: ../../include/argv.h
smtp_proto.o: smtp_sasl.h

View File

@@ -38,6 +38,7 @@
/* STANDARDS
/* RFC 821 (SMTP protocol)
/* RFC 1651 (SMTP service extensions)
/* RFC 1652 (8bit-MIME transport)
/* RFC 1870 (Message Size Declaration)
/* RFC 2197 (Pipelining)
/* RFC 2554 (AUTH command)

View File

@@ -100,6 +100,7 @@
#include <off_cvt.h>
#include <mark_corrupt.h>
#include <quote_821_local.h>
#include <mail_proto.h>
/* Application-specific. */
@@ -303,20 +304,20 @@ int smtp_xfer(SMTP_STATE *state)
/*
* Macros for readability.
*/
#define REWRITE_ADDRESS(addr) do { \
if (*(addr)) { \
quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
smtp_unalias_addr(state->scratch2, vstring_str(state->scratch)); \
myfree(addr); \
addr = mystrdup(vstring_str(state->scratch2)); \
#define REWRITE_ADDRESS(dst, mid, src) do { \
if (*(src)) { \
quote_821_local(mid, src, QUOTE_FLAG_8BITCLEAN); \
smtp_unalias_addr(dst, vstring_str(mid)); \
} else { \
vstring_strcpy(dst, src); \
} \
} while (0)
#define QUOTE_ADDRESS(addr) do { \
if (*(addr)) { \
quote_821_local(state->scratch, addr, QUOTE_FLAG_8BITCLEAN); \
myfree(addr); \
addr = mystrdup(vstring_str(state->scratch)); \
#define QUOTE_ADDRESS(dst, src) do { \
if (*(src)) { \
quote_821_local(dst, src, QUOTE_FLAG_8BITCLEAN); \
} else { \
vstring_strcpy(dst, src); \
} \
} while (0)
@@ -408,14 +409,25 @@ int smtp_xfer(SMTP_STATE *state)
*/
case SMTP_STATE_MAIL:
if (var_disable_dns == 0) {
REWRITE_ADDRESS(request->sender);
REWRITE_ADDRESS(state->scratch, state->scratch2,
request->sender);
} else {
QUOTE_ADDRESS(request->sender);
QUOTE_ADDRESS(state->scratch, request->sender);
}
vstring_sprintf(next_command, "MAIL FROM:<%s>", request->sender);
if (state->features & SMTP_FEATURE_SIZE)
vstring_sprintf(next_command, "MAIL FROM:<%s>",
vstring_str(state->scratch));
if (state->features & SMTP_FEATURE_SIZE) /* RFC 1652 */
vstring_sprintf_append(next_command, " SIZE=%lu",
request->data_size);
if (state->features & SMTP_FEATURE_8BITMIME) {
if (strcmp(request->encoding, MAIL_ATTR_ENC_8BIT) == 0)
vstring_strcat(next_command, " BODY=8BITMIME");
else if (strcmp(request->encoding, MAIL_ATTR_ENC_7BIT) == 0)
vstring_strcat(next_command, " BODY=7BIT");
else if (strcmp(request->encoding, MAIL_ATTR_ENC_NONE) != 0)
msg_warn("%s: unknown content encoding: %s",
request->queue_id, request->encoding);
}
next_state = SMTP_STATE_RCPT;
break;
@@ -426,11 +438,13 @@ int smtp_xfer(SMTP_STATE *state)
case SMTP_STATE_RCPT:
rcpt = request->rcpt_list.info + send_rcpt;
if (var_disable_dns == 0) {
REWRITE_ADDRESS(rcpt->address);
REWRITE_ADDRESS(state->scratch, state->scratch2,
rcpt->address);
} else {
QUOTE_ADDRESS(rcpt->address);
QUOTE_ADDRESS(state->scratch, rcpt->address);
}
vstring_sprintf(next_command, "RCPT TO:<%s>", rcpt->address);
vstring_sprintf(next_command, "RCPT TO:<%s>",
vstring_str(state->scratch));
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
next_state = SMTP_STATE_DATA;
break;

View File

@@ -130,6 +130,8 @@ smtpd.o: ../../include/verp_sender.h
smtpd.o: ../../include/string_list.h
smtpd.o: ../../include/match_list.h
smtpd.o: ../../include/match_ops.h
smtpd.o: ../../include/quote_822_local.h
smtpd.o: ../../include/quote_flags.h
smtpd.o: ../../include/mail_server.h
smtpd.o: smtpd_token.h
smtpd.o: smtpd.h

View File

@@ -655,6 +655,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
int narg;
char *arg;
char *verp_delims = 0;
char *encoding = 0;
state->msg_size = 0;
@@ -695,10 +696,11 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
}
for (narg = 3; narg < argc; narg++) {
arg = argv[narg].strval;
if (strcasecmp(arg, "BODY=8BITMIME") == 0
|| strcasecmp(arg, "BODY=7BIT") == 0) {
/* void */ ;
} else if (strncasecmp(arg, "SIZE=", 5) == 0) {
if (strcasecmp(arg, "BODY=8BITMIME") == 0) { /* RFC 1652 */
encoding = MAIL_ATTR_ENC_8BIT;
} else if (strcasecmp(arg, "BODY=7BIT") == 0) { /* RFC 1652 */
encoding = MAIL_ATTR_ENC_7BIT;
} else if (strncasecmp(arg, "SIZE=", 5) == 0) { /* RFC 1870 */
/* Reject non-numeric size. */
if (!alldig(arg + 5)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
@@ -771,6 +773,18 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
if (*var_filter_xport)
rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval);
if (encoding != 0)
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ENCODING, encoding);
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_CLIENT_NAME, state->name);
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_CLIENT_ADDR, state->addr);
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ORIGIN, state->namaddr);
if (state->helo_name != 0)
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_HELO_NAME, state->helo_name);
if (verp_delims)
rec_fputs(state->cleanup, REC_TYPE_VERP, verp_delims);
state->sender = mystrdup(argv[2].strval);

View File

@@ -26,7 +26,7 @@ SRCS = alldig.c argv.c argv_split.c attr_print0.c attr_print64.c \
unix_connect.c unix_listen.c unix_trigger.c unsafe.c username.c \
valid_hostname.c vbuf.c vbuf_print.c vstream.c vstream_popen.c \
vstring.c vstring_vstream.c watchdog.c writable.c write_buf.c \
write_wait.c strcasecmp.c
write_wait.c strcasecmp.c nvtable.c
OBJS = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
@@ -54,7 +54,7 @@ OBJS = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
unix_connect.o unix_listen.o unix_trigger.o unsafe.o username.o \
valid_hostname.o vbuf.o vbuf_print.o vstream.o vstream_popen.o \
vstring.o vstring_vstream.o watchdog.o writable.o write_buf.o \
write_wait.o $(STRCASE)
write_wait.o nvtable.o $(STRCASE)
HDRS = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
@@ -71,7 +71,8 @@ HDRS = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
scan_dir.h set_eugid.h set_ugid.h sigdelay.h spawn_command.h \
split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \
timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \
vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h
vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h \
nvtable.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -922,6 +923,11 @@ non_blocking.o: non_blocking.c
non_blocking.o: sys_defs.h
non_blocking.o: msg.h
non_blocking.o: iostuff.h
nvtable.o: nvtable.c
nvtable.o: sys_defs.h
nvtable.o: mymalloc.h
nvtable.o: htable.h
nvtable.o: nvtable.h
open_as.o: open_as.c
open_as.o: sys_defs.h
open_as.o: msg.h

View File

@@ -407,7 +407,7 @@ static int dict_eval_action(int type, VSTRING *buf, char *ptr)
char *myname = "dict_eval_action";
const char *pp;
if (msg_verbose)
if (msg_verbose > 1)
msg_info("%s: type %s buf %s context %s \"%s\" %s",
myname, type == MAC_PARSE_VARNAME ? "variable" : "literal",
STR(buf), ctxt->dict_name, STR(ctxt->buf),

122
postfix/src/util/nvtable.c Normal file
View File

@@ -0,0 +1,122 @@
/*++
/* NAME
/* nvtable 3
/* SUMMARY
/* attribute list manager
/* SYNOPSIS
/* #include <nvtable.h>
/*
/* typedef struct {
/* .in +4
/* char *key;
/* char *value;
/* /* private fields... */
/* .in -4
/* } NVTABLE_INFO;
/*
/* NVTABLE *nvtable_create(size)
/* int size;
/*
/* NVTABLE_INFO *nvtable_update(table, key, value)
/* NVTABLE *table;
/* const char *key;
/* const char *value;
/*
/* char *nvtable_find(table, key)
/* NVTABLE *table;
/* const char *key;
/*
/* NVTABLE_INFO *nvtable_locate(table, key)
/* NVTABLE *table;
/* const char *key;
/*
/* void nvtable_delete(table, key)
/* NVTABLE *table;
/* const char *key;
/*
/* void nvtable_free(table)
/* NVTABLE *table;
/*
/* void nvtable_walk(table, action, ptr)
/* NVTABLE *table;
/* void (*action)(NVTABLE_INFO *, char *ptr);
/* char *ptr;
/*
/* NVTABLE_INFO **nvtable_list(table)
/* NVTABLE *table;
/* DESCRIPTION
/* This module maintains one or more attribute lists. It provides a
/* more convenient interface than hash tables, although it uses the
/* same underlying implementation. Each attribute list entry consists
/* of a unique string-valued lookup key and a string value.
/*
/* nvtable_create() creates a table of the specified size and returns a
/* pointer to the result.
/*
/* nvtable_update() stores or updates a (key, value) pair in the specified
/* table and returns a pointer to the resulting entry. The key and the
/* value are copied.
/*
/* nvtable_find() returns the value that was stored under the given key,
/* or a null pointer if it was not found. In order to distinguish
/* a null value from a non-existent value, use nvtable_locate().
/*
/* nvtable_locate() returns a pointer to the entry that was stored
/* for the given key, or a null pointer if it was not found.
/*
/* nvtable_delete() removes one entry that was stored under the given key.
/*
/* nvtable_free() destroys a hash table, including contents.
/*
/* nvtable_walk() invokes the action function for each table entry, with
/* a pointer to the entry as its argument. The ptr argument is passed
/* on to the action function.
/*
/* nvtable_list() returns a null-terminated list of pointers to
/* all elements in the named table. The list should be passed to
/* myfree().
/* RESTRICTIONS
/* A callback function should not modify the attribute list that is
/* specified to its caller.
/* DIAGNOSTICS
/* The following conditions are reported and cause the program to
/* terminate immediately: memory allocation failure; an attempt
/* to delete a non-existent entry.
/* SEE ALSO
/* mymalloc(3) memory management wrapper
/* htable(3) hash table manager
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
/* C library */
#include <sys_defs.h>
/* Utility library. */
#include <mymalloc.h>
#include <htable.h>
#include <nvtable.h>
/* nvtable_update - update or enter (key, value) pair */
NVTABLE_INFO *nvtable_update(NVTABLE * table, const char *key, const char *value)
{
NVTABLE_INFO *ht;
if ((ht = htable_locate(table, key)) != 0) {
myfree(ht->value);
} else {
ht = htable_enter(table, key, (char *) 0);
}
ht->value = mystrdup(value);
return (ht);
}

View File

@@ -0,0 +1,44 @@
#ifndef _NVTABLE_H_INCLUDED_
#define _NVTABLE_H_INCLUDED_
/*++
/* NAME
/* nvtable 3h
/* SUMMARY
/* attribute list manager
/* SYNOPSIS
/* #include <nvtable.h>
/* DESCRIPTION
/* .nf
/*
* Utility library.
*/
#include <htable.h>
#include <mymalloc.h>
typedef struct HTABLE NVTABLE;
typedef struct HTABLE_INFO NVTABLE_INFO;
#define nvtable_create(size) htable_create(size)
#define nvtable_locate(table, key) htable_locate((table), (key))
#define nvtable_walk(table, action, ptr) htable_walk((table), (action), (ptr))
#define nvtable_list(table) htable_list(table)
#define nvtable_find(table, key) htable_find((table), (key))
#define nvtable_delete(table, key) htable_delete((table), (key), myfree)
#define nvtable_free(table) htable_free((table), myfree)
extern NVTABLE_INFO *nvtable_update(NVTABLE *, const char *, const char *);
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*--*/
#endif