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.
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).
#include <mail_params.h>
#include <lex_822.h>
#include <is_header.h>
+#include <quote_821_local.h>
/* Application-specific. */
/* 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
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));
/* 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;
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
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)
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));
if (msg_verbose)
msg_info("%s: deleted %d records for recipient \"%s\"",
- myname, count, rcpt);
+ myname, count, ext_rcpt);
CLEANUP_DEL_RCPT_RETURN(0);
}
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);
}
}
}
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);
* 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) {
/* Global library. */
#include <mail_params.h>
+#include <quote_821_local.h>
/* Milter library. */
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);
}