diff -urN ../exim-4.94.2.orig/src/globals.c ./src/globals.c --- ../exim-4.94.2.orig/src/globals.c 2021-04-30 15:08:21.000000000 +0300 +++ ./src/globals.c 2022-01-26 17:36:50.829262000 +0200 @@ -1464,7 +1464,8 @@ int smtp_mailcmd_count = 0; FILE *smtp_out = NULL; uschar *smtp_etrn_command = NULL; -int smtp_max_synprot_errors= 3; +//int smtp_max_synprot_errors= 3; +uschar *smtp_max_synprot_errors = NULL; int smtp_max_unknown_commands = 3; uschar *smtp_notquit_reason = NULL; uschar *smtp_ratelimit_hosts = NULL; diff -urN ../exim-4.94.2.orig/src/globals.h ./src/globals.h --- ../exim-4.94.2.orig/src/globals.h 2021-04-30 15:08:21.000000000 +0300 +++ ./src/globals.h 2022-01-26 17:36:50.829677000 +0200 @@ -944,7 +944,8 @@ extern FILE *smtp_in; /* Incoming SMTP input file */ extern int smtp_load_reserve; /* Only from reserved if load > this */ extern int smtp_mailcmd_count; /* Count of MAIL commands */ -extern int smtp_max_synprot_errors;/* Max syntax/protocol errors */ +//extern int smtp_max_synprot_errors;/* Max syntax/protocol errors */ +extern uschar *smtp_max_synprot_errors; /* Max syntax/protocol errors */ extern int smtp_max_unknown_commands; /* As it says */ extern uschar *smtp_notquit_reason; /* Global for disconnect reason */ extern FILE *smtp_out; /* Incoming SMTP output file */ diff -urN ../exim-4.94.2.orig/src/readconf.c ./src/readconf.c --- ../exim-4.94.2.orig/src/readconf.c 2021-04-30 15:08:21.000000000 +0300 +++ ./src/readconf.c 2022-07-04 18:40:54.290307000 +0300 @@ -310,7 +310,7 @@ { "smtp_etrn_command", opt_stringptr, {&smtp_etrn_command} }, { "smtp_etrn_serialize", opt_bool, {&smtp_etrn_serialize} }, { "smtp_load_reserve", opt_fixed, {&smtp_load_reserve} }, - { "smtp_max_synprot_errors", opt_int, {&smtp_max_synprot_errors} }, + { "smtp_max_synprot_errors", opt_stringptr, {&smtp_max_synprot_errors} }, { "smtp_max_unknown_commands",opt_int, {&smtp_max_unknown_commands} }, { "smtp_ratelimit_hosts", opt_stringptr, {&smtp_ratelimit_hosts} }, { "smtp_ratelimit_mail", opt_stringptr, {&smtp_ratelimit_mail} }, diff -urN ../exim-4.94.2.orig/src/smtp_in.c ./src/smtp_in.c --- ../exim-4.94.2.orig/src/smtp_in.c 2021-04-30 15:08:21.000000000 +0300 +++ ./src/smtp_in.c 2022-01-26 17:36:50.832063000 +0200 @@ -3169,8 +3169,39 @@ type == L_smtp_syntax_error ? "syntax" : "protocol", string_printing(smtp_cmd_buffer), host_and_ident(TRUE), errmess); -if (++synprot_error_count > smtp_max_synprot_errors) + +#define DEFAULT_MAX_SYNPROT_ERRORS 3 +int max_synprot_errors = -1; +if (smtp_max_synprot_errors != NULL) { + uschar *expanded = expand_string(smtp_max_synprot_errors); + if (expanded == NULL) + { + if (!f.expand_string_forcedfail) + log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_max_synprot_errors " + "failed for message from %s: %s; fallback to default value %d", host_and_ident(FALSE), expand_string_message, DEFAULT_MAX_SYNPROT_ERRORS); + } + /* For speed, interpret a decimal number inline here */ + else + { + max_synprot_errors = 0; + uschar *s = expanded; + while (isdigit(*s)) + max_synprot_errors = max_synprot_errors * 10 + *s++ - '0'; + if (*s != 0) + { + log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_max_synprot_errors " + "for message from %s contains non-digit: %s; fallback to default value %d", host_and_ident(FALSE), expanded, DEFAULT_MAX_SYNPROT_ERRORS); + max_synprot_errors = DEFAULT_MAX_SYNPROT_ERRORS; + } + } + } +if (max_synprot_errors == -1) max_synprot_errors = DEFAULT_MAX_SYNPROT_ERRORS; + + +//if (++synprot_error_count > smtp_max_synprot_errors) +if (++synprot_error_count > max_synprot_errors) + { yield = 1; log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many " "syntax or protocol errors (last command was \"%s\", %s)", @@ -4230,7 +4261,38 @@ *smtp_cmd_argument == 0 ? US"(no argument given)" : string_printing(smtp_cmd_argument)); - if (++synprot_error_count > smtp_max_synprot_errors) + +#define DEFAULT_MAX_SYNPROT_ERRORS 3 +int max_synprot_errors = -1; +if (smtp_max_synprot_errors != NULL) + { + uschar *expanded = expand_string(smtp_max_synprot_errors); + if (expanded == NULL) + { + if (!f.expand_string_forcedfail) + log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_max_synprot_errors " + "failed for message from %s: %s; fallback to default value %d", host_and_ident(FALSE), expand_string_message, DEFAULT_MAX_SYNPROT_ERRORS); + } + /* For speed, interpret a decimal number inline here */ + else + { + max_synprot_errors = 0; + uschar *s = expanded; + while (isdigit(*s)) + max_synprot_errors = max_synprot_errors * 10 + *s++ - '0'; + if (*s != 0) + { + log_write(0, LOG_MAIN|LOG_PANIC, "expansion of smtp_max_synprot_errors " + "for message from %s contains non-digit: %s; fallback to default value %d", host_and_ident(FALSE), expanded, DEFAULT_MAX_SYNPROT_ERRORS); + max_synprot_errors = DEFAULT_MAX_SYNPROT_ERRORS; + } + } + } +if (max_synprot_errors == -1) max_synprot_errors = DEFAULT_MAX_SYNPROT_ERRORS; + + +// if (++synprot_error_count > smtp_max_synprot_errors) + if (++synprot_error_count > max_synprot_errors) { log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many " "syntax or protocol errors (last command was \"%s\", %s)",