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