Documentation: typo fixes by IKEDA Nozomu.
+20040616
+
+ Bugfix: one missed variadic argument list fix. Victor
+ Duchovni, Morgan Stanley. File: global/verify.c.
+
+ Bugfix: the resolver client cache should be context dependent
+ because address verification probes may use a different
+ route than normal mail deliveries. File: global/resolve_clnt.c.
+
+ Safety: added similar context dependence to the address
+ rewriting client in order to avoid trouble when Postfix is
+ changed. File: global/rewrite_clnt.c.
+
+ Bugfix: space in HELO commands could end up in XFORWARD
+ commands. File: smtpd/smtpd.c.
+
Open problems:
Low: make sure CCARGS -I options come at the end.
the parent domain of the machine name.
For the sake of consistency between sender and recipient addresses, myorigin
-also specifies the default domain name that is appended to an unqualified
-recipient address.
+also specifies the domain name that is appended to an unqualified recipient
+address.
Examples (specify only one of the following):
domain of the machine name. </p>
<p> For the sake of consistency between sender and recipient addresses,
-<a href="postconf.5.html#myorigin">myorigin</a> also specifies the <a href="ADDRESS_CLASS_README.html#default_domain_class">default domain</a> name that is appended
+<a href="postconf.5.html#myorigin">myorigin</a> also specifies the domain name that is appended
to an unqualified recipient address. </p>
<p> Examples (specify only one of the following): </p>
</p>
<p>
-By default, address masquerading is limited to envelope recipient
+By default, address masquerading is limited to envelope sender
addresses, and to header sender and header recipient addresses.
This allows you to use address masquerading on a mail gateway while
still being able to forward mail to users on individual machines.
.SH masquerade_classes (default: envelope_sender, header_sender, header_recipient)
What addresses are subject to address masquerading.
.PP
-By default, address masquerading is limited to envelope recipient
+By default, address masquerading is limited to envelope sender
addresses, and to header sender and header recipient addresses.
This allows you to use address masquerading on a mail gateway while
still being able to forward mail to users on individual machines.
domain of the machine name. </p>
<p> For the sake of consistency between sender and recipient addresses,
-myorigin also specifies the default domain name that is appended
+myorigin also specifies the domain name that is appended
to an unqualified recipient address. </p>
<p> Examples (specify only one of the following): </p>
</p>
<p>
-By default, address masquerading is limited to envelope recipient
+By default, address masquerading is limited to envelope sender
addresses, and to header sender and header recipient addresses.
This allows you to use address masquerading on a mail gateway while
still being able to forward mail to users on individual machines.
* Patches change the patchlevel and the release date. Snapshots change the
* release date only.
*/
-#define MAIL_RELEASE_DATE "20040615"
+#define MAIL_RELEASE_DATE "20040616"
#define MAIL_VERSION_NUMBER "2.2"
#define VAR_MAIL_VERSION "mail_version"
mask_style = name_mask("mynetworks mask style", mask_styles,
var_mynetworks_style);
+ /*
+ * XXX Workaround: name_mask() needs a flags argument so that we can
+ * require exactly one value, or we need to provide an API that is
+ * dedicated for single-valued flags.
+ */
+ for (i = 0, junk = mask_style; junk != 0; junk >>= 1)
+ i += (junk & 1);
+ if (i != 1)
+ msg_fatal("bad %s value: %s; specify exactly one value",
+ VAR_MYNETWORKS_STYLE, var_mynetworks_style);
+
result = vstring_alloc(20);
my_addr_list = own_inet_addr_list();
my_mask_list = own_inet_mask_list();
*/
extern CLNT_STREAM *rewrite_clnt_stream;
+static VSTRING *last_class;
static VSTRING *last_addr;
static RESOLVE_REPLY last_reply;
* One-entry cache.
*/
if (last_addr == 0) {
+ last_class = vstring_alloc(10);
last_addr = vstring_alloc(100);
resolve_clnt_init(&last_reply);
}
*/
#define IFSET(flag, text) ((reply->flags & (flag)) ? (text) : "")
- if (*addr && strcmp(addr, STR(last_addr)) == 0) {
+ if (*addr && strcmp(addr, STR(last_addr)) == 0
+ && strcmp(class, STR(last_class)) == 0) {
vstring_strcpy(reply->transport, STR(last_reply.transport));
vstring_strcpy(reply->nexthop, STR(last_reply.nexthop));
vstring_strcpy(reply->recipient, STR(last_reply.recipient));
/*
* Update the cache.
*/
+ vstring_strcpy(last_class, class);
vstring_strcpy(last_addr, addr);
vstring_strcpy(last_reply.transport, STR(reply->transport));
vstring_strcpy(last_reply.nexthop, STR(reply->nexthop));
#include <stdlib.h>
#include <msg_vstream.h>
#include <vstring_vstream.h>
+#include <split_at.h>
#include <mail_conf.h>
static NORETURN usage(char *myname)
msg_fatal("usage: %s [-v] [address...]", myname);
}
-static void resolve(char *addr, RESOLVE_REPLY *reply)
+static void resolve(char *class, char *addr, RESOLVE_REPLY *reply)
{
struct RESOLVE_FLAG_TABLE {
int flag;
};
struct RESOLVE_FLAG_TABLE *fp;
- resolve_clnt_query(addr, reply);
+ resolve_clnt(class, addr, reply);
if (reply->flags & RESOLVE_FLAG_FAIL) {
vstream_printf("request failed\n");
} else {
+ vstream_printf("%-10s %s\n", "class", class);
vstream_printf("%-10s %s\n", "address", addr);
vstream_printf("%-10s %s\n", "transport", STR(reply->transport));
vstream_printf("%-10s %s\n", "nexthop", *STR(reply->nexthop) ?
int main(int argc, char **argv)
{
RESOLVE_REPLY reply;
+ char *addr;
int ch;
msg_vstream_init(argv[0], VSTREAM_ERR);
resolve_clnt_init(&reply);
if (argc > optind) {
- while (argv[optind]) {
- resolve(argv[optind], &reply);
- optind++;
+ while (argv[optind] && argv[optind + 1]) {
+ resolve(argv[optind], argv[optind + 1], &reply);
+ optind += 2;
}
} else {
VSTRING *buffer = vstring_alloc(1);
while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
- resolve(STR(buffer), &reply);
+ if ((addr = split_at(STR(buffer), ' ')) == 0 || *STR(buffer) == 0)
+ msg_fatal("need as input: class address");
+ resolve(STR(buffer), addr, &reply);
}
vstring_free(buffer);
}
-
-@
-@@
-@a.
-@..
-@.@.
-!
-a!
-!b
-a!b
-!@
-a!@
-!b@
-a!b@
-%
-a%
-%b
-a%b
-%@
-a%@
-%b@
-@@
-a@@
-@b@
-a@b@
-a%b@
-a%b@MYHOSTNAME
-a!b@MYHOSTNAME
-a@b@MYHOSTNAME
-a[b]@MYHOSTNAME@MYHOSTNAME
-a[b]%MYHOSTNAME@MYHOSTNAME
-a[b]%MYHOSTNAME%MYHOSTNAME
-MYHOSTNAME!a[b]@MYHOSTNAME
-MYHOSTNAME!a[b]%MYHOSTNAME
-MYHOSTNAME!MYHOSTNAME!a[b]
-user@dom.ain1@dom.ain2
-user%dom.ain1@dom.ain2
-dom.ain1!user@dom.ain2
-user@[1.2.3.4]@dom.ain2
-user%[1.2.3.4]@dom.ain2
-[1.2.3.4]!user@dom.ain2
-user@localhost.MYDOMAIN
-user@[321.1.2.3]
-user@1.2.3
-user@host:port
+resolve
+resolve @
+resolve @@
+resolve @a.
+resolve @..
+resolve @.@.
+resolve !
+resolve a!
+resolve !b
+resolve a!b
+resolve !@
+resolve a!@
+resolve !b@
+resolve a!b@
+resolve %
+resolve a%
+resolve %b
+resolve a%b
+resolve %@
+resolve a%@
+resolve %b@
+resolve @@
+resolve a@@
+resolve @b@
+resolve a@b@
+resolve a%b@
+resolve a%b@MYHOSTNAME
+resolve a!b@MYHOSTNAME
+resolve a@b@MYHOSTNAME
+resolve a[b]@MYHOSTNAME@MYHOSTNAME
+resolve a[b]%MYHOSTNAME@MYHOSTNAME
+resolve a[b]%MYHOSTNAME%MYHOSTNAME
+resolve MYHOSTNAME!a[b]@MYHOSTNAME
+resolve MYHOSTNAME!a[b]%MYHOSTNAME
+resolve MYHOSTNAME!MYHOSTNAME!a[b]
+resolve user@dom.ain1@dom.ain2
+resolve user%dom.ain1@dom.ain2
+resolve dom.ain1!user@dom.ain2
+resolve user@[1.2.3.4]@dom.ain2
+resolve user%[1.2.3.4]@dom.ain2
+resolve [1.2.3.4]!user@dom.ain2
+resolve user@localhost.MYDOMAIN
+resolve user@[321.1.2.3]
+resolve user@1.2.3
+resolve user@host:port
+resolve user@host
+resolve user@host
+verify user@host
+verify user@host
+class resolve
address
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address @
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address @@
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address @a.
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient @a
flags CLASS_DEFAULT
+class resolve
address @..
-transport smtp
-nexthop RELAYHOST
+transport CHANNEL NOT UPDATED
+nexthop NEXTHOP NOT UPDATED
recipient @..
flags FLAG_ERROR CLASS_DEFAULT
+class resolve
address @.@.
-transport smtp
-nexthop RELAYHOST
+transport CHANNEL NOT UPDATED
+nexthop NEXTHOP NOT UPDATED
recipient @.@.
-flags FLAG_ROUTED FLAG_ERROR CLASS_DEFAULT
+flags FLAG_ERROR CLASS_DEFAULT
+class resolve
address !
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address a!
transport smtp
-nexthop RELAYHOST
-recipient @a.MYDOMAIN
+nexthop porcupine.org
+recipient @a.porcupine.org
flags CLASS_DEFAULT
+class resolve
address !b
transport local
-nexthop MYHOSTNAME
-recipient b@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient b@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address a!b
transport smtp
-nexthop RELAYHOST
-recipient b@a.MYDOMAIN
+nexthop porcupine.org
+recipient b@a.porcupine.org
flags CLASS_DEFAULT
+class resolve
address !@
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address a!@
transport smtp
-nexthop RELAYHOST
-recipient @a.MYDOMAIN
+nexthop porcupine.org
+recipient @a.porcupine.org
flags CLASS_DEFAULT
+class resolve
address !b@
transport local
-nexthop MYHOSTNAME
-recipient b@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient b@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address a!b@
transport smtp
-nexthop RELAYHOST
-recipient b@a.MYDOMAIN
+nexthop porcupine.org
+recipient b@a.porcupine.org
flags CLASS_DEFAULT
+class resolve
address %
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address a%
transport local
-nexthop MYHOSTNAME
-recipient a@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address %b
transport smtp
-nexthop RELAYHOST
-recipient @b.MYDOMAIN
+nexthop porcupine.org
+recipient @b.porcupine.org
flags CLASS_DEFAULT
+class resolve
address a%b
transport smtp
-nexthop RELAYHOST
-recipient a@b.MYDOMAIN
+nexthop porcupine.org
+recipient a@b.porcupine.org
flags CLASS_DEFAULT
+class resolve
address %@
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address a%@
transport local
-nexthop MYHOSTNAME
-recipient a@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address %b@
transport smtp
-nexthop RELAYHOST
-recipient @b.MYDOMAIN
+nexthop porcupine.org
+recipient @b.porcupine.org
flags CLASS_DEFAULT
+class resolve
address @@
transport local
-nexthop MYHOSTNAME
-recipient MAILER-DAEMON@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient MAILER-DAEMON@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address a@@
transport local
-nexthop MYHOSTNAME
-recipient a@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address @b@
transport smtp
-nexthop RELAYHOST
-recipient @b.MYDOMAIN
+nexthop porcupine.org
+recipient @b.porcupine.org
flags CLASS_DEFAULT
+class resolve
address a@b@
transport smtp
-nexthop RELAYHOST
-recipient a@b.MYDOMAIN
+nexthop porcupine.org
+recipient a@b.porcupine.org
flags CLASS_DEFAULT
+class resolve
address a%b@
transport smtp
-nexthop RELAYHOST
-recipient a@b.MYDOMAIN
+nexthop porcupine.org
+recipient a@b.porcupine.org
flags CLASS_DEFAULT
-address a%b@MYHOSTNAME
+class resolve
+address a%b@tail.porcupine.org
transport smtp
-nexthop RELAYHOST
-recipient a@b.MYDOMAIN
+nexthop porcupine.org
+recipient a@b.porcupine.org
flags CLASS_DEFAULT
-address a!b@MYHOSTNAME
+class resolve
+address a!b@tail.porcupine.org
transport smtp
-nexthop RELAYHOST
-recipient b@a.MYDOMAIN
+nexthop porcupine.org
+recipient b@a.porcupine.org
flags CLASS_DEFAULT
-address a@b@MYHOSTNAME
+class resolve
+address a@b@tail.porcupine.org
transport smtp
-nexthop RELAYHOST
-recipient a@b.MYDOMAIN
+nexthop porcupine.org
+recipient a@b.porcupine.org
flags CLASS_DEFAULT
-address a[b]@MYHOSTNAME@MYHOSTNAME
+class resolve
+address a[b]@tail.porcupine.org@tail.porcupine.org
transport local
-nexthop MYHOSTNAME
-recipient a[b]@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a[b]@tail.porcupine.org
flags CLASS_LOCAL
-address a[b]%MYHOSTNAME@MYHOSTNAME
+class resolve
+address a[b]%tail.porcupine.org@tail.porcupine.org
transport local
-nexthop MYHOSTNAME
-recipient a[b]@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a[b]@tail.porcupine.org
flags CLASS_LOCAL
-address a[b]%MYHOSTNAME%MYHOSTNAME
+class resolve
+address a[b]%tail.porcupine.org%tail.porcupine.org
transport local
-nexthop MYHOSTNAME
-recipient a[b]@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a[b]@tail.porcupine.org
flags CLASS_LOCAL
-address MYHOSTNAME!a[b]@MYHOSTNAME
+class resolve
+address tail.porcupine.org!a[b]@tail.porcupine.org
transport local
-nexthop MYHOSTNAME
-recipient a [b]@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a [b]@tail.porcupine.org
flags CLASS_LOCAL
-address MYHOSTNAME!a[b]%MYHOSTNAME
+class resolve
+address tail.porcupine.org!a[b]%tail.porcupine.org
transport local
-nexthop MYHOSTNAME
-recipient a [b]@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a [b]@tail.porcupine.org
flags CLASS_LOCAL
-address MYHOSTNAME!MYHOSTNAME!a[b]
+class resolve
+address tail.porcupine.org!tail.porcupine.org!a[b]
transport local
-nexthop MYHOSTNAME
-recipient a [b]@MYHOSTNAME
+nexthop tail.porcupine.org
+recipient a [b]@tail.porcupine.org
flags CLASS_LOCAL
+class resolve
address user@dom.ain1@dom.ain2
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient user@dom.ain1@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
+class resolve
address user%dom.ain1@dom.ain2
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient user%dom.ain1@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
+class resolve
address dom.ain1!user@dom.ain2
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient dom.ain1!user@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
+class resolve
address user@[1.2.3.4]@dom.ain2
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient user@[1.2.3.4]@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
+class resolve
address user%[1.2.3.4]@dom.ain2
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient user%[1.2.3.4]@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
+class resolve
address [1.2.3.4]!user@dom.ain2
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient [1.2.3.4]!user@dom.ain2
flags FLAG_ROUTED CLASS_DEFAULT
-address user@localhost.MYDOMAIN
+class resolve
+address user@localhost.porcupine.org
transport local
-nexthop MYHOSTNAME
-recipient user@localhost.MYDOMAIN
+nexthop tail.porcupine.org
+recipient user@localhost.porcupine.org
flags CLASS_LOCAL
+class resolve
address user@[321.1.2.3]
-transport smtp
-nexthop RELAYHOST
+transport CHANNEL NOT UPDATED
+nexthop NEXTHOP NOT UPDATED
recipient user@[321.1.2.3]
flags FLAG_ERROR CLASS_DEFAULT
+class resolve
address user@1.2.3
transport smtp
-nexthop RELAYHOST
+nexthop porcupine.org
recipient user@1.2.3
flags CLASS_DEFAULT
+class resolve
address user@host:port
-transport smtp
-nexthop RELAYHOST
+transport CHANNEL NOT UPDATED
+nexthop NEXTHOP NOT UPDATED
recipient user@host:port
flags FLAG_ERROR CLASS_DEFAULT
+class resolve
+address user@host
+transport smtp
+nexthop porcupine.org
+recipient user@host
+flags CLASS_DEFAULT
+
+class resolve
+address user@host
+transport smtp
+nexthop porcupine.org
+recipient user@host
+flags CLASS_DEFAULT
+
+class verify
+address user@host
+transport smtp
+nexthop porcupine.org
+recipient user@host
+flags CLASS_DEFAULT
+
+class verify
+address user@host
+transport smtp
+nexthop porcupine.org
+recipient user@host
+flags CLASS_DEFAULT
+
*/
CLNT_STREAM *rewrite_clnt_stream = 0;
+static VSTRING *last_rule;
static VSTRING *last_addr;
static VSTRING *last_result;
* One-entry cache.
*/
if (last_addr == 0) {
+ last_rule = vstring_alloc(10);
last_addr = vstring_alloc(100);
last_result = vstring_alloc(100);
}
/*
* Peek at the cache.
- *
- * XXX Must be made "rule" specific.
*/
- if (strcmp(addr, STR(last_addr)) == 0) {
+ if (strcmp(addr, STR(last_addr)) == 0
+ && strcmp(rule, STR(last_rule)) == 0) {
vstring_strcpy(result, STR(last_result));
if (msg_verbose)
msg_info("rewrite_clnt: cached: %s: %s -> %s",
/*
* Update the cache.
*/
+ vstring_strcpy(last_rule, rule);
vstring_strcpy(last_addr, addr);
vstring_strcpy(last_result, STR(result));
*/
vstring_vsprintf(text, fmt, ap);
if (var_verify_neg_cache || rcpt_stat == DEL_RCPT_STAT_OK) {
- req_stat = verify_clnt_vupdate(orig_rcpt, rcpt_stat, fmt, ap);
+ req_stat = verify_clnt_update(orig_rcpt, rcpt_stat,
+ "%s", vstring_str(text));
if (req_stat == VRFY_STAT_OK && strcasecmp(recipient, orig_rcpt) != 0)
req_stat = verify_clnt_update(recipient, rcpt_stat,
"%s", vstring_str(text));
static void rcpt_reset(SMTPD_STATE *);
static void chat_reset(SMTPD_STATE *, int);
+ /*
+ * This filter is applied after printable().
+ */
+#define NEUTER_CHARACTERS " <>()\\\";:@"
+
#ifdef USE_SASL_AUTH
/*
mail_reset(state);
rcpt_reset(state);
state->helo_name = mystrdup(printable(argv[1].strval, '?'));
- neuter(state->helo_name, "<>()\\\";:@", '?');
+ neuter(state->helo_name, NEUTER_CHARACTERS, '?');
/* Downgrading the protocol name breaks the unauthorized pipelining test. */
if (strcasecmp(state->protocol, MAIL_PROTO_ESMTP) != 0
&& strcasecmp(state->protocol, MAIL_PROTO_SMTP) != 0) {
mail_reset(state);
rcpt_reset(state);
state->helo_name = mystrdup(printable(argv[1].strval, '?'));
- neuter(state->helo_name, "<>()\\\";:@", '?');
+ neuter(state->helo_name, NEUTER_CHARACTERS, '?');
if (strcasecmp(state->protocol, MAIL_PROTO_ESMTP) != 0) {
myfree(state->protocol);
state->protocol = mystrdup(MAIL_PROTO_ESMTP);
if (s) myfree(s); \
s = (v) ? mystrdup(v) : 0; \
} while(0)
-#define NEUTER_CHARACTERS "<>()\\\";:@"
/*
* Iterate over all attribute=value elements.