when it is given a non-existent command-line macro name.
File: pipe/pipe.c.
+20030810
+
+ Bugfix: dict_ldap had a few harmless memory leaks. By
+ Liviu Daia. File: util/dict_ldap.c.
+
+ Feature: support for LDAP URLs in the LDAP parameter
+ "server_host", if Postfix is linked against OpenLDAP. This
+ allows Postfix to connect to LDAP SSL sources. By Liviu
+ Daia. File: util/dict_ldap.c.
+
+
20030811
Cleanup: produce a warning when host:port specifies a badly
formatted numerical port. Files: util/find_inet.c,
smtp/smtp_connect.c, lmtp/lmtp_connect.c.
+20030822
+
+ Feature: the export_environment and import_environment
+ parameters now accept name=value information that will be
+ entered into the new environment. File: util/clean_env.c.
+
+20030823
+
+ Feature: smtpd_sasl_exceptions_networks parameter to prevent
+ Postfix from offering AUTH to clients that match the listed
+ networks. Based on code by Ben Rosengart, Panix. Files:
+ conf/sample-auth.cf, smtpd/smtpd.c.
+
+20030905
+
+ Workaround: Solaris 8 select() claims that a non-blocking
+ socket is readable and then read() fails with EAGAIN. Files:
+ util/timed_read.c and as precautionary measure,
+ util/timed_write.c.
+
+ Bugfix: dict_register() should not be called from dict_open()
+ in dict_mysql and dict_pgsql. Liviu Daia. Files:
+ util/dict_mysql.c, util/dict_pgsql.c.
+
+ Feature: LDAP parameters can now be specified in external
+ files. This makes it possible to securely store bind
+ passwords for plain auth outside of main.cf (which is world
+ readable). By Liviu Daia, based on a suggestion by Victor
+ Duchovni and Lamont Jones. File: util/dict_ldap.c.
+
+ Feature: STARTTLS option for LDAP, if Postfix is linked
+ against OpenLDAP. By Liviu Daia, amended by Victor Duchovni.
+ File: util/dict_ldap.c.
+
+ Cleanup: connections to LDAP sources are now postponed
+ until they are actually needed. By Liviu Daia. File:
+ util/dict_ldap.c.
+
+20030908
+
+ The 20030905 workaround triggers too many warnings. TCP
+ sockets are back to blocking, and keepalives are turned on
+ to kill off dead sockets, as suggested by Leandro Santi.
+ Files: master/{single,multi}_server.c, smtpd/smtpd.c,
+ util/sys_defs.h.
+
+20030909
+
+ Bugfix: the LMTP session caching code had problems with
+ SASL authentication after the first connection, and pipelining
+ was working poorly. Fix by Victor Duchovni, Morgan Stanley.
+ Files: lmtp/lmtp.c, lmtp/lmtp_proto.c.
+
+20030913
+
+ Safety: set-gid commands don't trust TZ. File: msg_syslog.c.
+
+20030914
+
+ Address extension propagation wasn't documented enough when
+ it was added to Postfix. Based on patches by Roman Neuhauser.
+
+ Added clarifying notes to main.cf, master.cf and access by
+ Dean Gibson.
+
+ In header/body_checks, DUNNO is now the preferred action
+ instead of the now deprecated OK.
+
+ In header/body_checks, allow text after IGNORE and DUNNO,
+ suggested by Victor Duchovni, Morgan Stanley. File:
+ src/cleanup/cleanup_message.c.
+
+ Feature: reject_rhsbl_helo. File: smtpd/smtpd_check.c.
+
+ Cleanup: the LMTP and SMTP clients now send "MAIL FROM:<sender>
+ AUTH=<>" when SASL authenticated. Suggested by by Victor
+ Duchovni, Morgan Stanley. Files: smtp/smtp_proto.c,
+ lmtp/lmtp_proto.c.
+
Open problems:
+ Med: do not list myorigin in virtual_alias_maps.
+
+ High: when virtual aliasing is turned off after content
+ filtering, local submissions may escape virtual aliasing.
+
+ Med: qmgr should not exit while an asynchronous bounce
+ request is in progress; this can result in multiple
+ non-delivery notifications.
+
+ Low: postcat should be null byte transparent.
+
+ Low: qmgr_move should not reset time stamps on queue files
+ without shared lock (i.e. not open by a delivery agent).
+
+ Low: postsuper re-run after renaming files, but only a
+ limited number of times.
+
Doc: mention the proxy_interfaces parameter everywhere the
inet_interfaces and mydestination parameters are mentioned.
In order to use LDAP lookups, define at least one LDAP source as a table
lookup in main.cf, for example:
- alias_maps = hash:/etc/aliases, ldap:ldapsource
+ alias_maps = hash:/etc/aliases, ldap:/etc/ldap-aliases.cf
-Each LDAP source can have the following parameters, which should be
-prefixed in main.cf with the name you've given the source in its
-definition and an underscore. To continue the example, the first
-parameter below, "server_host", would be defined in main.cf as
-"ldapsource_server_host". Defaults are given in parentheses:
+The file /etc/postfix/ldap-aliases.cf can specify the following
+parameters. Defaults are given in parentheses:
server_host (localhost)
The name of the host running the LDAP server, e.g.
- ldapsource_server_host = ldap.your.com
+ server_host = ldap.your.com
It should be possible with all the libraries mentioned above to
specify multiple servers separated by spaces, with the libraries
trying them in order should the first one fail. It should also
be possible to give each server in the list a different port, by
naming them like "ldap.your.com:1444".
+ With OpenLDAP, LDAP URLs can be used to request connection
+ over UNIX domain sockets (ldapi://%2Fsome%2Fpath) or LDAP SSL
+ (ldaps://ldap.your.com:636, provided OpenLDAP was compiled with
+ support for SSL).
+
server_port (389)
The port the LDAP server listens on, e.g.
- ldapsource_server_port = 778
+ server_port = 778
search_base (No default; you must configure this.)
The base at which to conduct the search, e.g.
- ldapsource_search_base = dc=your, dc=com
+ search_base = dc=your, dc=com
timeout (10 seconds)
The number of seconds a search can take before timing out, e.g.
- ldapsource_timeout = 5
+ timeout = 5
query_filter (mailacceptinggeneralid=%s)
The RFC2254 filter used to search the directory, where %s is a
substitute for the address Postfix is trying to resolve, e.g.
- ldapsource_query_filter = (&(mail=%s)(paid_up=true))
+ query_filter = (&(mail=%s)(paid_up=true))
result_filter (%s)
Filter applied to result attributes. Supports the same expansions
performed. This means that the LDAP map won't get searched for
'user', nor will it get searched for any domain not listed. This
can significantly reduce the query load on the LDAP server.
- ldapsource_domain = postfix.org, hash:/etc/postfix/searchdomains
+ domain = postfix.org, hash:/etc/postfix/searchdomains
result_attribute (maildrop)
The attribute(s) Postfix will read from any directory entries
returned by the lookup, to be resolved to an email address.
- ldapsource_result_attribute = mailbox,maildrop
+ result_attribute = mailbox,maildrop
special_result_attribute (No default)
The attribute(s) of directory entries that can contain DNs or URLs.
If found, a recursive subsequent search is done using their values.
- ldapsource_special_result_attribute = member
+ special_result_attribute = member
scope (sub)
The LDAP search scope: sub, base, or one. These translate into
Whether or not to bind to the LDAP server. Newer LDAP
implementations don't require clients to bind, which saves
time. Example:
- ldapsource_bind = no
+ bind = no
If you do need to bind, you might consider configuring Postfix
to connect to the local machine on a port that's an SSL tunnel
bind_dn ("")
If you do have to bind, do it with this distinguished name.
Example:
- ldapsource_bind_dn = uid=postfix, dc=your, dc=com
+ bind_dn = uid=postfix, dc=your, dc=com
bind_pw ("")
- The password for the distinguished name above. If you have to
- use this, you probably want to make main.cf readable only by
- the Postfix user. Example:
- ldapsource_bind_pw = postfixpw
+ The password for the distinguished name above. If you have to
+ use this, you probably want to make the map configuration file
+ readable only by the Postfix user. When using the obselete
+ ldap:ldapsource syntax, with map parameters in main.cf, it is
+ not possible to securely store the bind password. This is
+ because main.cf needs to be world readable to allow local
+ accounts to submit mail via the sendmail command. Example:
+ bind_pw = postfixpw
cache (IGNORED with a warning)
cache_expiry (IGNORED with a warning)
Don't use quotes in these variables; at least, not until the Postfix
configuration routines understand how to deal with quoted strings.
+For backward compatibility, these parameters can also be defined
+in main.cf, prefixed with the name you've given the source in its
+definition, and an underscore. For example, if the map is specified as
+"ldap:ldapsource", the first parameter above, "server_host", would be
+defined in main.cf as "ldapsource_server_host".
+
+LDAP SSL and STARTTLS
+---------------------
+
+If you're using the OpenLDAP libraries compiled with SSL support,
+Postfix can connect to LDAP SSL servers and can issue the STARTTLS
+command. The first form can be requested by using a LDAP URL in
+server_host:
+
+ server_host = ldaps://ldap.your.com:636
+
+STARTTLS can be turned on with the start_tls command:
+
+ start_tls = yes
+
+Both forms require LDAP protocol version 3, which has to be set
+explicitly:
+
+ version = 3
+
+If any of the Postfix programs querying the map is configured in
+master.cf to run chrooted, all the certificates and keys involved have
+to be copied to the chroot jail. Of course, the private keys should
+only be readable by the user "postfix".
+
+The following commands are relevant to LDAP SSL and STARTTLS:
+
+ start_tls (no)
+ Whether or not to issue STARTTLS upon connection to
+ the server. Don't set this with LDAP SSL.
+
+ tls_ca_cert_dir (No default; set either this or tls_ca_cert_file)
+ Directory containing, in separate individual files,
+ the X509 Certificate Authority certificates which
+ are to be recognized by the client in SSL/TLS con-
+ nections.
+
+ tls_ca_cert_file (No default; set either this or tls_ca_cert_dir)
+ File containing the X509 Certificate Authority cer-
+ tificates which are to be recognized by the client
+ in SSL/TLS connections. This setting takes prece-
+ dence over tls_ca_cert_dir.
+
+ tls_cert (No default; you must set this)
+ File containing client's X509 certificate to be
+ used by the client in SSL/TLS connections.
+
+ tls_key (No default; you must set this)
+ File containing the private key corresponding to
+ the above tls_cert.
+
+ tls_require_cert (no)
+ Whether or not to request server's X509 certificate
+ and check its validity when establishing SSL/TLS
+ connections.
+
+ tls_random_file (No default)
+ Path of a file to obtain random bits from when
+ /dev/[u]random is not available, to be used by the
+ client in SSL/TLS connections.
+
+ tls_cipher_suite (No default)
+ Cipher suite to use in SSL/TLS negotiations.
+
+
EXAMPLES
========
-------
Here's a basic example for using LDAP to look up aliases. Assume that in
-main.cf, you have these configuration parameters defined:
+main.cf, you have:
+
+alias_maps = hash:/etc/aliases, ldap:/etc/ldap-aliases.cf
+
+and in ldap:/etc/ldap-aliases.cf you have:
-alias_maps = hash:/etc/aliases, ldap:ldapsource
-ldapsource_server_host = ldap.my.com
-ldapsource_search_base = dc=my, dc=com
+server_host = ldap.my.com
+search_base = dc=my, dc=com
Upon receiving mail for a local address "ldapuser" that isn't found in
the /etc/aliases database, Postfix will search the LDAP server listening
Postfix can't know how to set the ownership for program or file
delivery. Your query_filter should probably look something like this:
- virtual_query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))
+ query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))
- And for that matter, even for aliases, you may not want users able to
specify their maildrops as programs, includes, etc. This might be
the fun stuff only for directory entries owned by an administrative
account:
- local_query_filter = (&(mailacceptinggeneralid=%s)(|(!(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))
+ query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))
So that if the object had a program as its maildrop and weren't owned
by "cn=root" it wouldn't be returned as a valid local user. This will
CREDITS
=======
-Manuel Guesdon: Spotted a bug with the ldapsource_timeout attribute.
+Manuel Guesdon: Spotted a bug with the timeout attribute.
John Hensley: Multiple LDAP sources with more configurable attributes.
Carsten Hoeger: Search scope handling.
LaMont Jones: Domain restriction, URL and DN searches, multiple result
the work on RFC 2254 escaping in queries. Spotted a bug
in binding.
Sami Haahtinen: Referral chasing and v3 support.
+Victor Duchovni: ldap_bind() timeout. With fixes from LaMont Jones:
+ OpenLDAP cache deprecation. Limits on recursion, expansion
+ and query results size.
+Liviu Daia: Support for SSL/STARTTLS. Support for storing map definitions in
+ external files (ldap:/path/ldap.cf) need to securely store
+ passwords for plain auth.
And of course Wietse.
-Purpose of the SMTPD pass-through proxy feature
-===============================================
+Purpose of the SMTP-based before-queue proxy filter feature
+===========================================================
Normally, Postfix receives mail, stores it in the mail queue and
then delivers it. The Postfix SMTP server can be configured to
-forward all incoming mail to an SMTP proxy server (for example, a
+forward all incoming mail through a proxy filter (for example, a
real-time SPAM filter) that inspects all mail BEFORE it is stored
in the Postfix mail queue.
FILTER_README document, where all mail is inspected AFTER it is
stored in the Postfix mail queue]
-This feature is meant to be used as follows:
- / smtp
- Internet -> smtpd -> proxy -> smtpd -> cleanup -> queue -> local
- Postfix Postfix \ virtual etc.
+The SMTP-based before-queue proxy filter is meant to be used as follows:
+
+ before / smtp
+ Internet -> smtpd -> queue -> smtpd -> cleanup -> queue -> local
+ Postfix filter Postfix \ virtual etc.
For reference, this is the normal path through Postfix:
Postfix \ virtual etc.
For comparison, this is the FILTER_README approach with an SMTP-based
-content filter:
+after-queue content filter:
/ smtp
Internet -> smtpd -> cleanup -> queue -> local
Postfix ^ v \ virtual etc.
smtpd smtp
Postfix Postfix
- \ /
- filter <-
+ \ after /
+ queue <-
+ filter
-The SMTP proxy server receives unfiltered mail from Postfix and
-does one of the following:
+The SMTP-based before-queue proxy filter receives unfiltered mail
+from Postfix and does one of the following:
-1 - Re-inject the mail back into Postfix, perhaps after changing
- content.
+1 - Re-inject the mail back into Postfix via SMTP, perhaps after
+ changing content.
2 - Reject the mail (by sending a suitable status code back to
Postfix). Postfix passes the status back to the remote SMTP
Limitations
===========
-When used with a real-time SPAM filter, this approach allows Postfix
-to reject mail before the SMTP mail transfer completes, so that
+The SMTP-based before-queue proxy filter allows Postfix to reject
+mail before the incoming SMTP mail transfer completes, so that
Postfix does not have to send rejected mail back to the sender.
Mail that is not accepted remains the responsibility of the client.
mail AFTER it is queued, because that gives you full control over
how many filtering processes can be run in parallel.
-The problem with real-time content filtering is that the remote
+The problem with before-queue content filtering is that the remote
SMTP client expects an SMTP reply within a deadline. As the system
load increases, fewer and fewer CPU cycles remain available to
answer within the deadline, and eventually you either have to stop
into Postfix via an alternative Postfix SMTP server that always
turns on content filtering.
-How the Postfix talks to the SMTP proxy
-=======================================
+How Postfix talks to the before-queue proxy filter
+==================================================
+
+When passing mail to the SMTP-based before-queue filter, Postfix
+generates its own EHLO, DATA and QUIT commands, and forwards
+unmodified copies of the MAIL FROM and RCPT TO commands that the
+Postfix SMTP server has approved. All commands are sent without
+using ESMTP command pipelining. The SMTP proxy server should accept
+the same MAIL FROM and RCPT TO command syntax as the Postfix SMTP
+server.
-When Postfix talks to the SMTP proxy server it generates its own
-EHLO, DATA and QUIT commands, and forwards unmodified copies of
-the MAIL FROM and RCPT TO commands that the Postfix SMTP server
-has approved. All commands are sent without using ESMTP command
-pipelining. The SMTP proxy server must accept the same MAIL FROM
-and RCPT TO command syntax as the Postfix SMTP server.
+The before-queue proxy filter is expected literally pass on the
+SMTP commands that it receives from Postfix to an after-filter
+Postfix SMTP server that listens on a non-standard port. When the
+filter rejects content, it should send a negative response back to
+Postfix, and it should abort any connection with the after-filter
+Postfix SMTP server without completing the SMTP dialog.
Configuration parameters
========================
smtpd_proxy_filter (syntax: host:port)
- The host and TCP port of the SMTP proxy server. When no host
- or host: is specified, localhost is assumed.
+ The host and TCP port of the before-queue proxy filter. When
+ no host or host: is specified, localhost is assumed.
smtpd_proxy_timeout (default: 100s)
- Timeout for connecting to the SMTP proxy server and for sending
- and receiving data. All proxy errors are logged to the maillog
- file, but the client sees "451 Error: queue file write error".
+ Timeout for connecting to the before-queue proxy filter and
+ for sending and receiving commands and data. All proxy errors
+ are logged to the maillog file. For privacy reasons, all the
+ remote SMTP client sees is "451 Error: queue file write error".
smtpd_proxy_ehlo (default: $myhostname)
- The hostname to use when sending an EHLO command to the SMTP
- proxy server.
+ The hostname to use when sending an EHLO command to the
+ before-queue proxy filter.
Testing the SMTP pass-through proxy feature
===========================================
The following example sets up a null proxy, that is, the Postfix
SMTP server gives the mail directly to another Postfix SMTP server
-process.
+process without intervening content filter. This useful only for
+testing, of course.
/etc/postfix/master.cf
smtp inet n - n - - smtpd
date. Snapshots change only the release date, unless they include
the same bugfixes as a patch release.
+Incompatible changes with Postfix snapshot 2.0.13-20030914
+==========================================================
+
+In header/body_checks actions, the OK action is being phased out,
+and the DUNNO action is being phased in. Both actions still work
+and do the same thing, but hopefully DUNNO causes less confusion.
+
+Major changes with Postfix snapshot 2.0.13-20030914
+===================================================
+
+LDAP parameters can now be defined in external files. Specify the
+LDAP maps in main.cf as
+
+ ldap:/path/to/ldap.cf
+
+and write the LDAP parameters in /path/to/ldap.cf, without the
+"ldapsource_" prefix. This makes it possible to securely store
+bind passwords for plain auth outside of main.cf (which must be
+world readable). The old syntax still works, for backwards
+compatibility. By Liviu Daia, based on a suggestion by Victor
+Duchovni and Lamont Jones.
+
+Support for LDAP URLs in the LDAP parameter "server_host", if
+Postfix is linked against OpenLDAP. LDAP hosts, ports, and connection
+protocols to be used as LDAP sources can be specified as a
+blank-separated list of LDAP URLs in "server_host". As with
+OpenLDAP, specifying a port in a LDAP URL overrides "server_port".
+Examples:
+
+ server_host = ldap://ldap.itd.umich.edu
+ server_host = ldaps://ldap.itd.umich.edu:636
+ server_host = ldapi://%2Fsome%2Fpath
+
+The LDAP SSL scheme ldaps:// is available if OpenLDAP was compiled
+with SSL support. New parameters "tls_ca_cert_dir", "tls_ca_cert_file",
+"tls_cert", "tls_key", "tls_require_cert", "tls_random_file",
+"tls_cipher_suite" control the certificates, source of random
+numbers, and cipher suites used for SSL connections. See LDAP_README
+for further information. By Liviu Daia.
+
+Support for STARTTLS command in LDAP, if Postfix is linked against
+OpenLDAP and OpenLDAP was compiled with SSL support. STARTTLS is
+controlled by the "start_tls" parameter. The above parameters for
+certificates, source of random numbers, and cipher suites also
+apply. See LDAP_README for further information. By Liviu Daia,
+amended by Victor Duchovni.
+
Major changes with Postfix snapshot 2.0.13-20030715
===================================================
# When a mail address localpart contains the optional recip-
# ient delimiter (e.g., user+foo@domain), the lookup order
# becomes: user+foo@domain, user@domain, user+foo, user, and
-# @domain. An unmatched address extension (+foo) is propa-
+# @domain.
+#
+# The propagate_unmatched_extensions parameter controls
+# whether an unmatched address extension (+foo) is propa-
# gated to the result of table lookup.
#
# REGULAR EXPRESSION TABLES
-# This section describes how the table lookups change when
+# This section describes how the table lookups change when
# the table is given in the form of regular expressions. For
-# a description of regular expression lookup table syntax,
+# a description of regular expression lookup table syntax,
# see regexp_table(5) or pcre_table(5).
#
-# Each pattern is a regular expression that is applied to
+# Each pattern is a regular expression that is applied to
# the entire address being looked up. Thus, user@domain mail
-# addresses are not broken up into their user and @domain
+# addresses are not broken up into their user and @domain
# constituent parts, nor is user+foo broken up into user and
# foo.
#
-# Patterns are applied in the order as specified in the
-# table, until a pattern is found that matches the search
+# Patterns are applied in the order as specified in the
+# table, until a pattern is found that matches the search
# string.
#
-# Results are the same as with indexed file lookups, with
-# the additional feature that parenthesized substrings from
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
# the pattern can be interpolated as $1, $2 and so on.
#
# TCP-BASED TABLES
-# This section describes how the table lookups change when
+# This section describes how the table lookups change when
# lookups are directed to a TCP-based server. For a descrip-
-# tion of the TCP client/server lookup protocol, see
+# tion of the TCP client/server lookup protocol, see
# tcp_table(5).
#
# Each lookup operation uses the entire address once. Thus,
-# user@domain mail addresses are not broken up into their
+# user@domain mail addresses are not broken up into their
# user and @domain constituent parts, nor is user+foo broken
# up into user and foo.
#
# Results are the same as with indexed file lookups.
#
# BUGS
-# The table format does not understand quoting conventions.
+# The table format does not understand quoting conventions.
#
# CONFIGURATION PARAMETERS
-# The following main.cf parameters are especially relevant
-# to this topic. See the Postfix main.cf file for syntax
-# details and for default values. Use the postfix reload
+# The following main.cf parameters are especially relevant
+# to this topic. See the Postfix main.cf file for syntax
+# details and for default values. Use the postfix reload
# command after a configuration change.
#
# canonical_maps
# Address mapping lookup table for envelope and
# header sender addresses.
#
+# propagate_unmatched_extensions
+# A list of address rewriting or forwarding mecha-
+# nisms that propagate an address extension from the
+# original address to the result. Specify zero or
+# more of canonical, virtual, alias, forward, or
+# include.
+#
# Other parameters of interest:
#
# inet_interfaces
-# The network interface addresses that this system
+# The network interface addresses that this system
# receives mail on. You need to stop and start Post-
# fix when this parameter changes.
#
# masquerade_classes
-# List of address classes subject to masquerading:
-# zero or more of envelope_sender, envelope_recipi-
+# List of address classes subject to masquerading:
+# zero or more of envelope_sender, envelope_recipi-
# ent, header_sender, header_recipient.
#
# masquerade_domains
-# List of domains that hide their subdomain struc-
+# List of domains that hide their subdomain struc-
# ture.
#
# masquerade_exceptions
-# List of user names that are not subject to address
+# List of user names that are not subject to address
# masquerading.
#
# mydestination
-# List of domains that this mail system considers
+# List of domains that this mail system considers
# local.
#
# myorigin
# tcp_table(5) TCP client/server table lookup protocol
#
# LICENSE
-# The Secure Mailer license must be distributed with this
+# The Secure Mailer license must be distributed with this
# software.
#
# AUTHOR(S)
# Global Postfix configuration file. This file lists only a subset
# of all 300+ parameters. See the sample-xxx.cf files for a full list.
#
-# The general format is lines with parameter = value pairs. Lines
+# The general format of each line is: parameter = value. Lines
# that begin with whitespace continue the previous line. A value can
# contain references to other $names or ${name}s.
#
# a name matches a lookup key (the right-hand side is ignored).
# Continue long lines by starting the next line with whitespace.
#
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+# DO NOT LIST RELAY DESTINATIONS IN MYDESTINATION.
+#
# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
#
#mydestination = $myhostname, localhost.$mydomain
# in the main.cf configuration file). See individual command man pages
# for specific command-line options, if any.
#
+# General main.cf options can be overridden for specific services.
+# To override one or more main.cf options, specify them as arguments
+# below, preceding each option by "-o". There must be no whitespace
+# in the option itself (separate multiple values for an option by
+# commas).
+#
# In order to use the "uucp" message tranport below, set up entries
# in the transport table.
#
#smtpd_sasl_local_domain = $mydomain
smtpd_sasl_local_domain = $myhostname
+# The smtpd_sasl_exceptions_networks parameter controls what SMTP
+# clients Postfix will not offer AUTH support.
+#
+# Some clients (Netscape 4 at least) have a bug that causes them to
+# require a login and password whenever AUTH is offered, whether it's
+# necessary or not. To work around this, specify, for example,
+# $mynetworks to prevent Postfix from offering AUTH to local clients.
+#
+# Specify an explicit list of network/netmask patterns, where the
+# mask specifies the number of bits in the network part of a host
+# address.
+#
+# You can also specify the absolute pathname of a pattern file instead
+# of listing the patterns here. Specify type:table for table-based lookups
+# (the value on the table right-hand side is not used).
+#
+#smtpd_sasl_exceptions_networks = $mynetworks
+smtpd_sasl_exceptions_networks =
+
# SMTP CLIENT CONTROLS
# The smtp_sasl_auth_enable parameter controls whether authentication
# REJECT [optional text...]
# Reject the entire message. The optional text is sent to the
# originator and is logged to the maillog file.
-# OK Skip all further header patterns for this header line.
-# IGNORE Silently discard the header line.
+# DUNNO [optional text...]
+# Skip all further header patterns for this header line.
+# IGNORE [optional text...]
+# Silently discard the header line.
# WARN [optional text...]
# Log the message header and the optional text. This is useful
# for testing. When the pattern is good, change the WARN into a
# REJECT or into a DISCARD.
# HOLD [optional text...]
# Place the message on the hold queue. Mail on hold can be
-# inspected with the postcat command, and can be destroyed or
-# taken off hold (i.e. delivered) with the postsuper command.
-# The matched header is logged with the optional text.
+# inspected with the postcat command, and can be destroyed or
+# taken off hold (i.e. delivered) with the postsuper command.
+# The matched header is logged with the optional text.
# DISCARD [optional text...]
# Claim successful delivery and silently discard the message.
-# The matched header is logged with the optional text.
+# The matched header is logged with the optional text.
# FILTER transport:nexthop
-# after the message is queued, the message is sent through
-# a content filter. This requires different cleanup servers
-# before and after the filter, with header/body checks turned
-# off in the second cleanup server. More info about content
+# After the message is queued, send the message through
+# a content filter. This requires different cleanup servers
+# before and after the filter, with header/body checks turned
+# off in the second cleanup server. More info about content
# filtering is in the Postfix FILTER_README file. This feature
# overrides the main.cf content_filter setting.
# REDIRECT user@domain
# For examples of pattern syntax see the sample-regexp-header.cf and
# sample-pcre-header files.
#
-# When a pattern matches, what happens next depends on the associated
-# action that is specified in the right-hand side of the table:
-#
-# REJECT [optional text...]
-# Reject the entire message. The optional text is sent to the
-# originator and is logged to the maillog file.
-# OK Skip all further header patterns for this header line.
-# IGNORE Silently discard the body line
-# WARN [optional text...]
-# Log the body line and the optional text. This is useful
-# for testing. When the pattern is good, change the WARN into a
-# REJECT or into a DISCARD.
-# HOLD [optional text...]
-# Place the message on the hold queue. Mail on hold can be
-# inspected with the postcat command, and can be destroyed or
-# taken off hold (i.e. delivered) with the postsuper command.
-# The matched body line is logged with the optional text.
-# DISCARD [optional text...]
-# Claim successful delivery and silently discard the message.
-# The matched body line is logged with the optional text.
-# FILTER transport:nexthop
-# after the message is queued, the message is sent through
-# a content filter. This requires different cleanup servers
-# before and after the filter, with header/body checks turned
-# off in the second cleanup server. More info about content
-# filtering is in the Postfix FILTER_README file. This feature
-# overrides the main.cf content_filter setting.
-# REDIRECT user@domain
-# Send the message to the specified address instead of the
-# intended recipient(s). This feature overrides the FILTER action.
-#
-# By default, the same patterns are applied as for header_checks.
+# Actions on the table right-hand side are the same as with header_checks.
#
mime_header_checks = $header_checks
# When a pattern matches, what happens next depends on the associated
# action that is specified in the right-hand side of the table:
#
-# REJECT [optional text...]
-# Reject the entire message. The optional text is sent to the
-# originator and is logged to the maillog file.
-# OK Skip all further header patterns for this header line.
-# IGNORE Silently discard the body line
-# WARN [optional text...]
-# Log the body line and the optional text. This is useful
-# for testing. When the pattern is good, change the WARN into a
-# REJECT or into a DISCARD.
-# HOLD [optional text...]
-# Place the message on the hold queue. Mail on hold can be
-# inspected with the postcat command, and can be destroyed or
-# taken off hold (i.e. delivered) with the postsuper command.
-# The matched body line is logged with the optional text.
-# DISCARD [optional text...]
-# Claim successful delivery and silently discard the message.
-# The matched body line is logged with the optional text.
-# FILTER transport:nexthop
-# after the message is queued, the message is sent through
-# a content filter. This requires different cleanup servers
-# before and after the filter, with header/body checks turned
-# off in the second cleanup server. More info about content
-# filtering is in the Postfix FILTER_README file. This feature
-# overrides the main.cf content_filter setting.
-# REDIRECT user@domain
-# Send the message to the specified address instead of the
-# intended recipient(s). This feature overrides the FILTER action.
+# Actions on the table right-hand side are the same as with header_checks.
#
# By default, the same patterns are applied as for header_checks.
#
# For examples of pattern syntax see the sample-regexp-body.cf and
# sample-pcre-body.cf files.
#
-# When a pattern matches, what happens next depends on the associated
-# action that is specified in the right-hand side of the table:
-#
-# REJECT the entire message is rejected.
-# REJECT text.... The text is sent to the originator.
-# IGNORE the body line is silently discarded.
-# WARN the body line is logged (not rejected) with a warning message.
-# WARN text... as above, and the text is logged, too.
-# FILTER transport:nexthop
-# after the message is queued, the message is sent through
-# a content filter. This requires different cleanup servers
-# before and after the filter, with header/body checks turned
-# off in the second cleanup server. More info about content
-# filtering is in the Postfix FILTER_README file. This feature
-# overrides the main.cf content_filter setting.
+# Actions on the table right-hand side are the same as with header_checks.
#
body_checks = regexp:/etc/postfix/body_checks
# parameters that control LDAP lookups. Source code for LDAP
# lookup is available separately from http://www.postfix.org/
-# The ldap_timeout parameter specifies the timeout for LDAP database
+# The timeout parameter specifies the timeout for LDAP database
# lookups.
#
-#ldap_timeout = 10
+#timeout = 10
-# The ldap_search_base parameter specifies the LDAP database to search.
+# The search_base parameter specifies the LDAP database to search.
#
-#ldap_search_base =
+#search_base =
-# The ldap_server_host parameter specifies the LDAP server hostname.
+# The server_host parameter specifies the LDAP server hostname.
#
-#ldap_server_host = localhost
+#server_host = localhost
-# The ldap_server_port parameter specifies the LDAP server port number.
+# The server_port parameter specifies the LDAP server port number.
#
-#ldap_server_port = 389
+#server_port = 389
-# The ldap_query_filter parameter specifies the filter used for queries.
+# The version parameter specifies the LDAP protocol version to use.
+#
+#version = 2
+
+# The query_filter parameter specifies the filter used for queries.
# The replacement for "%s" is the address input into the map; e.g.
# for alias maps, the "user" part (the RFC 2822 local-part) of
# "user@domain.com" for To: addresses destined for local delivery
# "%u" provides just the user portion of the input, and "%d" provides
# just the hostname.
#
-#ldap_query_filter = (mailacceptinggeneralid=%s)
+#query_filter = (mailacceptinggeneralid=%s)
-# The ldap_result_filter parameter specifies the filter to be applied
-# to the result attribute(s). See ldap_query_filter for valid expansions.
+# The result_filter parameter specifies the filter to be applied
+# to the result attribute(s). See query_filter for valid expansions.
#
-#ldap_result_filter = %s
+#result_filter = %s
-# The ldap_result_attribute parameter specifies the attribute returned by
+# The result_attribute parameter specifies the attribute returned by
# the search.
#
-#ldap_result_attribute = maildrop
+#result_attribute = maildrop
-# The ldap_special_result_attribute lists the attribute(s) of an
+# The special_result_attribute lists the attribute(s) of an
# entry which contain links, either ldap url's or distinguished names.
# The entries referenced by these links are (recursively) treated as if
# they were contained in the referencing entity.
#
-#ldap_special_result_attribute =
+#special_result_attribute =
-# The ldap_scope parameter specifies the LDAP search scope: sub, base, or one.
+# The scope parameter specifies the LDAP search scope: sub, base, or one.
#
-#ldap_scope = sub
+#scope = sub
-# The ldap_bind parameter specifies whether or not to bind to the server.
+# The bind parameter specifies whether or not to bind to the server.
# LDAP v3 implementations don't require it, which saves some overhead.
#
-#ldap_bind = yes
+#bind = yes
-# The ldap_bind_dn parameter specifies what distinguished name to use
+# The bind_dn parameter specifies what distinguished name to use
# when binding.
#
-#ldap_bind_dn =
+#bind_dn =
-# The ldap_bind_pw parameter specifies the password to use.
+# The bind_pw parameter specifies the password to use.
#
-#ldap_bind_pw =
+#bind_pw =
-#ldap_cache (IGNORED with a warning)
-#ldap_cache_expiry (IGNORED with a warning)
-#ldap_cache_size (IGNORED with a warning)
+#cache (IGNORED with a warning)
+#cache_expiry (IGNORED with a warning)
+#cache_size (IGNORED with a warning)
#
# The above parameters are NO LONGER SUPPORTED by Postfix.
# Cache support has been dropped from OpenLDAP as of release 2.1.13.
-# The ldap_recursion_limit parameter specifies a limit on the nesting
+# The recursion_limit parameter specifies a limit on the nesting
# depth of DN and URL special result attribute evaluation. The limit
# must be a non-zero positive number. The default value is 1000.
#
-#ldap_recursion_limit = 1000
+#recursion_limit = 1000
-# The ldap_expansion_limit parameter specifies a limit on the total
+# The expansion_limit parameter specifies a limit on the total
# number of result elements returned (as a comma separated list) by a lookup
# against the map. A setting of 0 disables the limit. Lookups fail with a
# temporary error if the limit is exceeded. Setting the limit to 1 ensures
# that lookups do not return multiple values. The default value is 0.
#
-#ldap_expansion_limit = 0
+#expansion_limit = 0
-# The ldap_size_limit parameter specifies a limit on the number of LDAP
+# The size_limit parameter specifies a limit on the number of LDAP
# entries returned by any single LDAP query performed as part of the
# lookup. A setting of 0 disables the limit. Expansion of DN and URL
# references involves nested LDAP queries, each of which is separately
-# subjected to this limit. The default value is $ldap_expansion_limit.
+# subjected to this limit. The default value is $expansion_limit.
#
# Note: even a single LDAP entry can generate multiple lookup results, via
# multiple result attributes and/or multi-valued result attributes.
# not the final multiplicity of the lookup result. It is analogous to the
# "-z" option of "ldapsearch".
#
-#ldap_size_limit = $ldap_expansion_limit
+#size_limit = 0
-# The ldap_deference parameter specifies how to handle LDAP aliases. See the
+# The deference parameter specifies how to handle LDAP aliases. See the
# ldap_open(3) man page.
#
-#ldap_dereference = 0
+#dereference = 0
-# The ldap_domain parameter limits the LDAP searches to just things in
+# The domain parameter limits the LDAP searches to just things in
# (exactly) the specified list of domains.
#
-#ldap_domain =
+#domain =
+
+# The start_tls parameter specifies whether or not to issue
+# STARTTLS upon connection to the server. STARTTLS requires LDAP
+# protocol version 3.
+#
+#start_tls = no
+
+# The tls_ca_cert_dir parameter specifies a directory containing,
+# in separate individual files, the X509 Certificate Authority
+# certificates which are to be recognized by the client in SSL/TLS
+# connections.
+#
+#tls_ca_cert_dir =
+
+# The tls_ca_cert_file parameter specifies a file containing the
+# X509 Certificate Authority certificates which are to be recognized by
+# the client in SSL/TLS connections. This setting takes precedence over
+# tls_ca_cert_dir.
+#
+#tls_ca_cert_file =
+
+# The tls_cert parameter specifies the client's X509 certificate to
+# be used in SSL/TLS connections.
+#
+#tls_cert =
+
+# The tls_key parameter specifies the private key corresponding to
+# the above tls_cert.
+#
+#tls_key =
+
+# The tls_require_cert parameter specifies whether or not to
+# request server's X509 certificate and check its validity when
+# establishing SSL/TLS connections.
+#
+#tls_require_cert = no
+
+# The tls_random_file parameter specifies a file to obtain random
+# bits from when /dev/[u]random is not available, to be used in SSL/TLS
+# connections.
+#
+#tls_random_file =
+
+# The tls_cipher_suite parameter specifies the cipher suite to be
+# use in SSL/TLS negotiations.
+#
+#tls_cipher_suite =
-# The ldap_debuglevel parameter sets the debug level in the OpenLDAP
+# The debuglevel parameter sets the debug level in the OpenLDAP
# libraries.
-#ldap_debuglevel = 0
+#debuglevel = 0
#
# - TZ is needed for sane time keeping on most SYSV-ish systems
#
-# Specify a list of names separated by whitespace or comma.
+# Specify a list of names and/or name=value pairs, separated by
+# whitespace or comma.
#
+#export_environment = TZ PATH=/bin:/usr/bin
export_environment = TZ
# The hash_queue_depth parameter specifies the number of subdirectory
# with an X-windows debugger.
# - MAIL_CONFIG is needed to make "postfix -c" work.
#
-# Specify a list of names separated by whitespace or comma.
+# Specify a list of names and/or name=value pairs, separated by
+# whitespace or comma.
#
#import_environment = MAIL_CONFIG TZ XAUTHORITY DISPLAY HOME PURIFYOPTIONS
import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY
# see access(5) for possible lookup results.
# check_policy_service transport:endpoint: delegate the decision to
# an external policy server. See SMTPD_POLICY_README for details.
+# reject_rhsbl_helo domain.tld: reject if the helo argument is listed
+# in an A record under domain.tld.
+# Append e.g., "=127.0.0.2" to the RBL domain name to select a specific
+# address record when an RBL server provides multi-valued results.
# reject: reject the request. Place this at the end of a restriction.
# permit: permit the request. Place this at the end of a restriction.
# warn_if_reject: next restriction logs a warning instead of rejecting.
# When a mail address localpart contains the optional recip-
# ient delimiter (e.g., user+foo@domain), the lookup order
# becomes: user+foo@domain, user@domain, user+foo, user, and
-# @domain. An unmatched address extension (+foo) is propa-
+# @domain.
+#
+# The propagate_unmatched_extensions parameter controls
+# whether an unmatched address extension (+foo) is propa-
# gated to the result of table lookup.
#
# VIRTUAL ALIAS DOMAINS
-# Besides virtual aliases, the virtual alias table can also
+# Besides virtual aliases, the virtual alias table can also
# be used to implement virtual alias domains. With a virtual
-# alias domain, all recipient addresses are aliased to
+# alias domain, all recipient addresses are aliased to
# addresses in other domains.
#
# Virtual alias domains are not to be confused with the vir-
# tual mailbox domains that are implemented with the Postfix
# virtual(8) mail delivery agent. With virtual mailbox
-# domains, each recipient address can have its own mailbox.
+# domains, each recipient address can have its own mailbox.
#
-# With a virtual alias domain, the virtual domain has its
-# own user name space. Local (i.e. non-virtual) usernames
-# are not visible in a virtual alias domain. In particular,
-# local aliases(5) and local mailing lists are not visible
+# With a virtual alias domain, the virtual domain has its
+# own user name space. Local (i.e. non-virtual) usernames
+# are not visible in a virtual alias domain. In particular,
+# local aliases(5) and local mailing lists are not visible
# as localname@virtual-alias.domain.
#
# Support for a virtual alias domain looks like:
# /etc/postfix/main.cf:
# virtual_alias_maps = hash:/etc/postfix/virtual
#
-# Note: some systems use dbm databases instead of hash.
+# Note: some systems use dbm databases instead of hash.
# See the output from postconf -m for available database
# types.
#
# user1@virtual-alias.domain address1
# user2@virtual-alias.domain address2, address3
#
-# The virtual-alias.domain anything entry is required for a
+# The virtual-alias.domain anything entry is required for a
# virtual alias domain. Without this entry, mail is rejected
-# with "relay access denied", or bounces with "mail loops
+# with "relay access denied", or bounces with "mail loops
# back to myself".
#
-# Do not specify virtual alias domain names in the main.cf
+# Do not specify virtual alias domain names in the main.cf
# mydestination or relay_domains configuration parameters.
#
-# With a virtual alias domain, the Postfix SMTP server
-# accepts mail for known-user@virtual-alias.domain, and
-# rejects mail for unknown-user@virtual-alias.domain as
+# With a virtual alias domain, the Postfix SMTP server
+# accepts mail for known-user@virtual-alias.domain, and
+# rejects mail for unknown-user@virtual-alias.domain as
# undeliverable.
#
-# Instead of specifying the virtual alias domain name via
-# the virtual_alias_maps table, you may also specify it via
+# Instead of specifying the virtual alias domain name via
+# the virtual_alias_maps table, you may also specify it via
# the main.cf virtual_alias_domains configuration parameter.
-# This latter parameter uses the same syntax as the main.cf
+# This latter parameter uses the same syntax as the main.cf
# mydestination configuration parameter.
#
# REGULAR EXPRESSION TABLES
-# This section describes how the table lookups change when
+# This section describes how the table lookups change when
# the table is given in the form of regular expressions. For
-# a description of regular expression lookup table syntax,
+# a description of regular expression lookup table syntax,
# see regexp_table(5) or pcre_table(5).
#
-# Each pattern is a regular expression that is applied to
+# Each pattern is a regular expression that is applied to
# the entire address being looked up. Thus, user@domain mail
-# addresses are not broken up into their user and @domain
+# addresses are not broken up into their user and @domain
# constituent parts, nor is user+foo broken up into user and
# foo.
#
-# Patterns are applied in the order as specified in the
-# table, until a pattern is found that matches the search
+# Patterns are applied in the order as specified in the
+# table, until a pattern is found that matches the search
# string.
#
-# Results are the same as with indexed file lookups, with
-# the additional feature that parenthesized substrings from
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
# the pattern can be interpolated as $1, $2 and so on.
#
# TCP-BASED TABLES
-# This section describes how the table lookups change when
+# This section describes how the table lookups change when
# lookups are directed to a TCP-based server. For a descrip-
-# tion of the TCP client/server lookup protocol, see
+# tion of the TCP client/server lookup protocol, see
# tcp_table(5).
#
# Each lookup operation uses the entire address once. Thus,
-# user@domain mail addresses are not broken up into their
+# user@domain mail addresses are not broken up into their
# user and @domain constituent parts, nor is user+foo broken
# up into user and foo.
#
# Results are the same as with indexed file lookups.
#
# BUGS
-# The table format does not understand quoting conventions.
+# The table format does not understand quoting conventions.
#
# CONFIGURATION PARAMETERS
-# The following main.cf parameters are especially relevant
-# to this topic. See the Postfix main.cf file for syntax
-# details and for default values. Use the postfix reload
+# The following main.cf parameters are especially relevant
+# to this topic. See the Postfix main.cf file for syntax
+# details and for default values. Use the postfix reload
# command after a configuration change.
#
# virtual_alias_maps
# List of virtual aliasing tables.
#
# virtual_alias_domains
-# List of virtual alias domains. This uses the same
+# List of virtual alias domains. This uses the same
# syntax as the mydestination parameter.
#
+# propagate_unmatched_extensions
+# A list of address rewriting or forwarding mecha-
+# nisms that propagate an address extension from the
+# original address to the result. Specify zero or
+# more of canonical, virtual, alias, forward, or
+# include.
+#
# Other parameters of interest:
#
# inet_interfaces
-# The network interface addresses that this system
+# The network interface addresses that this system
# receives mail on. You need to stop and start Post-
# fix when this parameter changes.
#
# mydestination
-# List of domains that this mail system considers
+# List of domains that this mail system considers
# local.
#
# myorigin
-# The domain that is appended to any address that
+# The domain that is appended to any address that
# does not have a domain.
#
# owner_request_special
# tcp_table(5) TCP client/server table lookup protocol
#
# LICENSE
-# The Secure Mailer license must be distributed with this
+# The Secure Mailer license must be distributed with this
# software.
#
# AUTHOR(S)
# or /var/tmp. DO NOT create the greylist database in a file system
# that can run out of space.
#
+# In case of database corruption, this script saves the database as
+# $database_name.time(), so that the mail system does not get stuck.
+#
$database_name="/var/mta/smtpd-policy.db";
$greylist_delay=3600;
#
# Read database. Use a shared lock to avoid reading the database
-# while it is being changed.
+# while it is being changed. XXX There should be a way to synchronize
+# our cache from the on-file database before looking up the key.
#
sub read_database {
my($key) = @_;
flock DATABASE_HANDLE, LOCK_SH ||
fatal_exit "Can't get shared lock on %s: $!", $database_name;
+ # XXX Synchronize our cache from the on-disk copy before lookup.
$value = $db_hash{$key};
syslog $syslog_priority, "lookup %s: %s", $key, $value if $verbose;
flock DATABASE_HANDLE, LOCK_UN ||
#
# Update database. Use an exclusive lock to avoid collisions with
-# other updaters, and to avoid surprises in database readers.
+# other updaters, and to avoid surprises in database readers. XXX
+# There should be a way to synchronize our cache from the on-file
+# database before updating the database.
#
sub update_database {
my($key, $value) = @_;
syslog $syslog_priority, "store %s: %s", $key, $value if $verbose;
flock DATABASE_HANDLE, LOCK_EX ||
fatal_exit "Can't exclusively lock %s: $!", $database_name;
+ # XXX Synchronize our cache from the on-disk copy before update.
$db_hash{$key} = $value;
$database_obj->sync() &&
fatal_exit "Can't update %s: $!", $database_name;
fatal_exit "Can't unlock %s: $!", $database_name;
}
+#
+# Signal 11 means that we have some kind of database corruption (yes
+# Berkeley DB should handle this better). Move the corrupted database
+# out of the way, and start with a new database.
+#
+sub sigsegv_handler {
+ my $backup = $database_name . time();
+
+ rename $database_name, $backup ||
+ fatal_exit "Can't save %s as %s: $!", $database_name, $backup;
+ fatal_exit "Caught signal 11; the corrupted database is saved as $backup";
+}
+
+$SIG{'SEGV'} = 'sigsegv_handler';
+
#
# This process runs as a daemon, so it can't log to a terminal. Use
# syslog so that people can actually see our messages.
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
CANONICAL(5) CANONICAL(5)
<b>NAME</b>
When a mail address localpart contains the optional recip-
ient delimiter (e.g., <i>user+foo</i>@<i>domain</i>), the lookup order
becomes: <i>user+foo</i>@<i>domain</i>, <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and
- @<i>domain</i>. An unmatched address extension (<i>+foo</i>) is propa-
+ @<i>domain</i>.
+
+ The <b>propagate_unmatched_extensions</b> parameter controls
+ whether an unmatched address extension (<i>+foo</i>) is propa-
gated to the result of table lookup.
<b>REGULAR EXPRESSION TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire address being looked up. Thus, <i>user@domain</i> mail
- addresses are not broken up into their <i>user</i> and <i>@domain</i>
+ addresses are not broken up into their <i>user</i> and <i>@domain</i>
constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and
<i>foo</i>.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Results are the same as with indexed file lookups, with
- the additional feature that parenthesized substrings from
+ Results are the same as with indexed file lookups, with
+ the additional feature that parenthesized substrings from
the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>TCP-BASED TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
lookups are directed to a TCP-based server. For a descrip-
- tion of the TCP client/server lookup protocol, see
+ tion of the TCP client/server lookup protocol, see
<a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
Each lookup operation uses the entire address once. Thus,
- <i>user@domain</i> mail addresses are not broken up into their
+ <i>user@domain</i> mail addresses are not broken up into their
<i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i> broken
up into <i>user</i> and <i>foo</i>.
Results are the same as with indexed file lookups.
<b>BUGS</b>
- The table format does not understand quoting conventions.
+ The table format does not understand quoting conventions.
<b>CONFIGURATION PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix reload</b>
command after a configuration change.
<b>canonical_maps</b>
Address mapping lookup table for envelope and
header sender addresses.
+ <b>propagate_unmatched_extensions</b>
+ A list of address rewriting or forwarding mecha-
+ nisms that propagate an address extension from the
+ original address to the result. Specify zero or
+ more of <b>canonical</b>, <b>virtual</b>, <b>alias</b>, <b>forward</b>, or
+ <b>include</b>.
+
Other parameters of interest:
<b>inet_interfaces</b>
- The network interface addresses that this system
+ The network interface addresses that this system
receives mail on. You need to stop and start Post-
fix when this parameter changes.
<b>masquerade_classes</b>
- List of address classes subject to masquerading:
- zero or more of <b>envelope_sender</b>, <b>envelope_recipi-</b>
+ List of address classes subject to masquerading:
+ zero or more of <b>envelope_sender</b>, <b>envelope_recipi-</b>
<b>ent</b>, <b>header_sender</b>, <b>header_recipient</b>.
<b>masquerade_domains</b>
- List of domains that hide their subdomain struc-
+ List of domains that hide their subdomain struc-
ture.
<b>masquerade_exceptions</b>
- List of user names that are not subject to address
+ List of user names that are not subject to address
masquerading.
<b>mydestination</b>
- List of domains that this mail system considers
+ List of domains that this mail system considers
local.
<b>myorigin</b>
<a href="tcp_table.5.html">tcp_table(5)</a> TCP client/server table lookup protocol
<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>
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
CLEANUP(8) CLEANUP(8)
<b>NAME</b>
List of user names that are not subject to address
masquerading.
+ <b>propagate_unmatched_extensions</b>
+ A list of address rewriting or forwarding mecha-
+ nisms that propagate an address extension from the
+ original address to the result. Specify zero or
+ more of <b>canonical</b>, <b>virtual</b>, <b>alias</b>, <b>forward</b>, or
+ <b>include</b>.
+
<b>virtual_alias_maps</b>
Address mapping lookup table for envelope recipient
addresses.
<p>
You run the Postfix SMTP server inside a <b>chroot</b> jail for
-extra security, but some configuration files are missing. In order
+extra security, but some configuration files are missing or have
+incorrect information. The command "postfix check" will report
+what files may have incorrect information. For example:
+
+<blockquote>
+<pre>
+warning: /var/spool/postfix/etc/resolv.conf and /etc/resolv.conf differ
+warning: /var/spool/postfix/etc/localtime and /etc/localtime differ
+</pre>
+</blockquote>
+
+<p>
+
+In order
to run inside a chroot jail, the Postfix SMTP client and server
need copies of system configuration files inside the Postfix queue
directory. The exact list of files is very system dependent, but
Check out your Postfix <b>master.cf</b> file. If the SMTP client
runs chrooted, then it needs a bunch of files inside the Postfix
queue directory. Examples are in the source distribution in the
-<b>examples</b> subdirectory.
+<b>examples</b> subdirectory. See also the other FAQ entry on
+<a href="#numerical_log">name service trouble</a>.
</ul>
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
LMTP(8) LMTP(8)
<b>NAME</b>
ified local or remote host. If no port is speci-
fied, connect to the port defined as <b>lmtp</b> in <b>ser-</b>
<b>vices</b>(4). If no such service is found, the
- <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b> configuration parameter (default
+ <b>lmtp_tcp_port</b> configuration parameter (default
value of 24) will be used.
The LMTP client does not perform MX (mail
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>notify</b><i>_</i><b>classes</b> parameter,
+ Depending on the setting of the <b>notify_classes</b> parameter,
the postmaster is notified of bounces, protocol problems,
and of other trouble.
<b>BUGS</b>
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
The following <b>main.cf</b> parameters are especially relevant
to this program. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix</b> <b>reload</b>
+ details and for default values. Use the <b>postfix reload</b>
command after a configuration change.
<b>Miscellaneous</b>
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
+ <b>debug_peer_level</b>
Verbose logging level increment for hosts that
- match a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> parameter.
+ match a pattern in the <b>debug_peer_list</b> parameter.
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+ <b>debug_peer_list</b>
List of domain or network patterns. When a remote
host matches a pattern, increase the verbose log-
ging level by the amount specified in the
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
+ <b>debug_peer_level</b> parameter.
- <b>error</b><i>_</i><b>notice</b><i>_</i><b>recipient</b>
+ <b>error_notice_recipient</b>
Recipient of protocol/policy/resource/software
error notices.
- <b>notify</b><i>_</i><b>classes</b>
+ <b>notify_classes</b>
When this parameter includes the <b>protocol</b> class,
send mail to the postmaster with transcripts of
LMTP sessions with protocol errors.
- <b>lmtp</b><i>_</i><b>skip</b><i>_</i><b>quit</b><i>_</i><b>response</b>
+ <b>lmtp_skip_quit_response</b>
Do not wait for the server response after sending
QUIT.
- <b>lmtp</b><i>_</i><b>tcp</b><i>_</i><b>port</b>
+ <b>lmtp_tcp_port</b>
The TCP port to be used when connecting to a LMTP
server. Used as backup if the <b>lmtp</b> service is not
found in <b>services</b>(4).
-<b>Authentication</b> <b>controls</b>
- <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>auth</b><i>_</i><b>enable</b>
+<b>Authentication controls</b>
+ <b>lmtp_sasl_auth_enable</b>
Enable per-session authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
(SASL). By default, Postfix is built without SASL
support.
- <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>password</b><i>_</i><b>maps</b>
+ <b>lmtp_sasl_password_maps</b>
Lookup tables with per-host or domain <i>name</i>:<i>password</i>
entries. No entry for a host means no attempt to
authenticate.
- <b>lmtp</b><i>_</i><b>sasl</b><i>_</i><b>security</b><i>_</i><b>options</b>
+ <b>lmtp_sasl_security_options</b>
Zero or more of the following.
<b>noplaintext</b>
<b>noanonymous</b>
Disallow anonymous logins.
-<b>Resource</b> <b>controls</b>
- <b>lmtp</b><i>_</i><b>cache</b><i>_</i><b>connection</b>
+<b>Resource controls</b>
+ <b>lmtp_cache_connection</b>
Should we cache the connection to the LMTP server?
The effectiveness of cached connections will be
determined by the number of LMTP servers in use,
<b>o</b> The LMTP client idle time limit is reached.
This limit is specified with the Postfix
- <b>max</b><i>_</i><b>idle</b> configuration parameter.
+ <b>max_idle</b> configuration parameter.
<b>o</b> A delivery request specifies a different
destination than the one currently cached.
<b>o</b> The per-process limit on the number of
delivery requests is reached. This limit is
- specified with the Postfix <b>max</b><i>_</i><b>use</b> configu-
+ specified with the Postfix <b>max_use</b> configu-
ration parameter.
<b>o</b> Upon the onset of another delivery request,
session does not respond to the <b>RSET</b> com-
mand.
- <i>transport_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+ <i>transport</i><b>_destination_concurrency_limit</b>
Limit the number of parallel deliveries to the same
destination via this mail delivery transport.
<i>transport</i> is the name of the service as specified
in the <b>master.cf</b> file. The default limit is taken
- from the <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+ from the <b>default_destination_concurrency_limit</b>
parameter.
- <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
+ <i>transport</i><b>_destination_recipient_limit</b>
Limit the number of recipients per message delivery
via this mail delivery transport. <i>transport</i> is the
name of the service as specified in the <b>master.cf</b>
file. The default limit is taken from the
- <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
+ <b>default_destination_recipient_limit</b> parameter.
This parameter becomes significant if the LMTP
client is used for local delivery. Some LMTP
of recipients. Exercise care when setting this
parameter.
-<b>Timeout</b> <b>controls</b>
+<b>Timeout controls</b>
The default time unit is seconds; an explicit time unit
can be specified by appending a one-letter suffix to the
value: s (seconds), m (minutes), h (hours), d (days) or w
(weeks).
- <b>lmtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
+ <b>lmtp_connect_timeout</b>
Timeout for opening a connection to the LMTP
server. If no connection can be made within the
deadline, the message is deferred.
- <b>lmtp</b><i>_</i><b>lhlo</b><i>_</i><b>timeout</b>
+ <b>lmtp_lhlo_timeout</b>
Timeout for sending the <b>LHLO</b> command, and for
receiving the server response.
- <b>lmtp</b><i>_</i><b>mail</b><i>_</i><b>timeout</b>
- Timeout for sending the <b>MAIL</b> <b>FROM</b> command, and for
+ <b>lmtp_mail_timeout</b>
+ Timeout for sending the <b>MAIL FROM</b> command, and for
receiving the server response.
- <b>lmtp</b><i>_</i><b>rcpt</b><i>_</i><b>timeout</b>
- Timeout for sending the <b>RCPT</b> <b>TO</b> command, and for
+ <b>lmtp_rcpt_timeout</b>
+ Timeout for sending the <b>RCPT TO</b> command, and for
receiving the server response.
- <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>init</b><i>_</i><b>timeout</b>
+ <b>lmtp_data_init_timeout</b>
Timeout for sending the <b>DATA</b> command, and for
receiving the server response.
- <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>xfer</b><i>_</i><b>timeout</b>
+ <b>lmtp_data_xfer_timeout</b>
Timeout for sending the message content.
- <b>lmtp</b><i>_</i><b>data</b><i>_</i><b>done</b><i>_</i><b>timeout</b>
+ <b>lmtp_data_done_timeout</b>
Timeout for sending the "<b>.</b>" command, and for
receiving the server response. When no response is
received, a warning is logged that the mail may be
delivered multiple times.
- <b>lmtp</b><i>_</i><b>rset</b><i>_</i><b>timeout</b>
+ <b>lmtp_rset_timeout</b>
Timeout for sending the <b>RSET</b> command, and for
receiving the server response.
- <b>lmtp</b><i>_</i><b>quit</b><i>_</i><b>timeout</b>
+ <b>lmtp_quit_timeout</b>
Timeout for sending the <b>QUIT</b> command, and for
receiving the server response.
-<b>SEE</b> <b>ALSO</b>
+<b>SEE ALSO</b>
<a href="bounce.8.html">bounce(8)</a> non-delivery status reports
<a href="local.8.html">local(8)</a> local mail delivery
<a href="master.8.html">master(8)</a> process manager
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
LOCAL(8) LOCAL(8)
<b>NAME</b>
The system administrator can specify a comma/space sepa-
rated list of ~/.<b>forward</b> like files through the <b>for-</b>
- <b>ward</b><i>_</i><b>path</b> configuration parameter. Upon delivery, the
+ <b>ward_path</b> configuration parameter. Upon delivery, the
local delivery agent tries each pathname in the list until
- a file is found. The <b>forward</b><i>_</i><b>path</b> parameter is subject to
+ a file is found. The <b>forward_path</b> parameter is subject to
interpolation of <b>$user</b> (recipient username), <b>$home</b> (recip-
ient home directory), <b>$shell</b> (recipient shell), <b>$recipient</b>
(complete recipient address), <b>$extension</b> (recipient
address extension), <b>$domain</b> (recipient domain), <b>local</b>
- (entire recipient address localpart) and <b>$recipient</b><i>_</i><b>delim-</b>
+ (entire recipient address localpart) and <b>$recipient_delim-</b>
<b>iter.</b> The forms <i>${name?value}</i> and <i>${name:value}</i> expand
conditionally to <i>value</i> when <i>$name</i> is (is not) defined.
Characters that may have special meaning to the shell or
file system are replaced by underscores. The list of
- acceptable characters is specified with the <b>forward</b><i>_</i><b>expan-</b>
- <b>sion</b><i>_</i><b>filter</b> configuration parameter.
+ acceptable characters is specified with the <b>forward_expan-</b>
+ <b>sion_filter</b> configuration parameter.
An alias or ~/.<b>forward</b> file may list any combination of
external commands, destination file names, <b>:include:</b>
In order to prevent the mail system from using up unrea-
sonable amounts of memory, input records read from
<b>:include:</b> or from ~/.<b>forward</b> files are broken up into
- chunks of length <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>.
+ chunks of length <b>line_length_limit</b>.
While expanding aliases, ~/.<b>forward</b> files, and so on, the
program attempts to avoid duplicate deliveries. The <b>dupli-</b>
- <b>cate</b><i>_</i><b>filter</b><i>_</i><b>limit</b> configuration parameter limits the num-
+ <b>cate_filter_limit</b> configuration parameter limits the num-
ber of remembered recipients.
<b>MAIL FORWARDING</b>
rate on-file delivery status record.
In order to stop mail forwarding loops early, the software
- adds an optional <b>Delivered-To:</b> header with the envelope
- recipient address. If mail arrives for a recipient that is
- already listed in a <b>Delivered-To:</b> header, the message is
- bounced.
+ adds an optional <b>Delivered-To:</b> header with the final enve-
+ lope recipient address. If mail arrives for a recipient
+ that is already listed in a <b>Delivered-To:</b> header, the mes-
+ sage is bounced.
<b>MAILBOX DELIVERY</b>
The default per-user mailbox is a file in the UNIX mail
spool directory (<b>/var/mail/</b><i>user</i> or <b>/var/spool/mail/</b><i>user</i>);
- the location can be specified with the <b>mail</b><i>_</i><b>spool</b><i>_</i><b>direc-</b>
+ the location can be specified with the <b>mail_spool_direc-</b>
<b>tory</b> configuration parameter. Specify a name ending in <b>/</b>
for <b>qmail</b>-compatible <b>maildir</b> delivery.
Alternatively, the per-user mailbox can be a file in the
user's home directory with a name specified via the
- <b>home</b><i>_</i><b>mailbox</b> configuration parameter. Specify a relative
+ <b>home_mailbox</b> configuration parameter. Specify a relative
path name. Specify a name ending in <b>/</b> for <b>qmail</b>-compatible
<b>maildir</b> delivery.
Mailbox delivery can be delegated to an external command
- specified with the <b>mailbox</b><i>_</i><b>command</b> configuration parame-
+ specified with the <b>mailbox_command</b> configuration parame-
ter. The command executes with the privileges of the
recipient user (exception: in case of delivery as root,
the command executes with the privileges of
- <b>default</b><i>_</i><b>privs</b>).
+ <b>default_privs</b>).
Mailbox delivery can be delegated to alternative message
transports specified in the <b>master.cf</b> file. The <b>mail-</b>
- <b>box</b><i>_</i><b>transport</b> configuration parameter specifies a message
+ <b>box_transport</b> configuration parameter specifies a message
transport that is to be used for all local recipients,
regardless of whether they are found in the UNIX passwd
- database. The <b>fallback</b><i>_</i><b>transport</b> parameter specifies a
+ database. The <b>fallback_transport</b> parameter specifies a
message transport for recipients that are not found in the
UNIX passwd database.
In the case of UNIX-style mailbox delivery, the <b>local</b> dae-
- mon prepends a "<b>From</b> <i>sender time_stamp</i>" envelope header to
+ mon prepends a "<b>From</b> <i>sender time</i><b>_</b><i>stamp</i>" envelope header to
each message, prepends an <b>X-Original-To:</b> header with the
recipient address as given to Postfix, prepends an
- optional <b>Delivered-To:</b> header with the envelope recipient
- address, prepends a <b>Return-Path:</b> header with the envelope
- sender address, prepends a > character to lines beginning
- with "<b>From</b> ", and appends an empty line. The mailbox is
- locked for exclusive access while delivery is in progress.
- In case of problems, an attempt is made to truncate the
- mailbox to its original length.
+ optional <b>Delivered-To:</b> header with the final envelope
+ recipient address, prepends a <b>Return-Path:</b> header with the
+ envelope sender address, prepends a > character to lines
+ beginning with "<b>From</b> ", and appends an empty line. The
+ mailbox is locked for exclusive access while delivery is
+ in progress. In case of problems, an attempt is made to
+ truncate the mailbox to its original length.
In the case of <b>maildir</b> delivery, the local daemon prepends
an optional <b>Delivered-To:</b> header with the final envelope
<b>Return-Path:</b> header with the envelope sender address.
<b>EXTERNAL COMMAND DELIVERY</b>
- The <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b> configuration parameter
+ The <b>allow_mail_to_commands</b> configuration parameter
restricts delivery to external commands. The default set-
ting (<b>alias, forward</b>) forbids command destinations in
<b>:include:</b> files.
A limited amount of command output (standard output and
standard error) is captured for inclusion with non-deliv-
ery status reports. A command is forcibly terminated if
- it does not complete within <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> seconds.
+ it does not complete within <b>command_time_limit</b> seconds.
Command exit status codes are expected to follow the con-
ventions defined in <<b>sysexits.h</b>>.
A limited amount of message context is exported via envi-
ronment variables. Characters that may have special mean-
ing to the shell are replaced by underscores. The list of
- acceptable characters is specified with the <b>command</b><i>_</i><b>expan-</b>
- <b>sion</b><i>_</i><b>filter</b> configuration parameter.
+ acceptable characters is specified with the <b>command_expan-</b>
+ <b>sion_filter</b> configuration parameter.
<b>SHELL</b> The recipient user's login shell.
The <b>PATH</b> environment variable is always reset to a system-
dependent default path, and environment variables whose
- names are blessed by the <b>export</b><i>_</i><b>environment</b> configuration
+ names are blessed by the <b>export_environment</b> configuration
parameter are exported unchanged.
The current working directory is the mail queue directory.
- The <b>local</b> daemon prepends a "<b>From</b> <i>sender time_stamp</i>" enve-
+ The <b>local</b> daemon prepends a "<b>From</b> <i>sender time</i><b>_</b><i>stamp</i>" enve-
lope header to each message, prepends an <b>X-Original-To:</b>
header with the recipient address as given to Postfix,
- prepends an optional <b>Delivered-To:</b> header with the recipi-
- ent envelope address, prepends a <b>Return-Path:</b> header with
- the sender envelope address, and appends no empty line.
+ prepends an optional <b>Delivered-To:</b> header with the final
+ recipient envelope address, prepends a <b>Return-Path:</b> header
+ with the sender envelope address, and appends no empty
+ line.
<b>EXTERNAL FILE DELIVERY</b>
- The delivery format depends on the destination filename
- syntax. The default is to use UNIX-style mailbox format.
- Specify a name ending in <b>/</b> for <b>qmail</b>-compatible <b>maildir</b>
+ The delivery format depends on the destination filename
+ syntax. The default is to use UNIX-style mailbox format.
+ Specify a name ending in <b>/</b> for <b>qmail</b>-compatible <b>maildir</b>
delivery.
- The <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b> configuration parameter restricts
- delivery to external files. The default setting (<b>alias,</b>
+ The <b>allow_mail_to_files</b> configuration parameter restricts
+ delivery to external files. The default setting (<b>alias,</b>
<b>forward</b>) forbids file destinations in <b>:include:</b> files.
In the case of UNIX-style mailbox delivery, the <b>local</b> dae-
- mon prepends a "<b>From</b> <i>sender time_stamp</i>" envelope header to
- each message, prepends an <b>X-Original-To:</b> header with the
- recipient address as given to Postfix, prepends an
- optional <b>Delivered-To:</b> header with the recipient envelope
- address, prepends a > character to lines beginning with
- "<b>From</b> ", and appends an empty line. The envelope sender
- address is available in the <b>Return-Path:</b> header. When the
- destination is a regular file, it is locked for exclusive
- access while delivery is in progress. In case of problems,
- an attempt is made to truncate a regular file to its orig-
- inal length.
+ mon prepends a "<b>From</b> <i>sender time</i><b>_</b><i>stamp</i>" envelope header to
+ each message, prepends an <b>X-Original-To:</b> header with the
+ recipient address as given to Postfix, prepends an
+ optional <b>Delivered-To:</b> header with the final recipient
+ envelope address, prepends a > character to lines begin-
+ ning with "<b>From</b> ", and appends an empty line. The enve-
+ lope sender address is available in the <b>Return-Path:</b>
+ header. When the destination is a regular file, it is
+ locked for exclusive access while delivery is in progress.
+ In case of problems, an attempt is made to truncate a reg-
+ ular file to its original length.
In the case of <b>maildir</b> delivery, the local daemon prepends
- an optional <b>Delivered-To:</b> header with the envelope recipi-
- ent address, and prepends an <b>X-Original-To:</b> header with
- the recipient address as given to Postfix. The envelope
- sender address is available in the <b>Return-Path:</b> header.
+ an optional <b>Delivered-To:</b> header with the final envelope
+ recipient address, and prepends an <b>X-Original-To:</b> header
+ with the recipient address as given to Postfix. The enve-
+ lope sender address is available in the <b>Return-Path:</b>
+ header.
<b>ADDRESS EXTENSION</b>
- The optional <b>recipient</b><i>_</i><b>delimiter</b> configuration parameter
+ The optional <b>recipient_delimiter</b> configuration parameter
specifies how to separate address extensions from local
recipient names.
- For example, with "<b>recipient</b><i>_</i><b>delimiter = +</b>", mail for
+ For example, with "<b>recipient_delimiter = +</b>", mail for
<i>name</i>+<i>foo</i> is delivered to the alias <i>name</i>+<i>foo</i> or to the
alias <i>name</i>, to the destinations listed in ~<i>name</i>/.<b>for-</b>
<b>ward</b>+<i>foo</i> or in ~<i>name</i>/.<b>forward</b>, to the mailbox owned by the
user <i>name</i>, or it is sent back as undeliverable.
In all cases the <b>local</b> daemon prepends an optional `<b>Deliv-</b>
- <b>ered-To:</b> <i>name</i>+<i>foo</i>' header line.
+ <b>ered-To:</b> header line with the final recipient address.
<b>DELIVERY RIGHTS</b>
Deliveries to external files and external commands are
the <b>local</b> daemon uses the owner rights of the <b>:include:</b>
file or alias database. When those files are owned by the
superuser, delivery is made with the rights specified with
- the <b>default</b><i>_</i><b>privs</b> configuration parameter.
+ the <b>default_privs</b> configuration parameter.
<b>STANDARDS</b>
<a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
rupted message files are marked so that the queue manager
can move them to the <b>corrupt</b> queue afterwards.
- Depending on the setting of the <b>notify</b><i>_</i><b>classes</b> parameter,
+ Depending on the setting of the <b>notify_classes</b> parameter,
the postmaster is notified of bounces and of other trou-
ble.
command after a configuration change.
<b>Miscellaneous</b>
- <b>alias</b><i>_</i><b>maps</b>
+ <b>alias_maps</b>
List of alias databases.
<b>biff</b> Enable or disable notification of new mail via the
<b>comsat</b> network service.
- <b>expand</b><i>_</i><b>owner</b><i>_</i><b>alias</b>
+ <b>expand_owner_alias</b>
When delivering to an alias that has an owner- com-
panion alias, set the envelope sender address to
the right-hand side of the owner alias, instead
using of the left-hand side address.
- <b>export</b><i>_</i><b>environment</b>
+ <b>export_environment</b>
List of names of environment parameters that can be
exported to non-Postfix processes.
- <b>forward</b><i>_</i><b>path</b>
+ <b>forward_path</b>
Search list for .forward files. The names are sub-
ject to <i>$name</i> expansion.
- <b>local</b><i>_</i><b>command</b><i>_</i><b>shell</b>
+ <b>local_command_shell</b>
Shell to use for external command execution (for
example, /some/where/smrsh -c). When a shell is
specified, it is invoked even when the command con-
tains no shell built-in commands or meta charac-
ters.
- <b>owner</b><i>_</i><b>request</b><i>_</i><b>special</b>
+ <b>owner_request_special</b>
Give special treatment to <b>owner-</b><i>xxx</i> and <i>xxx</i><b>-request</b>
addresses.
- <b>prepend</b><i>_</i><b>delivered</b><i>_</i><b>header</b>
+ <b>prepend_delivered_header</b>
Prepend an optional <b>Delivered-To:</b> header upon
external forwarding, delivery to command or file.
Specify zero or more of: <b>command, file, forward</b>.
Turning off <b>Delivered-To:</b> when forwarding mail is
not recommended.
- <b>recipient</b><i>_</i><b>delimiter</b>
+ <b>propagate_unmatched_extensions</b>
+ A list of address rewriting or forwarding mecha-
+ nisms that propagate an address extension from the
+ original address to the result. Specify zero or
+ more of <b>canonical</b>, <b>virtual</b>, <b>alias</b>, <b>forward</b>, or
+ <b>include</b>.
+
+ <b>recipient_delimiter</b>
Separator between username and address extension.
- <b>require</b><i>_</i><b>home</b><i>_</i><b>directory</b>
+ <b>require_home_directory</b>
Require that a recipient's home directory is acces-
sible by the recipient before attempting delivery.
Defer delivery otherwise.
<b>Mailbox delivery</b>
- <b>fallback</b><i>_</i><b>transport</b>
+ <b>fallback_transport</b>
Message transport for recipients that are not found
in the UNIX passwd database. This parameter over-
- rides <b>luser</b><i>_</i><b>relay</b>.
+ rides <b>luser_relay</b>.
- Note: you must update the <b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> set-
+ Note: you must update the <b>local_recipient_maps</b> set-
ting in the <b>main.cf</b> file, otherwise the Postfix
SMTP server will reject mail for non-UNIX accounts
with "<b>User unknown in local recipient table</b>".
- <b>home</b><i>_</i><b>mailbox</b>
+ <b>home_mailbox</b>
Pathname of a mailbox relative to a user's home
directory. Specify a path ending in <b>/</b> for maildir-
style delivery.
- <b>luser</b><i>_</i><b>relay</b>
+ <b>luser_relay</b>
Destination (<i>@domain</i> or <i>address</i>) for non-existent
users. The <i>address</i> is subjected to <i>$name</i> expan-
sion.
- Note: you must specify "<b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps =</b>"
+ Note: you must specify "<b>local_recipient_maps =</b>"
(i.e. empty) in the <b>main.cf</b> file, otherwise the
Postfix SMTP server will reject mail for non-UNIX
accounts with "<b>User unknown in local recipient</b>
<b>table</b>".
- <b>mail</b><i>_</i><b>spool</b><i>_</i><b>directory</b>
+ <b>mail_spool_directory</b>
Directory with UNIX-style mailboxes. The default
pathname is system dependent. Specify a path end-
ing in <b>/</b> for maildir-style delivery.
- <b>mailbox</b><i>_</i><b>command</b>
+ <b>mailbox_command</b>
External command to use for mailbox delivery. The
command executes with the recipient privileges
(exception: root). The string is subject to $name
expansions.
- <b>mailbox</b><i>_</i><b>command</b><i>_</i><b>maps</b>
+ <b>mailbox_command_maps</b>
Lookup tables with per-recipient external commands
to use for mailbox delivery. Behavior is as with
- <b>mailbox</b><i>_</i><b>command</b>.
+ <b>mailbox_command</b>.
- <b>mailbox</b><i>_</i><b>transport</b>
+ <b>mailbox_transport</b>
Message transport to use for mailbox delivery to
all local recipients, whether or not they are found
in the UNIX passwd database. This parameter over-
rides all other configuration parameters that con-
- trol mailbox delivery, including <b>luser</b><i>_</i><b>relay</b>.
+ trol mailbox delivery, including <b>luser_relay</b>.
Note: if you use this feature to receive mail for
non-UNIX accounts then you must update the
- <b>local</b><i>_</i><b>recipient</b><i>_</i><b>maps</b> setting in the <b>main.cf</b> file,
+ <b>local_recipient_maps</b> setting in the <b>main.cf</b> file,
otherwise the Postfix SMTP server will reject mail
for non-UNIX accounts with "<b>User unknown in local</b>
<b>recipient table</b>".
<b>Locking controls</b>
- <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
+ <b>deliver_lock_attempts</b>
Limit the number of attempts to acquire an exclu-
sive lock on a mailbox or external file.
- <b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
+ <b>deliver_lock_delay</b>
Time in seconds between successive attempts to
acquire an exclusive lock.
- <b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
+ <b>stale_lock_time</b>
Limit the time after which a stale lock is removed.
- <b>mailbox</b><i>_</i><b>delivery</b><i>_</i><b>lock</b>
+ <b>mailbox_delivery_lock</b>
What file locking method(s) to use when delivering
to a UNIX-style mailbox. The default setting is
system dependent. For a list of available file
locking methods, use the <b>postconf -l</b> command.
<b>Resource controls</b>
- <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>
+ <b>command_time_limit</b>
Limit the amount of time for delivery to external
command.
- <b>duplicate</b><i>_</i><b>filter</b><i>_</i><b>limit</b>
+ <b>duplicate_filter_limit</b>
Limit the size of the duplicate filter for results
from alias etc. expansion.
- <b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
+ <b>line_length_limit</b>
Limit the amount of memory used for processing a
partial input line.
- <b>local</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
+ <b>local_destination_concurrency_limit</b>
Limit the number of parallel deliveries to the same
user. The default limit is taken from the
- <b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.
+ <b>default_destination_concurrency_limit</b> parameter.
- <b>local</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
+ <b>local_destination_recipient_limit</b>
Limit the number of recipients per message deliv-
ery. The default limit is taken from the
- <b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
+ <b>default_destination_recipient_limit</b> parameter.
- <b>mailbox</b><i>_</i><b>size</b><i>_</i><b>limit</b>
+ <b>mailbox_size_limit</b>
Limit the size of a mailbox etc. file (any file
that is written to upon delivery). Set to zero to
disable the limit.
<b>Security controls</b>
- <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>
+ <b>allow_mail_to_commands</b>
Restrict the usage of mail delivery to external
command. Specify zero or more of: <b>alias</b>, <b>forward</b>,
<b>include</b>.
- <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b>
+ <b>allow_mail_to_files</b>
Restrict the usage of mail delivery to external
file. Specify zero or more of: <b>alias</b>, <b>forward</b>,
<b>include</b>.
- <b>command</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
+ <b>command_expansion_filter</b>
What characters are allowed to appear in $name
expansions of mailbox_command. Illegal characters
are replaced by underscores.
- <b>default</b><i>_</i><b>privs</b>
+ <b>default_privs</b>
Default rights for delivery to external file or
command.
- <b>forward</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
+ <b>forward_expansion_filter</b>
What characters are allowed to appear in $name
expansions of forward_path. Illegal characters are
replaced by underscores.
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
POSTALIAS(1) POSTALIAS(1)
<b>NAME</b>
ate a new file with default access permissions
(mode 0644).
- <b>-q</b> <i>key</i> Search the specified maps for <i>key</i> and print the
- first value found on the standard output stream.
+ <b>-q</b> <i>key</i> Search the specified maps for <i>key</i> and write the
+ first value found to the standard output stream.
The exit status is zero when the requested informa-
tion was found.
If a key value of <b>-</b> is specified, the program reads
key values from the standard input stream and
- prints one line of <i>key: value</i> output for each key
+ writes one line of <i>key: value</i> output for each key
that was found. The exit status is zero when at
least one of the requested keys was found.
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
SENDMAIL(1) SENDMAIL(1)
<b>NAME</b>
sendmail - Postfix to Sendmail compatibility interface
<b>SYNOPSIS</b>
- <b>sendmail</b> [<i>option</i> <i>...</i>] [<i>recipient</i> <i>...</i>]
+ <b>sendmail</b> [<i>option ...</i>] [<i>recipient ...</i>]
<b>mailq</b>
- <b>sendmail</b> <b>-bp</b>
+ <b>sendmail -bp</b>
<b>newaliases</b>
- <b>sendmail</b> <b>-I</b>
+ <b>sendmail -I</b>
<b>DESCRIPTION</b>
The <b>sendmail</b> program implements the Postfix to Sendmail
Initialize the alias database. If no input file is
specified (with the <b>-oA</b> option, see below), the
program processes the file(s) specified with the
- <b>alias</b><i>_</i><b>database</b> configuration parameter. If no
+ <b>alias_database</b> configuration parameter. If no
alias database type is specified, the program uses
- the type specified with the <b>default</b><i>_</i><b>database</b><i>_</i><b>type</b>
+ the type specified with the <b>default_database_type</b>
configuration parameter. This mode of operation is
implemented by running the <a href="postalias.1.html"><b>postalias</b>(1)</a> command.
regardless of whether or not a message is an ini-
tial submission.
- <b>-B</b> <i>body_type</i>
+ <b>-B</b> <i>body</i><b>_</b><i>type</i>
The message body MIME type: <b>7BIT</b> or <b>8BITMIME</b>.
- <b>-C</b> <i>config_file</i> (ignored :-)
+ <b>-C</b> <i>config</i><b>_</b><i>file</i> (ignored :-)
The path name of the <b>sendmail.cf</b> file. Postfix con-
figuration files are kept in <b>/etc/postfix</b>.
- <b>-F</b> <i>full_name</i>
+ <b>-F</b> <i>full</i><b>_</b><i>name</i>
Set the sender full name. This is used only with
messages that have no <b>From:</b> message header.
mand above.
<b>-L</b> <i>label</i> (ignored)
- The logging label. Use the <b>syslog</b><i>_</i><b>name</b> configura-
+ The logging label. Use the <b>syslog_name</b> configura-
tion parameter instead.
<b>-N</b> <i>dsn</i> (ignored)
Delivery status notification control. Currently,
Postfix does not implement <b>DSN</b>.
- <b>-R</b> <i>return_limit</i> (ignored)
+ <b>-R</b> <i>return</i><b>_</b><i>limit</i> (ignored)
Limit the size of bounced mail. Use the
- <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b> configuration parameter instead.
+ <b>bounce_size_limit</b> configuration parameter instead.
- <b>-X</b> <i>log_file</i> (ignored)
- Log mailer traffic. Use the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b> and
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> configuration parameters instead.
+ <b>-X</b> <i>log</i><b>_</b><i>file</i> (ignored)
+ Log mailer traffic. Use the <b>debug_peer_list</b> and
+ <b>debug_peer_level</b> configuration parameters instead.
<b>-U</b> (ignored)
Initial user submission.
By default, the personalized envelope sender
address is <i>owner-listname</i><b>+</b><i>user</i><b>=</b><i>domain</i>@<i>origin</i>. The
default <b>+</b> and <b>=</b> characters are configurable with
- the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b> configuration parame-
+ the <b>default_verp_delimiters</b> configuration parame-
ter.
<b>-V</b><i>xy</i> As <b>-V</b>, but uses <i>x</i> and <i>y</i> as the VERP delimiter char-
acters, instead of the characters specified with
- the <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b> configuration parame-
+ the <b>default_verp_delimiters</b> configuration parame-
ter.
<b>-bd</b> Go into daemon mode. This mode of operation is
- implemented by executing the <b>postfix</b> <b>start</b> command.
+ implemented by executing the <b>postfix start</b> command.
<b>-bi</b> Initialize alias database. See the <b>newaliases</b> com-
mand above.
dard output. In stand-alone SMTP server mode, UCE
restrictions and access controls are disabled by
default. To enable them, run the process as the
- <b>mail</b><i>_</i><b>owner</b> user.
+ <b>mail_owner</b> user.
This mode of operation is implemented by running
the <a href="smtpd.8.html"><b>smtpd</b>(8)</a> daemon.
address where delivery problems are sent to, unless
the message contains an <b>Errors-To:</b> message header.
- <b>-h</b> <i>hop_count</i> (ignored)
- Hop count limit. Use the <b>hopcount</b><i>_</i><b>limit</b> configura-
+ <b>-h</b> <i>hop</i><b>_</b><i>count</i> (ignored)
+ Hop count limit. Use the <b>hopcount_limit</b> configura-
tion parameter instead.
<b>-i</b> When reading a message from standard input, don't
<b>-n</b> (ignored)
Backwards compatibility.
- <b>-oA</b><i>alias_database</i>
+ <b>-oA</b><i>alias</i><b>_</b><i>database</i>
Non-default alias database. Specify <i>pathname</i> or
<i>type</i>:<i>pathname</i>. See <a href="postalias.1.html"><b>postalias</b>(1)</a> for details.
The sender is never eliminated from alias etc.
expansions.
- <b>-o</b> <i>x</i> <i>value</i> (ignored)
+ <b>-o</b> <i>x value</i> (ignored)
Set option <i>x</i> to <i>value</i>. Use the equivalent configu-
ration parameter in <b>main.cf</b> instead.
<b>-q</b><i>interval</i> (ignored)
The interval between queue runs. Use the
- <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b> configuration parameter instead.
+ <b>queue_run_delay</b> configuration parameter instead.
<b>-qR</b><i>site</i>
Schedule immediate delivery of all mail that is
<b>-qS</b><i>site</i>
This command is not implemented. Use the slower
- <b>sendmail</b> <b>-q</b> command instead.
+ <b>sendmail -q</b> command instead.
<b>-t</b> Extract recipients from message headers. These are
added to any recipients specified on the command
error stream.
<b>ENVIRONMENT</b>
- <b>MAIL</b><i>_</i><b>CONFIG</b>
+ <b>MAIL_CONFIG</b>
Directory with Postfix configuration files.
- <b>MAIL</b><i>_</i><b>VERBOSE</b>
+ <b>MAIL_VERBOSE</b>
Enable verbose logging for debugging purposes.
- <b>MAIL</b><i>_</i><b>DEBUG</b>
+ <b>MAIL_DEBUG</b>
Enable debugging with an external command, as spec-
- ified with the <b>debugger</b><i>_</i><b>command</b> configuration
+ ified with the <b>debugger_command</b> configuration
parameter.
<b>FILES</b>
/var/spool/postfix, mail queue
/etc/postfix, configuration files
-<b>CONFIGURATION</b> <b>PARAMETERS</b>
+<b>CONFIGURATION PARAMETERS</b>
See the Postfix <b>main.cf</b> file for syntax details and for
- default values. Use the <b>postfix</b> <b>reload</b> command after a
+ default values. Use the <b>postfix reload</b> command after a
configuration change.
- <b>alias</b><i>_</i><b>database</b>
+ <b>alias_database</b>
Default alias database(s) for <b>newaliases</b>. The
default value for this parameter is system-spe-
cific.
- <b>bounce</b><i>_</i><b>size</b><i>_</i><b>limit</b>
+ <b>bounce_size_limit</b>
The amount of original message context that is sent
along with a non-delivery notification.
- <b>default</b><i>_</i><b>database</b><i>_</i><b>type</b>
+ <b>default_database_type</b>
Default alias etc. database type. On many UNIX sys-
tems the default type is either <b>dbm</b> or <b>hash</b>.
- <b>debugger</b><i>_</i><b>command</b>
+ <b>debugger_command</b>
Command that is executed after a Postfix daemon has
initialized.
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b>
+ <b>debug_peer_level</b>
Increment in verbose logging level when a remote
- host matches a pattern in the <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+ host matches a pattern in the <b>debug_peer_list</b>
parameter.
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>list</b>
+ <b>debug_peer_list</b>
List of domain or network patterns. When a remote
host matches a pattern, increase the verbose log-
ging level by the amount specified in the
- <b>debug</b><i>_</i><b>peer</b><i>_</i><b>level</b> parameter.
+ <b>debug_peer_level</b> parameter.
- <b>default</b><i>_</i><b>verp</b><i>_</i><b>delimiters</b>
+ <b>default_verp_delimiters</b>
The VERP delimiter characters that are used when
the <b>-V</b> command line option is specified without
delimiter characters.
- <b>fast</b><i>_</i><b>flush</b><i>_</i><b>domains</b>
+ <b>fast_flush_domains</b>
List of domains that will receive "fast flush" ser-
vice (default: all domains that this system is
willing to relay mail to). This list specifies the
domains that Postfix accepts in the SMTP <b>ETRN</b>
- request and in the <b>sendmail</b> <b>-qR</b> command.
+ request and in the <b>sendmail -qR</b> command.
- <b>fork</b><i>_</i><b>attempts</b>
+ <b>fork_attempts</b>
Number of attempts to <b>fork</b>() a process before giv-
ing up.
- <b>fork</b><i>_</i><b>delay</b>
+ <b>fork_delay</b>
Delay in seconds between successive <b>fork</b>()
attempts.
- <b>hopcount</b><i>_</i><b>limit</b>
+ <b>hopcount_limit</b>
Limit the number of <b>Received:</b> message headers.
- <b>mail</b><i>_</i><b>owner</b>
+ <b>mail_owner</b>
The owner of the mail queue and of most Postfix
processes.
- <b>command</b><i>_</i><b>directory</b>
+ <b>command_directory</b>
Directory with Postfix support commands.
- <b>daemon</b><i>_</i><b>directory</b>
+ <b>daemon_directory</b>
Directory with Postfix daemon programs.
- <b>queue</b><i>_</i><b>directory</b>
+ <b>queue_directory</b>
Top-level directory of the Postfix queue. This is
also the root directory of Postfix daemons that run
chrooted.
- <b>queue</b><i>_</i><b>run</b><i>_</i><b>delay</b>
+ <b>queue_run_delay</b>
The time between successive scans of the deferred
queue.
- <b>verp</b><i>_</i><b>delimiter</b><i>_</i><b>filter</b>
+ <b>verp_delimiter_filter</b>
The characters that Postfix accepts as VERP delim-
iter characters.
-<b>SEE</b> <b>ALSO</b>
+<b>SEE ALSO</b>
<a href="pickup.8.html">pickup(8)</a> mail pickup daemon
<a href="postsuper.1.html">postsuper(1)</a> queue maintenance
<a href="postalias.1.html">postalias(1)</a> maintain alias database
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
SMTPD(8) SMTPD(8)
<b>NAME</b>
with comments that Sendmail allows.
<b>broken_sasl_auth_clients</b>
- Support older Microsoft clients that mis-implement
- the AUTH protocol, and that expect an EHLO response
- of "250 AUTH=list" instead of "250 AUTH list".
+ Support Microsoft clients that implement an older
+ version of the AUTH protocol, and that expect an
+ EHLO response of "250 AUTH=list" instead of "250
+ AUTH list".
+
+ <b>smtpd_sasl_exceptions_networks</b>
+ Don't offer AUTH in the response to EHLO when talk-
+ ing to clients in the specified networks. This is
+ a workaround for clients that that demand a login
+ and password from the user whenever AUTH is offered
+ by an SMTP server.
<b>smtpd_noop_commands</b>
List of commands that are treated as NOOP (no oper-
- ation) commands, without any parameter syntax
- checking and without any state change. This list
+ ation) commands, without any parameter syntax
+ checking and without any state change. This list
overrides built-in command definitions.
<b>Content inspection controls</b>
- Optionally, Postfix can be configured to send new mail to
+ Optionally, Postfix can be configured to send new mail to
external content filter software AFTER the mail is queued.
<b>content_filter</b>
- The name of a mail delivery transport that filters
+ The name of a mail delivery transport that filters
mail and that either bounces mail or re-injects the
- result back into Postfix. This parameter uses the
- same syntax as the right-hand side of a Postfix
+ result back into Postfix. This parameter uses the
+ same syntax as the right-hand side of a Postfix
transport table.
<b>receive_override_options</b>
- The following options override <b>main.cf</b> settings.
- The options are either implemented by the SMTP
- server or are passed on to the downstream cleanup
+ The following options override <b>main.cf</b> settings.
+ The options are either implemented by the SMTP
+ server or are passed on to the downstream cleanup
server.
<b>no_unknown_recipient_checks</b>
- Do not try to reject unknown recipients.
- This is typically specified with the SMTP
+ Do not try to reject unknown recipients.
+ This is typically specified with the SMTP
server <b>after</b> an external content filter.
<b>no_address_mappings</b>
- Disable canonical address mapping, virtual
- alias map expansion, address masquerading,
- and automatic BCC recipients. This is typi-
- cally specified with the SMTP server <b>before</b>
+ Disable canonical address mapping, virtual
+ alias map expansion, address masquerading,
+ and automatic BCC recipients. This is typi-
+ cally specified with the SMTP server <b>before</b>
an external content filter.
<b>no_header_body_checks</b>
- Disable header/body_checks. This is typi-
- cally specified with the SMTP server <b>after</b>
+ Disable header/body_checks. This is typi-
+ cally specified with the SMTP server <b>after</b>
an external content filter.
<b>Pass-through proxy</b>
- Optionally, the Postfix SMTP server can be configured to
- forward all mail to a proxy server, for example a real-
+ Optionally, the Postfix SMTP server can be configured to
+ forward all mail to a proxy server, for example a real-
time content filter, BEFORE mail is queued.
<b>smtpd_proxy_filter</b>
<b>Authentication controls</b>
<b>smtpd_sasl_auth_enable</b>
- Enable per-session authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
- (SASL). This functionality is available only when
+ Enable per-session authentication as per <a href="http://www.faqs.org/rfcs/rfc2554.html">RFC 2554</a>
+ (SASL). This functionality is available only when
explicitly selected at program build time and
explicitly enabled at runtime.
Disallow anonymous logins.
<b>smtpd_sender_login_maps</b>
- Maps that specify the SASL login name that owns a
- MAIL FROM sender address. Used by the
+ Maps that specify the SASL login name that owns a
+ MAIL FROM sender address. Used by the
<b>reject_sender_login_mismatch</b> sender anti-spoofing
restriction.
that are authorized to use the XVERP extension.
<b>debug_peer_level</b>
- Increment in verbose logging level when a remote
+ Increment in verbose logging level when a remote
host matches a pattern in the <b>debug_peer_list</b>
parameter.
<b>debug_peer_list</b>
- List of domain or network patterns. When a remote
- host matches a pattern, increase the verbose log-
- ging level by the amount specified in the
+ List of domain or network patterns. When a remote
+ host matches a pattern, increase the verbose log-
+ ging level by the amount specified in the
<b>debug_peer_level</b> parameter.
<b>default_verp_delimiters</b>
The default VERP delimiter characters that are used
- when the XVERP command is specified without
+ when the XVERP command is specified without
explicit delimiters.
<b>error_notice_recipient</b>
- Recipient of protocol/policy/resource/software
+ Recipient of protocol/policy/resource/software
error notices.
<b>hopcount_limit</b>
<b>notify_classes</b>
List of error classes. Of special interest are:
- <b>policy</b> When a client violates any policy, mail a
+ <b>policy</b> When a client violates any policy, mail a
transcript of the entire SMTP session to the
postmaster.
<b>protocol</b>
- When a client violates the SMTP protocol or
+ When a client violates the SMTP protocol or
issues an unimplemented command, mail a
transcript of the entire SMTP session to the
postmaster.
<b>smtpd_banner</b>
- Text that follows the <b>220</b> status code in the SMTP
+ Text that follows the <b>220</b> status code in the SMTP
greeting banner.
<b>smtpd_expansion_filter</b>
expansion of rbl template responses and other text.
<b>smtpd_recipient_limit</b>
- Restrict the number of recipients that the SMTP
+ Restrict the number of recipients that the SMTP
server accepts per message delivery.
<b>smtpd_timeout</b>
- Limit the time to send a server response and to
+ Limit the time to send a server response and to
receive a client request.
<b>soft_bounce</b>
- Change hard (5xx) reject responses into soft (4xx)
- reject responses. This can be useful for testing
+ Change hard (5xx) reject responses into soft (4xx)
+ reject responses. This can be useful for testing
purposes.
<b>verp_delimiter_filter</b>
- The characters that Postfix accepts as VERP delim-
+ The characters that Postfix accepts as VERP delim-
iter characters.
<b>Known versus unknown recipients</b>
<b>show_user_unknown_table_name</b>
- Whether or not to reveal the table name in the
- "User unknown" responses. The extra detail makes
- trouble shooting easier but also reveals informa-
+ Whether or not to reveal the table name in the
+ "User unknown" responses. The extra detail makes
+ trouble shooting easier but also reveals informa-
tion that is nobody elses business.
<b>unknown_local_recipient_reject_code</b>
The response code when a client specifies a recipi-
- ent whose domain matches <b>$mydestination</b> or
+ ent whose domain matches <b>$mydestination</b> or
<b>$inet_interfaces</b>, while <b>$local_recipient_maps</b> is
- non-empty and does not list the recipient address
+ non-empty and does not list the recipient address
or address local-part.
<b>unknown_relay_recipient_reject_code</b>
The response code when a client specifies a recipi-
ent whose domain matches <b>$relay_domains</b>, while
- <b>$relay_recipient_maps</b> is non-empty and does not
+ <b>$relay_recipient_maps</b> is non-empty and does not
list the recipient address.
<b>unknown_virtual_alias_reject_code</b>
The response code when a client specifies a recipi-
- ent whose domain matches <b>$virtual_alias_domains</b>,
- while the recipient is not listed in <b>$vir-</b>
+ ent whose domain matches <b>$virtual_alias_domains</b>,
+ while the recipient is not listed in <b>$vir-</b>
<b>tual_alias_maps</b>.
<b>unknown_virtual_mailbox_reject_code</b>
The response code when a client specifies a recipi-
- ent whose domain matches <b>$virtual_mailbox_domains</b>,
+ ent whose domain matches <b>$virtual_mailbox_domains</b>,
while the recipient is not listed in <b>$virtual_mail-</b>
<b>box_maps</b>.
<b>Resource controls</b>
<b>line_length_limit</b>
- Limit the amount of memory in bytes used for the
+ Limit the amount of memory in bytes used for the
handling of partial input lines.
<b>message_size_limit</b>
ing on-disk storage for envelope information.
<b>queue_minfree</b>
- Minimal amount of free space in bytes in the queue
- file system for the SMTP server to accept any mail
+ Minimal amount of free space in bytes in the queue
+ file system for the SMTP server to accept any mail
at all.
<b>smtpd_history_flush_threshold</b>
<b>smtpd_soft_error_limit</b>
When an SMTP client has made this number of errors,
- wait <i>error</i><b>_</b><i>count</i> seconds before responding to any
+ wait <i>error</i><b>_</b><i>count</i> seconds before responding to any
client request.
<b>smtpd_hard_error_limit</b>
- Disconnect after a client has made this number of
+ Disconnect after a client has made this number of
errors.
<b>smtpd_junk_command_limit</b>
Limit the number of times a client can issue a junk
- command such as NOOP, VRFY, ETRN or RSET in one
- SMTP session before it is penalized with tarpit
+ command such as NOOP, VRFY, ETRN or RSET in one
+ SMTP session before it is penalized with tarpit
delays.
<b>Delegated policy</b>
receiving from a delegated SMTPD policy server.
<b>smtpd_policy_service_max_idle</b>
- Time after which an unused SMTPD policy service
+ Time after which an unused SMTPD policy service
connection is closed.
<b>smtpd_policy_service_timeout</b>
- Time after which an active SMTPD policy service
+ Time after which an active SMTPD policy service
connection is closed.
<b>UCE control restrictions</b>
<b>parent_domain_matches_subdomains</b>
- List of Postfix features that use <i>domain.tld</i> pat-
- terns to match <i>sub.domain.tld</i> (as opposed to
+ List of Postfix features that use <i>domain.tld</i> pat-
+ terns to match <i>sub.domain.tld</i> (as opposed to
requiring <i>.domain.tld</i> patterns).
<b>smtpd_client_restrictions</b>
tem.
<b>smtpd_helo_required</b>
- Require that clients introduce themselves at the
+ Require that clients introduce themselves at the
beginning of an SMTP session.
<b>smtpd_helo_restrictions</b>
- Restrict what client hostnames are allowed in <b>HELO</b>
+ Restrict what client hostnames are allowed in <b>HELO</b>
and <b>EHLO</b> commands.
<b>smtpd_sender_restrictions</b>
- Restrict what sender addresses are allowed in <b>MAIL</b>
+ Restrict what sender addresses are allowed in <b>MAIL</b>
<b>FROM</b> commands.
<b>smtpd_recipient_restrictions</b>
- Restrict what recipient addresses are allowed in
+ Restrict what recipient addresses are allowed in
<b>RCPT TO</b> commands.
<b>smtpd_etrn_restrictions</b>
mands, and what clients may issue <b>ETRN</b> commands.
<b>smtpd_data_restrictions</b>
- Restrictions on the <b>DATA</b> command. Currently, the
- only restriction that makes sense here is
+ Restrictions on the <b>DATA</b> command. Currently, the
+ only restriction that makes sense here is
<b>reject_unauth_pipelining</b>.
<b>allow_untrusted_routing</b>
- Allow untrusted clients to specify addresses with
- sender-specified routing. Enabling this opens up
- nasty relay loopholes involving trusted backup MX
+ Allow untrusted clients to specify addresses with
+ sender-specified routing. Enabling this opens up
+ nasty relay loopholes involving trusted backup MX
hosts.
<b>smtpd_restriction_classes</b>
- Declares the name of zero or more parameters that
- contain a list of UCE restrictions. The names of
- these parameters can then be used instead of the
+ Declares the name of zero or more parameters that
+ contain a list of UCE restrictions. The names of
+ these parameters can then be used instead of the
restriction lists that they represent.
<b>smtpd_null_access_lookup_key</b>
- The lookup key to be used in SMTPD access tables
- instead of the null sender address. A null sender
+ The lookup key to be used in SMTPD access tables
+ instead of the null sender address. A null sender
address cannot be looked up.
<b>maps_rbl_domains</b> (deprecated)
- List of DNS domains that publish the addresses of
+ List of DNS domains that publish the addresses of
blacklisted hosts. This is used with the deprecated
<b>reject_maps_rbl</b> restriction.
<b>permit_mx_backup_networks</b>
- Only domains whose primary MX hosts match the
- listed networks are eligible for the <b>per-</b>
+ Only domains whose primary MX hosts match the
+ listed networks are eligible for the <b>per-</b>
<b>mit_mx_backup</b> feature.
<b>relay_domains</b>
- Restrict what domains this mail system will relay
- mail to. The domains are routed to the delivery
+ Restrict what domains this mail system will relay
+ mail to. The domains are routed to the delivery
agent specified with the <b>relay_transport</b> setting.
<b>Sender/recipient address verification</b>
Address verification is implemented by sending probe email
- messages that are not actually delivered, and is enabled
- via the reject_unverified_{sender,recipient} access
- restriction. The status of verification probes is main-
+ messages that are not actually delivered, and is enabled
+ via the reject_unverified_{sender,recipient} access
+ restriction. The status of verification probes is main-
tained by the address verification service.
<b>address_verify_poll_count</b>
- How many times to query the address verification
- service for completion of an address verification
- request. Specify 1 to implement a simple form of
- greylisting, that is, always defer the request for
+ How many times to query the address verification
+ service for completion of an address verification
+ request. Specify 1 to implement a simple form of
+ greylisting, that is, always defer the request for
a new sender or recipient address.
<b>address_verify_poll_delay</b>
- Time to wait after querying the address verifica-
+ Time to wait after querying the address verifica-
tion service for completion of an address verifica-
tion request.
<b>UCE control responses</b>
<b>access_map_reject_code</b>
- Response code when a client violates an access
+ Response code when a client violates an access
database restriction.
<b>default_rbl_reply</b>
Default template reply when a request is RBL black-
- listed. This template is used by the <b>reject_rbl_*</b>
- and <b>reject_rhsbl_*</b> restrictions. See also:
+ listed. This template is used by the <b>reject_rbl_*</b>
+ and <b>reject_rhsbl_*</b> restrictions. See also:
<b>rbl_reply_maps</b> and <b>smtpd_expansion_filter</b>.
<b>defer_code</b>
- Response code when a client request is rejected by
+ Response code when a client request is rejected by
the <b>defer</b> restriction.
<b>invalid_hostname_reject_code</b>
- Response code when a client violates the
+ Response code when a client violates the
<b>reject_invalid_hostname</b> restriction.
<b>maps_rbl_reject_code</b>
Response code when a request is RBL blacklisted.
<b>multi_recipient_bounce_reject_code</b>
- Response code when a multi-recipient bounce is
+ Response code when a multi-recipient bounce is
blocked.
<b>rbl_reply_maps</b>
- Table with template responses for RBL blacklisted
- requests, indexed by RBL domain name. These tem-
+ Table with template responses for RBL blacklisted
+ requests, indexed by RBL domain name. These tem-
plates are used by the <b>reject_rbl_*</b> and
- <b>reject_rhsbl_*</b> restrictions. See also:
+ <b>reject_rhsbl_*</b> restrictions. See also:
<b>default_rbl_reply</b> and <b>smtpd_expansion_filter</b>.
<b>reject_code</b>
- Response code when the client matches a <b>reject</b>
+ Response code when the client matches a <b>reject</b>
restriction.
<b>relay_domains_reject_code</b>
mail relay policy.
<b>unknown_address_reject_code</b>
- Response code when a client violates the
+ Response code when a client violates the
<b>reject_unknown_address</b> restriction.
<b>unknown_client_reject_code</b>
tion.
<b>unknown_hostname_reject_code</b>
- Response code when a client violates the
+ Response code when a client violates the
<b>reject_unknown_hostname</b> restriction.
<b>unverified_sender_reject_code</b>
- Response code when a sender address is known to be
+ Response code when a sender address is known to be
undeliverable.
<b>unverified_recipient_reject_code</b>
- Response code when a recipient address is known to
+ Response code when a recipient address is known to
be undeliverable.
<b>SEE ALSO</b>
<a href="verify.8.html">verify(8)</a> address verification service
<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>
Reject the message, log the header and the optional text,
and send the optional text to the originator.
-<dt>OK <dd>Skip all further header patterns for this header line.
+<dt>DUNNO <dd>
-<dt>IGNORE <dd> Delete the header line from the message.
+<dt>DUNNO text... <dd>Skip all further header patterns for this header line.
+This has the same effect as OK, which is deprecated.
+
+<dt>IGNORE <dd>
+
+<dt>IGNORE text... <dd> Delete the header line from the message.
<dt>WARN <dd>
Log (but do not reject) the body line with a warning, and log the
optional text.
-<dt>OK <dd>Skip all further body patterns for this body line.
+<dt>DUNNO <dd>
+
+<dt>DUNNO text... <dd>Skip all further body patterns for this body line.
+This has the same effect as OK, which is deprecated.
-<dt>IGNORE <dd> Delete the body line from the message.
+<dt>IGNORE <dd>
+
+<dt>IGNORE text... <dd> Delete the body line from the message.
<dt>HOLD <dd>
<dd> <b>smtpd_client_restrictions = hash:/etc/postfix/access,
reject_rbl_client relays.ordb.org</b> (free service)
-<dd> <b>smtpd_client_restrictions = hash:/etc/postfix/access,
-reject_rhsbl_client dsn.rfc-ignorant.org</b> (free service)
+<dd> <b>smtpd_sender_restrictions = hash:/etc/postfix/access,
+reject_rhsbl_sender dsn.rfc-ignorant.org</b> (free service)
<dd> <b>smtpd_client_restrictions = permit_mynetworks,
reject_unknown_client</b>
<p>
+<a name="reject_rhsbl_helo">
+
+<dt> <b>reject_rhsbl_helo</b> <i>domain.tld=127.0.0.2</i>
+
+<dt> <b>reject_rhsbl_helo</b> <i>domain.tld</i> <dd> Reject the
+request when the HELO (or EHLO) hostname is listed with an A record
+under <i>domain.tld</i>. See above for additional RBL related
+configuration parameters.
+
+Append the address to the RBL server's domain name to select a
+specific address from a multi-valued result.
+
+The <b> maps_rbl_reject_code</b> parameter specifies the response
+code for rejected requests (default: <b>554</b>), the <b><a
+href="#default_rbl_reply"> default_rbl_reply </a></b> parameter
+specifies the default server reply, and the <b><a href="#rbl_reply_maps">
+rbl_reply_maps </a></b> parameter specifies tables with server replies
+indexed by RBL domain.
+
+<p>
+
<dt> <b><a href="#permit">permit</a></b>
<dt> <b><a href="#defer">defer</a></b>
<table border="1">
-<tr><th>Recipient domain matches <th>Recipient lookup table
+<tr><th>Recipient domain matches</th> <th>Recipient lookup table</th>
-<tr><td><a href="basic.html#mydestination"> $mydestination</a> or
-<a href="basic.html#inet_interfaces">$inet_interfaces</a>
-<td>$local_recipient_maps
+</tr><tr><td><a href="basic.html#mydestination"> $mydestination</a> or
+<a href="basic.html#inet_interfaces">$inet_interfaces</a></td>
+<td>$local_recipient_maps</td>
-<tr><td>$virtual_alias_domains <td>$virtual_alias_maps
+</tr><tr><td>$virtual_alias_domains</td> <td>$virtual_alias_maps</td>
-<tr><td>$virtual_mailbox_domains <td>$virtual_mailbox_maps
+</tr><tr><td>$virtual_mailbox_domains</td> <td>$virtual_mailbox_maps</td>
-<tr><td>$relay_domains <td>$relay_recipient_maps
+</tr><tr><td>$relay_domains</td> <td>$relay_recipient_maps</td>
-</table>
+</tr></table>
</blockquote>
-<html> <head> </head> <body> <pre>
+<html> <body> <pre>
VIRTUAL(5) VIRTUAL(5)
<b>NAME</b>
When a mail address localpart contains the optional recip-
ient delimiter (e.g., <i>user+foo</i>@<i>domain</i>), the lookup order
becomes: <i>user+foo</i>@<i>domain</i>, <i>user</i>@<i>domain</i>, <i>user+foo</i>, <i>user</i>, and
- @<i>domain</i>. An unmatched address extension (<i>+foo</i>) is propa-
+ @<i>domain</i>.
+
+ The <b>propagate_unmatched_extensions</b> parameter controls
+ whether an unmatched address extension (<i>+foo</i>) is propa-
gated to the result of table lookup.
<b>VIRTUAL ALIAS DOMAINS</b>
- Besides virtual aliases, the virtual alias table can also
+ Besides virtual aliases, the virtual alias table can also
be used to implement virtual alias domains. With a virtual
- alias domain, all recipient addresses are aliased to
+ alias domain, all recipient addresses are aliased to
addresses in other domains.
Virtual alias domains are not to be confused with the vir-
tual mailbox domains that are implemented with the Postfix
<a href="virtual.8.html"><b>virtual</b>(8)</a> mail delivery agent. With virtual mailbox
- domains, each recipient address can have its own mailbox.
+ domains, each recipient address can have its own mailbox.
- With a virtual alias domain, the virtual domain has its
- own user name space. Local (i.e. non-virtual) usernames
- are not visible in a virtual alias domain. In particular,
- local <a href="aliases.5.html"><b>aliases</b>(5)</a> and local mailing lists are not visible
+ With a virtual alias domain, the virtual domain has its
+ own user name space. Local (i.e. non-virtual) usernames
+ are not visible in a virtual alias domain. In particular,
+ local <a href="aliases.5.html"><b>aliases</b>(5)</a> and local mailing lists are not visible
as <i>localname@virtual-alias.domain</i>.
Support for a virtual alias domain looks like:
/etc/postfix/main.cf:
virtual_alias_maps = hash:/etc/postfix/virtual
- Note: some systems use <b>dbm</b> databases instead of <b>hash</b>.
+ Note: some systems use <b>dbm</b> databases instead of <b>hash</b>.
See the output from <b>postconf -m</b> for available database
types.
<i>user1@virtual-alias.domain address1</i>
<i>user2@virtual-alias.domain address2, address3</i>
- The <i>virtual-alias.domain anything</i> entry is required for a
+ The <i>virtual-alias.domain anything</i> entry is required for a
virtual alias domain. <b>Without this entry, mail is rejected</b>
- <b>with "relay access denied", or bounces with "mail loops</b>
+ <b>with "relay access denied", or bounces with "mail loops</b>
<b>back to myself".</b>
- Do not specify virtual alias domain names in the <b>main.cf</b>
+ Do not specify virtual alias domain names in the <b>main.cf</b>
<b>mydestination</b> or <b>relay_domains</b> configuration parameters.
- With a virtual alias domain, the Postfix SMTP server
- accepts mail for <i>known-user@virtual-alias.domain</i>, and
- rejects mail for <i>unknown-user</i>@<i>virtual-alias.domain</i> as
+ With a virtual alias domain, the Postfix SMTP server
+ accepts mail for <i>known-user@virtual-alias.domain</i>, and
+ rejects mail for <i>unknown-user</i>@<i>virtual-alias.domain</i> as
undeliverable.
- Instead of specifying the virtual alias domain name via
- the <b>virtual_alias_maps</b> table, you may also specify it via
+ Instead of specifying the virtual alias domain name via
+ the <b>virtual_alias_maps</b> table, you may also specify it via
the <b>main.cf virtual_alias_domains</b> configuration parameter.
- This latter parameter uses the same syntax as the <b>main.cf</b>
+ This latter parameter uses the same syntax as the <b>main.cf</b>
<b>mydestination</b> configuration parameter.
<b>REGULAR EXPRESSION TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see <a href="regexp_table.5.html"><b>regexp_table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre_table</b>(5)</a>.
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire address being looked up. Thus, <i>user@domain</i> mail
- addresses are not broken up into their <i>user</i> and <i>@domain</i>
+ addresses are not broken up into their <i>user</i> and <i>@domain</i>
constituent parts, nor is <i>user+foo</i> broken up into <i>user</i> and
<i>foo</i>.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Results are the same as with indexed file lookups, with
- the additional feature that parenthesized substrings from
+ Results are the same as with indexed file lookups, with
+ the additional feature that parenthesized substrings from
the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
<b>TCP-BASED TABLES</b>
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
lookups are directed to a TCP-based server. For a descrip-
- tion of the TCP client/server lookup protocol, see
+ tion of the TCP client/server lookup protocol, see
<a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
Each lookup operation uses the entire address once. Thus,
- <i>user@domain</i> mail addresses are not broken up into their
+ <i>user@domain</i> mail addresses are not broken up into their
<i>user</i> and <i>@domain</i> constituent parts, nor is <i>user+foo</i> broken
up into <i>user</i> and <i>foo</i>.
Results are the same as with indexed file lookups.
<b>BUGS</b>
- The table format does not understand quoting conventions.
+ The table format does not understand quoting conventions.
<b>CONFIGURATION PARAMETERS</b>
- The following <b>main.cf</b> parameters are especially relevant
- to this topic. See the Postfix <b>main.cf</b> file for syntax
- details and for default values. Use the <b>postfix reload</b>
+ The following <b>main.cf</b> parameters are especially relevant
+ to this topic. See the Postfix <b>main.cf</b> file for syntax
+ details and for default values. Use the <b>postfix reload</b>
command after a configuration change.
<b>virtual_alias_maps</b>
List of virtual aliasing tables.
<b>virtual_alias_domains</b>
- List of virtual alias domains. This uses the same
+ List of virtual alias domains. This uses the same
syntax as the <b>mydestination</b> parameter.
+ <b>propagate_unmatched_extensions</b>
+ A list of address rewriting or forwarding mecha-
+ nisms that propagate an address extension from the
+ original address to the result. Specify zero or
+ more of <b>canonical</b>, <b>virtual</b>, <b>alias</b>, <b>forward</b>, or
+ <b>include</b>.
+
Other parameters of interest:
<b>inet_interfaces</b>
- The network interface addresses that this system
+ The network interface addresses that this system
receives mail on. You need to stop and start Post-
fix when this parameter changes.
<b>mydestination</b>
- List of domains that this mail system considers
+ List of domains that this mail system considers
local.
<b>myorigin</b>
- The domain that is appended to any address that
+ The domain that is appended to any address that
does not have a domain.
<b>owner_request_special</b>
<a href="tcp_table.5.html">tcp_table(5)</a> TCP client/server table lookup protocol
<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>
when creating a new file. Instead, create a new file with default
access permissions (mode 0644).
.IP "\fB-q \fIkey\fR"
-Search the specified maps for \fIkey\fR and print the first value
-found on the standard output stream. The exit status is zero
+Search the specified maps for \fIkey\fR and write the first value
+found to the standard output stream. The exit status is zero
when the requested information was found.
If a key value of \fB-\fR is specified, the program reads key
-values from the standard input stream and prints one line of
+values from the standard input stream and writes one line of
\fIkey: value\fR output for each key that was found. The exit
status is zero when at least one of the requested keys was found.
.IP \fB-r\fR
This program is the complement of the \fIsmtp-source\fR program.
Arguments:
+.IP \fB-a\fR
+Do not announce SASL authentication support.
.IP \fB-c\fR
Display a running counter that is updated whenever an SMTP
QUIT command is executed.
.IP \fB-e\fR
Disable ESMTP support.
+.IP "\fB-f \fIcommand,command,...\fR"
+Reject the specified commands with a hard (5xx) error code.
.IP \fB-h\fI hostname\fR
Use \fIhostname\fR in the SMTP greeting, in the HELO response,
and in the EHLO response. The default hostname is "smtp-sink".
.IP \fB-P\fR
Change the server greeting so that it appears to come through
a CISCO PIX system. Implies \fB-e\fR.
+.IP "\fB-r \fIcommand,command,...\fR"
+Reject the specified commands with a soft (4xx) error code.
.IP "\fB-s \fIcommand,command,...\fR"
Log the named commands to syslogd.
Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
When a mail address localpart contains the optional recipient delimiter
(e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
\fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-\fIuser\fR, and @\fIdomain\fR. An unmatched address extension
-(\fI+foo\fR) is propagated to the result of table lookup.
+\fIuser\fR, and @\fIdomain\fR.
+
+The \fBpropagate_unmatched_extensions\fR parameter controls whether
+an unmatched address extension (\fI+foo\fR) is propagated to the
+result of table lookup.
.SH REGULAR EXPRESSION TABLES
.na
.nf
.IP \fBsender_canonical_maps\fR
Address mapping lookup table for envelope and header sender
addresses.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
.PP
Other parameters of interest:
.IP \fBinet_interfaces\fR
When a mail address localpart contains the optional recipient delimiter
(e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
\fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-\fIuser\fR, and @\fIdomain\fR. An unmatched address extension
-(\fI+foo\fR) is propagated to the result of table lookup.
+\fIuser\fR, and @\fIdomain\fR.
+
+The \fBpropagate_unmatched_extensions\fR parameter controls whether
+an unmatched address extension (\fI+foo\fR) is propagated to the
+result of table lookup.
.SH VIRTUAL ALIAS DOMAINS
.na
.nf
.IP \fBvirtual_alias_domains\fR
List of virtual alias domains. This uses the same syntax
as the \fBmydestination\fR parameter.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
.PP
Other parameters of interest:
.IP \fBinet_interfaces\fR
List of domains that hide their subdomain structure.
.IP \fBmasquerade_exceptions\fR
List of user names that are not subject to address masquerading.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
.IP \fBvirtual_alias_maps\fR
Address mapping lookup table for envelope recipient addresses.
.SH "Resource controls"
In order to stop mail forwarding loops early, the software adds an
optional
-\fBDelivered-To:\fR header with the envelope recipient address. If
+\fBDelivered-To:\fR header with the final envelope recipient address. If
mail arrives for a recipient that is already listed in a
\fBDelivered-To:\fR header, the message is bounced.
.SH MAILBOX DELIVERY
\fBX-Original-To:\fR header with the recipient address as given to
Postfix, prepends an
optional \fBDelivered-To:\fR header
-with the envelope recipient address, prepends a \fBReturn-Path:\fR
+with the final envelope recipient address, prepends a \fBReturn-Path:\fR
header with the envelope sender address, prepends a \fB>\fR character
to lines beginning with "\fBFrom \fR", and appends an empty line.
The mailbox is locked for exclusive access while delivery is in
\fBX-Original-To:\fR header with the recipient address as given to
Postfix, prepends an
optional \fBDelivered-To:\fR
-header with the recipient envelope address, prepends a
+header with the final recipient envelope address, prepends a
\fBReturn-Path:\fR header with the sender envelope address,
and appends no empty line.
.SH EXTERNAL FILE DELIVERY
\fBX-Original-To:\fR header with the recipient address as given to
Postfix, prepends an
optional \fBDelivered-To:\fR
-header with the recipient envelope address, prepends a \fB>\fR
+header with the final recipient envelope address, prepends a \fB>\fR
character to lines beginning with "\fBFrom \fR", and appends an
empty line.
The envelope sender address is available in the \fBReturn-Path:\fR
In the case of \fBmaildir\fR delivery, the local daemon prepends
an optional
-\fBDelivered-To:\fR header with the envelope recipient address, and
-prepends an
+\fBDelivered-To:\fR header with the final envelope recipient address,
+and prepends an
\fBX-Original-To:\fR header with the recipient address as given to
Postfix.
The envelope sender address is available in the \fBReturn-Path:\fR
undeliverable.
In all cases the \fBlocal\fR daemon prepends an optional
-`\fBDelivered-To:\fR \fIname\fR+\fIfoo\fR' header line.
+`\fBDelivered-To:\fR header line with the final recipient
+address.
.SH DELIVERY RIGHTS
.na
.nf
forwarding, delivery to command or file. Specify zero or more of:
\fBcommand, file, forward\fR. Turning off \fBDelivered-To:\fR when
forwarding mail is not recommended.
+.IP \fBpropagate_unmatched_extensions\fR
+A list of address rewriting or forwarding mechanisms that propagate
+an address extension from the original address to the result.
+Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+\fBforward\fR, or \fBinclude\fR.
.IP \fBrecipient_delimiter\fR
Separator between username and address extension.
.IP \fBrequire_home_directory\fR
Disallow non-RFC 821 style addresses in SMTP commands. For example,
the RFC822-style address forms with comments that Sendmail allows.
.IP \fBbroken_sasl_auth_clients\fR
-Support older Microsoft clients that mis-implement the AUTH
+Support Microsoft clients that implement an older version of the AUTH
protocol, and that expect an EHLO response of "250 AUTH=list"
instead of "250 AUTH list".
+.IP \fBsmtpd_sasl_exceptions_networks\fR
+Don't offer AUTH in the response to EHLO when talking to clients
+in the specified networks. This is a workaround for clients that
+that demand a login and password from the user whenever AUTH is
+offered by an SMTP server.
.IP \fBsmtpd_noop_commands\fR
List of commands that are treated as NOOP (no operation) commands,
without any parameter syntax checking and without any state change.
# Crude script to convert formatted manual pages to HTML
-echo '<html> <head> </head> <body> <pre>'
+echo '<html> <body> <pre>'
sed '
s/\([<>&]\)\b\1/\1/g
# .sp
# The pattern \fIdomain.tld\fR also matches subdomains, but only
# when the string \fBsmtpd_access_maps\fR is listed in the Postfix
-# \fBparent_domain_matches_subdomains\fR configuration setting.
+# \fBparent_domain_matches_subdomains\fR configuration setting
+# (note that this is the default for some versions of Postfix).
# Otherwise, specify \fI.domain.tld\fR (note the initial dot) in
# order to match subdomains.
# .IP \fIuser\fR@
# When a mail address localpart contains the optional recipient delimiter
# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-# \fIuser\fR, and @\fIdomain\fR. An unmatched address extension
-# (\fI+foo\fR) is propagated to the result of table lookup.
+# \fIuser\fR, and @\fIdomain\fR.
+#
+# The \fBpropagate_unmatched_extensions\fR parameter controls whether
+# an unmatched address extension (\fI+foo\fR) is propagated to the
+# result of table lookup.
# REGULAR EXPRESSION TABLES
# .ad
# .fi
# .IP \fBsender_canonical_maps\fR
# Address mapping lookup table for envelope and header sender
# addresses.
+# .IP \fBpropagate_unmatched_extensions\fR
+# A list of address rewriting or forwarding mechanisms that propagate
+# an address extension from the original address to the result.
+# Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+# \fBforward\fR, or \fBinclude\fR.
# .PP
# Other parameters of interest:
# .IP \fBinet_interfaces\fR
# When a mail address localpart contains the optional recipient delimiter
# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
-# \fIuser\fR, and @\fIdomain\fR. An unmatched address extension
-# (\fI+foo\fR) is propagated to the result of table lookup.
+# \fIuser\fR, and @\fIdomain\fR.
+#
+# The \fBpropagate_unmatched_extensions\fR parameter controls whether
+# an unmatched address extension (\fI+foo\fR) is propagated to the
+# result of table lookup.
# VIRTUAL ALIAS DOMAINS
# .ad
# .fi
# .IP \fBvirtual_alias_domains\fR
# List of virtual alias domains. This uses the same syntax
# as the \fBmydestination\fR parameter.
+# .IP \fBpropagate_unmatched_extensions\fR
+# A list of address rewriting or forwarding mechanisms that propagate
+# an address extension from the original address to the result.
+# Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+# \fBforward\fR, or \fBinclude\fR.
# .PP
# Other parameters of interest:
# .IP \fBinet_interfaces\fR
/* Address mapping lookup table for envelope and header sender
/* addresses.
/* .IP \fBmasquerade_classes\fR
-/* List of address classes subject to masquerading: zero or
-/* more of \fBenvelope_sender\fR, \fBenvelope_recipient\fR,
+/* List of address classes subject to masquerading: zero or
+/* more of \fBenvelope_sender\fR, \fBenvelope_recipient\fR,
/* \fBheader_sender\fR, \fBheader_recipient\fR.
/* .IP \fBmasquerade_domains\fR
/* List of domains that hide their subdomain structure.
/* .IP \fBmasquerade_exceptions\fR
/* List of user names that are not subject to address masquerading.
+/* .IP \fBpropagate_unmatched_extensions\fR
+/* A list of address rewriting or forwarding mechanisms that propagate
+/* an address extension from the original address to the result.
+/* Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+/* \fBforward\fR, or \fBinclude\fR.
/* .IP \fBvirtual_alias_maps\fR
/* Address mapping lookup table for envelope recipient addresses.
/* .SH "Resource controls"
}
return (CLEANUP_ACT_KEEP);
}
- if (*optional_text)
- msg_warn("unexpected text after command in %s map: %s",
- map_class, value);
+ /* Allow and ignore optional text after the action. */
if (STREQUAL(value, "IGNORE", command_len))
return (CLEANUP_ACT_DROP);
- if (STREQUAL(value, "OK", command_len))
+ if (STREQUAL(value, "DUNNO", command_len)) /* preferred */
+ return (CLEANUP_ACT_KEEP);
+
+ if (STREQUAL(value, "OK", command_len)) /* compat */
return (CLEANUP_ACT_KEEP);
msg_warn("unknown command in %s map: %s", map_class, value);
#define DEF_LMTPD_JUNK_CMD 1000
extern int var_lmtpd_junk_cmd_limit;
+#define VAR_SMTPD_SASL_EXCEPTIONS_NETWORKS "smtpd_sasl_exceptions_networks"
+#define DEF_SMTPD_SASL_EXCEPTIONS_NETWORKS ""
+extern char *var_smtpd_sasl_exceptions_networks;
+
/*
* SASL authentication support, LMTP server side.
*/
#define REJECT_RBL "reject_rbl" /* LaMont compatibility */
#define REJECT_RBL_CLIENT "reject_rbl_client"
#define REJECT_RHSBL_CLIENT "reject_rhsbl_client"
+#define REJECT_RHSBL_HELO "reject_rhsbl_helo"
#define REJECT_RHSBL_SENDER "reject_rhsbl_sender"
#define REJECT_RHSBL_RECIPIENT "reject_rhsbl_recipient"
/* A message header contains 8-bit data. This is always illegal.
/* .IP MIME_ERR_8BIT_IN_7BIT_BODY
/* A MIME header specifies (or defaults to) 7-bit content, but the
-/* correspnding message body or body parts contain 8-bit content.
+/* corresponding message body or body parts contain 8-bit content.
/* .IP MIME_ERR_ENCODING_DOMAIN
/* An entity of type "message" or "multipart" specifies the wrong
/* content transfer encoding domain, or specifies a transformation
*/
case 0:
set_ugid(args.uid, args.gid);
- setsid();
+ if (setsid() < 0)
+ msg_warn("setsid failed: %m");
/*
* Pipe plumbing.
event_disable_readwrite(vstream_fileno(state->stream));
vstream_fclose(state->stream);
} else {
+ case EVENT_XCPT:
msg_warn("connect to service: %s: %m", var_cleanup_service);
}
myfree(state->sender);
lmtp_connect.o: ../../include/timed_connect.h
lmtp_connect.o: ../../include/stringops.h
lmtp_connect.o: ../../include/host_port.h
+lmtp_connect.o: ../../include/sane_connect.h
lmtp_connect.o: ../../include/mail_params.h
lmtp_connect.o: ../../include/mail_proto.h
lmtp_connect.o: ../../include/attr.h
lmtp_quit(state);
lmtp_chat_reset(state);
state->session = lmtp_session_free(state->session);
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable)
+ lmtp_sasl_cleanup(state);
+#endif
}
/*
else if (lmtp_rset(state) != 0) {
lmtp_chat_reset(state);
state->session = lmtp_session_free(state->session);
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable)
+ lmtp_sasl_cleanup(state);
+#endif
}
/*
*/
else if (lmtp_lhlo(state) != 0) {
state->session = lmtp_session_free(state->session);
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable)
+ lmtp_sasl_cleanup(state);
+#endif
}
/*
sasl_callback_t *sasl_callbacks; /* stateful callbacks */
#endif
int sndbufsize; /* total window size */
- int sndbuffree; /* remaining window */
int reuse; /* connection being reused */
} LMTP_STATE;
#include <timed_connect.h>
#include <stringops.h>
#include <host_port.h>
+#include <sane_connect.h>
/* Global library. */
non_blocking(sock, BLOCKING);
errno = saved_errno;
} else {
- conn_stat = connect(sock, sa, len);
+ conn_stat = sane_connect(sock, sa, len);
}
if (conn_stat < 0) {
vstring_sprintf(why, "connect to %s[%s]: %m",
if (msg_verbose)
msg_info("server features: 0x%x", state->features);
-#ifdef USE_SASL_AUTH
- if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH))
- return (lmtp_sasl_helo_login(state));
-#endif
-
/*
* We use LMTP command pipelining if the server said it supported it.
* Since we use blocking I/O, RFC 2197 says that we should inspect the
} else
state->sndbufsize = 0;
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable && (state->features & LMTP_FEATURE_AUTH))
+ return (lmtp_sasl_helo_login(state));
+#endif
+
return (0);
}
msg_warn("%s: unknown content encoding: %s",
request->queue_id, request->encoding);
}
+
+ /*
+ * We authenticate the client, not the sender.
+ */
+#ifdef USE_SASL_AUTH
+ if (var_lmtp_sasl_enable
+ && (state->features & LMTP_FEATURE_AUTH)
+ && state->sasl_passwd)
+ vstring_strcat(next_command, " AUTH=<>");
+#endif
next_state = LMTP_STATE_RCPT;
break;
&& sent(DEL_REQ_TRACE_FLAGS(request->flags),
request->queue_id, rcpt->orig_addr,
rcpt->address, session->namaddr,
- request->arrival_time, "%s",
- translit(resp->str, "\n", " ")) == 0) {
+ request->arrival_time, "%s",
+ translit(resp->str, "\n", " ")) == 0) {
if (request->flags & DEL_REQ_FLAG_SUCCESS)
deliver_completed(state->src, rcpt->offset);
rcpt->offset = 0; /* in case deferred */
/*
* Copy the next command to the buffer and update the sender state.
*/
- if (state->sndbuffree > 0)
- state->sndbuffree -= VSTRING_LEN(next_command) + 2;
+ if (sndbuffree > 0)
+ sndbuffree -= VSTRING_LEN(next_command) + 2;
lmtp_chat_cmd(state, "%s", vstring_str(next_command));
send_state = next_state;
send_rcpt = next_rcpt;
/* policy of the SASL authentication.
/*
/* lmtp_sasl_passwd_lookup() looks up the username/password
-/* for the current SMTP server. The result is zero in case
+/* for the current LMTP server. The result is zero in case
/* of failure.
/*
/* lmtp_sasl_authenticate() implements the SASL authentication
/* suceeds.
/*
/* lmtp_sasl_cleanup() cleans up. It must be called at the
-/* end of every SMTP session that uses SASL authentication.
+/* end of every LMTP session that uses SASL authentication.
/* This routine is a noop for non-SASL sessions.
/*
/* Arguments:
lmtp_sasl_connect(state);
#endif
state->sndbufsize = 0;
- state->sndbuffree = 0;
state->reuse = 0;
return (state);
}
/*
/* In order to stop mail forwarding loops early, the software adds an
/* optional
-/* \fBDelivered-To:\fR header with the envelope recipient address. If
+/* \fBDelivered-To:\fR header with the final envelope recipient address. If
/* mail arrives for a recipient that is already listed in a
/* \fBDelivered-To:\fR header, the message is bounced.
/* MAILBOX DELIVERY
/* \fBX-Original-To:\fR header with the recipient address as given to
/* Postfix, prepends an
/* optional \fBDelivered-To:\fR header
-/* with the envelope recipient address, prepends a \fBReturn-Path:\fR
+/* with the final envelope recipient address, prepends a \fBReturn-Path:\fR
/* header with the envelope sender address, prepends a \fB>\fR character
/* to lines beginning with "\fBFrom \fR", and appends an empty line.
/* The mailbox is locked for exclusive access while delivery is in
/* \fBX-Original-To:\fR header with the recipient address as given to
/* Postfix, prepends an
/* optional \fBDelivered-To:\fR
-/* header with the recipient envelope address, prepends a
+/* header with the final recipient envelope address, prepends a
/* \fBReturn-Path:\fR header with the sender envelope address,
/* and appends no empty line.
/* EXTERNAL FILE DELIVERY
/* \fBX-Original-To:\fR header with the recipient address as given to
/* Postfix, prepends an
/* optional \fBDelivered-To:\fR
-/* header with the recipient envelope address, prepends a \fB>\fR
+/* header with the final recipient envelope address, prepends a \fB>\fR
/* character to lines beginning with "\fBFrom \fR", and appends an
/* empty line.
/* The envelope sender address is available in the \fBReturn-Path:\fR
/*
/* In the case of \fBmaildir\fR delivery, the local daemon prepends
/* an optional
-/* \fBDelivered-To:\fR header with the envelope recipient address, and
-/* prepends an
+/* \fBDelivered-To:\fR header with the final envelope recipient address,
+/* and prepends an
/* \fBX-Original-To:\fR header with the recipient address as given to
/* Postfix.
/* The envelope sender address is available in the \fBReturn-Path:\fR
/* undeliverable.
/*
/* In all cases the \fBlocal\fR daemon prepends an optional
-/* `\fBDelivered-To:\fR \fIname\fR+\fIfoo\fR' header line.
+/* `\fBDelivered-To:\fR header line with the final recipient
+/* address.
/* DELIVERY RIGHTS
/* .ad
/* .fi
/* forwarding, delivery to command or file. Specify zero or more of:
/* \fBcommand, file, forward\fR. Turning off \fBDelivered-To:\fR when
/* forwarding mail is not recommended.
+/* .IP \fBpropagate_unmatched_extensions\fR
+/* A list of address rewriting or forwarding mechanisms that propagate
+/* an address extension from the original address to the result.
+/* Specify zero or more of \fBcanonical\fR, \fBvirtual\fR, \fBalias\fR,
+/* \fBforward\fR, or \fBinclude\fR.
/* .IP \fBrecipient_delimiter\fR
/* Separator between username and address extension.
/* .IP \fBrequire_home_directory\fR
/* when creating a new file. Instead, create a new file with default
/* access permissions (mode 0644).
/* .IP "\fB-q \fIkey\fR"
-/* Search the specified maps for \fIkey\fR and print the first value
-/* found on the standard output stream. The exit status is zero
+/* Search the specified maps for \fIkey\fR and write the first value
+/* found to the standard output stream. The exit status is zero
/* when the requested information was found.
/*
/* If a key value of \fB-\fR is specified, the program reads key
-/* values from the standard input stream and prints one line of
+/* values from the standard input stream and writes one line of
/* \fIkey: value\fR output for each key that was found. The exit
/* status is zero when at least one of the requested keys was found.
/* .IP \fB-r\fR
smtp_connect.o: ../../include/timed_connect.h
smtp_connect.o: ../../include/stringops.h
smtp_connect.o: ../../include/host_port.h
+smtp_connect.o: ../../include/sane_connect.h
smtp_connect.o: ../../include/mail_params.h
smtp_connect.o: ../../include/own_inet_addr.h
smtp_connect.o: ../../include/dns.h
#include <timed_connect.h>
#include <stringops.h>
#include <host_port.h>
+#include <sane_connect.h>
/* Global library. */
non_blocking(sock, BLOCKING);
errno = saved_errno;
} else {
- conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
+ conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
}
if (conn_stat < 0) {
vstring_sprintf(why, "connect to %s[%s]: %m",
msg_warn("%s: unknown content encoding: %s",
request->queue_id, request->encoding);
}
+
+ /*
+ * We authenticate the client, not the sender.
+ */
+#ifdef USE_SASL_AUTH
+ if (var_smtp_sasl_enable
+ && (state->features & SMTP_FEATURE_AUTH)
+ && state->sasl_passwd)
+ vstring_strcat(next_command, " AUTH=<>");
+#endif
next_state = SMTP_STATE_RCPT;
break;
/* Disallow non-RFC 821 style addresses in SMTP commands. For example,
/* the RFC822-style address forms with comments that Sendmail allows.
/* .IP \fBbroken_sasl_auth_clients\fR
-/* Support older Microsoft clients that mis-implement the AUTH
+/* Support Microsoft clients that implement an older version of the AUTH
/* protocol, and that expect an EHLO response of "250 AUTH=list"
/* instead of "250 AUTH list".
+/* .IP \fBsmtpd_sasl_exceptions_networks\fR
+/* Don't offer AUTH in the response to EHLO when talking to clients
+/* in the specified networks. This is a workaround for clients that
+/* that demand a login and password from the user whenever AUTH is
+/* offered by an SMTP server.
/* .IP \fBsmtpd_noop_commands\fR
/* List of commands that are treated as NOOP (no operation) commands,
/* without any parameter syntax checking and without any state change.
bool var_smtpd_sasl_enable;
char *var_smtpd_sasl_opts;
char *var_smtpd_sasl_realm;
+char *var_smtpd_sasl_exceptions_networks;
char *var_filter_xport;
bool var_broken_auth_clients;
char *var_perm_mx_networks;
static void rcpt_reset(SMTPD_STATE *);
static void chat_reset(SMTPD_STATE *, int);
+ /*
+ * SASL exceptions.
+ */
+static NAMADR_LIST *sasl_exceptions_networks;
+
+/* sasl_client_exception - can we offer AUTH for this client */
+
+static int sasl_client_exception(SMTPD_STATE *state)
+{
+ int match;
+
+ /*
+ * This is to work around a Netscape mail client bug where it tries to
+ * use AUTH if available, even if user has not configured it. Returns
+ * TRUE if AUTH should be offered in the EHLO.
+ */
+ if (sasl_exceptions_networks == 0)
+ return (0);
+
+ match = namadr_list_match(sasl_exceptions_networks,
+ state->name, state->addr);
+
+ if (msg_verbose)
+ msg_info("sasl_exceptions: %s[%s], match=%d",
+ state->name, state->addr, match);
+
+ return (match);
+}
+
/* collapse_args - put arguments together again */
static void collapse_args(int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "250-VRFY");
smtpd_chat_reply(state, "250-ETRN");
#ifdef USE_SASL_AUTH
- if (var_smtpd_sasl_enable) {
+ if (var_smtpd_sasl_enable && !sasl_client_exception(state)) {
smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
if (var_broken_auth_clients)
smtpd_chat_reply(state, "250-AUTH=%s", state->sasl_mechanism_list);
smtpd_state_init(&state, stream);
msg_info("connect from %s[%s]", state.name, state.addr);
- /*
- * XXX non_blocking() aborts upon error.
- */
-#ifdef BROKEN_READ_SELECT_ON_BLOCKING_SOCKET
- non_blocking(vstream_fileno(stream), NON_BLOCKING);
-#endif
-
/*
* See if we need to turn on verbose logging for this client.
*/
if (var_smtpd_sasl_enable)
#ifdef USE_SASL_AUTH
smtpd_sasl_initialize();
+
+ if (*var_smtpd_sasl_exceptions_networks)
+ sasl_exceptions_networks =
+ namadr_list_init(MATCH_FLAG_NONE,
+ var_smtpd_sasl_exceptions_networks);
#else
msg_warn("%s is true, but SASL support is not compiled in",
VAR_SMTPD_SASL_ENABLE);
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_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,
VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0,
VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, 0, 0,
/* configuration parameter specifies the reject status code used in
/* the default template (default: 554).
/* .IP reject_rhsbl_client rbl.domain.tld
+/* .IP reject_rhsbl_helo rbl.domain.tld
/* .IP reject_rhsbl_sender rbl.domain.tld
/* .IP reject_rhsbl_recipient rbl.domain.tld
-/* Look up the client/sender/recipient domain name in the specified
+/* Look up the client/helo/sender/recipient domain name in the specified
/* real-time blackhole DNS zone. The \fIrbl_reply_maps\fR configuration
/* parameter is used to generate the template for the reject message.
/* If it is not specified, or the rbl domain cannot be found, then a
status = reject_invalid_hostaddr(state, state->helo_name,
state->helo_name, SMTPD_NAME_HELO);
}
+ } else if (strcasecmp(name, REJECT_RHSBL_HELO) == 0) {
+ if (cpp[1] == 0)
+ msg_warn("restriction %s requires domain name argument",
+ name);
+ else {
+ cpp += 1;
+ if (state->helo_name)
+ status = reject_rbl_domain(state, *cpp, state->helo_name,
+ SMTPD_NAME_HELO);
+ }
}
/*
qmqp-source.o: ../../include/events.h
qmqp-source.o: ../../include/find_inet.h
qmqp-source.o: ../../include/netstring.h
+qmqp-source.o: ../../include/sane_connect.h
qmqp-source.o: ../../include/mail_date.h
qmqp-source.o: ../../include/qmqp_proto.h
smtp-sink.o: smtp-sink.c
smtp-sink.o: ../../include/mymalloc.h
smtp-sink.o: ../../include/msg_vstream.h
smtp-sink.o: ../../include/stringops.h
+smtp-sink.o: ../../include/sane_accept.h
smtp-sink.o: ../../include/smtp_stream.h
smtp-source.o: smtp-source.c
smtp-source.o: ../../include/sys_defs.h
smtp-source.o: ../../include/mymalloc.h
smtp-source.o: ../../include/events.h
smtp-source.o: ../../include/find_inet.h
+smtp-source.o: ../../include/sane_connect.h
smtp-source.o: ../../include/smtp_stream.h
smtp-source.o: ../../include/mail_date.h
#include <find_inet.h>
#include <iostuff.h>
#include <netstring.h>
+#include <sane_connect.h>
/* Global library. */
session->stream = vstream_fdopen(fd, O_RDWR);
event_enable_write(fd, connect_done, (char *) session);
netstring_setup(session->stream, var_timeout);
- if (connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
+ if (sane_connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
fail_connect(session);
}
/* This program is the complement of the \fIsmtp-source\fR program.
/*
/* Arguments:
+/* .IP \fB-a\fR
+/* Do not announce SASL authentication support.
/* .IP \fB-c\fR
/* Display a running counter that is updated whenever an SMTP
/* QUIT command is executed.
/* .IP \fB-e\fR
/* Disable ESMTP support.
+/* .IP "\fB-f \fIcommand,command,...\fR"
+/* Reject the specified commands with a hard (5xx) error code.
/* .IP \fB-h\fI hostname\fR
/* Use \fIhostname\fR in the SMTP greeting, in the HELO response,
/* and in the EHLO response. The default hostname is "smtp-sink".
/* .IP \fB-P\fR
/* Change the server greeting so that it appears to come through
/* a CISCO PIX system. Implies \fB-e\fR.
+/* .IP "\fB-r \fIcommand,command,...\fR"
+/* Reject the specified commands with a soft (4xx) error code.
/* .IP "\fB-s \fIcommand,command,...\fR"
/* Log the named commands to syslogd.
/* Examples of commands that can be logged are HELO, EHLO, LHLO, MAIL,
#include <iostuff.h>
#include <msg_vstream.h>
#include <stringops.h>
+#include <sane_accept.h>
/* Global library. */
static int disable_esmtp;
static int enable_lmtp;
static int pretend_pix;
+static int disable_saslauth;
/* ehlo_response - respond to EHLO command */
smtp_printf(state->stream, "250-PIPELINING");
if (!disable_8bitmime)
smtp_printf(state->stream, "250-8BITMIME");
+ if (!disable_saslauth)
+ smtp_printf(state->stream, "250-AUTH PLAIN LOGIN");
smtp_printf(state->stream, "250 ");
smtp_flush(state->stream);
}
static void dot_response(SINK_STATE *state)
{
if (enable_lmtp) {
- while (state->rcpts-- > 0) /* XXX this could block */
- ok_response(state); /* XXX this flushes too often */
+ while (state->rcpts-- > 0) /* XXX this could block */
+ ok_response(state); /* XXX this flushes too often */
} else {
ok_response(state);
}
#define FLAG_ENABLE (1<<0) /* command is enabled */
#define FLAG_SYSLOG (1<<1) /* log the command */
+#define FLAG_HARD_ERR (1<<2) /* report hard error */
+#define FLAG_SOFT_ERR (1<<3) /* report soft error */
static SINK_COMMAND command_table[] = {
"helo", helo_response, 0,
"ehlo", ehlo_response, 0,
"lhlo", ehlo_response, 0,
+ "auth", ok_response, FLAG_ENABLE,
"mail", mail_response, FLAG_ENABLE,
"rcpt", rcpt_response, FLAG_ENABLE,
"data", data_response, FLAG_ENABLE,
smtp_flush(state->stream);
return (0);
}
+ if (cmdp->flags & FLAG_HARD_ERR) {
+ smtp_printf(state->stream, "500 Error: command failed");
+ smtp_flush(state->stream);
+ return (0);
+ }
+ if (cmdp->flags & FLAG_SOFT_ERR) {
+ smtp_printf(state->stream, "450 Error: command failed");
+ smtp_flush(state->stream);
+ return (0);
+ }
/* We use raw syslog. Sanitize data content and length. */
if (cmdp->flags & FLAG_SYSLOG)
syslog(LOG_INFO, "%s %.100s", command, printable(ptr, '?'));
SINK_STATE *state;
int fd;
- if ((fd = accept(sock, &sa, &len)) >= 0) {
+ if ((fd = sane_accept(sock, &sa, &len)) >= 0) {
if (msg_verbose)
msg_info("connect (%s)",
#ifdef AF_LOCAL
/*
* Parse JCL.
*/
- while ((ch = GETOPT(argc, argv, "ceh:Ln:pPs:vw:8")) > 0) {
+ while ((ch = GETOPT(argc, argv, "acef:h:Ln:pPr:s:vw:8")) > 0) {
switch (ch) {
+ case 'a':
+ disable_saslauth = 1;
+ break;
case 'c':
count++;
break;
case 'e':
disable_esmtp = 1;
break;
+ case 'f':
+ set_cmds_flags(optarg, FLAG_HARD_ERR);
+ break;
case 'h':
var_myhostname = optarg;
break;
pretend_pix = 1;
disable_esmtp = 1;
break;
+ case 'r':
+ set_cmds_flags(optarg, FLAG_SOFT_ERR);
+ break;
case 's':
openlog(basename(argv[0]), LOG_PID, LOG_MAIL);
set_cmds_flags(optarg, FLAG_SYSLOG);
#include <events.h>
#include <find_inet.h>
#include <iostuff.h>
+#include <sane_connect.h>
/* Global library. */
session->stream = vstream_fdopen(fd, O_RDWR);
event_enable_write(fd, connect_done, (char *) session);
smtp_timeout_setup(session->stream, var_timeout);
- if (connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
+ if (sane_connect(fd, sa, sa_length) < 0 && errno != EINPROGRESS)
fail_connect(session);
}
#include <stdlib.h>
#include <string.h>
+#ifdef STRCASECMP_IN_STRINGS_H
+#include <strings.h>
+#endif
+
/* Utility library. */
#include <msg.h>
msg_warn("do not list domain %s in BOTH %s and %s",
rcpt_domain, VAR_VIRT_ALIAS_DOMS,
VAR_RELAY_DOMAINS);
+ if (strcasecmp(rcpt_domain, var_myorigin) == 0)
+ msg_warn("do not list $%s in %s",
+ VAR_MYORIGIN, VAR_VIRT_ALIAS_DOMS);
}
vstring_strcpy(channel, MAIL_SERVICE_ERROR);
vstring_sprintf(nexthop, "User unknown%s",
username.c valid_hostname.c vbuf.c vbuf_print.c vstream.c \
vstream_popen.c vstring.c vstring_vstream.c watchdog.c writable.c \
write_buf.c write_wait.c auto_clnt.c attr_clnt.c attr_scan_plain.c \
- attr_print_plain.c
+ attr_print_plain.c sane_connect.c
OBJS = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
username.o valid_hostname.o vbuf.o vbuf_print.o vstream.o \
vstream_popen.o vstring.o vstring_vstream.o watchdog.o writable.o \
write_buf.o write_wait.o auto_clnt.o attr_clnt.o attr_scan_plain.o \
- attr_print_plain.o $(STRCASE)
+ attr_print_plain.o sane_connect.o $(STRCASE)
HDRS = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
dict_cidr.h dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \
timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \
vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h \
- auto_clnt.h attr_clnt.h
+ auto_clnt.h attr_clnt.h sane_connect.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
inet_connect.o: find_inet.h
inet_connect.o: inet_util.h
inet_connect.o: iostuff.h
+inet_connect.o: sane_connect.h
inet_connect.o: connect.h
inet_connect.o: timed_connect.h
inet_listen.o: inet_listen.c
msg_syslog.o: msg.h
msg_syslog.o: msg_output.h
msg_syslog.o: msg_syslog.h
+msg_syslog.o: safe.h
msg_vstream.o: msg_vstream.c
msg_vstream.o: sys_defs.h
msg_vstream.o: vstream.h
sane_accept.o: sys_defs.h
sane_accept.o: msg.h
sane_accept.o: sane_accept.h
+sane_connect.o: sane_connect.c
+sane_connect.o: sys_defs.h
+sane_connect.o: msg.h
+sane_connect.o: sane_connect.h
sane_link.o: sane_link.c
sane_link.o: sys_defs.h
sane_link.o: msg.h
timed_connect.o: sys_defs.h
timed_connect.o: msg.h
timed_connect.o: iostuff.h
+timed_connect.o: sane_connect.h
timed_connect.o: timed_connect.h
timed_read.o: timed_read.c
timed_read.o: sys_defs.h
+timed_read.o: msg.h
timed_read.o: iostuff.h
timed_wait.o: timed_wait.c
timed_wait.o: sys_defs.h
timed_wait.o: timed_wait.h
timed_write.o: timed_write.c
timed_write.o: sys_defs.h
+timed_write.o: msg.h
timed_write.o: iostuff.h
translit.o: translit.c
translit.o: sys_defs.h
unix_connect.o: sys_defs.h
unix_connect.o: msg.h
unix_connect.o: iostuff.h
+unix_connect.o: sane_connect.h
unix_connect.o: connect.h
unix_connect.o: timed_connect.h
unix_listen.o: unix_listen.c
/* clean_env() reduces the process environment to the bare minimum.
/* The function takes a null-terminated list of arguments.
/* Each argument specifies the name of an environment variable
-/* that should be preserved.
+/* that should be preserved, or specifies a name=value that should
+/* be entered into the new environment.
/* DIAGNOSTICS
/* Fatal error: out of memory.
/* SEE ALSO
#include <sys_defs.h>
#include <stdlib.h>
#include <unistd.h>
+#include <string.h>
/* Utility library. */
ARGV *save_list;
char *value;
char **cpp;
+ char *eq;
/*
- * Preserve selected environment variables.
+ * Preserve or specify selected environment variables.
*/
+#define STRING_AND_LENGTH(x, y) (x), (y)
+
save_list = argv_alloc(10);
for (cpp = preserve_list; *cpp; cpp++)
- if ((value = safe_getenv(*cpp)) != 0)
+ if ((eq = strchr(*cpp, '=')) != 0)
+ argv_addn(save_list, STRING_AND_LENGTH(*cpp, eq - *cpp),
+ STRING_AND_LENGTH(eq + 1, strlen(eq + 1)), (char *) 0);
+ else if ((value = safe_getenv(*cpp)) != 0)
argv_add(save_list, *cpp, value, (char *) 0);
- argv_terminate(save_list);
/*
* Truncate the process environment, if available. On some systems
*/
for (cpp = save_list->argv; *cpp; cpp += 2)
if (setenv(cpp[0], cpp[1], 1))
- msg_fatal("setenv: %m");
+ msg_fatal("setenv(%s, %s): %m", cpp[0], cpp[1]);
/*
* Cleanup.
/*
/* Arguments:
/* .IP ldapsource
-/* The prefix which will be used to obtain configuration parameters
-/* for this search. If it's 'ldapone', the configuration variables below
-/* would look like 'ldapone_server_host', 'ldapone_search_base', and so
-/* on in main.cf.
+/* Either the path to the LDAP configuration file (if it starts
+/* with '/' or '.'), or the prefix which will be used to obtain
+/* configuration parameters for this search.
+/*
+/* In the first case, the configuration variables below are
+/* specified in the file as \fBname\fR=\fBvalue\fR pairs.
+/*
+/* In the second case, the configuration variables are prefixed
+/* with the value of \fIldapsource\fR and an underscore,
+/* and they are specified in main.cf. For example, if this
+/* value is \fBldapone\fR, the variables would look like
+/* \fBldapone_server_host\fR, \fBldapone_search_base\fR, and so on.
/* .IP dummy
/* Not used; this argument exists only for compatibility with
/* the dict_open(3) interface.
/* .PP
/* Configuration parameters:
-/* .IP \fIldapsource_\fRserver_host
-/* The host at which all LDAP queries are directed.
-/* .IP \fIldapsource_\fRserver_port
+/* .IP server_host
+/* Blank-separated list of hosts at which all LDAP queries are directed.
+/* The host names can also be LDAP URLs if the LDAP client library used
+/* is OpenLDAP.
+/* .IP server_port
/* The port the LDAP server listens on.
-/* .IP \fIldapsource_\fRsearch_base
+/* .IP search_base
/* The LDAP search base, for example: \fIO=organization name, C=country\fR.
-/* .IP \fIldapsource_\fRdomain
+/* .IP domain
/* If specified, only lookups ending in this value will be queried.
/* This can significantly reduce the query load on the LDAP server.
-/* .IP \fIldapsource_\fRtimeout
+/* .IP timeout
/* Deadline for LDAP open() and LDAP search() .
-/* .IP \fIldapsource_\fRquery_filter
+/* .IP query_filter
/* The filter used to search for directory entries, for example
/* \fI(mailacceptinggeneralid=%s)\fR.
-/* .IP \fIldapsource_\fRresult_filter
+/* .IP result_filter
/* The filter used to expand results from queries. Default is
/* \fI%s\fR.
-/* .IP \fIldapsource_\fRresult_attribute
+/* .IP result_attribute
/* The attribute(s) returned by the search, in which to find
/* RFC822 addresses, for example \fImaildrop\fR.
-/* .IP \fIldapsource_\fRspecial_result_attribute
+/* .IP special_result_attribute
/* The attribute(s) of directory entries that can contain DNs or URLs.
/* If found, a recursive subsequent search is done using their values.
-/* .IP \fIldapsource_\fRscope
+/* .IP scope
/* LDAP search scope: sub, base, or one.
-/* .IP \fIldapsource_\fRbind
+/* .IP bind
/* Whether or not to bind to the server -- LDAP v3 implementations don't
/* require it, which saves some overhead.
-/* .IP \fIldapsource_\fRbind_dn
+/* .IP bind_dn
/* If you must bind to the server, do it with this distinguished name ...
-/* .IP \fIldapsource_\fRbind_pw
+/* .IP bind_pw
/* \&... and this password.
-/* .IP \fIldapsource_\fRcache (no longer supported)
+/* .IP cache (no longer supported)
/* Whether or not to turn on client-side caching.
-/* .IP \fIldapsource_\fRcache_expiry (no longer supported)
+/* .IP cache_expiry (no longer supported)
/* If you do cache results, expire them after this many seconds.
-/* .IP \fIldapsource_\fRcache_size (no longer supported)
+/* .IP cache_size (no longer supported)
/* The cache size in bytes. Does nothing if the cache is off, of course.
-/* .IP \fIldapsource_\fRrecursion_limit
+/* .IP recursion_limit
/* Maximum recursion depth when expanding DN or URL references.
/* Queries which exceed the recursion limit fail with
/* dict_errno = DICT_ERR_RETRY.
-/* .IP \fIldapsource_\fRexpansion_limit
+/* .IP expansion_limit
/* Limit (if any) on the total number of lookup result values. Lookups which
/* exceed the limit fail with dict_errno=DICT_ERR_RETRY. Note that
/* each value of a multivalued result attribute counts as one result.
-/* .IP \fIldapsource_\fRsize_limit
+/* .IP size_limit
/* Limit on the number of entries returned by individual LDAP queries.
/* Queries which exceed the limit fail with dict_errno=DICT_ERR_RETRY.
/* This is an *entry* count, for any single query performed during the
/* possibly recursive lookup.
-/* .IP \fIldapsource_\fRchase_referrals
+/* .IP chase_referrals
/* Controls whether LDAP referrals are obeyed.
-/* .IP \fIldapsource_\fRdereference
+/* .IP dereference
/* How to handle LDAP aliases. See ldap.h or ldap_open(3) man page.
-/* .IP \fIldapsource_\fRdebuglevel
+/* .IP version
+/* Specifies the LDAP protocol version to use. Default is version
+/* \fI2\fR.
+/* .IP start_tls
+/* Whether or not to issue STARTTLS upon connection to the server.
+/* At this time, STARTTLS and LDAP SSL are only available if the
+/* LDAP client library used is OpenLDAP. Default is \fIno\fR.
+/* .IP tls_ca_cert_file
+/* File containing certificates for all of the X509 Certificate
+/* Authorities the client will recognize. Takes precedence over
+/* tls_ca_cert_dir.
+/* .IP tls_ca_cert_dir
+/* Directory containing X509 Certificate Authority certificates
+/* in separate individual files.
+/* .IP tls_cert
+/* File containing client's X509 certificate.
+/* .IP tls_key
+/* File containing the private key corresponding to
+/* tls_cert.
+/* .IP tls_require_cert
+/* Whether or not to request server's X509 certificate and check its
+/* validity.
+/* .IP tls_random_file
+/* Path of a file to obtain random bits from when /dev/[u]random is
+/* not available. Generally set to the name of the EGD/PRNGD socket.
+/* .IP tls_cipher_suite
+/* Cipher suite to use in SSL/TLS negotiations.
+/* .IP debuglevel
/* Debug level. See 'loglevel' option in slapd.conf(5) man page.
/* Currently only in openldap libraries (and derivatives).
/* SEE ALSO
#include "vstring.h"
#include "dict.h"
#include "dict_ldap.h"
+#include "stringops.h"
/* AAARGH!! */
int chase_referrals;
int debuglevel;
int version;
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+ int ldap_ssl;
+ int start_tls;
+ int tls_require_cert;
+ char *tls_ca_cert_file;
+ char *tls_ca_cert_dir;
+ char *tls_cert;
+ char *tls_key;
+ char *tls_random_file;
+ char *tls_cipher_suite;
+#endif
LDAP *ld;
} DICT_LDAP;
-#ifndef LDAP_OPT_NETWORK_TIMEOUT
+typedef struct {
+ char *(*get_str) (const char *, const char *, const char *, int, int);
+ int (*get_int) (const char *, const char *, int, int, int);
+ int (*get_bool) (const char *, const char *, int);
+} CFG_PARSER;
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) || !defined(LDAP_OPT_NETWORK_TIMEOUT)
/*
* LDAP connection timeout support.
*/
}
+static char *dict_ldap_get_dict_str(const char *opt_dict_name,
+ const char *name, const char *defval,
+ int min, int max)
+{
+ const char *strval;
+ int len;
+
+ if ((strval = (char *) dict_lookup(opt_dict_name, name)) == 0)
+ strval = defval;
+
+ len = strlen(strval);
+ if (min && len < min)
+ msg_fatal("%s: bad string length %d < %d: %s = %s",
+ opt_dict_name, len, min, name, strval);
+ if (max && len > max)
+ msg_fatal("%s: bad string length %d > %d: %s = %s",
+ opt_dict_name, len, max, name, strval);
+ return (mystrdup(strval));
+}
+
+static char *dict_ldap_get_mail_str(const char *opt_dict_name,
+ const char *name, const char *defval,
+ int min, int max)
+{
+ static VSTRING *buf = 0;
+
+ if (buf == 0)
+ buf = vstring_alloc(15);
+ vstring_sprintf(buf, "%s_%s", opt_dict_name, name);
+ return ((char *) get_mail_conf_str(vstring_str(buf),
+ defval, min, max));
+}
+
+static int dict_ldap_get_dict_int(const char *opt_dict_name,
+ const char *name, int defval, int min, int max)
+{
+ const char *strval;
+ int intval;
+ char junk;
+
+ if ((strval = (char *) dict_lookup(opt_dict_name, name)) != 0) {
+ if (sscanf(strval, "%d%c", &intval, &junk) != 1)
+ msg_fatal("%s: bad numerical configuration: %s = %s",
+ opt_dict_name, name, strval);
+ } else
+ intval = defval;
+ if (min && intval < min)
+ msg_fatal("%s: invalid %s parameter value %d < %d",
+ opt_dict_name, name, intval, min);
+ if (max && intval > max)
+ msg_fatal("%s: invalid %s parameter value %d > %d",
+ opt_dict_name, name, intval, max);
+ return (intval);
+}
+
+static int dict_ldap_get_mail_int(const char *opt_dict_name,
+ const char *name, int defval, int min, int max)
+{
+ static VSTRING *buf = 0;
+
+ if (buf == 0)
+ buf = vstring_alloc(15);
+ vstring_sprintf(buf, "%s_%s", opt_dict_name, name);
+ return (get_mail_conf_int(vstring_str(buf), defval, min, max));
+}
+
+static int dict_ldap_get_dict_bool(const char *opt_dict_name,
+ const char *name, int defval)
+{
+ const char *strval;
+ int intval;
+
+ if ((strval = (char *) dict_lookup(opt_dict_name, name)) != 0) {
+ if (strcasecmp(strval, CONFIG_BOOL_YES) == 0) {
+ intval = 1;
+ } else if (strcasecmp(strval, CONFIG_BOOL_NO) == 0) {
+ intval = 0;
+ } else {
+ msg_fatal("%s: bad boolean configuration: %s = %s",
+ opt_dict_name, name, strval);
+ }
+ } else
+ intval = defval;
+ return (intval);
+}
+
+static int dict_ldap_get_mail_bool(const char *opt_dict_name,
+ const char *name, int defval)
+{
+ static VSTRING *buf = 0;
+
+ if (buf == 0)
+ buf = vstring_alloc(15);
+ vstring_sprintf(buf, "%s_%s", opt_dict_name, name);
+ return (get_mail_conf_bool(vstring_str(buf), defval));
+}
+
+
static int dict_ldap_get_errno(LDAP * ld)
{
int rc;
return (ldap_result2error(dict_ldap->ld, res, 1));
}
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+static void dict_ldap_set_tls_options(DICT_LDAP *dict_ldap)
+{
+ char *myname = "dict_ldap_set_tls_options";
+ int rc;
+
+ if (dict_ldap->start_tls || dict_ldap->ldap_ssl) {
+ if (*dict_ldap->tls_random_file) {
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_RANDOM_FILE,
+ dict_ldap->tls_random_file)) != LDAP_SUCCESS)
+ msg_warn("%s: Unable to set tls_random_file to %s: %d: %s",
+ myname, dict_ldap->tls_random_file,
+ rc, ldap_err2string(rc));
+ }
+ if (*dict_ldap->tls_ca_cert_file) {
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTFILE,
+ dict_ldap->tls_ca_cert_file)) != LDAP_SUCCESS)
+ msg_warn("%s: Unable to set tls_ca_cert_file to %s: %d: %s",
+ myname, dict_ldap->tls_ca_cert_file,
+ rc, ldap_err2string(rc));
+ }
+ if (*dict_ldap->tls_ca_cert_dir) {
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CACERTDIR,
+ dict_ldap->tls_ca_cert_dir)) != LDAP_SUCCESS)
+ msg_warn("%s: Unable to set tls_ca_cert_dir to %s: %d: %s",
+ myname, dict_ldap->tls_ca_cert_dir,
+ rc, ldap_err2string(rc));
+ }
+ if (*dict_ldap->tls_cert) {
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CERTFILE,
+ dict_ldap->tls_cert)) != LDAP_SUCCESS)
+ msg_warn("%s: Unable to set tls_cert to %s: %d: %s",
+ myname, dict_ldap->tls_cert,
+ rc, ldap_err2string(rc));
+ }
+ if (*dict_ldap->tls_key) {
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_KEYFILE,
+ dict_ldap->tls_key)) != LDAP_SUCCESS)
+ msg_warn("%s: Unable to set tls_key to %s: %d: %s",
+ myname, dict_ldap->tls_key,
+ rc, ldap_err2string(rc));
+ }
+ if (*dict_ldap->tls_cipher_suite) {
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_CIPHER_SUITE,
+ dict_ldap->tls_cipher_suite)) != LDAP_SUCCESS)
+ msg_warn("%s: Unable to set tls_cipher_suite to %s: %d: %s",
+ myname, dict_ldap->tls_cipher_suite,
+ rc, ldap_err2string(rc));
+ }
+ if (dict_ldap->tls_require_cert) {
+ if ((rc = ldap_set_option(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT,
+ &(dict_ldap->tls_require_cert))) != LDAP_SUCCESS)
+ msg_warn("%s: Unable to set tls_require_cert to %d: %d: %s",
+ myname, dict_ldap->tls_require_cert,
+ rc, ldap_err2string(rc));
+ }
+ }
+}
+
+#endif
+
/* Establish a connection to the LDAP server. */
static int dict_ldap_connect(DICT_LDAP *dict_ldap)
{
#ifdef LDAP_OPT_NETWORK_TIMEOUT
struct timeval mytimeval;
-#else
+#endif
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) || !defined(LDAP_OPT_NETWORK_TIMEOUT)
void (*saved_alarm) (int);
#endif
dict_ldap->server_host);
#ifdef LDAP_OPT_NETWORK_TIMEOUT
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+ dict_ldap_set_tls_options(dict_ldap);
+ ldap_initialize(&(dict_ldap->ld), dict_ldap->server_host);
+#else
dict_ldap->ld = ldap_init(dict_ldap->server_host,
(int) dict_ldap->server_port);
+#endif
if (dict_ldap->ld == NULL) {
msg_warn("%s: Unable to init LDAP server %s",
myname, dict_ldap->server_host);
&dict_ldap->version) != LDAP_OPT_SUCCESS)
msg_warn("%s: Unable to get LDAP protocol version", myname);
else
- msg_warn("%s: Actual Protocol version used is %d.",
+ msg_info("%s: Actual Protocol version used is %d.",
myname, dict_ldap->version);
}
#endif
}
#endif
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+ if (dict_ldap->start_tls) {
+ if ((saved_alarm = signal(SIGALRM, dict_ldap_timeout)) == SIG_ERR) {
+ msg_warn("%s: Error setting signal handler for STARTTLS timeout: %m",
+ myname);
+ dict_errno = DICT_ERR_RETRY;
+ return (-1);
+ }
+ alarm(dict_ldap->timeout);
+ if (setjmp(env) == 0)
+ rc = ldap_start_tls_s(dict_ldap->ld, NULL, NULL);
+ else
+ rc = LDAP_TIMEOUT;
+ alarm(0);
+
+ if (signal(SIGALRM, saved_alarm) == SIG_ERR) {
+ msg_warn("%s: Error resetting signal handler after STARTTLS: %m",
+ myname);
+ dict_errno = DICT_ERR_RETRY;
+ return (-1);
+ }
+ if (rc != LDAP_SUCCESS) {
+ msg_error("%s: Unable to set STARTTLS: %d: %s", myname,
+ rc, ldap_err2string(rc));
+ dict_errno = DICT_ERR_RETRY;
+ return (-1);
+ }
+ }
+#endif
+
/*
* If this server requires a bind, do so. Thanks to Sam Tardieu for
* noticing that the original bind call was broken.
argv_free(dict_ldap->result_attributes);
myfree(dict_ldap->bind_dn);
myfree(dict_ldap->bind_pw);
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+ myfree(dict_ldap->tls_ca_cert_file);
+ myfree(dict_ldap->tls_ca_cert_dir);
+ myfree(dict_ldap->tls_cert);
+ myfree(dict_ldap->tls_key);
+ myfree(dict_ldap->tls_random_file);
+ myfree(dict_ldap->tls_cipher_suite);
+#endif
dict_free(dict);
}
{
char *myname = "dict_ldap_open";
DICT_LDAP *dict_ldap;
- VSTRING *config_param;
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT)
+ VSTRING *url_list;
+ char *s,
+ *h;
+
+#endif
+ char *server_host;
+ CFG_PARSER parser;
char *domainlist;
char *scope;
char *attr;
dict_ldap->dict.close = dict_ldap_close;
dict_ldap->dict.flags = dict_flags | DICT_FLAG_FIXED;
+ dict_ldap->ld = NULL;
dict_ldap->ldapsource = mystrdup(ldapsource);
- config_param = vstring_alloc(15);
- vstring_sprintf(config_param, "%s_server_host", ldapsource);
+ if (ldapsource[0] == '/' || ldapsource[0] == '.') {
+ dict_load_file(ldapsource, ldapsource);
+ parser.get_str = dict_ldap_get_dict_str;
+ parser.get_int = dict_ldap_get_dict_int;
+ parser.get_bool = dict_ldap_get_dict_bool;
+ } else {
+
+ /*
+ * msg_warn("Defining LDAP attributes in main.cf is deprecated. Use
+ * ldap:/path/to/file instead");
+ */
+ parser.get_str = dict_ldap_get_mail_str;
+ parser.get_int = dict_ldap_get_mail_int;
+ parser.get_bool = dict_ldap_get_mail_bool;
+ }
- dict_ldap->server_host =
- mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
- "localhost", 0, 0));
+ server_host = parser.get_str(ldapsource, "server_host",
+ "localhost", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param),
- dict_ldap->server_host);
+ msg_info("%s: %s server_host is %s", myname, ldapsource,
+ server_host);
/*
- * get configured value of "ldapsource_server_port"; default to LDAP_PORT
- * (389)
+ * get configured value of "server_port"; default to LDAP_PORT (389)
*/
- vstring_sprintf(config_param, "%s_server_port", ldapsource);
dict_ldap->server_port =
- get_mail_conf_int(vstring_str(config_param), LDAP_PORT, 0, 0);
+ parser.get_int(ldapsource, "server_port", LDAP_PORT, 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %d", myname, vstring_str(config_param),
+ msg_info("%s: %s server_port is %d", myname, ldapsource,
dict_ldap->server_port);
+ /*
+ * Define LDAP Version.
+ */
+ dict_ldap->version = parser.get_int(ldapsource, "version", 2, 0, 0);
+ switch (dict_ldap->version) {
+ case 2:
+ dict_ldap->version = LDAP_VERSION2;
+ break;
+ case 3:
+ dict_ldap->version = LDAP_VERSION3;
+ break;
+ default:
+ msg_warn("%s: %s Unknown version %d.", myname, ldapsource,
+ dict_ldap->version);
+ dict_ldap->version = LDAP_VERSION2;
+ }
+
+#if defined(LDAP_API_FEATURE_X_OPENLDAP) && defined(LDAP_OPT_NETWORK_TIMEOUT)
+
+ /*
+ * Convert (host, port) pairs to LDAP URLs
+ */
+ url_list = vstring_alloc(32);
+ s = server_host;
+ dict_ldap->ldap_ssl = 0;
+ while ((h = mystrtok(&s, " \t")) != NULL) {
+ if (ldap_is_ldap_url(h)) {
+ LDAPURLDesc *url_desc;
+ int rc;
+
+ if ((rc = ldap_url_parse(h, &url_desc)) != 0) {
+ msg_error("%s: error parsing URL %s: %d: %s; skipping", myname,
+ h, rc, ldap_err2string(rc));
+ continue;
+ }
+ if (strcasecmp(url_desc->lud_scheme, "ldap") != 0 &&
+ dict_ldap->version != LDAP_VERSION3) {
+ msg_warn("%s: URL scheme %s requires protocol version 3", myname,
+ url_desc->lud_scheme);
+ dict_ldap->version = LDAP_VERSION3;
+ }
+ if (strcasecmp(url_desc->lud_scheme, "ldaps") == 0)
+ dict_ldap->ldap_ssl = 1;
+ ldap_free_urldesc(url_desc);
+ vstring_sprintf_append(url_list, " %s", h);
+ } else {
+ if (strrchr(h, ':'))
+ vstring_sprintf_append(url_list, " ldap://%s", h);
+ else
+ vstring_sprintf_append(url_list, " ldap://%s:%d", h,
+ dict_ldap->server_port);
+ }
+ }
+ dict_ldap->server_host = mystrdup(vstring_str(url_list) + 1);
+ if (msg_verbose)
+ msg_info("%s: %s server_host URL is %s", myname, ldapsource,
+ dict_ldap->server_host);
+ myfree(server_host);
+ vstring_free(url_list);
+#else
+ dict_ldap->server_host = server_host;
+#endif
+
/*
* Scope handling thanks to Carsten Hoeger of SuSE.
*/
- vstring_sprintf(config_param, "%s_scope", ldapsource);
- scope =
- (char *) get_mail_conf_str(vstring_str(config_param), "sub", 0, 0);
+ scope = parser.get_str(ldapsource, "scope", "sub", 0, 0);
if (strcasecmp(scope, "one") == 0) {
dict_ldap->scope = LDAP_SCOPE_ONELEVEL;
if (msg_verbose)
- msg_info("%s: %s is LDAP_SCOPE_ONELEVEL", myname,
- vstring_str(config_param));
+ msg_info("%s: %s scope is LDAP_SCOPE_ONELEVEL", myname, ldapsource);
} else if (strcasecmp(scope, "base") == 0) {
dict_ldap->scope = LDAP_SCOPE_BASE;
if (msg_verbose)
- msg_info("%s: %s is LDAP_SCOPE_BASE", myname,
- vstring_str(config_param));
+ msg_info("%s: %s scope is LDAP_SCOPE_BASE", myname, ldapsource);
} else {
dict_ldap->scope = LDAP_SCOPE_SUBTREE;
if (msg_verbose)
- msg_info("%s: %s is LDAP_SCOPE_SUBTREE", myname,
- vstring_str(config_param));
+ msg_info("%s: %s scope is LDAP_SCOPE_SUBTREE", myname, ldapsource);
}
myfree(scope);
- vstring_sprintf(config_param, "%s_search_base", ldapsource);
- dict_ldap->search_base = mystrdup((char *)
- get_mail_conf_str(vstring_str
- (config_param), "",
- 0, 0));
+ dict_ldap->search_base = parser.get_str(ldapsource, "search_base",
+ "", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param),
+ msg_info("%s: %s search_base is %s", myname, ldapsource,
dict_ldap->search_base);
- vstring_sprintf(config_param, "%s_domain", ldapsource);
- domainlist =
- mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
- "", 0, 0));
+ domainlist = parser.get_str(ldapsource, "domain", "", 0, 0);
if (*domainlist) {
#ifdef MATCH_FLAG_NONE
dict_ldap->domain = match_list_init(MATCH_FLAG_NONE,
myfree(domainlist);
/*
- * get configured value of "ldapsource_timeout"; default to 10 seconds
+ * get configured value of "timeout"; default to 10 seconds
*
* Thanks to Manuel Guesdon for spotting that this wasn't really getting
* set.
*/
- vstring_sprintf(config_param, "%s_timeout", ldapsource);
dict_ldap->timeout =
- get_mail_conf_int(vstring_str(config_param), 10, 0, 0);
+ parser.get_int(ldapsource, "timeout", 10, 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %d", myname, vstring_str(config_param),
+ msg_info("%s: %s timeout is %d", myname, ldapsource,
dict_ldap->timeout);
- vstring_sprintf(config_param, "%s_query_filter", ldapsource);
dict_ldap->query_filter =
- mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
- "(mailacceptinggeneralid=%s)",
- 0, 0));
+ parser.get_str(ldapsource, "query_filter",
+ "(mailacceptinggeneralid=%s)", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param),
+ msg_info("%s: %s query_filter is %s", myname, ldapsource,
dict_ldap->query_filter);
- vstring_sprintf(config_param, "%s_result_filter", ldapsource);
dict_ldap->result_filter =
- mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
- "%s",
- 0, 0));
+ parser.get_str(ldapsource, "result_filter", "%s", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param),
+ msg_info("%s: %s result_filter is %s", myname, ldapsource,
dict_ldap->result_filter);
if (strcmp(dict_ldap->result_filter, "%s") == 0) {
myfree(dict_ldap->result_filter);
dict_ldap->result_filter = NULL;
}
- vstring_sprintf(config_param, "%s_result_attribute", ldapsource);
- attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
- "maildrop", 0, 0));
+ attr = parser.get_str(ldapsource, "result_attribute", "maildrop", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);;
+ msg_info("%s: %s result_attribute is %s", myname, ldapsource, attr);;
dict_ldap->result_attributes = argv_split(attr, " ,\t\r\n");
dict_ldap->num_attributes = dict_ldap->result_attributes->argc;
+ myfree(attr);
- vstring_sprintf(config_param, "%s_special_result_attribute", ldapsource);
- attr = mystrdup((char *) get_mail_conf_str(vstring_str(config_param),
- "", 0, 0));
+ attr = parser.get_str(ldapsource, "special_result_attribute", "", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param), attr);
-
+ msg_info("%s: %s special_result_attribute is %s", myname, ldapsource,
+ attr);
if (*attr) {
argv_split_append(dict_ldap->result_attributes, attr, " ,\t\r\n");
}
+ myfree(attr);
/*
- * get configured value of "ldapsource_bind"; default to true
+ * get configured value of "bind"; default to true
*/
- vstring_sprintf(config_param, "%s_bind", ldapsource);
- dict_ldap->bind = get_mail_conf_bool(vstring_str(config_param), 1);
+ dict_ldap->bind = parser.get_bool(ldapsource, "bind", 1);
if (msg_verbose)
- msg_info("%s: %s is %d", myname, vstring_str(config_param),
- dict_ldap->bind);
+ msg_info("%s: %s bind is %d", myname, ldapsource, dict_ldap->bind);
/*
- * get configured value of "ldapsource_bind_dn"; default to ""
+ * get configured value of "bind_dn"; default to ""
*/
- vstring_sprintf(config_param, "%s_bind_dn", ldapsource);
- dict_ldap->bind_dn = mystrdup((char *)
- get_mail_conf_str(vstring_str
- (config_param), "", 0,
- 0));
+ dict_ldap->bind_dn = parser.get_str(ldapsource, "bind_dn", "", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param),
+ msg_info("%s: %s bind_dn is %s", myname, ldapsource,
dict_ldap->bind_dn);
/*
- * get configured value of "ldapsource_bind_pw"; default to ""
+ * get configured value of "bind_pw"; default to ""
*/
- vstring_sprintf(config_param, "%s_bind_pw", ldapsource);
- dict_ldap->bind_pw = mystrdup((char *)
- get_mail_conf_str(vstring_str
- (config_param), "", 0,
- 0));
+ dict_ldap->bind_pw = parser.get_str(ldapsource, "bind_pw", "", 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %s", myname, vstring_str(config_param),
+ msg_info("%s: %s bind_pw is %s", myname, ldapsource,
dict_ldap->bind_pw);
/*
- * get configured value of "ldapsource_cache"; default to false
+ * get configured value of "cache"; default to false
*/
- vstring_sprintf(config_param, "%s_cache", ldapsource);
- tmp = get_mail_conf_bool(vstring_str(config_param), 0);
+ tmp = parser.get_bool(ldapsource, "cache", 0);
if (tmp)
- msg_warn("%s: ignoring %s", myname, vstring_str(config_param));
+ msg_warn("%s: %s ignoring cache", myname, ldapsource);
/*
- * get configured value of "ldapsource_cache_expiry"; default to 30
- * seconds
+ * get configured value of "cache_expiry"; default to 30 seconds
*/
- vstring_sprintf(config_param, "%s_cache_expiry", ldapsource);
- tmp = get_mail_conf_int(vstring_str(config_param), -1, 0, 0);
+ tmp = parser.get_int(ldapsource, "cache_expiry", -1, 0, 0);
if (tmp >= 0)
- msg_warn("%s: ignoring %s", myname, vstring_str(config_param));
+ msg_warn("%s: %s ignoring cache_expiry", myname, ldapsource);
/*
- * get configured value of "ldapsource_cache_size"; default to 32k
+ * get configured value of "cache_size"; default to 32k
*/
- vstring_sprintf(config_param, "%s_cache_size", ldapsource);
- tmp = get_mail_conf_int(vstring_str(config_param), -1, 0, 0);
+ tmp = parser.get_int(ldapsource, "cache_size", -1, 0, 0);
if (tmp >= 0)
- msg_warn("%s: ignoring %s", myname, vstring_str(config_param));
+ msg_warn("%s: %s ignoring cache_size", myname, ldapsource);
/*
- * get configured value of "ldapsource_recursion_limit"; default to 1000
+ * get configured value of "recursion_limit"; default to 1000
*/
- vstring_sprintf(config_param, "%s_recursion_limit", ldapsource);
- dict_ldap->recursion_limit = get_mail_conf_int(vstring_str(config_param),
- 1000, 1, 0);
+ dict_ldap->recursion_limit = parser.get_int(ldapsource, "recursion_limit",
+ 1000, 1, 0);
if (msg_verbose)
- msg_info("%s: %s is %ld", myname, vstring_str(config_param),
+ msg_info("%s: %s recursion_limit is %ld", myname, ldapsource,
dict_ldap->recursion_limit);
/*
- * get configured value of "ldapsource_expansion_limit"; default to 1000
+ * get configured value of "expansion_limit"; default to 0
*/
- vstring_sprintf(config_param, "%s_expansion_limit", ldapsource);
- dict_ldap->expansion_limit = get_mail_conf_int(vstring_str(config_param),
- 0, 0, 0);
+ dict_ldap->expansion_limit = parser.get_int(ldapsource, "expansion_limit",
+ 0, 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %ld", myname, vstring_str(config_param),
+ msg_info("%s: %s expansion_limit is %ld", myname, ldapsource,
dict_ldap->expansion_limit);
/*
- * get configured value of "ldapsource_size_limit"; default to
- * expansion_limit
+ * get configured value of "size_limit"; default to expansion_limit
*/
- vstring_sprintf(config_param, "%s_size_limit", ldapsource);
- dict_ldap->size_limit = get_mail_conf_int(vstring_str(config_param),
- dict_ldap->expansion_limit,
- 0, 0);
+ dict_ldap->size_limit = parser.get_int(ldapsource, "size_limit",
+ dict_ldap->expansion_limit,
+ 0, 0);
if (msg_verbose)
- msg_info("%s: %s is %ld", myname, vstring_str(config_param),
+ msg_info("%s: %s size_limit is %ld", myname, ldapsource,
dict_ldap->size_limit);
/*
* Alias dereferencing suggested by Mike Mattice.
*/
- vstring_sprintf(config_param, "%s_dereference", ldapsource);
- dict_ldap->dereference = get_mail_conf_int(vstring_str(config_param), 0, 0,
- 0);
-
- /*
- * Define LDAP Version.
- */
- vstring_sprintf(config_param, "%s_version", ldapsource);
- dict_ldap->version = get_mail_conf_int(vstring_str(config_param), 2, 0,
- 0);
- switch (dict_ldap->version) {
- case 2:
- dict_ldap->version = LDAP_VERSION2;
- break;
- case 3:
- dict_ldap->version = LDAP_VERSION3;
- break;
- default:
- msg_warn("%s: Unknown version %d.", myname, dict_ldap->version);
- dict_ldap->version = LDAP_VERSION2;
- }
-
- /*
- * Make sure only valid options for alias dereferencing are used.
- */
+ dict_ldap->dereference = parser.get_int(ldapsource, "dereference", 0, 0,
+ 0);
if (dict_ldap->dereference < 0 || dict_ldap->dereference > 3) {
- msg_warn("%s: Unrecognized value %d specified for %s; using 0",
- myname, dict_ldap->dereference, vstring_str(config_param));
+ msg_warn("%s: %s Unrecognized value %d specified for dereference; using 0",
+ myname, ldapsource, dict_ldap->dereference);
dict_ldap->dereference = 0;
}
if (msg_verbose)
- msg_info("%s: %s is %d", myname, vstring_str(config_param),
+ msg_info("%s: %s dereference is %d", myname, ldapsource,
dict_ldap->dereference);
/* Referral chasing */
- vstring_sprintf(config_param, "%s_chase_referrals", ldapsource);
- dict_ldap->chase_referrals = get_mail_conf_bool(vstring_str(config_param), 0);
+ dict_ldap->chase_referrals = parser.get_bool(ldapsource, "chase_referrals",
+ 0);
if (msg_verbose)
- msg_info("%s: %s is %d", myname, vstring_str(config_param),
+ msg_info("%s: %s chase_referrals is %d", myname, ldapsource,
dict_ldap->chase_referrals);
+#ifdef LDAP_API_FEATURE_X_OPENLDAP
+
/*
- * Debug level.
+ * TLS options
*/
-#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
- vstring_sprintf(config_param, "%s_debuglevel", ldapsource);
- dict_ldap->debuglevel = get_mail_conf_int(vstring_str(config_param), 0, 0,
- 0);
+ /* get configured value of "start_tls"; default to no */
+ dict_ldap->start_tls = parser.get_bool(ldapsource, "start_tls", 0);
if (msg_verbose)
- msg_info("%s: %s is %d", myname, vstring_str(config_param),
- dict_ldap->debuglevel);
+ msg_info("%s: %s start_tls is %d", myname, ldapsource,
+ dict_ldap->start_tls);
+ if (dict_ldap->start_tls && dict_ldap->version < LDAP_VERSION3) {
+ msg_warn("%s: %s start_tls requires protocol version 3", myname, ldapsource);
+ dict_ldap->version = LDAP_VERSION3;
+ }
+ /* get configured value of "tls_require_cert"; default to no */
+ dict_ldap->tls_require_cert = parser.get_bool(ldapsource, "tls_require_cert", 0);
+ if (msg_verbose)
+ msg_info("%s: %s tls_require_cert is %d", myname, ldapsource,
+ dict_ldap->tls_require_cert);
+ /* get configured value of "tls_ca_cert_file"; default "" */
+ dict_ldap->tls_ca_cert_file = parser.get_str(ldapsource, "tls_ca_cert_file",
+ "", 0, 0);
+ if (msg_verbose)
+ msg_info("%s: %s tls_ca_cert_file is %s", myname, ldapsource,
+ dict_ldap->tls_ca_cert_file);
+ /* get configured value of "tls_ca_cert_dir"; default "" */
+ dict_ldap->tls_ca_cert_dir = parser.get_str(ldapsource, "tls_ca_cert_dir",
+ "", 0, 0);
+ if (msg_verbose)
+ msg_info("%s: %s tls_ca_cert_dir is %s", myname, ldapsource,
+ dict_ldap->tls_ca_cert_dir);
+ /* get configured value of "tls_cert"; default "" */
+ dict_ldap->tls_cert = parser.get_str(ldapsource, "tls_cert",
+ "", 0, 0);
+ if (msg_verbose)
+ msg_info("%s: %s tls_cert is %s", myname, ldapsource,
+ dict_ldap->tls_cert);
+ /* get configured value of "tls_key"; default "" */
+ dict_ldap->tls_key = parser.get_str(ldapsource, "tls_key",
+ "", 0, 0);
+ if (msg_verbose)
+ msg_info("%s: %s tls_key is %s", myname, ldapsource,
+ dict_ldap->tls_key);
+ /* get configured value of "tls_random_file"; default "" */
+ dict_ldap->tls_random_file = parser.get_str(ldapsource,
+ "tls_random_file", "", 0, 0);
+ if (msg_verbose)
+ msg_info("%s: %s tls_random_file is %s", myname, ldapsource,
+ dict_ldap->tls_random_file);
+ /* get configured value of "tls_cipher_suite"; default "" */
+ dict_ldap->tls_cipher_suite = parser.get_str(ldapsource,
+ "tls_cipher_suite", "", 0, 0);
+ if (msg_verbose)
+ msg_info("%s: %s tls_cipher_suite is %s", myname, ldapsource,
+ dict_ldap->tls_cipher_suite);
#endif
- dict_ldap_connect(dict_ldap);
-
/*
- * if dict_ldap_connect() set dict_errno, free dict_ldap and abort.
+ * Debug level.
*/
- if (dict_errno) {
- if (dict_ldap->ld)
- ldap_unbind(dict_ldap->ld);
-
- myfree((char *) dict_ldap);
- return (0);
- }
+#if defined(LDAP_OPT_DEBUG_LEVEL) && defined(LBER_OPT_LOG_PRINT_FN)
+ dict_ldap->debuglevel = parser.get_int(ldapsource, "debuglevel", 0, 0, 0);
+ if (msg_verbose)
+ msg_info("%s: %s debuglevel is %d", myname, ldapsource,
+ dict_ldap->debuglevel);
+#endif
/*
- * Otherwise, we're all set. Return the new dict_ldap structure.
+ * Return the new dict_ldap structure.
*/
return (DICT_DEBUG (&dict_ldap->dict));
}
#ifdef USE_ULIMIT
if ((limit = ulimit(UL_GETFSIZE, 0)) < 0)
msg_fatal("ulimit: %m");
- if (limit > INT_MAX / ULIMIT_BLOCK_SIZE)
- limit = INT_MAX / ULIMIT_BLOCK_SIZE;
+ if (limit > OFF_T_MAX / ULIMIT_BLOCK_SIZE)
+ limit = OFF_T_MAX / ULIMIT_BLOCK_SIZE;
return (limit * ULIMIT_BLOCK_SIZE);
#else
struct rlimit rlim;
if (getrlimit(RLIMIT_FSIZE, &rlim) < 0)
msg_fatal("getrlimit: %m");
limit = rlim.rlim_cur;
- return (limit < 0 ? INT_MAX : rlim.rlim_cur);
+ return (limit < 0 ? OFF_T_MAX : rlim.rlim_cur);
#endif /* USE_ULIMIT */
}
#include "find_inet.h"
#include "inet_util.h"
#include "iostuff.h"
+#include "sane_connect.h"
#include "connect.h"
#include "timed_connect.h"
*/
else {
non_blocking(sock, block_mode);
- if (connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0
+ if (sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0
&& errno != EINPROGRESS) {
close(sock);
return (-1);
int inet_accept(int fd)
{
- return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0));
+ struct sockaddr_in sin;
+ SOCKADDR_SIZE len = sizeof(sin);
+
+ return (sane_accept(fd, (struct sockaddr *) & sin, &len));
}
#include <errno.h>
#include <syslog.h>
#include <string.h>
+#include <time.h>
/* Application-specific. */
#include "msg.h"
#include "msg_output.h"
#include "msg_syslog.h"
+#include "safe.h"
/*
* Stay a little below the 2048-byte limit of older syslog()
{
static int first_call = 1;
+ /*
+ * XXX If this program is set-gid, then TZ must not be trusted.
+ * This scrubbing code is in the wrong place.
+ */
+ if (unsafe())
+ putenv("TZ=");
+ tzset();
openlog(name, LOG_NDELAY | logopt, facility);
if (first_call) {
first_call = 0;
/* DESCRIPTION
/* sane_accept() implements the accept(2) socket call, and maps
/* known harmless error results to EAGAIN.
+/*
+/* If the buf and len arguments are not null, then additional
+/* workarounds may be enabled that depend on the socket type.
/* BUGS
/* Bizarre systems may have other harmless error results. Such
/* systems encourage programers to ignore error results, and
}
}
}
+
+ /*
+ * XXX Solaris select() produces false read events, so that read() blocks
+ * forever on a blocking socket, and fails with EAGAIN on a non-blocking
+ * socket. Turning on keepalives will fix a blocking socket provided that
+ * the kernel's keepalive timer expires before the Postfix watchdog
+ * timer.
+ */
+#if defined(BROKEN_READ_SELECT_ON_TCP_SOCKET) && defined(SO_KEEPALIVE)
+ else if (sa != 0 && sa->sa_family == AF_INET) {
+ int on = 1;
+
+ (void) setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE,
+ (char *) &on, sizeof(on));
+ }
+#endif
return (fd);
}
--- /dev/null
+/*++
+/* NAME
+/* sane_connect 3
+/* SUMMARY
+/* sanitize connect() results
+/* SYNOPSIS
+/* #include <sane_connect.h>
+/*
+/* int sane_connect(sock, buf, len)
+/* int sock;
+/* struct sockaddr *buf;
+/* SOCKADDR_SIZE *len;
+/* DESCRIPTION
+/* sane_connect() implements the accept(2) socket call, and maps
+/* known harmless error results to EAGAIN.
+/* BUGS
+/* Bizarre systems may have other harmless error results. Such
+/* systems encourage programers to ignore error results, and
+/* penalizes programmers who code defensively.
+/* 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 <sys/socket.h>
+#include <errno.h>
+
+/* Utility library. */
+
+#include "msg.h"
+#include "sane_connect.h"
+
+/* sane_connect - sanitize connect() results */
+
+int sane_connect(int sock, struct sockaddr * sa, SOCKADDR_SIZE len)
+{
+
+ /*
+ * XXX Solaris select() produces false read events, so that read() blocks
+ * forever on a blocking socket, and fails with EAGAIN on a non-blocking
+ * socket. Turning on keepalives will fix a blocking socket provided that
+ * the kernel's keepalive timer expires before the Postfix watchdog
+ * timer.
+ */
+#if defined(BROKEN_READ_SELECT_ON_TCP_SOCKET) && defined(SO_KEEPALIVE)
+ if (sa->sa_family == AF_INET) {
+ int on = 1;
+
+ (void) setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE,
+ (char *) &on, sizeof(on));
+ }
+#endif
+ return (connect(sock, sa, len));
+}
--- /dev/null
+#ifndef _SANE_CONNECT_H_
+#define _SANE_CONNECT_H_
+
+/*++
+/* NAME
+/* sane_connect 3h
+/* SUMMARY
+/* sanitize connect() results
+/* SYNOPSIS
+/* #include <sane_connect.h>
+/* DESCRIPTION
+/* .nf
+
+ /* External interface. */
+
+extern int sane_connect(int, struct sockaddr *, SOCKADDR_SIZE);
+
+/* 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
#define LOCAL_CONNECT stream_connect
#define LOCAL_TRIGGER stream_trigger
#define HAS_VOLATILE_LOCKS
-#define BROKEN_READ_SELECT_ON_BLOCKING_SOCKET
+#define BROKEN_READ_SELECT_ON_TCP_SOCKET
/*
* Allow build environment to override paths.
#else
#define SCANFLIKE(x,y)
#endif
+#endif
+
+ /*
+ * Bit banging!! There is no official constant that defines the INT_MAX
+ * equivalent of the off_t type. Wietse came up with the following macro
+ * that works as long as off_t is some two's complement number.
+ */
+#include <limits.h>
+#define __MAXINT__(T) ((T) (((T)1 << ((sizeof(T) * CHAR_BIT) - 1) ^ ((T) -1))))
+#ifndef OFF_T_MAX
+#define OFF_T_MAX __MAXINT__(off_t)
#endif
/*
#include "msg.h"
#include "iostuff.h"
+#include "sane_connect.h"
#include "timed_connect.h"
/* timed_connect - connect with deadline */
/*
* Start the connection, and handle all possible results.
*/
- if (connect(sock, sa, len) == 0)
+ if (sane_connect(sock, sa, len) == 0)
return (0);
if (errno != EINPROGRESS)
return (-1);
#include <sys_defs.h>
#include <unistd.h>
+#include <errno.h>
/* Utility library. */
-#include "iostuff.h"
+#include <msg.h>
+#include <iostuff.h>
/* timed_read - read with deadline */
int timed_read(int fd, void *buf, unsigned len,
int timeout, void *unused_context)
{
+ int ret;
/*
* Wait for a limited amount of time for something to happen. If nothing
* happens, report an ETIMEDOUT error.
+ *
+ * XXX Solaris 8 read() fails with EAGAIN after read-select() returns
+ * success.
*/
- if (timeout > 0 && read_wait(fd, timeout) < 0)
- return (-1);
- else
- return (read(fd, buf, len));
+ for (;;) {
+ if (timeout > 0 && read_wait(fd, timeout) < 0)
+ return (-1);
+ if ((ret = read(fd, buf, len)) < 0 && timeout > 0 && errno == EAGAIN) {
+ msg_warn("read() returns EAGAIN on a readable file descriptor!");
+ msg_warn("pausing to avoid going into a tight select/read loop!");
+ sleep(1);
+ } else {
+ return (ret);
+ }
+ }
}
#include <sys_defs.h>
#include <unistd.h>
+#include <errno.h>
/* Utility library. */
-#include "iostuff.h"
+#include <msg.h>
+#include <iostuff.h>
/* timed_write - write with deadline */
int timed_write(int fd, void *buf, unsigned len,
int timeout, void *unused_context)
{
+ int ret;
/*
* Wait for a limited amount of time for something to happen. If nothing
* happens, report an ETIMEDOUT error.
+ *
+ * XXX Solaris 8 read() fails with EAGAIN after read-select() returns
+ * success. The code below exists just in case their write implementation
+ * is equally broken.
+ *
+ * This condition may also be found on systems where select() returns
+ * success on pipes with less than PIPE_BUF bytes of space, and with
+ * badly designed software where multiple writers are fighting for access
+ * to the same resource.
*/
- if (timeout > 0 && write_wait(fd, timeout) < 0)
- return (-1);
- else
- return (write(fd, buf, len));
+ for (;;) {
+ if (timeout > 0 && write_wait(fd, timeout) < 0)
+ return (-1);
+ if ((ret = write(fd, buf, len)) < 0 && timeout > 0 && errno == EAGAIN) {
+ msg_warn("write() returns EAGAIN on a writable file descriptor!");
+ msg_warn("pausing to avoid going into a tight select/write loop!");
+ sleep(1);
+ } else {
+ return (ret);
+ }
+ }
}
#include "msg.h"
#include "iostuff.h"
+#include "sane_connect.h"
#include "connect.h"
#include "timed_connect.h"
*/
else {
non_blocking(sock, block_mode);
- if (connect(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0
+ if (sane_connect(sock, (struct sockaddr *) & sun, sizeof(sun)) < 0
&& errno != EINPROGRESS) {
close(sock);
return (-1);