]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.2-20160625
authorWietse Venema <wietse@porcupine.org>
Sat, 25 Jun 2016 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Tue, 26 Jul 2016 11:54:51 +0000 (07:54 -0400)
21 files changed:
postfix/HISTORY
postfix/WISHLIST
postfix/html/dnsblog.8.html
postfix/makedefs
postfix/man/man8/dnsblog.8
postfix/src/dnsblog/dnsblog.c
postfix/src/global/dict_mysql.c
postfix/src/global/mail_version.h
postfix/src/global/resolve_clnt.c
postfix/src/global/resolve_clnt.h
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_check.h
postfix/src/smtpd/smtpd_milter.c
postfix/src/smtpd/smtpd_resolve.c
postfix/src/smtpd/smtpd_resolve.h
postfix/src/smtpd/smtpd_sasl_glue.c
postfix/src/xsasl/xsasl.h
postfix/src/xsasl/xsasl_cyrus_server.c
postfix/src/xsasl/xsasl_server.c

index ad4a2be631d3987d2cc8722322943f3b8354a260..7246e352951b6818c347552cd65850c53596469d 100644 (file)
@@ -1,4 +1,8 @@
 In addition to the names listed below, the following people provided
+
+20160618
+
+       Bugfix: 
 useful inputs on many occasions: Paul D. Robertson, Simon J. Mudd.
 Apologies for any names omitted.
 
@@ -22370,5 +22374,40 @@ Apologies for any names omitted.
 
 20140612
 
-       Bugfix: missing server address/port conversion. File:
+       Bugfix (introduced: 20090211): missing server address
+       conversion for non-proxy, non-postscreen connections.  File:
        smtpd/smtpd_peer.c.
+
+       Bugfix (introduced: 20160611) missing server port conversion
+       for non-proxy, non-postscreen connections, because there was
+       no server address conversion.  File: smtpd/smtpd_peer.c.
+
+20160618
+
+       Bugfix(introduced: 20091121): with the introduction of
+       sender_dependent_default_transport_maps, the SMTP daemon
+       was not updated. This resulted in false rejects with
+       sender-dependent "error" transports. Based on a fix by
+       Russell Yanofsky.  Files: global/resolve_clnt.c,
+       global/resolve_clnt.h, smtpd/smtpd_check.c, smtpd/smtpd_check.h,
+       smtpd/smtpd_milter.c, smtpd/smtpd_resolve.c, smtpd/smtpd_resolve.h.
+
+20160619
+
+       Refinements to the 20160618 fix. For more consistent results
+       with sender address validation, use the recipient address
+       (if available) as the sender-dependent address resolver
+       context.  For better caching, pass sender context with all
+       attempts to resolve an email address.  File: smtpd/smtpd.c,
+       smtpd/smtpd_check.c, smtpd/smtpd_milter.c.
+
+20160625
+
+       Cleanup: the Postfix SMTP server now passes network address
+       and port information to the Cyrus SASL library. Build with
+       ``make makefiles "CCARGS=$CCARGS -DNO_IP_CYRUS_SASL_AUTH"''
+       for backwards compatibility. Files: makedefs,
+       smtpd/smtpd_sasl_glue.c, xsasl/xsasl.h, xsasl/xsasl_cyrus_server.c,
+       xsasl/xsasl_server.c.
+
+       Cleanup: dnsblog manpage. File: dnsblog/dnsblog.c.
index 488e361a10200deae425d399de77d097eb901c11..c9f6558cd43d120a2e4a6ded460c3df74ea1b06d 100644 (file)
@@ -9,6 +9,8 @@ Wish list:
        Propagate SMTPD_PEER_CODE_XXX from smtpd(8) to cleanup(8),
        so that {client_resolve} and {_} produce consistent results.
 
+       NO_IP_CYRUS_SASL_AUTH should be a main.cf parameter.
+
        Modeline support in config files to enable/disable trailing
        #comment, and to give hints about how to handle an LHS or
        RHS.
index 8e51362e47b9dd313471969934d935dd01abc4a3..229ccbae0bcb37b9542bbf0baab724df827be58d 100644 (file)
@@ -24,8 +24,8 @@ DNSBLOG(8)                                                          DNSBLOG(8)
        match and replies with the query arguments plus an  address  list  with
        the resulting IP addresses, separated by whitespace, and the reply TTL.
        Otherwise it replies with the query arguments  plus  an  empty  address
