[exim-cvs] Expand recipients_max

Αρχική Σελίδα
Delete this message
Reply to this message
Συντάκτης: Exim Git Commits Mailing List
Ημερομηνία:  
Προς: exim-cvs
Αντικείμενο: [exim-cvs] Expand recipients_max
Gitweb: https://git.exim.org/exim.git/commitdiff/cd19f9a79c20f9c0c9d650a8aa21d9cc54a66620
Commit:     cd19f9a79c20f9c0c9d650a8aa21d9cc54a66620
Parent:     a173a4376d168edbf3fe2494dff998c4060bf425
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Sun Feb 11 23:32:34 2024 +0000
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Tue Feb 13 18:32:04 2024 +0000


    Expand recipients_max
---
 doc/doc-docbook/spec.xfpt           | 14 ++++++++++++--
 doc/doc-txt/NewStuff                |  2 ++
 doc/doc-txt/OptionLists.txt         |  2 +-
 src/src/exim.c                      | 30 ++++++++++++++++++++++--------
 src/src/globals.c                   |  3 ++-
 src/src/globals.h                   |  3 ++-
 src/src/moan.c                      |  2 +-
 src/src/readconf.c                  |  2 +-
 src/src/receive.c                   |  8 +++++---
 src/src/smtp_in.c                   | 16 +++++++++++-----
 test/confs/0289                     |  4 ++++
 test/log/0289                       |  7 +++++++
 test/log/4710                       |  2 ++
 test/mail/0289.CALLER               | 21 +++++++++++++++++++++
 test/mail/0289.userx                | 10 ++++++++++
 test/mail/0289.usery                | 10 ++++++++++
 test/scripts/0000-Basic/0289        | 11 +++++++++++
 test/scripts/4710-esmtp-limits/4710 | 23 +++++++++++++++++++++++
 test/stdout/4710                    | 26 ++++++++++++++++++++++++++
 19 files changed, 173 insertions(+), 23 deletions(-)


diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 902f8e72f..316860aae 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -17472,16 +17472,26 @@ or if the message was submitted locally (not using TCP/IP), and the &%-bnq%&
option was not set.


-.option recipients_max main integer 50000
+.option recipients_max main integer&!! 50000
.cindex "limit" "number of recipients"
.cindex "recipient" "maximum number"
-If this option is set greater than zero, it specifies the maximum number of
+If the value resulting from expanding this option
+is set greater than zero, it specifies the maximum number of
original recipients for any message. Additional recipients that are generated
by aliasing or forwarding do not count. SMTP messages get a 452 response for
all recipients over the limit; earlier recipients are delivered as normal.
Non-SMTP messages with too many recipients are failed, and no deliveries are
done.

+.new
+For SMTP message the expansion is done after the connection is
+accepted (but before any SMTP conversation) and may depend on
+the IP addresses and port numbers of the connection.
+&*Note*&: If an expansion is used for the option,
+care should be taken that a resonable value results for
+non-SMTP messages.
+.wen
+
 .cindex "RCPT" "maximum number of incoming"
 &*Note*&: The RFCs specify that an SMTP server should accept at least 100
 RCPT commands in a single message.
diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index ad385b9ec..2439b3137 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -16,6 +16,8 @@ Version 4.98
     timestamp but no extiry timestamp.  Code by Simon Arlott; testsuite
     additions by jgh.


+ 4. The recipients_max main option is now expanded.
+
Version 4.97
------------

diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 4d7117697..987f096ba 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -475,7 +475,7 @@ receive_timeout                      time            0s            main
 received_header_text                 string*         +             main
 received_headers_max                 integer         30            main
 recipient_unqualified_hosts          host list       unset         main              4.00 replacing receiver_unqualified_hosts
-recipients_max                       integer         50000         main              1.60 default changed in 4.95 (was 0)
+recipients_max                       integer*        50000         main              1.60 default changed in 4.95 (was 0)
 recipients_max_reject                boolean         false         main              1.70
 redirect_router                      string          unset         routers           4.00
 remote_max_parallel                  integer         1             main
