pre-formatted message from file, and to handle replies other
than the expected 2xx or 3xx. File: smtpstone/smtp-source.c.
- Cleanup: streamlined Milter client error handling, so that
- the (Postfix SMTP server's Milter client) does not get out
- of sync with Milter applications after the (cleanup server's
- Milter client) encounters some non-recoverable problem.
- Files: milter/milter8.c, smtpd/smtpd.c.
+ Cleanup: Milter client error handling, so that the (Postfix
+ SMTP server's Milter client) does not get out of sync with
+ Milter applications after the (cleanup server's Milter
+ client) encounters some non-recoverable problem. Files:
+ milter/milter8.c, smtpd/smtpd.c.
+
+20070720
+
+ Support for RFC 4954 (SASL AUTH, updates RFC 2554, refines
+ some reply codes and introduces DSN enhanced status codes)
+ and RFC 3848 ("Received ... with ESMTPS?A? ...). Currently,
+ support for the latter is always on. Files: smtpd/smtpd.c,
+ smtpd/smtpd_sasl_proto.c, smtpd/smtpd_sasl_glue.c.
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
-Postfix SASL support (RFC 2554) can be used to authenticate remote SMTP clients
-to the Postfix SMTP server, and to authenticate the Postfix SMTP client to a
-remote SMTP server.
+Postfix SASL support (RFC 4954, formerly RFC 2554) can be used to authenticate
+remote SMTP clients to the Postfix SMTP server, and to authenticate the Postfix
+SMTP client to a remote SMTP server.
-When receiving mail, Postfix logs the client-provided username, authentication
-method, and sender address to the maillog file, and optionally grants mail
-access via the permit_sasl_authenticated UCE restriction.
+When receiving mail, the Postfix SMTP server logs the client-provided username,
+authentication 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 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.
+When sending mail, the Postfix SMTP client can look up the remote SMTP server
+hostname or destination domain (the address right-hand part) in a SASL password
+table, and if a username/password is found, it will use that username and
+password to authenticate to the remote SMTP 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:
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
-In order to enable SASL support in the SMTP server:
+In order to enable SASL support in the Postfix SMTP server:
/etc/postfix/main.cf:
smtpd_sasl_auth_enable = yes
-In order to allow mail relaying by authenticated clients:
+In order to allow mail relaying by authenticated remote SMTP clients:
/etc/postfix/main.cf:
smtpd_recipient_restrictions =
Dovecot SASL support is available in Postfix 2.3 and later. On the Postfix side
you need to specify the location of the Dovecot authentication daemon socket.
We use a pathname relative to the Postfix queue directory, so that it will work
-whether or not Postfix runs chrooted:
+whether or not the Postfix SMTP server runs chrooted:
/etc/postfix/main.cf:
smtpd_sasl_type = dovecot
C\bCy\byr\bru\bus\bs S\bSA\bAS\bSL\bL c\bco\bon\bnf\bfi\big\bgu\bur\bra\bat\bti\bio\bon\bn f\bfo\bor\br t\bth\bhe\be P\bPo\bos\bst\btf\bfi\bix\bx S\bSM\bMT\bTP\bP s\bse\ber\brv\bve\ber\br
-You need to configure how the Cyrus SASL library should authenticate a client's
-username and password. These settings must be stored in a separate
-configuration file.
+You need to configure how the Cyrus SASL library should authenticate a remote
+SMTP client's username and password. These settings must be stored in a
+separate configuration file.
The name of the configuration file (default: smtpd.conf) will be constructed
-from a value sent by Postfix to the Cyrus SASL library, which adds the suffix
-.conf. The value is configured using one of the following variables:
+from a value that the Postfix SMTP server sends to the Cyrus SASL library,
+which adds the suffix .conf. The value is configured using one of the following
+variables:
/etc/postfix/main.cf:
# Postfix 2.3 and later
pwcheck_method: pwcheck
IMPORTANT: pwcheck establishes a UNIX domain socket in /var/pwcheck and
- waits for authentication requests. Postfix processes must have
+ waits for authentication requests. The Postfix SMTP server must have
read+execute permission to this directory or authentication attempts
will fail.
a pam".
IMPORTANT: saslauthd usually establishes a UNIX domain socket in /var/run/
- saslauthd and waits for authentication requests. Postfix processes must
- have read+execute permission to this directory or authentication attempts
- will fail.
+ saslauthd and waits for authentication requests. The Postfix SMTP server
+ must have read+execute permission to this directory or authentication
+ attempts will fail.
Note: The directory where saslauthd puts the socket is configurable. See
the command-line option "-m /path/to/socket" in the saslauthd --help
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).
+ access permissions. With the OTP authentication mechanism, the Postfix SMTP
+ server also needs WRITE access to /etc/sasldb2 or /etc/sasldb (or the back
+ end SQL database, if used).
IMPORTANT: To get sasldb running, make sure that you set the SASL domain
(realm) to a fully qualified domain name.
sasldblistusers (Cyrus SASL version 1.5.x) or sasldblistusers2 (Cyrus SASL
version 2.1.x).
- On the Postfix side, you can have only one realm per smtpd instance, and
+ On the Postfix side, you can have only one realm per smtpd(8) 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:
+ Postfix variable smtpd_sasl_local_domain controls the realm used by smtpd
+ (8):
/etc/postfix/main.cf:
smtpd_sasl_local_domain = $myhostname
can only support the plaintext mechanisms PLAIN or LOGIN. However, the Cyrus
SASL library doesn't know this, and will happily advertise other authentication
mechanisms that the SASL library implements, such as DIGEST-MD5. As a result,
-if an SMTP client chooses any mechanism other than PLAIN or LOGIN while pwcheck
-or saslauthd are used, authentication will fail. Thus you may need to limit the
-list of mechanisms advertised by Postfix.
+if a remote SMTP client chooses any mechanism other than PLAIN or LOGIN while
+pwcheck or saslauthd are used, authentication will fail. Thus you may need to
+limit the list of mechanisms advertised by the Postfix SMTP server.
* With older Cyrus SASL versions you remove the corresponding library files
from the SASL plug-in directory (and again whenever the system is updated).
T\bTe\bes\bst\bti\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
-To test the server side, connect to the SMTP server, and you should be able to
-have a conversation as shown below. Information sent by the client is shown in
-bold font.
+To test the server side, connect (for example, with telnet) to the Postfix SMTP
+server port and you should be able to have a conversation as shown below.
+Information sent by the client (that is, you) is shown in bold font.
+ $ t\bte\bel\bln\bne\bet\bt s\bse\ber\brv\bve\ber\br.\b.e\bex\bxa\bam\bmp\bpl\ble\be.\b.c\bco\bom\bm 2\b25\b5
+ . . .
220 server.example.com ESMTP Postfix
E\bEH\bHL\bLO\bO c\bcl\bli\bie\ben\bnt\bt.\b.e\bex\bxa\bam\bmp\bpl\ble\be.\b.c\bco\bom\bm
250-server.example.com
% su postfix
-then run the resulting sample server and client in separate terminals. The
-sample applications send log messages to the syslog facility auth. Check the
-log to fix the problem or run strace / ktrace / truss on the server to see what
-makes it unhappy. Repeat the previous step until you can successfully
-authenticate with the sample client. Only then get back to Postfix.
+then run the resulting sample Cyrus SASL server and client in separate
+terminals. The sample applications send log messages to the syslog facility
+auth. Check the log to fix the problem or run strace / ktrace / truss on the
+server to see what makes it unhappy. Repeat the previous step until you can
+successfully authenticate with the sample Cyrus SASL client. Only then get back
+to Postfix.
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 c\bcl\bli\bie\ben\bnt\bt
Turn on client-side SASL authentication, and specify a table with per-host or
-per-destination username and password information. Postfix first searches the
-table for an entry with the server hostname; if no entry is found, then Postfix
-searches the table for an entry with the next-hop destination. Usually, that is
-the right-hand part of an email address, but it can also be the information
-that is specified with the relayhost parameter or with a transport(5) table.
+per-destination username and password information. The Postfix SMTP client
+first searches the table for an entry with the remote SMTP server hostname; if
+no entry is found, then the Postfix SMTP client searches the table for an entry
+with the next-hop destination. Usually, that is the right-hand part of an email
+address, but it can also be the information that is specified with the
+relayhost parameter or with a transport(5) table.
/etc/postfix/main.cf:
smtp_sasl_auth_enable = yes
[mail.myisp.net] username:password
[mail.myisp.net]:submission username:password
-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 and set
+The Postfix SMTP client opens the SASL client password file before entering the
+optional chroot jail, so you can keep the file in /etc/postfix and set
permissions read / write only for root to keep the username:password
combinations away from other system users.
[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:
+Note: some remote 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:
"Authentication failed: cannot SASL authenticate to server". To enable
plaintext authentication specify, for example:
/etc/postfix/main.cf:
smtp_sasl_security_options = noanonymous
-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:
+Note: some remote SMTP servers announce authentication mechanisms that don't
+actually work. It is possible via the smtp_sasl_mechanism_filter parameter to
+restrict the list of server mechanisms that the Postfix SMTP 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 or TLS.
+In the above example, the Postfix SMTP client will decline to use mechanisms
+that require special infrastructure such as Kerberos or TLS.
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
If you upgrade from Postfix 2.3 or earlier, read RELEASE_NOTES-2.4
before proceeding.
+Major changes with Postfix snapshot 20070724
+============================================
+
+Not really major. Support for RFC 3848 (ESMTPS, ESMTPA, ESMTPSA
+in Received: headers) and updated SASL support with reply codes and
+enhanced (DSN) status codes as per RFC 4954.
+
Incompatibility with Postfix snapshot 20070614
==============================================
<h2><a name="intro">How Postfix uses SASL authentication information</a></h2>
-<p> Postfix SASL support (<a href="http://tools.ietf.org/html/rfc2554">RFC 2554</a>) can be used to authenticate
+<p> Postfix SASL support (<a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a>, formerly RFC 2554) can be used
+to authenticate
remote SMTP clients to the Postfix SMTP server, and to authenticate
the Postfix SMTP client to a remote SMTP server. </p>
-<p> When receiving mail, Postfix logs the client-provided username,
+<p> When receiving mail, the Postfix SMTP server logs the client-provided
+username,
authentication method, and sender address to the maillog file, and
optionally grants mail access via the <a href="postconf.5.html#permit_sasl_authenticated">permit_sasl_authenticated</a>
UCE restriction. </p>
-<p> When sending mail, Postfix can look up the server hostname or
-destination domain (the address right-hand part) in a Postfix SASL password
+<p> When sending mail, the Postfix SMTP client can look up the
+remote SMTP server hostname or
+destination domain (the address right-hand part) in a 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,
+and password to authenticate to the remote SMTP server. And as of
+version 2.3,
Postfix can be configured to search its SASL password table by the
sender email address. </p>
<h2><a name="server_sasl">Enabling SASL authentication in the Postfix
SMTP server</a></h2>
-<p> In order to enable SASL support in the SMTP server: </p>
+<p> In order to enable SASL support in the Postfix SMTP server: </p>
<blockquote>
<pre>
</pre>
</blockquote>
-<p> In order to allow mail relaying by authenticated clients: </p>
+<p> In order to allow mail relaying by authenticated remote SMTP
+clients: </p>
<blockquote>
<pre>
the Postfix side you need to specify the location of the
Dovecot authentication daemon socket. We use a pathname relative
to the Postfix queue directory, so that it will work whether or not
-Postfix runs chrooted: </p>
+the Postfix SMTP server runs chrooted: </p>
<blockquote>
<pre>
SMTP server</a></h2>
<p> You need to configure how the Cyrus SASL library should
-authenticate a client's username and password. These settings must
+authenticate a remote SMTP client's username and password. These
+settings must
be stored in a separate configuration file. </p>
<p> The name of the configuration file (default: smtpd.conf) will
-be constructed from a value sent by Postfix to the Cyrus SASL
+be constructed from a value that the Postfix SMTP server sends to
+the Cyrus SASL
library, which adds the suffix .conf. The value is configured using
one of the following variables: </p>
</pre>
<p> IMPORTANT: pwcheck establishes a UNIX domain socket in /var/pwcheck
-and waits for authentication requests. Postfix processes must have
+and waits for authentication requests. The Postfix SMTP server must have
read+execute permission to this directory or authentication attempts
will fail. </p>
start saslauthd with "-a pam". </p>
<p> IMPORTANT: saslauthd usually establishes a UNIX domain socket
-in /var/run/saslauthd and waits for authentication requests. Postfix
-processes must have read+execute permission to this directory or
+in /var/run/saslauthd and waits for authentication requests. The Postfix
+SMTP server must have read+execute permission to this directory or
authentication attempts will fail. </p>
<p> Note: The directory where saslauthd puts the socket is configurable.
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 Postfix SMTP server also needs WRITE access to /etc/sasldb2 or
+/etc/sasldb
(or the back end SQL database, if used). </p>
<p> IMPORTANT: To get sasldb running, make sure that you set the SASL
in sasldb with <i>sasldblistusers</i> (Cyrus SASL version 1.5.x) or
<i>sasldblistusers2</i> (Cyrus SASL version 2.1.x). </p>
-<p> On the Postfix side, you can have only one realm per smtpd
+<p> On the Postfix side, you can have only one realm per <a href="smtpd.8.html">smtpd(8)</a>
instance, and only the users belonging to that realm would be able to
authenticate. The Postfix variable <a href="postconf.5.html#smtpd_sasl_local_domain">smtpd_sasl_local_domain</a> controls the
-realm used by smtpd: </p>
+realm used by <a href="smtpd.8.html">smtpd(8)</a>: </p>
<blockquote>
<pre>
and saslauthd can only support the plaintext mechanisms PLAIN or
LOGIN. However, the Cyrus SASL library doesn't know this, and will
happily advertise other authentication mechanisms that the SASL
-library implements, such as DIGEST-MD5. As a result, if an SMTP
+library implements, such as DIGEST-MD5. As a result, if a remote SMTP
client chooses any mechanism other than PLAIN or LOGIN while pwcheck
or saslauthd are used, authentication will fail. Thus you may need
-to limit the list of mechanisms advertised by Postfix. </p>
+to limit the list of mechanisms advertised by the Postfix SMTP
+server. </p>
<ul>
<h2><a name="server_test">Testing SASL authentication in the Postfix
SMTP server</a></h2>
-<p> To test the server side, connect to the SMTP server, and you should
+<p> To test the server side, connect (for example, with telnet) to the
+Postfix SMTP server port and you should
be able to have a conversation as shown below. Information sent by the
-client is shown in bold font. </p>
+client (that is, you) is shown in bold font. </p>
<blockquote>
<pre>
+$ <b>telnet server.example.com 25</b>
+. . .
220 server.example.com ESMTP Postfix
<b>EHLO client.example.com</b>
250-server.example.com
</pre>
</blockquote>
-<p> then run the resulting sample server and client in separate
-terminals. The sample applications send log messages to the syslog
+<p> then run the resulting sample Cyrus SASL server and client in
+separate terminals. The sample applications send log messages to
+the syslog
facility auth. Check the log to fix the problem or run strace /
ktrace / truss on the server to see what makes it unhappy. Repeat
the previous step until you can successfully authenticate with the
-sample client. Only then get back to Postfix. </p>
+sample Cyrus SASL client. Only then get back to Postfix. </p>
<h2><a name="client_sasl">Enabling SASL authentication in the
Postfix SMTP client</a></h2>
<p> Turn on client-side SASL authentication, and specify a table
with per-host or per-destination username and password information.
-Postfix first searches the table for an entry with the server
-hostname; if no entry is found, then Postfix searches the table for
+The Postfix SMTP client first searches the table for an entry with
+the remote SMTP server hostname; if no entry is found, then the
+Postfix SMTP client searches the table for
an entry with the next-hop destination. Usually, that is the
right-hand part of an email address, but it can also be the information
that is specified with the <a href="postconf.5.html#relayhost">relayhost</a> parameter or with a <a href="transport.5.html">transport(5)</a>
</pre>
</blockquote>
-<p> The Postfix SASL client password file is opened before the SMTP
-server enters the optional chroot jail, so you can keep the file
+<p> The Postfix SMTP client opens the SASL client password file
+before entering the optional chroot jail, so you can keep the file
in /etc/postfix and set permissions read / write only for root to
keep the username:password combinations away from other system
users. </p>
</pre>
</blockquote>
-<p> Note: some SMTP servers support PLAIN or LOGIN authentication only.
+<p> Note: some remote 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: "Authentication failed: cannot SASL
</pre>
</blockquote>
-<p> 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 <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>
+<p> Note: some remote SMTP servers announce authentication mechanisms
+that don't actually work. It is possible via the <a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a>
+parameter to restrict the list of server mechanisms that the Postfix
+SMTP client will take into consideration: </p>
<blockquote>
<pre>
</pre>
</blockquote>
-<p> In the above example, Postfix will decline to use mechanisms
+<p> In the above example, the Postfix SMTP client will decline to
+use mechanisms
that require special infrastructure such as Kerberos or TLS. </p>
<p> The Postfix SMTP client is backwards compatible with SMTP
<a href="http://tools.ietf.org/html/rfc3207">RFC 3207</a> (STARTTLS command)
<a href="http://tools.ietf.org/html/rfc3461">RFC 3461</a> (SMTP DSN Extension)
<a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes)
+ <a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a> (AUTH command)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Cor-
<a href="http://tools.ietf.org/html/rfc3207">RFC 3207</a> (STARTTLS command)
<a href="http://tools.ietf.org/html/rfc3461">RFC 3461</a> (SMTP DSN Extension)
<a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes)
+ <a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a> (AUTH command)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8). Cor-
<a href="http://tools.ietf.org/html/rfc3207">RFC 3207</a> (STARTTLS command)
<a href="http://tools.ietf.org/html/rfc3461">RFC 3461</a> (SMTP DSN Extension)
<a href="http://tools.ietf.org/html/rfc3463">RFC 3463</a> (Enhanced Status Codes)
+ <a href="http://tools.ietf.org/html/rfc3848">RFC 3848</a> (ESMTP Transmission Types)
+ <a href="http://tools.ietf.org/html/rfc4954">RFC 4954</a> (AUTH command)
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8).
RFC 3207 (STARTTLS command)
RFC 3461 (SMTP DSN Extension)
RFC 3463 (Enhanced Status Codes)
+RFC 4954 (AUTH command)
.SH DIAGNOSTICS
.ad
.fi
RFC 3207 (STARTTLS command)
RFC 3461 (SMTP DSN Extension)
RFC 3463 (Enhanced Status Codes)
+RFC 3848 (ESMTP Transmission Types)
+RFC 4954 (AUTH command)
.SH DIAGNOSTICS
.ad
.fi
<h2><a name="intro">How Postfix uses SASL authentication information</a></h2>
-<p> Postfix SASL support (RFC 2554) can be used to authenticate
+<p> Postfix SASL support (RFC 4954, formerly RFC 2554) can be used
+to authenticate
remote SMTP clients to the Postfix SMTP server, and to authenticate
the Postfix SMTP client to a remote SMTP server. </p>
-<p> When receiving mail, Postfix logs the client-provided username,
+<p> When receiving mail, the Postfix SMTP server logs the client-provided
+username,
authentication method, and sender address to the maillog file, and
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 Postfix SASL password
+<p> When sending mail, the Postfix SMTP client can look up the
+remote SMTP server hostname or
+destination domain (the address right-hand part) in a 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,
+and password to authenticate to the remote SMTP server. And as of
+version 2.3,
Postfix can be configured to search its SASL password table by the
sender email address. </p>
<h2><a name="server_sasl">Enabling SASL authentication in the Postfix
SMTP server</a></h2>
-<p> In order to enable SASL support in the SMTP server: </p>
+<p> In order to enable SASL support in the Postfix SMTP server: </p>
<blockquote>
<pre>
</pre>
</blockquote>
-<p> In order to allow mail relaying by authenticated clients: </p>
+<p> In order to allow mail relaying by authenticated remote SMTP
+clients: </p>
<blockquote>
<pre>
the Postfix side you need to specify the location of the
Dovecot authentication daemon socket. We use a pathname relative
to the Postfix queue directory, so that it will work whether or not
-Postfix runs chrooted: </p>
+the Postfix SMTP server runs chrooted: </p>
<blockquote>
<pre>
SMTP server</a></h2>
<p> You need to configure how the Cyrus SASL library should
-authenticate a client's username and password. These settings must
+authenticate a remote SMTP client's username and password. These
+settings must
be stored in a separate configuration file. </p>
<p> The name of the configuration file (default: smtpd.conf) will
-be constructed from a value sent by Postfix to the Cyrus SASL
+be constructed from a value that the Postfix SMTP server sends to
+the Cyrus SASL
library, which adds the suffix .conf. The value is configured using
one of the following variables: </p>
</pre>
<p> IMPORTANT: pwcheck establishes a UNIX domain socket in /var/pwcheck
-and waits for authentication requests. Postfix processes must have
+and waits for authentication requests. The Postfix SMTP server must have
read+execute permission to this directory or authentication attempts
will fail. </p>
start saslauthd with "-a pam". </p>
<p> IMPORTANT: saslauthd usually establishes a UNIX domain socket
-in /var/run/saslauthd and waits for authentication requests. Postfix
-processes must have read+execute permission to this directory or
+in /var/run/saslauthd and waits for authentication requests. The Postfix
+SMTP server must have read+execute permission to this directory or
authentication attempts will fail. </p>
<p> Note: The directory where saslauthd puts the socket is configurable.
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 Postfix SMTP server also needs WRITE access to /etc/sasldb2 or
+/etc/sasldb
(or the back end SQL database, if used). </p>
<p> IMPORTANT: To get sasldb running, make sure that you set the SASL
in sasldb with <i>sasldblistusers</i> (Cyrus SASL version 1.5.x) or
<i>sasldblistusers2</i> (Cyrus SASL version 2.1.x). </p>
-<p> On the Postfix side, you can have only one realm per smtpd
+<p> On the Postfix side, you can have only one realm per smtpd(8)
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: </p>
+realm used by smtpd(8): </p>
<blockquote>
<pre>
and saslauthd can only support the plaintext mechanisms PLAIN or
LOGIN. However, the Cyrus SASL library doesn't know this, and will
happily advertise other authentication mechanisms that the SASL
-library implements, such as DIGEST-MD5. As a result, if an SMTP
+library implements, such as DIGEST-MD5. As a result, if a remote SMTP
client chooses any mechanism other than PLAIN or LOGIN while pwcheck
or saslauthd are used, authentication will fail. Thus you may need
-to limit the list of mechanisms advertised by Postfix. </p>
+to limit the list of mechanisms advertised by the Postfix SMTP
+server. </p>
<ul>
<h2><a name="server_test">Testing SASL authentication in the Postfix
SMTP server</a></h2>
-<p> To test the server side, connect to the SMTP server, and you should
+<p> To test the server side, connect (for example, with telnet) to the
+Postfix SMTP server port and you should
be able to have a conversation as shown below. Information sent by the
-client is shown in bold font. </p>
+client (that is, you) is shown in bold font. </p>
<blockquote>
<pre>
+$ <b>telnet server.example.com 25</b>
+. . .
220 server.example.com ESMTP Postfix
<b>EHLO client.example.com</b>
250-server.example.com
</pre>
</blockquote>
-<p> then run the resulting sample server and client in separate
-terminals. The sample applications send log messages to the syslog
+<p> then run the resulting sample Cyrus SASL server and client in
+separate terminals. The sample applications send log messages to
+the syslog
facility auth. Check the log to fix the problem or run strace /
ktrace / truss on the server to see what makes it unhappy. Repeat
the previous step until you can successfully authenticate with the
-sample client. Only then get back to Postfix. </p>
+sample Cyrus SASL client. Only then get back to Postfix. </p>
<h2><a name="client_sasl">Enabling SASL authentication in the
Postfix SMTP client</a></h2>
<p> Turn on client-side SASL authentication, and specify a table
with per-host or per-destination username and password information.
-Postfix first searches the table for an entry with the server
-hostname; if no entry is found, then Postfix searches the table for
+The Postfix SMTP client first searches the table for an entry with
+the remote SMTP server hostname; if no entry is found, then the
+Postfix SMTP client searches the table for
an entry with the next-hop destination. Usually, that is the
right-hand part of an email address, but it can also be the information
that is specified with the relayhost parameter or with a transport(5)
</pre>
</blockquote>
-<p> The Postfix SASL client password file is opened before the SMTP
-server enters the optional chroot jail, so you can keep the file
+<p> The Postfix SMTP client opens the SASL client password file
+before entering the optional chroot jail, so you can keep the file
in /etc/postfix and set permissions read / write only for root to
keep the username:password combinations away from other system
users. </p>
</pre>
</blockquote>
-<p> Note: some SMTP servers support PLAIN or LOGIN authentication only.
+<p> Note: some remote 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: "Authentication failed: cannot SASL
</pre>
</blockquote>
-<p> 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: </p>
+<p> Note: some remote SMTP servers announce authentication mechanisms
+that don't actually work. It is possible via the smtp_sasl_mechanism_filter
+parameter to restrict the list of server mechanisms that the Postfix
+SMTP client will take into consideration: </p>
<blockquote>
<pre>
</pre>
</blockquote>
-<p> In the above example, Postfix will decline to use mechanisms
+<p> In the above example, the Postfix SMTP client will decline to
+use mechanisms
that require special infrastructure such as Kerberos or TLS. </p>
<p> The Postfix SMTP client is backwards compatible with SMTP
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20070720"
+#define MAIL_RELEASE_DATE "20070724"
#define MAIL_VERSION_NUMBER "2.5"
#ifdef SNAPSHOT
const char *reply;
/*
- * While reading the following, keep in mind that a client-side Milter
- * socket is shared between the Postfix SMTP server and the cleanup
- * server. The SMTP server reports only the SMTP events to the Milter.
- * The cleanup server reports the headers and body to the Milter, and
- * receives the header or body modification requests from the Milter.
- *
- * XXX When the cleanup server closes its end of the Milter socket after
- * some local/remote configuration error, the SMTP server is left out of
- * sync with the Milter. Sending an ABORT to the Milters will not restore
+ * XXX When the cleanup server closes its end of the Milter socket while
+ * editing a queue file, the SMTP server is left out of sync with the
+ * Milter. Sending an ABORT to the Milters will not restore
* synchronization, because there may be any number of Milter replies
* already in flight. Workaround: poison the socket and force the SMTP
* server to abandon it.
const char *reply;
/*
- * While reading the following, keep in mind that a client-side Milter
- * socket is shared between the Postfix SMTP server and the cleanup
- * server. The SMTP server reports only the SMTP events to the Milter.
- * The cleanup server reports the headers and body to the Milter, and
- * receives the header or body modification requests from the Milter.
- *
- * XXX When the cleanup server closes its end of the Milter socket after
- * some local or remote remote protocol error, the SMTP server is left
- * out of sync with the Milter. Sending an ABORT to the Milters will not
- * restore synchronization, because there may be any number of Milter
- * replies already in flight. Workaround: poison the socket and force the
- * SMTP server to abandon it.
+ * XXX When the cleanup server closes its end of the Milter socket while
+ * editing a queue file, the SMTP server is left out of sync with the
+ * Milter. Sending an ABORT to the Milters will not restore
+ * synchronization, because there may be any number of Milter replies
+ * already in flight. Workaround: poison the socket and force the SMTP
+ * server to abandon it.
*/
if (milter->fp != 0) {
(void) shutdown(vstream_fileno(milter->fp), SHUT_RDWR);
/*
* Receive the reply or replies.
*
- * Intercept all loop exits so that we can do post body replacement
+ * Intercept all loop exits so that we can do post header/body edit
* processing.
*
* XXX Bound the loop iteration count.
*
- * While reading the following, keep in mind that a client-side Milter
- * socket is shared between the Postfix SMTP server and the cleanup
- * server. The SMTP server reports only the SMTP events to the Milter.
- * The cleanup server reports the headers and body to the Milter, and
- * receives the header or body modification requests from the Milter.
- *
* In the end-of-body stage, the Milter may reply with one or more queue
* file edit requests before it replies with its final decision: accept,
- * reject, etc. After a local queue file edit error, do not close the
- * Milter socket in the cleanup server. Instead skip all further Milter
- * replies until the final decision. This way the Postfix SMTP server
- * stays in sync with the Milter, and Postfix doesn't have to lose the
- * ability to handle multiple deliveries within the same SMTP session.
- * This requires that the Postfix SMTP server uses something other than
- * CLEANUP_STAT_WRITE when it loses contact with the cleanup server.
+ * reject, etc. After a local queue file edit error (file too big, media
+ * write error), do not close the Milter socket in the cleanup server.
+ * Instead skip all further Milter replies until the final decision. This
+ * way the Postfix SMTP server stays in sync with the Milter, and Postfix
+ * doesn't have to lose the ability to handle multiple deliveries within
+ * the same SMTP session. This requires that the Postfix SMTP server uses
+ * something other than CLEANUP_STAT_WRITE when it loses contact with the
+ * cleanup server.
*/
#define IN_CONNECT_EVENT(e) ((e) == SMFIC_CONNECT || (e) == SMFIC_HELO)
/* RFC 3207 (STARTTLS command)
/* RFC 3461 (SMTP DSN Extension)
/* RFC 3463 (Enhanced Status Codes)
+/* RFC 4954 (AUTH command)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* Corrupted message files are marked so that the queue manager can
/* RFC 3207 (STARTTLS command)
/* RFC 3461 (SMTP DSN Extension)
/* RFC 3463 (Enhanced Status Codes)
+/* RFC 3848 (ESMTP Transmission Types)
+/* RFC 4954 (AUTH command)
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/*
int out_error;
char **cpp;
CLEANUP_STAT_DETAIL *detail;
+ const char *rfc3848_sess;
+ const char *rfc3848_auth;
#ifdef USE_TLS
VSTRING *peer_CN;
out_fprintf(out_stream, REC_TYPE_NORM,
"\t(No client certificate requested)");
}
+ /* RFC 3848 is defined for ESMTP only. */
+ if (state->tls_context != 0
+ && strcmp(state->protocol, MAIL_PROTO_ESMTP) == 0)
+ rfc3848_sess = "S";
+ else
#endif
+ rfc3848_sess = "";
#ifdef USE_SASL_AUTH
if (var_smtpd_sasl_enable && var_smtpd_sasl_auth_hdr && state->sasl_username) {
username = VSTRING_STRDUP(state->sasl_username);
"\t(Authenticated sender: %s)", STR(username));
vstring_free(username);
}
+ /* RFC 3848 is defined for ESMTP only. */
+ if (var_smtpd_sasl_enable && state->sasl_username
+ && strcmp(state->protocol, MAIL_PROTO_ESMTP) == 0)
+ rfc3848_auth = "A";
+ else
#endif
+ rfc3848_auth = "";
if (state->rcpt_count == 1 && state->recipient) {
out_fprintf(out_stream, REC_TYPE_NORM,
- state->cleanup ? "\tby %s (%s) with %s id %s" :
+ state->cleanup ? "\tby %s (%s) with %s%s%s id %s" :
"\tby %s (%s) with %s",
var_myhostname, var_mail_name,
- state->protocol, state->queue_id);
+ state->protocol, rfc3848_sess,
+ rfc3848_auth, state->queue_id);
quote_822_local(state->buffer, state->recipient);
out_fprintf(out_stream, REC_TYPE_NORM,
"\tfor <%s>; %s", STR(state->buffer),
mail_date(state->arrival_time.tv_sec));
} else {
out_fprintf(out_stream, REC_TYPE_NORM,
- state->cleanup ? "\tby %s (%s) with %s id %s;" :
+ state->cleanup ? "\tby %s (%s) with %s%s%s id %s;" :
"\tby %s (%s) with %s;",
var_myhostname, var_mail_name,
- state->protocol, state->queue_id);
+ state->protocol, rfc3848_sess,
+ rfc3848_auth, state->queue_id);
out_fprintf(out_stream, REC_TYPE_NORM,
"\t%s", mail_date(state->arrival_time.tv_sec));
}
}
/*
- * XXX If we lost the cleanup server, the Postfix SMTP server will be out
- * of sync with Milter applications. Sending an ABORT to the Milters is
- * not sufficient to restore synchronization, because there may be any
- * number of Milter replies already in flight. Destroying and recreating
- * the Milters (and faking the connect and ehlo events) is too much
- * trouble for testing and maintenance. Workaround: force the Postfix
- * SMTP server to hang up with a 421 response in the rare case that the
- * cleanup server breaks AND that the remote SMTP client continues the
- * session after end-of-data.
+ * XXX If we lose the cleanup server while it is editing a queue file,
+ * the Postfix SMTP server will be out of sync with Milter applications.
+ * Sending an ABORT to the Milters is not sufficient to restore
+ * synchronization, because there may be any number of Milter replies
+ * already in flight. Destroying and recreating the Milters (and faking
+ * the connect and ehlo events) is too much trouble for testing and
+ * maintenance. Workaround: force the Postfix SMTP server to hang up with
+ * a 421 response in the rare case that the cleanup server breaks AND
+ * that the remote SMTP client continues the session after end-of-data.
*
* XXX Should use something other than CLEANUP_STAT_WRITE when we lose
- * contact with the cleanup server. This requires internal changes to the
- * mail_stream module; these may affect other mail_stream_service() users
- * (qmqpd, sendmail, ...).
+ * contact with the cleanup server. This requires changes to the
+ * mail_stream module and its users (smtpd, qmqpd, perhaps sendmail).
*/
if (smtpd_milters != 0 && (state->err & CLEANUP_STAT_WRITE) != 0)
state->access_denied = mystrdup("421 4.3.0 Mail system error");
}
if (smtpd_tls_ctx == 0) {
state->error_mask |= MAIL_ERROR_SOFTWARE;
- smtpd_chat_reply(state, "454 4.3.0 TLS not available due to local problem");
+ /* RFC 4954 Section 6. */
+ smtpd_chat_reply(state, "454 4.7.0 TLS not available due to local problem");
return (-1);
}
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",
+ /* RFC 4954 Section 6. */
+ smtpd_chat_reply(state, "535 5.7.8 Error: authentication failed: %s",
STR(state->sasl_reply));
return (-1);
}
- smtpd_chat_reply(state, "235 2.0.0 Authentication successful");
+ /* RFC 4954 Section 6. */
+ smtpd_chat_reply(state, "235 2.7.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);
#ifdef USE_TLS
if (state->tls_auth_only && !state->tls_context) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "538 5.7.0 Encryption required for requested authentication mechanism");
+ /* RFC 4954, Section 4. */
+ smtpd_chat_reply(state, "504 5.5.4 Encryption required for requested authentication mechanism");
return (-1);
}
#endif