* Exim - an Internet mail transport agent *
*************************************************/
-/* Copyright (c) The Exim Maintainers 2020 - 2022 */
+/* Copyright (c) The Exim Maintainers 2020 - 2023 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
/* See the file NOTICE for conditions of use and distribution. */
/* SPDX-License-Identifier: GPL-2.0-or-later */
return EOD;
}
- smtp_printf("250 %u byte chunk received\r\n", FALSE, chunking_datasize);
+ smtp_printf("250 %u byte chunk received\r\n", SP_NO_MORE, chunking_datasize);
chunking_state = CHUNKING_OFFERED;
DEBUG(D_receive) debug_printf("chunking state %d\n", (int)chunking_state);
case NOOP_CMD:
HAD(SCH_NOOP);
- smtp_printf("250 OK\r\n", FALSE);
+ smtp_printf("250 OK\r\n", SP_NO_MORE);
goto next_cmd;
case BDAT_CMD:
{
if (!smtp_in || smtp_batched_input) return;
receive_swallow_smtp();
-smtp_printf("421 %s\r\n", FALSE, message);
+smtp_printf("421 %s\r\n", SP_NO_MORE, message);
for (;;) switch(smtp_read_command(FALSE, GETC_BUFFER_UNLIMITED))
{
case QUIT_CMD:
f.smtp_in_quit = TRUE;
- smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
+ smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname);
mac_smtp_fflush();
return;
case RSET_CMD:
- smtp_printf("250 Reset OK\r\n", FALSE);
+ smtp_printf("250 Reset OK\r\n", SP_NO_MORE);
break;
default:
- smtp_printf("421 %s\r\n", FALSE, message);
+ smtp_printf("421 %s\r\n", SP_NO_MORE, message);
break;
}
}
{
const uschar * hostname = sender_fullhost
? sender_fullhost : sender_host_address;
+gstring * g = string_catn(NULL, US"SMTP connection", 15);
+
+if (LOGGING(connection_id))
+ g = string_fmt_append(g, " Ci=%lu", connection_id);
+g = string_catn(g, US" from ", 6);
if (host_checking)
- return string_sprintf("SMTP connection from %s", hostname);
+ g = string_cat(g, hostname);
+
+else if (f.sender_host_unknown || f.sender_host_notsocket)
+ g = string_cat(g, sender_ident ? sender_ident : US"NULL");
-if (f.sender_host_unknown || f.sender_host_notsocket)
- return string_sprintf("SMTP connection from %s", sender_ident);
+else if (f.is_inetd)
+ g = string_append(g, 2, hostname, US" (via inetd)");
-if (f.is_inetd)
- return string_sprintf("SMTP connection from %s (via inetd)", hostname);
+else if (LOGGING(incoming_interface) && interface_address)
+ g = string_fmt_append(g, "%s I=[%s]:%d", hostname, interface_address, interface_port);
-if (LOGGING(incoming_interface) && interface_address)
- return string_sprintf("SMTP connection from %s I=[%s]:%d", hostname,
- interface_address, interface_port);
+else
+ g = string_cat(g, hostname);
-return string_sprintf("SMTP connection from %s", hostname);
+gstring_release_unused(g);
+return string_from_gstring(g);
}
/* Check maximum number allowed */
- if (recipients_max > 0 && recipients_count + 1 > recipients_max)
+ if ( recipients_max_expanded > 0
+ && recipients_count + 1 > recipients_max_expanded)
/* 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 */
static void
log_connect_tls_drop(const uschar * what, const uschar * log_msg)
{
-gstring * g = s_tlslog(NULL);
-uschar * tls = string_from_gstring(g);
-
-log_write(L_connection_reject,
- log_reject_target, "%s%s%s dropped by %s%s%s",
- LOGGING(dnssec) && sender_host_dnssec ? US" DS" : US"",
- host_and_ident(TRUE),
- tls ? tls : US"",
- what,
- log_msg ? US": " : US"", log_msg);
+if (log_reject_target)
+ {
+ gstring * g = s_tlslog(NULL);
+ uschar * tls = string_from_gstring(g);
+
+ log_write(L_connection_reject,
+ log_reject_target, "%s%s%s dropped by %s%s%s",
+ LOGGING(dnssec) && sender_host_dnssec ? US" DS" : US"",
+ host_and_ident(TRUE),
+ tls ? tls : US"",
+ what,
+ log_msg ? US": " : US"", log_msg);
+ }
}
/* Set up the message size limit; this may be host-specific */
+GET_OPTION("message_size_limit");
thismessage_size_limit = expand_string_integer(message_size_limit, TRUE);
if (expand_string_message)
{
{
log_write(0, LOG_MAIN, "getsockopt() failed from %s: %s",
host_and_ident(FALSE), strerror(errno));
- smtp_printf("451 SMTP service not available\r\n", FALSE);
+ smtp_printf("451 SMTP service not available\r\n", SP_NO_MORE);
return FALSE;
}
}
log_write(0, LOG_MAIN|LOG_REJECT,
"connection from %s refused (IP options)", host_and_ident(FALSE));
- smtp_printf("554 SMTP service not available\r\n", FALSE);
+ smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE);
return FALSE;
}
#ifndef DISABLE_TLS
if (!tls_in.on_connect)
#endif
- smtp_printf("554 SMTP service not available\r\n", FALSE);
+ smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE);
return FALSE;
}
log_write(L_connection_reject,
LOG_MAIN|LOG_REJECT, "refused connection from %s "
"(tcp wrappers)", host_and_ident(FALSE));
- smtp_printf("554 SMTP service not available\r\n", FALSE);
+ smtp_printf("554 SMTP service not available\r\n", SP_NO_MORE);
}
else
{
log_write(L_connection_reject,
LOG_MAIN|LOG_REJECT, "temporarily refused connection from %s "
"(tcp wrappers errno=%d)", host_and_ident(FALSE), save_errno);
- smtp_printf("451 Temporary local problem - please try later\r\n", FALSE);
+ smtp_printf("451 Temporary local problem - please try later\r\n", SP_NO_MORE);
}
return FALSE;
}
host_and_ident(FALSE), smtp_accept_count - 1, smtp_accept_max,
smtp_accept_reserve, (rc == DEFER)? " (lookup deferred)" : "");
smtp_printf("421 %s: Too many concurrent SMTP connections; "
- "please try again later\r\n", FALSE, smtp_active_hostname);
+ "please try again later\r\n", SP_NO_MORE, smtp_active_hostname);
return FALSE;
}
reserved_host = TRUE;
LOG_MAIN, "temporarily refused connection from %s: not in "
"reserve list and load average = %.2f", host_and_ident(FALSE),
(double)load_average/1000.0);
- smtp_printf("421 %s: Too much load; please try again later\r\n", FALSE,
+ smtp_printf("421 %s: Too much load; please try again later\r\n", SP_NO_MORE,
smtp_active_hostname);
return FALSE;
}
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;
/* Run the connect ACL if it exists */
user_msg = NULL;
+GET_OPTION("acl_smtp_connect");
if (acl_smtp_connect)
{
int rc;
esclen = codelen - 4;
}
}
-else if (!(s = expand_string(smtp_banner)))
+else
{
- log_write(0, f.expand_string_forcedfail ? LOG_MAIN : LOG_MAIN|LOG_PANIC_DIE,
- "Expansion of \"%s\" (smtp_banner) failed: %s",
- smtp_banner, expand_string_message);
- /* for force-fail */
-#ifndef DISABLE_TLS
- if (tls_in.on_connect) tls_close(NULL, TLS_SHUTDOWN_WAIT);
-#endif
- return FALSE;
+ GET_OPTION("smtp_banner");
+ if (!(s = expand_string(smtp_banner)))
+ {
+ log_write(0, f.expand_string_forcedfail ? LOG_MAIN : LOG_MAIN|LOG_PANIC_DIE,
+ "Expansion of \"%s\" (smtp_banner) failed: %s",
+ smtp_banner, expand_string_message);
+ /* for force-fail */
+ #ifndef DISABLE_TLS
+ if (tls_in.on_connect) tls_close(NULL, TLS_SHUTDOWN_WAIT);
+ #endif
+ return FALSE;
+ }
}
/* Remove any terminating newlines; might as well remove trailing space too */
"synchronization error (input sent without waiting for greeting): "
"rejected connection from %s input=\"%s\"", host_and_ident(TRUE),
string_printing(string_copyn(smtp_inptr, n)));
- smtp_printf("554 SMTP synchronization error\r\n", FALSE);
+ smtp_printf("554 SMTP synchronization error\r\n", SP_NO_MORE);
return FALSE;
}
/* Now output the banner */
/*XXX the ehlo-resp code does its own tls/nontls bit. Maybe subroutine that? */
-smtp_printf("%s",
+smtp_printf("%Y",
#ifndef DISABLE_PIPE_CONNECT
fl.pipe_connect_acceptable && pipeline_connect_sends(),
#else
- FALSE,
+ SP_NO_MORE,
#endif
- string_from_gstring(ss));
+ ss);
/* Attempt to see if we sent the banner before the last ACK of the 3-way
handshake arrived. If so we must have managed a TFO. */
{
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)",
+ "syntax or protocol errors (last command was \"%s\", %Y)",
host_and_ident(FALSE), string_printing(smtp_cmd_buffer),
- string_from_gstring(s_connhad_log(NULL))
+ s_connhad_log(NULL)
);
}
if (code > 0)
{
- smtp_printf("%d%c%s%s%s\r\n", FALSE, code, yield == 1 ? '-' : ' ',
+ smtp_printf("%d%c%s%s%s\r\n", SP_NO_MORE, code, yield == 1 ? '-' : ' ',
data ? data : US"", data ? US": " : US"", errmess);
if (yield == 1)
- smtp_printf("%d Too many syntax or protocol errors\r\n", FALSE, code);
+ smtp_printf("%d Too many syntax or protocol errors\r\n", SP_NO_MORE, code);
}
return yield;
*/
void
-smtp_respond(uschar* code, int codelen, BOOL final, uschar *msg)
+smtp_respond(uschar * code, int codelen, BOOL final, uschar * msg)
{
int esclen = 0;
uschar *esc = US"";
}
else
{
- smtp_printf("%.3s-%.*s%.*s\r\n", TRUE, code, esclen, esc, (int)(nl - msg), msg);
+ smtp_printf("%.3s-%.*s%.*s\r\n", SP_MORE, code, esclen, esc, (int)(nl - msg), msg);
msg = nl + 1;
Uskip_whitespace(&msg);
}
*/
int
-smtp_handle_acl_fail(int where, int rc, uschar *user_msg, uschar *log_msg)
+smtp_handle_acl_fail(int where, int rc, uschar * user_msg, uschar * log_msg)
{
BOOL drop = rc == FAIL_DROP;
int codelen = 3;
string_sprintf(": %s", sender_verified_failed->message));
if (rc == FAIL && sender_verified_failed->user_message)
- smtp_respond(smtp_code, codelen, FALSE, string_sprintf(
+ smtp_respond(smtp_code, codelen, SR_NOT_FINAL, string_sprintf(
testflag(sender_verified_failed, af_verify_pmfail)?
"Postmaster verification failed while checking <%s>\n%s\n"
"Several RFCs state that you are required to have a postmaster\n"
rc was FAIL_DROP we drop the connection and yield 2. */
if (rc == FAIL)
- smtp_respond(smtp_code, codelen, TRUE,
+ smtp_respond(smtp_code, codelen, SR_FINAL,
user_msg ? user_msg : US"Administrative prohibition");
/* Send temporary failure response to the command. Don't give any details,
&& sender_verified_failed
&& sender_verified_failed->message
)
- smtp_respond(smtp_code, codelen, FALSE, sender_verified_failed->message);
+ smtp_respond(smtp_code, codelen, SR_NOT_FINAL, sender_verified_failed->message);
- smtp_respond(smtp_code, codelen, TRUE, user_msg);
+ smtp_respond(smtp_code, codelen, SR_FINAL, user_msg);
}
else
- smtp_respond(smtp_code, codelen, TRUE,
+ smtp_respond(smtp_code, codelen, SR_FINAL,
US"Temporary local problem - please try later");
/* Log the incident to the logs that are specified by log_reject_target
the connection is not forcibly to be dropped, return 0. Otherwise, log why it
is closing if required and return 2. */
-if (log_reject_target != 0)
+if (log_reject_target)
{
#ifndef DISABLE_TLS
gstring * g = s_tlslog(NULL);
/* Call the not-QUIT ACL, if there is one, unless no reason is given. */
+GET_OPTION("acl_smtp_notquit");
if (acl_smtp_notquit && reason)
{
smtp_notquit_reason = reason;
if (code && defaultrespond)
{
if (user_msg)
- smtp_respond(code, 3, TRUE, user_msg);
+ smtp_respond(code, 3, SR_FINAL, user_msg);
else
{
gstring * g;
va_start(ap, defaultrespond);
g = string_vformat(NULL, SVFMT_EXTEND|SVFMT_REBUFFER, CS defaultrespond, ap);
va_end(ap);
- smtp_printf("%s %s\r\n", FALSE, code, string_from_gstring(g));
+ smtp_printf("%s %Y\r\n", SP_NO_MORE, code, g);
}
mac_smtp_fflush();
}
{
int len = 3;
smtp_message_code(&code, &len, &user_msg, NULL, TRUE);
-smtp_respond(code, len, TRUE, user_msg);
+smtp_respond(code, len, SR_FINAL, user_msg);
}
*recipient = US rewrite_address_qualify(*recipient, TRUE);
return rd;
}
-smtp_printf("501 %s: recipient address must contain a domain\r\n", FALSE,
+smtp_printf("501 %s: recipient address must contain a domain\r\n", SP_NO_MORE,
smtp_cmd_data);
log_write(L_smtp_syntax_error,
LOG_MAIN|LOG_REJECT, "unqualified %s rejected: <%s> %s%s",
HAD(SCH_QUIT);
f.smtp_in_quit = TRUE;
incomplete_transaction_log(US"QUIT");
+GET_OPTION("acl_smtp_quit");
if ( acl_smtp_quit
&& acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, user_msgp, log_msgp)
== ERROR)
#endif
if (*user_msgp)
- smtp_respond(US"221", 3, TRUE, *user_msgp);
+ smtp_respond(US"221", 3, SR_FINAL, *user_msgp);
else
- smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
+ smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname);
#ifdef SERVERSIDE_CLOSE_NOWAIT
# ifndef DISABLE_TLS
{
HAD(SCH_RSET);
incomplete_transaction_log(US"RSET");
-smtp_printf("250 Reset OK\r\n", FALSE);
+smtp_printf("250 Reset OK\r\n", SP_NO_MORE);
cmd_list[CL_RSET].is_mail_cmd = FALSE;
if (chunking_state > CHUNKING_OFFERED)
chunking_state = CHUNKING_OFFERED;
for (auth_instance * au = auths; au; au = au->next)
if (strcmpic(US"tls", au->driver_name) == 0)
{
+ GET_OPTION("acl_smtp_auth");
if ( acl_smtp_auth
&& (rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth,
&user_msg, &log_msg)) != OK
/* Check the ACL */
+ GET_OPTION("acl_smtp_auth");
if ( acl_smtp_auth
&& (rc = acl_check(ACL_WHERE_AUTH, NULL, acl_smtp_auth,
&user_msg, &log_msg)) != OK
{
int rc = smtp_in_auth(au, &smtp_resp, &errmsg);
- smtp_printf("%s\r\n", FALSE, smtp_resp);
+ smtp_printf("%s\r\n", SP_NO_MORE, smtp_resp);
if (rc != OK)
{
uschar * logmsg = NULL;
if (!check_helo(smtp_cmd_data))
{
- smtp_printf("501 Syntactically invalid %s argument(s)\r\n", FALSE, hello);
+ smtp_printf("501 Syntactically invalid %s argument(s)\r\n", SP_NO_MORE, hello);
log_write(0, LOG_MAIN|LOG_REJECT, "rejected %s from %s: syntactically "
"invalid argument(s): %s", hello, host_and_ident(FALSE),
if (++synprot_error_count > smtp_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)",
+ "syntax or protocol errors (last command was \"%s\", %Y)",
host_and_ident(FALSE), string_printing(smtp_cmd_buffer),
- string_from_gstring(s_connhad_log(NULL))
+ s_connhad_log(NULL)
);
done = 1;
}
{
if (fl.helo_verify_required)
{
- smtp_printf("%d %s argument does not match calling host\r\n", FALSE,
+ smtp_printf("%d %s argument does not match calling host\r\n", SP_NO_MORE,
tempfail? 451 : 550, hello);
log_write(0, LOG_MAIN|LOG_REJECT, "%srejected \"%s %s\" from %s",
tempfail? "temporarily " : "",
/* Apply an ACL check if one is defined; afterwards, recheck
synchronization in case the client started sending in a delay. */
+ GET_OPTION("acl_smtp_helo");
if (acl_smtp_helo)
if ((rc = acl_check(ACL_WHERE_HELO, NULL, acl_smtp_helo,
&user_msg, &log_msg)) != OK)
g = string_catn(g, US"-SIZE\r\n", 7);
}
-#ifdef EXPERIMENTAL_ESMTP_LIMITS
- if ( (smtp_mailcmd_max > 0 || recipients_max)
+#ifndef DISABLE_ESMTP_LIMITS
+ 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_expanded > 0)
+ g = string_fmt_append(g, " RCPTMAX=%d", recipients_max_expanded);
g = string_catn(g, US"\r\n", 2);
}
#endif
/* Advertise ETRN/VRFY/EXPN if there's are ACL checking whether a host is
permitted to issue them; a check is made when any host actually tries. */
+ GET_OPTION("acl_smtp_etrn");
if (acl_smtp_etrn)
{
g = string_catn(g, smtp_code, 3);
g = string_catn(g, US"-ETRN\r\n", 7);
}
+ GET_OPTION("acl_smtp_vrfy");
if (acl_smtp_vrfy)
{
g = string_catn(g, smtp_code, 3);
g = string_catn(g, US"-VRFY\r\n", 7);
}
+ GET_OPTION("acl_smtp_expn");
if (acl_smtp_expn)
{
g = string_catn(g, smtp_code, 3);
done = synprot_error(L_smtp_syntax_error, resp, NULL, errmsg);
else
{
- smtp_printf("%d %s\r\n", FALSE, resp, errmsg);
+ smtp_printf("%d %s\r\n", SP_NO_MORE, resp, errmsg);
log_write(0, LOG_MAIN|LOG_REJECT, "rejected XCLIENT from %s: %s",
host_and_ident(FALSE), errmsg);
}
We require that we do; the following HELO/EHLO handling will set
sender_helo_name as normal. */
- smtp_printf("%s XCLIENT success\r\n", FALSE, smtp_code);
+ smtp_printf("%s XCLIENT success\r\n", SP_NO_MORE, smtp_code);
}
break; /* XCLIENT */
}
if ( fl.helo_verify_required
|| verify_check_host(&hosts_require_helo) == OK)
{
- smtp_printf("503 HELO or EHLO required\r\n", FALSE);
+ smtp_printf("503 HELO or EHLO required\r\n", SP_NO_MORE);
log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL from %s: no "
"HELO/EHLO given", host_and_ident(FALSE));
break;
if (smtp_mailcmd_max > 0 && smtp_mailcmd_count > smtp_mailcmd_max)
{
- smtp_printf("421 too many messages in this connection\r\n", FALSE);
+ smtp_printf("421 too many messages in this connection\r\n", SP_NO_MORE);
log_write(0, LOG_MAIN|LOG_REJECT, "rejected MAIL command %s: too many "
"messages in one connection", host_and_ident(TRUE));
break;
US"invalid data for AUTH");
goto COMMAND_LOOP;
}
+ GET_OPTION("acl_smtp_mailauth");
if (!acl_smtp_mailauth)
{
ignore_msg = US"client not authenticated";
if (thismessage_size_limit > 0 && message_size > thismessage_size_limit)
{
- smtp_printf("552 Message size exceeds maximum permitted\r\n", FALSE);
+ smtp_printf("552 Message size exceeds maximum permitted\r\n", SP_NO_MORE);
log_write(L_size_reject,
LOG_MAIN|LOG_REJECT, "rejected MAIL FROM:<%s> %s: "
"message too big: size%s=%d max=%d",
smtp_check_spool_space && message_size >= 0
? message_size + 5000 : 0))
{
- smtp_printf("452 Space shortage, please try later\r\n", FALSE);
+ smtp_printf("452 Space shortage, please try later\r\n", SP_NO_MORE);
sender_address = NULL;
break;
}
}
else
{
- smtp_printf("501 %s: sender address must contain a domain\r\n", FALSE,
+ smtp_printf("501 %s: sender address must contain a domain\r\n", SP_NO_MORE,
smtp_cmd_data);
log_write(L_smtp_syntax_error,
LOG_MAIN|LOG_REJECT,
when pipelining is not advertised, do another sync check in case the ACL
delayed and the client started sending in the meantime. */
+ GET_OPTION("acl_smtp_mail");
if (acl_smtp_mail)
{
rc = acl_check(ACL_WHERE_MAIL, NULL, acl_smtp_mail, &user_msg, &log_msg);
{
if (f.smtp_in_pipelining_advertised && last_was_rej_mail)
{
- smtp_printf("503 sender not yet given\r\n", FALSE);
+ smtp_printf("503 sender not yet given\r\n", SP_NO_MORE);
was_rej_mail = TRUE;
}
else
/* 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)
{
rcpt_fail_count++;
- smtp_printf("552 too many recipients\r\n", FALSE);
+ smtp_printf("552 too many recipients\r\n", SP_NO_MORE);
if (!toomany)
log_write(0, LOG_MAIN|LOG_REJECT, "too many recipients: message "
"rejected: sender=<%s> %s", sender_address, host_and_ident(TRUE));
else
{
rcpt_defer_count++;
- smtp_printf("452 too many recipients\r\n", FALSE);
+ smtp_printf("452 too many recipients\r\n", SP_NO_MORE);
if (!toomany)
log_write(0, LOG_MAIN|LOG_REJECT, "too many recipients: excess "
"temporarily rejected: sender=<%s> %s", sender_address,
if (f.recipients_discarded)
rc = DISCARD;
else
+ {
+ GET_OPTION("acl_smtp_rcpt");
if ( (rc = acl_check(ACL_WHERE_RCPT, recipient, acl_smtp_rcpt, &user_msg,
&log_msg)) == OK
&& !f.smtp_in_pipelining_advertised && !check_sync())
goto SYNC_FAILURE;
+ }
/* The ACL was happy */
if (user_msg)
smtp_user_msg(US"250", user_msg);
else
- smtp_printf("250 Accepted\r\n", FALSE);
+ smtp_printf("250 Accepted\r\n", SP_NO_MORE);
rcpt_fail_count++;
discarded = TRUE;
log_write(0, LOG_MAIN|LOG_REJECT, "%s F=<%s> RCPT %s: "
{
uschar *code = US"503";
int len = Ustrlen(rcpt_smtp_response);
- smtp_respond(code, 3, FALSE, US"All RCPT commands were rejected with "
+ smtp_respond(code, 3, SR_NOT_FINAL, US"All RCPT commands were rejected with "
"this error:");
/* Responses from smtp_printf() will have \r\n on the end */
if (len > 2 && rcpt_smtp_response[len-2] == '\r')
rcpt_smtp_response[len-2] = 0;
- smtp_respond(code, 3, FALSE, rcpt_smtp_response);
+ smtp_respond(code, 3, SR_NOT_FINAL, rcpt_smtp_response);
}
if (f.smtp_in_pipelining_advertised && last_was_rcpt)
- smtp_printf("503 Valid RCPT command must precede %s\r\n", FALSE,
+ smtp_printf("503 Valid RCPT command must precede %s\r\n", SP_NO_MORE,
smtp_names[smtp_connection_had[SMTP_HBUFF_PREV(smtp_ch_index)]]);
else
done = synprot_error(L_smtp_protocol_error, 503, NULL,
{
sender_address = NULL; /* This will allow a new MAIL without RSET */
sender_address_unrewritten = NULL;
- smtp_printf("554 Too many recipients\r\n", FALSE);
+ smtp_printf("554 Too many recipients\r\n", SP_NO_MORE);
if (chunking_state > CHUNKING_OFFERED)
{
}
if (chunking_state > CHUNKING_OFFERED)
- rc = OK; /* No predata ACL or go-ahead output for BDAT */
+ rc = OK; /* There is no predata ACL or go-ahead output for BDAT */
else
{
- /* If there is an ACL, re-check the synchronization afterwards, since the
- ACL may have delayed. To handle cutthrough delivery enforce a dummy call
- to get the DATA command sent. */
+ /* If there is a predata-ACL, re-check the synchronization afterwards,
+ since the ACL may have delayed. To handle cutthrough delivery enforce a
+ dummy call to get the DATA command sent. */
+ GET_OPTION("acl_smtp_predata");
if (!acl_smtp_predata && cutthrough.cctx.sock < 0)
rc = OK;
else
smtp_user_msg(US"354", user_msg);
else
smtp_printf(
- "354 Enter message, ending with \".\" on a line by itself\r\n", FALSE);
+ "354 Enter message, ending with \".\" on a line by itself\r\n", SP_NO_MORE);
}
if (f.bdat_readers_wanted)
if (!(address = parse_extract_address(smtp_cmd_data, &errmess,
&start, &end, &recipient_domain, FALSE)))
{
- smtp_printf("501 %s\r\n", FALSE, errmess);
+ smtp_printf("501 %s\r\n", SP_NO_MORE, errmess);
break;
}
US"verify")))
break;
+ GET_OPTION("acl_smtp_vrfy");
if ((rc = acl_check(ACL_WHERE_VRFY, address, acl_smtp_vrfy,
&user_msg, &log_msg)) != OK)
done = smtp_handle_acl_fail(ACL_WHERE_VRFY, rc, user_msg, log_msg);
break;
}
- smtp_printf("%s\r\n", FALSE, s);
+ smtp_printf("%s\r\n", SP_NO_MORE, s);
}
break;
}
case EXPN_CMD:
HAD(SCH_EXPN);
+ GET_OPTION("acl_smtp_expn");
rc = acl_check(ACL_WHERE_EXPN, NULL, acl_smtp_expn, &user_msg, &log_msg);
if (rc != OK)
done = smtp_handle_acl_fail(ACL_WHERE_EXPN, rc, user_msg, log_msg);
/* Apply an ACL check if one is defined */
+ GET_OPTION("acl_smtp_starttls");
if ( acl_smtp_starttls
&& (rc = acl_check(ACL_WHERE_STARTTLS, NULL, acl_smtp_starttls,
&user_msg, &log_msg)) != OK
if (rc == DEFER)
{
- smtp_printf("454 TLS currently unavailable\r\n", FALSE);
+ smtp_printf("454 TLS currently unavailable\r\n", SP_NO_MORE);
break;
}
case QUIT_CMD:
f.smtp_in_quit = TRUE;
user_msg = NULL;
+ GET_OPTION("acl_smtp_quit");
if ( acl_smtp_quit
&& ((rc = acl_check(ACL_WHERE_QUIT, NULL, acl_smtp_quit, &user_msg,
&log_msg)) == ERROR))
log_write(0, LOG_MAIN|LOG_PANIC, "ACL for QUIT returned ERROR: %s",
log_msg);
if (user_msg)
- smtp_respond(US"221", 3, TRUE, user_msg);
+ smtp_respond(US"221", 3, SR_FINAL, user_msg);
else
- smtp_printf("221 %s closing connection\r\n", FALSE, smtp_active_hostname);
+ smtp_printf("221 %s closing connection\r\n", SP_NO_MORE, smtp_active_hostname);
log_close_event(US"by QUIT");
done = 2;
break;
default:
- smtp_printf("554 Security failure\r\n", FALSE);
+ smtp_printf("554 Security failure\r\n", SP_NO_MORE);
break;
}
tls_close(NULL, TLS_SHUTDOWN_NOWAIT);
case NOOP_CMD:
HAD(SCH_NOOP);
- smtp_printf("250 OK\r\n", FALSE);
+ smtp_printf("250 OK\r\n", SP_NO_MORE);
break;
case HELP_CMD:
HAD(SCH_HELP);
- smtp_printf("214-Commands supported:\r\n214", TRUE);
- smtp_printf(" AUTH", TRUE);
+ smtp_printf("214-Commands supported:\r\n214", SP_MORE);
+ smtp_printf(" AUTH", SP_MORE);
#ifndef DISABLE_TLS
if (tls_in.active.sock < 0 &&
verify_check_host(&tls_advertise_hosts) != FAIL)
- smtp_printf(" STARTTLS", TRUE);
+ smtp_printf(" STARTTLS", SP_MORE);
#endif
- smtp_printf(" HELO EHLO MAIL RCPT DATA BDAT", TRUE);
- smtp_printf(" NOOP QUIT RSET HELP", TRUE);
- if (acl_smtp_etrn) smtp_printf(" ETRN", TRUE);
- if (acl_smtp_expn) smtp_printf(" EXPN", TRUE);
- if (acl_smtp_vrfy) smtp_printf(" VRFY", TRUE);
+ smtp_printf(" HELO EHLO MAIL RCPT DATA BDAT", SP_MORE);
+ smtp_printf(" NOOP QUIT RSET HELP", SP_MORE);
+ if (acl_smtp_etrn) smtp_printf(" ETRN", SP_MORE);
+ if (acl_smtp_expn) smtp_printf(" EXPN", SP_MORE);
+ if (acl_smtp_vrfy) smtp_printf(" VRFY", SP_MORE);
#ifdef EXPERIMENTAL_XCLIENT
if (proxy_session || verify_check_host(&hosts_xclient) != FAIL)
- smtp_printf(" XCLIENT", TRUE);
+ smtp_printf(" XCLIENT", SP_MORE);
#endif
- smtp_printf("\r\n", FALSE);
+ smtp_printf("\r\n", SP_NO_MORE);
break;
log_write(L_etrn, LOG_MAIN, "ETRN %s received from %s", smtp_cmd_argument,
host_and_ident(FALSE));
+ GET_OPTION("acl_smtp_etrn");
if ((rc = acl_check(ACL_WHERE_ETRN, NULL, acl_smtp_etrn,
&user_msg, &log_msg)) != OK)
{
since that is strictly the only kind of ETRN that can be implemented
according to the RFC. */
+ GET_OPTION("smtp_etrn_command");
if (smtp_etrn_command)
{
uschar *error;
BOOL rc;
etrn_command = smtp_etrn_command;
deliver_domain = smtp_cmd_data;
- rc = transport_set_up_command(&argv, smtp_etrn_command, TRUE, 0, NULL,
- FALSE, US"ETRN processing", &error);
+ rc = transport_set_up_command(&argv, smtp_etrn_command, TSUC_EXPAND_ARGS, 0, NULL,
+ US"ETRN processing", &error);
deliver_domain = NULL;
if (!rc)
{
log_write(0, LOG_MAIN|LOG_PANIC, "failed to set up ETRN command: %s",
error);
- smtp_printf("458 Internal failure\r\n", FALSE);
+ smtp_printf("458 Internal failure\r\n", SP_NO_MORE);
break;
}
}
debug_printf("ETRN command is: %s\n", etrn_command);
debug_printf("ETRN command execution skipped\n");
}
- if (user_msg == NULL) smtp_printf("250 OK\r\n", FALSE);
+ if (user_msg == NULL) smtp_printf("250 OK\r\n", SP_NO_MORE);
else smtp_user_msg(US"250", user_msg);
break;
}
if (smtp_etrn_serialize && !enq_start(etrn_serialize_key, 1))
{
- smtp_printf("458 Already processing %s\r\n", FALSE, smtp_cmd_data);
+ smtp_printf("458 Already processing %s\r\n", SP_NO_MORE, smtp_cmd_data);
break;
}
{
log_write(0, LOG_MAIN|LOG_PANIC, "fork of process for ETRN failed: %s",
strerror(errno));
- smtp_printf("458 Unable to fork process\r\n", FALSE);
+ smtp_printf("458 Unable to fork process\r\n", SP_NO_MORE);
if (smtp_etrn_serialize) enq_end(etrn_serialize_key);
}
else
if (!user_msg)
- smtp_printf("250 OK\r\n", FALSE);
+ smtp_printf("250 OK\r\n", SP_NO_MORE);
else
smtp_user_msg(US"250", user_msg);
done = synprot_error(L_smtp_syntax_error, 0, NULL, /* Just logs */
US"NUL character(s) present (shown as '?')");
smtp_printf("501 NUL characters are not allowed in SMTP commands\r\n",
- FALSE);
+ SP_NO_MORE);
break;
#ifdef SUPPORT_PROXY
case PROXY_FAIL_IGNORE_CMD:
- smtp_printf("503 Command refused, required Proxy negotiation failed\r\n", FALSE);
+ smtp_printf("503 Command refused, required Proxy negotiation failed\r\n", SP_NO_MORE);
break;
#endif