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.
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
------------
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
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)
(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);
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;
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;
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");
return
moan_to_sender(ERRMESS_TOOMANYRECIP, NULL, NULL, stdin, TRUE)?
errors_sender_rc : EXIT_FAILURE;
+ }
#ifdef SUPPORT_I18N
{
}
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",
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;
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;
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 */
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:
{ "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} },
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;
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;
/* 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 */
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 */
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;
}
#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
/* 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)
{
# ----- Main settings -----
acl_smtp_rcpt = accept
+.ifdef DYNAMIC_OPTION
+recipients_max = ${if def:sender_host_address {1}{2}}
+.else
recipients_max = 1
+.endif
# ------ Routers ------
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@myhost.test.ex> 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@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 => userx <userx@myhost.test.ex> R=r1 T=local_delivery
+1999-03-02 09:44:33 10HmaY-000000005vi-0000 => usery <usery@myhost.test.ex> 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@myhost.test.ex> R=r1 T=local_delivery
+1999-03-02 09:44:33 10HmaZ-000000005vi-0000 Completed
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
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@myhost.test.ex;
+ Tue, 2 Mar 1999 09:44:33 +0000
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@myhost.test.ex>
+To: CALLER@myhost.test.ex
+Subject: Mail failure - too many recipients
+Message-Id: <E10HmaZ-000000005vi-0000@myhost.test.ex>
+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
+.
+
--- /dev/null
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmaY-000000005vi-0000;
+ Tue, 2 Mar 1999 09:44:33 +0000
+From: me@myhost.test.ex
+Message-Id: <E10HmaY-000000005vi-0000@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
--- /dev/null
+From CALLER@myhost.test.ex Tue Mar 02 09:44:33 1999
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+ (envelope-from <CALLER@myhost.test.ex>)
+ id 10HmaY-000000005vi-0000;
+ Tue, 2 Mar 1999 09:44:33 +0000
+From: me@myhost.test.ex
+Message-Id: <E10HmaY-000000005vi-0000@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
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
+.
+****
??? 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
??? 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