or master.cf, to improve their usability in matchlists. Files:
util/dict_stream.c, util/dict.h, util/dict_pcre.c,
util/dict_regexp.c, util/dict_cidr.c, and test files.
+
+ The smtpd_forbidden_commands default setting now also inludes
+ a regular expression regexp:{{/^[^A-Z]/ Bogus}} for bogus inputs.
+ File: global/mail_params.h.
+
+20210606
+
+ Cleanup: "Postfix is running with backwards-compatible..."
+ did not make sense when Postfix is down. File: postfix/postfix.c.
+
+ Cleanup: the postscreen BDAT handler now replies with "need
+ MAIL command" when the client did not provide a sender address.
+ File: postscreen/postscreen_smtpd.c.
+
+ Typo: silent_discard should be silent-discard. File:
+ proto/BDAT_README.html.
+
+20210610
+
+ Cleanup: escape non-printable characters in non-SMTP commands,
+ instead of replacing them with '?'. File: smtpd/smtpd.c.
+
+ Misc typofixes by Viktor Dukhovni. Files: conf/master.cf,
+ proto/regexp_table, proto/cidr_table.
+
+ Cleanup: simplify the LMDB error recovery code. File:
+ util/slmdb.c.
# The logging alternative:
smtpd_discard_ehlo_keywords = chunking
# The non-logging alternative:
- smtpd_discard_ehlo_keywords = chunking, silent_discard
+ smtpd_discard_ehlo_keywords = chunking, silent-discard
Specify '-o smtpd_discard_ehlo_keywords=' in master.cf for the submission and
smtps services, if you have clients that benefit from CHUNKING support.
Wish list:
- Make postscreen drop the connection after a non-SMTP command,
- just like the real Postfix SMTP daemon.
-
Add verp=+= to the qmgr "from=" logging.
Make smtpd_relay_before_recipient_restrictions settable
# -o smtpd_relay_restrictions=
# -o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
# -o milter_macro_daemon_name=ORIGINATING
-# Choose one: enable submssions for loopback clients only, or for any client.
-#127.0.0.1:submssions inet n - n - - smtpd
-#submssions inet n - n - - smtpd
+# Choose one: enable submissions for loopback clients only, or for any client.
+#127.0.0.1:submissions inet n - n - - smtpd
+#submissions inet n - n - - smtpd
# -o syslog_name=postfix/submissions
# -o smtpd_tls_wrappermode=yes
# -o smtpd_sasl_auth_enable=yes
# The logging alternative:
<a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking
# The non-logging alternative:
- <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking, silent_discard
+ <a href="postconf.5.html#smtpd_discard_ehlo_keywords">smtpd_discard_ehlo_keywords</a> = chunking, silent-discard
</pre>
</blockquote>
syntax is:
<a href="postconf.5.html">main.cf</a>:
- <i>parameter</i> <b>= .. <a href="pcre_table.5.html">pcre</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } ..</b>
+ <i>parameter</i> <b>= .. <a href="cidr_table.5.html">cidr</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } ..</b>
<a href="master.5.html">master.cf</a>:
- <b>.. -o {</b> <i>parameter</i> <b>= .. <a href="pcre_table.5.html">pcre</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
+ <b>.. -o {</b> <i>parameter</i> <b>= .. <a href="cidr_table.5.html">cidr</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
Postfix ignores whitespace after '{' and before '}', and writes each
<i>rule</i> as one text line to an in-memory file:
</DD>
<DT><b><a name="smtpd_forbidden_commands">smtpd_forbidden_commands</a>
-(default: CONNECT, GET, POST)</b></DT><DD>
+(default: CONNECT GET POST <a href="regexp_table.5.html">regexp</a>:{{/^[^A-Z]/ Bogus}})</b></DT><DD>
<p>
List of commands that cause the Postfix SMTP server to immediately
terminate the session with a 221 code. This can be used to disconnect
clients that obviously attempt to abuse the system. In addition to the
commands listed in this parameter, commands that follow the "Label:"
-format of message headers will also cause a disconnect.
+format of message headers will also cause a disconnect. With Postfix
+versions 3.6 and earlier, the default value is "CONNECT GET POST".
</p>
<p>
This feature is available in Postfix 2.2 and later.
</p>
+<p>
+Support for inline regular expressions was added in Postfix version
+3.7. See <a href="regexp_table.5.html">regexp_table(5)</a> for a description of the syntax and features.
+</p>
+
</DD>
syntax is:
<a href="postconf.5.html">main.cf</a>:
- <i>parameter</i> <b>= .. <a href="pcre_table.5.html">pcre</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } ..</b>
+ <i>parameter</i> <b>= .. <a href="regexp_table.5.html">regexp</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } ..</b>
<a href="master.5.html">master.cf</a>:
- <b>.. -o {</b> <i>parameter</i> <b>= .. <a href="pcre_table.5.html">pcre</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
+ <b>.. -o {</b> <i>parameter</i> <b>= .. <a href="regexp_table.5.html">regexp</a>:{ {</b> <i>rule-1</i> <b>}, {</b> <i>rule-2</i> <b>} .. } .. } ..</b>
Postfix ignores whitespace after '{' and before '}', and writes each
<i>rule</i> as one text line to an in-memory file:
Available in Postfix version 2.2 and later:
- <b><a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a> (CONNECT, GET, POST)</b>
+ <b><a href="postconf.5.html#smtpd_forbidden_commands">smtpd_forbidden_commands</a> (CONNECT GET POST <a href="regexp_table.5.html">regexp</a>:{{/^[^A-Z]/ Bogus}})</b>
List of commands that cause the Postfix SMTP server to immedi-
ately terminate the session with a 221 code.
.nf
main.cf:
- \fIparameter\fR \fB= .. pcre:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } ..\fR
+ \fIparameter\fR \fB= .. cidr:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } ..\fR
master.cf:
- \fB.. \-o { \fIparameter\fR \fB= .. pcre:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
+ \fB.. \-o { \fIparameter\fR \fB= .. cidr:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
.fi
Postfix ignores whitespace after '{' and before '}', and
parameter $name expansion.
.PP
This feature is available in Postfix 2.0 and later.
-.SH smtpd_forbidden_commands (default: CONNECT, GET, POST)
+.SH smtpd_forbidden_commands (default: CONNECT GET POST regexp:{{/^[^A\-Z]/ Bogus}})
List of commands that cause the Postfix SMTP server to immediately
terminate the session with a 221 code. This can be used to disconnect
clients that obviously attempt to abuse the system. In addition to the
commands listed in this parameter, commands that follow the "Label:"
-format of message headers will also cause a disconnect.
+format of message headers will also cause a disconnect. With Postfix
+versions 3.6 and earlier, the default value is "CONNECT GET POST".
.PP
This feature is available in Postfix 2.2 and later.
+.PP
+Support for inline regular expressions was added in Postfix version
+3.7. See \fBregexp_table\fR(5) for a description of the syntax and features.
.SH smtpd_hard_error_limit (default: normal: 20, overload: 1)
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail. The Postfix SMTP server disconnects
.nf
main.cf:
- \fIparameter\fR \fB= .. pcre:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } ..\fR
+ \fIparameter\fR \fB= .. regexp:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } ..\fR
master.cf:
- \fB.. \-o { \fIparameter\fR \fB= .. pcre:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
+ \fB.. \-o { \fIparameter\fR \fB= .. regexp:{ { \fIrule\-1\fB }, { \fIrule\-2\fB } .. } .. } ..\fR
.fi
Postfix ignores whitespace after '{' and before '}', and
records, so that, for example, "smtpd" becomes "prefix/smtpd".
.PP
Available in Postfix version 2.2 and later:
-.IP "\fBsmtpd_forbidden_commands (CONNECT, GET, POST)\fR"
+.IP "\fBsmtpd_forbidden_commands (CONNECT GET POST regexp:{{/^[^A\-Z]/ Bogus}})\fR"
List of commands that cause the Postfix SMTP server to immediately
terminate the session with a 221 code.
.PP
# The logging alternative:
smtpd_discard_ehlo_keywords = chunking
# The non-logging alternative:
- smtpd_discard_ehlo_keywords = chunking, silent_discard
+ smtpd_discard_ehlo_keywords = chunking, silent-discard
</pre>
</blockquote>
#
# .nf
# main.cf:
-# \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR
+# \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR
#
# master.cf:
-# \fB.. -o { \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
+# \fB.. -o { \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
# .fi
#
# Postfix ignores whitespace after '{' and before '}', and
This feature is available in Postfix 2.0 and later.
</p>
-%PARAM smtpd_forbidden_commands CONNECT, GET, POST
+%PARAM smtpd_forbidden_commands CONNECT GET POST regexp:{{/^[^A-Z]/ Bogus}}
<p>
List of commands that cause the Postfix SMTP server to immediately
terminate the session with a 221 code. This can be used to disconnect
clients that obviously attempt to abuse the system. In addition to the
commands listed in this parameter, commands that follow the "Label:"
-format of message headers will also cause a disconnect.
+format of message headers will also cause a disconnect. With Postfix
+versions 3.6 and earlier, the default value is "CONNECT GET POST".
</p>
<p>
This feature is available in Postfix 2.2 and later.
</p>
+<p>
+Support for inline regular expressions was added in Postfix version
+3.7. See regexp_table(5) for a description of the syntax and features.
+</p>
+
%PARAM smtpd_helo_required no
<p>
#
# .nf
# main.cf:
-# \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR
+# \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR
#
# master.cf:
-# \fB.. -o { \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
+# \fB.. -o { \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
# .fi
#
# Postfix ignores whitespace after '{' and before '}', and
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20210605"
+#define MAIL_RELEASE_DATE "20210612"
#define MAIL_VERSION_NUMBER "3.7"
#ifdef SNAPSHOT
* effect.
*/
if (compat_level < compat_level_from_string(LAST_COMPAT_LEVEL, msg_panic)) {
- msg_info("Postfix is running with backwards-compatible default "
- "settings");
+ msg_info("Postfix is using backwards-compatible default settings");
msg_info("See http://www.postfix.org/COMPATIBILITY_README.html "
"for details");
msg_info("To disable backwards compatibility use \"postconf "
../../bin/$(PROG): $(PROG)
cp $(PROG) ../../bin
-tests: test1 test2 fail_test quote_test file_test lmdb_abb_test lmdb_retry_test
+tests: test1 test2 fail_test quote_test file_test lmdb_abb_test \
+ lmdb_bulk_test lmdb_incr_test
root_tests:
diff lmdb_abb.ref lmdb_abb.tmp
rm -f lmdb_abb.tmp lmdb_abb.lmdb
-lmdb_retry_test: $(PROG)
+lmdb_bulk_test: $(PROG)
rm -f lmdb_retry.lmdb main.cf
tr A-Z a-z < /usr/share/dict/words| \
sed -e 's/.*/& &/' -e 10000q| LANG=C sort -u >lmdb_retry
- echo lmdb_map_size=1000 >main.cf
+ echo lmdb_map_size=10000 >main.cf
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . lmdb:lmdb_retry; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \
LANG=C sort > lmdb_retry.tmp)
cmp lmdb_retry lmdb_retry.tmp
rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf
+lmdb_incr_test: $(PROG)
+ rm -f lmdb_retry.lmdb main.cf
+ tr A-Z a-z < /usr/share/dict/words| \
+ sed -e 's/.*/& &/' -e 10000q| LANG=C sort -u >lmdb_retry
+ echo lmdb_map_size=10000 >main.cf
+ ($(SHLIB_ENV) $(VALGRIND) ./postmap -ic . lmdb:lmdb_retry <lmdb_retry; \
+ $(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \
+ LANG=C sort > lmdb_retry.tmp)
+ cmp lmdb_retry lmdb_retry.tmp
+ rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
else if (state->sender == 0)
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
psc_smtpd_time_event,
- "554 5.5.1 Error: need RCPT command\r\n");
+ "554 5.5.1 Error: need MAIL command\r\n");
else
PSC_CLEAR_EVENT_DROP_SESSION_STATE(state,
psc_smtpd_time_event,
/* records, so that, for example, "smtpd" becomes "prefix/smtpd".
/* .PP
/* Available in Postfix version 2.2 and later:
-/* .IP "\fBsmtpd_forbidden_commands (CONNECT, GET, POST)\fR"
+/* .IP "\fBsmtpd_forbidden_commands (CONNECT GET POST regexp:{{/^[^A-Z]/ Bogus}})\fR"
/* List of commands that cause the Postfix SMTP server to immediately
/* terminate the session with a 221 code.
/* .PP
if (is_header(argv[0].strval)
|| (*var_smtpd_forbid_cmds
&& string_list_match(smtpd_forbid_cmds, argv[0].strval))) {
+ VSTRING *escape_buf = vstring_alloc(100);
+
msg_warn("non-SMTP command from %s: %.100s",
- state->namaddr, vstring_str(state->buffer));
+ state->namaddr,
+ vstring_str(escape(escape_buf,
+ vstring_str(state->buffer),
+ VSTRING_LEN(state->buffer))));
smtpd_chat_reply(state, "221 2.7.0 Error: I can break rules, too. Goodbye.");
+ vstring_free(escape_buf);
break;
}
}
static int slmdb_recover(SLMDB *slmdb, int status)
{
MDB_envinfo info;
- int recover_bulk_transaction = 0;
/*
* This may be needed in non-MDB_NOLOCK mode. Recovery is rare enough
slmdb_cursor_close(slmdb);
/*
- * Recover bulk transactions only if they can be restarted. Limit the
- * number of recovery attempts per slmdb(3) API request.
- *
- * slmdb->txn must be either null (non-bulk transaction error), or an
- * aborted bulk-mode transaction.
+ * Limit the number of recovery attempts per slmdb(3) API request.
*/
- if ((slmdb->txn != 0 && slmdb->longjmp_fn == 0)
- || ((slmdb->api_retry_count += 1) >= slmdb->api_retry_limit))
+ if ((slmdb->api_retry_count += 1) >= slmdb->api_retry_limit)
return (status);
/*
- * Limit the number of recovery attempts per bulk transaction failure.
+ * Recover bulk transactions only if they can be restarted, but limit the
+ * number of recovery attempts.
*/
- if (slmdb->txn != 0 && slmdb->longjmp_fn != 0) {
- if ((slmdb->bulk_retry_count += 1) > slmdb->bulk_retry_limit)
- return (status);
- recover_bulk_transaction = 1;
- }
+ if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) != 0
+ && (slmdb->longjmp_fn == 0
+ || (slmdb->bulk_retry_count += 1) > slmdb->bulk_retry_limit))
+ return (status);
/*
* If we can recover from the error, we clear the error condition and the
* upgrade the lock to "exclusive", because the failed write transaction
* has no side effects.
*/
- if (status == 0 && recover_bulk_transaction != 0
+ if (status == 0 && (slmdb->slmdb_flags & SLMDB_FLAG_BULK) != 0
&& (status = mdb_txn_begin(slmdb->env, (MDB_txn *) 0,
slmdb->lmdb_flags & MDB_RDONLY,
&slmdb->txn)) == 0
if ((status = mdb_get(txn, slmdb->dbi, mdb_key, mdb_value)) != 0
&& status != MDB_NOTFOUND) {
mdb_txn_abort(txn);
+ if (txn == slmdb->txn)
+ slmdb->txn = 0;
if ((status = slmdb_recover(slmdb, status)) == 0)
status = slmdb_get(slmdb, mdb_key, mdb_value);
SLMDB_API_RETURN(slmdb, status);
if ((status = mdb_put(txn, slmdb->dbi, mdb_key, mdb_value, flags)) != 0) {
if (status != MDB_KEYEXIST) {
mdb_txn_abort(txn);
+ if (txn == slmdb->txn)
+ slmdb->txn = 0;
if ((status = slmdb_recover(slmdb, status)) == 0)
status = slmdb_put(slmdb, mdb_key, mdb_value, flags);
SLMDB_API_RETURN(slmdb, status);
if ((status = mdb_del(txn, slmdb->dbi, mdb_key, (MDB_val *) 0)) != 0) {
if (status != MDB_NOTFOUND) {
mdb_txn_abort(txn);
+ if (txn == slmdb->txn)
+ slmdb->txn = 0;
if ((status = slmdb_recover(slmdb, status)) == 0)
status = slmdb_del(slmdb, mdb_key);
SLMDB_API_RETURN(slmdb, status);
MDB_txn *txn;
int status = 0;
+ /*
+ * TODO: figure how we would recover a failing bulk transaction.
+ */
+ if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) != 0)
+ return (MDB_PANIC);
+
/*
* Open a read transaction and cursor if needed.
*/
* Finish an open bulk transaction. If slmdb_recover() returns after a
* bulk-transaction error, then it was unable to recover.
*/
- if (slmdb->txn != 0
+ if ((slmdb->slmdb_flags & SLMDB_FLAG_BULK) != 0 && slmdb->txn != 0
&& (status = mdb_txn_commit(slmdb->txn)) != 0)
status = slmdb_recover(slmdb, status);