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 | #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 | |
17 | transport name. Otherwise, look up the transport only if the destination is not | |
18 | already set. | |
19 | ||
20 | Some routers (e.g. accept) insist that their transport option is set at | |
21 | initialization time. However, for some (e.g. file_transport in redirect), there | |
22 | is no such check, because the transport may not be required. Calls to this | |
23 | function from the former type of router have require_name = NULL, because it | |
24 | will never be used. NULL is also used in verify_only cases, where a transport | |
25 | is not required. | |
26 | ||
27 | Arguments: | |
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 | ||
34 | Returns: 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 | ||
41 | BOOL | |
42 | rf_get_transport(uschar *tpname, transport_instance **tpptr, address_item *addr, | |
43 | uschar *router_name, uschar *require_name) | |
44 | { | |
45 | uschar *ss; | |
46 | BOOL expandable; | |
0756eb3c | 47 | |
f3ebb786 | 48 | if (!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 | ||
57 | expandable = Ustrchr(tpname, '$') != NULL; | |
58 | if (*tpptr != NULL && !expandable) return TRUE; | |
59 | ||
60 | if (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 |
79 | else |
80 | ss = tpname; | |
0756eb3c | 81 | |
d7978c0f | 82 | for (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 | |
90 | addr->basic_errno = ERRNO_BADTRANSPORT; | |
91 | addr->message = string_sprintf("transport \"%s\" not found in %s router", ss, | |
92 | router_name); | |
93 | return FALSE; | |
94 | } | |
95 | ||
96 | /* End of rf_get_transport.c */ |