diff --git a/src/src/exim.c b/src/src/exim.c
index 1f76f8f14..10fc98963 100644
--- a/src/src/exim.c
+++ b/src/src/exim.c
@@ -5339,6 +5339,7 @@ if (expansion_test)


   else if (expansion_test_message)
     {
+    uschar * rme = expand_string(recipients_max);
     int save_stdin = dup(0);
     int fd = Uopen(expansion_test_message, O_RDONLY, 0);
     if (fd < 0)
@@ -5347,6 +5348,7 @@ if (expansion_test)
     (void) dup2(fd, 0);
     filter_test = FTEST_USER;      /* Fudge to make it look like filter test */
     message_ended = END_NOTENDED;
+    recipients_max_expanded = atoi(CCS rme);
     read_message_body(receive_msg(extract_recipients));
     message_linecount += body_linecount;
     (void)dup2(save_stdin, 0);
@@ -5753,8 +5755,8 @@ for (BOOL more = TRUE; more; )
     int rc;
     if ((rc = smtp_setup_msg()) > 0)
       {
-      if (real_sender_address != NULL &&
-          !receive_check_set_sender(sender_address))
+      if (   real_sender_address
+      && !receive_check_set_sender(sender_address))
         {
         sender_address = raw_sender = real_sender_address;
         sender_address_unrewritten = NULL;
@@ -5801,10 +5803,12 @@ for (BOOL more = TRUE; more; )


   else
     {
-    int rcount = 0;
-    int count = argc - recipients_arg;
+    uschar * rme = expand_string(recipients_max);
+    int rcount = 0, count = argc - recipients_arg;
     const uschar ** list = argv + recipients_arg;


+    recipients_max_expanded = atoi(CCS rme);
+
     /* These options cannot be changed dynamically for non-SMTP messages */


     f.active_local_sender_retain = local_sender_retain;
@@ -5831,15 +5835,19 @@ for (BOOL more = TRUE; more; )
       while (*s)
         {
         BOOL finished = FALSE;
-        uschar *recipient;
-        uschar *ss = parse_find_address_end(s, FALSE);
+        uschar * recipient;
+        uschar * ss = parse_find_address_end(s, FALSE);


         if (*ss == ',') *ss = 0; else finished = TRUE;


         /* Check max recipients - if -t was used, these aren't recipients */


-        if (recipients_max > 0 && ++rcount > recipients_max &&
-            !extract_recipients)
+        if (  recipients_max_expanded > 0 && ++rcount > recipients_max_expanded
+       && !extract_recipients)
+      {
+      DEBUG(D_all) debug_printf("excess reipients (max %d)\n",
+        recipients_max_expanded);
+
           if (error_handling == ERRORS_STDERR)
             {
             fprintf(stderr, "exim: too many recipients\n");
@@ -5849,6 +5857,7 @@ for (BOOL more = TRUE; more; )
             return
               moan_to_sender(ERRMESS_TOOMANYRECIP, NULL, NULL, stdin, TRUE)?
                 errors_sender_rc : EXIT_FAILURE;
+      }


 #ifdef SUPPORT_I18N
     {
@@ -5873,6 +5882,10 @@ for (BOOL more = TRUE; more; )
           }


         if (!recipient)
+      {
+      DEBUG(D_all) debug_printf("bad recipient address \"%s\": %s\n",
+        string_printing(list[i]), errmess);
+
           if (error_handling == ERRORS_STDERR)
             {
             fprintf(stderr, "exim: bad recipient address \"%s\": %s\n",
@@ -5889,6 +5902,7 @@ for (BOOL more = TRUE; more; )
               moan_to_sender(ERRMESS_BADARGADDRESS, &eblock, NULL, stdin, TRUE)?
                 errors_sender_rc : EXIT_FAILURE;
             }
+      }


         receive_add_recipient(string_copy_taint(recipient, GET_TAINTED), -1);
         s = ss;
diff --git a/src/src/globals.c b/src/src/globals.c
index c483ab182..4af8668f0 100644
--- a/src/src/globals.c
+++ b/src/src/globals.c
@@ -1322,7 +1322,8 @@ uschar *recipient_verify_failure = NULL;
 int     recipients_count       = 0;
 recipient_item  *recipients_list = NULL;
 int     recipients_list_max    = 0;
-int     recipients_max         = 50000;
+uschar *recipients_max         = US"50000";
+int     recipients_max_expanded= 0;
 const pcre2_code *regex_AUTH         = NULL;
 const pcre2_code *regex_check_dns_names = NULL;
 const pcre2_code *regex_From         = NULL;
diff --git a/src/src/globals.h b/src/src/globals.h
index b5c3a520e..427590050 100644
--- a/src/src/globals.h
+++ b/src/src/globals.h
@@ -895,7 +895,8 @@ extern uschar *recipient_data;         /* lookup data for recipients */
 extern uschar *recipient_unqualified_hosts; /* Permitted unqualified recipients */
 extern uschar *recipient_verify_failure; /* What went wrong */
 extern int     recipients_list_max;    /* Maximum number fitting in list */
-extern int     recipients_max;         /* Max permitted */
+extern uschar *recipients_max;         /* Max permitted */
+extern int     recipients_max_expanded;
 extern BOOL    recipients_max_reject;  /* If TRUE, reject whole message */
 extern const pcre2_code *regex_AUTH;         /* For recognizing AUTH settings */
 extern const pcre2_code  *regex_check_dns_names; /* For DNS name checking */
diff --git a/src/src/moan.c b/src/src/moan.c
index c2e38d4f7..a3c8e0aba 100644
--- a/src/src/moan.c
+++ b/src/src/moan.c
@@ -561,7 +561,7 @@ switch(ident)


   case ERRMESS_TOOMANYRECIP:
   log_write(0, LOG_MAIN, "%s: too many recipients (max set to %d)", msg,
-    recipients_max);
+    recipients_max_expanded);
   break;


   case ERRMESS_LOCAL_SCAN:
diff --git a/src/src/readconf.c b/src/src/readconf.c
index 8ee6e9fe0..5b486d0b6 100644
--- a/src/src/readconf.c
+++ b/src/src/readconf.c
@@ -293,7 +293,7 @@ static optionlist optionlist_config[] = {
   { "received_header_text",     opt_stringptr,   {&received_header_text} },
   { "received_headers_max",     opt_int,         {&received_headers_max} },
   { "recipient_unqualified_hosts", opt_stringptr, {&recipient_unqualified_hosts} },
-  { "recipients_max",           opt_int,         {&recipients_max} },
+  { "recipients_max",           opt_stringptr,   {&recipients_max} },
   { "recipients_max_reject",    opt_bool,        {&recipients_max_reject} },
 #ifdef LOOKUP_REDIS
   { "redis_servers",            opt_stringptr,   {&redis_servers} },
diff --git a/src/src/receive.c b/src/src/receive.c
index ae4203e7f..990b9c22e 100644
--- a/src/src/receive.c
+++ b/src/src/receive.c
@@ -1204,6 +1204,8 @@ static void
 give_local_error(int errcode, uschar *text1, uschar *text2, int error_rc,
   FILE *f, header_line *hptr)
 {
+DEBUG(D_all) debug_printf("%s%s\n", text2, text1);
+
 if (error_handling == ERRORS_SENDER)
   {
   error_block eblock;
@@ -2622,12 +2624,12 @@ if (extract_recip)
     if ((h->type == htype_to || h->type == htype_cc || h->type == htype_bcc) &&
         (!contains_resent_headers || strncmpic(h->text, US"resent-", 7) == 0))
       {
-      uschar *s = Ustrchr(h->text, ':') + 1;
+      uschar * s = Ustrchr(h->text, ':') + 1;
       while (isspace(*s)) s++;


       f.parse_allow_group = TRUE;          /* Allow address group syntax */


-      while (*s != 0)
+      while (*s)
         {
         uschar *ss = parse_find_address_end(s, FALSE);
         uschar *recipient, *errmess, *pp;
@@ -2635,7 +2637,7 @@ if (extract_recip)


         /* Check on maximum */


-        if (recipients_max > 0 && ++rcount > recipients_max)
+        if (recipients_max_expanded > 0 && ++rcount > recipients_max_expanded)
           give_local_error(ERRMESS_TOOMANYRECIP, US"too many recipients",
             US"message rejected: ", error_rc, stdin, NULL);
           /* Does not return */
diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c
index a57c9821e..1d4c232a5 100644
--- a/src/src/smtp_in.c
+++ b/src/src/smtp_in.c
@@ -1879,7 +1879,7 @@ while (done <= 0)
       if (recipients_max > 0 && recipients_count + 1 > recipients_max)
     /* The function moan_smtp_batch() does not return. */
     moan_smtp_batch(smtp_cmd_buffer, "%s too many recipients",
-      recipients_max_reject? "552": "452");
+      recipients_max_reject ? "552": "452");


       /* Apply SMTP rewrite, then extract address. Don't allow "<>" as a
       recipient address */
@@ -2540,6 +2540,11 @@ if (!f.sender_host_unknown)
   fl.helo_accept_junk = verify_check_host(&helo_accept_junk_hosts) == OK;
   }


+/* Expand recipients_max, if needed */
+ {
+ uschar * rme = expand_string(recipients_max);
+ recipients_max_expanded = atoi(CCS rme);
+ }
/* For batch SMTP input we are now done. */

 if (smtp_batched_input) return TRUE;
@@ -4055,14 +4060,14 @@ while (done <= 0)
       }


 #ifndef DISABLE_ESMTP_LIMITS
-    if (  (smtp_mailcmd_max > 0 || recipients_max)
+    if (  (smtp_mailcmd_max > 0 || recipients_max_expanded > 0)
        && verify_check_host(&limits_advertise_hosts) == OK)
       {
       g = string_fmt_append(g, "%.3s-LIMITS", smtp_code);
       if (smtp_mailcmd_max > 0)
         g = string_fmt_append(g, " MAILMAX=%d", smtp_mailcmd_max);
-      if (recipients_max)
-        g = string_fmt_append(g, " RCPTMAX=%d", recipients_max);
+      if (recipients_max > 9)
+        g = string_fmt_append(g, " RCPTMAX=%d", recipients_max_expanded);
       g = string_catn(g, US"\r\n", 2);
       }
 #endif
@@ -4900,7 +4905,8 @@ while (done <= 0)


       /* Check maximum allowed */


-      if (rcpt_count+1 < 0 || rcpt_count > recipients_max && recipients_max > 0)
+      if (  rcpt_count+1 < 0
+         || rcpt_count > recipients_max_expanded && recipients_max_expanded > 0)
     {
     if (recipients_max_reject)
       {
diff --git a/test/confs/0289 b/test/confs/0289
index 44e40a528..a96799690 100644
--- a/test/confs/0289
+++ b/test/confs/0289
@@ -8,7 +8,11 @@ primary_hostname = myhost.test.ex
 # ----- Main settings -----


acl_smtp_rcpt = accept
+.ifdef DYNAMIC_OPTION
+recipients_max = ${if def:sender_host_address {1}{2}}
+.else
recipients_max = 1
+.endif


# ------ Routers ------
diff --git a/test/log/0289 b/test/log/0289
index 15064bcdb..e79c3e25e 100644
--- a/test/log/0289
+++ b/test/log/0289
@@ -1,3 +1,10 @@
1999-03-02 09:44:33 10HmaX-000000005vi-0000 <= <> U=EXIMUSER P=local S=sss
1999-03-02 09:44:33 10HmaX-000000005vi-0000 => CALLER <CALLER@???> R=r1 T=local_delivery
1999-03-02 09:44:33 10HmaX-000000005vi-0000 Completed
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 => userx <userx@???> R=r1 T=local_delivery
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 => usery <usery@???> R=r1 T=local_delivery
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 Completed
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 <= <> U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 => CALLER <CALLER@???> R=r1 T=local_delivery
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 Completed
diff --git a/test/log/4710 b/test/log/4710
index 3937611b8..99934ebf5 100644
--- a/test/log/4710
+++ b/test/log/4710
@@ -4,3 +4,5 @@
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1237, no queue runs, listening for SMTP on port PORT_D
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1238, no queue runs, listening for SMTP on port PORT_D
1999-03-02 09:44:33 exim x.yz daemon started: pid=p1239, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 exim x.yz daemon started: pid=p1240, no queue runs, listening for SMTP on port PORT_D
+1999-03-02 09:44:33 exim x.yz daemon started: pid=p1241, no queue runs, listening for SMTP on port PORT_D
diff --git a/test/mail/0289.CALLER b/test/mail/0289.CALLER
index 2ba67d12b..3dc4f79ba 100644
--- a/test/mail/0289.CALLER
+++ b/test/mail/0289.CALLER
@@ -21,3 +21,24 @@ From: me
Body
.

+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
+    id 10HmaZ-000000005vi-0000
+    for CALLER@???;
+    Tue, 2 Mar 1999 09:44:33 +0000
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@???>
+To: CALLER@???
+Subject: Mail failure - too many recipients
+Message-Id: <E10HmaZ-000000005vi-0000@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+A message that you sent contained more recipients than allowed on this
+system. It was not delivered to any recipients.
+
+------ This is a copy of your message, including all the headers. ------
+
+
+From: me
+.
+
diff --git a/test/mail/0289.userx b/test/mail/0289.userx
new file mode 100644
index 000000000..a789fc76e
--- /dev/null
+++ b/test/mail/0289.userx
@@ -0,0 +1,10 @@
+From CALLER@??? Tue Mar 02 09:44:33 1999
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+    (envelope-from <CALLER@???>)
+    id 10HmaY-000000005vi-0000;
+    Tue, 2 Mar 1999 09:44:33 +0000
+From: me@???
+Message-Id: <E10HmaY-000000005vi-0000@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
diff --git a/test/mail/0289.usery b/test/mail/0289.usery
new file mode 100644
index 000000000..a789fc76e
--- /dev/null
+++ b/test/mail/0289.usery
@@ -0,0 +1,10 @@
+From CALLER@??? Tue Mar 02 09:44:33 1999
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+    (envelope-from <CALLER@???>)
+    id 10HmaY-000000005vi-0000;
+    Tue, 2 Mar 1999 09:44:33 +0000
+From: me@???
+Message-Id: <E10HmaY-000000005vi-0000@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
diff --git a/test/scripts/0000-Basic/0289 b/test/scripts/0000-Basic/0289
index 2483b3706..f768b80d0 100644
--- a/test/scripts/0000-Basic/0289
+++ b/test/scripts/0000-Basic/0289
@@ -13,3 +13,14 @@ From: me
 Body
 .
 ****
+#
+# recipients_max should be expanded (here, for non-SMTP)
+exim -DDYNAMIC_OPTION -odi userx usery
+From: me
+.
+****
+1
+exim -odi -DDYNAMIC_OPTION userx usery userz
+From: me
+.
+****
diff --git a/test/scripts/4710-esmtp-limits/4710 b/test/scripts/4710-esmtp-limits/4710
index 875613cab..a5b9a6a6c 100644
--- a/test/scripts/4710-esmtp-limits/4710
+++ b/test/scripts/4710-esmtp-limits/4710
@@ -84,3 +84,26 @@ EHLO tester
 ??? 250
 ****
 killdaemon
+# recipients_max is expanded (at least for smtp)
+exim -DSERVER=server -DRCPT_MSG='${if eq {$sender_host_address}{HOSTIPV4}{4}{100}}' -bd -oX PORT_D
+****
+client HOSTIPV4 PORT_D
+??? 220
+EHLO tester
+??? 250-
+??? 250-SIZE
+??? 250-LIMITS MAILMAX=1000 RCPTMAX=4
+??? 250
+****
+killdaemon
+exim -DSERVER=server -DRCPT_MSG='${if eq {$sender_host_address}{HOSTIPV4}{4}{100}}' -bd -oX PORT_D
+****
+client 127.0.0.1 PORT_D
+??? 220
+EHLO tester
+??? 250-
+??? 250-SIZE
+??? 250-LIMITS MAILMAX=1000 RCPTMAX=100
+??? 250
+****
+killdaemon
diff --git a/test/stdout/4710 b/test/stdout/4710
index 701b4376c..7e031e244 100644
--- a/test/stdout/4710
+++ b/test/stdout/4710
@@ -85,3 +85,29 @@ Connecting to 127.0.0.1 port 1225 ... connected
 ??? 250
 <<< 250-8BITMIME
 End of script
+Connecting to ip4.ip4.ip4.ip4 port 1225 ... connected
+??? 220
+<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO tester
+??? 250-
+<<< 250-myhost.test.ex Hello tester [ip4.ip4.ip4.ip4]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-LIMITS MAILMAX=1000 RCPTMAX=4
+<<< 250-LIMITS MAILMAX=1000 RCPTMAX=4
+??? 250
+<<< 250-8BITMIME
+End of script
+Connecting to 127.0.0.1 port 1225 ... connected
+??? 220
+<<< 220 myhost.test.ex ESMTP Exim x.yz Tue, 2 Mar 1999 09:44:33 +0000
+>>> EHLO tester
+??? 250-
+<<< 250-myhost.test.ex Hello tester [127.0.0.1]
+??? 250-SIZE
+<<< 250-SIZE 52428800
+??? 250-LIMITS MAILMAX=1000 RCPTMAX=100
+<<< 250-LIMITS MAILMAX=1000 RCPTMAX=100
+??? 250
+<<< 250-8BITMIME
+End of script


--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/