-       list and the reply TTL; the reply TTL is -1 if there is no reply, or if
-       a negative reply contains  no  SOA  record.   Finally,  The  <a href="dnsblog.8.html"><b>dnsblog</b>(8)</a>
+       list  and the reply TTL; the reply TTL is -1 if there is no reply, or a
+       negative reply that contains no SOA record.   Finally,  the  <a href="dnsblog.8.html"><b>dnsblog</b>(8)</a>
        server closes the connection.
 
 <b>DIAGNOSTICS</b>
index 694868c47c12c4db06d02cd4c9dca89458875112..8b8f07acb8f479ad41a3a737803c2c98f1521d21 100644 (file)
 #
 #      Note: this directive is for debugging and testing only. It
 #      is not guaranteed to work on all platforms.
+# .IP \fB-DNO_IP_CYRUS_SASL_AUTH\fR
+#      Don't pass remote SMTP client and Postfix SMTP server IP
+#      address and port information to the Cyrus SASL library.
+#      This is compatible with Postfix < 3.2.
 # .IP \fB-DNO_KQUEUE\fR
 #      Do not build with FreeBSD/NetBSD/OpenBSD/MacOSX KQUEUE support.
 #      By default, KQUEUE support is compiled in on platforms that
index ba95973fe7da0027aba0d12b091c8989bc3e46b4..c9a8bff3595fe2e25ccdc3b95c8d57018f756a49 100644 (file)
@@ -29,8 +29,8 @@ query arguments plus an address list with the resulting IP
 addresses, separated by whitespace, and the reply TTL.
 Otherwise it replies with the query arguments plus an empty
 address list and the reply TTL; the reply TTL is \-1 if there
-is no reply, or if a negative reply contains no SOA record.
-Finally, The \fBdnsblog\fR(8) server closes the connection.
+is no reply, or a negative reply that contains no SOA record.
+Finally, the \fBdnsblog\fR(8) server closes the connection.
 .SH DIAGNOSTICS
 .ad
 .fi
index 5243828b68b902d98ecfb478b35585e3a8890a0a..ef9842ec2c8de52b1f4f649685838ddbd46669a8 100644 (file)
@@ -21,8 +21,8 @@
 /*     addresses, separated by whitespace, and the reply TTL.
 /*     Otherwise it replies with the query arguments plus an empty
 /*     address list and the reply TTL; the reply TTL is -1 if there
-/*     is no reply, or if a negative reply contains no SOA record.
-/*     Finally, The \fBdnsblog\fR(8) server closes the connection.
+/*     is no reply, or a negative reply that contains no SOA record.
+/*     Finally, the \fBdnsblog\fR(8) server closes the connection.
 /* DIAGNOSTICS
 /*     Problems and transactions are logged to \fBsyslogd\fR(8).
 /* CONFIGURATION PARAMETERS
index a0279f4f12df945f430ab972ada1cc166c248d89..732b63c045dbe914cb1eaecaae1a8fb2517ec47d 100644 (file)
@@ -295,8 +295,9 @@ static void dict_mysql_quote(DICT *dict, const char *name, VSTRING *result)
      * We won't get integer overflows in 2*len + 1, because Postfix input
      * keys have reasonable size limits, better safe than sorry.
      */
-    if (len > (INT_MAX - 1) / 2)
-       msg_panic("dict_mysql_quote: integer overflow in 2*%d+1", len);
+    if (len > (INT_MAX - VSTRING_LEN(result) - 1) / 2)
+       msg_panic("dict_mysql_quote: integer overflow in %lu+2*%d+1",
+                 (unsigned long) VSTRING_LEN(result), len);
     buflen = 2 * len + 1;
     VSTRING_SPACE(result, buflen);
 
index 11e92caa3c08e3e403ce2a376c69b1b269186617..f26efffd3bc6f56ee204dc95deb66d17761db9b7 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      "20160612"
+#define MAIL_RELEASE_DATE      "20160625"
 #define MAIL_VERSION_NUMBER    "3.2"
 
 #ifdef SNAPSHOT
