Make smtp_accept_max_per_connection expanded
authorJeremy Harris <jgh146exb@wizmail.org>
Fri, 19 Mar 2021 20:42:25 +0000 (20:42 +0000)
committerJeremy Harris <jgh146exb@wizmail.org>
Sat, 3 Apr 2021 20:27:25 +0000 (21:27 +0100)
doc/doc-docbook/spec.xfpt
doc/doc-txt/NewStuff
src/src/globals.c
src/src/globals.h
src/src/readconf.c
src/src/smtp_in.c

index d971bbf606c9c0841e246f628c5d95b29543f013..e6135eb52d4de12fe465df21cdf3db3d03581db6 100644 (file)
@@ -17575,7 +17575,7 @@ live with.
 . searchable.  NM changed this occurrence for bug 1197 to no longer allow
 . the option name to split.
 
 . searchable.  NM changed this occurrence for bug 1197 to no longer allow
 . the option name to split.
 
-.option "smtp_accept_max_per_connection" main integer 1000 &&&
+.option "smtp_accept_max_per_connection" main integer&!! 1000 &&&
          smtp_accept_max_per_connection
 .cindex "SMTP" "limiting incoming message count"
 .cindex "limit" "messages per SMTP connection"
          smtp_accept_max_per_connection
 .cindex "SMTP" "limiting incoming message count"
 .cindex "limit" "messages per SMTP connection"
@@ -17585,6 +17585,11 @@ results in the transfer of a message. After the limit is reached, a 421
 response is given to subsequent MAIL commands. This limit is a safety
 precaution against a client that goes mad (incidents of this type have been
 seen).
 response is given to subsequent MAIL commands. This limit is a safety
 precaution against a client that goes mad (incidents of this type have been
 seen).
+.new
+The option is expanded after the HELO or EHLO is received
+and may depend on values available at that time.
+An empty or zero value after expansion removes the limit.
+.wen
 
 
 .option smtp_accept_max_per_host main string&!! unset
 
 
 .option smtp_accept_max_per_host main string&!! unset
index cd1699dc6f11cde7c55083b149707da1f686b50d..50f7b435777e1f0c0d01df8fe4188eecb336a09f 100644 (file)
@@ -46,6 +46,8 @@ Version 4.95
 12. Proxy Protocol Timeout is configurable via "proxy_protocol_timeout"
     main config option.
 
 12. Proxy Protocol Timeout is configurable via "proxy_protocol_timeout"
     main config option.
 
+13. Option "smtp_accept_msx_per_connection" is now expanded.
+
 Version 4.94
 ------------
 
 Version 4.94
 ------------
 
index b7e117868100d8136e37a3e08127fe33d29e050d..04e47050ec190b556490fb287cd1c335f9b94af7 100644 (file)
@@ -1450,7 +1450,7 @@ int     smtp_accept_count      = 0;
 int     smtp_accept_max        = 20;
 int     smtp_accept_max_nonmail= 10;
 uschar *smtp_accept_max_nonmail_hosts = US"*";
 int     smtp_accept_max        = 20;
 int     smtp_accept_max_nonmail= 10;
 uschar *smtp_accept_max_nonmail_hosts = US"*";
-int     smtp_accept_max_per_connection = 1000;
+uschar *smtp_accept_max_per_connection = US"1000";
 uschar *smtp_accept_max_per_host = NULL;
 int     smtp_accept_queue      = 0;
 int     smtp_accept_queue_per_connection = 10;
 uschar *smtp_accept_max_per_host = NULL;
 int     smtp_accept_queue      = 0;
 int     smtp_accept_queue_per_connection = 10;
index 41705fb4bb7254d8e2c02da581681ea8ab2aee0b..652518ade62252292298d808fbcf4eb4eaddcb1e 100644 (file)
@@ -926,7 +926,7 @@ extern BOOL    smtp_accept_keepalive;  /* Set keepalive on incoming */
 extern int     smtp_accept_max;        /* Max SMTP connections */
 extern int     smtp_accept_max_nonmail;/* Max non-mail commands in one con */
 extern uschar *smtp_accept_max_nonmail_hosts; /* Limit non-mail cmds from these hosts */
 extern int     smtp_accept_max;        /* Max SMTP connections */
 extern int     smtp_accept_max_nonmail;/* Max non-mail commands in one con */
 extern uschar *smtp_accept_max_nonmail_hosts; /* Limit non-mail cmds from these hosts */
-extern int     smtp_accept_max_per_connection; /* Max msgs per connection */
+extern uschar *smtp_accept_max_per_connection; /* Max msgs per connection */
 extern uschar *smtp_accept_max_per_host; /* Max SMTP cons from one IP addr */
 extern int     smtp_accept_queue;      /* Queue after so many connections */
 extern int     smtp_accept_queue_per_connection; /* Queue after so many msgs */
 extern uschar *smtp_accept_max_per_host; /* Max SMTP cons from one IP addr */
 extern int     smtp_accept_queue;      /* Queue after so many connections */
 extern int     smtp_accept_queue_per_connection; /* Queue after so many msgs */
