From a97acc2300946f7fa33bc174b604e6c234c57ad0 Mon Sep 17 00:00:00 2001 From: Wietse Venema Date: Sat, 21 Sep 2002 00:00:00 -0500 Subject: [PATCH] postfix-1.1.11-20020921 --- postfix/.indent.pro | 2 + postfix/HISTORY | 9 + postfix/src/global/mail_params.h | 5 + postfix/src/global/mail_version.h | 2 +- postfix/src/smtpd/Makefile.in | 15 +- postfix/src/smtpd/smtpd.c | 2 + postfix/src/smtpd/smtpd.h | 1 + postfix/src/smtpd/smtpd_check.c | 391 +++++++++++++++++++++++---- postfix/src/smtpd/smtpd_check_access | 7 + postfix/src/smtpd/smtpd_exp.in | 16 ++ postfix/src/smtpd/smtpd_exp.ref | 25 ++ postfix/src/smtpd/smtpd_state.c | 3 + 12 files changed, 415 insertions(+), 63 deletions(-) create mode 100644 postfix/src/smtpd/smtpd_exp.in create mode 100644 postfix/src/smtpd/smtpd_exp.ref diff --git a/postfix/.indent.pro b/postfix/.indent.pro index 3d3da589c..c5594a1c5 100644 --- a/postfix/.indent.pro +++ b/postfix/.indent.pro @@ -131,6 +131,8 @@ -TSINK_STATE -TSMTPD_CMD -TSMTPD_DEFER +-TSMTPD_RBL_EXPAND_CONTEXT +-TSMTPD_RBL_STATE -TSMTPD_STATE -TSMTPD_TOKEN -TSMTP_ADDR diff --git a/postfix/HISTORY b/postfix/HISTORY index 8de67f0b4..444f12d66 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -6978,6 +6978,15 @@ Apologies for any names omitted. Bugfix: pickup should not preserve INSPECT or FILTER records from "postsuper -r". File: pickup/pickup.c. +20020919 + + Feature: reject_rbl by LaMont Jones. + +20020921 + + Internal: generic caching and reject reporting that can be + used for both RBL and RHSBL. + Open problems: Low: smtpd should log queue ID with reject/warn/hold/discard diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 25fa510de..6b625a595 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -1202,6 +1202,11 @@ extern int var_access_map_code; #define WARN_IF_REJECT "warn_if_reject" +#define REJECT_RBL "reject_rbl" +#define VAR_RBL_REPLY_MAPS "rbl_reply_maps" +#define DEF_RBL_REPLY_MAPS "" +extern char *var_rbl_reply_maps; + #define REJECT_MAPS_RBL "reject_maps_rbl" #define VAR_MAPS_RBL_CODE "maps_rbl_reject_code" #define DEF_MAPS_RBL_CODE 554 diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index a16e7f030..772bd9211 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -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 "20020918" +#define MAIL_RELEASE_DATE "20020921" #define VAR_MAIL_VERSION "mail_version" #define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index 9a4b28b08..ed185bac9 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -67,26 +67,33 @@ depend: $(MAKES) done) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in @$(EXPORT) make -f Makefile.in Makefile 1>&2 -tests: smtpd_check_test smtpd_check_test2 smtpd_acl_test smtpd_token_test +tests: smtpd_check_test smtpd_check_test2 smtpd_acl_test smtpd_exp_test \ + smtpd_token_test -smtpd_check_test: smtpd_check smtpd_check.in smtpd_check.ref +smtpd_check_test: smtpd_check smtpd_check.in smtpd_check.ref smtpd_check_access ../postmap/postmap hash:smtpd_check_access ./smtpd_check smtpd_check.tmp 2>&1 diff smtpd_check.ref smtpd_check.tmp rm -f smtpd_check.tmp smtpd_check_access.* -smtpd_check_test2: smtpd_check smtpd_check.in2 smtpd_check.ref2 +smtpd_check_test2: smtpd_check smtpd_check.in2 smtpd_check.ref2 smtpd_check_access ../postmap/postmap hash:smtpd_check_access ./smtpd_check smtpd_check.tmp 2>&1 diff smtpd_check.ref2 smtpd_check.tmp rm -f smtpd_check.tmp smtpd_check_access.* -smtpd_acl_test: smtpd_check smtpd_acl.in smtpd_acl.ref +smtpd_acl_test: smtpd_check smtpd_acl.in smtpd_acl.ref smtpd_check_access ../postmap/postmap hash:smtpd_check_access ./smtpd_check smtpd_check.tmp 2>&1 diff smtpd_acl.ref smtpd_check.tmp rm -f smtpd_check.tmp smtpd_check_access.* +smtpd_exp_test: smtpd_check smtpd_exp.in smtpd_exp.ref + ../postmap/postmap hash:smtpd_check_access + ./smtpd_check smtpd_exp.tmp 2>&1 + diff smtpd_exp.ref smtpd_exp.tmp + rm -f smtpd_exp.tmp smtpd_check_access.* + smtpd_token_test: smtpd_token smtpd_token.in smtpd_token.ref ./smtpd_token smtpd_token.tmp 2>&1 diff smtpd_token.ref smtpd_token.tmp diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 08c5bf949..2a4d16be7 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -362,6 +362,7 @@ int var_relay_code; int var_maps_rbl_code; int var_access_map_code; char *var_maps_rbl_domains; +char *var_rbl_reply_maps; int var_helo_required; int var_reject_code; int var_defer_code; @@ -1616,6 +1617,7 @@ int main(int argc, char **argv) VAR_ETRN_CHECKS, DEF_ETRN_CHECKS, &var_etrn_checks, 0, 0, VAR_DATA_CHECKS, DEF_DATA_CHECKS, &var_data_checks, 0, 0, VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0, + VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, 0, VAR_ALWAYS_BCC, DEF_ALWAYS_BCC, &var_always_bcc, 0, 0, VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0, VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes, 0, 0, diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h index 5cb9f19ec..c76bb9d9a 100644 --- a/postfix/src/smtpd/smtpd.h +++ b/postfix/src/smtpd/smtpd.h @@ -89,6 +89,7 @@ typedef struct SMTPD_STATE { int warn_if_reject; /* force reject into warning */ SMTPD_DEFER defer_if_reject; /* force reject into deferral */ SMTPD_DEFER defer_if_permit; /* force permit into deferral */ + VSTRING *expand_buf; /* scratch space for $name expansion */ } SMTPD_STATE; extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *); diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c index dafc23734..965820cfa 100644 --- a/postfix/src/smtpd/smtpd_check.c +++ b/postfix/src/smtpd/smtpd_check.c @@ -89,12 +89,19 @@ /* .IP "check_recipient_access maptype:mapname" /* Look up the resolved recipient address in the named access table, /* any parent domains of the recipient domain, and the localpart@. +/* .IP reject_rbl rbl.domain +/* Look up the reversed client network address in the specified +/* real-time blackhole DNS zone. The \fIrbl_reply_maps\fR configuration +/* parameter is used to generate the template for the reject message. +/* If it is not specified, or the rbl domain cannot be found, then a +/* default template is used. The \fImaps_rbl_reject_code\fR +/* configuration parameter specifies the reject status code used in +/* the default template (default: 554). /* .IP reject_maps_rbl /* Look up the reversed client network address in the real-time blackhole /* DNS zones below the domains listed in the "maps_rbl_domains" -/* configuration parameter. The \fImaps_rbl_reject_code\fR -/* configuration parameter specifies the reject status code -/* (default: 554). +/* configuration parameter. This is equivalent to using "reject_rbl" +/* once for each such domain. /* .IP permit_naked_ip_address /* Permit the use of a naked IP address (without enclosing []) /* in HELO/EHLO commands. @@ -277,6 +284,7 @@ #include #include #include +#include /* DNS library. */ @@ -326,6 +334,7 @@ static jmp_buf smtpd_check_buf; */ static VSTRING *error_text; static CTABLE *smtpd_resolve_cache; +static CTABLE *smtpd_rbl_cache; /* * Pre-opened SMTP recipient maps so we can reject mail for unknown users. @@ -339,6 +348,11 @@ static MAPS *virtual_maps; static MAPS *virt_mailbox_maps; static MAPS *relocated_maps; + /* + * Response templates for various rbl domains. + */ +static MAPS *rbl_reply_maps; + /* * Pre-opened sender to login name mapping. */ @@ -413,6 +427,23 @@ static void PRINTFLIKE(3, 4) defer_if(SMTPD_DEFER *, int, const char *,...); defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2), (a3)) #define DEFER_IF_PERMIT2(state, class, fmt, a1, a2) \ defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2)) + + /* + * Cached RBL lookup state. + */ +typedef struct { + char *txt; /* TXT record or null */ +} SMTPD_RBL_STATE; + + /* + * Context for RBL $name expansion. + */ +typedef struct { + SMTPD_STATE *state; /* general state */ + SMTPD_RBL_STATE *rbl_state; /* cached RBL state */ + const char *domain; /* query domain */ +} SMTPD_RBL_EXPAND_CONTEXT; + /* resolve_pagein - page in an address resolver result */ static void *resolve_pagein(const char *addr, void *unused_context) @@ -455,6 +486,53 @@ static void resolve_pageout(void *data, void *unused_context) myfree((void *) reply); } +/* rbl_pagein - page in an RBL lookup result */ + +static void *rbl_pagein(const char *query, void *unused_context) +{ + DNS_RR *txt_list; + VSTRING *why; + int dns_status; + SMTPD_RBL_STATE *rbl; + + /* + * Do the query. + */ + why = vstring_alloc(10); + dns_status = dns_lookup(query, T_A, 0, (DNS_RR **) 0, + (VSTRING *) 0, why); + if (dns_status != DNS_OK && dns_status != DNS_NOTFOUND) + msg_warn("%s: RBL lookup error: %s", query, STR(why)); + vstring_free(why); + if (dns_status != DNS_OK) + return (0); + + /* + * Save the result. + */ + rbl = (SMTPD_RBL_STATE *) mymalloc(sizeof(*rbl)); + if (dns_lookup(query, T_TXT, 0, &txt_list, + (VSTRING *) 0, (VSTRING *) 0) == DNS_OK) { + rbl->txt = mystrdup(txt_list->data); + dns_rr_free(txt_list); + } else + rbl->txt = 0; + return ((void *) rbl); +} + +/* rbl_pageout - page out an RBL lookup result */ + +static void rbl_pageout(void *data, void *unused_context) +{ + SMTPD_RBL_STATE *rbl = (SMTPD_RBL_STATE *) data; + + if (rbl != 0) { + if (rbl->txt) + myfree(rbl->txt); + myfree((char *) rbl); + } +} + /* smtpd_check_parse - pre-parse restrictions */ static ARGV *smtpd_check_parse(const char *checks) @@ -581,6 +659,12 @@ void smtpd_check_init(void) access_parent_style = match_parent_style(SMTPD_ACCESS_MAPS); + /* + * Templates for RBL rejection replies. + */ + rbl_reply_maps = maps_create(VAR_RBL_REPLY_MAPS, var_rbl_reply_maps, + DICT_FLAG_LOCK); + /* * Sender to login name mapping. */ @@ -596,8 +680,13 @@ void smtpd_check_init(void) /* * Initialize the resolved address cache. */ - smtpd_resolve_cache = ctable_create(100, resolve_pagein, - resolve_pageout, (void *) 0); + smtpd_resolve_cache = ctable_create(100, resolve_pagein, resolve_pageout, + (void *) 0); + + /* + * Initialize the RBL lookup cache. + */ + smtpd_rbl_cache = ctable_create(100, rbl_pagein, rbl_pageout, (void *) 0); /* * Pre-parse the restriction lists. At the same time, pre-open tables @@ -2034,24 +2123,190 @@ static int check_mail_access(SMTPD_STATE *state, const char *table, CHECK_MAIL_ACCESS_RETURN(SMTPD_CHECK_DUNNO); } -/* reject_maps_rbl - reject if client address in real-time blackhole list */ +/* edit_addr - return address or substring thereof */ -static int reject_maps_rbl(SMTPD_STATE *state) +static const char *edit_addr(VSTRING *buf, const char *addr, const char *name) { - char *myname = "reject_maps_rbl"; - ARGV *octets = argv_split(state->addr, "."); - VSTRING *query = vstring_alloc(100); - char *saved_domains = mystrdup(var_maps_rbl_domains); - char *bp = saved_domains; - char *rbl_domain; - char *rbl_reason; - char *rbl_fodder; - DNS_RR *txt_list; - int reverse_len; - int dns_status = DNS_FAIL; + const char *p; + + /* + * Return "undefined" when the address is unavailable. + */ + if (addr == 0) + return (0); + + /* + * "sender" or "recipient". + */ + if (*name == 0) { + if (*addr) + return (addr); + else + return ("<>"); + } + + /* + * "sender_name" or "recipient_name". + */ +#define STREQ(x,y) (*(x) == *(y) && strcmp((x), (y)) == 0) + + else if (STREQ(name, "_name")) { + if (*addr) { + if ((p = strrchr(addr, '@')) != 0) { + vstring_strncpy(buf, addr, p - addr); + return (STR(buf)); + } else { + return (addr); + } + } else + return ("<>"); + } + + /* + * "sender_domain" or "recipient_domain". + */ + else if (STREQ(name, "_domain")) { + if (*addr) { + if ((p = strrchr(addr, '@')) != 0) { + return (p + 1); + } else { + return (0); + } + } else + return (0); + } + + /* + * Unknown. + */ + else + return (0); +} + +/* smtpd_expand_lookup - generic SMTP attribute $name expansion */ + +static const char *smtpd_expand_lookup(const char *name, int unused_mode, + char *context) +{ + SMTPD_STATE *state = (SMTPD_STATE *) context; + + if (state->expand_buf == 0) + state->expand_buf = vstring_alloc(10); + + if (msg_verbose > 1) + msg_info("smtpd_expand_lookup: ${%s}", name); + +#define STREQN(x,y,n) (*(x) == *(y) && strncmp((x), (y), (n)) == 0) +#define CONST_LEN(x) (sizeof(x) - 1) + + /* + * Don't query main.cf parameters, as the result of expansion could + * reveal system-internal information in server replies. + */ + if (STREQ(name, "client")) { + return (state->namaddr); + } else if (STREQ(name, "client_address")) { + return (state->addr); + } else if (STREQ(name, "client_name")) { + return (state->name); + } else if (STREQ(name, "helo_name")) { + return (state->helo_name ? state->helo_name : 0); + } else if (STREQN(name, "sender", CONST_LEN("sender"))) { + return (edit_addr(state->expand_buf, state->sender, + name + CONST_LEN("sender"))); + } else if (STREQN(name, "recipient", CONST_LEN("recipient"))) { + return (edit_addr(state->expand_buf, state->recipient, + name + CONST_LEN("recipient"))); + } else { + return (0); + } +} + +/* rbl_expand_lookup - RBL specific $name expansion */ + +static const char *rbl_expand_lookup(const char *name, int mode, + char *context) +{ + SMTPD_RBL_EXPAND_CONTEXT *rbl_exp = (SMTPD_RBL_EXPAND_CONTEXT *) context; + SMTPD_RBL_STATE *rbl = rbl_exp->rbl_state; + SMTPD_STATE *state = rbl_exp->state; + + if (state->expand_buf == 0) + state->expand_buf = vstring_alloc(10); + + if (msg_verbose > 1) + msg_info("rbl_expand_lookup: ${%s}", name); + + if (STREQ(name, "rbl_code")) { + vstring_sprintf(state->expand_buf, "%d", var_maps_rbl_code); + return (STR(state->expand_buf)); + } else if (STREQ(name, "rbl_domain")) { + return (rbl_exp->domain); + } else if (STREQ(name, "rbl_txt")) { + return (rbl->txt); + } else { + return (smtpd_expand_lookup(name, mode, (char *) state)); + } +} + +/* rbl_reject_reply - format reply after RBL reject */ + +static int rbl_reject_reply(SMTPD_STATE *state, SMTPD_RBL_STATE *rbl, + const char *rbl_domain) +{ + const char *myname = "rbl_reject_reply"; + VSTRING *why = 0; + const char *template = 0; + char *low_name; + SMTPD_RBL_EXPAND_CONTEXT rbl_exp; + int result; + + if (*var_rbl_reply_maps) { + low_name = lowercase(mystrdup(rbl_domain)); + template = maps_find(rbl_reply_maps, low_name, 0); + myfree(low_name); + } + if (template) { + why = vstring_alloc(10); + rbl_exp.state = state; /* XXX */ + rbl_exp.rbl_state = rbl; + rbl_exp.domain = rbl_domain; +#define NO_SMTPD_EXP_FILTER ((char *) 0) /* XXX */ + if (mac_expand(why, template, MAC_EXP_FLAG_NONE, + NO_SMTPD_EXP_FILTER, rbl_expand_lookup, + (char *) &rbl_exp) & MAC_PARSE_ERROR) { + msg_warn("%s: bad rbl template: %s", myname, template); + template = 0; /* pretend not found */ + } + } + if (template) { + result = smtpd_check_reject(state, MAIL_ERROR_POLICY, STR(why)); + } else { + result = smtpd_check_reject(state, MAIL_ERROR_POLICY, + "%d Service unavailable; [%s] blocked using %s%s%s", + var_maps_rbl_code, state->addr, + rbl_domain, rbl->txt ? ", reason: " : "", rbl->txt); + } + + /* + * Clean up. + */ + if (why) + vstring_free(why); + + return (result); +} + +/* reject_rbl - reject if client address in real-time blackhole list */ + +static int reject_rbl(SMTPD_STATE *state, const char *rbl_domain) +{ + char *myname = "reject_rbl"; + ARGV *octets; + VSTRING *query; int i; int result; - VSTRING *why; + SMTPD_RBL_STATE *rbl; if (msg_verbose) msg_info("%s: %s", myname, state->addr); @@ -2065,57 +2320,62 @@ static int reject_maps_rbl(SMTPD_STATE *state) #endif /* - * Build the constant part of the RBL query: the reverse client address. + * Initialize. */ + query = vstring_alloc(100); + + /* + * Reverse the client IPV4 address, tack on the RBL domain name and query + * the DNS for an A record. If the record exists, the client address is + * blacklisted. If the DNS lookup produces no definitive reply, give the + * client the benefit of the doubt. We can't block all email simply + * because an RBL server is unavailable. + */ + octets = argv_split(state->addr, "."); for (i = octets->argc - 1; i >= 0; i--) { vstring_strcat(query, octets->argv[i]); vstring_strcat(query, "."); } - reverse_len = VSTRING_LEN(query); + argv_free(octets); + vstring_strcat(query, rbl_domain); + rbl = (SMTPD_RBL_STATE *) ctable_locate(smtpd_rbl_cache, STR(query)); - /* - * Tack on each RBL domain name and query the DNS for an A record. If the - * record exists, the client address is blacklisted. - */ - why = vstring_alloc(10); - while ((rbl_domain = mystrtok(&bp, " \t\r\n,")) != 0) { - vstring_truncate(query, reverse_len); - vstring_strcat(query, rbl_domain); - dns_status = dns_lookup(STR(query), T_A, 0, (DNS_RR **) 0, - (VSTRING *) 0, why); - if (dns_status == DNS_OK) - break; - if (dns_status != DNS_NOTFOUND) - msg_warn("%s: RBL lookup error: %s", STR(query), STR(why)); - } - vstring_free(why); - - /* - * Report the result. - */ - if (dns_status == DNS_OK) { - if (dns_lookup(STR(query), T_TXT, 0, &txt_list, - (VSTRING *) 0, (VSTRING *) 0) == DNS_OK) { - rbl_fodder = ", reason: "; - rbl_reason = (char *) txt_list->data; - } else { - txt_list = 0; - rbl_fodder = rbl_reason = ""; - } - result = smtpd_check_reject(state, MAIL_ERROR_POLICY, - "%d Service unavailable; [%s] blocked using %s%s%s", - var_maps_rbl_code, state->addr, rbl_domain, - rbl_fodder, rbl_reason); - if (txt_list) - dns_rr_free(txt_list); - } else + if (rbl == 0) { result = SMTPD_CHECK_DUNNO; + } else { + result = rbl_reject_reply(state, rbl, rbl_domain); + } /* * Clean up. */ - argv_free(octets); vstring_free(query); + + return (result); +} + +/* reject_maps_rbl - reject if client address in real-time blackhole list */ + +static int reject_maps_rbl(SMTPD_STATE *state) +{ + char *myname = "reject_maps_rbl"; + char *saved_domains = mystrdup(var_maps_rbl_domains); + char *bp = saved_domains; + char *rbl_domain; + int result = SMTPD_CHECK_DUNNO; + + if (msg_verbose) + msg_info("%s: %s", myname, state->addr); + + while ((rbl_domain = mystrtok(&bp, " \t\r\n,")) != 0) { + result = reject_rbl(state, rbl_domain); + if (result != SMTPD_CHECK_DUNNO) + break; + } + + /* + * Clean up. + */ myfree(saved_domains); return (result); @@ -2268,6 +2528,12 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions, SMTPD_NAME_CLIENT, def_acl); } else if (strcasecmp(name, REJECT_MAPS_RBL) == 0) { status = reject_maps_rbl(state); + } else if (strcasecmp(name, REJECT_RBL) == 0) { + if (*(cpp += 1) == 0) + msg_warn("restriction %s requires domain name argument", + REJECT_RBL); + else + status = reject_rbl(state, *cpp); } /* @@ -2894,6 +3160,7 @@ char *var_par_dom_match; char *var_smtpd_null_key; char *var_smtpd_snd_auth_maps; char *var_double_bounce_sender; +char *var_rbl_reply_maps; typedef struct { char *name; @@ -2920,6 +3187,7 @@ static STRING_TABLE string_table[] = { VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, VAR_SMTPD_NULL_KEY, DEF_SMTPD_NULL_KEY, &var_smtpd_null_key, VAR_DOUBLE_BOUNCE, DEF_DOUBLE_BOUNCE, &var_double_bounce_sender, + VAR_RBL_REPLY_MAPS, DEF_RBL_REPLY_MAPS, &var_rbl_reply_maps, 0, }; @@ -3258,6 +3526,13 @@ int main(int argc, char **argv) resp = 0; break; } + if (strcasecmp(args->argv[0], "rbl_reply_maps") == 0) { + UPDATE_STRING(var_rbl_reply_maps, args->argv[1]); + UPDATE_MAPS(rbl_reply_maps, VAR_RBL_REPLY_MAPS, + var_rbl_reply_maps, DICT_FLAG_LOCK); + resp = 0; + break; + } if (strcasecmp(args->argv[0], "mynetworks") == 0) { namadr_list_free(mynetworks); mynetworks = diff --git a/postfix/src/smtpd/smtpd_check_access b/postfix/src/smtpd/smtpd_check_access index b9cf1761f..3f031d243 100644 --- a/postfix/src/smtpd/smtpd_check_access +++ b/postfix/src/smtpd/smtpd_check_access @@ -30,3 +30,10 @@ reject@ok.domain REJECT ok@ok.domain OK ok.domain OK <> 550 Go away postmaster + +blackholes.mail-abuse.org $rbl_code client=$client + client_address=$client_address + client_name=$client_name helo_name=$helo_name + sender=$sender sender_name=$sender_name + recipient=$recipient recipient_name=$recipient_name + rbl_code=$rbl_code rbl_domain=$rbl_domain rbl_txt=$rbl_txt diff --git a/postfix/src/smtpd/smtpd_exp.in b/postfix/src/smtpd/smtpd_exp.in new file mode 100644 index 000000000..072f56873 --- /dev/null +++ b/postfix/src/smtpd/smtpd_exp.in @@ -0,0 +1,16 @@ +# +# Initialize. +# +#! ../bin/postmap smtpd_check_access +#msg_verbose 1 +smtpd_delay_reject 0 +mynetworks 127.0.0.0/8,168.100.189.0/28 +relay_domains porcupine.org +maps_rbl_domains blackholes.mail-abuse.org +rbl_reply_maps hash:smtpd_check_access +# +# RBL +# +client_restrictions reject_maps_rbl +client spike.porcupine.org 168.100.189.2 +client foo 127.0.0.2 diff --git a/postfix/src/smtpd/smtpd_exp.ref b/postfix/src/smtpd/smtpd_exp.ref new file mode 100644 index 000000000..5f8013ba6 --- /dev/null +++ b/postfix/src/smtpd/smtpd_exp.ref @@ -0,0 +1,25 @@ +>>> # +>>> # Initialize. +>>> # +>>> #! ../bin/postmap smtpd_check_access +>>> #msg_verbose 1 +>>> smtpd_delay_reject 0 +OK +>>> mynetworks 127.0.0.0/8,168.100.189.0/28 +OK +>>> relay_domains porcupine.org +OK +>>> maps_rbl_domains blackholes.mail-abuse.org +OK +>>> rbl_reply_maps hash:smtpd_check_access +OK +>>> # +>>> # RBL +>>> # +>>> client_restrictions reject_maps_rbl +OK +>>> client spike.porcupine.org 168.100.189.2 +OK +>>> client foo 127.0.0.2 +./smtpd_check: reject: CONNECT from foo[127.0.0.2]: 554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name= sender= sender_name= recipient= recipient_name= rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see +554 client=foo[127.0.0.2] client_address=127.0.0.2 client_name=foo helo_name= sender= sender_name= recipient= recipient_name= rbl_code=554 rbl_domain=blackholes.mail-abuse.org rbl_txt=Blackholed - see diff --git a/postfix/src/smtpd/smtpd_state.c b/postfix/src/smtpd/smtpd_state.c index 5139d1b1c..2887544ac 100644 --- a/postfix/src/smtpd/smtpd_state.c +++ b/postfix/src/smtpd/smtpd_state.c @@ -93,6 +93,7 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream) state->junk_cmds = 0; state->defer_if_reject.reason = 0; state->defer_if_permit.reason = 0; + state->expand_buf = 0; #ifdef USE_SASL_AUTH if (SMTPD_STAND_ALONE(state)) @@ -129,6 +130,8 @@ void smtpd_state_reset(SMTPD_STATE *state) vstring_free(state->defer_if_permit.reason); if (state->defer_if_reject.reason) vstring_free(state->defer_if_reject.reason); + if (state->expand_buf) + vstring_free(state->expand_buf); #ifdef USE_SASL_AUTH if (var_smtpd_sasl_enable)