index 40ef3b77ca55f34e16675772dc92254f9487cc3e..3014e4a1bf1d947338f61a778b355ac1a8ba125b 100644 (file)
 /*     void    resolve_clnt_init(reply)
 /*     RESOLVE_REPLY *reply;
 /*
-/*     void    resolve_clnt_query(address, reply)
-/*     const char *address;
-/*     RESOLVE_REPLY *reply;
-/*
 /*     void    resolve_clnt_query_from(sender, address, reply)
 /*     const char *sender;
 /*     const char *address;
 /*     RESOLVE_REPLY *reply;
 /*
-/*     void    resolve_clnt_verify(address, reply)
-/*     const char *address;
-/*     RESOLVE_REPLY *reply;
-/*
 /*     void    resolve_clnt_verify_from(sender, address, reply)
 /*     const char *sender;
 /*     const char *address;
 /*     by resolve_clnt_query(). The structure is destroyed by passing
 /*     it to resolve_clnt_free().
 /*
-/*     resolve_clnt_query() sends an internal-form recipient address
+/*     resolve_clnt_query_from() sends an internal-form recipient address
 /*     (user@domain) to the resolver daemon and returns the resulting
 /*     transport name, next_hop host name, and internal-form recipient
 /*     address. In case of communication failure the program keeps trying
-/*     until the mail system goes down.
+/*     until the mail system goes down. The internal-form sender
+/*     information is used for sender-dependent relayhost lookup.
+/*     Specify RESOLVE_NULL_FROM when the sender is unavailable.
 /*
-/*     resolve_clnt_verify() implements an alternative version that can
+/*     resolve_clnt_verify_from() implements an alternative version that can
 /*     be used for address verification.
 /*
-/*     resolve_clnt_query_from() and resolve_clnt_verify_from()
-/*     allow the caller to supply sender context that will be used
-/*     for sender-dependent relayhost lookup.
-/*
 /*     In the resolver reply, the flags member is the bit-wise OR of
 /*     zero or more of the following:
 /* .IP RESOLVE_FLAG_FINAL
index a198bfdaf41580bcddc8f41ac90848c4d9d8d91c..b4290c0c1691135771f9ec6e152d4369a91ac858 100644 (file)
@@ -53,11 +53,6 @@ extern void resolve_clnt_free(RESOLVE_REPLY *);
 
 #define RESOLVE_NULL_FROM      ""
 
-#define resolve_clnt_query(a, r) \
-       resolve_clnt(RESOLVE_REGULAR, RESOLVE_NULL_FROM, (a), (r))
-#define resolve_clnt_verify(a, r) \
-       resolve_clnt(RESOLVE_VERIFY, RESOLVE_NULL_FROM, (a), (r))
-
 #define resolve_clnt_query_from(f, a, r) \
        resolve_clnt(RESOLVE_REGULAR, (f), (a), (r))
 #define resolve_clnt_verify_from(f, a, r) \
index d5ffb4069920df76b309e9150851ae0dd46ace83..2ad34988f34cdf86fac1a6afedeb13736edb07c2 100644 (file)
@@ -531,6 +531,7 @@ smtpd_resolve.o: ../../include/mymalloc.h
 smtpd_resolve.o: ../../include/nvtable.h
 smtpd_resolve.o: ../../include/resolve_clnt.h
 smtpd_resolve.o: ../../include/rewrite_clnt.h
+smtpd_resolve.o: ../../include/split_at.h
 smtpd_resolve.o: ../../include/stringops.h
 smtpd_resolve.o: ../../include/sys_defs.h
 smtpd_resolve.o: ../../include/vbuf.h
index 1365e7d8b81fe76ee31cf27075b59a4b4ae89f71..2e24a08b896eb628af4c4e7e77e70c24a972df2f 100644 (file)
@@ -2286,7 +2286,9 @@ static int extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
        if ((STR(state->addr_buf)[0] == 0 && !allow_empty_addr)
            || (strict_rfc821 && STR(state->addr_buf)[0] == '@')
            || (SMTPD_STAND_ALONE(state) == 0
-               && smtpd_check_addr(STR(state->addr_buf), smtputf8) != 0)) {
+            && smtpd_check_addr(strcmp(state->where, SMTPD_CMD_MAIL) == 0 ?
+                                state->recipient : state->sender,
+                                STR(state->addr_buf), smtputf8) != 0)) {
            msg_warn("Illegal address syntax from %s in %s command: %s",
                     state->namaddr, state->where,
                     printable(STR(arg->vstrval), '?'));
index a0287725e4970a0932269b8f2689562ff675ac5d..546e468849394583b4935e6089476db1097bfb73 100644 (file)
@@ -9,7 +9,8 @@
 /*
 /*     void    smtpd_check_init()
 /*
-/*     int     smtpd_check_addr(address, smtputf8)
+/*     int     smtpd_check_addr(sender, address, smtputf8)
+/*     const char *sender;
 /*     const char *address;
 /*     int     smtputf8;
 /*
@@ -57,7 +58,9 @@
 /*     once during the process life time.
 /*
 /*     smtpd_check_addr() sanity checks an email address and returns
-/*     non-zero in case of badness.
+/*     non-zero in case of badness. The sender argument provides sender
+/*     context for address resolution and caching, or a null pointer
+/*     if information is unavailable.
 /*
 /*     smtpd_check_rewrite() should be called before opening a queue
 /*     file or proxy connection, in order to establish the proper
@@ -351,7 +354,8 @@ static int generic_checks(SMTPD_STATE *, ARGV *, const char *, const char *, con
   */
 static int check_sender_rcpt_maps(SMTPD_STATE *, const char *);
 static int check_recipient_rcpt_maps(SMTPD_STATE *, const char *);
