Commit | Line | Data |
---|---|---|
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 | |
18 | particular address. If there is a setting in the router block, then expand and | |
19 | verify it, and if it works, use it. Otherwise use any setting that is in the | |
20 | address itself. This might be NULL, meaning unset (the message's sender is then | |
21 | used). Verification isn't done when the original address is just being | |
22 | verified, as otherwise there might be routing loops if someone sets up a silly | |
23 | configuration. | |
24 | ||
25 | Arguments: | |
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 | ||
31 | Returns: OK if no problem | |
32 | DEFER if verifying the address caused a deferment | |
33 | or a big disaster (e.g. expansion failure) | |
34 | */ | |
35 | ||
36 | int | |
37 | rf_get_errors_address(address_item *addr, router_instance *rblock, | |
fd6de02e | 38 | int verify, uschar **errors_to) |
0756eb3c PH |
39 | { |
40 | uschar *s; | |
41 | ||
d43cbe25 | 42 | *errors_to = addr->prop.errors_address; |
0756eb3c PH |
43 | if (rblock->errors_to == NULL) return OK; |
44 | ||
45 | s = expand_string(rblock->errors_to); | |
46 | ||
47 | if (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 | ||
62 | if (*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 | |
70 | save effort (but we do verify when testing an address). When we do verify, set | |
71 | the sender address to null, because that's what it will be when sending an | |
72 | error message, and there are now configuration options that control the running | |
73 | of routers by checking the sender address. When testing an address, there may | |
74 | not be a sender address. We also need to save and restore the expansion values | |
75 | associated with an address. */ | |
76 | ||
fd6de02e | 77 | if (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 | } | |
83 | else | |
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 | ||
129 | return OK; | |
130 | } | |
131 | ||
132 | /* End of rf_get_errors_address.c */ |