X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Facl.c;h=e3efb7ed873c627b89474a8940ff3dab13824e5b;hb=27f9999e2828002705cabd10ef62ce86378287e3;hp=eb21796104665914d954d0f9204bde085cfccbdf;hpb=4840604e4f365545a43f01d0e953ce33afd1c3d5;p=exim.git diff --git a/src/src/acl.c b/src/src/acl.c index eb2179610..e3efb7ed8 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -21,8 +21,13 @@ enum { ACL_ACCEPT, ACL_DEFER, ACL_DENY, ACL_DISCARD, ACL_DROP, ACL_REQUIRE, /* ACL verbs */ -static uschar *verbs[] = - { US"accept", US"defer", US"deny", US"discard", US"drop", US"require", +static uschar *verbs[] = { + US"accept", + US"defer", + US"deny", + US"discard", + US"drop", + US"require", US"warn" }; /* For each verb, the conditions for which "message" or "log_message" are used @@ -102,6 +107,7 @@ enum { ACLC_ACL, ACLC_SPF, ACLC_SPF_GUESS, #endif + ACLC_UDPSEND, ACLC_VERIFY }; /* ACL conditions/modifiers: "delay", "control", "continue", "endpass", @@ -166,6 +172,7 @@ static uschar *conditions[] = { US"spf", US"spf_guess", #endif + US"udpsend", US"verify" }; @@ -310,6 +317,7 @@ static uschar cond_expand_at_top[] = { TRUE, /* spf */ TRUE, /* spf_guess */ #endif + TRUE, /* udpsend */ TRUE /* verify */ }; @@ -374,6 +382,7 @@ static uschar cond_modifiers[] = { FALSE, /* spf */ FALSE, /* spf_guess */ #endif + TRUE, /* udpsend */ FALSE /* verify */ }; @@ -574,6 +583,8 @@ static unsigned int cond_forbids[] = { (1<name = hostname; +h->port = portnum; +h->mx = MX_NONE; + +if (string_is_ip_address(hostname, NULL)) + h->address = hostname, r = HOST_FOUND; +else + r = host_find_byname(h, NULL, 0, NULL, FALSE); +if (r == HOST_FIND_FAILED || r == HOST_FIND_AGAIN) + { + *log_msgptr = US"DNS lookup failed in \"udpsend\" modifier"; + return DEFER; + } + +HDEBUG(D_acl) + debug_printf("udpsend [%s]:%d %s\n", h->address, portnum, arg); + +host_af = (Ustrchr(h->address, ':') == NULL)? AF_INET:AF_INET6; +r = s = ip_socket(SOCK_DGRAM, host_af); +if (r < 0) goto defer; +r = ip_connect(s, host_af, h->address, portnum, 1); +if (r < 0) goto defer; +len = Ustrlen(arg); +r = send(s, arg, len, MSG_NOSIGNAL); +if (r < 0) goto defer; +if (r < len) + { + *log_msgptr = + string_sprintf("\"udpsend\" truncated from %d to %d octets", len, r); + return DEFER; + } + +HDEBUG(D_acl) + debug_printf("udpsend %d bytes\n", r); + +return OK; + +defer: +*log_msgptr = string_sprintf("\"udpsend\" failed: %s", strerror(errno)); +return DEFER; +} + + + /************************************************* * Handle conditions/modifiers on an ACL item * *************************************************/ @@ -3328,8 +3439,9 @@ for (; cb != NULL; cb = cb->next) #ifdef EXPERIMENTAL_DMARC case ACLC_DMARC_STATUS: - if (dmarc_has_been_checked++ == 0) + if (!dmarc_has_been_checked) dmarc_process(); + dmarc_has_been_checked = TRUE; /* used long way of dmarc_exim_expand_query() in case we need more * view into the process in the future. */ rc = match_isinlist(dmarc_exim_expand_query(DMARC_VERIFY_STATUS), @@ -3540,6 +3652,10 @@ for (; cb != NULL; cb = cb->next) break; #endif + case ACLC_UDPSEND: + rc = acl_udpsend(arg, log_msgptr); + break; + /* If the verb is WARN, discard any user message from verification, because such messages are SMTP responses, not header additions. The latter come only from explicit "message" modifiers. However, put the user message into