X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/46d2a5e6f6e7709d172903b13945d23fc0a2c888..a85c067ba6c6940512cf57ec213277a370d87e70:/src/src/route.c diff --git a/src/src/route.c b/src/src/route.c index c7833ebb4..7e6e4eb69 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -2,8 +2,10 @@ * Exim - an Internet mail transport agent * *************************************************/ +/* Copyright (c) The Exim Maintainers 2020 - 2022 */ /* Copyright (c) University of Cambridge 1995 - 2018 */ /* See the file NOTICE for conditions of use and distribution. */ +/* SPDX-License-Identifier: GPL-2.0-only */ /* Functions concerned with routing, and the list of generic router options. */ @@ -287,7 +289,12 @@ for (router_instance * r = routers; r; r = r->next) /* Build a host list if fallback hosts is set. */ - host_build_hostlist(&(r->fallback_hostlist), r->fallback_hosts, FALSE); + { + int old_pool = store_pool; + store_pool = POOL_PERM; + host_build_hostlist(&r->fallback_hostlist, r->fallback_hosts, FALSE); + store_pool = old_pool; + } /* Check redirect_router and pass_router are valid */ @@ -606,14 +613,13 @@ gid_t gid = 0; /* For picky compilers */ BOOL ugid_set = FALSE; const uschar *listptr; uschar *check; -uschar buffer[1024]; if (!s) return OK; DEBUG(D_route) debug_printf("checking require_files\n"); listptr = s; -while ((check = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))) +while ((check = string_nextinlist(&listptr, &sep, NULL, 0))) { int rc; int eacces_code = 0; @@ -947,7 +953,7 @@ if ((rc = route_check_dls(r->name, US"local_parts", r->local_parts, login of a local user. Note: the third argument to route_finduser() must be NULL here, to prevent a numeric string being taken as a numeric uid. If the user is found, set deliver_home to the home directory, and also set -local_user_{uid,gid} and local_part_verified. */ +local_user_{uid,gid} and local_part_data. */ if (r->check_local_user) { @@ -958,7 +964,8 @@ if (r->check_local_user) r->name, addr->local_part); return SKIP; } - deliver_localpart_verified = string_copy(US (*pw)->pw_name); + addr->prop.localpart_data = + deliver_localpart_data = string_copy(US (*pw)->pw_name); deliver_home = string_copy(US (*pw)->pw_dir); local_user_gid = (*pw)->pw_gid; local_user_uid = (*pw)->pw_uid; @@ -972,22 +979,19 @@ confusing. */ if (r->router_home_directory) { - uschar *router_home = expand_string(r->router_home_directory); - if (!router_home) - { - if (!f.expand_string_forcedfail) - { - *perror = string_sprintf("failed to expand \"%s\" for " - "router_home_directory: %s", r->router_home_directory, - expand_string_message); - return DEFER; - } - } - else + uschar * router_home = expand_string(r->router_home_directory); + if (router_home) { setflag(addr, af_home_expanded); /* Note set from router_home_directory */ deliver_home = router_home; } + else if (!f.expand_string_forcedfail) + { + *perror = string_sprintf("failed to expand \"%s\" for " + "router_home_directory: %s", r->router_home_directory, + expand_string_message); + return DEFER; + } } /* Skip if the sender condition is not met. We leave this one till after the @@ -1496,7 +1500,7 @@ for (uschar * ele; (ele = string_nextinlist(&varlist, &sep, NULL, 0)); ) if (!(node = tree_search(*root, name))) { /* name should never be tainted */ - node = store_get(sizeof(tree_node) + Ustrlen(name), FALSE); + node = store_get(sizeof(tree_node) + Ustrlen(name), GET_UNTAINTED); Ustrcpy(node->name, name); (void)tree_insertnode(root, node); } @@ -1656,8 +1660,18 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) int plen = route_check_prefix(addr->local_part, r->prefix, &vlen); if (plen > 0) { - addr->prefix = string_copyn(addr->local_part, plen); - if (vlen) addr->prefix_v = string_copyn(addr->local_part, vlen); + /* If the variable-part is zero-length then the prefix was not + wildcarded and we can detaint-copy it since it matches the + (non-expandable) router option. Otherwise copy the (likely) tainted match + and the variable-part of the match from the local_part. */ + + if (vlen) + { + addr->prefix = string_copyn(addr->local_part, plen); + addr->prefix_v = string_copyn(addr->local_part, vlen); + } + else + addr->prefix = string_copyn_taint(addr->local_part, plen, GET_UNTAINTED); addr->local_part += plen; DEBUG(D_route) debug_printf("stripped prefix %s\n", addr->prefix); } @@ -1678,7 +1692,9 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) if (slen > 0) { int lplen = Ustrlen(addr->local_part) - slen; - addr->suffix = addr->local_part + lplen; + addr->suffix = vlen + ? addr->local_part + lplen + : string_copy_taint(addr->local_part + lplen, GET_UNTAINTED); addr->suffix_v = addr->suffix + Ustrlen(addr->suffix) - vlen; addr->local_part = string_copyn(addr->local_part, lplen); DEBUG(D_route) debug_printf("stripped suffix %s\n", addr->suffix); @@ -1695,7 +1711,8 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) the local part sorted. */ router_name = r->name; - deliver_localpart_verified = NULL; + driver_srcfile = r->srcfile; + driver_srcline = r->srcline; deliver_set_expansions(addr); /* For convenience, the pre-router checks are in a separate function, which @@ -1703,7 +1720,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) if ((rc = check_router_conditions(r, addr, verify, &pw, &error)) != OK) { - router_name = NULL; + driver_srcfile = router_name = NULL; driver_srcline = 0; if (rc == SKIP) continue; addr->message = error; yield = rc; @@ -1754,7 +1771,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) { DEBUG(D_route) debug_printf("\"more\"=false: skipping remaining routers\n"); - router_name = NULL; + driver_srcfile = router_name = NULL; driver_srcline = 0; r = NULL; break; } @@ -1806,7 +1823,7 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) yield = (r->info->code)(r, addr, pw, verify, paddr_local, paddr_remote, addr_new, addr_succeed); - router_name = NULL; + driver_srcfile = router_name = NULL; driver_srcline = 0; if (yield == FAIL) { @@ -2034,10 +2051,23 @@ if (yield == DEFER && addr->message) addr->message = expand_hide_passwords(addr->message); deliver_set_expansions(NULL); -router_name = NULL; +driver_srcfile = router_name = NULL; driver_srcline = 0; f.disable_logging = FALSE; return yield; } + + +/* For error messages, a string describing the config location associated +with current processing. NULL if we are not in a router. */ +/* Name only, for now */ + +uschar * +router_current_name(void) +{ +if (!router_name) return NULL; +return string_sprintf(" (router %s, %s %d)", router_name, driver_srcfile, driver_srcline); +} + #endif /*!MACRO_PREDEF*/ /* End of route.c */