1--- src/postscreen/Makefile.in.orig	2024-03-09 21:34:49 UTC
2+++ src/postscreen/Makefile.in
3@@ -3,13 +3,13 @@ SRCS	= postscreen.c postscreen_dict.c postscreen_dnsbl
4 	postscreen_early.c postscreen_smtpd.c postscreen_misc.c \
5 	postscreen_state.c postscreen_tests.c postscreen_send.c \
6 	postscreen_starttls.c postscreen_expand.c postscreen_endpt.c \
7-	postscreen_haproxy.c
8+	postscreen_haproxy.c pfilter.c
9 OBJS	= postscreen.o postscreen_dict.o postscreen_dnsbl.o \
10 	postscreen_early.o postscreen_smtpd.o postscreen_misc.o \
11 	postscreen_state.o postscreen_tests.o postscreen_send.o \
12 	postscreen_starttls.o postscreen_expand.o postscreen_endpt.o \
13-	postscreen_haproxy.o
14-HDRS	=
15+	postscreen_haproxy.o pfilter.o
16+HDRS	= pfilter.h
17 TESTSRC	=
18 DEFS	= -I. -I$(INC_DIR) -D$(SYSTYPE)
19 CFLAGS	= $(DEBUG) $(OPT) $(DEFS)
20--- src/postscreen/pfilter.c.orig	2025-07-11 20:30:00 UTC
21+++ src/postscreen/pfilter.c
22@@ -0,0 +1,19 @@
23+#include "pfilter.h"
24+#include <stdio.h>	/* for NULL */
25+#include <blacklist.h>
26+
27+static struct blacklist *blstate;
28+
29+void
30+pfilter_notify(int a, int fd)
31+{
32+	if (blstate == NULL)
33+		blstate = blacklist_open();
34+	if (blstate == NULL)
35+		return;
36+	(void)blacklist_r(blstate, a, fd, "postscreen");
37+	if (a == 0) {
38+		blacklist_close(blstate);
39+		blstate = NULL;
40+	}
41+}
42--- src/postscreen/pfilter.h.orig	2025-07-11 20:30:00 UTC
43+++ src/postscreen/pfilter.h
44@@ -0,0 +1 @@
45+void pfilter_notify(int, int);
46--- src/postscreen/postscreen_early.c.orig	2021-02-18 18:55:31 UTC
47+++ src/postscreen/postscreen_early.c
48@@ -52,6 +52,7 @@
49 /* Application-specific. */
50
51 #include <postscreen.h>
52+#include "pfilter.h" /* for blacklistd(8) */
53
54 static char *psc_teaser_greeting;
55 static VSTRING *psc_escape_buf;
56@@ -183,6 +184,10 @@ static void psc_early_event(int event, void *context)
57 		msg_info("DNSBL rank %d for [%s]:%s",
58 			 state->dnsbl_score, PSC_CLIENT_ADDR_PORT(state));
59 		PSC_FAIL_SESSION_STATE(state, PSC_STATE_FLAG_DNSBL_FAIL);
60+
61+		/* notify blacklistd of DNSBL rank violation */
62+		pfilter_notify(1, vstream_fileno(state->smtp_client_stream));
63+
64 		switch (psc_dnsbl_action) {
65 		case PSC_ACT_DROP:
66 		    state->dnsbl_reply = vstring_sprintf(vstring_alloc(100),
67--- src/smtpd/Makefile.in.orig	2025-01-09 22:06:10 UTC
68+++ src/smtpd/Makefile.in
69@@ -2,14 +2,14 @@ SRCS	= smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.
70 SRCS	= smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
71 	smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
72 	smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c \
73-	smtpd_expand.c smtpd_haproxy.c
74+	smtpd_expand.c smtpd_haproxy.c pfilter.c
75 OBJS	= smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
76 	smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \
77 	smtpd_xforward.o smtpd_dsn_fix.o smtpd_milter.o smtpd_resolve.o \
78-	smtpd_expand.o smtpd_haproxy.o
79+	smtpd_expand.o smtpd_haproxy.o pfilter.o
80 HDRS	= smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
81 	smtpd_sasl_glue.h smtpd_proxy.h smtpd_dsn_fix.h smtpd_milter.h \
82-	smtpd_resolve.h smtpd_expand.h
83+	smtpd_resolve.h smtpd_expand.h pfilter.h
84 TESTSRC	= smtpd_token_test.c
85 DEFS	= -I. -I$(INC_DIR) -D$(SYSTYPE)
86 CFLAGS	= $(DEBUG) $(OPT) $(DEFS)
87--- src/smtpd/pfilter.c.orig	2025-07-11 20:30:00 UTC
88+++ src/smtpd/pfilter.c
89@@ -0,0 +1,19 @@
90+#include "pfilter.h"
91+#include <stdio.h>	/* for NULL */
92+#include <blacklist.h>
93+
94+static struct blacklist *blstate;
95+
96+void
97+pfilter_notify(int a, int fd)
98+{
99+	if (blstate == NULL)
100+		blstate = blacklist_open();
101+	if (blstate == NULL)
102+		return;
103+	(void)blacklist_r(blstate, a, fd, "smtpd");
104+	if (a == 0) {
105+		blacklist_close(blstate);
106+		blstate = NULL;
107+	}
108+}
109--- src/smtpd/pfilter.h.orig	2025-07-11 20:30:00 UTC
110+++ src/smtpd/pfilter.h
111@@ -0,0 +1 @@
112+void pfilter_notify(int, int);
113--- src/smtpd/smtpd_check.c.orig	2025-07-11 20:34:19 UTC
114+++ src/smtpd/smtpd_check.c
115@@ -1767,6 +1767,7 @@ static int reject_unauth_destination(SMTPD_STATE *stat
116     /*
117      * Reject relaying to sites that are not listed in relay_domains.
118      */
119+    pfilter_notify(1, vstream_fileno(state->client));
120     return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
121 			       reply_code, reply_dsn,
122 			       "<%s>: Relay access denied",
123--- src/smtpd/smtpd_milter.c.orig	2025-07-11 20:33:21 UTC
124+++ src/smtpd/smtpd_milter.c
125@@ -193,6 +193,7 @@ const char *smtpd_milter_eval(const char *name, void *
126 	    return ("");
127 	if (state->milter_reject_text) {
128 	    /* 554 5.7.1 <user@example.com>: Relay access denied */
129+	    pfilter_notify(1, vstream_fileno(state->client));
130 	    vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
131 	    cp = split_at(STR(state->expand_buf), ' ');
132 	    return (cp ? split_at(cp, ' ') : cp);
133@@ -210,6 +211,7 @@ const char *smtpd_milter_eval(const char *name, void *
134 	    return (0);
135 	if (state->milter_reject_text) {
136 	    /* 554 5.7.1 <user@example.com>: Relay access denied */
137+	    pfilter_notify(1, vstream_fileno(state->client));
138 	    vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
139 	    (void) split_at(STR(state->expand_buf), ' ');
140 	    return (STR(state->expand_buf));
141--- src/smtpd/smtpd_sasl_glue.c.orig	2023-11-12 21:41:13 UTC
142+++ src/smtpd/smtpd_sasl_glue.c
143@@ -153,6 +153,7 @@
144 #include "smtpd.h"
145 #include "smtpd_sasl_glue.h"
146 #include "smtpd_chat.h"
147+#include "pfilter.h" /* for blacklistd(8) */
148
149 #ifdef USE_SASL_AUTH
150
151@@ -358,8 +359,12 @@ int     smtpd_sasl_authenticate(SMTPD_STATE *state,
152 	else
153 	    smtpd_chat_reply(state, "535 5.7.8 Error: authentication failed: %s",
154 			     reason);
155+
156+	/* notify blacklistd of SASL authentication failure */
157+	pfilter_notify(1, vstream_fileno(state->client));
158 	return (-1);
159     }
160+
161     /* RFC 4954 Section 6. */
162     smtpd_chat_reply(state, "235 2.7.0 Authentication successful");
163     if ((sasl_username = xsasl_server_get_username(state->sasl_server)) == 0)
164