X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=src%2Fsrc%2Facl.c;h=684b93bbb31641bb4e59784b1f3d9589e91f4e09;hb=dc525e9633df9a3a21eb636ff070e2b3b6d02410;hp=e79c87f83daa5e8ff6ae0588b0527961f36cab63;hpb=3386088d5af4d4c61faa12ae29560e2c5bd43304;p=exim.git diff --git a/src/src/acl.c b/src/src/acl.c index e79c87f83..684b93bbb 100644 --- a/src/src/acl.c +++ b/src/src/acl.c @@ -208,7 +208,7 @@ enum { #endif CONTROL_FAKEDEFER, CONTROL_FAKEREJECT, -#ifdef EXPERIMENTAL_INTERNATIONAL +#ifdef SUPPORT_I18N CONTROL_UTF8_DOWNCONVERT, #endif CONTROL_NO_MULTILINE, @@ -251,7 +251,7 @@ static uschar *controls[] = { #endif US"fakedefer", US"fakereject", -#ifdef EXPERIMENTAL_INTERNATIONAL +#ifdef SUPPORT_I18N US"utf8_downconvert", #endif US"no_multiline_responses", @@ -475,11 +475,14 @@ static unsigned int cond_forbids[] = { ~(1<value) test whether it was successful or not. (This is for optional verification; for mandatory verification, the connection doesn't last this long.) */ - if (tls_in.certificate_verified) return OK; - *user_msgptr = US"no verified certificate"; - return FAIL; + if (tls_in.certificate_verified) return OK; + *user_msgptr = US"no verified certificate"; + return FAIL; case VERIFY_HELO: /* We can test the result of optional HELO verification that might have occurred earlier. If not, we can attempt the verification now. */ - if (!helo_verified && !helo_verify_failed) smtp_verify_helo(); - return helo_verified? OK : FAIL; + if (!helo_verified && !helo_verify_failed) smtp_verify_helo(); + return helo_verified? OK : FAIL; case VERIFY_CSA: /* Do Client SMTP Authorization checks in a separate function, and turn the result code into user-friendly strings. */ - rc = acl_verify_csa(list); - *log_msgptr = *user_msgptr = string_sprintf("client SMTP authorization %s", + rc = acl_verify_csa(list); + *log_msgptr = *user_msgptr = string_sprintf("client SMTP authorization %s", csa_reason_string[rc]); - csa_status = csa_status_string[rc]; - DEBUG(D_acl) debug_printf("CSA result %s\n", csa_status); - return csa_return_code[rc]; + csa_status = csa_status_string[rc]; + DEBUG(D_acl) debug_printf("CSA result %s\n", csa_status); + return csa_return_code[rc]; case VERIFY_HDR_SYNTAX: /* Check that all relevant header lines have the correct syntax. If there is @@ -1832,8 +1836,11 @@ switch(vp->value) always). */ rc = verify_check_headers(log_msgptr); - if (rc != OK && smtp_return_error_details && *log_msgptr != NULL) - *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr); + if (rc != OK && *log_msgptr) + if (smtp_return_error_details) + *user_msgptr = string_sprintf("Rejected after DATA: %s", *log_msgptr); + else + acl_verify_message = *log_msgptr; return rc; case VERIFY_HDR_NAMES_ASCII: @@ -2092,7 +2099,7 @@ else if (verify_sender_address != NULL) uschar *save_address_data = deliver_address_data; sender_vaddr = deliver_make_addr(verify_sender_address, TRUE); -#ifdef EXPERIMENTAL_INTERNATIONAL +#ifdef SUPPORT_I18N if ((sender_vaddr->prop.utf8_msg = message_smtputf8)) { sender_vaddr->prop.utf8_downcvt = message_utf8_downconvert == 1; @@ -3372,7 +3379,11 @@ for (; cb != NULL; cb = cb->next) break; case CONTROL_CUTTHROUGH_DELIVERY: +#ifndef DISABLE_PRDR if (prdr_requested) +#else + if (0) +#endif /* 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" */ @@ -3395,7 +3406,7 @@ for (; cb != NULL; cb = cb->next) } return ERROR; - #ifdef EXPERIMENTAL_INTERNATIONAL +#ifdef SUPPORT_I18N case CONTROL_UTF8_DOWNCONVERT: if (*p == '/') { @@ -3433,7 +3444,7 @@ for (; cb != NULL; cb = cb->next) break; } return ERROR; - #endif +#endif } break; @@ -3480,6 +3491,34 @@ for (; cb != NULL; cb = cb->next) debug_printf("delay skipped in -bh checking mode\n"); } + /* NOTE 1: Remember that we may be + dealing with stdin/stdout here, in addition to TCP/IP connections. + Also, delays may be specified for non-SMTP input, where smtp_out and + smtp_in will be NULL. Whatever is done must work in all cases. + + NOTE 2: The added feature of flushing the output before a delay must + apply only to SMTP input. Hence the test for smtp_out being non-NULL. + */ + + else + { + if (smtp_out != NULL && !disable_delay_flush) + mac_smtp_fflush(); + +#if !defined(NO_POLL_H) && defined (POLLRDHUP) + { + struct pollfd p; + nfds_t n = 0; + if (smtp_out) + { + p.fd = fileno(smtp_out); + p.events = POLLRDHUP; + n = 1; + } + if (poll(&p, n, delay*1000) > 0) + HDEBUG(D_acl) debug_printf("delay cancelled by peer close\n"); + } +#else /* It appears to be impossible to detect that a TCP/IP connection has gone away without reading from it. This means that we cannot shorten the delay below if the client goes away, because we cannot discover @@ -3489,20 +3528,10 @@ for (; cb != NULL; cb = cb->next) Exim process is not held up unnecessarily. However, it seems that we can't. The poll() function does not do the right thing, and in any case it is not always available. - - NOTE 1: If ever this state of affairs changes, remember that we may be - dealing with stdin/stdout here, in addition to TCP/IP connections. - Also, delays may be specified for non-SMTP input, where smtp_out and - smtp_in will be NULL. Whatever is done must work in all cases. - - NOTE 2: The added feature of flushing the output before a delay must - apply only to SMTP input. Hence the test for smtp_out being non-NULL. */ - else - { - if (smtp_out != NULL && !disable_delay_flush) mac_smtp_fflush(); while (delay > 0) delay = sleep(delay); +#endif } } } @@ -3542,7 +3571,7 @@ for (; cb != NULL; cb = cb->next) #endif case ACLC_DNSLISTS: - rc = verify_check_dnsbl(&arg); + rc = verify_check_dnsbl(where, &arg, log_msgptr); break; case ACLC_DOMAINS: @@ -3718,7 +3747,12 @@ for (; cb != NULL; cb = cb->next) case ACLC_SET: { int old_pool = store_pool; - if (cb->u.varname[0] == 'c') store_pool = POOL_PERM; + if ( cb->u.varname[0] == 'c' +#ifndef DISABLE_EVENT + || event_name /* An event is being delivered */ +#endif + ) + store_pool = POOL_PERM; acl_var_create(cb->u.varname)->data.ptr = string_copy(arg); store_pool = old_pool; } @@ -3766,7 +3800,8 @@ for (; cb != NULL; cb = cb->next) case ACLC_VERIFY: rc = acl_verify(where, addr, arg, user_msgptr, log_msgptr, basic_errno); - acl_verify_message = *user_msgptr; + if (*user_msgptr) + acl_verify_message = *user_msgptr; if (verb == ACL_WARN) *user_msgptr = NULL; break; @@ -4265,7 +4300,7 @@ while (acl != NULL) case ACL_WARN: if (cond == OK) acl_warn(where, *user_msgptr, *log_msgptr); - else if (cond == DEFER && (log_extra_selector & LX_acl_warn_skipped) != 0) + else if (cond == DEFER && LOGGING(acl_warn_skipped)) log_write(0, LOG_MAIN, "%s Warning: ACL \"warn\" statement skipped: " "condition test deferred%s%s", host_and_ident(TRUE), (*log_msgptr == NULL)? US"" : US": ", @@ -4421,9 +4456,9 @@ ratelimiters_cmd = NULL; 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_VRFY || where==ACL_WHERE_PRDR) #else -if (where == ACL_WHERE_RCPT) +if (where==ACL_WHERE_RCPT || where==ACL_WHERE_VRFY) #endif { adb = address_defaults; @@ -4434,7 +4469,7 @@ if (where == ACL_WHERE_RCPT) *log_msgptr = US"defer in percent_hack_domains check"; return DEFER; } -#ifdef EXPERIMENTAL_INTERNATIONAL +#ifdef SUPPORT_I18N if ((addr->prop.utf8_msg = message_smtputf8)) { addr->prop.utf8_downcvt = message_utf8_downconvert == 1;