index fb9164c9d608aa8224f942e6469f6556f84c3e68..0ae3166c330b91baffc4007d4082fbd4cca168bc 100644 (file)
@@ -300,7 +300,7 @@ static optionlist optionlist_config[] = {
   { "smtp_accept_max",          opt_int,         {&smtp_accept_max} },
   { "smtp_accept_max_nonmail",  opt_int,         {&smtp_accept_max_nonmail} },
   { "smtp_accept_max_nonmail_hosts", opt_stringptr, {&smtp_accept_max_nonmail_hosts} },
   { "smtp_accept_max",          opt_int,         {&smtp_accept_max} },
   { "smtp_accept_max_nonmail",  opt_int,         {&smtp_accept_max_nonmail} },
   { "smtp_accept_max_nonmail_hosts", opt_stringptr, {&smtp_accept_max_nonmail_hosts} },
-  { "smtp_accept_max_per_connection", opt_int,   {&smtp_accept_max_per_connection} },
+  { "smtp_accept_max_per_connection", opt_stringptr,   {&smtp_accept_max_per_connection} },
   { "smtp_accept_max_per_host", opt_stringptr,   {&smtp_accept_max_per_host} },
   { "smtp_accept_queue",        opt_int,         {&smtp_accept_queue} },
   { "smtp_accept_queue_per_connection", opt_int, {&smtp_accept_queue_per_connection} },
   { "smtp_accept_max_per_host", opt_stringptr,   {&smtp_accept_max_per_host} },
   { "smtp_accept_queue",        opt_int,         {&smtp_accept_queue} },
   { "smtp_accept_queue_per_connection", opt_int, {&smtp_accept_queue_per_connection} },
index 6d6370ffd9d3f2e06e4d67f34be84bf8b8606ede..5888b8037036691c5f24d575103d49f5d83f05b4 100644 (file)
@@ -3879,6 +3879,13 @@ cmd_list[CMD_LIST_RSET].is_mail_cmd = FALSE;
 }
 
 
 }
 
 
+static int
+expand_mailmax(const uschar * s)
+{
+if (!(s = expand_cstring(s)))
+  log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand smtp_accept_max_per_connection");
+return *s ? Uatoi(s) : 0;
+}
 
 /*************************************************
 *       Initialize for SMTP incoming message     *
 
 /*************************************************
 *       Initialize for SMTP incoming message     *
@@ -3909,6 +3916,7 @@ int
 smtp_setup_msg(void)
 {
 int done = 0;
 smtp_setup_msg(void)
 {
 int done = 0;
+int mailmax = -1;
 BOOL toomany = FALSE;
 BOOL discarded = FALSE;
 BOOL last_was_rej_mail = FALSE;
 BOOL toomany = FALSE;
 BOOL discarded = FALSE;
 BOOL last_was_rej_mail = FALSE;
@@ -4266,6 +4274,9 @@ while (done <= 0)
       fl.smtputf8_advertised = FALSE;
 #endif
 
       fl.smtputf8_advertised = FALSE;
 #endif
 
+      /* Expand the per-connection message count limit option */
+      mailmax = expand_mailmax(smtp_accept_max_per_connection);
+
       smtp_code = US"250 ";        /* Default response code plus space*/
       if (!user_msg)
        {
       smtp_code = US"250 ";        /* Default response code plus space*/
       if (!user_msg)
        {
@@ -4541,13 +4552,16 @@ while (done <= 0)
       was_rej_mail = TRUE;               /* Reset if accepted */
       env_mail_type_t * mail_args;       /* Sanity check & validate args */
 
       was_rej_mail = TRUE;               /* Reset if accepted */
       env_mail_type_t * mail_args;       /* Sanity check & validate args */
 
-      if (fl.helo_required && !fl.helo_seen)
-       {
-       smtp_printf("503 HELO or EHLO required\r\n", FALSE);
-       log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no "
-         "HELO/EHLO given", host_and_ident(FALSE));
-       break;
-       }
+      if (!fl.helo_seen)
+       if (fl.helo_required)
+         {
+         smtp_printf("503 HELO or EHLO required\r\n", FALSE);
+         log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no "
+           "HELO/EHLO given", host_and_ident(FALSE));
+         break;
+         }
+       else if (mailmax < 0)
+         mailmax = expand_mailmax(smtp_accept_max_per_connection);
 
       if (sender_address)
        {
 
       if (sender_address)
        {
@@ -4566,8 +4580,7 @@ while (done <= 0)
       /* Check to see if the limit for messages per connection would be
       exceeded by accepting further messages. */
 
       /* Check to see if the limit for messages per connection would be
       exceeded by accepting further messages. */
 
-      if (smtp_accept_max_per_connection > 0 &&
-         smtp_mailcmd_count > smtp_accept_max_per_connection)
+      if (mailmax > 0 && smtp_mailcmd_count > mailmax)
        {
        smtp_printf("421 too many messages in this connection\r\n", FALSE);
        log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL command %s: too many "
        {
        smtp_printf("421 too many messages in this connection\r\n", FALSE);
        log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL command %s: too many "