]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.7-20090828
authorWietse Venema <wietse@porcupine.org>
Fri, 28 Aug 2009 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:35:39 +0000 (06:35 +0000)
postfix/HISTORY
postfix/RELEASE_NOTES
postfix/src/global/mail_version.h
postfix/src/smtpd/smtpd_check.c

index b7925f75cc41bfe7e663d721cb13363858e17507..9bb8ec2638bf2b20c8c91cd8395bd6fb40432f2d 100644 (file)
@@ -15335,34 +15335,3 @@ Apologies for any names omitted.
 
        Bugfix: don't panic when an unexpected smtpd access map is
        specified. File: smtpd/smtpd_check.c.
-
-20090807
-
-       Workaround: NS record lookups for certain domains always
-       fail, while other queries for those domains always succeed
-       (and even return replies with NS records as additional
-       information).
-
-       This inconsistency would allow spammers to avoid the Postfix
-       check_{client,helo,sender,etc}_ns_access restrictions,
-       because those restrictions have effect only for names that
-       are known in the DNS.
-
-       To address this specific inconsistency, the Postfix
-       check_{client,etc}_ns_access feature now requires that a
-       known-in-DNS domain name (or parent thereof) resolves to
-       at least one name server IP address.
-
-       For consistency, check_{client,etc}_mx_access now requires
-       that a known-in-DNS domain name resolves to at least one
-       mail server IP address.
-
-       In addition, reject_unknown_helo_hostname,
-       reject_unknown_sender_domain now require that an MX record
-       resolves to at least one IP address. Until now, the existence
-       of an MX record was sufficient.
-
-       The IP addresses thus obtained may or may not be "correct".
-       There is little to stop an uncooperative DNS server from
-       lying, especially when the owner of the domain has no
-       intention to receive email.  File: smtpd/smtpd_check.c.
index 8875c6b3ccc002dbde430ccb9d8dacd1c7b88021..620a44132a7ec8da5a8ee391c79e90100686d10b 100644 (file)
@@ -14,32 +14,6 @@ specifies the release date of a stable release or snapshot release.
 If you upgrade from Postfix 2.5 or earlier, read RELEASE_NOTES-2.6
 before proceeding.
 
-Incompatibility with snapshot 20090807
-======================================
-
-With some domain names, NS record lookups always fail while other
-lookups always succeed (and may even return NS records as additional
-information).  This anomaly could be used by evil elements to skip
-Postfix check_{client,helo,sender,recipient}_ns_access checks,
-because these apply only to domains that are known in the DNS.
-
-To address this specific problem, check_{client,etc}_ns_access now
-requires that a known-in-DNS domain name (or parent thereof) resolves
-to at least one name server IP address.
-
-For consistency, check_{client,etc}_mx_access now requires that a
-known-in-DNS domain name resolves to at least one mail server IP
-address.
-
-In addition, reject_unknown_helo_hostname, reject_unknown_sender_domain
-and reject_unknown_recipient_domain now require that an MX record
-resolves to at least one IP address.  Until now, the existence of
-an MX record was sufficient.
-
-Keep in mind that these measures provide no hard assurances. There
-is little to stop an uncooperative DNS server from lying, especially
-when the owner of the domain has no intention to receive email.
-
 Incompatibility with snapshot 20090606
 ======================================
 
index b4977fc56af371e527cf54091ce340526706c5ac..27aab4fb87e1537860f286caf96fdedc16a7c510 100644 (file)
@@ -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      "20090807"
+#define MAIL_RELEASE_DATE      "20090828"
 #define MAIL_VERSION_NUMBER    "2.7"
 
 #ifdef SNAPSHOT
index 939429dee4c3d979991c2bcd6aa62d18abbb8e22..9b5e522fcfe6d8706f3428e37173b6993dff4d2c 100644 (file)
@@ -354,19 +354,6 @@ static int unk_addr_tf_act;
 static int unv_rcpt_tf_act;
 static int unv_from_tf_act;
 
- /*
-  * What address types to query for when we determine domain existence.
-  * 
-  * XXX Should we accept mail from a domain that has IPv6 addresses only, when
-  * the local system has IPv4 only? This can happen when the receiving system
-  * uses an IPv6-enabled relayhost.
-  */
-#ifdef T_AAAA
-#define CHECK_RR_ADDR_TYPES    T_A, T_AAAA
-#else
-#define CHECK_RR_ADDR_TYPES    T_A
-#endif
-
  /*
   * YASLM.
   */
@@ -1148,94 +1135,29 @@ static int reject_non_fqdn_hostname(SMTPD_STATE *state, char *name,
     return (stat);
 }
 
