mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-31 14:17:41 +00:00
postfix-1.1.11-20021115
This commit is contained in:
committed by
Viktor Dukhovni
parent
7f49c002a2
commit
6f5af3ebe3
@@ -7219,6 +7219,13 @@ Apologies for any names omitted.
|
||||
when the SMTP server is unable to send a reply to the remote
|
||||
client. File: smtpd/smtpd_chat.c.
|
||||
|
||||
20021115
|
||||
|
||||
Bugfix: initialization error with "*" transport table
|
||||
lookup, reported by LaMont Jones. The transport map lookup
|
||||
code had grown into a monster and needed to be replaced.
|
||||
trivial-rewrite/transport.c.
|
||||
|
||||
Open problems:
|
||||
|
||||
Low: revise other local delivery agent duplicate filters.
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* Patches change the patchlevel and the release date. Snapshots change the
|
||||
* release date only, unless they include the same bugfix as a patch release.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20021114"
|
||||
#define MAIL_RELEASE_DATE "20021115"
|
||||
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE
|
||||
|
@@ -87,89 +87,135 @@ void transport_init(void)
|
||||
|
||||
}
|
||||
|
||||
/* find_transport_entry - look up and parse transport table entry */
|
||||
|
||||
static int find_transport_entry(const char *key, int flags,
|
||||
VSTRING *channel, VSTRING *nexthop)
|
||||
{
|
||||
char *saved_value;
|
||||
const char *host;
|
||||
const char *value;
|
||||
|
||||
#define FOUND 1
|
||||
#define NOTFOUND 0
|
||||
|
||||
if (transport_path == 0)
|
||||
msg_panic("find_transport_entry: missing initialization");
|
||||
|
||||
/*
|
||||
* Look up an entry with extreme prejedice.
|
||||
*/
|
||||
if ((value = maps_find(transport_path, key, flags)) == 0) {
|
||||
if (dict_errno != 0)
|
||||
msg_fatal("transport table lookup problem.");
|
||||
return (NOTFOUND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Can't do transport:user@domain until we have a way to pass the
|
||||
* recipient back to the application, and until we have verified that
|
||||
* this does not open security holes via, for example, regexp maps.
|
||||
* Nothing is supposed to trust a transport name, envelope recipient
|
||||
* address or next-hop hostname, but to be on the safe side we probably
|
||||
* should add some syntax sanity checks.
|
||||
*/
|
||||
else {
|
||||
saved_value = mystrdup(value);
|
||||
if ((host = split_at(saved_value, ':')) != 0 && *host != 0) {
|
||||
#if 0
|
||||
if ((ratsign = strrchr(host, '@'))) {
|
||||
vstring_strcpy(recipient, host);
|
||||
vstring_strcpy(nexthop, ratsign + 1);
|
||||
} else
|
||||
#endif
|
||||
vstring_strcpy(nexthop, host);
|
||||
}
|
||||
if (*saved_value != 0)
|
||||
vstring_strcpy(channel, saved_value);
|
||||
myfree(saved_value);
|
||||
return (FOUND);
|
||||
}
|
||||
}
|
||||
|
||||
/* transport_wildcard_init - post-jail initialization */
|
||||
|
||||
void transport_wildcard_init(void)
|
||||
{
|
||||
wildcard_channel = vstring_alloc(10);
|
||||
wildcard_nexthop = vstring_alloc(10);
|
||||
VSTRING *channel = vstring_alloc(10);
|
||||
VSTRING *nexthop = vstring_alloc(10);
|
||||
|
||||
if (transport_lookup("*", wildcard_channel, wildcard_nexthop)) {
|
||||
#define WILDCARD "*"
|
||||
#define FULL 0
|
||||
#define PARTIAL DICT_FLAG_FIXED
|
||||
|
||||
if (find_transport_entry(WILDCARD, FULL, channel, nexthop)) {
|
||||
wildcard_channel = channel;
|
||||
wildcard_nexthop = nexthop;
|
||||
if (msg_verbose)
|
||||
msg_info("wildcard_{chan:hop}={%s:%s}",
|
||||
vstring_str(wildcard_channel), vstring_str(wildcard_nexthop));
|
||||
} else {
|
||||
vstring_free(wildcard_channel);
|
||||
wildcard_channel = 0;
|
||||
vstring_free(wildcard_nexthop);
|
||||
wildcard_nexthop = 0;
|
||||
vstring_free(channel);
|
||||
vstring_free(nexthop);
|
||||
}
|
||||
}
|
||||
|
||||
/* check_maps_find - map lookup with extreme prejudice */
|
||||
|
||||
static const char *check_maps_find(MAPS *maps, const char *key, int flags)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
if ((value = maps_find(maps, key, flags)) == 0 && dict_errno != 0)
|
||||
msg_fatal("transport table lookup problem.");
|
||||
return (value);
|
||||
}
|
||||
|
||||
/* transport_lookup - map a transport domain */
|
||||
|
||||
int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
|
||||
{
|
||||
char *full_addr = lowercase(mystrdup(*addr ? addr : var_xport_null_key));
|
||||
char *stripped_addr = 0;
|
||||
char *stripped_addr;
|
||||
char *ratsign = 0;
|
||||
const char *name;
|
||||
const char *next;
|
||||
const char *value;
|
||||
const char *host;
|
||||
char *saved_value;
|
||||
char *transport;
|
||||
int found = 0;
|
||||
int found;
|
||||
|
||||
#define FULL 0
|
||||
#define PARTIAL DICT_FLAG_FIXED
|
||||
#define STRNE strcmp
|
||||
#define STREQ(x,y) (strcmp((x), (y)) == 0)
|
||||
#define DISCARD_EXTENSION ((char **) 0)
|
||||
|
||||
if (transport_path == 0)
|
||||
msg_panic("transport_lookup: missing initialization");
|
||||
/*
|
||||
* The optimizer will replace multiple instances of this macro expansion
|
||||
* by gotos to a single instance that does the same thing.
|
||||
*/
|
||||
#define RETURN_FREE(x) { \
|
||||
myfree(full_addr); \
|
||||
return (x); \
|
||||
}
|
||||
|
||||
if (STRNE(full_addr, var_xport_null_key) && STRNE(full_addr, "*"))
|
||||
if ((ratsign = strrchr(full_addr, '@')) == 0)
|
||||
msg_panic("transport_lookup: bad address: \"%s\"", full_addr);
|
||||
/*
|
||||
* If this is a special address such as <> do only one lookup of the full
|
||||
* string. Specify the FULL flag to include regexp maps in the query.
|
||||
*/
|
||||
if (STREQ(full_addr, var_xport_null_key)) {
|
||||
if (find_transport_entry(full_addr, FULL, channel, nexthop))
|
||||
RETURN_FREE(FOUND);
|
||||
RETURN_FREE(NOTFOUND);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the full address with the FULL flag to include regexp maps in
|
||||
* the query.
|
||||
*/
|
||||
if ((value = check_maps_find(transport_path, full_addr, FULL)) != 0) {
|
||||
found = 1;
|
||||
}
|
||||
if ((ratsign = strrchr(full_addr, '@')) == 0)
|
||||
msg_panic("transport_lookup: bad address: \"%s\"", full_addr);
|
||||
|
||||
/*
|
||||
* If this is a special address such as <> or *, not user@domain, then we
|
||||
* are done now.
|
||||
*/
|
||||
else if (ratsign == 0) {
|
||||
found = 0;
|
||||
}
|
||||
if (find_transport_entry(full_addr, FULL, channel, nexthop))
|
||||
RETURN_FREE(FOUND);
|
||||
|
||||
/*
|
||||
* If the full address did not match, and there is an address extension,
|
||||
* look up the stripped address with the PARTIAL flag to avoid matching
|
||||
* partial lookup keys with regular expressions.
|
||||
*/
|
||||
else if ((stripped_addr = strip_addr(full_addr, DISCARD_EXTENSION,
|
||||
*var_rcpt_delim)) != 0
|
||||
&& (value = check_maps_find(transport_path, stripped_addr,
|
||||
PARTIAL)) != 0) {
|
||||
found = 1;
|
||||
if ((stripped_addr = strip_addr(full_addr, DISCARD_EXTENSION,
|
||||
*var_rcpt_delim)) != 0) {
|
||||
if (find_transport_entry(stripped_addr, PARTIAL, channel, nexthop)) {
|
||||
myfree(stripped_addr);
|
||||
RETURN_FREE(FOUND);
|
||||
} else {
|
||||
myfree(stripped_addr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -188,58 +234,28 @@ int transport_lookup(const char *addr, VSTRING *channel, VSTRING *nexthop)
|
||||
* Specify that the lookup key is partial, to avoid matching partial keys
|
||||
* with regular expressions.
|
||||
*/
|
||||
else if (found == 0) {
|
||||
for (name = ratsign + 1; /* void */ ; name = next) {
|
||||
if ((value = maps_find(transport_path, name, PARTIAL)) != 0) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
if ((next = strchr(name + 1, '.')) == 0)
|
||||
break;
|
||||
if (transport_match_parent_style == MATCH_FLAG_PARENT)
|
||||
next++;
|
||||
}
|
||||
for (found = 0, name = ratsign + 1; /* void */ ; name = next) {
|
||||
if (find_transport_entry(name, PARTIAL, channel, nexthop))
|
||||
RETURN_FREE(FOUND);
|
||||
if ((next = strchr(name + 1, '.')) == 0)
|
||||
break;
|
||||
if (transport_match_parent_style == MATCH_FLAG_PARENT)
|
||||
next++;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX user+ext@ and user@ lookups for domains that resolve locally?
|
||||
*/
|
||||
|
||||
/*
|
||||
* We found an answer in the transport table. Use the results to
|
||||
* override transport and/or next-hop information.
|
||||
*/
|
||||
if (found == 1) {
|
||||
saved_value = mystrdup(value);
|
||||
if ((host = split_at(saved_value, ':')) != 0 && *host != 0) {
|
||||
#if 0
|
||||
if (strchr(host, '@'))
|
||||
vstring_strcpy(recipient, host);
|
||||
else
|
||||
#endif
|
||||
vstring_strcpy(nexthop, host);
|
||||
}
|
||||
if (*(transport = saved_value) != 0)
|
||||
vstring_strcpy(channel, transport);
|
||||
myfree(saved_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
myfree(full_addr);
|
||||
if (stripped_addr)
|
||||
myfree(stripped_addr);
|
||||
|
||||
/*
|
||||
* Fall back to the wild-card entry.
|
||||
*/
|
||||
if (found == 0 && wildcard_channel) {
|
||||
if (wildcard_channel) {
|
||||
if (*vstring_str(wildcard_channel))
|
||||
vstring_strcpy(channel, vstring_str(wildcard_channel));
|
||||
if (*vstring_str(wildcard_nexthop))
|
||||
vstring_strcpy(nexthop, vstring_str(wildcard_nexthop));
|
||||
found = 1;
|
||||
RETURN_FREE(FOUND);
|
||||
}
|
||||
return (found);
|
||||
|
||||
/*
|
||||
* We really did not find it.
|
||||
*/
|
||||
RETURN_FREE(NOTFOUND);
|
||||
}
|
||||
|
Reference in New Issue
Block a user