diff -urN ../exim-4.95.orig/src/globals.c ./src/globals.c --- ../exim-4.95.orig/src/globals.c 2021-09-28 11:24:46.000000000 +0300 +++ ./src/globals.c 2022-01-26 19:02:38.369397000 +0200 @@ -1499,7 +1499,8 @@ int smtp_mailcmd_max = -1; 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; unsigned smtp_peer_options = 0; diff -urN ../exim-4.95.orig/src/globals.h ./src/globals.h --- ../exim-4.95.orig/src/globals.h 2021-09-28 11:24:46.000000000 +0300 +++ ./src/globals.h 2022-01-26 19:03:58.478267000 +0200 @@ -971,7 +971,8 @@ extern int smtp_load_reserve; /* Only from reserved if load > this */ extern int smtp_mailcmd_count; /* Count of MAIL commands */ extern int smtp_mailcmd_max; /* Limit for 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_names[]; /* decode for command codes */ extern uschar *smtp_notquit_reason; /* Global for disconnect reason */ diff -urN ../exim-4.95.orig/src/readconf.c ./src/readconf.c --- ../exim-4.95.orig/src/readconf.c 2021-09-28 11:24:46.000000000 +0300 +++ ./src/readconf.c 2022-01-28 00:48:18.536119000 +0200 @@ -324,7 +324,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.95.orig/src/smtp_in.c ./src/smtp_in.c --- ../exim-4.95.orig/src/smtp_in.c 2021-09-28 11:24:46.000000000 +0300 +++ ./src/smtp_in.c 2022-01-26 19:03:06.370672000 +0200 @@ -3134,8 +3134,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)", @@ -4236,7 +4267,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)",