From 16652106219027b2e4afad51995c69c913d29973 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sat, 12 Jun 2021 00:00:00 -0500 Subject: [PATCH] postfix-3.7-20210612 --- postfix/HISTORY | 27 ++++++++++++++++ postfix/README_FILES/BDAT_README | 2 +- postfix/WISHLIST | 3 -- postfix/conf/master.cf | 6 ++-- postfix/html/BDAT_README.html | 2 +- postfix/html/cidr_table.5.html | 4 +-- postfix/html/postconf.5.html | 10 ++++-- postfix/html/regexp_table.5.html | 4 +-- postfix/html/smtpd.8.html | 2 +- postfix/man/man5/cidr_table.5 | 4 +-- postfix/man/man5/postconf.5 | 8 +++-- postfix/man/man5/regexp_table.5 | 4 +-- postfix/man/man8/smtpd.8 | 2 +- postfix/proto/BDAT_README.html | 2 +- postfix/proto/cidr_table | 4 +-- postfix/proto/postconf.proto | 10 ++++-- postfix/proto/regexp_table | 4 +-- postfix/src/global/mail_version.h | 2 +- postfix/src/postfix/postfix.c | 3 +- postfix/src/postmap/Makefile.in | 18 +++++++++-- postfix/src/postscreen/postscreen_smtpd.c | 2 +- postfix/src/smtpd/smtpd.c | 10 ++++-- postfix/src/util/slmdb.c | 38 +++++++++++++---------- 23 files changed, 117 insertions(+), 54 deletions(-) diff --git a/postfix/HISTORY b/postfix/HISTORY index f722a7b6e..29457aefc 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -25597,3 +25597,30 @@ Apologies for any names omitted. 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. diff --git a/postfix/README_FILES/BDAT_README b/postfix/README_FILES/BDAT_README index 2dc1df35c..124880409 100644 --- a/postfix/README_FILES/BDAT_README +++ b/postfix/README_FILES/BDAT_README @@ -23,7 +23,7 @@ BDAT support is enabled by default. To disable BDAT support globally: # 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. diff --git a/postfix/WISHLIST b/postfix/WISHLIST index 46cad79d5..3c6c7fbd2 100644 --- a/postfix/WISHLIST +++ b/postfix/WISHLIST @@ -1,8 +1,5 @@ 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 diff --git a/postfix/conf/master.cf b/postfix/conf/master.cf index 4220165db..83fc6fdf7 100644 --- a/postfix/conf/master.cf +++ b/postfix/conf/master.cf @@ -32,9 +32,9 @@ smtp inet n - n - - smtpd # -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 diff --git a/postfix/html/BDAT_README.html b/postfix/html/BDAT_README.html index e96fe9348..cb9775541 100644 --- a/postfix/html/BDAT_README.html +++ b/postfix/html/BDAT_README.html @@ -51,7 +51,7 @@ globally:

# 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 diff --git a/postfix/html/cidr_table.5.html b/postfix/html/cidr_table.5.html index 457afbb56..cd90384c8 100644 --- a/postfix/html/cidr_table.5.html +++ b/postfix/html/cidr_table.5.html @@ -103,10 +103,10 @@ CIDR_TABLE(5) CIDR_TABLE(5) syntax is: main.cf: - parameter = .. pcre:{ { rule-1 }, { rule-2 } .. } .. + parameter = .. cidr:{ { rule-1 }, { rule-2 } .. } .. master.cf: - .. -o { parameter = .. pcre:{ { rule-1 }, { rule-2 } .. } .. } .. + .. -o { parameter = .. cidr:{ { rule-1 }, { rule-2 } .. } .. } .. Postfix ignores whitespace after '{' and before '}', and writes each rule as one text line to an in-memory file: diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html index 4cce2fbd1..5b0691c36 100644 --- a/postfix/html/postconf.5.html +++ b/postfix/html/postconf.5.html @@ -15300,20 +15300,26 @@ This feature is available in Postfix 2.0 and later.
smtpd_forbidden_commands -(default: CONNECT, GET, POST)
+(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".

This feature is available in Postfix 2.2 and later.

+

+Support for inline regular expressions was added in Postfix version +3.7. See regexp_table(5) for a description of the syntax and features. +

+
diff --git a/postfix/html/regexp_table.5.html b/postfix/html/regexp_table.5.html index 3d53436e1..b0e864819 100644 --- a/postfix/html/regexp_table.5.html +++ b/postfix/html/regexp_table.5.html @@ -132,10 +132,10 @@ REGEXP_TABLE(5) REGEXP_TABLE(5) syntax is: main.cf: - parameter = .. pcre:{ { rule-1 }, { rule-2 } .. } .. + parameter = .. regexp:{ { rule-1 }, { rule-2 } .. } .. master.cf: - .. -o { parameter = .. pcre:{ { rule-1 }, { rule-2 } .. } .. } .. + .. -o { parameter = .. regexp:{ { rule-1 }, { rule-2 } .. } .. } .. Postfix ignores whitespace after '{' and before '}', and writes each rule as one text line to an in-memory file: diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index ef9d7fd37..4dbc75661 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -1318,7 +1318,7 @@ SMTPD(8) SMTPD(8) Available in Postfix version 2.2 and later: - smtpd_forbidden_commands (CONNECT, GET, POST) + smtpd_forbidden_commands (CONNECT GET POST regexp:{{/^[^A-Z]/ Bogus}}) List of commands that cause the Postfix SMTP server to immedi- ately terminate the session with a 221 code. diff --git a/postfix/man/man5/cidr_table.5 b/postfix/man/man5/cidr_table.5 index a8754fc8f..2e182ee5b 100644 --- a/postfix/man/man5/cidr_table.5 +++ b/postfix/man/man5/cidr_table.5 @@ -120,10 +120,10 @@ The basic syntax is: .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 diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5 index 151afdfbc..f9c0263a3 100644 --- a/postfix/man/man5/postconf.5 +++ b/postfix/man/man5/postconf.5 @@ -10413,14 +10413,18 @@ The smtpd_expansion_filter value is not subject to Postfix configuration 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 diff --git a/postfix/man/man5/regexp_table.5 b/postfix/man/man5/regexp_table.5 index 9ebc6a6c3..7b5192196 100644 --- a/postfix/man/man5/regexp_table.5 +++ b/postfix/man/man5/regexp_table.5 @@ -143,10 +143,10 @@ The basic syntax is: .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 diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index f016451c7..419fd0d46 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -1138,7 +1138,7 @@ A prefix that is prepended to the process name in syslog 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 diff --git a/postfix/proto/BDAT_README.html b/postfix/proto/BDAT_README.html index ace54928f..85adeac00 100644 --- a/postfix/proto/BDAT_README.html +++ b/postfix/proto/BDAT_README.html @@ -51,7 +51,7 @@ globally:

# 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 diff --git a/postfix/proto/cidr_table b/postfix/proto/cidr_table index d96fa554a..ca0381399 100644 --- a/postfix/proto/cidr_table +++ b/postfix/proto/cidr_table @@ -106,10 +106,10 @@ # # .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 diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto index 9a0420848..59aecf5e7 100644 --- a/postfix/proto/postconf.proto +++ b/postfix/proto/postconf.proto @@ -5680,20 +5680,26 @@ parameter $name expansion. This feature is available in Postfix 2.0 and later.

-%PARAM smtpd_forbidden_commands CONNECT, GET, POST +%PARAM smtpd_forbidden_commands 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".

This feature is available in Postfix 2.2 and later.

+

+Support for inline regular expressions was added in Postfix version +3.7. See regexp_table(5) for a description of the syntax and features. +

+ %PARAM smtpd_helo_required no

diff --git a/postfix/proto/regexp_table b/postfix/proto/regexp_table index 31d9902b2..969b8a9f8 100644 --- a/postfix/proto/regexp_table +++ b/postfix/proto/regexp_table @@ -127,10 +127,10 @@ # # .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 diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 9a8db34c3..f57b8a1ef 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * 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 diff --git a/postfix/src/postfix/postfix.c b/postfix/src/postfix/postfix.c index 357124ff5..0c4b6de50 100644 --- a/postfix/src/postfix/postfix.c +++ b/postfix/src/postfix/postfix.c @@ -587,8 +587,7 @@ int main(int argc, char **argv) * 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 " diff --git a/postfix/src/postmap/Makefile.in b/postfix/src/postmap/Makefile.in index 18f94ea53..c28af2aea 100644 --- a/postfix/src/postmap/Makefile.in +++ b/postfix/src/postmap/Makefile.in @@ -26,7 +26,8 @@ update: ../../bin/$(PROG) ../../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: @@ -80,17 +81,28 @@ lmdb_abb_test: $(PROG) lmdb_abb lmdb_abb.ref 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.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 diff --git a/postfix/src/postscreen/postscreen_smtpd.c b/postfix/src/postscreen/postscreen_smtpd.c index ca7088803..70183e7ee 100644 --- a/postfix/src/postscreen/postscreen_smtpd.c +++ b/postfix/src/postscreen/postscreen_smtpd.c @@ -637,7 +637,7 @@ static int psc_bdat_cmd(PSC_STATE *state, char *args) 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, diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 067b9b2d2..3f7b20167 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -1080,7 +1080,7 @@ /* 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 @@ -5693,9 +5693,15 @@ static void smtpd_proto(SMTPD_STATE *state) 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; } } diff --git a/postfix/src/util/slmdb.c b/postfix/src/util/slmdb.c index 37aa30d76..ac1594ff3 100644 --- a/postfix/src/util/slmdb.c +++ b/postfix/src/util/slmdb.c @@ -410,7 +410,6 @@ static int slmdb_prepare(SLMDB *slmdb) 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 @@ -420,24 +419,19 @@ static int slmdb_recover(SLMDB *slmdb, int status) 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 @@ -516,7 +510,7 @@ static int slmdb_recover(SLMDB *slmdb, int status) * 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 @@ -559,6 +553,8 @@ int slmdb_get(SLMDB *slmdb, MDB_val *mdb_key, MDB_val *mdb_value) 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); @@ -595,6 +591,8 @@ int slmdb_put(SLMDB *slmdb, MDB_val *mdb_key, 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); @@ -636,6 +634,8 @@ int slmdb_del(SLMDB *slmdb, MDB_val *mdb_key) 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); @@ -664,6 +664,12 @@ int slmdb_cursor_get(SLMDB *slmdb, MDB_val *mdb_key, 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. */ @@ -786,7 +792,7 @@ int slmdb_close(SLMDB *slmdb) * 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); -- 2.47.3