20020816
- Cleanup: "postqueue -f" now also trigger delivery of mail
+ Cleanup: "postqueue -f" now also triggers delivery of mail
in the maildrop directory. This is needed when the master
does not frequently wake up the pickup service. Files:
global/mail_flush.c, postqueue/postqueue.c.
queue, and so that the bouncer would not find the queue
file.
+ Bugfix: the #ifdef that detects too old LDAP libraries was
+ in the wrong place. Victor Duchovni. File: util/dict_ldap.c.
+
Feature: new header/body_checks DISCARD pattern that causes
mail to be silently discarded. Files: global/cleanup_user.h,
- cleanup/cleanup_message.c.
+ cleanup/cleanup_message.c, cleanup/cleanup_api.c.
Bugfix: the local delivery agent's mailbox duplicate delivery
- eliminator was not updated when address extensions were
- added to Postfix. The other local duplicate eliminators
- may need revision as well. File: local/mailbox.c.
+ eliminator was not updated in the days that address extensions
+ were added to Postfix. The other local duplicate eliminators
+ probably need revision as well. File: local/mailbox.c.
20020821
Feature: HOLD and DISCARD actions in SMTPD access tables.
- These requests are propagated to the cleanup daemon,
- which required a bit of redesign of internal protocols.
- Files: cleanup/cleanup.c pickup/pickup.c smtpd/smtpd.c
- global/post_mail.c qmqpd/qmqpd.c local/forward.c.
+ These requests are propagated to the cleanup daemon.
+ Files: cleanup/cleanup_envelope.c smtpd/smtpd_check.c.
+
+ Cleanup: eliminate unnecessary references to the obsolete
+ program_directory configuration parameter (but keep the
+ parameter so as to not break existing installations).
+ Matthias Andree, many little changes in documentation.
+
+20020822
+
+ Bit Rot: OpenLDAP incompatible change with URL parsing.
+ Patches by Will Day, Georgia Tech, and Carsten Hoeger,
+ SUSE. File: util/dict_ldap.c.
Open problems:
+ Low: smtpd should log queue ID with reject/warn/hold/discard
+ actions.
+
Medium: should permit_mx_backup defer delivery if DNS has
some error of some kind?
+ Low: revise other local delivery agent duplicate filters.
+
Low: all table lookups should consistently use internalized
(unquoted) or externalized (quoted) forms as lookup keys.
smtpd, qmgr, local, etc. use unquoted address forms as
date. Snapshots change only the release date, unless they include
the same bugfixes as a patch release.
-Incompatible changes with Postfix snapshot 1.1.11-20020821
-==========================================================
-
-After switching Postfix versions you need to "postfix reload"
-because internal protocols have changed.
-
-Incompatible changes with Postfix snapshot 1.1.11-20020818
+Incompatible changes with Postfix snapshot 1.1.11-20020819
==========================================================
The qmgr_site_hog_factor feature is gone (this would defer mail
#
# OK Accept the address etc. that matches the pattern.
#
+# all-numerical
+# An all-numerical result is treated as OK. This for-
+# mat is generated by address-based relay authoriza-
+# tion schemes.
+#
# HOLD Place the message on the hold queue, where it will
# sit until someone either deletes it or releases it
# for delivery. Mail that is placed on hold can be
# Claim successful delivery and silently discard the
# message.
#
-# all-numerical
-# An all-numerical result is treated as OK. This for-
-# mat is generated by address-based relay authoriza-
-# tion schemes.
-#
# restriction...
# Apply the named UCE restriction(s) (permit, reject,
# reject_unauth_destination, and so on).
<b>OK</b> Accept the address etc. that matches the pattern.
+ <i>all-numerical</i>
+ An all-numerical result is treated as OK. This for-
+ mat is generated by address-based relay authoriza-
+ tion schemes.
+
<b>HOLD</b> Place the message on the <b>hold</b> queue, where it will
sit until someone either deletes it or releases it
for delivery. Mail that is placed on hold can be
Claim successful delivery and silently discard the
message.
- <i>all-numerical</i>
- An all-numerical result is treated as OK. This for-
- mat is generated by address-based relay authoriza-
- tion schemes.
-
<i>restriction...</i>
Apply the named UCE restriction(s) (<b>permit</b>, <b>reject</b>,
<b>reject</b><i>_</i><b>unauth</b><i>_</i><b>destination</b>, and so on).
processes.
<b>command</b><i>_</i><b>directory</b>
- Directory with Postfix support commands (default:
- <b>$program</b><i>_</i><b>directory</b>).
+ Directory with Postfix support commands.
<b>daemon</b><i>_</i><b>directory</b>
- Directory with Postfix daemon programs (default:
- <b>$program</b><i>_</i><b>directory</b>).
+ Directory with Postfix daemon programs.
<b>queue</b><i>_</i><b>directory</b>
Top-level directory of the Postfix queue. This is
the system.
<b>command</b><i>_</i><b>directory</b>
- Location of Postfix support commands (default:
- <b>$program</b><i>_</i><b>directory</b>).
+ Location of Postfix support commands.
<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 default VERP delimiter characters that are used
- when the XVERP command is specified without
+ when the XVERP command is specified without
explicit delimiters.
<b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
- Recipient of protocol/policy/resource/software
+ Recipient of protocol/policy/resource/software
error notices.
<b>hopcount</b><i>_</i><b>limit</b>
Limit the number of <b>Received:</b> message headers.
<b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b>
- List of maps with user names that are local to
+ List of maps with user names that are local to
<b>$myorigin</b> or <b>$inet</b><i>_</i><b>interfaces</b>. If this parameter is
- defined, then the SMTP server rejects mail for
+ defined, then the SMTP server rejects mail for
unknown local users.
<b>notify</b><i>_</i><b>classes</b>
List of error classes. Of special interest are:
- <b>policy</b> When a client violates any policy, mail a
+ <b>policy</b> When a client violates any policy, mail a
transcript of the entire SMTP session to the
postmaster.
<b>protocol</b>
- When a client violates the SMTP protocol or
+ When a client violates the SMTP protocol or
issues an unimplemented command, mail a
transcript of the entire SMTP session to the
postmaster.
<b>smtpd</b><i>_</i><b>banner</b>
- Text that follows the <b>220</b> status code in the SMTP
+ Text that follows the <b>220</b> status code in the SMTP
greeting banner.
<b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
- Restrict the number of recipients that the SMTP
+ Restrict the number of recipients that the SMTP
server accepts per message delivery.
<b>smtpd</b><i>_</i><b>timeout</b>
- Limit the time to send a server response and to
+ Limit the time to send a server response and to
receive a client request.
<b>soft</b><i>_</i><b>bounce</b>
- Change hard (5xx) reject responses into soft (4xx)
- reject responses. This can be useful for testing
+ Change hard (5xx) reject responses into soft (4xx)
+ reject responses. This can be useful for testing
purposes.
<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>Resource</b> <b>controls</b>
<b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
- Limit the amount of memory in bytes used for the
+ Limit the amount of memory in bytes used for the
handling of partial input lines.
<b>message</b><i>_</i><b>size</b><i>_</i><b>limit</b>
ing on-disk storage for envelope information.
<b>queue</b><i>_</i><b>minfree</b>
- Minimal amount of free space in bytes in the queue
- file system for the SMTP server to accept any mail
+ Minimal amount of free space in bytes in the queue
+ file system for the SMTP server to accept any mail
at all.
<b>smtpd</b><i>_</i><b>history</b><i>_</i><b>flush</b><i>_</i><b>threshold</b>
<b>smtpd</b><i>_</i><b>soft</b><i>_</i><b>error</b><i>_</i><b>limit</b>
When an SMTP client has made this number of errors,
- wait <i>error_count</i> seconds before responding to any
+ wait <i>error_count</i> seconds before responding to any
client request.
<b>smtpd</b><i>_</i><b>hard</b><i>_</i><b>error</b><i>_</i><b>limit</b>
- Disconnect after a client has made this number of
+ Disconnect after a client has made this number of
errors.
<b>smtpd</b><i>_</i><b>junk</b><i>_</i><b>command</b><i>_</i><b>limit</b>
Limit the number of times a client can issue a junk
- command such as NOOP, VRFY, ETRN or RSET in one
- SMTP session before it is penalized with tarpit
+ command such as NOOP, VRFY, ETRN or RSET in one
+ SMTP session before it is penalized with tarpit
delays.
<b>UCE</b> <b>control</b> <b>restrictions</b>
<b>parent</b><i>_</i><b>domain</b><i>_</i><b>matches</b><i>_</i><b>subdomains</b>
- List of Postfix features that use <i>domain.tld</i> pat-
- terns to match <i>sub.domain.tld</i> (as opposed to
+ List of Postfix features that use <i>domain.tld</i> pat-
+ terns to match <i>sub.domain.tld</i> (as opposed to
requiring <i>.domain.tld</i> patterns).
<b>smtpd</b><i>_</i><b>client</b><i>_</i><b>restrictions</b>
tem.
<b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>required</b>
- Require that clients introduce themselves at the
+ Require that clients introduce themselves at the
beginning of an SMTP session.
<b>smtpd</b><i>_</i><b>helo</b><i>_</i><b>restrictions</b>
- Restrict what client hostnames are allowed in <b>HELO</b>
+ Restrict what client hostnames are allowed in <b>HELO</b>
and <b>EHLO</b> commands.
<b>smtpd</b><i>_</i><b>sender</b><i>_</i><b>restrictions</b>
- Restrict what sender addresses are allowed in <b>MAIL</b>
+ Restrict what sender addresses are allowed in <b>MAIL</b>
<b>FROM</b> commands.
<b>smtpd</b><i>_</i><b>recipient</b><i>_</i><b>restrictions</b>
- Restrict what recipient addresses are allowed in
+ Restrict what recipient addresses are allowed in
<b>RCPT</b> <b>TO</b> commands.
<b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
mands, and what clients may issue <b>ETRN</b> commands.
<b>allow</b><i>_</i><b>untrusted</b><i>_</i><b>routing</b>
- Allow untrusted clients to specify addresses with
- sender-specified routing. Enabling this opens up
- nasty relay loopholes involving trusted backup MX
+ Allow untrusted clients to specify addresses with
+ sender-specified routing. Enabling this opens up
+ nasty relay loopholes involving trusted backup MX
hosts.
<b>smtpd</b><i>_</i><b>restriction</b><i>_</i><b>classes</b>
- Declares the name of zero or more parameters that
- contain a list of UCE restrictions. The names of
- these parameters can then be used instead of the
+ Declares the name of zero or more parameters that
+ contain a list of UCE restrictions. The names of
+ these parameters can then be used instead of the
restriction lists that they represent.
<b>smtpd</b><i>_</i><b>null</b><i>_</i><b>access</b><i>_</i><b>lookup</b><i>_</i><b>key</b>
- The lookup key to be used in SMTPD access tables
- instead of the null sender address. A null sender
+ The lookup key to be used in SMTPD access tables
+ instead of the null sender address. A null sender
address cannot be looked up.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b>
- List of DNS domains that publish the addresses of
+ List of DNS domains that publish the addresses of
blacklisted hosts.
<b>permit</b><i>_</i><b>mx</b><i>_</i><b>backup</b><i>_</i><b>networks</b>
- Only domains whose primary MX hosts match the
- listed networks are eligible for the <b>per-</b>
+ Only domains whose primary MX hosts match the
+ listed networks are eligible for the <b>per-</b>
<b>mit</b><i>_</i><b>mx</b><i>_</i><b>backup</b> feature.
<b>relay</b><i>_</i><b>domains</b>
- Restrict what domains or networks this mail system
+ Restrict what domains or networks this mail system
will relay mail from or to.
<b>UCE</b> <b>control</b> <b>responses</b>
<b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates an access
+ Server response when a client violates an access
database restriction.
<b>defer</b><i>_</i><b>code</b>
- Server response when a client request is rejected
+ Server response when a client request is rejected
by the <b>defer</b> restriction.
<b>invalid</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>invalid</b><i>_</i><b>hostname</b> restriction.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b> restriction.
<b>reject</b><i>_</i><b>code</b>
- Response code when the client matches a <b>reject</b>
+ Response code when the client matches a <b>reject</b>
restriction.
<b>relay</b><i>_</i><b>domains</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client attempts to violate
+ Server response when a client attempts to violate
the mail relay policy.
<b>unknown</b><i>_</i><b>address</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
<b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client without address to
- name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
+ Server response when a client without address to
+ name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
restriction.
<b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
<b>SEE</b> <b>ALSO</b>
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>
.IP \fBmail_owner\fR
The owner of the mail queue and of most Postfix processes.
.IP \fBcommand_directory\fR
-Directory with Postfix support commands (default:
-\fB$program_directory\fR).
+Directory with Postfix support commands.
.IP \fBdaemon_directory\fR
-Directory with Postfix daemon programs (default:
-\fB$program_directory\fR).
+Directory with Postfix daemon programs.
.IP \fBqueue_directory\fR
Top-level directory of the Postfix queue. This is also the root
directory of Postfix daemons that run chrooted.
error response message is generated.
.IP \fBOK\fR
Accept the address etc. that matches the pattern.
+.IP \fIall-numerical\fR
+An all-numerical result is treated as OK. This format is
+generated by address-based relay authorization schemes.
.IP \fBHOLD\fR
Place the message on the \fBhold\fR queue, where it will sit
until someone either deletes it or releases it for delivery.
the \fBpostsuper\fR(1) command.
.IP \fBDISCARD\fR
Claim successful delivery and silently discard the message.
-.IP \fIall-numerical\fR
-An all-numerical result is treated as OK. This format is
-generated by address-based relay authorization schemes.
.IP \fIrestriction...\fR
Apply the named UCE restriction(s) (\fBpermit\fR, \fBreject\fR,
\fBreject_unauth_destination\fR, and so on).
.IP \fBalways_bcc\fR
Address to send a copy of each message that enters the system.
.IP \fBcommand_directory\fR
-Location of Postfix support commands (default:
-\fB$program_directory\fR).
+Location of Postfix support commands.
.IP \fBdebug_peer_level\fR
Increment in verbose logging level when a remote host matches a
pattern in the \fBdebug_peer_list\fR parameter.
* Read the and validate the client request.
*/
if (mail_command_server(client,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, &flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient,
ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
* Read and validate the client request.
*/
if (mail_command_server(client,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, &flags,
+ 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,
* Read and validate the client request.
*/
if (mail_command_server(client,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, &flags,
+ 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,
* Read and validate the client request.
*/
if (mail_command_server(client,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, &unused_flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &unused_flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
state = cleanup_open();
/*
- * Send the queue id to the client.
+ * Send the queue id to the client. Read client processing options. If we
+ * can't read the client processing options we can pretty much forget
+ * about the whole operation.
*/
attr_print(src, ATTR_FLAG_NONE,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, state->queue_id,
ATTR_TYPE_END);
+ if (attr_scan(src, ATTR_FLAG_STRICT,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
+ ATTR_TYPE_END) != 1) {
+ state->errs |= CLEANUP_STAT_BAD;
+ flags = 0;
+ }
+ cleanup_control(state, flags);
/*
* XXX Rely on the front-end programs to enforce record size limits.
/* queue_id result structure member.
/*
/* cleanup_control() processes per-message flags specified by the caller.
-/* These flags control the storage of mail and the handling of errors.
-/* It is an error to any change error handling flags in the middle of
-/* a message.
+/* 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
/* mail (too many hops, message too large) to the sender.
* definition.
*/
if ((state->flags = flags) & CLEANUP_FLAG_BOUNCE) {
- if (state->err_mask && state->err_mask != CLEANUP_STAT_MASK_INCOMPLETE)
- msg_fatal("can't set CLEANUP_FLAG_BOUNCE after initializations");
state->err_mask = CLEANUP_STAT_MASK_INCOMPLETE;
} else {
state->err_mask = ~CLEANUP_STAT_MASK_EXTRACT_RCPT;
if (REMOVE(cleanup_path))
msg_warn("remove %s: %m", cleanup_path);
}
+
/*
* Make sure that our queue file will not be deleted by the error handler
* AFTER we have taken responsibility for delivery. Better to deliver
char *attr_name;
char *attr_value;
const char *error_text;
+ int extra_flags;
if (type == REC_TYPE_MESG) {
if (state->sender == 0 || state->time == 0) {
}
return;
}
+ if (type == REC_TYPE_FLGS) {
+ extra_flags = atol(buf);
+ if (extra_flags & ~CLEANUP_FLAG_MASK_EXTRA)
+ msg_warn("%s: bad extra flags: 0x%x", state->queue_id, extra_flags);
+ else
+ state->flags |= extra_flags;
+ return;
+ }
if (strchr(REC_TYPE_ENVELOPE, type) == 0) {
msg_warn("%s: unexpected record type %d in envelope",
state->queue_id, type);
return;
}
nvtable_update(state->attr, attr_name, attr_value);
- } else if (type == REC_TYPE_FLGS) {
-
- /*
- * For safety's sake, allow setting flags only. Even this sucks when
- * people set the CLEANUP_FLAG_BOUNCE flag too late in the game.
- */
- cleanup_control(state, state->flags | atol(buf));
} else {
cleanup_out(state, type, buf, len);
}
state->reason = mystrdup(*optional_text ? optional_text :
cleanup_strerror(CLEANUP_STAT_CONT));
state->errs |= CLEANUP_STAT_CONT;
+ state->flags &= ~CLEANUP_FLAG_FILTER;
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",
*optional_text ? ": " : "",
*optional_text ? optional_text : "");
state->flags |= CLEANUP_FLAG_DISCARD;
+ state->flags &= ~CLEANUP_FLAG_FILTER;
return (CLEANUP_ACT_KEEP);
}
if (STREQUAL(value, "HOLD", command_len)) {
if (attr_print(ap->fp, ATTR_FLAG_NONE,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, command,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ 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,
if (attr_print(ap->fp, ATTR_FLAG_NONE,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, command,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ 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,
if (mail_command_client(MAIL_CLASS_PRIVATE, var_soft_bounce ?
var_defer_service : var_bounce_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient,
ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(why),
return (-1);
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ 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,
vstring_vsprintf(why, fmt, ap);
if (mail_command_client(MAIL_CLASS_PRIVATE, var_bounce_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_ONE,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ 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,
#define CLEANUP_FLAG_BOUNCE (1<<0) /* Bounce bad messages */
#define CLEANUP_FLAG_FILTER (1<<1) /* Enable content filter */
#define CLEANUP_FLAG_HOLD (1<<2) /* Place message on hold */
-#define CLEANUP_FLAG_DISCARD (1<<3) /* Discard message */
+#define CLEANUP_FLAG_DISCARD (1<<3) /* Discard message silently */
+
+ /*
+ * These are set on the fly while processing SMTP envelopes or message
+ * content.
+ */
+#define CLEANUP_FLAG_MASK_EXTRA \
+ (CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD)
/*
* Diagnostics.
vstring_vsprintf(why, fmt, ap);
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_APPEND,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient,
ATTR_TYPE_STR, MAIL_ATTR_WHY, vstring_str(why),
{
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_FLUSH,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ 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,
{
if (mail_command_client(MAIL_CLASS_PRIVATE, var_defer_service,
ATTR_TYPE_NUM, MAIL_ATTR_NREQ, BOUNCE_CMD_WARN,
- ATTR_TYPE_NUM, MAIL_ATTR_BFLAGS, flags,
+ 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,
int stat;
attr_print(stream, ATTR_FLAG_NONE,
- ATTR_TYPE_NUM, MAIL_ATTR_DFLAGS, request->flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, request->flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, request->queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, request->queue_id,
ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, request->data_offset,
* the conversation when they send bad information.
*/
if (attr_scan(stream, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
- ATTR_TYPE_NUM, MAIL_ATTR_DFLAGS, &request->flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &request->flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &request->data_offset,
#define MAIL_ATTR_NREQ "nrequest"
#define MAIL_ATTR_STATUS "status"
-#define MAIL_ATTR_BFLAGS "bounce_flags"
-#define MAIL_ATTR_DFLAGS "delivery_flags"
-#define MAIL_ATTR_RFLAGS "resolve_flags"
+#define MAIL_ATTR_FLAGS "flags"
#define MAIL_ATTR_QUEUE "queue_name"
#define MAIL_ATTR_QUEUEID "queue_id"
#define MAIL_ATTR_SENDER "sender"
* 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 "20020821"
+#define MAIL_RELEASE_DATE "20020822"
#define VAR_MAIL_VERSION "mail_version"
#define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE
*/
if (attr_scan(stream, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, id,
- ATTR_TYPE_END) != 1)
+ ATTR_TYPE_END) != 1
+ || attr_print(stream, ATTR_FLAG_NONE,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
+ ATTR_TYPE_END) != 0)
msg_fatal("unable to contact the %s service", var_cleanup_service);
/*
* Generate a minimal envelope section. The cleanup service will add a
* size record.
*/
- rec_fprintf(stream, REC_TYPE_FLGS, "%d", flags);
rec_fprintf(stream, REC_TYPE_TIME, "%ld", (long) now);
rec_fprintf(stream, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ORIGIN, MAIL_ATTR_ORG_LOCAL);
#define REC_TYPE_ORCP 'O' /* original recipient, optional */
#define REC_TYPE_WARN 'W' /* warning message time */
#define REC_TYPE_ATTR 'A' /* named attribute for extensions */
-#define REC_TYPE_FLGS 'f' /* set processing flags */
+
+#define REC_TYPE_FLGS 'f' /* cleanup processing flags */
#define REC_TYPE_MESG 'M' /* start message records */
* 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 "MCTFILSDROWVAf"
+#define REC_TYPE_ENVELOPE "MCTFILSDROWVA"
#define REC_TYPE_CONTENT "XLN"
#define REC_TYPE_EXTRACT "EDROPreAFI"
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, reply->nexthop,
ATTR_TYPE_STR, MAIL_ATTR_RECIP, reply->recipient,
- ATTR_TYPE_NUM, MAIL_ATTR_RFLAGS, &reply->flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &reply->flags,
ATTR_TYPE_END) != 4) {
if (msg_verbose || (errno != EPIPE && errno != ENOENT))
msg_warn("%s: bad read: %m", myname);
info->cleanup = cleanup;
info->queue_id = mystrdup(vstring_str(buffer));
info->posting_time = time((time_t *) 0);
+ attr_print(cleanup, ATTR_FLAG_NONE,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, CLEANUP_FLAG_BOUNCE,
+ ATTR_TYPE_END);
/*
* Send initial message envelope information. For bounces, set the
* designated sender: mailing list owner, posting user, whatever.
*/
- rec_fprintf(cleanup, REC_TYPE_FLGS, "%d", CLEANUP_FLAG_BOUNCE);
rec_fprintf(cleanup, REC_TYPE_TIME, "%ld", (long) info->posting_time);
rec_fputs(cleanup, REC_TYPE_FROM, sender);
/* Global library. */
#include <mail_params.h>
+#include <mail_version.h>
#include <debug_process.h>
#include <mail_task.h>
#include <mail_conf.h>
master_config();
master_sigsetup();
master_flow_init();
- msg_info("daemon started");
+ msg_info("daemon started -- version %s", var_mail_version);
/*
* Process events. The event handler will execute the read/write/timer
nexthop = (cp = strrchr(entry->queue->name, '@')) != 0 && cp[1] ?
cp + 1 : entry->queue->name;
attr_print(stream, ATTR_FLAG_MORE,
- ATTR_TYPE_NUM, MAIL_ATTR_DFLAGS, flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, message->queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, message->queue_id,
ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
else if (queue->peers.next != queue->peers.prev)
msg_warn("you may need a separate master.cf transport for %s",
queue->name);
- else if (transport->dest_concurrency_limit / 2 > queue->busy_refcount)
+ else {
+ msg_warn("you may need to reduce %s connect and helo timeouts",
+ transport->name);
+ msg_warn("so that Postfix quickly skips unavailable hosts");
+ msg_warn("you may need to increase the main.cf %s and %s",
+ VAR_MIN_BACKOFF_TIME, VAR_MAX_BACKOFF_TIME);
+ msg_warn("so that Postfix wastes less time on undeliverable mail");
msg_warn("you may need to increase the master.cf %s process limit",
transport->name);
+ }
+ msg_warn("please avoid flushing the whole queue when you have");
+ msg_warn("lots of deferred mail, that is bad for performance");
msg_warn("to turn off these warnings specify: %s = 0",
VAR_QMGR_CLOG_WARN_TIME);
queue->clog_time_to_warn = now + var_qmgr_clog_warn_time;
info->rcpt = mystrdup(vstring_str(buf));
if (type == REC_TYPE_TIME)
continue;
- if (type == REC_TYPE_FLGS)
- continue;
if (type == REC_TYPE_ATTR) {
if ((error_text = split_nameval(vstring_str(buf), &attr_name,
&attr_value)) != 0) {
info->id, (int) (now - info->st.st_mtime) / DAY_SECONDS);
}
- /*
- * Send our processing options. In case of trouble, request that the
- * cleanup service bounces its copy of the message. because the original
- * input file is not readable by the bounce service.
- */
-#define PICKUP_CLEANUP_FLAGS (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_FILTER)
-
- rec_fprintf(cleanup, REC_TYPE_FLGS, "%d", PICKUP_CLEANUP_FLAGS);
-
/*
* Make sure the message has a posting-time record.
*/
/*
* Contact the cleanup service and read the queue ID that it has
- * allocated.
+ * allocated. In case of trouble, request that the cleanup service
+ * bounces its copy of the message. because the original input file is
+ * not readable by the bounce service.
*
* The actual message copying code is in a separate routine, so that it is
* easier to implement the many possible error exits without forgetting
* to close files, or to release memory.
*/
+#define PICKUP_CLEANUP_FLAGS (CLEANUP_FLAG_BOUNCE | CLEANUP_FLAG_FILTER)
cleanup = mail_connect_wait(MAIL_CLASS_PUBLIC, var_cleanup_service);
if (attr_scan(cleanup, ATTR_FLAG_STRICT,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, buf,
- ATTR_TYPE_END) != 1) {
+ ATTR_TYPE_END) != 1
+ || attr_print(cleanup, ATTR_FLAG_NONE,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, PICKUP_CLEANUP_FLAGS,
+ ATTR_TYPE_END) != 0) {
status = KEEP_MESSAGE_FILE;
} else {
info->id = mystrdup(vstring_str(buf));
*
* If something goes wrong, slurp up the input before responding to the
* client, otherwise the client will give up after detecting SIGPIPE.
- *
- * XXX Need to add REC_TYPE_ATTR filtering code before we can talk directly
- * to the cleanup daemon.
*/
vstream_control(VSTREAM_IN, VSTREAM_CTL_PATH, "stdin", VSTREAM_CTL_END);
buf = vstring_alloc(100);
}
if (rec_type == REC_TYPE_ERROR)
msg_fatal("uid=%ld: malformed input", (long) uid);
+ if (rec_type == REC_TYPE_TIME)
+ rec_fprintf(dst->stream, REC_TYPE_TIME, "%ld",
+ (long) time((time_t *) 0));
if (strchr(*expected, rec_type) == 0)
msg_fatal("uid=%ld: unexpected record type: %d", (long) uid, rec_type);
if (rec_type == **expected)
expected++;
- if (rec_type == REC_TYPE_TIME) {
- rec_fprintf(dst->stream, REC_TYPE_TIME, "%ld",
- (long) time((time_t *) 0));
- continue;
- }
- if (rec_type == REC_TYPE_FLGS)
- continue;
if (REC_PUT_BUF(dst->stream, rec_type, buf) < 0) {
while ((rec_type = rec_get(VSTREAM_IN, buf, var_line_limit)) > 0
&& rec_type != REC_TYPE_END)
nexthop = (cp = strrchr(entry->queue->name, '@')) != 0 && cp[1] ?
cp + 1 : entry->queue->name;
attr_print(stream, ATTR_FLAG_MORE,
- ATTR_TYPE_NUM, MAIL_ATTR_DFLAGS, flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_STR, MAIL_ATTR_QUEUE, message->queue_name,
ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, message->queue_id,
ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, message->data_offset,
else if (queue->peers.next != queue->peers.prev)
msg_warn("you may need a separate master.cf transport for %s",
queue->name);
- else if (transport->dest_concurrency_limit / 2 > queue->busy_refcount)
+ else {
+ msg_warn("you may need to reduce %s connect and helo timeouts",
+ transport->name);
+ msg_warn("so that Postfix quickly skips unavailable hosts");
+ msg_warn("you may need to increase the main.cf %s and %s",
+ VAR_MIN_BACKOFF_TIME, VAR_MAX_BACKOFF_TIME);
+ msg_warn("so that Postfix wastes less time on undeliverable mail");
msg_warn("you may need to increase the master.cf %s process limit",
transport->name);
+ }
+ msg_warn("please avoid flushing the whole queue when you have");
+ msg_warn("lots of deferred mail, that is bad for performance");
msg_warn("to turn off these warnings specify: %s = 0",
VAR_QMGR_CLOG_WARN_TIME);
queue->clog_time_to_warn = now + var_qmgr_clog_warn_time;
* Connect to the cleanup server. Log client name/address with queue ID.
*/
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC, var_cleanup_service);
- if (state->dest == 0)
+ if (state->dest == 0
+ || attr_print(state->dest->stream, ATTR_FLAG_NONE,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, CLEANUP_FLAG_FILTER,
+ ATTR_TYPE_END) != 0)
msg_fatal("unable to connect to the %s %s service",
MAIL_CLASS_PUBLIC, var_cleanup_service);
state->cleanup = state->dest->stream;
* bloody likely, but present for the sake of consistency with all other
* Postfix points of entrance).
*/
- rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d", CLEANUP_FLAG_FILTER);
rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld", (long) state->time);
if (*var_filter_xport)
rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
if (SMTPD_STAND_ALONE(state) == 0) {
state->dest = mail_stream_service(MAIL_CLASS_PUBLIC,
var_cleanup_service);
- if (state->dest == 0)
+ if (state->dest == 0
+ || attr_print(state->dest->stream, ATTR_FLAG_NONE,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, CLEANUP_FLAG_FILTER,
+ ATTR_TYPE_END) != 0)
msg_fatal("unable to connect to the %s %s service",
MAIL_CLASS_PUBLIC, var_cleanup_service);
- rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
- CLEANUP_FLAG_FILTER);
}
/*
var_access_map_code, reply_name, reply_class));
/*
- * HOLD means deliver later.
+ * HOLD means deliver later. But we may still change our mind, and
+ * reject/discard the message for other reasons.
*/
if (strcasecmp(value, "HOLD") == 0) {
vstring_sprintf(error_text, "<%s>: %s triggers HOLD action",
reply_name, reply_class);
log_whatsup(state, "hold", STR(error_text));
+#ifndef TEST
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
CLEANUP_FLAG_HOLD);
+#endif
+ return (SMTPD_CHECK_DUNNO);
}
/*
* DISCARD means silently discard and claim successful delivery.
+ *
+ * XXX Set some global flag that disables all further restrictions.
+ * Triggering a "reject" or "hold" action after "discard" is silly.
*/
if (strcasecmp(value, "DISCARD") == 0) {
vstring_sprintf(error_text, "<%s>: %s triggers DISCARD action",
reply_name, reply_class);
log_whatsup(state, "discard", STR(error_text));
+#ifndef TEST
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
CLEANUP_FLAG_DISCARD);
+#endif
+ return (SMTPD_CHECK_OK);
}
/*
struct hostent *hp;
int i;
+ /*
+ * Avoid suprious complaints from Purify on Solaris.
+ */
+ memset((char *) &sin, 0, len);
+
/*
* Look up the peer address information.
*/
ATTR_TYPE_STR, MAIL_ATTR_TRANSPORT, STR(channel),
ATTR_TYPE_STR, MAIL_ATTR_NEXTHOP, STR(nexthop),
ATTR_TYPE_STR, MAIL_ATTR_RECIP, STR(nextrcpt),
- ATTR_TYPE_NUM, MAIL_ATTR_RFLAGS, flags,
+ ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, flags,
ATTR_TYPE_END);
if (vstream_fflush(stream) != 0) {
char *attr;
char *myname = "dict_ldap_get_values";
struct timeval tv;
+ LDAPURLDesc *url;
tv.tv_sec = dict_ldap->timeout;
tv.tv_usec = 0;
if (msg_verbose)
msg_info("%s: looking up URL %s", myname,
vals[i]);
- rc = ldap_url_search_st(dict_ldap->ld, vals[i],
- 0, &tv, &resloop);
+ rc = ldap_url_parse(vals[i], &url);
+ if (rc == 0) {
+ rc = ldap_search_st(dict_ldap->ld, url->lud_dn,
+ url->lud_scope, url->lud_filter,
+ url->lud_attrs, 0, &tv,
+ &resloop);
+ ldap_free_urldesc(url);
+ }
} else {
if (msg_verbose)
msg_info("%s: looking up DN %s", myname, vals[i]);