-static int check_rcpt_maps(SMTPD_STATE *, const char *, const char *);
+static int check_rcpt_maps(SMTPD_STATE *, const char *, const char *,
+                                  const char *);
 
  /*
   * Tempfail actions;
@@ -1615,7 +1619,7 @@ static int permit_auth_destination(SMTPD_STATE *state, char *recipient)
     /*
      * Resolve the address.
      */
-    reply = smtpd_resolve_addr(recipient);
+    reply = smtpd_resolve_addr(state->sender, recipient);
     if (reply->flags & RESOLVE_FLAG_FAIL)
        reject_dict_retry(state, recipient);
 
@@ -1910,7 +1914,7 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient,
     /*
      * Resolve the address.
      */
-    reply = smtpd_resolve_addr(recipient);
+    reply = smtpd_resolve_addr(state->sender, recipient);
     if (reply->flags & RESOLVE_FLAG_FAIL)
        reject_dict_retry(state, recipient);
 
@@ -2098,7 +2102,8 @@ static int reject_unknown_address(SMTPD_STATE *state, const char *addr,
     /*
      * Resolve the address.
      */
-    reply = smtpd_resolve_addr(addr);
+    reply = smtpd_resolve_addr(strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
+                              state->recipient : state->sender, addr);
     if (reply->flags & RESOLVE_FLAG_FAIL)
        reject_dict_retry(state, addr);
 
@@ -3155,7 +3160,8 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
     /*
      * Resolve the address.
      */
-    reply = smtpd_resolve_addr(addr);
+    reply = smtpd_resolve_addr(strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
+                              state->recipient : state->sender, addr);
     if (reply->flags & RESOLVE_FLAG_FAIL)
        reject_dict_retry(state, addr);
 
@@ -3806,7 +3812,7 @@ static int reject_auth_sender_login_mismatch(SMTPD_STATE *state, const char *sen
      * Reject if the client is logged in and does not own the sender address.
      */
     if (smtpd_sender_login_maps && state->sasl_username) {
-       reply = smtpd_resolve_addr(sender);
+       reply = smtpd_resolve_addr(state->recipient, sender);
        if (reply->flags & RESOLVE_FLAG_FAIL)
            reject_dict_retry(state, sender);
        if ((owners = check_mail_addr_find(state, sender, smtpd_sender_login_maps,
@@ -3840,7 +3846,7 @@ static int reject_unauth_sender_login_mismatch(SMTPD_STATE *state, const char *s
      * owner.
      */
     if (smtpd_sender_login_maps && !state->sasl_username) {
-       reply = smtpd_resolve_addr(sender);
+       reply = smtpd_resolve_addr(state->recipient, sender);
        if (reply->flags & RESOLVE_FLAG_FAIL)
            reject_dict_retry(state, sender);
        if (check_mail_addr_find(state, sender, smtpd_sender_login_maps,
@@ -4658,7 +4664,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
 
 /* smtpd_check_addr - address sanity check */
 
-int     smtpd_check_addr(const char *addr, int smtputf8)
+int     smtpd_check_addr(const char *sender, const char *addr, int smtputf8)
 {
     const RESOLVE_REPLY *resolve_reply;
     const char *myname = "smtpd_check_addr";
@@ -4674,7 +4680,7 @@ int     smtpd_check_addr(const char *addr, int smtputf8)
      */
     if (addr == 0 || *addr == 0)
        return (0);
-    resolve_reply = smtpd_resolve_addr(addr);
+    resolve_reply = smtpd_resolve_addr(sender, addr);
     if (resolve_reply->flags & RESOLVE_FLAG_ERROR)
        return (-1);
 
@@ -5084,7 +5090,8 @@ static int check_recipient_rcpt_maps(SMTPD_STATE *state, const char *recipient)
     if (state->warn_if_reject == 0)
        /* We really validate the recipient address. */
        state->recipient_rcptmap_checked = 1;
-    return (check_rcpt_maps(state, recipient, SMTPD_NAME_RECIPIENT));
+    return (check_rcpt_maps(state, state->sender, recipient,
+                           SMTPD_NAME_RECIPIENT));
 }
 
 /* check_sender_rcpt_maps - generic_checks() sender table check */
@@ -5103,12 +5110,14 @@ static int check_sender_rcpt_maps(SMTPD_STATE *state, const char *sender)
     if (state->warn_if_reject == 0)
        /* We really validate the sender address. */
        state->sender_rcptmap_checked = 1;
-    return (check_rcpt_maps(state, sender, SMTPD_NAME_SENDER));
+    return (check_rcpt_maps(state, state->recipient, sender,
+                           SMTPD_NAME_SENDER));
 }
 
 /* check_rcpt_maps - generic_checks() interface for recipient table check */
 
-static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient,
+static int check_rcpt_maps(SMTPD_STATE *state, const char *sender,
+                                  const char *recipient,
                                   const char *reply_class)
 {
     const RESOLVE_REPLY *reply;
@@ -5120,7 +5129,7 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient,
     /*
      * Resolve the address.
      */
-    reply = smtpd_resolve_addr(recipient);
+    reply = smtpd_resolve_addr(sender, recipient);
     if (reply->flags & RESOLVE_FLAG_FAIL)
        reject_dict_retry(state, recipient);
 
index a654cd6e09c528bafda9b92a39c657b94e415830..e7f440145331098ea55e4243426a8073a375ccf7 100644 (file)
@@ -13,7 +13,7 @@
   * External interface.
   */
 extern void smtpd_check_init(void);
-extern int smtpd_check_addr(const char *, int);
+extern int smtpd_check_addr(const char *, const char *, int);
 extern char *smtpd_check_rewrite(SMTPD_STATE *);
 extern char *smtpd_check_client(SMTPD_STATE *);
 extern char *smtpd_check_helo(SMTPD_STATE *, char *);
index 463097e82d20a3b8dcb885d1587d4e78313b3832..5deba67981436a5f0433f8b4e5a26ecf6b399d69 100644 (file)
@@ -162,7 +162,7 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
            return (0);
        if (state->sender[0] == 0)
            return ("");
-       reply = smtpd_resolve_addr(state->sender);
+       reply = smtpd_resolve_addr(state->recipient, state->sender);
        /* Sendmail 8.13 does not externalize the null string. */
        if (STR(reply->recipient)[0])
            quote_821_local(state->expand_buf, STR(reply->recipient));
@@ -173,13 +173,13 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
     if (strcmp(name, S8_MAC_MAIL_HOST) == 0) {
        if (state->sender == 0)
            return (0);
-       reply = smtpd_resolve_addr(state->sender);
+       reply = smtpd_resolve_addr(state->recipient, state->sender);
        return (STR(reply->nexthop));
     }
     if (strcmp(name, S8_MAC_MAIL_MAILER) == 0) {
        if (state->sender == 0)
            return (0);
-       reply = smtpd_resolve_addr(state->sender);
+       reply = smtpd_resolve_addr(state->recipient, state->sender);
        return (STR(reply->transport));
     }
 
@@ -197,7 +197,7 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
            cp = split_at(STR(state->expand_buf), ' ');
            return (cp ? split_at(cp, ' ') : cp);
        }
-       reply = smtpd_resolve_addr(state->recipient);
+       reply = smtpd_resolve_addr(state->sender, state->recipient);
        /* Sendmail 8.13 does not externalize the null string. */
        if (STR(reply->recipient)[0])
            quote_821_local(state->expand_buf, STR(reply->recipient));
@@ -214,7 +214,7 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
            (void) split_at(STR(state->expand_buf), ' ');
            return (STR(state->expand_buf));
        }
-       reply = smtpd_resolve_addr(state->recipient);
+       reply = smtpd_resolve_addr(state->sender, state->recipient);
        return (STR(reply->nexthop));
     }
     if (strcmp(name, S8_MAC_RCPT_MAILER) == 0) {
@@ -222,7 +222,7 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
            return (0);
        if (state->milter_reject_text)
            return (S8_RCPT_MAILER_ERROR);
-       reply = smtpd_resolve_addr(state->recipient);
+       reply = smtpd_resolve_addr(state->sender, state->recipient);
        return (STR(reply->transport));
     }
     return (0);
index 7cd8e4cda03fe47da15c154306f506d57ac7270f..0adf6904e6b59fafa62cd4eeb2047da814901166 100644 (file)
@@ -9,7 +9,8 @@
 /*     void    smtpd_resolve_init(cache_size)
 /*     int     cache_size;
 /*
-/*     const RESOLVE_REPLY *smtpd_resolve_addr(addr)
+/*     const RESOLVE_REPLY *smtpd_resolve_addr(sender, addr)
+/*     const char *sender;
 /*     const char *addr;
 /* DESCRIPTION
 /*     This module maintains a resolve client cache that persists
@@ -26,6 +27,8 @@
 /*     Arguments:
 /* .IP cache_size
 /*     The requested cache size.
+/* .IP sender
+/*     The message sender, or null pointer.
 /* .IP addr
 /*     The address to resolve.
 /* DIAGNOSTICS
@@ -56,6 +59,7 @@
 #include <vstring.h>
 #include <ctable.h>
 #include <stringops.h>
+#include <split_at.h>
 
 /* Global library. */
 
 static CTABLE *smtpd_resolve_cache;
 
 #define STR(x) vstring_str(x)
+#define SENDER_ADDR_JOIN_CHAR '\n'
 
 /* resolve_pagein - page in an address resolver result */
 
-static void *resolve_pagein(const char *addr, void *unused_context)
+static void *resolve_pagein(const char *sender_plus_addr, void *unused_context)
 {
+    const char myname[] = "resolve_pagein";
     static VSTRING *query;
+    static VSTRING *junk;
+    static VSTRING *sender_buf;
     RESOLVE_REPLY *reply;
-    char   *tmp;
+    const char *sender;
+    const char *addr;
 
     /*
      * Initialize on the fly.
      */
-    if (query == 0)
+    if (query == 0) {
        query = vstring_alloc(10);
+       junk = vstring_alloc(10);
+       sender_buf = vstring_alloc(10);
+    }
 
     /*
      * Initialize.
@@ -91,14 +103,22 @@ static void *resolve_pagein(const char *addr, void *unused_context)
     reply = (RESOLVE_REPLY *) mymalloc(sizeof(*reply));
     resolve_clnt_init(reply);
 
+    /*
+     * Split the sender and address.
+     */
+    vstring_strcpy(junk, sender_plus_addr);
+    sender = STR(junk);
+    if ((addr = split_at(STR(junk), SENDER_ADDR_JOIN_CHAR)) == 0)
+       msg_panic("%s: bad search key: \"%s\"", myname, sender_plus_addr);
+
     /*
      * Resolve the address.
      */
+    rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, sender, sender_buf);
     rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, addr, query);
-    resolve_clnt_query(STR(query), reply);
-    tmp = mystrdup(STR(reply->recipient));
-    casefold(reply->recipient, tmp);           /* XXX */
-    myfree(tmp);
+    resolve_clnt_query_from(STR(sender_buf), STR(query), reply);
+    vstring_strcpy(junk, STR(reply->recipient));
+    casefold(reply->recipient, STR(junk));     /* XXX */
 
     /*
      * Save the result.
@@ -136,10 +156,17 @@ void    smtpd_resolve_init(int cache_size)
                                        resolve_pageout, (void *) 0);
 }
 
-/* smtpd_resolve_addr - resolve cached addres */
+/* smtpd_resolve_addr - resolve cached address */
 
-const RESOLVE_REPLY *smtpd_resolve_addr(const char *addr)
+const RESOLVE_REPLY *smtpd_resolve_addr(const char *sender, const char *addr)
 {
+    static VSTRING *sender_plus_addr_buf;
+
+    /*
+     * Initialize on the fly.
+     */
+    if (sender_plus_addr_buf == 0)
+       sender_plus_addr_buf = vstring_alloc(10);
 
     /*
      * Sanity check.
@@ -150,5 +177,9 @@ const RESOLVE_REPLY *smtpd_resolve_addr(const char *addr)
     /*
      * Reply from the read-through cache.
      */
-    return (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, addr);
+    vstring_sprintf(sender_plus_addr_buf, "%s%c%s",
+                   sender ? sender : RESOLVE_NULL_FROM,
+                   SENDER_ADDR_JOIN_CHAR, addr);
+    return (const RESOLVE_REPLY *)
+       ctable_locate(smtpd_resolve_cache, STR(sender_plus_addr_buf));
 }
index bfbc494dad0bd7443ebd94c266edbc72e1014f1b..c04c52a7a9157d0895a72092abefd69ff980ac9b 100644 (file)
@@ -17,7 +17,7 @@
   * External interface.
   */
 extern void smtpd_resolve_init(int);
-extern const RESOLVE_REPLY *smtpd_resolve_addr(const char *);
+extern const RESOLVE_REPLY *smtpd_resolve_addr(const char*, const char *);
 
 /* LICENSE
 /* .ad
index 3dcd18fe6d42302624353990107b553953330d64..569f771d7ec31543a1c9732213b0672609d441fe 100644 (file)
@@ -218,10 +218,15 @@ void    smtpd_sasl_activate(SMTPD_STATE *state, const char *sasl_opts_name,
     if ((state->sasl_server =
         XSASL_SERVER_CREATE(smtpd_sasl_impl, &create_args,
                             stream = state->client,
-                            server_addr = (state->dest_addr ?
-                                           state->dest_addr : ""),
+                            addr_family = state->addr_family,
+                            server_addr = ADDR_OR_EMPTY(state->dest_addr,
+                                                      SERVER_ADDR_UNKNOWN),
+                            server_port = ADDR_OR_EMPTY(state->dest_port,
+                                                      SERVER_PORT_UNKNOWN),
                             client_addr = ADDR_OR_EMPTY(state->addr,
                                                       CLIENT_ADDR_UNKNOWN),
+                            client_port = ADDR_OR_EMPTY(state->port,
+                                                      CLIENT_PORT_UNKNOWN),
                             service = var_smtpd_sasl_service,
                           user_realm = REALM_OR_NULL(var_smtpd_sasl_realm),
                             security_options = sasl_opts_val,
index 976a676aea93ef19e157257306b4681495d71392..b494d7e22b16f5ca33fe94dd479e922dfef0b1ac 100644 (file)
@@ -46,8 +46,11 @@ typedef struct XSASL_SERVER {
   */
 typedef struct XSASL_SERVER_CREATE_ARGS {
     VSTREAM *stream;
+    int     addr_family;
     const char *server_addr;
+    const char *server_port;
     const char *client_addr;
+    const char *client_port;
     const char *service;
     const char *user_realm;
     const char *security_options;
@@ -64,9 +67,10 @@ extern ARGV *xsasl_server_types(void);
 
 #define xsasl_server_create(impl, args) \
        (impl)->create((impl), (args))
-#define XSASL_SERVER_CREATE(impl, args, a1, a2, a3, a4, a5, a6, a7) \
+#define XSASL_SERVER_CREATE(impl, args, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \
        xsasl_server_create((impl), (((args)->a1), ((args)->a2), ((args)->a3), \
-       ((args)->a4), ((args)->a5), ((args)->a6), ((args)->a7), (args)))
+       ((args)->a4), ((args)->a5), ((args)->a6), ((args)->a7), ((args)->a8), \
+       ((args)->a9), ((args)->a10), (args)))
 #define xsasl_server_done(impl) (impl)->done((impl));
 
  /*
index 70e7a9d68468c885aecec3a8ce25f50ce9e1fdb1..89e1fc9a0c7a38abbc8e1736b1f8fc48595d559e 100644 (file)
@@ -57,6 +57,7 @@
 /* System library. */
 
 #include <sys_defs.h>
+#include <sys/socket.h>
 #include <stdlib.h>
 #include <string.h>
 
@@ -139,6 +140,10 @@ typedef int MECHANISM_COUNT_TYPE;
 typedef const char *SERVEROUT_TYPE;
 typedef const void *VOID_SERVEROUT_TYPE;
 
+#endif
+
+#ifndef NO_IP_CYRUS_SASL_AUTH
+#define USE_IP_CYRUS_SASL_AUTH
 #endif
 
  /*
@@ -264,8 +269,8 @@ static XSASL_SERVER *xsasl_cyrus_server_create(XSASL_SERVER_IMPL *unused_impl,
                                             XSASL_SERVER_CREATE_ARGS *args)
 {
     const char *myname = "xsasl_cyrus_server_create";
-    char   *server_address;
-    char   *client_address;
+    char   *server_addr_port = 0;
+    char   *client_addr_port = 0;
     sasl_conn_t *sasl_conn = 0;
     XSASL_CYRUS_SERVER *server = 0;
     int     sasl_status;
@@ -286,6 +291,15 @@ static XSASL_SERVER *xsasl_cyrus_server_create(XSASL_SERVER_IMPL *unused_impl,
            if (sasl_conn) \
                sasl_dispose(&sasl_conn); \
        } \
+       XSASL_CYRUS_SERVER_CREATE_RETURN(x); \
+    } while (0)
+
+#define XSASL_CYRUS_SERVER_CREATE_RETURN(x) \
+    do { \
+       if (server_addr_port) \
+           myfree(server_addr_port); \
+       if (client_addr_port) \
+           myfree(client_addr_port); \
        return (x); \
     } while (0)
 
@@ -296,27 +310,31 @@ static XSASL_SERVER *xsasl_cyrus_server_create(XSASL_SERVER_IMPL *unused_impl,
 #define NO_SESSION_CALLBACKS   ((sasl_callback_t *) 0)
 #define NO_AUTH_REALM          ((char *) 0)
 
-#if SASL_VERSION_MAJOR >= 2 && defined(USE_SASL_IP_AUTH)
+#if SASL_VERSION_MAJOR >= 2 && defined(USE_IP_CYRUS_SASL_AUTH)
 
     /*
-     * Get IP addresses of local and remote endpoints for SASL.
+     * Get IP address and port of local and remote endpoints for SASL. Some
+     * implementation supports "[ipv6addr]:port" and "ipv4addr:port" (e.g.,
+     * https://illumos.org/man/3sasl/sasl_server_new), They still support the
+     * historical "address;port" syntax, so we stick with that for now.
      */
-#error "USE_SASL_IP_AUTH is not implemented"
-
+    server_addr_port = (*args->server_addr && *args->server_port ?
+                       concatenate(args->server_addr, ";",
+                                   args->server_port, (char *) 0) : 0);
+    client_addr_port = (*args->client_addr && *args->client_port ?
+                       concatenate(args->client_addr, ";",
+                                   args->client_port, (char *) 0) : 0);
 #else
 
     /*
-     * Don't give any IP address information to SASL.  SASLv1 doesn't use it,
-     * and in SASLv2 this will disable any mechanisms that do.
+     * Don't give any IP address information to SASL.
      */
-    server_address = 0;
-    client_address = 0;
 #endif
 
     if ((sasl_status =
         SASL_SERVER_NEW(args->service, var_myhostname,
                         args->user_realm ? args->user_realm : NO_AUTH_REALM,
-                        server_address, client_address,
+                        server_addr_port, client_addr_port,
                         NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
                         &sasl_conn)) != SASL_OK) {
        msg_warn("SASL per-connection server initialization: %s",
@@ -345,7 +363,7 @@ static XSASL_SERVER *xsasl_cyrus_server_create(XSASL_SERVER_IMPL *unused_impl,
        != XSASL_AUTH_OK)
        XSASL_CYRUS_SERVER_CREATE_ERROR_RETURN(0);
 
-    return (&server->xsasl);
+    XSASL_CYRUS_SERVER_CREATE_RETURN(&server->xsasl);
 }
 
 /* xsasl_cyrus_server_set_security - set security properties */
index 6b45ab8b098eb21a371c4122c3a0e45a94842494..669a867a65377f0e74496d8efc4d6cad25f4967f 100644 (file)
 /*     after successful authentication.
 /*
 /*     Arguments:
+/* .IP addr_family
+/*     The network address family: AF_INET6 or AF_INET.
 /* .IP auth_method
 /*     AUTH command authentication method.
 /* .IP client_addr
 /*     IPv4 or IPv6 address (no surrounding [] or ipv6: prefix),
 /*     or zero-length string if unavailable.
+/* .IP client_port
+/*     TCP port or zero-length string if unavailable.
 /* .IP init_resp
 /*     AUTH command initial response or null pointer.
 /* .IP implementation
 /* .IP server_addr
 /*     IPv4 or IPv6 address (no surrounding [] or ipv6: prefix),
 /*     or zero-length string if unavailable.
+/* .IP server_port
+/*     TCP port or zero-length string if unavailable.
 /* .IP server_reply
 /*     BASE64 encoded server non-error reply (without SMTP reply
 /*     code or enhanced status code), or ASCII error description.