X-Git-Url: https://vcs.fsf.org/?p=exim.git;a=blobdiff_plain;f=src%2Fsrc%2Froute.c;h=271175e4bee12f076ad64c9b4ed10539ad37615c;hp=436f769a275e644d5be4d931a267720af41b70bc;hb=d2af03f4c11273d6f52c9043119e24e732080885;hpb=d8fe1c03b30ec7dba12669726e41b3b6f5303632 diff --git a/src/src/route.c b/src/src/route.c index 436f769a2..271175e4b 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -1,10 +1,8 @@ -/* $Cambridge: exim/src/src/route.c,v 1.9 2006/07/14 14:00:16 ph10 Exp $ */ - /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2006 */ +/* Copyright (c) University of Cambridge 1995 - 2014 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions concerned with routing, and the list of generic router options. */ @@ -50,7 +48,7 @@ optionlist optionlist_routers[] = { (void *)(offsetof(router_instance, caseful_local_part)) }, { "check_local_user", opt_bool | opt_public, (void *)(offsetof(router_instance, check_local_user)) }, - { "condition", opt_stringptr|opt_public, + { "condition", opt_stringptr|opt_public|opt_rep_con, (void *)offsetof(router_instance, condition) }, { "debug_print", opt_stringptr | opt_public, (void *)offsetof(router_instance, debug_string) }, @@ -74,9 +72,9 @@ optionlist optionlist_routers[] = { (void *)offsetof(router_instance, fallback_hosts) }, { "group", opt_expand_gid | opt_public, (void *)(offsetof(router_instance, gid)) }, - { "headers_add", opt_stringptr|opt_public, + { "headers_add", opt_stringptr|opt_public|opt_rep_str, (void *)offsetof(router_instance, extra_headers) }, - { "headers_remove", opt_stringptr|opt_public, + { "headers_remove", opt_stringptr|opt_public|opt_rep_str, (void *)offsetof(router_instance, remove_headers) }, { "ignore_target_hosts",opt_stringptr|opt_public, (void *)offsetof(router_instance, ignore_target_hosts) }, @@ -825,6 +823,7 @@ check_router_conditions(router_instance *r, address_item *addr, int verify, { int rc; uschar *check_local_part; +unsigned int *localpart_cache; /* Reset variables to hold a home directory and data from lookup of a domain or local part, and ensure search_find_defer is unset, in case there aren't any @@ -885,12 +884,17 @@ if ((rc = route_check_dls(r->name, US"domains", r->domains, &domainlist_anchor, caseful local part, so that +caseful can restore it, even if this router is handling local parts caselessly. However, we can't just pass cc_local_part, because that doesn't have the prefix or suffix stripped. A bit of massaging is -required. */ +required. Also, we only use the match cache for local parts that have not had +a prefix or suffix stripped. */ if (addr->prefix == NULL && addr->suffix == NULL) + { + localpart_cache = addr->localpart_cache; check_local_part = addr->cc_local_part; + } else { + localpart_cache = NULL; check_local_part = string_copy(addr->cc_local_part); if (addr->prefix != NULL) check_local_part += Ustrlen(addr->prefix); @@ -899,7 +903,7 @@ else } if ((rc = route_check_dls(r->name, US"local_parts", r->local_parts, - &localpartlist_anchor, addr->localpart_cache, MCL_LOCALPART, + &localpartlist_anchor, localpart_cache, MCL_LOCALPART, check_local_part, &deliver_localpart_data, !r->caseful_local_part, perror)) != OK) return rc; @@ -1109,6 +1113,7 @@ if (!cache_set) else for (;;) { + errno = 0; if ((lastpw = getpwnam(CS s)) != NULL) break; if (++i > finduser_retries) break; sleep(1); @@ -1628,6 +1633,7 @@ for (r = (addr->start_router == NULL)? routers : addr->start_router; /* Set the expansion variables now that we have the affixes and the case of the local part sorted. */ + router_name = r->name; deliver_set_expansions(addr); /* For convenience, the pre-router checks are in a separate function, which @@ -1635,6 +1641,7 @@ for (r = (addr->start_router == NULL)? routers : addr->start_router; if ((rc = check_router_conditions(r, addr, verify, &pw, &error)) != OK) { + router_name = NULL; if (rc == SKIP) continue; addr->message = error; yield = rc; @@ -1673,6 +1680,7 @@ for (r = (addr->start_router == NULL)? routers : addr->start_router; { DEBUG(D_route) debug_printf("\"more\"=false: skipping remaining routers\n"); + router_name = NULL; r = NULL; break; } @@ -1716,6 +1724,8 @@ for (r = (addr->start_router == NULL)? routers : addr->start_router; yield = (r->info->code)(r, addr, pw, verify, paddr_local, paddr_remote, addr_new, addr_succeed); + router_name = NULL; + if (yield == FAIL) { HDEBUG(D_route) debug_printf("%s router forced address failure\n", r->name); @@ -1883,7 +1893,7 @@ if (r->translate_ip_address != NULL) h->mx = MX_NONE; store_pool = POOL_PERM; - rc = host_find_byname(h, NULL, NULL, TRUE); + rc = host_find_byname(h, NULL, HOST_FIND_QUALIFY_SINGLE, NULL, TRUE); store_pool = old_pool; if (rc == HOST_FIND_FAILED || rc == HOST_FIND_AGAIN) @@ -1945,7 +1955,27 @@ if (unseen && r->next != NULL) /* Unset the address expansions, and return the final result. */ ROUTE_EXIT: +if (yield == DEFER) { + if ( + ((Ustrstr(addr->message, "failed to expand") != NULL) || (Ustrstr(addr->message, "expansion of ") != NULL)) && + ( + Ustrstr(addr->message, "mysql") != NULL || + Ustrstr(addr->message, "pgsql") != NULL || +#ifdef EXPERIMENTAL_REDIS + Ustrstr(addr->message, "redis") != NULL || +#endif + Ustrstr(addr->message, "sqlite") != NULL || + Ustrstr(addr->message, "ldap:") != NULL || + Ustrstr(addr->message, "ldapdn:") != NULL || + Ustrstr(addr->message, "ldapm:") != NULL + ) + ) { + addr->message = string_sprintf("Temporary internal error"); + } +} + deliver_set_expansions(NULL); +router_name = NULL; disable_logging = FALSE; return yield; }