From 96b619cc129afed52411b9fad3407037a1cb7207 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 6 May 2024 02:47:26 +0200 Subject: Adding upstream version 4.92. Signed-off-by: Daniel Baumann --- src/routers/rf_get_errors_address.c | 131 ++++++++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 src/routers/rf_get_errors_address.c (limited to 'src/routers/rf_get_errors_address.c') diff --git a/src/routers/rf_get_errors_address.c b/src/routers/rf_get_errors_address.c new file mode 100644 index 0000000..858c806 --- /dev/null +++ b/src/routers/rf_get_errors_address.c @@ -0,0 +1,131 @@ +/************************************************* +* Exim - an Internet mail transport agent * +*************************************************/ + +/* Copyright (c) University of Cambridge 1995 - 2018 */ +/* See the file NOTICE for conditions of use and distribution. */ + +#include "../exim.h" +#include "rf_functions.h" + + +/************************************************* +* Get errors address for a router * +*************************************************/ + +/* This function is called by routers to sort out the errors address for a +particular address. If there is a setting in the router block, then expand and +verify it, and if it works, use it. Otherwise use any setting that is in the +address itself. This might be NULL, meaning unset (the message's sender is then +used). Verification isn't done when the original address is just being +verified, as otherwise there might be routing loops if someone sets up a silly +configuration. + +Arguments: + addr the input address + rblock the router instance + verify v_none / v_recipient / v_sender / v_expn + errors_to point the errors address here + +Returns: OK if no problem + DEFER if verifying the address caused a deferment + or a big disaster (e.g. expansion failure) +*/ + +int +rf_get_errors_address(address_item *addr, router_instance *rblock, + int verify, uschar **errors_to) +{ +uschar *s; + +*errors_to = addr->prop.errors_address; +if (rblock->errors_to == NULL) return OK; + +s = expand_string(rblock->errors_to); + +if (s == NULL) + { + if (f.expand_string_forcedfail) + { + DEBUG(D_route) + debug_printf("forced expansion failure - ignoring errors_to\n"); + return OK; + } + addr->message = string_sprintf("%s router failed to expand \"%s\": %s", + rblock->name, rblock->errors_to, expand_string_message); + return DEFER; + } + +/* If the errors_to address is empty, it means "ignore errors" */ + +if (*s == 0) + { + addr->prop.ignore_error = TRUE; /* For locally detected errors */ + *errors_to = US""; /* Return path for SMTP */ + return OK; + } + +/* If we are already verifying, do not check the errors address, in order to +save effort (but we do verify when testing an address). When we do verify, set +the sender address to null, because that's what it will be when sending an +error message, and there are now configuration options that control the running +of routers by checking the sender address. When testing an address, there may +not be a sender address. We also need to save and restore the expansion values +associated with an address. */ + +if (verify != v_none) + { + *errors_to = s; + DEBUG(D_route) + debug_printf("skipped verify errors_to address: already verifying\n"); + } +else + { + BOOL save_address_test_mode = f.address_test_mode; + int save1 = 0; + int i; + const uschar ***p; + const uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT]; + address_item *snew = deliver_make_addr(s, FALSE); + + if (sender_address != NULL) + { + save1 = sender_address[0]; + sender_address[0] = 0; + } + + for (i = 0, p = address_expansions; *p != NULL;) + address_expansions_save[i++] = **p++; + f.address_test_mode = FALSE; + + /* NOTE: the address is verified as a recipient, not a sender. This is + perhaps confusing. It isn't immediately obvious what to do: we want to have + some confidence that we can deliver to the address, in which case it will be + a recipient, but on the other hand, it will be passed on in SMTP deliveries + as a sender. However, I think on balance recipient is right because sender + verification is really about the *incoming* sender of the message. + + If this code is changed, note that you must set vopt_fake_sender instead of + vopt_is_recipient, as otherwise sender_address may be altered because + verify_address() thinks it is dealing with *the* sender of the message. */ + + DEBUG(D_route|D_verify) + debug_printf("------ Verifying errors address %s ------\n", s); + if (verify_address(snew, NULL, + vopt_is_recipient /* vopt_fake_sender is the alternative */ + | vopt_qualify, -1, -1, -1, NULL, NULL, NULL) == OK) + *errors_to = snew->address; + DEBUG(D_route|D_verify) + debug_printf("------ End verifying errors address %s ------\n", s); + + f.address_test_mode = save_address_test_mode; + for (i = 0, p = address_expansions; *p != NULL;) + **p++ = address_expansions_save[i++]; + + if (sender_address != NULL) sender_address[0] = save1; + } + +return OK; +} + +/* End of rf_get_errors_address.c */ -- cgit v1.2.3