Copyright updates:
[exim.git] / src / src / routers / rf_get_errors_address.c
CommitLineData
0756eb3c
PH
1/*************************************************
2* Exim - an Internet mail transport agent *
3*************************************************/
4
f9ba5e22 5/* Copyright (c) University of Cambridge 1995 - 2018 */
1e1ddfac 6/* Copyright (c) The Exim Maintainers 2020 */
0756eb3c
PH
7/* See the file NOTICE for conditions of use and distribution. */
8
9#include "../exim.h"
10#include "rf_functions.h"
11
12
13/*************************************************
14* Get errors address for a router *
15*************************************************/
16
17/* This function is called by routers to sort out the errors address for a
18particular address. If there is a setting in the router block, then expand and
19verify it, and if it works, use it. Otherwise use any setting that is in the
20address itself. This might be NULL, meaning unset (the message's sender is then
21used). Verification isn't done when the original address is just being
22verified, as otherwise there might be routing loops if someone sets up a silly
23configuration.
24
25Arguments:
26 addr the input address
27 rblock the router instance
fd6de02e 28 verify v_none / v_recipient / v_sender / v_expn
0756eb3c
PH
29 errors_to point the errors address here
30
31Returns: OK if no problem
32 DEFER if verifying the address caused a deferment
33 or a big disaster (e.g. expansion failure)
34*/
35
36int
37rf_get_errors_address(address_item *addr, router_instance *rblock,
fd6de02e 38 int verify, uschar **errors_to)
0756eb3c
PH
39{
40uschar *s;
41
d43cbe25 42*errors_to = addr->prop.errors_address;
0756eb3c
PH
43if (rblock->errors_to == NULL) return OK;
44
45s = expand_string(rblock->errors_to);
46
47if (s == NULL)
48 {
8768d548 49 if (f.expand_string_forcedfail)
0756eb3c
PH
50 {
51 DEBUG(D_route)
52 debug_printf("forced expansion failure - ignoring errors_to\n");
53 return OK;
54 }
55 addr->message = string_sprintf("%s router failed to expand \"%s\": %s",
56 rblock->name, rblock->errors_to, expand_string_message);
57 return DEFER;
58 }
59
60/* If the errors_to address is empty, it means "ignore errors" */
61
62if (*s == 0)
63 {
7eb0e5d2 64 addr->prop.ignore_error = TRUE; /* For locally detected errors */
0756eb3c
PH
65 *errors_to = US""; /* Return path for SMTP */
66 return OK;
67 }
68
69/* If we are already verifying, do not check the errors address, in order to
70save effort (but we do verify when testing an address). When we do verify, set
71the sender address to null, because that's what it will be when sending an
72error message, and there are now configuration options that control the running
73of routers by checking the sender address. When testing an address, there may
74not be a sender address. We also need to save and restore the expansion values
75associated with an address. */
76
fd6de02e 77if (verify != v_none)
0756eb3c
PH
78 {
79 *errors_to = s;
80 DEBUG(D_route)
81 debug_printf("skipped verify errors_to address: already verifying\n");
82 }
83else
84 {
8768d548 85 BOOL save_address_test_mode = f.address_test_mode;
0756eb3c
PH
86 int save1 = 0;
87 int i;
55414b25
JH
88 const uschar ***p;
89 const uschar *address_expansions_save[ADDRESS_EXPANSIONS_COUNT];
0756eb3c
PH
90 address_item *snew = deliver_make_addr(s, FALSE);
91
163144aa 92 if (sender_address)
0756eb3c
PH
93 {
94 save1 = sender_address[0];
95 sender_address[0] = 0;
96 }
97
163144aa 98 for (i = 0, p = address_expansions; *p;)
0756eb3c 99 address_expansions_save[i++] = **p++;
8768d548 100 f.address_test_mode = FALSE;
0756eb3c 101
58de37c5
PH
102 /* NOTE: the address is verified as a recipient, not a sender. This is
103 perhaps confusing. It isn't immediately obvious what to do: we want to have
104 some confidence that we can deliver to the address, in which case it will be
105 a recipient, but on the other hand, it will be passed on in SMTP deliveries
106 as a sender. However, I think on balance recipient is right because sender
107 verification is really about the *incoming* sender of the message.
108
109 If this code is changed, note that you must set vopt_fake_sender instead of
110 vopt_is_recipient, as otherwise sender_address may be altered because
111 verify_address() thinks it is dealing with *the* sender of the message. */
112
0756eb3c
PH
113 DEBUG(D_route|D_verify)
114 debug_printf("------ Verifying errors address %s ------\n", s);
58de37c5
PH
115 if (verify_address(snew, NULL,
116 vopt_is_recipient /* vopt_fake_sender is the alternative */
117 | vopt_qualify, -1, -1, -1, NULL, NULL, NULL) == OK)
118 *errors_to = snew->address;
0756eb3c
PH
119 DEBUG(D_route|D_verify)
120 debug_printf("------ End verifying errors address %s ------\n", s);
121
8768d548 122 f.address_test_mode = save_address_test_mode;
163144aa 123 for (i = 0, p = address_expansions; *p; )
0756eb3c
PH
124 **p++ = address_expansions_save[i++];
125
163144aa 126 if (sender_address) sender_address[0] = save1;
0756eb3c
PH
127 }
128
129return OK;
130}
131
132/* End of rf_get_errors_address.c */