sender verify callout
[exim.git] / src / src / routers / ipliteral.c
CommitLineData
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#include "ipliteral.h"
12
13
14/* Options specific to the ipliteral router. Because some compilers do not like
15empty declarations ("undefined" in the Standard) we put in a dummy value. */
16
17optionlist ipliteral_router_options[] = {
18 { "", opt_hidden, NULL }
19};
20
21/* Size of the options list. An extern variable has to be used so that its
22address can appear in the tables drtables.c. */
23
24int ipliteral_router_options_count =
25 sizeof(ipliteral_router_options)/sizeof(optionlist);
26
27/* Default private options block for the ipliteral router. Again, a dummy
28value is present to keep some compilers happy. */
29
30ipliteral_router_options_block ipliteral_router_option_defaults = { 0 };
31
32
33
34/*************************************************
35* Initialization entry point *
36*************************************************/
37
38/* Called for each instance, after its options have been read, to enable
39consistency checks to be done, or anything else that needs to be set up. */
40
41void
42ipliteral_router_init(router_instance *rblock)
43{
44/*
45ipliteral_router_options_block *ob =
46 (ipliteral_router_options_block *)(rblock->options_block);
47*/
48rblock = rblock;
49}
50
51
52
53/*************************************************
54* Main entry point *
55*************************************************/
56
57/* See local README for interface details. This router returns:
58
59DECLINE
60 . the domain is not in the form of an IP literal
61
62DEFER
63 . verifying the errors address caused a deferment or a big disaster such
64 as an expansion failure (rf_get_errors_address)
65 . expanding a headers_{add,remove} string caused a deferment or another
66 expansion error (rf_get_munge_headers)
67 . a problem in rf_get_transport: no transport when one is needed;
68 failed to expand dynamic transport; failed to find dynamic transport
69 . failure to expand or find a uid/gid (rf_get_ugid via rf_queue_add)
70 . self = "freeze", self = "defer"
71
72PASS
73 . self = "pass"
74
75REROUTED
76 . self = "reroute"
77
78FAIL
79 . self = "fail"
80
81OK
82 added address to addr_local or addr_remote, as appropriate for the
83 type of transport; this includes the self="send" case.
84*/
85
86int
87ipliteral_router_entry(
88 router_instance *rblock, /* data for this instantiation */
89 address_item *addr, /* address we are working on */
90 struct passwd *pw, /* passwd entry after check_local_user */
fd6de02e 91 int verify, /* v_none/v_recipient/v_sender/v_expn */
0756eb3c
PH
92 address_item **addr_local, /* add it to this if it's local */
93 address_item **addr_remote, /* add it to this if it's remote */
94 address_item **addr_new, /* put new addresses on here */
95 address_item **addr_succeed) /* put old address here on success */
96{
97/*
98ipliteral_router_options_block *ob =
99 (ipliteral_router_options_block *)(rblock->options_block);
100*/
101host_item *h;
55414b25
JH
102const uschar *domain = addr->domain;
103const uschar *ip;
0756eb3c 104int len = Ustrlen(domain);
7e66e54d 105int rc, ipv;
0756eb3c
PH
106
107addr_new = addr_new; /* Keep picky compilers happy */
108addr_succeed = addr_succeed;
109
110DEBUG(D_route) debug_printf("%s router called for %s: domain = %s\n",
111 rblock->name, addr->address, addr->domain);
112
f9daeae0
PH
113/* Check that the domain is an IP address enclosed in square brackets. Remember
114to allow for the "official" form of IPv6 addresses. If not, the router
115declines. Otherwise route to the single IP address, setting the host name to
116"(unnamed)". */
0756eb3c
PH
117
118if (domain[0] != '[' || domain[len-1] != ']') return DECLINE;
55414b25 119ip = string_copyn(domain+1, len-2);
f9daeae0
PH
120if (strncmpic(ip, US"IPV6:", 5) == 0 || strncmpic(ip, US"IPV4:", 5) == 0)
121 ip += 5;
122
7e66e54d
PH
123ipv = string_is_ip_address(ip, NULL);
124if (ipv == 0 || (disable_ipv6 && ipv == 6))
0756eb3c 125 return DECLINE;
0756eb3c
PH
126
127/* It seems unlikely that ignore_target_hosts will be used with this router,
128but if it is set, it should probably work. */
129
55414b25
JH
130if (verify_check_this_host(CUSS&rblock->ignore_target_hosts,
131 NULL, domain, ip, NULL) == OK)
0756eb3c
PH
132 {
133 DEBUG(D_route)
f9daeae0 134 debug_printf("%s is in ignore_target_hosts\n", ip);
0756eb3c 135 addr->message = US"IP literal host explicitly ignored";
0756eb3c
PH
136 return DECLINE;
137 }
138
139/* Set up a host item */
140
141h = store_get(sizeof(host_item));
142
143h->next = NULL;
f9daeae0 144h->address = string_copy(ip);
0756eb3c 145h->port = PORT_NONE;
55414b25 146h->name = domain;
0756eb3c
PH
147h->mx = MX_NONE;
148h->status = hstatus_unknown;
149h->why = hwhy_unknown;
150h->last_try = 0;
151
152/* Determine whether the host is the local host, and if so, take action
153according to the configuration. */
154
155if (host_scan_for_local_hosts(h, &h, NULL) == HOST_FOUND_LOCAL)
156 {
157 int rc = rf_self_action(addr, h, rblock->self_code, rblock->self_rewrite,
158 rblock->self, addr_new);
159 if (rc != OK) return rc;
160 }
161
162/* Address is routed to this host */
163
164addr->host_list = h;
165
166/* Set up the errors address, if any. */
167
168rc = rf_get_errors_address(addr, rblock, verify, &(addr->p.errors_address));
169if (rc != OK) return rc;
170
171/* Set up the additional and removeable headers for this address. */
172
173rc = rf_get_munge_headers(addr, rblock, &(addr->p.extra_headers),
174 &(addr->p.remove_headers));
175if (rc != OK) return rc;
176
177/* Fill in the transport, queue the address for local or remote delivery, and
178yield success. For local delivery, of course, the IP address won't be used. If
179just verifying, there need not be a transport, in which case it doesn't matter
180which queue we put the address on. This is all now handled by the route_queue()
181function. */
182
183if (!rf_get_transport(rblock->transport_name, &(rblock->transport),
184 addr, rblock->name, NULL))
185 return DEFER;
186
187addr->transport = rblock->transport;
188
189return rf_queue_add(addr, addr_local, addr_remote, rblock, pw)?
190 OK : DEFER;
191}
192
193/* End of routers/ipliteral.c */