X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Froute.c;h=fd3cb3e6483675909697b78c5ead65013e0ce95d;hb=afd5e75ffc8f64f0ebed1df9dce64793011c14a6;hp=16ce72c2b1588bac41bb4b0f83d4ff05d3de20bc;hpb=163144aab02a47427340d0ecc75e2abde675f4c9;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/route.c b/src/src/route.c index 16ce72c2b..fd3cb3e64 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -14,132 +14,133 @@ /* Generic options for routers, all of which live inside router_instance data blocks and which therefore have the opt_public flag set. */ +#define LOFF(field) OPT_OFF(router_instance, field) optionlist optionlist_routers[] = { { "*expand_group", opt_stringptr | opt_hidden | opt_public, - (void *)(offsetof(router_instance, expand_gid)) }, + LOFF(expand_gid) }, { "*expand_more", opt_stringptr | opt_hidden | opt_public, - (void *)(offsetof(router_instance, expand_more)) }, + LOFF(expand_more) }, { "*expand_unseen", opt_stringptr | opt_hidden | opt_public, - (void *)(offsetof(router_instance, expand_unseen)) }, + LOFF(expand_unseen) }, { "*expand_user", opt_stringptr | opt_hidden | opt_public, - (void *)(offsetof(router_instance, expand_uid)) }, + LOFF(expand_uid) }, { "*set_group", opt_bool | opt_hidden | opt_public, - (void *)(offsetof(router_instance, gid_set)) }, + LOFF(gid_set) }, { "*set_user", opt_bool | opt_hidden | opt_public, - (void *)(offsetof(router_instance, uid_set)) }, + LOFF(uid_set) }, { "address_data", opt_stringptr|opt_public, - (void *)(offsetof(router_instance, address_data)) }, + LOFF(address_data) }, { "address_test", opt_bool|opt_public, - (void *)(offsetof(router_instance, address_test)) }, + LOFF(address_test) }, #ifdef EXPERIMENTAL_BRIGHTMAIL { "bmi_deliver_alternate", opt_bool | opt_public, - (void *)(offsetof(router_instance, bmi_deliver_alternate)) }, + LOFF(bmi_deliver_alternate) }, { "bmi_deliver_default", opt_bool | opt_public, - (void *)(offsetof(router_instance, bmi_deliver_default)) }, + LOFF(bmi_deliver_default) }, { "bmi_dont_deliver", opt_bool | opt_public, - (void *)(offsetof(router_instance, bmi_dont_deliver)) }, + LOFF(bmi_dont_deliver) }, { "bmi_rule", opt_stringptr|opt_public, - (void *)(offsetof(router_instance, bmi_rule)) }, + LOFF(bmi_rule) }, #endif { "cannot_route_message", opt_stringptr | opt_public, - (void *)(offsetof(router_instance, cannot_route_message)) }, + LOFF(cannot_route_message) }, { "caseful_local_part", opt_bool | opt_public, - (void *)(offsetof(router_instance, caseful_local_part)) }, + LOFF(caseful_local_part) }, { "check_local_user", opt_bool | opt_public, - (void *)(offsetof(router_instance, check_local_user)) }, + LOFF(check_local_user) }, { "condition", opt_stringptr|opt_public|opt_rep_con, - (void *)offsetof(router_instance, condition) }, + LOFF(condition) }, { "debug_print", opt_stringptr | opt_public, - (void *)offsetof(router_instance, debug_string) }, + LOFF(debug_string) }, { "disable_logging", opt_bool | opt_public, - (void *)offsetof(router_instance, disable_logging) }, + LOFF(disable_logging) }, { "dnssec_request_domains", opt_stringptr|opt_public, - (void *)offsetof(router_instance, dnssec.request) }, + LOFF(dnssec.request) }, { "dnssec_require_domains", opt_stringptr|opt_public, - (void *)offsetof(router_instance, dnssec.require) }, + LOFF(dnssec.require) }, { "domains", opt_stringptr|opt_public, - (void *)offsetof(router_instance, domains) }, + LOFF(domains) }, { "driver", opt_stringptr|opt_public, - (void *)offsetof(router_instance, driver_name) }, + LOFF(driver_name) }, { "dsn_lasthop", opt_bool|opt_public, - (void *)offsetof(router_instance, dsn_lasthop) }, + LOFF(dsn_lasthop) }, { "errors_to", opt_stringptr|opt_public, - (void *)(offsetof(router_instance, errors_to)) }, + LOFF(errors_to) }, { "expn", opt_bool|opt_public, - (void *)offsetof(router_instance, expn) }, + LOFF(expn) }, { "fail_verify", opt_bool_verify|opt_hidden|opt_public, - (void *)offsetof(router_instance, fail_verify_sender) }, + LOFF(fail_verify_sender) }, { "fail_verify_recipient", opt_bool|opt_public, - (void *)offsetof(router_instance, fail_verify_recipient) }, + LOFF(fail_verify_recipient) }, { "fail_verify_sender", opt_bool|opt_public, - (void *)offsetof(router_instance, fail_verify_sender) }, + LOFF(fail_verify_sender) }, { "fallback_hosts", opt_stringptr|opt_public, - (void *)offsetof(router_instance, fallback_hosts) }, + LOFF(fallback_hosts) }, { "group", opt_expand_gid | opt_public, - (void *)(offsetof(router_instance, gid)) }, + LOFF(gid) }, { "headers_add", opt_stringptr|opt_public|opt_rep_str, - (void *)offsetof(router_instance, extra_headers) }, + LOFF(extra_headers) }, { "headers_remove", opt_stringptr|opt_public|opt_rep_str, - (void *)offsetof(router_instance, remove_headers) }, + LOFF(remove_headers) }, { "ignore_target_hosts",opt_stringptr|opt_public, - (void *)offsetof(router_instance, ignore_target_hosts) }, + LOFF(ignore_target_hosts) }, { "initgroups", opt_bool | opt_public, - (void *)(offsetof(router_instance, initgroups)) }, + LOFF(initgroups) }, { "local_part_prefix", opt_stringptr|opt_public, - (void *)offsetof(router_instance, prefix) }, + LOFF(prefix) }, { "local_part_prefix_optional",opt_bool|opt_public, - (void *)offsetof(router_instance, prefix_optional) }, + LOFF(prefix_optional) }, { "local_part_suffix", opt_stringptr|opt_public, - (void *)offsetof(router_instance, suffix) }, + LOFF(suffix) }, { "local_part_suffix_optional",opt_bool|opt_public, - (void *)offsetof(router_instance, suffix_optional) }, + LOFF(suffix_optional) }, { "local_parts", opt_stringptr|opt_public, - (void *)offsetof(router_instance, local_parts) }, + LOFF(local_parts) }, { "log_as_local", opt_bool|opt_public, - (void *)offsetof(router_instance, log_as_local) }, + LOFF(log_as_local) }, { "more", opt_expand_bool|opt_public, - (void *)offsetof(router_instance, more) }, + LOFF(more) }, { "pass_on_timeout", opt_bool|opt_public, - (void *)offsetof(router_instance, pass_on_timeout) }, + LOFF(pass_on_timeout) }, { "pass_router", opt_stringptr|opt_public, - (void *)offsetof(router_instance, pass_router_name) }, + LOFF(pass_router_name) }, { "redirect_router", opt_stringptr|opt_public, - (void *)offsetof(router_instance, redirect_router_name) }, + LOFF(redirect_router_name) }, { "require_files", opt_stringptr|opt_public, - (void *)offsetof(router_instance, require_files) }, + LOFF(require_files) }, { "retry_use_local_part", opt_bool|opt_public, - (void *)offsetof(router_instance, retry_use_local_part) }, + LOFF(retry_use_local_part) }, { "router_home_directory", opt_stringptr|opt_public, - (void *)offsetof(router_instance, router_home_directory) }, + LOFF(router_home_directory) }, { "self", opt_stringptr|opt_public, - (void *)(offsetof(router_instance, self)) }, + LOFF(self) }, { "senders", opt_stringptr|opt_public, - (void *)offsetof(router_instance, senders) }, + LOFF(senders) }, { "set", opt_stringptr|opt_public|opt_rep_str, - (void *)offsetof(router_instance, set) }, + LOFF(set) }, #ifdef SUPPORT_TRANSLATE_IP_ADDRESS { "translate_ip_address", opt_stringptr|opt_public, - (void *)offsetof(router_instance, translate_ip_address) }, + LOFF(translate_ip_address) }, #endif { "transport", opt_stringptr|opt_public, - (void *)offsetof(router_instance, transport_name) }, + LOFF(transport_name) }, { "transport_current_directory", opt_stringptr|opt_public, - (void *)offsetof(router_instance, current_directory) }, + LOFF(current_directory) }, { "transport_home_directory", opt_stringptr|opt_public, - (void *)offsetof(router_instance, home_directory) }, + LOFF(home_directory) }, { "unseen", opt_expand_bool|opt_public, - (void *)offsetof(router_instance, unseen) }, + LOFF(unseen) }, { "user", opt_expand_uid | opt_public, - (void *)(offsetof(router_instance, uid)) }, + LOFF(uid) }, { "verify", opt_bool_verify|opt_hidden|opt_public, - (void *)offsetof(router_instance, verify_sender) }, + LOFF(verify_sender) }, { "verify_only", opt_bool|opt_public, - (void *)offsetof(router_instance, verify_only) }, + LOFF(verify_only) }, { "verify_recipient", opt_bool|opt_public, - (void *)offsetof(router_instance, verify_recipient) }, + LOFF(verify_recipient) }, { "verify_sender", opt_bool|opt_public, - (void *)offsetof(router_instance, verify_sender) } + LOFF(verify_sender) } }; int optionlist_routers_size = nelem(optionlist_routers); @@ -334,19 +335,20 @@ wildcard. Arguments: local_part the local part to check prefixes the list of prefixes + vp if set, pointer to place for size of wildcard portion Returns: length of matching prefix or zero */ int -route_check_prefix(const uschar *local_part, const uschar *prefixes) +route_check_prefix(const uschar * local_part, const uschar * prefixes, + unsigned * vp) { int sep = 0; uschar *prefix; const uschar *listptr = prefixes; -uschar prebuf[64]; -while ((prefix = string_nextinlist(&listptr, &sep, prebuf, sizeof(prebuf)))) +while ((prefix = string_nextinlist(&listptr, &sep, NULL, 0))) { int plen = Ustrlen(prefix); if (prefix[0] == '*') @@ -354,10 +356,19 @@ while ((prefix = string_nextinlist(&listptr, &sep, prebuf, sizeof(prebuf)))) prefix++; for (const uschar * p = local_part + Ustrlen(local_part) - (--plen); p >= local_part; p--) - if (strncmpic(prefix, p, plen) == 0) return plen + p - local_part; + if (strncmpic(prefix, p, plen) == 0) + { + unsigned vlen = p - local_part; + if (vp) *vp = vlen; + return plen + vlen; + } } else - if (strncmpic(prefix, local_part, plen) == 0) return plen; + if (strncmpic(prefix, local_part, plen) == 0) + { + if (vp) *vp = 0; + return plen; + } } return 0; @@ -376,31 +387,40 @@ is a wildcard. Arguments: local_part the local part to check suffixes the list of suffixes + vp if set, pointer to place for size of wildcard portion Returns: length of matching suffix or zero */ int -route_check_suffix(const uschar *local_part, const uschar *suffixes) +route_check_suffix(const uschar * local_part, const uschar * suffixes, + unsigned * vp) { int sep = 0; int alen = Ustrlen(local_part); uschar *suffix; const uschar *listptr = suffixes; -uschar sufbuf[64]; -while ((suffix = string_nextinlist(&listptr, &sep, sufbuf, sizeof(sufbuf)))) +while ((suffix = string_nextinlist(&listptr, &sep, NULL, 0))) { int slen = Ustrlen(suffix); if (suffix[slen-1] == '*') { - const uschar *pend = local_part + alen - (--slen) + 1; + const uschar * pend = local_part + alen - (--slen) + 1; for (const uschar * p = local_part; p < pend; p++) - if (strncmpic(suffix, p, slen) == 0) return alen - (p - local_part); + if (strncmpic(suffix, p, slen) == 0) + { + int tlen = alen - (p - local_part); + if (vp) *vp = tlen - slen; + return tlen; + } } else if (alen > slen && strncmpic(suffix, local_part + alen - slen, slen) == 0) + { + if (vp) *vp = 0; return slen; + } } return 0; @@ -739,9 +759,9 @@ while ((check = string_nextinlist(&listptr, &sep, buffer, sizeof(buffer)))) exim_setugid(uid, gid, TRUE, string_sprintf("require_files check, file=%s", ss)); if (route_check_access(ss, uid, gid, 4)) - exim_underbar_exit(0); + exim_underbar_exit(0, US"route-check-access"); DEBUG(D_route) debug_printf("route_check_access() failed\n"); - exim_underbar_exit(1); + exim_underbar_exit(1, US"route-check-access"); } /* In the parent, wait for the child to finish */ @@ -1619,9 +1639,9 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) /* Default no affixes and select whether to use a caseful or caseless local part in this router. */ - addr->prefix = addr->suffix = NULL; - addr->local_part = r->caseful_local_part? - addr->cc_local_part : addr->lc_local_part; + addr->prefix = addr->prefix_v = addr->suffix = addr->suffix_v = NULL; + addr->local_part = r->caseful_local_part + ? addr->cc_local_part : addr->lc_local_part; DEBUG(D_route) debug_printf("local_part=%s domain=%s\n", addr->local_part, addr->domain); @@ -1632,10 +1652,12 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) if (r->prefix) { - int plen = route_check_prefix(addr->local_part, r->prefix); + unsigned vlen; + 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); addr->local_part += plen; DEBUG(D_route) debug_printf("stripped prefix %s\n", addr->prefix); } @@ -1651,11 +1673,13 @@ for (r = addr->start_router ? addr->start_router : routers; r; r = nextr) if (r->suffix) { - int slen = route_check_suffix(addr->local_part, r->suffix); + unsigned vlen; + int slen = route_check_suffix(addr->local_part, r->suffix, &vlen); if (slen > 0) { int lplen = Ustrlen(addr->local_part) - slen; addr->suffix = addr->local_part + lplen; + 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); }