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