-/* $Cambridge: exim/src/src/smtp_in.c,v 1.32 2006/02/13 16:23:57 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.37 2006/03/16 11:14:46 ph10 Exp $ */
/*************************************************
* Exim - an Internet mail transport agent *
DEBUG(D_receive)
{
+ uschar *cr, *end;
va_start(ap, format);
(void) string_vformat(big_buffer, big_buffer_size, format, ap);
+ va_end(ap);
+ end = big_buffer + Ustrlen(big_buffer);
+ while ((cr = Ustrchr(big_buffer, '\r')) != NULL) /* lose CRs */
+ memmove(cr, cr + 1, (end--) - cr);
debug_printf("SMTP>> %s", big_buffer);
}
raw_recipients_count = recipients_count = recipients_list_max = 0;
message_linecount = 0;
message_size = -1;
-acl_warn_headers = NULL;
+acl_added_headers = NULL;
queue_only_policy = FALSE;
deliver_freeze = FALSE; /* Can be set by ACL */
freeze_tell = freeze_tell_config; /* Can be set by ACL */
/* If there's been a sender verification failure with a specific message, and
we have not sent a response about it yet, do so now, as a preliminary line for
-failures, but not defers. However, log it in both cases. */
+failures, but not defers. However, always log it for defer, and log it for fail
+unless the sender_verify_fail log selector has been turned off. */
if (sender_verified_failed != NULL &&
!testflag(sender_verified_failed, af_sverify_told))
{
setflag(sender_verified_failed, af_sverify_told);
- log_write(0, LOG_MAIN|LOG_REJECT, "%s sender verify %s for <%s>%s",
- host_and_ident(TRUE),
- ((sender_verified_failed->special_action & 255) == DEFER)? "defer" : "fail",
- sender_verified_failed->address,
- (sender_verified_failed->message == NULL)? US"" :
- string_sprintf(": %s", sender_verified_failed->message));
+ if (rc != FAIL || (log_extra_selector & LX_sender_verify_fail) != 0)
+ log_write(0, LOG_MAIN|LOG_REJECT, "%s sender verify %s for <%s>%s",
+ host_and_ident(TRUE),
+ ((sender_verified_failed->special_action & 255) == DEFER)? "defer":"fail",
+ sender_verified_failed->address,
+ (sender_verified_failed->message == NULL)? US"" :
+ string_sprintf(": %s", sender_verified_failed->message));
if (rc == FAIL && sender_verified_failed->user_message != NULL)
smtp_respond(code, FALSE, string_sprintf(
switch(smtp_read_command(TRUE))
{
/* The AUTH command is not permitted to occur inside a transaction, and may
- occur successfully only once per connection, and then only when we've
- advertised it. Actually, that isn't quite true. When TLS is started, all
- previous information about a connection must be discarded, so a new AUTH is
- permitted at that time.
+ occur successfully only once per connection. Actually, that isn't quite
+ true. When TLS is started, all previous information about a connection must
+ be discarded, so a new AUTH is permitted at that time.
+
+ AUTH may only be used when it has been advertised. However, it seems that
+ there are clients that send AUTH when it hasn't been advertised, some of
+ them even doing this after HELO. And there are MTAs that accept this. Sigh.
+ So there's a get-out that allows this to happen.
AUTH is initially labelled as a "nonmail command" so that one occurrence
doesn't get counted. We change the label here so that multiple failing
authentication_failed = TRUE;
cmd_list[CMD_LIST_AUTH].is_mail_cmd = FALSE;
- if (!auth_advertised)
+ if (!auth_advertised && !allow_auth_unadvertised)
{
done = synprot_error(L_smtp_protocol_error, 503, NULL,
US"AUTH command used when not advertised");
}
/* Search for an authentication mechanism which is configured for use
- as a server and which has been advertised. */
+ as a server and which has been advertised (unless, sigh, allow_auth_
+ unadvertised is set). */
for (au = auths; au != NULL; au = au->next)
{
if (strcmpic(s, au->public_name) == 0 && au->server &&
- au->advertised) break;
+ (au->advertised || allow_auth_unadvertised)) break;
}
if (au == NULL)
#endif
(void)fwrite(s, 1, ptr, smtp_out);
- DEBUG(D_receive) debug_printf("SMTP>> %s", s);
+ DEBUG(D_receive)
+ {
+ uschar *cr;
+ while ((cr = Ustrchr(s, '\r')) != NULL) /* lose CRs */
+ memmove(cr, cr + 1, (ptr--) - (cr - s));
+ debug_printf("SMTP>> %s", s);
+ }
helo_seen = TRUE;
break; /* HELO/EHLO */
break;
case DEFER:
- s = (addr->message != NULL)?
- string_sprintf("451 <%s> %s", address, addr->message) :
+ s = (addr->user_message != NULL)?
+ string_sprintf("451 <%s> %s", address, addr->user_message) :
string_sprintf("451 Cannot resolve <%s> at this time", address);
break;
case FAIL:
- s = (addr->message != NULL)?
- string_sprintf("550 <%s> %s", address, addr->message) :
+ s = (addr->user_message != NULL)?
+ string_sprintf("550 <%s> %s", address, addr->user_message) :
string_sprintf("550 <%s> is not deliverable", address);
log_write(0, LOG_MAIN, "VRFY failed for %s %s",
smtp_cmd_argument, host_and_ident(TRUE));