mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 01:49:47 +00:00
postfix-2.11-20131217
This commit is contained in:
parent
33f88e4f81
commit
64700e1f71
14
postfix/.indent.pro
vendored
14
postfix/.indent.pro
vendored
@ -155,6 +155,7 @@
|
||||
-TLMTP_STATE
|
||||
-TLOCAL_EXP
|
||||
-TLOCAL_STATE
|
||||
-TLONG_NAME_MASK
|
||||
-TMAC_EXP
|
||||
-TMAC_HEAD
|
||||
-TMAC_PARSE
|
||||
@ -193,6 +194,7 @@
|
||||
-TMKMAP_DB
|
||||
-TMKMAP_DBM
|
||||
-TMKMAP_OPEN_INFO
|
||||
-TMKMAP_SDBM
|
||||
-TMSG_STATS
|
||||
-TMULTI_SERVER
|
||||
-TMVECT
|
||||
@ -206,10 +208,14 @@
|
||||
-TOPTIONS
|
||||
-TPC_DBMS_INFO
|
||||
-TPC_EVAL_CTX
|
||||
-TPC_MASTER_EDIT_REQ
|
||||
-TPC_MASTER_ENT
|
||||
-TPC_MASTER_FIELD_REQ
|
||||
-TPC_PARAM_CTX
|
||||
-TPC_PARAM_NODE
|
||||
-TPC_PARAM_TABLE
|
||||
-TPC_SERVICE_DEF
|
||||
-TPC_SERVICE_PATTERN
|
||||
-TPC_STRING_NV
|
||||
-TPEER_NAME
|
||||
-TPGSQL_NAME
|
||||
@ -341,6 +347,7 @@
|
||||
-TXSASL_CLIENT_CREATE_ARGS
|
||||
-TXSASL_CLIENT_IMPL
|
||||
-TXSASL_CLIENT_IMPL_INFO
|
||||
-TXSASL_CYRUS_CB
|
||||
-TXSASL_CYRUS_CLIENT
|
||||
-TXSASL_CYRUS_ERROR_INFO
|
||||
-TXSASL_CYRUS_SERVER
|
||||
@ -352,18 +359,25 @@
|
||||
-TXSASL_SERVER_CREATE_ARGS
|
||||
-TXSASL_SERVER_IMPL
|
||||
-TXSASL_SERVER_IMPL_INFO
|
||||
-Tbind_props
|
||||
-Tcipher_probe_t
|
||||
-Tdane_digest
|
||||
-Tfilter_ctx
|
||||
-Tgeneral_name_stack_t
|
||||
-Tiana_digest
|
||||
-Toff_t
|
||||
-Tregex_t
|
||||
-Tregmatch_t
|
||||
-Tsasl_conn_t
|
||||
-Tsasl_secret_t
|
||||
-Tsfsistat
|
||||
-Tsigset_t
|
||||
-Tsize_t
|
||||
-Tsockaddr
|
||||
-Tssize_t
|
||||
-Tssl_cipher_stack_t
|
||||
-Tssl_comp_stack_t
|
||||
-Ttime_t
|
||||
-Ttlsa_filter
|
||||
-Tx509_extension_stack_t
|
||||
-Tx509_stack_t
|
||||
|
159
postfix/HISTORY
159
postfix/HISTORY
@ -18218,6 +18218,13 @@ Apologies for any names omitted.
|
||||
Factor out the master.cf line parser so that it can be
|
||||
reused for "postconf -Me". File: postconf/postconf_master.c.
|
||||
|
||||
20130113
|
||||
|
||||
Feature: master.cf attribute namespace. "postconf -F" shows
|
||||
individual master.cf fields as "service/type/attribute =
|
||||
value", where attribute is "service", "type", "private",
|
||||
"unprivileged", "wakeup", "process_limit", or "command".
|
||||
|
||||
20130121
|
||||
|
||||
Bugfix (introduced 20120307): the postconf -X option erased
|
||||
@ -19232,9 +19239,161 @@ Apologies for any names omitted.
|
||||
cleanup/cleanup_milter.c, cleanup/cleanup_state.c,
|
||||
global/xtext.c, global/xtext.h, milter/test-milter.c.
|
||||
|
||||
20131122
|
||||
|
||||
Feature: "postcon -Fe service/type/attribute = value" edits
|
||||
master.cf attribute values. The -e is optional. Example:
|
||||
use "postconf -F "*/*/chroot = n" to turn off chroot on all
|
||||
master.cf services. Files: postconf/postconf.h,
|
||||
postconf/postconf.c, postconf/postcof_master.c,
|
||||
postconf/postconf_edit.c.
|
||||
|
||||
20131124
|
||||
|
||||
Cleanup: remove extra blank line from ccformat output,
|
||||
making it compatible with the script that Wietse actually
|
||||
uses (this line was part of a test to detect file truncation,
|
||||
but it is now obsolete). File: mantools/ccformat.
|
||||
|
||||
Feature: master.cf parameter namespace. "postconf -P" shows
|
||||
master.cf parameter settings as "service/type/parameter =
|
||||
value". This is applicable only to parameter settings in
|
||||
master.cf. Files: postconf/postconf.h, postconf/postconf.c,
|
||||
postconf/postcof_master.c, postconf/postconf_print.c.
|
||||
|
||||
Incompatibility: the master_service_disable syntax has
|
||||
changed: use "service/type" instead of "service.type". The
|
||||
new form is consistent with master.cf parameter namespaces.
|
||||
The old form is still supported to avoid breaking existing
|
||||
configurations. Files: global/master_service.c,
|
||||
master/master_ent.c.
|
||||
|
||||
20131125
|
||||
|
||||
Feature: change, add or delete "-o parameter=value" setting
|
||||
in master.cf. Examples: "postconf -P smtp/inet/parameter=value"
|
||||
(add or modify "-o name=value" setting) and "postconf -P
|
||||
smtp/inet/parameter" (delete "-o parameter=value" setting).
|
||||
Files: util/argv.[hc], postconf/postconf.h,
|
||||
postconf/postconf_edit.c, postconf_master.c.
|
||||
|
||||
20131126
|
||||
|
||||
Cleanup: Leave SSLv3 enabled with DANE. Viktor Dukhovni.
|
||||
Files: proto/TLS_README.html proto/postconf.proto
|
||||
tls/tls_client.c.
|
||||
|
||||
Cleanup: DANE support: Drop support for usage 0. It SHOULD
|
||||
NOT be supported in DANE with SMTP, and we already don't
|
||||
support digest TLSA RRs in this case, while full content
|
||||
TLSA RRs are not recommended for DNS bloat reasons. Viktor
|
||||
Dukhovni. Files: proto/postconf.proto src/global/mail_params.h
|
||||
src/smtp/smtp.c src/tls/tls_dane.c src/tls/tls_misc.c.
|
||||
|
||||
Feature: TLS support: Support future digest algorithms
|
||||
without re-compilation. Viktor Dukhovni. Files: .indent.pro
|
||||
proto/postconf.proto src/tls/tls_dane.c.
|
||||
|
||||
Feature: DNS support: New configurable digest agility.
|
||||
Viktor Dukhovni. Files: .indent.pro proto/TLS_README.html
|
||||
proto/postconf.proto src/global/mail_params.h src/tls/tls_dane.c
|
||||
src/tls/tls_misc.c.
|
||||
|
||||
20131127
|
||||
|
||||
Bugfix (introduced: 20090106): the postconf '-#' option
|
||||
erased prior options. File: postconf/postconf.c.
|
||||
|
||||
20131129
|
||||
|
||||
Bugfix: Makefile example in MULTI_INSTANCE_README. Viktor
|
||||
Dukhovni. File: proto/MULTI_INSTANCE_README.html.
|
||||
|
||||
20131130
|
||||
|
||||
Cleanup: simplify fingerprint security level implementation
|
||||
in new DANE code. Viktor Dukhovni. Files: src/tls/tls.h
|
||||
src/smtp/smtp_tls_policy.c src/tls/tls_dane.c
|
||||
src/posttls-finger/posttls-finger.c.
|
||||
|
||||
20131209
|
||||
|
||||
Cleanup: safe_strtoul() did not report an error for empty
|
||||
or all-space input (the code to report this was in the wrong
|
||||
place). This was not a problem as long as safe_strtoul()
|
||||
was used only for output from safe_ultostr(). Files:
|
||||
global/safe_ultostr.c, global/safe_ultostr.in,
|
||||
global/safe_ultostr.ref.
|
||||
|
||||
20131210
|
||||
|
||||
Documentation: updated description of SSL protocol controls.
|
||||
In particular, enabled protocols are part of a contiguous
|
||||
range. Viktor Dukhovni. Files: proto/TLS_README.html,
|
||||
proto/postconf.proto.
|
||||
|
||||
Bugfix: DANE support: handle OpenSSL memory allocation
|
||||
error. Viktor Dukhovni. File: tls/tls_dane.c.
|
||||
|
||||
Cleanup: LMDB_README was not installed. File: conf/postfix-files.
|
||||
|
||||
20131214
|
||||
|
||||
Portability: on some platforms posttls-finger now requires
|
||||
explicitly linking libdl. File: posttls-finger/Makefile.in.
|
||||
|
||||
Cleanup: DANE support: extension gymnastics. Viktor Dukhovni.
|
||||
File: tls/tls_dane.c.
|
||||
|
||||
Bugfix: DANE support: the wrap_cert() and wrap_key() calls
|
||||
should never fail, but some callers ignored the return
|
||||
value. The only failure is for lack of memory, so we use
|
||||
msg_fatal() internally and change wrap_cert() and wrap_key()
|
||||
to return void. Viktor Dukhovni. File: tls/tls_dane.c.
|
||||
|
||||
Bugfix: DANE support: avoid making DANE certificates with
|
||||
replaced public-keys appear as if they were self-signed.
|
||||
Viktor Dukhovni. File: tls/tls_dane.c.
|
||||
|
||||
Cleanup: DANE support: simplify grow_chain() to always apply
|
||||
trust consistently. Viktor Dukhovni. File: tls/tls_dane.c.
|
||||
|
||||
Bugfix: DANE support: backport fixes from OpenSSL DANE
|
||||
testing. Discard errors generated by raw TA key signature
|
||||
checks. Record the tadepth as zero with self-signed depth
|
||||
0 TAs. Robustness: Though it should never happen, don't
|
||||
update the tadepth if already set. Viktor Dukhovni. Files:
|
||||
tls/tls_dane.c, tls/tls_server.c.
|
||||
|
||||
20131215
|
||||
|
||||
Cleanup: OpenSSL "const" declarations have changed over
|
||||
time. Viktor Dukhovni. Files: src/tls/tls.h, src/tls/tls_client.c,
|
||||
src/tls/tls_dane.c, src/tls/tls_server.c.
|
||||
|
||||
20131216
|
||||
|
||||
Cleanup: TLS support. Eliminate calls of deprecated functions
|
||||
before they are removed from OpenSSL. CRYPTO_thread_id is
|
||||
deprecated and we don't need it. Replace the deprecated
|
||||
ERR_remove_state() call with ERR_remove_thread_state(), and
|
||||
use RSA_generate_key_ex(). Viktor Dukhovni. Files:
|
||||
posttls-finger/posttls-finger.c, tls/tls_misc.c, tls/tls_rsa.c.
|
||||
|
||||
Cleanup: DANE support: Reduce #ifdef clutter to improve
|
||||
redability and maintability. Viktor Dukhovni. File:
|
||||
tls/tls_dane.c.
|
||||
|
||||
Future proofing: Tolerate disappearance of named bug-workaround
|
||||
bits without invalidating user configurations. When support
|
||||
for a bug workaround is removed from OpenSSL, the corresponding
|
||||
bit is defined as zero (i.e. NOOP) intstead of causing
|
||||
programs to break. Viktor Dukhovni. File: tls/tls_misc.c.
|
||||
|
||||
20131217
|
||||
|
||||
Portability: RSA_generate_key_ex() is not available on all
|
||||
supported platforms, so this change is made conditional.
|
||||
Enforce that this function will be used only for creating
|
||||
a 512-bit ephemeral RSA key. Viktor Dukhovni. File:
|
||||
tls/tls_rsa.c.
|
||||
|
@ -177,7 +177,7 @@ database when none exists.
|
||||
generic: Makefile
|
||||
@echo Creating $@
|
||||
@rm -f $@.tmp
|
||||
@printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` > $@.tmp
|
||||
@printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` > $@.tmp
|
||||
@mv $@.tmp generic
|
||||
|
||||
%.cdb: %
|
||||
|
@ -135,9 +135,10 @@ assume that the certificate for "server.example.com" was issued by
|
||||
|
||||
% ccaatt sseerrvveerr__cceerrtt..ppeemm iinntteerrmmeeddiiaattee__CCAA..ppeemm >> sseerrvveerr..ppeemm
|
||||
|
||||
* If you use RFC 6698 TLSA "2 0 1" or "2 1 1" records to specify root CA
|
||||
* If you publish RFC 6698 TLSA "2 0 1" or "2 1 1" records to specify root CA
|
||||
certificate digests, you must include the corresponding root CA
|
||||
certificates in the "server.pem" certificate file.
|
||||
certificates in the "server.pem" certificate file. See the documentation of
|
||||
the tls_dane_trust_anchor_digest_enable main.cf parameter.
|
||||
|
||||
% ccaatt sseerrvveerr__cceerrtt..ppeemm iinntteerrmmeeddiiaattee__CCAA..ppeemm rroooott..ppeemm >> sseerrvveerr..ppeemm
|
||||
|
||||
@ -147,20 +148,13 @@ assume that the certificate for "server.example.com" was issued by
|
||||
published TLSA records will typically cause the SMTP client to defer mail
|
||||
delivery. The foregoing also applies to "2 0 2" and "2 1 2" TLSA records or
|
||||
any other digest of a CA certificate, but it is expected that SHA256 will
|
||||
be by far the most common digest for TLSA. You are strongly urged to
|
||||
likewise include the root CA certificate in your server certificate file
|
||||
even if you use "0 0 1" or "0 1 1" TLSA records. Some DANE implementations
|
||||
in SMTP clients (Postfix among them) may treat RFC 6698 certificate usages
|
||||
"0" and "2" interchangeably.
|
||||
be by far the most common digest for TLSA.
|
||||
|
||||
By default, support for TLSA records that specify certificate usage "0" via
|
||||
a digest is disabled in the Postfix SMTP client. As a best practice,
|
||||
publish either "3 0 1" or "3 1 1" TLSA associations that specify the SHA256
|
||||
digest of the server certificate public key with the alias-expanded
|
||||
hostname of each STARTTLS capable SMTP server. These continue to work when
|
||||
a certificate is renewed with the same public/private key pair. See the
|
||||
documentation of the tls_dane_trust_anchor_digest_enable main.cf parameter
|
||||
for details.
|
||||
As a best practice, publish either "3 0 1" or "3 1 1" TLSA associations
|
||||
that specify the SHA256 digest of the server certificate public key with
|
||||
the alias-expanded hostname of each STARTTLS capable SMTP server. These
|
||||
continue to work when a certificate is renewed with the same public/private
|
||||
key pair.
|
||||
|
||||
For instructions on how to compute the digest of a certificate or its public
|
||||
key for use in TLSA records, see the documentation of the
|
||||
@ -418,7 +412,7 @@ from scratch.
|
||||
|
||||
Since Postfix uses multiple smtpd(8) service processes, an in-memory cache is
|
||||
not sufficient for session re-use. Clients store at most one cached session per
|
||||
server and are very unlikey to repeatedly connect to the same server process.
|
||||
server and are very unlikely to repeatedly connect to the same server process.
|
||||
Thus session caching in the Postfix SMTP server generally requires a shared
|
||||
cache (an alternative available with Postfix >= 2.11 is described below).
|
||||
|
||||
@ -614,7 +608,8 @@ configurations with no server certificates that use oonnllyy the anonymous c
|
||||
This is enabled by explicitly setting "smtpd_tls_cert_file = none" and not
|
||||
specifying an smtpd_tls_dcert_file or smtpd_tls_eccert_file.
|
||||
|
||||
Example, MSA that requires TLSv1, not SSLv2 or SSLv3, with high grade ciphers:
|
||||
Example, MSA that requires TLSv1 or higher, not SSLv2 or SSLv3, with high grade
|
||||
ciphers:
|
||||
|
||||
/etc/postfix/main.cf:
|
||||
smtpd_tls_cert_file = /etc/postfix/cert.pem
|
||||
@ -622,9 +617,9 @@ Example, MSA that requires TLSv1, not SSLv2 or SSLv3, with high grade ciphers:
|
||||
smtpd_tls_mandatory_ciphers = high
|
||||
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5
|
||||
smtpd_tls_security_level = encrypt
|
||||
# Preferred form with Postfix >= 2.5:
|
||||
# Preferred syntax with Postfix >= 2.5:
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
|
||||
If you want to take advantage of ciphers with ephemeral Diffie-Hellman (EDH)
|
||||
@ -656,21 +651,25 @@ Examples:
|
||||
smtpd_tls_eecdh_grade = strong
|
||||
|
||||
Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later allows TLS
|
||||
servers to preempt the TLS client's cipher preference list. This is possible
|
||||
only with SSLv3 and later, as in SSLv2 the client chooses the cipher from a
|
||||
list supplied by the server.
|
||||
servers to preempt the TLS client's cipher-suite preference list. This is
|
||||
possible only with SSLv3 and later, as in SSLv2 the client chooses the cipher-
|
||||
suite from a list supplied by the server.
|
||||
|
||||
By default, the OpenSSL server selects the client's most preferred cipher that
|
||||
the server supports. With SSLv3 and later, the server may choose its own most
|
||||
preferred cipher that is supported (offered) by the client. Setting
|
||||
"tls_preempt_cipherlist = yes" enables server cipher preferences. The default
|
||||
OpenSSL behavior applies with "tls_preempt_cipherlist = no".
|
||||
By default, the OpenSSL server selects the client's most preferred cipher-suite
|
||||
that the server supports. With SSLv3 and later, the server may choose its own
|
||||
most preferred cipher-suite that is supported (offered) by the client. Setting
|
||||
"tls_preempt_cipherlist = yes" enables server cipher-suite preferences. The
|
||||
default OpenSSL behavior applies with "tls_preempt_cipherlist = no".
|
||||
|
||||
While server cipher selection may in some cases lead to a more secure or
|
||||
performant cipher choice, there is some risk of interoperability issues. In the
|
||||
past, some SSL clients have listed lower priority ciphers that they did not
|
||||
implement correctly. If the server chooses a cipher that the client prefers
|
||||
less, it may select a cipher whose client implementation is flawed.
|
||||
While server cipher-suite selection may in some cases lead to a more secure or
|
||||
performant cipher-suite choice, there is some risk of interoperability issues.
|
||||
In the past, some SSL clients have listed lower priority ciphers that they did
|
||||
not implement correctly. If the server chooses a cipher that the client prefers
|
||||
less, it may select a cipher whose client implementation is flawed. Most
|
||||
notably Windows 2003 Microsoft Exchange servers have flawed implementations of
|
||||
DES-CBC3-SHA, which OpenSSL considers stronger than RC4-SHA. Enabling server
|
||||
cipher-suite selection may create interoperability issues with Windows 2003
|
||||
Microsoft Exchange clients.
|
||||
|
||||
MMiisscceellllaanneeoouuss sseerrvveerr ccoonnttrroollss
|
||||
|
||||
@ -916,78 +915,74 @@ level.
|
||||
The "dane" level is a stronger form of opportunistic TLS that is resistant to
|
||||
man in the middle and downgrade attacks when the destination domain uses DNSSEC
|
||||
to publish DANE TLSA records for its MX hosts. If a remote SMTP server has
|
||||
usable DANE TLSA records, these will be used to authenticate the server. If
|
||||
TLSA records are published for a given remote SMTP server (implying TLS
|
||||
support), but are not usable due to unsupported parameters, the Postfix SMTP
|
||||
client will use mandatory unauthenticated TLS. Otherwise, the Postfix SMTP
|
||||
client behavior is the same as with may.
|
||||
"usable" (see RFC 6698) DANE TLSA records, the server connection will be
|
||||
authenticated. When DANE authentication fails, there is no fallback to
|
||||
unauthenticated or plaintext delivery.
|
||||
|
||||
If TLSA records are published for a given remote SMTP server (implying TLS
|
||||
support), but are all "unusable" due to unsupported parameters or malformed
|
||||
data, the Postfix SMTP client will use mandatory unauthenticated TLS.
|
||||
Otherwise, when no TLSA records are published, the Postfix SMTP client behavior
|
||||
is the same as with may.
|
||||
|
||||
TLSA records must be published in DNSSEC validated DNS zones. Any TLSA records
|
||||
in DNS zones not protected via DNSSEC are ignored. The Postfix SMTP client will
|
||||
not look for TLSA records associated with MX hosts whose "A" or "AAAA" records
|
||||
lie in an "insecure" DNS zone. Such lookups have been observed to cause
|
||||
interoperability issues with poorly implemented DNS servers, and are in any
|
||||
case not expected to ever yield "secure" results, since that would require a
|
||||
very unlikely DLV DNS trust anchor configured between the host record and the
|
||||
associated "_25._tcp" child TLSA record.
|
||||
|
||||
The "dane-only" level is a form of secure-channel TLS based on the DANE PKI. If
|
||||
usable TLSA records are present these are used to authenticate the remote SMTP
|
||||
server. Otherwise, or when server certificate verification fails, delivery via
|
||||
the server in question tempfails.
|
||||
"usable" TLSA records are present these are used to authenticate the remote
|
||||
SMTP server. Otherwise, or when server certificate verification fails, delivery
|
||||
via the server in question tempfails.
|
||||
|
||||
At both security levels, the TLS policy for the destination is obtained via
|
||||
TLSA records validated with DNSSEC. For TLSA policy to be in effect, the
|
||||
destination domain's containing DNS zone must be signed and the Postfix SMTP
|
||||
client's operating system must be configured to send its DNS queries to a
|
||||
recursive DNS nameserver that is able to validate the signed records. Each MX
|
||||
host's DNS zone should also be signed, and should publish DANE TLSA (RFC 6698)
|
||||
records that specify how that MX host's TLS certificate is to be verified. TLSA
|
||||
records do not preempt the normal SMTP MX host selection algorithm, if some MX
|
||||
hosts support TLSA and others do not, TLS security will vary from delivery to
|
||||
delivery. It is up to the domain owner to configure their MX hosts and their
|
||||
DNS sensibly. To configure the Postfix SMTP client for DNSSEC lookups see the
|
||||
documentation for the smtp_dns_support_level main.cf parameter. The
|
||||
tls_dane_trust_anchor_digest_enable main.cf parameter controls optional support
|
||||
for trust-anchor digest TLSA records.
|
||||
host's DNS zone needs to also be signed, and needs to publish DANE TLSA (RFC
|
||||
6698) records that specify how that MX host's TLS certificate is to be
|
||||
verified.
|
||||
|
||||
The Postfix SMTP client deviates from RFC 6698 in cases where strict adherence
|
||||
is likely to create opportunities for delayed (or eventually bounced) email
|
||||
with no substantive security gain. Most notably, it is not expected that
|
||||
smtp_tls_CAfile and smtp_tls_CApath can reasonably include every public CA that
|
||||
a remote SMTP server's administrator may believe to be well-known. Therefore,
|
||||
certificate usages "0" and "2" from RFC 6698 which are intended to "constrain"
|
||||
existing PKI trust, are instead treated as "trust assertions" and mapped to "1"
|
||||
and "3" respectively. That is, with certificate usage "0" and "2", Postfix will
|
||||
not require the remote SMTP server's certificate to be trusted with respect to
|
||||
any locally defined public CAs, it is the domain owner's responsibility to
|
||||
ensure that the certificate associations in their TLSA records are appropriate
|
||||
to authenticate their SMTP servers.
|
||||
TLSA records do not preempt the normal SMTP MX host selection algorithm, if
|
||||
some MX hosts support TLSA and others do not, TLS security will vary from
|
||||
delivery to delivery. It is up to the domain owner to configure their MX hosts
|
||||
and their DNS sensibly. To configure the Postfix SMTP client for DNSSEC lookups
|
||||
see the documentation for the smtp_dns_support_level main.cf parameter. The
|
||||
tls_dane_trust_anchor_digest_enable main.cf parameter controls support for
|
||||
trust-anchor digest TLSA records. The tls_dane_digests and
|
||||
tls_dane_digest_agility parameters control the list of supported digests and
|
||||
digest downgrade attack resistance.
|
||||
|
||||
In addition, the Postfix SMTP client does not assume that the remote SMTP
|
||||
server will necessarily be configured to present the certificate of any usage
|
||||
"0" root CA in its TLS protocol certificate_list. Therefore, support for usage
|
||||
"0" certificate and public-key digests is disabled by default, see
|
||||
tls_dane_trust_anchor_digest_enable for details. While undigested trust-anchor
|
||||
certificates in TLSA records are supported, publishing complete certificates in
|
||||
DNS is unwise given the resulting excessively large DNS record sizes.
|
||||
Therefore, in its default configuration the Postfix SMTP client essentially
|
||||
supports only certificate usages "1", "2" and "3" (with "1" treated as though
|
||||
it were "3").
|
||||
DANE for SMTP MTAs deviates in some details from the baseline DANE protocol in
|
||||
RFC 6698. Most notably, it is not expected that SMTP MTAs can reasonably
|
||||
include every public CA that a remote SMTP server's administrator may believe
|
||||
to be well-known. Nor is there an interactive user to "click OK" when
|
||||
authentication fails.
|
||||
|
||||
Finally, the interaction of DANE with MX hostnames that are CNAMEs differs from
|
||||
the draft specification in the names used to construct the associated TLSA
|
||||
queries. When the MX hostname is a CNAME, the draft proposal to use the
|
||||
unexpanded MX hostname in TLSA lookups is fragile and unintuitive. For this to
|
||||
work, the domain owner has to either duplicate the TLSA records of the target
|
||||
(host, service) pair in his own DNS or furnish the target host with an
|
||||
additional certificate and private key that would be negotiated via SNI.
|
||||
Neither of these are robust or easy to manage. It is far better to expand the
|
||||
CNAME recursively to the underlying target hostname (keeping track of DNSSEC
|
||||
validation along the way) and to use the expanded name to construct the TLSA
|
||||
query and, if appropriate, in server certificate name checks. This is the
|
||||
approach taken by the Postfix SMTP client, and if sanity prevails will also be
|
||||
the approach taken in the final standard.
|
||||
Therefore, certificate usages "0" and "1" from RFC 6698 which are intended to
|
||||
"constrain" existing PKI trust, are not supported. TLSA records with usage "0"
|
||||
are treated as "unusable". TLSA records with usage "1" are instead treated as
|
||||
"trust assertions" and mapped to usage "3". Specifically, with certificate
|
||||
usage "1", Postfix will not require the remote SMTP server's certificate to be
|
||||
trusted with respect to any locally defined public CAs, it is the domain
|
||||
owner's responsibility to ensure that the certificate associations in their
|
||||
TLSA records are appropriate to authenticate their SMTP servers.
|
||||
|
||||
The Postfix SMTP client supports only certificate usages "2" and "3" (with "1"
|
||||
treated as though it were "3"). See tls_dane_trust_anchor_digest_enable for
|
||||
usage "2" usability considerations. Support for certificate usage "1" is an
|
||||
experiment, it may be withdrawn in the future. Server operators SHOULD NOT
|
||||
publish TLSA records with usage "1".
|
||||
|
||||
When usable TLSA records are obtained for the remote SMTP server the Postfix
|
||||
SMTP client is obligated to include the SNI TLS extension in its SSL client
|
||||
hello message. This may help the remote SMTP server live up to its promise to
|
||||
provide a certificate that matches its TLSA records. Since TLS extensions
|
||||
require TLS 1.0 or later, the Postfix SMTP client must disable SSLv2 and SSLv3
|
||||
when SNI is required. If you use "dane" or "dane-only", do not disable TLSv1,
|
||||
except perhaps via the policy table for destinations which you are sure will
|
||||
support TLSv1.1 or TLSv1.2.
|
||||
SMTP client sends the SNI TLS extension in its SSL client hello message. This
|
||||
may help the remote SMTP server live up to its promise to provide a certificate
|
||||
that matches its TLSA records.
|
||||
|
||||
For purposes of protocol and cipher selection, the "dane" security level is
|
||||
treated like a "mandatory" TLS security level, and weak ciphers and protocols
|
||||
@ -1010,8 +1005,8 @@ administrators should publish such EE records in preference to all other types.
|
||||
|
||||
The pre-requisites for DANE support in the Postfix SMTP client are:
|
||||
|
||||
* A compile-time OpenSSL library that supports the TLS SNI extension and the
|
||||
"sha256" and "sha512" message digests.
|
||||
* A compile-time OpenSSL library that supports the TLS SNI extension and
|
||||
"SHA-2" message digests.
|
||||
* A compile-time DNS resolver library that supports DNSSEC. Postfix binaries
|
||||
built on an older system will not support DNSSEC even if deployed on a
|
||||
system with an updated resolver library.
|
||||
@ -1566,9 +1561,9 @@ security policy.
|
||||
On the SMTP client, there are further complications. When delivering mail to a
|
||||
given domain, in contrast to HTTPS, one rarely uses the domain name directly as
|
||||
the target host of the SMTP session. More typically, one uses MX lookups -
|
||||
these are usually unauthenticated - to obtain the domain's SMTP server hostname
|
||||
(s). When, as is current practice, the client verifies the insecurely obtained
|
||||
MX hostname, it is subject to a DNS man-in-the-middle attack.
|
||||
- these are usually unauthenticated -- to obtain the domain's SMTP server
|
||||
hostname(s). When, as is current practice, the client verifies the insecurely
|
||||
obtained MX hostname, it is subject to a DNS man-in-the-middle attack.
|
||||
|
||||
Adoption of DNSSEC and RFC6698 (DANE) may gradually (as domains implement
|
||||
DNSSEC and publish TLSA records for their MX hosts) address the DNS man-in-the-
|
||||
@ -1660,21 +1655,18 @@ ddaannee
|
||||
TLSA records in DNSSEC. If no TLSA records are found, the effective
|
||||
security level used is may. If TLSA records are found, but none are usable,
|
||||
the effective security level is encrypt. When usable TLSA records are
|
||||
obtained for the remote SMTP server, SSLv2 and SSLv3 are automatically
|
||||
disabled (see smtp_tls_mandatory_protocols), and the server certificate
|
||||
must match the TLSA records. The tls_dane_trust_anchor_digest_enable
|
||||
parameter controls optional support for trust-anchor digest TLSA records.
|
||||
RFC 6698 (DANE) TLS authentication and DNSSEC support is available with
|
||||
Postfix 2.11 and later.
|
||||
obtained for the remote SMTP server, SSLv2 is automatically disabled (see
|
||||
smtp_tls_mandatory_protocols), and the server certificate must match the
|
||||
TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
|
||||
available with Postfix 2.11 and later.
|
||||
ddaannee--oonnllyy
|
||||
Mandatory DANE TLS. The TLS policy for the destination is obtained via TLSA
|
||||
records in DNSSEC. If no TLSA records are found, or none are usable, no
|
||||
connection is made to the server. When usable TLSA records are obtained for
|
||||
the remote SMTP server, SSLv2 and SSLv3 are automatically disabled (see
|
||||
the remote SMTP server, SSLv2 is automatically disabled (see
|
||||
smtp_tls_mandatory_protocols), and the server certificate must match the
|
||||
TLSA records. The tls_dane_trust_anchor_digest_enable parameter controls
|
||||
optional support for trust-anchor digest TLSA records. RFC 6698 (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11 and later.
|
||||
TLSA records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
|
||||
available with Postfix 2.11 and later.
|
||||
ffiinnggeerrpprriinntt
|
||||
Certificate fingerprint verification. Available with Postfix 2.5 and later.
|
||||
At this security level, there are no trusted certificate authorities. The
|
||||
@ -1745,9 +1737,8 @@ Example:
|
||||
/etc/postfix/tls_policy:
|
||||
example.edu none
|
||||
example.mil may
|
||||
example.gov encrypt protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.com verify
|
||||
match=hostname:dot-nexthop protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.gov encrypt ciphers=high
|
||||
example.com verify match=hostname:dot-nexthop ciphers=high
|
||||
example.net secure
|
||||
.example.net secure match=.example.net:example.net
|
||||
[mail.example.org]:587 secure match=nexthop
|
||||
@ -1838,7 +1829,7 @@ Example:
|
||||
smtp_tls_exclude_ciphers = aNULL
|
||||
# Preferred form with Postfix >= 2.5:
|
||||
smtp_tls_mandatory_protocols = !SSLv2
|
||||
# Alternative form.
|
||||
# Legacy form for Postifx < 2.5:
|
||||
smtp_tls_mandatory_protocols = SSLv3, TLSv1
|
||||
# Also available with Postfix >= 2.6:
|
||||
smtp_tls_ciphers = export
|
||||
|
@ -1,3 +1,5 @@
|
||||
This is the Postfix 2.11 (experimental) branch.
|
||||
|
||||
The stable Postfix release is called postfix-2.10.x where 2=major
|
||||
release number, 10=minor release number, x=patchlevel. The stable
|
||||
release never changes except for patches that address bugs or
|
||||
@ -14,6 +16,156 @@ specifies the release date of a stable release or snapshot release.
|
||||
If you upgrade from Postfix 2.9 or earlier, read RELEASE_NOTES-2.10
|
||||
before proceeding.
|
||||
|
||||
Incompatible changes with snapshot 20131217
|
||||
===========================================
|
||||
|
||||
The master_service_disable syntax has changed: use "service/type"
|
||||
instead of "service.type". The new form is consistent with master.cf
|
||||
parameter namespaces. The old form is still supported to avoid
|
||||
breaking existing configurations.
|
||||
|
||||
Major changes with with snapshot 20131217
|
||||
=========================================
|
||||
|
||||
Support for advanced master.cf query and update operations. This
|
||||
was implemented primarily to support automated system management
|
||||
tools.
|
||||
|
||||
The goal is to make all Postfix master.cf details accessible as
|
||||
lists of "name=value" pairs, where the names are organized into
|
||||
structured name spaces. This allows other programs to query
|
||||
information or request updates, without having to worry about the
|
||||
exact layout of master.cf files.
|
||||
|
||||
Managing master.cf service attributes
|
||||
-------------------------------------
|
||||
|
||||
First, an example that shows the smtp/inet service in the traditional
|
||||
form:
|
||||
|
||||
$ postconf -M smtp/inet
|
||||
smtp inet n - n - - smtpd
|
||||
|
||||
Different variants of this command show different amounts of output.
|
||||
For example, "postconf -M smtp" enumerates all services that have
|
||||
a name "smtp" and any service type ("inet", "unix", etc.), and
|
||||
"postconf -M" enumerates all master.cf services.
|
||||
|
||||
General rule: each name component that is not present becomes a "*"
|
||||
wildcard.
|
||||
|
||||
Coming back to the above example, the postconf -F option can now
|
||||
enumerate the smtp/inet service fields as follows:
|
||||
|
||||
$ postconf -F smtp/inet
|
||||
smtp/inet/service = smtp
|
||||
smtp/inet/type = inet
|
||||
smtp/inet/private = n
|
||||
smtp/inet/unprivileged = -
|
||||
smtp/inet/chroot = n
|
||||
smtp/inet/wakeup = -
|
||||
smtp/inet/process_limit = -
|
||||
smtp/inet/command = smtpd
|
||||
|
||||
This form makes it very easy to change one field in master.cf.
|
||||
For example to turn on chroot on the smtp/inet service you use:
|
||||
|
||||
$ postconf -F smtp/inet/chroot=y
|
||||
$ postfix reload
|
||||
|
||||
Moreover, with "-F" you can specify "*" for service name or service
|
||||
type to get a wild-card match. For example, to turn off chroot on
|
||||
all Postfix daemons, use this:
|
||||
|
||||
$ postconf -F '*/*/chroot=n'
|
||||
$ postfix reload
|
||||
|
||||
Managing master.cf service "-o parameter=value" settings
|
||||
--------------------------------------------------------
|
||||
|
||||
For a second example, let's look at the submission service. This
|
||||
service typically has multiple "-o parameter=value" overrides. First
|
||||
the traditional view:
|
||||
|
||||
$ postconf -Mf submission
|
||||
submission inet n - n - - smtpd
|
||||
-o smtpd_tls_security_level=encrypt
|
||||
-o smtpd_sasl_auth_enable=yes
|
||||
...
|
||||
|
||||
The postconf -P option can now enumerate these parameters as follows:
|
||||
|
||||
$ postconf -P submission
|
||||
submission/inet/smtpd_sasl_auth_enable = yes
|
||||
submission/inet/smtpd_tls_security_level = encrypt
|
||||
...
|
||||
|
||||
Again, this form makes it very easy to modify one parameter
|
||||
setting. For example, to change the smtpd_tls_security_level setting
|
||||
for the submission/inet service:
|
||||
|
||||
$ postconf -P 'submission/inet/smtpd_tls_security_level=may'
|
||||
|
||||
You can create or remove a parametername=parametervalue setting:
|
||||
|
||||
Create:
|
||||
$ postconf -P 'submission/inet/parametername=parametervalue'
|
||||
|
||||
Remove:
|
||||
$ postconf -PX submission/inet/parametername
|
||||
|
||||
Finally, always execute "postfix reload" after updating master.cf.
|
||||
|
||||
Managing master.cf service entries
|
||||
----------------------------------
|
||||
|
||||
Finally, adding master.cf entries is possible, but currently this
|
||||
does not yet have "advanced" support. It can only be done at the
|
||||
level of the traditional master.cf file format.
|
||||
|
||||
Suppose that you need to configure a Postfix SMTP client that will
|
||||
handle slow email deliveries. To implement this you need to clone
|
||||
the smtp/unix service settings and create a new delay/unix service.
|
||||
|
||||
First, you would enumerate the smtp/unix service like this:
|
||||
|
||||
$ postconf -M smtp/unix
|
||||
smtp unix - - n - - smtp
|
||||
|
||||
Then you would copy those fields (except the first field) by hand
|
||||
to create the delay/unix service:
|
||||
|
||||
$ postconf -M delay/unix="delay unix - - n - - smtp"
|
||||
|
||||
To combine the above steps in one command:
|
||||
|
||||
$ postconf -M delay/unix="`postconf -M smtp/unix|awk '{$1 = "delay"}'`"
|
||||
|
||||
This is perhaps not super-convenient for manual cloning, but it
|
||||
should be sufficient for programmatic configuration management.
|
||||
|
||||
Again, always execute "postfix reload" after updating master.cf.
|
||||
|
||||
Deleting or commenting out master.cf entries
|
||||
--------------------------------------------
|
||||
|
||||
The -X (delete entry) and -# (comment out entry) options already
|
||||
exist for main.cf, and they now also work work for entire master.cf
|
||||
entries:
|
||||
|
||||
Remove main.cf or master.cf entry:
|
||||
$ postconf -X parametername
|
||||
$ postconf -MX delay/unix
|
||||
|
||||
Comment out main.cf or master.cf entry:
|
||||
$ postconf -# parametername
|
||||
$ postconf -M# delay/unix
|
||||
|
||||
As with main.cf, there is no support to "undo" master.cf changes
|
||||
that are made with -X or -#.
|
||||
|
||||
Again, always execute "postfix reload" after updating master.cf.
|
||||
|
||||
Major changes with snapshot 20131031
|
||||
====================================
|
||||
|
||||
|
@ -264,6 +264,7 @@ $readme_directory/INSTALL:f:root:-:644
|
||||
$readme_directory/IPV6_README:f:root:-:644
|
||||
$readme_directory/LDAP_README:f:root:-:644
|
||||
$readme_directory/LINUX_README:f:root:-:644
|
||||
$readme_directory/LMDB_README:f:root:-:644
|
||||
$readme_directory/LOCAL_RECIPIENT_README:f:root:-:644
|
||||
$readme_directory/MACOSX_README:f:root:-:644:o
|
||||
$readme_directory/MAILDROP_README:f:root:-:644
|
||||
@ -319,6 +320,7 @@ $html_directory/INSTALL.html:f:root:-:644
|
||||
$html_directory/IPV6_README.html:f:root:-:644
|
||||
$html_directory/LDAP_README.html:f:root:-:644
|
||||
$html_directory/LINUX_README.html:f:root:-:644
|
||||
$html_directory/LMDB_README.html:f:root:-:644
|
||||
$html_directory/LOCAL_RECIPIENT_README.html:f:root:-:644
|
||||
$html_directory/MAILDROP_README.html:f:root:-:644
|
||||
$html_directory/MILTER_README.html:f:root:-:644
|
||||
|
@ -428,13 +428,13 @@ tables are implemented:
|
||||
|
||||
<dl>
|
||||
|
||||
<dt> <b><a href="DATABASE_README.html#types">unix</a>:passwd.byname</b> </dt>
|
||||
<dt> <b>unix:passwd.byname</b> </dt>
|
||||
|
||||
<dd>The table is the UNIX password database. The key is a login
|
||||
name. The result is a password file entry in passwd(5) format.
|
||||
</dd>
|
||||
|
||||
<dt> <b><a href="DATABASE_README.html#types">unix</a>:group.byname</b> </dt>
|
||||
<dt> <b>unix:group.byname</b> </dt>
|
||||
|
||||
<dd> The table is the UNIX group database. The key is a group name.
|
||||
The result is a group file entry in group(5) format. </dd>
|
||||
|
@ -233,7 +233,7 @@ creates a "generic" database when none exists. </p>
|
||||
generic: Makefile
|
||||
@echo Creating $@
|
||||
@rm -f $@.tmp
|
||||
@printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` > $@.tmp
|
||||
@printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` > $@.tmp
|
||||
@mv $@.tmp generic
|
||||
|
||||
%.<a href="CDB_README.html">cdb</a>: %
|
||||
|
@ -209,7 +209,7 @@ described in the <a href="postconf.5.html">postconf(5)</a> manual page. </p>
|
||||
<a href="postconf.5.html#smtpd_data_restrictions">smtpd_data_restrictions</a> = <a href="postconf.5.html#reject_unauth_pipelining">reject_unauth_pipelining</a>
|
||||
|
||||
# Enforce mail volume quota via policy service callouts.
|
||||
<a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a> = <a href="postconf.5.html#check_policy_service">check_policy_service</a> <a href="DATABASE_README.html#types">unix</a>:private/policy
|
||||
<a href="postconf.5.html#smtpd_end_of_data_restrictions">smtpd_end_of_data_restrictions</a> = <a href="postconf.5.html#check_policy_service">check_policy_service</a> unix:private/policy
|
||||
</pre>
|
||||
|
||||
<p> Each restriction list is evaluated from left to right until
|
||||
|
@ -235,8 +235,8 @@ or to a UNIX-domain socket. Examples: </p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
inet:127.0.0.1:9998
|
||||
<a href="DATABASE_README.html#types">unix</a>:/some/where/policy
|
||||
<a href="DATABASE_README.html#types">unix</a>:private/policy
|
||||
unix:/some/where/policy
|
||||
unix:private/policy
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
@ -261,7 +261,7 @@ daemon, you would use something like this: </p>
|
||||
6 <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
|
||||
7 ...
|
||||
8 <a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>
|
||||
9 <a href="postconf.5.html#check_policy_service">check_policy_service</a> <a href="DATABASE_README.html#types">unix</a>:private/policy
|
||||
9 <a href="postconf.5.html#check_policy_service">check_policy_service</a> unix:private/policy
|
||||
10 ...
|
||||
11 <a href="postconf.5.html#transport_time_limit">policy_time_limit</a> = 3600
|
||||
</pre>
|
||||
@ -411,7 +411,7 @@ processes only: </p>
|
||||
7 <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> =
|
||||
8 ...
|
||||
9 <a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>
|
||||
10 <a href="postconf.5.html#check_policy_service">check_policy_service</a> <a href="DATABASE_README.html#types">unix</a>:private/greylist
|
||||
10 <a href="postconf.5.html#check_policy_service">check_policy_service</a> unix:private/greylist
|
||||
11 ...
|
||||
</pre>
|
||||
</blockquote>
|
||||
@ -454,7 +454,7 @@ a built-in suffix (in the above example: "_time_limit"). </p>
|
||||
</ul>
|
||||
|
||||
<p> With Solaris < 9, or Postfix < 2.10 on any Solaris
|
||||
version, use inet: style sockets instead of <a href="DATABASE_README.html#types">unix</a>:
|
||||
version, use inet: style sockets instead of unix:
|
||||
style, as detailed in the "<a href="#client_config">Policy
|
||||
client/server configuration</a>" section above. </p>
|
||||
|
||||
@ -492,7 +492,7 @@ forged MAIL FROM domains could be found at
|
||||
6 <a href="postconf.5.html#check_sender_access">check_sender_access</a> <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_access
|
||||
7 ...
|
||||
8 <a href="postconf.5.html#smtpd_restriction_classes">smtpd_restriction_classes</a> = greylist
|
||||
9 greylist = <a href="postconf.5.html#check_policy_service">check_policy_service</a> <a href="DATABASE_README.html#types">unix</a>:private/greylist
|
||||
9 greylist = <a href="postconf.5.html#check_policy_service">check_policy_service</a> unix:private/greylist
|
||||
10
|
||||
11 /etc/postfix/sender_access:
|
||||
12 aol.com greylist
|
||||
@ -548,7 +548,7 @@ most of the delays and most of the database pollution problem. </p>
|
||||
4 ...
|
||||
5 <a href="postconf.5.html#reject_unauth_destination">reject_unauth_destination</a>
|
||||
6 <a href="postconf.5.html#check_sender_access">check_sender_access</a> <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/sender_access
|
||||
7 <a href="postconf.5.html#check_policy_service">check_policy_service</a> <a href="DATABASE_README.html#types">unix</a>:private/policy
|
||||
7 <a href="postconf.5.html#check_policy_service">check_policy_service</a> unix:private/policy
|
||||
8 ...
|
||||
9
|
||||
10 /etc/postfix/sender_access:
|
||||
|
@ -226,9 +226,11 @@ size of the server TLS handshake. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<li> <p> If you use <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> TLSA "2 0 1" or "2 1 1" records to
|
||||
<li> <p> If you publish <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> TLSA "2 0 1" or "2 1 1" records to
|
||||
specify root CA certificate digests, you must include the corresponding
|
||||
root CA certificates in the "server.pem" certificate file. </p>
|
||||
root CA certificates in the "server.pem" certificate file. See the
|
||||
documentation of the <a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> <a href="postconf.5.html">main.cf</a>
|
||||
parameter. </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -236,29 +238,20 @@ root CA certificates in the "server.pem" certificate file. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Remote SMTP clients will
|
||||
be able to use the TLSA record you publish (which only contains the
|
||||
certificate digest) only if they have access to the corresponding
|
||||
certificate. Failure to verify certificates per the server's
|
||||
published TLSA records will typically cause the SMTP client to defer
|
||||
mail delivery. The foregoing also applies to "2 0 2" and "2 1 2"
|
||||
TLSA records or any other digest of a CA certificate, but it is
|
||||
expected that SHA256 will be by far the most common digest for TLSA.
|
||||
You are <i>strongly</i> urged to likewise include the root CA
|
||||
certificate in your server certificate file even if you use "0 0
|
||||
1" or "0 1 1" TLSA records. Some DANE implementations in SMTP
|
||||
clients (Postfix among them) may treat <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> certificate usages
|
||||
"0" and "2" interchangeably. </p>
|
||||
<p> Remote SMTP clients will be able to use the TLSA record you
|
||||
publish (which only contains the certificate digest) only if they
|
||||
have access to the corresponding certificate. Failure to verify
|
||||
certificates per the server's published TLSA records will typically
|
||||
cause the SMTP client to defer mail delivery. The foregoing also
|
||||
applies to "2 0 2" and "2 1 2" TLSA records or any other digest of
|
||||
a CA certificate, but it is expected that SHA256 will be by far the
|
||||
most common digest for TLSA. </p>
|
||||
|
||||
<p>By default, support for TLSA records that specify certificate
|
||||
usage "0" via a digest is disabled in the Postfix SMTP client. As
|
||||
a best practice, publish either "3 0 1" or "3 1 1" TLSA associations
|
||||
that specify the SHA256 digest of the server certificate public key
|
||||
with the alias-expanded hostname of each STARTTLS capable SMTP
|
||||
server. These continue to work when a certificate is renewed with
|
||||
the same public/private key pair. See the documentation of the
|
||||
<a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> <a href="postconf.5.html">main.cf</a> parameter for details.
|
||||
</p>
|
||||
<p> As a best practice, publish either "3 0 1" or "3 1 1" TLSA
|
||||
associations that specify the SHA256 digest of the server certificate
|
||||
public key with the alias-expanded hostname of each STARTTLS capable
|
||||
SMTP server. These continue to work when a certificate is renewed
|
||||
with the same public/private key pair. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -614,7 +607,7 @@ from scratch. </p>
|
||||
|
||||
<p> Since Postfix uses multiple <a href="smtpd.8.html">smtpd(8)</a> service processes, an
|
||||
in-memory cache is not sufficient for session re-use. Clients store
|
||||
at most one cached session per server and are very unlikey to
|
||||
at most one cached session per server and are very unlikely to
|
||||
repeatedly connect to the same server process. Thus session caching
|
||||
in the Postfix SMTP server generally requires a shared cache (an
|
||||
alternative available with Postfix ≥ 2.11 is described below).
|
||||
@ -861,8 +854,8 @@ certificates</a> that use <b>only</b> the anonymous ciphers. This is
|
||||
enabled by explicitly setting "<a href="postconf.5.html#smtpd_tls_cert_file">smtpd_tls_cert_file</a> = none"
|
||||
and not specifying an <a href="postconf.5.html#smtpd_tls_dcert_file">smtpd_tls_dcert_file</a> or <a href="postconf.5.html#smtpd_tls_eccert_file">smtpd_tls_eccert_file</a>. </p>
|
||||
|
||||
<p> Example, MSA that requires TLSv1, not SSLv2 or SSLv3, with high grade
|
||||
ciphers: </p>
|
||||
<p> Example, MSA that requires TLSv1 or higher, not SSLv2 or SSLv3,
|
||||
with high grade ciphers: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -872,9 +865,9 @@ ciphers: </p>
|
||||
<a href="postconf.5.html#smtpd_tls_mandatory_ciphers">smtpd_tls_mandatory_ciphers</a> = high
|
||||
<a href="postconf.5.html#smtpd_tls_mandatory_exclude_ciphers">smtpd_tls_mandatory_exclude_ciphers</a> = aNULL, MD5
|
||||
<a href="postconf.5.html#smtpd_tls_security_level">smtpd_tls_security_level</a> = encrypt
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
# Preferred syntax with Postfix ≥ 2.5:
|
||||
<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = TLSv1
|
||||
</pre>
|
||||
</blockquote>
|
||||
@ -918,23 +911,27 @@ secure for most situations. </p>
|
||||
</blockquote>
|
||||
|
||||
<p> Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later
|
||||
allows TLS servers to preempt the TLS client's cipher preference list.
|
||||
allows TLS servers to preempt the TLS client's cipher-suite preference list.
|
||||
This is possible only with SSLv3 and later, as in SSLv2 the client
|
||||
chooses the cipher from a list supplied by the server. </p>
|
||||
chooses the cipher-suite from a list supplied by the server. </p>
|
||||
|
||||
<p> By default, the OpenSSL server selects the client's most preferred
|
||||
cipher that the server supports. With SSLv3 and later, the server
|
||||
may choose its own most preferred cipher that is supported (offered)
|
||||
cipher-suite that the server supports. With SSLv3 and later, the server
|
||||
may choose its own most preferred cipher-suite that is supported (offered)
|
||||
by the client. Setting "<a href="postconf.5.html#tls_preempt_cipherlist">tls_preempt_cipherlist</a> = yes" enables server
|
||||
cipher preferences. The default OpenSSL behavior applies with
|
||||
cipher-suite preferences. The default OpenSSL behavior applies with
|
||||
"<a href="postconf.5.html#tls_preempt_cipherlist">tls_preempt_cipherlist</a> = no". </p>
|
||||
|
||||
<p> While server cipher selection may in some cases lead to a more secure
|
||||
or performant cipher choice, there is some risk of interoperability
|
||||
issues. In the past, some SSL clients have listed lower priority ciphers
|
||||
that they did not implement correctly. If the server chooses a cipher
|
||||
that the client prefers less, it may select a cipher whose client
|
||||
implementation is flawed. </p>
|
||||
<p> While server cipher-suite selection may in some cases lead to
|
||||
a more secure or performant cipher-suite choice, there is some risk
|
||||
of interoperability issues. In the past, some SSL clients have
|
||||
listed lower priority ciphers that they did not implement correctly.
|
||||
If the server chooses a cipher that the client prefers less, it may
|
||||
select a cipher whose client implementation is flawed. Most notably
|
||||
Windows 2003 Microsoft Exchange servers have flawed implementations
|
||||
of DES-CBC3-SHA, which OpenSSL considers stronger than RC4-SHA.
|
||||
Enabling server cipher-suite selection may create interoperability
|
||||
issues with Windows 2003 Microsoft Exchange clients. </p>
|
||||
|
||||
<h3><a name="server_misc"> Miscellaneous server controls</a> </h3>
|
||||
|
||||
@ -1251,17 +1248,30 @@ the mandatory "dane-only" level. </p>
|
||||
href="#client_tls_may">opportunistic</a> TLS that is resistant to
|
||||
man in the middle and downgrade attacks when the destination domain
|
||||
uses DNSSEC to publish DANE TLSA records for its MX hosts. If a
|
||||
remote SMTP server has usable DANE TLSA records, these will be used
|
||||
to authenticate the server. If TLSA records are published for a
|
||||
given remote SMTP server (implying TLS support), but are not usable
|
||||
due to unsupported parameters, the Postfix SMTP client will use <a
|
||||
remote SMTP server has "usable" (see <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>) DANE TLSA records,
|
||||
the server connection will be authenticated. When DANE authentication
|
||||
fails, there is no fallback to unauthenticated or plaintext delivery. </p>
|
||||
|
||||
<p> If TLSA records are published for a given remote SMTP server
|
||||
(implying TLS support), but are all "unusable" due to unsupported
|
||||
parameters or malformed data, the Postfix SMTP client will use <a
|
||||
href="#client_tls_encrypt">mandatory</a> unauthenticated TLS.
|
||||
Otherwise, the Postfix SMTP client behavior is the same as with <a
|
||||
href="#client_tls_may">may</a>. </p>
|
||||
Otherwise, when no TLSA records are published, the Postfix SMTP
|
||||
client behavior is the same as with <a href="#client_tls_may">may</a>. </p>
|
||||
|
||||
<p> TLSA records must be published in DNSSEC validated DNS zones.
|
||||
Any TLSA records in DNS zones not protected via DNSSEC are ignored.
|
||||
The Postfix SMTP client will not look for TLSA records associated
|
||||
with MX hosts whose "A" or "AAAA" records lie in an "insecure" DNS
|
||||
zone. Such lookups have been observed to cause interoperability
|
||||
issues with poorly implemented DNS servers, and are in any case not
|
||||
expected to ever yield "secure" results, since that would require
|
||||
a very unlikely DLV DNS trust anchor configured between the host
|
||||
record and the associated "_25._tcp" child TLSA record. </p>
|
||||
|
||||
<p> The "dane-only" level is a form of <a
|
||||
href="#client_tls_secure">secure-channel</a> TLS based on the DANE PKI.
|
||||
If usable TLSA records are present these are used to authenticate the
|
||||
If "usable" TLSA records are present these are used to authenticate the
|
||||
remote SMTP server. Otherwise, or when server certificate verification
|
||||
fails, delivery via the server in question tempfails. </p>
|
||||
|
||||
@ -1271,73 +1281,51 @@ to be in effect, the destination domain's containing DNS zone must
|
||||
be signed and the Postfix SMTP client's operating system must be
|
||||
configured to send its DNS queries to a recursive DNS nameserver
|
||||
that is able to validate the signed records. Each MX host's DNS
|
||||
zone should also be signed, and should publish DANE TLSA (<a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>)
|
||||
zone needs to also be signed, and needs to publish DANE TLSA (<a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>)
|
||||
records that specify how that MX host's TLS certificate is to be
|
||||
verified. TLSA records do not preempt the normal SMTP MX host
|
||||
verified. </p>
|
||||
|
||||
<p> TLSA records do not preempt the normal SMTP MX host
|
||||
selection algorithm, if some MX hosts support TLSA and others do
|
||||
not, TLS security will vary from delivery to delivery. It is up
|
||||
to the domain owner to configure their MX hosts and their DNS
|
||||
sensibly. To configure the Postfix SMTP client for DNSSEC lookups
|
||||
see the documentation for the <a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a> <a href="postconf.5.html">main.cf</a>
|
||||
parameter. The <a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> <a href="postconf.5.html">main.cf</a> parameter
|
||||
controls optional support for trust-anchor digest TLSA records.
|
||||
controls support for trust-anchor digest TLSA records. The
|
||||
<a href="postconf.5.html#tls_dane_digests">tls_dane_digests</a> and tls_dane_digest_agility parameters control
|
||||
the list of supported digests and digest downgrade attack resistance.
|
||||
</p>
|
||||
|
||||
<p> The Postfix SMTP client deviates from <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> in cases where
|
||||
strict adherence is likely to create opportunities for delayed (or
|
||||
eventually bounced) email with no substantive security gain. Most
|
||||
notably, it is not expected that <a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> and <a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a>
|
||||
can reasonably include every public CA that a remote SMTP server's
|
||||
administrator may believe to be well-known. Therefore, certificate
|
||||
usages "0" and "2" from <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> which are intended to "constrain"
|
||||
existing PKI trust, are instead treated as "trust assertions" and
|
||||
mapped to "1" and "3" respectively. That is, with certificate usage
|
||||
"0" and "2", Postfix will not require the remote SMTP server's
|
||||
certificate to be trusted with respect to any locally defined public
|
||||
CAs, it is the domain owner's responsibility to ensure that the
|
||||
certificate associations in their TLSA records are appropriate
|
||||
to authenticate their SMTP servers. </p>
|
||||
<p> DANE for SMTP MTAs deviates in some details from the baseline
|
||||
DANE protocol in <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>. Most notably, it is not expected that
|
||||
SMTP MTAs can reasonably include every public CA that a remote SMTP
|
||||
server's administrator may believe to be well-known. Nor is there
|
||||
an interactive user to "click OK" when authentication fails. </p>
|
||||
|
||||
<p> In addition, the Postfix SMTP client does not assume that the
|
||||
remote SMTP server will necessarily be configured to present the
|
||||
certificate of any usage "0" root CA in its TLS protocol <a
|
||||
href="https://tools.ietf.org/html/rfc2246#section-7.4.2">certificate_list</a>.
|
||||
Therefore, support for usage "0" certificate and public-key digests
|
||||
is disabled by default, see <a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> for
|
||||
details. While undigested trust-anchor certificates in TLSA records
|
||||
are supported, publishing complete certificates in DNS is unwise
|
||||
given the resulting excessively large DNS record sizes. Therefore,
|
||||
in its default configuration the Postfix SMTP client essentially
|
||||
supports only certificate usages "1", "2" and "3" (with "1" treated as
|
||||
though it were "3"). </p>
|
||||
<p> Therefore, certificate usages "0" and "1" from <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> which
|
||||
are intended to "constrain" existing PKI trust, are not supported.
|
||||
TLSA records with usage "0" are treated as "unusable". TLSA records
|
||||
with usage "1" are instead treated as "trust assertions" and mapped
|
||||
to usage "3". Specifically, with certificate usage "1", Postfix
|
||||
will not require the remote SMTP server's certificate to be trusted
|
||||
with respect to any locally defined public CAs, it is the domain
|
||||
owner's responsibility to ensure that the certificate associations
|
||||
in their TLSA records are appropriate to authenticate their SMTP
|
||||
servers. </p>
|
||||
|
||||
<p> Finally, the interaction of DANE with MX hostnames that are
|
||||
CNAMEs differs from the draft specification in the names used to
|
||||
construct the associated <a
|
||||
href="https://tools.ietf.org/html/draft-ietf-dane-srv-02#section-3.2">TLSA
|
||||
queries</a>. When the MX hostname is a CNAME, the draft proposal
|
||||
to use the unexpanded MX hostname in TLSA lookups is fragile and
|
||||
unintuitive. For this to work, the domain owner has to either
|
||||
duplicate the TLSA records of the target (host, service) pair in
|
||||
his own DNS or furnish the target host with an additional
|
||||
certificate and private key that would be negotiated via SNI.
|
||||
Neither of these are robust or easy to manage. It is far better
|
||||
to expand the CNAME recursively to the underlying target hostname
|
||||
(keeping track of DNSSEC validation along the way) and to use the
|
||||
expanded name to construct the TLSA query and, if appropriate, in
|
||||
server certificate name checks. This is the approach taken by the
|
||||
Postfix SMTP client, and if sanity prevails will also be the approach
|
||||
taken in the final standard. </p>
|
||||
<p> The Postfix SMTP client supports only certificate usages "2"
|
||||
and "3" (with "1" treated as though it were "3"). See
|
||||
<a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> for usage "2" usability
|
||||
considerations. Support for certificate usage "1" is an experiment,
|
||||
it may be withdrawn in the future. Server operators SHOULD NOT
|
||||
publish TLSA records with usage "1". </p>
|
||||
|
||||
<p> When usable TLSA records are obtained for the remote SMTP server
|
||||
the Postfix SMTP client is obligated to include the SNI TLS extension
|
||||
in its SSL client hello message. This may help the remote SMTP
|
||||
server live up to its promise to provide a certificate that matches
|
||||
its TLSA records. Since TLS extensions require TLS 1.0 or later,
|
||||
the Postfix SMTP client must disable SSLv2 and SSLv3 when SNI is
|
||||
required. If you use "dane" or "dane-only", do not disable TLSv1,
|
||||
except perhaps via the policy table for destinations which you are
|
||||
sure will support TLSv1.1 or TLSv1.2. </p>
|
||||
the Postfix SMTP client sends the SNI TLS extension in its SSL
|
||||
client hello message. This may help the remote SMTP server live
|
||||
up to its promise to provide a certificate that matches its TLSA
|
||||
records. </p>
|
||||
|
||||
<p> For purposes of protocol and cipher selection, the "dane"
|
||||
security level is treated like a "mandatory" TLS security level,
|
||||
@ -1357,14 +1345,14 @@ certificate must contain at least one of these names. </p>
|
||||
<p> When a DANE TLSA record specifies an end-entity (EE) certificate,
|
||||
(that is the actual server certificate), as with the fingerprint
|
||||
security level below, no name checks or certificate expiration checks
|
||||
are applied. The server certificate (or its public key) either matches
|
||||
are applied. The server certificate (or its public key) either matches
|
||||
the DANE record or not. Server administrators should publish such
|
||||
EE records in preference to all other types. </p>
|
||||
|
||||
<p> The pre-requisites for DANE support in the Postfix SMTP client are: </p>
|
||||
<ul>
|
||||
<li> A <i>compile-time</i> OpenSSL library that supports the TLS SNI
|
||||
extension and the "sha256" and "sha512" message digests.
|
||||
extension and "SHA-2" message digests.
|
||||
<li> A <i>compile-time</i> DNS resolver library that supports DNSSEC.
|
||||
Postfix binaries built on an older system will not support DNSSEC even
|
||||
if deployed on a system with an updated resolver library.
|
||||
@ -2068,12 +2056,13 @@ server has a greater opportunity to mandate client security policy when
|
||||
it is a dedicated MSA that only handles outbound mail from trusted clients,
|
||||
below we focus on the client security policy. </p>
|
||||
|
||||
<p> On the SMTP client, there are further complications. When delivering
|
||||
mail to a given domain, in contrast to HTTPS, one rarely uses the domain
|
||||
name directly as the target host of the SMTP session. More typically,
|
||||
one uses MX lookups - these are usually unauthenticated - to obtain the domain's SMTP server
|
||||
hostname(s). When, as is current practice, the client verifies the
|
||||
insecurely obtained MX hostname, it is subject to a DNS man-in-the-middle
|
||||
<p> On the SMTP client, there are further complications. When
|
||||
delivering mail to a given domain, in contrast to HTTPS, one rarely
|
||||
uses the domain name directly as the target host of the SMTP session.
|
||||
More typically, one uses MX lookups — these are usually
|
||||
unauthenticated — to obtain the domain's SMTP server hostname(s).
|
||||
When, as is current practice, the client verifies the insecurely
|
||||
obtained MX hostname, it is subject to a DNS man-in-the-middle
|
||||
attack. </p>
|
||||
|
||||
<p> Adoption of DNSSEC and <a href="http://tools.ietf.org/html/rfc6698">RFC6698</a> (DANE) may gradually (as domains
|
||||
@ -2184,24 +2173,19 @@ DNSSEC. If no TLSA records are found, the effective security level
|
||||
used is <a href="#client_tls_may">may</a>. If TLSA records are
|
||||
found, but none are usable, the effective security level is <a
|
||||
href="#client_tls_encrypt">encrypt</a>. When usable TLSA records
|
||||
are obtained for the remote SMTP server, SSLv2 and SSLv3 are
|
||||
automatically disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the
|
||||
server certificate must match the TLSA records. The
|
||||
<a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> parameter controls optional
|
||||
support for trust-anchor digest TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
are obtained for the remote SMTP server, SSLv2 is automatically
|
||||
disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate
|
||||
must match the TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication
|
||||
and DNSSEC support is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
<dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
|
||||
The TLS policy for the destination is obtained via TLSA records in
|
||||
DNSSEC. If no TLSA records are found, or none are usable, no
|
||||
connection is made to the server. When usable TLSA records are
|
||||
obtained for the remote SMTP server, SSLv2 and SSLv3 are automatically
|
||||
disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate
|
||||
must match the TLSA records. The <a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a>
|
||||
parameter controls optional support for trust-anchor digest TLSA
|
||||
records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication and DNSSEC support is
|
||||
available with Postfix 2.11 and later. </dd>
|
||||
obtained for the remote SMTP server, SSLv2 is automatically disabled
|
||||
(see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>), and the server certificate must
|
||||
match the TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication and
|
||||
DNSSEC support is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
<dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
|
||||
fingerprint verification.</a> Available with Postfix 2.5 and
|
||||
@ -2291,9 +2275,8 @@ Example:
|
||||
/etc/postfix/tls_policy:
|
||||
example.edu none
|
||||
example.mil may
|
||||
example.gov encrypt protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.com verify
|
||||
match=hostname:dot-nexthop protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.gov encrypt ciphers=high
|
||||
example.com verify match=hostname:dot-nexthop ciphers=high
|
||||
example.net secure
|
||||
.example.net secure match=.example.net:example.net
|
||||
[mail.example.org]:587 secure match=nexthop
|
||||
@ -2407,7 +2390,7 @@ the SSL/TLS protocols used with opportunistic TLS. </p>
|
||||
<a href="postconf.5.html#smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a> = aNULL
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2
|
||||
# Alternative form.
|
||||
# Legacy form for Postifx < 2.5:
|
||||
<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = SSLv3, TLSv1
|
||||
# Also available with Postfix ≥ 2.6:
|
||||
<a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a> = export
|
||||
|
@ -410,7 +410,7 @@ examples (use only one): </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
<a href="postconf.5.html#virtual_transport">virtual_transport</a> = <a href="lmtp.8.html">lmtp</a>:<a href="DATABASE_README.html#types">unix</a>:/path/name (uses UNIX-domain socket)
|
||||
<a href="postconf.5.html#virtual_transport">virtual_transport</a> = <a href="lmtp.8.html">lmtp</a>:unix:/path/name (uses UNIX-domain socket)
|
||||
<a href="postconf.5.html#virtual_transport">virtual_transport</a> = <a href="lmtp.8.html">lmtp</a>:hostname:port (uses TCP socket)
|
||||
<a href="postconf.5.html#virtual_transport">virtual_transport</a> = maildrop: (uses <a href="pipe.8.html">pipe(8)</a> to command)
|
||||
</pre>
|
||||
|
@ -34,16 +34,16 @@ LMDB_TABLE(5) LMDB_TABLE(5)
|
||||
When a transaction fails due to a full database, Postfix
|
||||
resizes the database and retries the transaction.
|
||||
|
||||
Postfix access, address mapping and routing tables will
|
||||
generate partial search keys such as domain names without
|
||||
one or more subdomains, network addresses without one or
|
||||
more least-significant octets, or email addresses without
|
||||
the localpart, address extension or domain portion. This
|
||||
behavior is also found with <a href="DATABASE_README.html#types">btree</a>:, <a href="DATABASE_README.html#types">hash</a>:, or <a href="ldap_table.5.html">ldap</a>:
|
||||
tables.
|
||||
Postfix access, address mapping and routing table lookups
|
||||
may generate partial search keys such as domain names
|
||||
without one or more subdomains, network addresses without
|
||||
one or more least-significant octets, or email addresses
|
||||
without the localpart, address extension or domain por-
|
||||
tion. This behavior is also found with <a href="DATABASE_README.html#types">btree</a>:, <a href="DATABASE_README.html#types">hash</a>:, or
|
||||
<a href="ldap_table.5.html">ldap</a>: tables.
|
||||
|
||||
Unlike other flat-file based Postfix databases, changes to
|
||||
an LMDB database do not require automatic daemon program
|
||||
an LMDB database do not trigger automatic daemon program
|
||||
restart.
|
||||
|
||||
<b>RELIABILITY</b>
|
||||
@ -56,10 +56,12 @@ LMDB_TABLE(5) LMDB_TABLE(5)
|
||||
The Postfix LMDB adapter implements locking with fcntl(2)
|
||||
locks at whole-file granularity. LMDB's native locking
|
||||
scheme would require world-writable lockfiles and would
|
||||
therefore violate the Postfix security model. Unlike some
|
||||
other Postfix flat-file databases, LMDB databases can
|
||||
safely be updated without serializing requests through the
|
||||
<a href="proxymap.8.html">proxymap(8)</a> service.
|
||||
therefore violate the Postfix security model.
|
||||
|
||||
Multiple processes can safely update an LMDB database
|
||||
without serializing requests through the <a href="proxymap.8.html">proxymap(8)</a> ser-
|
||||
vice. This makes LMDB suitable as a shared cache for <a href="verify.8.html">ver-</a>
|
||||
<a href="verify.8.html">ify(8)</a> or <a href="postscreen.8.html">postscreen(8)</a> services.
|
||||
|
||||
<b>CONFIGURATION PARAMETERS</b>
|
||||
Short-lived programs automatically pick up changes to
|
||||
|
@ -598,14 +598,13 @@ SMTP(8) SMTP(8)
|
||||
hostname is not an alias and its address records
|
||||
lie in an unsigned zone.
|
||||
|
||||
<b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> (trust-anchor-asser-</b>
|
||||
<b>tion)</b>
|
||||
<b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> (yes)</b>
|
||||
<a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> trust-anchor digest support in the Postfix
|
||||
TLS library.
|
||||
|
||||
<b><a href="postconf.5.html#tlsmgr_service_name">tlsmgr_service_name</a> (tlsmgr)</b>
|
||||
The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in mas-
|
||||
ter.cf.
|
||||
The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">mas-
|
||||
ter.cf</a>.
|
||||
|
||||
<b>OBSOLETE STARTTLS CONTROLS</b>
|
||||
The following configuration parameters exist for compati-
|
||||
|
@ -609,7 +609,9 @@ LOCAL(8) LOCAL(8)
|
||||
|
||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||
The set of characters that can separate a user name
|
||||
from its address extension (user+foo).
|
||||
from its extension (example: user+foo), or a .for-
|
||||
ward file name from its extension (example: .for-
|
||||
ward+foo).
|
||||
|
||||
<b><a href="postconf.5.html#require_home_directory">require_home_directory</a> (no)</b>
|
||||
Require that a <a href="local.8.html"><b>local</b>(8)</a> recipient's home directory
|
||||
|
@ -41,12 +41,12 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5)
|
||||
"inet:" followed by a hostname or address, ":", and
|
||||
a port name or number. Specify an IPv6 address
|
||||
inside "[]". For a UNIX-domain server specify
|
||||
"<a href="DATABASE_README.html#types">unix</a>:" followed by the socket pathname. Examples:
|
||||
"unix:" followed by the socket pathname. Examples:
|
||||
|
||||
memcache = inet:memcache.example.com:11211
|
||||
memcache = inet:127.0.0.1:11211
|
||||
memcache = inet:[fc00:8d00:189::3]:11211
|
||||
memcache = <a href="DATABASE_README.html#types">unix</a>:/path/to/socket
|
||||
memcache = unix:/path/to/socket
|
||||
|
||||
NOTE: to access a UNIX-domain socket with the <a href="proxymap.8.html">prox-</a>
|
||||
<a href="proxymap.8.html">ymap(8)</a> server, the socket must be accessible by
|
||||
|
@ -80,10 +80,10 @@ MYSQL_TABLE(5) MYSQL_TABLE(5)
|
||||
|
||||
<b>MYSQL PARAMETERS</b>
|
||||
<b>hosts</b> The hosts that Postfix will try to connect to and
|
||||
query from. Specify <i><a href="DATABASE_README.html#types">unix</a>:</i> for UNIX domain sockets,
|
||||
query from. Specify <i>unix:</i> for UNIX domain sockets,
|
||||
<i>inet:</i> for TCP connections (default). Example:
|
||||
hosts = host1.some.domain host2.some.domain:port
|
||||
hosts = <a href="DATABASE_README.html#types">unix</a>:/file/name
|
||||
hosts = unix:/file/name
|
||||
|
||||
The hosts are tried in random order, with all con-
|
||||
nections over UNIX domain sockets being tried
|
||||
|
@ -86,10 +86,10 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
||||
|
||||
<b>PGSQL PARAMETERS</b>
|
||||
<b>hosts</b> The hosts that Postfix will try to connect to and
|
||||
query from. Specify <i><a href="DATABASE_README.html#types">unix</a>:</i> for UNIX-domain sockets,
|
||||
query from. Specify <i>unix:</i> for UNIX-domain sockets,
|
||||
<i>inet:</i> for TCP connections (default). Example:
|
||||
hosts = host1.some.domain host2.some.domain:port
|
||||
hosts = <a href="DATABASE_README.html#types">unix</a>:/file/name
|
||||
hosts = unix:/file/name
|
||||
|
||||
The hosts are tried in random order, with all con-
|
||||
nections over UNIX domain sockets being tried
|
||||
@ -97,7 +97,7 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
|
||||
matically closed after being idle for about 1
|
||||
minute, and are re-opened as necessary.
|
||||
|
||||
NOTE: the <i><a href="DATABASE_README.html#types">unix</a>:</i> and <i>inet:</i> prefixes are accepted for
|
||||
NOTE: the <i>unix:</i> and <i>inet:</i> prefixes are accepted for
|
||||
backwards compatibility reasons, but are actually
|
||||
ignored. The PostgreSQL client library will always
|
||||
try to connect to an UNIX socket if the name starts
|
||||
|
@ -488,7 +488,9 @@ PIPE(8) PIPE(8)
|
||||
|
||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||
The set of characters that can separate a user name
|
||||
from its address extension (user+foo).
|
||||
from its extension (example: user+foo), or a .for-
|
||||
ward file name from its extension (example: .for-
|
||||
ward+foo).
|
||||
|
||||
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
|
||||
The syslog facility of Postfix logging.
|
||||
|
@ -15,13 +15,35 @@ POSTCONF(1) POSTCONF(1)
|
||||
<b>postconf</b> [<b>-dfhnovx</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<b>-C</b> <i>class,...</i>] [<i>param-</i>
|
||||
<i>eter ...</i>]
|
||||
|
||||
<b>postconf</b> [<b>-ev</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>parameter=value ...</i>]
|
||||
<b>postconf</b> [<b>-ev</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] <i>parameter=value ...</i>
|
||||
|
||||
<b>postconf</b> [<b>-#vX</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>parameter ...</i>]
|
||||
<b>postconf</b> [<b>-#vX</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] <i>parameter ...</i>
|
||||
|
||||
<b>Managing <a href="master.5.html">master.cf</a>:</b>
|
||||
<b>Managing <a href="master.5.html">master.cf</a> service entries:</b>
|
||||
|
||||
<b>postconf</b> [<b>-fMovx</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>service ...</i>]
|
||||
<b>postconf</b> [<b>-fMovx</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>service</i>[<b>/</b><i>type</i>] <i>...</i>]
|
||||
|
||||
<b>postconf</b> [<b>-eMv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] <i>service</i><b>/</b><i>type=value ...</i>
|
||||
|
||||
<b>postconf</b> [<b>-#MvX</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] <i>service</i><b>/</b><i>type ...</i>
|
||||
|
||||
<b>Managing <a href="master.5.html">master.cf</a> service fields:</b>
|
||||
|
||||
<b>postconf</b> [<b>-fFovx</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>service</i>[<b>/</b><i>type</i>[<b>/</b><i>field</i>]]
|
||||
<i>...</i>]
|
||||
|
||||
<b>postconf</b> [<b>-eFv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] <i>service</i><b>/</b><i>type</i><b>/</b><i>field=value</i>
|
||||
<i>...</i>
|
||||
|
||||
<b>Managing <a href="master.5.html">master.cf</a> service parameters:</b>
|
||||
|
||||
<b>postconf</b> [<b>-fPovx</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>service</i>[<b>/</b><i>type</i>[<b>/</b><i>parame-</i>
|
||||
<i>ter</i>]] <i>...</i>]
|
||||
|
||||
<b>postconf</b> [<b>-ePv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] <i>service</i><b>/</b><i>type</i><b>/</b><i>parame-</i>
|
||||
<i>ter=value ...</i>
|
||||
|
||||
<b>postconf</b> [<b>-PXv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] <i>service</i><b>/</b><i>type</i><b>/</b><i>parameter ...</i>
|
||||
|
||||
<b>Managing bounce message templates:</b>
|
||||
|
||||
@ -35,73 +57,73 @@ POSTCONF(1) POSTCONF(1)
|
||||
By default, the <a href="postconf.1.html"><b>postconf</b>(1)</a> command displays the values of
|
||||
<a href="postconf.5.html"><b>main.cf</b></a> configuration parameters, and warns about possible
|
||||
mis-typed parameter names (Postfix 2.9 and later). It can
|
||||
also change <a href="postconf.5.html"><b>main.cf</b></a> configuration parameter values, or
|
||||
display other configuration information about the Postfix
|
||||
also change <a href="postconf.5.html"><b>main.cf</b></a> configuration parameter values, or
|
||||
display other configuration information about the Postfix
|
||||
mail system.
|
||||
|
||||
Options:
|
||||
|
||||
<b>-a</b> List the available SASL server plug-in types. The
|
||||
SASL plug-in type is selected with the
|
||||
<b>-a</b> List the available SASL server plug-in types. The
|
||||
SASL plug-in type is selected with the
|
||||
<b><a href="postconf.5.html#smtpd_sasl_type">smtpd_sasl_type</a></b> configuration parameter by specify-
|
||||
ing one of the names listed below.
|
||||
|
||||
<b>cyrus</b> This server plug-in is available when Post-
|
||||
<b>cyrus</b> This server plug-in is available when Post-
|
||||
fix is built with Cyrus SASL support.
|
||||
|
||||
<b>dovecot</b>
|
||||
This server plug-in uses the Dovecot authen-
|
||||
tication server, and is available when Post-
|
||||
fix is built with any form of SASL support.
|
||||
|
||||
This feature is available with Postfix 2.3 and
|
||||
later.
|
||||
|
||||
<b>-A</b> List the available SASL client plug-in types. The
|
||||
SASL plug-in type is selected with the
|
||||
<b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b> or <b><a href="postconf.5.html#lmtp_sasl_type">lmtp_sasl_type</a></b> configuration
|
||||
parameters by specifying one of the names listed
|
||||
below.
|
||||
|
||||
<b>cyrus</b> This client plug-in is available when Post-
|
||||
fix is built with Cyrus SASL support.
|
||||
|
||||
This feature is available with Postfix 2.3 and
|
||||
later.
|
||||
|
||||
<b>-b</b> [<i>template</i><b>_</b><i>file</i>]
|
||||
Display the message text that appears at the begin-
|
||||
ning of delivery status notification (DSN) mes-
|
||||
sages, replacing $<b>name</b> expressions with actual val-
|
||||
ues as described in <a href="bounce.5.html"><b>bounce</b>(5)</a>.
|
||||
|
||||
To override the built-in templates, specify a tem-
|
||||
plate file name at the end of the <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
|
||||
mand line, or specify a file name in <a href="postconf.5.html"><b>main.cf</b></a> with
|
||||
the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.
|
||||
|
||||
To force selection of the built-in templates, spec-
|
||||
ify an empty template file name on the <a href="postconf.1.html"><b>postconf</b>(1)</a>
|
||||
command line (in shell language: "").
|
||||
fix is built with any form of SASL support.
|
||||
|
||||
This feature is available with Postfix 2.3 and
|
||||
later.
|
||||
|
||||
<b>-A</b> List the available SASL client plug-in types. The
|
||||
SASL plug-in type is selected with the
|
||||
<b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b> or <b><a href="postconf.5.html#lmtp_sasl_type">lmtp_sasl_type</a></b> configuration
|
||||
parameters by specifying one of the names listed
|
||||
below.
|
||||
|
||||
<b>cyrus</b> This client plug-in is available when Post-
|
||||
fix is built with Cyrus SASL support.
|
||||
|
||||
This feature is available with Postfix 2.3 and
|
||||
later.
|
||||
|
||||
<b>-b</b> [<i>template</i><b>_</b><i>file</i>]
|
||||
Display the message text that appears at the begin-
|
||||
ning of delivery status notification (DSN) mes-
|
||||
sages, replacing $<b>name</b> expressions with actual val-
|
||||
ues as described in <a href="bounce.5.html"><b>bounce</b>(5)</a>.
|
||||
|
||||
To override the built-in templates, specify a tem-
|
||||
plate file name at the end of the <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
|
||||
mand line, or specify a file name in <a href="postconf.5.html"><b>main.cf</b></a> with
|
||||
the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.
|
||||
|
||||
To force selection of the built-in templates, spec-
|
||||
ify an empty template file name on the <a href="postconf.1.html"><b>postconf</b>(1)</a>
|
||||
command line (in shell language: "").
|
||||
|
||||
This feature is available with Postfix 2.3 and
|
||||
later.
|
||||
|
||||
<b>-c</b> <i>config</i><b>_</b><i>dir</i>
|
||||
The <a href="postconf.5.html"><b>main.cf</b></a> configuration file is in the named
|
||||
The <a href="postconf.5.html"><b>main.cf</b></a> configuration file is in the named
|
||||
directory instead of the default configuration
|
||||
directory.
|
||||
|
||||
<b>-C</b> <i>class,...</i>
|
||||
When displaying <a href="postconf.5.html"><b>main.cf</b></a> parameters, select only
|
||||
When displaying <a href="postconf.5.html"><b>main.cf</b></a> parameters, select only
|
||||
parameters from the specified class(es):
|
||||
|
||||
<b>builtin</b>
|
||||
Parameters with built-in names.
|
||||
|
||||
<b>service</b>
|
||||
Parameters with service-defined names (the
|
||||
first field of a <a href="master.5.html"><b>master.cf</b></a> entry plus a
|
||||
Parameters with service-defined names (the
|
||||
first field of a <a href="master.5.html"><b>master.cf</b></a> entry plus a
|
||||
Postfix-defined suffix).
|
||||
|
||||
<b>user</b> Parameters with user-defined names.
|
||||
@ -111,18 +133,41 @@ POSTCONF(1) POSTCONF(1)
|
||||
The default is as if "<b>-C all</b>" is specified.
|
||||
|
||||
<b>-d</b> Print <a href="postconf.5.html"><b>main.cf</b></a> default parameter settings instead of
|
||||
actual settings. Specify <b>-df</b> to fold long lines
|
||||
actual settings. Specify <b>-df</b> to fold long lines
|
||||
for human readability (Postfix 2.9 and later).
|
||||
|
||||
<b>-e</b> Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and update
|
||||
parameter settings with the "<i>name=value</i>" pairs on
|
||||
the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line. The file is copied to
|
||||
a temporary file then renamed into place. Specify
|
||||
quotes to protect special characters and whitespace
|
||||
on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
|
||||
<b>-e</b> Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and update
|
||||
parameter settings with the "<i>name=value</i>" pairs on
|
||||
the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
|
||||
|
||||
The <b>-e</b> is no longer needed with Postfix version 2.8
|
||||
and later.
|
||||
With <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and
|
||||
replace one or more service entries with new values
|
||||
as specified with "<i>service/type=value</i>" on the <a href="postconf.1.html"><b>post-</b></a>
|
||||
<a href="postconf.1.html"><b>conf</b>(1)</a> command line.
|
||||
|
||||
With <b>-F</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and
|
||||
replace one or more service fields with new values
|
||||
as specied with "<i>service/type/field=value</i>" on the
|
||||
<a href="postconf.1.html"><b>postconf</b>(1)</a> command line. Currently, the "command"
|
||||
field contains the command name and command argu-
|
||||
ments. this may change in the near future, so that
|
||||
the "command" field contains only the command name,
|
||||
and a new "arguments" pseudofield contains the com-
|
||||
mand arguments.
|
||||
|
||||
With <b>-P</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and
|
||||
add or update one or more service parameter set-
|
||||
tings (-o parameter=value settings) with new values
|
||||
as specied with "<i>service/type/parameter=value</i>" on
|
||||
the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
|
||||
|
||||
In all cases the file is copied to a temporary file
|
||||
then renamed into place. Specify quotes to protect
|
||||
special characters and whitespace on the <a href="postconf.1.html"><b>post-</b></a>
|
||||
<a href="postconf.1.html"><b>conf</b>(1)</a> command line.
|
||||
|
||||
The <b>-e</b> option is no longer needed with Postfix ver-
|
||||
sion 2.8 and later.
|
||||
|
||||
<b>-f</b> Fold long lines when printing <a href="postconf.5.html"><b>main.cf</b></a> or <a href="master.5.html"><b>master.cf</b></a>
|
||||
configuration file entries, for human readability.
|
||||
@ -130,8 +175,22 @@ POSTCONF(1) POSTCONF(1)
|
||||
This feature is available with Postfix 2.9 and
|
||||
later.
|
||||
|
||||
<b>-h</b> Show <a href="postconf.5.html"><b>main.cf</b></a> parameter values without the "<i>name</i> = "
|
||||
label that normally precedes the value.
|
||||
<b>-F</b> Show <a href="master.5.html"><b>master.cf</b></a> per-entry field settings (by default
|
||||
all services and all fields), formatted as one
|
||||
"<i>service/type/field=value</i>" per line. Specify <b>-Ff</b> to
|
||||
fold long lines.
|
||||
|
||||
Specify one or more "<i>service/type/field</i>" instances
|
||||
on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line to limit the output
|
||||
to fields of interest. Trailing parameter name or
|
||||
service type fields that are omitted will be han-
|
||||
dled as "*" wildcard fields.
|
||||
|
||||
This feature is available with Postfix 2.11 and
|
||||
later.
|
||||
|
||||
<b>-h</b> Show parameter or attribute values without the
|
||||
"<i>name</i> = " label that normally precedes the value.
|
||||
|
||||
<b>-l</b> List the names of all supported mailbox locking
|
||||
methods. Postfix supports the following methods:
|
||||
@ -195,15 +254,15 @@ POSTCONF(1) POSTCONF(1)
|
||||
A non-shared, in-memory hash table. Its con-
|
||||
tent are lost when a process terminates.
|
||||
|
||||
<b>ldap</b> (read-only)
|
||||
LDAP database client. This is described in
|
||||
<a href="ldap_table.5.html"><b>ldap_table</b>(5)</a>.
|
||||
|
||||
<b>lmdb</b> OpenLDAP LMDB database (a memory-mapped,
|
||||
persistent file). Available on systems with
|
||||
support for LMDB databases. This is
|
||||
support for LMDB databases. This is
|
||||
described in <a href="lmdb_table.5.html"><b>lmdb_table</b>(5)</a>.
|
||||
|
||||
<b>ldap</b> (read-only)
|
||||
LDAP database client. This is described in
|
||||
<a href="ldap_table.5.html"><b>ldap_table</b>(5)</a>.
|
||||
|
||||
<b>memcache</b>
|
||||
Memcache database client. This is described
|
||||
in <a href="memcache_table.5.html"><b>memcache_table</b>(5)</a>.
|
||||
@ -213,12 +272,6 @@ POSTCONF(1) POSTCONF(1)
|
||||
with support for MySQL databases. This is
|
||||
described in <a href="mysql_table.5.html"><b>mysql_table</b>(5)</a>.
|
||||
|
||||
<b>nis</b> (read-only)
|
||||
NIS client.
|
||||
|
||||
<b>nisplus</b> (read-only)
|
||||
NIS+ client.
|
||||
|
||||
<b>pcre</b> (read-only)
|
||||
A lookup table based on Perl Compatible Reg-
|
||||
ular Expressions. The file format is
|
||||
@ -274,13 +327,13 @@ POSTCONF(1) POSTCONF(1)
|
||||
database. The following tables are imple-
|
||||
mented:
|
||||
|
||||
<b><a href="DATABASE_README.html#types">unix</a>:passwd.byname</b>
|
||||
<b>unix:passwd.byname</b>
|
||||
The table is the UNIX password data-
|
||||
base. The key is a login name. The
|
||||
result is a password file entry in
|
||||
<b>passwd</b>(5) format.
|
||||
|
||||
<b><a href="DATABASE_README.html#types">unix</a>:group.byname</b>
|
||||
<b>unix:group.byname</b>
|
||||
The table is the UNIX group database.
|
||||
The key is a group name. The result
|
||||
is a group file entry in <b>group</b>(5)
|
||||
@ -293,28 +346,52 @@ POSTCONF(1) POSTCONF(1)
|
||||
file contents. Specify <b>-Mf</b> to fold long lines for
|
||||
human readability.
|
||||
|
||||
If <i>service ...</i> is specified, only the matching ser-
|
||||
vices will be output. For example, "<b>postconf -Mf</b>
|
||||
<b>inet</b>" will output all services that listen on the
|
||||
network.
|
||||
Specify zero or more arguments, each with a <i>ser-</i>
|
||||
<i>vice-name</i> or <i>service-name/service-type</i> pair, where
|
||||
<i>service-name</i> is the first field of a <a href="master.5.html">master.cf</a>
|
||||
entry and <i>service-type</i> is one of (<b>inet</b>, <b>unix</b>, <b>fifo</b>,
|
||||
or <b>pass</b>).
|
||||
|
||||
Specify zero or more arguments, each with a <i>ser-</i>
|
||||
<i>vice-type</i> name (<b>inet</b>, <b>unix</b>, <b>fifo</b>, or <b>pass</b>) or with
|
||||
a <i>service-name.service-type</i> pair, where <i>service-</i>
|
||||
<i>name</i> is the first field of a <a href="master.5.html">master.cf</a> entry.
|
||||
If <i>service-name</i> or <i>service-name/service-type</i> is
|
||||
specified, only the matching <a href="master.5.html">master.cf</a> entries will
|
||||
be output. For example, "<b>postconf -Mf smtp</b>" will
|
||||
output all services named "smtp", and "<b>postconf -Mf</b>
|
||||
<b>smtp/inet</b>" will output only the smtp service that
|
||||
listens on the network. Trailing service type
|
||||
fields that are omitted will be handled as "*"
|
||||
wildcard fields.
|
||||
|
||||
This feature is available with Postfix 2.9 and
|
||||
later.
|
||||
This feature is available with Postfix 2.9 and
|
||||
later. The syntax was changed from "<i>name.type</i>" to
|
||||
"<i>name/type</i>", and "*" wildcard support was added
|
||||
with Postfix 2.11.
|
||||
|
||||
<b>-n</b> Show only configuration parameters that have
|
||||
explicit <i>name=value</i> settings in <a href="postconf.5.html"><b>main.cf</b></a>. Specify
|
||||
<b>-n</b> Show only configuration parameters that have
|
||||
explicit <i>name=value</i> settings in <a href="postconf.5.html"><b>main.cf</b></a>. Specify
|
||||
<b>-nf</b> to fold long lines for human readability (Post-
|
||||
fix 2.9 and later).
|
||||
|
||||
<b>-o</b> <i>name=value</i>
|
||||
Override <a href="postconf.5.html"><b>main.cf</b></a> parameter settings.
|
||||
|
||||
This feature is available with Postfix 2.10 and
|
||||
This feature is available with Postfix 2.10 and
|
||||
later.
|
||||
|
||||
<b>-p</b> Show <a href="postconf.5.html"><b>main.cf</b></a> parameter settings. This is the
|
||||
default.
|
||||
|
||||
<b>-P</b> Show <a href="master.5.html"><b>master.cf</b></a> service parameter settings (by
|
||||
default all services and all parameters). format-
|
||||
ted as one "<i>service/type/parameter=value</i>" per line.
|
||||
Specify <b>-Pf</b> to fold long lines.
|
||||
|
||||
Specify one or more "<i>service/type/parameter</i>"
|
||||
instances on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line to limit
|
||||
the output to parameters of interest. Trailing
|
||||
parameter name or service type fields that are
|
||||
omitted will be handled as "*" wildcard fields.
|
||||
|
||||
This feature is available with Postfix 2.11 and
|
||||
later.
|
||||
|
||||
<b>-t</b> [<i>template</i><b>_</b><i>file</i>]
|
||||
@ -346,25 +423,51 @@ POSTCONF(1) POSTCONF(1)
|
||||
|
||||
<b>-X</b> Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and remove the
|
||||
parameters named on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
|
||||
The file is copied to a temporary file then renamed
|
||||
into place. Specify a list of parameter names, not
|
||||
"<i>name=value</i>" pairs. There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
|
||||
mand to perform the reverse operation.
|
||||
Specify a list of parameter names, not "<i>name=value</i>"
|
||||
pairs.
|
||||
|
||||
This feature is available with Postfix 2.10 and
|
||||
later.
|
||||
With <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and
|
||||
remove one or more service entries as specified
|
||||
with "<i>service/type</i>" on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command
|
||||
line.
|
||||
|
||||
With <b>-P</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and
|
||||
remove one or more service parameter settings (-o
|
||||
parameter=value settings) as specied with "<i>ser-</i>
|
||||
<i>vice/type/parameter</i>" on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command
|
||||
line.
|
||||
|
||||
In all cases the file is copied to a temporary file
|
||||
then renamed into place. Specify quotes to protect
|
||||
special characters on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
|
||||
|
||||
There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the
|
||||
reverse operation.
|
||||
|
||||
This feature is available with Postfix 2.10 and
|
||||
later. Support for -M and -P was added with Post-
|
||||
fix 2.11.
|
||||
|
||||
<b>-#</b> Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and comment
|
||||
out the parameters named on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command
|
||||
line, so that those parameters revert to their
|
||||
default values. The file is copied to a temporary
|
||||
file then renamed into place. Specify a list of
|
||||
parameter names, not "<i>name=value</i>" pairs. There is
|
||||
no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the reverse oper-
|
||||
ation.
|
||||
default values. Specify a list of parameter names,
|
||||
not "<i>name=value</i>" pairs.
|
||||
|
||||
With <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and
|
||||
comment out one or more service entries as speci-
|
||||
fied with "<i>service/type</i>" on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command
|
||||
line.
|
||||
|
||||
In all cases the file is copied to a temporary file
|
||||
then renamed into place. Specify quotes to protect
|
||||
special characters on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
|
||||
|
||||
There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the
|
||||
reverse operation.
|
||||
|
||||
This feature is available with Postfix 2.6 and
|
||||
later.
|
||||
later. Support for -M was added with Postfix 2.11.
|
||||
|
||||
<b>DIAGNOSTICS</b>
|
||||
Problems are reported to the standard error stream.
|
||||
@ -374,41 +477,39 @@ POSTCONF(1) POSTCONF(1)
|
||||
Directory with Postfix configuration files.
|
||||
|
||||
<b>CONFIGURATION PARAMETERS</b>
|
||||
The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant
|
||||
The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant
|
||||
to this program.
|
||||
|
||||
The text below provides only a parameter summary. See
|
||||
The text below provides only a parameter summary. See
|
||||
<a href="postconf.5.html"><b>postconf</b>(5)</a> for more details including examples.
|
||||
|
||||
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
|
||||
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
|
||||
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
|
||||
<a href="master.5.html">master.cf</a> configuration files.
|
||||
|
||||
<b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a> (empty)</b>
|
||||
Pathname of a configuration file with bounce mes-
|
||||
Pathname of a configuration file with bounce mes-
|
||||
sage templates.
|
||||
|
||||
<b>FILES</b>
|
||||
/etc/postfix/<a href="postconf.5.html">main.cf</a>, Postfix configuration parameters
|
||||
/etc/postfix/<a href="master.5.html">master.cf</a>, Postfix master daemon configuraton
|
||||
/etc/postfix/<a href="master.5.html">master.cf</a>, Postfix master daemon configuration
|
||||
|
||||
<b>SEE ALSO</b>
|
||||
<a href="bounce.5.html">bounce(5)</a>, bounce template file format
|
||||
<a href="master.5.html">master(5)</a>, <a href="master.5.html">master.cf</a> configuration file syntax
|
||||
<a href="postconf.5.html">postconf(5)</a>, <a href="postconf.5.html">main.cf</a> configuration file syntax
|
||||
<a href="bounce.5.html">bounce(5)</a>, bounce template file format <a href="master.5.html">master(5)</a>, <a href="master.5.html">master.cf</a>
|
||||
configuration file syntax <a href="postconf.5.html">postconf(5)</a>, <a href="postconf.5.html">main.cf</a> configuration
|
||||
file syntax
|
||||
|
||||
<b>README FILES</b>
|
||||
<a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
Wietse Venema
|
||||
IBM T.J. Watson Research
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
Wietse Venema IBM T.J. Watson Research P.O. Box 704 Yorktown
|
||||
Heights, NY 10598, USA
|
||||
|
||||
POSTCONF(1)
|
||||
</pre> </body> </html>
|
||||
|
@ -5220,7 +5220,7 @@ system. </p>
|
||||
</DD>
|
||||
|
||||
<DT><b><a name="local_recipient_maps">local_recipient_maps</a>
|
||||
(default: <a href="proxymap.8.html">proxy</a>:<a href="DATABASE_README.html#types">unix</a>:passwd.byname $<a href="postconf.5.html#alias_maps">alias_maps</a>)</b></DT><DD>
|
||||
(default: <a href="proxymap.8.html">proxy</a>:unix:passwd.byname $<a href="postconf.5.html#alias_maps">alias_maps</a>)</b></DT><DD>
|
||||
|
||||
<p> Lookup tables with all names or addresses of local recipients:
|
||||
a recipient address is local when its domain matches $<a href="postconf.5.html#mydestination">mydestination</a>,
|
||||
@ -8558,23 +8558,27 @@ Example:
|
||||
(default: empty)</b></DT><DD>
|
||||
|
||||
<p> The set of characters that can separate a user name from its
|
||||
address extension (user+foo). See <a href="canonical.5.html">canonical(5)</a>, <a href="local.8.html">local(8)</a>, <a href="relocated.5.html">relocated(5)</a>
|
||||
and <a href="virtual.5.html">virtual(5)</a> for the effects this has on aliases, canonical,
|
||||
virtual, and relocated lookups. Basically, the software tries
|
||||
user+foo and .forward+foo before trying user and .forward. </p>
|
||||
|
||||
<p> This implementation recognizes one delimiter character per email
|
||||
address, and one address extension per email address. </p>
|
||||
extension (example: user+foo), or a .forward file name from its
|
||||
extension (example: .forward+foo). Basically, the software tries
|
||||
user+foo and .forward+foo before trying user and .forward. This
|
||||
implementation recognizes one delimiter character and one extension
|
||||
per email address or .forward file name. </p>
|
||||
|
||||
<p> When the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> set contains multiple characters
|
||||
(Postfix 2.11 and later), a user name is separated from its address
|
||||
extension by the first character that matches the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>
|
||||
set. </p>
|
||||
(Postfix 2.11 and later), a user name or .forward file name is
|
||||
separated from its extension by the first character that matches
|
||||
the <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> set. </p>
|
||||
|
||||
<p> See <a href="canonical.5.html">canonical(5)</a>, <a href="local.8.html">local(8)</a>, <a href="relocated.5.html">relocated(5)</a> and <a href="virtual.5.html">virtual(5)</a> for the
|
||||
effects of <a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> on lookups in aliases, canonical,
|
||||
virtual, and relocated maps, and see the <a href="postconf.5.html#propagate_unmatched_extensions">propagate_unmatched_extensions</a>
|
||||
parameter for propagating an extension from one email address to
|
||||
another. </p>
|
||||
|
||||
<p> When used in <a href="postconf.5.html#command_execution_directory">command_execution_directory</a>, <a href="postconf.5.html#forward_path">forward_path</a>, or
|
||||
<a href="postconf.5.html#luser_relay">luser_relay</a>, ${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>} is replaced
|
||||
with the recipient delimiter that was found in the recipient email
|
||||
address (Postfix 2.11 and later), or it is replaced with the <a href="postconf.5.html">main.cf</a>
|
||||
<a href="postconf.5.html#luser_relay">luser_relay</a>, ${<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a>} is replaced with the actual
|
||||
recipient delimiter that was found in the recipient email address
|
||||
(Postfix 2.11 and later), or it is replaced with the <a href="postconf.5.html">main.cf</a>
|
||||
<a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> parameter value (Postfix 2.10 and earlier).
|
||||
</p>
|
||||
|
||||
@ -9550,7 +9554,7 @@ IP address),
|
||||
transport map,
|
||||
|
||||
<li> if mail is sent via a UNIX-domain socket: a pathname (without
|
||||
the <a href="DATABASE_README.html#types">unix</a>: prefix),
|
||||
the unix: prefix),
|
||||
|
||||
<li> a /file/name with domain names and/or <a href="postconf.5.html#relayhost">relay host</a> names as
|
||||
defined above,
|
||||
@ -11479,6 +11483,35 @@ whitespace, commas or colons. In the policy table "protocols" attribute
|
||||
empty value means allow all protocols. The valid protocol names, (see
|
||||
<b>SSL_get_version(3)</b>), are "SSLv2", "SSLv3" and "TLSv1". </p>
|
||||
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax was expanded to support
|
||||
protocol exclusions. One can explicitly exclude "SSLv2" by setting
|
||||
"<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2". To exclude both "SSLv2" and
|
||||
"SSLv3" set "<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the underlying OpenSSL interface semantics.
|
||||
</p>
|
||||
|
||||
<p> The range of protocols advertised by an SSL/TLS client must be
|
||||
contiguous. When a protocol version is enabled, disabling any
|
||||
higher version implicitly disables all versions above that higher
|
||||
version. Thus, for example: </p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2, !TLSv1
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p> also disables any protocols version higher than TLSv1 leaving
|
||||
only "SSLv3" enabled. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". When Postfix ≤ 2.5 is linked against OpenSSL 1.0.1
|
||||
or later, these, or any other new protocol versions, cannot be
|
||||
disabled except by also disabling "TLSv1" (typically leaving just
|
||||
"SSLv3"). The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can explicitly disable support for
|
||||
"TLSv1.1" or "TLSv1.2". </p>
|
||||
|
||||
<p> At the <a href="TLS_README.html#client_tls_dane">dane</a> and
|
||||
<a href="TLS_README.html#client_tls_dane">dane-only</a> security
|
||||
levels, when usable TLSA records are obtained for the remote SMTP
|
||||
@ -11486,24 +11519,10 @@ server, the Postfix SMTP client is obligated to include the SNI TLS
|
||||
extension in its SSL client hello message. This may help the remote
|
||||
SMTP server live up to its promise to provide a certificate that
|
||||
matches its TLSA records. Since TLS extensions require TLS 1.0 or
|
||||
later, the Postfix SMTP client must disable SSLv2 and SSLv3 when
|
||||
later, the Postfix SMTP client must disable "SSLv2" and "SSLv3" when
|
||||
SNI is required. If you use "dane" or "dane-only" do not disable
|
||||
TLSv1, except perhaps via the policy table for destinations which
|
||||
you are sure will support TLSv1.1 or TLSv1.2. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax is expanded to support
|
||||
protocol exclusions. One can now explicitly exclude SSLv2 by setting
|
||||
"<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2". To exclude both SSLv2 and
|
||||
SSLv3 set "<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the behavior when the OpenSSL library is newer than Postfix.
|
||||
</p>
|
||||
you are sure will support "TLSv1.1" or "TLSv1.2". </p>
|
||||
|
||||
<p> Since SSL version 2 has known protocol weaknesses and is now
|
||||
deprecated, the default setting excludes "SSLv2". This means that by
|
||||
@ -11516,9 +11535,9 @@ and higher. </p>
|
||||
<p> Example: </p>
|
||||
|
||||
<pre>
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
# Preferred syntax with Postfix ≥ 2.5:
|
||||
<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = TLSv1
|
||||
</pre>
|
||||
|
||||
@ -11637,7 +11656,7 @@ which is either the recipient domain, or the verbatim next-hop
|
||||
specified in the transport table, $<a href="postconf.5.html#local_transport">local_transport</a>, $<a href="postconf.5.html#virtual_transport">virtual_transport</a>,
|
||||
$<a href="postconf.5.html#relay_transport">relay_transport</a> or $<a href="postconf.5.html#default_transport">default_transport</a>. This includes any enclosing
|
||||
square brackets and any non-default destination server port suffix. The
|
||||
LMTP socket type prefix (inet: or <a href="DATABASE_README.html#types">unix</a>:) is not included in the lookup
|
||||
LMTP socket type prefix (inet: or unix:) is not included in the lookup
|
||||
key. </p>
|
||||
|
||||
<p> Only the next-hop domain, or $<a href="postconf.5.html#myhostname">myhostname</a> with LMTP over UNIX-domain
|
||||
@ -11690,23 +11709,17 @@ the effective security level used is <a
|
||||
href="TLS_README.html#client_tls_may">may</a>. If TLSA records are
|
||||
found, but none are usable, the effective security level is <a
|
||||
href="TLS_README.html#client_tls_encrypt">encrypt</a>. When usable
|
||||
TLSA records are obtained for the remote SMTP server, SSLv2 and
|
||||
SSLv3 are automatically disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>),
|
||||
and the server certificate must match the TLSA records. The
|
||||
<a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> parameter controls optional
|
||||
support for trust-anchor digest TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
TLSA records are obtained for the remote SMTP server, the
|
||||
server certificate must match the TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE)
|
||||
TLS authentication and DNSSEC support is available with Postfix
|
||||
2.11 and later. </dd>
|
||||
|
||||
<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt>
|
||||
<dd>Mandatory DANE TLS. The TLS policy for the destination is
|
||||
obtained via TLSA records in DNSSEC. If no TLSA records are found,
|
||||
or none are usable, no connection is made to the server. When
|
||||
usable TLSA records are obtained for the remote SMTP server, SSLv2
|
||||
and SSLv3 are automatically disabled (see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a>),
|
||||
and the server certificate must match the TLSA records. The
|
||||
<a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> parameter controls optional
|
||||
support for trust-anchor digest TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS
|
||||
usable TLSA records are obtained for the remote SMTP server, the
|
||||
server certificate must match the TLSA records. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
|
||||
@ -11807,22 +11820,34 @@ separator is colon. An empty value means allow all protocols. The valid
|
||||
protocol names, (see <b>SSL_get_version(3)</b>), are "SSLv2", "SSLv3"
|
||||
and "TLSv1". </p>
|
||||
|
||||
<p> The range of protocols advertised by an SSL/TLS client must be
|
||||
contiguous. When a protocol version is enabled, disabling any
|
||||
higher version implicitly disables all versions above that higher
|
||||
version. Thus, for example: </p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
<a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> = !SSLv2, !TLSv1
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p> also disables any protocols version higher than TLSv1 leaving
|
||||
only "SSLv3" enabled. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
and "TLSv1.2". The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can explicitly disable support for
|
||||
"TLSv1.1" or "TLSv1.2"</p>
|
||||
|
||||
<p> To include a protocol list its name, to exclude it, prefix the name
|
||||
with a "!" character. To exclude SSLv2 even for opportunistic TLS set
|
||||
"<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a> = !SSLv2". To exclude both "SSLv2" and "SSLv3" set
|
||||
"<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a> = !SSLv2, !SSLv3". Explicitly listing the protocols to
|
||||
include, rather than protocols to exclude, is supported, but not
|
||||
recommended. The exclusion form more closely matches the behavior
|
||||
when the OpenSSL library is newer than Postfix. </p>
|
||||
recommended. The exclusion form more closely matches the underlying
|
||||
OpenSSL interface semantics. </p>
|
||||
|
||||
<p> Example: </p>
|
||||
<pre>
|
||||
# TLSv1 only!
|
||||
# TLSv1 or better:
|
||||
<a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a> = !SSLv2, !SSLv3
|
||||
</pre>
|
||||
|
||||
@ -11955,20 +11980,17 @@ parameter. When TLSA records are not found or are all unusable the
|
||||
effective security level is "may" or "encrypt" respectively. For
|
||||
purposes of protocol and cipher selection, the "dane" security level
|
||||
is treated like a "mandatory" TLS security level, and weak ciphers
|
||||
and protocols are disabled. SSLv2 and SSLv3 are automatically
|
||||
disabled when usable TLSA records are obtained for the remote SMTP
|
||||
server, see <a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> for details. Since DANE
|
||||
authenticates server certificates the "aNULL" cipher-suites are
|
||||
transparently excluded at this level, no need to configure this
|
||||
manually. The <a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> <a href="postconf.5.html">main.cf</a> parameter
|
||||
controls optional support for trust-anchor digest TLSA records.
|
||||
<a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
and protocols are disabled. Since DANE authenticates server
|
||||
certificates the "aNULL" cipher-suites are transparently excluded
|
||||
at this level, no need to configure this manually. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE)
|
||||
TLS authentication is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt>
|
||||
<dd>Mandatory DANE TLS. This is just like "dane" above, only DANE
|
||||
TLSA authentication is mandatory. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE) TLS authentication
|
||||
is available with Postfix 2.11 and later. </dd>
|
||||
<dd>Mandatory DANE TLS. This is just like "dane" above, but DANE
|
||||
TLSA authentication is required. There is no fallback to "may" or
|
||||
"encrypt" when TLSA records are missing or unusable. <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>
|
||||
(DANE) TLS authentication is available with Postfix 2.11 and later.
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="TLS_README.html#client_tls_fingerprint">fingerprint</a></b></dt>
|
||||
<dd>Certificate fingerprint verification.
|
||||
@ -13785,7 +13807,7 @@ supposed to give the result to another Postfix SMTP server process.
|
||||
</p>
|
||||
|
||||
<p> Specify "host:port" or "inet:host:port" for a TCP endpoint, or
|
||||
"<a href="DATABASE_README.html#types">unix</a>:pathname" for a UNIX-domain endpoint. The host can be specified
|
||||
"unix:pathname" for a UNIX-domain endpoint. The host can be specified
|
||||
as an IP address or as a symbolic name; no MX lookups are done.
|
||||
When no "host" or "host:" are specified, the local machine is
|
||||
assumed. Pathname interpretation is relative to the Postfix queue
|
||||
@ -13793,7 +13815,7 @@ directory. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.1 and later. </p>
|
||||
|
||||
<p> The "inet:" and "<a href="DATABASE_README.html#types">unix</a>:" prefixes are available in Postfix 2.3
|
||||
<p> The "inet:" and "unix:" prefixes are available in Postfix 2.3
|
||||
and later. </p>
|
||||
|
||||
|
||||
@ -15615,25 +15637,26 @@ works in addition to the exclusions listed with <a href="postconf.5.html#smtpd_t
|
||||
(default: !SSLv2)</b></DT><DD>
|
||||
|
||||
<p> The SSL/TLS protocols accepted by the Postfix SMTP server with
|
||||
mandatory TLS encryption. If the list is empty, the server supports all
|
||||
available SSL/TLS protocol versions. A non-empty value is a list
|
||||
of protocol
|
||||
names separated by whitespace, commas or colons. The supported protocol
|
||||
names are "SSLv2", "SSLv3" and "TLSv1", and are not case sensitive. </p>
|
||||
mandatory TLS encryption. If the list is empty, the server supports
|
||||
all available SSL/TLS protocol versions. A non-empty value is a
|
||||
list of protocol names separated by whitespace, commas or colons.
|
||||
The supported protocol names are "SSLv2", "SSLv3" and "TLSv1", and
|
||||
are not case sensitive. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax is expanded to support
|
||||
protocol exclusions. One can now explicitly exclude SSLv2 by setting
|
||||
"<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = !SSLv2". To exclude both SSLv2 and
|
||||
SSLv3 set "<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = !SSLv2, !SSLv3". Listing
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax was expanded to support
|
||||
protocol exclusions. One can explicitly exclude "SSLv2" by setting
|
||||
"<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = !SSLv2". To exclude both "SSLv2" and
|
||||
"SSLv3" set "<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the behavior when the OpenSSL library is newer than Postfix.
|
||||
</p>
|
||||
matches the underlying OpenSSL interface semantics. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". When Postfix ≤ 2.5 is linked against OpenSSL 1.0.1
|
||||
or later, these, or any other new protocol versions, cannot be
|
||||
disabled. The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or
|
||||
"TLSv1.2". </p>
|
||||
|
||||
<p> Since SSL version 2 has known protocol weaknesses and is now
|
||||
deprecated, the default setting excludes "SSLv2". This means that
|
||||
@ -15643,9 +15666,10 @@ level. </p>
|
||||
<p> Example: </p>
|
||||
|
||||
<pre>
|
||||
<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = TLSv1
|
||||
# Alternative form with Postfix ≥ 2.5:
|
||||
# Preferred syntax with Postfix ≥ 2.5:
|
||||
<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = !SSLv2, !SSLv3
|
||||
# Legacy syntax:
|
||||
<a href="postconf.5.html#smtpd_tls_mandatory_protocols">smtpd_tls_mandatory_protocols</a> = TLSv1
|
||||
</pre>
|
||||
|
||||
<p> This feature is available in Postfix 2.3 and later. </p>
|
||||
@ -15657,28 +15681,25 @@ level. </p>
|
||||
(default: empty)</b></DT><DD>
|
||||
|
||||
<p> List of TLS protocols that the Postfix SMTP server will exclude
|
||||
or include with opportunistic TLS encryption. This parameter SHOULD be
|
||||
left at its default empty value, allowing all protocols to be used with
|
||||
opportunistic TLS. </p>
|
||||
|
||||
<p> In <a href="postconf.5.html">main.cf</a> the values are separated by whitespace, commas or
|
||||
colons. An empty value means allow all protocols. The valid protocol
|
||||
names, (see <b>SSL_get_version(3)</b>), are "SSLv2", "SSLv3" and
|
||||
"TLSv1". In <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> table entries, "protocols" attribute
|
||||
values are separated by a colon. </p>
|
||||
or include with opportunistic TLS encryption. This parameter SHOULD
|
||||
be left at its default empty value, allowing all protocols to be
|
||||
used with opportunistic TLS. A non-empty value is a list of protocol
|
||||
names separated by whitespace, commas or colons. The supported
|
||||
protocol names are "SSLv2", "SSLv3" and "TLSv1", and are not case
|
||||
sensitive. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
and "TLSv1.2". The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or
|
||||
"TLSv1.2". </p>
|
||||
|
||||
<p> To include a protocol list its name, to exclude it, prefix the name
|
||||
with a "!" character. To exclude SSLv2 even for opportunistic TLS set
|
||||
"<a href="postconf.5.html#smtpd_tls_protocols">smtpd_tls_protocols</a> = !SSLv2". To exclude both "SSLv2" and "SSLv3" set
|
||||
"<a href="postconf.5.html#smtpd_tls_protocols">smtpd_tls_protocols</a> = !SSLv2, !SSLv3". Explicitly listing the protocols to
|
||||
include, rather than protocols to exclude, is supported, but not
|
||||
recommended. The exclusion form more closely matches the behavior
|
||||
when the OpenSSL library is newer than Postfix. </p>
|
||||
recommended. The exclusion form more closely matches the underlying
|
||||
OpenSSL interface semantics. </p>
|
||||
|
||||
<p> Example: </p>
|
||||
<pre>
|
||||
@ -16212,6 +16233,70 @@ bytes (equivalent to 256 bits) is sufficient to generate a 128bit
|
||||
<p> This feature is available in Postfix 2.2 and later. </p>
|
||||
|
||||
|
||||
</DD>
|
||||
|
||||
<DT><b><a name="tls_dane_digest_agility">tls_dane_digest_agility</a>
|
||||
(default: on)</b></DT><DD>
|
||||
|
||||
<p> Configure DANE TLSA digest algorithm agility. When digest
|
||||
algorithm agility is enabled, and the server and client support a
|
||||
common strong digest algorithm, TLSA records with weaker digest
|
||||
algorithms are ignored. </p>
|
||||
|
||||
<p> Specify one of the following: </p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><b>off</b></dt>
|
||||
<dd> DANE verification examines each well-formed record in the TLSA
|
||||
RRset whose matching type is either "0" (no hash used) or is one of
|
||||
the digest algorithms listed in $<a href="postconf.5.html#tls_dane_digests">tls_dane_digests</a>. This setting
|
||||
is not recommended. </dd>
|
||||
|
||||
<dt><b>on</b></dt>
|
||||
<dd> From each group of well-formed TLSA RRs a non-zero digest
|
||||
matching type with the same certificate usage and selector, DANE
|
||||
verification examines only those records whose matching type has
|
||||
the highest precedence (appear earliest in $<a href="postconf.5.html#tls_dane_digests">tls_dane_digests</a>).
|
||||
</dd>
|
||||
|
||||
<dt><b>maybe</b></dt>
|
||||
<dd> For compatibility with digest algorithm agility, each certificate
|
||||
or public key whose digest is included in a DANE TLSA RRset, SHOULD
|
||||
be published with the same set of digest matching type values as
|
||||
any other with the same usage and selector. Therefore, compatible
|
||||
TLSA RRsets will contain an identical count of well-formed RRs with
|
||||
each non-zero digest matching type for any fixed combination of
|
||||
usage and selector. When this constraint is violated, or any of
|
||||
the digest records are malformed, digest algorithm agility will
|
||||
disabled. Otherwise, digest algorithm agility is enabled. </dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<p> Digest algorithm agility ensures that the strongest digest
|
||||
supported by both the Postfix SMTP client and the remote server is
|
||||
used, and weaker digests are ignored. This supports non-disruptive
|
||||
deprecation of outdated digest algorithms. </p>
|
||||
|
||||
<p> To ensure compatibility with digest algorithm agility during
|
||||
key rotation, when a certificate or public key is being replaced
|
||||
with another, and both are published during the transition, both
|
||||
the old and the new certificate MUST be specified with the same set
|
||||
of digests. One can change the list of digest algorithms later,
|
||||
once old keys are retired. At any given time, change either the
|
||||
list of digests without changing the list of certificates or public
|
||||
keys or the list of certificates or public keys without changing
|
||||
the list of digests. Full value matching type "0" records are not
|
||||
subject to this constraint, but are discouraged due to the size of
|
||||
the resulting DNS records. </p>
|
||||
|
||||
<p> It is expected that this algorithm agility mechanism will be
|
||||
published in a standards track RFC for SMTP with DANE, and also in
|
||||
an eventual update to <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11 and later. </p>
|
||||
|
||||
|
||||
</DD>
|
||||
|
||||
<DT><b><a name="tls_dane_digests">tls_dane_digests</a>
|
||||
@ -16220,85 +16305,58 @@ bytes (equivalent to 256 bits) is sufficient to generate a 128bit
|
||||
<p> <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> TLSA resource-record "matching type" digest algorithms
|
||||
in descending preference order. All the specified algorithms must
|
||||
be supported by the underlying OpenSSL library, otherwise the Postfix
|
||||
SMTP client will not support DANE TLSA security. </p>
|
||||
SMTP client will not support DANE TLSA security. </p>
|
||||
|
||||
<p> Specify a list of digest names separated by commas and/or
|
||||
whitespace. Each digest name may be followed by an optional
|
||||
"=<number>" suffix. For example, "sha512" may instead be specified
|
||||
as "sha512=2" and "sha256" may instead be specified as "sha256=1".
|
||||
The optional number must match the <a
|
||||
href="https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types"
|
||||
>IANA</a> assigned TLSA matching type number the algorithm in question.
|
||||
Postfix will check this constraint for the algorithms it knows about.
|
||||
Additional matching type algorithms registered with IANA can be added
|
||||
with explicit numbers provided they are supported by OpenSSL. </p>
|
||||
|
||||
<p> Invalid list elements are logged with a warning and disable DANE
|
||||
support. TLSA RRs that specify digests not included in the list are
|
||||
ignored with a warning. </p>
|
||||
|
||||
<p> Note: It is unwise to omit sha256 from the digest list. This
|
||||
digest algorithm is the only mandatory to implement digest algorithm
|
||||
in <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>, and many servers are expected publish TLSA records
|
||||
with just sha256 digests. Unless one of the standard digests is
|
||||
seriously compromised and servers have had ample time to update their
|
||||
TLSA records you should not omit any standard digests, just arrange
|
||||
them in order from strongest to weakest. </p>
|
||||
|
||||
<p> When for a particular combination of "certificate usage" and
|
||||
"selector" the TLSA RRset contains a well-formed record with a
|
||||
matching type of "0", i.e. a full value of the associated certificate
|
||||
or public key, the Postfix SMTP client will ignore all other matching
|
||||
types for the same certificate usage and selector. In this case
|
||||
the first algorithm listed in <a href="postconf.5.html#tls_dane_digests">tls_dane_digests</a> will be used to
|
||||
compute a digest of the full value, which will then be used to match
|
||||
certificates or public keys in the server's certificate chain. </p>
|
||||
"selector" the TLSA RRset contains records with more than one digest
|
||||
matching type, the tls_dane_digest_agility parameter determines
|
||||
whether all the RRs are used, or only those with the most preferred
|
||||
digest matching type. </p>
|
||||
|
||||
<p> Otherwise, when for a particular combination of "certificate
|
||||
usage" and "selector" the TLSA RRset contains a records with more
|
||||
than one non-zero matching type, i.e. multiple digest algorithms,
|
||||
only records with the highest preference digest are used after
|
||||
discarding any records with an incorrect digest length as unusable. </p>
|
||||
<p> The <a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> parameter controls
|
||||
whether any digest TLSA records are acceptable in usage "2" (trust
|
||||
anchor assertion) TLSA records. </p>
|
||||
|
||||
<p> This strategy ensures that the strongest digest supported by
|
||||
both the Postfix SMTP client and the remote server is used, and
|
||||
weaker digests are ignored. This supports non-disruptive deprecation
|
||||
of outdated digest algorithms. </p>
|
||||
|
||||
<p> The strategy requires that when a TLSA RRset provides association
|
||||
data for multiple certificates or public keys, all RRs with the same
|
||||
"certificate usage" and "selector" be published with the same set
|
||||
of digests. In particular, during key rotation, when a certificate
|
||||
or public key is being replaced with another (and both are published
|
||||
during the transition) both the old and the new certificate MUST be
|
||||
specified with the same set of digests. One can change the list of
|
||||
digest algorithms later, once old keys are retired. At any given
|
||||
time change either the list of digests without changing the list of
|
||||
certificates or public keys or the list of certificates or public
|
||||
keys without changing the list of digests. </p>
|
||||
|
||||
<p> It is expected that this algorithm agility mechanism will be
|
||||
published in a standards track RFC for SMTP with DANE, and perhaps
|
||||
in an eventual update to <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a>. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11. </p>
|
||||
<p> This feature is available in Postfix 2.11 and later. </p>
|
||||
|
||||
|
||||
</DD>
|
||||
|
||||
<DT><b><a name="tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a>
|
||||
(default: trust-anchor-assertion)</b></DT><DD>
|
||||
(default: yes)</b></DT><DD>
|
||||
|
||||
<p> <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> trust-anchor digest support in the Postfix TLS library.
|
||||
Specify zero or more of the following options, separated by comma or
|
||||
whitespace. Option names are case-insensitive. </p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><b>ca-constraint</b></dt>
|
||||
|
||||
<dd> Enable support for <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE TLSA) DNS records that
|
||||
contain digests of trust-anchors with certificate usage "0".
|
||||
These are often public root CAs, and server operators may
|
||||
expect that clients will have the corresponding root certificate
|
||||
in their CAfile or CApath. Most SSL/TLS servers do not send public
|
||||
root CA certificate in their certificate chain, so if Postfix does
|
||||
not have the CA certificate locally, there is no way to associate
|
||||
the digest with the trust chain from the server. These TLSA records
|
||||
are fragile, and only work when you have a complete (whatever that
|
||||
means) set of public CAs in your CAfile or CApath. Enable this
|
||||
with caution if at all. </dd>
|
||||
|
||||
<dt><b>trust-anchor-assertion</b></dt>
|
||||
|
||||
<dd> Enable support for <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE TLSA) DNS records that contain
|
||||
Enable support for <a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> (DANE TLSA) DNS records that contain
|
||||
digests of trust-anchors with certificate usage "2". In this case
|
||||
the certificate usage logically requires the server administrator
|
||||
to configure the server to include the trust-anchor certificate in
|
||||
the server's SSL certificate chain. These TLSA records are less
|
||||
fragile than "ca-constraint" TLSA records, and are enabled by
|
||||
default. Having a "complete" CAfile or CApath does not help in
|
||||
this case, you are at the mercy of the remote server administrator's
|
||||
competence. </dd>
|
||||
|
||||
</dl>
|
||||
the server's SSL certificate chain. If enough domains mess this
|
||||
up, you can disable support for these TLSA records, but you'll no
|
||||
longer have secure connections that get it right and only publish
|
||||
trust anchor records. </p>
|
||||
|
||||
<p> At the <a href="TLS_README.html#client_tls_dane">dane</a>
|
||||
security level, when a TLSA RRset includes only unusable associations,
|
||||
@ -16309,6 +16367,11 @@ href="TLS_README.html#client_tls_dane">dane-only</a> security level,
|
||||
the server in question is skipped and delivery is deferred if no
|
||||
secure servers are found. </p>
|
||||
|
||||
<p> The <a href="postconf.5.html#tls_dane_digests">tls_dane_digests</a> parameter controls the list of digest
|
||||
algorithms that are supported in TLSA records. The tls_dane_digest_agility
|
||||
parameter controls digest algorithm downgrade attack resistance.
|
||||
</p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11 and later. </p>
|
||||
|
||||
|
||||
@ -16572,7 +16635,11 @@ or performant cipher choice, there is some risk of interoperability
|
||||
issues. In the past, some SSL clients have listed lower priority ciphers
|
||||
that they did not implement correctly. If the server chooses a cipher
|
||||
that the client prefers less, it may select a cipher whose client
|
||||
implementation is flawed. </p>
|
||||
implementation is flawed. Most notably Windows 2003 Microsoft
|
||||
Exchange servers have flawed implementations of DES-CBC3-SHA, which
|
||||
OpenSSL considers stronger than RC4-SHA. Enabling server cipher-suite
|
||||
selection may create interoperability issues with Windows 2003
|
||||
Microsoft Exchange clients. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.8 and later, in combination
|
||||
with OpenSSL 0.9.7 and later. </p>
|
||||
|
@ -598,14 +598,13 @@ SMTP(8) SMTP(8)
|
||||
hostname is not an alias and its address records
|
||||
lie in an unsigned zone.
|
||||
|
||||
<b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> (trust-anchor-asser-</b>
|
||||
<b>tion)</b>
|
||||
<b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> (yes)</b>
|
||||
<a href="http://tools.ietf.org/html/rfc6698">RFC 6698</a> trust-anchor digest support in the Postfix
|
||||
TLS library.
|
||||
|
||||
<b><a href="postconf.5.html#tlsmgr_service_name">tlsmgr_service_name</a> (tlsmgr)</b>
|
||||
The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in mas-
|
||||
ter.cf.
|
||||
The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">mas-
|
||||
ter.cf</a>.
|
||||
|
||||
<b>OBSOLETE STARTTLS CONTROLS</b>
|
||||
The following configuration parameters exist for compati-
|
||||
|
@ -1287,7 +1287,9 @@ SMTPD(8) SMTPD(8)
|
||||
|
||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||
The set of characters that can separate a user name
|
||||
from its address extension (user+foo).
|
||||
from its extension (example: user+foo), or a .for-
|
||||
ward file name from its extension (example: .for-
|
||||
ward+foo).
|
||||
|
||||
<b><a href="postconf.5.html#smtpd_banner">smtpd_banner</a> ($<a href="postconf.5.html#myhostname">myhostname</a> ESMTP $<a href="postconf.5.html#mail_name">mail_name</a>)</b>
|
||||
The text that follows the 220 status code in the
|
||||
|
@ -11,10 +11,10 @@ SOCKETMAP_TABLE(5) SOCKETMAP_TABLE(5)
|
||||
|
||||
<b>SYNOPSIS</b>
|
||||
<b>postmap -q "</b><i>string</i><b>" <a href="socketmap_table.html">socketmap</a>:inet:</b><i>host</i><b>:</b><i>port</i><b>:</b><i>name</i>
|
||||
<b>postmap -q "</b><i>string</i><b>" <a href="socketmap_table.html">socketmap</a>:<a href="DATABASE_README.html#types">unix</a>:</b><i>pathname</i><b>:</b><i>name</i>
|
||||
<b>postmap -q "</b><i>string</i><b>" <a href="socketmap_table.html">socketmap</a>:unix:</b><i>pathname</i><b>:</b><i>name</i>
|
||||
|
||||
<b>postmap -q - <a href="socketmap_table.html">socketmap</a>:inet:</b><i>host</i><b>:</b><i>port</i><b>:</b><i>name</i> <<i>inputfile</i>
|
||||
<b>postmap -q - <a href="socketmap_table.html">socketmap</a>:<a href="DATABASE_README.html#types">unix</a>:</b><i>pathname</i><b>:</b><i>name</i> <<i>inputfile</i>
|
||||
<b>postmap -q - <a href="socketmap_table.html">socketmap</a>:unix:</b><i>pathname</i><b>:</b><i>name</i> <<i>inputfile</i>
|
||||
|
||||
<b>DESCRIPTION</b>
|
||||
The Postfix mail system uses optional tables for address
|
||||
@ -22,7 +22,7 @@ SOCKETMAP_TABLE(5) SOCKETMAP_TABLE(5)
|
||||
|
||||
The Postfix socketmap client expects TCP endpoint names of
|
||||
the form <b>inet:</b><i>host</i><b>:</b><i>port</i><b>:</b><i>name</i>, or UNIX-domain endponts of
|
||||
the form <b><a href="DATABASE_README.html#types">unix</a>:</b><i>pathname</i><b>:</b><i>name</i>. In both cases, <i>name</i> speci-
|
||||
the form <b>unix:</b><i>pathname</i><b>:</b><i>name</i>. In both cases, <i>name</i> speci-
|
||||
fies the name field in a socketmap client request (see
|
||||
"REQUEST FORMAT" below).
|
||||
|
||||
|
@ -138,7 +138,9 @@ TRIVIAL-REWRITE(8) TRIVIAL-REWRITE(8)
|
||||
|
||||
<b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
|
||||
The set of characters that can separate a user name
|
||||
from its address extension (user+foo).
|
||||
from its extension (example: user+foo), or a .for-
|
||||
ward file name from its extension (example: .for-
|
||||
ward+foo).
|
||||
|
||||
<b><a href="postconf.5.html#swap_bangpath">swap_bangpath</a> (yes)</b>
|
||||
Enable the rewriting of "site!user" into
|
||||
|
@ -201,7 +201,7 @@ case "$SYSTEM.$RELEASE" in
|
||||
;;
|
||||
SunOS.5*) SYSTYPE=SUNOS5
|
||||
RANLIB=echo
|
||||
SYSLIBS="-lresolv -lsocket -lnsl"
|
||||
SYSLIBS="-lresolv -lsocket -lnsl -ldl"
|
||||
# Stock awk breaks with >10 files.
|
||||
test -x /usr/xpg4/bin/awk && AWK=/usr/xpg4/bin/awk
|
||||
# Solaris 2.5 added usleep(), POSIX regexp, POSIX getpwnam/uid_r
|
||||
|
@ -15,15 +15,40 @@ Postfix configuration utility
|
||||
[\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
|
||||
|
||||
\fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
|
||||
[\fIparameter=value ...\fR]
|
||||
\fIparameter=value ...\fR
|
||||
|
||||
\fBpostconf\fR [\fB-#vX\fR] [\fB-c \fIconfig_dir\fR]
|
||||
[\fIparameter ...\fR]
|
||||
\fIparameter ...\fR
|
||||
|
||||
\fBManaging master.cf:\fR
|
||||
\fBManaging master.cf service entries:\fR
|
||||
|
||||
\fBpostconf\fR [\fB-fMovx\fR] [\fB-c \fIconfig_dir\fR]
|
||||
[\fIservice ...\fR]
|
||||
[\fIservice\fR[\fB/\fItype\fR]\fI ...\fR]
|
||||
|
||||
\fBpostconf\fR [\fB-eMv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
\fIservice\fB/\fItype=value ...\fR
|
||||
|
||||
\fBpostconf\fR [\fB-#MvX\fR] [\fB-c \fIconfig_dir\fR]
|
||||
\fIservice\fB/\fItype ...\fR
|
||||
|
||||
\fBManaging master.cf service fields:\fR
|
||||
|
||||
\fBpostconf\fR [\fB-fFovx\fR] [\fB-c \fIconfig_dir\fR]
|
||||
[\fIservice\fR[\fB/\fItype\fR[\fB/\fIfield\fR]]\fI ...\fR]
|
||||
|
||||
\fBpostconf\fR [\fB-eFv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
\fIservice\fB/\fItype\fB/\fIfield=value ...\fR
|
||||
|
||||
\fBManaging master.cf service parameters:\fR
|
||||
|
||||
\fBpostconf\fR [\fB-fPovx\fR] [\fB-c \fIconfig_dir\fR]
|
||||
[\fIservice\fR[\fB/\fItype\fR[\fB/\fIparameter\fR]]\fI ...\fR]
|
||||
|
||||
\fBpostconf\fR [\fB-ePv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
\fIservice\fB/\fItype\fB/\fIparameter=value ...\fR
|
||||
|
||||
\fBpostconf\fR [\fB-PXv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
\fIservice\fB/\fItype\fB/\fIparameter ...\fR
|
||||
|
||||
\fBManaging bounce message templates:\fR
|
||||
|
||||
@ -114,21 +139,56 @@ Specify \fB-df\fR to fold long lines for human readability
|
||||
(Postfix 2.9 and later).
|
||||
.IP \fB-e\fR
|
||||
Edit the \fBmain.cf\fR configuration file, and update
|
||||
parameter settings with the "\fIname=value\fR" pairs
|
||||
on the \fBpostconf\fR(1) command line. The file is copied
|
||||
to a temporary file then renamed into place.
|
||||
Specify quotes to protect special characters and whitespace
|
||||
on the \fBpostconf\fR(1) command line.
|
||||
parameter settings with the "\fIname=value\fR" pairs on the
|
||||
\fBpostconf\fR(1) command line.
|
||||
|
||||
The \fB-e\fR is no longer needed with Postfix version 2.8
|
||||
and later.
|
||||
With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
and replace one or more service entries with new values as
|
||||
specified with "\fIservice/type=value\fR" on the \fBpostconf\fR(1)
|
||||
command line.
|
||||
|
||||
With \fB-F\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
and replace one or more service fields with new values as
|
||||
specied with "\fIservice/type/field=value\fR" on the
|
||||
\fBpostconf\fR(1) command line. Currently, the "command"
|
||||
field contains the command name and command arguments. this
|
||||
may change in the near future, so that the "command" field
|
||||
contains only the command name, and a new "arguments"
|
||||
pseudofield contains the command arguments.
|
||||
|
||||
With \fB-P\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
and add or update one or more service parameter settings
|
||||
(-o parameter=value settings) with new values as specied
|
||||
with "\fIservice/type/parameter=value\fR" on the \fBpostconf\fR(1)
|
||||
command line.
|
||||
|
||||
In all cases the file is copied to a temporary file then
|
||||
renamed into place. Specify quotes to protect special
|
||||
characters and whitespace on the \fBpostconf\fR(1) command
|
||||
line.
|
||||
|
||||
The \fB-e\fR option is no longer needed with Postfix version
|
||||
2.8 and later.
|
||||
.IP \fB-f\fR
|
||||
Fold long lines when printing \fBmain.cf\fR or \fBmaster.cf\fR
|
||||
configuration file entries, for human readability.
|
||||
|
||||
This feature is available with Postfix 2.9 and later.
|
||||
.IP \fB-F\fR
|
||||
Show \fBmaster.cf\fR per-entry field settings (by default
|
||||
all services and all fields), formatted as one
|
||||
"\fIservice/type/field=value\fR" per line. Specify \fB-Ff\fR
|
||||
to fold long lines.
|
||||
|
||||
Specify one or more "\fIservice/type/field\fR" instances
|
||||
on the \fBpostconf\fR(1) command line to limit the output
|
||||
to fields of interest. Trailing parameter name or service
|
||||
type fields that are omitted will be handled as "*" wildcard
|
||||
fields.
|
||||
|
||||
This feature is available with Postfix 2.11 and later.
|
||||
.IP \fB-h\fR
|
||||
Show \fBmain.cf\fR parameter values without the "\fIname\fR
|
||||
Show parameter or attribute values without the "\fIname\fR
|
||||
= " label that normally precedes the value.
|
||||
.IP \fB-l\fR
|
||||
List the names of all supported mailbox locking methods.
|
||||
@ -139,21 +199,22 @@ A kernel-based advisory locking method for local files only.
|
||||
This locking method is available on systems with a BSD
|
||||
compatible library.
|
||||
.IP \fBfcntl\fR
|
||||
A kernel-based advisory locking method for local and remote files.
|
||||
A kernel-based advisory locking method for local and remote
|
||||
files.
|
||||
.IP \fBdotlock\fR
|
||||
An application-level locking method. An application locks a file
|
||||
named \fIfilename\fR by creating a file named \fIfilename\fB.lock\fR.
|
||||
The application is expected to remove its own lock file, as well as
|
||||
stale lock files that were left behind after abnormal program
|
||||
termination.
|
||||
An application-level locking method. An application locks
|
||||
a file named \fIfilename\fR by creating a file named
|
||||
\fIfilename\fB.lock\fR. The application is expected to
|
||||
remove its own lock file, as well as stale lock files that
|
||||
were left behind after abnormal program termination.
|
||||
.RE
|
||||
.IP \fB-m\fR
|
||||
List the names of all supported lookup table types. In Postfix
|
||||
configuration files,
|
||||
lookup tables are specified as \fItype\fB:\fIname\fR, where
|
||||
\fItype\fR is one of the types listed below. The table \fIname\fR
|
||||
syntax depends on the lookup table type as described in the
|
||||
DATABASE_README document.
|
||||
List the names of all supported lookup table types. In
|
||||
Postfix configuration files, lookup tables are specified
|
||||
as \fItype\fB:\fIname\fR, where \fItype\fR is one of the
|
||||
types listed below. The table \fIname\fR syntax depends on
|
||||
the lookup table type as described in the DATABASE_README
|
||||
document.
|
||||
.RS
|
||||
.IP \fBbtree\fR
|
||||
A sorted, balanced tree structure. Available on systems
|
||||
@ -181,22 +242,18 @@ with support for Berkeley DB databases.
|
||||
.IP \fBinternal\fR
|
||||
A non-shared, in-memory hash table. Its content are lost
|
||||
when a process terminates.
|
||||
.IP "\fBldap\fR (read-only)"
|
||||
LDAP database client. This is described in \fBldap_table\fR(5).
|
||||
.IP "\fBlmdb\fR"
|
||||
OpenLDAP LMDB database (a memory-mapped, persistent file).
|
||||
Available on systems with support for LMDB databases. This
|
||||
is described in \fBlmdb_table\fR(5).
|
||||
.IP "\fBldap\fR (read-only)"
|
||||
LDAP database client. This is described in \fBldap_table\fR(5).
|
||||
.IP "\fBmemcache\fR"
|
||||
Memcache database client. This is described in
|
||||
\fBmemcache_table\fR(5).
|
||||
.IP "\fBmysql\fR (read-only)"
|
||||
MySQL database client. Available on systems with support
|
||||
for MySQL databases. This is described in \fBmysql_table\fR(5).
|
||||
.IP "\fBnis\fR (read-only)"
|
||||
NIS client.
|
||||
.IP "\fBnisplus\fR (read-only)"
|
||||
NIS+ client.
|
||||
.IP "\fBpcre\fR (read-only)"
|
||||
A lookup table based on Perl Compatible Regular Expressions.
|
||||
The file format is described in \fBpcre_table\fR(5).
|
||||
@ -220,53 +277,78 @@ UNIX-domain server. This is described in \fBsocketmap_table\fR(5).
|
||||
.IP "\fBsqlite\fR (read-only)"
|
||||
SQLite database. This is described in \fBsqlite_table\fR(5).
|
||||
.IP "\fBstatic\fR (read-only)"
|
||||
A table that always returns its name as lookup result. For example,
|
||||
\fBstatic:foobar\fR always returns the string \fBfoobar\fR as lookup
|
||||
result.
|
||||
A table that always returns its name as lookup result. For
|
||||
example, \fBstatic:foobar\fR always returns the string
|
||||
\fBfoobar\fR as lookup result.
|
||||
.IP "\fBtcp\fR (read-only)"
|
||||
TCP/IP client. The protocol is described in \fBtcp_table\fR(5).
|
||||
.IP "\fBtexthash\fR (read-only)"
|
||||
Produces similar results as hash: files, except that you don't
|
||||
need to run the \fBpostmap\fR(1) command before you can use the file,
|
||||
and that it does not detect changes after the file is read.
|
||||
Produces similar results as hash: files, except that you
|
||||
don't need to run the \fBpostmap\fR(1) command before you
|
||||
can use the file, and that it does not detect changes after
|
||||
the file is read.
|
||||
.IP "\fBunix\fR (read-only)"
|
||||
A limited view of the UNIX authentication database. The
|
||||
following tables are implemented:
|
||||
.RS
|
||||
. IP \fBunix:passwd.byname\fR
|
||||
The table is the UNIX password database. The key is a login name.
|
||||
The result is a password file entry in \fBpasswd\fR(5) format.
|
||||
The table is the UNIX password database. The key is a login
|
||||
name. The result is a password file entry in \fBpasswd\fR(5)
|
||||
format.
|
||||
.IP \fBunix:group.byname\fR
|
||||
The table is the UNIX group database. The key is a group name.
|
||||
The result is a group file entry in \fBgroup\fR(5) format.
|
||||
The table is the UNIX group database. The key is a group
|
||||
name. The result is a group file entry in \fBgroup\fR(5)
|
||||
format.
|
||||
.RE
|
||||
.RE
|
||||
.IP
|
||||
Other table types may exist depending on how Postfix was built.
|
||||
Other table types may exist depending on how Postfix was
|
||||
built.
|
||||
.IP \fB-M\fR
|
||||
Show \fBmaster.cf\fR file contents instead of \fBmain.cf\fR
|
||||
file contents.
|
||||
Specify \fB-Mf\fR to fold long lines for human readability.
|
||||
file contents. Specify \fB-Mf\fR to fold long lines for
|
||||
human readability.
|
||||
|
||||
If \fIservice ...\fR is specified, only the matching services
|
||||
will be output. For example, "\fBpostconf -Mf inet\fR"
|
||||
will output all services that listen on the network.
|
||||
Specify zero or more arguments, each with a \fIservice-name\fR
|
||||
or \fIservice-name/service-type\fR pair, where \fIservice-name\fR
|
||||
is the first field of a master.cf entry and \fIservice-type\fR
|
||||
is one of (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR).
|
||||
|
||||
Specify zero or more arguments, each with a \fIservice-type\fR
|
||||
name (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR)
|
||||
or with a \fIservice-name.service-type\fR pair, where
|
||||
\fIservice-name\fR is the first field of a master.cf entry.
|
||||
If \fIservice-name\fR or \fIservice-name/service-type\fR
|
||||
is specified, only the matching master.cf entries will be
|
||||
output. For example, "\fBpostconf -Mf smtp\fR" will output
|
||||
all services named "smtp", and "\fBpostconf -Mf smtp/inet\fR"
|
||||
will output only the smtp service that listens on the
|
||||
network. Trailing service type fields that are omitted
|
||||
will be handled as "*" wildcard fields.
|
||||
|
||||
This feature is available with Postfix 2.9 and later.
|
||||
This feature is available with Postfix 2.9 and later. The
|
||||
syntax was changed from "\fIname.type\fR" to "\fIname/type\fR",
|
||||
and "*" wildcard support was added with Postfix 2.11.
|
||||
.IP \fB-n\fR
|
||||
Show only configuration parameters that have explicit
|
||||
\fIname=value\fR settings in \fBmain.cf\fR.
|
||||
Specify \fB-nf\fR to fold long lines for human readability
|
||||
(Postfix 2.9 and later).
|
||||
\fIname=value\fR settings in \fBmain.cf\fR. Specify \fB-nf\fR
|
||||
to fold long lines for human readability (Postfix 2.9 and
|
||||
later).
|
||||
.IP "\fB-o \fIname=value\fR"
|
||||
Override \fBmain.cf\fR parameter settings.
|
||||
|
||||
This feature is available with Postfix 2.10 and later.
|
||||
.IP \fB-p\fR
|
||||
Show \fBmain.cf\fR parameter settings. This is the default.
|
||||
.IP \fB-P\fR
|
||||
Show \fBmaster.cf\fR service parameter settings (by default
|
||||
all services and all parameters). formatted as one
|
||||
"\fIservice/type/parameter=value\fR" per line. Specify
|
||||
\fB-Pf\fR to fold long lines.
|
||||
|
||||
Specify one or more "\fIservice/type/parameter\fR" instances
|
||||
on the \fBpostconf\fR(1) command line to limit the output
|
||||
to parameters of interest. Trailing parameter name or
|
||||
service type fields that are omitted will be handled as "*"
|
||||
wildcard fields.
|
||||
|
||||
This feature is available with Postfix 2.11 and later.
|
||||
.IP "\fB-t\fR [\fItemplate_file\fR]"
|
||||
Display the templates for text that appears at the beginning
|
||||
of delivery status notification (DSN) messages, without
|
||||
@ -283,34 +365,59 @@ line (in shell language: "").
|
||||
|
||||
This feature is available with Postfix 2.3 and later.
|
||||
.IP \fB-v\fR
|
||||
Enable verbose logging for debugging purposes. Multiple \fB-v\fR
|
||||
options make the software increasingly verbose.
|
||||
Enable verbose logging for debugging purposes. Multiple
|
||||
\fB-v\fR options make the software increasingly verbose.
|
||||
.IP \fB-x\fR
|
||||
Expand \fI$name\fR in \fBmain.cf\fR or \fBmaster.cf\fR
|
||||
parameter values. The expansion is recursive.
|
||||
|
||||
This feature is available with Postfix 2.10 and later.
|
||||
.IP \fB-X\fR
|
||||
Edit the \fBmain.cf\fR configuration file, and remove
|
||||
the parameters named on the \fBpostconf\fR(1) command line.
|
||||
The file is copied to a temporary file then renamed into
|
||||
place.
|
||||
Edit the \fBmain.cf\fR configuration file, and remove the
|
||||
parameters named on the \fBpostconf\fR(1) command line.
|
||||
Specify a list of parameter names, not "\fIname=value\fR"
|
||||
pairs. There is no \fBpostconf\fR(1) command to perform
|
||||
the reverse operation.
|
||||
pairs.
|
||||
|
||||
With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
and remove one or more service entries as specified with
|
||||
"\fIservice/type\fR" on the \fBpostconf\fR(1) command line.
|
||||
|
||||
With \fB-P\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
and remove one or more service parameter settings (-o
|
||||
parameter=value settings) as specied with
|
||||
"\fIservice/type/parameter\fR" on the \fBpostconf\fR(1)
|
||||
command line.
|
||||
|
||||
In all cases the file is copied to a temporary file then
|
||||
renamed into place. Specify quotes to protect special
|
||||
characters on the \fBpostconf\fR(1) command line.
|
||||
|
||||
There is no \fBpostconf\fR(1) command to perform the reverse
|
||||
operation.
|
||||
|
||||
This feature is available with Postfix 2.10 and later.
|
||||
Support for -M and -P was added with Postfix 2.11.
|
||||
.IP \fB-#\fR
|
||||
Edit the \fBmain.cf\fR configuration file, and comment out
|
||||
the parameters named on the \fBpostconf\fR(1) command line,
|
||||
so that those parameters revert to their default values.
|
||||
The file is copied to a temporary file then renamed into
|
||||
place.
|
||||
Specify a list of parameter names, not "\fIname=value\fR"
|
||||
pairs. There is no \fBpostconf\fR(1) command to perform
|
||||
the reverse operation.
|
||||
pairs.
|
||||
|
||||
This feature is available with Postfix 2.6 and later.
|
||||
With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
and comment out one or more service entries as specified
|
||||
with "\fIservice/type\fR" on the \fBpostconf\fR(1) command
|
||||
line.
|
||||
|
||||
In all cases the file is copied to a temporary file then
|
||||
renamed into place. Specify quotes to protect special
|
||||
characters on the \fBpostconf\fR(1) command line.
|
||||
|
||||
There is no \fBpostconf\fR(1) command to perform the reverse
|
||||
operation.
|
||||
|
||||
This feature is available with Postfix 2.6 and later. Support
|
||||
for -M was added with Postfix 2.11.
|
||||
.SH DIAGNOSTICS
|
||||
.ad
|
||||
.fi
|
||||
@ -327,8 +434,8 @@ Directory with Postfix configuration files.
|
||||
.nf
|
||||
.ad
|
||||
.fi
|
||||
The following \fBmain.cf\fR parameters are especially relevant to
|
||||
this program.
|
||||
The following \fBmain.cf\fR parameters are especially
|
||||
relevant to this program.
|
||||
|
||||
The text below provides only a parameter summary. See
|
||||
\fBpostconf\fR(5) for more details including examples.
|
||||
@ -341,20 +448,20 @@ Pathname of a configuration file with bounce message templates.
|
||||
.na
|
||||
.nf
|
||||
/etc/postfix/main.cf, Postfix configuration parameters
|
||||
/etc/postfix/master.cf, Postfix master daemon configuraton
|
||||
/etc/postfix/master.cf, Postfix master daemon configuration
|
||||
.SH "SEE ALSO"
|
||||
.na
|
||||
.nf
|
||||
bounce(5), bounce template file format
|
||||
master(5), master.cf configuration file syntax
|
||||
postconf(5), main.cf configuration file syntax
|
||||
bounce(5), bounce template file format master(5), master.cf
|
||||
configuration file syntax postconf(5), main.cf configuration
|
||||
file syntax
|
||||
.SH "README FILES"
|
||||
.na
|
||||
.nf
|
||||
.ad
|
||||
.fi
|
||||
Use "\fBpostconf readme_directory\fR" or
|
||||
"\fBpostconf html_directory\fR" to locate this information.
|
||||
Use "\fBpostconf readme_directory\fR" or "\fBpostconf
|
||||
html_directory\fR" to locate this information.
|
||||
.na
|
||||
.nf
|
||||
DATABASE_README, Postfix lookup table overview
|
||||
@ -363,11 +470,10 @@ DATABASE_README, Postfix lookup table overview
|
||||
.nf
|
||||
.ad
|
||||
.fi
|
||||
The Secure Mailer license must be distributed with this software.
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
.SH "AUTHOR(S)"
|
||||
.na
|
||||
.nf
|
||||
Wietse Venema
|
||||
IBM T.J. Watson Research
|
||||
P.O. Box 704
|
||||
Yorktown Heights, NY 10598, USA
|
||||
Wietse Venema IBM T.J. Watson Research P.O. Box 704 Yorktown
|
||||
Heights, NY 10598, USA
|
||||
|
@ -38,8 +38,8 @@ can be stored under a fixed lookup key.
|
||||
When a transaction fails due to a full database, Postfix
|
||||
resizes the database and retries the transaction.
|
||||
|
||||
Postfix access, address mapping and routing tables will
|
||||
generate partial search keys such as domain names without
|
||||
Postfix access, address mapping and routing table lookups
|
||||
may generate partial search keys such as domain names without
|
||||
one or more subdomains, network addresses without one or
|
||||
more least-significant octets, or email addresses without
|
||||
the localpart, address extension or domain portion.
|
||||
@ -47,7 +47,7 @@ This behavior is also found with btree:, hash:, or ldap:
|
||||
tables.
|
||||
|
||||
Unlike other flat-file based Postfix databases, changes to
|
||||
an LMDB database do not require automatic daemon program
|
||||
an LMDB database do not trigger automatic daemon program
|
||||
restart.
|
||||
.SH "RELIABILITY"
|
||||
.na
|
||||
@ -63,10 +63,12 @@ curruption due stray pointer bugs.
|
||||
The Postfix LMDB adapter implements locking with fcntl(2)
|
||||
locks at whole-file granularity. LMDB's native locking
|
||||
scheme would require world-writable lockfiles and would
|
||||
therefore violate the Postfix security model. Unlike some
|
||||
other Postfix flat-file databases, LMDB databases can safely
|
||||
be updated without serializing requests through the proxymap(8)
|
||||
service.
|
||||
therefore violate the Postfix security model.
|
||||
|
||||
Multiple processes can safely update an LMDB database without
|
||||
serializing requests through the proxymap(8) service. This
|
||||
makes LMDB suitable as a shared cache for verify(8) or
|
||||
postscreen(8) services.
|
||||
.SH "CONFIGURATION PARAMETERS"
|
||||
.na
|
||||
.nf
|
||||
|
@ -12,10 +12,10 @@ Postfix configuration parameters
|
||||
.SH DESCRIPTION
|
||||
.ad
|
||||
.fi
|
||||
The Postfix main.cf configuration file specifies a small subset
|
||||
of all the parameters that control the operation of the Postfix
|
||||
mail system. Parameters not specified in main.cf are left at their
|
||||
default values.
|
||||
The Postfix main.cf configuration file specifies parameters that
|
||||
control the operation of the Postfix mail system. Typically the
|
||||
file contains only a small subset of all parameters; parameters
|
||||
not specified are left at their default values.
|
||||
.PP
|
||||
The general format of the main.cf file is as follows:
|
||||
.IP \(bu
|
||||
@ -5131,23 +5131,27 @@ recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
|
||||
.ft R
|
||||
.SH recipient_delimiter (default: empty)
|
||||
The set of characters that can separate a user name from its
|
||||
address extension (user+foo). See \fBcanonical\fR(5), \fBlocal\fR(8), \fBrelocated\fR(5)
|
||||
and \fBvirtual\fR(5) for the effects this has on aliases, canonical,
|
||||
virtual, and relocated lookups. Basically, the software tries
|
||||
user+foo and .forward+foo before trying user and .forward.
|
||||
.PP
|
||||
This implementation recognizes one delimiter character per email
|
||||
address, and one address extension per email address.
|
||||
extension (example: user+foo), or a .forward file name from its
|
||||
extension (example: .forward+foo). Basically, the software tries
|
||||
user+foo and .forward+foo before trying user and .forward. This
|
||||
implementation recognizes one delimiter character and one extension
|
||||
per email address or .forward file name.
|
||||
.PP
|
||||
When the recipient_delimiter set contains multiple characters
|
||||
(Postfix 2.11 and later), a user name is separated from its address
|
||||
extension by the first character that matches the recipient_delimiter
|
||||
set.
|
||||
(Postfix 2.11 and later), a user name or .forward file name is
|
||||
separated from its extension by the first character that matches
|
||||
the recipient_delimiter set.
|
||||
.PP
|
||||
See \fBcanonical\fR(5), \fBlocal\fR(8), \fBrelocated\fR(5) and \fBvirtual\fR(5) for the
|
||||
effects of recipient_delimiter on lookups in aliases, canonical,
|
||||
virtual, and relocated maps, and see the propagate_unmatched_extensions
|
||||
parameter for propagating an extension from one email address to
|
||||
another.
|
||||
.PP
|
||||
When used in command_execution_directory, forward_path, or
|
||||
luser_relay, ${recipient_delimiter} is replaced
|
||||
with the recipient delimiter that was found in the recipient email
|
||||
address (Postfix 2.11 and later), or it is replaced with the main.cf
|
||||
luser_relay, ${recipient_delimiter} is replaced with the actual
|
||||
recipient delimiter that was found in the recipient email address
|
||||
(Postfix 2.11 and later), or it is replaced with the main.cf
|
||||
recipient_delimiter parameter value (Postfix 2.10 and earlier).
|
||||
.PP
|
||||
The recipient_delimiter is not applied to the mailer-daemon
|
||||
@ -7220,6 +7224,39 @@ whitespace, commas or colons. In the policy table "protocols" attribute
|
||||
empty value means allow all protocols. The valid protocol names, (see
|
||||
\\fBfBSSL_get_version\fR(3)\fR), are "SSLv2", "SSLv3" and "TLSv1".
|
||||
.PP
|
||||
With Postfix >= 2.5 the parameter syntax was expanded to support
|
||||
protocol exclusions. One can explicitly exclude "SSLv2" by setting
|
||||
"smtp_tls_mandatory_protocols = !SSLv2". To exclude both "SSLv2" and
|
||||
"SSLv3" set "smtp_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the underlying OpenSSL interface semantics.
|
||||
.PP
|
||||
The range of protocols advertised by an SSL/TLS client must be
|
||||
contiguous. When a protocol version is enabled, disabling any
|
||||
higher version implicitly disables all versions above that higher
|
||||
version. Thus, for example:
|
||||
.sp
|
||||
.in +4
|
||||
.nf
|
||||
.na
|
||||
.ft C
|
||||
smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
|
||||
.fi
|
||||
.ad
|
||||
.ft R
|
||||
.in -4
|
||||
also disables any protocols version higher than TLSv1 leaving
|
||||
only "SSLv3" enabled.
|
||||
.PP
|
||||
Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". When Postfix <= 2.5 is linked against OpenSSL 1.0.1
|
||||
or later, these, or any other new protocol versions, cannot be
|
||||
disabled except by also disabling "TLSv1" (typically leaving just
|
||||
"SSLv3"). The latest patch levels of Postfix >= 2.6, and all
|
||||
versions of Postfix >= 2.10 can explicitly disable support for
|
||||
"TLSv1.1" or "TLSv1.2".
|
||||
.PP
|
||||
At the dane and
|
||||
dane-only security
|
||||
levels, when usable TLSA records are obtained for the remote SMTP
|
||||
@ -7227,23 +7264,10 @@ server, the Postfix SMTP client is obligated to include the SNI TLS
|
||||
extension in its SSL client hello message. This may help the remote
|
||||
SMTP server live up to its promise to provide a certificate that
|
||||
matches its TLSA records. Since TLS extensions require TLS 1.0 or
|
||||
later, the Postfix SMTP client must disable SSLv2 and SSLv3 when
|
||||
later, the Postfix SMTP client must disable "SSLv2" and "SSLv3" when
|
||||
SNI is required. If you use "dane" or "dane-only" do not disable
|
||||
TLSv1, except perhaps via the policy table for destinations which
|
||||
you are sure will support TLSv1.1 or TLSv1.2.
|
||||
.PP
|
||||
Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled.
|
||||
.PP
|
||||
With Postfix >= 2.5 the parameter syntax is expanded to support
|
||||
protocol exclusions. One can now explicitly exclude SSLv2 by setting
|
||||
"smtp_tls_mandatory_protocols = !SSLv2". To exclude both SSLv2 and
|
||||
SSLv3 set "smtp_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the behavior when the OpenSSL library is newer than Postfix.
|
||||
you are sure will support "TLSv1.1" or "TLSv1.2".
|
||||
.PP
|
||||
Since SSL version 2 has known protocol weaknesses and is now
|
||||
deprecated, the default setting excludes "SSLv2". This means that by
|
||||
@ -7258,9 +7282,9 @@ Example:
|
||||
.nf
|
||||
.na
|
||||
.ft C
|
||||
# Preferred form with Postfix >= 2.5:
|
||||
# Preferred syntax with Postfix >= 2.5:
|
||||
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
smtp_tls_mandatory_protocols = TLSv1
|
||||
.fi
|
||||
.ad
|
||||
@ -7415,23 +7439,17 @@ Opportunistic DANE TLS. The TLS policy for the destination is
|
||||
obtained via TLSA records in DNSSEC. If no TLSA records are found,
|
||||
the effective security level used is may. If TLSA records are
|
||||
found, but none are usable, the effective security level is encrypt. When usable
|
||||
TLSA records are obtained for the remote SMTP server, SSLv2 and
|
||||
SSLv3 are automatically disabled (see smtp_tls_mandatory_protocols),
|
||||
and the server certificate must match the TLSA records. The
|
||||
tls_dane_trust_anchor_digest_enable parameter controls optional
|
||||
support for trust-anchor digest TLSA records. RFC 6698 (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later.
|
||||
TLSA records are obtained for the remote SMTP server, the
|
||||
server certificate must match the TLSA records. RFC 6698 (DANE)
|
||||
TLS authentication and DNSSEC support is available with Postfix
|
||||
2.11 and later.
|
||||
.br
|
||||
.IP "\fBdane-only\fR"
|
||||
Mandatory DANE TLS. The TLS policy for the destination is
|
||||
obtained via TLSA records in DNSSEC. If no TLSA records are found,
|
||||
or none are usable, no connection is made to the server. When
|
||||
usable TLSA records are obtained for the remote SMTP server, SSLv2
|
||||
and SSLv3 are automatically disabled (see smtp_tls_mandatory_protocols),
|
||||
and the server certificate must match the TLSA records. The
|
||||
tls_dane_trust_anchor_digest_enable parameter controls optional
|
||||
support for trust-anchor digest TLSA records. RFC 6698 (DANE) TLS
|
||||
usable TLSA records are obtained for the remote SMTP server, the
|
||||
server certificate must match the TLSA records. RFC 6698 (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later.
|
||||
.br
|
||||
@ -7532,24 +7550,41 @@ separator is colon. An empty value means allow all protocols. The valid
|
||||
protocol names, (see \\fBfBSSL_get_version\fR(3)\fR), are "SSLv2", "SSLv3"
|
||||
and "TLSv1".
|
||||
.PP
|
||||
The range of protocols advertised by an SSL/TLS client must be
|
||||
contiguous. When a protocol version is enabled, disabling any
|
||||
higher version implicitly disables all versions above that higher
|
||||
version. Thus, for example:
|
||||
.sp
|
||||
.in +4
|
||||
.nf
|
||||
.na
|
||||
.ft C
|
||||
smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
|
||||
.fi
|
||||
.ad
|
||||
.ft R
|
||||
.in -4
|
||||
also disables any protocols version higher than TLSv1 leaving
|
||||
only "SSLv3" enabled.
|
||||
.PP
|
||||
Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled.
|
||||
and "TLSv1.2". The latest patch levels of Postfix >= 2.6, and all
|
||||
versions of Postfix >= 2.10 can explicitly disable support for
|
||||
"TLSv1.1" or "TLSv1.2"
|
||||
.PP
|
||||
To include a protocol list its name, to exclude it, prefix the name
|
||||
with a "!" character. To exclude SSLv2 even for opportunistic TLS set
|
||||
"smtp_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set
|
||||
"smtp_tls_protocols = !SSLv2, !SSLv3". Explicitly listing the protocols to
|
||||
include, rather than protocols to exclude, is supported, but not
|
||||
recommended. The exclusion form more closely matches the behavior
|
||||
when the OpenSSL library is newer than Postfix.
|
||||
recommended. The exclusion form more closely matches the underlying
|
||||
OpenSSL interface semantics.
|
||||
.PP
|
||||
Example:
|
||||
.nf
|
||||
.na
|
||||
.ft C
|
||||
# TLSv1 only!
|
||||
# TLSv1 or better:
|
||||
smtp_tls_protocols = !SSLv2, !SSLv3
|
||||
.fi
|
||||
.ad
|
||||
@ -7666,20 +7701,16 @@ parameter. When TLSA records are not found or are all unusable the
|
||||
effective security level is "may" or "encrypt" respectively. For
|
||||
purposes of protocol and cipher selection, the "dane" security level
|
||||
is treated like a "mandatory" TLS security level, and weak ciphers
|
||||
and protocols are disabled. SSLv2 and SSLv3 are automatically
|
||||
disabled when usable TLSA records are obtained for the remote SMTP
|
||||
server, see smtp_tls_mandatory_protocols for details. Since DANE
|
||||
authenticates server certificates the "aNULL" cipher-suites are
|
||||
transparently excluded at this level, no need to configure this
|
||||
manually. The tls_dane_trust_anchor_digest_enable main.cf parameter
|
||||
controls optional support for trust-anchor digest TLSA records.
|
||||
RFC 6698 (DANE) TLS authentication is available with Postfix 2.11
|
||||
and later.
|
||||
and protocols are disabled. Since DANE authenticates server
|
||||
certificates the "aNULL" cipher-suites are transparently excluded
|
||||
at this level, no need to configure this manually. RFC 6698 (DANE)
|
||||
TLS authentication is available with Postfix 2.11 and later.
|
||||
.br
|
||||
.IP "\fBdane-only\fR"
|
||||
Mandatory DANE TLS. This is just like "dane" above, only DANE
|
||||
TLSA authentication is mandatory. RFC 6698 (DANE) TLS authentication
|
||||
is available with Postfix 2.11 and later.
|
||||
Mandatory DANE TLS. This is just like "dane" above, but DANE
|
||||
TLSA authentication is required. There is no fallback to "may" or
|
||||
"encrypt" when TLSA records are missing or unusable. RFC 6698
|
||||
(DANE) TLS authentication is available with Postfix 2.11 and later.
|
||||
.br
|
||||
.IP "\fBfingerprint\fR"
|
||||
Certificate fingerprint verification.
|
||||
@ -10599,24 +10630,26 @@ works in addition to the exclusions listed with smtpd_tls_exclude_ciphers
|
||||
This feature is available in Postfix 2.3 and later.
|
||||
.SH smtpd_tls_mandatory_protocols (default: !SSLv2)
|
||||
The SSL/TLS protocols accepted by the Postfix SMTP server with
|
||||
mandatory TLS encryption. If the list is empty, the server supports all
|
||||
available SSL/TLS protocol versions. A non-empty value is a list
|
||||
of protocol
|
||||
names separated by whitespace, commas or colons. The supported protocol
|
||||
names are "SSLv2", "SSLv3" and "TLSv1", and are not case sensitive.
|
||||
mandatory TLS encryption. If the list is empty, the server supports
|
||||
all available SSL/TLS protocol versions. A non-empty value is a
|
||||
list of protocol names separated by whitespace, commas or colons.
|
||||
The supported protocol names are "SSLv2", "SSLv3" and "TLSv1", and
|
||||
are not case sensitive.
|
||||
.PP
|
||||
Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled.
|
||||
.PP
|
||||
With Postfix >= 2.5 the parameter syntax is expanded to support
|
||||
protocol exclusions. One can now explicitly exclude SSLv2 by setting
|
||||
"smtpd_tls_mandatory_protocols = !SSLv2". To exclude both SSLv2 and
|
||||
SSLv3 set "smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
With Postfix >= 2.5 the parameter syntax was expanded to support
|
||||
protocol exclusions. One can explicitly exclude "SSLv2" by setting
|
||||
"smtpd_tls_mandatory_protocols = !SSLv2". To exclude both "SSLv2" and
|
||||
"SSLv3" set "smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the behavior when the OpenSSL library is newer than Postfix.
|
||||
matches the underlying OpenSSL interface semantics.
|
||||
.PP
|
||||
Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". When Postfix <= 2.5 is linked against OpenSSL 1.0.1
|
||||
or later, these, or any other new protocol versions, cannot be
|
||||
disabled. The latest patch levels of Postfix >= 2.6, and all
|
||||
versions of Postfix >= 2.10 can disable support for "TLSv1.1" or
|
||||
"TLSv1.2".
|
||||
.PP
|
||||
Since SSL version 2 has known protocol weaknesses and is now
|
||||
deprecated, the default setting excludes "SSLv2". This means that
|
||||
@ -10628,9 +10661,10 @@ Example:
|
||||
.nf
|
||||
.na
|
||||
.ft C
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
# Alternative form with Postfix >= 2.5:
|
||||
# Preferred syntax with Postfix >= 2.5:
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Legacy syntax:
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
.fi
|
||||
.ad
|
||||
.ft R
|
||||
@ -10638,28 +10672,25 @@ smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
This feature is available in Postfix 2.3 and later.
|
||||
.SH smtpd_tls_protocols (default: empty)
|
||||
List of TLS protocols that the Postfix SMTP server will exclude
|
||||
or include with opportunistic TLS encryption. This parameter SHOULD be
|
||||
left at its default empty value, allowing all protocols to be used with
|
||||
opportunistic TLS.
|
||||
.PP
|
||||
In main.cf the values are separated by whitespace, commas or
|
||||
colons. An empty value means allow all protocols. The valid protocol
|
||||
names, (see \\fBfBSSL_get_version\fR(3)\fR), are "SSLv2", "SSLv3" and
|
||||
"TLSv1". In smtp_tls_policy_maps table entries, "protocols" attribute
|
||||
values are separated by a colon.
|
||||
or include with opportunistic TLS encryption. This parameter SHOULD
|
||||
be left at its default empty value, allowing all protocols to be
|
||||
used with opportunistic TLS. A non-empty value is a list of protocol
|
||||
names separated by whitespace, commas or colons. The supported
|
||||
protocol names are "SSLv2", "SSLv3" and "TLSv1", and are not case
|
||||
sensitive.
|
||||
.PP
|
||||
Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled.
|
||||
and "TLSv1.2". The latest patch levels of Postfix >= 2.6, and all
|
||||
versions of Postfix >= 2.10 can disable support for "TLSv1.1" or
|
||||
"TLSv1.2".
|
||||
.PP
|
||||
To include a protocol list its name, to exclude it, prefix the name
|
||||
with a "!" character. To exclude SSLv2 even for opportunistic TLS set
|
||||
"smtpd_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set
|
||||
"smtpd_tls_protocols = !SSLv2, !SSLv3". Explicitly listing the protocols to
|
||||
include, rather than protocols to exclude, is supported, but not
|
||||
recommended. The exclusion form more closely matches the behavior
|
||||
when the OpenSSL library is newer than Postfix.
|
||||
recommended. The exclusion form more closely matches the underlying
|
||||
OpenSSL interface semantics.
|
||||
.PP
|
||||
Example:
|
||||
.nf
|
||||
@ -11007,78 +11038,110 @@ bytes (equivalent to 256 bits) is sufficient to generate a 128bit
|
||||
(or 168bit) session key.
|
||||
.PP
|
||||
This feature is available in Postfix 2.2 and later.
|
||||
.SH tls_dane_digest_agility (default: on)
|
||||
Configure DANE TLSA digest algorithm agility. When digest
|
||||
algorithm agility is enabled, and the server and client support a
|
||||
common strong digest algorithm, TLSA records with weaker digest
|
||||
algorithms are ignored.
|
||||
.PP
|
||||
Specify one of the following:
|
||||
.IP "\fBoff\fR"
|
||||
DANE verification examines each well-formed record in the TLSA
|
||||
RRset whose matching type is either "0" (no hash used) or is one of
|
||||
the digest algorithms listed in $tls_dane_digests. This setting
|
||||
is not recommended.
|
||||
.br
|
||||
.IP "\fBon\fR"
|
||||
From each group of well-formed TLSA RRs a non-zero digest
|
||||
matching type with the same certificate usage and selector, DANE
|
||||
verification examines only those records whose matching type has
|
||||
the highest precedence (appear earliest in $tls_dane_digests).
|
||||
.br
|
||||
.IP "\fBmaybe\fR"
|
||||
For compatibility with digest algorithm agility, each certificate
|
||||
or public key whose digest is included in a DANE TLSA RRset, SHOULD
|
||||
be published with the same set of digest matching type values as
|
||||
any other with the same usage and selector. Therefore, compatible
|
||||
TLSA RRsets will contain an identical count of well-formed RRs with
|
||||
each non-zero digest matching type for any fixed combination of
|
||||
usage and selector. When this constraint is violated, or any of
|
||||
the digest records are malformed, digest algorithm agility will
|
||||
disabled. Otherwise, digest algorithm agility is enabled.
|
||||
.br
|
||||
.br
|
||||
.PP
|
||||
Digest algorithm agility ensures that the strongest digest
|
||||
supported by both the Postfix SMTP client and the remote server is
|
||||
used, and weaker digests are ignored. This supports non-disruptive
|
||||
deprecation of outdated digest algorithms.
|
||||
.PP
|
||||
To ensure compatibility with digest algorithm agility during
|
||||
key rotation, when a certificate or public key is being replaced
|
||||
with another, and both are published during the transition, both
|
||||
the old and the new certificate MUST be specified with the same set
|
||||
of digests. One can change the list of digest algorithms later,
|
||||
once old keys are retired. At any given time, change either the
|
||||
list of digests without changing the list of certificates or public
|
||||
keys or the list of certificates or public keys without changing
|
||||
the list of digests. Full value matching type "0" records are not
|
||||
subject to this constraint, but are discouraged due to the size of
|
||||
the resulting DNS records.
|
||||
.PP
|
||||
It is expected that this algorithm agility mechanism will be
|
||||
published in a standards track RFC for SMTP with DANE, and also in
|
||||
an eventual update to RFC 6698.
|
||||
.PP
|
||||
This feature is available in Postfix 2.11 and later.
|
||||
.SH tls_dane_digests (default: sha512 sha256)
|
||||
RFC 6698 TLSA resource-record "matching type" digest algorithms
|
||||
in descending preference order. All the specified algorithms must
|
||||
be supported by the underlying OpenSSL library, otherwise the Postfix
|
||||
SMTP client will not support DANE TLSA security.
|
||||
.PP
|
||||
Specify a list of digest names separated by commas and/or
|
||||
whitespace. Each digest name may be followed by an optional
|
||||
"=<number>" suffix. For example, "sha512" may instead be specified
|
||||
as "sha512=2" and "sha256" may instead be specified as "sha256=1".
|
||||
The optional number must match the <a
|
||||
href="https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types"
|
||||
>IANA assigned TLSA matching type number the algorithm in question.
|
||||
Postfix will check this constraint for the algorithms it knows about.
|
||||
Additional matching type algorithms registered with IANA can be added
|
||||
with explicit numbers provided they are supported by OpenSSL.
|
||||
.PP
|
||||
Invalid list elements are logged with a warning and disable DANE
|
||||
support. TLSA RRs that specify digests not included in the list are
|
||||
ignored with a warning.
|
||||
.PP
|
||||
Note: It is unwise to omit sha256 from the digest list. This
|
||||
digest algorithm is the only mandatory to implement digest algorithm
|
||||
in RFC 6698, and many servers are expected publish TLSA records
|
||||
with just sha256 digests. Unless one of the standard digests is
|
||||
seriously compromised and servers have had ample time to update their
|
||||
TLSA records you should not omit any standard digests, just arrange
|
||||
them in order from strongest to weakest.
|
||||
.PP
|
||||
When for a particular combination of "certificate usage" and
|
||||
"selector" the TLSA RRset contains a well-formed record with a
|
||||
matching type of "0", i.e. a full value of the associated certificate
|
||||
or public key, the Postfix SMTP client will ignore all other matching
|
||||
types for the same certificate usage and selector. In this case
|
||||
the first algorithm listed in tls_dane_digests will be used to
|
||||
compute a digest of the full value, which will then be used to match
|
||||
certificates or public keys in the server's certificate chain.
|
||||
"selector" the TLSA RRset contains records with more than one digest
|
||||
matching type, the tls_dane_digest_agility parameter determines
|
||||
whether all the RRs are used, or only those with the most preferred
|
||||
digest matching type.
|
||||
.PP
|
||||
Otherwise, when for a particular combination of "certificate
|
||||
usage" and "selector" the TLSA RRset contains a records with more
|
||||
than one non-zero matching type, i.e. multiple digest algorithms,
|
||||
only records with the highest preference digest are used after
|
||||
discarding any records with an incorrect digest length as unusable.
|
||||
The tls_dane_trust_anchor_digest_enable parameter controls
|
||||
whether any digest TLSA records are acceptable in usage "2" (trust
|
||||
anchor assertion) TLSA records.
|
||||
.PP
|
||||
This strategy ensures that the strongest digest supported by
|
||||
both the Postfix SMTP client and the remote server is used, and
|
||||
weaker digests are ignored. This supports non-disruptive deprecation
|
||||
of outdated digest algorithms.
|
||||
.PP
|
||||
The strategy requires that when a TLSA RRset provides association
|
||||
data for multiple certificates or public keys, all RRs with the same
|
||||
"certificate usage" and "selector" be published with the same set
|
||||
of digests. In particular, during key rotation, when a certificate
|
||||
or public key is being replaced with another (and both are published
|
||||
during the transition) both the old and the new certificate MUST be
|
||||
specified with the same set of digests. One can change the list of
|
||||
digest algorithms later, once old keys are retired. At any given
|
||||
time change either the list of digests without changing the list of
|
||||
certificates or public keys or the list of certificates or public
|
||||
keys without changing the list of digests.
|
||||
.PP
|
||||
It is expected that this algorithm agility mechanism will be
|
||||
published in a standards track RFC for SMTP with DANE, and perhaps
|
||||
in an eventual update to RFC 6698.
|
||||
.PP
|
||||
This feature is available in Postfix 2.11.
|
||||
.SH tls_dane_trust_anchor_digest_enable (default: trust-anchor-assertion)
|
||||
This feature is available in Postfix 2.11 and later.
|
||||
.SH tls_dane_trust_anchor_digest_enable (default: yes)
|
||||
RFC 6698 trust-anchor digest support in the Postfix TLS library.
|
||||
Specify zero or more of the following options, separated by comma or
|
||||
whitespace. Option names are case-insensitive.
|
||||
.IP "\fBca-constraint\fR"
|
||||
Enable support for RFC 6698 (DANE TLSA) DNS records that
|
||||
contain digests of trust-anchors with certificate usage "0".
|
||||
These are often public root CAs, and server operators may
|
||||
expect that clients will have the corresponding root certificate
|
||||
in their CAfile or CApath. Most SSL/TLS servers do not send public
|
||||
root CA certificate in their certificate chain, so if Postfix does
|
||||
not have the CA certificate locally, there is no way to associate
|
||||
the digest with the trust chain from the server. These TLSA records
|
||||
are fragile, and only work when you have a complete (whatever that
|
||||
means) set of public CAs in your CAfile or CApath. Enable this
|
||||
with caution if at all.
|
||||
.br
|
||||
.IP "\fBtrust-anchor-assertion\fR"
|
||||
Enable support for RFC 6698 (DANE TLSA) DNS records that contain
|
||||
digests of trust-anchors with certificate usage "2". In this case
|
||||
the certificate usage logically requires the server administrator
|
||||
to configure the server to include the trust-anchor certificate in
|
||||
the server's SSL certificate chain. These TLSA records are less
|
||||
fragile than "ca-constraint" TLSA records, and are enabled by
|
||||
default. Having a "complete" CAfile or CApath does not help in
|
||||
this case, you are at the mercy of the remote server administrator's
|
||||
competence.
|
||||
.br
|
||||
.br
|
||||
the server's SSL certificate chain. If enough domains mess this
|
||||
up, you can disable support for these TLSA records, but you'll no
|
||||
longer have secure connections that get it right and only publish
|
||||
trust anchor records.
|
||||
.PP
|
||||
At the dane
|
||||
security level, when a TLSA RRset includes only unusable associations,
|
||||
@ -11088,6 +11151,10 @@ security level. At the dane-only security level,
|
||||
the server in question is skipped and delivery is deferred if no
|
||||
secure servers are found.
|
||||
.PP
|
||||
The tls_dane_digests parameter controls the list of digest
|
||||
algorithms that are supported in TLSA records. The tls_dane_digest_agility
|
||||
parameter controls digest algorithm downgrade attack resistance.
|
||||
.PP
|
||||
This feature is available in Postfix 2.11 and later.
|
||||
.SH tls_disable_workarounds (default: see "postconf -d" output)
|
||||
List or bit-mask of OpenSSL bug work-arounds to disable.
|
||||
@ -11301,7 +11368,11 @@ or performant cipher choice, there is some risk of interoperability
|
||||
issues. In the past, some SSL clients have listed lower priority ciphers
|
||||
that they did not implement correctly. If the server chooses a cipher
|
||||
that the client prefers less, it may select a cipher whose client
|
||||
implementation is flawed.
|
||||
implementation is flawed. Most notably Windows 2003 Microsoft
|
||||
Exchange servers have flawed implementations of DES-CBC3-SHA, which
|
||||
OpenSSL considers stronger than RC4-SHA. Enabling server cipher-suite
|
||||
selection may create interoperability issues with Windows 2003
|
||||
Microsoft Exchange clients.
|
||||
.PP
|
||||
This feature is available in Postfix 2.8 and later, in combination
|
||||
with OpenSSL 0.9.7 and later.
|
||||
|
@ -576,7 +576,8 @@ key to the lookup result.
|
||||
The location of the Postfix top-level queue directory.
|
||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||
The set of characters that can separate a user name from its
|
||||
address extension (user+foo).
|
||||
extension (example: user+foo), or a .forward file name from its
|
||||
extension (example: .forward+foo).
|
||||
.IP "\fBrequire_home_directory (no)\fR"
|
||||
Require that a \fBlocal\fR(8) recipient's home directory exists
|
||||
before mail delivery is attempted.
|
||||
|
@ -417,7 +417,8 @@ The process name of a Postfix command or daemon process.
|
||||
The location of the Postfix top-level queue directory.
|
||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||
The set of characters that can separate a user name from its
|
||||
address extension (user+foo).
|
||||
extension (example: user+foo), or a .forward file name from its
|
||||
extension (example: .forward+foo).
|
||||
.IP "\fBsyslog_facility (mail)\fR"
|
||||
The syslog facility of Postfix logging.
|
||||
.IP "\fBsyslog_name (see 'postconf -d' output)\fR"
|
||||
|
@ -479,7 +479,7 @@ and/or public keys.
|
||||
.IP "\fBsmtp_tls_force_insecure_host_tlsa_lookup (no)\fR"
|
||||
Lookup the associated DANE TLSA RRset even when a hostname is
|
||||
not an alias and its address records lie in an unsigned zone.
|
||||
.IP "\fBtls_dane_trust_anchor_digest_enable (trust-anchor-assertion)\fR"
|
||||
.IP "\fBtls_dane_trust_anchor_digest_enable (yes)\fR"
|
||||
RFC 6698 trust-anchor digest support in the Postfix TLS library.
|
||||
.IP "\fBtlsmgr_service_name (tlsmgr)\fR"
|
||||
The name of the \fBtlsmgr\fR(8) service entry in master.cf.
|
||||
|
@ -1009,7 +1009,8 @@ The process name of a Postfix command or daemon process.
|
||||
The location of the Postfix top-level queue directory.
|
||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||
The set of characters that can separate a user name from its
|
||||
address extension (user+foo).
|
||||
extension (example: user+foo), or a .forward file name from its
|
||||
extension (example: .forward+foo).
|
||||
.IP "\fBsmtpd_banner ($myhostname ESMTP $mail_name)\fR"
|
||||
The text that follows the 220 status code in the SMTP greeting
|
||||
banner.
|
||||
|
@ -135,7 +135,8 @@ With locally submitted mail, append the string ".$mydomain" to
|
||||
addresses that have no ".domain" information.
|
||||
.IP "\fBrecipient_delimiter (empty)\fR"
|
||||
The set of characters that can separate a user name from its
|
||||
address extension (user+foo).
|
||||
extension (example: user+foo), or a .forward file name from its
|
||||
extension (example: .forward+foo).
|
||||
.IP "\fBswap_bangpath (yes)\fR"
|
||||
Enable the rewriting of "site!user" into "user@site".
|
||||
.PP
|
||||
|
@ -1112,7 +1112,7 @@ while (<>) {
|
||||
s/\b(static):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
||||
s/\b(tcp):/<a href="tcp_table.5.html">$1<\/a>:/g;
|
||||
s/\b(texthash):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
||||
s/\b(unix):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
||||
#s/\b(unix):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
|
||||
|
||||
# Do nice links for smtp:host:port etc.
|
||||
|
||||
|
@ -233,7 +233,7 @@ creates a "generic" database when none exists. </p>
|
||||
generic: Makefile
|
||||
@echo Creating $@
|
||||
@rm -f $@.tmp
|
||||
@printf '%s\t%s+root=%s\n' root $MTAADMIN `uname -n` > $@.tmp
|
||||
@printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` > $@.tmp
|
||||
@mv $@.tmp generic
|
||||
|
||||
%.cdb: %
|
||||
|
@ -226,9 +226,11 @@ size of the server TLS handshake. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<li> <p> If you use RFC 6698 TLSA "2 0 1" or "2 1 1" records to
|
||||
<li> <p> If you publish RFC 6698 TLSA "2 0 1" or "2 1 1" records to
|
||||
specify root CA certificate digests, you must include the corresponding
|
||||
root CA certificates in the "server.pem" certificate file. </p>
|
||||
root CA certificates in the "server.pem" certificate file. See the
|
||||
documentation of the tls_dane_trust_anchor_digest_enable main.cf
|
||||
parameter. </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -236,29 +238,20 @@ root CA certificates in the "server.pem" certificate file. </p>
|
||||
</pre>
|
||||
</blockquote>
|
||||
|
||||
<p> Remote SMTP clients will
|
||||
be able to use the TLSA record you publish (which only contains the
|
||||
certificate digest) only if they have access to the corresponding
|
||||
certificate. Failure to verify certificates per the server's
|
||||
published TLSA records will typically cause the SMTP client to defer
|
||||
mail delivery. The foregoing also applies to "2 0 2" and "2 1 2"
|
||||
TLSA records or any other digest of a CA certificate, but it is
|
||||
expected that SHA256 will be by far the most common digest for TLSA.
|
||||
You are <i>strongly</i> urged to likewise include the root CA
|
||||
certificate in your server certificate file even if you use "0 0
|
||||
1" or "0 1 1" TLSA records. Some DANE implementations in SMTP
|
||||
clients (Postfix among them) may treat RFC 6698 certificate usages
|
||||
"0" and "2" interchangeably. </p>
|
||||
<p> Remote SMTP clients will be able to use the TLSA record you
|
||||
publish (which only contains the certificate digest) only if they
|
||||
have access to the corresponding certificate. Failure to verify
|
||||
certificates per the server's published TLSA records will typically
|
||||
cause the SMTP client to defer mail delivery. The foregoing also
|
||||
applies to "2 0 2" and "2 1 2" TLSA records or any other digest of
|
||||
a CA certificate, but it is expected that SHA256 will be by far the
|
||||
most common digest for TLSA. </p>
|
||||
|
||||
<p>By default, support for TLSA records that specify certificate
|
||||
usage "0" via a digest is disabled in the Postfix SMTP client. As
|
||||
a best practice, publish either "3 0 1" or "3 1 1" TLSA associations
|
||||
that specify the SHA256 digest of the server certificate public key
|
||||
with the alias-expanded hostname of each STARTTLS capable SMTP
|
||||
server. These continue to work when a certificate is renewed with
|
||||
the same public/private key pair. See the documentation of the
|
||||
tls_dane_trust_anchor_digest_enable main.cf parameter for details.
|
||||
</p>
|
||||
<p> As a best practice, publish either "3 0 1" or "3 1 1" TLSA
|
||||
associations that specify the SHA256 digest of the server certificate
|
||||
public key with the alias-expanded hostname of each STARTTLS capable
|
||||
SMTP server. These continue to work when a certificate is renewed
|
||||
with the same public/private key pair. </p>
|
||||
|
||||
</ul>
|
||||
|
||||
@ -614,7 +607,7 @@ from scratch. </p>
|
||||
|
||||
<p> Since Postfix uses multiple smtpd(8) service processes, an
|
||||
in-memory cache is not sufficient for session re-use. Clients store
|
||||
at most one cached session per server and are very unlikey to
|
||||
at most one cached session per server and are very unlikely to
|
||||
repeatedly connect to the same server process. Thus session caching
|
||||
in the Postfix SMTP server generally requires a shared cache (an
|
||||
alternative available with Postfix ≥ 2.11 is described below).
|
||||
@ -861,8 +854,8 @@ certificates</a> that use <b>only</b> the anonymous ciphers. This is
|
||||
enabled by explicitly setting "smtpd_tls_cert_file = none"
|
||||
and not specifying an smtpd_tls_dcert_file or smtpd_tls_eccert_file. </p>
|
||||
|
||||
<p> Example, MSA that requires TLSv1, not SSLv2 or SSLv3, with high grade
|
||||
ciphers: </p>
|
||||
<p> Example, MSA that requires TLSv1 or higher, not SSLv2 or SSLv3,
|
||||
with high grade ciphers: </p>
|
||||
|
||||
<blockquote>
|
||||
<pre>
|
||||
@ -872,9 +865,9 @@ ciphers: </p>
|
||||
smtpd_tls_mandatory_ciphers = high
|
||||
smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5
|
||||
smtpd_tls_security_level = encrypt
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
# Preferred syntax with Postfix ≥ 2.5:
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
</pre>
|
||||
</blockquote>
|
||||
@ -918,23 +911,27 @@ secure for most situations. </p>
|
||||
</blockquote>
|
||||
|
||||
<p> Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later
|
||||
allows TLS servers to preempt the TLS client's cipher preference list.
|
||||
allows TLS servers to preempt the TLS client's cipher-suite preference list.
|
||||
This is possible only with SSLv3 and later, as in SSLv2 the client
|
||||
chooses the cipher from a list supplied by the server. </p>
|
||||
chooses the cipher-suite from a list supplied by the server. </p>
|
||||
|
||||
<p> By default, the OpenSSL server selects the client's most preferred
|
||||
cipher that the server supports. With SSLv3 and later, the server
|
||||
may choose its own most preferred cipher that is supported (offered)
|
||||
cipher-suite that the server supports. With SSLv3 and later, the server
|
||||
may choose its own most preferred cipher-suite that is supported (offered)
|
||||
by the client. Setting "tls_preempt_cipherlist = yes" enables server
|
||||
cipher preferences. The default OpenSSL behavior applies with
|
||||
cipher-suite preferences. The default OpenSSL behavior applies with
|
||||
"tls_preempt_cipherlist = no". </p>
|
||||
|
||||
<p> While server cipher selection may in some cases lead to a more secure
|
||||
or performant cipher choice, there is some risk of interoperability
|
||||
issues. In the past, some SSL clients have listed lower priority ciphers
|
||||
that they did not implement correctly. If the server chooses a cipher
|
||||
that the client prefers less, it may select a cipher whose client
|
||||
implementation is flawed. </p>
|
||||
<p> While server cipher-suite selection may in some cases lead to
|
||||
a more secure or performant cipher-suite choice, there is some risk
|
||||
of interoperability issues. In the past, some SSL clients have
|
||||
listed lower priority ciphers that they did not implement correctly.
|
||||
If the server chooses a cipher that the client prefers less, it may
|
||||
select a cipher whose client implementation is flawed. Most notably
|
||||
Windows 2003 Microsoft Exchange servers have flawed implementations
|
||||
of DES-CBC3-SHA, which OpenSSL considers stronger than RC4-SHA.
|
||||
Enabling server cipher-suite selection may create interoperability
|
||||
issues with Windows 2003 Microsoft Exchange clients. </p>
|
||||
|
||||
<h3><a name="server_misc"> Miscellaneous server controls</a> </h3>
|
||||
|
||||
@ -1251,17 +1248,30 @@ the mandatory "dane-only" level. </p>
|
||||
href="#client_tls_may">opportunistic</a> TLS that is resistant to
|
||||
man in the middle and downgrade attacks when the destination domain
|
||||
uses DNSSEC to publish DANE TLSA records for its MX hosts. If a
|
||||
remote SMTP server has usable DANE TLSA records, these will be used
|
||||
to authenticate the server. If TLSA records are published for a
|
||||
given remote SMTP server (implying TLS support), but are not usable
|
||||
due to unsupported parameters, the Postfix SMTP client will use <a
|
||||
remote SMTP server has "usable" (see RFC 6698) DANE TLSA records,
|
||||
the server connection will be authenticated. When DANE authentication
|
||||
fails, there is no fallback to unauthenticated or plaintext delivery. </p>
|
||||
|
||||
<p> If TLSA records are published for a given remote SMTP server
|
||||
(implying TLS support), but are all "unusable" due to unsupported
|
||||
parameters or malformed data, the Postfix SMTP client will use <a
|
||||
href="#client_tls_encrypt">mandatory</a> unauthenticated TLS.
|
||||
Otherwise, the Postfix SMTP client behavior is the same as with <a
|
||||
href="#client_tls_may">may</a>. </p>
|
||||
Otherwise, when no TLSA records are published, the Postfix SMTP
|
||||
client behavior is the same as with <a href="#client_tls_may">may</a>. </p>
|
||||
|
||||
<p> TLSA records must be published in DNSSEC validated DNS zones.
|
||||
Any TLSA records in DNS zones not protected via DNSSEC are ignored.
|
||||
The Postfix SMTP client will not look for TLSA records associated
|
||||
with MX hosts whose "A" or "AAAA" records lie in an "insecure" DNS
|
||||
zone. Such lookups have been observed to cause interoperability
|
||||
issues with poorly implemented DNS servers, and are in any case not
|
||||
expected to ever yield "secure" results, since that would require
|
||||
a very unlikely DLV DNS trust anchor configured between the host
|
||||
record and the associated "_25._tcp" child TLSA record. </p>
|
||||
|
||||
<p> The "dane-only" level is a form of <a
|
||||
href="#client_tls_secure">secure-channel</a> TLS based on the DANE PKI.
|
||||
If usable TLSA records are present these are used to authenticate the
|
||||
If "usable" TLSA records are present these are used to authenticate the
|
||||
remote SMTP server. Otherwise, or when server certificate verification
|
||||
fails, delivery via the server in question tempfails. </p>
|
||||
|
||||
@ -1271,73 +1281,51 @@ to be in effect, the destination domain's containing DNS zone must
|
||||
be signed and the Postfix SMTP client's operating system must be
|
||||
configured to send its DNS queries to a recursive DNS nameserver
|
||||
that is able to validate the signed records. Each MX host's DNS
|
||||
zone should also be signed, and should publish DANE TLSA (RFC 6698)
|
||||
zone needs to also be signed, and needs to publish DANE TLSA (RFC 6698)
|
||||
records that specify how that MX host's TLS certificate is to be
|
||||
verified. TLSA records do not preempt the normal SMTP MX host
|
||||
verified. </p>
|
||||
|
||||
<p> TLSA records do not preempt the normal SMTP MX host
|
||||
selection algorithm, if some MX hosts support TLSA and others do
|
||||
not, TLS security will vary from delivery to delivery. It is up
|
||||
to the domain owner to configure their MX hosts and their DNS
|
||||
sensibly. To configure the Postfix SMTP client for DNSSEC lookups
|
||||
see the documentation for the smtp_dns_support_level main.cf
|
||||
parameter. The tls_dane_trust_anchor_digest_enable main.cf parameter
|
||||
controls optional support for trust-anchor digest TLSA records.
|
||||
controls support for trust-anchor digest TLSA records. The
|
||||
tls_dane_digests and tls_dane_digest_agility parameters control
|
||||
the list of supported digests and digest downgrade attack resistance.
|
||||
</p>
|
||||
|
||||
<p> The Postfix SMTP client deviates from RFC 6698 in cases where
|
||||
strict adherence is likely to create opportunities for delayed (or
|
||||
eventually bounced) email with no substantive security gain. Most
|
||||
notably, it is not expected that smtp_tls_CAfile and smtp_tls_CApath
|
||||
can reasonably include every public CA that a remote SMTP server's
|
||||
administrator may believe to be well-known. Therefore, certificate
|
||||
usages "0" and "2" from RFC 6698 which are intended to "constrain"
|
||||
existing PKI trust, are instead treated as "trust assertions" and
|
||||
mapped to "1" and "3" respectively. That is, with certificate usage
|
||||
"0" and "2", Postfix will not require the remote SMTP server's
|
||||
certificate to be trusted with respect to any locally defined public
|
||||
CAs, it is the domain owner's responsibility to ensure that the
|
||||
certificate associations in their TLSA records are appropriate
|
||||
to authenticate their SMTP servers. </p>
|
||||
<p> DANE for SMTP MTAs deviates in some details from the baseline
|
||||
DANE protocol in RFC 6698. Most notably, it is not expected that
|
||||
SMTP MTAs can reasonably include every public CA that a remote SMTP
|
||||
server's administrator may believe to be well-known. Nor is there
|
||||
an interactive user to "click OK" when authentication fails. </p>
|
||||
|
||||
<p> In addition, the Postfix SMTP client does not assume that the
|
||||
remote SMTP server will necessarily be configured to present the
|
||||
certificate of any usage "0" root CA in its TLS protocol <a
|
||||
href="https://tools.ietf.org/html/rfc2246#section-7.4.2">certificate_list</a>.
|
||||
Therefore, support for usage "0" certificate and public-key digests
|
||||
is disabled by default, see tls_dane_trust_anchor_digest_enable for
|
||||
details. While undigested trust-anchor certificates in TLSA records
|
||||
are supported, publishing complete certificates in DNS is unwise
|
||||
given the resulting excessively large DNS record sizes. Therefore,
|
||||
in its default configuration the Postfix SMTP client essentially
|
||||
supports only certificate usages "1", "2" and "3" (with "1" treated as
|
||||
though it were "3"). </p>
|
||||
<p> Therefore, certificate usages "0" and "1" from RFC 6698 which
|
||||
are intended to "constrain" existing PKI trust, are not supported.
|
||||
TLSA records with usage "0" are treated as "unusable". TLSA records
|
||||
with usage "1" are instead treated as "trust assertions" and mapped
|
||||
to usage "3". Specifically, with certificate usage "1", Postfix
|
||||
will not require the remote SMTP server's certificate to be trusted
|
||||
with respect to any locally defined public CAs, it is the domain
|
||||
owner's responsibility to ensure that the certificate associations
|
||||
in their TLSA records are appropriate to authenticate their SMTP
|
||||
servers. </p>
|
||||
|
||||
<p> Finally, the interaction of DANE with MX hostnames that are
|
||||
CNAMEs differs from the draft specification in the names used to
|
||||
construct the associated <a
|
||||
href="https://tools.ietf.org/html/draft-ietf-dane-srv-02#section-3.2">TLSA
|
||||
queries</a>. When the MX hostname is a CNAME, the draft proposal
|
||||
to use the unexpanded MX hostname in TLSA lookups is fragile and
|
||||
unintuitive. For this to work, the domain owner has to either
|
||||
duplicate the TLSA records of the target (host, service) pair in
|
||||
his own DNS or furnish the target host with an additional
|
||||
certificate and private key that would be negotiated via SNI.
|
||||
Neither of these are robust or easy to manage. It is far better
|
||||
to expand the CNAME recursively to the underlying target hostname
|
||||
(keeping track of DNSSEC validation along the way) and to use the
|
||||
expanded name to construct the TLSA query and, if appropriate, in
|
||||
server certificate name checks. This is the approach taken by the
|
||||
Postfix SMTP client, and if sanity prevails will also be the approach
|
||||
taken in the final standard. </p>
|
||||
<p> The Postfix SMTP client supports only certificate usages "2"
|
||||
and "3" (with "1" treated as though it were "3"). See
|
||||
tls_dane_trust_anchor_digest_enable for usage "2" usability
|
||||
considerations. Support for certificate usage "1" is an experiment,
|
||||
it may be withdrawn in the future. Server operators SHOULD NOT
|
||||
publish TLSA records with usage "1". </p>
|
||||
|
||||
<p> When usable TLSA records are obtained for the remote SMTP server
|
||||
the Postfix SMTP client is obligated to include the SNI TLS extension
|
||||
in its SSL client hello message. This may help the remote SMTP
|
||||
server live up to its promise to provide a certificate that matches
|
||||
its TLSA records. Since TLS extensions require TLS 1.0 or later,
|
||||
the Postfix SMTP client must disable SSLv2 and SSLv3 when SNI is
|
||||
required. If you use "dane" or "dane-only", do not disable TLSv1,
|
||||
except perhaps via the policy table for destinations which you are
|
||||
sure will support TLSv1.1 or TLSv1.2. </p>
|
||||
the Postfix SMTP client sends the SNI TLS extension in its SSL
|
||||
client hello message. This may help the remote SMTP server live
|
||||
up to its promise to provide a certificate that matches its TLSA
|
||||
records. </p>
|
||||
|
||||
<p> For purposes of protocol and cipher selection, the "dane"
|
||||
security level is treated like a "mandatory" TLS security level,
|
||||
@ -1357,14 +1345,14 @@ certificate must contain at least one of these names. </p>
|
||||
<p> When a DANE TLSA record specifies an end-entity (EE) certificate,
|
||||
(that is the actual server certificate), as with the fingerprint
|
||||
security level below, no name checks or certificate expiration checks
|
||||
are applied. The server certificate (or its public key) either matches
|
||||
are applied. The server certificate (or its public key) either matches
|
||||
the DANE record or not. Server administrators should publish such
|
||||
EE records in preference to all other types. </p>
|
||||
|
||||
<p> The pre-requisites for DANE support in the Postfix SMTP client are: </p>
|
||||
<ul>
|
||||
<li> A <i>compile-time</i> OpenSSL library that supports the TLS SNI
|
||||
extension and the "sha256" and "sha512" message digests.
|
||||
extension and "SHA-2" message digests.
|
||||
<li> A <i>compile-time</i> DNS resolver library that supports DNSSEC.
|
||||
Postfix binaries built on an older system will not support DNSSEC even
|
||||
if deployed on a system with an updated resolver library.
|
||||
@ -2068,12 +2056,13 @@ server has a greater opportunity to mandate client security policy when
|
||||
it is a dedicated MSA that only handles outbound mail from trusted clients,
|
||||
below we focus on the client security policy. </p>
|
||||
|
||||
<p> On the SMTP client, there are further complications. When delivering
|
||||
mail to a given domain, in contrast to HTTPS, one rarely uses the domain
|
||||
name directly as the target host of the SMTP session. More typically,
|
||||
one uses MX lookups - these are usually unauthenticated - to obtain the domain's SMTP server
|
||||
hostname(s). When, as is current practice, the client verifies the
|
||||
insecurely obtained MX hostname, it is subject to a DNS man-in-the-middle
|
||||
<p> On the SMTP client, there are further complications. When
|
||||
delivering mail to a given domain, in contrast to HTTPS, one rarely
|
||||
uses the domain name directly as the target host of the SMTP session.
|
||||
More typically, one uses MX lookups — these are usually
|
||||
unauthenticated — to obtain the domain's SMTP server hostname(s).
|
||||
When, as is current practice, the client verifies the insecurely
|
||||
obtained MX hostname, it is subject to a DNS man-in-the-middle
|
||||
attack. </p>
|
||||
|
||||
<p> Adoption of DNSSEC and RFC6698 (DANE) may gradually (as domains
|
||||
@ -2184,24 +2173,19 @@ DNSSEC. If no TLSA records are found, the effective security level
|
||||
used is <a href="#client_tls_may">may</a>. If TLSA records are
|
||||
found, but none are usable, the effective security level is <a
|
||||
href="#client_tls_encrypt">encrypt</a>. When usable TLSA records
|
||||
are obtained for the remote SMTP server, SSLv2 and SSLv3 are
|
||||
automatically disabled (see smtp_tls_mandatory_protocols), and the
|
||||
server certificate must match the TLSA records. The
|
||||
tls_dane_trust_anchor_digest_enable parameter controls optional
|
||||
support for trust-anchor digest TLSA records. RFC 6698 (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
are obtained for the remote SMTP server, SSLv2 is automatically
|
||||
disabled (see smtp_tls_mandatory_protocols), and the server certificate
|
||||
must match the TLSA records. RFC 6698 (DANE) TLS authentication
|
||||
and DNSSEC support is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
<dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
|
||||
The TLS policy for the destination is obtained via TLSA records in
|
||||
DNSSEC. If no TLSA records are found, or none are usable, no
|
||||
connection is made to the server. When usable TLSA records are
|
||||
obtained for the remote SMTP server, SSLv2 and SSLv3 are automatically
|
||||
disabled (see smtp_tls_mandatory_protocols), and the server certificate
|
||||
must match the TLSA records. The tls_dane_trust_anchor_digest_enable
|
||||
parameter controls optional support for trust-anchor digest TLSA
|
||||
records. RFC 6698 (DANE) TLS authentication and DNSSEC support is
|
||||
available with Postfix 2.11 and later. </dd>
|
||||
obtained for the remote SMTP server, SSLv2 is automatically disabled
|
||||
(see smtp_tls_mandatory_protocols), and the server certificate must
|
||||
match the TLSA records. RFC 6698 (DANE) TLS authentication and
|
||||
DNSSEC support is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
<dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
|
||||
fingerprint verification.</a> Available with Postfix 2.5 and
|
||||
@ -2291,9 +2275,8 @@ Example:
|
||||
/etc/postfix/tls_policy:
|
||||
example.edu none
|
||||
example.mil may
|
||||
example.gov encrypt protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.com verify
|
||||
match=hostname:dot-nexthop protocols=SSLv3:TLSv1 ciphers=high
|
||||
example.gov encrypt ciphers=high
|
||||
example.com verify match=hostname:dot-nexthop ciphers=high
|
||||
example.net secure
|
||||
.example.net secure match=.example.net:example.net
|
||||
[mail.example.org]:587 secure match=nexthop
|
||||
@ -2407,7 +2390,7 @@ the SSL/TLS protocols used with opportunistic TLS. </p>
|
||||
smtp_tls_exclude_ciphers = aNULL
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
smtp_tls_mandatory_protocols = !SSLv2
|
||||
# Alternative form.
|
||||
# Legacy form for Postifx < 2.5:
|
||||
smtp_tls_mandatory_protocols = SSLv3, TLSv1
|
||||
# Also available with Postfix ≥ 2.6:
|
||||
smtp_tls_ciphers = export
|
||||
|
@ -30,8 +30,8 @@
|
||||
# When a transaction fails due to a full database, Postfix
|
||||
# resizes the database and retries the transaction.
|
||||
#
|
||||
# Postfix access, address mapping and routing tables will
|
||||
# generate partial search keys such as domain names without
|
||||
# Postfix access, address mapping and routing table lookups
|
||||
# may generate partial search keys such as domain names without
|
||||
# one or more subdomains, network addresses without one or
|
||||
# more least-significant octets, or email addresses without
|
||||
# the localpart, address extension or domain portion.
|
||||
@ -39,7 +39,7 @@
|
||||
# tables.
|
||||
#
|
||||
# Unlike other flat-file based Postfix databases, changes to
|
||||
# an LMDB database do not require automatic daemon program
|
||||
# an LMDB database do not trigger automatic daemon program
|
||||
# restart.
|
||||
# RELIABILITY
|
||||
# .ad
|
||||
@ -53,10 +53,12 @@
|
||||
# The Postfix LMDB adapter implements locking with fcntl(2)
|
||||
# locks at whole-file granularity. LMDB's native locking
|
||||
# scheme would require world-writable lockfiles and would
|
||||
# therefore violate the Postfix security model. Unlike some
|
||||
# other Postfix flat-file databases, LMDB databases can safely
|
||||
# be updated without serializing requests through the proxymap(8)
|
||||
# service.
|
||||
# therefore violate the Postfix security model.
|
||||
#
|
||||
# Multiple processes can safely update an LMDB database without
|
||||
# serializing requests through the proxymap(8) service. This
|
||||
# makes LMDB suitable as a shared cache for verify(8) or
|
||||
# postscreen(8) services.
|
||||
# CONFIGURATION PARAMETERS
|
||||
# .ad
|
||||
# .fi
|
||||
|
@ -12,10 +12,10 @@ Postfix configuration parameters
|
||||
.SH DESCRIPTION
|
||||
.ad
|
||||
.fi
|
||||
The Postfix main.cf configuration file specifies a small subset
|
||||
of all the parameters that control the operation of the Postfix
|
||||
mail system. Parameters not specified in main.cf are left at their
|
||||
default values.
|
||||
The Postfix main.cf configuration file specifies parameters that
|
||||
control the operation of the Postfix mail system. Typically the
|
||||
file contains only a small subset of all parameters; parameters
|
||||
not specified are left at their default values.
|
||||
.PP
|
||||
The general format of the main.cf file is as follows:
|
||||
.IP \(bu
|
||||
|
@ -3505,23 +3505,27 @@ recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
|
||||
%PARAM recipient_delimiter
|
||||
|
||||
<p> The set of characters that can separate a user name from its
|
||||
address extension (user+foo). See canonical(5), local(8), relocated(5)
|
||||
and virtual(5) for the effects this has on aliases, canonical,
|
||||
virtual, and relocated lookups. Basically, the software tries
|
||||
user+foo and .forward+foo before trying user and .forward. </p>
|
||||
|
||||
<p> This implementation recognizes one delimiter character per email
|
||||
address, and one address extension per email address. </p>
|
||||
extension (example: user+foo), or a .forward file name from its
|
||||
extension (example: .forward+foo). Basically, the software tries
|
||||
user+foo and .forward+foo before trying user and .forward. This
|
||||
implementation recognizes one delimiter character and one extension
|
||||
per email address or .forward file name. </p>
|
||||
|
||||
<p> When the recipient_delimiter set contains multiple characters
|
||||
(Postfix 2.11 and later), a user name is separated from its address
|
||||
extension by the first character that matches the recipient_delimiter
|
||||
set. </p>
|
||||
(Postfix 2.11 and later), a user name or .forward file name is
|
||||
separated from its extension by the first character that matches
|
||||
the recipient_delimiter set. </p>
|
||||
|
||||
<p> See canonical(5), local(8), relocated(5) and virtual(5) for the
|
||||
effects of recipient_delimiter on lookups in aliases, canonical,
|
||||
virtual, and relocated maps, and see the propagate_unmatched_extensions
|
||||
parameter for propagating an extension from one email address to
|
||||
another. </p>
|
||||
|
||||
<p> When used in command_execution_directory, forward_path, or
|
||||
luser_relay, ${recipient_delimiter} is replaced
|
||||
with the recipient delimiter that was found in the recipient email
|
||||
address (Postfix 2.11 and later), or it is replaced with the main.cf
|
||||
luser_relay, ${recipient_delimiter} is replaced with the actual
|
||||
recipient delimiter that was found in the recipient email address
|
||||
(Postfix 2.11 and later), or it is replaced with the main.cf
|
||||
recipient_delimiter parameter value (Postfix 2.10 and earlier).
|
||||
</p>
|
||||
|
||||
@ -10668,23 +10672,17 @@ the effective security level used is <a
|
||||
href="TLS_README.html#client_tls_may">may</a>. If TLSA records are
|
||||
found, but none are usable, the effective security level is <a
|
||||
href="TLS_README.html#client_tls_encrypt">encrypt</a>. When usable
|
||||
TLSA records are obtained for the remote SMTP server, SSLv2 and
|
||||
SSLv3 are automatically disabled (see smtp_tls_mandatory_protocols),
|
||||
and the server certificate must match the TLSA records. The
|
||||
tls_dane_trust_anchor_digest_enable parameter controls optional
|
||||
support for trust-anchor digest TLSA records. RFC 6698 (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
TLSA records are obtained for the remote SMTP server, the
|
||||
server certificate must match the TLSA records. RFC 6698 (DANE)
|
||||
TLS authentication and DNSSEC support is available with Postfix
|
||||
2.11 and later. </dd>
|
||||
|
||||
<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt>
|
||||
<dd>Mandatory DANE TLS. The TLS policy for the destination is
|
||||
obtained via TLSA records in DNSSEC. If no TLSA records are found,
|
||||
or none are usable, no connection is made to the server. When
|
||||
usable TLSA records are obtained for the remote SMTP server, SSLv2
|
||||
and SSLv3 are automatically disabled (see smtp_tls_mandatory_protocols),
|
||||
and the server certificate must match the TLSA records. The
|
||||
tls_dane_trust_anchor_digest_enable parameter controls optional
|
||||
support for trust-anchor digest TLSA records. RFC 6698 (DANE) TLS
|
||||
usable TLSA records are obtained for the remote SMTP server, the
|
||||
server certificate must match the TLSA records. RFC 6698 (DANE) TLS
|
||||
authentication and DNSSEC support is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
|
||||
@ -10777,6 +10775,35 @@ whitespace, commas or colons. In the policy table "protocols" attribute
|
||||
empty value means allow all protocols. The valid protocol names, (see
|
||||
<b>SSL_get_version(3)</b>), are "SSLv2", "SSLv3" and "TLSv1". </p>
|
||||
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax was expanded to support
|
||||
protocol exclusions. One can explicitly exclude "SSLv2" by setting
|
||||
"smtp_tls_mandatory_protocols = !SSLv2". To exclude both "SSLv2" and
|
||||
"SSLv3" set "smtp_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the underlying OpenSSL interface semantics.
|
||||
</p>
|
||||
|
||||
<p> The range of protocols advertised by an SSL/TLS client must be
|
||||
contiguous. When a protocol version is enabled, disabling any
|
||||
higher version implicitly disables all versions above that higher
|
||||
version. Thus, for example: </p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p> also disables any protocols version higher than TLSv1 leaving
|
||||
only "SSLv3" enabled. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". When Postfix ≤ 2.5 is linked against OpenSSL 1.0.1
|
||||
or later, these, or any other new protocol versions, cannot be
|
||||
disabled except by also disabling "TLSv1" (typically leaving just
|
||||
"SSLv3"). The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can explicitly disable support for
|
||||
"TLSv1.1" or "TLSv1.2". </p>
|
||||
|
||||
<p> At the <a href="TLS_README.html#client_tls_dane">dane</a> and
|
||||
<a href="TLS_README.html#client_tls_dane">dane-only</a> security
|
||||
levels, when usable TLSA records are obtained for the remote SMTP
|
||||
@ -10784,24 +10811,10 @@ server, the Postfix SMTP client is obligated to include the SNI TLS
|
||||
extension in its SSL client hello message. This may help the remote
|
||||
SMTP server live up to its promise to provide a certificate that
|
||||
matches its TLSA records. Since TLS extensions require TLS 1.0 or
|
||||
later, the Postfix SMTP client must disable SSLv2 and SSLv3 when
|
||||
later, the Postfix SMTP client must disable "SSLv2" and "SSLv3" when
|
||||
SNI is required. If you use "dane" or "dane-only" do not disable
|
||||
TLSv1, except perhaps via the policy table for destinations which
|
||||
you are sure will support TLSv1.1 or TLSv1.2. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax is expanded to support
|
||||
protocol exclusions. One can now explicitly exclude SSLv2 by setting
|
||||
"smtp_tls_mandatory_protocols = !SSLv2". To exclude both SSLv2 and
|
||||
SSLv3 set "smtp_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the behavior when the OpenSSL library is newer than Postfix.
|
||||
</p>
|
||||
you are sure will support "TLSv1.1" or "TLSv1.2". </p>
|
||||
|
||||
<p> Since SSL version 2 has known protocol weaknesses and is now
|
||||
deprecated, the default setting excludes "SSLv2". This means that by
|
||||
@ -10814,9 +10827,9 @@ TLS_README for more information about security levels. </p>
|
||||
<p> Example: </p>
|
||||
|
||||
<pre>
|
||||
# Preferred form with Postfix ≥ 2.5:
|
||||
# Preferred syntax with Postfix ≥ 2.5:
|
||||
smtp_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Alternative form.
|
||||
# Legacy syntax:
|
||||
smtp_tls_mandatory_protocols = TLSv1
|
||||
</pre>
|
||||
|
||||
@ -10970,25 +10983,26 @@ configuration parameter. See there for details. </p>
|
||||
%PARAM smtpd_tls_mandatory_protocols !SSLv2
|
||||
|
||||
<p> The SSL/TLS protocols accepted by the Postfix SMTP server with
|
||||
mandatory TLS encryption. If the list is empty, the server supports all
|
||||
available SSL/TLS protocol versions. A non-empty value is a list
|
||||
of protocol
|
||||
names separated by whitespace, commas or colons. The supported protocol
|
||||
names are "SSLv2", "SSLv3" and "TLSv1", and are not case sensitive. </p>
|
||||
mandatory TLS encryption. If the list is empty, the server supports
|
||||
all available SSL/TLS protocol versions. A non-empty value is a
|
||||
list of protocol names separated by whitespace, commas or colons.
|
||||
The supported protocol names are "SSLv2", "SSLv3" and "TLSv1", and
|
||||
are not case sensitive. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax is expanded to support
|
||||
protocol exclusions. One can now explicitly exclude SSLv2 by setting
|
||||
"smtpd_tls_mandatory_protocols = !SSLv2". To exclude both SSLv2 and
|
||||
SSLv3 set "smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
<p> With Postfix ≥ 2.5 the parameter syntax was expanded to support
|
||||
protocol exclusions. One can explicitly exclude "SSLv2" by setting
|
||||
"smtpd_tls_mandatory_protocols = !SSLv2". To exclude both "SSLv2" and
|
||||
"SSLv3" set "smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3". Listing
|
||||
the protocols to include, rather than protocols to exclude, is
|
||||
supported, but not recommended. The exclusion form more closely
|
||||
matches the behavior when the OpenSSL library is newer than Postfix.
|
||||
</p>
|
||||
matches the underlying OpenSSL interface semantics. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". When Postfix ≤ 2.5 is linked against OpenSSL 1.0.1
|
||||
or later, these, or any other new protocol versions, cannot be
|
||||
disabled. The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or
|
||||
"TLSv1.2". </p>
|
||||
|
||||
<p> Since SSL version 2 has known protocol weaknesses and is now
|
||||
deprecated, the default setting excludes "SSLv2". This means that
|
||||
@ -10998,9 +11012,10 @@ level. </p>
|
||||
<p> Example: </p>
|
||||
|
||||
<pre>
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
# Alternative form with Postfix ≥ 2.5:
|
||||
# Preferred syntax with Postfix ≥ 2.5:
|
||||
smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3
|
||||
# Legacy syntax:
|
||||
smtpd_tls_mandatory_protocols = TLSv1
|
||||
</pre>
|
||||
|
||||
<p> This feature is available in Postfix 2.3 and later. </p>
|
||||
@ -11063,21 +11078,18 @@ parameter. When TLSA records are not found or are all unusable the
|
||||
effective security level is "may" or "encrypt" respectively. For
|
||||
purposes of protocol and cipher selection, the "dane" security level
|
||||
is treated like a "mandatory" TLS security level, and weak ciphers
|
||||
and protocols are disabled. SSLv2 and SSLv3 are automatically
|
||||
disabled when usable TLSA records are obtained for the remote SMTP
|
||||
server, see smtp_tls_mandatory_protocols for details. Since DANE
|
||||
authenticates server certificates the "aNULL" cipher-suites are
|
||||
transparently excluded at this level, no need to configure this
|
||||
manually. The tls_dane_trust_anchor_digest_enable main.cf parameter
|
||||
controls optional support for trust-anchor digest TLSA records.
|
||||
RFC 6698 (DANE) TLS authentication is available with Postfix 2.11
|
||||
and later. </dd>
|
||||
and protocols are disabled. Since DANE authenticates server
|
||||
certificates the "aNULL" cipher-suites are transparently excluded
|
||||
at this level, no need to configure this manually. RFC 6698 (DANE)
|
||||
TLS authentication is available with Postfix 2.11 and later. </dd>
|
||||
|
||||
|
||||
<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt>
|
||||
<dd>Mandatory DANE TLS. This is just like "dane" above, only DANE
|
||||
TLSA authentication is mandatory. RFC 6698 (DANE) TLS authentication
|
||||
is available with Postfix 2.11 and later. </dd>
|
||||
<dd>Mandatory DANE TLS. This is just like "dane" above, but DANE
|
||||
TLSA authentication is required. There is no fallback to "may" or
|
||||
"encrypt" when TLSA records are missing or unusable. RFC 6698
|
||||
(DANE) TLS authentication is available with Postfix 2.11 and later.
|
||||
</dd>
|
||||
|
||||
<dt><b><a href="TLS_README.html#client_tls_fingerprint">fingerprint</a></b></dt>
|
||||
<dd>Certificate fingerprint verification.
|
||||
@ -12127,22 +12139,34 @@ separator is colon. An empty value means allow all protocols. The valid
|
||||
protocol names, (see <b>SSL_get_version(3)</b>), are "SSLv2", "SSLv3"
|
||||
and "TLSv1". </p>
|
||||
|
||||
<p> The range of protocols advertised by an SSL/TLS client must be
|
||||
contiguous. When a protocol version is enabled, disabling any
|
||||
higher version implicitly disables all versions above that higher
|
||||
version. Thus, for example: </p>
|
||||
<blockquote>
|
||||
<pre>
|
||||
smtp_tls_mandatory_protocols = !SSLv2, !TLSv1
|
||||
</pre>
|
||||
</blockquote>
|
||||
<p> also disables any protocols version higher than TLSv1 leaving
|
||||
only "SSLv3" enabled. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
and "TLSv1.2". The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can explicitly disable support for
|
||||
"TLSv1.1" or "TLSv1.2"</p>
|
||||
|
||||
<p> To include a protocol list its name, to exclude it, prefix the name
|
||||
with a "!" character. To exclude SSLv2 even for opportunistic TLS set
|
||||
"smtp_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set
|
||||
"smtp_tls_protocols = !SSLv2, !SSLv3". Explicitly listing the protocols to
|
||||
include, rather than protocols to exclude, is supported, but not
|
||||
recommended. The exclusion form more closely matches the behavior
|
||||
when the OpenSSL library is newer than Postfix. </p>
|
||||
recommended. The exclusion form more closely matches the underlying
|
||||
OpenSSL interface semantics. </p>
|
||||
|
||||
<p> Example: </p>
|
||||
<pre>
|
||||
# TLSv1 only!
|
||||
# TLSv1 or better:
|
||||
smtp_tls_protocols = !SSLv2, !SSLv3
|
||||
</pre>
|
||||
|
||||
@ -12151,28 +12175,25 @@ smtp_tls_protocols = !SSLv2, !SSLv3
|
||||
%PARAM smtpd_tls_protocols
|
||||
|
||||
<p> List of TLS protocols that the Postfix SMTP server will exclude
|
||||
or include with opportunistic TLS encryption. This parameter SHOULD be
|
||||
left at its default empty value, allowing all protocols to be used with
|
||||
opportunistic TLS. </p>
|
||||
|
||||
<p> In main.cf the values are separated by whitespace, commas or
|
||||
colons. An empty value means allow all protocols. The valid protocol
|
||||
names, (see <b>SSL_get_version(3)</b>), are "SSLv2", "SSLv3" and
|
||||
"TLSv1". In smtp_tls_policy_maps table entries, "protocols" attribute
|
||||
values are separated by a colon. </p>
|
||||
or include with opportunistic TLS encryption. This parameter SHOULD
|
||||
be left at its default empty value, allowing all protocols to be
|
||||
used with opportunistic TLS. A non-empty value is a list of protocol
|
||||
names separated by whitespace, commas or colons. The supported
|
||||
protocol names are "SSLv2", "SSLv3" and "TLSv1", and are not case
|
||||
sensitive. </p>
|
||||
|
||||
<p> Note: As of OpenSSL 1.0.1 two new protocols are defined, "TLSv1.1"
|
||||
and "TLSv1.2". If an older Postfix version is linked against OpenSSL
|
||||
1.0.1 or later, these, or any other new protocol versions, are
|
||||
unconditionally enabled. </p>
|
||||
and "TLSv1.2". The latest patch levels of Postfix ≥ 2.6, and all
|
||||
versions of Postfix ≥ 2.10 can disable support for "TLSv1.1" or
|
||||
"TLSv1.2". </p>
|
||||
|
||||
<p> To include a protocol list its name, to exclude it, prefix the name
|
||||
with a "!" character. To exclude SSLv2 even for opportunistic TLS set
|
||||
"smtpd_tls_protocols = !SSLv2". To exclude both "SSLv2" and "SSLv3" set
|
||||
"smtpd_tls_protocols = !SSLv2, !SSLv3". Explicitly listing the protocols to
|
||||
include, rather than protocols to exclude, is supported, but not
|
||||
recommended. The exclusion form more closely matches the behavior
|
||||
when the OpenSSL library is newer than Postfix. </p>
|
||||
recommended. The exclusion form more closely matches the underlying
|
||||
OpenSSL interface semantics. </p>
|
||||
|
||||
<p> Example: </p>
|
||||
<pre>
|
||||
@ -14265,7 +14286,11 @@ or performant cipher choice, there is some risk of interoperability
|
||||
issues. In the past, some SSL clients have listed lower priority ciphers
|
||||
that they did not implement correctly. If the server chooses a cipher
|
||||
that the client prefers less, it may select a cipher whose client
|
||||
implementation is flawed. </p>
|
||||
implementation is flawed. Most notably Windows 2003 Microsoft
|
||||
Exchange servers have flawed implementations of DES-CBC3-SHA, which
|
||||
OpenSSL considers stronger than RC4-SHA. Enabling server cipher-suite
|
||||
selection may create interoperability issues with Windows 2003
|
||||
Microsoft Exchange clients. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.8 and later, in combination
|
||||
with OpenSSL 0.9.7 and later. </p>
|
||||
@ -15256,41 +15281,17 @@ configuration parameter. See there for details. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11 and later. </p>
|
||||
|
||||
%PARAM tls_dane_trust_anchor_digest_enable trust-anchor-assertion
|
||||
%PARAM tls_dane_trust_anchor_digest_enable yes
|
||||
|
||||
<p> RFC 6698 trust-anchor digest support in the Postfix TLS library.
|
||||
Specify zero or more of the following options, separated by comma or
|
||||
whitespace. Option names are case-insensitive. </p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><b>ca-constraint</b></dt>
|
||||
|
||||
<dd> Enable support for RFC 6698 (DANE TLSA) DNS records that
|
||||
contain digests of trust-anchors with certificate usage "0".
|
||||
These are often public root CAs, and server operators may
|
||||
expect that clients will have the corresponding root certificate
|
||||
in their CAfile or CApath. Most SSL/TLS servers do not send public
|
||||
root CA certificate in their certificate chain, so if Postfix does
|
||||
not have the CA certificate locally, there is no way to associate
|
||||
the digest with the trust chain from the server. These TLSA records
|
||||
are fragile, and only work when you have a complete (whatever that
|
||||
means) set of public CAs in your CAfile or CApath. Enable this
|
||||
with caution if at all. </dd>
|
||||
|
||||
<dt><b>trust-anchor-assertion</b></dt>
|
||||
|
||||
<dd> Enable support for RFC 6698 (DANE TLSA) DNS records that contain
|
||||
Enable support for RFC 6698 (DANE TLSA) DNS records that contain
|
||||
digests of trust-anchors with certificate usage "2". In this case
|
||||
the certificate usage logically requires the server administrator
|
||||
to configure the server to include the trust-anchor certificate in
|
||||
the server's SSL certificate chain. These TLSA records are less
|
||||
fragile than "ca-constraint" TLSA records, and are enabled by
|
||||
default. Having a "complete" CAfile or CApath does not help in
|
||||
this case, you are at the mercy of the remote server administrator's
|
||||
competence. </dd>
|
||||
|
||||
</dl>
|
||||
the server's SSL certificate chain. If enough domains mess this
|
||||
up, you can disable support for these TLSA records, but you'll no
|
||||
longer have secure connections that get it right and only publish
|
||||
trust anchor records. </p>
|
||||
|
||||
<p> At the <a href="TLS_README.html#client_tls_dane">dane</a>
|
||||
security level, when a TLSA RRset includes only unusable associations,
|
||||
@ -15301,6 +15302,11 @@ href="TLS_README.html#client_tls_dane">dane-only</a> security level,
|
||||
the server in question is skipped and delivery is deferred if no
|
||||
secure servers are found. </p>
|
||||
|
||||
<p> The tls_dane_digests parameter controls the list of digest
|
||||
algorithms that are supported in TLSA records. The tls_dane_digest_agility
|
||||
parameter controls digest algorithm downgrade attack resistance.
|
||||
</p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11 and later. </p>
|
||||
|
||||
%PARAM tls_wildcard_matches_multiple_labels yes
|
||||
@ -15448,47 +15454,104 @@ are not prepared to handle the new TLSA RRset. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11. </p>
|
||||
|
||||
%PARAM tls_dane_digest_agility on
|
||||
|
||||
<p> Configure DANE TLSA digest algorithm agility. When digest
|
||||
algorithm agility is enabled, and the server and client support a
|
||||
common strong digest algorithm, TLSA records with weaker digest
|
||||
algorithms are ignored. </p>
|
||||
|
||||
<p> Specify one of the following: </p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><b>off</b></dt>
|
||||
<dd> DANE verification examines each well-formed record in the TLSA
|
||||
RRset whose matching type is either "0" (no hash used) or is one of
|
||||
the digest algorithms listed in $tls_dane_digests. This setting
|
||||
is not recommended. </dd>
|
||||
|
||||
<dt><b>on</b></dt>
|
||||
<dd> From each group of well-formed TLSA RRs a non-zero digest
|
||||
matching type with the same certificate usage and selector, DANE
|
||||
verification examines only those records whose matching type has
|
||||
the highest precedence (appear earliest in $tls_dane_digests).
|
||||
</dd>
|
||||
|
||||
<dt><b>maybe</b></dt>
|
||||
<dd> For compatibility with digest algorithm agility, each certificate
|
||||
or public key whose digest is included in a DANE TLSA RRset, SHOULD
|
||||
be published with the same set of digest matching type values as
|
||||
any other with the same usage and selector. Therefore, compatible
|
||||
TLSA RRsets will contain an identical count of well-formed RRs with
|
||||
each non-zero digest matching type for any fixed combination of
|
||||
usage and selector. When this constraint is violated, or any of
|
||||
the digest records are malformed, digest algorithm agility will
|
||||
disabled. Otherwise, digest algorithm agility is enabled. </dd>
|
||||
|
||||
</dl>
|
||||
|
||||
<p> Digest algorithm agility ensures that the strongest digest
|
||||
supported by both the Postfix SMTP client and the remote server is
|
||||
used, and weaker digests are ignored. This supports non-disruptive
|
||||
deprecation of outdated digest algorithms. </p>
|
||||
|
||||
<p> To ensure compatibility with digest algorithm agility during
|
||||
key rotation, when a certificate or public key is being replaced
|
||||
with another, and both are published during the transition, both
|
||||
the old and the new certificate MUST be specified with the same set
|
||||
of digests. One can change the list of digest algorithms later,
|
||||
once old keys are retired. At any given time, change either the
|
||||
list of digests without changing the list of certificates or public
|
||||
keys or the list of certificates or public keys without changing
|
||||
the list of digests. Full value matching type "0" records are not
|
||||
subject to this constraint, but are discouraged due to the size of
|
||||
the resulting DNS records. </p>
|
||||
|
||||
<p> It is expected that this algorithm agility mechanism will be
|
||||
published in a standards track RFC for SMTP with DANE, and also in
|
||||
an eventual update to RFC 6698. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11 and later. </p>
|
||||
|
||||
%PARAM tls_dane_digests sha512 sha256
|
||||
|
||||
<p> RFC 6698 TLSA resource-record "matching type" digest algorithms
|
||||
in descending preference order. All the specified algorithms must
|
||||
be supported by the underlying OpenSSL library, otherwise the Postfix
|
||||
SMTP client will not support DANE TLSA security. </p>
|
||||
SMTP client will not support DANE TLSA security. </p>
|
||||
|
||||
<p> Specify a list of digest names separated by commas and/or
|
||||
whitespace. Each digest name may be followed by an optional
|
||||
"=<number>" suffix. For example, "sha512" may instead be specified
|
||||
as "sha512=2" and "sha256" may instead be specified as "sha256=1".
|
||||
The optional number must match the <a
|
||||
href="https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types"
|
||||
>IANA</a> assigned TLSA matching type number the algorithm in question.
|
||||
Postfix will check this constraint for the algorithms it knows about.
|
||||
Additional matching type algorithms registered with IANA can be added
|
||||
with explicit numbers provided they are supported by OpenSSL. </p>
|
||||
|
||||
<p> Invalid list elements are logged with a warning and disable DANE
|
||||
support. TLSA RRs that specify digests not included in the list are
|
||||
ignored with a warning. </p>
|
||||
|
||||
<p> Note: It is unwise to omit sha256 from the digest list. This
|
||||
digest algorithm is the only mandatory to implement digest algorithm
|
||||
in RFC 6698, and many servers are expected publish TLSA records
|
||||
with just sha256 digests. Unless one of the standard digests is
|
||||
seriously compromised and servers have had ample time to update their
|
||||
TLSA records you should not omit any standard digests, just arrange
|
||||
them in order from strongest to weakest. </p>
|
||||
|
||||
<p> When for a particular combination of "certificate usage" and
|
||||
"selector" the TLSA RRset contains a well-formed record with a
|
||||
matching type of "0", i.e. a full value of the associated certificate
|
||||
or public key, the Postfix SMTP client will ignore all other matching
|
||||
types for the same certificate usage and selector. In this case
|
||||
the first algorithm listed in tls_dane_digests will be used to
|
||||
compute a digest of the full value, which will then be used to match
|
||||
certificates or public keys in the server's certificate chain. </p>
|
||||
"selector" the TLSA RRset contains records with more than one digest
|
||||
matching type, the tls_dane_digest_agility parameter determines
|
||||
whether all the RRs are used, or only those with the most preferred
|
||||
digest matching type. </p>
|
||||
|
||||
<p> Otherwise, when for a particular combination of "certificate
|
||||
usage" and "selector" the TLSA RRset contains a records with more
|
||||
than one non-zero matching type, i.e. multiple digest algorithms,
|
||||
only records with the highest preference digest are used after
|
||||
discarding any records with an incorrect digest length as unusable. </p>
|
||||
<p> The tls_dane_trust_anchor_digest_enable parameter controls
|
||||
whether any digest TLSA records are acceptable in usage "2" (trust
|
||||
anchor assertion) TLSA records. </p>
|
||||
|
||||
<p> This strategy ensures that the strongest digest supported by
|
||||
both the Postfix SMTP client and the remote server is used, and
|
||||
weaker digests are ignored. This supports non-disruptive deprecation
|
||||
of outdated digest algorithms. </p>
|
||||
|
||||
<p> The strategy requires that when a TLSA RRset provides association
|
||||
data for multiple certificates or public keys, all RRs with the same
|
||||
"certificate usage" and "selector" be published with the same set
|
||||
of digests. In particular, during key rotation, when a certificate
|
||||
or public key is being replaced with another (and both are published
|
||||
during the transition) both the old and the new certificate MUST be
|
||||
specified with the same set of digests. One can change the list of
|
||||
digest algorithms later, once old keys are retired. At any given
|
||||
time change either the list of digests without changing the list of
|
||||
certificates or public keys or the list of certificates or public
|
||||
keys without changing the list of digests. </p>
|
||||
|
||||
<p> It is expected that this algorithm agility mechanism will be
|
||||
published in a standards track RFC for SMTP with DANE, and perhaps
|
||||
in an eventual update to RFC 6698. </p>
|
||||
|
||||
<p> This feature is available in Postfix 2.11. </p>
|
||||
<p> This feature is available in Postfix 2.11 and later. </p>
|
||||
|
@ -208,11 +208,12 @@ extern int dns_rr_eq_sa(DNS_RR *, struct sockaddr *);
|
||||
* dns_lookup.c
|
||||
*/
|
||||
extern int dns_lookup_r(const char *, unsigned, unsigned, DNS_RR **,
|
||||
VSTRING *, VSTRING *, int *);
|
||||
VSTRING *, VSTRING *, int *);
|
||||
extern int dns_lookup_rl(const char *, unsigned, DNS_RR **, VSTRING *,
|
||||
VSTRING *, int *, int,...);
|
||||
VSTRING *, int *, int,...);
|
||||
extern int dns_lookup_rv(const char *, unsigned, DNS_RR **, VSTRING *,
|
||||
VSTRING *, int *, int, unsigned *);
|
||||
VSTRING *, int *, int, unsigned *);
|
||||
|
||||
#define dns_lookup(name, type, rflags, list, fqdn, why) \
|
||||
dns_lookup_r((name), (type), (rflags), (list), (fqdn), (why), (int *) 0)
|
||||
#define dns_lookup_l(name, rflags, list, fqdn, why, lflags, ...) \
|
||||
|
@ -312,6 +312,7 @@ tests: tok822_test mime_tests strip_addr_test tok822_limit_test \
|
||||
xtext_test scache_multi_test ehlo_mask_test \
|
||||
namadr_list_test mail_conf_time_test header_body_checks_tests \
|
||||
mail_version_test server_acl_test resolve_local_test maps_test
|
||||
safe_ultostr_test
|
||||
|
||||
mime_tests: mime_test mime_nest mime_8bit mime_dom mime_trunc mime_cvt \
|
||||
mime_cvt2 mime_cvt3 mime_garb1 mime_garb2 mime_garb3 mime_garb4
|
||||
@ -516,6 +517,11 @@ mail_conf_time_test: mail_conf_time mail_conf_time.ref
|
||||
diff mail_conf_time.ref mail_conf_time.tmp
|
||||
rm -f mail_conf_time.tmp
|
||||
|
||||
safe_ultostr_test: safe_ultostr safe_ultostr.in safe_ultostr.ref
|
||||
./safe_ultostr <safe_ultostr.in >safe_ultostr.tmp 2>&1
|
||||
diff safe_ultostr.ref safe_ultostr.tmp
|
||||
rm -f safe_ultostr.tmp
|
||||
|
||||
header_body_checks_null_test: header_body_checks header_body_checks_null.ref
|
||||
./header_body_checks "" "" "" "" \
|
||||
<mime_test.in >header_body_checks_null.tmp 2>&1
|
||||
|
@ -3103,6 +3103,16 @@ extern char *var_tls_ssl_options;
|
||||
#define DEF_TLS_BC_PKEY_FPRINT 0
|
||||
extern bool var_tls_bc_pkey_fprint;
|
||||
|
||||
/*
|
||||
* Ordered list of DANE digest algorithms.
|
||||
*/
|
||||
#define TLS_DANE_AGILITY_OFF "off"
|
||||
#define TLS_DANE_AGILITY_ON "on"
|
||||
#define TLS_DANE_AGILITY_MAYBE "maybe"
|
||||
#define VAR_TLS_DANE_AGILITY "tls_dane_digest_agility"
|
||||
#define DEF_TLS_DANE_AGILITY TLS_DANE_AGILITY_ON
|
||||
extern char *var_tls_dane_agility;
|
||||
|
||||
/*
|
||||
* Ordered list of DANE digest algorithms.
|
||||
*/
|
||||
@ -3113,13 +3123,11 @@ extern char *var_tls_dane_digests;
|
||||
/*
|
||||
* External interface for enabling trust-anchor digests, which are risky
|
||||
* when the corresponding certificate is missing from the peer chain (this
|
||||
* can't happend with the leaf certificate).
|
||||
* can't happen with the leaf certificate).
|
||||
*/
|
||||
#define TLS_DANE_CC "ca-constraint"
|
||||
#define TLS_DANE_TAA "trust-anchor-assertion"
|
||||
#define VAR_TLS_DANE_TA_DGST "tls_dane_trust_anchor_digest_enable"
|
||||
#define DEF_TLS_DANE_TA_DGST TLS_DANE_TAA
|
||||
extern char *var_tls_dane_ta_dgst;
|
||||
#define VAR_TLS_DANE_TAA_DGST "tls_dane_trust_anchor_digest_enable"
|
||||
#define DEF_TLS_DANE_TAA_DGST 1
|
||||
extern bool var_tls_dane_taa_dgst;
|
||||
|
||||
/*
|
||||
* Sendmail-style mail filter support.
|
||||
|
@ -20,7 +20,7 @@
|
||||
* Patches change both the patchlevel and the release date. Snapshots have no
|
||||
* patchlevel; they change the release date only.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20131126"
|
||||
#define MAIL_RELEASE_DATE "20131217"
|
||||
#define MAIL_VERSION_NUMBER "2.11"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -26,7 +26,7 @@
|
||||
/* that it does not drag in all the LDAP, SQL and other map
|
||||
/* lookup client code into programs that don't need it.
|
||||
/*
|
||||
/* Each pattern is of the form "name.type" or "type", where
|
||||
/* Each pattern is of the form "name/type" or "type", where
|
||||
/* "name" and "type" are the first two fields of a master.cf
|
||||
/* entry. Patterns are separated by whitespace and/or commas.
|
||||
/* Matches are case insensitive. Patterns are matched in the
|
||||
@ -34,6 +34,9 @@
|
||||
/* match. In order to reverse the result of a pattern match,
|
||||
/* precede a pattern with an exclamation point (!).
|
||||
/*
|
||||
/* For backwards compatibility, the form name.type is still
|
||||
/* supported.
|
||||
/*
|
||||
/* match_service_init() parses the pattern list. The result
|
||||
/* must be passed to match_service_match() or match_service_free().
|
||||
/*
|
||||
@ -78,6 +81,19 @@
|
||||
#include <stringops.h>
|
||||
#include <match_service.h>
|
||||
|
||||
/* match_service_compat - backwards compatibility */
|
||||
|
||||
static void match_service_compat(ARGV *argv)
|
||||
{
|
||||
char **cpp;
|
||||
char *cp;
|
||||
|
||||
for (cpp = argv->argv; *cpp; cpp++) {
|
||||
if (strrchr(*cpp, '/') == 0 && (cp = strrchr(*cpp, '.')) != 0)
|
||||
*cp = '/';
|
||||
}
|
||||
}
|
||||
|
||||
/* match_service_init - initialize pattern list */
|
||||
|
||||
ARGV *match_service_init(const char *patterns)
|
||||
@ -92,6 +108,7 @@ ARGV *match_service_init(const char *patterns)
|
||||
argv_add(list, item, (char *) 0);
|
||||
argv_terminate(list);
|
||||
myfree(saved_patterns);
|
||||
match_service_compat(list);
|
||||
return (list);
|
||||
}
|
||||
|
||||
@ -105,6 +122,7 @@ ARGV *match_service_init_argv(char **patterns)
|
||||
for (cpp = patterns; *cpp; cpp++)
|
||||
argv_add(list, *cpp, (char *) 0);
|
||||
argv_terminate(list);
|
||||
match_service_compat(list);
|
||||
return (list);
|
||||
}
|
||||
|
||||
@ -127,8 +145,8 @@ int match_service_match(ARGV *list, const char *name_type)
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
if ((type = strrchr(name_type, '.')) == 0 || *++type == 0)
|
||||
msg_panic("%s: malformed service: \"%s\"; need \"name.type\" format",
|
||||
if ((type = strrchr(name_type, '/')) == 0 || *++type == 0)
|
||||
msg_panic("%s: malformed service: \"%s\"; need \"name/type\" format",
|
||||
myname, name_type);
|
||||
|
||||
/*
|
||||
@ -139,7 +157,7 @@ int match_service_match(ARGV *list, const char *name_type)
|
||||
msg_info("%s: %s ~? %s", myname, name_type, pattern);
|
||||
for (match = 1; *pattern == '!'; pattern++)
|
||||
match = !match;
|
||||
if (strcasecmp(strchr(pattern, '.') ? name_type : type, pattern) == 0) {
|
||||
if (strcasecmp(strchr(pattern, '/') ? name_type : type, pattern) == 0) {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s: found match", myname, name_type);
|
||||
return (match);
|
||||
|
@ -97,7 +97,7 @@ static unsigned char safe_chars[] =
|
||||
/* safe_ultostr - convert unsigned long to safe alphanumerical string */
|
||||
|
||||
char *safe_ultostr(VSTRING *buf, unsigned long ulval, int base,
|
||||
int padlen, int padchar)
|
||||
int padlen, int padchar)
|
||||
{
|
||||
const char *myname = "safe_ultostr";
|
||||
char *start;
|
||||
@ -171,6 +171,8 @@ unsigned long safe_strtoul(const char *start, char **end, int base)
|
||||
/*
|
||||
* Skip leading whitespace. We don't implement sign/base prefixes.
|
||||
*/
|
||||
if (end)
|
||||
*end = (char *) start;
|
||||
while (ISSPACE(*start))
|
||||
++start;
|
||||
|
||||
@ -178,13 +180,7 @@ unsigned long safe_strtoul(const char *start, char **end, int base)
|
||||
* Start the conversion.
|
||||
*/
|
||||
errno = 0;
|
||||
for (cp = (unsigned char *) start; *cp; cp++) {
|
||||
/* Return (0, EINVAL) if no conversion was made. */
|
||||
if ((char_val = char_map[*cp]) >= base) {
|
||||
if (cp == (unsigned char *) start)
|
||||
errno = EINVAL;
|
||||
break;
|
||||
}
|
||||
for (cp = (unsigned char *) start; (char_val = char_map[*cp]) < base; cp++) {
|
||||
/* Return (ULONG_MAX, ERANGE) if the result is too large. */
|
||||
if (sum > div_limit
|
||||
|| (sum == div_limit && char_val > mod_limit)) {
|
||||
@ -197,7 +193,10 @@ unsigned long safe_strtoul(const char *start, char **end, int base)
|
||||
}
|
||||
sum = sum * base + char_val;
|
||||
}
|
||||
if (end)
|
||||
/* Return (0, EINVAL) after no conversion. Test moved here 20131209. */
|
||||
if (cp == (unsigned char *) start)
|
||||
errno = EINVAL;
|
||||
else if (end)
|
||||
*end = (char *) cp;
|
||||
return (sum);
|
||||
}
|
||||
@ -225,6 +224,16 @@ int main(int unused_argc, char **unused_argv)
|
||||
#define strtoul strtol
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Hard-coded string-to-number test.
|
||||
*/
|
||||
ulval2 = safe_strtoul(" ", &junk, 10);
|
||||
if (*junk == 0 || errno != EINVAL)
|
||||
msg_warn("input=' ' result=%lu errno=%m", ulval2);
|
||||
|
||||
/*
|
||||
* Configurable number-to-string-to-number test.
|
||||
*/
|
||||
while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
|
||||
ch = 0;
|
||||
if (sscanf(STR(buf), "%lu %d%c", &ulval, &base, &ch) != 2 || ch) {
|
||||
|
4
postfix/src/global/safe_ultostr.in
Normal file
4
postfix/src/global/safe_ultostr.in
Normal file
@ -0,0 +1,4 @@
|
||||
4294967295 2
|
||||
4294967295 10
|
||||
4294967295 16
|
||||
4294967295 52
|
4
postfix/src/global/safe_ultostr.ref
Normal file
4
postfix/src/global/safe_ultostr.ref
Normal file
@ -0,0 +1,4 @@
|
||||
4294967295 = 11111111111111111111111111111111
|
||||
4294967295 = 4294967295
|
||||
4294967295 = HHHHHHHH
|
||||
4294967295 = CHPgSv
|
@ -532,7 +532,8 @@
|
||||
/* The location of the Postfix top-level queue directory.
|
||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||
/* The set of characters that can separate a user name from its
|
||||
/* address extension (user+foo).
|
||||
/* extension (example: user+foo), or a .forward file name from its
|
||||
/* extension (example: .forward+foo).
|
||||
/* .IP "\fBrequire_home_directory (no)\fR"
|
||||
/* Require that a \fBlocal\fR(8) recipient's home directory exists
|
||||
/* before mail delivery is attempted.
|
||||
|
@ -294,7 +294,7 @@ MASTER_SERV *get_master_ent()
|
||||
continue;
|
||||
name = cp;
|
||||
transport = get_str_ent(&bufp, "transport type", (char *) 0);
|
||||
vstring_sprintf(junk, "%s.%s", name, transport);
|
||||
vstring_sprintf(junk, "%s/%s", name, transport);
|
||||
if (match_service_match(master_disable, vstring_str(junk)) == 0)
|
||||
break;
|
||||
}
|
||||
|
@ -358,7 +358,7 @@ static sfsistat test_eom(SMFICTX *ctx)
|
||||
#endif
|
||||
{
|
||||
int count;
|
||||
char *args;
|
||||
char *args;
|
||||
|
||||
for (count = 0; count < add_rcpt_count; count++) {
|
||||
if ((args = strchr(add_rcpt[count], ' ')) != 0) {
|
||||
|
@ -395,7 +395,8 @@
|
||||
/* The location of the Postfix top-level queue directory.
|
||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||
/* The set of characters that can separate a user name from its
|
||||
/* address extension (user+foo).
|
||||
/* extension (example: user+foo), or a .forward file name from its
|
||||
/* extension (example: .forward+foo).
|
||||
/* .IP "\fBsyslog_facility (mail)\fR"
|
||||
/* The syslog facility of Postfix logging.
|
||||
/* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
|
||||
|
@ -2,11 +2,11 @@ SHELL = /bin/sh
|
||||
SRCS = postconf.c postconf_builtin.c postconf_edit.c postconf_main.c \
|
||||
postconf_master.c postconf_misc.c postconf_node.c postconf_other.c \
|
||||
postconf_service.c postconf_unused.c postconf_user.c postconf_dbms.c \
|
||||
postconf_lookup.c
|
||||
postconf_lookup.c postconf_match.c postconf_print.c
|
||||
OBJS = postconf.o postconf_builtin.o postconf_edit.o postconf_main.o \
|
||||
postconf_master.o postconf_misc.o postconf_node.o postconf_other.o \
|
||||
postconf_service.o postconf_unused.o postconf_user.o postconf_dbms.o \
|
||||
postconf_lookup.o
|
||||
postconf_lookup.o postconf_match.o postconf_print.o
|
||||
HDRS = postconf.h
|
||||
TESTSRC =
|
||||
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
|
||||
@ -45,7 +45,9 @@ test: $(TESTPROG)
|
||||
tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
|
||||
test12 test13 test14 test15 test16 test17 test18 test19 test20 test21 \
|
||||
test22 test23 test24 test25 test26 test27 test28 test29 test30 test4b \
|
||||
test31 test32 test33 test34 test35 test36 test37 test39 test40
|
||||
test31 test32 test33 test34 test35 test36 test37 test39 test40 test41 \
|
||||
test42 test43 test44 test45 test46 test47 test48 test49 test50 test51 \
|
||||
test52 test53 test54 test55 test56
|
||||
|
||||
root_tests:
|
||||
|
||||
@ -169,7 +171,7 @@ test9: $(PROG) test9.ref
|
||||
touch main.cf master.cf
|
||||
echo foo inet - n n - 0 spawn >> master.cf
|
||||
echo bar unix - n n - 0 spawn >> master.cf
|
||||
./$(PROG) -c . -M inet >test9.tmp 2>&1
|
||||
./$(PROG) -c . -M '*'/inet >test9.tmp 2>&1
|
||||
diff test9.ref test9.tmp
|
||||
rm -f main.cf master.cf test9.tmp
|
||||
|
||||
@ -178,7 +180,7 @@ test10: $(PROG) test10.ref
|
||||
touch main.cf master.cf
|
||||
echo foo inet - n n - 0 spawn >> master.cf
|
||||
echo bar unix - n n - 0 spawn >> master.cf
|
||||
./$(PROG) -c . -M bar.inet foo.unix >test10.tmp 2>&1
|
||||
./$(PROG) -c . -M bar/inet foo/unix >test10.tmp 2>&1
|
||||
diff test10.ref test10.tmp
|
||||
rm -f main.cf master.cf test10.tmp
|
||||
|
||||
@ -513,7 +515,7 @@ test39: $(PROG) test39.ref
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mfc . unix >test39.tmp 2>&1
|
||||
./$(PROG) -Mfc . '*'/unix >test39.tmp 2>&1
|
||||
diff test39.ref test39.tmp
|
||||
rm -f main.cf master.cf test39.tmp
|
||||
|
||||
@ -524,10 +526,183 @@ test40: $(PROG) test40.ref
|
||||
echo ' -voaaa=bbb' >> master.cf
|
||||
echo ' -vo ccc=$$aaa' >> master.cf
|
||||
echo ' -v -oddd=$$ccc' >> master.cf
|
||||
./$(PROG) -Mfxc . unix >test40.tmp 2>&1
|
||||
./$(PROG) -Mfxc . '*'/unix >test40.tmp 2>&1
|
||||
diff test40.ref test40.tmp
|
||||
rm -f main.cf master.cf test40.tmp
|
||||
|
||||
test41: $(PROG) test41.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar unix - n n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Pc . bar/unix/xxx=yyy bar/unix/aaa=bbb >test41.tmp 2>&1
|
||||
./$(PROG) -Mfc. >>test41.tmp 2>&1
|
||||
./$(PROG) -Pc . bar/unix/xxx=YYY bar/unix/aaa=BBB >>test41.tmp 2>&1
|
||||
./$(PROG) -Mfc. >>test41.tmp 2>&1
|
||||
./$(PROG) -Pc . >>test41.tmp 2>&1
|
||||
diff test41.ref test41.tmp
|
||||
rm -f main.cf master.cf test41.tmp
|
||||
|
||||
test42: $(PROG) test42.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar unix - n n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Pc . bar/unix/xxx=yyy bar/unix/aaa=bbb >test42.tmp 2>&1
|
||||
./$(PROG) -Mfc. >>test42.tmp 2>&1
|
||||
./$(PROG) -Pc . >>test42.tmp 2>&1
|
||||
./$(PROG) -PXc. bar/unix/xxx bar/unix/aaa >>test42.tmp 2>&1
|
||||
./$(PROG) -Mfc. >>test42.tmp 2>&1
|
||||
diff test42.ref test42.tmp
|
||||
rm -f main.cf master.cf test42.tmp
|
||||
|
||||
test43: $(PROG) test43.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar unix - n n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Fc . bar/unix/chroot=y bar/unix/command='aa -stuffobb=cc dd' >test43.tmp 2>&1
|
||||
./$(PROG) -Mfc. >>test43.tmp 2>&1
|
||||
diff test43.ref test43.tmp
|
||||
rm -f main.cf master.cf test43.tmp
|
||||
|
||||
test44: $(PROG) test44.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar unix - n n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mc . bar/unix='xx inet - n n - 0 aa -stuffobb=cc dd' >test44.tmp 2>&1
|
||||
./$(PROG) -Mfc. >>test44.tmp 2>&1
|
||||
diff test44.ref test44.tmp
|
||||
rm -f main.cf master.cf test44.tmp
|
||||
|
||||
test45: $(PROG) test45.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar xxxx - n n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mfc. >test45.tmp 2>&1 || true
|
||||
diff test45.ref test45.tmp
|
||||
rm -f main.cf master.cf test45.tmp
|
||||
|
||||
test46: $(PROG) test46.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet X n n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mfc. >test46.tmp 2>&1 || true
|
||||
diff test46.ref test46.tmp
|
||||
rm -f main.cf master.cf test46.tmp
|
||||
|
||||
test47: $(PROG) test47.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - X n - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mfc. >test47.tmp 2>&1 || true
|
||||
diff test47.ref test47.tmp
|
||||
rm -f main.cf master.cf test47.tmp
|
||||
|
||||
test48: $(PROG) test48.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n X - 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mfc. >test48.tmp 2>&1 || true
|
||||
diff test48.ref test48.tmp
|
||||
rm -f main.cf master.cf test48.tmp
|
||||
|
||||
test49: $(PROG) test49.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n X 0 other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mfc. >test49.tmp 2>&1 || true
|
||||
diff test49.ref test49.tmp
|
||||
rm -f main.cf master.cf test49.tmp
|
||||
|
||||
test50: $(PROG) test50.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n - X other >> master.cf
|
||||
echo baz unix - n n - 0 other >> master.cf
|
||||
./$(PROG) -Mfc. >test50.tmp 2>&1 || true
|
||||
diff test50.ref test50.tmp
|
||||
rm -f main.cf master.cf test50.tmp
|
||||
|
||||
test51: $(PROG) test51.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n -? 0 other >> master.cf
|
||||
echo bar inet - n n X? 0 other >> master.cf
|
||||
echo baz unix - n n 0? 0 other >> master.cf
|
||||
./$(PROG) -Mfc. >test51.tmp 2>&1 || true
|
||||
diff test51.ref test51.tmp
|
||||
rm -f main.cf master.cf test51.tmp
|
||||
|
||||
test52: $(PROG) test52.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n 0 0 other >> master.cf
|
||||
echo baz unix - n n 0 0 other >> master.cf
|
||||
./$(PROG) -MXc. bar/inet foo/unix xxx/yyy
|
||||
./$(PROG) -Mfc. >test52.tmp 2>&1 || true
|
||||
diff test52.ref test52.tmp
|
||||
rm -f main.cf master.cf test52.tmp
|
||||
|
||||
test53: $(PROG) test53.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n 0 0 other >> master.cf
|
||||
echo baz unix - n n 0 0 other >> master.cf
|
||||
./$(PROG) -M#c. bar/inet xxx/yyy
|
||||
diff test53.ref master.cf
|
||||
rm -f main.cf master.cf test53.tmp
|
||||
|
||||
test54: $(PROG) test54.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n 0 0 other >> master.cf
|
||||
echo baz unix - n n 0 0 other >> master.cf
|
||||
./$(PROG) -M#c. bar/inet foo/unix
|
||||
diff test54.ref master.cf
|
||||
rm -f main.cf master.cf test54.tmp
|
||||
|
||||
test55: $(PROG) test55.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n 0 0 other >> master.cf
|
||||
echo baz unix - n n 0 0 other >> master.cf
|
||||
./$(PROG) -M#c. bar/inet baz/unix
|
||||
diff test55.ref master.cf
|
||||
rm -f main.cf master.cf test55.tmp
|
||||
|
||||
test56: $(PROG) test56.ref
|
||||
rm -f main.cf master.cf
|
||||
touch main.cf master.cf
|
||||
echo foo unix - n n - 0 other >> master.cf
|
||||
echo bar inet - n n 0 0 other >> master.cf
|
||||
echo " -o first" >> master.cf
|
||||
echo " -o second" >> master.cf
|
||||
echo baz unix - n n 0 0 other >> master.cf
|
||||
./$(PROG) -M#c. bar/inet xxx/yyy
|
||||
diff test56.ref master.cf
|
||||
rm -f main.cf master.cf test56.tmp
|
||||
|
||||
printfck: $(OBJS) $(PROG)
|
||||
rm -rf printfck
|
||||
mkdir printfck
|
||||
@ -568,6 +743,7 @@ postconf.o: ../../include/msg.h
|
||||
postconf.o: ../../include/msg_vstream.h
|
||||
postconf.o: ../../include/myflock.h
|
||||
postconf.o: ../../include/mymalloc.h
|
||||
postconf.o: ../../include/name_code.h
|
||||
postconf.o: ../../include/name_mask.h
|
||||
postconf.o: ../../include/stringops.h
|
||||
postconf.o: ../../include/sys_defs.h
|
||||
@ -593,6 +769,7 @@ postconf_builtin.o: ../../include/msg.h
|
||||
postconf_builtin.o: ../../include/myflock.h
|
||||
postconf_builtin.o: ../../include/mymalloc.h
|
||||
postconf_builtin.o: ../../include/mynetworks.h
|
||||
postconf_builtin.o: ../../include/name_code.h
|
||||
postconf_builtin.o: ../../include/server_acl.h
|
||||
postconf_builtin.o: ../../include/stringops.h
|
||||
postconf_builtin.o: ../../include/sys_defs.h
|
||||
@ -634,6 +811,7 @@ postconf_dbms.o: ../../include/mac_expand.h
|
||||
postconf_dbms.o: ../../include/mac_parse.h
|
||||
postconf_dbms.o: ../../include/mail_conf.h
|
||||
postconf_dbms.o: ../../include/myflock.h
|
||||
postconf_dbms.o: ../../include/name_code.h
|
||||
postconf_dbms.o: ../../include/split_at.h
|
||||
postconf_dbms.o: ../../include/stringops.h
|
||||
postconf_dbms.o: ../../include/sys_defs.h
|
||||
@ -650,7 +828,9 @@ postconf_edit.o: ../../include/mail_params.h
|
||||
postconf_edit.o: ../../include/msg.h
|
||||
postconf_edit.o: ../../include/myflock.h
|
||||
postconf_edit.o: ../../include/mymalloc.h
|
||||
postconf_edit.o: ../../include/name_code.h
|
||||
postconf_edit.o: ../../include/readlline.h
|
||||
postconf_edit.o: ../../include/split_at.h
|
||||
postconf_edit.o: ../../include/stringops.h
|
||||
postconf_edit.o: ../../include/sys_defs.h
|
||||
postconf_edit.o: ../../include/vbuf.h
|
||||
@ -668,6 +848,7 @@ postconf_lookup.o: ../../include/mail_conf.h
|
||||
postconf_lookup.o: ../../include/msg.h
|
||||
postconf_lookup.o: ../../include/myflock.h
|
||||
postconf_lookup.o: ../../include/mymalloc.h
|
||||
postconf_lookup.o: ../../include/name_code.h
|
||||
postconf_lookup.o: ../../include/stringops.h
|
||||
postconf_lookup.o: ../../include/sys_defs.h
|
||||
postconf_lookup.o: ../../include/vbuf.h
|
||||
@ -685,6 +866,7 @@ postconf_main.o: ../../include/mail_params.h
|
||||
postconf_main.o: ../../include/msg.h
|
||||
postconf_main.o: ../../include/myflock.h
|
||||
postconf_main.o: ../../include/mymalloc.h
|
||||
postconf_main.o: ../../include/name_code.h
|
||||
postconf_main.o: ../../include/readlline.h
|
||||
postconf_main.o: ../../include/stringops.h
|
||||
postconf_main.o: ../../include/sys_defs.h
|
||||
@ -697,11 +879,13 @@ postconf_master.o: ../../include/argv.h
|
||||
postconf_master.o: ../../include/dict.h
|
||||
postconf_master.o: ../../include/htable.h
|
||||
postconf_master.o: ../../include/mail_params.h
|
||||
postconf_master.o: ../../include/match_service.h
|
||||
postconf_master.o: ../../include/master_proto.h
|
||||
postconf_master.o: ../../include/msg.h
|
||||
postconf_master.o: ../../include/myflock.h
|
||||
postconf_master.o: ../../include/mymalloc.h
|
||||
postconf_master.o: ../../include/name_code.h
|
||||
postconf_master.o: ../../include/readlline.h
|
||||
postconf_master.o: ../../include/split_at.h
|
||||
postconf_master.o: ../../include/stringops.h
|
||||
postconf_master.o: ../../include/sys_defs.h
|
||||
postconf_master.o: ../../include/vbuf.h
|
||||
@ -709,6 +893,20 @@ postconf_master.o: ../../include/vstream.h
|
||||
postconf_master.o: ../../include/vstring.h
|
||||
postconf_master.o: postconf.h
|
||||
postconf_master.o: postconf_master.c
|
||||
postconf_match.o: ../../include/argv.h
|
||||
postconf_match.o: ../../include/dict.h
|
||||
postconf_match.o: ../../include/htable.h
|
||||
postconf_match.o: ../../include/msg.h
|
||||
postconf_match.o: ../../include/myflock.h
|
||||
postconf_match.o: ../../include/mymalloc.h
|
||||
postconf_match.o: ../../include/name_code.h
|
||||
postconf_match.o: ../../include/split_at.h
|
||||
postconf_match.o: ../../include/sys_defs.h
|
||||
postconf_match.o: ../../include/vbuf.h
|
||||
postconf_match.o: ../../include/vstream.h
|
||||
postconf_match.o: ../../include/vstring.h
|
||||
postconf_match.o: postconf.h
|
||||
postconf_match.o: postconf_match.c
|
||||
postconf_misc.o: ../../include/argv.h
|
||||
postconf_misc.o: ../../include/dict.h
|
||||
postconf_misc.o: ../../include/htable.h
|
||||
@ -716,6 +914,7 @@ postconf_misc.o: ../../include/mail_conf.h
|
||||
postconf_misc.o: ../../include/mail_params.h
|
||||
postconf_misc.o: ../../include/myflock.h
|
||||
postconf_misc.o: ../../include/mymalloc.h
|
||||
postconf_misc.o: ../../include/name_code.h
|
||||
postconf_misc.o: ../../include/safe.h
|
||||
postconf_misc.o: ../../include/sys_defs.h
|
||||
postconf_misc.o: ../../include/vbuf.h
|
||||
@ -729,6 +928,7 @@ postconf_node.o: ../../include/htable.h
|
||||
postconf_node.o: ../../include/msg.h
|
||||
postconf_node.o: ../../include/myflock.h
|
||||
postconf_node.o: ../../include/mymalloc.h
|
||||
postconf_node.o: ../../include/name_code.h
|
||||
postconf_node.o: ../../include/sys_defs.h
|
||||
postconf_node.o: ../../include/vbuf.h
|
||||
postconf_node.o: ../../include/vstream.h
|
||||
@ -740,6 +940,7 @@ postconf_other.o: ../../include/dict.h
|
||||
postconf_other.o: ../../include/htable.h
|
||||
postconf_other.o: ../../include/mbox_conf.h
|
||||
postconf_other.o: ../../include/myflock.h
|
||||
postconf_other.o: ../../include/name_code.h
|
||||
postconf_other.o: ../../include/sys_defs.h
|
||||
postconf_other.o: ../../include/vbuf.h
|
||||
postconf_other.o: ../../include/vstream.h
|
||||
@ -747,6 +948,18 @@ postconf_other.o: ../../include/vstring.h
|
||||
postconf_other.o: ../../include/xsasl.h
|
||||
postconf_other.o: postconf.h
|
||||
postconf_other.o: postconf_other.c
|
||||
postconf_print.o: ../../include/argv.h
|
||||
postconf_print.o: ../../include/dict.h
|
||||
postconf_print.o: ../../include/htable.h
|
||||
postconf_print.o: ../../include/msg.h
|
||||
postconf_print.o: ../../include/myflock.h
|
||||
postconf_print.o: ../../include/name_code.h
|
||||
postconf_print.o: ../../include/sys_defs.h
|
||||
postconf_print.o: ../../include/vbuf.h
|
||||
postconf_print.o: ../../include/vstream.h
|
||||
postconf_print.o: ../../include/vstring.h
|
||||
postconf_print.o: postconf.h
|
||||
postconf_print.o: postconf_print.c
|
||||
postconf_service.o: ../../include/argv.h
|
||||
postconf_service.o: ../../include/dict.h
|
||||
postconf_service.o: ../../include/htable.h
|
||||
@ -754,6 +967,7 @@ postconf_service.o: ../../include/mail_params.h
|
||||
postconf_service.o: ../../include/msg.h
|
||||
postconf_service.o: ../../include/myflock.h
|
||||
postconf_service.o: ../../include/mymalloc.h
|
||||
postconf_service.o: ../../include/name_code.h
|
||||
postconf_service.o: ../../include/stringops.h
|
||||
postconf_service.o: ../../include/sys_defs.h
|
||||
postconf_service.o: ../../include/vbuf.h
|
||||
@ -768,6 +982,7 @@ postconf_unused.o: ../../include/mail_conf.h
|
||||
postconf_unused.o: ../../include/mail_params.h
|
||||
postconf_unused.o: ../../include/msg.h
|
||||
postconf_unused.o: ../../include/myflock.h
|
||||
postconf_unused.o: ../../include/name_code.h
|
||||
postconf_unused.o: ../../include/sys_defs.h
|
||||
postconf_unused.o: ../../include/vbuf.h
|
||||
postconf_unused.o: ../../include/vstream.h
|
||||
@ -784,6 +999,7 @@ postconf_user.o: ../../include/mail_params.h
|
||||
postconf_user.o: ../../include/msg.h
|
||||
postconf_user.o: ../../include/myflock.h
|
||||
postconf_user.o: ../../include/mymalloc.h
|
||||
postconf_user.o: ../../include/name_code.h
|
||||
postconf_user.o: ../../include/stringops.h
|
||||
postconf_user.o: ../../include/sys_defs.h
|
||||
postconf_user.o: ../../include/vbuf.h
|
||||
|
@ -11,15 +11,40 @@
|
||||
/* [\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* [\fIparameter=value ...\fR]
|
||||
/* \fIparameter=value ...\fR
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-#vX\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* [\fIparameter ...\fR]
|
||||
/* \fIparameter ...\fR
|
||||
/*
|
||||
/* \fBManaging master.cf:\fR
|
||||
/* \fBManaging master.cf service entries:\fR
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-fMovx\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* [\fIservice ...\fR]
|
||||
/* [\fIservice\fR[\fB/\fItype\fR]\fI ...\fR]
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-eMv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* \fIservice\fB/\fItype=value ...\fR
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-#MvX\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* \fIservice\fB/\fItype ...\fR
|
||||
/*
|
||||
/* \fBManaging master.cf service fields:\fR
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-fFovx\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* [\fIservice\fR[\fB/\fItype\fR[\fB/\fIfield\fR]]\fI ...\fR]
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-eFv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* \fIservice\fB/\fItype\fB/\fIfield=value ...\fR
|
||||
/*
|
||||
/* \fBManaging master.cf service parameters:\fR
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-fPovx\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* [\fIservice\fR[\fB/\fItype\fR[\fB/\fIparameter\fR]]\fI ...\fR]
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-ePv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* \fIservice\fB/\fItype\fB/\fIparameter=value ...\fR
|
||||
/*
|
||||
/* \fBpostconf\fR [\fB-PXv\fR] [\fB-c \fIconfig_dir\fR]
|
||||
/* \fIservice\fB/\fItype\fB/\fIparameter ...\fR
|
||||
/*
|
||||
/* \fBManaging bounce message templates:\fR
|
||||
/*
|
||||
@ -108,21 +133,56 @@
|
||||
/* (Postfix 2.9 and later).
|
||||
/* .IP \fB-e\fR
|
||||
/* Edit the \fBmain.cf\fR configuration file, and update
|
||||
/* parameter settings with the "\fIname=value\fR" pairs
|
||||
/* on the \fBpostconf\fR(1) command line. The file is copied
|
||||
/* to a temporary file then renamed into place.
|
||||
/* Specify quotes to protect special characters and whitespace
|
||||
/* on the \fBpostconf\fR(1) command line.
|
||||
/* parameter settings with the "\fIname=value\fR" pairs on the
|
||||
/* \fBpostconf\fR(1) command line.
|
||||
/*
|
||||
/* The \fB-e\fR is no longer needed with Postfix version 2.8
|
||||
/* and later.
|
||||
/* With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
/* and replace one or more service entries with new values as
|
||||
/* specified with "\fIservice/type=value\fR" on the \fBpostconf\fR(1)
|
||||
/* command line.
|
||||
/*
|
||||
/* With \fB-F\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
/* and replace one or more service fields with new values as
|
||||
/* specied with "\fIservice/type/field=value\fR" on the
|
||||
/* \fBpostconf\fR(1) command line. Currently, the "command"
|
||||
/* field contains the command name and command arguments. this
|
||||
/* may change in the near future, so that the "command" field
|
||||
/* contains only the command name, and a new "arguments"
|
||||
/* pseudofield contains the command arguments.
|
||||
/*
|
||||
/* With \fB-P\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
/* and add or update one or more service parameter settings
|
||||
/* (-o parameter=value settings) with new values as specied
|
||||
/* with "\fIservice/type/parameter=value\fR" on the \fBpostconf\fR(1)
|
||||
/* command line.
|
||||
/*
|
||||
/* In all cases the file is copied to a temporary file then
|
||||
/* renamed into place. Specify quotes to protect special
|
||||
/* characters and whitespace on the \fBpostconf\fR(1) command
|
||||
/* line.
|
||||
/*
|
||||
/* The \fB-e\fR option is no longer needed with Postfix version
|
||||
/* 2.8 and later.
|
||||
/* .IP \fB-f\fR
|
||||
/* Fold long lines when printing \fBmain.cf\fR or \fBmaster.cf\fR
|
||||
/* configuration file entries, for human readability.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.9 and later.
|
||||
/* .IP \fB-F\fR
|
||||
/* Show \fBmaster.cf\fR per-entry field settings (by default
|
||||
/* all services and all fields), formatted as one
|
||||
/* "\fIservice/type/field=value\fR" per line. Specify \fB-Ff\fR
|
||||
/* to fold long lines.
|
||||
/*
|
||||
/* Specify one or more "\fIservice/type/field\fR" instances
|
||||
/* on the \fBpostconf\fR(1) command line to limit the output
|
||||
/* to fields of interest. Trailing parameter name or service
|
||||
/* type fields that are omitted will be handled as "*" wildcard
|
||||
/* fields.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.11 and later.
|
||||
/* .IP \fB-h\fR
|
||||
/* Show \fBmain.cf\fR parameter values without the "\fIname\fR
|
||||
/* Show parameter or attribute values without the "\fIname\fR
|
||||
/* = " label that normally precedes the value.
|
||||
/* .IP \fB-l\fR
|
||||
/* List the names of all supported mailbox locking methods.
|
||||
@ -133,21 +193,22 @@
|
||||
/* This locking method is available on systems with a BSD
|
||||
/* compatible library.
|
||||
/* .IP \fBfcntl\fR
|
||||
/* A kernel-based advisory locking method for local and remote files.
|
||||
/* A kernel-based advisory locking method for local and remote
|
||||
/* files.
|
||||
/* .IP \fBdotlock\fR
|
||||
/* An application-level locking method. An application locks a file
|
||||
/* named \fIfilename\fR by creating a file named \fIfilename\fB.lock\fR.
|
||||
/* The application is expected to remove its own lock file, as well as
|
||||
/* stale lock files that were left behind after abnormal program
|
||||
/* termination.
|
||||
/* An application-level locking method. An application locks
|
||||
/* a file named \fIfilename\fR by creating a file named
|
||||
/* \fIfilename\fB.lock\fR. The application is expected to
|
||||
/* remove its own lock file, as well as stale lock files that
|
||||
/* were left behind after abnormal program termination.
|
||||
/* .RE
|
||||
/* .IP \fB-m\fR
|
||||
/* List the names of all supported lookup table types. In Postfix
|
||||
/* configuration files,
|
||||
/* lookup tables are specified as \fItype\fB:\fIname\fR, where
|
||||
/* \fItype\fR is one of the types listed below. The table \fIname\fR
|
||||
/* syntax depends on the lookup table type as described in the
|
||||
/* DATABASE_README document.
|
||||
/* List the names of all supported lookup table types. In
|
||||
/* Postfix configuration files, lookup tables are specified
|
||||
/* as \fItype\fB:\fIname\fR, where \fItype\fR is one of the
|
||||
/* types listed below. The table \fIname\fR syntax depends on
|
||||
/* the lookup table type as described in the DATABASE_README
|
||||
/* document.
|
||||
/* .RS
|
||||
/* .IP \fBbtree\fR
|
||||
/* A sorted, balanced tree structure. Available on systems
|
||||
@ -210,53 +271,78 @@
|
||||
/* .IP "\fBsqlite\fR (read-only)"
|
||||
/* SQLite database. This is described in \fBsqlite_table\fR(5).
|
||||
/* .IP "\fBstatic\fR (read-only)"
|
||||
/* A table that always returns its name as lookup result. For example,
|
||||
/* \fBstatic:foobar\fR always returns the string \fBfoobar\fR as lookup
|
||||
/* result.
|
||||
/* A table that always returns its name as lookup result. For
|
||||
/* example, \fBstatic:foobar\fR always returns the string
|
||||
/* \fBfoobar\fR as lookup result.
|
||||
/* .IP "\fBtcp\fR (read-only)"
|
||||
/* TCP/IP client. The protocol is described in \fBtcp_table\fR(5).
|
||||
/* .IP "\fBtexthash\fR (read-only)"
|
||||
/* Produces similar results as hash: files, except that you don't
|
||||
/* need to run the \fBpostmap\fR(1) command before you can use the file,
|
||||
/* and that it does not detect changes after the file is read.
|
||||
/* Produces similar results as hash: files, except that you
|
||||
/* don't need to run the \fBpostmap\fR(1) command before you
|
||||
/* can use the file, and that it does not detect changes after
|
||||
/* the file is read.
|
||||
/* .IP "\fBunix\fR (read-only)"
|
||||
/* A limited view of the UNIX authentication database. The
|
||||
/* following tables are implemented:
|
||||
/* .RS
|
||||
/*. IP \fBunix:passwd.byname\fR
|
||||
/* The table is the UNIX password database. The key is a login name.
|
||||
/* The result is a password file entry in \fBpasswd\fR(5) format.
|
||||
/* The table is the UNIX password database. The key is a login
|
||||
/* name. The result is a password file entry in \fBpasswd\fR(5)
|
||||
/* format.
|
||||
/* .IP \fBunix:group.byname\fR
|
||||
/* The table is the UNIX group database. The key is a group name.
|
||||
/* The result is a group file entry in \fBgroup\fR(5) format.
|
||||
/* The table is the UNIX group database. The key is a group
|
||||
/* name. The result is a group file entry in \fBgroup\fR(5)
|
||||
/* format.
|
||||
/* .RE
|
||||
/* .RE
|
||||
/* .IP
|
||||
/* Other table types may exist depending on how Postfix was built.
|
||||
/* Other table types may exist depending on how Postfix was
|
||||
/* built.
|
||||
/* .IP \fB-M\fR
|
||||
/* Show \fBmaster.cf\fR file contents instead of \fBmain.cf\fR
|
||||
/* file contents.
|
||||
/* Specify \fB-Mf\fR to fold long lines for human readability.
|
||||
/* file contents. Specify \fB-Mf\fR to fold long lines for
|
||||
/* human readability.
|
||||
/*
|
||||
/* If \fIservice ...\fR is specified, only the matching services
|
||||
/* will be output. For example, "\fBpostconf -Mf inet\fR"
|
||||
/* will output all services that listen on the network.
|
||||
/* Specify zero or more arguments, each with a \fIservice-name\fR
|
||||
/* or \fIservice-name/service-type\fR pair, where \fIservice-name\fR
|
||||
/* is the first field of a master.cf entry and \fIservice-type\fR
|
||||
/* is one of (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR).
|
||||
/*
|
||||
/* Specify zero or more arguments, each with a \fIservice-type\fR
|
||||
/* name (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR)
|
||||
/* or with a \fIservice-name.service-type\fR pair, where
|
||||
/* \fIservice-name\fR is the first field of a master.cf entry.
|
||||
/* If \fIservice-name\fR or \fIservice-name/service-type\fR
|
||||
/* is specified, only the matching master.cf entries will be
|
||||
/* output. For example, "\fBpostconf -Mf smtp\fR" will output
|
||||
/* all services named "smtp", and "\fBpostconf -Mf smtp/inet\fR"
|
||||
/* will output only the smtp service that listens on the
|
||||
/* network. Trailing service type fields that are omitted
|
||||
/* will be handled as "*" wildcard fields.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.9 and later.
|
||||
/* This feature is available with Postfix 2.9 and later. The
|
||||
/* syntax was changed from "\fIname.type\fR" to "\fIname/type\fR",
|
||||
/* and "*" wildcard support was added with Postfix 2.11.
|
||||
/* .IP \fB-n\fR
|
||||
/* Show only configuration parameters that have explicit
|
||||
/* \fIname=value\fR settings in \fBmain.cf\fR.
|
||||
/* Specify \fB-nf\fR to fold long lines for human readability
|
||||
/* (Postfix 2.9 and later).
|
||||
/* \fIname=value\fR settings in \fBmain.cf\fR. Specify \fB-nf\fR
|
||||
/* to fold long lines for human readability (Postfix 2.9 and
|
||||
/* later).
|
||||
/* .IP "\fB-o \fIname=value\fR"
|
||||
/* Override \fBmain.cf\fR parameter settings.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.10 and later.
|
||||
/* .IP \fB-p\fR
|
||||
/* Show \fBmain.cf\fR parameter settings. This is the default.
|
||||
/* .IP \fB-P\fR
|
||||
/* Show \fBmaster.cf\fR service parameter settings (by default
|
||||
/* all services and all parameters). formatted as one
|
||||
/* "\fIservice/type/parameter=value\fR" per line. Specify
|
||||
/* \fB-Pf\fR to fold long lines.
|
||||
/*
|
||||
/* Specify one or more "\fIservice/type/parameter\fR" instances
|
||||
/* on the \fBpostconf\fR(1) command line to limit the output
|
||||
/* to parameters of interest. Trailing parameter name or
|
||||
/* service type fields that are omitted will be handled as "*"
|
||||
/* wildcard fields.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.11 and later.
|
||||
/* .IP "\fB-t\fR [\fItemplate_file\fR]"
|
||||
/* Display the templates for text that appears at the beginning
|
||||
/* of delivery status notification (DSN) messages, without
|
||||
@ -273,34 +359,59 @@
|
||||
/*
|
||||
/* This feature is available with Postfix 2.3 and later.
|
||||
/* .IP \fB-v\fR
|
||||
/* Enable verbose logging for debugging purposes. Multiple \fB-v\fR
|
||||
/* options make the software increasingly verbose.
|
||||
/* Enable verbose logging for debugging purposes. Multiple
|
||||
/* \fB-v\fR options make the software increasingly verbose.
|
||||
/* .IP \fB-x\fR
|
||||
/* Expand \fI$name\fR in \fBmain.cf\fR or \fBmaster.cf\fR
|
||||
/* parameter values. The expansion is recursive.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.10 and later.
|
||||
/* .IP \fB-X\fR
|
||||
/* Edit the \fBmain.cf\fR configuration file, and remove
|
||||
/* the parameters named on the \fBpostconf\fR(1) command line.
|
||||
/* The file is copied to a temporary file then renamed into
|
||||
/* place.
|
||||
/* Edit the \fBmain.cf\fR configuration file, and remove the
|
||||
/* parameters named on the \fBpostconf\fR(1) command line.
|
||||
/* Specify a list of parameter names, not "\fIname=value\fR"
|
||||
/* pairs. There is no \fBpostconf\fR(1) command to perform
|
||||
/* the reverse operation.
|
||||
/* pairs.
|
||||
/*
|
||||
/* With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
/* and remove one or more service entries as specified with
|
||||
/* "\fIservice/type\fR" on the \fBpostconf\fR(1) command line.
|
||||
/*
|
||||
/* With \fB-P\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
/* and remove one or more service parameter settings (-o
|
||||
/* parameter=value settings) as specied with
|
||||
/* "\fIservice/type/parameter\fR" on the \fBpostconf\fR(1)
|
||||
/* command line.
|
||||
/*
|
||||
/* In all cases the file is copied to a temporary file then
|
||||
/* renamed into place. Specify quotes to protect special
|
||||
/* characters on the \fBpostconf\fR(1) command line.
|
||||
/*
|
||||
/* There is no \fBpostconf\fR(1) command to perform the reverse
|
||||
/* operation.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.10 and later.
|
||||
/* Support for -M and -P was added with Postfix 2.11.
|
||||
/* .IP \fB-#\fR
|
||||
/* Edit the \fBmain.cf\fR configuration file, and comment out
|
||||
/* the parameters named on the \fBpostconf\fR(1) command line,
|
||||
/* so that those parameters revert to their default values.
|
||||
/* The file is copied to a temporary file then renamed into
|
||||
/* place.
|
||||
/* Specify a list of parameter names, not "\fIname=value\fR"
|
||||
/* pairs. There is no \fBpostconf\fR(1) command to perform
|
||||
/* the reverse operation.
|
||||
/* pairs.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.6 and later.
|
||||
/* With \fB-M\fR, edit the \fBmaster.cf\fR configuration file,
|
||||
/* and comment out one or more service entries as specified
|
||||
/* with "\fIservice/type\fR" on the \fBpostconf\fR(1) command
|
||||
/* line.
|
||||
/*
|
||||
/* In all cases the file is copied to a temporary file then
|
||||
/* renamed into place. Specify quotes to protect special
|
||||
/* characters on the \fBpostconf\fR(1) command line.
|
||||
/*
|
||||
/* There is no \fBpostconf\fR(1) command to perform the reverse
|
||||
/* operation.
|
||||
/*
|
||||
/* This feature is available with Postfix 2.6 and later. Support
|
||||
/* for -M was added with Postfix 2.11.
|
||||
/* DIAGNOSTICS
|
||||
/* Problems are reported to the standard error stream.
|
||||
/* ENVIRONMENT
|
||||
@ -311,8 +422,8 @@
|
||||
/* CONFIGURATION PARAMETERS
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The following \fBmain.cf\fR parameters are especially relevant to
|
||||
/* this program.
|
||||
/* The following \fBmain.cf\fR parameters are especially
|
||||
/* relevant to this program.
|
||||
/*
|
||||
/* The text below provides only a parameter summary. See
|
||||
/* \fBpostconf\fR(5) for more details including examples.
|
||||
@ -323,28 +434,27 @@
|
||||
/* Pathname of a configuration file with bounce message templates.
|
||||
/* FILES
|
||||
/* /etc/postfix/main.cf, Postfix configuration parameters
|
||||
/* /etc/postfix/master.cf, Postfix master daemon configuraton
|
||||
/* /etc/postfix/master.cf, Postfix master daemon configuration
|
||||
/* SEE ALSO
|
||||
/* bounce(5), bounce template file format
|
||||
/* master(5), master.cf configuration file syntax
|
||||
/* postconf(5), main.cf configuration file syntax
|
||||
/* bounce(5), bounce template file format master(5), master.cf
|
||||
/* configuration file syntax postconf(5), main.cf configuration
|
||||
/* file syntax
|
||||
/* README FILES
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* Use "\fBpostconf readme_directory\fR" or
|
||||
/* "\fBpostconf html_directory\fR" to locate this information.
|
||||
/* Use "\fBpostconf readme_directory\fR" or "\fBpostconf
|
||||
/* html_directory\fR" to locate this information.
|
||||
/* .na
|
||||
/* .nf
|
||||
/* DATABASE_README, Postfix lookup table overview
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* 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
|
||||
/* Wietse Venema IBM T.J. Watson Research P.O. Box 704 Yorktown
|
||||
/* Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
@ -390,6 +500,153 @@ int cmd_mode = DEF_MODE;
|
||||
*/
|
||||
MAIL_VERSION_STAMP_DECLARE;
|
||||
|
||||
/*
|
||||
* This program has so many command-line options that we have to implement a
|
||||
* compatibility matrix to weed out the conflicting option combinations, and
|
||||
* to alert the user about option combinations that have no effect.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Options that are mutually-exclusive. First entry must specify the major
|
||||
* modes. Other entries specify conflicts between option modifiers.
|
||||
*/
|
||||
static const int incompat_options[] = {
|
||||
/* Major modes. */
|
||||
SHOW_SASL_SERV | SHOW_SASL_CLNT | EXP_DSN_TEMPL | SHOW_LOCKS | SHOW_MAPS \
|
||||
|DUMP_DSN_TEMPL | MAIN_PARAM | MASTER_ENTRY | MASTER_FIELD | MASTER_PARAM,
|
||||
/* Modifiers. */
|
||||
SHOW_DEFS | EDIT_CONF | SHOW_NONDEF | COMMENT_OUT | EDIT_EXCL,
|
||||
FOLD_LINE | EDIT_CONF | COMMENT_OUT | EDIT_EXCL,
|
||||
SHOW_EVAL | EDIT_CONF | COMMENT_OUT | EDIT_EXCL,
|
||||
MAIN_OVER | SHOW_DEFS | EDIT_CONF | COMMENT_OUT | EDIT_EXCL,
|
||||
HIDE_NAME | EDIT_CONF | COMMENT_OUT | EDIT_EXCL,
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Options, and the only options that they are compatible with. There must
|
||||
* be one entry for each major mode. Other entries specify compatibility
|
||||
* between option modifiers.
|
||||
*/
|
||||
static const int compat_options[][2] = {
|
||||
/* Major modes. */
|
||||
{SHOW_SASL_SERV, 0},
|
||||
{SHOW_SASL_CLNT, 0},
|
||||
{EXP_DSN_TEMPL, 0},
|
||||
{SHOW_LOCKS, 0},
|
||||
{SHOW_MAPS, 0,},
|
||||
{DUMP_DSN_TEMPL, 0},
|
||||
{MAIN_PARAM, EDIT_CONF | EDIT_EXCL | COMMENT_OUT | FOLD_LINE | HIDE_NAME \
|
||||
|PARAM_CLASS | SHOW_EVAL | SHOW_DEFS | SHOW_NONDEF | MAIN_OVER},
|
||||
{MASTER_ENTRY, EDIT_CONF | EDIT_EXCL | COMMENT_OUT | FOLD_LINE | MAIN_OVER \
|
||||
|SHOW_EVAL},
|
||||
{MASTER_FIELD, EDIT_CONF | FOLD_LINE | HIDE_NAME | MAIN_OVER | SHOW_EVAL},
|
||||
{MASTER_PARAM, EDIT_CONF | EDIT_EXCL | FOLD_LINE | HIDE_NAME | MAIN_OVER \
|
||||
|SHOW_EVAL},
|
||||
/* Modifiers. */
|
||||
{PARAM_CLASS, MAIN_PARAM | SHOW_DEFS | SHOW_NONDEF},
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
* Compatibility to string conversion support.
|
||||
*/
|
||||
static const NAME_MASK compat_names[] = {
|
||||
"-a", SHOW_SASL_SERV,
|
||||
"-A", SHOW_SASL_CLNT,
|
||||
"-b", EXP_DSN_TEMPL,
|
||||
"-C", PARAM_CLASS,
|
||||
"-d", SHOW_DEFS,
|
||||
"-e", EDIT_CONF,
|
||||
"-f", FOLD_LINE,
|
||||
"-F", MASTER_FIELD,
|
||||
"-h", HIDE_NAME,
|
||||
"-l", SHOW_LOCKS,
|
||||
"-m", SHOW_MAPS,
|
||||
"-M", MASTER_ENTRY,
|
||||
"-n", SHOW_NONDEF,
|
||||
"-o", MAIN_OVER,
|
||||
"-p", MAIN_PARAM,
|
||||
"-P", MASTER_PARAM,
|
||||
"-t", DUMP_DSN_TEMPL,
|
||||
"-x", SHOW_EVAL,
|
||||
"-X", EDIT_EXCL,
|
||||
"-#", COMMENT_OUT,
|
||||
0,
|
||||
};
|
||||
|
||||
/* usage - enumerate parameters without compatibility info */
|
||||
|
||||
static void usage(const char *progname)
|
||||
{
|
||||
msg_fatal("usage: %s"
|
||||
" [-a (server SASL types)]"
|
||||
" [-A (client SASL types)]"
|
||||
" [-b (bounce templates)]"
|
||||
" [-c config_dir]"
|
||||
" [-c param_class]"
|
||||
" [-d (parameter defaults)]"
|
||||
" [-e (edit configuration)]"
|
||||
" [-f (fold lines)]"
|
||||
" [-F (master.cf fields)]"
|
||||
" [-h (no names)]"
|
||||
" [-l (lock types)]"
|
||||
" [-m (map types)]"
|
||||
" [-M (master.cf)]"
|
||||
" [-n (non-default parameters)]"
|
||||
" [-o name=value (override parameter value)]"
|
||||
" [-p (main.cf, default)]"
|
||||
" [-P (master.cf parameters)]"
|
||||
" [-t (bounce templates)]"
|
||||
" [-v (verbose)]"
|
||||
" [-x (expand parameter values)]"
|
||||
" [-X (exclude)]"
|
||||
" [-# (comment-out)]"
|
||||
" [name...]", progname);
|
||||
}
|
||||
|
||||
/* check_exclusive_options - complain about mutually-exclusive options */
|
||||
|
||||
static void check_exclusive_options(int optval)
|
||||
{
|
||||
const char *myname = "check_exclusive_options";
|
||||
const int *op;
|
||||
int oval;
|
||||
unsigned mask;
|
||||
|
||||
for (op = incompat_options; (oval = *op) != 0; op++) {
|
||||
oval &= optval;
|
||||
for (mask = ~0; (mask & oval) != 0; mask >>= 1) {
|
||||
if ((mask & oval) != oval)
|
||||
msg_fatal("specify one of %s",
|
||||
str_name_mask(myname, compat_names, oval));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* check_compat_options - complain about incompatible options */
|
||||
|
||||
static void check_compat_options(int optval)
|
||||
{
|
||||
const char *myname = "check_compat_options";
|
||||
VSTRING *buf1 = vstring_alloc(10);
|
||||
VSTRING *buf2 = vstring_alloc(10);
|
||||
const int (*op)[2];
|
||||
int excess;
|
||||
|
||||
for (op = compat_options; op[0][0] != 0; op++) {
|
||||
if ((optval & *op[0]) != 0
|
||||
&& (excess = (optval & ~((*op)[0] | (*op)[1]))) != 0)
|
||||
msg_fatal("with option %s, do not specify %s",
|
||||
str_name_mask_opt(buf1, myname, compat_names,
|
||||
(*op)[0], NAME_MASK_NUMBER),
|
||||
str_name_mask_opt(buf2, myname, compat_names, excess,
|
||||
NAME_MASK_NUMBER));
|
||||
}
|
||||
vstring_free(buf1);
|
||||
vstring_free(buf2);
|
||||
}
|
||||
|
||||
/* main */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
@ -397,7 +654,6 @@ int main(int argc, char **argv)
|
||||
int ch;
|
||||
int fd;
|
||||
struct stat st;
|
||||
int junk;
|
||||
ARGV *ext_argv = 0;
|
||||
int param_class = PC_PARAM_MASK_CLASS;
|
||||
static const NAME_MASK param_class_table[] = {
|
||||
@ -437,7 +693,7 @@ int main(int argc, char **argv)
|
||||
/*
|
||||
* Parse JCL.
|
||||
*/
|
||||
while ((ch = GETOPT(argc, argv, "aAbc:C:deEf#hlmMno:tvxX")) > 0) {
|
||||
while ((ch = GETOPT(argc, argv, "aAbc:C:deEfFhlmMno:pPtvxX#")) > 0) {
|
||||
switch (ch) {
|
||||
case 'a':
|
||||
cmd_mode |= SHOW_SASL_SERV;
|
||||
@ -446,6 +702,7 @@ int main(int argc, char **argv)
|
||||
cmd_mode |= SHOW_SASL_CLNT;
|
||||
break;
|
||||
case 'b':
|
||||
cmd_mode |= EXP_DSN_TEMPL;
|
||||
if (ext_argv)
|
||||
msg_fatal("specify one of -b and -t");
|
||||
ext_argv = argv_alloc(2);
|
||||
@ -463,16 +720,19 @@ int main(int argc, char **argv)
|
||||
cmd_mode |= SHOW_DEFS;
|
||||
break;
|
||||
case 'e':
|
||||
cmd_mode |= EDIT_MAIN;
|
||||
cmd_mode |= EDIT_CONF;
|
||||
break;
|
||||
case 'f':
|
||||
cmd_mode |= FOLD_LINE;
|
||||
break;
|
||||
case 'F':
|
||||
cmd_mode |= MASTER_FIELD;
|
||||
break;
|
||||
case '#':
|
||||
cmd_mode = COMMENT_OUT;
|
||||
cmd_mode |= COMMENT_OUT;
|
||||
break;
|
||||
case 'h':
|
||||
cmd_mode &= ~SHOW_NAME;
|
||||
cmd_mode |= HIDE_NAME;
|
||||
break;
|
||||
case 'l':
|
||||
cmd_mode |= SHOW_LOCKS;
|
||||
@ -481,17 +741,25 @@ int main(int argc, char **argv)
|
||||
cmd_mode |= SHOW_MAPS;
|
||||
break;
|
||||
case 'M':
|
||||
cmd_mode |= SHOW_MASTER;
|
||||
cmd_mode |= MASTER_ENTRY;
|
||||
break;
|
||||
case 'n':
|
||||
cmd_mode |= SHOW_NONDEF;
|
||||
break;
|
||||
case 'o':
|
||||
cmd_mode |= MAIN_OVER;
|
||||
if (override_params == 0)
|
||||
override_params = argv_alloc(2);
|
||||
argv_add(override_params, optarg, (char *) 0);
|
||||
break;
|
||||
case 'p':
|
||||
cmd_mode |= MAIN_PARAM;
|
||||
break;
|
||||
case 'P':
|
||||
cmd_mode |= MASTER_PARAM;
|
||||
break;
|
||||
case 't':
|
||||
cmd_mode |= DUMP_DSN_TEMPL;
|
||||
if (ext_argv)
|
||||
msg_fatal("specify one of -b and -t");
|
||||
ext_argv = argv_alloc(2);
|
||||
@ -508,27 +776,27 @@ int main(int argc, char **argv)
|
||||
msg_verbose++;
|
||||
break;
|
||||
default:
|
||||
msg_fatal("usage: %s [-a (server SASL types)] [-A (client SASL types)] [-b (bounce templates)] [-c config_dir] [-C param_class] [-d (defaults)] [-e (edit)] [-f (fold lines)] [-# (comment-out)] [-h (no names)] [-l (lock types)] [-m (map types)] [-M (master.cf)] [-n (non-defaults)] [-v] [-X (exclude)] [name...]", argv[0]);
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Make all options explicit, before checking their compatibility.
|
||||
*/
|
||||
if ((cmd_mode & incompat_options[0]) == 0)
|
||||
cmd_mode |= MAIN_PARAM;
|
||||
if ((cmd_mode & (MAIN_PARAM | MASTER_ENTRY | MASTER_FIELD | MASTER_PARAM))
|
||||
&& argv[optind] && strchr(argv[optind], '='))
|
||||
cmd_mode |= EDIT_CONF;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
junk = (cmd_mode & (SHOW_DEFS | SHOW_MAPS | SHOW_LOCKS | EDIT_MAIN | SHOW_SASL_SERV | SHOW_SASL_CLNT | COMMENT_OUT | SHOW_MASTER | EDIT_EXCL));
|
||||
if (junk != 0 && ((junk != SHOW_DEFS
|
||||
&& junk != SHOW_MAPS && junk != SHOW_LOCKS && junk != EDIT_MAIN
|
||||
&& junk != SHOW_SASL_SERV && junk != SHOW_SASL_CLNT
|
||||
&& junk != COMMENT_OUT && junk != SHOW_MASTER
|
||||
&& junk != EDIT_EXCL)
|
||||
|| ext_argv != 0))
|
||||
msg_fatal("specify one of -a, -A, -b, -d, -e, -#, -l, -m, -M, and -X");
|
||||
if ((cmd_mode & SHOW_EVAL) != 0 && junk != 0 && junk != SHOW_DEFS && junk != SHOW_MASTER)
|
||||
msg_fatal("do not specify -x with -a, -A, -b, -e, -#, -l, -m, or -X");
|
||||
if ((cmd_mode & SHOW_NONDEF) != 0 && junk != 0)
|
||||
msg_fatal("do not specify -n with -a, -A, -b, -d, -e, -#, -l, -m, -M, or -X");
|
||||
if (override_params != 0 && junk != 0 && junk != SHOW_MASTER)
|
||||
msg_fatal("do not specify -o with -a, -A, -b, -d, -e, -#, -l, -m, or -X");
|
||||
check_exclusive_options(cmd_mode);
|
||||
check_compat_options(cmd_mode);
|
||||
|
||||
if ((cmd_mode & EDIT_CONF) && argc == optind)
|
||||
msg_fatal("-e requires name=value argument");
|
||||
|
||||
/*
|
||||
* Display bounce template information and exit.
|
||||
@ -569,7 +837,8 @@ int main(int argc, char **argv)
|
||||
/*
|
||||
* If showing master.cf entries, show them and exit
|
||||
*/
|
||||
else if (cmd_mode & SHOW_MASTER) {
|
||||
else if ((cmd_mode & (MASTER_ENTRY | MASTER_FIELD | MASTER_PARAM))
|
||||
&& !(cmd_mode & (EDIT_CONF | EDIT_EXCL | COMMENT_OUT))) {
|
||||
read_master(FAIL_ON_OPEN_ERROR);
|
||||
read_parameters();
|
||||
if (override_params)
|
||||
@ -577,7 +846,12 @@ int main(int argc, char **argv)
|
||||
register_builtin_parameters(basename(argv[0]), getpid());
|
||||
register_service_parameters();
|
||||
register_user_parameters();
|
||||
show_master(VSTREAM_OUT, cmd_mode, argv + optind);
|
||||
if (cmd_mode & MASTER_FIELD)
|
||||
show_master_fields(VSTREAM_OUT, cmd_mode, argc - optind, argv + optind);
|
||||
else if (cmd_mode & MASTER_PARAM)
|
||||
show_master_params(VSTREAM_OUT, cmd_mode, argc - optind, argv + optind);
|
||||
else
|
||||
show_master_entries(VSTREAM_OUT, cmd_mode, argc - optind, argv + optind);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -590,13 +864,16 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/*
|
||||
* Edit main.cf.
|
||||
* Edit main.cf or master.cf.
|
||||
*/
|
||||
else if (cmd_mode & (EDIT_MAIN | COMMENT_OUT | EDIT_EXCL)) {
|
||||
edit_parameters(cmd_mode, argc - optind, argv + optind);
|
||||
} else if (cmd_mode == DEF_MODE
|
||||
&& argv[optind] && strchr(argv[optind], '=')) {
|
||||
edit_parameters(cmd_mode | EDIT_MAIN, argc - optind, argv + optind);
|
||||
else if (cmd_mode & (EDIT_CONF | COMMENT_OUT | EDIT_EXCL)) {
|
||||
if (optind == argc)
|
||||
msg_fatal("missing service argument");
|
||||
if (cmd_mode & (MASTER_ENTRY | MASTER_FIELD | MASTER_PARAM)) {
|
||||
edit_master(cmd_mode, argc - optind, argv + optind);
|
||||
} else {
|
||||
edit_main(cmd_mode, argc - optind, argv + optind);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -19,25 +19,33 @@
|
||||
#include <htable.h>
|
||||
#include <argv.h>
|
||||
#include <dict.h>
|
||||
#include <name_code.h>
|
||||
|
||||
/*
|
||||
* What we're supposed to be doing.
|
||||
*/
|
||||
#define SHOW_NONDEF (1<<0) /* show main.cf non-default settings */
|
||||
#define SHOW_DEFS (1<<1) /* show main.cf default setting */
|
||||
#define SHOW_NAME (1<<2) /* show main.cf parameter name */
|
||||
#define HIDE_NAME (1<<2) /* hide main.cf parameter name */
|
||||
#define SHOW_MAPS (1<<3) /* show map types */
|
||||
#define EDIT_MAIN (1<<4) /* edit main.cf */
|
||||
#define EDIT_CONF (1<<4) /* edit main.cf or master.cf */
|
||||
#define SHOW_LOCKS (1<<5) /* show mailbox lock methods */
|
||||
#define SHOW_EVAL (1<<6) /* expand main.cf right-hand sides */
|
||||
#define SHOW_SASL_SERV (1<<7) /* show server auth plugin types */
|
||||
#define SHOW_SASL_CLNT (1<<8) /* show client auth plugin types */
|
||||
#define COMMENT_OUT (1<<9) /* #-out selected main.cf entries */
|
||||
#define SHOW_MASTER (1<<10) /* show master.cf entries */
|
||||
#define MASTER_ENTRY (1<<10) /* manage master.cf entries */
|
||||
#define FOLD_LINE (1<<11) /* fold long *.cf entries */
|
||||
#define EDIT_EXCL (1<<12) /* exclude main.cf entries */
|
||||
#define MASTER_FIELD (1<<13) /* hierarchical pathname */
|
||||
#define MAIN_PARAM (1<<14) /* manage main.cf entries */
|
||||
#define EXP_DSN_TEMPL (1<<15) /* expand bounce templates */
|
||||
#define PARAM_CLASS (1<<16) /* select parameter class */
|
||||
#define MAIN_OVER (1<<17) /* override parameter values */
|
||||
#define DUMP_DSN_TEMPL (1<<18) /* show bounce templates */
|
||||
#define MASTER_PARAM (1<<19) /* manage master.cf -o name=value */
|
||||
|
||||
#define DEF_MODE SHOW_NAME /* default mode */
|
||||
#define DEF_MODE 0
|
||||
|
||||
/*
|
||||
* Structure for one "valid parameter" (built-in, service-defined or valid
|
||||
@ -105,7 +113,7 @@ extern VSTRING *param_string_buf;
|
||||
* Structure of one master.cf entry.
|
||||
*/
|
||||
typedef struct {
|
||||
char *name_space; /* service.type, parameter name space */
|
||||
char *name_space; /* service/type, parameter name space */
|
||||
ARGV *argv; /* null, or master.cf fields */
|
||||
DICT *all_params; /* null, or all name=value entries */
|
||||
HTABLE *valid_names; /* null, or "valid" parameter names */
|
||||
@ -113,10 +121,31 @@ typedef struct {
|
||||
|
||||
#define PC_MASTER_MIN_FIELDS 8 /* mandatory field count */
|
||||
|
||||
/*
|
||||
* Lookup table for master.cf entries. The table is terminated with an entry
|
||||
* that has a null argv member.
|
||||
*/
|
||||
#define PC_MASTER_NAME_SERVICE "service"
|
||||
#define PC_MASTER_NAME_TYPE "type"
|
||||
#define PC_MASTER_NAME_PRIVATE "private"
|
||||
#define PC_MASTER_NAME_UNPRIV "unprivileged"
|
||||
#define PC_MASTER_NAME_CHROOT "chroot"
|
||||
#define PC_MASTER_NAME_WAKEUP "wakeup"
|
||||
#define PC_MASTER_NAME_MAXPROC "process_limit"
|
||||
#define PC_MASTER_NAME_CMD "command"
|
||||
|
||||
#define PC_MASTER_FIELD_SERVICE 0 /* service name */
|
||||
#define PC_MASTER_FIELD_TYPE 1 /* service type */
|
||||
#define PC_MASTER_FIELD_PRIVATE 2 /* private service */
|
||||
#define PC_MASTER_FIELD_UNPRIV 3 /* unprivileged service */
|
||||
#define PC_MASTER_FIELD_CHROOT 4 /* chrooted service */
|
||||
#define PC_MASTER_FIELD_WAKEUP 5 /* wakeup timer */
|
||||
#define PC_MASTER_FIELD_MAXPROC 6 /* process limit */
|
||||
#define PC_MASTER_FIELD_CMD 7 /* command */
|
||||
|
||||
#define PC_MASTER_FIELD_WILDC -1 /* wild-card */
|
||||
#define PC_MASTER_FIELD_NONE -2 /* not available
|
||||
*
|
||||
/* Lookup table for master.cf
|
||||
* entries. The table is terminated
|
||||
* with an entry that has a null argv
|
||||
* member. */
|
||||
PC_MASTER_ENT *master_table;
|
||||
|
||||
/*
|
||||
@ -147,18 +176,75 @@ extern void show_parameters(VSTREAM *, int, int, char **);
|
||||
/*
|
||||
* postconf_edit.c
|
||||
*/
|
||||
extern void edit_parameters(int, int, char **);
|
||||
extern void edit_main(int, int, char **);
|
||||
extern void edit_master(int, int, char **);
|
||||
|
||||
/*
|
||||
* postconf_master.c.
|
||||
*/
|
||||
extern const char daemon_options_expecting_value[];
|
||||
extern void read_master(int);
|
||||
extern void show_master(VSTREAM *, int, char **);
|
||||
extern void show_master_entries(VSTREAM *, int, int, char **);
|
||||
extern const char *parse_master_entry(PC_MASTER_ENT *, const char *);
|
||||
extern void print_master_entry(VSTREAM *, int, PC_MASTER_ENT *);
|
||||
extern void free_master_entry(PC_MASTER_ENT *);
|
||||
extern void show_master_fields(VSTREAM *, int, int, char **);
|
||||
extern void edit_master_field(PC_MASTER_ENT *, int, const char *);
|
||||
extern void show_master_params(VSTREAM *, int, int, char **);
|
||||
extern void edit_master_param(PC_MASTER_ENT *, int, const char *, const char *);
|
||||
|
||||
#define WARN_ON_OPEN_ERROR 0
|
||||
#define FAIL_ON_OPEN_ERROR 1
|
||||
|
||||
#define PC_MASTER_BLANKS " \t\r\n" /* XXX */
|
||||
|
||||
/*
|
||||
* Master.cf parameter namespace management. The idea is to manage master.cf
|
||||
* "-o name=value" settings with other tools than text editors.
|
||||
*
|
||||
* The natural choice is to use "service-name.service-type.parameter-name", but
|
||||
* unfortunately the '.' may appear in service and parameter names.
|
||||
*
|
||||
* For example, a spawn(8) listener can have a service name 127.0.0.1:10028.
|
||||
* This service name becomes part of a service-dependent parameter name
|
||||
* "127.0.0.1:10028_time_limit". All those '.' characters mean we can't use
|
||||
* '.' as the parameter namespace delimiter.
|
||||
*
|
||||
* (We could require that such service names are specified as $foo:port with
|
||||
* the value of "foo" defined in main.cf or at the top of master.cf.)
|
||||
*
|
||||
* But it is easier if we use '/' instead.
|
||||
*/
|
||||
#define PC_NAMESP_SEP_CH '/'
|
||||
#define PC_NAMESP_SEP_STR "/"
|
||||
|
||||
#define PC_LEGACY_SEP_CH '.'
|
||||
|
||||
/*
|
||||
* postconf_match.c.
|
||||
*/
|
||||
#define PC_MATCH_WILDC_STR "*"
|
||||
#define PC_MATCH_ANY(p) ((p)[0] == PC_MATCH_WILDC_STR[0] && (p)[1] == 0)
|
||||
#define PC_MATCH_STRING(p, s) (PC_MATCH_ANY(p) || strcmp((p), (s)) == 0)
|
||||
|
||||
extern ARGV *parse_service_pattern(const char *, int, int);
|
||||
extern int parse_field_pattern(const char *);
|
||||
|
||||
#define IS_MAGIC_SERVICE_PATTERN(pat) \
|
||||
(PC_MATCH_ANY((pat)->argv[0]) || PC_MATCH_ANY((pat)->argv[1]))
|
||||
#define MATCH_SERVICE_PATTERN(pat, name, type) \
|
||||
(PC_MATCH_STRING((pat)->argv[0], (name)) \
|
||||
&& PC_MATCH_STRING((pat)->argv[1], (type)))
|
||||
|
||||
#define is_magic_field_pattern(pat) ((pat) == PC_MASTER_FIELD_WILDC)
|
||||
#define str_field_pattern(pat) ((const char *) (field_name_offset[pat].name))
|
||||
|
||||
#define IS_MAGIC_PARAM_PATTERN(pat) PC_MATCH_ANY(pat)
|
||||
#define MATCH_PARAM_PATTERN(pat, name) PC_MATCH_STRING((pat), (name))
|
||||
|
||||
/* The following is not part of the postconf_match API. */
|
||||
extern NAME_CODE field_name_offset[];
|
||||
|
||||
/*
|
||||
* postconf_builtin.c.
|
||||
*/
|
||||
@ -197,6 +283,11 @@ const char *lookup_parameter_value(int, const char *, PC_MASTER_ENT *,
|
||||
|
||||
char *expand_parameter_value(VSTRING *, int, const char *, PC_MASTER_ENT *);
|
||||
|
||||
/*
|
||||
* postconf_print.c.
|
||||
*/
|
||||
extern void print_line(VSTREAM *, int, const char *,...);
|
||||
|
||||
/*
|
||||
* postconf_unused.c.
|
||||
*/
|
||||
|
@ -2,24 +2,57 @@
|
||||
/* NAME
|
||||
/* postconf_edit 3
|
||||
/* SUMMARY
|
||||
/* edit main.cf
|
||||
/* edit main.cf or master.cf
|
||||
/* SYNOPSIS
|
||||
/* #include <postconf.h>
|
||||
/*
|
||||
/* void edit_parameters(mode, argc, argv)
|
||||
/* void edit_main(mode, argc, argv)
|
||||
/* int mode;
|
||||
/* int argc;
|
||||
/* char **argv;
|
||||
/*
|
||||
/* void edit_master(mode, argc, argv)
|
||||
/* int mode;
|
||||
/* int argc;
|
||||
/* char **argv;
|
||||
/* DESCRIPTION
|
||||
/* Edit the \fBmain.cf\fR configuration file, and update
|
||||
/* parameter settings with the "\fIname\fR=\fIvalue\fR" pairs
|
||||
/* given on the command line. The file is copied to a temporary
|
||||
/* file then renamed into place.
|
||||
/* edit_main() edits the \fBmain.cf\fR configuration
|
||||
/* file. It replaces or adds parameter settings given as
|
||||
/* "\fIname=value\fR" pairs given on the command line, or
|
||||
/* removes parameter settings given as "\fIname\fR" on the
|
||||
/* command line. The file is copied to a temporary file
|
||||
/* then renamed into place.
|
||||
/*
|
||||
/* edit_master() edits the \fBmaster.cf\fR configuration file.
|
||||
/* The file is copied to a temporary file then renamed into
|
||||
/* place. Depending on the flags in \fBmode\fR:
|
||||
/* .IP MASTER_ENTRY
|
||||
/* With EDIT_CONF, edit_master() replaces or adds entire
|
||||
/* master.cf entries, specified on the command line as
|
||||
/* "\fIname/type = name type private unprivileged chroot wakeup
|
||||
/* process_limit command...\fR".
|
||||
/*
|
||||
/* With EDIT_EXCL or COMMENT_OUT, edit_master() removes or
|
||||
/* comments out entries specified on the command line as
|
||||
/* "\fIname/type\fR.
|
||||
/* .IP MASTER_FIELD
|
||||
/* With EDIT_CONF, edit_master() replaces the value of specific
|
||||
/* service attributes, specified on the command line as
|
||||
/* "\fIname/type/attribute = value\fR".
|
||||
/* .IP MASTER_PARAM
|
||||
/* With EDIT_CONF, edit_master() replaces or adds the value
|
||||
/* of service parameters, specified on the command line as
|
||||
/* "\fIname/type/parameter = value\fR".
|
||||
/*
|
||||
/* With EDIT_EXCL, edit_master() removes service parameters
|
||||
/* specified on the command line as "\fIparametername\fR".
|
||||
/* DIAGNOSTICS
|
||||
/* Problems are reported to the standard error stream.
|
||||
/* FILES
|
||||
/* /etc/postfix/main.cf, Postfix configuration parameters
|
||||
/* /etc/postfix/main.cf.tmp, temporary name
|
||||
/* /etc/postfix/master.cf, Postfix configuration parameters
|
||||
/* /etc/postfix/master.cf.tmp, temporary name
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -47,6 +80,7 @@
|
||||
#include <edit_file.h>
|
||||
#include <readlline.h>
|
||||
#include <stringops.h>
|
||||
#include <split_at.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
@ -58,9 +92,61 @@
|
||||
|
||||
#define STR(x) vstring_str(x)
|
||||
|
||||
/* edit_parameters - edit parameter file */
|
||||
/* find_cf_info - pass-through non-content line, return content or null */
|
||||
|
||||
void edit_parameters(int mode, int argc, char **argv)
|
||||
static char *find_cf_info(VSTRING *buf, VSTREAM *dst)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
for (cp = STR(buf); ISSPACE(*cp) /* including newline */ ; cp++)
|
||||
/* void */ ;
|
||||
/* Pass-through comment, all-whitespace, or empty line. */
|
||||
if (*cp == '#' || *cp == 0) {
|
||||
vstream_fputs(STR(buf), dst);
|
||||
return (0);
|
||||
} else {
|
||||
return (cp);
|
||||
}
|
||||
}
|
||||
|
||||
/* next_cf_line - return next content line, pass-through non-content */
|
||||
|
||||
static char *next_cf_line(VSTRING *buf, VSTREAM *src, VSTREAM *dst, int *lineno)
|
||||
{
|
||||
char *cp;
|
||||
|
||||
while (vstring_get(buf, src) != VSTREAM_EOF) {
|
||||
if (lineno)
|
||||
*lineno += 1;
|
||||
if ((cp = find_cf_info(buf, dst)) != 0)
|
||||
return (cp);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* gobble_cf_line - accumulate multi-line content, pass-through non-content */
|
||||
|
||||
static void gobble_cf_line(VSTRING *full_entry_buf, VSTRING *line_buf,
|
||||
VSTREAM *src, VSTREAM *dst, int *lineno)
|
||||
{
|
||||
int ch;
|
||||
|
||||
vstring_strcpy(full_entry_buf, STR(line_buf));
|
||||
for (;;) {
|
||||
if ((ch = VSTREAM_GETC(src)) != VSTREAM_EOF)
|
||||
vstream_ungetc(src, ch);
|
||||
if ((ch != '#' && !ISSPACE(ch))
|
||||
|| vstring_get(line_buf, src) == VSTREAM_EOF)
|
||||
break;
|
||||
lineno += 1;
|
||||
if (find_cf_info(line_buf, dst))
|
||||
vstring_strcat(full_entry_buf, STR(line_buf));
|
||||
}
|
||||
}
|
||||
|
||||
/* edit_main - edit main.cf file */
|
||||
|
||||
void edit_main(int mode, int argc, char **argv)
|
||||
{
|
||||
char *path;
|
||||
EDIT_FILE *ep;
|
||||
@ -69,8 +155,8 @@ void edit_parameters(int mode, int argc, char **argv)
|
||||
VSTRING *buf = vstring_alloc(100);
|
||||
VSTRING *key = vstring_alloc(10);
|
||||
char *cp;
|
||||
char *edit_key;
|
||||
char *edit_val;
|
||||
char *pattern;
|
||||
char *edit_value;
|
||||
HTABLE *table;
|
||||
struct cvalue {
|
||||
char *value;
|
||||
@ -93,24 +179,24 @@ void edit_parameters(int mode, int argc, char **argv)
|
||||
cp++;
|
||||
if (*cp == '#')
|
||||
msg_fatal("-e, -X, or -# accepts no comment input");
|
||||
if (mode & EDIT_MAIN) {
|
||||
if ((err = split_nameval(cp, &edit_key, &edit_val)) != 0)
|
||||
if (mode & EDIT_CONF) {
|
||||
if ((err = split_nameval(cp, &pattern, &edit_value)) != 0)
|
||||
msg_fatal("%s: \"%s\"", err, cp);
|
||||
} else if (mode & (COMMENT_OUT | EDIT_EXCL)) {
|
||||
if (*cp == 0)
|
||||
msg_fatal("-X or -# requires non-blank parameter names");
|
||||
if (strchr(cp, '=') != 0)
|
||||
msg_fatal("-X or -# requires parameter names only");
|
||||
edit_key = cp;
|
||||
trimblanks(edit_key, 0);
|
||||
edit_val = 0;
|
||||
msg_fatal("-X or -# requires parameter names without value");
|
||||
pattern = cp;
|
||||
trimblanks(pattern, 0);
|
||||
edit_value = 0;
|
||||
} else {
|
||||
msg_panic("edit_parameters: unknown mode %d", mode);
|
||||
msg_panic("edit_main: unknown mode %d", mode);
|
||||
}
|
||||
cvalue = (struct cvalue *) mymalloc(sizeof(*cvalue));
|
||||
cvalue->value = edit_val;
|
||||
cvalue->value = edit_value;
|
||||
cvalue->found = 0;
|
||||
htable_enter(table, edit_key, (char *) cvalue);
|
||||
htable_enter(table, pattern, (char *) cvalue);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -139,15 +225,9 @@ void edit_parameters(int mode, int argc, char **argv)
|
||||
#define STR(x) vstring_str(x)
|
||||
|
||||
interesting = 0;
|
||||
while (vstring_get(buf, src) != VSTREAM_EOF) {
|
||||
for (cp = STR(buf); ISSPACE(*cp) /* including newline */ ; cp++)
|
||||
/* void */ ;
|
||||
/* Copy comment, all-whitespace, or empty line. */
|
||||
if (*cp == '#' || *cp == 0) {
|
||||
vstream_fputs(STR(buf), dst);
|
||||
}
|
||||
while ((cp = next_cf_line(buf, src, dst, (int *) 0)) != 0) {
|
||||
/* Copy, skip or replace continued text. */
|
||||
else if (cp > STR(buf)) {
|
||||
if (cp > STR(buf)) {
|
||||
if (interesting == 0)
|
||||
vstream_fputs(STR(buf), dst);
|
||||
else if (mode & COMMENT_OUT)
|
||||
@ -160,7 +240,7 @@ void edit_parameters(int mode, int argc, char **argv)
|
||||
if ((interesting = !!cvalue) != 0) {
|
||||
if (cvalue->found++ == 1)
|
||||
msg_warn("%s: multiple entries for \"%s\"", path, STR(key));
|
||||
if (mode & EDIT_MAIN)
|
||||
if (mode & EDIT_CONF)
|
||||
vstream_fprintf(dst, "%s = %s\n", STR(key), cvalue->value);
|
||||
else if (mode & COMMENT_OUT)
|
||||
vstream_fprintf(dst, "#%s", cp);
|
||||
@ -173,7 +253,7 @@ void edit_parameters(int mode, int argc, char **argv)
|
||||
/*
|
||||
* Generate new entries for parameters that were not found.
|
||||
*/
|
||||
if (mode & EDIT_MAIN) {
|
||||
if (mode & EDIT_CONF) {
|
||||
for (ht_info = ht = htable_list(table); *ht; ht++) {
|
||||
cvalue = (struct cvalue *) ht[0]->value;
|
||||
if (cvalue->found == 0)
|
||||
@ -198,3 +278,298 @@ void edit_parameters(int mode, int argc, char **argv)
|
||||
vstring_free(key);
|
||||
htable_free(table, myfree);
|
||||
}
|
||||
|
||||
/*
|
||||
* Data structure to hold a master.cf edit request.
|
||||
*/
|
||||
typedef struct {
|
||||
int match_count; /* hit count */
|
||||
const char *raw_text; /* unparsed command-line argument */
|
||||
char *parsed_text; /* destructive parse */
|
||||
ARGV *service_pattern; /* service name, type, ... */
|
||||
int field_number; /* attribute field number */
|
||||
const char *param_pattern; /* parameter name */
|
||||
char *edit_value; /* value substring */
|
||||
} PC_MASTER_EDIT_REQ;
|
||||
|
||||
/* edit_master - edit master.cf file */
|
||||
|
||||
void edit_master(int mode, int argc, char **argv)
|
||||
{
|
||||
const char *myname = "edit_master";
|
||||
char *path;
|
||||
EDIT_FILE *ep;
|
||||
VSTREAM *src;
|
||||
VSTREAM *dst;
|
||||
VSTRING *line_buf = vstring_alloc(100);
|
||||
VSTRING *parse_buf = vstring_alloc(100);
|
||||
int lineno;
|
||||
PC_MASTER_ENT *new_entry;
|
||||
VSTRING *full_entry_buf = vstring_alloc(100);
|
||||
char *cp;
|
||||
char *pattern;
|
||||
int service_name_type_matched;
|
||||
const char *err;
|
||||
PC_MASTER_EDIT_REQ *edit_reqs;
|
||||
PC_MASTER_EDIT_REQ *req;
|
||||
int num_reqs = argc;
|
||||
const char *edit_opts = "-Me, -Fe, -Pe, -X, or -#";
|
||||
char *service_name;
|
||||
char *service_type;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
if (num_reqs <= 0)
|
||||
msg_panic("%s: empty argument list", myname);
|
||||
|
||||
/*
|
||||
* Preprocessing: split pattern=value, then split the pattern components.
|
||||
*/
|
||||
edit_reqs = (PC_MASTER_EDIT_REQ *) mymalloc(sizeof(*edit_reqs) * num_reqs);
|
||||
for (req = edit_reqs; *argv != 0; req++, argv++) {
|
||||
req->match_count = 0;
|
||||
req->raw_text = *argv;
|
||||
cp = req->parsed_text = mystrdup(req->raw_text);
|
||||
if (strchr(cp, '\n') != 0)
|
||||
msg_fatal("%s accept no multi-line input", edit_opts);
|
||||
while (ISSPACE(*cp))
|
||||
cp++;
|
||||
if (*cp == '#')
|
||||
msg_fatal("%s accept no comment input", edit_opts);
|
||||
/* Separate the pattern from the value. */
|
||||
if (mode & EDIT_CONF) {
|
||||
if ((err = split_nameval(cp, &pattern, &req->edit_value)) != 0)
|
||||
msg_fatal("%s: \"%s\"", err, req->raw_text);
|
||||
if ((mode & MASTER_PARAM)
|
||||
&& req->edit_value[strcspn(req->edit_value, PC_MASTER_BLANKS)])
|
||||
msg_fatal("whitespace in parameter value: \"%s\"",
|
||||
req->raw_text);
|
||||
} else if (mode & (COMMENT_OUT | EDIT_EXCL)) {
|
||||
if (strchr(cp, '=') != 0)
|
||||
msg_fatal("-X or -# requires names without value");
|
||||
pattern = cp;
|
||||
trimblanks(pattern, 0);
|
||||
req->edit_value = 0;
|
||||
} else {
|
||||
msg_panic("%s: unknown mode %d", myname, mode);
|
||||
}
|
||||
|
||||
#define PC_MASTER_MASK (MASTER_ENTRY | MASTER_FIELD | MASTER_PARAM)
|
||||
|
||||
/*
|
||||
* Split name/type or name/type/whatever pattern into components.
|
||||
*/
|
||||
switch (mode & PC_MASTER_MASK) {
|
||||
case MASTER_ENTRY:
|
||||
if ((req->service_pattern =
|
||||
parse_service_pattern(pattern, 2, 2)) == 0)
|
||||
msg_fatal("-Me, -MX or -M# requires service_name/type");
|
||||
break;
|
||||
case MASTER_FIELD:
|
||||
if ((req->service_pattern =
|
||||
parse_service_pattern(pattern, 3, 3)) == 0)
|
||||
msg_fatal("-Fe or -FX requires service_name/type/field_name");
|
||||
req->field_number =
|
||||
parse_field_pattern(req->service_pattern->argv[2]);
|
||||
if (is_magic_field_pattern(req->field_number))
|
||||
msg_fatal("-Fe does not accept wild-card field name");
|
||||
if ((mode & EDIT_CONF)
|
||||
&& req->field_number < PC_MASTER_FIELD_CMD
|
||||
&& req->edit_value[strcspn(req->edit_value, PC_MASTER_BLANKS)])
|
||||
msg_fatal("-Fe does not accept whitespace in non-command field");
|
||||
break;
|
||||
case MASTER_PARAM:
|
||||
if ((req->service_pattern =
|
||||
parse_service_pattern(pattern, 3, 3)) == 0)
|
||||
msg_fatal("-Pe or -PX requires service_name/type/parameter");
|
||||
req->param_pattern = req->service_pattern->argv[2];
|
||||
if (IS_MAGIC_PARAM_PATTERN(req->param_pattern))
|
||||
msg_fatal("-Pe does not accept wild-card parameter name");
|
||||
if ((mode & EDIT_CONF)
|
||||
&& req->edit_value[strcspn(req->edit_value, PC_MASTER_BLANKS)])
|
||||
msg_fatal("-Pe does not accept whitespace in parameter value");
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: unknown edit mode %d", myname, mode);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a temp file for the result. This uses a deterministic name so we
|
||||
* don't leave behind thrash with random names.
|
||||
*/
|
||||
set_config_dir();
|
||||
path = concatenate(var_config_dir, "/", MASTER_CONF_FILE, (char *) 0);
|
||||
if ((ep = edit_file_open(path, O_CREAT | O_WRONLY, 0644)) == 0)
|
||||
msg_fatal("open %s%s: %m", path, EDIT_FILE_SUFFIX);
|
||||
dst = ep->tmp_fp;
|
||||
|
||||
/*
|
||||
* Open the original file for input.
|
||||
*/
|
||||
if ((src = vstream_fopen(path, O_RDONLY, 0)) == 0) {
|
||||
/* OK to delete, since we control the temp file name exclusively. */
|
||||
(void) unlink(ep->tmp_path);
|
||||
msg_fatal("open %s for reading: %m", path);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy original file to temp file, while replacing service entries on
|
||||
* the fly.
|
||||
*/
|
||||
service_name_type_matched = 0;
|
||||
new_entry = 0;
|
||||
lineno = 0;
|
||||
while ((cp = next_cf_line(parse_buf, src, dst, &lineno)) != 0) {
|
||||
vstring_strcpy(line_buf, STR(parse_buf));
|
||||
|
||||
/*
|
||||
* Copy, skip or replace continued text.
|
||||
*/
|
||||
if (cp > STR(parse_buf)) {
|
||||
if (service_name_type_matched == 0)
|
||||
vstream_fputs(STR(line_buf), dst);
|
||||
else if (mode & COMMENT_OUT)
|
||||
vstream_fprintf(dst, "#%s", STR(line_buf));
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy or replace (start of) logical line.
|
||||
*/
|
||||
else {
|
||||
service_name_type_matched = 0;
|
||||
|
||||
/*
|
||||
* Parse out the service name and type.
|
||||
*/
|
||||
if ((service_name = mystrtok(&cp, PC_MASTER_BLANKS)) == 0
|
||||
|| (service_type = mystrtok(&cp, PC_MASTER_BLANKS)) == 0)
|
||||
msg_fatal("file %s: line %d: specify service name and type "
|
||||
"on the same line", path, lineno);
|
||||
if (strchr(service_name, '='))
|
||||
msg_fatal("file %s: line %d: service name syntax \"%s\" is "
|
||||
"unsupported with %s", path, lineno, service_name,
|
||||
edit_opts);
|
||||
if (service_type[strcspn(service_type, "=/")] != 0)
|
||||
msg_fatal("file %s: line %d: "
|
||||
"service type syntax \"%s\" is unsupported with %s",
|
||||
path, lineno, service_type, edit_opts);
|
||||
|
||||
/*
|
||||
* Match each service pattern.
|
||||
*/
|
||||
for (req = edit_reqs; req < edit_reqs + num_reqs; req++) {
|
||||
if (MATCH_SERVICE_PATTERN(req->service_pattern, service_name,
|
||||
service_type)) {
|
||||
service_name_type_matched = 1; /* Sticky flag */
|
||||
req->match_count += 1;
|
||||
|
||||
/*
|
||||
* Generate replacement master.cf entries.
|
||||
*/
|
||||
if ((mode & EDIT_CONF)
|
||||
|| ((mode & MASTER_PARAM) && (mode & EDIT_EXCL))) {
|
||||
switch (mode & PC_MASTER_MASK) {
|
||||
|
||||
/*
|
||||
* Replace master.cf entry field or parameter
|
||||
* value.
|
||||
*/
|
||||
case MASTER_FIELD:
|
||||
case MASTER_PARAM:
|
||||
if (new_entry == 0) {
|
||||
/* Gobble up any continuation lines. */
|
||||
gobble_cf_line(full_entry_buf, line_buf, src,
|
||||
dst, &lineno);
|
||||
new_entry = (PC_MASTER_ENT *)
|
||||
mymalloc(sizeof(*new_entry));
|
||||
if ((err = parse_master_entry(new_entry,
|
||||
STR(full_entry_buf))) != 0)
|
||||
msg_fatal("file %s: line %d: %s",
|
||||
path, lineno, err);
|
||||
}
|
||||
if (mode & MASTER_FIELD) {
|
||||
edit_master_field(new_entry, req->field_number,
|
||||
req->edit_value);
|
||||
} else {
|
||||
edit_master_param(new_entry, mode,
|
||||
req->param_pattern,
|
||||
req->edit_value);
|
||||
}
|
||||
break;
|
||||
|
||||
/*
|
||||
* Replace entire master.cf entry.
|
||||
*/
|
||||
case MASTER_ENTRY:
|
||||
if (new_entry != 0)
|
||||
free_master_entry(new_entry);
|
||||
new_entry = (PC_MASTER_ENT *)
|
||||
mymalloc(sizeof(*new_entry));
|
||||
if ((err = parse_master_entry(new_entry,
|
||||
req->edit_value)) != 0)
|
||||
msg_fatal("%s: \"%s\"", err, req->raw_text);
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: unknown edit mode %d", myname, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Pass through or replace the current input line.
|
||||
*/
|
||||
if (new_entry) {
|
||||
print_master_entry(dst, FOLD_LINE, new_entry);
|
||||
free_master_entry(new_entry);
|
||||
new_entry = 0;
|
||||
} else if (service_name_type_matched == 0) {
|
||||
vstream_fputs(STR(line_buf), dst);
|
||||
} else if (mode & COMMENT_OUT) {
|
||||
vstream_fprintf(dst, "#%s", STR(line_buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Postprocessing: when editing entire service entries, generate new
|
||||
* entries for services not found. Otherwise (editing fields or
|
||||
* parameters), "service not found" is a fatal error.
|
||||
*/
|
||||
for (req = edit_reqs; req < edit_reqs + num_reqs; req++) {
|
||||
if (req->match_count == 0) {
|
||||
if ((mode & MASTER_ENTRY) && (mode & EDIT_CONF)) {
|
||||
new_entry = (PC_MASTER_ENT *) mymalloc(sizeof(*new_entry));
|
||||
if ((err = parse_master_entry(new_entry, req->edit_value)) != 0)
|
||||
msg_fatal("%s: \"%s\"", err, req->raw_text);
|
||||
print_master_entry(dst, FOLD_LINE, new_entry);
|
||||
free_master_entry(new_entry);
|
||||
} else if ((mode & MASTER_ENTRY) == 0) {
|
||||
msg_warn("unmatched service_name/type: \"%s\"", req->raw_text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* When all is well, rename the temp file to the original one.
|
||||
*/
|
||||
if (vstream_fclose(src))
|
||||
msg_fatal("read %s: %m", path);
|
||||
if (edit_file_close(ep) != 0)
|
||||
msg_fatal("close %s%s: %m", path, EDIT_FILE_SUFFIX);
|
||||
|
||||
/*
|
||||
* Cleanup.
|
||||
*/
|
||||
myfree(path);
|
||||
vstring_free(line_buf);
|
||||
vstring_free(parse_buf);
|
||||
vstring_free(full_entry_buf);
|
||||
for (req = edit_reqs; req < edit_reqs + num_reqs; req++) {
|
||||
argv_free(req->service_pattern);
|
||||
myfree(req->parsed_text);
|
||||
}
|
||||
myfree((char *) edit_reqs);
|
||||
}
|
||||
|
@ -129,59 +129,6 @@ void set_parameters(char **name_val_array)
|
||||
}
|
||||
}
|
||||
|
||||
/* print_line - show line possibly folded, and with normalized whitespace */
|
||||
|
||||
static void print_line(VSTREAM *fp, int mode, const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
static VSTRING *buf = 0;
|
||||
char *start;
|
||||
char *next;
|
||||
int line_len = 0;
|
||||
int word_len;
|
||||
|
||||
/*
|
||||
* One-off initialization.
|
||||
*/
|
||||
if (buf == 0)
|
||||
buf = vstring_alloc(100);
|
||||
|
||||
/*
|
||||
* Format the text.
|
||||
*/
|
||||
va_start(ap, fmt);
|
||||
vstring_vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/*
|
||||
* Normalize the whitespace. We don't use the line_wrap() routine because
|
||||
* 1) that function does not normalize whitespace between words and 2) we
|
||||
* want to normalize whitespace even when not wrapping lines.
|
||||
*
|
||||
* XXX Some parameters preserve whitespace: for example, smtpd_banner and
|
||||
* smtpd_reject_footer. If we have to preserve whitespace between words,
|
||||
* then perhaps readlline() can be changed to canonicalize whitespace
|
||||
* that follows a newline.
|
||||
*/
|
||||
for (start = STR(buf); *(start += strspn(start, SEPARATORS)) != 0; start = next) {
|
||||
word_len = strcspn(start, SEPARATORS);
|
||||
if (*(next = start + word_len) != 0)
|
||||
*next++ = 0;
|
||||
if (word_len > 0 && line_len > 0) {
|
||||
if ((mode & FOLD_LINE) == 0 || line_len + word_len < LINE_LIMIT) {
|
||||
vstream_fputs(" ", fp);
|
||||
line_len += 1;
|
||||
} else {
|
||||
vstream_fputs("\n" INDENT_TEXT, fp);
|
||||
line_len = INDENT_LEN;
|
||||
}
|
||||
}
|
||||
vstream_fputs(start, fp);
|
||||
line_len += word_len;
|
||||
}
|
||||
vstream_fputs("\n", fp);
|
||||
}
|
||||
|
||||
/* print_parameter - show specific parameter */
|
||||
|
||||
static void print_parameter(VSTREAM *fp, int mode, const char *name,
|
||||
@ -202,7 +149,7 @@ static void print_parameter(VSTREAM *fp, int mode, const char *name,
|
||||
if ((mode & SHOW_EVAL) != 0 && PC_RAW_PARAMETER(node) == 0)
|
||||
value = expand_parameter_value((VSTRING *) 0, mode, value,
|
||||
(PC_MASTER_ENT *) 0);
|
||||
if (mode & SHOW_NAME) {
|
||||
if ((mode & HIDE_NAME) == 0) {
|
||||
print_line(fp, mode, "%s = %s\n", name, value);
|
||||
} else {
|
||||
print_line(fp, mode, "%s\n", value);
|
||||
|
@ -11,19 +11,76 @@
|
||||
/* void read_master(fail_on_open)
|
||||
/* int fail_on_open;
|
||||
/*
|
||||
/* void show_master(fp, mode, filters)
|
||||
/* void show_master_entries(fp, mode, service_filters)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* char **filters;
|
||||
/* char **service_filters;
|
||||
/*
|
||||
/* void show_master_fields(fp, mode, n_filters, field_filters)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* int n_filters;
|
||||
/* char **field_filters;
|
||||
/*
|
||||
/* void edit_master_field(masterp, field, new_value)
|
||||
/* PC_MASTER_ENT *masterp;
|
||||
/* int field;
|
||||
/* const char *new_value;
|
||||
/*
|
||||
/* void show_master_params(fp, mode, argc, **param_filters)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* int argc;
|
||||
/* char **param_filters;
|
||||
/*
|
||||
/* void edit_master_param(masterp, mode, param_name, param_value)
|
||||
/* PC_MASTER_ENT *masterp;
|
||||
/* int mode;
|
||||
/* const char *param_name;
|
||||
/* const char *param_value;
|
||||
/* AUXILIARY FUNCTIONS
|
||||
/* const char *parse_master_entry(masterp, buf)
|
||||
/* PC_MASTER_ENT *masterp;
|
||||
/* const char *buf;
|
||||
/*
|
||||
/* void print_master_entry(fp, mode, masterp)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* PC_MASTER_ENT *masterp;
|
||||
/*
|
||||
/* void free_master_entry(masterp)
|
||||
/* PC_MASTER_ENT *masterp;
|
||||
/* DESCRIPTION
|
||||
/* read_master() reads entries from master.cf into memory.
|
||||
/*
|
||||
/* show_master() writes the entries in the master.cf file
|
||||
/* show_master_entries() writes the entries in the master.cf
|
||||
/* file to the specified stream.
|
||||
/*
|
||||
/* show_master_fields() writes name/type/field=value records to
|
||||
/* the specified stream.
|
||||
/*
|
||||
/* edit_master_field() updates the value of a single-column
|
||||
/* or multi-column attribute.
|
||||
/*
|
||||
/* show_master_params() writes name/type/parameter=value records
|
||||
/* to the specified stream.
|
||||
/*
|
||||
/* edit_master_param() updates, removes or adds the named
|
||||
/* parameter in a master.cf entry (the remove request ignores
|
||||
/* the parameter value).
|
||||
/*
|
||||
/* daemon_options_expecting_value[] is an array of master.cf
|
||||
/* daemon command-line options that expect an option value.
|
||||
/*
|
||||
/* parse_master_entry() parses a (perhaps multi-line) string
|
||||
/* that contains a complete master.cf entry, and normalizes
|
||||
/* daemon command-line options to simplify further handling.
|
||||
/*
|
||||
/* print_master_entry() prints a parsed master.cf entry.
|
||||
/*
|
||||
/* free_master_entry() returns storage to the heap that was
|
||||
/* allocated by parse_master_entry().
|
||||
/*
|
||||
/* Arguments
|
||||
/* .IP fail_on_open
|
||||
/* Specify FAIL_ON_OPEN if open failure is a fatal error,
|
||||
@ -31,12 +88,37 @@
|
||||
/* .IP fp
|
||||
/* Output stream.
|
||||
/* .IP mode
|
||||
/* If the FOLD_LINE flag is set, show_master() wraps long
|
||||
/* output lines.
|
||||
/* .IP filters
|
||||
/* A list of zero or more expressions in master_service(3)
|
||||
/* format. If no list is specified, show_master() outputs
|
||||
/* Bit-wise OR of flags. Flags other than the following are ignored.
|
||||
/* .RS
|
||||
/* .IP FOLD_LINE
|
||||
/* Wrap long output lines.
|
||||
/* .IP SHOW_EVAL
|
||||
/* Expand $name in parameter values.
|
||||
/* .IP EDIT_EXCL
|
||||
/* Request that edit_master_param() removes the parameter.
|
||||
/* .RE
|
||||
/* .IP n_filters
|
||||
/* The number of command-line filters.
|
||||
/* .IP field_filters
|
||||
/* A list of zero or more service field patterns (name/type/field).
|
||||
/* The output is formatted as "name/type/field = value". If
|
||||
/* no filters are specified, show_master_fields() outputs the
|
||||
/* fields of all master.cf entries in the specified order.
|
||||
/* .IP param_filters
|
||||
/* A list of zero or more service parameter patterns
|
||||
/* (name/type/parameter). The output is formatted as
|
||||
/* "name/type/parameter = value". If no filters are specified,
|
||||
/* show_master_params() outputs the parameters of all master.cf
|
||||
/* entries in sorted order.
|
||||
/* .IP service_filters
|
||||
/* A list of zero or more service patterns (name or name/type).
|
||||
/* If no filters are specified, show_master_entries() outputs
|
||||
/* all master.cf entries in the specified order.
|
||||
/* .IP field
|
||||
/* Index into parsed master.cf entry.
|
||||
/* .IP new_value
|
||||
/* Replacement value for the specified field. It is split
|
||||
/* in whitespace in case of a multi-field attribute.
|
||||
/* DIAGNOSTICS
|
||||
/* Problems are reported to the standard error stream.
|
||||
/* LICENSE
|
||||
@ -54,6 +136,8 @@
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
@ -64,11 +148,15 @@
|
||||
#include <vstream.h>
|
||||
#include <readlline.h>
|
||||
#include <stringops.h>
|
||||
#include <split_at.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <mail_params.h>
|
||||
#include <match_service.h>
|
||||
|
||||
/* Master library. */
|
||||
|
||||
#include <master_proto.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
@ -76,6 +164,30 @@
|
||||
|
||||
const char daemon_options_expecting_value[] = "o";
|
||||
|
||||
/*
|
||||
* Data structure to capture a command-line service field filter.
|
||||
*/
|
||||
typedef struct {
|
||||
int match_count; /* hit count */
|
||||
const char *raw_text; /* full pattern text */
|
||||
ARGV *service_pattern; /* parsed service name, type, ... */
|
||||
int field_pattern; /* parsed field pattern */
|
||||
const char *param_pattern; /* parameter pattern */
|
||||
} PC_MASTER_FIELD_REQ;
|
||||
|
||||
/*
|
||||
* Valid inputs.
|
||||
*/
|
||||
static const char *valid_master_types[] = {
|
||||
MASTER_XPORT_NAME_UNIX,
|
||||
MASTER_XPORT_NAME_FIFO,
|
||||
MASTER_XPORT_NAME_INET,
|
||||
MASTER_XPORT_NAME_PASS,
|
||||
0,
|
||||
};
|
||||
|
||||
static const char valid_bool_types[] = "yn-";
|
||||
|
||||
#define STR(x) vstring_str(x)
|
||||
|
||||
/* normalize_options - bring options into canonical form */
|
||||
@ -97,7 +209,7 @@ static void normalize_options(ARGV *argv)
|
||||
for (cp = arg + 1; *cp; cp++) {
|
||||
if (strchr(daemon_options_expecting_value, *cp) != 0
|
||||
&& cp > arg + 1) {
|
||||
/* Split "-stuffo" into "-stuff" and "-o". */
|
||||
/* Split "-stuffozz" into "-stuff" and "-ozz". */
|
||||
junk = concatenate("-", cp, (char *) 0);
|
||||
argv_insert_one(argv, field + 1, junk);
|
||||
myfree(junk);
|
||||
@ -120,9 +232,80 @@ static void normalize_options(ARGV *argv)
|
||||
}
|
||||
}
|
||||
|
||||
/* parse_master_line - parse one master line */
|
||||
/* fix_fatal - fix multiline text before release */
|
||||
|
||||
static const char *parse_master_line(PC_MASTER_ENT *masterp, const char *buf)
|
||||
static NORETURN PRINTFLIKE(1, 2) fix_fatal(const char *fmt,...)
|
||||
{
|
||||
VSTRING *buf = vstring_alloc(100);
|
||||
va_list ap;
|
||||
|
||||
/*
|
||||
* Replace newline with whitespace.
|
||||
*/
|
||||
va_start(ap, fmt);
|
||||
vstring_vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
translit(STR(buf), "\n", " ");
|
||||
msg_fatal("%s", STR(buf));
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* check_master_entry - sanity check master.cf entry */
|
||||
|
||||
static void check_master_entry(ARGV *argv, const char *raw_text)
|
||||
{
|
||||
const char **cpp;
|
||||
char *cp;
|
||||
int len;
|
||||
int field;
|
||||
|
||||
cp = argv->argv[PC_MASTER_FIELD_TYPE];
|
||||
for (cpp = valid_master_types; /* see below */ ; cpp++) {
|
||||
if (*cpp == 0)
|
||||
fix_fatal("invalid " PC_MASTER_NAME_TYPE " field \"%s\" in \"%s\"",
|
||||
cp, raw_text);
|
||||
if (strcmp(*cpp, cp) == 0)
|
||||
break;
|
||||
}
|
||||
|
||||
for (field = PC_MASTER_FIELD_PRIVATE; field <= PC_MASTER_FIELD_CHROOT; field++) {
|
||||
cp = argv->argv[field];
|
||||
if (cp[1] != 0 || strchr(valid_bool_types, *cp) == 0)
|
||||
fix_fatal("invalid %s field \%s\" in \"%s\"",
|
||||
str_field_pattern(field), cp, raw_text);
|
||||
}
|
||||
|
||||
cp = argv->argv[PC_MASTER_FIELD_WAKEUP];
|
||||
len = strlen(cp);
|
||||
if (len > 0 && cp[len - 1] == '?')
|
||||
len--;
|
||||
if (!(cp[0] == '-' && len == 1) && strspn(cp, "0123456789") != len)
|
||||
fix_fatal("invalid " PC_MASTER_NAME_WAKEUP " field \%s\" in \"%s\"",
|
||||
cp, raw_text);
|
||||
|
||||
cp = argv->argv[PC_MASTER_FIELD_MAXPROC];
|
||||
if (strcmp("-", cp) != 0 && cp[strspn(cp, "0123456789")] != 0)
|
||||
fix_fatal("invalid " PC_MASTER_NAME_MAXPROC " field \%s\" in \"%s\"",
|
||||
cp, raw_text);
|
||||
}
|
||||
|
||||
/* free_master_entry - destroy parsed entry */
|
||||
|
||||
void free_master_entry(PC_MASTER_ENT *masterp)
|
||||
{
|
||||
/* XX Fixme: allocation/deallocation asymmetry. */
|
||||
myfree(masterp->name_space);
|
||||
argv_free(masterp->argv);
|
||||
if (masterp->valid_names)
|
||||
htable_free(masterp->valid_names, myfree);
|
||||
if (masterp->all_params)
|
||||
dict_free(masterp->all_params);
|
||||
myfree((char *) masterp);
|
||||
}
|
||||
|
||||
/* parse_master_entry - parse one master line */
|
||||
|
||||
const char *parse_master_entry(PC_MASTER_ENT *masterp, const char *buf)
|
||||
{
|
||||
ARGV *argv;
|
||||
|
||||
@ -134,17 +317,18 @@ static const char *parse_master_line(PC_MASTER_ENT *masterp, const char *buf)
|
||||
* The postconf command needs to show default fields as "-", and needs to
|
||||
* know about all service names so that it can generate service-dependent
|
||||
* parameter names (transport-dependent etc.).
|
||||
*
|
||||
* XXX Do per-field sanity checks.
|
||||
*/
|
||||
#define MASTER_BLANKS " \t\r\n" /* XXX */
|
||||
|
||||
argv = argv_split(buf, MASTER_BLANKS);
|
||||
argv = argv_split(buf, PC_MASTER_BLANKS);
|
||||
if (argv->argc < PC_MASTER_MIN_FIELDS) {
|
||||
argv_free(argv); /* Coverity 201311 */
|
||||
return ("bad field count");
|
||||
}
|
||||
check_master_entry(argv, buf);
|
||||
normalize_options(argv);
|
||||
masterp->name_space =
|
||||
concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0);
|
||||
concatenate(argv->argv[0], PC_NAMESP_SEP_STR, argv->argv[1], (char *) 0);
|
||||
masterp->argv = argv;
|
||||
masterp->valid_names = 0;
|
||||
masterp->all_params = 0;
|
||||
@ -194,8 +378,8 @@ void read_master(int fail_on_open_error)
|
||||
while (readlline(buf, fp, &line_count) != 0) {
|
||||
master_table = (PC_MASTER_ENT *) myrealloc((char *) master_table,
|
||||
(entry_count + 2) * sizeof(*master_table));
|
||||
if ((err = parse_master_line(master_table + entry_count,
|
||||
STR(buf))) != 0)
|
||||
if ((err = parse_master_entry(master_table + entry_count,
|
||||
STR(buf))) != 0)
|
||||
msg_fatal("file %s: line %d: %s", path, line_count, err);
|
||||
entry_count += 1;
|
||||
}
|
||||
@ -210,9 +394,9 @@ void read_master(int fail_on_open_error)
|
||||
myfree(path);
|
||||
}
|
||||
|
||||
/* print_master_line - print one master line */
|
||||
/* print_master_entry - print one master line */
|
||||
|
||||
static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
void print_master_entry(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
{
|
||||
char **argv = masterp->argv->argv;
|
||||
const char *arg;
|
||||
@ -268,11 +452,11 @@ static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
*/
|
||||
if (arg[0] != '-' || strcmp(arg, "--") == 0) {
|
||||
in_daemon_options = 0;
|
||||
if ((mode & FOLD_LINE)
|
||||
&& line_len > column_goal[PC_MASTER_MIN_FIELDS - 1]) {
|
||||
#if 0
|
||||
if (mode & FOLD_LINE)
|
||||
/* Force line wrap. */
|
||||
line_len = LINE_LIMIT;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -281,6 +465,9 @@ static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
else if (strchr(daemon_options_expecting_value, arg[1]) != 0
|
||||
&& (aval = argv[field + 1]) != 0) {
|
||||
|
||||
/* Force line wrap before option with value. */
|
||||
line_len = LINE_LIMIT;
|
||||
|
||||
/*
|
||||
* Optionally, expand $name in parameter value.
|
||||
*/
|
||||
@ -313,36 +500,497 @@ static void print_master_line(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
ADD_SPACE;
|
||||
ADD_TEXT(aval, strlen(aval));
|
||||
field += 1;
|
||||
|
||||
/* Force line wrap after option with value. */
|
||||
line_len = LINE_LIMIT;
|
||||
|
||||
}
|
||||
}
|
||||
vstream_fputs("\n", fp);
|
||||
|
||||
if (msg_verbose)
|
||||
vstream_fflush(fp);
|
||||
}
|
||||
|
||||
/* show_master - show master.cf entries */
|
||||
/* show_master_entries - show master.cf entries */
|
||||
|
||||
void show_master(VSTREAM *fp, int mode, char **filters)
|
||||
void show_master_entries(VSTREAM *fp, int mode, int argc, char **argv)
|
||||
{
|
||||
PC_MASTER_ENT *masterp;
|
||||
ARGV *service_filter = 0;
|
||||
PC_MASTER_FIELD_REQ *field_reqs;
|
||||
PC_MASTER_FIELD_REQ *req;
|
||||
|
||||
/*
|
||||
* Initialize the service filter.
|
||||
* Parse the filter expressions.
|
||||
*/
|
||||
if (filters[0])
|
||||
service_filter = match_service_init_argv(filters);
|
||||
if (argc > 0) {
|
||||
field_reqs = (PC_MASTER_FIELD_REQ *)
|
||||
mymalloc(sizeof(*field_reqs) * argc);
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
req->match_count = 0;
|
||||
req->raw_text = *argv++;
|
||||
req->service_pattern =
|
||||
parse_service_pattern(req->raw_text, 1, 2);
|
||||
if (req->service_pattern == 0)
|
||||
msg_fatal("-M option requires service_name[/type]");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the master table.
|
||||
*/
|
||||
for (masterp = master_table; masterp->argv != 0; masterp++)
|
||||
if ((service_filter == 0
|
||||
|| match_service_match(service_filter, masterp->name_space))
|
||||
&& ((mode & SHOW_NONDEF) == 0 || masterp->all_params != 0))
|
||||
print_master_line(fp, mode, masterp);
|
||||
for (masterp = master_table; masterp->argv != 0; masterp++) {
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (MATCH_SERVICE_PATTERN(req->service_pattern,
|
||||
masterp->argv->argv[0],
|
||||
masterp->argv->argv[1])) {
|
||||
req->match_count++;
|
||||
print_master_entry(fp, mode, masterp);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
print_master_entry(fp, mode, masterp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup.
|
||||
*/
|
||||
if (service_filter != 0)
|
||||
argv_free(service_filter);
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (req->match_count == 0)
|
||||
msg_warn("unmatched request: \"%s\"", req->raw_text);
|
||||
argv_free(req->service_pattern);
|
||||
}
|
||||
myfree((char *) field_reqs);
|
||||
}
|
||||
}
|
||||
|
||||
/* print_master_field - scaffolding */
|
||||
|
||||
static void print_master_field(VSTREAM *fp, int mode,
|
||||
PC_MASTER_ENT *masterp,
|
||||
int field)
|
||||
{
|
||||
char **argv = masterp->argv->argv;
|
||||
const char *arg;
|
||||
const char *aval;
|
||||
int arg_len;
|
||||
int line_len;
|
||||
int in_daemon_options;
|
||||
|
||||
/*
|
||||
* Show the field value, or the first value in the case of a multi-column
|
||||
* field.
|
||||
*/
|
||||
#define ADD_CHAR(ch) ADD_TEXT((ch), 1)
|
||||
|
||||
line_len = 0;
|
||||
if ((mode & HIDE_NAME) == 0) {
|
||||
ADD_TEXT(argv[0], strlen(argv[0]));
|
||||
ADD_CHAR(PC_NAMESP_SEP_STR);
|
||||
ADD_TEXT(argv[1], strlen(argv[1]));
|
||||
ADD_CHAR(PC_NAMESP_SEP_STR);
|
||||
ADD_TEXT(str_field_pattern(field), strlen(str_field_pattern(field)));
|
||||
ADD_TEXT(" = ", 3);
|
||||
if (line_len + strlen(argv[field]) > LINE_LIMIT) {
|
||||
vstream_fputs("\n" INDENT_TEXT, fp);
|
||||
line_len = INDENT_LEN;
|
||||
}
|
||||
}
|
||||
ADD_TEXT(argv[field], strlen(argv[field]));
|
||||
|
||||
/*
|
||||
* Format the daemon command-line options and non-option arguments. Here,
|
||||
* we have no data-dependent preference for column positions, but we do
|
||||
* have argument grouping preferences.
|
||||
*/
|
||||
if (field == PC_MASTER_FIELD_CMD) {
|
||||
in_daemon_options = 1;
|
||||
for (field += 1; (arg = argv[field]) != 0; field++) {
|
||||
arg_len = strlen(arg);
|
||||
aval = 0;
|
||||
if (in_daemon_options) {
|
||||
|
||||
/*
|
||||
* We make no special case for generic options (-v -D)
|
||||
* options.
|
||||
*/
|
||||
if (arg[0] != '-' || strcmp(arg, "--") == 0) {
|
||||
in_daemon_options = 0;
|
||||
} else if (strchr(daemon_options_expecting_value, arg[1]) != 0
|
||||
&& (aval = argv[field + 1]) != 0) {
|
||||
|
||||
/* Force line break before option with value. */
|
||||
line_len = LINE_LIMIT;
|
||||
|
||||
/*
|
||||
* Optionally, expand $name in parameter value.
|
||||
*/
|
||||
if (strcmp(arg, "-o") == 0
|
||||
&& (mode & SHOW_EVAL) != 0)
|
||||
aval = expand_parameter_value((VSTRING *) 0, mode,
|
||||
aval, masterp);
|
||||
|
||||
/*
|
||||
* Keep option and value on the same line.
|
||||
*/
|
||||
arg_len += strlen(aval) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert a line break when the next item won't fit.
|
||||
*/
|
||||
if (line_len > INDENT_LEN) {
|
||||
if ((mode & FOLD_LINE) == 0
|
||||
|| line_len + 1 + arg_len < LINE_LIMIT) {
|
||||
ADD_SPACE;
|
||||
} else {
|
||||
vstream_fputs("\n" INDENT_TEXT, fp);
|
||||
line_len = INDENT_LEN;
|
||||
}
|
||||
}
|
||||
ADD_TEXT(arg, strlen(arg));
|
||||
if (aval) {
|
||||
ADD_SPACE;
|
||||
ADD_TEXT(aval, strlen(aval));
|
||||
field += 1;
|
||||
|
||||
/* Force line break after option with value. */
|
||||
line_len = LINE_LIMIT;
|
||||
}
|
||||
}
|
||||
}
|
||||
vstream_fputs("\n", fp);
|
||||
|
||||
if (msg_verbose)
|
||||
vstream_fflush(fp);
|
||||
}
|
||||
|
||||
/* show_master_fields - show master.cf fields */
|
||||
|
||||
void show_master_fields(VSTREAM *fp, int mode, int argc, char **argv)
|
||||
{
|
||||
const char *myname = "show_master_fields";
|
||||
PC_MASTER_ENT *masterp;
|
||||
PC_MASTER_FIELD_REQ *field_reqs;
|
||||
PC_MASTER_FIELD_REQ *req;
|
||||
int field;
|
||||
|
||||
/*
|
||||
* Parse the filter expressions.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
field_reqs = (PC_MASTER_FIELD_REQ *)
|
||||
mymalloc(sizeof(*field_reqs) * argc);
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
req->match_count = 0;
|
||||
req->raw_text = *argv++;
|
||||
req->service_pattern =
|
||||
parse_service_pattern(req->raw_text, 1, 3);
|
||||
if (req->service_pattern == 0)
|
||||
msg_fatal("-F option requires service_name[/type[/field]]");
|
||||
field = req->field_pattern =
|
||||
parse_field_pattern(req->service_pattern->argv[2]);
|
||||
if (is_magic_field_pattern(field) == 0
|
||||
&& (field < 0 || field > PC_MASTER_FIELD_CMD))
|
||||
msg_panic("%s: bad attribute field index: %d",
|
||||
myname, field);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the master table.
|
||||
*/
|
||||
for (masterp = master_table; masterp->argv != 0; masterp++) {
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (MATCH_SERVICE_PATTERN(req->service_pattern,
|
||||
masterp->argv->argv[0],
|
||||
masterp->argv->argv[1])) {
|
||||
req->match_count++;
|
||||
field = req->field_pattern;
|
||||
if (is_magic_field_pattern(field)) {
|
||||
for (field = 0; field <= PC_MASTER_FIELD_CMD; field++)
|
||||
print_master_field(fp, mode, masterp, field);
|
||||
} else {
|
||||
print_master_field(fp, mode, masterp, field);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (field = 0; field <= PC_MASTER_FIELD_CMD; field++)
|
||||
print_master_field(fp, mode, masterp, field);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (req->match_count == 0)
|
||||
msg_warn("unmatched request: \"%s\"", req->raw_text);
|
||||
argv_free(req->service_pattern);
|
||||
}
|
||||
myfree((char *) field_reqs);
|
||||
}
|
||||
}
|
||||
|
||||
/* edit_master_field - replace master.cf field value. */
|
||||
|
||||
void edit_master_field(PC_MASTER_ENT *masterp, int field,
|
||||
const char *new_value)
|
||||
{
|
||||
|
||||
/*
|
||||
* Replace multi-column attribute.
|
||||
*/
|
||||
if (field == PC_MASTER_FIELD_CMD) {
|
||||
argv_truncate(masterp->argv, PC_MASTER_FIELD_CMD);
|
||||
argv_split_append(masterp->argv, new_value, PC_MASTER_BLANKS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Replace single-column attribute.
|
||||
*/
|
||||
else {
|
||||
argv_replace_one(masterp->argv, field, new_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do per-field sanity checks.
|
||||
*/
|
||||
check_master_entry(masterp->argv, new_value);
|
||||
}
|
||||
|
||||
/* print_master_param - scaffolding */
|
||||
|
||||
static void print_master_param(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp,
|
||||
const char *param_name, const char *param_value)
|
||||
{
|
||||
if ((mode & SHOW_EVAL) != 0)
|
||||
param_value = expand_parameter_value((VSTRING *) 0, mode,
|
||||
param_value, masterp);
|
||||
if ((mode & HIDE_NAME) == 0) {
|
||||
print_line(fp, mode, "%s%c%s = %s\n",
|
||||
masterp->name_space, PC_NAMESP_SEP_CH,
|
||||
param_name, param_value);
|
||||
} else {
|
||||
print_line(fp, mode, "%s\n", param_value);
|
||||
}
|
||||
if (msg_verbose)
|
||||
vstream_fflush(fp);
|
||||
}
|
||||
|
||||
/* sort_argv_cb - sort argv call-back */
|
||||
|
||||
static int sort_argv_cb(const void *a, const void *b)
|
||||
{
|
||||
return (strcmp(*(char **) a, *(char **) b));
|
||||
}
|
||||
|
||||
/* show_master_any_param - show any parameter in master.cf service entry */
|
||||
|
||||
static void show_master_any_param(VSTREAM *fp, int mode, PC_MASTER_ENT *masterp)
|
||||
{
|
||||
const char *myname = "show_master_any_param";
|
||||
ARGV *argv = argv_alloc(10);
|
||||
DICT *dict = masterp->all_params;
|
||||
const char *param_name;
|
||||
const char *param_value;
|
||||
int param_count = 0;
|
||||
int how;
|
||||
char **cpp;
|
||||
|
||||
/*
|
||||
* Print parameters in sorted order. The number of parameters per
|
||||
* master.cf entry is small, so we optmiize for code simplicity and don't
|
||||
* worry about the cost of double lookup.
|
||||
*/
|
||||
|
||||
/* Look up the parameter names and ignore the values. */
|
||||
|
||||
for (how = DICT_SEQ_FUN_FIRST;
|
||||
dict->sequence(dict, how, ¶m_name, ¶m_value) == 0;
|
||||
how = DICT_SEQ_FUN_NEXT) {
|
||||
argv_add(argv, param_name, ARGV_END);
|
||||
param_count++;
|
||||
}
|
||||
|
||||
/* Print the parameters in sorted order. */
|
||||
|
||||
qsort(argv->argv, param_count, sizeof(argv->argv[0]), sort_argv_cb);
|
||||
for (cpp = argv->argv; (param_name = *cpp) != 0; cpp++) {
|
||||
if ((param_value = dict_get(dict, param_name)) == 0)
|
||||
msg_panic("%s: parameter name not found: %s", myname, param_name);
|
||||
print_master_param(fp, mode, masterp, param_name, param_value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean up.
|
||||
*/
|
||||
argv_free(argv);
|
||||
}
|
||||
|
||||
/* show_master_params - show master.cf params */
|
||||
|
||||
void show_master_params(VSTREAM *fp, int mode, int argc, char **argv)
|
||||
{
|
||||
PC_MASTER_ENT *masterp;
|
||||
PC_MASTER_FIELD_REQ *field_reqs;
|
||||
PC_MASTER_FIELD_REQ *req;
|
||||
DICT *dict;
|
||||
const char *param_value;
|
||||
|
||||
/*
|
||||
* Parse the filter expressions.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
field_reqs = (PC_MASTER_FIELD_REQ *)
|
||||
mymalloc(sizeof(*field_reqs) * argc);
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
req->match_count = 0;
|
||||
req->raw_text = *argv++;
|
||||
req->service_pattern =
|
||||
parse_service_pattern(req->raw_text, 1, 3);
|
||||
if (req->service_pattern == 0)
|
||||
msg_fatal("-P option requires service_name[/type[/parameter]]");
|
||||
req->param_pattern = req->service_pattern->argv[2];
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Iterate over the master table.
|
||||
*/
|
||||
for (masterp = master_table; masterp->argv != 0; masterp++) {
|
||||
if ((dict = masterp->all_params) != 0) {
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (MATCH_SERVICE_PATTERN(req->service_pattern,
|
||||
masterp->argv->argv[0],
|
||||
masterp->argv->argv[1])) {
|
||||
if (IS_MAGIC_PARAM_PATTERN(req->param_pattern)) {
|
||||
show_master_any_param(fp, mode, masterp);
|
||||
req->match_count += 1;
|
||||
} else if ((param_value = dict_get(dict,
|
||||
req->param_pattern)) != 0) {
|
||||
print_master_param(fp, mode, masterp,
|
||||
req->param_pattern,
|
||||
param_value);
|
||||
req->match_count += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
show_master_any_param(fp, mode, masterp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Cleanup.
|
||||
*/
|
||||
if (argc > 0) {
|
||||
for (req = field_reqs; req < field_reqs + argc; req++) {
|
||||
if (req->match_count == 0)
|
||||
msg_warn("unmatched request: \"%s\"", req->raw_text);
|
||||
argv_free(req->service_pattern);
|
||||
}
|
||||
myfree((char *) field_reqs);
|
||||
}
|
||||
}
|
||||
|
||||
/* edit_master_param - update, add or remove -o parameter=value */
|
||||
|
||||
void edit_master_param(PC_MASTER_ENT *masterp, int mode,
|
||||
const char *param_name,
|
||||
const char *param_value)
|
||||
{
|
||||
const char *myname = "edit_master_param";
|
||||
ARGV *argv = masterp->argv;
|
||||
const char *arg;
|
||||
const char *aval;
|
||||
int param_match = 0;
|
||||
int name_len = strlen(param_name);
|
||||
int field;
|
||||
|
||||
for (field = PC_MASTER_MIN_FIELDS; argv->argv[field] != 0; field++) {
|
||||
arg = argv->argv[field];
|
||||
|
||||
/*
|
||||
* Stop at the first non-option argument or end-of-list.
|
||||
*/
|
||||
if (arg[0] != '-' || strcmp(arg, "--") == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zoom in on command-line options with a value.
|
||||
*/
|
||||
else if (strchr(daemon_options_expecting_value, arg[1]) != 0
|
||||
&& (aval = argv->argv[field + 1]) != 0) {
|
||||
|
||||
/*
|
||||
* Zoom in on "-o parameter=value".
|
||||
*/
|
||||
if (strcmp(arg, "-o") == 0) {
|
||||
if (strncmp(aval, param_name, name_len) == 0
|
||||
&& aval[name_len] == '=') {
|
||||
param_match = 1;
|
||||
switch (mode & (EDIT_CONF | EDIT_EXCL)) {
|
||||
|
||||
/*
|
||||
* Update parameter=value.
|
||||
*/
|
||||
case EDIT_CONF:
|
||||
aval = concatenate(param_name, "=",
|
||||
param_value, (char *) 0);
|
||||
argv_replace_one(argv, field + 1, aval);
|
||||
myfree((char *) aval);
|
||||
if (masterp->all_params)
|
||||
dict_put(masterp->all_params, param_name, param_value);
|
||||
/* XXX Update parameter "used/defined" status. */
|
||||
break;
|
||||
|
||||
/*
|
||||
* Delete parameter=value.
|
||||
*/
|
||||
case EDIT_EXCL:
|
||||
argv_delete(argv, field, 2);
|
||||
if (masterp->all_params)
|
||||
dict_del(masterp->all_params, param_name);
|
||||
/* XXX Update parameter "used/defined" status. */
|
||||
field -= 2;
|
||||
break;
|
||||
default:
|
||||
msg_panic("%s: unexpected mode: %d", myname, mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over the command-line option value.
|
||||
*/
|
||||
field += 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add unmatched parameter.
|
||||
*/
|
||||
if ((mode & EDIT_CONF) && param_match == 0) {
|
||||
/* XXX Generalize: argv_insert(argv, where, list...) */
|
||||
argv_insert_one(argv, field, "-o");
|
||||
aval = concatenate(param_name, "=",
|
||||
param_value, (char *) 0);
|
||||
argv_insert_one(argv, field + 1, aval);
|
||||
if (masterp->all_params)
|
||||
dict_put(masterp->all_params, param_name, param_value);
|
||||
/* XXX May affect parameter "used/defined" status. */
|
||||
myfree((char *) aval);
|
||||
param_match = 1;
|
||||
}
|
||||
}
|
||||
|
188
postfix/src/postconf/postconf_match.c
Normal file
188
postfix/src/postconf/postconf_match.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* postconf_match 3
|
||||
/* SUMMARY
|
||||
/* pattern-matching support
|
||||
/* SYNOPSIS
|
||||
/* #include <postconf.h>
|
||||
/*
|
||||
/* int parse_field_pattern(field_expr)
|
||||
/* char *field_expr;
|
||||
/*
|
||||
/* const char *str_field_pattern(field_pattern)
|
||||
/* int field_pattern;
|
||||
/*
|
||||
/* int is_magic_field_pattern(field_pattern)
|
||||
/* int field_pattern;
|
||||
/*
|
||||
/* ARGV *parse_service_pattern(service_expr, min_expr, max_expr)
|
||||
/* const char *service_expr;
|
||||
/* int min_expr;
|
||||
/* int max_expr;
|
||||
/*
|
||||
/* int IS_MAGIC_SERVICE_PATTERN(service_pattern)
|
||||
/* const ARGV *service_pattern;
|
||||
/*
|
||||
/* int MATCH_SERVICE_PATTERN(service_pattern, service_name,
|
||||
/* service_type)
|
||||
/* const ARGV *service_pattern;
|
||||
/* const char *service_name;
|
||||
/* const char *service_type;
|
||||
/*
|
||||
/* const char *str_field_pattern(field_pattern)
|
||||
/* int field_pattern;
|
||||
/*
|
||||
/* int IS_MAGIC_PARAM_PATTERN(param_pattern)
|
||||
/* const char *param_pattern;
|
||||
/*
|
||||
/* int MATCH_PARAM_PATTERN(param_pattern, param_name)
|
||||
/* const char *param_pattern;
|
||||
/* const char *param_name;
|
||||
/* DESCRIPTION
|
||||
/* parse_service_pattern() takes an expression and splits it
|
||||
/* up on '/' into an array of sub-expressions, This function
|
||||
/* returns null if the input does fewer than "min" or more
|
||||
/* than "max" sub-expressions.
|
||||
/*
|
||||
/* IS_MAGIC_SERVICE_PATTERN() returns non-zero if any of the
|
||||
/* service name or service type sub-expressions contains a
|
||||
/* matching operator (as opposed to string literals that only
|
||||
/* match themselves). This is an unsafe macro that evaluates
|
||||
/* its arguments more than once.
|
||||
/*
|
||||
/* MATCH_SERVICE_PATTERN() matches a service name and type
|
||||
/* from master.cf against the parsed pattern. This is an unsafe
|
||||
/* macro that evaluates its arguments more than once.
|
||||
/*
|
||||
/* parse_field_pattern() converts a field sub-expression, and
|
||||
/* returns the conversion result.
|
||||
/*
|
||||
/* str_field_pattern() converts a result from parse_field_pattern()
|
||||
/* into string form.
|
||||
/*
|
||||
/* is_magic_field_pattern() returns non-zero if the field
|
||||
/* pattern sub-expression contained a matching operator (as
|
||||
/* opposed to a string literal that only matches itself).
|
||||
/*
|
||||
/* IS_MAGIC_PARAM_PATTERN() returns non-zero if the parameter
|
||||
/* sub-expression contains a matching operator (as opposed to
|
||||
/* a string literal that only matches itself). This is an
|
||||
/* unsafe macro that evaluates its arguments more than once.
|
||||
/*
|
||||
/* MATCH_PARAM_PATTERN() matches a parameter name from master.cf
|
||||
/* against the parsed pattern. This is an unsafe macro that
|
||||
/* evaluates its arguments more than once.
|
||||
/*
|
||||
/* Arguments
|
||||
/* .IP field_expr
|
||||
/* A field expression.
|
||||
/* .IP service_expr
|
||||
/* This argument is split on '/' into its constituent
|
||||
/* sub-expressions.
|
||||
/* .IP min_expr
|
||||
/* The minimum number of sub-expressions in service_expr.
|
||||
/* .IP max_expr
|
||||
/* The maximum number of sub-expressions in service_expr.
|
||||
/* .IP service_name
|
||||
/* Service name from master.cf.
|
||||
/* .IP service_type
|
||||
/* Service type from master.cf.
|
||||
/* .IP param_pattern
|
||||
/* A parameter name expression.
|
||||
/* DIAGNOSTICS
|
||||
/* Fatal errors: invalid syntax.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <mymalloc.h>
|
||||
#include <vstring.h>
|
||||
|
||||
/* Global library. */
|
||||
|
||||
#include <split_at.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
#include <postconf.h>
|
||||
|
||||
/*
|
||||
* Conversion table. Each PC_MASTER_NAME_XXX name entry must be stored at
|
||||
* table offset PC_MASTER_FIELD_XXX. So don't mess it up.
|
||||
*/
|
||||
NAME_CODE field_name_offset[] = {
|
||||
PC_MASTER_NAME_SERVICE, PC_MASTER_FIELD_SERVICE,
|
||||
PC_MASTER_NAME_TYPE, PC_MASTER_FIELD_TYPE,
|
||||
PC_MASTER_NAME_PRIVATE, PC_MASTER_FIELD_PRIVATE,
|
||||
PC_MASTER_NAME_UNPRIV, PC_MASTER_FIELD_UNPRIV,
|
||||
PC_MASTER_NAME_CHROOT, PC_MASTER_FIELD_CHROOT,
|
||||
PC_MASTER_NAME_WAKEUP, PC_MASTER_FIELD_WAKEUP,
|
||||
PC_MASTER_NAME_MAXPROC, PC_MASTER_FIELD_MAXPROC,
|
||||
PC_MASTER_NAME_CMD, PC_MASTER_FIELD_CMD,
|
||||
"*", PC_MASTER_FIELD_WILDC,
|
||||
0, PC_MASTER_FIELD_NONE,
|
||||
};
|
||||
|
||||
/* parse_field_pattern - parse service attribute pattern */
|
||||
|
||||
int parse_field_pattern(const char *field_name)
|
||||
{
|
||||
int field_pattern;
|
||||
|
||||
if ((field_pattern = name_code(field_name_offset,
|
||||
NAME_CODE_FLAG_STRICT_CASE,
|
||||
field_name)) == PC_MASTER_FIELD_NONE)
|
||||
msg_fatal("invalid service attribute name: \"%s\"", field_name);
|
||||
return (field_pattern);
|
||||
}
|
||||
|
||||
/* parse_service_pattern - parse service pattern */
|
||||
|
||||
ARGV *parse_service_pattern(const char *pattern, int min_expr, int max_expr)
|
||||
{
|
||||
ARGV *argv;
|
||||
char **cpp;
|
||||
|
||||
/*
|
||||
* Work around argv_split() lameness.
|
||||
*/
|
||||
if (*pattern == '/')
|
||||
return (0);
|
||||
argv = argv_split(pattern, PC_NAMESP_SEP_STR);
|
||||
if (argv->argc < min_expr || argv->argc > max_expr) {
|
||||
argv_free(argv);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allow '*' only all by itself.
|
||||
*/
|
||||
for (cpp = argv->argv; *cpp; cpp++) {
|
||||
if (!PC_MATCH_ANY(*cpp) && strchr(*cpp, PC_MATCH_WILDC_STR[0]) != 0) {
|
||||
argv_free(argv);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Provide defaults for missing fields.
|
||||
*/
|
||||
while (argv->argc < max_expr)
|
||||
argv_add(argv, PC_MATCH_WILDC_STR, ARGV_END);
|
||||
return (argv);
|
||||
}
|
@ -45,13 +45,13 @@
|
||||
|
||||
/* set_config_dir - forcibly override var_config_dir */
|
||||
|
||||
void set_config_dir(void)
|
||||
void set_config_dir(void)
|
||||
{
|
||||
char *config_dir;
|
||||
|
||||
if (var_config_dir)
|
||||
myfree(var_config_dir);
|
||||
myfree(var_config_dir);
|
||||
var_config_dir = mystrdup((config_dir = safe_getenv(CONF_ENV_PATH)) != 0 ?
|
||||
config_dir : DEF_CONFIG_DIR); /* XXX */
|
||||
config_dir : DEF_CONFIG_DIR); /* XXX */
|
||||
set_mail_conf_str(VAR_CONFIG_DIR, var_config_dir);
|
||||
}
|
||||
|
113
postfix/src/postconf/postconf_print.c
Normal file
113
postfix/src/postconf/postconf_print.c
Normal file
@ -0,0 +1,113 @@
|
||||
/*++
|
||||
/* NAME
|
||||
/* postconf_print 3
|
||||
/* SUMMARY
|
||||
/* basic line printing support
|
||||
/* SYNOPSIS
|
||||
/* #include <postconf.h>
|
||||
/*
|
||||
/* void print_line(fp, mode, const char *fmt, ...)
|
||||
/* VSTREAM *fp;
|
||||
/* int mode;
|
||||
/* const char *fmt;
|
||||
/* DESCRIPTION
|
||||
/* print_line() formats text, normalized whitespace, and
|
||||
/* optionally folds long lines.
|
||||
/*
|
||||
/* Arguments:
|
||||
/* .IP fp
|
||||
/* Output stream.
|
||||
/* .IP mode
|
||||
/* Bit-wise OR of zero or more of the following (other flags
|
||||
/* are ignored):
|
||||
/* .RS
|
||||
/* .IP FOLD_LINE
|
||||
/* Fold long lines.
|
||||
/* .RE
|
||||
/* .IP fmt
|
||||
/* Format string.
|
||||
/* DIAGNOSTICS
|
||||
/* Problems are reported to the standard error stream.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* The Secure Mailer license must be distributed with this software.
|
||||
/* AUTHOR(S)
|
||||
/* Wietse Venema
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
/* Utility library. */
|
||||
|
||||
#include <msg.h>
|
||||
#include <vstream.h>
|
||||
#include <vstring.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
#include <postconf.h>
|
||||
|
||||
/* SLMs. */
|
||||
|
||||
#define STR(x) vstring_str(x)
|
||||
|
||||
/* print_line - show line possibly folded, and with normalized whitespace */
|
||||
|
||||
void print_line(VSTREAM *fp, int mode, const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
static VSTRING *buf = 0;
|
||||
char *start;
|
||||
char *next;
|
||||
int line_len = 0;
|
||||
int word_len;
|
||||
|
||||
/*
|
||||
* One-off initialization.
|
||||
*/
|
||||
if (buf == 0)
|
||||
buf = vstring_alloc(100);
|
||||
|
||||
/*
|
||||
* Format the text.
|
||||
*/
|
||||
va_start(ap, fmt);
|
||||
vstring_vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
/*
|
||||
* Normalize the whitespace. We don't use the line_wrap() routine because
|
||||
* 1) that function does not normalize whitespace between words and 2) we
|
||||
* want to normalize whitespace even when not wrapping lines.
|
||||
*
|
||||
* XXX Some parameters preserve whitespace: for example, smtpd_banner and
|
||||
* smtpd_reject_footer. If we have to preserve whitespace between words,
|
||||
* then perhaps readlline() can be changed to canonicalize whitespace
|
||||
* that follows a newline.
|
||||
*/
|
||||
for (start = STR(buf); *(start += strspn(start, SEPARATORS)) != 0; start = next) {
|
||||
word_len = strcspn(start, SEPARATORS);
|
||||
if (*(next = start + word_len) != 0)
|
||||
*next++ = 0;
|
||||
if (word_len > 0 && line_len > 0) {
|
||||
if ((mode & FOLD_LINE) == 0 || line_len + word_len < LINE_LIMIT) {
|
||||
vstream_fputs(" ", fp);
|
||||
line_len += 1;
|
||||
} else {
|
||||
vstream_fputs("\n" INDENT_TEXT, fp);
|
||||
line_len = INDENT_LEN;
|
||||
}
|
||||
}
|
||||
vstream_fputs(start, fp);
|
||||
line_len += word_len;
|
||||
}
|
||||
vstream_fputs("\n", fp);
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
./postconf: warning: unmatched request: "bar/inet"
|
||||
./postconf: warning: unmatched request: "foo/unix"
|
@ -1,2 +1,4 @@
|
||||
whatever unix - n n - 0 other
|
||||
-o mydestination=yyy -o always_bcc=ccc -o aaa=ccc
|
||||
-o mydestination=yyy
|
||||
-o always_bcc=ccc
|
||||
-o aaa=ccc
|
||||
|
@ -1,2 +1,6 @@
|
||||
foo unix - n n - 0 other -v -o aaa=bbb -v
|
||||
-o ccc=bbb -v -o ddd=bbb
|
||||
foo unix - n n - 0 other -v
|
||||
-o aaa=bbb
|
||||
-v
|
||||
-o ccc=bbb
|
||||
-v
|
||||
-o ddd=bbb
|
||||
|
12
postfix/src/postconf/test41.ref
Normal file
12
postfix/src/postconf/test41.ref
Normal file
@ -0,0 +1,12 @@
|
||||
foo unix - n n - 0 other
|
||||
bar unix - n n - 0 other
|
||||
-o xxx=yyy
|
||||
-o aaa=bbb
|
||||
baz unix - n n - 0 other
|
||||
foo unix - n n - 0 other
|
||||
bar unix - n n - 0 other
|
||||
-o xxx=YYY
|
||||
-o aaa=BBB
|
||||
baz unix - n n - 0 other
|
||||
bar/unix/aaa = BBB
|
||||
bar/unix/xxx = YYY
|
10
postfix/src/postconf/test42.ref
Normal file
10
postfix/src/postconf/test42.ref
Normal file
@ -0,0 +1,10 @@
|
||||
foo unix - n n - 0 other
|
||||
bar unix - n n - 0 other
|
||||
-o xxx=yyy
|
||||
-o aaa=bbb
|
||||
baz unix - n n - 0 other
|
||||
bar/unix/aaa = bbb
|
||||
bar/unix/xxx = yyy
|
||||
foo unix - n n - 0 other
|
||||
bar unix - n n - 0 other
|
||||
baz unix - n n - 0 other
|
5
postfix/src/postconf/test43.ref
Normal file
5
postfix/src/postconf/test43.ref
Normal file
@ -0,0 +1,5 @@
|
||||
foo unix - n n - 0 other
|
||||
bar unix - n y - 0 aa -stuff
|
||||
-o bb=cc
|
||||
dd
|
||||
baz unix - n n - 0 other
|
5
postfix/src/postconf/test44.ref
Normal file
5
postfix/src/postconf/test44.ref
Normal file
@ -0,0 +1,5 @@
|
||||
foo unix - n n - 0 other
|
||||
xx inet - n n - 0 aa -stuff
|
||||
-o bb=cc
|
||||
dd
|
||||
baz unix - n n - 0 other
|
1
postfix/src/postconf/test45.ref
Normal file
1
postfix/src/postconf/test45.ref
Normal file
@ -0,0 +1 @@
|
||||
./postconf: fatal: invalid type field "xxxx" in "bar xxxx - n n - 0 other"
|
1
postfix/src/postconf/test46.ref
Normal file
1
postfix/src/postconf/test46.ref
Normal file
@ -0,0 +1 @@
|
||||
./postconf: fatal: invalid private field X" in "bar inet X n n - 0 other"
|
1
postfix/src/postconf/test47.ref
Normal file
1
postfix/src/postconf/test47.ref
Normal file
@ -0,0 +1 @@
|
||||
./postconf: fatal: invalid unprivileged field X" in "bar inet - X n - 0 other"
|
1
postfix/src/postconf/test48.ref
Normal file
1
postfix/src/postconf/test48.ref
Normal file
@ -0,0 +1 @@
|
||||
./postconf: fatal: invalid chroot field X" in "bar inet - n X - 0 other"
|
1
postfix/src/postconf/test49.ref
Normal file
1
postfix/src/postconf/test49.ref
Normal file
@ -0,0 +1 @@
|
||||
./postconf: fatal: invalid wakeup field X" in "bar inet - n n X 0 other"
|
1
postfix/src/postconf/test50.ref
Normal file
1
postfix/src/postconf/test50.ref
Normal file
@ -0,0 +1 @@
|
||||
./postconf: fatal: invalid process_limit field X" in "bar inet - n n - X other"
|
1
postfix/src/postconf/test51.ref
Normal file
1
postfix/src/postconf/test51.ref
Normal file
@ -0,0 +1 @@
|
||||
./postconf: fatal: invalid wakeup field X?" in "bar inet - n n X? 0 other"
|
1
postfix/src/postconf/test52.ref
Normal file
1
postfix/src/postconf/test52.ref
Normal file
@ -0,0 +1 @@
|
||||
baz unix - n n 0 0 other
|
3
postfix/src/postconf/test53.ref
Normal file
3
postfix/src/postconf/test53.ref
Normal file
@ -0,0 +1,3 @@
|
||||
foo unix - n n - 0 other
|
||||
#bar inet - n n 0 0 other
|
||||
baz unix - n n 0 0 other
|
3
postfix/src/postconf/test54.ref
Normal file
3
postfix/src/postconf/test54.ref
Normal file
@ -0,0 +1,3 @@
|
||||
#foo unix - n n - 0 other
|
||||
#bar inet - n n 0 0 other
|
||||
baz unix - n n 0 0 other
|
3
postfix/src/postconf/test55.ref
Normal file
3
postfix/src/postconf/test55.ref
Normal file
@ -0,0 +1,3 @@
|
||||
foo unix - n n - 0 other
|
||||
#bar inet - n n 0 0 other
|
||||
#baz unix - n n 0 0 other
|
5
postfix/src/postconf/test56.ref
Normal file
5
postfix/src/postconf/test56.ref
Normal file
@ -0,0 +1,5 @@
|
||||
foo unix - n n - 0 other
|
||||
#bar inet - n n 0 0 other
|
||||
# -o first
|
||||
# -o second
|
||||
baz unix - n n 0 0 other
|
@ -798,7 +798,7 @@ static int doproto(STATE *state)
|
||||
|
||||
/* connect_sock - connect a socket over some transport */
|
||||
|
||||
static VSTREAM *connect_sock(int sock, struct sockaddr * sa, int salen,
|
||||
static VSTREAM *connect_sock(int sock, struct sockaddr *sa, int salen,
|
||||
const char *name, const char *addr, STATE *state)
|
||||
{
|
||||
DSN_BUF *why = state->why;
|
||||
@ -895,7 +895,7 @@ static VSTREAM *connect_unix(STATE *state, const char *path)
|
||||
if (msg_verbose)
|
||||
msg_info("%s: trying: %s...", myname, path);
|
||||
|
||||
return (connect_sock(sock, (struct sockaddr *) & sock_un, sizeof(sock_un),
|
||||
return (connect_sock(sock, (struct sockaddr *) &sock_un, sizeof(sock_un),
|
||||
var_myhostname, path, state));
|
||||
}
|
||||
|
||||
@ -906,7 +906,7 @@ static VSTREAM *connect_addr(STATE *state, DNS_RR *addr)
|
||||
static const char *myname = "connect_addr";
|
||||
DSN_BUF *why = state->why;
|
||||
struct sockaddr_storage ss; /* remote */
|
||||
struct sockaddr *sa = (struct sockaddr *) & ss;
|
||||
struct sockaddr *sa = (struct sockaddr *) &ss;
|
||||
SOCKADDR_SIZE salen = sizeof(ss);
|
||||
MAI_HOSTADDR_STR hostaddr;
|
||||
int sock;
|
||||
@ -1392,7 +1392,7 @@ static int finger(STATE *state)
|
||||
state->why = dsb_create();
|
||||
|
||||
if (!(err = connect_dest(state))) {
|
||||
if (state->pass == 1)
|
||||
if (state->pass == 1 && !state->nochat)
|
||||
msg_info("Connected to %s", state->namaddrport);
|
||||
err = doproto(state);
|
||||
}
|
||||
@ -1430,7 +1430,11 @@ static int finger(STATE *state)
|
||||
|
||||
static void ssl_cleanup(void)
|
||||
{
|
||||
ERR_remove_state(0);
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
ERR_remove_thread_state(0); /* Thread-id is now a pointer */
|
||||
#else
|
||||
ERR_remove_state(0); /* Deprecated with OpenSSL 1.0.0 */
|
||||
#endif
|
||||
ENGINE_cleanup();
|
||||
CONF_modules_unload(1);
|
||||
ERR_free_strings();
|
||||
@ -1745,10 +1749,10 @@ static void parse_match(STATE *state, int argc, char *argv[])
|
||||
argv_add(state->match, "hostname", ARGV_END);
|
||||
break;
|
||||
case TLS_LEV_FPRINT:
|
||||
state->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
|
||||
state->dane = tls_dane_alloc();
|
||||
while (*argv)
|
||||
tls_dane_split((TLS_DANE *) state->dane, TLS_DANE_EE, TLS_DANE_PKEY,
|
||||
state->mdalg, *argv++, "");
|
||||
tls_dane_add_ee_digests((TLS_DANE *) state->dane,
|
||||
state->mdalg, *argv++, "");
|
||||
break;
|
||||
case TLS_LEV_DANE:
|
||||
state->match = argv_alloc(2);
|
||||
@ -1773,7 +1777,7 @@ static void parse_tas(STATE *state)
|
||||
return;
|
||||
case TLS_LEV_SECURE:
|
||||
case TLS_LEV_VERIFY:
|
||||
state->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
|
||||
state->dane = tls_dane_alloc();
|
||||
for (file = state->options.tas->argv; *file; ++file) {
|
||||
if (!tls_dane_load_trustfile((TLS_DANE *) state->dane, *file))
|
||||
break;
|
||||
|
@ -449,7 +449,7 @@
|
||||
/* .IP "\fBsmtp_tls_force_insecure_host_tlsa_lookup (no)\fR"
|
||||
/* Lookup the associated DANE TLSA RRset even when a hostname is
|
||||
/* not an alias and its address records lie in an unsigned zone.
|
||||
/* .IP "\fBtls_dane_trust_anchor_digest_enable (trust-anchor-assertion)\fR"
|
||||
/* .IP "\fBtls_dane_trust_anchor_digest_enable (yes)\fR"
|
||||
/* RFC 6698 trust-anchor digest support in the Postfix TLS library.
|
||||
/* .IP "\fBtlsmgr_service_name (tlsmgr)\fR"
|
||||
/* The name of the \fBtlsmgr\fR(8) service entry in master.cf.
|
||||
|
@ -308,9 +308,9 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
|
||||
break;
|
||||
case TLS_LEV_FPRINT:
|
||||
if (!tls->dane)
|
||||
tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
|
||||
tls_dane_split(tls->dane, TLS_DANE_EE, TLS_DANE_PKEY,
|
||||
var_smtp_tls_fpt_dgst, val, "|");
|
||||
tls->dane = tls_dane_alloc();
|
||||
tls_dane_add_ee_digests(tls->dane,
|
||||
var_smtp_tls_fpt_dgst, val, "|");
|
||||
break;
|
||||
case TLS_LEV_VERIFY:
|
||||
case TLS_LEV_SECURE:
|
||||
@ -345,7 +345,7 @@ static void tls_policy_lookup_one(SMTP_TLS_POLICY *tls, int *site_level,
|
||||
INVALID_RETURN(tls->why, site_level);
|
||||
}
|
||||
if (!tls->dane)
|
||||
tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
|
||||
tls->dane = tls_dane_alloc();
|
||||
if (!tls_dane_load_trustfile(tls->dane, val)) {
|
||||
INVALID_RETURN(tls->why, site_level);
|
||||
}
|
||||
@ -559,11 +559,10 @@ static void *policy_create(const char *unused_key, void *context)
|
||||
break;
|
||||
case TLS_LEV_FPRINT:
|
||||
if (tls->dane == 0)
|
||||
tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
|
||||
tls->dane = tls_dane_alloc();
|
||||
if (!TLS_DANE_HASEE(tls->dane)) {
|
||||
tls_dane_split(tls->dane, TLS_DANE_EE, TLS_DANE_PKEY,
|
||||
var_smtp_tls_fpt_dgst, var_smtp_tls_fpt_cmatch,
|
||||
"\t\n\r, ");
|
||||
tls_dane_add_ee_digests(tls->dane, var_smtp_tls_fpt_dgst,
|
||||
var_smtp_tls_fpt_cmatch, "\t\n\r, ");
|
||||
if (!TLS_DANE_HASEE(tls->dane)) {
|
||||
msg_warn("nexthop domain %s: configured at fingerprint "
|
||||
"security level, but with no fingerprints to match.",
|
||||
@ -582,7 +581,7 @@ static void *policy_create(const char *unused_key, void *context)
|
||||
"\t\n\r, :");
|
||||
if (*var_smtp_tls_tafile) {
|
||||
if (tls->dane == 0)
|
||||
tls->dane = tls_dane_alloc(TLS_DANE_FLAG_MIXED);
|
||||
tls->dane = tls_dane_alloc();
|
||||
if (!TLS_DANE_HASTA(tls->dane)
|
||||
&& !load_tas(tls->dane, var_smtp_tls_tafile)) {
|
||||
MARK_INVALID(tls->why, &tls->level);
|
||||
|
@ -953,7 +953,8 @@
|
||||
/* The location of the Postfix top-level queue directory.
|
||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||
/* The set of characters that can separate a user name from its
|
||||
/* address extension (user+foo).
|
||||
/* extension (example: user+foo), or a .forward file name from its
|
||||
/* extension (example: .forward+foo).
|
||||
/* .IP "\fBsmtpd_banner ($myhostname ESMTP $mail_name)\fR"
|
||||
/* The text that follows the 220 status code in the SMTP greeting
|
||||
/* banner.
|
||||
|
@ -17,7 +17,7 @@ DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
|
||||
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
|
||||
INCL =
|
||||
LIB = libtls.a
|
||||
TESTPROG= tls_dh tls_mgr
|
||||
TESTPROG= tls_dh tls_mgr tls_rsa
|
||||
|
||||
LIBS = ../../lib/libglobal.a ../../lib/libutil.a
|
||||
LIB_DIR = ../../lib
|
||||
@ -81,6 +81,11 @@ tls_mgr: $(LIB) $(LIBS)
|
||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
|
||||
mv junk $@.o
|
||||
|
||||
tls_rsa: $(LIB) $(LIBS)
|
||||
mv $@.o junk
|
||||
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
|
||||
mv junk $@.o
|
||||
|
||||
depend: $(MAKES)
|
||||
(sed '1,/^# do not edit/!d' Makefile.in; \
|
||||
set -e; for i in [a-z][a-z0-9]*.c; do \
|
||||
@ -151,7 +156,9 @@ tls_dane.o: ../../include/myaddrinfo.h
|
||||
tls_dane.o: ../../include/mymalloc.h
|
||||
tls_dane.o: ../../include/name_code.h
|
||||
tls_dane.o: ../../include/name_mask.h
|
||||
tls_dane.o: ../../include/safe_ultostr.h
|
||||
tls_dane.o: ../../include/sock_addr.h
|
||||
tls_dane.o: ../../include/split_at.h
|
||||
tls_dane.o: ../../include/stringops.h
|
||||
tls_dane.o: ../../include/sys_defs.h
|
||||
tls_dane.o: ../../include/timecmp.h
|
||||
@ -320,6 +327,7 @@ tls_proxy_scan.o: tls_proxy.h
|
||||
tls_proxy_scan.o: tls_proxy_scan.c
|
||||
tls_rsa.o: ../../include/argv.h
|
||||
tls_rsa.o: ../../include/dns.h
|
||||
tls_rsa.o: ../../include/msg.h
|
||||
tls_rsa.o: ../../include/myaddrinfo.h
|
||||
tls_rsa.o: ../../include/name_code.h
|
||||
tls_rsa.o: ../../include/name_mask.h
|
||||
|
@ -82,6 +82,20 @@ extern const NAME_CODE tls_level_table[];
|
||||
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x00090700f)
|
||||
#error "need OpenSSL version 0.9.7 or later"
|
||||
#endif
|
||||
|
||||
/* SSL_CIPHER_get_name() got constified in 0.9.7g */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090707fL /* constification */
|
||||
#define SSL_CIPHER_const const
|
||||
#else
|
||||
#define SSL_CIPHER_const
|
||||
#endif
|
||||
|
||||
/* d2i_X509() got constified in 0.9.8a */
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x0090801fL
|
||||
#define D2I_const const
|
||||
#else
|
||||
#define D2I_const
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -108,10 +122,9 @@ extern const NAME_CODE tls_level_table[];
|
||||
#define TLS_DANE_CERT 0 /* Match the certificate digest */
|
||||
#define TLS_DANE_PKEY 1 /* Match the public key digest */
|
||||
|
||||
#define TLS_DANE_FLAG_MIXED (1<<0) /* Combined pkeys and certs */
|
||||
#define TLS_DANE_FLAG_NORRS (1<<1) /* Nothing found in DNS */
|
||||
#define TLS_DANE_FLAG_EMPTY (1<<2) /* Nothing usable found in DNS */
|
||||
#define TLS_DANE_FLAG_ERROR (1<<3) /* TLSA record lookup error */
|
||||
#define TLS_DANE_FLAG_NORRS (1<<0) /* Nothing found in DNS */
|
||||
#define TLS_DANE_FLAG_EMPTY (1<<1) /* Nothing usable found in DNS */
|
||||
#define TLS_DANE_FLAG_ERROR (1<<2) /* TLSA record lookup error */
|
||||
|
||||
#define tls_dane_unusable(dane) ((dane)->flags & TLS_DANE_FLAG_EMPTY)
|
||||
#define tls_dane_notfound(dane) ((dane)->flags & TLS_DANE_FLAG_NORRS)
|
||||
@ -146,10 +159,6 @@ typedef struct TLS_PKEYS {
|
||||
struct TLS_PKEYS *next;
|
||||
} TLS_PKEYS;
|
||||
|
||||
/*
|
||||
* When TLS_DANE_FLAG_MIXED is set, the pkeys digest list is not allocated
|
||||
* separately, and aliases the certs digest list for each algorithm.
|
||||
*/
|
||||
typedef struct TLS_DANE {
|
||||
TLS_TLSA *ta; /* Trust-anchor cert/pubkey digests */
|
||||
TLS_TLSA *ee; /* End-entity cert/pubkey digests */
|
||||
@ -170,9 +179,9 @@ typedef struct TLS_DANE {
|
||||
extern int tls_dane_avail(void);
|
||||
extern void tls_dane_flush(void);
|
||||
extern void tls_dane_verbose(int);
|
||||
extern TLS_DANE *tls_dane_alloc(int);
|
||||
extern void tls_dane_split(TLS_DANE *, int, int, const char *, const char *,
|
||||
const char *);
|
||||
extern TLS_DANE *tls_dane_alloc(void);
|
||||
extern void tls_dane_add_ee_digests(TLS_DANE *, const char *, const char *,
|
||||
const char *);
|
||||
extern void tls_dane_free(TLS_DANE *);
|
||||
extern TLS_DANE *tls_dane_resolve(unsigned, const char *, DNS_RR *, int);
|
||||
extern int tls_dane_load_trustfile(TLS_DANE *, const char *);
|
||||
|
@ -756,7 +756,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
int protomask;
|
||||
const char *cipher_list;
|
||||
SSL_SESSION *session = 0;
|
||||
const SSL_CIPHER *cipher;
|
||||
SSL_CIPHER_const SSL_CIPHER *cipher;
|
||||
X509 *peercert;
|
||||
TLS_SESS_STATE *TLScontext;
|
||||
TLS_APPL_STATE *app_ctx = props->ctx;
|
||||
@ -788,9 +788,9 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
|
||||
props->namaddr, props->protocols);
|
||||
return (0);
|
||||
}
|
||||
/* The DANE level requires TLS 1.0 or later, not SSLv2 or SSLv3. */
|
||||
/* The DANE level requires SSLv3 or later, not SSLv2. */
|
||||
if (props->tls_level == TLS_LEV_DANE)
|
||||
protomask |= TLS_PROTOCOL_SSLv3 | TLS_PROTOCOL_SSLv2;
|
||||
protomask |= TLS_PROTOCOL_SSLv2;
|
||||
|
||||
/*
|
||||
* Per session cipher selection for sessions with mandatory encryption
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -223,9 +223,6 @@ char *tls_serverid_digest(const TLS_CLIENT_START_PROPS *props, long protomask,
|
||||
* we must include the SNI name in the session id.
|
||||
*/
|
||||
if (props->dane) {
|
||||
int mixed = (props->dane->flags & TLS_DANE_FLAG_MIXED);
|
||||
|
||||
digest_object(&mixed);
|
||||
digest_dane(props->dane, ta);
|
||||
#if 0
|
||||
digest_dane(props->dane, ee); /* See above */
|
||||
|
@ -14,10 +14,11 @@
|
||||
/* char *var_tls_null_clist;
|
||||
/* char *var_tls_eecdh_strong;
|
||||
/* char *var_tls_eecdh_ultra;
|
||||
/* char *var_tls_dane_ta_dgst;
|
||||
/* char *var_tls_dane_agility;
|
||||
/* char *var_tls_dane_digests;
|
||||
/* int var_tls_daemon_rand_bytes;
|
||||
/* bool var_tls_append_def_CA;
|
||||
/* bool var_tls_dane_taa_dgst;
|
||||
/* bool var_tls_preempt_clist;
|
||||
/* bool var_tls_bc_pkey_fprint;
|
||||
/* bool var_tls_multi_wildcard;
|
||||
@ -221,15 +222,15 @@ char *var_tls_null_clist;
|
||||
int var_tls_daemon_rand_bytes;
|
||||
char *var_tls_eecdh_strong;
|
||||
char *var_tls_eecdh_ultra;
|
||||
char *var_tls_dane_agility;
|
||||
char *var_tls_dane_digests;
|
||||
char *var_tls_dane_ta_dgst;
|
||||
bool var_tls_append_def_CA;
|
||||
char *var_tls_bug_tweaks;
|
||||
char *var_tls_ssl_options;
|
||||
bool var_tls_bc_pkey_fprint;
|
||||
bool var_tls_dane_taa_dgst;
|
||||
bool var_tls_multi_wildcard;
|
||||
char *var_tls_mgr_service;
|
||||
char *tls_dane_digests;
|
||||
|
||||
#ifdef VAR_TLS_PREEMPT_CLIST
|
||||
bool var_tls_preempt_clist;
|
||||
@ -264,59 +265,72 @@ static const NAME_CODE protocol_table[] = {
|
||||
#define NAMEBUG(x) #x, SSL_OP_##x
|
||||
static const LONG_NAME_MASK ssl_bug_tweaks[] = {
|
||||
|
||||
#if defined(SSL_OP_MICROSOFT_SESS_ID_BUG)
|
||||
NAMEBUG(MICROSOFT_SESS_ID_BUG), /* 0x00000001L */
|
||||
#ifndef SSL_OP_MICROSOFT_SESS_ID_BUG
|
||||
#define SSL_OP_MICROSOFT_SESS_ID_BUG 0
|
||||
#endif
|
||||
NAMEBUG(MICROSOFT_SESS_ID_BUG),
|
||||
|
||||
#if defined(SSL_OP_NETSCAPE_CHALLENGE_BUG)
|
||||
NAMEBUG(NETSCAPE_CHALLENGE_BUG), /* 0x00000002L */
|
||||
#ifndef SSL_OP_NETSCAPE_CHALLENGE_BUG
|
||||
#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0
|
||||
#endif
|
||||
NAMEBUG(NETSCAPE_CHALLENGE_BUG),
|
||||
|
||||
#if defined(SSL_OP_LEGACY_SERVER_CONNECT)
|
||||
NAMEBUG(LEGACY_SERVER_CONNECT), /* 0x00000004L */
|
||||
#ifndef SSL_OP_LEGACY_SERVER_CONNECT
|
||||
#define SSL_OP_LEGACY_SERVER_CONNECT 0
|
||||
#endif
|
||||
NAMEBUG(LEGACY_SERVER_CONNECT),
|
||||
|
||||
#if defined(SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG)
|
||||
NAMEBUG(NETSCAPE_REUSE_CIPHER_CHANGE_BUG), /* 0x00000008L */
|
||||
#ifndef SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
|
||||
#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0
|
||||
#endif
|
||||
NAMEBUG(NETSCAPE_REUSE_CIPHER_CHANGE_BUG),
|
||||
"CVE-2010-4180", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG,
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG)
|
||||
NAMEBUG(SSLREF2_REUSE_CERT_TYPE_BUG), /* 0x00000010L */
|
||||
#ifndef SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
|
||||
#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0
|
||||
#endif
|
||||
NAMEBUG(SSLREF2_REUSE_CERT_TYPE_BUG),
|
||||
|
||||
#if defined(SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER)
|
||||
NAMEBUG(MICROSOFT_BIG_SSLV3_BUFFER),/* 0x00000020L */
|
||||
#ifndef SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
|
||||
#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0
|
||||
#endif
|
||||
NAMEBUG(MICROSOFT_BIG_SSLV3_BUFFER),
|
||||
|
||||
#if defined(SSL_OP_MSIE_SSLV2_RSA_PADDING)
|
||||
NAMEBUG(MSIE_SSLV2_RSA_PADDING), /* 0x00000040L */
|
||||
#ifndef SSL_OP_MSIE_SSLV2_RSA_PADDING
|
||||
#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0
|
||||
#endif
|
||||
NAMEBUG(MSIE_SSLV2_RSA_PADDING),
|
||||
"CVE-2005-2969", SSL_OP_MSIE_SSLV2_RSA_PADDING,
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_SSLEAY_080_CLIENT_DH_BUG)
|
||||
NAMEBUG(SSLEAY_080_CLIENT_DH_BUG), /* 0x00000080L */
|
||||
#ifndef SSL_OP_SSLEAY_080_CLIENT_DH_BUG
|
||||
#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0
|
||||
#endif
|
||||
NAMEBUG(SSLEAY_080_CLIENT_DH_BUG),
|
||||
|
||||
#if defined(SSL_OP_TLS_D5_BUG)
|
||||
NAMEBUG(TLS_D5_BUG), /* 0x00000100L */
|
||||
#ifndef SSL_OP_TLS_D5_BUG
|
||||
#define SSL_OP_TLS_D5_BUG 0
|
||||
#endif
|
||||
NAMEBUG(TLS_D5_BUG),
|
||||
|
||||
#if defined(SSL_OP_TLS_BLOCK_PADDING_BUG)
|
||||
NAMEBUG(TLS_BLOCK_PADDING_BUG), /* 0x00000200L */
|
||||
#ifndef SSL_OP_TLS_BLOCK_PADDING_BUG
|
||||
#define SSL_OP_TLS_BLOCK_PADDING_BUG 0
|
||||
#endif
|
||||
NAMEBUG(TLS_BLOCK_PADDING_BUG),
|
||||
|
||||
#if defined(SSL_OP_TLS_ROLLBACK_BUG)
|
||||
NAMEBUG(TLS_ROLLBACK_BUG), /* 0x00000400L */
|
||||
#ifndef SSL_OP_TLS_ROLLBACK_BUG
|
||||
#define SSL_OP_TLS_ROLLBACK_BUG 0
|
||||
#endif
|
||||
NAMEBUG(TLS_ROLLBACK_BUG),
|
||||
|
||||
#if defined(SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS)
|
||||
NAMEBUG(DONT_INSERT_EMPTY_FRAGMENTS), /* 0x00000800L */
|
||||
#ifndef SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
|
||||
#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0
|
||||
#endif
|
||||
NAMEBUG(DONT_INSERT_EMPTY_FRAGMENTS),
|
||||
|
||||
#if defined(SSL_OP_CRYPTOPRO_TLSEXT_BUG)
|
||||
NAMEBUG(CRYPTOPRO_TLSEXT_BUG), /* 0x80000000L */
|
||||
#ifndef SSL_OP_CRYPTOPRO_TLSEXT_BUG
|
||||
#define SSL_OP_CRYPTOPRO_TLSEXT_BUG 0
|
||||
#endif
|
||||
NAMEBUG(CRYPTOPRO_TLSEXT_BUG),
|
||||
0, 0,
|
||||
};
|
||||
|
||||
@ -328,17 +342,20 @@ static const LONG_NAME_MASK ssl_bug_tweaks[] = {
|
||||
#define NAME_SSL_OP(x) #x, SSL_OP_##x
|
||||
static const LONG_NAME_MASK ssl_op_tweaks[] = {
|
||||
|
||||
#if defined(SSL_OP_LEGACY_SERVER_CONNECT)
|
||||
#ifndef SSL_OP_LEGACY_SERVER_CONNECT
|
||||
#define SSL_OP_LEGACY_SERVER_CONNECT 0
|
||||
#endif
|
||||
NAME_SSL_OP(LEGACY_SERVER_CONNECT),
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_NO_TICKET)
|
||||
#ifndef SSL_OP_NO_TICKET
|
||||
#define SSL_OP_NO_TICKET 0
|
||||
#endif
|
||||
NAME_SSL_OP(NO_TICKET),
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_NO_COMPRESSION)
|
||||
NAME_SSL_OP(NO_COMPRESSION),
|
||||
#ifndef SSL_OP_NO_COMPRESSION
|
||||
#define SSL_OP_NO_COMPRESSION 0
|
||||
#endif
|
||||
NAME_SSL_OP(NO_COMPRESSION),
|
||||
0, 0,
|
||||
};
|
||||
|
||||
@ -597,8 +614,8 @@ void tls_param_init(void)
|
||||
VAR_TLS_EECDH_ULTRA, DEF_TLS_EECDH_ULTRA, &var_tls_eecdh_ultra, 1, 0,
|
||||
VAR_TLS_BUG_TWEAKS, DEF_TLS_BUG_TWEAKS, &var_tls_bug_tweaks, 0, 0,
|
||||
VAR_TLS_SSL_OPTIONS, DEF_TLS_SSL_OPTIONS, &var_tls_ssl_options, 0, 0,
|
||||
VAR_TLS_DANE_AGILITY, DEF_TLS_DANE_AGILITY, &var_tls_dane_agility, 1, 0,
|
||||
VAR_TLS_DANE_DIGESTS, DEF_TLS_DANE_DIGESTS, &var_tls_dane_digests, 1, 0,
|
||||
VAR_TLS_DANE_TA_DGST, DEF_TLS_DANE_TA_DGST, &var_tls_dane_ta_dgst, 0, 0,
|
||||
VAR_TLS_MGR_SERVICE, DEF_TLS_MGR_SERVICE, &var_tls_mgr_service, 1, 0,
|
||||
0,
|
||||
};
|
||||
@ -609,6 +626,7 @@ void tls_param_init(void)
|
||||
static const CONFIG_BOOL_TABLE bool_table[] = {
|
||||
VAR_TLS_APPEND_DEF_CA, DEF_TLS_APPEND_DEF_CA, &var_tls_append_def_CA,
|
||||
VAR_TLS_BC_PKEY_FPRINT, DEF_TLS_BC_PKEY_FPRINT, &var_tls_bc_pkey_fprint,
|
||||
VAR_TLS_DANE_TAA_DGST, DEF_TLS_DANE_TAA_DGST, &var_tls_dane_taa_dgst,
|
||||
VAR_TLS_PREEMPT_CLIST, DEF_TLS_PREEMPT_CLIST, &var_tls_preempt_clist,
|
||||
VAR_TLS_MULTI_WILDCARD, DEF_TLS_MULTI_WILDCARD, &var_tls_multi_wildcard,
|
||||
0,
|
||||
@ -934,7 +952,8 @@ long tls_bug_bits(void)
|
||||
{
|
||||
long bits = SSL_OP_ALL; /* Work around all known bugs */
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x00908000L && \
|
||||
OPENSSL_VERSION_NUMBER < 0x10000000L
|
||||
long lib_version = SSLeay();
|
||||
|
||||
/*
|
||||
@ -960,6 +979,10 @@ long tls_bug_bits(void)
|
||||
bits &= ~long_name_mask_opt(VAR_TLS_BUG_TWEAKS, ssl_bug_tweaks,
|
||||
var_tls_bug_tweaks, NAME_MASK_ANY_CASE |
|
||||
NAME_MASK_NUMBER | NAME_MASK_WARN);
|
||||
#ifdef SSL_OP_SAFARI_ECDHE_ECDSA_BUG
|
||||
/* Not relevant to SMTP */
|
||||
bits &= ~SSL_OP_SAFARI_ECDHE_ECDSA_BUG;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -988,17 +1011,14 @@ void tls_print_errors(void)
|
||||
const char *data;
|
||||
int line;
|
||||
int flags;
|
||||
unsigned long thread;
|
||||
|
||||
thread = CRYPTO_thread_id();
|
||||
while ((err = ERR_get_error_line_data(&file, &line, &data, &flags)) != 0) {
|
||||
ERR_error_string_n(err, buffer, sizeof(buffer));
|
||||
if (flags & ERR_TXT_STRING)
|
||||
msg_warn("TLS library problem: %lu:%s:%s:%d:%s:",
|
||||
thread, buffer, file, line, data);
|
||||
msg_warn("TLS library problem: %s:%s:%d:%s:",
|
||||
buffer, file, line, data);
|
||||
else
|
||||
msg_warn("TLS library problem: %lu:%s:%s:%d:",
|
||||
thread, buffer, file, line);
|
||||
msg_warn("TLS library problem: %s:%s:%d:", buffer, file, line);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -12,10 +12,12 @@
|
||||
/* int export;
|
||||
/* int keylength;
|
||||
/* DESCRIPTION
|
||||
/* This module maintains parameters for Diffie-Hellman key generation.
|
||||
/*
|
||||
/* tls_tmp_rsa_cb() is a call-back routine for the
|
||||
/* SSL_CTX_set_tmp_rsa_callback() function.
|
||||
/*
|
||||
/* This implementation will generate only 512-bit ephemeral
|
||||
/* RSA keys for export ciphersuites. It will log a warning in
|
||||
/* all other usage contexts.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
@ -35,11 +37,14 @@
|
||||
/* IBM T.J. Watson Research
|
||||
/* P.O. Box 704
|
||||
/* Yorktown Heights, NY 10598, USA
|
||||
/*
|
||||
/* Viktor Dukhovni.
|
||||
/*--*/
|
||||
|
||||
/* System library. */
|
||||
|
||||
#include <sys_defs.h>
|
||||
#include <msg.h>
|
||||
|
||||
#ifdef USE_TLS
|
||||
|
||||
@ -50,25 +55,63 @@
|
||||
|
||||
/* tls_tmp_rsa_cb - call-back to generate ephemeral RSA key */
|
||||
|
||||
RSA *tls_tmp_rsa_cb(SSL *unused_ssl, int unused_export, int keylength)
|
||||
RSA *tls_tmp_rsa_cb(SSL *unused_ssl, int export, int keylength)
|
||||
{
|
||||
static RSA *rsa_tmp;
|
||||
|
||||
/* Code adapted from OpenSSL apps/s_cb.c */
|
||||
/*
|
||||
* We generate ephemeral RSA keys only for export ciphersuites. In all
|
||||
* other contexts use of ephemeral RSA keys violates the SSL/TLS
|
||||
* protocol, and only takes place when applications ask for trouble and
|
||||
* set the SSL_OP_EPHEMERAL_RSA option. Postfix should never do that.
|
||||
*/
|
||||
if (!export || keylength != 512) {
|
||||
msg_warn("%sexport %d-bit ephemeral RSA key requested",
|
||||
export ? "" : "non-", keylength);
|
||||
return 0;
|
||||
}
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10000000L
|
||||
if (rsa_tmp == 0) {
|
||||
BIGNUM *e = BN_new();
|
||||
|
||||
if (e != 0 && BN_set_word(e, RSA_F4) && (rsa_tmp = RSA_new()) != 0)
|
||||
if (!RSA_generate_key_ex(rsa_tmp, keylength, e, 0)) {
|
||||
RSA_free(rsa_tmp);
|
||||
rsa_tmp = 0;
|
||||
}
|
||||
if (e)
|
||||
BN_free(e);
|
||||
}
|
||||
#else
|
||||
if (rsa_tmp == 0)
|
||||
rsa_tmp = RSA_generate_key(keylength, RSA_F4, NULL, NULL);
|
||||
#endif
|
||||
|
||||
return (rsa_tmp);
|
||||
}
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
int main(int unused_argc, char **unused_argv)
|
||||
#include <msg_vstream.h>
|
||||
|
||||
int main(int unused_argc, char *const argv[])
|
||||
{
|
||||
tls_tmp_rsa_cb(0, 1, 512);
|
||||
tls_tmp_rsa_cb(0, 1, 1024);
|
||||
tls_tmp_rsa_cb(0, 1, 2048);
|
||||
tls_tmp_rsa_cb(0, 0, 512);
|
||||
RSA *rsa;
|
||||
int ok;
|
||||
|
||||
msg_vstream_init(argv[0], VSTREAM_ERR);
|
||||
|
||||
/* Export at 512-bits should work */
|
||||
rsa = tls_tmp_rsa_cb(0, 1, 512);
|
||||
ok = rsa != 0 && RSA_size(rsa) == 512 / 8;
|
||||
ok = ok && PEM_write_RSAPrivateKey(stdout, rsa, 0, 0, 0, 0, 0);
|
||||
tls_print_errors();
|
||||
|
||||
/* Non-export or unexpected bit length should fail */
|
||||
ok = ok && tls_tmp_rsa_cb(0, 0, 512) == 0;
|
||||
ok = ok && tls_tmp_rsa_cb(0, 1, 1024) == 0;
|
||||
|
||||
return ok ? 0 : 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -183,8 +183,8 @@ static SSL_SESSION *get_server_session_cb(SSL *ssl, unsigned char *session_id,
|
||||
do { \
|
||||
buf = vstring_alloc(2 * (len + strlen(service))); \
|
||||
hex_encode(buf, (char *) (id), (len)); \
|
||||
vstring_sprintf_append(buf, "&s=%s", (service)); \
|
||||
vstring_sprintf_append(buf, "&l=%ld", (long) SSLeay()); \
|
||||
vstring_sprintf_append(buf, "&s=%s", (service)); \
|
||||
vstring_sprintf_append(buf, "&l=%ld", (long) SSLeay()); \
|
||||
} while (0)
|
||||
|
||||
|
||||
@ -797,7 +797,7 @@ TLS_SESS_STATE *tls_server_start(const TLS_SERVER_START_PROPS *props)
|
||||
|
||||
TLS_SESS_STATE *tls_server_post_accept(TLS_SESS_STATE *TLScontext)
|
||||
{
|
||||
const SSL_CIPHER *cipher;
|
||||
SSL_CIPHER_const SSL_CIPHER *cipher;
|
||||
X509 *peer;
|
||||
char buf[CCERT_BUFSIZ];
|
||||
|
||||
|
@ -115,7 +115,8 @@
|
||||
/* addresses that have no ".domain" information.
|
||||
/* .IP "\fBrecipient_delimiter (empty)\fR"
|
||||
/* The set of characters that can separate a user name from its
|
||||
/* address extension (user+foo).
|
||||
/* extension (example: user+foo), or a .forward file name from its
|
||||
/* extension (example: .forward+foo).
|
||||
/* .IP "\fBswap_bangpath (yes)\fR"
|
||||
/* Enable the rewriting of "site!user" into "user@site".
|
||||
/* .PP
|
||||
|
@ -41,6 +41,11 @@
|
||||
/* ssize_t pos;
|
||||
/* const char *arg;
|
||||
/*
|
||||
/* void argv_delete(argvp, pos, how_many)
|
||||
/* ARGV *argvp;
|
||||
/* ssize_t pos;
|
||||
/* ssize_t how_many;
|
||||
/*
|
||||
/* void ARGV_FAKE_BEGIN(argv, arg)
|
||||
/* const char *arg;
|
||||
/*
|
||||
@ -85,6 +90,10 @@
|
||||
/* argv_replace_one() replaces one string at the specified
|
||||
/* position.
|
||||
/*
|
||||
/* argv_delete() deletes the specified number of elements
|
||||
/* starting at the specified array position. The result is
|
||||
/* null-terminated.
|
||||
/*
|
||||
/* ARGV_FAKE_BEGIN/END are an optimization for the case where
|
||||
/* a single string needs to be passed into an ARGV-based
|
||||
/* interface. ARGV_FAKE_BEGIN() opens a statement block and
|
||||
@ -292,3 +301,23 @@ void argv_replace_one(ARGV *argvp, ssize_t where, const char *arg)
|
||||
myfree(argvp->argv[where]);
|
||||
argvp->argv[where] = mystrdup(arg);
|
||||
}
|
||||
|
||||
/* argv_delete - remove string(s) from array */
|
||||
|
||||
void argv_delete(ARGV *argvp, ssize_t first, ssize_t how_many)
|
||||
{
|
||||
ssize_t pos;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
if (first < 0 || how_many < 0 || first + how_many > argvp->argc)
|
||||
msg_panic("argv_delete bad range: (start=%ld count=%ld)",
|
||||
(long) first, (long) how_many);
|
||||
|
||||
for (pos = first; pos < first + how_many; pos++)
|
||||
myfree(argvp->argv[pos]);
|
||||
for (pos = first; pos <= argvp->argc - how_many; pos++)
|
||||
argvp->argv[pos] = argvp->argv[pos + how_many];
|
||||
argvp->argc -= how_many;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ extern void argv_terminate(ARGV *);
|
||||
extern void argv_truncate(ARGV *, ssize_t);
|
||||
extern void argv_insert_one(ARGV *, ssize_t, const char *);
|
||||
extern void argv_replace_one(ARGV *, ssize_t, const char *);
|
||||
extern void argv_delete(ARGV *, ssize_t, ssize_t);
|
||||
extern ARGV *argv_free(ARGV *);
|
||||
|
||||
extern ARGV *argv_split(const char *, const char *);
|
||||
|
@ -8,9 +8,11 @@
|
||||
/*
|
||||
/* ARGV *argv_split(string, delim)
|
||||
/* const char *string;
|
||||
/* const char *delim;
|
||||
/*
|
||||
/* ARGV *argv_split_count(string, delim, count)
|
||||
/* const char *string;
|
||||
/* const char *delim;
|
||||
/* ssize_t count;
|
||||
/*
|
||||
/* ARGV *argv_split_append(argv, string, delim)
|
||||
|
@ -115,7 +115,7 @@ const char *host_port(char *buf, char **host, char *def_host,
|
||||
char *cp = buf;
|
||||
int ipv6 = 0;
|
||||
|
||||
/*
|
||||
/*-
|
||||
* [host]:port, [host]:, [host].
|
||||
* [ipv6:ipv6addr]:port, [ipv6:ipv6addr]:, [ipv6:ipv6addr].
|
||||
*/
|
||||
|
@ -296,8 +296,8 @@ static int slmdb_recover(SLMDB *slmdb, int status)
|
||||
MDB_envinfo info;
|
||||
|
||||
/*
|
||||
* Recover bulk transactions only if they can be restarted. Limit
|
||||
* the number of recovery attempts per slmdb(3) API request.
|
||||
* Recover bulk transactions only if they can be restarted. Limit the
|
||||
* number of recovery attempts per slmdb(3) API request.
|
||||
*/
|
||||
if ((slmdb->txn != 0 && slmdb->longjmp_fn == 0)
|
||||
|| ((slmdb->api_retry_count += 1) >= slmdb->api_retry_limit))
|
||||
|
Loading…
x
Reference in New Issue
Block a user