-/* resolve_server_list - check if at least some name resolves */
-
-static int resolve_server_list(const char *name, int type,
-                                      const char *reply_name,
-                                      const char *reply_class)
-{
-    const char *myname = "resolve_server_list";
-    const char *domain = name;
-    DNS_RR *server_list;
-    DNS_RR *server;
-    int     dns_status;
-    int     soft_err = 0;
-
-    /*
-     * Require that at least one server record exists.
-     */
-    dns_status = dns_lookup(domain, type, 0, &server_list,
-                           (VSTRING *) 0, (VSTRING *) 0);
-    if (dns_status == DNS_NOTFOUND /* Not: h_errno == NO_DATA */ ) {
-       if (type == T_MX) {
-           server_list = dns_rr_create(domain, domain, type, C_IN, 0, 0,
-                                       domain, strlen(domain) + 1);
-           dns_status = DNS_OK;
-       } else if (type == T_NS && h_errno == NO_DATA) {
-           while ((domain = strchr(domain, '.')) != 0 && domain[1]) {
-               domain += 1;
-               dns_status = dns_lookup(domain, type, 0, &server_list,
-                                       (VSTRING *) 0, (VSTRING *) 0);
-               if (dns_status != DNS_NOTFOUND || h_errno != NO_DATA)
-                   break;
-           }
-       }
-    }
-    if (dns_status != DNS_OK) {
-       msg_warn("Unable to look up %s host for %s: %s", dns_strtype(type),
-                domain && domain[1] ? domain : name, dns_strerror(h_errno));
-       return (dns_status);
-    }
-
-    /*
-     * Require that at least one server record resolves to an IP address.
-     */
-    for (server = server_list; server != 0; server = server->next) {
-       if (msg_verbose)
-           msg_info("%s: %s hostname check: %s",
-                    myname, dns_strtype(type), (char *) server->data);
-       if (valid_hostaddr((char *) server->data, DONT_GRIPE)) {
-           soft_err = 0;
-           break;
-       }
-       dns_status = dns_lookup_l((char *) server->data, 0, (DNS_RR **) 0,
-                                 (VSTRING *) 0, (VSTRING *) 0,
-                                 DNS_REQ_FLAG_STOP_OK,
-                                 CHECK_RR_ADDR_TYPES, 0);
-       if (dns_status == DNS_OK) {
-           soft_err = 0;
-           break;
-       }
-       msg_warn("Unable to look up %s host %s for %s %s: %s",
-                dns_strtype(type), (char *) server->data,
-                reply_class, reply_name, dns_strerror(h_errno));
-       if (dns_status == DNS_RETRY)
-           soft_err = 1;
-    }
-    dns_rr_free(server_list);
-    return (soft_err ? DNS_RETRY : dns_status);
-}
-
-/* reject_unknown_hostname - fail if name has no NS, A, AAAA or MX record */
+/* reject_unknown_hostname - fail if name has no A, AAAA or MX record */
 
 static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
                                        char *reply_name, char *reply_class)
 {
     const char *myname = "reject_unknown_hostname";
     int     dns_status;
+    DNS_RR *dummy;
 
     if (msg_verbose)
        msg_info("%s: %s", myname, name);
 
-    /*
-     * Require that at least one record exists of each type that
-     * check_server_access() wants to check.
-     */
-    dns_status = resolve_server_list(name, T_MX, reply_name, reply_class);
-#ifdef REQUIRE_NS_FOR_REJECT_UNKNOWN_DOMAIN_CHECK
-    if (dns_status == DNS_OK)
-       dns_status = resolve_server_list(name, T_NS, reply_name, reply_class);
+#ifdef T_AAAA
+#define RR_ADDR_TYPES  T_A, T_AAAA
+#else
+#define RR_ADDR_TYPES  T_A
 #endif
+
+    dns_status = dns_lookup_l(name, 0, &dummy, (VSTRING *) 0,
+                             (VSTRING *) 0, DNS_REQ_FLAG_STOP_OK,
+                             RR_ADDR_TYPES, T_MX, 0);
+    if (dummy)
+       dns_rr_free(dummy);
     if (dns_status != DNS_OK) {                        /* incl. DNS_INVAL */
        if (dns_status != DNS_RETRY)
            return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
@@ -1254,26 +1176,25 @@ static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
     return (SMTPD_CHECK_DUNNO);
 }
 
-/* reject_unknown_mailhost - fail if name has no NS, A, AAAA or MX record */
+/* reject_unknown_mailhost - fail if name has no A, AAAA or MX record */
 
 static int reject_unknown_mailhost(SMTPD_STATE *state, const char *name,
                            const char *reply_name, const char *reply_class)
 {
     const char *myname = "reject_unknown_mailhost";
     int     dns_status;
+    DNS_RR *dummy;
 
     if (msg_verbose)
        msg_info("%s: %s", myname, name);
 
-    /*
-     * Require that at least one record exists of each type that
-     * check_server_access() wants to check.
-     */
-    dns_status = resolve_server_list(name, T_MX, reply_name, reply_class);
-#ifdef REQUIRE_NS_FOR_REJECT_UNKNOWN_DOMAIN_CHECK
-    if (dns_status == DNS_OK)
-       dns_status = resolve_server_list(name, T_NS, reply_name, reply_class);
-#endif
+#define MAILHOST_LOOKUP_FLAGS  (DNS_REQ_FLAG_STOP_OK | DNS_REQ_FLAG_STOP_INVAL)
+
+    dns_status = dns_lookup_l(name, 0, &dummy, (VSTRING *) 0,
+                             (VSTRING *) 0, MAILHOST_LOOKUP_FLAGS,
+                             T_MX, RR_ADDR_TYPES, 0);
+    if (dummy)
+       dns_rr_free(dummy);
     if (dns_status != DNS_OK) {                        /* incl. DNS_INVAL */
        if (dns_status != DNS_RETRY)
            return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
@@ -2594,10 +2515,6 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
     struct addrinfo *res;
     int     status;
     INET_PROTO_INFO *proto_info;
-    const char *saved_domain;
-    int     non_err, soft_err;
-    int     known_name_in_dns;
-    int     ping_status;
 
     /*
      * Sanity check.
@@ -2652,20 +2569,9 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
      * 
      * If the domain name exists but no NS record exists, look up parent domain
      * NS records.
-     * 
-     * After the initial lookup fails, do one final DNS sanity check. Reject
-     * mail when the name exists, but MX lookup produces no valid response or
-     * NS lookup fails for any reason. Beware, this sanity check provides no
-     * hard assurance. An uncooperative DNS server may lie about everything,
-     * including non-existence.
      */
-#define SOME_DNS_RR_EXISTS(stat, herr) \
-       ((stat) == DNS_OK || (stat) == DNS_INVAL || (herr) == NO_DATA)
-
-    saved_domain = domain;
     dns_status = dns_lookup(domain, type, 0, &server_list,
                            (VSTRING *) 0, (VSTRING *) 0);
-    known_name_in_dns = SOME_DNS_RR_EXISTS(dns_status, h_errno);
     if (dns_status == DNS_NOTFOUND /* Not: h_errno == NO_DATA */ ) {
        if (type == T_MX) {
            server_list = dns_rr_create(domain, domain, type, C_IN, 0, 0,
@@ -2684,22 +2590,6 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
     if (dns_status != DNS_OK) {
        msg_warn("Unable to look up %s host for %s: %s", dns_strtype(type),
                 domain && domain[1] ? domain : name, dns_strerror(h_errno));
-       if (known_name_in_dns == 0) {
-           /* With hostile DNS, an address query is more likely to work. */
-           ping_status = dns_lookup_l(saved_domain, 0, (DNS_RR **) 0,
-                                      (VSTRING *) 0, (VSTRING *) 0,
-                                      DNS_REQ_FLAG_STOP_OK,
-                                      CHECK_RR_ADDR_TYPES, 0);
-           known_name_in_dns = SOME_DNS_RR_EXISTS(ping_status, h_errno);
-       }
-       if (known_name_in_dns)
-           return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
-                                      dns_status == DNS_RETRY ?
-                                  var_map_defer_code : var_map_reject_code,
-                                      smtpd_dsn_fix("4.1.8", reply_class),
-                                      "<%s>: %s rejected: %s",
-                                      reply_name, reply_class,
-                                      "Domain not found"));
        return (SMTPD_CHECK_DUNNO);
     }
 
@@ -2712,13 +2602,11 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
      * Check the hostnames first, then the addresses.
      */
     proto_info = inet_proto_info();
-    non_err = soft_err = 0;
     for (server = server_list; server != 0; server = server->next) {
        if (msg_verbose)
            msg_info("%s: %s hostname check: %s",
                     myname, dns_strtype(type), (char *) server->data);
        if (valid_hostaddr((char *) server->data, DONT_GRIPE)) {
-           non_err = 1;
            if ((status = check_addr_access(state, table, (char *) server->data,
                                      FULL, &found, reply_name, reply_class,
                                            def_acl)) != 0 || found)
@@ -2734,11 +2622,8 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
            msg_warn("Unable to look up %s host %s for %s %s: %s",
                     dns_strtype(type), (char *) server->data,
                     reply_class, reply_name, MAI_STRERROR(aierr));
-           if (aierr == EAI_AGAIN || aierr == EAI_SYSTEM)
-               soft_err = 1;
            continue;
        }
-       non_err = 1;
        /* Now we must also free the addrinfo result. */
        if (msg_verbose)
            msg_info("%s: %s host address check: %s",
@@ -2762,15 +2647,7 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
        }
        freeaddrinfo(res0);                     /* 200412 */
     }
-    status = non_err ? SMTPD_CHECK_DUNNO :
-       smtpd_check_reject(state, MAIL_ERROR_POLICY,
-                          soft_err ? var_map_defer_code :
-                          var_map_reject_code,
-                          smtpd_dsn_fix("4.1.8", reply_class),
-                          "<%s>: %s rejected: %s",
-                          reply_name, reply_class,
-                          "Domain not found");
-    CHECK_SERVER_RETURN(status);
+    CHECK_SERVER_RETURN(SMTPD_CHECK_DUNNO);
 }
 
 /* check_ccert_access - access for TLS clients by certificate fingerprint */