assertion: legitimate SMTP clients are all explicitly authorized with CSA
SRV records of their own. */
- if (found != domain)
+ if (Ustrcmp(found, domain) != 0)
{
if (port & 1)
return t->data.val = CSA_FAIL_EXPLICIT;
unsigned alt_opt_sep; /* >0 Non-/ option separator (custom parser) */
} verify_type_t;
static verify_type_t verify_type_list[] = {
- { US"reverse_host_lookup", VERIFY_REV_HOST_LKUP, ~0, TRUE, 0 },
+ { US"reverse_host_lookup", VERIFY_REV_HOST_LKUP, ~0, FALSE, 0 },
{ US"certificate", VERIFY_CERT, ~0, TRUE, 0 },
{ US"helo", VERIFY_HELO, ~0, TRUE, 0 },
{ US"csa", VERIFY_CSA, ~0, FALSE, 0 },
{
case VERIFY_REV_HOST_LKUP:
if (sender_host_address == NULL) return OK;
- return acl_verify_reverse(user_msgptr, log_msgptr);
+ if ((rc = acl_verify_reverse(user_msgptr, log_msgptr)) == DEFER)
+ while ((ss = string_nextinlist(&list, &sep, big_buffer, big_buffer_size)))
+ if (strcmpic(ss, US"defer_ok") == 0)
+ return OK;
+ return rc;
case VERIFY_CERT:
/* TLS certificate verification is done at STARTTLS time; here we just
sender_rate_limit = string_nextinlist(&arg, &sep, NULL, 0);
if (sender_rate_limit == NULL)
+ {
limit = -1.0;
+ ss = NULL; /* compiler quietening */
+ }
else
{
limit = Ustrtod(sender_rate_limit, &ss);
uschar *p = NULL;
int rc = OK;
#ifdef WITH_CONTENT_SCAN
-int sep = '/';
+int sep = -'/';
#endif
for (; cb != NULL; cb = cb->next)
break;
case CONTROL_CUTTHROUGH_DELIVERY:
- if (deliver_freeze)
- *log_msgptr = US"frozen";
- else if (queue_only_policy)
- *log_msgptr = US"queue-only";
- else if (fake_response == FAIL)
- *log_msgptr = US"fakereject";
+ if (prdr_requested)
+ /* Too hard to think about for now. We might in future cutthrough
+ the case where both sides handle prdr and this-node prdr acl
+ is "accept" */
+ *log_msgptr = string_sprintf(US"PRDR on %s reception\n", arg);
else
{
- cutthrough_delivery = TRUE;
- break;
+ if (deliver_freeze)
+ *log_msgptr = US"frozen";
+ else if (queue_only_policy)
+ *log_msgptr = US"queue-only";
+ else if (fake_response == FAIL)
+ *log_msgptr = US"fakereject";
+ else
+ {
+ if (rcpt_count == 1) cutthrough.delivery = TRUE;
+ break;
+ }
+ *log_msgptr = string_sprintf("\"control=%s\" on %s item",
+ arg, *log_msgptr);
}
- *log_msgptr = string_sprintf("\"control=%s\" on %s item",
- arg, *log_msgptr);
return ERROR;
}
break;
break;
#ifdef WITH_CONTENT_SCAN
- case ACLC_MALWARE:
+ case ACLC_MALWARE: /* Run the malware backend. */
{
/* Separate the regular expression and any optional parameters. */
uschar *ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size);
- /* Run the malware backend. */
- rc = malware(&ss);
- /* Modify return code based upon the existance of options. */
- while ((ss = string_nextinlist(&arg, &sep, big_buffer, big_buffer_size))
- != NULL) {
- if (strcmpic(ss, US"defer_ok") == 0 && rc == DEFER)
- {
- /* FAIL so that the message is passed to the next ACL */
- rc = FAIL;
- }
- }
+ uschar *opt;
+ BOOL defer_ok = FALSE;
+ int timeout = 0;
+
+ while ((opt = string_nextinlist(&arg, &sep, NULL, 0)))
+ if (strcmpic(opt, US"defer_ok") == 0)
+ defer_ok = TRUE;
+ else if ( strncmpic(opt, US"tmo=", 4) == 0
+ && (timeout = readconf_readtime(opt+4, '\0', FALSE)) < 0
+ )
+ {
+ *log_msgptr = string_sprintf("bad timeout value in '%s'", opt);
+ return ERROR;
+ }
+
+ rc = malware(ss, timeout);
+ if (rc == DEFER && defer_ok)
+ rc = FAIL; /* FAIL so that the message is passed to the next ACL */
}
break;
switch(acl->verb)
{
case ACL_ACCEPT:
- if (cond == OK || cond == DISCARD) return cond;
+ if (cond == OK || cond == DISCARD)
+ {
+ HDEBUG(D_acl) debug_printf("end of %s: ACCEPT\n", acl_name);
+ return cond;
+ }
if (endpass_seen)
{
HDEBUG(D_acl) debug_printf("accept: endpass encountered - denying access\n");
case ACL_DEFER:
if (cond == OK)
{
+ HDEBUG(D_acl) debug_printf("end of %s: DEFER\n", acl_name);
acl_temp_details = TRUE;
return DEFER;
}
break;
case ACL_DENY:
- if (cond == OK) return FAIL;
+ if (cond == OK)
+ {
+ HDEBUG(D_acl) debug_printf("end of %s: DENY\n", acl_name);
+ return FAIL;
+ }
break;
case ACL_DISCARD:
- if (cond == OK || cond == DISCARD) return DISCARD;
+ if (cond == OK || cond == DISCARD)
+ {
+ HDEBUG(D_acl) debug_printf("end of %s: DISCARD\n", acl_name);
+ return DISCARD;
+ }
if (endpass_seen)
{
HDEBUG(D_acl) debug_printf("discard: endpass encountered - denying access\n");
break;
case ACL_DROP:
- if (cond == OK) return FAIL_DROP;
+ if (cond == OK)
+ {
+ HDEBUG(D_acl) debug_printf("end of %s: DROP\n", acl_name);
+ return FAIL_DROP;
+ }
break;
case ACL_REQUIRE:
- if (cond != OK) return cond;
+ if (cond != OK)
+ {
+ HDEBUG(D_acl) debug_printf("end of %s: not OK\n", acl_name);
+ return cond;
+ }
break;
case ACL_WARN:
log_reject_target = LOG_MAIN|LOG_REJECT;
#ifndef DISABLE_PRDR
-if (where == ACL_WHERE_RCPT || where == ACL_WHERE_PRDR )
+if (where == ACL_WHERE_RCPT || where == ACL_WHERE_PRDR)
#else
-if (where == ACL_WHERE_RCPT )
+if (where == ACL_WHERE_RCPT)
#endif
{
adb = address_defaults;
#ifndef DISABLE_PRDR
case ACL_WHERE_PRDR:
#endif
- if( rcpt_count > 1 )
- cancel_cutthrough_connection("more than one recipient");
- else if (rc == OK && cutthrough_delivery && cutthrough_fd < 0)
+ if (rc == OK && cutthrough.delivery && rcpt_count > cutthrough.nrcpt)
open_cutthrough_connection(addr);
break;