X-Git-Url: https://git.exim.org/exim.git/blobdiff_plain/059ec3d9952740285fb1ebf47961b8aca2eb1b4a..184e88237dea64ce48076cdd0184612d057cbafd:/src/src/route.c diff --git a/src/src/route.c b/src/src/route.c index 427570ef7..aa27b5cb3 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -1,10 +1,10 @@ -/* $Cambridge: exim/src/src/route.c,v 1.1 2004/10/07 10:39:01 ph10 Exp $ */ +/* $Cambridge: exim/src/src/route.c,v 1.12 2007/01/08 10:50:18 ph10 Exp $ */ /************************************************* * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2004 */ +/* Copyright (c) University of Cambridge 1995 - 2007 */ /* See the file NOTICE for conditions of use and distribution. */ /* Functions concerned with routing, and the list of generic router options. */ @@ -34,6 +34,16 @@ optionlist optionlist_routers[] = { (void *)(offsetof(router_instance, address_data)) }, { "address_test", opt_bool|opt_public, (void *)(offsetof(router_instance, address_test)) }, +#ifdef EXPERIMENTAL_BRIGHTMAIL + { "bmi_deliver_alternate", opt_bool | opt_public, + (void *)(offsetof(router_instance, bmi_deliver_alternate)) }, + { "bmi_deliver_default", opt_bool | opt_public, + (void *)(offsetof(router_instance, bmi_deliver_default)) }, + { "bmi_dont_deliver", opt_bool | opt_public, + (void *)(offsetof(router_instance, bmi_dont_deliver)) }, + { "bmi_rule", opt_stringptr|opt_public, + (void *)(offsetof(router_instance, bmi_rule)) }, +#endif { "cannot_route_message", opt_stringptr | opt_public, (void *)(offsetof(router_instance, cannot_route_message)) }, { "caseful_local_part", opt_bool | opt_public, @@ -982,6 +992,46 @@ if (r->condition != NULL) } } +#ifdef EXPERIMENTAL_BRIGHTMAIL +/* check if a specific Brightmail AntiSpam rule fired on the message */ +if (r->bmi_rule != NULL) { + DEBUG(D_route) debug_printf("checking bmi_rule\n"); + if (bmi_check_rule(bmi_base64_verdict, r->bmi_rule) == 0) { + /* none of the rules fired */ + DEBUG(D_route) + debug_printf("%s router skipped: none of bmi_rule rules fired\n", r->name); + return SKIP; + }; +}; + +/* check if message should not be delivered */ +if (r->bmi_dont_deliver) { + if (bmi_deliver == 1) { + DEBUG(D_route) + debug_printf("%s router skipped: bmi_dont_deliver is FALSE\n", r->name); + return SKIP; + }; +}; + +/* check if message should go to an alternate location */ +if (r->bmi_deliver_alternate) { + if ((bmi_deliver == 0) || (bmi_alt_location == NULL)) { + DEBUG(D_route) + debug_printf("%s router skipped: bmi_deliver_alternate is FALSE\n", r->name); + return SKIP; + }; +}; + +/* check if message should go to default location */ +if (r->bmi_deliver_default) { + if ((bmi_deliver == 0) || (bmi_alt_location != NULL)) { + DEBUG(D_route) + debug_printf("%s router skipped: bmi_deliver_default is FALSE\n", r->name); + return SKIP; + }; +}; +#endif + /* All the checks passed. */ return OK; @@ -1027,7 +1077,12 @@ static uschar lastshell[128]; BOOL route_finduser(uschar *s, struct passwd **pw, uid_t *return_uid) { -if (Ustrcmp(lastname, s) != 0) +BOOL cache_set = (Ustrcmp(lastname, s) == 0); + +DEBUG(D_uid) debug_printf("seeking password data for user \"%s\": %s\n", s, + cache_set? "using cached result" : "cache not available"); + +if (!cache_set) { int i = 0; @@ -1054,6 +1109,7 @@ if (Ustrcmp(lastname, s) != 0) else for (;;) { + errno = 0; if ((lastpw = getpwnam(CS s)) != NULL) break; if (++i > finduser_retries) break; sleep(1); @@ -1072,14 +1128,25 @@ if (Ustrcmp(lastname, s) != 0) pwcopy.pw_shell = CS lastshell; lastpw = &pwcopy; } + + else DEBUG(D_uid) + { + if (errno != 0) debug_printf("getpwnam(%s) failed: %s\n", s, + strerror(errno)); + } + } + +if (lastpw == NULL) + { + DEBUG(D_uid) debug_printf("getpwnam() returned NULL (user not found)\n"); + return FALSE; } else { - DEBUG(D_uid) debug_printf("finduser used cached passwd data for %s\n", s); + DEBUG(D_uid) debug_printf("getpwnam() succeeded uid=%d gid=%d\n", + lastpw->pw_uid, lastpw->pw_gid); } -if (lastpw == NULL) return FALSE; - if (return_uid != NULL) *return_uid = lastpw->pw_uid; if (pw != NULL) *pw = lastpw; @@ -1647,8 +1714,8 @@ for (r = (addr->start_router == NULL)? routers : addr->start_router; HDEBUG(D_route) debug_printf("calling %s router\n", r->name); - yield = (r->info->code)(r, addr, pw, verify != v_none, paddr_local, - paddr_remote, addr_new, addr_succeed); + yield = (r->info->code)(r, addr, pw, verify, paddr_local, paddr_remote, + addr_new, addr_succeed); if (yield == FAIL) { @@ -1804,7 +1871,7 @@ if (r->translate_ip_address != NULL) DEBUG(D_route) debug_printf("%s [%s] translated to %s\n", h->name, h->address, newaddress); - if (string_is_ip_address(newaddress, NULL)) + if (string_is_ip_address(newaddress, NULL) != 0) { h->address = newaddress; continue; @@ -1817,7 +1884,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) @@ -1839,8 +1906,6 @@ yield = exp_bool(addr, r->name, US"unseen", r->unseen, r->expand_unseen, &unseen); if (yield != OK) goto ROUTE_EXIT; - - /* Debugging output recording a successful routing */ HDEBUG(D_route)