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