follow the sender address. */
smtp_cmd_argument = smtp_cmd_buffer + p->len;
- while (isspace(*smtp_cmd_argument)) smtp_cmd_argument++;
+ Uskip_whitespace(&smtp_cmd_argument);
Ustrcpy(smtp_data_buffer, smtp_cmd_argument);
smtp_cmd_data = smtp_data_buffer;
g = string_cat(g, hostname);
else if (f.sender_host_unknown || f.sender_host_notsocket)
- g = string_cat(g, sender_ident);
+ g = string_cat(g, sender_ident ? sender_ident : US"NULL");
else if (f.is_inetd)
g = string_append(g, 2, hostname, US" (via inetd)");
/* 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");
case HELP_CMD:
case NOOP_CMD:
case ETRN_CMD:
+#ifdef EXPERIMENTAL_WELLKNOWN
+ case WELLKNOWN_CMD:
+#endif
bsmtp_transaction_linecount = receive_linecount;
break;
/* 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)
{
/* 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 */
if (where == ACL_WHERE_AUTH) /* avoid logging auth creds */
{
- uschar * s;
- for (s = smtp_cmd_data; *s && !isspace(*s); ) s++;
+ uschar * s = smtp_cmd_data;
+ Uskip_nonwhite(&s);
lim = s - smtp_cmd_data; /* atop after method */
}
what = string_sprintf("%s %.*s", acl_wherenames[where], lim, place);
/* 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;
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)
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
if (*smtp_cmd_data)
{
- *smtp_cmd_data++ = 0;
- while (isspace(*smtp_cmd_data)) smtp_cmd_data++;
+ *smtp_cmd_data++ = '\0';
+ Uskip_whitespace(&smtp_cmd_data);
}
/* Search for an authentication mechanism which is configured for use
if (!f.sender_host_unknown)
{
BOOL old_helo_verified = f.helo_verified;
- uschar *p = smtp_cmd_data;
+ uschar * p = smtp_cmd_data;
- while (*p != 0 && !isspace(*p)) { *p = tolower(*p); p++; }
- *p = 0;
+ while (*p && !isspace(*p)) { *p = tolower(*p); p++; }
+ *p = '\0';
/* Force a reverse lookup if HELO quoted something in helo_lookup_domains
because otherwise the log can be confusing. */
/* 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_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 > 9)
+ if (recipients_max_expanded > 0)
g = string_fmt_append(g, " RCPTMAX=%d", recipients_max_expanded);
g = string_catn(g, US"\r\n", 2);
}
/* 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);
US"invalid data for AUTH");
goto COMMAND_LOOP;
}
+ GET_OPTION("acl_smtp_mailauth");
if (!acl_smtp_mailauth)
{
ignore_msg = US"client not authenticated";
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.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 */
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
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);
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
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(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;
case TOO_MANY_NONMAIL_CMD:
s = smtp_cmd_buffer;
- while (*s && !isspace(*s)) s++;
+ Uskip_nonwhite(&s);
incomplete_transaction_log(US"too many non-mail commands");
log_write(0, LOG_MAIN|LOG_REJECT, "SMTP call from %s dropped: too many "
"nonmail commands (last was \"%.*s\")", host_and_ident(FALSE),