indices in replacement text, and silently treated $text as
$0. Found by Michael Tokarev. File: dict_pcre.c.
+20021107
+
+ The behavior of the SMTP server's defer_if_permit flag has
+ changed. The flag is still set when an UCE reject restriction
+ fails due to a temporary (DNS) problem, to prevent unwanted
+ mail from slipping through. However, the flag is no longer
+ tested at the end of client, helo or sender restrictions.
+ Instead, the flag is now tested at the end of the ETRN and
+ recipient restrictions only.
+
+ The behavior of the warn_if_reject restriction has changed.
+ It no longer activates any already made defer_if_permit or
+ defer_if_reject decisions (the defer_if_reject flag is set
+ when some UCE permit restriction fails due to a temporary
+ (DNS) problem, to avoid loss of legitimate mail).
+
+ Instead of setting the defer_if_permit flag, a failing
+ reject restriction after warn_if_reject now merely logs
+ that it would have caused mail to be deferred.
+
+ A failing permit restriction after warn_if_reject still
+ raises the defer_if_reject flag, to avoid loss of legitimate
+ mail.
+
Open problems:
Low: revise other local delivery agent duplicate filters.
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-20021107
+==========================================================
+
+The behavior of the SMTP server's defer_if_permit flag has changed.
+The flag is still set when an UCE reject restriction fails due to
+a temporary (DNS) problem, to prevent unwanted mail from slipping
+through. However, the flag is no longer tested at the end of client,
+helo or sender restrictions. Instead, the flag is now tested at
+the end of the ETRN and recipient restrictions only.
+
+The behavior of the warn_if_reject restriction has changed. It no
+longer activates any pending defer_if_permit or defer_if_reject
+decisions (the defer_if_reject flag is set when some UCE permit
+restriction fails due to a temporary (DNS) problem, to avoid loss
+of legitimate mail).
+
+Instead of setting the defer_if_permit flag, a failing reject
+restriction after warn_if_reject now merely logs that it would have
+caused mail to be deferred.
+
+A failing permit restriction after warn_if_reject still raises the
+defer_if_reject flag, to avoid loss of legitimate mail.
+
Incompatible changes with Postfix snapshot 1.1.11-20021028
==========================================================
* results happen with:
*
* reject_unknown_client, hostname-based white-list, reject
+ *
+ * XXX Don't raise the defer_if_permit flag with a failing reject-style
+ * restriction that follows warn_if_reject. Instead, log the warning for the
+ * resulting defer message.
+ *
+ * XXX Do raise the defer_if_reject flag with a failing permit-style
+ * restriction that follows warn_if_reject. Otherwise, we could reject
+ * legitimate mail.
*/
static void PRINTFLIKE(3, 4) defer_if(SMTPD_DEFER *, int, const char *,...);
defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2))
#define DEFER_IF_REJECT3(state, class, fmt, a1, a2, a3) \
defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2), (a3))
-#define DEFER_IF_PERMIT2(state, class, fmt, a1, a2) \
- defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2))
+#define DEFER_IF_PERMIT2(state, class, fmt, a1, a2) do { \
+ if ((state)->warn_if_reject == 0) \
+ defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2)); \
+ else \
+ (void) smtpd_check_reject((state), (class), (fmt), (a1), (a2)); \
+ } while (0)
/*
* Cached RBL lookup state.
int warn_if_reject;
const char *whatsup;
- /*
- * defer_if_whatever has precedence over warn_if_reject, so as to
- * minimize confusion. Bummer. There goes transparency.
- */
- if (state->warn_if_reject && state->defer_if_reject.active) {
- state->warn_if_reject = state->defer_if_reject.active = 0;
- return (smtpd_check_reject(state, state->defer_if_reject.class,
- "%s", STR(state->defer_if_reject.reason)));
- }
- if (state->warn_if_reject && state->defer_if_permit.active) {
- state->warn_if_reject = state->defer_if_permit.active = 0;
- return (smtpd_check_reject(state, state->defer_if_permit.class,
- "%s", STR(state->defer_if_permit.reason)));
- }
-
/*
* Do not reject mail if we were asked to warn only. However,
* configuration errors cannot be converted into warnings.
if (STREQUAL(value, "REJECT", cmd_len)) {
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
"%d <%s>: %s rejected: %s",
- var_access_map_code, reply_name, reply_class,
+ var_access_map_code, reply_name, reply_class,
*cmd_text ? cmd_text : "Access denied"));
}
/*
* Don't get carried away with recursion.
*/
- if (state->recursion++ > 100) {
+ if (state->recursion > 100) {
msg_warn("SMTPD access map %s entry %s causes unreasonable recursion",
table, value);
longjmp(smtpd_check_buf, smtpd_check_reject(state, MAIL_ERROR_SOFTWARE,
int status = 0;
ARGV *list;
int found;
- int saved_recursion = state->recursion;
+ int saved_recursion = state->recursion++;
if (msg_verbose)
msg_info("%s: START", myname);
state->recursion = saved_recursion;
- /*
- * Force this permission into deferral because of some earlier temporary
- * error that may have prevented us from rejecting mail, and report the
- * earlier problem instead.
- */
- if (status == SMTPD_CHECK_OK || status == SMTPD_CHECK_DUNNO) {
- if (state->defer_if_permit.active)
- status = smtpd_check_reject(state, state->defer_if_permit.class,
- "%s", STR(state->defer_if_permit.reason));
- }
return (status);
}
return (0);
#define SMTPD_CHECK_RESET() { \
- state->recursion = 1; \
+ state->recursion = 0; \
state->warn_if_reject = 0; \
state->defer_if_reject.active = 0; \
- state->defer_if_permit.active = 0; \
}
+ /*
+ * This is cleared before client restrictions, and is tested after
+ * recipient and etrn restrictions.
+ */
+ state->defer_if_permit.active = 0;
+
/*
* Apply restrictions in the order as specified.
*/
status = generic_checks(state, rcpt_restrctions,
recipient, SMTPD_NAME_RECIPIENT, CHECK_RECIP_ACL);
+ /*
+ * Force permission into deferral when some earlier temporary error may
+ * have prevented us from rejecting mail, and report the earlier problem.
+ */
+ if (status != SMTPD_CHECK_REJECT && state->defer_if_permit.active)
+ status = smtpd_check_reject(state, state->defer_if_permit.class,
+ "%s", STR(state->defer_if_permit.reason));
+
SMTPD_CHECK_RCPT_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
}
status = generic_checks(state, etrn_restrctions, domain,
SMTPD_NAME_ETRN, CHECK_ETRN_ACL);
+ /*
+ * Force permission into deferral when some earlier temporary error may
+ * have prevented us from rejecting mail, and report the earlier problem.
+ */
+ if (status != SMTPD_CHECK_REJECT && state->defer_if_permit.active)
+ status = smtpd_check_reject(state, state->defer_if_permit.class,
+ "%s", STR(state->defer_if_permit.reason));
+
SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
}