OpenSSL: under resumption open ticket DB writable, for record delete
[exim.git] / src / src / routers / rf_get_transport.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#include "../exim.h"
9#include "rf_functions.h"
10
11
12/*************************************************
13* Get transport for a router *
14*************************************************/
15
16/* If transport_name contains $, it must be expanded each time and used as a
17transport name. Otherwise, look up the transport only if the destination is not
18already set.
19
20Some routers (e.g. accept) insist that their transport option is set at
21initialization time. However, for some (e.g. file_transport in redirect), there
22is no such check, because the transport may not be required. Calls to this
23function from the former type of router have require_name = NULL, because it
24will never be used. NULL is also used in verify_only cases, where a transport
25is not required.
26
27Arguments:
28 tpname the text of the transport name
29 tpptr where to put the transport
30 addr the address being processed
31 router_name for error messages
32 require_name used in the error message if transport is unset
33
34Returns: TRUE if *tpptr is already set and tpname has no '$' in it;
35 TRUE if a transport has been placed in tpptr;
36 FALSE if there's a problem, in which case
37 addr->message contains a message, and addr->basic_errno has
38 ERRNO_BADTRANSPORT set in it.
39*/
40
41BOOL
42rf_get_transport(uschar *tpname, transport_instance **tpptr, address_item *addr,
43 uschar *router_name, uschar *require_name)
44{
45uschar *ss;
46BOOL expandable;
0756eb3c 47
f3ebb786 48if (!tpname)
0756eb3c 49 {
f3ebb786 50 if (!require_name) return TRUE;
0756eb3c
PH
51 addr->basic_errno = ERRNO_BADTRANSPORT;
52 addr->message = string_sprintf("%s unset in %s router", require_name,
53 router_name);
54 return FALSE;
55 }
56
57expandable = Ustrchr(tpname, '$') != NULL;
58if (*tpptr != NULL && !expandable) return TRUE;
59
60if (expandable)
61 {
f3ebb786 62 if (!(ss = expand_string(tpname)))
0756eb3c
PH
63 {
64 addr->basic_errno = ERRNO_BADTRANSPORT;
65 addr->message = string_sprintf("failed to expand transport "
66 "\"%s\" in %s router: %s", tpname, router_name, expand_string_message);
67 return FALSE;
68 }
f3ebb786
JH
69 if (is_tainted(ss))
70 {
71 log_write(0, LOG_MAIN|LOG_PANIC,
72 "attempt to use tainted value '%s' from '%s' for transport", ss, tpname);
73 addr->basic_errno = ERRNO_BADTRANSPORT;
74 /* Avoid leaking info to an attacker */
75 addr->message = US"internal configuration error";
76 return FALSE;
77 }
0756eb3c 78 }
f3ebb786
JH
79else
80 ss = tpname;
0756eb3c 81
d7978c0f 82for (transport_instance * tp = transports; tp; tp = tp->next)
0756eb3c
PH
83 if (Ustrcmp(tp->name, ss) == 0)
84 {
85 DEBUG(D_route) debug_printf("set transport %s\n", ss);
86 *tpptr = tp;
87 return TRUE;
88 }
0756eb3c
PH
89
90addr->basic_errno = ERRNO_BADTRANSPORT;
91addr->message = string_sprintf("transport \"%s\" not found in %s router", ss,
92 router_name);
93return FALSE;
94}
95
96/* End of rf_get_transport.c */