]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.3-20051220
authorWietse Venema <wietse@porcupine.org>
Tue, 20 Dec 2005 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:31:54 +0000 (06:31 +0000)
84 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/Makefile.in
postfix/README_FILES/SASL_README
postfix/README_FILES/SMTPD_POLICY_README
postfix/RELEASE_NOTES
postfix/html/SASL_README.html
postfix/html/SMTPD_POLICY_README.html
postfix/html/postconf.1.html
postfix/html/postconf.5.html
postfix/html/smtp.8.html
postfix/html/smtpd.8.html
postfix/man/man1/postconf.1
postfix/man/man5/postconf.5
postfix/man/man8/smtp.8
postfix/man/man8/smtpd.8
postfix/mantools/postlink
postfix/proto/SASL_README.html
postfix/proto/SMTPD_POLICY_README.html
postfix/proto/postconf.proto
postfix/src/bounce/bounce_trace_service.c
postfix/src/cleanup/cleanup_envelope.c
postfix/src/cleanup/cleanup_out_recipient.c
postfix/src/dns/dns_rr_to_sa.c
postfix/src/global/Makefile.in
postfix/src/global/cfg_parser.c
postfix/src/global/deliver_pass.c
postfix/src/global/dict_ldap.c
postfix/src/global/dict_mysql.c
postfix/src/global/mail_params.h
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.h
postfix/src/global/rec_type.h
postfix/src/global/sent.c
postfix/src/postconf/Makefile.in
postfix/src/postconf/postconf.c
postfix/src/postqueue/postqueue.c
postfix/src/qmqpd/qmqpd.c
postfix/src/qmqpd/qmqpd_peer.c
postfix/src/smtp/Makefile.in
postfix/src/smtp/lmtp_params.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp.h
postfix/src/smtp/smtp_chat.c
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_map11.c
postfix/src/smtp/smtp_params.c
postfix/src/smtp/smtp_proto.c
postfix/src/smtp/smtp_sasl_glue.c
postfix/src/smtp/smtp_sasl_proto.c
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_peer.c
postfix/src/smtpd/smtpd_proxy.c
postfix/src/smtpd/smtpd_sasl_glue.c
postfix/src/smtpd/smtpd_sasl_glue.h
postfix/src/smtpd/smtpd_sasl_proto.c
postfix/src/smtpd/smtpd_token.c
postfix/src/smtpstone/qmqp-sink.c
postfix/src/tls/tls_client.c
postfix/src/tls/tls_mgr.c
postfix/src/tls/tls_verify.c
postfix/src/util/dict_pcre.c
postfix/src/util/name_mask.c
postfix/src/util/sane_basename.c
postfix/src/util/stringops.h
postfix/src/util/unescape.c
postfix/src/util/unix_recv_fd.c
postfix/src/util/unix_send_fd.c
postfix/src/util/vbuf_print.c
postfix/src/xsasl/.indent.pro [new symlink]
postfix/src/xsasl/Makefile.in [new file with mode: 0644]
postfix/src/xsasl/README [new file with mode: 0644]
postfix/src/xsasl/xsasl.h [new file with mode: 0644]
postfix/src/xsasl/xsasl_client.c [new file with mode: 0644]
postfix/src/xsasl/xsasl_cyrus.h [new file with mode: 0644]
postfix/src/xsasl/xsasl_cyrus_client.c [new file with mode: 0644]
postfix/src/xsasl/xsasl_cyrus_common.h [new file with mode: 0644]
postfix/src/xsasl/xsasl_cyrus_log.c [new file with mode: 0644]
postfix/src/xsasl/xsasl_cyrus_security.c [new file with mode: 0644]
postfix/src/xsasl/xsasl_cyrus_server.c [new file with mode: 0644]
postfix/src/xsasl/xsasl_server.c [new file with mode: 0644]

index 1dea5debd926b0bbe04eac5ef63f1083bafa92e7..785f167846ecba7c890eb316d1ff12f47908005f 100644 (file)
@@ -44,6 +44,9 @@
 -TCRYPTO_EX_DATA
 -TCTABLE
 -TCTABLE_ENTRY
+-TXSASL_CYRUS_CLIENT
+-TXSASL_CYRUS_ERROR_INFO
+-TXSASL_CYRUS_SERVER
 -TDELIVER_ATTR
 -TDELIVER_REQUEST
 -TDELTA_TIME
 -TX509
 -TX509_NAME
 -TX509_STORE_CTX
+-TXSASL_CLIENT
+-TXSASL_CLIENT_IMPL
+-TXSASL_CLIENT_IMPL_INFO
+-TXSASL_SERVER
+-TXSASL_SERVER_IMPL
+-TXSASL_SERVER_IMPL_INFO
 -Tregex_t
 -Tregmatch_t
 -Tsasl_conn_t
index ebce17863248baafc060d04373a0a80091d9be42..08c78ebbdf5eb38c856671b9d2c277a9f1b128ed 100644 (file)
@@ -11549,7 +11549,7 @@ Apologies for any names omitted.
        logic for address list and fallback relay processing.
        Still need to simplify deferred recipient handling.
 
-20051210
+20051212
 
        Bugfix: after a failed TLS session, the 20051210 SMTP client
        code cleanup broke sessions with backup servers, causing the
@@ -11559,8 +11559,71 @@ Apologies for any names omitted.
        was Ralf Hildebrandt, detectives Victor Duchovni and Wietse.
        File: smtp/smtp_proto.c.
 
+20051213 
+
+       Bugfix: *SQL, proxy and LDAP map types were not defined in
+       user-land commands such as postqueue. Leandro Santi. File:
+       postqueue/postqueue.c.
+
+20051212-14
+
+       Server-side plug-in interface for SASL authentication. This
+       uses Cyrus SASL by default, so nothing has changed except
+       error messages may be more informative.  Files:
+       smtpd/smtpd_sasl_proto.c smtpd/smtpd_sasl_glue.c,
+       xsasl/xsasl_server.[hc], xsasl/cyrus_server.[hc]
+       xsasl/cyrus_strerror.c, xsasl/cyrus_log.c, xsasl/cyrus_security.c.
+
+20051215
+
+       Portability: IRIX 6.5.28 defines sa_len as a macro, so it
+       can't be used as a variable identifier. Zach McDanel. Files:
+       dns/dns_rr_to_sa.c, smtpd/smtpd_peer.c, qmqpd/qmqpd_peer.c.
+
+20051216
+
+       Cleanup: removed some scar tissue that was introduced with
+       server-side SASL plug-in support. Files: smtpd_sasl_proto.c,
+       smtpd_sasl_glue.c.
+
+       Client-side plug-in interface for SASL authentication. This
+       uses Cyrus SASL by default, so nothing has changed except
+       error messages may be more informative.  Files: smtp_sasl_glue.c,
+       xsasl/xsasl_client.[hc], xsasl/cyrus_client.[hc].
+
+20051217
+
+       Bugfix: when a SASL client password is required by a specific
+       server, defer delivery when no server-announced mechanism
+       survives the smtp_sasl_mechanism_filter, instead of ignoring
+       the SASL announcement and trying to deliver the mail over
+       an unauthenticated connection and risking that mail will
+       be rejected.  File: smtp/smtp_sasl_proto.c, smtp/smtp_proto.c.
+
+       Portability: zero the "struct msg" just in case. Both purify
+       (Linux) and valgrind (FreeBSD) complain about uninitialized
+       bits.  Files: util/unix_{send,recv}_fd.c.
+
+20051219
+
+       Cleanup: generic smtpd_sasl_path, smtp_sasl_path and
+       lmtp_sasl_path configuration parameters; simplified the
+       SASL plug-in API, and made initial provisions for SASL
+       session encryption. Files: xsasl/*.[hc].
+
+       Feature: "postconf -a" lists the available SASL server
+       plug-in types, and "postconf -A" does the same for the
+       client.  Files: postconf.c, xsasl_{client,server}.c.
+
+       Feature: new SMTPD policy attributes "encryption_protocol",
+       "encryption_cypher" and "encryption_keysize", to distinguish
+       plaintext from encrypted connections.
+
 Open problems:
 
+       Reject numeric domains only when strict envelope syntax is
+       turned on.
+
        "postsuper -r" no longer resets the message arrival time,
        because pickup(8) no longer overrides queue file time stamp
        information. This can be a problem when mail "on hold" is
index a5a7ecdd4076c79a38de740b6c66ab0a82170b86..9c9c7b38b8b902454bd77dd4e245b3e92240d756 100644 (file)
@@ -1,7 +1,7 @@
 SHELL  = /bin/sh
 WARN    = -Wmissing-prototypes -Wformat
 OPTS   = 'CC=$(CC)'
-DIRS   = src/util src/global src/dns src/tls src/master src/postfix src/smtpstone \
+DIRS   = src/util src/global src/dns src/tls src/xsasl src/master src/postfix src/smtpstone \
        src/sendmail src/error src/pickup src/cleanup src/smtpd src/local \
        src/trivial-rewrite src/qmgr src/oqmgr src/smtp src/bounce \
        src/pipe src/showq src/postalias src/postcat src/postconf src/postdrop \
index 86e0bfee66dc36496530c0180c73ab6cff342003..da0e31b7daf1a58d40cf9ba0c067e8169e5aa3e9 100644 (file)
@@ -6,9 +6,8 @@ W\bWA\bAR\bRN\bNI\bIN\bNG\bG
 
 People who go to the trouble of installing Postfix may have the expectation
 that Postfix is more secure than some other mailers. The Cyrus SASL library is
-a lot of code. With SASL authentication enabled in the Postfix SMTP client and
-SMTP server, Postfix becomes as secure as other mail systems that use the Cyrus
-SASL library.
+a lot of code. With this, Postfix becomes as secure as other mail systems that
+use the Cyrus SASL library.
 
 H\bHo\bow\bw P\bPo\bos\bst\btf\bfi\bix\bx u\bus\bse\bes\bs S\bSA\bAS\bSL\bL a\bau\but\bth\bhe\ben\bnt\bti\bic\bca\bat\bti\bio\bon\bn i\bin\bnf\bfo\bor\brm\bma\bat\bti\bio\bon\bn
 
@@ -21,14 +20,16 @@ method, and sender address to the maillog file, and optionally grants mail
 access via the permit_sasl_authenticated UCE restriction.
 
 When sending mail, Postfix can look up the server hostname or destination
-domain (the address right-hand part) in a table, and if a username/password is
-found, it will use that username and password to authenticate to the server.
+domain (the address right-hand part) in a Postfix SASL password table, and if a
+username/password is found, it will use that username and password to
+authenticate to the server. And as of version 2.3, Postfix can be configured to
+search its SASL password table by the sender email address.
 
 This document covers the following topics:
 
   * What SASL versions are supported
-  * Building the SASL library
-  * Building Postfix with SASL authentication support
+  * Building the Cyrus SASL library
+  * Building Postfix with Cyrus SASL support
   * Enabling SASL authentication in the Postfix SMTP server
   * Testing SASL authentication in the Postfix SMTP server
   * Trouble shooting the SASL internals
@@ -37,27 +38,17 @@ This document covers the following topics:
 
 W\bWh\bha\bat\bt S\bSA\bAS\bSL\bL v\bve\ber\brs\bsi\bio\bon\bns\bs a\bar\bre\be s\bsu\bup\bpp\bpo\bor\brt\bte\bed\bd
 
-Postfix+SASL 1.5.5 was seen working on RedHat 6.1 (pwcheck_method set to shadow
-or sasldb), Solaris 2.7 (pwcheck_method set to shadow or sasldb), and FreeBSD
-3.4 (pwcheck_method set to sasldb). On RedHat 6.1, SASL 1.5.5 insisted on write
-access to /etc/sasldb. Note that this seems to be related to the
-auto_transition switch in SASL. Note also that the Cyrus SASL documentation
-says that it is pointless to enable that if you use "sasldb" for
-"pwcheck_method". Later versions of the SASL 1.5.x series should also work.
+This document describes Postfix with Cyrus SASL version 1 and Cyrus SASL
+version 2. Postfix version 2.3 introduces has a plug-in mechanism for other
+SASL implementations. Support for other implementations is currently not part
+of the Postfix distribution and will be described elsewhere.
 
-Postfix+SASL 2.1.1 appears to work on Mandrake Linux 8.1 (pwcheck_method set to
-saslauthd or auxprop). Note that the 'auxprop' pwcheck_method replaces the
-'sasldb' method from SASL 1.5.x. Postfix may need write access to /etc/sasldb2
-if you use the auto_transition feature, or if you use an authentication
-mechanism such as OTP (one-time passwords) that needs to update secrets in the
-database.
-
-B\bBu\bui\bil\bld\bdi\bin\bng\bg t\bth\bhe\be S\bSA\bAS\bSL\bL l\bli\bib\bbr\bra\bar\bry\by
+B\bBu\bui\bil\bld\bdi\bin\bng\bg t\bth\bhe\be C\bCy\byr\bru\bus\bs S\bSA\bAS\bSL\bL l\bli\bib\bbr\bra\bar\bry\by
 
 Postfix appears to work with cyrus-sasl-1.5.5 or cyrus-sasl-2.1.1, which are
 available from:
 
-    ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/.
+    ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
 
 IMPORTANT: if you install the Cyrus SASL libraries as per the default, you will
 have to symlink /usr/lib/sasl -> /usr/local/lib/sasl for version 1.5.5 or /usr/
@@ -67,7 +58,7 @@ Reportedly, Microsoft Internet Explorer version 5 requires the non-standard
 SASL LOGIN authentication method. To enable this authentication method, specify
 ``./configure --enable-login''.
 
-B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bS\bSA\bAS\bSL\bL a\bau\but\bth\bhe\ben\bnt\bti\bic\bca\bat\bti\bio\bon\bn s\bsu\bup\bpp\bpo\bor\brt\bt
+B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bC\bCy\byr\bru\bus\bs S\bSA\bAS\bSL\bL s\bsu\bup\bpp\bpo\bor\brt\bt
 
 To build Postfix with SASL authentication support, the following assumes that
 the Cyrus SASL include files are in /usr/local/include, and that the Cyrus SASL
@@ -75,32 +66,34 @@ libraries are in /usr/local/lib.
 
 On some systems this generates the necessary Makefile definitions:
 
-(for SASL version 1.5.5):
+(for Cyrus SASL version 1.5.5):
 
     % make tidy # if you have left-over files from a previous build
-    % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
-        AUXLIBS="-L/usr/local/lib -lsasl"
+    % make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+        -I/usr/local/include" AUXLIBS="-L/usr/local/lib -lsasl"
 
-(for SASL version 2.1.1):
+(for Cyrus SASL version 2.1.1):
 
     % make tidy # if you have left-over files from a previous build
-    % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
-        AUXLIBS="-L/usr/local/lib -lsasl2"
+    % make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+        -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib -lsasl2"
 
 On Solaris 2.x you need to specify run-time link information, otherwise ld.so
 will not find the SASL shared library:
 
-(for SASL version 1.5.5):
+(for Cyrus SASL version 1.5.5):
 
     % make tidy # if you have left-over files from a previous build
-    % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
-        AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
+    % make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+        -I/usr/local/include" AUXLIBS="-L/usr/local/lib \
+        -R/usr/local/lib -lsasl"
 
-(for SASL version 2.1.1):
+(for Cyrus SASL version 2.1.1):
 
     % make tidy # if you have left-over files from a previous build
-    % make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
-        AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl2"
+    % make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+        -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib \
+        -R/usr/local/lib -lsasl2"
 
 E\bEn\bna\bab\bbl\bli\bin\bng\bg S\bSA\bAS\bSL\bL a\bau\but\bth\bhe\ben\bnt\bti\bic\bca\bat\bti\bio\bon\bn i\bin\bn t\bth\bhe\be P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bP s\bse\ber\brv\bve\ber\br
 
@@ -123,76 +116,101 @@ and later):
 
 Note: the SASL login names will be shared with the entire world.
 
-In /usr/local/lib/sasl/smtpd.conf (SASL version 1.5.5) or /usr/local/lib/sasl2/
-smtpd.conf (SASL version 2.1.1) you need to specify how the server should
-validate client passwords.
+In /usr/local/lib/sasl/smtpd.conf (Cyrus SASL version 1.5.5) or /usr/local/lib/
+sasl2/smtpd.conf (Cyrus SASL version 2.1.1) you need to specify how the server
+should validate client passwords.
 
 Note: some Postfix distributions are modified and look for the smtpd.conf file
 in /etc/postfix.
 
-Note: some Cyrus SASL distributions are modified and look for the smtpd.conf
-file in /etc/sasl2.
+Note: some Cyrus SASL distributions look for the smtpd.conf file in /etc/sasl2.
 
-In order to authenticate against the UNIX password database, try:
+  * To authenticate against the UNIX password database, try:
 
-(SASL version 1.5.5)
+    (Cyrus SASL version 1.5.5)
 
-    /usr/local/lib/sasl/smtpd.conf:
-        pwcheck_method: pwcheck
+        /usr/local/lib/sasl/smtpd.conf:
+            pwcheck_method: pwcheck
 
-(SASL version 2.1.1)
+    (Cyrus SASL version 2.1.1)
 
-    /usr/local/lib/sasl2/smtpd.conf:
-        pwcheck_method: pwcheck
+        /usr/local/lib/sasl2/smtpd.conf:
+            pwcheck_method: pwcheck
 
-The name of the file in /usr/local/lib/sasl (SASL version 1.5.5) or /usr/local/
-lib/sasl2 (SASL version 2.1.1) used by the SASL library for configuration can
-be set with:
+    The name of the file in /usr/local/lib/sasl (Cyrus SASL version 1.5.5) or /
+    usr/local/lib/sasl2 (Cyrus SASL version 2.1.1) used by the SASL library for
+    configuration can be set with:
 
-    /etc/postfix/main.cf:
-        smtpd_sasl_application_name = smtpd
+        /etc/postfix/main.cf:
+            smtpd_sasl_application_name = smtpd
+
+    The pwcheck daemon is contained in the cyrus-sasl source tarball.
+
+    IMPORTANT: postfix processes need to have group read+execute permission for
+    the /var/pwcheck directory, otherwise authentication attempts will fail.
+
+  * Alternately, in Cyrus SASL 1.5.26 and later (including 2.1.1), try:
+
+    (Cyrus SASL version 1.5.26)
+
+        /usr/local/lib/sasl/smtpd.conf:
+            pwcheck_method: saslauthd
+
+    (Cyrus SASL version 2.1.1)
 
-The pwcheck daemon is contained in the cyrus-sasl source tarball.
+        /usr/local/lib/sasl2/smtpd.conf:
+            pwcheck_method: saslauthd
 
-IMPORTANT: postfix processes need to have group read+execute permission for the
-/var/pwcheck directory, otherwise authentication attempts will fail.
+    The saslauthd daemon is also contained in the cyrus-sasl source tarball. It
+    is more flexible than the pwcheck daemon, in that it can authenticate
+    against PAM and various other sources. To use PAM, start saslauthd with "-
+    a pam".
 
-Alternately, in SASL 1.5.26 and later (including 2.1.1), try:
+  * To authenticate against Cyrus SASL's own password database:
 
-(SASL version 1.5.26)
+    (Cyrus SASL version 1.5.5)
 
-    /usr/local/lib/sasl/smtpd.conf:
-        pwcheck_method: saslauthd
+        /usr/local/lib/sasl/smtpd.conf:
+            pwcheck_method:  sasldb
 
-(SASL version 2.1.1)
+    (Cyrus SASL version 2.1.1)
 
-    /usr/local/lib/sasl2/smtpd.conf:
-        pwcheck_method: saslauthd
+        /usr/local/lib/sasl2/smtpd.conf:
+            pwcheck_method:  auxprop
 
-The saslauthd daemon is also contained in the cyrus-sasl source tarball. It is
-more flexible than the pwcheck daemon, in that it can authenticate against PAM
-and various other sources. To use PAM, start saslauthd with "-a pam".
+    This will use the Cyrus SASL password file (default: /etc/sasldb in version
+    1.5.5, or /etc/sasldb2 in version 2.1.1), which is maintained with the
+    saslpasswd or saslpasswd2 command (part of the Cyrus SASL software). On
+    some poorly-supported systems the saslpasswd command needs to be run
+    multiple times before it stops complaining. The Postfix SMTP server needs
+    read access to the sasldb file - you may have to play games with group
+    access permissions. With the OTP authentication mechanism, the SMTP server
+    also needs WRITE access to /etc/sasldb2 or /etc/sasldb (or the back end SQL
+    database, if used).
 
-In order to authenticate against SASL's own password database:
+    IMPORTANT: To get sasldb running, make sure that you set the SASL domain
+    (realm) to a fully qualified domain name.
 
-(SASL version 1.5.5)
+    EXAMPLE:
 
-    /usr/local/lib/sasl/smtpd.conf:
-        pwcheck_method:  sasldb
+    (Cyrus SASL version 1.5.5)
 
-(SASL version 2.1.1)
+        % saslpasswd -c -u `postconf -h myhostname` exampleuser
 
-    /usr/local/lib/sasl2/smtpd.conf:
-        pwcheck_method:  auxprop
+    (Cyrus SASL version 2.1.1)
 
-This will use the SASL password file (default: /etc/sasldb in version 1.5.5, or
-/etc/sasldb2 in version 2.1.1), which is maintained with the saslpasswd or
-saslpasswd2 command (part of the Cyrus SASL software). On some poorly-supported
-systems the saslpasswd command needs to be run multiple times before it stops
-complaining. The Postfix SMTP server needs read access to the sasldb file - you
-may have to play games with group access permissions. With the OTP
-authentication mechanism, the SMTP server also needs write access to /etc/
-sasldb2 or /etc/sasldb (or the back end SQL database, if used).
+        % saslpasswd2 -c -u `postconf -h myhostname` exampleuser
+
+    You can find out SASL's idea about the realms of the users in sasldb with
+    sasldblistusers (Cyrus SASL version 1.5.5) or sasldblistusers2 (Cyrus SASL
+    version 2.1.1).
+
+    On the Postfix side, you can have only one realm per smtpd instance, and
+    only the users belonging to that realm would be able to authenticate. The
+    Postfix variable smtpd_sasl_local_domain controls the realm used by smtpd:
+
+        /etc/postfix/main.cf:
+            smtpd_sasl_local_domain = $myhostname
 
 IMPORTANT: all users must be able to authenticate using ALL authentication
 mechanisms advertised by Postfix, otherwise the negotiation might end up with
@@ -203,42 +221,27 @@ stand a chance to succeed, yet the SASL library would also advertise other
 mechanisms, such as DIGEST-MD5. This happens because those mechanisms are made
 available by other plugins, and the SASL library have no way to know that your
 only valid authentication source is PAM. Thus you might need to limit the list
-of mechanisms advertised by Postfix. This is only possible with SASL version
-2.1.1 or later:
-
-    /usr/local/lib/sasl2/smtpd.conf:
-        mech_list: plain login
-
-For the same reasons you might want to limit the list of plugins used for
-authentication. With SASL version 1.5.5 your only choice is to delete the
-corresponding libraries from /usr/local/lib/sasl. With SASL version 2.1.1:
-
-    /usr/local/lib/sasl2/smtpd.conf:
-        pwcheck_method:  auxprop
-        auxprop_plugin:  sql
-
-IMPORTANT: To get sasldb running, make sure that you set the SASL domain
-(realm) to a fully qualified domain name.
+of mechanisms advertised by Postfix.
 
-EXAMPLE:
+  * With older Cyrus SASL versions you remove the corresponding library files
+    from the SASL plug-in directory (and again whenever the system is updated).
 
-(SASL version 1.5.5)
+  * With Cyrus SASL version 2.1.1 or later:
 
-    % saslpasswd -c -u `postconf -h myhostname` exampleuser
+        /usr/local/lib/sasl2/smtpd.conf:
+            mech_list: plain login
 
-(SASL version 2.1.1)
-
-    % saslpasswd2 -c -u `postconf -h myhostname` exampleuser
+For the same reasons you might want to limit the list of plugins used for
+authentication.
 
-You can find out SASL's idea about the realms of the users in sasldb with
-sasldblistusers (SASL version 1.5.5) or sasldblistusers2 (SASL version 2.1.1).
+  * With Cyrus SASL version 1.5.5 your only choice is to delete the
+    corresponding library files from the SASL plug-in directory.
 
-On the Postfix side, you can have only one realm per smtpd instance, and only
-the users belonging to that realm would be able to authenticate. The Postfix
-variable smtpd_sasl_local_domain controls the realm used by smtpd:
+  * With SASL version 2.1.1:
 
-    /etc/postfix/main.cf:
-        smtpd_sasl_local_domain = $myhostname
+        /usr/local/lib/sasl2/smtpd.conf:
+            pwcheck_method:  auxprop
+            auxprop_plugin:  sql
 
 To run software chrooted with SASL support is an interesting exercise. It
 probably is not worth the trouble.
@@ -317,6 +320,20 @@ that is specified with the relayhost parameter or with a transport(5) table.
         [mail.myisp.net]            username:password
         [mail.myisp.net]:submission username:password
 
+Postfix version 2.3 supports-per-sender SASL password information. To search
+the Postfix SASL password by sender before it searches by destination, specify:
+
+    /etc/postfix/main.cf:
+        smtp_sender_dependent_authentication = yes
+        smtp_sasl_auth_enable = yes
+        smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+
+    /etc/postfix/sasl_passwd:
+        user@example.com            username:password
+        bar.com                     username
+        [mail.myisp.net]            username:password
+        [mail.myisp.net]:submission username:password
+
 Note: some SMTP servers support PLAIN or LOGIN authentication only. By default,
 the Postfix SMTP client does not use authentication methods that send plaintext
 passwords, and defers delivery with the following error message:
@@ -324,16 +341,22 @@ passwords, and defers delivery with the following error message:
 plaintext authentication specify, for example:
 
     /etc/postfix/main.cf:
-        smtp_sasl_security_options =
+        smtp_sasl_security_options = noanonymous
 
-The SASL client password file is opened before the SMTP server enters the
-optional chroot jail, so you can keep the file in /etc/postfix.
+The Postfix SASL client password file is opened before the SMTP server enters
+the optional chroot jail, so you can keep the file in /etc/postfix.
 
 Note: Some SMTP servers support authentication mechanisms that, although
 available on the client system, may not in practice work or possess the
 appropriate credentials to authenticate to the server. It is possible via the
 smtp_sasl_mechanism_filter parameter to further restrict the list of server
-mechanisms that the smtp(8) client will take into consideration.
+mechanisms that the smtp(8) client will take into consideration:
+
+    /etc/postfix/main.cf:
+        smtp_sasl_mechanism_filter = !gssapi, !external, static:all
+
+In the above example, Postfix will decline to use mechanisms that require
+special infrastructure such as Kerberos.
 
 The Postfix SMTP client is backwards compatible with SMTP servers that use the
 non-standard "AUTH=method..." syntax in response to the EHLO command; there is
@@ -344,9 +367,11 @@ C\bCr\bre\bed\bdi\bit\bts\bs
   * Postfix SASL support was originally implemented by Till Franke of SuSE
     Rhein/Main AG.
   * Wietse trimmed down the code to only the bare necessities.
-  * Support for SASL version 2 was contributed by Jason Hoos.
+  * Support for Cyrus SASL version 2 was contributed by Jason Hoos.
   * Liviu Daia added smtpd_sasl_application_name, split
     reject_sender_login_mismatch into
     reject_authenticated_sender_login_mismatch and
     reject_unauthenticated_sender_login_mismatch, and revised the docs.
+  * Wietse made another iteration through the code to add plug-in support for
+    multiple implementations.
 
index 0a21779cb9d896a86fcd92dc016e327ffac7394c..2bfbef5046edd81dcee0b06d53fafa4c68e8dbc2 100644 (file)
@@ -51,13 +51,18 @@ a delegated SMTPD access policy request:
     client_name=another.domain.tld
     reverse_client_name=another.domain.tld
     instance=123.456.7
+    P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 2\b2.\b.2\b2 a\ban\bnd\bd l\bla\bat\bte\ber\br:\b:
     sasl_method=plain
     sasl_username=you
     sasl_sender=
+    size=12345
     ccert_subject=solaris9.porcupine.org
     ccert_issuer=Wietse Venema
     ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04
-    size=12345
+    P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 2\b2.\b.3\b3 a\ban\bnd\bd l\bla\bat\bte\ber\br:\b:
+    encryption_protocol=TLSv1/SSLv3
+    encryption_cipher=DHE-RSA-AES256-SHA
+    encryption_keysize=256
     [empty line]
 
 Notes:
@@ -93,10 +98,16 @@ Notes:
     sends the END-OF-DATA command.
 
   * The "sasl_*" attributes (Postfix 2.2 and later) specify information about
-    how the client was authenticated via SASL.
+    how the client was authenticated via SASL. These attributes are empty in
+    case of no SASL authentication.
 
   * The "ccert_*" attributes (Postfix 2.2 and later) specify information about
-    how the client was authenticated via TLS.
+    how the client was authenticated via TLS. These attributes are empty in
+    case of no certificate authentication.
+
+  * The "encryption_*" attributes (Postfix 2.3 and later) specify information
+    about how the connection is encrypted. With plaintext connections the
+    protocol and cypher attributes are empty and the keysize is zero.
 
 The following is specific to SMTPD delegated policy requests:
 
index c479bb59423be023ad5df98013b362cf65f82d4e..df9b5f944d2bf7c83903bd668f5bc6f1b7e1ae02 100644 (file)
@@ -17,6 +17,42 @@ Incompatibility with Postfix 2.1 and earlier
 If you upgrade from Postfix 2.1 or earlier, read RELEASE_NOTES-2.2
 before proceeding.
 
+Incompatibility with snapshot 20051220
+======================================
+
+The Postfix-with-Cyrus-SASL build procedure has changed. You now
+need to specify -DUSE_CYRUS_SASL in addition to -DUSE_SASL_AUTH or
+else you end up without any Cyrus SASL support. The error messages
+are:
+
+    unsupported SASL server implementation: cyrus
+    unsupported SASL client implementation: cyrus
+
+Major changes with snapshot 20051220
+====================================
+
+Plug-in support for SASL authentication in the SMTP server and in
+the SMTP+LMTP client. With this, Postfix can support multiple SASL
+implementations without source code patches.  Some distributors may
+even make SASL support a run-time linking option, just like they
+do with Postfix lookup tables.
+
+Hints and tips for plug-in developers are in the xsasl/README file.
+
+For backwards compatibility the default plug-in type is Cyrus SASL,
+so everything should behave like it did before. Some error messages
+are slightly different, but these are generally improvements.
+
+The "postconf -a" command shows what plug-in implementations are
+available for the SMTP server, and "postconf -A" does the same for
+the SMTP+LMTP client.  Plug-in implementations are selected with
+the smtpd_sasl_type, smtp_sasl_type and lmtp_sasl_type configuration
+parameters.
+
+Other new configuration parameters are smtpd_sasl_path, smtp_sasl_path
+and lmtp_sasl_path. These are better left alone; they are introduced
+for the convenience of other SASL implementations.
+
 Incompatibility with snapshot 20051208
 ======================================
 
index 438709dac8154dfdf6370f921eaf9e63ed20ecc1..4a720afc995e2303b7791444181b3a3562f23dd4 100644 (file)
 
 <h2>WARNING</h2>
 
-<p> People who go to the trouble of installing Postfix may have
-the expectation that Postfix is more secure than some other mailers.
-The Cyrus SASL library is a lot of code. With SASL authentication
-enabled in the Postfix SMTP client and SMTP server, Postfix becomes
+<p> People who go to the trouble of installing Postfix may have the
+expectation that Postfix is more secure than some other mailers.
+The Cyrus SASL library is a lot of code. With this, Postfix becomes
 as secure as other mail systems that use the Cyrus SASL library.
 </p>
 
@@ -38,9 +37,11 @@ optionally grants mail access via the <a href="postconf.5.html#permit_sasl_authe
 UCE restriction. </p>
 
 <p> When sending mail, Postfix can look up the server hostname or
-destination domain (the address right-hand part) in a table, and if a
-username/password is found, it will use that username and password
-to authenticate to the server. </p>
+destination domain (the address right-hand part) in a Postfix SASL password
+table, and if a username/password is found, it will use that username
+and password to authenticate to the server.  And as of version 2.3,
+Postfix can be configured to search its SASL password table by the
+sender email address. </p>
 
 <p>This document covers the following topics: </p>
 
@@ -48,9 +49,9 @@ to authenticate to the server. </p>
 
 <li><a href="#versions">What SASL versions are supported</a>
 
-<li><a href="#build_sasl">Building the SASL library</a>
+<li><a href="#build_sasl">Building the Cyrus SASL library</a>
 
-<li><a href="#build_postfix">Building Postfix with SASL authentication
+<li><a href="#build_postfix">Building Postfix with Cyrus SASL
 support</a></li>
 
 <li><a href="#server_sasl">Enabling SASL authentication in the
@@ -70,31 +71,20 @@ Postfix SMTP client</a></li>
 
 <h2><a name="versions">What SASL versions are supported</a></h2>
 
-<p> Postfix+SASL 1.5.5 was seen working on RedHat 6.1 (pwcheck_method
-set to shadow or sasldb), Solaris 2.7 (pwcheck_method set to shadow
-or sasldb), and FreeBSD 3.4 (pwcheck_method set to sasldb).  On
-RedHat 6.1, SASL 1.5.5 insisted on write access to /etc/sasldb.
-Note that this seems to be related to the auto_transition switch
-in SASL. Note also that the Cyrus SASL documentation says that it
-is pointless to enable that if you use "sasldb" for "pwcheck_method".
-Later versions of the SASL 1.5.x series should also work. </p>
-
-<p> Postfix+SASL 2.1.1 appears to work on Mandrake Linux 8.1
-(pwcheck_method set to saslauthd or auxprop).  Note that the
-'auxprop' pwcheck_method replaces the 'sasldb' method from SASL
-1.5.x.  Postfix may need write access to /etc/sasldb2 if you use
-the auto_transition feature, or if you use an authentication
-mechanism such as OTP (one-time passwords) that needs to update
-secrets in the database. </p>
-
-<h2><a name="build_sasl">Building the SASL library</a></h2>
+<p> This document describes Postfix with Cyrus SASL version 1 and
+Cyrus SASL version 2. Postfix version 2.3 introduces has a plug-in
+mechanism for other SASL implementations.  Support for other
+implementations is currently not part of the Postfix distribution
+and will be described elsewhere.  </p>
+
+<h2><a name="build_sasl">Building the Cyrus SASL library</a></h2>
 
 <p> Postfix appears to work with cyrus-sasl-1.5.5 or cyrus-sasl-2.1.1, 
 which are available from: </p>
 
 <blockquote>
 <pre>
-<a href="ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/">ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/</a>.
+<a href="ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/">ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/</a>
 </pre>
 </blockquote>
 
@@ -107,8 +97,7 @@ version 2.1.1. </p>
 non-standard SASL LOGIN authentication method. To enable this
 authentication method, specify ``./configure --enable-login''. </p>
 
-<h2><a name="build_postfix">Building Postfix with SASL authentication
-support</a></h2>
+<h2><a name="build_postfix">Building Postfix with Cyrus SASL support</a></h2>
 
 <p> To build Postfix with SASL authentication support, the following
 assumes that the Cyrus SASL include files are in /usr/local/include,
@@ -119,20 +108,20 @@ and that the Cyrus SASL libraries are in /usr/local/lib. </p>
 
 <dl>
 
-<dt> (for SASL version 1.5.5):
+<dt> (for Cyrus SASL version 1.5.5):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
-    AUXLIBS="-L/usr/local/lib -lsasl"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include" AUXLIBS="-L/usr/local/lib -lsasl"
 </pre>
 
-<dt> (for SASL version 2.1.1):
+<dt> (for Cyrus SASL version 2.1.1):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
-    AUXLIBS="-L/usr/local/lib -lsasl2"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib -lsasl2"
 </pre>
 
 </dl>
@@ -142,20 +131,22 @@ otherwise ld.so will not find the SASL shared library: </p>
 
 <dl>
 
-<dt> (for SASL version 1.5.5):
+<dt> (for Cyrus SASL version 1.5.5):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
-    AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include" AUXLIBS="-L/usr/local/lib \
+    -R/usr/local/lib -lsasl"
 </pre>
 
-<dt> (for SASL version 2.1.1):
+<dt> (for Cyrus SASL version 2.1.1):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
-    AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl2"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib \
+    -R/usr/local/lib -lsasl2"
 </pre>
 
 </dl>
@@ -195,20 +186,22 @@ SMTP server</a></h2>
 <p> Note: the SASL login names will be shared with the entire world.
 </p>
 
-<p> In /usr/local/lib/sasl/smtpd.conf (SASL version 1.5.5) or
-/usr/local/lib/sasl2/smtpd.conf (SASL version 2.1.1) you need to
+<p> In /usr/local/lib/sasl/smtpd.conf (Cyrus SASL version 1.5.5) or
+/usr/local/lib/sasl2/smtpd.conf (Cyrus SASL version 2.1.1) you need to
 specify how the server should validate client passwords. </p>
 
 <p> Note: some Postfix distributions are modified and look for 
 the smtpd.conf file in /etc/postfix. </p>
 
-<p> Note: some Cyrus SASL distributions are modified and look for
-the smtpd.conf file in /etc/sasl2. </p>
+<p> Note: some Cyrus SASL distributions look for the smtpd.conf
+file in /etc/sasl2. </p>
+
+<ul>
 
-<p> In order to authenticate against the UNIX password database, try: </p>
+<li> <p> To authenticate against the UNIX password database, try: </p>
 
 <dl>
-<dt> (SASL version 1.5.5)
+<dt> (Cyrus SASL version 1.5.5)
 <dd>
 <pre>
 /usr/local/lib/sasl/smtpd.conf:
@@ -216,7 +209,7 @@ the smtpd.conf file in /etc/sasl2. </p>
 
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 /usr/local/lib/sasl2/smtpd.conf:
@@ -225,14 +218,15 @@ the smtpd.conf file in /etc/sasl2. </p>
 
 </dl>
 
-<p> The name of the file in /usr/local/lib/sasl (SASL version 1.5.5)
-or /usr/local/lib/sasl2 (SASL version 2.1.1) used by the SASL
+<p> The name of the file in /usr/local/lib/sasl (Cyrus SASL version
+1.5.5) or /usr/local/lib/sasl2 (Cyrus SASL version 2.1.1) used by
+the SASL
 library for configuration can be set with: </p>
 
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    <a href="postconf.5.html#smtpd_sasl_application_name">smtpd_sasl_application_name</a> = smtpd
+    smtpd_sasl_application_name = smtpd
 </pre>
 </blockquote>
 
@@ -242,18 +236,19 @@ library for configuration can be set with: </p>
 permission for the /var/pwcheck directory, otherwise authentication
 attempts will fail. </p>
 
-<p> Alternately, in SASL 1.5.26 and later (including 2.1.1), try: </p>
+<li> <p> Alternately, in Cyrus SASL 1.5.26 and later (including
+2.1.1), try: </p>
 
 <dl>
 
-<dt> (SASL version 1.5.26)
+<dt> (Cyrus SASL version 1.5.26)
 <dd>
 <pre>
 /usr/local/lib/sasl/smtpd.conf:
     pwcheck_method: saslauthd
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 /usr/local/lib/sasl2/smtpd.conf:
@@ -267,17 +262,17 @@ tarball.  It is more flexible than the pwcheck daemon, in that it
 can authenticate against PAM and various other sources. To use PAM,
 start saslauthd with "-a pam". </p>
 
-<p> In order to authenticate against SASL's own password database: </p>
+<li> <p> To authenticate against Cyrus SASL's own password database: </p>
 
 <dl>
-<dt> (SASL version 1.5.5)
+<dt> (Cyrus SASL version 1.5.5)
 <dd>
 <pre>
 /usr/local/lib/sasl/smtpd.conf:
     pwcheck_method:  sasldb
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 /usr/local/lib/sasl2/smtpd.conf:
@@ -286,63 +281,29 @@ start saslauthd with "-a pam". </p>
 
 </dl>
 
-<p> This will use the SASL password file (default: /etc/sasldb in
+<p> This will use the Cyrus SASL password file (default: /etc/sasldb in
 version 1.5.5, or /etc/sasldb2 in version 2.1.1), which is maintained
 with the saslpasswd or saslpasswd2 command (part of the Cyrus SASL
 software). On some poorly-supported systems the saslpasswd command needs
 to be run multiple times before it stops complaining.  The Postfix SMTP
 server needs read access to the sasldb file - you may have to play games
 with group access permissions.  With the OTP authentication mechanism,
-the SMTP server also needs write access to /etc/sasldb2 or /etc/sasldb
+the SMTP server also needs WRITE access to /etc/sasldb2 or /etc/sasldb
 (or the back end SQL database, if used). </p>
 
-<p> IMPORTANT: all users must be able to authenticate using ALL
-authentication mechanisms advertised by Postfix, otherwise the
-negotiation might end up with an unsupported mechanism, and
-authentication would fail.  For example if you configure SASL to
-use <i>saslauthd</i> for authentication against PAM (pluggable
-authentication modules), only the PLAIN and LOGIN mechanisms are
-supported and stand a chance to succeed, yet the SASL library would also
-advertise other mechanisms, such as DIGEST-MD5.  This happens because
-those mechanisms are made available by other plugins, and the SASL
-library have no way to know that your only valid authentication source
-is PAM.  Thus you might need to limit the list of mechanisms advertised
-by Postfix.  This is only possible with SASL version 2.1.1 or later:
-</p>
-
-<blockquote>
-<pre>
-/usr/local/lib/sasl2/smtpd.conf:
-    mech_list: plain login
-</pre>
-</blockquote>
-
-<p> For the same reasons you might want to limit the list of plugins
-used for authentication.  With SASL version 1.5.5 your only choice is to
-delete the corresponding libraries from /usr/local/lib/sasl.  With SASL
-version 2.1.1: </p>
-
-<blockquote>
-<pre>
-/usr/local/lib/sasl2/smtpd.conf:
-    pwcheck_method:  auxprop
-    auxprop_plugin:  sql
-</pre>
-</blockquote>
-
 <p> IMPORTANT: To get sasldb running, make sure that you set the SASL
 domain (realm) to a fully qualified domain name. </p>
 
 <p> EXAMPLE: </p>
 
 <dl>
-<dt> (SASL version 1.5.5)
+<dt> (Cyrus SASL version 1.5.5)
 <dd>
 <pre>
 % saslpasswd -c -u `postconf -h <a href="postconf.5.html#myhostname">myhostname</a>` exampleuser
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 % saslpasswd2 -c -u `postconf -h <a href="postconf.5.html#myhostname">myhostname</a>` exampleuser
@@ -351,8 +312,8 @@ domain (realm) to a fully qualified domain name. </p>
 </dl>
 
 <p> You can find out SASL's idea about the realms of the users
-in sasldb with <i>sasldblistusers</i> (SASL version 1.5.5) or
-<i>sasldblistusers2</i> (SASL version 2.1.1). </p>
+in sasldb with <i>sasldblistusers</i> (Cyrus SASL version 1.5.5) or
+<i>sasldblistusers2</i> (Cyrus SASL version 2.1.1). </p>
 
 <p> On the Postfix side, you can have only one realm per smtpd
 instance, and only the users belonging to that realm would be able to
@@ -366,6 +327,59 @@ realm used by smtpd: </p>
 </pre>
 </blockquote>
 
+</ul>
+
+<p> IMPORTANT: all users must be able to authenticate using ALL
+authentication mechanisms advertised by Postfix, otherwise the
+negotiation might end up with an unsupported mechanism, and
+authentication would fail.  For example if you configure SASL to
+use <i>saslauthd</i> for authentication against PAM (pluggable
+authentication modules), only the PLAIN and LOGIN mechanisms are
+supported and stand a chance to succeed, yet the SASL library would also
+advertise other mechanisms, such as DIGEST-MD5.  This happens because
+those mechanisms are made available by other plugins, and the SASL
+library have no way to know that your only valid authentication source
+is PAM.  Thus you might need to limit the list of mechanisms advertised
+by Postfix. </p>
+
+<ul> 
+
+<li> <p> With older Cyrus SASL versions you remove the corresponding
+library files from the SASL plug-in directory (and again whenever
+the system is updated). </p>
+
+<li> <p> With Cyrus SASL version 2.1.1 or later: </p>
+
+<blockquote>
+<pre>
+/usr/local/lib/sasl2/smtpd.conf:
+    mech_list: plain login
+</pre>
+</blockquote>
+
+</ul>
+
+<p> For the same reasons you might want to limit the list of plugins
+used for authentication. </p>
+
+<ul>
+
+<li> <p> With Cyrus SASL version 1.5.5 your only choice is to
+delete the corresponding library files from the SASL plug-in 
+directory. </p>
+
+<li> <p> With SASL version 2.1.1: </p>
+
+<blockquote>
+<pre>
+/usr/local/lib/sasl2/smtpd.conf:
+    pwcheck_method:  auxprop
+    auxprop_plugin:  sql
+</pre>
+</blockquote>
+
+</ul>
+
 <p> To run software chrooted with SASL support is an interesting
 exercise.  It probably is not worth the trouble. </p>
 
@@ -470,6 +484,25 @@ table. </p>
 </pre>
 </blockquote>
 
+<p> Postfix version 2.3 supports-per-sender SASL password
+information. To search the Postfix SASL password by sender 
+before it searches by destination, specify: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    <a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> = yes
+    <a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> = yes
+    <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> = hash:/etc/postfix/sasl_passwd
+
+/etc/postfix/sasl_passwd:
+    user@example.com            username:password
+    bar.com                     username
+    [mail.myisp.net]            username:password
+    [mail.myisp.net]:submission username:password
+</pre>
+</blockquote>
+
 <p> Note: some SMTP servers support PLAIN or LOGIN authentication only.
 By default, the Postfix SMTP client does not use authentication
 methods that send plaintext passwords, and defers delivery with
@@ -480,11 +513,11 @@ for example: </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    <a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> = 
+    <a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> = noanonymous
 </pre>
 </blockquote>
 
-<p> The SASL client password file is opened before the SMTP server
+<p> The Postfix SASL client password file is opened before the SMTP server
 enters the optional chroot jail, so you can keep the file in
 /etc/postfix. </p>
 
@@ -493,7 +526,17 @@ although available on the client system, may not in practice work or
 possess the appropriate credentials to authenticate to the server. It
 is possible via the <a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> parameter to further
 restrict the list of server mechanisms that the <a href="smtp.8.html">smtp(8)</a> client will take
-into consideration.  </p>
+into consideration:  </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    <a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> = !gssapi, !external, static:all
+</pre>
+</blockquote>
+
+<p> In the above example, Postfix will decline to use mechanisms
+that require special infrastructure such as Kerberos. </p>
 
 <p> The Postfix SMTP client is backwards compatible with SMTP
 servers that use the non-standard "AUTH=method..." syntax in response
@@ -509,13 +552,16 @@ of SuSE Rhein/Main AG.
 
 <li> Wietse trimmed down the code to only the bare necessities.
 
-<li> Support for SASL version 2 was contributed by Jason Hoos.
+<li> Support for Cyrus SASL version 2 was contributed by Jason Hoos.
 
-<li> Liviu Daia added <a href="postconf.5.html#smtpd_sasl_application_name">smtpd_sasl_application_name</a>, split
+<li> Liviu Daia added smtpd_sasl_application_name, split
 <a href="postconf.5.html#reject_sender_login_mismatch">reject_sender_login_mismatch</a> into
 <a href="postconf.5.html#reject_authenticated_sender_login_mismatch">reject_authenticated_sender_login_mismatch</a> and
 <a href="postconf.5.html#reject_unauthenticated_sender_login_mismatch">reject_unauthenticated_sender_login_mismatch</a>, and revised the docs.
 
+<li> Wietse made another iteration through the code to add
+plug-in support for multiple implementations.
+
 </ul>
 
 </body>
index a6e075d3eab3e9f261bd8a0b56cdade86787b19d..d495262b1d7a6480f7b6ed971331f3476022e2b4 100644 (file)
@@ -83,13 +83,18 @@ client_address=1.2.3.4
 client_name=another.domain.tld
 reverse_client_name=another.domain.tld
 instance=123.456.7
+<b>Postfix version 2.2 and later:</b>
 sasl_method=plain
 sasl_username=you
 sasl_sender=
+size=12345
 ccert_subject=solaris9.porcupine.org
 ccert_issuer=Wietse Venema
 ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04
-size=12345
+<b>Postfix version 2.3 and later:</b>
+encryption_protocol=TLSv1/SSLv3
+encryption_cipher=DHE-RSA-AES256-SHA
+encryption_keysize=256
 [empty line]
 </pre>
 </blockquote>
@@ -137,12 +142,19 @@ size=12345
 
     <li> <p> The "sasl_*" attributes (Postfix 2.2 and later) specify
     information about how the client was authenticated via SASL.
+    These attributes are empty in case of no SASL authentication.
     </p>
 
     <li> <p> The "ccert_*" attributes (Postfix 2.2 and later) specify
     information about how the client was authenticated via TLS.
+    These attributes are empty in case of no certificate authentication.
     </p>
 
+    <li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
+    specify information about how the connection is encrypted. With
+    plaintext connections the protocol and cypher attributes are
+    empty and the keysize is zero.  </p>
+
 </ul>
 
 <p> The following is specific to SMTPD delegated policy requests:
index 0d0de949d7126ad846cb4f71224aaf97bfb7ab5f..7e4de63d225370730c9c20fea9c552d1218d0eb0 100644 (file)
@@ -10,7 +10,9 @@ POSTCONF(1)                                                        POSTCONF(1)
        postconf - Postfix configuration utility
 
 <b>SYNOPSIS</b>
-       <b>postconf</b> [<b>-dhmlnv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>parameter ...</i>]
+       <b>postconf</b> [<b>-dhnv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>parameter ...</i>]
+
+       <b>postconf</b> [<b>-aAmlv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>]
 
        <b>postconf</b> [<b>-ev</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>parameter=value ...</i>]
 
@@ -24,74 +26,89 @@ POSTCONF(1)                                                        POSTCONF(1)
 
        Options:
 
+       <b>-a</b>     List the available SASL server plug-in types.   The
+              SASL    plug-in   type   is   selected   with   the
+              <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b> configuration parameter.
+
+              This feature is  available  with  Postfix  2.3  and
+              later.
+
+       <b>-A</b>     List  the available SASL client plug-in types.  The
+              SASL   plug-in   type   is   selected   with    the
+              <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>   or   <b><a href="postconf.5.html#lmtp_sasl_type">lmtp_sasl_type</a></b>  configuration
+              parameters.
+
+              This feature is  available  with  Postfix  2.3  and
+              later.
+
        <b>-b</b> [<i>template</i><b>_</b><i>file</i>]
               Display the message text that appears at the begin-
-              ning  of  delivery  status  notification (DSN) mes-
-              sages, with $<b>name</b> expressions  replaced  by  actual
-              values.   To  override  the  built-in message text,
-              specify a template file at the end of  the  command
-              line,  or  specify  a template file in main.cf with
-              the  <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b>  parameter.    To   force
-              selection  of  the built-in message text templates,
-              specify an empty template file name (in shell  lan-
+              ning of delivery  status  notification  (DSN)  mes-
+              sages,  with  $<b>name</b>  expressions replaced by actual
+              values.  To override  the  built-in  message  text,
+              specify  a  template file at the end of the command
+              line, or specify a template file  in  main.cf  with
+              the   <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b>   parameter.   To  force
+              selection of the built-in message  text  templates,
+              specify  an empty template file name (in shell lan-
               guage: "").
 
-              This  feature  is  available  with  Postfix 2.3 and
+              This feature is  available  with  Postfix  2.3  and
               later.
 
        <b>-c</b> <i>config</i><b>_</b><i>dir</i>
-              The <b>main.cf</b> configuration  file  is  in  the  named
+              The  <b>main.cf</b>  configuration  file  is  in the named
               directory  instead  of  the  default  configuration
               directory.
 
-       <b>-d</b>     Print default parameter settings instead of  actual
+       <b>-d</b>     Print  default parameter settings instead of actual
               settings.
 
-       <b>-e</b>     Edit  the  <b>main.cf</b>  configuration file. The file is
+       <b>-e</b>     Edit the <b>main.cf</b> configuration file.  The  file  is
               copied to a temporary file then renamed into place.
-              Parameters  and values are specified on the command
-              line.  Use  quotes  in  order  to   protect   shell
+              Parameters and values are specified on the  command
+              line.   Use   quotes  in  order  to  protect  shell
               metacharacters and whitespace.
 
-       <b>-h</b>     Show  parameter  values  only,  not the ``name = ''
+       <b>-h</b>     Show parameter values only, not  the  ``name  =  ''
               label that normally precedes the value.
 
-       <b>-l</b>     List the names of  all  supported  mailbox  locking
+       <b>-l</b>     List  the  names  of  all supported mailbox locking
               methods.  Postfix supports the following methods:
 
-              <b>flock</b>  A  kernel-based  advisory locking method for
-                     local files only.  This  locking  method  is
-                     available  on  systems with a BSD compatible
+              <b>flock</b>  A kernel-based advisory locking  method  for
+                     local  files  only.   This locking method is
+                     available on systems with a  BSD  compatible
                      library.
 
-              <b>fcntl</b>  A kernel-based advisory locking  method  for
+              <b>fcntl</b>  A  kernel-based  advisory locking method for
                      local and remote files.
 
               <b>dotlock</b>
-                     An   application-level  locking  method.  An
-                     application locks a file named  <i>filename</i>  by
-                     creating  a  file  named <i>filename</i><b>.lock</b>.  The
-                     application is expected to  remove  its  own
-                     lock  file, as well as stale lock files that
+                     An  application-level  locking  method.   An
+                     application  locks  a file named <i>filename</i> by
+                     creating a file  named  <i>filename</i><b>.lock</b>.   The
+                     application  is  expected  to remove its own
+                     lock file, as well as stale lock files  that
                      were left behind after abnormal termination.
 
        <b>-m</b>     List the names of all supported lookup table types.
-              In Postfix configuration files, lookup  tables  are
-              specified  as  <i>type</i><b>:</b><i>name</i>,  where <i>type</i> is one of the
-              types listed below. The table <i>name</i>  syntax  depends
-              on  the lookup table type as described in the <a href="DATABASE_README.html">DATA</a>-
+              In  Postfix  configuration files, lookup tables are
+              specified as <i>type</i><b>:</b><i>name</i>, where <i>type</i> is  one  of  the
+              types  listed  below. The table <i>name</i> syntax depends
+              on the lookup table type as described in the  <a href="DATABASE_README.html">DATA</a>-
               <a href="DATABASE_README.html">BASE_README</a> document.
 
-              <b>btree</b>  A sorted, balanced tree structure.  This  is
+              <b>btree</b>  A  sorted, balanced tree structure.  This is
                      available on systems with support for Berke-
                      ley DB databases.
 
-              <b>cdb</b>    A read-optimized structure with  no  support
-                     for  incremental updates.  This is available
+              <b>cdb</b>    A  read-optimized  structure with no support
+                     for incremental updates.  This is  available
                      on systems with support for CDB databases.
 
-              <b>cidr</b>   A table that associates values  with  Class-
-                     less  Inter-Domain  Routing (CIDR) patterns.
+              <b>cidr</b>   A  table  that associates values with Class-
+                     less Inter-Domain Routing  (CIDR)  patterns.
                      This is described in <a href="cidr_table.5.html"><b>cidr_table</b>(5)</a>.
 
               <b>dbm</b>    An indexed file type based on hashing.  This
@@ -100,75 +117,75 @@ POSTCONF(1)                                                        POSTCONF(1)
 
               <b>environ</b>
                      The  UNIX  process  environment  array.  The
-                     lookup  key is the variable name. Originally
-                     implemented for testing,  someone  may  find
+                     lookup key is the variable name.  Originally
+                     implemented  for  testing,  someone may find
                      this useful someday.
 
               <b>hash</b>   An indexed file type based on hashing.  This
-                     is available on  systems  with  support  for
+                     is  available  on  systems  with support for
                      Berkeley DB databases.
 
               <b>ldap</b> (read-only)
-                     Perform  lookups  using  the  LDAP protocol.
+                     Perform lookups  using  the  LDAP  protocol.
                      This is described in <a href="ldap_table.5.html"><b>ldap_table</b>(5)</a>.
 
               <b>mysql</b> (read-only)
-                     Perform lookups using  the  MYSQL  protocol.
+                     Perform  lookups  using  the MYSQL protocol.
                      This is described in <a href="mysql_table.5.html"><b>mysql_table</b>(5)</a>.
 
               <b>pcre</b> (read-only)
                      A lookup table based on Perl Compatible Reg-
-                     ular  Expressions.  The   file   format   is
+                     ular   Expressions.   The   file  format  is
                      described in <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
 
               <b>pgsql</b> (read-only)
-                     Perform  lookups using the PostgreSQL proto-
+                     Perform lookups using the PostgreSQL  proto-
                      col. This is described in <a href="pgsql_table.5.html"><b>pgsql_table</b>(5)</a>.
 
               <b>proxy</b> (read-only)
-                     A lookup table that is implemented  via  the
-                     Postfix  <a href="proxymap.8.html"><b>proxymap</b>(8)</a> service. The table name
+                     A  lookup  table that is implemented via the
+                     Postfix <a href="proxymap.8.html"><b>proxymap</b>(8)</a> service. The table  name
                      syntax is <i>type</i><b>:</b><i>name</i>.
 
               <b>regexp</b> (read-only)
                      A lookup table based on regular expressions.
-                     The  file  format is described in <a href="regexp_table.5.html"><b>regexp_ta-</b></a>
+                     The file format is described  in  <a href="regexp_table.5.html"><b>regexp_ta-</b></a>
                      <a href="regexp_table.5.html"><b>ble</b>(5)</a>.
 
               <b>sdbm</b>   An indexed file type based on hashing.  This
-                     is  available  on  systems  with support for
+                     is available on  systems  with  support  for
                      SDBM databases.
 
               <b>static</b> (read-only)
-                     A table that  always  returns  its  name  as
-                     lookup  result.  For  example, <b>static:foobar</b>
-                     always returns the string <b>foobar</b>  as  lookup
+                     A  table  that  always  returns  its name as
+                     lookup result.  For  example,  <b>static:foobar</b>
+                     always  returns  the string <b>foobar</b> as lookup
                      result.
 
               <b>tcp</b> (read-only)
                      Perform lookups using a simple request-reply
-                     protocol that is described in  <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
-                     This  feature  is  not included with Postfix
+                     protocol  that is described in <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
+                     This feature is not  included  with  Postfix
                      2.2.
 
               <b>unix</b> (read-only)
-                     A limited way to query the UNIX  authentica-
+                     A  limited way to query the UNIX authentica-
                      tion  database.  The  following  tables  are
                      implemented:
 
                      <b>unix:passwd.byname</b>
-                            The table is the UNIX password  data-
-                            base.  The  key is a login name.  The
-                            result is a password  file  entry  in
+                            The  table is the UNIX password data-
+                            base. The key is a login  name.   The
+                            result  is  a  password file entry in
                             <b>passwd</b>(5) format.
 
                      <b>unix:group.byname</b>
                             The table is the UNIX group database.
-                            The key is a group name.  The  result
-                            is  a  group  file  entry in <b>group</b>(5)
+                            The  key is a group name.  The result
+                            is a group  file  entry  in  <b>group</b>(5)
                             format.
 
-              Other table types may exist depending on how  Post-
+              Other  table types may exist depending on how Post-
               fix was built.
 
        <b>-n</b>     Print parameter settings that are not left at their
@@ -177,18 +194,18 @@ POSTCONF(1)                                                        POSTCONF(1)
 
        <b>-t</b> [<i>template</i><b>_</b><i>file</i>]
               Display the templates for delivery status notifica-
-              tion (DSN) messages. To override the built-in  tem-
-              plates,  specify  a template file at the end of the
+              tion  (DSN) messages. To override the built-in tem-
+              plates, specify a template file at the end  of  the
               command line, or specify a template file in main.cf
-              with  the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.  To force
-              selection of the  built-in  templates,  specify  an
+              with the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.  To  force
+              selection  of  the  built-in  templates, specify an
               empty template file name (in shell language: "").
 
-              This  feature  is  available  with  Postfix 2.3 and
+              This feature is  available  with  Postfix  2.3  and
               later.
 
        <b>-v</b>     Enable verbose logging for debugging purposes. Mul-
-              tiple  <b>-v</b>  options  make  the software increasingly
+              tiple <b>-v</b> options  make  the  software  increasingly
               verbose.
 
 <b>DIAGNOSTICS</b>
@@ -199,18 +216,18 @@ POSTCONF(1)                                                        POSTCONF(1)
               Directory with Postfix configuration files.
 
 <b>CONFIGURATION PARAMETERS</b>
-       The following <b>main.cf</b> parameters are  especially  relevant
+       The  following  <b>main.cf</b> parameters are especially relevant
        to this program.
 
-       The  text  below  provides  only  a parameter summary. See
+       The text below provides  only  a  parameter  summary.  See
        <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The default location of  the  Postfix  main.cf  and
+              The  default  location  of  the Postfix main.cf and
               master.cf configuration files.
 
        <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a> (empty)</b>
-              Pathname  of  a configuration file with bounce mes-
+              Pathname of a configuration file with  bounce  mes-
               sage templates.
 
 <b>FILES</b>
@@ -224,7 +241,7 @@ POSTCONF(1)                                                        POSTCONF(1)
        <a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
 
 <b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
+       The Secure Mailer license must be  distributed  with  this
        software.
 
 <b>AUTHOR(S)</b>
index 6f314d737e8e880e0339011831323c52a5aad102..03a5ec6c3eac2d5be061f72a949f4eccd82d05f8 100644 (file)
@@ -2319,7 +2319,7 @@ This feature was removed in Postfix version 2.1.
 <p>
 Optional list of relay hosts for SMTP destinations that can't be
 found or that are unreachable. With Postfix 2.3 this parameter
-is renamed to smtp_fallback_relay. </p>
+is renamed to <a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a>. </p>
 
 <p>
 By default, mail is returned to the sender when a destination is
@@ -3222,7 +3222,7 @@ concurrency per recipient.  </p>
 <p> Lookup tables, indexed by the remote LMTP server address, with
 case insensitive lists of LHLO keywords (pipelining, starttls,
 auth, etc.) that the LMTP client will ignore in the LHLO response
-from a remote LMTP server. See lmtp_discard_lhlo_keywords for
+from a remote LMTP server. See <a href="postconf.5.html#lmtp_discard_lhlo_keywords">lmtp_discard_lhlo_keywords</a> for
 details. </p>
 
 <p> This feature is available in Postfix 2.3 and later. </p>
@@ -3246,7 +3246,7 @@ from a remote LMTP server. </p>
 <li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent
 this action from being logged. </p>
 
-<li> <p> Use the lmtp_discard_lhlo_keyword_address_maps feature to
+<li> <p> Use the <a href="postconf.5.html#lmtp_discard_lhlo_keyword_address_maps">lmtp_discard_lhlo_keyword_address_maps</a> feature to
 discard LHLO keywords selectively. </p>
 
 </ul>
@@ -3307,7 +3307,7 @@ client, for example:
 
 <pre>
   /etc/postfix/master.cf:
-        mylmtp ... lmtp -o lmtp_lhlo_name=foo.bar.com
+        mylmtp ... lmtp -o <a href="postconf.5.html#lmtp_lhloname">lmtp_lhlo_name</a>=foo.bar.com
 </pre>
 
 <p>
@@ -3502,16 +3502,30 @@ to the remote host.
 </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_sasl_path">lmtp_sasl_path</a>
+(default: empty)</b></DT><DD>
+
+<p> Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+<b><a href="postconf.5.html#lmtp_sasl_type">lmtp_sasl_type</a></b>.  Typically this specifies the name of a
+configuration file or rendez-vous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_sasl_security_options">lmtp_sasl_security_options</a>
 (default: noplaintext, noanonymous)</b></DT><DD>
 
-<p>
-What authentication mechanisms the Postfix LMTP client is allowed
-to use. The list of available authentication mechanisms is system
-dependent.
-</p>
+<p> SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with <b><a href="postconf.5.html#lmtp_sasl_type">lmtp_sasl_type</a></b>.  </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+client SASL implementation: </p>
 
 <dl>
 
@@ -3555,6 +3569,18 @@ configuration parameter.  See there for details. </p>
 <p> This feature is available in Postfix 2.3 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_sasl_type">lmtp_sasl_type</a>
+(default: cyrus)</b></DT><DD>
+
+<p> The SASL plug-in type that the Postfix LMTP client should use
+for authentication.  The available types are listed with the
+"<b>postconf -A</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_send_xforward_command">lmtp_send_xforward_command</a>
@@ -5089,6 +5115,19 @@ This feature is available in Postfix 2.0 and later.
 </p>
 
 
+</DD>
+
+<DT><b><a name="plaintext_session_reject_code">plaintext_session_reject_code</a>
+(default: 450)</b></DT><DD>
+
+<p>
+The numerical Postfix SMTP server response code when a request
+is rejected by the <b><a href="postconf.5.html#reject_plaintext_session">reject_plaintext_session</a></b> restriction.
+</p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="prepend_delivered_header">prepend_delivered_header</a>
@@ -6662,7 +6701,7 @@ host, host:port, [host]:port, [address] or [address]:port; the form
 destinations, Postfix will try them in the specified order.  </p>
 
 <p> To prevent mailer loops between MX hosts and fall-back hosts,
-Postfix version 2.3 and later will not use the smtp_fallback_relay
+Postfix version 2.3 and later will not use the <a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a>
 feature for destinations that it is MX host for. </p>
 
 
@@ -7036,16 +7075,30 @@ chroot jail, so you can leave the password file in /etc/postfix.
 </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_sasl_path">smtp_sasl_path</a>
+(default: empty)</b></DT><DD>
+
+<p> Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+<b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.  Typically this specifies the name of a
+configuration file or rendez-vous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_sasl_security_options">smtp_sasl_security_options</a>
 (default: noplaintext, noanonymous)</b></DT><DD>
 
-<p>
-What authentication mechanisms the Postfix SMTP client is allowed
-to use. The list of available authentication mechanisms is system
-dependent.
-</p>
+<p> SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.  </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+client SASL implementation: </p>
 
 <p>
 Specify zero or more of the following:
@@ -7095,6 +7148,18 @@ Example:
 client uses for TLS encrypted SMTP sessions. </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_sasl_type">smtp_sasl_type</a>
+(default: cyrus)</b></DT><DD>
+
+<p> The SASL plug-in type that the Postfix SMTP client should use
+for authentication.  The available types are listed with the
+"<b>postconf -A</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_send_xforward_command">smtp_send_xforward_command</a>
@@ -8016,6 +8081,16 @@ The <a href="postconf.5.html#multi_recipient_bounce_reject_code">multi_recipient
 response code for rejected requests (default:  550).  This feature
 is available in Postfix 2.1 and later. </dd>
 
+<dt><b><a name="reject_plaintext_session">reject_plaintext_session</a></b></dt>
+
+<dd>Reject the request when the connection is not encrypted. This
+restriction should not be used before the client has had a chance
+to negotiate encryption with the AUTH or STARTTLS commands.
+<br>
+The <a href="postconf.5.html#plaintext_session_reject_code">plaintext_session_reject_code</a> parameter specifies the response
+code for rejected requests (default:  450).  This feature is available
+in Postfix 2.3 and later. </dd>
+
 <dt><b><a name="reject_unauth_pipelining">reject_unauth_pipelining</a></b></dt>
 
 <dd>Reject the request when the client sends SMTP commands ahead
@@ -9086,11 +9161,31 @@ Examples:
 </pre>
 
 
+</DD>
+
+<DT><b><a name="smtpd_sasl_path">smtpd_sasl_path</a>
+(default: smtpd)</b></DT><DD>
+
+<p> Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+<b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b>.  Typically this specifies the name of a
+configuration file or rendez-vous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtpd_sasl_security_options">smtpd_sasl_security_options</a>
 (default: noanonymous)</b></DT><DD>
 
+<p> SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL server implementation that is selected
+with <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b>.  </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+server SASL implementation: </p>
+
 <p>
 Restrict what authentication mechanisms the Postfix SMTP server
 will offer to the client.  The list of available authentication
@@ -9158,6 +9253,18 @@ Example:
 server uses for TLS encrypted SMTP sessions. </p>
 
 
+</DD>
+
+<DT><b><a name="smtpd_sasl_type">smtpd_sasl_type</a>
+(default: cyrus)</b></DT><DD>
+
+<p> The SASL plug-in type that the Postfix SMTP server should use
+for authentication. The available types are listed with the
+"<b>postconf -a</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="smtpd_sender_login_maps">smtpd_sender_login_maps</a>
index 78f1ca8b360ca7d263c5cbd679065c6d4a9f7d58..41d9075d9e186cf047b7afa98cde9d7182a357a8 100644 (file)
@@ -48,19 +48,25 @@ SMTP(8)                                                                SMTP(8)
 <b>SMTP DESTINATION SYNTAX</b>
        SMTP destinations have the following form:
 
-       <i>domainname</i>, <i>domainname</i>:<i>port</i>
+       <i>domainname</i>
+
+       <i>domainname</i>:<i>port</i>
               Look up  the  mail  exchangers  for  the  specified
-              domain.
+              domain, and connect to the specified port (default:
+              <b>smtp</b>).
 
-       [<i>hostname</i>], [<i>hostname</i>]:<i>port</i>
-              Look up the address of the specified host.
+       [<i>hostname</i>]
 
-       [<i>address</i>], [<i>address</i>]:<i>port</i>
-              Connect  to  the  host at the specified address. An
-              IPv6 address must be formatted as [<b>ipv6</b>:<i>address</i>].
+       [<i>hostname</i>]:<i>port</i>
+              Look up the address(es) of the specified host,  and
+              connect to the specified port (default: <b>smtp</b>).
 
-       In all the above cases, when no port is specified, look up
-       the port defined as <b>smtp</b> in <b>services</b>(4).
+       [<i>address</i>]
+
+       [<i>address</i>]:<i>port</i>
+              Connect  to  the host at the specified address, and
+              connect to the specified port (default:  <b>smtp</b>).  An
+              IPv6 address must be formatted as [<b>ipv6</b>:<i>address</i>].
 
 <b>LMTP DESTINATION SYNTAX</b>
        LMTP destinations have the following form:
@@ -71,19 +77,24 @@ SMTP(8)                                                                SMTP(8)
               runs  chrooted, an absolute pathname is interpreted
               relative to the Postfix queue directory.
 
-       <b>inet</b>:<i>hostname</i>, <b>inet:</b><i>hostname</i>:<i>port</i>
+       <b>inet</b>:<i>hostname</i>
 
-       <b>inet</b>:[<i>address</i>], <b>inet</b>:[<i>address</i>]:<i>port</i>
+       <b>inet:</b><i>hostname</i>:<i>port</i>
+
+       <b>inet</b>:[<i>address</i>]
+
+       <b>inet</b>:[<i>address</i>]:<i>port</i>
               Connect to the specified TCP port on the  specified
               local or remote host. If no port is specified, con-
               nect to the port defined as  <b>lmtp</b>  in  <b>services</b>(4).
               If no such service is found, the <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a></b> con-
               figuration parameter (default value of 24) will  be
-              used.
+              used.    An  IPv6  address  must  be  formatted  as
+              [<b>ipv6</b>:<i>address</i>].
 
 <b>SECURITY</b>
-       The  SMTP+LMTP client is moderately security-sensitive. It
-       talks to SMTP or LMTP servers and to DNS  servers  on  the
+       The SMTP+LMTP client is moderately security-sensitive.  It
+       talks  to  SMTP  or LMTP servers and to DNS servers on the
        network. The SMTP+LMTP client can be run chrooted at fixed
        low privilege.
 
@@ -104,35 +115,41 @@ SMTP(8)                                                                SMTP(8)
        <a href="http://www.faqs.org/rfcs/rfc3463.html">RFC 3463</a> (Enhanced Status Codes)
 
 <b>DIAGNOSTICS</b>
-       Problems and transactions are logged to <b>syslogd</b>(8).   Cor-
-       rupted  message files are marked so that the queue manager
+       Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
+       rupted message files are marked so that the queue  manager
        can move them to the <b>corrupt</b> queue for further inspection.
 
-       Depending  on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b> parameter,
-       the postmaster is notified of bounces, protocol  problems,
+       Depending on the setting of the <b><a href="postconf.5.html#notify_classes">notify_classes</a></b>  parameter,
+       the  postmaster is notified of bounces, protocol problems,
        and of other trouble.
 
 <b>BUGS</b>
-       SMTP  and  LMTP connection caching does not work with TLS.
-       The necessary support for TLS object passivation  and  re-
-       activation  does  not  exist  without closing the session,
+       SMTP and LMTP connection caching does not work  with  TLS.
+       The  necessary  support for TLS object passivation and re-
+       activation does not exist  without  closing  the  session,
        which defeats the purpose.
 
        SMTP and LMTP connection caching assumes that SASL creden-
-       tials  are  valid  for  all destinations that map onto the
+       tials are valid for all destinations  that  map  onto  the
        same IP address and TCP port.
 
 <b>CONFIGURATION PARAMETERS</b>
-       Most smtp_<i>xxx</i> configuration parameters  have  an  lmtp_<i>xxx</i>
-       "ghost"  parameter  for  the equivalent LMTP feature. This
+       Before  Postfix version 2.3, the LMTP client is a separate
+       program that implements only a subset of the functionality
+       available with SMTP: there is no support for TLS, and con-
+       nections are cached in-process, making it ineffective when
+       the client is used for multiple domains.
+
+       Most  smtp_<i>xxx</i>  configuration  parameters have an lmtp_<i>xxx</i>
+       "ghost" parameter for the equivalent  LMTP  feature.  This
        document describes only those LMTP-related parameters that
        aren't simply "ghost" parameters.
 
        Changes to <b>main.cf</b> are picked up automatically, as <a href="smtp.8.html"><b>smtp</b>(8)</a>
-       processes run for only a limited amount of time.  Use  the
+       processes  run  for only a limited amount of time. Use the
        command "<b>postfix reload</b>" to speed up a change.
 
-       The  text  below  provides  only  a parameter summary. See
+       The text below provides  only  a  parameter  summary.  See
        <a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
 
 <b>COMPATIBILITY CONTROLS</b>
@@ -146,7 +163,7 @@ SMTP(8)                                                                SMTP(8)
               Never send EHLO at the start of an SMTP session.
 
        <b><a href="postconf.5.html#smtp_defer_if_no_mx_address_found">smtp_defer_if_no_mx_address_found</a> (no)</b>
-              Defer mail delivery when no MX record  resolves  to
+              Defer  mail  delivery when no MX record resolves to
               an IP address.
 
        <b><a href="postconf.5.html#smtp_line_length_limit">smtp_line_length_limit</a> (990)</b>
@@ -154,17 +171,17 @@ SMTP(8)                                                                SMTP(8)
               that Postfix will send via SMTP.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_delay_time">smtp_pix_workaround_delay_time</a> (10s)</b>
-              How long the  Postfix  SMTP  client  pauses  before
+              How  long  the  Postfix  SMTP  client pauses before
               sending ".&lt;CR&gt;&lt;LF&gt;" in order to work around the PIX
               firewall "&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;" bug.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_threshold_time">smtp_pix_workaround_threshold_time</a> (500s)</b>
-              How long a message must be queued  before  the  PIX
-              firewall   "&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;"  bug  workaround  is
+              How  long  a  message must be queued before the PIX
+              firewall  "&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;"  bug  workaround   is
               turned on.
 
        <b><a href="postconf.5.html#smtp_quote_rfc821_envelope">smtp_quote_rfc821_envelope</a> (yes)</b>
-              Quote addresses in SMTP MAIL FROM and RCPT TO  com-
+              Quote  addresses in SMTP MAIL FROM and RCPT TO com-
               mands as required by <a href="http://www.faqs.org/rfcs/rfc821.html">RFC 821</a>.
 
        <b><a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a> (yes)</b>
@@ -172,7 +189,7 @@ SMTP(8)                                                                SMTP(8)
               (go away, do not try again later).
 
        <b><a href="postconf.5.html#smtp_skip_quit_response">smtp_skip_quit_response</a> (yes)</b>
-              Do not wait for the response to the SMTP QUIT  com-
+              Do  not wait for the response to the SMTP QUIT com-
               mand.
 
        Available in Postfix version 2.0 and earlier:
@@ -184,36 +201,36 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_discard_ehlo_keyword_address_maps">smtp_discard_ehlo_keyword_address_maps</a> (empty)</b>
-              Lookup tables, indexed by the  remote  SMTP  server
-              address,  with  case insensitive lists of EHLO key-
-              words (pipelining, starttls, auth, etc.)  that  the
+              Lookup  tables,  indexed  by the remote SMTP server
+              address, with case insensitive lists of  EHLO  key-
+              words  (pipelining,  starttls, auth, etc.) that the
               SMTP client will ignore in the EHLO response from a
               remote SMTP server.
 
        <b><a href="postconf.5.html#smtp_discard_ehlo_keywords">smtp_discard_ehlo_keywords</a> (empty)</b>
-              A case insensitive list of EHLO keywords  (pipelin-
-              ing,  starttls,  auth,  etc.)  that the SMTP client
+              A  case insensitive list of EHLO keywords (pipelin-
+              ing, starttls, auth, etc.)  that  the  SMTP  client
               will ignore in the EHLO response from a remote SMTP
               server.
 
        <b><a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> (empty)</b>
               Optional lookup tables that perform address rewrit-
-              ing in the SMTP client, typically  to  transform  a
+              ing  in  the  SMTP client, typically to transform a
               locally valid address into a globally valid address
               when sending mail across the Internet.
 
        Available in Postfix version 2.3 and later:
 
-       <b>lmtp_discard_lhlo_keyword_address_maps (empty)</b>
-              Lookup tables, indexed by the  remote  LMTP  server
-              address,  with  case insensitive lists of LHLO key-
-              words (pipelining, starttls, auth, etc.)  that  the
+       <b><a href="postconf.5.html#lmtp_discard_lhlo_keyword_address_maps">lmtp_discard_lhlo_keyword_address_maps</a> (empty)</b>
+              Lookup  tables,  indexed  by the remote LMTP server
+              address, with case insensitive lists of  LHLO  key-
+              words  (pipelining,  starttls, auth, etc.) that the
               LMTP client will ignore in the LHLO response from a
               remote LMTP server.
 
-       <b>lmtp_discard_lhlo_keywords ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              A case insensitive list of LHLO keywords  (pipelin-
-              ing,  starttls,  auth,  etc.)  that the LMTP client
+       <b><a href="postconf.5.html#lmtp_discard_lhlo_keywords">lmtp_discard_lhlo_keywords</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
+              A  case insensitive list of LHLO keywords (pipelin-
+              ing, starttls, auth, etc.)  that  the  LMTP  client
               will ignore in the LHLO response from a remote LMTP
               server.
 
@@ -221,7 +238,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.0 and later:
 
        <b><a href="postconf.5.html#disable_mime_output_conversion">disable_mime_output_conversion</a> (no)</b>
-              Disable  the  conversion of 8BITMIME format to 7BIT
+              Disable the conversion of 8BITMIME format  to  7BIT
               format.
 
        <b><a href="postconf.5.html#mime_boundary_length_limit">mime_boundary_length_limit</a> (2048)</b>
@@ -236,41 +253,52 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_send_xforward_command">smtp_send_xforward_command</a> (no)</b>
-              Send the non-standard  XFORWARD  command  when  the
-              Postfix  SMTP  server EHLO response announces XFOR-
+              Send  the  non-standard  XFORWARD  command when the
+              Postfix SMTP server EHLO response  announces  XFOR-
               WARD support.
 
 <b>SASL AUTHENTICATION CONTROLS</b>
        <b><a href="postconf.5.html#smtp_sasl_auth_enable">smtp_sasl_auth_enable</a> (no)</b>
-              Enable SASL  authentication  in  the  Postfix  SMTP
+              Enable  SASL  authentication  in  the  Postfix SMTP
               client.
 
        <b><a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> (empty)</b>
-              Optional  SMTP  client lookup tables with one user-
-              name:password entry per remote hostname or  domain,
+              Optional SMTP client lookup tables with  one  user-
+              name:password  entry per remote hostname or domain,
               or sender address when sender-dependent authentica-
               tion is enabled.
 
        <b><a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
-              What authentication  mechanisms  the  Postfix  SMTP
-              client is allowed to use.
+              SASL  security  options; as of Postfix 2.3 the list
+              of available features depends on  the  SASL  client
+              implementation     that     is     selected    with
+              <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> (empty)</b>
-              If  non-empty, a Postfix SMTP client filter for the
-              remote SMTP server's list of  offered  SASL  mecha-
+              If non-empty, a Postfix SMTP client filter for  the
+              remote  SMTP  server's  list of offered SASL mecha-
               nisms.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> (no)</b>
-              Enable  sender-dependent authentication in the SMTP
-              client; this is available only with SASL  authenti-
-              cation,  and  disables  SMTP  connection caching to
-              ensure that mail from different  senders  will  use
+              Enable sender-dependent authentication in the  SMTP
+              client;  this is available only with SASL authenti-
+              cation, and disables  SMTP  connection  caching  to
+              ensure  that  mail  from different senders will use
               the appropriate credentials.
 
+       <b><a href="postconf.5.html#smtp_sasl_path">smtp_sasl_path</a> (empty)</b>
+              Implementation-specific information that is  passed
+              through  to the SASL plug-in implementation that is
+              selected with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
+
+       <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a> (cyrus)</b>
+              The SASL plug-in type that the Postfix SMTP  client
+              should use for authentication.
+
 <b>STARTTLS SUPPORT CONTROLS</b>
        Detailed  information  about STARTTLS configuration may be
        found in the <a href="TLS_README.html">TLS_README</a> document.
@@ -437,14 +465,20 @@ SMTP(8)                                                                SMTP(8)
               The  SMTP  client  time  limit for sending the RSET
               command, and for receiving the server response.
 
+       Available in Postfix version 2.2 and earlier:
+
+       <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
+              Keep Postfix LMTP client connections open for up to
+              $<a href="postconf.5.html#max_idle">max_idle</a> seconds.
+
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently enable SMTP connection caching for  the
+              Permanently  enable SMTP connection caching for the
               specified destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily  enable SMTP connection caching while a
+              Temporarily enable SMTP connection caching while  a
               destination has a high volume of mail in the active
               queue.
 
@@ -454,57 +488,57 @@ SMTP(8)                                                                SMTP(8)
 
        <b><a href="postconf.5.html#smtp_connection_cache_time_limit">smtp_connection_cache_time_limit</a> (2s)</b>
               When SMTP connection caching is enabled, the amount
-              of  time  that an unused SMTP client socket is kept
+              of time that an unused SMTP client socket  is  kept
               open before it is closed.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
-              Time limit for connection cache  connect,  send  or
+              Time  limit  for  connection cache connect, send or
               receive operations.
 
 <b>TROUBLE SHOOTING CONTROLS</b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The  increment  in  verbose  logging  level  when a
-              remote client or server matches a  pattern  in  the
+              The increment  in  verbose  logging  level  when  a
+              remote  client  or  server matches a pattern in the
               <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional  list  of remote client or server hostname
-              or network address patterns that cause the  verbose
-              logging  level  to increase by the amount specified
+              Optional list of remote client or  server  hostname
+              or  network address patterns that cause the verbose
+              logging level to increase by the  amount  specified
               in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The recipient  of  postmaster  notifications  about
-              mail  delivery  problems that are caused by policy,
+              The  recipient  of  postmaster  notifications about
+              mail delivery problems that are caused  by  policy,
               resource, software or protocol errors.
 
        <b><a href="postconf.5.html#notify_classes">notify_classes</a> (resource, software)</b>
-              The list of error classes that are reported to  the
+              The  list of error classes that are reported to the
               postmaster.
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where  the  Postfix SMTP client should deliver mail
+              Where the Postfix SMTP client should  deliver  mail
               when it detects a "mail loops back to myself" error
               condition.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The  default  location  of  the Postfix main.cf and
+              The default location of  the  Postfix  main.cf  and
               master.cf configuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How much time a Postfix daemon process may take  to
-              handle  a  request  before  it  is  terminated by a
+              How  much time a Postfix daemon process may take to
+              handle a request  before  it  is  terminated  by  a
               built-in watchdog timer.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The maximal number  of  digits  after  the  decimal
+              The  maximal  number  of  digits  after the decimal
               point when logging sub-second delay values.
 
        <b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
-              Disable  DNS  lookups  in the Postfix SMTP and LMTP
+              Disable DNS lookups in the Postfix  SMTP  and  LMTP
               clients.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
@@ -512,7 +546,7 @@ SMTP(8)                                                                SMTP(8)
               tem receives mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (ipv4)</b>
-              The  Internet protocols Postfix will attempt to use
+              The Internet protocols Postfix will attempt to  use
               when making or accepting connections.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
@@ -520,74 +554,74 @@ SMTP(8)                                                                SMTP(8)
               over an internal communication channel.
 
        <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
-              The  default  TCP port that the Postfix LMTP client
+              The default TCP port that the Postfix  LMTP  client
               connects to.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The maximum amount of time  that  an  idle  Postfix
-              daemon  process  waits for the next service request
+              The  maximum  amount  of  time that an idle Postfix
+              daemon process waits for the next  service  request
               before exiting.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
-              The maximal number of connection requests before  a
+              The  maximal number of connection requests before a
               Postfix daemon process terminates.
 
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
-              The  process  ID  of  a  Postfix  command or daemon
+              The process ID  of  a  Postfix  command  or  daemon
               process.
 
        <b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
-              The process name of a  Postfix  command  or  daemon
+              The  process  name  of  a Postfix command or daemon
               process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
               The network interface addresses that this mail sys-
-              tem receives mail on by way of a proxy  or  network
+              tem  receives  mail on by way of a proxy or network
               address translation unit.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
               An optional numerical network address that the SMTP
-              client should bind to when making an  IPv4  connec-
+              client  should  bind to when making an IPv4 connec-
               tion.
 
        <b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
               An optional numerical network address that the SMTP
-              client should bind to when making an  IPv6  connec-
+              client  should  bind to when making an IPv6 connec-
               tion.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
-              The  hostname to send in the SMTP EHLO or HELO com-
+              The hostname to send in the SMTP EHLO or HELO  com-
               mand.
 
-       <b>lmtp_lhlo_name ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
+       <b><a href="postconf.5.html#lmtp_lhloname">lmtp_lhlo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
               The hostname to send in the LMTP LHLO command.
 
        <b><a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a> (dns)</b>
-              What mechanisms when the SMTP client uses  to  look
+              What  mechanisms  when the SMTP client uses to look
               up a host's IP address.
 
        <b><a href="postconf.5.html#smtp_randomize_addresses">smtp_randomize_addresses</a> (yes)</b>
-              Randomize  the  order  of  equal-preference MX host
+              Randomize the order  of  equal-preference  MX  host
               addresses.
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
-              The mail system  name  that  is  prepended  to  the
-              process  name  in  syslog  records, so that "smtpd"
+              The  mail  system  name  that  is  prepended to the
+              process name in syslog  records,  so  that  "smtpd"
               becomes, for example, "postfix/smtpd".
 
        Available with Postfix 2.2 and earlier:
 
        <b><a href="postconf.5.html#fallback_relay">fallback_relay</a> (empty)</b>
-              Optional list of relay hosts for SMTP  destinations
+              Optional  list of relay hosts for SMTP destinations
               that can't be found or that are unreachable.
 
        Available with Postfix 2.3 and later:
 
-       <b>smtp_fallback_relay ($<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b>
-              Optional  list of relay hosts for SMTP destinations
+       <b><a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a> ($<a href="postconf.5.html#fallback_relay">fallback_relay</a>)</b>
+              Optional list of relay hosts for SMTP  destinations
               that can't be found or that are unreachable.
 
 <b>SEE ALSO</b>
@@ -605,7 +639,7 @@ SMTP(8)                                                                SMTP(8)
        <a href="TLS_README.html">TLS_README</a>, Postfix STARTTLS howto
 
 <b>LICENSE</b>
-       The  Secure  Mailer  license must be distributed with this
+       The Secure Mailer license must be  distributed  with  this
        software.
 
 <b>AUTHOR(S)</b>
index 15a9c85ce09b118664568e3f4da49f32bd06fff0..1ecc286582fd8838dc10cdb7cec95c38073c4ee2 100644 (file)
@@ -207,33 +207,40 @@ SMTPD(8)                                                              SMTPD(8)
               Enable SASL  authentication  in  the  Postfix  SMTP
               server.
 
-       <b><a href="postconf.5.html#smtpd_sasl_application_name">smtpd_sasl_application_name</a> (smtpd)</b>
-              The  application name used for SASL server initial-
-              ization.
-
        <b><a href="postconf.5.html#smtpd_sasl_local_domain">smtpd_sasl_local_domain</a> (empty)</b>
               The name of the local SASL authentication realm.
 
        <b><a href="postconf.5.html#smtpd_sasl_security_options">smtpd_sasl_security_options</a> (noanonymous)</b>
-              Restrict what authentication mechanisms the Postfix
-              SMTP server will offer to the client.
+              SASL  security  options; as of Postfix 2.3 the list
+              of available features depends on  the  SASL  server
+              implementation     that     is     selected    with
+              <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b>.
 
        <b><a href="postconf.5.html#smtpd_sender_login_maps">smtpd_sender_login_maps</a> (empty)</b>
-              Optional  lookup  table  with  the SASL login names
+              Optional lookup table with  the  SASL  login  names
               that own sender (MAIL FROM) addresses.
 
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtpd_sasl_exceptions_networks">smtpd_sasl_exceptions_networks</a> (empty)</b>
-              What SMTP clients Postfix will not offer AUTH  sup-
+              What  SMTP clients Postfix will not offer AUTH sup-
               port to.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#smtpd_sasl_authenticated_header">smtpd_sasl_authenticated_header</a> (no)</b>
-              Report  the  SASL  authenticated  user  name in the
+              Report the SASL  authenticated  user  name  in  the
               <a href="smtpd.8.html"><b>smtpd</b>(8)</a> Received message header.
 
+       <b>smtpd_sasl_path (smtpd)</b>
+              Implementation-specific  information that is passed
+              through to the SASL plug-in implementation that  is
+              selected with <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b>.
+
+       <b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a> (cyrus)</b>
+              The  SASL plug-in type that the Postfix SMTP server
+              should use for authentication.
+
 <b>STARTTLS SUPPORT CONTROLS</b>
        Detailed information about STARTTLS configuration  may  be
        found in the <a href="TLS_README.html">TLS_README</a> document.
@@ -811,6 +818,11 @@ SMTPD(8)                                                              SMTPD(8)
               <a href="postconf.5.html#reject_non_fqdn_sender">reject_non_fqdn_sender</a> or <a href="postconf.5.html#reject_non_fqdn_recipient">reject_non_fqdn_recipient</a>
               restriction.
 
+       <b>plaintext_reject_code (450)</b>
+              The  numerical  Postfix  SMTP  server response code
+              when a request is  rejected  by  the  <b>reject_plain-</b>
+              <b>text_session</b> restriction.
+
        <b><a href="postconf.5.html#reject_code">reject_code</a> (554)</b>
               The  numerical  Postfix  SMTP  server response code
               when a remote SMTP client request  is  rejected  by
index 05ee5f8d5949242410475b3f3ba279ae3d467370..1b982d816b46d4e325987c5ee9dd62899300f334 100644 (file)
@@ -9,9 +9,11 @@ Postfix configuration utility
 .na
 .nf
 .fi
-\fBpostconf\fR [\fB-dhmlnv\fR] [\fB-c \fIconfig_dir\fR]
+\fBpostconf\fR [\fB-dhnv\fR] [\fB-c \fIconfig_dir\fR]
 [\fIparameter ...\fR]
 
+\fBpostconf\fR [\fB-aAmlv\fR] [\fB-c \fIconfig_dir\fR]
+
 \fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
 [\fIparameter=value ...\fR]
 
@@ -25,6 +27,18 @@ values, or displays other configuration information about
 the Postfix mail system.
 
 Options:
+.IP \fB-a\fR
+List the available SASL server plug-in types.  The SASL
+plug-in type is selected with the \fBsmtpd_sasl_type\fR
+configuration parameter.
+
+This feature is available with Postfix 2.3 and later.
+.IP \fB-A\fR
+List the available SASL client plug-in types.  The SASL
+plug-in type is selected with the \fBsmtp_sasl_type\fR or
+\fBlmtp_sasl_type\fR configuration parameters.
+
+This feature is available with Postfix 2.3 and later.
 .IP "\fB-b\fR [\fItemplate_file\fR]"
 Display the message text that appears at the beginning of
 delivery status notification (DSN) messages, with $\fBname\fR
index 7c56cf5ce3c15560a1e0bd95b1e951427bb01227..97247d18b36e07e9f154de5bb72c0c91ff45de1c 100644 (file)
@@ -1859,10 +1859,20 @@ Optional LMTP client lookup tables with one username:password entry
 per host or domain.  If a remote host or domain has no username:password
 entry, then the Postfix LMTP client will not attempt to authenticate
 to the remote host.
+.SH lmtp_sasl_path (default: empty)
+Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+\fBlmtp_sasl_type\fR.  Typically this specifies the name of a
+configuration file or rendez-vous point.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_sasl_security_options (default: noplaintext, noanonymous)
-What authentication mechanisms the Postfix LMTP client is allowed
-to use. The list of available authentication mechanisms is system
-dependent.
+SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with \fBlmtp_sasl_type\fR.
+.PP
+The following security features are defined for the \fBcyrus\fR
+client SASL implementation:
 .IP "\fBnoplaintext\fR"
 Disallow authentication methods that use plaintext passwords.
 .IP "\fBnoactive\fR"
@@ -1888,6 +1898,12 @@ The LMTP-specific version of the smtp_sasl_tls_security_options
 configuration parameter.  See there for details.
 .PP
 This feature is available in Postfix 2.3 and later.
+.SH lmtp_sasl_type (default: cyrus)
+The SASL plug-in type that the Postfix LMTP client should use
+for authentication.  The available types are listed with the
+"\fBpostconf -A\fR" command.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH lmtp_send_xforward_command (default: no)
 Send an XFORWARD command to the LMTP server when the LMTP LHLO
 server response announces XFORWARD support.  This allows an \fBlmtp\fR(8)
@@ -2786,6 +2802,11 @@ The name of the \fBpickup\fR(8) service. This service picks up local mail
 submissions from the Postfix maildrop queue.
 .PP
 This feature is available in Postfix 2.0 and later.
+.SH plaintext_session_reject_code (default: 450)
+The numerical Postfix SMTP server response code when a request
+is rejected by the \fBreject_plaintext_session\fR restriction.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH prepend_delivered_header (default: command, file, forward)
 The message delivery contexts where the Postfix \fBlocal\fR(8) delivery
 agent prepends a Delivered-To:  message header with the address
@@ -3919,10 +3940,20 @@ attempt to authenticate to the remote host.
 .PP
 The Postfix SMTP client opens the lookup table before going to
 chroot jail, so you can leave the password file in /etc/postfix.
+.SH smtp_sasl_path (default: empty)
+Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+\fBsmtp_sasl_type\fR.  Typically this specifies the name of a
+configuration file or rendez-vous point.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH smtp_sasl_security_options (default: noplaintext, noanonymous)
-What authentication mechanisms the Postfix SMTP client is allowed
-to use. The list of available authentication mechanisms is system
-dependent.
+SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with \fBsmtp_sasl_type\fR.
+.PP
+The following security features are defined for the \fBcyrus\fR
+client SASL implementation:
 .PP
 Specify zero or more of the following:
 .IP "\fBnoplaintext\fR"
@@ -3949,6 +3980,12 @@ smtp_sasl_security_options = noplaintext
 .SH smtp_sasl_tls_security_options (default: $smtp_sasl_security_options)
 The SASL authentication security options that the Postfix SMTP
 client uses for TLS encrypted SMTP sessions.
+.SH smtp_sasl_type (default: cyrus)
+The SASL plug-in type that the Postfix SMTP client should use
+for authentication.  The available types are listed with the
+"\fBpostconf -A\fR" command.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH smtp_send_xforward_command (default: no)
 Send the non-standard XFORWARD command when the Postfix SMTP server EHLO
 response announces XFORWARD support.
@@ -4570,6 +4607,14 @@ Use at the RCPT stage will only reject the second etc.  recipient.
 The multi_recipient_bounce_reject_code parameter specifies the
 response code for rejected requests (default:  550).  This feature
 is available in Postfix 2.1 and later.
+.IP "\fBreject_plaintext_session\fR"
+Reject the request when the connection is not encrypted. This
+restriction should not be used before the client has had a chance
+to negotiate encryption with the AUTH or STARTTLS commands.
+.br
+The plaintext_session_reject_code parameter specifies the response
+code for rejected requests (default:  450).  This feature is available
+in Postfix 2.3 and later.
 .IP "\fBreject_unauth_pipelining\fR"
 Reject the request when the client sends SMTP commands ahead
 of time where it is not allowed, or when the client sends SMTP
@@ -5241,7 +5286,21 @@ smtpd_sasl_local_domain = $myhostname
 .fi
 .ad
 .ft R
+.SH smtpd_sasl_path (default: smtpd)
+Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+\fBsmtpd_sasl_type\fR.  Typically this specifies the name of a
+configuration file or rendez-vous point.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH smtpd_sasl_security_options (default: noanonymous)
+SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL server implementation that is selected
+with \fBsmtpd_sasl_type\fR.
+.PP
+The following security features are defined for the \fBcyrus\fR
+server SASL implementation:
+.PP
 Restrict what authentication mechanisms the Postfix SMTP server
 will offer to the client.  The list of available authentication
 mechanisms is system dependent.
@@ -5281,6 +5340,12 @@ smtpd_sasl_security_options = noanonymous, noplaintext
 .SH smtpd_sasl_tls_security_options (default: $smtpd_sasl_security_options)
 The SASL authentication security options that the Postfix SMTP
 server uses for TLS encrypted SMTP sessions.
+.SH smtpd_sasl_type (default: cyrus)
+The SASL plug-in type that the Postfix SMTP server should use
+for authentication. The available types are listed with the
+"\fBpostconf -a\fR" command.
+.PP
+This feature is available in Postfix 2.3 and later.
 .SH smtpd_sender_login_maps (default: empty)
 Optional lookup table with the SASL login names that own sender
 (MAIL FROM) addresses.
index a7176c63b8f60ec8839b9a1e8695eb7895e1f924..3f42ff7d1247f6b7c742175001797ed4cf260608 100644 (file)
@@ -47,16 +47,19 @@ specific destinations.
 .ad
 .fi
 SMTP destinations have the following form:
-.IP "\fIdomainname\fR, \fIdomainname\fR:\fIport\fR"
-Look up the mail exchangers for the specified domain.
-.IP "[\fIhostname\fR], [\fIhostname\fR]:\fIport\fR"
-Look up the address of the specified host.
-.IP "[\fIaddress\fR], [\fIaddress\fR]:\fIport\fR"
-Connect to the host at the specified address. An IPv6
-address must be formatted as [\fBipv6\fR:\fIaddress\fR].
-.PP
-In all the above cases, when no port is specified, look up
-the port defined as \fBsmtp\fR in \fBservices\fR(4).
+.IP \fIdomainname\fR
+.IP \fIdomainname\fR:\fIport\fR
+Look up the mail exchangers for the specified domain, and
+connect to the specified port (default: \fBsmtp\fR).
+.IP [\fIhostname\fR]
+.IP [\fIhostname\fR]:\fIport\fR
+Look up the address(es) of the specified host, and connect to
+the specified port (default: \fBsmtp\fR).
+.IP [\fIaddress\fR]
+.IP [\fIaddress\fR]:\fIport\fR
+Connect to the host at the specified address, and connect
+to the specified port (default: \fBsmtp\fR). An IPv6 address
+must be formatted as [\fBipv6\fR:\fIaddress\fR].
 .SH "LMTP DESTINATION SYNTAX"
 .na
 .nf
@@ -67,13 +70,16 @@ LMTP destinations have the following form:
 Connect to the local UNIX-domain server that is bound to the specified
 \fIpathname\fR. If the process runs chrooted, an absolute pathname
 is interpreted relative to the Postfix queue directory.
-.IP "\fBinet\fR:\fIhostname\fR, \fBinet\fB:\fIhostname\fR:\fIport\fR"
-.IP "\fBinet\fR:[\fIaddress\fR], \fBinet\fR:[\fIaddress\fR]:\fIport\fR"
+.IP \fBinet\fR:\fIhostname\fR
+.IP \fBinet\fB:\fIhostname\fR:\fIport\fR
+.IP \fBinet\fR:[\fIaddress\fR]
+.IP \fBinet\fR:[\fIaddress\fR]:\fIport\fR
 Connect to the specified TCP port on the specified local or
 remote host. If no port is specified, connect to the port defined as
 \fBlmtp\fR in \fBservices\fR(4).
 If no such service is found, the \fBlmtp_tcp_port\fR configuration
 parameter (default value of 24) will be used.
+An IPv6 address must be formatted as [\fBipv6\fR:\fIaddress\fR].
 .PP
 .SH "SECURITY"
 .na
@@ -126,6 +132,12 @@ address and TCP port.
 .nf
 .ad
 .fi
+Before Postfix version 2.3, the LMTP client is a separate
+program that implements only a subset of the functionality
+available with SMTP: there is no support for TLS, and
+connections are cached in-process, making it ineffective
+when the client is used for multiple domains.
+
 Most smtp_\fIxxx\fR configuration parameters have an
 lmtp_\fIxxx\fR "ghost" parameter for the equivalent LMTP
 feature. This document describes only those LMTP-related
@@ -233,8 +245,9 @@ Optional SMTP client lookup tables with one username:password entry
 per remote hostname or domain, or sender address when sender-dependent
 authentication is enabled.
 .IP "\fBsmtp_sasl_security_options (noplaintext, noanonymous)\fR"
-What authentication mechanisms the Postfix SMTP client is allowed
-to use.
+SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with \fBsmtp_sasl_type\fR.
 .PP
 Available in Postfix version 2.2 and later:
 .IP "\fBsmtp_sasl_mechanism_filter (empty)\fR"
@@ -247,6 +260,13 @@ Enable sender-dependent authentication in the SMTP client; this is
 available only with SASL authentication, and disables SMTP connection
 caching to ensure that mail from different senders will use the
 appropriate credentials.
+.IP "\fBsmtp_sasl_path (empty)\fR"
+Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+\fBsmtp_sasl_type\fR.
+.IP "\fBsmtp_sasl_type (cyrus)\fR"
+The SASL plug-in type that the Postfix SMTP client should use
+for authentication.
 .SH "STARTTLS SUPPORT CONTROLS"
 .na
 .nf
@@ -360,6 +380,11 @@ limit).
 The SMTP client time limit for sending the RSET command, and
 for receiving the server response.
 .PP
+Available in Postfix version 2.2 and earlier:
+.IP "\fBlmtp_cache_connection (yes)\fR"
+Keep Postfix LMTP client connections open for up to $max_idle
+seconds.
+.PP
 Available in Postfix version 2.2 and later:
 .IP "\fBsmtp_connection_cache_destinations (empty)\fR"
 Permanently enable SMTP connection caching for the specified
index 16de5979eac19197e1b42b62c2da5b2e39644a2b..9b030aa9c3efaeaa7fce010baee9fb62b7a64b44 100644 (file)
@@ -202,13 +202,12 @@ Enable inter-operability with SMTP clients that implement an obsolete
 version of the AUTH command (RFC 2554).
 .IP "\fBsmtpd_sasl_auth_enable (no)\fR"
 Enable SASL authentication in the Postfix SMTP server.
-.IP "\fBsmtpd_sasl_application_name (smtpd)\fR"
-The application name used for SASL server initialization.
 .IP "\fBsmtpd_sasl_local_domain (empty)\fR"
 The name of the local SASL authentication realm.
 .IP "\fBsmtpd_sasl_security_options (noanonymous)\fR"
-Restrict what authentication mechanisms the Postfix SMTP server
-will offer to the client.
+SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL server implementation that is selected
+with \fBsmtpd_sasl_type\fR.
 .IP "\fBsmtpd_sender_login_maps (empty)\fR"
 Optional lookup table with the SASL login names that own sender
 (MAIL FROM) addresses.
@@ -221,6 +220,13 @@ Available in Postfix version 2.3 and later:
 .IP "\fBsmtpd_sasl_authenticated_header (no)\fR"
 Report the SASL authenticated user name in the \fBsmtpd\fR(8) Received
 message header.
+.IP "\fBsmtpd_sasl_path (smtpd)\fR"
+Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+\fBsmtpd_sasl_type\fR.
+.IP "\fBsmtpd_sasl_type (cyrus)\fR"
+The SASL plug-in type that the Postfix SMTP server should use
+for authentication.
 .SH "STARTTLS SUPPORT CONTROLS"
 .na
 .nf
@@ -653,6 +659,9 @@ reject_rhsbl_sender or reject_rhsbl_recipient restriction.
 The numerical Postfix SMTP server reply code when a client request
 is rejected by the reject_non_fqdn_helo_hostname, reject_non_fqdn_sender
 or reject_non_fqdn_recipient restriction.
+.IP "\fBplaintext_reject_code (450)\fR"
+The numerical Postfix SMTP server response code when a request
+is rejected by the \fBreject_plaintext_session\fR restriction.
 .IP "\fBreject_code (554)\fR"
 The numerical Postfix SMTP server response code when a remote SMTP
 client request is rejected by the "reject" restriction.
index eab0521be135631b0965c50ff32f05a49e9975af..d57349ca932aa5f292dac20e79586e18aad4d2de 100755 (executable)
@@ -192,7 +192,37 @@ while (<>) {
     s;\bipc_timeout\b;<a href="postconf.5.html#ipc_timeout">$&</a>;g;
     s;\bipc_ttl\b;<a href="postconf.5.html#ipc_ttl">$&</a>;g;
     s;\bline_length_limit\b;<a href="postconf.5.html#line_length_limit">$&</a>;g;
+    s;\blmtp_bind_address\b;<a href="postconf.5.html#lmtp_bind_address">$&</a>;g;
+    s;\blmtp_bind_address6\b;<a href="postconf.5.html#lmtp_bind_address6">$&</a>;g;
     s;\blmtp_cache_connection\b;<a href="postconf.5.html#lmtp_cache_connection">$&</a>;g;
+    s;\blmtp_discard_lhlo_keyword_address_maps\b;<a href="postconf.5.html#lmtp_discard_lhlo_keyword_address_maps">$&</a>;g;
+    s;\blmtp_discard_lhlo_keywords\b;<a href="postconf.5.html#lmtp_discard_lhlo_keywords">$&</a>;g;
+    s;\blmtp_sasl_tls_security_options\b;<a href="postconf.5.html#lmtp_sasl_tls_security_options">$&</a>;g;
+    s;\blmtp_sasl_mechanism_filter\b;<a href="postconf.5.html#lmtp_sasl_mechanism_filter">$&</a>;g;
+    s;\blmtp_host_lookup\b;<a href="postconf.5.html#lmtp_host_lookup">$&</a>;g;
+    s;\blmtp_connection_cache_destinations\b;<a href="postconf.5.html#lmtp_connection_cache_destinations">$&</a>;g;
+    s;\blmtp_tls_per_site\b;<a href="postconf.5.html#lmtp_tls_per_site">$&</a>;g;
+    s;\blmtp_generic_maps\b;<a href="postconf.5.html#lmtp_generic_maps">$&</a>;g;
+    s;\blmtp_pix_workaround_threshold_time\b;<a href="postconf.5.html#lmtp_pix_workaround_threshold_time">$&</a>;g;
+    s;\blmtp_pix_workaround_delay_time\b;<a href="postconf.5.html#lmtp_pix_workaround_delay_time">$&</a>;g;
+    s;\blmtp_connection_reuse_time_limit\b;<a href="postconf.5.html#lmtp_connection_reuse_time_limit">$&</a>;g;
+    s;\blmtp_starttls_timeout\b;<a href="postconf.5.html#lmtp_starttls_timeout">$&</a>;g;
+    s;\blmtp_line_length_limit\b;<a href="postconf.5.html#lmtp_line_length_limit">$&</a>;g;
+    s;\blmtp_mx_address_limit\b;<a href="postconf.5.html#lmtp_mx_address_limit">$&</a>;g;
+    s;\blmtp_mx_session_limit\b;<a href="postconf.5.html#lmtp_mx_session_limit">$&</a>;g;
+    s;\blmtp_tls_scert_verifydepth\b;<a href="postconf.5.html#lmtp_tls_scert_verifydepth">$&</a>;g;
+    s;\blmtp_skip_5xx_greeting\b;<a href="postconf.5.html#lmtp_skip_5xx_greeting">$&</a>;g;
+    s;\blmtp_randomize_addresses\b;<a href="postconf.5.html#lmtp_randomize_addresses">$&</a>;g;
+    s;\blmtp_quote_rfc821_envelope\b;<a href="postconf.5.html#lmtp_quote_rfc821_envelope">$&</a>;g;
+    s;\blmtp_defer_if_no_mx_address_found\b;<a href="postconf.5.html#lmtp_defer_if_no_mx_address_found">$&</a>;g;
+    s;\blmtp_connection_cache_on_demand\b;<a href="postconf.5.html#lmtp_connection_cache_on_demand">$&</a>;g;
+    s;\blmtp_use_tls\b;<a href="postconf.5.html#lmtp_use_tls">$&</a>;g;
+    s;\blmtp_enforce_tls\b;<a href="postconf.5.html#lmtp_enforce_tls">$&</a>;g;
+    s;\blmtp_tls_enforce_peername\b;<a href="postconf.5.html#lmtp_tls_enforce_peername">$&</a>;g;
+    s;\blmtp_tls_note_starttls_offer\b;<a href="postconf.5.html#lmtp_tls_note_starttls_offer">$&</a>;g;
+    s;\blmtp_sender_dependent_authentication\b;<a href="postconf.5.html#lmtp_sender_dependent_authentication">$&</a>;g;
+    s;\blmtp_sasl_path\b;<a href="postconf.5.html#lmtp_sasl_path">$&</a>;g;
+    s;\blmtp_lhlo_name\b;<a href="postconf.5.html#lmtp_lhloname">$&</a>;g;
     s;\blmtp_connect_timeout\b;<a href="postconf.5.html#lmtp_connect_timeout">$&</a>;g;
     s;\blmtp_data_done_timeout\b;<a href="postconf.5.html#lmtp_data_done_timeout">$&</a>;g;
     s;\blmtp_data_init_timeout\b;<a href="postconf.5.html#lmtp_data_init_timeout">$&</a>;g;
@@ -205,6 +235,7 @@ while (<>) {
     s;\blmtp_sasl_auth_enable\b;<a href="postconf.5.html#lmtp_sasl_auth_enable">$&</a>;g;
     s;\blmtp_sasl_password_maps\b;<a href="postconf.5.html#lmtp_sasl_password_maps">$&</a>;g;
     s;\blmtp_sasl_security_options\b;<a href="postconf.5.html#lmtp_sasl_security_options">$&</a>;g;
+    s;\blmtp_sasl_type\b;<a href="postconf.5.html#lmtp_sasl_type">$&</a>;g;
     s;\blmtp_send_xforward_command\b;<a href="postconf.5.html#lmtp_send_xforward_command">$&</a>;g;
     s;\blmtp_skip_quit_response\b;<a href="postconf.5.html#lmtp_skip_quit_response">$&</a>;g;
     s;\blmtp_tcp_port\b;<a href="postconf.5.html#lmtp_tcp_port">$&</a>;g;
@@ -259,6 +290,7 @@ while (<>) {
     s;\bpar[-</bB>]*\n* *[<bB>]*ent_domain_matches_subdomains\b;<a href="postconf.5.html#parent_domain_matches_subdomains">$&</a>;g;
     s;\bpermit_mx_backup_networks\b;<a href="postconf.5.html#permit_mx_backup_networks">$&</a>;g;
     s;\bpickup_service_name\b;<a href="postconf.5.html#pickup_service_name">$&</a>;g;
+    s;\bplaintext_session_reject_code\b;<a href="postconf.5.html#plaintext_session_reject_code">$&</a>;g;
     s;\bprepend_delivered_header\b;<a href="postconf.5.html#prepend_delivered_header">$&</a>;g;
     s;\bprocess_id\b;<a href="postconf.5.html#process_id">$&</a>;g;
     s;\bprocess_id_directory\b;<a href="postconf.5.html#process_id_directory">$&</a>;g;
@@ -364,6 +396,7 @@ while (<>) {
     s;\bsmtp_sasl_auth_enable\b;<a href="postconf.5.html#smtp_sasl_auth_enable">$&</a>;g;
     s;\bsmtp_sasl_mechanism_filter\b;<a href="postconf.5.html#smtp_sasl_mechanism_filter">$&</a>;g;
     s;\bsmtp_sasl_password_maps\b;<a href="postconf.5.html#smtp_sasl_password_maps">$&</a>;g;
+    s;\bsmtp_sasl_path\b;<a href="postconf.5.html#smtp_sasl_path">$&</a>;g;
     s;\bsmtp_sasl_secu[-</Bb>]*\n* *[<Bb>]*rity_options\b;<a href="postconf.5.html#smtp_sasl_security_options">$&</a>;g;
     s;\bsmtp_send_xforward_command\b;<a href="postconf.5.html#smtp_send_xforward_command">$&</a>;g;
     s;\bsmtp_skip_4xx_greeting\b;<a href="postconf.5.html#smtp_skip_4xx_greeting">$&</a>;g;
@@ -410,7 +443,7 @@ while (<>) {
     s;\bsmtpd_reject_unlisted_recip[-</bB>]*\n* *[<bB>]*ient\b;<a href="postconf.5.html#smtpd_reject_unlisted_recipient">$&</a>;g;
     s;\bsmtpd_reject_unlisted_sender\b;<a href="postconf.5.html#smtpd_reject_unlisted_sender">$&</a>;g;
     s;\bsmtpd_restriction_classes\b;<a href="postconf.5.html#smtpd_restriction_classes">$&</a>;g;
-    s;\bsmtpd_sasl_application_name\b;<a href="postconf.5.html#smtpd_sasl_application_name">$&</a>;g;
+    s;\bsmtpd_sasl_path\b;<a href="postconf.5.html#smtpd_sasl_path">$&</a>;g;
     s;\bsmtpd_sasl_auth_enable\b;<a href="postconf.5.html#smtpd_sasl_auth_enable">$&</a>;g;
     s;\bsmtpd_sasl_authenticated_header\b;<a href="postconf.5.html#smtpd_sasl_authenticated_header">$&</a>;g;
     s;\bsmtpd_sasl_exceptions_networks\b;<a href="postconf.5.html#smtpd_sasl_exceptions_networks">$&</a>;g;
@@ -462,8 +495,10 @@ while (<>) {
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_uid_maps\b;<a href="postconf.5.html#virtual_uid_maps">$&</a>;g;
 
     s;\bsmtp_enforce_tls\b;<a href="postconf.5.html#smtp_enforce_tls">$&</a>;g;
+    s;\bsmtp_fallback_relay\b;<a href="postconf.5.html#smtp_fallback_relay">$&</a>;g;
     s;\bsmtp_sasl_tls_security_options\b;<a href="postconf.5.html#smtp_sasl_tls_security_options">$&</a>;g;
     s;\bsmtp_sasl_tls_verified_security_options\b;<a href="postconf.5.html#smtp_sasl_tls_verified_security_options">$&</a>;g;
+    s;\bsmtp_sasl_type\b;<a href="postconf.5.html#smtp_sasl_type">$&</a>;g;
     s;\bsmtp_starttls_timeout\b;<a href="postconf.5.html#smtp_starttls_timeout">$&</a>;g;
     s;\bsmtp_tls_CAfile\b;<a href="postconf.5.html#smtp_tls_CAfile">$&</a>;g;
     s;\bsmtp_tls_CApath\b;<a href="postconf.5.html#smtp_tls_CApath">$&</a>;g;
@@ -482,6 +517,7 @@ while (<>) {
     s;\bsmtp_use_tls\b;<a href="postconf.5.html#smtp_use_tls">$&</a>;g;
     s;\bsmtpd_enforce_tls\b;<a href="postconf.5.html#smtpd_enforce_tls">$&</a>;g;
     s;\bsmtpd_sasl_tls_security_options\b;<a href="postconf.5.html#smtpd_sasl_tls_security_options">$&</a>;g;
+    s;\bsmtpd_sasl_type\b;<a href="postconf.5.html#smtpd_sasl_type">$&</a>;g;
     s;\bsmtpd_starttls_timeout\b;<a href="postconf.5.html#smtpd_starttls_timeout">$&</a>;g;
     s;\bsmtpd_tls_CAfile\b;<a href="postconf.5.html#smtpd_tls_CAfile">$&</a>;g;
     s;\bsmtpd_tls_CApath\b;<a href="postconf.5.html#smtpd_tls_CApath">$&</a>;g;
@@ -607,6 +643,7 @@ while (<>) {
     s;\bdefer_if_permit\b;<a href="postconf.5.html#defer_if_permit">$&</a>;g;
     s;\bdefer_if_reject\b;<a href="postconf.5.html#defer_if_reject">$&</a>;g;
     s;\breject_multi_recip[-</bB>]*\n* *[<bB>]*ient_bounce\b;<a href="postconf.5.html#reject_multi_recipient_bounce">$&</a>;g;
+    s;\breject_plaintext_session\b;<a href="postconf.5.html#reject_plaintext_session">$&</a>;g;
     s;\breject_unauth_pipelining\b;<a href="postconf.5.html#reject_unauth_pipelining">$&</a>;g;
     s;\bwarn_if_reject\b;<a href="postconf.5.html#warn_if_reject">$&</a>;g;
 
index b60ba9aeaa36b47a6954b572d0808c86ceece3a7..90da1ee6e10549f429a9a4838c245c79eb41f9bd 100644 (file)
 
 <h2>WARNING</h2>
 
-<p> People who go to the trouble of installing Postfix may have
-the expectation that Postfix is more secure than some other mailers.
-The Cyrus SASL library is a lot of code. With SASL authentication
-enabled in the Postfix SMTP client and SMTP server, Postfix becomes
+<p> People who go to the trouble of installing Postfix may have the
+expectation that Postfix is more secure than some other mailers.
+The Cyrus SASL library is a lot of code. With this, Postfix becomes
 as secure as other mail systems that use the Cyrus SASL library.
 </p>
 
@@ -38,9 +37,11 @@ optionally grants mail access via the permit_sasl_authenticated
 UCE restriction. </p>
 
 <p> When sending mail, Postfix can look up the server hostname or
-destination domain (the address right-hand part) in a table, and if a
-username/password is found, it will use that username and password
-to authenticate to the server. </p>
+destination domain (the address right-hand part) in a Postfix SASL password
+table, and if a username/password is found, it will use that username
+and password to authenticate to the server.  And as of version 2.3,
+Postfix can be configured to search its SASL password table by the
+sender email address. </p>
 
 <p>This document covers the following topics: </p>
 
@@ -48,9 +49,9 @@ to authenticate to the server. </p>
 
 <li><a href="#versions">What SASL versions are supported</a>
 
-<li><a href="#build_sasl">Building the SASL library</a>
+<li><a href="#build_sasl">Building the Cyrus SASL library</a>
 
-<li><a href="#build_postfix">Building Postfix with SASL authentication
+<li><a href="#build_postfix">Building Postfix with Cyrus SASL
 support</a></li>
 
 <li><a href="#server_sasl">Enabling SASL authentication in the
@@ -70,31 +71,20 @@ Postfix SMTP client</a></li>
 
 <h2><a name="versions">What SASL versions are supported</a></h2>
 
-<p> Postfix+SASL 1.5.5 was seen working on RedHat 6.1 (pwcheck_method
-set to shadow or sasldb), Solaris 2.7 (pwcheck_method set to shadow
-or sasldb), and FreeBSD 3.4 (pwcheck_method set to sasldb).  On
-RedHat 6.1, SASL 1.5.5 insisted on write access to /etc/sasldb.
-Note that this seems to be related to the auto_transition switch
-in SASL. Note also that the Cyrus SASL documentation says that it
-is pointless to enable that if you use "sasldb" for "pwcheck_method".
-Later versions of the SASL 1.5.x series should also work. </p>
-
-<p> Postfix+SASL 2.1.1 appears to work on Mandrake Linux 8.1
-(pwcheck_method set to saslauthd or auxprop).  Note that the
-'auxprop' pwcheck_method replaces the 'sasldb' method from SASL
-1.5.x.  Postfix may need write access to /etc/sasldb2 if you use
-the auto_transition feature, or if you use an authentication
-mechanism such as OTP (one-time passwords) that needs to update
-secrets in the database. </p>
-
-<h2><a name="build_sasl">Building the SASL library</a></h2>
+<p> This document describes Postfix with Cyrus SASL version 1 and
+Cyrus SASL version 2. Postfix version 2.3 introduces has a plug-in
+mechanism for other SASL implementations.  Support for other
+implementations is currently not part of the Postfix distribution
+and will be described elsewhere.  </p>
+
+<h2><a name="build_sasl">Building the Cyrus SASL library</a></h2>
 
 <p> Postfix appears to work with cyrus-sasl-1.5.5 or cyrus-sasl-2.1.1, 
 which are available from: </p>
 
 <blockquote>
 <pre>
-ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/.
+ftp://ftp.andrew.cmu.edu/pub/cyrus-mail/
 </pre>
 </blockquote>
 
@@ -107,8 +97,7 @@ version 2.1.1. </p>
 non-standard SASL LOGIN authentication method. To enable this
 authentication method, specify ``./configure --enable-login''. </p>
 
-<h2><a name="build_postfix">Building Postfix with SASL authentication
-support</a></h2>
+<h2><a name="build_postfix">Building Postfix with Cyrus SASL support</a></h2>
 
 <p> To build Postfix with SASL authentication support, the following
 assumes that the Cyrus SASL include files are in /usr/local/include,
@@ -119,20 +108,20 @@ and that the Cyrus SASL libraries are in /usr/local/lib. </p>
 
 <dl>
 
-<dt> (for SASL version 1.5.5):
+<dt> (for Cyrus SASL version 1.5.5):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
-    AUXLIBS="-L/usr/local/lib -lsasl"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include" AUXLIBS="-L/usr/local/lib -lsasl"
 </pre>
 
-<dt> (for SASL version 2.1.1):
+<dt> (for Cyrus SASL version 2.1.1):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
-    AUXLIBS="-L/usr/local/lib -lsasl2"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib -lsasl2"
 </pre>
 
 </dl>
@@ -142,20 +131,22 @@ otherwise ld.so will not find the SASL shared library: </p>
 
 <dl>
 
-<dt> (for SASL version 1.5.5):
+<dt> (for Cyrus SASL version 1.5.5):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include" \
-    AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include" AUXLIBS="-L/usr/local/lib \
+    -R/usr/local/lib -lsasl"
 </pre>
 
-<dt> (for SASL version 2.1.1):
+<dt> (for Cyrus SASL version 2.1.1):
 <dd>
 <pre>
 % make tidy # if you have left-over files from a previous build
-% make makefiles CCARGS="-DUSE_SASL_AUTH -I/usr/local/include/sasl" \
-    AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lsasl2"
+% make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+    -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib \
+    -R/usr/local/lib -lsasl2"
 </pre>
 
 </dl>
@@ -195,20 +186,22 @@ SMTP server</a></h2>
 <p> Note: the SASL login names will be shared with the entire world.
 </p>
 
-<p> In /usr/local/lib/sasl/smtpd.conf (SASL version 1.5.5) or
-/usr/local/lib/sasl2/smtpd.conf (SASL version 2.1.1) you need to
+<p> In /usr/local/lib/sasl/smtpd.conf (Cyrus SASL version 1.5.5) or
+/usr/local/lib/sasl2/smtpd.conf (Cyrus SASL version 2.1.1) you need to
 specify how the server should validate client passwords. </p>
 
 <p> Note: some Postfix distributions are modified and look for 
 the smtpd.conf file in /etc/postfix. </p>
 
-<p> Note: some Cyrus SASL distributions are modified and look for
-the smtpd.conf file in /etc/sasl2. </p>
+<p> Note: some Cyrus SASL distributions look for the smtpd.conf
+file in /etc/sasl2. </p>
+
+<ul>
 
-<p> In order to authenticate against the UNIX password database, try: </p>
+<li> <p> To authenticate against the UNIX password database, try: </p>
 
 <dl>
-<dt> (SASL version 1.5.5)
+<dt> (Cyrus SASL version 1.5.5)
 <dd>
 <pre>
 /usr/local/lib/sasl/smtpd.conf:
@@ -216,7 +209,7 @@ the smtpd.conf file in /etc/sasl2. </p>
 
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 /usr/local/lib/sasl2/smtpd.conf:
@@ -225,8 +218,9 @@ the smtpd.conf file in /etc/sasl2. </p>
 
 </dl>
 
-<p> The name of the file in /usr/local/lib/sasl (SASL version 1.5.5)
-or /usr/local/lib/sasl2 (SASL version 2.1.1) used by the SASL
+<p> The name of the file in /usr/local/lib/sasl (Cyrus SASL version
+1.5.5) or /usr/local/lib/sasl2 (Cyrus SASL version 2.1.1) used by
+the SASL
 library for configuration can be set with: </p>
 
 <blockquote>
@@ -242,18 +236,19 @@ library for configuration can be set with: </p>
 permission for the /var/pwcheck directory, otherwise authentication
 attempts will fail. </p>
 
-<p> Alternately, in SASL 1.5.26 and later (including 2.1.1), try: </p>
+<li> <p> Alternately, in Cyrus SASL 1.5.26 and later (including
+2.1.1), try: </p>
 
 <dl>
 
-<dt> (SASL version 1.5.26)
+<dt> (Cyrus SASL version 1.5.26)
 <dd>
 <pre>
 /usr/local/lib/sasl/smtpd.conf:
     pwcheck_method: saslauthd
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 /usr/local/lib/sasl2/smtpd.conf:
@@ -267,17 +262,17 @@ tarball.  It is more flexible than the pwcheck daemon, in that it
 can authenticate against PAM and various other sources. To use PAM,
 start saslauthd with "-a pam". </p>
 
-<p> In order to authenticate against SASL's own password database: </p>
+<li> <p> To authenticate against Cyrus SASL's own password database: </p>
 
 <dl>
-<dt> (SASL version 1.5.5)
+<dt> (Cyrus SASL version 1.5.5)
 <dd>
 <pre>
 /usr/local/lib/sasl/smtpd.conf:
     pwcheck_method:  sasldb
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 /usr/local/lib/sasl2/smtpd.conf:
@@ -286,63 +281,29 @@ start saslauthd with "-a pam". </p>
 
 </dl>
 
-<p> This will use the SASL password file (default: /etc/sasldb in
+<p> This will use the Cyrus SASL password file (default: /etc/sasldb in
 version 1.5.5, or /etc/sasldb2 in version 2.1.1), which is maintained
 with the saslpasswd or saslpasswd2 command (part of the Cyrus SASL
 software). On some poorly-supported systems the saslpasswd command needs
 to be run multiple times before it stops complaining.  The Postfix SMTP
 server needs read access to the sasldb file - you may have to play games
 with group access permissions.  With the OTP authentication mechanism,
-the SMTP server also needs write access to /etc/sasldb2 or /etc/sasldb
+the SMTP server also needs WRITE access to /etc/sasldb2 or /etc/sasldb
 (or the back end SQL database, if used). </p>
 
-<p> IMPORTANT: all users must be able to authenticate using ALL
-authentication mechanisms advertised by Postfix, otherwise the
-negotiation might end up with an unsupported mechanism, and
-authentication would fail.  For example if you configure SASL to
-use <i>saslauthd</i> for authentication against PAM (pluggable
-authentication modules), only the PLAIN and LOGIN mechanisms are
-supported and stand a chance to succeed, yet the SASL library would also
-advertise other mechanisms, such as DIGEST-MD5.  This happens because
-those mechanisms are made available by other plugins, and the SASL
-library have no way to know that your only valid authentication source
-is PAM.  Thus you might need to limit the list of mechanisms advertised
-by Postfix.  This is only possible with SASL version 2.1.1 or later:
-</p>
-
-<blockquote>
-<pre>
-/usr/local/lib/sasl2/smtpd.conf:
-    mech_list: plain login
-</pre>
-</blockquote>
-
-<p> For the same reasons you might want to limit the list of plugins
-used for authentication.  With SASL version 1.5.5 your only choice is to
-delete the corresponding libraries from /usr/local/lib/sasl.  With SASL
-version 2.1.1: </p>
-
-<blockquote>
-<pre>
-/usr/local/lib/sasl2/smtpd.conf:
-    pwcheck_method:  auxprop
-    auxprop_plugin:  sql
-</pre>
-</blockquote>
-
 <p> IMPORTANT: To get sasldb running, make sure that you set the SASL
 domain (realm) to a fully qualified domain name. </p>
 
 <p> EXAMPLE: </p>
 
 <dl>
-<dt> (SASL version 1.5.5)
+<dt> (Cyrus SASL version 1.5.5)
 <dd>
 <pre>
 % saslpasswd -c -u `postconf -h myhostname` exampleuser
 </pre>
 
-<dt> (SASL version 2.1.1)
+<dt> (Cyrus SASL version 2.1.1)
 <dd>
 <pre>
 % saslpasswd2 -c -u `postconf -h myhostname` exampleuser
@@ -351,8 +312,8 @@ domain (realm) to a fully qualified domain name. </p>
 </dl>
 
 <p> You can find out SASL's idea about the realms of the users
-in sasldb with <i>sasldblistusers</i> (SASL version 1.5.5) or
-<i>sasldblistusers2</i> (SASL version 2.1.1). </p>
+in sasldb with <i>sasldblistusers</i> (Cyrus SASL version 1.5.5) or
+<i>sasldblistusers2</i> (Cyrus SASL version 2.1.1). </p>
 
 <p> On the Postfix side, you can have only one realm per smtpd
 instance, and only the users belonging to that realm would be able to
@@ -366,6 +327,59 @@ realm used by smtpd: </p>
 </pre>
 </blockquote>
 
+</ul>
+
+<p> IMPORTANT: all users must be able to authenticate using ALL
+authentication mechanisms advertised by Postfix, otherwise the
+negotiation might end up with an unsupported mechanism, and
+authentication would fail.  For example if you configure SASL to
+use <i>saslauthd</i> for authentication against PAM (pluggable
+authentication modules), only the PLAIN and LOGIN mechanisms are
+supported and stand a chance to succeed, yet the SASL library would also
+advertise other mechanisms, such as DIGEST-MD5.  This happens because
+those mechanisms are made available by other plugins, and the SASL
+library have no way to know that your only valid authentication source
+is PAM.  Thus you might need to limit the list of mechanisms advertised
+by Postfix. </p>
+
+<ul> 
+
+<li> <p> With older Cyrus SASL versions you remove the corresponding
+library files from the SASL plug-in directory (and again whenever
+the system is updated). </p>
+
+<li> <p> With Cyrus SASL version 2.1.1 or later: </p>
+
+<blockquote>
+<pre>
+/usr/local/lib/sasl2/smtpd.conf:
+    mech_list: plain login
+</pre>
+</blockquote>
+
+</ul>
+
+<p> For the same reasons you might want to limit the list of plugins
+used for authentication. </p>
+
+<ul>
+
+<li> <p> With Cyrus SASL version 1.5.5 your only choice is to
+delete the corresponding library files from the SASL plug-in 
+directory. </p>
+
+<li> <p> With SASL version 2.1.1: </p>
+
+<blockquote>
+<pre>
+/usr/local/lib/sasl2/smtpd.conf:
+    pwcheck_method:  auxprop
+    auxprop_plugin:  sql
+</pre>
+</blockquote>
+
+</ul>
+
 <p> To run software chrooted with SASL support is an interesting
 exercise.  It probably is not worth the trouble. </p>
 
@@ -470,6 +484,25 @@ table. </p>
 </pre>
 </blockquote>
 
+<p> Postfix version 2.3 supports-per-sender SASL password
+information. To search the Postfix SASL password by sender 
+before it searches by destination, specify: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    smtp_sender_dependent_authentication = yes
+    smtp_sasl_auth_enable = yes
+    smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+
+/etc/postfix/sasl_passwd:
+    user@example.com            username:password
+    bar.com                     username
+    [mail.myisp.net]            username:password
+    [mail.myisp.net]:submission username:password
+</pre>
+</blockquote>
+
 <p> Note: some SMTP servers support PLAIN or LOGIN authentication only.
 By default, the Postfix SMTP client does not use authentication
 methods that send plaintext passwords, and defers delivery with
@@ -480,11 +513,11 @@ for example: </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    smtp_sasl_security_options = 
+    smtp_sasl_security_options = noanonymous
 </pre>
 </blockquote>
 
-<p> The SASL client password file is opened before the SMTP server
+<p> The Postfix SASL client password file is opened before the SMTP server
 enters the optional chroot jail, so you can keep the file in
 /etc/postfix. </p>
 
@@ -493,7 +526,17 @@ although available on the client system, may not in practice work or
 possess the appropriate credentials to authenticate to the server. It
 is possible via the smtp_sasl_mechanism_filter parameter to further
 restrict the list of server mechanisms that the smtp(8) client will take
-into consideration.  </p>
+into consideration:  </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+    smtp_sasl_mechanism_filter = !gssapi, !external, static:all
+</pre>
+</blockquote>
+
+<p> In the above example, Postfix will decline to use mechanisms
+that require special infrastructure such as Kerberos. </p>
 
 <p> The Postfix SMTP client is backwards compatible with SMTP
 servers that use the non-standard "AUTH=method..." syntax in response
@@ -509,13 +552,16 @@ of SuSE Rhein/Main AG.
 
 <li> Wietse trimmed down the code to only the bare necessities.
 
-<li> Support for SASL version 2 was contributed by Jason Hoos.
+<li> Support for Cyrus SASL version 2 was contributed by Jason Hoos.
 
 <li> Liviu Daia added smtpd_sasl_application_name, split
 reject_sender_login_mismatch into
 reject_authenticated_sender_login_mismatch and
 reject_unauthenticated_sender_login_mismatch, and revised the docs.
 
+<li> Wietse made another iteration through the code to add
+plug-in support for multiple implementations.
+
 </ul>
 
 </body>
index 5a3b5e26a21868a8a0e2939d37251fd03d1f4dbd..24e8cd8cc3454ec0e0e3999eec25db94a505d7e5 100644 (file)
@@ -83,13 +83,18 @@ client_address=1.2.3.4
 client_name=another.domain.tld
 reverse_client_name=another.domain.tld
 instance=123.456.7
+<b>Postfix version 2.2 and later:</b>
 sasl_method=plain
 sasl_username=you
 sasl_sender=
+size=12345
 ccert_subject=solaris9.porcupine.org
 ccert_issuer=Wietse Venema
 ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04
-size=12345
+<b>Postfix version 2.3 and later:</b>
+encryption_protocol=TLSv1/SSLv3
+encryption_cipher=DHE-RSA-AES256-SHA
+encryption_keysize=256
 [empty line]
 </pre>
 </blockquote>
@@ -137,12 +142,19 @@ size=12345
 
     <li> <p> The "sasl_*" attributes (Postfix 2.2 and later) specify
     information about how the client was authenticated via SASL.
+    These attributes are empty in case of no SASL authentication.
     </p>
 
     <li> <p> The "ccert_*" attributes (Postfix 2.2 and later) specify
     information about how the client was authenticated via TLS.
+    These attributes are empty in case of no certificate authentication.
     </p>
 
+    <li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
+    specify information about how the connection is encrypted. With
+    plaintext connections the protocol and cypher attributes are
+    empty and the keysize is zero.  </p>
+
 </ul>
 
 <p> The following is specific to SMTPD delegated policy requests:
index cf73234eb741bc7882831c773a564bfb901696dd..cc47868935b4c50639b74f3f6eda39b248641c71 100644 (file)
@@ -4048,11 +4048,12 @@ chroot jail, so you can leave the password file in /etc/postfix.
 
 %PARAM smtp_sasl_security_options noplaintext, noanonymous
 
-<p>
-What authentication mechanisms the Postfix SMTP client is allowed
-to use. The list of available authentication mechanisms is system
-dependent.
-</p>
+<p> SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with <b>smtp_sasl_type</b>.  </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+client SASL implementation: </p>
 
 <p>
 Specify zero or more of the following:
@@ -4703,6 +4704,16 @@ The multi_recipient_bounce_reject_code parameter specifies the
 response code for rejected requests (default:  550).  This feature
 is available in Postfix 2.1 and later. </dd>
 
+<dt><b><a name="reject_plaintext_session">reject_plaintext_session</a></b></dt>
+
+<dd>Reject the request when the connection is not encrypted. This
+restriction should not be used before the client has had a chance
+to negotiate encryption with the AUTH or STARTTLS commands.
+<br>
+The plaintext_session_reject_code parameter specifies the response
+code for rejected requests (default:  450).  This feature is available
+in Postfix 2.3 and later. </dd>
+
 <dt><b><a name="reject_unauth_pipelining">reject_unauth_pipelining</a></b></dt>
 
 <dd>Reject the request when the client sends SMTP commands ahead
@@ -5447,6 +5458,13 @@ smtpd_sasl_local_domain = $myhostname
 
 %PARAM smtpd_sasl_security_options noanonymous
 
+<p> SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL server implementation that is selected
+with <b>smtpd_sasl_type</b>.  </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+server SASL implementation: </p>
+
 <p>
 Restrict what authentication mechanisms the Postfix SMTP server
 will offer to the client.  The list of available authentication
@@ -6746,11 +6764,12 @@ to the remote host.
 
 %PARAM lmtp_sasl_security_options noplaintext, noanonymous
 
-<p>
-What authentication mechanisms the Postfix LMTP client is allowed
-to use. The list of available authentication mechanisms is system
-dependent.
-</p>
+<p> SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with <b>lmtp_sasl_type</b>.  </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+client SASL implementation: </p>
 
 <dl>
 
@@ -9036,3 +9055,64 @@ configuration parameter.  See there for details. </p>
 operations.  The time limit is enforced in the client. </p>
 
 <p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_sasl_type cyrus
+
+<p> The SASL plug-in type that the Postfix SMTP server should use
+for authentication. The available types are listed with the
+"<b>postconf -a</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_sasl_type cyrus
+
+<p> The SASL plug-in type that the Postfix SMTP client should use
+for authentication.  The available types are listed with the    
+"<b>postconf -A</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+%PARAM lmtp_sasl_type cyrus
+
+<p> The SASL plug-in type that the Postfix LMTP client should use
+for authentication.  The available types are listed with the    
+"<b>postconf -A</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_sasl_path smtpd
+
+<p> Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+<b>smtpd_sasl_type</b>.  Typically this specifies the name of a
+configuration file or rendez-vous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_sasl_path
+
+<p> Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+<b>smtp_sasl_type</b>.  Typically this specifies the name of a
+configuration file or rendez-vous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_sasl_path
+
+<p> Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+<b>lmtp_sasl_type</b>.  Typically this specifies the name of a
+configuration file or rendez-vous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM plaintext_session_reject_code 450
+
+<p>
+The numerical Postfix SMTP server response code when a request
+is rejected by the <b>reject_plaintext_session</b> restriction.
+</p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
index a1f9fd532885ef64c99651bbfae7863dc3067cef..04cf425ce8f1afb7bab1fd6c15a65b49747fa285 100644 (file)
 #include <string.h>
 #include <ctype.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <msg.h>
index 11ec09bc15bf159480a16404c75086618e0c54e9..bd1f46e99dcb62c3766dbfb4c0d49b317e87fc7d 100644 (file)
 #include <stdlib.h>
 #include <ctype.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <msg.h>
index 94af4cb78835edc9e836fbc23a9184db0c36c368..476dc44b56271e0ab3adeff8bf497ab9ecda44cd 100644 (file)
 #include <sys_defs.h>
 #include <string.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <argv.h>
index 4611fdabce918f1f1a1e7a96362d33e1c63f0a9d..0ebe087a070ea54822374c64e291271f4ca037d3 100644 (file)
@@ -6,11 +6,11 @@
 /* SYNOPSIS
 /*     #include <dns.h>
 /*
-/*     int     dns_rr_to_sa(rr, port, sa, sa_len)
+/*     int     dns_rr_to_sa(rr, port, sa, sa_length)
 /*     DNS_RR  *rr;
 /*     unsigned port;
 /*     struct sockaddr *sa;
-/*     SOCKADDR_SIZE *sa_len;
+/*     SOCKADDR_SIZE *sa_length;
 /* DESCRIPTION
 /*     dns_rr_to_sa() converts the address in a DNS resource record into
 /*     a socket address of the corresponding type.
@@ -22,7 +22,7 @@
 /*     TCP or UDP port, network byte order.
 /* .IP sa
 /*     Socket address pointer.
-/* .IP sa_len
+/* .IP sa_length
 /*     On input, the available socket address storage space.
 /*     On output, the amount of space actually used.
 /* DIAGNOSTICS
@@ -55,7 +55,7 @@
 /* dns_rr_to_sa - resource record to socket address */
 
 int     dns_rr_to_sa(DNS_RR *rr, unsigned port, struct sockaddr * sa,
-                            SOCKADDR_SIZE *sa_len)
+                            SOCKADDR_SIZE *sa_length)
 {
     SOCKADDR_SIZE sock_addr_len;
 
@@ -63,7 +63,7 @@ int     dns_rr_to_sa(DNS_RR *rr, unsigned port, struct sockaddr * sa,
        if (rr->data_len != sizeof(SOCK_ADDR_IN_ADDR(sa))) {
            errno = EINVAL;
            return (-1);
-       } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN_PTR(sa))) > *sa_len) {
+       } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN_PTR(sa))) > *sa_length) {
            errno = ENOSPC;
            return (-1);
        } else {
@@ -74,7 +74,7 @@ int     dns_rr_to_sa(DNS_RR *rr, unsigned port, struct sockaddr * sa,
 #ifdef HAS_SA_LEN
            sa->sa_len = sock_addr_len;
 #endif
-           *sa_len = sock_addr_len;
+           *sa_length = sock_addr_len;
            return (0);
        }
 #ifdef HAS_IPV6
@@ -82,7 +82,7 @@ int     dns_rr_to_sa(DNS_RR *rr, unsigned port, struct sockaddr * sa,
        if (rr->data_len != sizeof(SOCK_ADDR_IN6_ADDR(sa))) {
            errno = EINVAL;
            return (-1);
-       } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN6_PTR(sa))) > *sa_len) {
+       } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN6_PTR(sa))) > *sa_length) {
            errno = ENOSPC;
            return (-1);
        } else {
@@ -93,7 +93,7 @@ int     dns_rr_to_sa(DNS_RR *rr, unsigned port, struct sockaddr * sa,
 #ifdef HAS_SA_LEN
            sa->sa_len = sock_addr_len;
 #endif
-           *sa_len = sock_addr_len;
+           *sa_length = sock_addr_len;
            return (0);
        }
 #endif
@@ -127,7 +127,7 @@ int     main(int argc, char **argv)
     MAI_SERVPORT_STR portnum;
     struct sockaddr_storage ss;
     struct sockaddr *sa = (struct sockaddr *) & ss;
-    SOCKADDR_SIZE sa_len = sizeof(ss);
+    SOCKADDR_SIZE sa_length = sizeof(ss);
     VSTRING *why;
     int     type;
     int     port;
@@ -146,10 +146,10 @@ int     main(int argc, char **argv)
            usage();
        if (dns_lookup(argv[1], type, 0, &rr, (VSTRING *) 0, why) != DNS_OK)
            msg_fatal("%s: %s", argv[1], vstring_str(why));
-       sa_len = sizeof(ss);
-       if (dns_rr_to_sa(rr, htons(port), sa, &sa_len) != 0)
+       sa_length = sizeof(ss);
+       if (dns_rr_to_sa(rr, htons(port), sa, &sa_length) != 0)
            msg_fatal("dns_rr_to_sa: %m");
-       SOCKADDR_TO_HOSTADDR(sa, sa_len, &hostaddr, &portnum, 0);
+       SOCKADDR_TO_HOSTADDR(sa, sa_length, &hostaddr, &portnum, 0);
        vstream_printf("%s %s -> %s %s\n",
                       argv[1], argv[2], hostaddr.buf, portnum.buf);
        vstream_fflush(VSTREAM_OUT);
index 590a02221a4843a9c757dbfd672f833be569c5f3..e46bf79a671f0cc23f165b92459abe81905bede0 100644 (file)
@@ -631,6 +631,8 @@ deliver_pass.o: ../../include/sys_defs.h
 deliver_pass.o: ../../include/vbuf.h
 deliver_pass.o: ../../include/vstream.h
 deliver_pass.o: ../../include/vstring.h
+deliver_pass.o: bounce.h
+deliver_pass.o: defer.h
 deliver_pass.o: deliver_pass.c
 deliver_pass.o: deliver_pass.h
 deliver_pass.o: deliver_request.h
index 58a3c4afdb51d0a45cc4b580c30ee2ad1f921609..525294889f4203076a991e4299269995229fab29 100644 (file)
 #include <stdio.h>
 #include <string.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include "msg.h"
index 09403e820b532bb367d2d00db64046513bd0d896..91675b495741b43d5e57f3528d1ca2a41ad3abcd 100644 (file)
@@ -68,6 +68,7 @@
 #include <mail_params.h>
 #include <deliver_pass.h>
 #include <dsb_scan.h>
+#include <defer.h>
 
 #define DELIVER_PASS_DEFER     1
 #define DELIVER_PASS_UNKNOWN   2
index 24daf2972dd111d0fc2a0575e58f18d1eb1f16c8..eaaad4908df53bb9d12837751ff39dfff365b2c8 100644 (file)
 #include <ctype.h>
 #include <unistd.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
  /*
   * Older APIs have weird memory freeing behavior.
   */
index 62dbf38b32363a83ed44b01375403cecf0ee4b36..282366c6ce30cb3cc700bc2f26eb65884a740f71 100644 (file)
 #include <time.h>
 #include <mysql.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include "dict.h"
index eff145f19d15ae2d859281994b304b3dee6b7e05..2decd4cef49dfd3a05c5db7ef25f0a6eaa09bad1 100644 (file)
@@ -1246,12 +1246,12 @@ extern bool var_smtpd_sasl_auth_hdr;
 #define DEF_SMTPD_SASL_OPTS    "noanonymous"
 extern char *var_smtpd_sasl_opts;
 
-#define VAR_SMTPD_SASL_APPNAME "smtpd_sasl_application_name"
-#define DEF_SMTPD_SASL_APPNAME "smtpd"
-extern char *var_smtpd_sasl_appname;
+#define VAR_SMTPD_SASL_PATH    "smtpd_sasl_path"
+#define DEF_SMTPD_SASL_PATH    "smtpd"
+extern char *var_smtpd_sasl_path;
 
 #define VAR_SMTPD_SASL_TLS_OPTS        "smtpd_sasl_tls_security_options"
-#define DEF_SMTPD_SASL_TLS_OPTS        "$smtpd_sasl_security_options"
+#define DEF_SMTPD_SASL_TLS_OPTS        "$" VAR_SMTPD_SASL_OPTS
 extern char *var_smtpd_sasl_tls_opts;
 
 #define VAR_SMTPD_SASL_REALM   "smtpd_sasl_local_domain"
@@ -1262,6 +1262,14 @@ extern char *var_smtpd_sasl_realm;
 #define DEF_SMTPD_SASL_EXCEPTIONS_NETWORKS     ""
 extern char *var_smtpd_sasl_exceptions_networks;
 
+#ifndef DEF_SERVER_SASL_TYPE
+#define DEF_SERVER_SASL_TYPE   "cyrus"
+#endif
+
+#define VAR_SMTPD_SASL_TYPE    "smtpd_sasl_type"
+#define DEF_SMTPD_SASL_TYPE    DEF_SERVER_SASL_TYPE
+extern char *var_smtpd_sasl_type;
+
 #define VAR_SMTPD_SND_AUTH_MAPS        "smtpd_sender_login_maps"
 #define DEF_SMTPD_SND_AUTH_MAPS        ""
 extern char *var_smtpd_snd_auth_maps;
@@ -1287,16 +1295,30 @@ extern char *var_smtp_sasl_passwd;
 #define DEF_SMTP_SASL_OPTS     "noplaintext, noanonymous"
 extern char *var_smtp_sasl_opts;
 
+#define VAR_SMTP_SASL_PATH     "smtp_sasl_path"
+#define DEF_SMTP_SASL_PATH     ""
+extern char *var_smtp_sasl_path;
+
 #define VAR_SMTP_SASL_MECHS    "smtp_sasl_mechanism_filter"
 #define DEF_SMTP_SASL_MECHS    ""
 #define VAR_LMTP_SASL_MECHS    "lmtp_sasl_mechanism_filter"
 #define DEF_LMTP_SASL_MECHS    ""
 extern char *var_smtp_sasl_mechs;
 
+#ifndef DEF_CLIENT_SASL_TYPE
+#define DEF_CLIENT_SASL_TYPE   "cyrus"
+#endif
+
+#define VAR_SMTP_SASL_TYPE     "smtp_sasl_type"
+#define DEF_SMTP_SASL_TYPE     DEF_CLIENT_SASL_TYPE
+#define VAR_LMTP_SASL_TYPE     "lmtp_sasl_type"
+#define DEF_LMTP_SASL_TYPE     DEF_CLIENT_SASL_TYPE
+extern char *var_smtp_sasl_type;
+
 #define VAR_SMTP_SASL_TLS_OPTS "smtp_sasl_tls_security_options"
-#define DEF_SMTP_SASL_TLS_OPTS "$var_smtp_sasl_opts"
+#define DEF_SMTP_SASL_TLS_OPTS "$" VAR_SMTP_SASL_OPTS
 #define VAR_LMTP_SASL_TLS_OPTS "lmtp_sasl_tls_security_options"
-#define DEF_LMTP_SASL_TLS_OPTS "$var_lmtp_sasl_opts"
+#define DEF_LMTP_SASL_TLS_OPTS "$" VAR_LMTP_SASL_OPTS
 extern char *var_smtp_sasl_tls_opts;
 
  /*
@@ -1362,6 +1384,10 @@ extern char *var_lmtp_sasl_passwd;
 #define DEF_LMTP_SASL_OPTS     "noplaintext, noanonymous"
 extern char *var_lmtp_sasl_opts;
 
+#define VAR_LMTP_SASL_PATH     "lmtp_sasl_path"
+#define DEF_LMTP_SASL_PATH     ""
+extern char *var_lmtp_sasl_path;
+
  /*
   * SASL-based relay etc. control.
   */
@@ -1649,6 +1675,11 @@ extern int var_defer_code;
 
 #define SLEEP                  "sleep"
 
+#define REJECT_PLAINTEXT_SESSION "reject_plaintext_session"
+#define VAR_PLAINTEXT_CODE     "plaintext_reject_code"
+#define DEF_PLAINTEXT_CODE     450
+extern int var_plaintext_code;
+
 #define REJECT_UNKNOWN_CLIENT  "reject_unknown_client"
 #define REJECT_UNKNOWN_CLIENT_HOSTNAME "reject_unknown_client_hostname"
 #define REJECT_UNKNOWN_REVERSE_HOSTNAME "reject_unknown_reverse_client_hostname"
index b6e46ec5b324dad0a9531ac7ce0532726965e9a9..2612900dcc93c349d8b2a6319ee00c925e02e99b 100644 (file)
@@ -134,6 +134,9 @@ extern char *mail_pathname(const char *, const char *);
 #define MAIL_ATTR_CCERT_SUBJECT        "ccert_subject"
 #define MAIL_ATTR_CCERT_ISSSUER        "ccert_issuer"
 #define MAIL_ATTR_CCERT_FINGERPRINT "ccert_fingerprint"
+#define MAIL_ATTR_CRYPTO_PROTOCOL "encryption_protocol"
+#define MAIL_ATTR_CRYPTO_CYPHER        "encryption_cipher"
+#define MAIL_ATTR_CRYPTO_KEYSIZE "encryption_keysize"
 
  /*
   * Suffixes for sender_name, sender_domain etc.
index 317e55d5c595d66b196e18e9e3b8c149c1d37397..b2924d7be64b337733713c88248f7bd2bca36c95 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      "20051212"
+#define MAIL_RELEASE_DATE      "20051220"
 #define MAIL_VERSION_NUMBER    "2.3"
 
 #ifdef SNAPSHOT
index 4e1b83bc7c636ef5aa75d42f8471500c81225ae5..ead07996441cae625b99272226e590338ec3f660 100644 (file)
 /* DESCRIPTION
 /* .nf
 
+ /*
+  * System library.
+  */
+#include <ctype.h>
+#include <stdlib.h>
+
  /*
   * Diagnostic codes, not real record lookup results.
   */
index 56fdd8e2f2cf4c4bd6701275edac28ec598a8751..c99ae5b174bfa7eb4527597a0fd3a07af8992f40 100644 (file)
 #include <sys_defs.h>
 #include <string.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <msg.h>
index db3f9cb193e7961caf49683a87383cae2e5ce2f1..5aee04ba0a08943dd2bf561e6cc377a18afef9d5 100644 (file)
@@ -11,7 +11,7 @@ MAKES = bool_table.h bool_vars.h int_table.h int_vars.h str_table.h \
 PROG   = postconf
 SAMPLES        = ../../conf/main.cf.default
 INC_DIR        = ../../include
-LIBS   = ../../lib/libglobal.a ../../lib/libutil.a
+LIBS   = ../../lib/libxsasl.a ../../lib/libglobal.a ../../lib/libutil.a
 
 .c.o:; $(CC) $(CFLAGS) -c $*.c
 
@@ -97,6 +97,7 @@ postconf.o: ../../include/vbuf.h
 postconf.o: ../../include/vstream.h
 postconf.o: ../../include/vstring.h
 postconf.o: ../../include/vstring_vstream.h
+postconf.o: ../../include/xsasl.h
 postconf.o: auto_table.h
 postconf.o: auto_vars.h
 postconf.o: bool_table.h
index ed3796d4d50eb3937ca197139f9c877f74d1754f..be948313fe06c00393166b7d831f56097dba3fa7 100644 (file)
@@ -5,9 +5,11 @@
 /*     Postfix configuration utility
 /* SYNOPSIS
 /* .fi
-/*     \fBpostconf\fR [\fB-dhmlnv\fR] [\fB-c \fIconfig_dir\fR]
+/*     \fBpostconf\fR [\fB-dhnv\fR] [\fB-c \fIconfig_dir\fR]
 /*     [\fIparameter ...\fR]
 /*
+/*     \fBpostconf\fR [\fB-aAmlv\fR] [\fB-c \fIconfig_dir\fR]
+/*
 /*     \fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
 /*     [\fIparameter=value ...\fR]
 /*
 /*     the Postfix mail system.
 /*
 /*     Options:
+/* .IP \fB-a\fR
+/*     List the available SASL server plug-in types.  The SASL
+/*     plug-in type is selected with the \fBsmtpd_sasl_type\fR
+/*     configuration parameter.
+/*
+/*     This feature is available with Postfix 2.3 and later.
+/* .IP \fB-A\fR
+/*     List the available SASL client plug-in types.  The SASL
+/*     plug-in type is selected with the \fBsmtp_sasl_type\fR or
+/*     \fBlmtp_sasl_type\fR configuration parameters.
+/*
+/*     This feature is available with Postfix 2.3 and later.
 /* .IP "\fB-b\fR [\fItemplate_file\fR]"
 /*     Display the message text that appears at the beginning of
 /*     delivery status notification (DSN) messages, with $\fBname\fR
 #include <unistd.h>
 #include <ctype.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 #ifdef USE_PATHS_H
 #include <paths.h>
 #endif
 #include <mbox_conf.h>
 #include <mail_run.h>
 
+/* XSASL library. */
+
+#include <xsasl.h>
+
  /*
   * What we're supposed to be doing.
   */
 #define EDIT_MAIN      (1<<4)          /* edit main.cf */
 #define SHOW_LOCKS     (1<<5)          /* show mailbox lock methods */
 #define SHOW_EVAL      (1<<6)          /* expand right-hand sides */
+#define SHOW_SASL_SERV (1<<7)          /* show server auth plugin types */
+#define SHOW_SASL_CLNT (1<<7)          /* show client auth plugin types */
 
  /*
   * Lookup table for in-core parameter info.
@@ -878,13 +894,27 @@ static void show_maps(void)
 
 static void show_locks(void)
 {
-    ARGV   *maps_argv;
+    ARGV   *locks_argv;
     int     i;
 
-    maps_argv = mbox_lock_names();
-    for (i = 0; i < maps_argv->argc; i++)
-       vstream_printf("%s\n", maps_argv->argv[i]);
-    argv_free(maps_argv);
+    locks_argv = mbox_lock_names();
+    for (i = 0; i < locks_argv->argc; i++)
+       vstream_printf("%s\n", locks_argv->argv[i]);
+    argv_free(locks_argv);
+}
+
+/* show_sasl - show SASL plug-in types */
+
+static void show_sasl(int what)
+{
+    ARGV   *sasl_argv;
+    int     i;
+
+    sasl_argv = (what & SHOW_SASL_SERV) ? xsasl_server_types() :
+       xsasl_client_types();
+    for (i = 0; i < sasl_argv->argc; i++)
+       vstream_printf("%s\n", sasl_argv->argv[i]);
+    argv_free(sasl_argv);
 }
 
 /* show_parameters - show parameter info */
@@ -953,8 +983,14 @@ int     main(int argc, char **argv)
     /*
      * Parse JCL.
      */
-    while ((ch = GETOPT(argc, argv, "bc:deEhmlntv")) > 0) {
+    while ((ch = GETOPT(argc, argv, "aAbc:deEhmlntv")) > 0) {
        switch (ch) {
+       case 'a':
+           mode |= SHOW_SASL_SERV;
+           break;
+       case 'A':
+           mode |= SHOW_SASL_CLNT;
+           break;
        case 'b':
            if (ext_argv)
                msg_fatal("specify one of -b and -t");
@@ -1005,18 +1041,19 @@ int     main(int argc, char **argv)
            msg_verbose++;
            break;
        default:
-           msg_fatal("usage: %s [-b (bounce templates)] [-c config_dir] [-d (defaults)] [-e (edit)] [-h (no names)] [-l (lock types)] [-m (map types)] [-n (non-defaults)] [-v] [name...]", argv[0]);
+           msg_fatal("usage: %s [-a (server SASL types)] [-A (client SASL types)] [-b (bounce templates)] [-c config_dir] [-d (defaults)] [-e (edit)] [-h (no names)] [-l (lock types)] [-m (map types)] [-n (non-defaults)] [-v] [name...]", argv[0]);
        }
     }
 
     /*
      * Sanity check.
      */
-    junk = (mode & (SHOW_DEFS | SHOW_NONDEF | SHOW_MAPS | SHOW_LOCKS | EDIT_MAIN));
+    junk = (mode & (SHOW_DEFS | SHOW_NONDEF | SHOW_MAPS | SHOW_LOCKS | EDIT_MAIN | SHOW_SASL_SERV | SHOW_SASL_CLNT));
     if (junk != 0 && ((junk != SHOW_DEFS && junk != SHOW_NONDEF
-           && junk != SHOW_MAPS && junk != SHOW_LOCKS && junk != EDIT_MAIN)
+            && junk != SHOW_MAPS && junk != SHOW_LOCKS && junk != EDIT_MAIN
+                      && junk != SHOW_SASL_SERV && junk != SHOW_SASL_CLNT)
                      || ext_argv != 0))
-       msg_fatal("specify one of -b, -d, -e, -m, -l and -n");
+       msg_fatal("specify one of -a, -A, -b, -d, -e, -m, -l and -n");
 
     /*
      * Display bounce template information and exit.
@@ -1054,6 +1091,15 @@ int     main(int argc, char **argv)
        show_locks();
     }
 
+    /*
+     * If showing SASL plug-in types, show them and exit
+     */
+    else if (mode & SHOW_SASL_SERV) {
+       show_sasl(SHOW_SASL_SERV);
+    } else if (mode & SHOW_SASL_CLNT) {
+       show_sasl(SHOW_SASL_CLNT);
+    }
+
     /*
      * Edit main.cf.
      */
index 70f34cfb5090ab962cb8156f01bafd3daa2a42cf..44b377bad9a4e3b82e5850aad3eef3e36041c3c0 100644 (file)
@@ -451,6 +451,7 @@ int     main(int argc, char **argv)
      * Further initialization...
      */
     mail_conf_read();
+    mail_dict_init();                          /* proxy, sql, ldap */
     get_mail_conf_str_table(str_table);
 
     /*
index 558515d4c8f6a5beb09c737d9c96d7937b4191ec..bb8a5ab4ff0aa765d57f4681b28f690281b426cf 100644 (file)
 #include <ctype.h>
 #include <stdarg.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <msg.h>
index e05e77c8e10a09f1ccc6b6d25e5431eda55df391..a42e184d2083e4b9cfcc5d131cf4f14160fa6560 100644 (file)
@@ -75,16 +75,16 @@ void    qmqpd_peer_init(QMQPD_STATE *state)
     char   *myname = "qmqpd_peer_init";
     struct sockaddr_storage ss;
     struct sockaddr *sa;
-    SOCKADDR_SIZE sa_len;
+    SOCKADDR_SIZE sa_length;
     INET_PROTO_INFO *proto_info = inet_proto_info();
 
     sa = (struct sockaddr *) & ss;
-    sa_len = sizeof(ss);
+    sa_length = sizeof(ss);
 
     /*
      * Look up the peer address information.
      */
-    if (getpeername(vstream_fileno(state->client), sa, &sa_len) >= 0) {
+    if (getpeername(vstream_fileno(state->client), sa, &sa_length) >= 0) {
        errno = 0;
     }
 
@@ -121,7 +121,7 @@ void    qmqpd_peer_init(QMQPD_STATE *state)
        /*
         * Convert the client address to printable form.
         */
-       if ((aierr = sockaddr_to_hostaddr(sa, sa_len, &client_addr,
+       if ((aierr = sockaddr_to_hostaddr(sa, sa_length, &client_addr,
                                          (MAI_SERVPORT_STR *) 0, 0)) != 0)
            msg_fatal("%s: cannot convert client address to string: %s",
                      myname, MAI_STRERROR(aierr));
@@ -149,10 +149,10 @@ void    qmqpd_peer_init(QMQPD_STATE *state)
                if (aierr)
                    msg_fatal("%s: cannot convert %s from string to binary: %s",
                              myname, state->addr, MAI_STRERROR(aierr));
-               sa_len = res0->ai_addrlen;
-               if (sa_len > sizeof(ss))
-                   sa_len = sizeof(ss);
-               memcpy((char *) sa, res0->ai_addr, sa_len);
+               sa_length = res0->ai_addrlen;
+               if (sa_length > sizeof(ss))
+                   sa_length = sizeof(ss);
+               memcpy((char *) sa, res0->ai_addr, sa_length);
                freeaddrinfo(res0);
            }
 
@@ -195,7 +195,7 @@ void    qmqpd_peer_init(QMQPD_STATE *state)
        state->name = mystrdup(CLIENT_NAME_UNKNOWN); \
     }
 
-       if ((aierr = sockaddr_to_hostname(sa, sa_len, &client_name,
+       if ((aierr = sockaddr_to_hostname(sa, sa_length, &client_name,
                                          (MAI_SERVNAME_STR *) 0, 0)) != 0) {
            state->name = mystrdup(CLIENT_NAME_UNKNOWN);
        } else {
index b384472076befd418b8c920d18bb064654d6a549..00a4ed30b264fcb6fc29e7cf236bf9d430646f2f 100644 (file)
@@ -15,7 +15,7 @@ TESTPROG= smtp_unalias smtp_map11
 PROG   = smtp
 INC_DIR        = ../../include
 LIBS   = ../../lib/libmaster.a ../../lib/libtls.a ../../lib/libdns.a \
-       ../../lib/libglobal.a ../../lib/libutil.a
+       ../../lib/libxsasl.a ../../lib/libglobal.a ../../lib/libutil.a
 
 .c.o:; $(CC) $(CFLAGS) -c $*.c
 
@@ -38,7 +38,7 @@ update: ../../libexec/$(PROG)
 
 smtp.o:        smtp.c smtp_params.c lmtp_params.c
 
-lmtp_params.c: smtp_params.c $(INC_DIR)/mail_params.h
+lmtp_params.c: smtp_params.c
        egrep -v -f smtp-only smtp_params.c | \
            sed 's/SMTP/LMTP/g; s/smtp_\([a-z]*_table\)/lmtp_\1/' >$@
 
@@ -412,7 +412,6 @@ smtp_sasl_glue.o: ../../include/match_ops.h
 smtp_sasl_glue.o: ../../include/msg.h
 smtp_sasl_glue.o: ../../include/msg_stats.h
 smtp_sasl_glue.o: ../../include/mymalloc.h
-smtp_sasl_glue.o: ../../include/name_mask.h
 smtp_sasl_glue.o: ../../include/recipient_list.h
 smtp_sasl_glue.o: ../../include/resolve_clnt.h
 smtp_sasl_glue.o: ../../include/scache.h
@@ -425,6 +424,7 @@ smtp_sasl_glue.o: ../../include/tok822.h
 smtp_sasl_glue.o: ../../include/vbuf.h
 smtp_sasl_glue.o: ../../include/vstream.h
 smtp_sasl_glue.o: ../../include/vstring.h
+smtp_sasl_glue.o: ../../include/xsasl.h
 smtp_sasl_glue.o: smtp.h
 smtp_sasl_glue.o: smtp_sasl.h
 smtp_sasl_glue.o: smtp_sasl_glue.c
index 39f2018726dd7550e841c9dd62daed8100ca1b46..efb85e3e624594e2917c9c78b2a3e9a29f6cf7ee 100644 (file)
@@ -4,10 +4,12 @@
        VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
        VAR_LMTP_SASL_PASSWD, DEF_LMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
        VAR_LMTP_SASL_OPTS, DEF_LMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
+       VAR_LMTP_SASL_PATH, DEF_LMTP_SASL_PATH, &var_smtp_sasl_path, 0, 0,
 #ifdef USE_TLS
        VAR_LMTP_SASL_TLS_OPTS, DEF_LMTP_SASL_TLS_OPTS, &var_smtp_sasl_tls_opts, 0, 0,
 #endif
        VAR_LMTP_SASL_MECHS, DEF_LMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
+       VAR_LMTP_SASL_TYPE, DEF_LMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
        VAR_LMTP_BIND_ADDR, DEF_LMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
        VAR_LMTP_BIND_ADDR6, DEF_LMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
        VAR_LMTP_HELO_NAME, DEF_LMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
index ee1312b18421dd4fd672c3d76163529b364e405f..a2b862daaa87788dc6a34395b88e9d198912c71e 100644 (file)
 /* .ad
 /* .fi
 /*     SMTP destinations have the following form:
-/* .IP "\fIdomainname\fR, \fIdomainname\fR:\fIport\fR"
-/*     Look up the mail exchangers for the specified domain.
-/* .IP "[\fIhostname\fR], [\fIhostname\fR]:\fIport\fR"
-/*     Look up the address of the specified host.
-/* .IP "[\fIaddress\fR], [\fIaddress\fR]:\fIport\fR"
-/*     Connect to the host at the specified address. An IPv6
-/*     address must be formatted as [\fBipv6\fR:\fIaddress\fR].
-/* .PP
-/*     In all the above cases, when no port is specified, look up
-/*     the port defined as \fBsmtp\fR in \fBservices\fR(4).
+/* .IP \fIdomainname\fR
+/* .IP \fIdomainname\fR:\fIport\fR
+/*     Look up the mail exchangers for the specified domain, and
+/*     connect to the specified port (default: \fBsmtp\fR).
+/* .IP [\fIhostname\fR]
+/* .IP [\fIhostname\fR]:\fIport\fR
+/*     Look up the address(es) of the specified host, and connect to
+/*     the specified port (default: \fBsmtp\fR).
+/* .IP [\fIaddress\fR]
+/* .IP [\fIaddress\fR]:\fIport\fR
+/*     Connect to the host at the specified address, and connect
+/*     to the specified port (default: \fBsmtp\fR). An IPv6 address
+/*     must be formatted as [\fBipv6\fR:\fIaddress\fR].
 /* LMTP DESTINATION SYNTAX
 /* .ad
 /* .fi
 /*      Connect to the local UNIX-domain server that is bound to the specified
 /*      \fIpathname\fR. If the process runs chrooted, an absolute pathname
 /*      is interpreted relative to the Postfix queue directory.
-/* .IP "\fBinet\fR:\fIhostname\fR, \fBinet\fB:\fIhostname\fR:\fIport\fR"
-/* .IP "\fBinet\fR:[\fIaddress\fR], \fBinet\fR:[\fIaddress\fR]:\fIport\fR"
+/* .IP \fBinet\fR:\fIhostname\fR
+/* .IP \fBinet\fB:\fIhostname\fR:\fIport\fR
+/* .IP \fBinet\fR:[\fIaddress\fR]
+/* .IP \fBinet\fR:[\fIaddress\fR]:\fIport\fR
 /*      Connect to the specified TCP port on the specified local or
 /*      remote host. If no port is specified, connect to the port defined as
 /*      \fBlmtp\fR in \fBservices\fR(4).
 /*      If no such service is found, the \fBlmtp_tcp_port\fR configuration
 /*      parameter (default value of 24) will be used.
+/*     An IPv6 address must be formatted as [\fBipv6\fR:\fIaddress\fR].
 /* .PP
 /* SECURITY
 /* .ad
 /* CONFIGURATION PARAMETERS
 /* .ad
 /* .fi
+/*     Before Postfix version 2.3, the LMTP client is a separate
+/*     program that implements only a subset of the functionality
+/*     available with SMTP: there is no support for TLS, and
+/*     connections are cached in-process, making it ineffective
+/*     when the client is used for multiple domains.
+/*
 /*     Most smtp_\fIxxx\fR configuration parameters have an
 /*     lmtp_\fIxxx\fR "ghost" parameter for the equivalent LMTP
 /*     feature. This document describes only those LMTP-related
 /*     per remote hostname or domain, or sender address when sender-dependent
 /*     authentication is enabled.
 /* .IP "\fBsmtp_sasl_security_options (noplaintext, noanonymous)\fR"
-/*     What authentication mechanisms the Postfix SMTP client is allowed
-/*     to use.
+/*     SASL security options; as of Postfix 2.3 the list of available
+/*     features depends on the SASL client implementation that is selected
+/*     with \fBsmtp_sasl_type\fR.
 /* .PP
 /*     Available in Postfix version 2.2 and later:
 /* .IP "\fBsmtp_sasl_mechanism_filter (empty)\fR"
 /*     available only with SASL authentication, and disables SMTP connection
 /*     caching to ensure that mail from different senders will use the
 /*     appropriate credentials.
+/* .IP "\fBsmtp_sasl_path (empty)\fR"
+/*     Implementation-specific information that is passed through to
+/*     the SASL plug-in implementation that is selected with
+/*     \fBsmtp_sasl_type\fR.
+/* .IP "\fBsmtp_sasl_type (cyrus)\fR"
+/*     The SASL plug-in type that the Postfix SMTP client should use
+/*     for authentication.
 /* STARTTLS SUPPORT CONTROLS
 /* .ad
 /* .fi
 /*     The SMTP client time limit for sending the RSET command, and
 /*     for receiving the server response.
 /* .PP
+/*     Available in Postfix version 2.2 and earlier:
+/* .IP "\fBlmtp_cache_connection (yes)\fR"
+/*     Keep Postfix LMTP client connections open for up to $max_idle
+/*     seconds.
+/* .PP
 /*     Available in Postfix version 2.2 and later:
 /* .IP "\fBsmtp_connection_cache_destinations (empty)\fR"
 /*     Permanently enable SMTP connection caching for the specified
@@ -548,9 +573,11 @@ char   *var_error_rcpt;
 int     var_smtp_always_ehlo;
 int     var_smtp_never_ehlo;
 char   *var_smtp_sasl_opts;
+char   *var_smtp_sasl_path;
 char   *var_smtp_sasl_passwd;
 bool    var_smtp_sasl_enable;
 char   *var_smtp_sasl_mechs;
+char   *var_smtp_sasl_type;
 char   *var_smtp_bind_addr;
 char   *var_smtp_bind_addr6;
 bool    var_smtp_rand_addr;
@@ -799,16 +826,6 @@ static void pre_accept(char *unused_name, char **unused_argv)
     }
 }
 
-/* pre_exit - pre-exit cleanup */
-
-static void pre_exit(void)
-{
-#ifdef USE_SASL_AUTH
-    if (var_smtp_sasl_enable)
-       sasl_done();
-#endif
-}
-
 /* main - pass control to the single-threaded skeleton */
 
 int     main(int argc, char **argv)
@@ -837,6 +854,5 @@ int     main(int argc, char **argv)
                       MAIL_SERVER_PRE_INIT, pre_init,
                       MAIL_SERVER_POST_INIT, post_init,
                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
-                      MAIL_SERVER_EXIT, pre_exit,
                       0);
 }
index 2c9b785e3540a7367ed5e6ec03c10ac4a8618cc6..9e4e5c8edd111e70254d3ac7f7151f7bd6eefbad 100644 (file)
@@ -8,14 +8,6 @@
 /* DESCRIPTION
 /* .nf
 
- /*
-  * SASL library.
-  */
-#ifdef USE_SASL_AUTH
-#include <sasl.h>
-#include <saslutil.h>
-#endif
-
  /*
   * Utility library.
   */
@@ -208,10 +200,8 @@ typedef struct SMTP_SESSION {
     char   *sasl_mechanism_list;       /* server mechanism list */
     char   *sasl_username;             /* client username */
     char   *sasl_passwd;               /* client password */
-    sasl_conn_t *sasl_conn;            /* SASL internal state */
-    VSTRING *sasl_encoded;             /* encoding buffer */
-    VSTRING *sasl_decoded;             /* decoding buffer */
-    sasl_callback_t *sasl_callbacks;   /* stateful callbacks */
+    struct XSASL_CLIENT *sasl_client;  /* SASL internal state */
+    VSTRING *sasl_reply;               /* client response */
 #endif
 
     /*
@@ -433,6 +423,7 @@ extern void smtp_dsn_formal(DSN_BUF *, const char *, const char *, int,
   * Silly little macros.
   */
 #define STR(s) vstring_str(s)
+#define LEN(s) VSTRING_LEN(s)
 
 /* LICENSE
 /* .ad
index 61f7a389e2926613deec34067ef4dddfc5417f38..6008b2d0b1c76cc3326b68e9ffb3ce9db283d92c 100644 (file)
 
 #include "smtp.h"
 
-#define LEN    VSTRING_LEN
-
 /* smtp_chat_init - initialize SMTP transaction log */
 
 void    smtp_chat_init(SMTP_SESSION *session)
@@ -288,7 +286,9 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session)
         */
        session->error_mask |= MAIL_ERROR_PROTOCOL;
        if (session->features & SMTP_FEATURE_PIPELINING) {
-           msg_warn("non-SMTP response from %s: %s",
+           msg_warn("non-%s response from %s: %s",
+                    (session->state->misc_flags &
+                     SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP",
                     session->namaddr, STR(session->buffer));
            vstream_longjmp(session->stream, SMTP_ERR_PROTO);
        }
@@ -391,8 +391,11 @@ void    smtp_chat_notify(SMTP_SESSION *session)
     post_mail_fprintf(notice, "From: %s (Mail Delivery System)",
                      mail_addr_mail_daemon());
     post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt);
-    post_mail_fprintf(notice, "Subject: %s SMTP client: errors from %s",
-                     var_mail_name, session->namaddr);
+    post_mail_fprintf(notice, "Subject: %s %s client: errors from %s",
+                     var_mail_name,
+                     (session->state->misc_flags &
+                      SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "SMTP",
+                     session->namaddr);
     post_mail_fputs(notice, "");
     post_mail_fprintf(notice, "Unexpected response from %s.", session->namaddr);
     post_mail_fputs(notice, "");
index a3b79866b98715c54ea581ed83a854bd41316bb8..6e883116d27092c916e359dcce35210000b7de5f 100644 (file)
@@ -342,7 +342,8 @@ static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr * sa,
     if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
        smtp_dsn_update(why, DSN_BY_LOCAL_MTA,
                        "4.4.0", 421, "421 Lost connection",
-                       "connect to %s[%s]: server dropped connection without sending the initial SMTP greeting",
+                       "connect to %s[%s]: server dropped connection"
+                       " without sending the initial greeting",
                        addr->name, hostaddr.buf);
        smtp_errno = SMTP_ERR_RETRY;
        vstream_fclose(stream);
@@ -378,7 +379,7 @@ static char *smtp_parse_destination(char *destination, char *def_service,
      * destination argument so the parsing can be destructive.
      */
     if ((err = host_port(buf, hostp, (char *) 0, &service, def_service)) != 0)
-       msg_fatal("%s in SMTP server description: %s", err, destination);
+       msg_fatal("%s in server description: %s", err, destination);
 
     /*
      * Convert service to port number, network byte order.
index 8c42db3734e10167c9e0974217d5b1b8e93f0077..297dee8a03287d8ef04536e7bcf082c781ec0ea6 100644 (file)
 #include <sys_defs.h>
 #include <string.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <msg.h>
index 021229c434fd00c15befc1e7a7e0cd90f0d37ebe..f3a1494b1428618627b434111aa4acd4b68654d0 100644 (file)
@@ -5,10 +5,12 @@
        VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
        VAR_SMTP_SASL_PASSWD, DEF_SMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
        VAR_SMTP_SASL_OPTS, DEF_SMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
+       VAR_SMTP_SASL_PATH, DEF_SMTP_SASL_PATH, &var_smtp_sasl_path, 0, 0,
 #ifdef USE_TLS
        VAR_SMTP_SASL_TLS_OPTS, DEF_SMTP_SASL_TLS_OPTS, &var_smtp_sasl_tls_opts, 0, 0,
 #endif
        VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
+       VAR_SMTP_SASL_TYPE, DEF_SMTP_SASL_TYPE, &var_smtp_sasl_type, 1, 0,
        VAR_SMTP_BIND_ADDR, DEF_SMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
        VAR_SMTP_BIND_ADDR6, DEF_SMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
        VAR_SMTP_HELO_NAME, DEF_SMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
index bb92a2000afddfa7808202af64e1b766c0fbdcba..5fbe78d73032ec902e7d3e05a0f1643e02aabce7 100644 (file)
@@ -490,7 +490,9 @@ int     smtp_helo(SMTP_STATE *state)
                msg_fatal("%s: setsockopt: %m", myname);
        }
        if (msg_verbose)
-           msg_info("Using ESMTP PIPELINING, TCP send buffer size is %d",
+           msg_info("Using %s PIPELINING, TCP send buffer size is %d",
+                    (state->misc_flags &
+                     SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP",
                     session->sndbufsize);
     } else {
        session->sndbufsize = 0;
@@ -597,8 +599,18 @@ int     smtp_helo(SMTP_STATE *state)
     }
 #endif
 #ifdef USE_SASL_AUTH
-    if (var_smtp_sasl_enable && (session->features & SMTP_FEATURE_AUTH))
-       return (smtp_sasl_helo_login(state));
+    if (var_smtp_sasl_enable && (session->features & SMTP_FEATURE_AUTH)) {
+       if (session->sasl_mechanism_list != 0)
+           return (smtp_sasl_helo_login(state));
+       else
+           return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
+                                  SMTP_RESP_FAKE(&fake, 421, "4.7.0",
+                                         "421 SASL authentication failed: "
+                 "server offered no compatible authentication mechanisms"),
+                                  "SASL authentication failed: "
+               "server %s offered no compatible authentication mechanisms",
+                                  session->namaddr));
+    }
 #endif
 
     return (0);
index 8e78942d241956bc4bed634bc86a10580a9b638a..b08ed135c12d21274c19ab7337ff52d9b883d2bd 100644 (file)
@@ -1,6 +1,6 @@
 /*++
 /* NAME
-/*     smtp_sasl 3
+/*     smtp_sasl_glue 3
 /* SUMMARY
 /*     Postfix SASL interface for SMTP client
 /* SYNOPSIS
@@ -54,7 +54,7 @@
 /*     case of unsuccessful authentication, > 0 in case of success.
 /*     The why argument is updated with a reason for failure.
 /*     This routine must be called only when smtp_sasl_passwd_lookup()
-/*     suceeds.
+/*     succeeds.
 /*
 /*     smtp_sasl_cleanup() cleans up. It must be called at the
 /*     end of every SMTP session that uses SASL authentication.
@@ -97,9 +97,6 @@
 #include <sys_defs.h>
 #include <stdlib.h>
 #include <string.h>
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
 
  /*
   * Utility library
 #include <mymalloc.h>
 #include <stringops.h>
 #include <split_at.h>
-#include <name_mask.h>
 
  /*
   * Global library
 #include <maps.h>
 #include <mail_addr_find.h>
 
+ /*
+  * XSASL library.
+  */
+#include <xsasl.h>
+
  /*
   * Application-specific
   */
 
 #ifdef USE_SASL_AUTH
 
- /*
-  * Authentication security options.
-  */
-static NAME_MASK smtp_sasl_sec_mask[] = {
-    "noplaintext", SASL_SEC_NOPLAINTEXT,
-    "noactive", SASL_SEC_NOACTIVE,
-    "nodictionary", SASL_SEC_NODICTIONARY,
-    "noanonymous", SASL_SEC_NOANONYMOUS,
-#if SASL_VERSION_MAJOR >= 2
-    "mutual_auth", SASL_SEC_MUTUAL_AUTH,
-#endif
-    0,
-};
-
- /*
-  * Macros to handle API differences between SASLv1 and SASLv2. Specifics:
-  * 
-  * The SASL_LOG_* constants were renamed in SASLv2.
-  * 
-  * SASLv2's sasl_client_new takes two new parameters to specify local and
-  * remote IP addresses for auth mechs that use them.
-  * 
-  * SASLv2's sasl_client_start function no longer takes the secret parameter.
-  * 
-  * SASLv2's sasl_decode64 function takes an extra parameter for the length of
-  * the output buffer.
-  * 
-  * The other major change is that SASLv2 now takes more responsibility for
-  * deallocating memory that it allocates internally.  Thus, some of the
-  * function parameters are now 'const', to make sure we don't try to free
-  * them too.  This is dealt with in the code later on.
-  */
-
-#if SASL_VERSION_MAJOR < 2
-/* SASL version 1.x */
-#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
-       sasl_client_new(srv, fqdn, prompt, secflags, pconn)
-#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
-       sasl_client_start(conn, mechlst, secret, prompt, clout, cllen, mech)
-#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
-       sasl_decode64(in, inlen, out, outlen)
-#endif
-
-#if SASL_VERSION_MAJOR >= 2
-/* SASL version > 2.x */
-#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
-       sasl_client_new(srv, fqdn, lport, rport, prompt, secflags, pconn)
-#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
-       sasl_client_start(conn, mechlst, prompt, clout, cllen, mech)
-#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
-       sasl_decode64(in, inlen, out, outmaxlen, outlen)
-#endif
-
  /*
   * Per-host login/password information.
   */
@@ -189,119 +137,10 @@ static MAPS *smtp_sasl_passwd_map;
   */
 STRING_LIST *smtp_sasl_mechs;
 
-/* smtp_sasl_log - logging call-back routine */
-
-static int smtp_sasl_log(void *unused_context, int priority,
-                                const char *message)
-{
-    switch (priority) {
-       case SASL_LOG_ERR:              /* unusual errors */
-#ifdef SASL_LOG_WARN                   /* non-fatal warnings (Cyrus-SASL v2) */
-       case SASL_LOG_WARN:
-#endif
-#ifdef SASL_LOG_WARNING                        /* non-fatal warnings (Cyrus-SASL v1) */
-       case SASL_LOG_WARNING:
-#endif
-       msg_warn("SASL authentication problem: %s", message);
-       break;
-#ifdef SASL_LOG_INFO
-    case SASL_LOG_INFO:                        /* other info (Cyrus-SASL v1) */
-       if (msg_verbose)
-           msg_info("SASL authentication info: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_NOTE
-    case SASL_LOG_NOTE:                        /* other info (Cyrus-SASL v2) */
-       if (msg_verbose)
-           msg_info("SASL authentication info: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_FAIL
-    case SASL_LOG_FAIL:                        /* authentication failures
-                                                * (Cyrus-SASL v2) */
-       msg_warn("SASL authentication failure: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_DEBUG
-    case SASL_LOG_DEBUG:                       /* more verbose than LOG_NOTE
-                                                * (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication debug: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_TRACE
-    case SASL_LOG_TRACE:                       /* traces of internal
-                                                * protocols (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication trace: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_PASS
-    case SASL_LOG_PASS:                        /* traces of internal
-                                                * protocols, including
-                                                * passwords (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication pass: %s", message);
-       break;
-#endif
-    }
-    return (SASL_OK);
-}
-
-/* smtp_sasl_get_user - username lookup call-back routine */
-
-static int smtp_sasl_get_user(void *context, int unused_id, const char **result,
-                                     unsigned *len)
-{
-    char   *myname = "smtp_sasl_get_user";
-    SMTP_SESSION *session = (SMTP_SESSION *) context;
-
-    if (msg_verbose)
-       msg_info("%s: %s", myname, session->sasl_username);
-
-    /*
-     * Sanity check.
-     */
-    if (session->sasl_passwd == 0)
-       msg_panic("%s: no username looked up", myname);
-
-    *result = session->sasl_username;
-    if (len)
-       *len = strlen(session->sasl_username);
-    return (SASL_OK);
-}
-
-/* smtp_sasl_get_passwd - password lookup call-back routine */
-
-static int smtp_sasl_get_passwd(sasl_conn_t *conn, void *context,
-                                       int id, sasl_secret_t **psecret)
-{
-    char   *myname = "smtp_sasl_get_passwd";
-    SMTP_SESSION *session = (SMTP_SESSION *) context;
-    int     len;
-
-    if (msg_verbose)
-       msg_info("%s: %s", myname, session->sasl_passwd);
-
-    /*
-     * Sanity check.
-     */
-    if (!conn || !psecret || id != SASL_CB_PASS)
-       return (SASL_BADPARAM);
-    if (session->sasl_passwd == 0)
-       msg_panic("%s: no password looked up", myname);
-
-    /*
-     * Convert the password into a counted string.
-     */
-    len = strlen(session->sasl_passwd);
-    if ((*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len)) == 0)
-       return (SASL_NOMEM);
-    (*psecret)->len = len;
-    memcpy((*psecret)->data, session->sasl_passwd, len + 1);
-
-    return (SASL_OK);
-}
+ /*
+  * SASL implementation handle.
+  */
+static XSASL_CLIENT_IMPL *smtp_sasl_impl;
 
 /* smtp_sasl_passwd_lookup - password lookup routine */
 
@@ -358,43 +197,10 @@ int     smtp_sasl_passwd_lookup(SMTP_SESSION *session)
 void    smtp_sasl_initialize(void)
 {
 
-    /*
-     * Global callbacks. These have no per-session context.
-     */
-    static sasl_callback_t callbacks[] = {
-       {SASL_CB_LOG, &smtp_sasl_log, 0},
-       {SASL_CB_LIST_END, 0, 0}
-    };
-
-#if SASL_VERSION_MAJOR >= 2 && (SASL_VERSION_MINOR >= 2 \
-    || (SASL_VERSION_MINOR == 1 && SASL_VERSION_STEP >= 19))
-    int     sasl_major;
-    int     sasl_minor;
-    int     sasl_step;
-
-    /*
-     * DLL hell guard.
-     */
-    sasl_version_info((const char **) 0, (const char **) 0,
-                     &sasl_major, &sasl_minor,
-                     &sasl_step, (int *) 0);
-    if (sasl_major != SASL_VERSION_MAJOR
-#if 0
-       || sasl_minor != SASL_VERSION_MINOR
-       || sasl_step != SASL_VERSION_STEP
-#endif
-       )
-       msg_fatal("incorrect SASL library version. "
-             "Postfix was built with include files from version %d.%d.%d, "
-                 "but the run-time library version is %d.%d.%d",
-                 SASL_VERSION_MAJOR, SASL_VERSION_MINOR, SASL_VERSION_STEP,
-                 sasl_major, sasl_minor, sasl_step);
-#endif
-
     /*
      * Sanity check.
      */
-    if (smtp_sasl_passwd_map)
+    if (smtp_sasl_passwd_map || smtp_sasl_impl)
        msg_panic("smtp_sasl_initialize: repeated call");
     if (*var_smtp_sasl_passwd == 0)
        msg_fatal("specify a password table via the `%s' configuration parameter",
@@ -406,7 +212,8 @@ void    smtp_sasl_initialize(void)
      */
     smtp_sasl_passwd_map = maps_create("smtp_sasl_passwd",
                                       var_smtp_sasl_passwd, DICT_FLAG_LOCK);
-    if (sasl_client_init(callbacks) != SASL_OK)
+    if ((smtp_sasl_impl = xsasl_client_init(var_smtp_sasl_type,
+                                           var_smtp_sasl_path)) == 0)
        msg_fatal("SASL library initialization");
 
     /*
@@ -421,13 +228,16 @@ void    smtp_sasl_initialize(void)
 
 void    smtp_sasl_connect(SMTP_SESSION *session)
 {
+
+    /*
+     * This initialization happens whenever we instantiate an SMTP session
+     * object. We don't instantiate a SASL client until we actually need one.
+     */
     session->sasl_mechanism_list = 0;
     session->sasl_username = 0;
     session->sasl_passwd = 0;
-    session->sasl_conn = 0;
-    session->sasl_encoded = 0;
-    session->sasl_decoded = 0;
-    session->sasl_callbacks = 0;
+    session->sasl_client = 0;
+    session->sasl_reply = 0;
 }
 
 /* smtp_sasl_start - per-session SASL initialization */
@@ -435,62 +245,13 @@ void    smtp_sasl_connect(SMTP_SESSION *session)
 void    smtp_sasl_start(SMTP_SESSION *session, const char *sasl_opts_name,
                                const char *sasl_opts_val)
 {
-    static sasl_callback_t callbacks[] = {
-       {SASL_CB_USER, &smtp_sasl_get_user, 0},
-       {SASL_CB_AUTHNAME, &smtp_sasl_get_user, 0},
-       {SASL_CB_PASS, &smtp_sasl_get_passwd, 0},
-       {SASL_CB_LIST_END, 0, 0}
-    };
-    sasl_callback_t *cp;
-    sasl_security_properties_t sec_props;
-
     if (msg_verbose)
        msg_info("starting new SASL client");
-
-    /*
-     * Per-session initialization. Provide each session with its own callback
-     * context.
-     */
-#define NULL_SECFLAGS          0
-
-    session->sasl_callbacks = (sasl_callback_t *) mymalloc(sizeof(callbacks));
-    memcpy((char *) session->sasl_callbacks, callbacks, sizeof(callbacks));
-    for (cp = session->sasl_callbacks; cp->id != SASL_CB_LIST_END; cp++)
-       cp->context = (void *) session;
-
-#define NULL_SERVER_ADDR       ((char *) 0)
-#define NULL_CLIENT_ADDR       ((char *) 0)
-
-    if (SASL_CLIENT_NEW(var_procname, session->host,
-                       NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
-                       session->sasl_callbacks, NULL_SECFLAGS,
-                       (sasl_conn_t **) &session->sasl_conn) != SASL_OK)
-       msg_fatal("per-session SASL client initialization");
-
-    /*
-     * Per-session security properties. XXX This routine is not sufficiently
-     * documented. What is the purpose of all this?
-     */
-    memset(&sec_props, 0L, sizeof(sec_props));
-    sec_props.min_ssf = 0;
-    sec_props.max_ssf = 0;                     /* don't allow real SASL
-                                                * security layer */
-    sec_props.security_flags = name_mask(sasl_opts_name, smtp_sasl_sec_mask,
-                                        sasl_opts_val);
-    sec_props.maxbufsize = 0;
-    sec_props.property_names = 0;
-    sec_props.property_values = 0;
-    if (sasl_setprop(session->sasl_conn, SASL_SEC_PROPS,
-                    &sec_props) != SASL_OK)
-       msg_fatal("set per-session SASL security properties");
-
-    /*
-     * We use long-lived conversion buffers rather than local variables in
-     * order to avoid memory leaks in case of read/write timeout or I/O
-     * error.
-     */
-    session->sasl_encoded = vstring_alloc(10);
-    session->sasl_decoded = vstring_alloc(10);
+    if ((session->sasl_client =
+        xsasl_client_create(smtp_sasl_impl, session->stream, var_procname,
+                            session->host, sasl_opts_val)) == 0)
+       msg_fatal("SASL per-connection initialization failed");
+    session->sasl_reply = vstring_alloc(20);
 }
 
 /* smtp_sasl_authenticate - run authentication protocol */
@@ -498,27 +259,16 @@ void    smtp_sasl_start(SMTP_SESSION *session, const char *sasl_opts_name,
 int     smtp_sasl_authenticate(SMTP_SESSION *session, DSN_BUF *why)
 {
     char   *myname = "smtp_sasl_authenticate";
-    unsigned enc_length;
-    unsigned enc_length_out;
-
-#if SASL_VERSION_MAJOR >= 2
-    const char *clientout;
-
-#else
-    char   *clientout;
-
-#endif
-    unsigned clientoutlen;
-    unsigned serverinlen;
     SMTP_RESP *resp;
     const char *mechanism;
     int     result;
     char   *line;
 
-#define NO_SASL_SECRET         0
-#define NO_SASL_INTERACTION    0
-#define NO_SASL_LANGLIST       ((const char *) 0)
-#define NO_SASL_OUTLANG                ((const char **) 0)
+    /*
+     * Sanity check.
+     */
+    if (session->sasl_mechanism_list == 0)
+       msg_panic("%s: no mechanism list", myname);
 
     if (msg_verbose)
        msg_info("%s: %s: SASL mechanisms %s",
@@ -527,18 +277,16 @@ int     smtp_sasl_authenticate(SMTP_SESSION *session, DSN_BUF *why)
     /*
      * Start the client side authentication protocol.
      */
-    result = SASL_CLIENT_START((sasl_conn_t *) session->sasl_conn,
-                              session->sasl_mechanism_list,
-                              NO_SASL_SECRET, NO_SASL_INTERACTION,
-                              &clientout, &clientoutlen, &mechanism);
-    if (result != SASL_OK && result != SASL_CONTINUE) {
+    result = xsasl_client_first(session->sasl_client,
+                               session->sasl_mechanism_list,
+                               session->sasl_username,
+                               session->sasl_passwd,
+                               &mechanism, session->sasl_reply);
+    if (result != XSASL_AUTH_OK) {
        dsb_update(why, "4.7.0", DSB_DEF_ACTION, DSB_SKIP_RMTA, DSB_DTYPE_SASL,
-                  421, sasl_errstring(result, NO_SASL_LANGLIST,
-                                      NO_SASL_OUTLANG),
+                  421, STR(session->sasl_reply),
                   "cannot authenticate to server %s: %s",
-                  session->namaddr,
-                  sasl_errstring(result, NO_SASL_LANGLIST,
-                                 NO_SASL_OUTLANG));
+                  session->namaddr, STR(session->sasl_reply));
        return (-1);
     }
 
@@ -547,24 +295,9 @@ int     smtp_sasl_authenticate(SMTP_SESSION *session, DSN_BUF *why)
      * sasl_encode64() produces four bytes for each complete or incomplete
      * triple of input bytes. Allocate an extra byte for string termination.
      */
-#define ENCODE64_LENGTH(n)     ((((n) + 2) / 3) * 4)
-
-    if (clientoutlen > 0) {
-       if (msg_verbose)
-           msg_info("%s: %s: uncoded initial reply: %.*s",
-                  myname, session->namaddr, (int) clientoutlen, clientout);
-       enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
-       VSTRING_SPACE(session->sasl_encoded, enc_length);
-       if (sasl_encode64(clientout, clientoutlen,
-                         STR(session->sasl_encoded), enc_length,
-                         &enc_length_out) != SASL_OK)
-           msg_panic("%s: sasl_encode64 botch", myname);
-#if SASL_VERSION_MAJOR < 2
-       /* SASL version 1 doesn't free memory that it allocates. */
-       free(clientout);
-#endif
+    if (LEN(session->sasl_reply) > 0) {
        smtp_chat_cmd(session, "AUTH %s %s", mechanism,
-                     STR(session->sasl_encoded));
+                     STR(session->sasl_reply));
     } else {
        smtp_chat_cmd(session, "AUTH %s", mechanism);
     }
@@ -580,50 +313,21 @@ int     smtp_sasl_authenticate(SMTP_SESSION *session, DSN_BUF *why)
         */
        line = resp->str;
        (void) mystrtok(&line, "- \t\n");       /* skip over result code */
-       serverinlen = strlen(line);
-       VSTRING_SPACE(session->sasl_decoded, serverinlen);
-       if (SASL_DECODE64(line, serverinlen, STR(session->sasl_decoded),
-                         serverinlen, &enc_length) != SASL_OK) {
-           smtp_dsn_update(why, "5.7.0", DSN_BY_LOCAL_MTA,
-                           501, "501 malformed SASL challenge",
-                           "malformed SASL challenge from server %s",
-                           session->namaddr);
-           return (-1);
+       result = xsasl_client_next(session->sasl_client, line,
+                                  session->sasl_reply);
+       if (result != XSASL_AUTH_OK) {
+           dsb_update(why, "4.7.0", DSB_DEF_ACTION,    /* Fix 200512 */
+                      DSB_SKIP_RMTA, DSB_DTYPE_SASL,
+                      421, STR(session->sasl_reply),
+                      "cannot authenticate to server %s: %s",
+                      session->namaddr, STR(session->sasl_reply));
+           return (-1);                        /* Fix 200512 */
        }
-       if (msg_verbose)
-           msg_info("%s: %s: decoded challenge: %.*s",
-                    myname, session->namaddr, (int) enc_length,
-                    STR(session->sasl_decoded));
-       result = sasl_client_step((sasl_conn_t *) session->sasl_conn,
-                                 STR(session->sasl_decoded), enc_length,
-                           NO_SASL_INTERACTION, &clientout, &clientoutlen);
-       if (result != SASL_OK && result != SASL_CONTINUE)
-           msg_warn("SASL authentication failed to server %s: %s",
-                 session->namaddr, sasl_errstring(result, NO_SASL_LANGLIST,
-                                                  NO_SASL_OUTLANG));
 
        /*
         * Send a client response.
         */
-       if (clientoutlen > 0) {
-           if (msg_verbose)
-               msg_info("%s: %s: uncoded client response %.*s",
-                        myname, session->namaddr,
-                        (int) clientoutlen, clientout);
-           enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
-           VSTRING_SPACE(session->sasl_encoded, enc_length);
-           if (sasl_encode64(clientout, clientoutlen,
-                             STR(session->sasl_encoded), enc_length,
-                             &enc_length_out) != SASL_OK)
-               msg_panic("%s: sasl_encode64 botch", myname);
-#if SASL_VERSION_MAJOR < 2
-           /* SASL version 1 doesn't free memory that it allocates. */
-           free(clientout);
-#endif
-       } else {
-           vstring_strcat(session->sasl_encoded, "");
-       }
-       smtp_chat_cmd(session, "%s", STR(session->sasl_encoded));
+       smtp_chat_cmd(session, "%s", STR(session->sasl_reply));
     }
 
     /*
@@ -655,22 +359,15 @@ void    smtp_sasl_cleanup(SMTP_SESSION *session)
        myfree(session->sasl_mechanism_list);
        session->sasl_mechanism_list = 0;
     }
-    if (session->sasl_conn) {
+    if (session->sasl_client) {
        if (msg_verbose)
            msg_info("disposing SASL state information");
-       sasl_dispose(&session->sasl_conn);
-    }
-    if (session->sasl_callbacks) {
-       myfree((char *) session->sasl_callbacks);
-       session->sasl_callbacks = 0;
-    }
-    if (session->sasl_encoded) {
-       vstring_free(session->sasl_encoded);
-       session->sasl_encoded = 0;
+       xsasl_client_free(session->sasl_client);
+       session->sasl_client = 0;
     }
-    if (session->sasl_decoded) {
-       vstring_free(session->sasl_decoded);
-       session->sasl_decoded = 0;
+    if (session->sasl_reply) {
+       vstring_free(session->sasl_reply);
+       session->sasl_reply = 0;
     }
 }
 
index 153b041a5e789078f44be1e5daf2297d2a65a54e..699f163d2c5724211cc460f932ecbf3df501c857 100644 (file)
@@ -136,12 +136,12 @@ void    smtp_sasl_helo_auth(SMTP_SESSION *session, const char *words)
     }
     if (strlen(mech_list) > 0) {
        session->sasl_mechanism_list = mystrdup(mech_list);
-       session->features |= SMTP_FEATURE_AUTH;
     } else {
        msg_warn(*words ? "%s offered no supported AUTH mechanisms: '%s'" :
                 "%s offered null AUTH mechanism list",
                 session->namaddr, words);
     }
+    session->features |= SMTP_FEATURE_AUTH;
 }
 
 /* smtp_sasl_helo_login - perform SASL login */
index 6b42681f937959ea9bffb917ccd4d1bc91c93348..da78675d01a07494d5b6f03f583d1fe1a2278dfd 100644 (file)
@@ -14,7 +14,7 @@ TESTPROG= smtpd_token smtpd_check
 PROG   = smtpd
 INC_DIR        = ../../include
 LIBS   = ../../lib/libmaster.a ../../lib/libtls.a ../../lib/libdns.a \
-       ../../lib/libglobal.a ../../lib/libutil.a
+       ../../lib/libxsasl.a ../../lib/libglobal.a ../../lib/libutil.a
 
 .c.o:; $(CC) $(CFLAGS) -c $*.c
 
@@ -321,20 +321,16 @@ smtpd_proxy.o: smtpd_proxy.h
 smtpd_sasl_glue.o: ../../include/argv.h
 smtpd_sasl_glue.o: ../../include/mail_params.h
 smtpd_sasl_glue.o: ../../include/mail_stream.h
-smtpd_sasl_glue.o: ../../include/match_list.h
-smtpd_sasl_glue.o: ../../include/match_ops.h
 smtpd_sasl_glue.o: ../../include/msg.h
 smtpd_sasl_glue.o: ../../include/myaddrinfo.h
 smtpd_sasl_glue.o: ../../include/mymalloc.h
-smtpd_sasl_glue.o: ../../include/namadr_list.h
-smtpd_sasl_glue.o: ../../include/name_mask.h
-smtpd_sasl_glue.o: ../../include/smtp_stream.h
 smtpd_sasl_glue.o: ../../include/stringops.h
 smtpd_sasl_glue.o: ../../include/sys_defs.h
 smtpd_sasl_glue.o: ../../include/tls.h
 smtpd_sasl_glue.o: ../../include/vbuf.h
 smtpd_sasl_glue.o: ../../include/vstream.h
 smtpd_sasl_glue.o: ../../include/vstring.h
+smtpd_sasl_glue.o: ../../include/xsasl.h
 smtpd_sasl_glue.o: smtpd.h
 smtpd_sasl_glue.o: smtpd_chat.h
 smtpd_sasl_glue.o: smtpd_sasl_glue.c
index 6cdeb3a8bc5d705e62bfb54e64c73c589f1414e6..f0c37f90da27863adcc4146f96b07acd290aa24d 100644 (file)
 /*     version of the AUTH command (RFC 2554).
 /* .IP "\fBsmtpd_sasl_auth_enable (no)\fR"
 /*     Enable SASL authentication in the Postfix SMTP server.
-/* .IP "\fBsmtpd_sasl_application_name (smtpd)\fR"
-/*     The application name used for SASL server initialization.
 /* .IP "\fBsmtpd_sasl_local_domain (empty)\fR"
 /*     The name of the local SASL authentication realm.
 /* .IP "\fBsmtpd_sasl_security_options (noanonymous)\fR"
-/*     Restrict what authentication mechanisms the Postfix SMTP server
-/*     will offer to the client.
+/*     SASL security options; as of Postfix 2.3 the list of available
+/*     features depends on the SASL server implementation that is selected
+/*     with \fBsmtpd_sasl_type\fR.
 /* .IP "\fBsmtpd_sender_login_maps (empty)\fR"
 /*     Optional lookup table with the SASL login names that own sender
 /*     (MAIL FROM) addresses.
 /* .IP "\fBsmtpd_sasl_authenticated_header (no)\fR"
 /*     Report the SASL authenticated user name in the \fBsmtpd\fR(8) Received
 /*     message header.
+/* .IP "\fBsmtpd_sasl_path (smtpd)\fR"
+/*     Implementation-specific information that is passed through to
+/*     the SASL plug-in implementation that is selected with
+/*     \fBsmtpd_sasl_type\fR.
+/* .IP "\fBsmtpd_sasl_type (cyrus)\fR"
+/*     The SASL plug-in type that the Postfix SMTP server should use
+/*     for authentication.
 /* STARTTLS SUPPORT CONTROLS
 /* .ad
 /* .fi
 /*     The numerical Postfix SMTP server reply code when a client request
 /*     is rejected by the reject_non_fqdn_helo_hostname, reject_non_fqdn_sender
 /*     or reject_non_fqdn_recipient restriction.
+/* .IP "\fBplaintext_reject_code (450)\fR"
+/*     The numerical Postfix SMTP server response code when a request
+/*     is rejected by the \fBreject_plaintext_session\fR restriction.
 /* .IP "\fBreject_code (554)\fR"
 /*     The numerical Postfix SMTP server response code when a remote SMTP
 /*     client request is rejected by the "reject" restriction.
@@ -881,9 +890,10 @@ int     var_smtpd_rcpt_overlim;
 bool    var_smtpd_sasl_enable;
 bool    var_smtpd_sasl_auth_hdr;
 char   *var_smtpd_sasl_opts;
-char   *var_smtpd_sasl_appname;
+char   *var_smtpd_sasl_path;
 char   *var_smtpd_sasl_realm;
 char   *var_smtpd_sasl_exceptions_networks;
+char   *var_smtpd_sasl_type;
 char   *var_filter_xport;
 bool    var_broken_auth_clients;
 char   *var_perm_mx_networks;
@@ -945,6 +955,7 @@ char   *var_smtpd_sasl_tls_opts;
 #endif
 
 bool    var_smtpd_peername_lookup;
+int     var_plaintext_code;
 
  /*
   * Silly little macros.
@@ -3705,6 +3716,7 @@ int     main(int argc, char **argv)
        VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code, 0, 0,
        VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, 0, 0,
        VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, 0, 0,
+       VAR_PLAINTEXT_CODE, DEF_PLAINTEXT_CODE, &var_plaintext_code, 0, 0,
        VAR_VERIFY_POLL_COUNT, DEF_VERIFY_POLL_COUNT, &var_verify_poll_count, 1, 0,
        VAR_SMTPD_CRATE_LIMIT, DEF_SMTPD_CRATE_LIMIT, &var_smtpd_crate_limit, 0, 0,
        VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0,
@@ -3774,7 +3786,7 @@ int     main(int argc, char **argv)
        VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps, 0, 0,
        VAR_LOCAL_RCPT_MAPS, DEF_LOCAL_RCPT_MAPS, &var_local_rcpt_maps, 0, 0,
        VAR_SMTPD_SASL_OPTS, DEF_SMTPD_SASL_OPTS, &var_smtpd_sasl_opts, 0, 0,
-       VAR_SMTPD_SASL_APPNAME, DEF_SMTPD_SASL_APPNAME, &var_smtpd_sasl_appname, 1, 0,
+       VAR_SMTPD_SASL_PATH, DEF_SMTPD_SASL_PATH, &var_smtpd_sasl_path, 1, 0,
        VAR_SMTPD_SASL_REALM, DEF_SMTPD_SASL_REALM, &var_smtpd_sasl_realm, 0, 0,
        VAR_SMTPD_SASL_EXCEPTIONS_NETWORKS, DEF_SMTPD_SASL_EXCEPTIONS_NETWORKS, &var_smtpd_sasl_exceptions_networks, 0, 0,
        VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0,
@@ -3799,6 +3811,7 @@ int     main(int argc, char **argv)
        VAR_RELAY_CCERTS, DEF_RELAY_CCERTS, &var_smtpd_relay_ccerts, 0, 0,
        VAR_SMTPD_SASL_TLS_OPTS, DEF_SMTPD_SASL_TLS_OPTS, &var_smtpd_sasl_tls_opts, 0, 0,
 #endif
+       VAR_SMTPD_SASL_TYPE, DEF_SMTPD_SASL_TYPE, &var_smtpd_sasl_type, 1, 0,
        0,
     };
     static CONFIG_RAW_TABLE raw_table[] = {
index cb061f4160311176cb2130134b7aef5b4ba71e30..f1d9af340674c6a6b0121e95709e6a90976dbead 100644 (file)
 #include <sys/time.h>
 #include <unistd.h>
 
- /*
-  * SASL library.
-  */
-#ifdef USE_SASL_AUTH
-#include <sasl.h>
-#include <saslutil.h>
-#endif
-
  /*
   * Utility library.
   */
@@ -112,17 +104,12 @@ typedef struct SMTPD_STATE {
      * SASL specific.
      */
 #ifdef USE_SASL_AUTH
-#if SASL_VERSION_MAJOR >= 2
-    const char *sasl_mechanism_list;
-#else
+    struct XSASL_SERVER *sasl_server;
+    VSTRING *sasl_reply;
     char   *sasl_mechanism_list;
-#endif
     char   *sasl_method;
     char   *sasl_username;
     char   *sasl_sender;
-    sasl_conn_t *sasl_conn;
-    VSTRING *sasl_encoded;
-    VSTRING *sasl_decoded;
 #endif
 
     /*
index 86e2c4df0e76f1b64a4dcc4dfe24c2633096c7f5..5c4b07a19677c313045248d9a1bcd9e89cf4d8e4 100644 (file)
@@ -952,6 +952,24 @@ static int reject_unknown_client(SMTPD_STATE *state)
     return (SMTPD_CHECK_DUNNO);
 }
 
+/* reject_plaintext_session - fail if session is not encrypted */
+
+static int reject_plaintext_session(SMTPD_STATE *state)
+{
+#ifdef USE_TLS
+    char   *myname = "reject_plaintext_session";
+
+    if (msg_verbose)
+       msg_info("%s: %s %s", myname, state->name, state->addr);
+
+    if (state->tls_context == 0)
+       return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
+                                  var_plaintext_code, "4.7.1",
+                                  "Session encryption is required"));
+#endif
+    return (SMTPD_CHECK_DUNNO);
+}
+
 /* permit_inet_interfaces - succeed if client my own address */
 
 static int permit_inet_interfaces(SMTPD_STATE *state)
@@ -3283,6 +3301,13 @@ static int check_policy_service(SMTPD_STATE *state, const char *server,
                          IF_VERIFIED(state->tls_context->issuer_CN),
                          ATTR_TYPE_STR, MAIL_ATTR_CCERT_FINGERPRINT,
                          IF_VERIFIED(state->tls_context->peer_fingerprint),
+#define IF_ENCRYPTED(x) ((state->tls_context && ((x) != 0)) ? (x) : "")
+                         ATTR_TYPE_STR, MAIL_ATTR_CRYPTO_PROTOCOL,
+                         IF_ENCRYPTED(state->tls_context->protocol),
+                         ATTR_TYPE_STR, MAIL_ATTR_CRYPTO_CYPHER,
+                         IF_ENCRYPTED(state->tls_context->cipher_name),
+                         ATTR_TYPE_NUM, MAIL_ATTR_CRYPTO_KEYSIZE,
+                         state->tls_context->cipher_usebits,
 #endif
                          ATTR_TYPE_END,
                          ATTR_FLAG_MISSING,    /* Reply attributes. */
@@ -3456,6 +3481,10 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
                                           "Server configuration error"));
            } else
                sleep(atoi(*++cpp));
+#endif
+#ifdef USE_TLS
+       } else if (strcasecmp(name, REJECT_PLAINTEXT_SESSION) == 0) {
+           status = reject_plaintext_session(state);
 #endif
        }
 
index 034f9cefe4bd39d8e9f80f0622b032c14eae595c..7d46f3285f1e731986cb253a634103d8d9d93c79 100644 (file)
 void    smtpd_peer_init(SMTPD_STATE *state)
 {
     char   *myname = "smtpd_peer_init";
-    SOCKADDR_SIZE sa_len;
+    SOCKADDR_SIZE sa_length;
     struct sockaddr *sa;
     INET_PROTO_INFO *proto_info = inet_proto_info();
 
     sa = (struct sockaddr *) & (state->sockaddr);
-    sa_len = sizeof(state->sockaddr);
+    sa_length = sizeof(state->sockaddr);
 
     /*
      * Look up the peer address information.
      */
-    if (getpeername(vstream_fileno(state->client), sa, &sa_len) >= 0) {
+    if (getpeername(vstream_fileno(state->client), sa, &sa_length) >= 0) {
        errno = 0;
     }
 
@@ -179,7 +179,7 @@ void    smtpd_peer_init(SMTPD_STATE *state)
        /*
         * Convert the client address to printable form.
         */
-       if ((aierr = sockaddr_to_hostaddr(sa, sa_len, &client_addr,
+       if ((aierr = sockaddr_to_hostaddr(sa, sa_length, &client_addr,
                                          (MAI_SERVPORT_STR *) 0, 0)) != 0)
            msg_fatal("%s: cannot convert client address to string: %s",
                      myname, MAI_STRERROR(aierr));
@@ -207,10 +207,10 @@ void    smtpd_peer_init(SMTPD_STATE *state)
                if (aierr)
                    msg_fatal("%s: cannot convert %s from string to binary: %s",
                              myname, state->addr, MAI_STRERROR(aierr));
-               sa_len = res0->ai_addrlen;
-               if (sa_len > sizeof(state->sockaddr))
-                   sa_len = sizeof(state->sockaddr);
-               memcpy((char *) sa, res0->ai_addr, sa_len);
+               sa_length = res0->ai_addrlen;
+               if (sa_length > sizeof(state->sockaddr))
+                   sa_length = sizeof(state->sockaddr);
+               memcpy((char *) sa, res0->ai_addr, sa_length);
                freeaddrinfo(res0);             /* 200412 */
            }
 
@@ -262,7 +262,7 @@ void    smtpd_peer_init(SMTPD_STATE *state)
            state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
            state->name_status = SMTPD_PEER_CODE_PERM;
            state->reverse_name_status = SMTPD_PEER_CODE_PERM;
-       } else if ((aierr = sockaddr_to_hostname(sa, sa_len, &client_name,
+       } else if ((aierr = sockaddr_to_hostname(sa, sa_length, &client_name,
                                         (MAI_SERVNAME_STR *) 0, 0)) != 0) {
            state->name = mystrdup(CLIENT_NAME_UNKNOWN);
            state->reverse_name = mystrdup(CLIENT_NAME_UNKNOWN);
index 0bae676d952a6bc422d937294b995626b9635cd0..2cb7ca853fffb577831cf84651589d159cecb317 100644 (file)
 #include <sys_defs.h>
 #include <ctype.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include <msg.h>
index 10cfd371286ebfa422cf55fb5a27d59c7954efc9..76f5bb9f1c3b3c014b718294e1e8825d0b7fe48b 100644 (file)
@@ -6,10 +6,12 @@
 /* SYNOPSIS
 /*     #include "smtpd_sasl_glue.h"
 /*
-/*     void    smtpd_sasl_initialize()
+/*     void    smtpd_sasl_initialize()
 /*
 /*     void    smtpd_sasl_connect(state, sasl_opts_name, sasl_opts_val)
 /*     SMTPD_STATE *state;
+/*     const char *sasl_opts_name;
+/*     const char *sasl_opts_val;
 /*
 /*     char    *smtpd_sasl_authenticate(state, sasl_method, init_response)
 /*     SMTPD_STATE *state;
 /*     are the postfix configuration parameters setting the security
 /*     policy of the SASL authentication.
 /*
-/*     smtpd_sasl_authenticate() implements the authentication dialog.
-/*     The result is a null pointer in case of success, an SMTP reply
-/*     in case of failure. smtpd_sasl_authenticate() updates the
-/*     following state structure members:
+/*     smtpd_sasl_authenticate() implements the authentication
+/*     dialog.  The result is zero in case of success, -1 in case
+/*     of failure. smtpd_sasl_authenticate() updates the following
+/*     state structure members:
 /* .IP sasl_method
 /*     The authentication method that was successfully applied.
 /*     This member is a null pointer in the absence of successful
 /*     Arguments:
 /* .IP state
 /*     SMTP session context.
+/* .IP sasl_opts_name
+/*     Security options parameter name.
+/* .IP sasl_opts_val
+/*     Security options parameter value.
 /* .IP sasl_method
 /*     A SASL mechanism name
 /* .IP init_reply
 
 #include <msg.h>
 #include <mymalloc.h>
-#include <namadr_list.h>
-#include <name_mask.h>
 #include <stringops.h>
 
 /* Global library. */
 
 #include <mail_params.h>
-#include <smtp_stream.h>
+
+/* XSASL library. */
+
+#include <xsasl.h>
 
 /* Application-specific. */
 
 #define STR(s) vstring_str(s)
 
  /*
-  * Macros to handle API differences between SASLv1 and SASLv2. Specifics:
-  * 
-  * The SASL_LOG_* constants were renamed in SASLv2.
-  * 
-  * SASLv2's sasl_server_new takes two new parameters to specify local and
-  * remote IP addresses for auth mechs that use them.
-  * 
-  * SASLv2's sasl_server_start and sasl_server_step no longer have the errstr
-  * parameter.
-  * 
-  * SASLv2's sasl_decode64 function takes an extra parameter for the length of
-  * the output buffer.
-  * 
-  * The other major change is that SASLv2 now takes more responsibility for
-  * deallocating memory that it allocates internally.  Thus, some of the
-  * function parameters are now 'const', to make sure we don't try to free
-  * them too.  This is dealt with in the code later on.
+  * SASL server implementation handle.
   */
-
-#if SASL_VERSION_MAJOR < 2
-/* SASL version 1.x */
-#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
-       sasl_server_new(srv, fqdn, rlm, cb, secflags, pconn)
-#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
-       sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen, err)
-#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
-       sasl_server_step(conn, clin, clinlen, srvout, srvoutlen, err)
-#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
-       sasl_decode64(in, inlen, out, outlen)
-#endif
-
-#if SASL_VERSION_MAJOR >= 2
-/* SASL version > 2.x */
-#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
-       sasl_server_new(srv, fqdn, rlm, lport, rport, cb, secflags, pconn)
-#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
-       sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen)
-#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
-       sasl_server_step(conn, clin, clinlen, srvout, srvoutlen)
-#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
-       sasl_decode64(in, inlen, out, outmaxlen, outlen)
-#endif
-
-/* smtpd_sasl_log - SASL logging callback */
-
-static int smtpd_sasl_log(void *unused_context, int priority,
-                                 const char *message)
-{
-    switch (priority) {
-       case SASL_LOG_ERR:              /* unusual errors */
-#ifdef SASL_LOG_WARN                   /* non-fatal warnings (Cyrus-SASL v2) */
-       case SASL_LOG_WARN:
-#endif
-#ifdef SASL_LOG_WARNING                        /* non-fatal warnings (Cyrus-SASL v1) */
-       case SASL_LOG_WARNING:
-#endif
-       msg_warn("SASL authentication problem: %s", message);
-       break;
-#ifdef SASL_LOG_INFO
-    case SASL_LOG_INFO:                        /* other info (Cyrus-SASL v1) */
-       if (msg_verbose)
-           msg_info("SASL authentication info: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_NOTE
-    case SASL_LOG_NOTE:                        /* other info (Cyrus-SASL v2) */
-       if (msg_verbose)
-           msg_info("SASL authentication info: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_FAIL
-    case SASL_LOG_FAIL:                        /* authentication failures
-                                                * (Cyrus-SASL v2) */
-       msg_warn("SASL authentication failure: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_DEBUG
-    case SASL_LOG_DEBUG:                       /* more verbose than LOG_NOTE
-                                                * (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication debug: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_TRACE
-    case SASL_LOG_TRACE:                       /* traces of internal
-                                                * protocols (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication trace: %s", message);
-       break;
-#endif
-#ifdef SASL_LOG_PASS
-    case SASL_LOG_PASS:                        /* traces of internal
-                                                * protocols, including
-                                                * passwords (Cyrus-SASL v2) */
-       if (msg_verbose > 1)
-           msg_info("SASL authentication pass: %s", message);
-       break;
-#endif
-    }
-    return (SASL_OK);
-}
-
- /*
-  * SASL callback interface structure. These call-backs have no per-session
-  * context.
-  */
-#define NO_CALLBACK_CONTEXT    0
-
-static sasl_callback_t callbacks[] = {
-    {SASL_CB_LOG, &smtpd_sasl_log, NO_CALLBACK_CONTEXT},
-    {SASL_CB_LIST_END, 0, 0}
-};
-
-static NAME_MASK smtpd_sasl_mask[] = {
-    "noplaintext", SASL_SEC_NOPLAINTEXT,
-    "noactive", SASL_SEC_NOACTIVE,
-    "nodictionary", SASL_SEC_NODICTIONARY,
-    "noanonymous", SASL_SEC_NOANONYMOUS,
-#if SASL_VERSION_MAJOR >= 2
-    "mutual_auth", SASL_SEC_MUTUAL_AUTH,
-#endif
-    0,
-};
+static XSASL_SERVER_IMPL *smtpd_sasl_impl;
 
 /* smtpd_sasl_initialize - per-process initialization */
 
 void    smtpd_sasl_initialize(void)
 {
-#if SASL_VERSION_MAJOR >= 2 && (SASL_VERSION_MINOR >= 2 \
-    || (SASL_VERSION_MINOR == 1 && SASL_VERSION_STEP >= 19))
-    int     sasl_major;
-    int     sasl_minor;
-    int     sasl_step;
 
     /*
-     * DLL hell guard.
+     * Sanity check.
      */
-    sasl_version_info((const char **) 0, (const char **) 0,
-                     &sasl_major, &sasl_minor,
-                     &sasl_step, (int *) 0);
-    if (sasl_major != SASL_VERSION_MAJOR
-#if 0
-       || sasl_minor != SASL_VERSION_MINOR
-       || sasl_step != SASL_VERSION_STEP
-#endif
-       )
-       msg_fatal("incorrect SASL library version. "
-             "Postfix was built with include files from version %d.%d.%d, "
-                 "but the run-time library version is %d.%d.%d",
-                 SASL_VERSION_MAJOR, SASL_VERSION_MINOR, SASL_VERSION_STEP,
-                 sasl_major, sasl_minor, sasl_step);
-#endif
+    if (smtpd_sasl_impl)
+       msg_panic("smtpd_sasl_initialize: repeated call");
 
     /*
-     * Initialize the library: load SASL plug-in routines, etc.
+     * Initialize the SASL library.
      */
-    if (msg_verbose)
-       msg_info("smtpd_sasl_initialize: SASL config file is %s.conf",
-                var_smtpd_sasl_appname);
-    if (sasl_server_init(callbacks, var_smtpd_sasl_appname) != SASL_OK)
+    if ((smtpd_sasl_impl = xsasl_server_init(var_smtpd_sasl_type,
+                                            var_smtpd_sasl_path)) == 0)
        msg_fatal("SASL per-process initialization failed");
 
 }
@@ -283,16 +150,7 @@ void    smtpd_sasl_initialize(void)
 void    smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
                                   const char *sasl_opts_val)
 {
-#if SASL_VERSION_MAJOR < 2
-    unsigned sasl_mechanism_count;
-
-#else
-    int     sasl_mechanism_count;
-
-#endif
-    sasl_security_properties_t sec_props;
-    char   *server_address;
-    char   *client_address;
+    const char *mechanism_list;
 
     /*
      * Initialize SASL-specific state variables. Use long-lived storage for
@@ -300,246 +158,114 @@ void    smtpd_sasl_connect(SMTPD_STATE *state, const char *sasl_opts_name,
      * memory leaks when a read or write routine returns abnormally after
      * timeout or I/O error.
      */
+    state->sasl_reply = vstring_alloc(20);
     state->sasl_mechanism_list = 0;
     state->sasl_username = 0;
     state->sasl_method = 0;
     state->sasl_sender = 0;
-    state->sasl_conn = 0;
-    state->sasl_decoded = vstring_alloc(10);
-    state->sasl_encoded = vstring_alloc(10);
 
     /*
      * Set up a new server context for this connection.
      */
-#define NO_SECURITY_LAYERS     (0)
-#define NO_SESSION_CALLBACKS   ((sasl_callback_t *) 0)
-#define NO_AUTH_REALM          ((char *) 0)
-
-#if SASL_VERSION_MAJOR >= 2 && defined(USE_SASL_IP_AUTH)
-
-    /*
-     * Get IP addresses of local and remote endpoints for SASL.
-     */
-#error "USE_SASL_IP_AUTH is not implemented"
-
-#else
-
-    /*
-     * Don't give any IP address information to SASL.  SASLv1 doesn't use it,
-     * and in SASLv2 this will disable any mechaniams that do.
-     */
-    server_address = 0;
-    client_address = 0;
-#endif
-
-    if (SASL_SERVER_NEW("smtp", var_myhostname, *var_smtpd_sasl_realm ?
-                       var_smtpd_sasl_realm : NO_AUTH_REALM,
-                       server_address, client_address,
-                       NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
-                       &state->sasl_conn) != SASL_OK)
-       msg_fatal("SASL per-connection server initialization");
+#define SMTPD_SASL_SERVICE "smtp"
 
-    /*
-     * Security options. Some information can be found in the sasl.h include
-     * file. Disallow anonymous authentication; this is because the
-     * permit_sasl_authenticated feature is restricted to authenticated
-     * clients only.
-     */
-    memset(&sec_props, 0, sizeof(sec_props));
-    sec_props.min_ssf = 0;
-    sec_props.max_ssf = 0;                     /* don't allow real SASL
-                                                * security layer */
-    sec_props.security_flags = name_mask(sasl_opts_name, smtpd_sasl_mask,
-                                        sasl_opts_val);
-    sec_props.maxbufsize = 0;
-    sec_props.property_names = 0;
-    sec_props.property_values = 0;
-
-    if (sasl_setprop(state->sasl_conn, SASL_SEC_PROPS,
-                    &sec_props) != SASL_OK)
-       msg_fatal("SASL per-connection security setup");
+    if ((state->sasl_server =
+        xsasl_server_create(smtpd_sasl_impl, state->client,
+                            SMTPD_SASL_SERVICE, *var_smtpd_sasl_realm ?
+                            var_smtpd_sasl_realm : (char *) 0,
+                            sasl_opts_val)) == 0)
+       msg_fatal("SASL per-connection initialization failed");
 
     /*
      * Get the list of authentication mechanisms.
      */
-#define UNSUPPORTED_USER       ((char *) 0)
-#define IGNORE_MECHANISM_LEN   ((unsigned *) 0)
-
-    if (sasl_listmech(state->sasl_conn, UNSUPPORTED_USER,
-                     "", " ", "",
-                     &state->sasl_mechanism_list,
-                     IGNORE_MECHANISM_LEN,
-                     &sasl_mechanism_count) != SASL_OK)
-       msg_fatal("cannot lookup SASL authentication mechanisms");
-    if (sasl_mechanism_count <= 0)
+    if ((mechanism_list =
+        xsasl_server_get_mechanism_list(state->sasl_server)) == 0)
        msg_fatal("no SASL authentication mechanisms");
+    state->sasl_mechanism_list = mystrdup(mechanism_list);
 }
 
 /* smtpd_sasl_disconnect - per-connection cleanup */
 
 void    smtpd_sasl_disconnect(SMTPD_STATE *state)
 {
+    if (state->sasl_reply) {
+       vstring_free(state->sasl_reply);
+       state->sasl_reply = 0;
+    }
     if (state->sasl_mechanism_list) {
-#if SASL_VERSION_MAJOR < 2
-       /* SASL version 1 doesn't free memory that it allocates. */
-       free(state->sasl_mechanism_list);
-#endif
+       myfree(state->sasl_mechanism_list);
        state->sasl_mechanism_list = 0;
     }
-    if (state->sasl_conn) {
-       sasl_dispose(&state->sasl_conn);
-       state->sasl_conn = 0;
+    if (state->sasl_username) {
+       myfree(state->sasl_username);
+       state->sasl_username = 0;
+    }
+    if (state->sasl_method) {
+       myfree(state->sasl_method);
+       state->sasl_method = 0;
+    }
+    if (state->sasl_sender) {
+       myfree(state->sasl_sender);
+       state->sasl_sender = 0;
+    }
+    if (state->sasl_server) {
+       xsasl_server_free(state->sasl_server);
+       state->sasl_server = 0;
     }
-    vstring_free(state->sasl_decoded);
-    vstring_free(state->sasl_encoded);
 }
 
 /* smtpd_sasl_authenticate - per-session authentication */
 
-char   *smtpd_sasl_authenticate(SMTPD_STATE *state,
+int     smtpd_sasl_authenticate(SMTPD_STATE *state,
                                        const char *sasl_method,
                                        const char *init_response)
 {
-    char   *myname = "smtpd_sasl_authenticate";
-    char   *dec_buffer;
-    unsigned dec_length;
-    unsigned enc_length;
-    unsigned enc_length_out;
-    unsigned reply_len;
-    unsigned serveroutlen;
-    int     result;
-
-#if SASL_VERSION_MAJOR < 2
-    char   *serverout = 0;
-
-#else
-    const char *serverout = 0;
-
-#endif
-
-#if SASL_VERSION_MAJOR < 2
-    const char *errstr = 0;
-
-#endif
-
-#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
-
-    if (msg_verbose)
-       msg_info("%s: sasl_method %s%s%s", myname, sasl_method,
-                IFELSE(init_response, ", init_response ", ""),
-                IFELSE(init_response, init_response, ""));
-
-    /*
-     * Sanity check.
-     */
-    if (state->sasl_username || state->sasl_method)
-       msg_panic("%s: already authenticated", myname);
+    int     status;
+    const char *sasl_username;
 
     /*
      * SASL authentication protocol start-up. Process any initial client
      * response that was sent along in the AUTH command.
      */
-    if (init_response) {
-       reply_len = strlen(init_response);
-       VSTRING_SPACE(state->sasl_decoded, reply_len);
-       dec_buffer = STR(state->sasl_decoded);
-       if (SASL_DECODE64(init_response, reply_len,
-                         dec_buffer, reply_len, &dec_length) != SASL_OK)
-           return ("501 5.7.0 Authentication failed: malformed initial response");
-       if (msg_verbose)
-           msg_info("%s: decoded initial response %s", myname, dec_buffer);
-    } else {
-       dec_buffer = 0;
-       dec_length = 0;
-    }
-    result = SASL_SERVER_START(state->sasl_conn, sasl_method, dec_buffer,
-                           dec_length, &serverout, &serveroutlen, &errstr);
-
-    /*
-     * Repeat until done or until the client gives up.
-     */
-    while (result == SASL_CONTINUE) {
+    for (status = xsasl_server_first(state->sasl_server, sasl_method,
+                                    init_response, state->sasl_reply);
+        status == XSASL_AUTH_MORE;
+        status = xsasl_server_next(state->sasl_server, STR(state->buffer),
+                                   state->sasl_reply)) {
 
        /*
-        * Send a server challenge. Avoid storing the challenge in a local
-        * variable, because we would leak memory when smtpd_chat_reply()
-        * does not return due to timeout or I/O error. sasl_encode64()
-        * null-terminates the result if the result buffer is large enough.
-        * 
-        * Regarding the hairy expression below: output from sasl_encode64()
-        * comes in multiples of four bytes for each triple of input bytes,
-        * plus four bytes for any incomplete last triple, plus one byte for
-        * the null terminator.
-        * 
-        * XXX Replace the klunky sasl_encode64() interface by something that
-        * uses VSTRING buffers.
+        * Send a server challenge.
         */
-       if (msg_verbose)
-           msg_info("%s: uncoded challenge: %.*s",
-                    myname, (int) serveroutlen, serverout);
-       enc_length = ((serveroutlen + 2) / 3) * 4 + 1;
-       VSTRING_SPACE(state->sasl_encoded, enc_length);
-       if (sasl_encode64(serverout, serveroutlen, STR(state->sasl_encoded),
-                         enc_length, &enc_length_out) != SASL_OK)
-           msg_panic("%s: sasl_encode64 botch", myname);
-#if SASL_VERSION_MAJOR < 2
-       /* SASL version 1 doesn't free memory that it allocates. */
-       free(serverout);
-#endif
-       serverout = 0;
-       smtpd_chat_reply(state, "334 %s", STR(state->sasl_encoded));
+       smtpd_chat_reply(state, "334 %s", STR(state->sasl_reply));
 
        /*
         * Receive the client response. "*" means that the client gives up.
-        * XXX For now we ignore the fact that excessively long responses
-        * will be truncated. To handle such responses, we need to change
-        * smtpd_chat_query() so that it returns an error indication.
+        * XXX For now we ignore the fact that an excessively long response
+        * will be chopped into multiple reponses. To handle such responses,
+        * we need to change smtpd_chat_query() so that it returns an error
+        * indication.
         */
        smtpd_chat_query(state);
-       if (strcmp(vstring_str(state->buffer), "*") == 0)
-           return ("501 5.7.0 Authentication aborted");        /* XXX */
-       reply_len = VSTRING_LEN(state->buffer);
-       VSTRING_SPACE(state->sasl_decoded, reply_len);
-       if (SASL_DECODE64(vstring_str(state->buffer), reply_len,
-                         STR(state->sasl_decoded), reply_len,
-                         &dec_length) != SASL_OK)
-           return ("501 5.7.0 Error: malformed authentication response");
-       if (msg_verbose)
-           msg_info("%s: decoded response: %.*s",
-                    myname, (int) dec_length, STR(state->sasl_decoded));
-       result = SASL_SERVER_STEP(state->sasl_conn, STR(state->sasl_decoded),
-                           dec_length, &serverout, &serveroutlen, &errstr);
+       if (strcmp(STR(state->buffer), "*") == 0) {
+           msg_warn("%s[%s]: SASL %s authentication aborted",
+                    state->name, state->addr, sasl_method);
+           smtpd_chat_reply(state, "501 5.7.0 Authentication aborted");
+           return (-1);
+       }
     }
-
-    /*
-     * Cleanup. What an awful interface.
-     */
-#if SASL_VERSION_MAJOR < 2
-    if (serverout)
-       free(serverout);
-#endif
-
-    /*
-     * The authentication protocol was completed.
-     */
-    if (result != SASL_OK)
-       return ("535 5.7.0 Error: authentication failed");
-
-    /*
-     * Authentication succeeded. Find out the login name for logging and for
-     * accounting purposes. For the sake of completeness we also record the
-     * authentication method that was used. XXX Do not free(serverout).
-     */
-#if SASL_VERSION_MAJOR >= 2
-    result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
-                         (const void **) &serverout);
-#else
-    result = sasl_getprop(state->sasl_conn, SASL_USERNAME,
-                         (void **) &serverout);
-#endif
-    if (result != SASL_OK || serverout == 0)
-       msg_panic("%s: sasl_getprop SASL_USERNAME botch", myname);
-    state->sasl_username = mystrdup(serverout);
+    if (status != XSASL_AUTH_DONE) {
+       msg_warn("%s[%s]: SASL %s authentication failed: %s",
+                state->name, state->addr, sasl_method,
+                STR(state->sasl_reply));
+       smtpd_chat_reply(state, "535 5.7.0 Error: authentication failed: %s",
+                        STR(state->sasl_reply));
+       return (-1);
+    }
+    smtpd_chat_reply(state, "235 2.0.0 Authentication successful");
+    if ((sasl_username = xsasl_server_get_username(state->sasl_server)) == 0)
+       msg_panic("cannot look up the authenticated SASL username");
+    state->sasl_username = mystrdup(sasl_username);
     printable(state->sasl_username, '?');
     state->sasl_method = mystrdup(sasl_method);
     printable(state->sasl_method, '?');
index 2466f9a57e0df2e5a9aafab6270d3dd5bb4dcfd1..b11981cd6cf1fa0d59472ad3ea27ffbb0231b007 100644 (file)
@@ -4,7 +4,7 @@
 /* SUMMARY
 /*     Postfix SMTP server, SASL support interface
 /* SYNOPSIS
-/*     #include "smtpd_sasl.h"
+/*     #include "smtpd_sasl_glue.h"
 /* DESCRIPTION
 /* .nf
 
@@ -14,7 +14,7 @@
 extern void smtpd_sasl_initialize(void);
 extern void smtpd_sasl_connect(SMTPD_STATE *, const char *, const char *);
 extern void smtpd_sasl_disconnect(SMTPD_STATE *);
-extern char *smtpd_sasl_authenticate(SMTPD_STATE *, const char *, const char *);
+extern int smtpd_sasl_authenticate(SMTPD_STATE *, const char *, const char *);
 extern void smtpd_sasl_logout(SMTPD_STATE *);
 extern int permit_sasl_auth(SMTPD_STATE *, int, int);
 
index 3e200cdfcfe2d6658ac808a06c462305b17d950b..e7c2edd4a8d221dfd7bc8ab13d0d851e1ea6515c 100644 (file)
@@ -5,7 +5,7 @@
 /*     Postfix SMTP protocol support for SASL authentication
 /* SYNOPSIS
 /*     #include "smtpd.h"
-/*     #include "smtpd_sasl.h"
+/*     #include "smtpd_sasl_proto.h"
 /*
 /*     void    smtpd_sasl_auth_cmd(state, argc, argv)
 /*     SMTPD_STATE *state;
 /*     the SMTP protocol interface for SASL negotiation. The goal
 /*     is to reduce clutter of the main SMTP server source code.
 /*
-/*     smtpd_sasl_auth_cmd() implements the AUTH command.
-/*
+/*     smtpd_sasl_auth_cmd() implements the AUTH command and updates
+/*     the following state structure members:
+/* .IP sasl_method
+/*     The authentication method that was successfully applied.
+/*     This member is a null pointer in the absence of successful
+/*     authentication.
+/* .IP sasl_username
+/*     The username that was successfully authenticated.
+/*     This member is a null pointer in the absence of successful
+/*     authentication.
+/* .PP
 /*     smtpd_sasl_auth_reset() cleans up after the AUTH command.
+/*     This is required before smtpd_sasl_auth_cmd() can be used again.
 /*
 /*     smtpd_sasl_mail_opt() implements the SASL-specific AUTH=sender
 /*     option to the MAIL FROM command. The result is an error response
 #include <sys_defs.h>
 #include <string.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include <msg.h>
@@ -124,7 +138,6 @@ int     smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
 {
     char   *auth_mechanism;
     char   *initial_response;
-    char   *err;
 
     if (var_helo_required && state->helo_name == 0) {
        state->error_mask |= MAIL_ERROR_POLICY;
@@ -161,15 +174,7 @@ int     smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
      */
     auth_mechanism = argv[1].strval;
     initial_response = (argc == 3 ? argv[2].strval : 0);
-    err = smtpd_sasl_authenticate(state, auth_mechanism, initial_response);
-    if (err != 0) {
-       msg_warn("%s[%s]: SASL %s authentication failed",
-                state->name, state->addr, auth_mechanism);
-       smtpd_chat_reply(state, "%s", err);
-       return (-1);
-    }
-    smtpd_chat_reply(state, "235 2.0.0 Authentication successful");
-    return (0);
+    return (smtpd_sasl_authenticate(state, auth_mechanism, initial_response));
 }
 
 /* smtpd_sasl_auth_reset - clean up after AUTH command */
index d454081324d0d33e295bd8b3be8fa8bb93e20e0b..7180317c444382d2a0f610bd86cd4c259cbdabeb 100644 (file)
 #include <string.h>
 #include <unistd.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include <mymalloc.h>
index d0c2d07c2d4de918e9495831228f0343d34f3cc9..3be497a458a2e172505e7bbac1bbbc9744f55826 100644 (file)
 #include <fcntl.h>
 #include <signal.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <msg.h>
index 3e4a0dc3e87439677a46c3c954d497dda7986e58..c4bcce919525d83bfb856a9ea756662c65804ece 100644 (file)
 #ifdef USE_TLS
 #include <string.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include <mymalloc.h>
index 22b9acdba78de2ed281c195031f70ffcf93b688c..0e1cdf93cb2580e85173314acb0e2650f2b95ad0 100644 (file)
 
 #ifdef USE_TLS
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include <msg.h>
index 4471da58e68e874579cb4956d81c3561cc070848..91a85ed6f32601b7bafbf968f65213ab71efad77 100644 (file)
 #ifdef USE_TLS
 #include <string.h>
 
-#ifdef STRCASECMP_IN_STRINGS_H
-#include <strings.h>
-#endif
-
 /* Utility library. */
 
 #include <msg.h>
index 6a554e0da2c9e16fc7d03873f78f35318955c801..cc7b24bcfd68b83e27b9182318df306d6c8da711 100644 (file)
 #include <string.h>
 #include <ctype.h>
 
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
 /* Utility library. */
 
 #include "mymalloc.h"
index 3ce83ffc4021c12fb58a62412eb8eb30b3c3c0bc..8a2a361ee05dd1f2c0067fcfbd924726ec8d5e55 100644 (file)
@@ -64,8 +64,8 @@
 /* .IP NAME_MASK_RETURN
 /*     Require that all names listed in \fIname\fR exist in \fItable\fR,
 /*     and that all bits listed in \fImask\fR exist in \fItable\fR.
-/*     Return 0 (name_mask()) or a null pointer (str_name_mask())
-/*     if this condition is not met.
+/*     Log a warning, and return 0 (name_mask()) or a null pointer
+/*     (str_name_mask()) if this condition is not met.
 /* .IP NAME_MASK_ANY_CASE
 /*     Enable case-insensitive matching.
 /*     This feature is not enabled by default when calling name_mask();
@@ -137,8 +137,11 @@ int     name_mask_opt(const char *context, NAME_MASK *table, const char *names,
                if (flags & NAME_MASK_FATAL)
                    msg_fatal("unknown %s value \"%s\" in \"%s\"",
                              context, name, names);
-               if (flags & NAME_MASK_RETURN)
+               if (flags & NAME_MASK_RETURN) {
+                   msg_warn("unknown %s value \"%s\" in \"%s\"",
+                            context, name, names);
                    return (0);
+               }
                break;
            }
            if (lookup(name, np->name) == 0) {
@@ -174,8 +177,11 @@ const char *str_name_mask_opt(const char *context, NAME_MASK *table,
            if (flags & NAME_MASK_FATAL)
                msg_fatal("%s: invalid %s bit in mask: 0x%x",
                          myname, context, mask);
-           if (flags & NAME_MASK_RETURN)
+           if (flags & NAME_MASK_RETURN) {
+               msg_warn("%s: invalid %s bit in mask: 0x%x",
+                        myname, context, mask);
                return (0);
+           }
            break;
        }
        if (mask & np->mask) {
index 3dea9e16fb42a1272fd3dbed1c66e74f3ab8d392..6c3a4c19e430f3eb7e1defcc2b00a8a49babc3bb 100644 (file)
@@ -55,6 +55,7 @@
 /* System library. */
 
 #include <sys_defs.h>
+#include <string.h>
 
 /* Utility library. */
 
index 04e09df00a55d8abfc42e3643208098a51b2a28f..8f96aa4b7a5c495d6af54b59a1dd616d8edff478 100644 (file)
@@ -35,6 +35,7 @@ extern char *basename(const char *);
 extern char *sane_basename(VSTRING *, const char *);
 extern char *sane_dirname(VSTRING *, const char *);
 extern VSTRING *unescape(VSTRING *, const char *);
+extern VSTRING *escape(VSTRING *, const char *, ssize_t);
 extern int alldig(const char *);
 extern int allprint(const char *);
 extern int allspace(const char *);
index ef76d6d6444349beab14a685b0d56f9cc0cbf367..14be31fa6d01936638f53c2b2bfe9174ab8bc10c 100644 (file)
@@ -9,11 +9,18 @@
 /*     VSTRING *unescape(result, input)
 /*     VSTRING *result;
 /*     const char *input;
+/*
+/*     VSTRING *escape(result, input, len)
+/*     VSTRING *result;
+/*     const char *input;
+/*     ssize_t len;
 /* DESCRIPTION
 /*     unescape() translates C-like escape sequences in the null-terminated
 /*     string \fIinput\fR and places the result in \fIresult\fR. The result
 /*     is null-terminated, and is the function result value.
 /*
+/*     escape() does the reverse transformation.
+/*
 /*     Escape sequences and their translations:
 /* .IP \ea
 /*     Bell character.
@@ -121,6 +128,50 @@ VSTRING *unescape(VSTRING *result, const char *data)
     return (result);
 }
 
+/* escape - reverse transformation */
+
+VSTRING *escape(VSTRING *result, const char *data, ssize_t len)
+{
+    int     ch;
+
+    VSTRING_RESET(result);
+    while (len-- > 0) {
+       ch = *UCHAR(data++);
+       if (ISASCII(ch)) {
+           if (ISPRINT(ch)) {
+               if (ch == '\\')
+                   VSTRING_ADDCH(result, ch);
+               VSTRING_ADDCH(result, ch);
+               continue;
+           } else if (ch == '\a') {            /* \a -> audible bell */
+               vstring_strcat(result, "\a");
+               continue;
+           } else if (ch == '\b') {            /* \b -> backspace */
+               vstring_strcat(result, "\b");
+               continue;
+           } else if (ch == '\f') {            /* \f -> formfeed */
+               vstring_strcat(result, "\f");
+               continue;
+           } else if (ch == '\n') {            /* \n -> newline */
+               vstring_strcat(result, "\n");
+               continue;
+           } else if (ch == '\r') {            /* \r -> carriagereturn */
+               vstring_strcat(result, "\r");
+               continue;
+           } else if (ch == '\t') {            /* \t -> horizontal tab */
+               vstring_strcat(result, "\t");
+               continue;
+           } else if (ch == '\v') {            /* \v -> vertical tab */
+               vstring_strcat(result, "\v");
+               continue;
+           }
+       }
+       vstring_sprintf_append(result, "\\%03d", ch);
+    }
+    VSTRING_TERMINATE(result);
+    return (result);
+}
+
 #ifdef TEST
 
 #include <stdlib.h>
index d7fbb7ebab7e0fb7664660a788b5788b7eec7380..5c1658531f70f6bd23564ae4d42285640180e1e4 100644 (file)
@@ -33,6 +33,7 @@
 #include <sys_defs.h>                  /* includes <sys/types.h> */
 #include <sys/socket.h>
 #include <sys/uio.h>
+#include <string.h>
 
 /* Utility library. */
 
@@ -71,6 +72,7 @@ int     unix_recv_fd(int fd)
     }       control_un;
     struct cmsghdr *cmptr;
 
+    memset((char *) &msg, 0, sizeof(msg));
     msg.msg_control = control_un.control;
     msg.msg_controllen = CMSG_LEN(sizeof(newfd));      /* Fix 200506 */
 #else
index f913de53e4a5ba7cbdfc6222b05676082330b370..20436a0fbbe719d9539b7adb7094c418de2526f2 100644 (file)
@@ -36,6 +36,7 @@
 #include <sys_defs.h>                  /* includes <sys/types.h> */
 #include <sys/socket.h>
 #include <sys/uio.h>
+#include <string.h>
 
 /* Utility library. */
 
@@ -73,6 +74,7 @@ int     unix_send_fd(int fd, int sendfd)
     }       control_un;
     struct cmsghdr *cmptr;
 
+    memset((char *) &msg, 0, sizeof(msg));
     msg.msg_control = control_un.control;
     msg.msg_controllen = CMSG_LEN(sizeof(sendfd));     /* Fix 200506 */
 
index c7281db08248fa90f406f62f8d5d78ea6204e58b..4046110e6519c95b19cc71b51483a63b76a43049 100644 (file)
 
 VBUF   *vbuf_print(VBUF *bp, const char *format, va_list ap)
 {
+    const char *myname = "vbuf_print";
     static VSTRING *fmt;               /* format specifier */
     unsigned char *cp;
-    unsigned width;                    /* field width */
-    unsigned prec;                     /* numerical precision */
+    int     width;                     /* width and numerical precision */
+    int     prec;                      /* are signed for overflow defense */
     unsigned long_flag;                        /* long or plain integer */
     int     ch;
     char   *s;
@@ -160,6 +161,10 @@ VBUF   *vbuf_print(VBUF *bp, const char *format, va_list ap)
                    VSTRING_ADDCH(fmt, ch);
                }
            }
+           if (width < 0) {
+               msg_warn("%s: bad width %d in %.50s", myname, width, format);
+               width = 0;
+           }
            if (*cp == '.')                     /* width/precision separator */
                VSTRING_ADDCH(fmt, *cp++);
            if (*cp == '*') {                   /* dynamic precision */
@@ -172,6 +177,10 @@ VBUF   *vbuf_print(VBUF *bp, const char *format, va_list ap)
                    VSTRING_ADDCH(fmt, ch);
                }
            }
+           if (prec < 0) {
+               msg_warn("%s: bad precision %d in %.50s", myname, prec, format);
+               prec = 0;
+           }
            if ((long_flag = (*cp == 'l')) != 0)/* long whatever */
                VSTRING_ADDCH(fmt, *cp++);
            if (*cp == 0)                       /* premature end, punt */
diff --git a/postfix/src/xsasl/.indent.pro b/postfix/src/xsasl/.indent.pro
new file mode 120000 (symlink)
index 0000000..5c837ec
--- /dev/null
@@ -0,0 +1 @@
+../../.indent.pro
\ No newline at end of file
diff --git a/postfix/src/xsasl/Makefile.in b/postfix/src/xsasl/Makefile.in
new file mode 100644 (file)
index 0000000..0e45a12
--- /dev/null
@@ -0,0 +1,130 @@
+SHELL  = /bin/sh
+SRCS   = xsasl_server.c xsasl_cyrus_server.c xsasl_cyrus_log.c \
+       xsasl_cyrus_security.c xsasl_client.c xsasl_cyrus_client.c
+OBJS   = xsasl_server.o xsasl_cyrus_server.o xsasl_cyrus_log.o \
+       xsasl_cyrus_security.o xsasl_client.o xsasl_cyrus_client.o
+HDRS   = xsasl.h
+TESTSRC        = 
+DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
+CFLAGS = $(DEBUG) $(OPT) $(DEFS)
+INCL   =
+LIB    = libxsasl.a
+TESTPROG= 
+
+LIBS   = ../../lib/libglobal.a ../../lib/libutil.a
+LIB_DIR        = ../../lib
+INC_DIR        = ../../include
+MAKES  =
+
+.c.o:; $(CC) $(CFLAGS) -c $*.c
+
+all: $(LIB)
+
+$(OBJS): ../../conf/makedefs.out
+
+Makefile: Makefile.in
+       (cat ../../conf/makedefs.out $?) >$@
+
+test:  $(TESTPROG)
+
+$(LIB):        $(OBJS)
+       $(AR) $(ARFL) $(LIB) $?
+       $(RANLIB) $(LIB)
+
+$(LIB_DIR)/$(LIB): $(LIB)
+       cp $(LIB) $(LIB_DIR)
+       $(RANLIB) $(LIB_DIR)/$(LIB)
+
+update: $(LIB_DIR)/$(LIB) $(HDRS)
+       -for i in $(HDRS); \
+       do \
+         cmp -s $$i $(INC_DIR)/$$i 2>/dev/null || cp $$i $(INC_DIR); \
+       done
+       cd $(INC_DIR); chmod 644 $(HDRS)
+
+printfck: $(OBJS) $(PROG)
+       rm -rf printfck
+       mkdir printfck
+       cp *.h printfck
+       sed '1,/^# do not edit/!d' Makefile >printfck/Makefile
+       set -e; for i in *.c; do printfck -f .printfck $$i >printfck/$$i; done
+       cd printfck; make "INC_DIR=../../../include" `cd ..; ls *.o`
+
+lint:
+       lint $(DEFS) $(SRCS) $(LINTFIX)
+
+clean:
+       rm -f *.o $(LIB) *core $(TESTPROG) junk
+       rm -rf printfck
+
+tidy:  clean
+
+foo: $(LIB) $(LIBS)
+       mv $@.o junk
+       $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+       mv junk $@.o
+
+depend: $(MAKES)
+       (sed '1,/^# do not edit/!d' Makefile.in; \
+       set -e; for i in [a-z][a-z0-9]*.c; do \
+           $(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
+           -e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \
+           -e 's/o: \.\//o: /' -e p -e '}' ; \
+       done | sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
+       @$(EXPORT) make -f Makefile.in Makefile 1>&2
+
+# do not edit below this line - it is generated by 'make depend'
+xsasl_client.o: ../../include/argv.h
+xsasl_client.o: ../../include/msg.h
+xsasl_client.o: ../../include/mymalloc.h
+xsasl_client.o: ../../include/sys_defs.h
+xsasl_client.o: ../../include/vbuf.h
+xsasl_client.o: ../../include/vstream.h
+xsasl_client.o: ../../include/vstring.h
+xsasl_client.o: xsasl.h
+xsasl_client.o: xsasl_client.c
+xsasl_client.o: xsasl_cyrus.h
+xsasl_cyrus_client.o: ../../include/argv.h
+xsasl_cyrus_client.o: ../../include/msg.h
+xsasl_cyrus_client.o: ../../include/mymalloc.h
+xsasl_cyrus_client.o: ../../include/stringops.h
+xsasl_cyrus_client.o: ../../include/sys_defs.h
+xsasl_cyrus_client.o: ../../include/vbuf.h
+xsasl_cyrus_client.o: ../../include/vstream.h
+xsasl_cyrus_client.o: ../../include/vstring.h
+xsasl_cyrus_client.o: xsasl.h
+xsasl_cyrus_client.o: xsasl_cyrus.h
+xsasl_cyrus_client.o: xsasl_cyrus_client.c
+xsasl_cyrus_client.o: xsasl_cyrus_common.h
+xsasl_cyrus_log.o: ../../include/msg.h
+xsasl_cyrus_log.o: ../../include/sys_defs.h
+xsasl_cyrus_log.o: xsasl_cyrus_common.h
+xsasl_cyrus_log.o: xsasl_cyrus_log.c
+xsasl_cyrus_security.o: ../../include/name_mask.h
+xsasl_cyrus_security.o: ../../include/sys_defs.h
+xsasl_cyrus_security.o: xsasl_cyrus_common.h
+xsasl_cyrus_security.o: xsasl_cyrus_security.c
+xsasl_cyrus_server.o: ../../include/argv.h
+xsasl_cyrus_server.o: ../../include/mail_params.h
+xsasl_cyrus_server.o: ../../include/msg.h
+xsasl_cyrus_server.o: ../../include/mymalloc.h
+xsasl_cyrus_server.o: ../../include/name_mask.h
+xsasl_cyrus_server.o: ../../include/stringops.h
+xsasl_cyrus_server.o: ../../include/sys_defs.h
+xsasl_cyrus_server.o: ../../include/vbuf.h
+xsasl_cyrus_server.o: ../../include/vstream.h
+xsasl_cyrus_server.o: ../../include/vstring.h
+xsasl_cyrus_server.o: xsasl.h
+xsasl_cyrus_server.o: xsasl_cyrus.h
+xsasl_cyrus_server.o: xsasl_cyrus_common.h
+xsasl_cyrus_server.o: xsasl_cyrus_server.c
+xsasl_server.o: ../../include/argv.h
+xsasl_server.o: ../../include/msg.h
+xsasl_server.o: ../../include/mymalloc.h
+xsasl_server.o: ../../include/sys_defs.h
+xsasl_server.o: ../../include/vbuf.h
+xsasl_server.o: ../../include/vstream.h
+xsasl_server.o: ../../include/vstring.h
+xsasl_server.o: xsasl.h
+xsasl_server.o: xsasl_cyrus.h
+xsasl_server.o: xsasl_server.c
diff --git a/postfix/src/xsasl/README b/postfix/src/xsasl/README
new file mode 100644 (file)
index 0000000..6755b67
--- /dev/null
@@ -0,0 +1,105 @@
+Purpose of this document
+========================
+
+This document describes how to add your own SASL implementation to
+Postfix.  You don't have to provide both the server and client side.
+You can provide just one and omit the other. The examples below
+assume you do both.
+
+The plug-in API is described in cyrus_server.c and cyrus_client.c.
+It was unavoidably contaminated^h^h^h^h^h^h^h^h^h^h^h^hinfluenced
+by Cyrus SASL and may need revision as other implementations are
+added.
+
+For an example of how the plug-in interface is implemented, have a
+look at the xsasl/xsasl_cyrus_client.c and xsasl/xsasl_cyrus_server.c.
+
+Configuration features
+======================
+
+There are two configuration parameters that allow you to pass
+information from main.cf into the plug_in:
+
+    smtpd_sasl_path, smtpd_sasl_security_options
+    smtp_sasl_path, smtp_sasl_security_options
+    lmtp_sasl_path, lmtp_sasl_security_options
+
+The parameter values are passed to the plug-in without any
+interpretation. The following restrictions are imposed by the main.cf
+file parser: parameter values never contain newlines, and they never
+start or end with whitespace characters.
+
+The _path parameter value is passed only once during process
+initialization (i.e. it is a class variable). The path typically
+specifies the location of a configuration file or rendez-vous point.
+The _security_options parameter value is passed each time SASL is
+turned on for a connection (i.e. it is an instance variable).  The
+options may depend on whether or not TLS encryption is turned on.
+Remember that one Postfix process may perform up to 100 mail
+transactions during its life time. Things that happen in one
+transaction must not affect later transactions.
+
+Adding Postfix support for your own SASL implementation
+=======================================================
+
+To add your own SASL implementation, say, FOOBAR:
+
+- Copy xsasl/xsasl_cyrus.h to xsasl/xsasl_foobar.h and replace
+  CYRUS by FOOBAR:
+
+ #if defined(USE_SASL_AUTH) && defined(USE_FOOBAR_SASL)
+  /*
+   * SASL protocol interface
+   */
+ #define XSASL_TYPE_FOOBAR "foobar"
+ extern XSASL_SERVER_IMPL *xsasl_foobar_server_init(const char *, const char *);
+ extern XSASL_CLIENT_IMPL *xsasl_foobar_client_init(const char *, const char *);
+ #endif
+
+- Edit xsasl/xsasl_server.c, add your #include <xsasl_foobar.h> line
+  under #include <xsasl_cyrus.h> at the top, and add your initialization
+  function in the table at the bottom as shown below:
+
+  static XSASL_SERVER_IMPL_INFO server_impl_info[] = {
+  #ifdef XSASL_TYPE_CYRUS
+      XSASL_TYPE_CYRUS, xsasl_cyrus_server_init,
+  #endif
+  #ifdef XSASL_TYPE_FOOBAR
+      XSASL_TYPE_FOOBAR, xsasl_foobar_server_init,
+  #endif
+      0,
+  };
+
+- Repeat the (almost) same procedure for xsasl/xsasl_client.c.
+
+- Create your own xsasl/xsasl_foobar_{client,server}.c and support
+  files. Perhaps it's convenient to copy the cyrus files, rip out
+  the function bodies, and replace CYRUS by FOOBAR.
+
+- List your source files in Makefile.in. Don't forget to do "make
+  depend" after you do "make makefiles" in the step that follows
+  after this one.
+
+  SRCS    = xsasl_server.c xsasl_cyrus_server.c xsasl_cyrus_log.c \
+          xsasl_cyrus_security.c xsasl_client.c xsasl_cyrus_client.c \
+          xsasl_foobar_client.c xsasl_foobar_server.c
+  OBJS    = xsasl_server.o xsasl_cyrus_server.o xsasl_cyrus_log.o \
+          xsasl_cyrus_security.o xsasl_client.o xsasl_cyrus_client.o \
+          xsasl_foobar_client.o xsasl_foobar_server.o
+
+- Create the Postfix makefiles from the top-level directory:
+
+  % make makefiles CCARGS='-DUSE_SASL_AUTH -DUSE_FOOBAR_SASL \
+      -DDEF_CLIENT_SASL_TYPE=\"foobar\" -DDEF_SERVER_TYPE=\"foobar\" \
+      -I/some/where/include' AUXLIBS='-L/some/where/lib -lfoobar'
+
+  Yes, you can have different default SASL implementation types for
+  the client and server plug-ins.
+
+  Of course you don't have to override the default SASL implementation
+  type; it is shown here as an example.
+  
+
+- Don't forget to do "make depend" in the xsasl directory.
+
+- Document your build and configuration with a README document.
diff --git a/postfix/src/xsasl/xsasl.h b/postfix/src/xsasl/xsasl.h
new file mode 100644 (file)
index 0000000..291ff8e
--- /dev/null
@@ -0,0 +1,113 @@
+#ifndef _XSASL_H_INCLUDED_
+#define _XSASL_H_INCLUDED_
+
+/*++
+/* NAME
+/*     xsasl 3h
+/* SUMMARY
+/*     Postfix SASL plug-in interface
+/* SYNOPSIS
+/*     #include <xsasl.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <argv.h>
+#include <vstream.h>
+#include <vstring.h>
+
+ /*
+  * Generic server object. Specific instances extend this with their own
+  * private data.
+  */
+typedef struct XSASL_SERVER {
+    void    (*free) (struct XSASL_SERVER *);
+    int     (*first) (struct XSASL_SERVER *, const char *, const char *, VSTRING *);
+    int     (*next) (struct XSASL_SERVER *, const char *, VSTRING *);
+    const char *(*get_mechanism_list) (struct XSASL_SERVER *);
+    const char *(*get_username) (struct XSASL_SERVER *);
+} XSASL_SERVER;
+
+#define xsasl_server_free(server) (server)->free(server)
+#define xsasl_server_first(server, method, init_resp, reply) \
+       (server)->first((server), (method), (init_resp), (reply))
+#define xsasl_server_next(server, request, reply) \
+       (server)->next((server), (request), (reply))
+#define xsasl_server_get_mechanism_list(server) \
+       (server)->get_mechanism_list((server))
+#define xsasl_server_get_username(server) \
+       (server)->get_username((server))
+
+ /*
+  * Generic server implementation. Specific instances extend this with their
+  * own private data.
+  */
+typedef struct XSASL_SERVER_IMPL {
+    XSASL_SERVER *(*create) (struct XSASL_SERVER_IMPL *, VSTREAM *, const char *, const char *, const char *);
+    void    (*done) (struct XSASL_SERVER_IMPL *);
+} XSASL_SERVER_IMPL;
+
+extern XSASL_SERVER_IMPL *xsasl_server_init(const char *, const char *);
+extern ARGV *xsasl_server_types(void);
+
+#define xsasl_server_create(impl, stream, service, realm, sec_props) \
+       (impl)->create((impl), (stream), (service), (realm), (sec_props))
+#define xsasl_server_done(impl) (impl)->done((impl));
+
+ /*
+  * Generic client object. Specific instances extend this with their own
+  * private data.
+  */
+typedef struct XSASL_CLIENT {
+    void    (*free) (struct XSASL_CLIENT *);
+    int     (*first) (struct XSASL_CLIENT *, const char *, const char *, const char *, const char **, VSTRING *);
+    int     (*next) (struct XSASL_CLIENT *, const char *, VSTRING *);
+} XSASL_CLIENT;
+
+#define xsasl_client_free(client) (client)->free(client)
+#define xsasl_client_first(client, server, method, user, pass, init_resp) \
+       (client)->first((client), (server), (method), (user), (pass), (init_resp))
+#define xsasl_client_next(client, request, reply) \
+       (client)->next((client), (request), (reply))
+#define xsasl_client_set_password(client, user, pass) \
+       (client)->set_password((client), (user), (pass))
+
+ /*
+  * Generic client implementation. Specific instances extend this with their
+  * own private data.
+  */
+typedef struct XSASL_CLIENT_IMPL {
+    XSASL_CLIENT *(*create) (struct XSASL_CLIENT_IMPL *, VSTREAM *, const char *, const char *, const char *);
+    void    (*done) (struct XSASL_CLIENT_IMPL *);
+} XSASL_CLIENT_IMPL;
+
+extern XSASL_CLIENT_IMPL *xsasl_client_init(const char *, const char *);
+extern ARGV *xsasl_client_types(void);
+
+#define xsasl_client_create(impl, stream, service, server, sec_props) \
+       (impl)->create((impl), (stream), (service), (server), (sec_props))
+#define xsasl_client_done(impl) (impl)->done((impl));
+
+ /*
+  * Status codes.
+  */
+#define XSASL_AUTH_OK  1               /* Success */
+#define XSASL_AUTH_MORE        2               /* Need another c/s protocol exchange */
+#define XSASL_AUTH_DONE        3               /* Authentication completed */
+#define XSASL_AUTH_FORM        4               /* Cannot decode response */
+#define XSASL_AUTH_FAIL        5               /* Error */
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_client.c b/postfix/src/xsasl/xsasl_client.c
new file mode 100644 (file)
index 0000000..0e6267c
--- /dev/null
@@ -0,0 +1,223 @@
+/*++
+/* NAME
+/*     xsasl_client 3
+/* SUMMARY
+/*     Postfix SASL client plug-in interface
+/* SYNOPSIS
+/*     #include <xsasl.h>
+/*
+/*     XSASL_CLIENT_IMPL *xsasl_client_init(client_type, path_info)
+/*     const char *client_type;
+/*     const char *path_info;
+/*
+/*     void    xsasl_client_done(implementation)
+/*     XSASL_CLIENT_IMPL *implementation;
+/*
+/*     ARGV    *xsasl_client_types()
+/*
+/*     XSASL_CLIENT *xsasl_client_create(implementation, stream, service, 
+/*                                     server_name, security_properties)
+/*     XSASL_CLIENT_IMPL *implementation;
+/*     VSTREAM *stream;
+/*     const char *service;
+/*     const char *server_name;
+/*     const char *security_properties;
+/*
+/*     void    xsasl_client_free(client)
+/*     XSASL_CLIENT *client;
+/*
+/*     int     xsasl_client_first(client, stream, mech_list, username,
+/*                                     password, auth_method, init_resp)
+/*     XSASL_CLIENT *client;
+/*     const char *mech_list;
+/*     const char *username;
+/*     const char *password;
+/*     const char **auth_method;
+/*     VSTRING *init_resp;
+/*
+/*     int     xsasl_client_next(client, server_reply, client_reply)
+/*     XSASL_CLIENT *client;
+/*     const char *server_reply;
+/*     VSTRING *client_reply;
+/* DESCRIPTION
+/*     The XSASL_CLIENT abstraction implements a generic interface
+/*     to one or more SASL authentication implementations.
+/*
+/*     xsasl_client_init() is called once during process initialization.
+/*     It selects a SASL implementation by name, specifies the
+/*     location of a configuration file or rendez-vous point, and
+/*     returns an implementation handle that can be used to generate
+/*     SASL client instances. This function is typically used to
+/*     initialize the underlying implementation.
+/*
+/*     xsasl_client_done() disposes of an implementation handle,
+/*     and allows the underlying implementation to release resources.
+/*
+/*     xsasl_client_types() lists the available implementation types.
+/*     The result should be destroyed by the caller.
+/*
+/*     xsasl_client_create() is called at the start of an SMTP
+/*     session. It generates a Postfix SASL plug-in client instance
+/*     for the specified service and server name, with the specified
+/*     security properties. The stream handle is stored so that
+/*     encryption can be turned on after successful negotiations.
+/*
+/*     xsasl_client_free() is called at the end of an SMTP session.
+/*     It destroys a SASL client instance, and disables further
+/*     read/write operations if encryption was turned on.
+/*
+/*     xsasl_client_first() produces the client input for the AUTH
+/*     command. The input is an authentication method list from
+/*     an EHLO response, a username and a password. On return, the
+/*     method argument specifies the authentication method; storage
+/*     space is owned by the underlying implementation.  The initial
+/*     response and client non-error replies are BASE64 encoded.
+/*     Client error replies are 7-bit ASCII text without control
+/*     characters, and without BASE64 encoding. They are meant for
+/*     the local application, not for transmission to the server.
+/*     The client may negotiate encryption of the client-server
+/*     connection.
+/*
+/*     The result is one of the following:
+/* .IP XSASL_AUTH_OK
+/*     Success.
+/* .IP XSASL_AUTH_FORM
+/*     The server reply is incorrectly formatted. The client error
+/*     reply explains why.
+/* .IP XSASL_AUTH_FAIL
+/*     Other error. The client error reply explains why.
+/* .PP
+/*     xsasl_client_next() supports the subsequent stages of the
+/*     AUTH protocol. Both the client reply and client non-error
+/*     responses are BASE64 encoded.  See xsasl_client_first() for
+/*     other details.
+/*
+/*     Arguments:
+/* .IP client
+/*     SASL plug-in client handle.
+/* .IP client_reply
+/*     BASE64 encoded non-error client reply, or ASCII error
+/*     description for the user.
+/* .IP client_type
+/*     The name of a Postfix SASL client plug_in implementation.
+/* .IP client_types
+/*     Null-terminated array of strings with SASL client plug-in
+/*     implementation names.
+/* .IP init_resp
+/*     The AUTH command initial response.
+/* .IP implementation
+/*     Implementation handle that was obtained with xsasl_client_init().
+/* .IP mech_list
+/*     List of SASL mechanisms as announced by the server.
+/* .IP auth_method
+/*     The AUTH command authentication method.
+/* .IP password
+/*     Information from the Postfix SASL password file or equivalent.
+/* .IP path_info
+/*     The value of the smtp_sasl_path parameter or equivalent.
+/*     This specifies the implementation-dependent location of a
+/*     configuration file, rendez-vous point, etc., and is passed
+/*     unchanged to the plug-in.
+/* .IP security_options
+/*     The value of the smtp_sasl_security_options parameter or
+/*     equivalent. This is passed unchanged to the plug-in.
+/* .IP server_name
+/*     The remote server fully qualified hostname.
+/* .IP server_reply
+/*     BASE64 encoded server reply without SMTP reply code or
+/*     enhanced status code.
+/* .IP service
+/*     The service that is implemented by the local client (typically,
+/*     "lmtp" or "smtp").
+/* .IP stream
+/*     The connection between client and server.
+/*     When SASL encryption is negotiated, the plug-in will
+/*     transparently intercept the socket read/write operations.
+/* .IP username
+/*     Information from the Postfix SASL password file.
+/* SECURITY
+/* .ad
+/* .fi
+/*     The caller does not sanitize the server reply. It is the
+/*     responsibility of the underlying SASL client implementation
+/*     to produce 7-bit ASCII without control characters as client
+/*     non-error and error replies.
+/* DIAGNOSTICS
+/*     In case of error, xsasl_client_init() and xsasl_client_create()
+/*     log a warning and return a null pointer.
+/*
+/*     Functions that normally return XSASL_AUTH_OK will log a warning
+/*     and return an appropriate result value.
+/*
+/*     Panic: interface violation.
+/*
+/*     Fatal errors: out of memory.
+/* SEE ALSO
+/*     cyrus_security(3) Cyrus SASL security features
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this
+/*     software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+
+/* SASL implementations. */
+
+#include <xsasl.h>
+#include <xsasl_cyrus.h>
+
+ /*
+  * Lookup table for available SASL client implementations.
+  */
+typedef struct {
+    char   *client_type;
+    struct XSASL_CLIENT_IMPL *(*client_init) (const char *, const char *);
+} XSASL_CLIENT_IMPL_INFO;
+
+static XSASL_CLIENT_IMPL_INFO client_impl_info[] = {
+#ifdef XSASL_TYPE_CYRUS
+    XSASL_TYPE_CYRUS, xsasl_cyrus_client_init,
+#endif
+    0,
+};
+
+/* xsasl_client_init - look up client implementation by name */
+
+XSASL_CLIENT_IMPL *xsasl_client_init(const char *client_type,
+                                            const char *path_info)
+{
+    XSASL_CLIENT_IMPL_INFO *xp;
+
+    for (xp = client_impl_info; xp->client_type; xp++)
+       if (strcmp(client_type, xp->client_type) == 0)
+           return (xp->client_init(client_type, path_info));
+    msg_warn("unsupported SASL client implementation: %s", client_type);
+    return (0);
+}
+
+/* xsasl_client_types - report available implementation types */
+
+ARGV   *xsasl_client_types(void)
+{
+    XSASL_CLIENT_IMPL_INFO *xp;
+    ARGV   *argv = argv_alloc(1);
+
+    for (xp = client_impl_info; xp->client_type; xp++)
+       argv_add(argv, xp->client_type, ARGV_END);
+    return (argv);
+}
diff --git a/postfix/src/xsasl/xsasl_cyrus.h b/postfix/src/xsasl/xsasl_cyrus.h
new file mode 100644 (file)
index 0000000..5e78dcd
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef _XSASL_CYRUS_H_INCLUDED_
+#define _XSASL_CYRUS_H_INCLUDED_
+
+/*++
+/* NAME
+/*     xsasl_cyrus 3h
+/* SUMMARY
+/*     Cyrus SASL plug-in
+/* SYNOPSIS
+/*     #include <xsasl_cyrus.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * XSASL library.
+  */
+#include <xsasl.h>
+
+#if defined(USE_SASL_AUTH) && defined(USE_CYRUS_SASL)
+
+ /*
+  * SASL protocol interface
+  */
+#define XSASL_TYPE_CYRUS "cyrus"
+
+extern XSASL_SERVER_IMPL *xsasl_cyrus_server_init(const char *, const char *);
+extern XSASL_CLIENT_IMPL *xsasl_cyrus_client_init(const char *, const char *);
+
+#endif
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_cyrus_client.c b/postfix/src/xsasl/xsasl_cyrus_client.c
new file mode 100644 (file)
index 0000000..5e9e85b
--- /dev/null
@@ -0,0 +1,565 @@
+/*++
+/* NAME
+/*     xsasl_cyrus_client 3
+/* SUMMARY
+/*     Cyrus SASL client-side plug-in
+/* SYNOPSIS
+/*     #include <xsasl_cyrus_client.h>
+/*
+/*     XSASL_CLIENT_IMPL *xsasl_cyrus_client_init(client_type, path_info)
+/*     const char *client_type;
+/* DESCRIPTION
+/*     This module implements the Cyrus SASL client-side authentication
+/*     plug-in.
+/*
+/*     xsasl_cyrus_client_init() initializes the Cyrus SASL library and
+/*     returns an implementation handle that can be used to generate
+/*     SASL client instances.
+/*
+/*     Arguments:
+/* .IP client_type
+/*     The plug-in SASL client type (cyrus). This argument is
+/*     ignored, but it could be used when one implementation
+/*     provides multiple variants.
+/* .IP path_info
+/*     Implementation-specific information to specify the location
+/*     of a configuration file, rendez-vous point, etc. This
+/*     information is ignored by the Cyrus SASL client plug-in.
+/* DIAGNOSTICS
+/*     Fatal: out of memory.
+/*
+/*     Panic: interface violation.
+/*
+/*     Other: the routines log a warning and return an error result
+/*     as specified in xsasl_client(3).
+/* SEE ALSO
+/*     xsasl_client(3) Client API
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Original author:
+/*     Till Franke
+/*     SuSE Rhein/Main AG
+/*     65760 Eschborn, Germany
+/*
+/*     Adopted by:
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+ /*
+  * System library.
+  */
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+
+ /*
+  * Utility library
+  */
+#include <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+
+ /*
+  * Application-specific
+  */
+#include <xsasl.h>
+#include <xsasl_cyrus.h>
+#include <xsasl_cyrus_common.h>
+
+#if defined(USE_SASL_AUTH) && defined(USE_CYRUS_SASL)
+
+#include <sasl.h>
+#include <saslutil.h>
+
+/*
+ * Silly little macros.
+ */
+#define STR(s)  vstring_str(s)
+
+ /*
+  * Macros to handle API differences between SASLv1 and SASLv2. Specifics:
+  * 
+  * The SASL_LOG_* constants were renamed in SASLv2.
+  * 
+  * SASLv2's sasl_client_new takes two new parameters to specify local and
+  * remote IP addresses for auth mechs that use them.
+  * 
+  * SASLv2's sasl_client_start function no longer takes the secret parameter.
+  * 
+  * SASLv2's sasl_decode64 function takes an extra parameter for the length of
+  * the output buffer.
+  * 
+  * The other major change is that SASLv2 now takes more responsibility for
+  * deallocating memory that it allocates internally.  Thus, some of the
+  * function parameters are now 'const', to make sure we don't try to free
+  * them too.  This is dealt with in the code later on.
+  */
+#if SASL_VERSION_MAJOR < 2
+/* SASL version 1.x */
+#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
+       sasl_client_new(srv, fqdn, prompt, secflags, pconn)
+#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
+       sasl_client_start(conn, mechlst, secret, prompt, clout, cllen, mech)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+       sasl_decode64(in, inlen, out, outlen)
+typedef char *CLIENTOUT_TYPE;
+
+#endif
+
+#if SASL_VERSION_MAJOR >= 2
+/* SASL version > 2.x */
+#define SASL_CLIENT_NEW(srv, fqdn, lport, rport, prompt, secflags, pconn) \
+       sasl_client_new(srv, fqdn, lport, rport, prompt, secflags, pconn)
+#define SASL_CLIENT_START(conn, mechlst, secret, prompt, clout, cllen, mech) \
+       sasl_client_start(conn, mechlst, prompt, clout, cllen, mech)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+       sasl_decode64(in, inlen, out, outmaxlen, outlen)
+typedef const char *CLIENTOUT_TYPE;
+
+#endif
+
+ /*
+  * The XSASL_CYRUS_CLIENT object is derived from the generic XSASL_CLIENT
+  * object.
+  */
+typedef struct {
+    XSASL_CLIENT xsasl;                        /* generic members, must be first */
+    VSTREAM *stream;                   /* client-server connection */
+    sasl_conn_t *sasl_conn;            /* SASL context */
+    VSTRING *decoded;                  /* decoded server challenge */
+    sasl_callback_t *callbacks;                /* user/password lookup */
+    char   *username;
+    char   *password;
+} XSASL_CYRUS_CLIENT;
+
+ /*
+  * Forward declarations.
+  */
+static void xsasl_cyrus_client_done(XSASL_CLIENT_IMPL *);
+static XSASL_CLIENT *xsasl_cyrus_client_create(XSASL_CLIENT_IMPL *,
+                                                      VSTREAM *,
+                                                      const char *,
+                                                      const char *,
+                                                      const char *);
+static int xsasl_cyrus_client_set_security(XSASL_CLIENT *, const char *);
+static int xsasl_cyrus_client_first(XSASL_CLIENT *, const char *, const char *,
+                                   const char *, const char **, VSTRING *);
+static int xsasl_cyrus_client_next(XSASL_CLIENT *, const char *, VSTRING *);
+static void xsasl_cyrus_client_free(XSASL_CLIENT *);
+
+/* xsasl_cyrus_client_get_user - username lookup call-back routine */
+
+static int xsasl_cyrus_client_get_user(void *context, int unused_id,
+                                              const char **result,
+                                              unsigned *len)
+{
+    char   *myname = "xsasl_cyrus_get_user";
+    XSASL_CYRUS_CLIENT *client = (XSASL_CYRUS_CLIENT *) context;
+
+    if (msg_verbose)
+       msg_info("%s: %s", myname, client->username);
+
+    /*
+     * Sanity check.
+     */
+    if (client->password == 0)
+       msg_panic("%s: no username looked up", myname);
+
+    *result = client->username;
+    if (len)
+       *len = strlen(client->username);
+    return (SASL_OK);
+}
+
+/* xsasl_cyrus_client_get_passwd - password lookup call-back routine */
+
+static int xsasl_cyrus_client_get_passwd(sasl_conn_t *conn, void *context,
+                                           int id, sasl_secret_t **psecret)
+{
+    char   *myname = "xsasl_cyrus_get_passwd";
+    XSASL_CYRUS_CLIENT *client = (XSASL_CYRUS_CLIENT *) context;
+    int     len;
+
+    if (msg_verbose)
+       msg_info("%s: %s", myname, client->password);
+
+    /*
+     * Sanity check.
+     */
+    if (!conn || !psecret || id != SASL_CB_PASS)
+       return (SASL_BADPARAM);
+    if (client->password == 0)
+       msg_panic("%s: no password looked up", myname);
+
+    /*
+     * Convert the password into a counted string.
+     */
+    len = strlen(client->password);
+    if ((*psecret = (sasl_secret_t *) malloc(sizeof(sasl_secret_t) + len)) == 0)
+       return (SASL_NOMEM);
+    (*psecret)->len = len;
+    memcpy((*psecret)->data, client->password, len + 1);
+
+    return (SASL_OK);
+}
+
+/* xsasl_cyrus_client_init - initialize Cyrus SASL library */
+
+XSASL_CLIENT_IMPL *xsasl_cyrus_client_init(const char *unused_client_type,
+                                              const char *unused_path_info)
+{
+    XSASL_CLIENT_IMPL *xp;
+    int     sasl_status;
+
+    /*
+     * Global callbacks. These have no per-session context.
+     */
+    static sasl_callback_t callbacks[] = {
+       {SASL_CB_LOG, &xsasl_cyrus_log, 0},
+       {SASL_CB_LIST_END, 0, 0}
+    };
+
+#if SASL_VERSION_MAJOR >= 2 && (SASL_VERSION_MINOR >= 2 \
+    || (SASL_VERSION_MINOR == 1 && SASL_VERSION_STEP >= 19))
+    int     sasl_major;
+    int     sasl_minor;
+    int     sasl_step;
+
+    /*
+     * DLL hell guard.
+     */
+    sasl_version_info((const char **) 0, (const char **) 0,
+                     &sasl_major, &sasl_minor,
+                     &sasl_step, (int *) 0);
+    if (sasl_major != SASL_VERSION_MAJOR
+#if 0
+       || sasl_minor != SASL_VERSION_MINOR
+       || sasl_step != SASL_VERSION_STEP
+#endif
+       ) {
+       msg_warn("incorrect SASL library version. "
+             "Postfix was built with include files from version %d.%d.%d, "
+                "but the run-time library version is %d.%d.%d",
+                SASL_VERSION_MAJOR, SASL_VERSION_MINOR, SASL_VERSION_STEP,
+                sasl_major, sasl_minor, sasl_step);
+       return (0);
+    }
+#endif
+
+    /*
+     * Initialize the SASL library.
+     */
+    if ((sasl_status = sasl_client_init(callbacks)) != SASL_OK) {
+       msg_warn("SASL library initialization error: %s",
+                xsasl_cyrus_strerror(sasl_status));
+       return (0);
+    }
+
+    /*
+     * Return a generic XSASL_CLIENT_IMPL object. We don't need to extend it
+     * with our own methods or data.
+     */
+    xp = (XSASL_CLIENT_IMPL *) mymalloc(sizeof(*xp));
+    xp->create = xsasl_cyrus_client_create;
+    xp->done = xsasl_cyrus_client_done;
+    return (xp);
+}
+
+/* xsasl_cyrus_client_done - dispose of implementation */
+
+static void xsasl_cyrus_client_done(XSASL_CLIENT_IMPL *impl)
+{
+    myfree((char *) impl);
+    sasl_done();
+}
+
+/* xsasl_cyrus_client_create - per-session SASL initialization */
+
+XSASL_CLIENT *xsasl_cyrus_client_create(XSASL_CLIENT_IMPL *unused_impl,
+                                               VSTREAM *stream,
+                                               const char *service,
+                                               const char *server,
+                                               const char *sec_props)
+{
+    XSASL_CYRUS_CLIENT *client = 0;
+    static sasl_callback_t callbacks[] = {
+       {SASL_CB_USER, &xsasl_cyrus_client_get_user, 0},
+       {SASL_CB_AUTHNAME, &xsasl_cyrus_client_get_user, 0},
+       {SASL_CB_PASS, &xsasl_cyrus_client_get_passwd, 0},
+       {SASL_CB_LIST_END, 0, 0}
+    };
+    sasl_conn_t *sasl_conn = 0;
+    sasl_callback_t *custom_callbacks = 0;
+    sasl_callback_t *cp;
+    int     sasl_status;
+
+    /*
+     * The optimizer will eliminate duplication and/or dead code.
+     */
+#define XSASL_CYRUS_CLIENT_CREATE_ERROR_RETURN(x) \
+    do { \
+       if (client) { \
+           xsasl_cyrus_client_free(&client->xsasl); \
+       } else { \
+           if (custom_callbacks) \
+               myfree((char *) custom_callbacks); \
+           if (sasl_conn) \
+               sasl_dispose(&sasl_conn); \
+       } \
+       return (x); \
+    } while (0)
+
+    /*
+     * Per-session initialization. Provide each session with its own callback
+     * context.
+     */
+#define NULL_SECFLAGS          0
+
+    custom_callbacks = (sasl_callback_t *) mymalloc(sizeof(callbacks));
+    memcpy((char *) custom_callbacks, callbacks, sizeof(callbacks));
+
+#define NULL_SERVER_ADDR       ((char *) 0)
+#define NULL_CLIENT_ADDR       ((char *) 0)
+
+    if ((sasl_status = SASL_CLIENT_NEW(service, server,
+                                      NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
+                                      custom_callbacks, NULL_SECFLAGS,
+                                      &sasl_conn)) != SASL_OK) {
+       msg_warn("per-session SASL client initialization: %s",
+                xsasl_cyrus_strerror(sasl_status));
+       XSASL_CYRUS_CLIENT_CREATE_ERROR_RETURN(0);
+    }
+
+    /*
+     * Extend XSASL_CLIENT_IMPL object with our own state. We use long-lived
+     * conversion buffers rather than local variables to avoid memory leaks
+     * in case of read/write timeout or I/O error.
+     * 
+     * XXX If we enable SASL encryption, there needs to be a way to inform the
+     * application, so that they can turn off connection caching, refuse
+     * STARTTLS, etc.
+     */
+    client = (XSASL_CYRUS_CLIENT *) mymalloc(sizeof(*client));
+    client->xsasl.free = xsasl_cyrus_client_free;
+    client->xsasl.first = xsasl_cyrus_client_first;
+    client->xsasl.next = xsasl_cyrus_client_next;
+    client->stream = stream;
+    client->sasl_conn = sasl_conn;
+    client->callbacks = custom_callbacks;
+    client->decoded = vstring_alloc(20);
+    client->username = 0;
+    client->password = 0;
+
+    for (cp = custom_callbacks; cp->id != SASL_CB_LIST_END; cp++)
+       cp->context = (void *) client;
+
+    if (xsasl_cyrus_client_set_security(&client->xsasl, sec_props)
+       != XSASL_AUTH_OK)
+       XSASL_CYRUS_CLIENT_CREATE_ERROR_RETURN(0);
+
+    return (&client->xsasl);
+}
+
+/* xsasl_cyrus_client_set_security - set security properties */
+
+static int xsasl_cyrus_client_set_security(XSASL_CLIENT *xp,
+                                                  const char *sasl_opts_val)
+{
+    XSASL_CYRUS_CLIENT *client = (XSASL_CYRUS_CLIENT *) xp;
+    sasl_security_properties_t sec_props;
+    int     sasl_status;
+
+    /*
+     * Per-session security properties. XXX This routine is not sufficiently
+     * documented. What is the purpose of all this?
+     */
+    memset(&sec_props, 0L, sizeof(sec_props));
+    sec_props.min_ssf = 0;
+    sec_props.max_ssf = 0;                     /* don't allow real SASL
+                                                * security layer */
+    if (*sasl_opts_val == 0) {
+       sec_props.security_flags = 0;
+    } else {
+       sec_props.security_flags =
+           xsasl_cyrus_security_parse_opts(sasl_opts_val);
+       if (sec_props.security_flags == 0) {
+           msg_warn("bad per-session SASL security properties");
+           return (XSASL_AUTH_FAIL);
+       }
+    }
+    sec_props.maxbufsize = 0;
+    sec_props.property_names = 0;
+    sec_props.property_values = 0;
+    if ((sasl_status = sasl_setprop(client->sasl_conn, SASL_SEC_PROPS,
+                                   &sec_props)) != SASL_OK) {
+       msg_warn("set per-session SASL security properties: %s",
+                xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_FAIL);
+    }
+    return (XSASL_AUTH_OK);
+}
+
+/* xsasl_cyrus_client_first - run authentication protocol */
+
+static int xsasl_cyrus_client_first(XSASL_CLIENT *xp,
+                                           const char *mechanism_list,
+                                           const char *username,
+                                           const char *password,
+                                           const char **mechanism,
+                                           VSTRING *init_resp)
+{
+    char   *myname = "xsasl_cyrus_client_first";
+    XSASL_CYRUS_CLIENT *client = (XSASL_CYRUS_CLIENT *) xp;
+    unsigned enc_length;
+    unsigned enc_length_out;
+    CLIENTOUT_TYPE clientout;
+    unsigned clientoutlen;
+    int     sasl_status;
+
+#define NO_SASL_SECRET         0
+#define NO_SASL_INTERACTION    0
+
+    /*
+     * Save the username and password for the call-backs.
+     */
+    if (client->username)
+       myfree(client->username);
+    client->username = mystrdup(username);
+    if (client->password)
+       myfree(client->password);
+    client->password = mystrdup(password);
+
+    /*
+     * Start the client side authentication protocol.
+     */
+    sasl_status = SASL_CLIENT_START((sasl_conn_t *) client->sasl_conn,
+                                   mechanism_list,
+                                   NO_SASL_SECRET, NO_SASL_INTERACTION,
+                                   &clientout, &clientoutlen, mechanism);
+    if (sasl_status != SASL_OK && sasl_status != SASL_CONTINUE) {
+       vstring_strcpy(init_resp, xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_FAIL);
+    }
+
+    /*
+     * Generate the AUTH command and the optional initial client response.
+     * sasl_encode64() produces four bytes for each complete or incomplete
+     * triple of input bytes. Allocate an extra byte for string termination.
+     */
+#define ENCODE64_LENGTH(n)     ((((n) + 2) / 3) * 4)
+
+    if (clientoutlen > 0) {
+       if (msg_verbose) {
+           escape(client->decoded, clientout, clientoutlen);
+           msg_info("%s: uncoded initial reply: %s",
+                    myname, STR(client->decoded));
+       }
+       enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
+       VSTRING_RESET(init_resp);               /* Fix 200512 */
+       VSTRING_SPACE(init_resp, enc_length);
+       if ((sasl_status = sasl_encode64(clientout, clientoutlen,
+                                        STR(init_resp),
+                                        vstring_avail(init_resp),
+                                        &enc_length_out)) != SASL_OK)
+           msg_panic("%s: sasl_encode64 botch: %s",
+                     myname, xsasl_cyrus_strerror(sasl_status));
+       VSTRING_AT_OFFSET(init_resp, enc_length_out);   /* XXX */
+#if SASL_VERSION_MAJOR < 2
+       /* SASL version 1 doesn't free memory that it allocates. */
+       free(clientout);
+#endif
+    } else {
+       vstring_strcpy(init_resp, "");
+    }
+    return (XSASL_AUTH_OK);
+}
+
+/* xsasl_cyrus_client_next - continue authentication */
+
+static int xsasl_cyrus_client_next(XSASL_CLIENT *xp, const char *server_reply,
+                                          VSTRING *client_reply)
+{
+    char   *myname = "xsasl_cyrus_client_next";
+    XSASL_CYRUS_CLIENT *client = (XSASL_CYRUS_CLIENT *) xp;
+    unsigned enc_length;
+    unsigned enc_length_out;
+    CLIENTOUT_TYPE clientout;
+    unsigned clientoutlen;
+    unsigned serverinlen;
+    int     sasl_status;
+
+    /*
+     * Process a server challenge.
+     */
+    serverinlen = strlen(server_reply);
+    VSTRING_RESET(client->decoded);            /* Fix 200512 */
+    VSTRING_SPACE(client->decoded, serverinlen);
+    if ((sasl_status = SASL_DECODE64(server_reply, serverinlen,
+                                    STR(client->decoded),
+                                    vstring_avail(client->decoded),
+                                    &enc_length)) != SASL_OK) {
+       vstring_strcpy(client_reply, xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_FORM);
+    }
+    if (msg_verbose)
+       msg_info("%s: decoded challenge: %.*s",
+                myname, (int) enc_length, STR(client->decoded));
+    sasl_status = sasl_client_step(client->sasl_conn, STR(client->decoded),
+                                  enc_length, NO_SASL_INTERACTION,
+                                  &clientout, &clientoutlen);
+    if (sasl_status != SASL_OK && sasl_status != SASL_CONTINUE) {
+       vstring_strcpy(client_reply, xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_FAIL);
+    }
+
+    /*
+     * Send a client response.
+     */
+    if (clientoutlen > 0) {
+       if (msg_verbose)
+           msg_info("%s: uncoded client response %.*s",
+                    myname, (int) clientoutlen, clientout);
+       enc_length = ENCODE64_LENGTH(clientoutlen) + 1;
+       VSTRING_RESET(client_reply);            /* Fix 200512 */
+       VSTRING_SPACE(client_reply, enc_length);
+       if ((sasl_status = sasl_encode64(clientout, clientoutlen,
+                                        STR(client_reply),
+                                        vstring_avail(client_reply),
+                                        &enc_length_out)) != SASL_OK)
+           msg_panic("%s: sasl_encode64 botch: %s",
+                     myname, xsasl_cyrus_strerror(sasl_status));
+#if SASL_VERSION_MAJOR < 2
+       /* SASL version 1 doesn't free memory that it allocates. */
+       free(clientout);
+#endif
+    } else {
+       /* XXX Can't happen. */
+       vstring_strcpy(client_reply, "");
+    }
+    return (XSASL_AUTH_OK);
+}
+
+/* xsasl_cyrus_client_free - per-session cleanup */
+
+void    xsasl_cyrus_client_free(XSASL_CLIENT *xp)
+{
+    XSASL_CYRUS_CLIENT *client = (XSASL_CYRUS_CLIENT *) xp;
+
+    if (client->username)
+       myfree(client->username);
+    if (client->password)
+       myfree(client->password);
+    if (client->sasl_conn)
+       sasl_dispose(&client->sasl_conn);
+    myfree((char *) client->callbacks);
+    vstring_free(client->decoded);
+    myfree((char *) client);
+}
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_cyrus_common.h b/postfix/src/xsasl/xsasl_cyrus_common.h
new file mode 100644 (file)
index 0000000..5447378
--- /dev/null
@@ -0,0 +1,39 @@
+#ifndef _CYRUS_COMMON_H_INCLUDED_
+#define _CYRUS_COMMON_H_INCLUDED_
+
+/*++
+/* NAME
+/*     cyrus_common 3h
+/* SUMMARY
+/*     Cyrus SASL plug-in helpers
+/* SYNOPSIS
+/*     #include <cyrus_common.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * External interface.
+  */
+#if defined(USE_SASL_AUTH) && defined(USE_CYRUS_SASL)
+
+#define NO_SASL_LANGLIST       ((const char *) 0)
+#define NO_SASL_OUTLANG                ((const char **) 0)
+#define xsasl_cyrus_strerror(status) \
+       sasl_errstring((status), NO_SASL_LANGLIST, NO_SASL_OUTLANG)
+extern int xsasl_cyrus_log(void *, int, const char *);
+extern int xsasl_cyrus_security_parse_opts(const char *);
+
+#endif
+
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_cyrus_log.c b/postfix/src/xsasl/xsasl_cyrus_log.c
new file mode 100644 (file)
index 0000000..7bf25c3
--- /dev/null
@@ -0,0 +1,104 @@
+/*++
+/* NAME
+/*     xsasl_cyrus_log 3
+/* SUMMARY
+/*     Cyrus SASL logging call-back routine
+/* SYNOPSIS
+/*     #include <xsasl_cyrus_common.h>
+/*
+/*     int     xsasl_cyrus_log(context, priority, text)
+/*     void    *context;
+/*     int     priority;
+/*     const char *text;
+/* DESCRIPTION
+/*     xsasl_cyrus_log() logs a Cyrus message.
+/* DIAGNOSTICS:
+/*     Fatal: out of memory.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+
+/* Application-specific */
+
+#include <xsasl_cyrus_common.h>
+
+#if defined(USE_SASL_AUTH) && defined(USE_CYRUS_SASL)
+
+#include <sasl.h>
+#include <saslutil.h>
+
+/* xsasl_cyrus_log - logging callback */
+
+int     xsasl_cyrus_log(void *unused_context, int priority,
+                               const char *message)
+{
+    switch (priority) {
+       case SASL_LOG_ERR:              /* unusual errors */
+#ifdef SASL_LOG_WARN                   /* non-fatal warnings (Cyrus-SASL v2) */
+       case SASL_LOG_WARN:
+#endif
+#ifdef SASL_LOG_WARNING                        /* non-fatal warnings (Cyrus-SASL v1) */
+       case SASL_LOG_WARNING:
+#endif
+       msg_warn("SASL authentication problem: %s", message);
+       break;
+#ifdef SASL_LOG_INFO
+    case SASL_LOG_INFO:                        /* other info (Cyrus-SASL v1) */
+       if (msg_verbose)
+           msg_info("SASL authentication info: %s", message);
+       break;
+#endif
+#ifdef SASL_LOG_NOTE
+    case SASL_LOG_NOTE:                        /* other info (Cyrus-SASL v2) */
+       if (msg_verbose)
+           msg_info("SASL authentication info: %s", message);
+       break;
+#endif
+#ifdef SASL_LOG_FAIL
+    case SASL_LOG_FAIL:                        /* authentication failures
+                                                * (Cyrus-SASL v2) */
+       msg_warn("SASL authentication failure: %s", message);
+       break;
+#endif
+#ifdef SASL_LOG_DEBUG
+    case SASL_LOG_DEBUG:                       /* more verbose than LOG_NOTE
+                                                * (Cyrus-SASL v2) */
+       if (msg_verbose > 1)
+           msg_info("SASL authentication debug: %s", message);
+       break;
+#endif
+#ifdef SASL_LOG_TRACE
+    case SASL_LOG_TRACE:                       /* traces of internal
+                                                * protocols (Cyrus-SASL v2) */
+       if (msg_verbose > 1)
+           msg_info("SASL authentication trace: %s", message);
+       break;
+#endif
+#ifdef SASL_LOG_PASS
+    case SASL_LOG_PASS:                        /* traces of internal
+                                                * protocols, including
+                                                * passwords (Cyrus-SASL v2) */
+       if (msg_verbose > 1)
+           msg_info("SASL authentication pass: %s", message);
+       break;
+#endif
+    }
+    return (SASL_OK);
+}
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_cyrus_security.c b/postfix/src/xsasl/xsasl_cyrus_security.c
new file mode 100644 (file)
index 0000000..c4c6d44
--- /dev/null
@@ -0,0 +1,82 @@
+/*++
+/* NAME
+/*     xsasl_cyrus_security 3
+/* SUMMARY
+/*     convert Cyrus SASL security properties to bit mask
+/* SYNOPSIS
+/*     #include <xsasl_cyrus_common.h>
+/*
+/*     int     xsasl_cyrus_security_parse_opts(properties)
+/*     const char *properties;
+/* DESCRIPTION
+/*     xsasl_cyrus_security_parse_opts() converts a list of security
+/*     properties to a bit mask. The result is zero in case of error.
+/*
+/*     Arguments:
+/* .IP properties
+/*     A comma or space separated list of zero or more of the
+/*     following:
+/* .RS
+/* .IP noplaintext
+/*     Disallow authentication methods that use plaintext passwords.
+/* .IP noactive
+/*     Disallow authentication methods that are vulnerable to
+/*     non-dictionary active attacks.
+/* .IP nodictionary
+/*     Disallow authentication methods that are vulnerable to
+/*     passive dictionary attack.
+/* .IP noanonymous
+/*     Disallow anonymous logins.
+/* .RE
+/* DIAGNOSTICS:
+/*     Warning: bad input.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <name_mask.h>
+
+/* Application-specific. */
+
+#include <xsasl_cyrus_common.h>
+
+#if defined(USE_SASL_AUTH) && defined(USE_CYRUS_SASL)
+
+#include <sasl.h>
+
+ /*
+  * SASL Security options.
+  */
+static NAME_MASK xsasl_cyrus_sec_mask[] = {
+    "noplaintext", SASL_SEC_NOPLAINTEXT,
+    "noactive", SASL_SEC_NOACTIVE,
+    "nodictionary", SASL_SEC_NODICTIONARY,
+    "noanonymous", SASL_SEC_NOANONYMOUS,
+#if SASL_VERSION_MAJOR >= 2
+    "mutual_auth", SASL_SEC_MUTUAL_AUTH,
+#endif
+    0,
+};
+
+/* xsasl_cyrus_security - parse security options */
+
+int     xsasl_cyrus_security_parse_opts(const char *sasl_opts_val)
+{
+    return (name_mask_opt("SASL security options", xsasl_cyrus_sec_mask,
+                         sasl_opts_val, NAME_MASK_RETURN));
+}
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_cyrus_server.c b/postfix/src/xsasl/xsasl_cyrus_server.c
new file mode 100644 (file)
index 0000000..40147e4
--- /dev/null
@@ -0,0 +1,599 @@
+/*++
+/* NAME
+/*     xsasl_cyrus_server 3
+/* SUMMARY
+/*     Cyrus SASL server-side plug-in
+/* SYNOPSIS
+/*     #include <xsasl_cyrus_server.h>
+/*
+/*     XSASL_SERVER_IMPL *xsasl_cyrus_server_init(server_type, path_info)
+/*     const char *server_type;
+/*     const char *path_info;
+/* DESCRIPTION
+/*     This module implements the Cyrus SASL server-side authentication
+/*     plug-in.
+/*
+/*     xsasl_cyrus_server_init() initializes the Cyrus SASL library and
+/*     returns an implementation handle that can be used to generate
+/*     SASL server instances.
+/*
+/*     Arguments:
+/* .IP server_type
+/*     The server type (cyrus). This argument is ignored, but it
+/*     could be used when one implementation provides multiple
+/*     variants.
+/* .IP path_info
+/*     The base name of the SASL server configuration file (example:
+/*     smtpd becomes /usr/lib/sasl2/smtpd.conf).
+/* DIAGNOSTICS
+/*     Fatal: out of memory.
+/*
+/*     Panic: interface violation.
+/*
+/*     Other: the routines log a warning and return an error result
+/*     as specified in xsasl_server(3).
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Initial implementation by:
+/*     Till Franke
+/*     SuSE Rhein/Main AG
+/*     65760 Eschborn, Germany
+/*
+/*     Adopted by:
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <name_mask.h>
+#include <stringops.h>
+
+/* Global library. */
+
+#include <mail_params.h>
+
+/* Application-specific. */
+
+#include <xsasl.h>
+#include <xsasl_cyrus.h>
+#include <xsasl_cyrus_common.h>
+
+#if defined(USE_SASL_AUTH) && defined(USE_CYRUS_SASL)
+
+#include <sasl.h>
+#include <saslutil.h>
+
+/*
+ * Silly little macros.
+ */
+#define STR(s) vstring_str(s)
+
+ /*
+  * Macros to handle API differences between SASLv1 and SASLv2. Specifics:
+  * 
+  * The SASL_LOG_* constants were renamed in SASLv2.
+  * 
+  * SASLv2's sasl_server_new takes two new parameters to specify local and
+  * remote IP addresses for auth mechs that use them.
+  * 
+  * SASLv2's sasl_server_start and sasl_server_step no longer have the errstr
+  * parameter.
+  * 
+  * SASLv2's sasl_decode64 function takes an extra parameter for the length of
+  * the output buffer.
+  * 
+  * The other major change is that SASLv2 now takes more responsibility for
+  * deallocating memory that it allocates internally.  Thus, some of the
+  * function parameters are now 'const', to make sure we don't try to free
+  * them too.  This is dealt with in the code later on.
+  */
+
+#if SASL_VERSION_MAJOR < 2
+/* SASL version 1.x */
+#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
+       sasl_server_new(srv, fqdn, rlm, cb, secflags, pconn)
+#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
+       sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen, err)
+#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
+       sasl_server_step(conn, clin, clinlen, srvout, srvoutlen, err)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+       sasl_decode64(in, inlen, out, outlen)
+typedef char *MECHANISM_TYPE;
+typedef unsigned MECHANISM_COUNT_TYPE;
+typedef char *SERVEROUT_TYPE;
+typedef void *VOID_SERVEROUT_TYPE;
+
+#endif
+
+#if SASL_VERSION_MAJOR >= 2
+/* SASL version > 2.x */
+#define SASL_SERVER_NEW(srv, fqdn, rlm, lport, rport, cb, secflags, pconn) \
+       sasl_server_new(srv, fqdn, rlm, lport, rport, cb, secflags, pconn)
+#define SASL_SERVER_START(conn, mech, clin, clinlen, srvout, srvoutlen, err) \
+       sasl_server_start(conn, mech, clin, clinlen, srvout, srvoutlen)
+#define SASL_SERVER_STEP(conn, clin, clinlen, srvout, srvoutlen, err) \
+       sasl_server_step(conn, clin, clinlen, srvout, srvoutlen)
+#define SASL_DECODE64(in, inlen, out, outmaxlen, outlen) \
+       sasl_decode64(in, inlen, out, outmaxlen, outlen)
+typedef const char *MECHANISM_TYPE;
+typedef int MECHANISM_COUNT_TYPE;
+typedef const char *SERVEROUT_TYPE;
+typedef const void *VOID_SERVEROUT_TYPE;
+
+#endif
+
+ /*
+  * The XSASL_CYRUS_SERVER object is derived from the generic XSASL_SERVER
+  * object.
+  */
+typedef struct {
+    XSASL_SERVER xsasl;                        /* generic members, must be first */
+    VSTREAM *stream;                   /* client-server connection */
+    sasl_conn_t *sasl_conn;            /* SASL context */
+    VSTRING *decoded;                  /* decoded challenge or response */
+    char   *username;                  /* authenticated user */
+    char   *mechanism_list;            /* applicable mechanisms */
+} XSASL_CYRUS_SERVER;
+
+ /*
+  * Forward declarations.
+  */
+static void xsasl_cyrus_server_done(XSASL_SERVER_IMPL *);
+static XSASL_SERVER *xsasl_cyrus_server_create(XSASL_SERVER_IMPL *,
+                                                      VSTREAM *,
+                                                      const char *,
+                                                      const char *,
+                                                      const char *);
+static void xsasl_cyrus_server_free(XSASL_SERVER *);
+static int xsasl_cyrus_server_first(XSASL_SERVER *, const char *,
+                                           const char *, VSTRING *);
+static int xsasl_cyrus_server_next(XSASL_SERVER *, const char *, VSTRING *);
+static int xsasl_cyrus_server_set_security(XSASL_SERVER *, const char *);
+static const char *xsasl_cyrus_server_get_mechanism_list(XSASL_SERVER *);
+static const char *xsasl_cyrus_server_get_username(XSASL_SERVER *);
+
+ /*
+  * SASL callback interface structure. These call-backs have no per-session
+  * context.
+  */
+#define NO_CALLBACK_CONTEXT    0
+
+static sasl_callback_t callbacks[] = {
+    {SASL_CB_LOG, &xsasl_cyrus_log, NO_CALLBACK_CONTEXT},
+    {SASL_CB_LIST_END, 0, 0}
+};
+
+/* xsasl_cyrus_server_init - create implementation handle */
+
+XSASL_SERVER_IMPL *xsasl_cyrus_server_init(const char *unused_server_type,
+                                                  const char *path_info)
+{
+    const char *myname = "xsasl_cyrus_server_init";
+    XSASL_SERVER_IMPL *xp;
+    int     sasl_status;
+
+#if SASL_VERSION_MAJOR >= 2 && (SASL_VERSION_MINOR >= 2 \
+    || (SASL_VERSION_MINOR == 1 && SASL_VERSION_STEP >= 19))
+    int     sasl_major;
+    int     sasl_minor;
+    int     sasl_step;
+
+    /*
+     * DLL hell guard.
+     */
+    sasl_version_info((const char **) 0, (const char **) 0,
+                     &sasl_major, &sasl_minor,
+                     &sasl_step, (int *) 0);
+    if (sasl_major != SASL_VERSION_MAJOR
+#if 0
+       || sasl_minor != SASL_VERSION_MINOR
+       || sasl_step != SASL_VERSION_STEP
+#endif
+       ) {
+       msg_warn("incorrect SASL library version. "
+             "Postfix was built with include files from version %d.%d.%d, "
+                "but the run-time library version is %d.%d.%d",
+                SASL_VERSION_MAJOR, SASL_VERSION_MINOR, SASL_VERSION_STEP,
+                sasl_major, sasl_minor, sasl_step);
+       return (0);
+    }
+#endif
+
+    /*
+     * Initialize the library: load SASL plug-in routines, etc.
+     */
+    if (msg_verbose)
+       msg_info("%s: SASL config file is %s.conf", myname, path_info);
+    if ((sasl_status = sasl_server_init(callbacks, path_info)) != SASL_OK) {
+       msg_warn("SASL per-process initialization failed: %s",
+                xsasl_cyrus_strerror(sasl_status));
+       return (0);
+    }
+
+    /*
+     * Return a generic XSASL_SERVER_IMPL object. We don't need to extend it
+     * with our own methods or data.
+     */
+    xp = (XSASL_SERVER_IMPL *) mymalloc(sizeof(*xp));
+    xp->create = xsasl_cyrus_server_create;
+    xp->done = xsasl_cyrus_server_done;
+    return (xp);
+}
+
+/* xsasl_cyrus_server_done - dispose of implementation */
+
+static void xsasl_cyrus_server_done(XSASL_SERVER_IMPL *impl)
+{
+    myfree((char *) impl);
+    sasl_done();
+}
+
+/* xsasl_cyrus_server_create - create server instance */
+
+static XSASL_SERVER *xsasl_cyrus_server_create(XSASL_SERVER_IMPL *unused_impl,
+                                                      VSTREAM *stream,
+                                                      const char *service,
+                                                      const char *realm,
+                                                      const char *sec_props)
+{
+    const char *myname = "xsasl_cyrus_server_create";
+    char   *server_address;
+    char   *client_address;
+    sasl_conn_t *sasl_conn = 0;
+    XSASL_CYRUS_SERVER *server = 0;
+    int     sasl_status;
+
+    if (msg_verbose)
+       msg_info("%s: SASL service=%s, realm=%s",
+                myname, service, realm ? realm : "(null)");
+
+    /*
+     * The optimizer will eliminate duplication and/or dead code.
+     */
+#define XSASL_CYRUS_SERVER_CREATE_ERROR_RETURN(x) \
+    do { \
+       if (server) { \
+           xsasl_cyrus_server_free(&server->xsasl); \
+       } else { \
+           if (sasl_conn) \
+               sasl_dispose(&sasl_conn); \
+       } \
+       return (x); \
+    } while (0)
+
+    /*
+     * Set up a new server context.
+     */
+#define NO_SECURITY_LAYERS     (0)
+#define NO_SESSION_CALLBACKS   ((sasl_callback_t *) 0)
+#define NO_AUTH_REALM          ((char *) 0)
+
+#if SASL_VERSION_MAJOR >= 2 && defined(USE_SASL_IP_AUTH)
+
+    /*
+     * Get IP addresses of local and remote endpoints for SASL.
+     */
+#error "USE_SASL_IP_AUTH is not implemented"
+
+#else
+
+    /*
+     * Don't give any IP address information to SASL.  SASLv1 doesn't use it,
+     * and in SASLv2 this will disable any mechaniams that do.
+     */
+    server_address = 0;
+    client_address = 0;
+#endif
+
+    if ((sasl_status =
+        SASL_SERVER_NEW(service, var_myhostname,
+                        realm ? realm : NO_AUTH_REALM,
+                        server_address, client_address,
+                        NO_SESSION_CALLBACKS, NO_SECURITY_LAYERS,
+                        &sasl_conn)) != SASL_OK) {
+       msg_warn("SASL per-connection server initialization: %s",
+                xsasl_cyrus_strerror(sasl_status));
+       XSASL_CYRUS_SERVER_CREATE_ERROR_RETURN(0);
+    }
+
+    /*
+     * Extend the XSASL_SERVER_IMPL object with our own data. We use
+     * long-lived conversion buffers rather than local variables to avoid
+     * memory leaks in case of read/write timeout or I/O error.
+     */
+    server = (XSASL_CYRUS_SERVER *) mymalloc(sizeof(*server));
+    server->xsasl.free = xsasl_cyrus_server_free;
+    server->xsasl.first = xsasl_cyrus_server_first;
+    server->xsasl.next = xsasl_cyrus_server_next;
+    server->xsasl.get_mechanism_list = xsasl_cyrus_server_get_mechanism_list;
+    server->xsasl.get_username = xsasl_cyrus_server_get_username;
+    server->stream = stream;
+    server->sasl_conn = sasl_conn;
+    server->decoded = vstring_alloc(20);
+    server->username = 0;
+    server->mechanism_list = 0;
+
+    if (xsasl_cyrus_server_set_security(&server->xsasl, sec_props)
+       != XSASL_AUTH_OK)
+       XSASL_CYRUS_SERVER_CREATE_ERROR_RETURN(0);
+
+    return (&server->xsasl);
+}
+
+/* xsasl_cyrus_server_set_security - set security properties */
+
+static int xsasl_cyrus_server_set_security(XSASL_SERVER *xp,
+                                                  const char *sasl_opts_val)
+{
+    XSASL_CYRUS_SERVER *server = (XSASL_CYRUS_SERVER *) xp;
+    sasl_security_properties_t sec_props;
+    int     sasl_status;
+
+    /*
+     * Security options. Some information can be found in the sasl.h include
+     * file.
+     */
+    memset(&sec_props, 0, sizeof(sec_props));
+    sec_props.min_ssf = 0;
+    sec_props.max_ssf = 0;                     /* don't allow real SASL
+                                                * security layer */
+    if (*sasl_opts_val == 0) {
+       sec_props.security_flags = 0;
+    } else {
+       sec_props.security_flags =
+           xsasl_cyrus_security_parse_opts(sasl_opts_val);
+       if (sec_props.security_flags == 0) {
+           msg_warn("bad per-session SASL security properties");
+           return (XSASL_AUTH_FAIL);
+       }
+    }
+    sec_props.maxbufsize = 0;
+    sec_props.property_names = 0;
+    sec_props.property_values = 0;
+
+    if ((sasl_status = sasl_setprop(server->sasl_conn, SASL_SEC_PROPS,
+                                   &sec_props)) != SASL_OK) {
+       msg_warn("SASL per-connection security setup; %s",
+                xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_FAIL);
+    }
+    return (XSASL_AUTH_OK);
+}
+
+/* xsasl_cyrus_server_get_mechanism_list - get available mechanisms */
+
+static const char *xsasl_cyrus_server_get_mechanism_list(XSASL_SERVER *xp)
+{
+    const char *myname = "xsasl_cyrus_server_get_mechanism_list";
+    XSASL_CYRUS_SERVER *server = (XSASL_CYRUS_SERVER *) xp;
+    MECHANISM_TYPE mechanism_list;
+    MECHANISM_COUNT_TYPE mechanism_count;
+    int     sasl_status;
+
+    /*
+     * Get the list of authentication mechanisms.
+     */
+#define UNSUPPORTED_USER       ((char *) 0)
+#define IGNORE_MECHANISM_LEN   ((unsigned *) 0)
+
+    if ((sasl_status = sasl_listmech(server->sasl_conn, UNSUPPORTED_USER,
+                                    "", " ", "",
+                                    &mechanism_list,
+                                    IGNORE_MECHANISM_LEN,
+                                    &mechanism_count)) != SASL_OK) {
+       msg_warn("%s: %s", myname, xsasl_cyrus_strerror(sasl_status));
+       return (0);
+    }
+    if (mechanism_count <= 0) {
+       msg_warn("%s: no applicable SASL mechanisms", myname);
+       return (0);
+    }
+    server->mechanism_list = mystrdup(mechanism_list);
+#if SASL_VERSION_MAJOR < 2
+    /* SASL version 1 doesn't free memory that it allocates. */
+    free(mechanism_list);
+#endif
+    return (server->mechanism_list);
+}
+
+/* xsasl_cyrus_server_free - destroy server instance */
+
+static void xsasl_cyrus_server_free(XSASL_SERVER *xp)
+{
+    XSASL_CYRUS_SERVER *server = (XSASL_CYRUS_SERVER *) xp;
+
+    sasl_dispose(&server->sasl_conn);
+    vstring_free(server->decoded);
+    if (server->username)
+       myfree(server->username);
+    if (server->mechanism_list)
+       myfree(server->mechanism_list);
+    myfree((char *) server);
+}
+
+/* xsasl_cyrus_server_auth_response - encode server first/next response */
+
+static int xsasl_cyrus_server_auth_response(int sasl_status,
+                                                   SERVEROUT_TYPE serverout,
+                                                   unsigned serveroutlen,
+                                                   VSTRING *reply)
+{
+    const char *myname = "xsasl_cyrus_server_auth_response";
+    unsigned enc_length;
+    unsigned enc_length_out;
+
+    /*
+     * Encode the server first/next non-error response; otherwise return the
+     * unencoded error text that corresponds to the SASL error status.
+     * 
+     * Regarding the hairy expression below: output from sasl_encode64() comes
+     * in multiples of four bytes for each triple of input bytes, plus four
+     * bytes for any incomplete last triple, plus one byte for the null
+     * terminator.
+     */
+    if (sasl_status == SASL_OK) {
+       vstring_strcpy(reply, "");
+       return (XSASL_AUTH_DONE);
+    } else if (sasl_status == SASL_CONTINUE) {
+       if (msg_verbose)
+           msg_info("%s: uncoded server challenge: %.*s",
+                    myname, (int) serveroutlen, serverout);
+       enc_length = ((serveroutlen + 2) / 3) * 4 + 1;
+       VSTRING_RESET(reply);                   /* Fix 200512 */
+       VSTRING_SPACE(reply, enc_length);
+       if ((sasl_status = sasl_encode64(serverout, serveroutlen,
+                                        STR(reply), vstring_avail(reply),
+                                        &enc_length_out)) != SASL_OK)
+           msg_panic("%s: sasl_encode64 botch: %s",
+                     myname, xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_MORE);
+    } else {
+       vstring_strcpy(reply, xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_FAIL);
+    }
+}
+
+/* xsasl_cyrus_server_first - per-session authentication */
+
+int     xsasl_cyrus_server_first(XSASL_SERVER *xp, const char *sasl_method,
+                                 const char *init_response, VSTRING *reply)
+{
+    char   *myname = "xsasl_cyrus_server_first";
+    XSASL_CYRUS_SERVER *server = (XSASL_CYRUS_SERVER *) xp;
+    char   *dec_buffer;
+    unsigned dec_length;
+    unsigned reply_len;
+    unsigned serveroutlen;
+    int     sasl_status;
+    SERVEROUT_TYPE serverout = 0;
+    int     xsasl_status;
+
+#if SASL_VERSION_MAJOR < 2
+    const char *errstr = 0;
+
+#endif
+
+#define IFELSE(e1,e2,e3) ((e1) ? (e2) : (e3))
+
+    if (msg_verbose)
+       msg_info("%s: sasl_method %s%s%s", myname, sasl_method,
+                IFELSE(init_response, ", init_response ", ""),
+                IFELSE(init_response, init_response, ""));
+
+    /*
+     * SASL authentication protocol start-up. Process any initial client
+     * response that was sent along in the AUTH command.
+     */
+    if (init_response) {
+       reply_len = strlen(init_response);
+       VSTRING_RESET(server->decoded);         /* Fix 200512 */
+       VSTRING_SPACE(server->decoded, reply_len);
+       if ((sasl_status = SASL_DECODE64(init_response, reply_len,
+                                        dec_buffer = STR(server->decoded),
+                                        vstring_avail(server->decoded),
+                                        &dec_length)) != SASL_OK) {
+           vstring_strcpy(reply, xsasl_cyrus_strerror(sasl_status));
+           return (XSASL_AUTH_FORM);
+       }
+       if (msg_verbose)
+           msg_info("%s: decoded initial response %s", myname, dec_buffer);
+    } else {
+       dec_buffer = 0;
+       dec_length = 0;
+    }
+    sasl_status = SASL_SERVER_START(server->sasl_conn, sasl_method, dec_buffer,
+                                   dec_length, &serverout,
+                                   &serveroutlen, &errstr);
+    xsasl_status = xsasl_cyrus_server_auth_response(sasl_status, serverout,
+                                                   serveroutlen, reply);
+#if SASL_VERSION_MAJOR < 2
+    /* SASL version 1 doesn't free memory that it allocates. */
+    free(serverout);
+#endif
+    return (xsasl_status);
+}
+
+/* xsasl_cyrus_server_next - continue authentication */
+
+static int xsasl_cyrus_server_next(XSASL_SERVER *xp, const char *request,
+                                          VSTRING *reply)
+{
+    char   *myname = "xsasl_cyrus_server_next";
+    XSASL_CYRUS_SERVER *server = (XSASL_CYRUS_SERVER *) xp;
+    unsigned dec_length;
+    unsigned request_len;
+    unsigned serveroutlen;
+    int     sasl_status;
+    SERVEROUT_TYPE serverout = 0;
+    int     xsasl_status;
+
+#if SASL_VERSION_MAJOR < 2
+    const char *errstr = 0;
+
+#endif
+
+    request_len = strlen(request);
+    VSTRING_RESET(server->decoded);            /* Fix 200512 */
+    VSTRING_SPACE(server->decoded, request_len);
+    if ((sasl_status = SASL_DECODE64(request, request_len,
+                                    STR(server->decoded),
+                                    vstring_avail(server->decoded),
+                                    &dec_length)) != SASL_OK) {
+       vstring_strcpy(reply, xsasl_cyrus_strerror(sasl_status));
+       return (XSASL_AUTH_FORM);
+    }
+    if (msg_verbose)
+       msg_info("%s: decoded response: %.*s",
+                myname, (int) dec_length, STR(server->decoded));
+    sasl_status = SASL_SERVER_STEP(server->sasl_conn, STR(server->decoded),
+                                  dec_length, &serverout,
+                                  &serveroutlen, &errstr);
+    xsasl_status = xsasl_cyrus_server_auth_response(sasl_status, serverout,
+                                                   serveroutlen, reply);
+#if SASL_VERSION_MAJOR < 2
+    /* SASL version 1 doesn't free memory that it allocates. */
+    free(serverout);
+#endif
+    return (xsasl_status);
+}
+
+/* xsasl_cyrus_server_get_username - get authenticated username */
+
+static const char *xsasl_cyrus_server_get_username(XSASL_SERVER *xp)
+{
+    const char *myname = "xsasl_cyrus_server_get_username";
+    XSASL_CYRUS_SERVER *server = (XSASL_CYRUS_SERVER *) xp;
+    VOID_SERVEROUT_TYPE serverout = 0;
+    int     sasl_status;
+
+    /*
+     * XXX Do not free(serverout).
+     */
+    sasl_status = sasl_getprop(server->sasl_conn, SASL_USERNAME, &serverout);
+    if (sasl_status != SASL_OK || serverout == 0) {
+       msg_warn("%s: sasl_getprop SASL_USERNAME botch: %s",
+                myname, xsasl_cyrus_strerror(sasl_status));
+       return (0);
+    }
+    if (server->username)
+       myfree(server->username);
+    server->username = mystrdup(serverout);
+    printable(server->username, '?');
+    return (server->username);
+}
+
+#endif
diff --git a/postfix/src/xsasl/xsasl_server.c b/postfix/src/xsasl/xsasl_server.c
new file mode 100644 (file)
index 0000000..729cb46
--- /dev/null
@@ -0,0 +1,228 @@
+/*++
+/* NAME
+/*     xsasl-server 3
+/* SUMMARY
+/*     Postfix SASL server plug-in interface
+/* SYNOPSIS
+/*     #include <xsasl.h>
+/*
+/*     XSASL_SERVER_IMPL *xsasl_server_init(server_type, path_info)
+/*     const char *server_type;
+/*     const char *path_info;
+/*
+/*     void    xsasl_server_done(implementation)
+/*     XSASL_SERVER_IMPL *implementation;
+/*
+/*     ARGV    *xsasl_server_types()
+/*
+/*     XSASL_SERVER *xsasl_server_create(implementation, stream, service,
+/*                                             user_realm, security_options)
+/*     XSASL_SERVER_IMPL *implementation;
+/*     const char *service;
+/*     VSTREAM *stream;
+/*     const char *user_realm;
+/*     const char *security_options;
+/*
+/*     void xsasl_server_free(server)
+/*     XSASL_SERVER *server;
+/*
+/*     int     xsasl_server_first(server, auth_method, init_resp, server_reply)
+/*     XSASL_SERVER *server;
+/*     const char *auth_method;
+/*     const char *init_resp;
+/*     VSTRING *server_reply;
+/*
+/*     int     xsasl_server_next(server, client_request, server_reply)
+/*     XSASL_SERVER *server;
+/*     const char *client_request;
+/*     VSTRING *server_reply;
+/*
+/*     const char *xsasl_server_get_mechanism_list(server)
+/*     XSASL_SERVER *server;
+/*
+/*     const char *xsasl_server_get_username(server)
+/*     XSASL_SERVER *server;
+/* DESCRIPTION
+/*     The XSASL_SERVER abstraction implements a generic interface
+/*     to one or more SASL authentication implementations.
+/*
+/*     xsasl_server_init() is called once during process initialization.
+/*     It selects a SASL implementation by name, specifies the
+/*     location of a configuration file or rendez-vous point, and
+/*     returns an implementation handle that can be used to generate
+/*     SASL server instances. This function is typically used to
+/*     initialize the underlying implementation.
+/*
+/*     xsasl_server_done() disposes of an implementation handle,
+/*     and allows the underlying implementation to release resources.
+/*
+/*     xsasl_server_types() lists the available implementation types.
+/*     The result should be destroyed by the caller.
+/*
+/*     xsasl_server_create() is called at the start of an SMTP
+/*     session. It generates a Postfix SASL plug-in server instance
+/*     for the specified service and authentication realm, and
+/*     with the specified security properties. Specify a null
+/*     pointer when no realm should be used. The stream handle is
+/*     stored so that encryption can be turned on after successful
+/*     negotiations.
+/*
+/*     xsasl_server_free() is called at the end of an SMTP session.
+/*     It destroys a SASL server instance, and disables further
+/*     read/write operations if encryption was turned on.
+/*
+/*     xsasl_server_first() produces the server reponse for the
+/*     client AUTH command. The client input are an authentication
+/*     method, and an optional initial response or null pointer.
+/*     The initial response and server non-error replies are BASE64
+/*     encoded.  Server error replies are 7-bit ASCII text without
+/*     control characters, without BASE64 encoding, and without
+/*     SMTP reply code or enhanced status code.
+/*
+/*     The result is one of the following:
+/* .IP XSASL_AUTH_MORE
+/*     More client input is needed. The server reply specifies
+/*     what.
+/* .IP XSASL_AUTH_DONE
+/*     Authentication completed successfully.
+/* .IP XSASL_AUTH_FORM
+/*     The client input is incorrectly formatted. The server error
+/*     reply explains why.
+/* .IP XSASL_AUTH_FAIL
+/*     Authentication failed. The server error reply explains why.
+/* .PP
+/*     xsasl_server_next() supports the subsequent stages of the
+/*     client-server AUTH protocol. Both the client input and
+/*     server non-error responses are BASE64 encoded.  See
+/*     xsasl_server_first() for other details.
+/*
+/*     xsasl_server_get_mechanism_list() returns the authentication
+/*     mechanisms that match the security properties, as a white-space
+/*     separated list. This is meant to be used in the SMTP EHLO
+/*     reply.
+/*
+/*     xsasl_server_get_username() returns the stored username
+/*     after successful authentication.
+/*
+/*     Arguments:
+/* .IP auth_method
+/*     AUTH command authentication method.
+/* .IP init_resp
+/*     AUTH command initial response or null pointer.
+/* .IP implementation
+/*     Implementation handle that was obtained with xsasl_server_init().
+/* .IP path_info
+/*     The value of the smtpd_sasl_path parameter or equivalent.
+/*     This specifies the implementation-dependent location of a
+/*     configuration file, rendez-vous point, etc., and is passed
+/*     unchanged to the plug-in.
+/* .IP security_options
+/*     The value of the smtpd_security_options parameter or
+/*     equivalent. This is passed unchanged to the plug-in.
+/* .IP server
+/*     SASL plug-in server handle.
+/* .IP server_reply
+/*     BASE64 encoded server non-error reply (without SMTP reply
+/*     code or enhanced status code), or ASCII error description.
+/* .IP server_type
+/*     The name of a Postfix SASL server plug_in implementation.
+/* .IP server_types
+/*     Null-terminated array of strings with SASL server plug-in
+/*     implementation names.
+/* .IP service
+/*     The service that is implemented by the local server, typically
+/*     "smtp" or "lmtp".
+/* .IP stream
+/*     The connection between client and server.  When SASL
+/*     encryption is negotiated, the plug-in will transparently
+/*     intercept the socket read/write operations.
+/* .IP user_realm
+/*     Authentication domain or null pointer.
+/* SECURITY
+/* .ad
+/* .fi
+/*     The caller does not sanitize client input. It is the
+/*     responsibility of the underlying SASL server implementation
+/*     to produce 7-bit ASCII without control characters as server
+/*     non-error and error replies, and as the result from
+/*     xsasl_server_method() and xsasl_server_username().
+/* DIAGNOSTICS
+/*     In case of failure, xsasl_server_init(), xsasl_server_create(),
+/*     xsasl_server_get_mechanism_list() and xsasl_server_get_username()
+/*     log a warning and return a null pointer.
+/*
+/*     Functions that normally return XSASL_AUTH_OK will log a warning
+/*     and return an appropriate result value.
+/*
+/*     Fatal errors: out of memory.
+/*
+/*     Panic: interface violations.
+/* SEE ALSO
+/*     cyrus_security(3) Cyrus SASL security features
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this
+/*     software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+
+/* SASL implementations. */
+
+#include <xsasl.h>
+#include <xsasl_cyrus.h>
+
+ /*
+  * Lookup table for available SASL server implementations.
+  */
+typedef struct {
+    char   *server_type;
+    struct XSASL_SERVER_IMPL *(*server_init) (const char *, const char *);
+} XSASL_SERVER_IMPL_INFO;
+
+static XSASL_SERVER_IMPL_INFO server_impl_info[] = {
+#ifdef XSASL_TYPE_CYRUS
+    XSASL_TYPE_CYRUS, xsasl_cyrus_server_init,
+#endif
+    0,
+};
+
+/* xsasl_server_init - look up server implementation by name */
+
+XSASL_SERVER_IMPL *xsasl_server_init(const char *server_type,
+                                            const char *path_info)
+{
+    XSASL_SERVER_IMPL_INFO *xp;
+
+    for (xp = server_impl_info; xp->server_type; xp++)
+       if (strcmp(server_type, xp->server_type) == 0)
+           return (xp->server_init(server_type, path_info));
+    msg_warn("unsupported SASL server implementation: %s", server_type);
+    return (0);
+}
+
+/* xsasl_server_types - report available implementation types */
+
+ARGV   *xsasl_server_types(void)
+{
+    XSASL_SERVER_IMPL_INFO *xp;
+    ARGV   *argv = argv_alloc(1);
+
+    for (xp = server_impl_info; xp->server_type; xp++)
+       argv_add(argv, xp->server_type, ARGV_END);
+    return (argv);
+}