From: Wietse Venema Date: Sun, 15 Oct 2006 05:00:00 +0000 (-0500) Subject: postfix-2.4-20061015 X-Git-Tag: v2.4.0-RC1~35 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=220fa5cc408c709031cee9acb5d0c1f4e5dca67e;p=thirdparty%2Fpostfix.git postfix-2.4-20061015 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index aeee142e6..1a86bb7c2 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -12789,8 +12789,26 @@ Apologies for any names omitted. multiple (x)inetd.conf entries. Victor Duchovni. Files: smtpd/smtpd.c, tls/tls_server.c. +20061015 + + Cleanup: convert the Milter {mail_addr} and {rcpt_addr} + macro values to external form. File: smtpd/smtpd_milter.c. + + Cleanup: the Milter {mail_addr} and {rcpt_addr} macros are + now available with non-SMTP mail. File: cleanup/cleanup_milter.c. + + Cleanup: convert addresses in Milter recipient add/delete + requests to internal form. File: cleanup/cleanup_milter.c. + + Cleanup: with non-SMTP mail, convert addresses in simulated + MAIL FROM and RCPT TO events to external form. File: + cleanup/cleanup_milter.c. + Wish list: + Find out if with Sendmail, a Milter "add recipient" request + results in NOTIFY=NONE as Postfix does now. + Update FILTER_README with mailing list suggestions to tag with a badness indicator and then filter down-stream. @@ -12836,11 +12854,6 @@ Wish list: Do or don't introduce unknown_reverse_client_reject_code. - In Milter events, mail_addr/rcpt_addr should be externalized - as they are in Sendmail. Likewise, addresses in add/delete - requests should be internalized before updating the queue - file. - Check that "UINT32 == unsigned int" choice is ok (i.e. LP64 UNIX). diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html index 7b7526787..0e512a166 100644 --- a/postfix/html/local.8.html +++ b/postfix/html/local.8.html @@ -46,7 +46,7 @@ LOCAL(8) LOCAL(8) local delivery agent tries each pathname in the list until a file is found. - Delivery via ~/..forward files is done with the privileges + Delivery via ~/.forward files is done with the privileges of the recipient. Thus, ~/.forward like files must be readable by the recipient, and their parent directory needs to have "execute" permission for the recipient. diff --git a/postfix/man/man8/local.8 b/postfix/man/man8/local.8 index 7a3cd2e4c..324bb2a27 100644 --- a/postfix/man/man8/local.8 +++ b/postfix/man/man8/local.8 @@ -49,7 +49,7 @@ of ~\fR/.\fBforward\fR like files through the \fBforward_path\fR configuration parameter. Upon delivery, the local delivery agent tries each pathname in the list until a file is found. -Delivery via ~/.\fB.forward\fR files is done with the privileges +Delivery via ~/.\fBforward\fR files is done with the privileges of the recipient. Thus, ~/.\fBforward\fR like files must be readable by the recipient, and their parent directory needs to have "execute" diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in index d84538915..843e94dbc 100644 --- a/postfix/src/cleanup/Makefile.in +++ b/postfix/src/cleanup/Makefile.in @@ -577,6 +577,8 @@ cleanup_milter.o: ../../include/msg.h cleanup_milter.o: ../../include/mymalloc.h cleanup_milter.o: ../../include/nvtable.h cleanup_milter.o: ../../include/off_cvt.h +cleanup_milter.o: ../../include/quote_821_local.h +cleanup_milter.o: ../../include/quote_flags.h cleanup_milter.o: ../../include/rec_attr_map.h cleanup_milter.o: ../../include/rec_type.h cleanup_milter.o: ../../include/record.h diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h index 12b1d77dc..2c7637ecb 100644 --- a/postfix/src/cleanup/cleanup.h +++ b/postfix/src/cleanup/cleanup.h @@ -95,6 +95,8 @@ typedef struct CLEANUP_STATE { const char *client_addr; /* real or ersatz client */ int client_af; /* real or ersatz client */ const char *client_port; /* real or ersatz client */ + VSTRING *milter_ext_from; /* externalized sender */ + VSTRING *milter_ext_rcpt; /* externalized recipient */ } CLEANUP_STATE; /* diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c index c01d56ef1..b63ddb28a 100644 --- a/postfix/src/cleanup/cleanup_milter.c +++ b/postfix/src/cleanup/cleanup_milter.c @@ -104,6 +104,7 @@ #include #include #include +#include /* Application-specific. */ @@ -968,15 +969,19 @@ static const char *cleanup_del_header(void *context, ssize_t index, /* cleanup_add_rcpt - append recipient address */ -static const char *cleanup_add_rcpt(void *context, char *rcpt) +static const char *cleanup_add_rcpt(void *context, char *ext_rcpt) { const char *myname = "cleanup_add_rcpt"; CLEANUP_STATE *state = (CLEANUP_STATE *) context; off_t new_rcpt_offset; off_t reverse_ptr_offset; + int addr_count; + TOK822 *tree; + TOK822 *tp; + VSTRING *int_rcpt_buf; if (msg_verbose) - msg_info("%s: \"%s\"", myname, rcpt); + msg_info("%s: \"%s\"", myname, ext_rcpt); /* * To simplify implementation, the cleanup server writes a dummy @@ -1006,7 +1011,35 @@ static const char *cleanup_add_rcpt(void *context, char *rcpt) msg_warn("%s: seek file %s: %m", myname, cleanup_path); return (cleanup_milter_error(state, errno)); } - cleanup_addr_bcc(state, rcpt); + + /* + * Transform recipient from external form to internal form. This also + * removes the enclosing <>, if present. + * + * XXX vstring_alloc() rejects zero-length requests. + */ + int_rcpt_buf = vstring_alloc(strlen(ext_rcpt) + 1); + tree = tok822_parse(ext_rcpt); + for (addr_count = 0, tp = tree; tp != 0; tp = tp->next) { + if (tp->type == TOK822_ADDR) { + if (addr_count == 0) { + tok822_internalize(int_rcpt_buf, tp->head, TOK822_STR_DEFL); + addr_count += 1; + } else { + msg_warn("%s: Milter request to add multi-recipient: \"%s\"", + state->queue_id, ext_rcpt); + break; + } + } + } + tok822_free_tree(tree); + cleanup_addr_bcc(state, STR(int_rcpt_buf)); + vstring_free(int_rcpt_buf); + if (addr_count == 0) { + msg_warn("%s: ignoring attempt from Milter to add null recipient", + state->queue_id); + return (CLEANUP_OUT_OK(state) ? 0 : cleanup_milter_error(state, 0)); + } if ((reverse_ptr_offset = vstream_ftell(state->dst)) < 0) { msg_warn("%s: vstream_ftell file %s: %m", myname, cleanup_path); return (cleanup_milter_error(state, errno)); @@ -1042,7 +1075,7 @@ static const char *cleanup_add_rcpt(void *context, char *rcpt) /* cleanup_del_rcpt - remove recipient and all its expansions */ -static const char *cleanup_del_rcpt(void *context, char *rcpt) +static const char *cleanup_del_rcpt(void *context, char *ext_rcpt) { const char *myname = "cleanup_del_rcpt"; CLEANUP_STATE *state = (CLEANUP_STATE *) context; @@ -1057,9 +1090,13 @@ static const char *cleanup_del_rcpt(void *context, char *rcpt) int rec_type; int junk; int count = 0; + TOK822 *tree; + TOK822 *tp; + VSTRING *int_rcpt_buf; + int addr_count; if (msg_verbose) - msg_info("%s: \"%s\"", myname, rcpt); + msg_info("%s: \"%s\"", myname, ext_rcpt); /* * Virtual aliasing and other address rewriting happens after the mail @@ -1091,9 +1128,32 @@ static const char *cleanup_del_rcpt(void *context, char *rcpt) if (dsn_orcpt != 0) \ myfree(dsn_orcpt); \ vstring_free(buf); \ + vstring_free(int_rcpt_buf); \ return (ret); \ } while (0) + /* + * Transform recipient from external form to internal form. This also + * removes the enclosing <>, if present. + * + * XXX vstring_alloc() rejects zero-length requests. + */ + int_rcpt_buf = vstring_alloc(strlen(ext_rcpt) + 1); + tree = tok822_parse(ext_rcpt); + for (addr_count = 0, tp = tree; tp != 0; tp = tp->next) { + if (tp->type == TOK822_ADDR) { + if (addr_count == 0) { + tok822_internalize(int_rcpt_buf, tp->head, TOK822_STR_DEFL); + addr_count += 1; + } else { + msg_warn("%s: Milter request to drop multi-recipient: \"%s\"", + state->queue_id, ext_rcpt); + break; + } + } + } + tok822_free_tree(tree); + buf = vstring_alloc(100); for (;;) { if (CLEANUP_OUT_OK(state) == 0) @@ -1154,7 +1214,7 @@ static const char *cleanup_del_rcpt(void *context, char *rcpt) orig_rcpt = mystrdup(start); break; case REC_TYPE_RCPT: /* rewritten RCPT TO address */ - if (strcmp(orig_rcpt ? orig_rcpt : start, rcpt) == 0) { + if (strcmp(orig_rcpt ? orig_rcpt : start, STR(int_rcpt_buf)) == 0) { if (vstream_fseek(state->dst, curr_offset, SEEK_SET) < 0) { msg_warn("%s: seek file %s: %m", myname, cleanup_path); CLEANUP_DEL_RCPT_RETURN(cleanup_milter_error(state, errno)); @@ -1183,7 +1243,7 @@ static const char *cleanup_del_rcpt(void *context, char *rcpt) if (msg_verbose) msg_info("%s: deleted %d records for recipient \"%s\"", - myname, count, rcpt); + myname, count, ext_rcpt); CLEANUP_DEL_RCPT_RETURN(0); } @@ -1260,18 +1320,14 @@ static const char *cleanup_milter_eval(const char *name, void *ptr) if (strcmp(name, S8_MAC_AUTH_AUTHOR) == 0) return (nvtable_find(state->attr, MAIL_ATTR_SASL_SENDER)); #endif -#if 0 if (strcmp(name, S8_MAC_MAIL_ADDR) == 0) - return (state->sender); -#endif + return (state->milter_ext_from ? STR(state->milter_ext_from) : 0); /* * RCPT TO macros. */ -#if 0 if (strcmp(name, S8_MAC_RCPT_ADDR) == 0) - return (state->recipient); -#endif + return (state->milter_ext_rcpt ? STR(state->milter_ext_rcpt) : 0); return (0); } @@ -1485,7 +1541,14 @@ void cleanup_milter_emul_mail(CLEANUP_STATE *state, } } if (CLEANUP_MILTER_OK(state)) { - argv[0] = addr; + if (state->milter_ext_from == 0) + state->milter_ext_from = vstring_alloc(100); + /* Sendmail 8.13 does not externalize the null address. */ + if (*addr) + quote_821_local(state->milter_ext_from, addr); + else + vstring_strcpy(state->milter_ext_from, addr); + argv[0] = STR(state->milter_ext_from); argv[1] = 0; if ((resp = milter_mail_event(milters, argv)) != 0) { cleanup_milter_apply(state, "MAIL", resp); @@ -1515,7 +1578,14 @@ void cleanup_milter_emul_rcpt(CLEANUP_STATE *state, * attribute, but CLEANUP_STAT_DEFER takes precedence. It terminates * queue record processing, and prevents bounces from being sent. */ - argv[0] = addr; + if (state->milter_ext_rcpt == 0) + state->milter_ext_rcpt = vstring_alloc(100); + /* Sendmail 8.13 does not externalize the null address. */ + if (*addr) + quote_821_local(state->milter_ext_rcpt, addr); + else + vstring_strcpy(state->milter_ext_rcpt, addr); + argv[0] = STR(state->milter_ext_rcpt); argv[1] = 0; if ((resp = milter_rcpt_event(milters, argv)) != 0 && cleanup_milter_apply(state, "RCPT", resp) != 0) { diff --git a/postfix/src/cleanup/cleanup_state.c b/postfix/src/cleanup/cleanup_state.c index 2cbd73ec2..9a35f107d 100644 --- a/postfix/src/cleanup/cleanup_state.c +++ b/postfix/src/cleanup/cleanup_state.c @@ -113,6 +113,8 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src) state->client_addr = 0; state->client_af = 0; state->client_port = 0; + state->milter_ext_from = 0; + state->milter_ext_rcpt = 0; return (state); } @@ -159,5 +161,9 @@ void cleanup_state_free(CLEANUP_STATE *state) myfree(state->verp_delims); if (state->milters) milter_free(state->milters); + if (state->milter_ext_from) + vstring_free(state->milter_ext_from); + if (state->milter_ext_rcpt) + vstring_free(state->milter_ext_rcpt); myfree((char *) state); } diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index a4a7665fb..3329b61f8 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -20,7 +20,7 @@ * Patches change both the patchlevel and the release date. Snapshots have no * patchlevel; they change the release date only. */ -#define MAIL_RELEASE_DATE "20061006" +#define MAIL_RELEASE_DATE "20061015" #define MAIL_VERSION_NUMBER "2.4" #ifdef SNAPSHOT diff --git a/postfix/src/local/local.c b/postfix/src/local/local.c index 43a2596c6..623bd4782 100644 --- a/postfix/src/local/local.c +++ b/postfix/src/local/local.c @@ -39,7 +39,7 @@ /* configuration parameter. Upon delivery, the local delivery agent /* tries each pathname in the list until a file is found. /* -/* Delivery via ~/.\fB.forward\fR files is done with the privileges +/* Delivery via ~/.\fBforward\fR files is done with the privileges /* of the recipient. /* Thus, ~/.\fBforward\fR like files must be readable by the /* recipient, and their parent directory needs to have "execute" diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index a6ee5150d..69ac49e33 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -200,6 +200,7 @@ smtpd.o: smtpd_token.h smtpd_chat.o: ../../include/argv.h smtpd_chat.o: ../../include/attr.h smtpd_chat.o: ../../include/cleanup_user.h +smtpd_chat.o: ../../include/int_filt.h smtpd_chat.o: ../../include/iostuff.h smtpd_chat.o: ../../include/line_wrap.h smtpd_chat.o: ../../include/mail_addr.h @@ -303,6 +304,8 @@ smtpd_milter.o: ../../include/milter.h smtpd_milter.o: ../../include/myaddrinfo.h smtpd_milter.o: ../../include/name_code.h smtpd_milter.o: ../../include/name_mask.h +smtpd_milter.o: ../../include/quote_821_local.h +smtpd_milter.o: ../../include/quote_flags.h smtpd_milter.o: ../../include/sys_defs.h smtpd_milter.o: ../../include/tls.h smtpd_milter.o: ../../include/vbuf.h diff --git a/postfix/src/smtpd/smtpd_milter.c b/postfix/src/smtpd/smtpd_milter.c index 2b4df40a9..44480ed0b 100644 --- a/postfix/src/smtpd/smtpd_milter.c +++ b/postfix/src/smtpd/smtpd_milter.c @@ -36,6 +36,7 @@ /* Global library. */ #include +#include /* Milter library. */ @@ -148,14 +149,33 @@ const char *smtpd_milter_eval(const char *name, void *ptr) if (strcmp(name, S8_MAC_AUTH_AUTHOR) == 0) return (IF_SASL_ENABLED(state->sasl_sender)); #endif - if (strcmp(name, S8_MAC_MAIL_ADDR) == 0) - return (state->sender); + if (strcmp(name, S8_MAC_MAIL_ADDR) == 0) { + if (state->sender == 0) + return (0); + if (state->expand_buf == 0) + state->expand_buf = vstring_alloc(10); + /* Sendmail 8.13 does not externalize the null string. */ + if (state->sender[0]) + quote_821_local(state->expand_buf, state->sender); + else + vstring_strcpy(state->expand_buf, state->sender); + return (STR(state->expand_buf)); + } /* * RCPT TO macros. */ - if (strcmp(name, S8_MAC_RCPT_ADDR) == 0) - return (state->recipient); - + if (strcmp(name, S8_MAC_RCPT_ADDR) == 0) { + if (state->recipient == 0) + return (0); + if (state->expand_buf == 0) + state->expand_buf = vstring_alloc(10); + /* Sendmail 8.13 does not externalize the null string. */ + if (state->recipient[0]) + quote_821_local(state->expand_buf, state->recipient); + else + vstring_strcpy(state->expand_buf, state->recipient); + return (STR(state->expand_buf)); + } return (0); }