diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/src/deliver.c | 4 | ||||
-rw-r--r-- | src/src/expand.c | 2 | ||||
-rw-r--r-- | src/src/functions.h | 4 | ||||
-rw-r--r-- | src/src/globals.c | 4 | ||||
-rw-r--r-- | src/src/globals.h | 2 | ||||
-rw-r--r-- | src/src/receive.c | 5 | ||||
-rw-r--r-- | src/src/route.c | 53 | ||||
-rw-r--r-- | src/src/structs.h | 2 | ||||
-rw-r--r-- | src/src/transport.c | 6 |
9 files changed, 59 insertions, 23 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c index 467813800..5c5167b3a 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -220,7 +220,9 @@ if (!addr->next) deliver_localpart = addr->local_part; deliver_localpart_prefix = addr->prefix; + deliver_localpart_prefix_v = addr->prefix_v; deliver_localpart_suffix = addr->suffix; + deliver_localpart_suffix_v = addr->suffix_v; for (addr_orig = addr; addr_orig->parent; addr_orig = addr_orig->parent) ; deliver_domain_orig = addr_orig->domain; @@ -260,7 +262,9 @@ if (!addr->next) else if (deliver_localpart[0] == '|') address_pipe = addr->local_part; deliver_localpart = addr->parent->local_part; deliver_localpart_prefix = addr->parent->prefix; + deliver_localpart_prefix_v = addr->parent->prefix_v; deliver_localpart_suffix = addr->parent->suffix; + deliver_localpart_suffix_v = addr->parent->suffix_v; } } diff --git a/src/src/expand.c b/src/src/expand.c index 661959306..660fe98cf 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -589,7 +589,9 @@ static var_entry var_table[] = { { "local_part", vtype_stringptr, &deliver_localpart }, { "local_part_data", vtype_stringptr, &deliver_localpart_data }, { "local_part_prefix", vtype_stringptr, &deliver_localpart_prefix }, + { "local_part_prefix_v", vtype_stringptr, &deliver_localpart_prefix_v }, { "local_part_suffix", vtype_stringptr, &deliver_localpart_suffix }, + { "local_part_suffix_v", vtype_stringptr, &deliver_localpart_suffix_v }, { "local_part_verified", vtype_stringptr, &deliver_localpart_verified }, #ifdef HAVE_LOCAL_SCAN { "local_scan_data", vtype_stringptr, &local_scan_data }, diff --git a/src/src/functions.h b/src/src/functions.h index be929a710..df4b33606 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -421,8 +421,8 @@ extern uschar *rfc2047_decode2(uschar *, BOOL, uschar *, int, int *, int *, uschar **); extern int route_address(address_item *, address_item **, address_item **, address_item **, address_item **, int); -extern int route_check_prefix(const uschar *, const uschar *); -extern int route_check_suffix(const uschar *, const uschar *); +extern int route_check_prefix(const uschar *, const uschar *, unsigned *); +extern int route_check_suffix(const uschar *, const uschar *, unsigned *); extern BOOL route_findgroup(uschar *, gid_t *); extern BOOL route_finduser(const uschar *, struct passwd **, uid_t *); extern BOOL route_find_expanded_group(uschar *, uschar *, uschar *, gid_t *, diff --git a/src/src/globals.c b/src/src/globals.c index a5711c73b..4ce15acaa 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -541,7 +541,9 @@ address_item address_defaults = { .lc_local_part = NULL, .local_part = NULL, .prefix = NULL, + .prefix_v = NULL, .suffix = NULL, + .suffix_v = NULL, .domain = NULL, .address_retry_key = NULL, .domain_retry_key = NULL, @@ -822,7 +824,9 @@ uschar *deliver_localpart_data = NULL; uschar *deliver_localpart_orig = NULL; uschar *deliver_localpart_parent = NULL; uschar *deliver_localpart_prefix = NULL; +uschar *deliver_localpart_prefix_v = NULL; uschar *deliver_localpart_suffix = NULL; +uschar *deliver_localpart_suffix_v = NULL; uschar *deliver_localpart_verified = NULL; uschar *deliver_out_buffer = NULL; int deliver_queue_load_max = -1; diff --git a/src/src/globals.h b/src/src/globals.h index b570078c3..1fea9c9b0 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -490,7 +490,9 @@ extern uschar *deliver_localpart_data; /* From local part lookup */ extern uschar *deliver_localpart_orig; /* The original local part for delivery */ extern uschar *deliver_localpart_parent; /* The parent local part for delivery */ extern uschar *deliver_localpart_prefix; /* The stripped prefix, if any */ +extern uschar *deliver_localpart_prefix_v; /* The stripped-prefix variable portion, if any */ extern uschar *deliver_localpart_suffix; /* The stripped suffix, if any */ +extern uschar *deliver_localpart_suffix_v; /* The stripped-suffix variable portion, if any */ extern uschar *deliver_localpart_verified; /* de-tainted by check_local_part */ extern uschar *deliver_out_buffer; /* Buffer for copying file */ extern int deliver_queue_load_max; /* Different value for queue running */ diff --git a/src/src/receive.c b/src/src/receive.c index f30ffd92d..96a48fe65 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -2907,9 +2907,8 @@ if ( from_header uschar *at = domain ? from_address + domain - 1 : NULL; if (at) *at = 0; - from_address += route_check_prefix(from_address, local_from_prefix); - slen = route_check_suffix(from_address, local_from_suffix); - if (slen > 0) + from_address += route_check_prefix(from_address, local_from_prefix, NULL); + if ((slen = route_check_suffix(from_address, local_from_suffix, NULL)) > 0) { memmove(from_address+slen, from_address, Ustrlen(from_address)-slen); from_address += slen; diff --git a/src/src/route.c b/src/src/route.c index a1426d58f..8b43613ce 100644 --- a/src/src/route.c +++ b/src/src/route.c @@ -335,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] == '*') @@ -355,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; @@ -377,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; @@ -1620,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); @@ -1633,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); } @@ -1652,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); } diff --git a/src/src/structs.h b/src/src/structs.h index aa394ac73..7d700fb72 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -553,7 +553,9 @@ typedef struct address_item { uschar *lc_local_part; /* lowercased local part */ uschar *local_part; /* points to cc or lc version */ uschar *prefix; /* stripped prefix of local part */ + uschar *prefix_v; /* variable part of above */ uschar *suffix; /* stripped suffix of local part */ + uschar *suffix_v; /* variable part of above */ const uschar *domain; /* working domain (lower cased) */ uschar *address_retry_key; /* retry key including full address */ diff --git a/src/src/transport.c b/src/src/transport.c index d9eba1621..90789fd60 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -591,14 +591,14 @@ if (include_affixes) return addr->address; } -if (addr->suffix == NULL) +if (!addr->suffix) { - if (addr->prefix == NULL) return addr->address; + if (!addr->prefix) return addr->address; return addr->address + Ustrlen(addr->prefix); } at = Ustrrchr(addr->address, '@'); -plen = (addr->prefix == NULL)? 0 : Ustrlen(addr->prefix); +plen = addr->prefix ? Ustrlen(addr->prefix) : 0; slen = Ustrlen(addr->suffix); return string_sprintf("%.*s@%s", (int)(at - addr->address - plen - slen), |