Bugfix: when updating the same header multiple times, the
Postfix Milter client created a queue file that caused
delivery agents to loop. File: cleanup/cleanup_milter.c.
+
+20060725
+
+ Bugfix: damaged queue file record after a Milter request
+ to modify a message header when 1) it was the last header
+ in the unmodified message, and 2) the old header was less
+ than 15 characters long. File: cleanup/cleanup_milter.c.
+
+ Bugfix: don't panic in smtp_rcpt_cleanup() after detecting
+ a damaged queue file record. File: smtp/smtp_proto.c.
+
+20060726
+
+ Bugfix: the 20051013 change to enforce the message size
+ limit in the SMTP server didn't work for size limits close
+ enough to INT_MAX. File: smtpd/smtpd.c.
+
+ Bugfix: after an SMTP client was rejected with "smtpd_delay_reject
+ = no", the SMTP server would panic as it generated spurious
+ Milter requests for unrecognized commands. File: smtpd/smtpd.c.
+
+20060727
+
+ Cleanup: change redundant milter_abort() and milter_disc_event()
+ calls into NO-OPs. This avoids unnecessary panic() events
+ for completely harmless conditions. File: milter/milter8.c.
Specifically, DSN support gives an email sender the ability to specify:
* What notifications are sent: success, failure, delay, or none. Normally,
- Postfix informs the sender only mail when delivery is delayed or when
+ Postfix informs the sender only when mail delivery is delayed or when
delivery fails.
* What content is returned in case of failure: only the message headers, or
<ul>
<li> <p> What notifications are sent: success, failure, delay, or
-none. Normally, Postfix informs the sender only mail when delivery
+none. Normally, Postfix informs the sender only when mail delivery
is delayed or when delivery fails. </p>
<li> <p> What content is returned in case of failure: only the
<blockquote>
<pre>
-/etc/postfix/main.cf:
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
<a href="postconf.5.html#smtpd_discard_ehlo_keyword_address_maps">smtpd_discard_ehlo_keyword_address_maps</a> =
<a href="cidr_table.5.html">cidr</a>:/etc/postfix/esmtp_access
<blockquote>
<pre>
-/etc/postfix/main.cf:
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
<a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = silent-discard, dsn
</pre>
</blockquote>
<ul>
<li> <p> What notifications are sent: success, failure, delay, or
-none. Normally, Postfix informs the sender only mail when delivery
+none. Normally, Postfix informs the sender only when mail delivery
is delayed or when delivery fails. </p>
<li> <p> What content is returned in case of failure: only the
msg_warn("%s: seek file %s: %m", myname, cleanup_path);
CLEANUP_PATCH_HEADER_RETURN(cleanup_milter_error(state, errno));
}
- CLEANUP_OUT_BUF(state, rec_type, buf);
+ /* The saved "append header" pointer record may still contain "0". */
+ if (saved_read_offset == state->append_hdr_pt_offset)
+ cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
+ (long) state->append_hdr_pt_target);
+ else
+ CLEANUP_OUT_BUF(state, rec_type, buf);
if (msg_verbose > 1)
msg_info("%s: %ld: write %.*s", myname, (long) write_offset,
LEN(buf) > 30 ? 30 : (int) LEN(buf), STR(buf));
CLEANUP_UPD_HEADER_RETURN(cleanup_milter_error(state, errno));
}
if (rec_type == REC_TYPE_PTR) {
+ /* The "append header" pointer record content must be saved. */
+ if (saved_read_offset == state->append_hdr_pt_offset)
+ break;
if (jumped == 0) {
/* Enough contiguous space for writing a PTR record. */
avail_space += read_offset - saved_read_offset;
#define DEF_SMTP_SASL_PASSWD ""
extern char *var_smtp_sasl_passwd;
-#define VAR_SMTP_SASL_ENFORCE "smtp_sasl_auth_enforce"
-#define DEF_SMTP_SASL_ENFORCE 1
-extern bool var_smtp_sasl_enforce;
-
#define VAR_SMTP_SASL_OPTS "smtp_sasl_security_options"
#define DEF_SMTP_SASL_OPTS "noplaintext, noanonymous"
extern char *var_smtp_sasl_opts;
#define DEF_LMTP_SASL_PASSWD ""
extern char *var_lmtp_sasl_passwd;
-#define VAR_LMTP_SASL_ENFORCE "lmtp_sasl_auth_enforce"
-#define DEF_LMTP_SASL_ENFORCE 1
-
#define VAR_LMTP_SASL_OPTS "lmtp_sasl_security_options"
#define DEF_LMTP_SASL_OPTS "noplaintext, noanonymous"
extern char *var_lmtp_sasl_opts;
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20060724"
-#define MAIL_VERSION_NUMBER "2.3.1"
+#define MAIL_RELEASE_DATE "20060727"
+#define MAIL_VERSION_NUMBER "2.3.2"
#ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
/*
/* milter_disc_event() reports an SMTP client disconnection
/* event to the specified milter instances. No events can
-/* reported after this call, not even abort() events.
+/* reported after this call. To simplify usage, redundant calls
+/* of this function are NO-OPs and don't raise a run-time
+/* error.
/*
/* milter_helo_event() reports a HELO or EHLO event to the
/* specified milter instances, after sending the macros that
/* by a preceding milter. This function must be called with
/* as argument an open Postfix queue file.
/*
-/* milter_abort() cancels a mail transaction in progress. This
-/* function is safe to call anywhere between connect and
-/* disconnect events.
+/* milter_abort() cancels a mail transaction in progress. To
+/* simplify usage, redundant calls of this function are NO-OPs
+/* and don't raise a run-time error.
/*
/* milter_send() sends a list of mail filters over the specified
/* stream. When given a null list pointer, a "no filter"
* has to open a new MTA-to-filter socket for each SMTP client.
*/
switch (milter->state) {
+ case MILTER8_STAT_CLOSED:
+ case MILTER8_STAT_READY:
+ return;
case MILTER8_STAT_ERROR:
case MILTER8_STAT_ACCEPT_CON:
case MILTER8_STAT_REJECT_CON:
* has to open a new MTA-to-filter socket for each SMTP client.
*/
switch (milter->state) {
+ case MILTER8_STAT_CLOSED:
+ case MILTER8_STAT_READY:
+ return;
case MILTER8_STAT_ERROR:
#ifdef LIBMILTER_AUTO_DISCONNECT
case MILTER8_STAT_ACCEPT_CON:
NOCLOBBER int mail_from_rejected;
NOCLOBBER int downgrading;
int mime_errs;
+ SMTP_RESP fake;
+ int fail_status;
/*
* Macros for readability.
if (rec_type != REC_TYPE_XTRA) {
msg_warn("%s: bad record type: %d in message content",
request->queue_id, rec_type);
- RETURN(mark_corrupt(state->src));
+ fail_status = smtp_mesg_fail(state, DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "5.3.0"),
+ "unreadable mail queue entry");
+ if (fail_status == 0)
+ (void) mark_corrupt(state->src);
+ RETURN(fail_status);
}
}
&& (state->proxy == 0 ? (++start, --len) == 0 : len == 1))
break;
if (state->err == CLEANUP_STAT_OK) {
- state->act_size += len + 2;
- if (var_message_limit > 0 && state->act_size > var_message_limit)
+ if (var_message_limit > 0 && var_message_limit - state->act_size < len + 2)
state->err = CLEANUP_STAT_SIZE;
- else if (out_record(out_stream, curr_rec_type, start, len) < 0)
- state->err = out_error;
+ else {
+ state->act_size += len + 2;
+ if (out_record(out_stream, curr_rec_type, start, len) < 0)
+ state->err = out_error;
+ }
}
}
state->where = SMTPD_AFTER_DOT;
smtpd_chat_reply(state, "221 2.7.0 Error: I can break rules, too. Goodbye.");
break;
}
+ }
+ /* XXX We use the real client for connect access control. */
+ if (state->access_denied && cmdp->action != quit_cmd) {
+ smtpd_chat_reply(state, "503 5.7.0 Error: access denied for %s",
+ state->namaddr); /* RFC 2821 Sec 3.1 */
+ state->error_count++;
+ continue;
+ }
+ /* state->access_denied == 0 || cmdp->action == quit_cmd */
+ if (cmdp->name == 0) {
if (smtpd_milters != 0
&& SMTPD_STAND_ALONE(state) == 0
&& (err = milter_unknown_event(smtpd_milters,
state->error_count++;
continue;
}
- /* XXX We use the real client for connect access control. */
- if (state->access_denied && cmdp->action != quit_cmd) {
- smtpd_chat_reply(state, "503 5.7.0 Error: access denied for %s",
- state->namaddr); /* RFC 2821 Sec 3.1 */
- state->error_count++;
- continue;
- }
#ifdef USE_TLS
if (state->tls_enforce_tls &&
!state->tls_context &&