]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-1.1.11-20020921
authorWietse Venema <wietse@porcupine.org>
Sat, 21 Sep 2002 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:28:17 +0000 (06:28 +0000)
12 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd.h
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_check_access
postfix/src/smtpd/smtpd_exp.in [new file with mode: 0644]
postfix/src/smtpd/smtpd_exp.ref [new file with mode: 0644]
postfix/src/smtpd/smtpd_state.c

index 3d3da589cfbea019c335928ac3cebe6e347ef72f..c5594a1c56ff2fdae292efce2e5cfa8f19ccac1d 100644 (file)
 -TSINK_STATE
 -TSMTPD_CMD
 -TSMTPD_DEFER
+-TSMTPD_RBL_EXPAND_CONTEXT
+-TSMTPD_RBL_STATE
 -TSMTPD_STATE
 -TSMTPD_TOKEN
 -TSMTP_ADDR
index 8de67f0b44dcd58103c5cda640c040ff3a6bbb26..444f12d66ce20a19a9cc9976c94ebd3633e24bd4 100644 (file)
@@ -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 <domainname> 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
index 25fa510ded96874216525a4da7f89bd72f99564a..6b625a595200898cd31c64fdcd7859910db35187 100644 (file)
@@ -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
index a16e7f0300c9539092c4c785decfa73cae508b46..772bd92112d71537d9cb2362eb8c00063899cb8b 100644 (file)
@@ -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
index 9a4b28b0841fc019b60bbfdfdd6e6440030cbb7f..ed185bac94657a12546988d095fec6bded4b50db 100644 (file)
@@ -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.in >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.in2 >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_acl.in >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.in >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.in >smtpd_token.tmp 2>&1
        diff smtpd_token.ref smtpd_token.tmp
index 08c5bf949c41169facfb84caa0ae9fd7ddecdf40..2a4d16be7bcf95e7dc44f7f4d3653f034b1fe1e5 100644 (file)
@@ -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,
index 5cb9f19ec13381f4c34f3c7d71997adc0bbb921e..c76bb9d9a671814aaa203b82f819c8d5f91f5362 100644 (file)
@@ -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 *);
index dafc2373451dfa8b7d85594b8c648bcb71bd5ce9..965820cfac3df5eadcd4795cb4cdeab68788d79a 100644 (file)
 /* .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.
 #include <dict.h>
 #include <htable.h>
 #include <ctable.h>
+#include <mac_expand.h>
 
 /* 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));
+
+    if (rbl == 0) {
+       result = SMTPD_CHECK_DUNNO;
+    } else {
+       result = rbl_reject_reply(state, rbl, rbl_domain);
+    }
 
     /*
-     * Tack on each RBL domain name and query the DNS for an A record. If the
-     * record exists, the client address is blacklisted.
+     * Clean up.
      */
-    why = vstring_alloc(10);
+    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) {
-       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)
+       result = reject_rbl(state, rbl_domain);
+       if (result != SMTPD_CHECK_DUNNO)
            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
-       result = SMTPD_CHECK_DUNNO;
 
     /*
      * Clean up.
      */
-    argv_free(octets);
-    vstring_free(query);
     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 =
index b9cf1761fa0ad2a2f43625cb1cf43ad3a0d1ac45..3f031d243e927d3f3b0baa147774fe0524339877 100644 (file)
@@ -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 (file)
index 0000000..072f568
--- /dev/null
@@ -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 (file)
index 0000000..5f8013b
--- /dev/null
@@ -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 <URL:http://mail-abuse.org/cgi-bin/lookup?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 <URL:http://mail-abuse.org/cgi-bin/lookup?127.0.0.2>
index 5139d1b1c4bf60e7547181c8997659d54e0732ef..2887544acd6f70cb6757c152223758a0a262aae6 100644 (file)
@@ -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)