* 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-or-later */
/* Functions concerned with routing, and the list of generic router options. */
/* 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 */
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;
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)
{
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;
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
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);
}
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);
}
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);
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
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;
{
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;
}
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)
{
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 */