Commit | Line | Data |
---|---|---|
0756eb3c PH |
1 | /************************************************* |
2 | * Exim - an Internet mail transport agent * | |
3 | *************************************************/ | |
4 | ||
0a49a7a4 | 5 | /* Copyright (c) University of Cambridge 1995 - 2009 */ |
0756eb3c PH |
6 | /* See the file NOTICE for conditions of use and distribution. */ |
7 | ||
8 | ||
9 | #include "../exim.h" | |
10 | #include "rf_functions.h" | |
11 | ||
12 | ||
13 | ||
14 | /************************************************* | |
15 | * Decode actions for self reference * | |
16 | *************************************************/ | |
17 | ||
18 | /* This function is called from a number of routers on receiving | |
19 | HOST_FOUND_LOCAL when looking up a supposedly remote host. The action is | |
20 | controlled by a generic configuration option called "self" on each router, | |
21 | which can be one of: | |
22 | ||
23 | . freeze: Log the incident, freeze, and return DEFER | |
24 | ||
25 | . defer: Log the incident and return DEFER | |
26 | ||
27 | . fail: Fail the address | |
28 | ||
29 | . send: Carry on with the delivery regardless - | |
30 | this makes sense only if the SMTP | |
31 | listener on this machine is a differently | |
32 | configured MTA | |
33 | ||
34 | . pass: The router passes; the address | |
35 | gets passed to the next router, overriding | |
36 | the setting of no_more | |
37 | ||
38 | . reroute:<new-domain> Change the domain to the given domain | |
39 | and return REROUTE so it gets passed back | |
40 | to the routers. | |
41 | ||
42 | . reroute:rewrite:<new-domain> The same, but headers containing the | |
43 | old domain get rewritten. | |
44 | ||
45 | These string values are interpreted earlier on, and passed into this function | |
46 | as the values of "code" and "rewrite". | |
47 | ||
48 | Arguments: | |
49 | addr the address being routed | |
50 | host the host that is local, with MX set (or -1 if MX not used) | |
51 | code the action to be taken (one of the self_xxx enums) | |
52 | rewrite TRUE if rewriting headers required for REROUTED | |
53 | new new domain to be used for REROUTED | |
54 | addr_new child chain for REROUTEED | |
55 | ||
56 | Returns: DEFER, REROUTED, PASS, FAIL, or OK, according to the value of code. | |
57 | */ | |
58 | ||
59 | int | |
60 | rf_self_action(address_item *addr, host_item *host, int code, BOOL rewrite, | |
61 | uschar *new, address_item **addr_new) | |
62 | { | |
63 | uschar *msg = (host->mx >= 0)? | |
64 | US"lowest numbered MX record points to local host" : | |
65 | US"remote host address is the local host"; | |
66 | ||
67 | switch (code) | |
68 | { | |
69 | case self_freeze: | |
70 | ||
71 | /* If there is no message id, this is happening during an address | |
72 | verification, so give information about the address that is being verified, | |
73 | and where it has come from. Otherwise, during message delivery, the normal | |
74 | logging for the address will be sufficient. */ | |
75 | ||
76 | if (message_id[0] == 0) | |
77 | { | |
78 | if (sender_fullhost == NULL) | |
79 | { | |
80 | log_write(0, LOG_MAIN, "%s: %s (while routing <%s>)", msg, | |
81 | addr->domain, addr->address); | |
82 | } | |
83 | else | |
84 | { | |
85 | log_write(0, LOG_MAIN, "%s: %s (while verifying <%s> from host %s)", | |
86 | msg, addr->domain, addr->address, sender_fullhost); | |
87 | } | |
88 | } | |
89 | else | |
90 | log_write(0, LOG_MAIN, "%s: %s", msg, addr->domain); | |
91 | ||
92 | addr->message = msg; | |
93 | addr->special_action = SPECIAL_FREEZE; | |
94 | return DEFER; | |
95 | ||
96 | case self_defer: | |
97 | addr->message = msg; | |
98 | return DEFER; | |
99 | ||
100 | case self_reroute: | |
101 | DEBUG(D_route) | |
102 | { | |
103 | debug_printf("%s: %s", msg, addr->domain); | |
104 | debug_printf(": domain changed to %s\n", new); | |
105 | } | |
106 | rf_change_domain(addr, new, rewrite, addr_new); | |
107 | return REROUTED; | |
108 | ||
109 | case self_send: | |
110 | DEBUG(D_route) | |
111 | { | |
112 | debug_printf("%s: %s", msg, addr->domain); | |
113 | debug_printf(": configured to try delivery anyway\n"); | |
114 | } | |
115 | return OK; | |
116 | ||
117 | case self_pass: /* This is soft failure; pass to next router */ | |
118 | DEBUG(D_route) | |
119 | { | |
120 | debug_printf("%s: %s", msg, addr->domain); | |
121 | debug_printf(": passed to next router (self = pass)\n"); | |
122 | } | |
123 | addr->message = msg; | |
124 | addr->self_hostname = string_copy(host->name); | |
125 | return PASS; | |
126 | ||
127 | case self_fail: | |
128 | DEBUG(D_route) | |
129 | { | |
130 | debug_printf("%s: %s", msg, addr->domain); | |
131 | debug_printf(": address failed (self = fail)\n"); | |
132 | } | |
133 | addr->message = msg; | |
16f12c76 | 134 | setflag(addr, af_pass_message); |
0756eb3c PH |
135 | return FAIL; |
136 | } | |
137 | ||
138 | return DEFER; /* paranoia */ | |
139 | } | |
140 | ||
141 | /* End of rf_self_action.c */ |