From 04018b3a75e96f0610d0ead00ac3c209f90b173f Mon Sep 17 00:00:00 2001
From: Wietse Venema
Date: Mon, 17 Jan 2005 00:00:00 -0500
Subject: [PATCH] postfix-2.2-20050117
---
postfix/.indent.pro | 7 +
postfix/COMPATIBILITY | 8 +-
postfix/HISTORY | 163 ++++
postfix/IPv6-ChangeLog | 483 +++++++++++
postfix/Makefile.in | 8 +-
postfix/README_FILES/AAAREADME | 1 +
postfix/README_FILES/FILTER_README | 10 +-
postfix/README_FILES/IPV6_README | 250 ++++++
postfix/README_FILES/SMTPD_POLICY_README | 3 +
postfix/RELEASE_NOTES | 48 +
postfix/conf/access | 174 ++--
postfix/conf/post-install | 15 +-
postfix/conf/postfix-files | 3 +
postfix/conf/postfix-script | 71 +-
postfix/html/FILTER_README.html | 10 +-
postfix/html/IPV6_README.html | 370 ++++++++
postfix/html/SASL_README.html | 4 +-
postfix/html/SMTPD_POLICY_README.html | 4 +
postfix/html/access.5.html | 172 ++--
postfix/html/cidr_table.5.html | 22 +-
postfix/html/index.html | 2 +
postfix/html/master.8.html | 23 +-
postfix/html/postconf.5.html | 190 +++-
postfix/html/postqueue.1.html | 57 +-
postfix/html/qmqp-sink.1.html | 16 +-
postfix/html/qmqp-source.1.html | 11 +-
postfix/html/qmqpd.8.html | 2 +-
postfix/html/sendmail.1.html | 3 +
postfix/html/smtp-sink.1.html | 45 +-
postfix/html/smtp-source.1.html | 48 +-
postfix/html/smtp.8.html | 26 +-
postfix/html/smtpd.8.html | 290 ++++---
postfix/makedefs | 19 +-
postfix/man/man1/postqueue.1 | 4 +-
postfix/man/man1/qmqp-sink.1 | 15 +-
postfix/man/man1/qmqp-source.1 | 10 +-
postfix/man/man1/sendmail.1 | 2 +
postfix/man/man1/smtp-sink.1 | 11 +-
postfix/man/man1/smtp-source.1 | 11 +-
postfix/man/man5/access.5 | 43 +-
postfix/man/man5/cidr_table.5 | 8 +-
postfix/man/man5/postconf.5 | 181 +++-
postfix/man/man8/master.8 | 6 +-
postfix/man/man8/qmqpd.8 | 2 +-
postfix/man/man8/smtp.8 | 12 +-
postfix/man/man8/smtpd.8 | 7 +-
postfix/mantools/ccformat | 2 +-
postfix/mantools/makereadme | 2 +-
postfix/mantools/postlink | 2 +
postfix/mantools/xpostdef | 1 -
postfix/proto/FILTER_README.html | 10 +-
postfix/proto/IPV6_README.html | 370 ++++++++
postfix/proto/Makefile.in | 12 +-
postfix/proto/SMTPD_POLICY_README.html | 4 +
postfix/proto/SMTPD_PROXY_README.html | 2 +-
postfix/proto/access | 43 +-
postfix/proto/cidr_table | 8 +-
postfix/proto/postconf.proto | 182 +++-
postfix/proto/stop | 24 +
postfix/src/anvil/Makefile.in | 2 +-
postfix/src/bounce/Makefile.in | 2 +-
postfix/src/cleanup/Makefile.in | 3 +-
postfix/src/discard/Makefile.in | 2 +-
postfix/src/dns/Makefile.in | 95 +-
postfix/src/dns/dns.h | 50 +-
postfix/src/dns/dns_lookup.c | 125 ++-
postfix/src/dns/dns_rr.c | 20 +-
postfix/src/dns/dns_rr_eq_sa.c | 137 +++
postfix/src/dns/dns_rr_eq_sa.in | 4 +
postfix/src/dns/dns_rr_eq_sa.ref | 24 +
postfix/src/dns/dns_rr_to_pa.c | 113 +++
postfix/src/dns/dns_rr_to_pa.in | 2 +
postfix/src/dns/dns_rr_to_pa.ref | 2 +
postfix/src/dns/dns_rr_to_sa.c | 163 ++++
postfix/src/dns/dns_rr_to_sa.in | 2 +
postfix/src/dns/dns_rr_to_sa.ref | 2 +
postfix/src/dns/dns_sa_to_rr.c | 118 +++
postfix/src/dns/dns_sa_to_rr.in | 1 +
postfix/src/dns/dns_sa_to_rr.ref | 2 +
postfix/src/dns/test_dns_lookup.c | 14 +-
postfix/src/error/Makefile.in | 2 +-
postfix/src/flush/Makefile.in | 2 +-
postfix/src/fsstone/Makefile.in | 2 +-
postfix/src/global/Makefile.in | 55 +-
postfix/src/global/mail_params.c | 31 +-
postfix/src/global/mail_params.h | 19 +-
postfix/src/global/mail_version.h | 2 +-
postfix/src/global/mime_state.c | 2 +-
postfix/src/global/mynetworks.c | 230 +++--
postfix/src/global/namadr_list.in | 17 +
postfix/src/global/namadr_list.ref | 17 +
postfix/src/global/own_inet_addr.c | 75 +-
postfix/src/global/own_inet_addr.h | 8 +-
postfix/src/global/resolve_local.c | 63 +-
postfix/src/global/smtp_stream.c | 1 -
postfix/src/global/valid_mailhost_addr.c | 152 ++++
postfix/src/global/valid_mailhost_addr.h | 38 +
postfix/src/global/wildcard_inet_addr.c | 68 ++
postfix/src/global/wildcard_inet_addr.h | 33 +
postfix/src/global/xtext.c | 2 +-
postfix/src/lmtp/Makefile.in | 9 +-
postfix/src/lmtp/lmtp_addr.c | 81 +-
postfix/src/lmtp/lmtp_connect.c | 40 +-
postfix/src/local/Makefile.in | 4 +-
postfix/src/master/Makefile.in | 11 +-
postfix/src/master/master.c | 29 +-
postfix/src/master/master_ent.c | 20 +-
postfix/src/master/master_listen.c | 34 +-
postfix/src/master/master_vars.c | 14 +
postfix/src/oqmgr/Makefile.in | 2 +-
postfix/src/pickup/Makefile.in | 2 +-
postfix/src/pipe/Makefile.in | 2 +-
postfix/src/postalias/Makefile.in | 2 +-
postfix/src/postcat/Makefile.in | 2 +-
postfix/src/postconf/Makefile.in | 3 +-
postfix/src/postconf/postconf.c | 9 +
postfix/src/postdrop/Makefile.in | 2 +-
postfix/src/postfix/Makefile.in | 2 +-
postfix/src/postkick/Makefile.in | 2 +-
postfix/src/postlock/Makefile.in | 2 +-
postfix/src/postlog/Makefile.in | 2 +-
postfix/src/postmap/Makefile.in | 2 +-
postfix/src/postqueue/Makefile.in | 3 +-
postfix/src/postqueue/postqueue.c | 15 +-
postfix/src/postsuper/Makefile.in | 2 +-
postfix/src/proxymap/Makefile.in | 2 +-
postfix/src/qmgr/Makefile.in | 2 +-
postfix/src/qmqpd/Makefile.in | 13 +-
postfix/src/qmqpd/qmqpd.c | 6 +-
postfix/src/qmqpd/qmqpd.h | 1 +
postfix/src/qmqpd/qmqpd_peer.c | 180 ++--
postfix/src/scache/Makefile.in | 2 +-
postfix/src/sendmail/Makefile.in | 2 +-
postfix/src/sendmail/sendmail.c | 4 +-
postfix/src/showq/Makefile.in | 2 +-
postfix/src/smtp/Makefile.in | 12 +-
postfix/src/smtp/smtp.c | 24 +-
postfix/src/smtp/smtp_addr.c | 136 +--
postfix/src/smtp/smtp_connect.c | 163 ++--
postfix/src/smtp/smtp_reuse.c | 8 +-
postfix/src/smtp/smtp_session.c | 2 +-
postfix/src/smtp/smtp_unalias.c | 8 +-
postfix/src/smtpd/Makefile.in | 14 +-
postfix/src/smtpd/smtpd.c | 53 +-
postfix/src/smtpd/smtpd.h | 4 +-
postfix/src/smtpd/smtpd_backup.in | 20 +
postfix/src/smtpd/smtpd_backup.ref | 34 +
postfix/src/smtpd/smtpd_check.c | 206 +++--
postfix/src/smtpd/smtpd_check.in | 4 +
postfix/src/smtpd/smtpd_check.ref | 10 +
postfix/src/smtpd/smtpd_peer.c | 187 ++--
postfix/src/smtpd/smtpd_xforward.c | 2 +
postfix/src/smtpstone/Makefile.in | 12 +-
postfix/src/smtpstone/qmqp-sink.c | 27 +-
postfix/src/smtpstone/qmqp-source.c | 52 +-
postfix/src/smtpstone/smtp-sink.c | 25 +-
postfix/src/smtpstone/smtp-source.c | 53 +-
postfix/src/spawn/Makefile.in | 2 +-
postfix/src/trivial-rewrite/Makefile.in | 4 +-
postfix/src/trivial-rewrite/resolve.c | 10 +-
postfix/src/util/Makefile.in | 123 ++-
postfix/src/util/argv.h | 4 +-
postfix/src/util/cidr_match.c | 230 +++++
postfix/src/util/cidr_match.h | 64 ++
postfix/src/util/dict_alloc.c | 2 +-
postfix/src/util/dict_cidr.c | 114 +--
postfix/src/util/dict_cidr.in | 4 +
postfix/src/util/dict_cidr.map | 9 +
postfix/src/util/dict_cidr.ref | 14 +-
postfix/src/util/exec_command.c | 2 +-
postfix/src/util/find_inet.c | 1 +
postfix/src/util/hex_quote.c | 2 +-
postfix/src/util/host_port.c | 97 ++-
postfix/src/util/host_port.h | 2 +-
postfix/src/util/host_port.in | 4 +-
postfix/src/util/host_port.ref | 12 +-
postfix/src/util/inet_addr_host.c | 113 ++-
postfix/src/util/inet_addr_list.c | 45 +-
postfix/src/util/inet_addr_list.h | 8 +-
postfix/src/util/inet_addr_local.c | 510 ++++++++++-
postfix/src/util/inet_addr_local.h | 2 +-
postfix/src/util/inet_connect.c | 91 +-
postfix/src/util/inet_listen.c | 101 ++-
postfix/src/util/inet_proto.c | 274 ++++++
postfix/src/util/inet_proto.h | 51 ++
postfix/src/util/inet_util.c | 61 --
postfix/src/util/mac_parse.c | 3 +-
postfix/src/util/make_dirs.c | 2 +-
postfix/src/util/mask_addr.c | 68 ++
postfix/src/util/{inet_util.h => mask_addr.h} | 17 +-
postfix/src/util/match_list.c | 7 +-
postfix/src/util/match_ops.c | 108 ++-
postfix/src/util/msg_syslog.c | 2 +-
postfix/src/util/myaddrinfo.c | 821 ++++++++++++++++++
postfix/src/util/myaddrinfo.h | 211 +++++
postfix/src/util/myaddrinfo.ref | 8 +
postfix/src/util/myaddrinfo.ref2 | 5 +
postfix/src/util/myaddrinfo4.ref | 6 +
postfix/src/util/myaddrinfo4.ref2 | 5 +
postfix/src/util/name_mask.c | 16 -
postfix/src/util/sock_addr.c | 169 ++++
postfix/src/util/sock_addr.h | 95 ++
postfix/src/util/stream_send_fd.c | 2 +-
postfix/src/util/sys_compat.c | 91 ++
postfix/src/util/sys_defs.h | 70 +-
postfix/src/util/valid_hostname.c | 208 +++--
postfix/src/util/valid_hostname.h | 3 +-
postfix/src/util/valid_hostname.in | 24 +-
postfix/src/util/valid_hostname.ref | 176 ++--
postfix/src/util/vstring.c | 2 +-
postfix/src/util/vstring_vstream.c | 2 +-
postfix/src/util/watchdog.c | 2 +-
postfix/src/verify/Makefile.in | 2 +-
postfix/src/verify/verify.c | 5 +
postfix/src/virtual/Makefile.in | 2 +-
215 files changed, 9027 insertions(+), 1861 deletions(-)
create mode 100644 postfix/IPv6-ChangeLog
create mode 100644 postfix/README_FILES/IPV6_README
create mode 100644 postfix/html/IPV6_README.html
create mode 100644 postfix/proto/IPV6_README.html
create mode 100644 postfix/src/dns/dns_rr_eq_sa.c
create mode 100644 postfix/src/dns/dns_rr_eq_sa.in
create mode 100644 postfix/src/dns/dns_rr_eq_sa.ref
create mode 100644 postfix/src/dns/dns_rr_to_pa.c
create mode 100644 postfix/src/dns/dns_rr_to_pa.in
create mode 100644 postfix/src/dns/dns_rr_to_pa.ref
create mode 100644 postfix/src/dns/dns_rr_to_sa.c
create mode 100644 postfix/src/dns/dns_rr_to_sa.in
create mode 100644 postfix/src/dns/dns_rr_to_sa.ref
create mode 100644 postfix/src/dns/dns_sa_to_rr.c
create mode 100644 postfix/src/dns/dns_sa_to_rr.in
create mode 100644 postfix/src/dns/dns_sa_to_rr.ref
create mode 100644 postfix/src/global/namadr_list.in
create mode 100644 postfix/src/global/namadr_list.ref
create mode 100644 postfix/src/global/valid_mailhost_addr.c
create mode 100644 postfix/src/global/valid_mailhost_addr.h
create mode 100644 postfix/src/global/wildcard_inet_addr.c
create mode 100644 postfix/src/global/wildcard_inet_addr.h
create mode 100644 postfix/src/smtpd/smtpd_backup.in
create mode 100644 postfix/src/smtpd/smtpd_backup.ref
create mode 100644 postfix/src/util/cidr_match.c
create mode 100644 postfix/src/util/cidr_match.h
create mode 100644 postfix/src/util/inet_proto.c
create mode 100644 postfix/src/util/inet_proto.h
delete mode 100644 postfix/src/util/inet_util.c
create mode 100644 postfix/src/util/mask_addr.c
rename postfix/src/util/{inet_util.h => mask_addr.h} (55%)
create mode 100644 postfix/src/util/myaddrinfo.c
create mode 100644 postfix/src/util/myaddrinfo.h
create mode 100644 postfix/src/util/myaddrinfo.ref
create mode 100644 postfix/src/util/myaddrinfo.ref2
create mode 100644 postfix/src/util/myaddrinfo4.ref
create mode 100644 postfix/src/util/myaddrinfo4.ref2
create mode 100644 postfix/src/util/sock_addr.c
create mode 100644 postfix/src/util/sock_addr.h
diff --git a/postfix/.indent.pro b/postfix/.indent.pro
index 8536d0b57..a6844755a 100644
--- a/postfix/.indent.pro
+++ b/postfix/.indent.pro
@@ -1,4 +1,5 @@
-TABOUNCE
+-TADDR_PATTERN
-TALIAS_TOKEN
-TANVIL_CLNT
-TANVIL_LOCAL
@@ -16,6 +17,7 @@
-TBOUNCE_LOG
-TBOUNCE_STAT
-TCFG_PARSER
+-TCIDR_MATCH
-TCLEANUP_STATE
-TCLIENT_LIST
-TCLNT_STREAM
@@ -81,6 +83,7 @@
-THTABLE
-THTABLE_INFO
-TINET_ADDR_LIST
+-TINET_PROTO_INFO
-TINTV
-TINT_TABLE
-TJMP_BUF_WRAPPER
@@ -97,6 +100,10 @@
-TMAIL_PRINT
-TMAIL_SCAN
-TMAIL_STREAM
+-TMAI_HOSTADDR_STR
+-TMAI_HOSTNAME_STR
+-TMAI_SERVNAME_STR
+-TMAI_SERVPORT_STR
-TMAPS
-TMASTER_PROC
-TMASTER_SERV
diff --git a/postfix/COMPATIBILITY b/postfix/COMPATIBILITY
index 9bda1ac9b..4ee0668de 100644
--- a/postfix/COMPATIBILITY
+++ b/postfix/COMPATIBILITY
@@ -3,7 +3,6 @@
/usr/spool/mail yes (compile time option)
/var/mail yes (compile time option)
/var/spool/mail yes (compile time option)
-8bit->7bit MIME yes
:include: yes (mail to /file and |command is off by default)
address probing yes (optional persistent database)
aliases yes (can enable/disable mail to /file or |command)
@@ -23,7 +22,7 @@ genericstable no (to be done)
greylist yes (delegated policy script)
home mailbox yes
ident lookup no
-ipv6 no (to be done, patches exist)
+ipv6 yes (compatibility for ipv4-only kernels/libraries)
ldap tables yes (contributed)
lmtp support yes (client)
luser relay yes
@@ -35,12 +34,11 @@ mailertable yes (it's called transport)
mailq yes
majordomo yes (edit approve script to delete /^delivered-to:/i)
mime yes (including 8bit to quoted-printable conversion)
-mime conversion not yet; postfix uses just-send-eight
mysql tables yes (contributed)
netinfo tables yes (contributed)
newaliases yes (main alias database only)
nis tables yes
-nis+ tables yes
+nis+ tables yes (contributed)
no <> in smtp yes (most common address forms)
pgsql tables yes (contributed)
pipeline option yes (server and client)
@@ -62,7 +60,7 @@ session caching yes (SMTP shared multi-session; LMTP non-shared single-session)
size option yes, server and client
smarthost yes (specify relayhost in main.cf)
spf yes (delegated policy script)
-starttls yes (third party patch)
+starttls yes
tcp wrapper no (use built-in blacklist facility)
user+extension yes (also: .forward+extension)
user-extension yes (also: .forward-extension)
diff --git a/postfix/HISTORY b/postfix/HISTORY
index eef5f5c67..4fa3e13fd 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -9993,6 +9993,32 @@ Apologies for any names omitted.
Bugfix: further postcat corner cases.
+20041221-9
+
+ Infrastructure: unified IPv4/IPv6 name/address API so that
+ Postfix can support IPv6 without #ifdef INET6 everywhere.
+ In particular, we allow #ifdef in libraries but avoid it
+ in applications. Files: util/myaddrinfo.[hc],
+ util/sock_addr.[hc], dns/dns_rr_to_pa.c, dns/dns_sa_to_rr.c,
+ dns/dns_rr_eq_sa.c, dns/dns_rr_to_sa.c, inet_proto.[hc].
+
+ Postfix no longer attempts to deliver mail via IPv6 when
+ the system has no IPv6 connectivity. Network protocol
+ support is now selected with the "inet_protocols" configuration
+ parameter, instead of "inet_interfaces". The "inet_protocols"
+ parameter also controls what DNS lookups Postfix will do.
+
+ Infrastructure: eliminated two host/port parsing routines.
+ Only one survives: host_port(), in an extended form that
+ allows for missing host or missing service information but
+ not both. File: util/host_port.c.
+
+20041229
+
+ Milestone: Postfix with the unified IPv4/IPv6 socket/name
+ API builds without compiler error on IPv4-only system and
+ actually works.
+
20041228
Bugfix: SMTPD_PROXY_README incorrectly claimed that ":port"
@@ -10000,8 +10026,145 @@ Apologies for any names omitted.
without exposing the service to the network. Instead,
":port" causes a client to connect to "localhost".
+20041231
+
+ Linux workaround: when mynetworks isn't set, a chrooted
+ process could not read the IPv6 address information from
+ /proc. We now invoke own_inet_addr() before chrooting,
+ while processing main.cf. File: global/mail_params.c.
+
+20050101
+
+ Workaround for (Linux) systems without IPV6_V6ONLY support
+ (RFC 3493). When Postfix listened on an IPv4 wild-card
+ smtp socket, the IPv6 wild-card smtp listener would fail
+ with EADDRINUSE (and vice versa). File: util/myaddrinfo.c.
+
+20050103
+
+ Safety: when the IPV6 netmask can't be determined, assume
+ /128 (host only). File: util/inet_addr_local.c.
+
+20050104
+
+ Re-implemented IPv6 support for net/mask pattern matching.
+ Files: util/cidr_match.[hc], util/dict_cidr.c,
+ util/match_ops.[hc], proto/cidr_table.
+
+20050105
+
+ Moved mask_addr() to its own module so that it could also
+ be called by mynetworks() and inet_addr_local() to remove
+ non-zero host bits from IPv6 network/mask patterns. File:
+ util/mask_addr.c.
+
+20050108
+
+ Re-implemented IPv6 support for network interface lookup
+ via the Linux /proc file system. File: util/inet_addr_local.c.
+
+20050111
+
+ Feature: specify "inet_interfaces = loopback-only" for
+ servers that must listen on local interfaces only, without
+ having to specify IPv4 and/or IPv6 addresses in main.cf or
+ master.cf. File: global/own_inet_addr.c.
+
+ Workaround: AIX 5.1 getaddrinfo() can't handle a null host
+ argument with AI_PASSIVE. Instead we specify an explicit
+ protocol family, a host of "::" or "0.0.0.0", and turn off
+ IPV6_V6ONLY. Files: util_myaddrinfo.c, util/inet_listen.c.
+
+ Workaround: AIX 5.1 getaddrinfo() can't handle a "0" service
+ argument. Instead we specify "1". Files: util/inet_addr_host.c.
+
+20040513
+
+ Cleanup: now that the over-all structure is proving itself,
+ clean up some internal APIs to increase robustness and get
+ rid of some clumsiness. Mainly, the getaddrinfo(3) interface.
+
+ Start-up performance: the hash_queue_names default setting
+ is reduced from eight directories to just defer and deferred.
+ This reduces time for checking the Postfix queue. Files:
+ conf/post-install, global/mail_params.h.
+
+20040514
+
+ Further cleanup: eliminate duplicate IPv6 results when the
+ mynetworks value is generated by Postfix. More documentation
+ of the new internal APIs.
+
+ Performance: reduced start-up delay by moving warning-only
+ startup checks into the background; they now start after
+ one minute to allow the system to finish booting. File:
+ conf/postfix-script.
+
+20050115
+
+ Further hardening of the IPv6 support: don't trust system
+ libraries to protect Postfix against malformed IPv6 address
+ literals. Their syntax is complex enough that errors are
+ likely. Files: global/resolve_local.c, util/valid_hostname.c.
+
+ Further cleanup: RFC 2821 requires the IPv6: prefix with
+ IPv6 address strings. The smtp and qmqp servers maintain
+ separate address instances, the bare address and the RFC
+ 2821 compatible form, and use each where appropriate. This
+ strict separation simplifies address syntax checks as well
+ as the implementation of XCLIENT and XFORWARD.
+
+20050116
+
+ Infrastructure: new valid_mailhost_addr() routine to verify
+ that an address literal satisfies RFC 2821. An IPv4 address
+ is in dotted-quad decimal form, and an IPv6 address is in
+ hexadecimal form, with the "IPv6:" prefix. Files:
+ global/valid_mailhost_addr.[hc].
+
+ Further cleanup: valid_hostname() no longer allows network
+ addresses or numerical domain names. While it made some
+ sense with IPv4 dotted quad decimal forms, with IPv6 it
+ just made no sense anymore. Again, being stricter actually
+ simplifies code. Files: util/valid_hostname.c and a
+ surprisingly small number of valid_hostname() callers that
+ did not reject numerical forms.
+
+ Bugfix: in the Postfix 2.2 SMTP client, the debug_peer_init()
+ call was moved to the after-chroot initialization.
+
+20050117
+
+ Milestone: first non-non-production snapshot with IPv6.
+
Open problems:
+ Med: transform IPv4-in-IPv6 address literals to IPv4 form
+ when comparing against local IP addresses?
+
+ Med: transform IPv4-in-IPv6 address literals to IPv4 form
+ when eliminating MX mailer loops?
+
+ Med: Postfix requires [] around IPv6 address information
+ in match lists such as mynetworks, debug_peer_list etc.,
+ but the [] must not be specified in access(5) maps. Other
+ places don't care. For now, this gotcha is documented in
+ IPV6_README and in postconf(5) with each feature that may
+ use IPv6 address information. The general recommendation
+ is not to use [] unless absolutely necessary.
+
+ Med: the partial address matching of IPv6 addresses in
+ access(5) maps is a bit lame: it repeatedly truncates the
+ last ":octetpair" from the printable address representation
+ until a match is found or until truncation is no longer
+ possible. Since one or more ":" are usually omitted from
+ the printable IPv6 address representation, this does not
+ really try all the possibilities that one might expect to
+ be tried. For now, this gotcha is documented in access(5).
+
+ Low: cap bounce queue life time with regular queue life
+ time.
+
Med: implement ${name[?:]value} in main.cf or update the
postconf(5) manual.
diff --git a/postfix/IPv6-ChangeLog b/postfix/IPv6-ChangeLog
new file mode 100644
index 000000000..ed55e641b
--- /dev/null
+++ b/postfix/IPv6-ChangeLog
@@ -0,0 +1,483 @@
+ChangeLog for Dean Strik's IPv6 patch for Postfix. The patch is based on
+PLD's patch, which in turn seems to be based on KAME's. For more information:
+
+ http://www.ipnet6.org/postfix/
+
+---------------------------------------------------------------------
+
+Version 1.25 Postfix release 2.1.3
+ Postfix release 2.0.20
+ Postfix snapshot 2.2-20040616
+
+ Bugfix: Misplaced myfree() caused a small memory leak. Reported
+ by Christian von Roques.
+ File: util/match_ops.c
+
+ Removed the colon (:) from the characters XFORWARD replaces by
+ a question mark (IPv6 addresses looked like 2001?610?1108?5010??1
+ in logging). Reported by Philipp Morger.
+ File: smtpd/smtpd.c
+
+Version 1.24 Postfix release 2.1.1
+ Postfix release 2.0.20
+ Postfix snapshot 2.0.19-20040312
+ Postfix snapshot 2.2-20040504
+
+ Bugfix: Prefixlen non-null host portion validation (in CIDR maps
+ for example) yielded incorrect results sometimes because signed
+ arithmetic was used instead of unsigned.
+ File: util/match_ops.c
+
+ Patch correction: The TLS+IPv6 patch for Postfix 2.1.0 missed
+ the master.cf update (used for new installations). Added it
+ back.
+
+Version 1.23 Postfix release 2.1.0
+ Postfix release 2.0.20
+ Postfix snapshot 2.0.19-20040312
+
+ Patch fixes: Several code fixes to make the patch compile
+ and work correctly when compiled without IPv6 support.
+
+ Bugfix (Solaris only?): address family length was not updated
+ which could cause client hostname validation errors.
+ File: smtpd/smtpd_peer.c
+
+ Portability: added support for Darwin 7.3+. This may need
+ some further testing.
+
+ Cleanup: Restructure and redocument interface address
+ retrieval functions. (This reduced the number of preprocessor
+ statements from 99 to 93 ;)
+ File: util/inet_addr_local.c
+
+ Cleanup: make several explicit casts to have compilers shut
+ their pie holes about uninteresting things.
+
+Version 1.22 Postfix release 2.0.19
+ Postfix snapshot 2.0.19-20040312
+
+ Feature: Support "inet_interfaces = IPv4:all" and
+ "inet_interfaces = IPv6:all", to restrict postfix to use
+ either IPv4-only or IPv6-only. A more complete implementation
+ will be part of a future patch. (Slightly modified) patch by
+ Michal Ludvig, SuSE.
+ Files: util/interfaces_to_af.[ch], util/inet_addr_local.c,
+ global/own_inet_addr.c, global/wildcard_inet_addr.[ch],
+ master/master_ent.ch
+
+ Bugfix: In Postfix snapshots, a #define was misplaced with
+ the effect that IPv6 subnets were not included in auto-
+ generated $mynetworks (i.e., mynetworks not defined in main.cf,
+ when also mynetworks_style=subnet) on Linux 2.x systems.
+ File: utils/sys_defs.h
+
+Version 1.21a Postfix snapshots 2.0.18-2004{0122,0205,0209}
+ 2.0.19-20040312
+
+ TLS/snapshot version: Update TLS patch to 0.8.18-20040122.
+ Performed as a total repatch. 0.8.18 is cleaner with tls_*
+ variables if TLS is not actually compiled in.
+
+Version 1.21 Postfix releases 2.0.18 - 2.0.19
+ Postfix snapshot 2.0.16-20031231
+
+ Bugfix: The SMTP client could fail to setup a connection,
+ erroring with a bogus "getaddrinfo(...): hostname nor servname
+ provided" warning, because the wrong address was selected.
+ File: smtp/smtp_connect.c
+
+ Safety: in dynamically growing data structures, update the
+ length info after (instead of before) updating the data size.
+ File: util/inet_addr_list.c
+
+Version 1.20 Postfix release 2.0.16
+ Postfix snapshot 2.0.16-20031207
+
+ Bugfix: The SMTP client would abort when binding to specific
+ IPv6 addresses.
+ File: smtp/smtp_connect.c
+
+ Synchronisation/bugfix: LMTP source address binding is identical
+ to the SMTP source binding setup, avoiding the need for
+ lmtp_bind_address(6) if inet_interfaces is set to a single
+ host for an address family.
+ File: lmtp/lmtp_connect.c
+
+Version 1.19 Postfix release 2.0.16
+ Postfix snapshot 2.0.16-20031207
+
+ Bugfix: Synchronisation of TLS patches in snapshots of 1.18[ab]
+ was not complete, causing a crash of smtpd if used with the new
+ proxy agent.
+ File: smtpd/smtpd.c
+
+ Bugfix: SMTP source address binding based on a single hostname
+ in inet_interfaces did not work since the code counted IPv4 and
+ IPv6 addresses instead of only the used address family. Fixed,
+ thereby no longer requiring exact specification of
+ smtp_bind_address(6) in this case.
+ File: smtp/smtp_connect.c
+
+ Bugfix: The QMQP sink server did not compile correctly. This
+ program, part of smtpstone tools, is not compiled or installed
+ by default.
+ File: smtpstone/qmqp-sink.c
+
+ Bugfix: NI_WITHSCOPEID was not correctly defined everywhere,
+ which could result in EAI_BADFLAGS. Changed location of
+ definition to correct it.
+ Files: util/sys_defs.h, util/inet_addr_list.h
+
+Version 1.18b Postfix snapshot 2.0.16-20030921
+
+ IPv6 support: Added IPv6-enabled code to the new snapshot
+ check_*_{ns,mx}_access restrictions.
+ File: smtpd/smtpd_check.c
+
+Version 1.18a Postfix release 2.0.16
+
+ Update (TLS patches): Updated Lutz Jaenicke's TLS patch to
+ version 0.8.16. See pfixtls/ChangeLog for details.
+ Diff contributed by Tuomo Soini.
+
+ The TLS+IPv6 patch now contains the original TLS patch
+ documentation from Lutz Jaenicke.
+
+Version 1.18 Postfix releases 2.0.14 - 2.0.15
+ Postfix snapshot 2.0.14-20030812
+
+ Bugfix: Perform actual hostname verification in the SMTP
+ and QMTP servers. This was never supported in the IPv6
+ patch. Reported by Wolfgang S. Rupprecht.
+ Files: smtpd/smtpd_peer.c, qmqpd/qmqpd_peer.c
+
+ IPv6 address ranges using address/prefixlength (e.g. in
+ mynetworks and access maps) should be written as
+ [ipv6:addr:ess]/plen (e.g. [fec0:10:20::]/48). The old
+ supported syntax, [ipv6:addr:ess/plen] is deprecated and
+ support will be removed in a later version.
+ Thanks to Dr. Peter Bieringer and Pekka Savola for discussion.
+ Files: util/match_ops.c, global/mynetworks.c
+
+ Explicitly prefer IPv6 over IPv4 addresses when delivering
+ to a host when MX lookups are disabled when SMTP address
+ randomization is on (default).
+ File: smtp/smtp_addr.c
+
+ Compliance: write IPv6 address literals in mail headers
+ as [IPv6:addr] instead of [addr] as per RFC 2821:4.1.3
+ tagging requirement, for example [IPv6:fec0:10:20::1].
+ Pointed out by Dr. Peter Bieringer.
+ Files: smtpd/smtpd{,_peer,_state}.c, smtpd/smtpd.h
+
+Version 1.17 Postfix release 2.0.13, 2.0.14
+ Postfix snapshot 2.0.13-20030706, 2.0.14-20030812
+
+ Bugfix: Two memory allocation/deallocation bugs were
+ introduced in patch 1.16. The impact of these bugs could
+ be 'arbitrary' memory corruption.
+ File: util/match_ops.c
+
+Version 1.16 Postfix release 2.0.13
+ Postfix snapshot 2.0.13-20030706
+
+ Cleanup: rewrote match_ops.c. This rewrite is partly based on
+ patch by Takahiro Igarashi. The rewrite enables some better
+ handling of scoped addresses, and drops all GPL code from the
+ patch, easying license considerations. Also, allowed for
+ use of this code by the CIDR maps.
+ Files: util/match_ops.[ch]
+
+ Bugfix: correctly relay for scoped unicast addresses when
+ applicable. Until now, while Postfix was able to recognize
+ scoped addresses, it was not able to see e.g. fe80::10%fxp0
+ as local in mynetworks validation. KAME-only code.
+ (I've never heard of people using scoped addresses (think
+ link-local addresses) for mail relaying though...)
+ Files: util/inet_addr_list.[ch]
+
+ Feature (snapshot only): rewrote CIDR maps code to support
+ IPv6 addresses, using new match_ops code. Allow the use
+ of [::/0] since it allows one to easily disable further
+ checks for IPv6 addresses.
+ File: util/dict_cidr.c
+
+ Consistency: require IPv6 addresses in inet_interfaces to
+ be enclosed in square brackets.
+ File: util/inet_addr_host.c
+
+ Bugfix: (Linux2-only) A #define was misspelled. This could
+ lead to Postfix being unable to read the system's local IPv6
+ addresses (e.g. when using inet_interfaces).
+ Spotted by Jochen Friedrich.
+ File: util/sys_defs.h
+
+ Cleanup: require non-null host portion in CIDR /
+ prefixlength notations for IPv6 (was IPv4-only).
+
+Version 1.15a Postfix release 2.0.13
+
+ Update (TLS patches): Updated Lutz Jaenicke's TLS patch
+ to version 0.8.15. This version introduces new options
+ for managing SASL mechanisms. More information at:
+ http://www.aet.tu-cottbus.de/personen/jaenicke/pfixtls/
+ Diff contributed by Tuomo Soini.
+
+Version 1.15 Postfix release 2.0.12, 2.0.13
+ Postfix snapshot 2.0.12-20030621
+
+ Bugfix (TLS-snapshots only): a change in Postfix snapshot
+ 2.0.11-20030609 broke initialisation of TLS in smtpd,
+ causing TLS to both be unadvertised and unaccepted.
+ This was fixed again by reordering initialisation.
+ File: smtpd/smtpd.c
+
+ Update (TLS patches): Updated Lutz Jaenicke's TLS patch
+ to version 0.8.14. This version introduces a few fixes and
+ uses USE_SSL instead of HAS_SSL. More information at:
+ http://www.aet.tu-cottbus.de/personen/jaenicke/pfixtls/
+ Diff contributed by Tuomo Soini.
+
+ Bugfix (Postfix releases only - this was already added to
+ the snapshots in patch 1.14). KAME derived systems only.
+ Correctly decode scoped addresses, including network
+ interface specifiers.
+ File: util/inet_addr_local.c
+
+Version 1.14 Postfix releases 2.0.9, 2.0.10, 2.0.11, 2.0.12
+ Postfix snapshots 2.0.9-20030424, 2.0.10-20030521,
+ 2.0.11-20030609, 2.0.12-20030611
+
+ Patch change: made the patch available as an IPv6-only
+ patch (i.e., without the TLS code). This on popular
+ request by users and packagers.
+ A TLS+IPv6 version is still available of course.
+
+ Bugfix: correctly decode scoped addresses from now on
+ (KAME derived systems only). I think the original code
+ was written by Itojun, so I'm rather puzzled that it
+ didn't work...
+ File: util/inet_addr_local.c
+
+ Bugfix/portability: Recent KAME snapshots return both
+ TCP and SCTP address information on getaddrinfo() if
+ no protocol was specified. This causes the socket counts
+ to be wrong, confusing child processes.
+ Merged patch by JINMEI Tatuya of KAME to fix this.
+ Files: master/master.h, master/master_{ent,conf}.[ch],
+ util/inet_listen.c
+
+ Documentation: added an IPV6_README file to the patch.
+ This file contains the primary documentation. Also,
+ added a sample-ipv6.cf to describe the (currently few)
+ IPv6 related main.cf parameters.
+
+ Bugfix: the netmask structures for the *unsupported*
+ platforms (boldly assume /64) were added to the wrong
+ list (addresses instead of masks). This bug did not affect
+ any supported platform though.
+ File: util/inet_addr_local.c
+
+ Portability: added support for HP/Compaq Tru64Unix V5.1
+ and later. (compiled with CompaqCC only).
+ Thanks to Sten Spans for providing root access to an
+ IPv6-connected Tru64 testing machine.
+
+Version 1.13 Postfix releases 2.0.4 - 2.0.9
+ Postfix snapshots 2.0.3-20030126 - 2.0.7-20030319
+
+ Bugfix: Due to a missing storage pointer, DNS lookup
+ results in the permit_mx_backups code were not processed,
+ and smtpd would likely crash.
+ Thanks to Wouter de Jong for reporting the crashes.
+ File: smtpd/smtpd_check.c
+
+ Incompatible change: The addresses given to the parameters
+ smtp_bind_address6 and lmtp_bind_address6 now need to be
+ enclosed in square brackets for consistency.
+ Files: [ls]mtp/[ls]mtp_connect.c
+
+Version 1.12 Postfix releases 2.0.2, 2.0.3
+ Postfix snapshots 2.0.2-20030115, 2.0.3-20030126
+
+ Bugfix/workaround (Solaris): A simplified comparison
+ function for Solaris' qsort() function, would result
+ in corruption of network addresses in the SMTP client.
+ Fixed. Reported with possible fix by Edvard Tuinder.
+ File: smtp/smtp_addr.c
+
+Version 1.11 Postfix releases 2.0.0.x, 2.0.1, 2.0.2
+ Postfix snapshots 2.0.0-20030105, 2.0.1-20030112
+ 2.0.2-20030115
+
+ Bugfix (Solaris): Properly initialize lifconf structure
+ when requesting host interface addresses. If you get
+ warnings about SIOCGLIFCONF with earlier versions,
+ please upgrade.
+ File: util/inet_addr_local.c
+
+ Patch fix: fixed compilation errors in case the patch is
+ applied but built without IPv6 support (i.e., on unsupported
+ platforms).
+
+Version 1.10 Postfix snapshots 1.1.12-200212{19,21}
+ Postfix releases 2.0.0, 2.0.0.{1,2}
+ Postfix snapshots 2.0.0-20021223 - 2.0.0-20030101
+
+ 'Bugfix': don't show spurious warnings on Linux systems
+ about missing /proc/net/if_inet6 unless verbose mode
+ is enabled.
+ File: util/inet_addr_local.c
+
+ Bugfix: If unable to create a socket for a specific adress
+ in the SMTP client (e.g., when trying to create an IPv6
+ connection while the local host has no configured IPv6
+ addresses), then stop the attempt.
+ File: smtp/smtp_connect.c
+
+ Small bugfix: never query DNS for .
+ This syntax now correctly generates an error immediately.
+ File: global/resolve_local.c
+
+ Updated TLS patch to 0.8.12-1.1.12-20021219-0.9.6h, fixing
+ a bug with "sendmail -bs".
+
+Version 1.9 Postfix version 1.1.11-20021115
+ Postfix version 1.1.12-2002{1124,1209-1213}
+
+ Bugfix: with getifaddrs() code (*BSD, linux-USAGI), IPv4
+ netmasks were set to /32 effectively. Work around broken
+ netmask data structures (*BSD only perhaps).
+
+ Bugfix: same data corruption in another place created
+ entirely wrong IPv4 netmasks. Work around broken
+ SIOCGIFNETMASK structure.
+
+ New code was added for correct IPv6 netmasks. The original
+ code did not contain IPv6 netmask support at all!
+ For Solaris, use SIOCGLIF*; Linux: /proc/net/if_inet6.
+ Getifaddrs() support is used otherwise. This should cover
+ all supported systems. Other systems also work, prefix
+ length is always set to /64 then.
+
+ Since there are no classes (context: Class A, class B etc
+ networks) with IPv6, default to IPv6 subnet style if the
+ mynetworks style is 'class'. I recommend against this style
+ anyway.
+
+ Added support to display IPv6 nets mynetworks output.
+
+Version 1.8 Postfix version 1.1.11-200211{01,15}
+
+ An earlier author of the patch made a typo in the GAI_STRERROR()
+ macro, resulting in bogus error messages when checking for
+ PTR records. Fixed.
+
+ IPv4-mapped addresses in the smtpd are converted to true IPv4
+ addresses just after the connection has been made. This means
+ that all IPv4-mapped addresses are now logged as true IPv4
+ addresses. Hence beside RBL checks, also access maps now treat
+ IPv4-mapped addresses as native IPv4. Note that ::ffff:...
+ entries in your access tables will no longer work.
+
+ You can now specify IPv6 'parent' networks in your access maps,
+ e.g. to reject all mail from 3ffe:200:... nodes, add the line
+ 3ffe:200 REJECT
+ Use of trailing colons is discouraged because postmap will
+ warn about it possibly being an alias...
+ NOTE: I'll soon obsolete this again in favor of the more
+ common address/len notation. This was just so trivial to add
+ that it didn't hurt and I needed it :)
+
+ For easy reference, the version of the TLS/IPv6 patch can be
+ dynamically queried using the tls_ipv6_version variable.
+ This gives the short version (like, "1.8").
+
+ The service bind address for 'inet' sockets in master.cf (e.g.,
+ smtpd), must be enclosed in square brackets '[..]' for IPv6
+ addresses. The old style (without brackets) still works but is
+ unsupported and may be removed in the future. Example
+ [::1]:smtp inet n - n - - smtpd
+
+Version 1.7 Postfix version 1.1.11-20021029 - 1.1.11-20021101
+
+ Postfix' SMTP client performs randomization of MX addresses
+ when sending mail. This however could result in A records
+ being used before AAAA records. This has been corrected.
+
+ Note that from Postfix version 1.1.11-20021029 on, there is
+ a proxy_interfaces parameter. This has of course not been
+ ported to IPv6 addresses...
+
+Version 1.6 Postfix version 1.1.11-20020928
+
+ Added IPv6 support for backup_mx_networks feature; also the
+ behaviour when DNS lookups fail when checking whether the
+ local host is an MX for a domain conforms to the IPv4 case:
+ defer rather than allow.
+
+Version 1.5 Postfix version 1.1.11-20020917
+
+ I introduced two bugs when I rewrote my older LMTP IPv6 patch.
+ These bugs effectively rendered LMTP useless. Now fixed.
+ Bugs spotted by Kaj Niemi.
+
+ Now supports Solaris 8 and 9. Due to lack of testing equipment,
+ this has been only tested in production on Solaris 9, both
+ with gcc and the Sun Workshop Compiler.
+
+Version 1.4 Postfix version 1.1.11-20020822 - 1.1.11-20020917
+
+ OpenBSD (>=200003) and FreeBSD release 4 and up now use
+ getifaddrs(). This makes for cleaner code. The old code
+ seems to be bug-ridden anyway.
+
+ Got rid of some compiler warnings. Should be cleaner on
+ Alpha as well now. Thanks to Sten Spans for providing me
+ access to an Alpha running FreeBSD4.
+
+ Fixed an old bug in smtpd memory alloation if you compiled
+ without IPv6 support (the wrong buffer size was used. This
+ was harmless for IPv6-enabled compiles since the sizes were
+ equal then).
+
+ Added ChangeLog to the patch (as IPv6-ChangeLog) (this
+ was absent in 1.3 contrary to docs).
+
+Version 1.3 Postfix version 1.1.11-20020613 - 1.1.11-20020718
+
+ FYI: In postfix version 1.1.11-20020718, DNS lookups for
+ AAAA can be done natively. The code matches the code in
+ the patch (though the #ifdef changed from INET6 to T_AAAA).
+ This change causes the patch for 1.1.11-20020718 to be a
+ bit smaller.
+
+Version 1.2 Postfix version 1.1.11-20020613
+
+ Added IPv6 support for the LMTP client.
+
+ Added lmtp_bind_address and lmtp_bind_address6 parameters,
+ similar to those for smtp.
+
+ Added IPv6 support for the QMQP server.
+
+Version 1.1 Postfix version 1.1.11-20020602 - 1.1.11-20020613
+
+ Added parameter smtp_bind_address6. By using this parameter,
+ it is possible to bind to an IPv6 address, independently of
+ IPv4 address binding.
+
+ Lutz fixed a bug in his TLS patch regarding SASL. Incorporated.
+
+Version 1.0.x Postfix version 1.1.8-20020505 - 1.1.11-20020602
+
+ Patch derived from PLD's IPv6 patch for Postfix, revision 1.10
+ which applied to early Postfix snapshots 1.1.x. Updated this
+ patch to apply to 1.1.8-20020505.
+
+ Added compile-time checks for SS_LEN. Some Linux installations,
+ and maybe other systems, do define SA_LEN, but not SS_LEN.
+
+ Several updates of postfix snapshots.
+
diff --git a/postfix/Makefile.in b/postfix/Makefile.in
index a4b9e964e..e2a772976 100644
--- a/postfix/Makefile.in
+++ b/postfix/Makefile.in
@@ -13,14 +13,14 @@ MANDIRS = proto man html
default: update
makefiles Makefiles:
+ (echo "# Do not edit -- this file documents how Postfix was built for your machine."; $(SHELL) makedefs) >makedefs.tmp
+ set +e; if cmp makedefs.tmp conf/makedefs.out; then rm makedefs.tmp; \
+ else mv makedefs.tmp conf/makedefs.out; fi >/dev/null 2>/dev/null
set -e; for i in $(DIRS); do \
(set -e; echo "[$$i]"; cd $$i; rm -f Makefile; \
$(MAKE) -f Makefile.in Makefile MAKELEVEL=) || exit 1; \
done;
- rm -f Makefile; (set -e; $(SHELL) makedefs && cat Makefile.in) >Makefile
- (echo "# Do not edit -- this file documents how Postfix was built for your machine."; $(SHELL) makedefs) >makedefs.tmp
- set +e; if cmp makedefs.tmp conf/makedefs.out; then rm makedefs.tmp; \
- else mv makedefs.tmp conf/makedefs.out; fi >/dev/null 2>/dev/null
+ rm -f Makefile; (tail +2 conf/makedefs.out; cat Makefile.in) >Makefile
update printfck tests:
set -e; for i in $(DIRS); do \
diff --git a/postfix/README_FILES/AAAREADME b/postfix/README_FILES/AAAREADME
index 1496a490d..c2d8e4263 100644
--- a/postfix/README_FILES/AAAREADME
+++ b/postfix/README_FILES/AAAREADME
@@ -8,6 +8,7 @@ GGeenneerraall ccoonnffiigguurraattiioonn
* ADDRESS_REWRITING_README: Address rewriting
* VIRTUAL_README: Virtual domain hosting
* SASL_README: SASL Authentication
+ * IPV6_README: IP Version 6 Support
* INSTALL: Installation from source code
PPrroobblleemm ssoollvviinngg
diff --git a/postfix/README_FILES/FILTER_README b/postfix/README_FILES/FILTER_README
index 62efdb70f..ed4a84dc0 100644
--- a/postfix/README_FILES/FILTER_README
+++ b/postfix/README_FILES/FILTER_README
@@ -473,7 +473,7 @@ server IP addresses in master.cf:
# (yes) (yes) (yes) (never) (100)
# =================================================================
1.2.3.5:smtp inet n - n - - smtpd
- -o content_filter=foo:bar
+ -o content_filter=filter-service:filter-destination
-o receive_override_options=no_address_mappings
After this, you can follow the same procedure as outlined in the "advanced" or
@@ -492,14 +492,14 @@ content filter service.
# service type private unpriv chroot wakeup maxproc command
# (yes) (yes) (yes) (never) (100)
# =================================================================
- # SMTP service for domains that are content filtered with foo:bar
+ # SMTP service for domains that are filtered with service1:dest1
1.2.3.4:smtp inet n - n - - smtpd
- -o content_filter=foo:bar
+ -o content_filter=service1:dest1
-o receive_override_options=no_address_mappings
- # SMTP service for domains that are content filtered with xxx:yyy
+ # SMTP service for domains that are filtered with service2:dest2
1.2.3.5:smtp inet n - n - - smtpd
- -o content_filter=xxx:yyy
+ -o content_filter=service2:dest2
-o receive_override_options=no_address_mappings
After this, you can follow the same procedure as outlined in the "advanced" or
diff --git a/postfix/README_FILES/IPV6_README b/postfix/README_FILES/IPV6_README
new file mode 100644
index 000000000..ee03468f9
--- /dev/null
+++ b/postfix/README_FILES/IPV6_README
@@ -0,0 +1,250 @@
+PPoossttffiixx IIPPvv66 SSuuppppoorrtt
+
+-------------------------------------------------------------------------------
+
+IInnttrroodduuccttiioonn
+
+Postfix 2.2 introduces support for the IPv6 (IP version 6) protocol, whose main
+feature of interest is that it uses 128-bit IP addresses instead of the 32-bit
+addresses used by IPv4.
+
+With this, Postfix can use the same SMTP protocol over IPv6 as it already uses
+over the older IPv4 network, and Postfix can do AAAA record lookups in the DNS
+in addition to the older A records. Information about IPv6 can be found at
+http://www.ipv6.org/.
+
+This document provides information on the following topics:
+
+ * Supported platforms
+ * Configuration
+ * Known limitations
+ * Compatibility with Postfix <2.2 IPv6 support
+ * IPv6 Support for unsupported platforms
+ * Credits
+
+SSuuppppoorrtteedd PPllaattffoorrmmss
+
+Postfix version 2.2 supports IPv4 and IPv6 on the following platforms:
+
+ * AIX 5.1+
+ * Darwin 7.3+
+ * FreeBSD 4+
+ * Linux 2.4+
+ * NetBSD 1.5+
+ * OpenBSD 2+
+ * Solaris 8+
+ * Tru64Unix V5.1+
+
+On other platforms Postfix will simply use IPv4 as it has always done.
+
+See below for tips how to port Postfix IPv6 support to other environments.
+
+CCoonnffiigguurraattiioonn
+
+Postfix IPv6 support introduces two new main.cf configuration parameters, and
+introduces an important change in address syntax notation in match lists such
+as mynetworks or debug_peer_list.
+
+Postfix IPv6 address syntax is a little tricky, because there are a few places
+where you must enclose IPv6 address inside [] characters, and a few places
+where you must not. It is a good idea to use [] only in the few places where
+you have to. Check out the postconf(5) manual whenever you do IPv6 related
+configuration work with Postfix.
+
+ * The new inet_protocols parameter specifies what IP protocols Postfix will
+ use. This parameter also controls what DNS lookups Postfix will do.
+
+ /etc/postfix/main.cf:
+ # You must stop/start Postfix after changing this parameter.
+ inet_protocols = ipv4 (DEFAULT: enable IPv4 only)
+ inet_protocols = all (enable both IPv4 and IPv6)
+ inet_protocols = ipv4, ipv6 (enable both IPv4 and IPv6)
+ inet_protocols = ipv6 (enable IPv6 only)
+
+ By default, Postfix uses IPv4 only, because most systems aren't attached to
+ an IPv6 network.
+
+ o On systems with combined IPv4/IPv6 stacks, attempts to deliver mail via
+ IPv6 would always fail with "network unreachable", and those attempts
+ would only slow down Postfix.
+
+ o Linux kernels don't even load IPv6 protocol support by default. Any
+ attempt to use it would fail immediately.
+
+ Note 1: you must stop and start Postfix after changing the inet_protocols
+ configuration parameter.
+
+ Note 2: if you see error messages like the following, then you're running
+ Linux and need to turn on IPv6 in the kernel: see http://www.ipv6.org/ for
+ hints and tips. Unlike other systems, Linux does not have a combined stack
+ for IPv4 and IPv6, and IPv6 protocol support is not loaded by default.
+
+ postconf: warning: inet_protocols: IPv6 support is disabled: Address
+ family not supported by protocol
+ postconf: warning: inet_protocols: configuring for IPv4 support only
+
+ Note 3: on older Linux and Solaris systems, the setting "inet_protocols =
+ ipv6" will not prevent Postfix from accepting IPv4 connections. Postfix
+ will present the client IP addresses in IPv6 format, though. In all other
+ cases, Postfix always presents IPv4 client IP addresses in the traditional
+ dotted quad IPv4 format.
+
+ * The other new parameter is smtp_bind_address6. This sets the local
+ interface address for outgoing IPv6 SMTP connections, just like the
+ smtp_bind_address parameter does for IPv4:
+
+ /etc/postfix/main.cf:
+ smtp_bind_address6 = 2001:240:5c7:0:250:56ff:fe89:1
+
+ * If you left the value of the mynetworks parameter at its default (i.e. no
+ mynetworks setting in main.cf) Postfix will figure out by itself what its
+ network addresses are. This is what a typical setting looks like:
+
+ % postconf mynetworks
+ mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [fe80::]/10 [2001:
+ 240:5c7::]/64
+
+ If you did specify the mynetworks parameter value in main.cf, you need
+ update the mynetworks value to include the IPv6 networks the system is in.
+ Be sure to specify IPv6 address information inside [], like this:
+
+ /etc/postfix/main.cf:
+ mynetworks = ...IPv4 networks... [::1]/128 [2001:240:5c7::]/64 ...
+
+NNOOTTEE:: wwhheenn ccoonnffiigguurriinngg PPoossttffiixx mmaattcchh lliissttss ssuucchh aass mmyynneettwwoorrkkss oorr
+ddeebbuugg__ppeeeerr__lliisstt,, yyoouu mmuusstt ssppeecciiffyy IIPPvv66 aaddddrreessss iinnffoorrmmaattiioonn iinnssiiddee [[]] iinn tthhee
+mmaaiinn..ccff ppaarraammeetteerr vvaalluuee aanndd iinn ffiilleess ssppeecciiffiieedd wwiitthh aa ""//ffiillee//nnaammee"" ppaatttteerrnn..
+IIPPvv66 aaddddrreesssseess ccoonnttaaiinn tthhee ""::"" cchhaarraacctteerr,, aanndd wwoouulldd ootthheerrwwiissee bbee ccoonnffuusseedd wwiitthh
+aa ""ttyyppee::ttaabbllee"" ppaatttteerrnn..
+
+KKnnoowwnn LLiimmiittaattiioonnss
+
+ * The order of IPv6/IPv4 outgoing connection attempts is not yet
+ configurable. Currently, IPv6 is tried before IPv4.
+
+ * Postfix currently does not support DNSBL (real-time blackhole list) lookups
+ for IPv6 client IP addresses; currently there are no blacklists that cover
+ the IPv6 address space.
+
+ * IPv6 does not have class A, B, C, etc. networks. With IPv6 networks, the
+ setting "mynetworks_style = class" has the same effect as the setting
+ "mynetworks_style = subnet".
+
+ * On Tru64Unix, Postfix can't figure out the local subnet mask and always
+ assumes a /128 network. This is a problem only with "mynetworks_style =
+ subnet" and no explicit mynetworks setting in main.cf.
+
+CCoommppaattiibbiilliittyy wwiitthh PPoossttffiixx <<22..22 IIPPvv66 ssuuppppoorrtt
+
+Postfix version 2.2 IPv6 support is based on the Postfix/IPv6 patch by Dean
+Strik and others, but differs in a few minor ways.
+
+ * main.cf: The inet_interfaces parameter does not support the notation "ipv6:
+ all" or "ipv4:all". Use the inet_protocols parameter instead.
+
+ * main.cf: Specify "inet_protocols = all" or "inet_protocols = ipv4, ipv6" in
+ order to enable both IPv4 and IPv6 support.
+
+ * main.cf: The inet_protocols parameter also controls what DNS lookups
+ Postfix will attempt to make when delivering or receiving mail.
+
+ * main.cf: Specify "inet_interfaces = loopback-only" to listen on loopback
+ network interfaces only.
+
+ * The lmtp_bind_address and lmtp_bind_address6 features were omitted. The
+ Postfix LMTP client will be absorbed into the SMTP client, so there is no
+ reason to keep adding features to the LMTP client.
+
+ * The SMTP server now requires that IPv6 addresses in SMTP commands are
+ specified as [ipv6:ipv6address], as described in RFC 2821.
+
+ * The IPv6 network address matching code was rewritten from the ground up,
+ and is expected to be closer to the specification. The result may be
+ incompatible with the Postfix/IPv6 patch.
+
+IIPPvv66 SSuuppppoorrtt ffoorr uunnssuuppppoorrtteedd ppllaattffoorrmmss
+
+Getting Postfix IPv6 working on other platforms involves the following steps:
+
+ * Specify how Postfix should find the local network interfaces. Postfix needs
+ this information to avoid mailer loops and to find out if mail for user@
+ [ipaddress] is a local or remote destination.
+
+ If your system has the getifaddrs() routine then add the following to your
+ platform-specific section in src/util/sys_defs.h:
+
+ #ifndef NO_IPV6
+ # define HAS_IPV6
+ # define HAVE_GETIFADDRS
+ #endif
+
+ Otherwise, if your system has the SIOCGLIF ioctl() command in /usr/include/
+ */*.h, add the following to your platform-specific section in src/util/
+ sys_defs.h:
+
+ #ifndef NO_IPV6
+ # define HAS_IPV6
+ # define HAS_SIOCGLIF
+ #endif
+
+ Otherwise, Postfix will have to use the old SIOCGIF commands and get along
+ with reduced IPv6 functionality (it won't be able to figure out your IPv6
+ netmasks, which are needed for "mynetworks_style = subnet". Add this to
+ your platform-specific section in src/util/sys_defs.h:
+
+ #ifndef NO_IPV6
+ # define HAS_IPV6
+ #endif
+
+ * Test if Postfix can figure out its interface information.
+
+ After compiling Postfix in the usual manner, step into the src/util
+ directory and type "make inet_addr_local". Running this file by hand should
+ produce all the interface addresses and network masks, for example:
+
+ % make
+ % cd src/util
+ % make inet_addr_local
+ [... some messages ...]
+ % ./inet_addr_local
+ [... some messages ...]
+ ./inet_addr_local: inet_addr_local: configured 2 IPv4 addresses
+ ./inet_addr_local: inet_addr_local: configured 4 IPv6 addresses
+ 168.100.189.2/255.255.255.224
+ 127.0.0.1/255.0.0.0
+ fe80:1::2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+ 2001:240:5c7:0:2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+ fe80:5::1/ffff:ffff:ffff:ffff::
+ ::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+
+ The above is for an old FreeBSD machine. Other systems produce slightly
+ different results, but you get the idea.
+
+If none of all this produces a usable result, send email to the postfix-
+users@postfix.org mailing list and we'll try to help you through this.
+
+CCrreeddiittss
+
+The following information is in part based on information that was compiled by
+Dean Strik.
+
+ * Mark Huizer wrote the original Postfix IPv6 patch.
+
+ * Jun-ichiro 'itojun' Hagino of the KAME project made substantial
+ improvements. Since then, we speak of the KAME patch.
+
+ * The PLD Linux Distribution ported the code to other stacks (notably USAGI).
+ We speak of the PLD patch. A very important feature of the PLD patch was
+ that it can work with Lutz Jaenicke's TLS patch for Postfix.
+
+ * Dean Strik extended IPv6 support to platforms other than KAME and USAGI,
+ updated the patch to keep up with Postfix development, and provided a
+ combined IPv6 + TLS patch. Information about his effort can be found on
+ Dean Strik's Postfix website at http://www.ipnet6.org/postfix/.
+
+ * Wietse Venema took Dean Strik's IPv6 patch, merged it into Postfix 2.2, and
+ took the opportunity to eliminate all IPv4-specific code from Postfix that
+ could be removed. For systems without IPv6 support in the kernel and system
+ libraries, Postfix has a simple compatibility layer, so that it will use
+ IPv4 as before.
+
diff --git a/postfix/README_FILES/SMTPD_POLICY_README b/postfix/README_FILES/SMTPD_POLICY_README
index 34ef8ba2c..2b1b4561f 100644
--- a/postfix/README_FILES/SMTPD_POLICY_README
+++ b/postfix/README_FILES/SMTPD_POLICY_README
@@ -69,6 +69,9 @@ Notes:
* When an attribute value is unavailable, the client either does not send the
attribute, or sends the attribute with an empty value ("name=").
+ * The client address is an IPv4 dotted quad in the form 1.2.3.4 or it is an
+ IPv6 address in the form 1:2:3::4:5:6.
+
* An attribute name must not contain "=", null or newline, and an attribute
value must not contain null or newline.
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index aa1c54149..bc4123a1f 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -7,6 +7,54 @@ snapshot release). Patches are issued for the official release
and change the patchlevel and the release date. Patches are never
issued for snapshot releases.
+Incompatible changes with snapshot Postfix-2.2-20050117
+=======================================================
+
+Only the deferred and defer queue directories are hashed by default,
+instead of eight queue directories. With modern file systems, this
+speeds up Postfix boot time without compromising performance under
+high load too much. Hashing is now turned on only for the defer and
+deferred queue directories, because those contain lots of mail when
+undeliverable mail is backing up.
+
+In order to speed up start-up, some Postfix file permission checks
+are run in the background after Postfix is started.
+
+The SMTP server now requires that IPv6 addresses in SMTP commands
+are specified as [ipv6:ipv6address], as described in RFC 2821.
+
+Incompatible changes with snapshot Postfix-2.2-20050111+IPV6
+============================================================
+
+Postfix version 2.2 IP version 6 support is based on the Postfix/IPv6
+patch by Dean Strik, but differs in a few minor ways.
+
+- Network protocol support including DNS lookup is selected with
+the inet_protocols parameter instead of the inet_interfaces parameter.
+This is needed so that Postfix will not attempt to deliver mail
+via IPv6 when the system has no IPv6 connectivity.
+
+- The lmtp_bind_address6 feature was omitted. The Postfix LMTP
+client will be absorbed into the SMTP client, so there is no reason
+to keep adding features to the LMTP client.
+
+- The cidr-based address matching code was rewritten. The new
+behavior is believed to be closer to expectation. The results may
+be incompatible with that of the Postfix/IPv6 patch.
+
+Major changes with snapshot Postfix-2.2-20050111+IPV6
+=====================================================
+
+Postfix version 2.2 IP version 6 support based on the Postfix/IPv6
+patch by Dean Strik and others. IP version 6 support is selected
+in main.cf; it is not selected at compile time as with TLS or SASL.
+
+IP version 6 support is always compiled into Postfix on systems
+that have Postfix compatible IP version 6 support. On other systems
+Postfix will simply use IP version 4 just like it did before. See
+the IPV6_README document for what systems are supported, and how
+to turn on IPv6 in main.cf.
+
Major changes with snapshot Postfix-2.2-20041218
================================================
diff --git a/postfix/conf/access b/postfix/conf/access
index dd10ffd97..48f5532ef 100644
--- a/postfix/conf/access
+++ b/postfix/conf/access
@@ -14,7 +14,7 @@
# The optional access table directs the Postfix SMTP server
# to selectively reject or accept mail. Access can be
# allowed or denied for specific host names, domain names,
-# networks, host network addresses or mail addresses.
+# networks, host addresses or mail addresses.
#
# For an example, see the EXAMPLE section at the end of this
# manual page.
@@ -110,39 +110,79 @@
#
# net.work
#
-# net Matches any host address in the specified network.
-# A network address is a sequence of one or more
-# octets separated by ".".
+# net Matches the specified IPv4 host address or subnet-
+# work. An IPv4 host address is a sequence of four
+# decimal octets separated by ".".
#
-# NOTE: use the cidr lookup table type to specify
+# Subnetworks are matched by repeatedly truncating
+# the last ".octet" from the remote IPv4 host address
+# string until a match is found in the access table,
+# or until further truncation is not possible.
+#
+# NOTE 1: The information in the access map should be
+# in canonical form, with unnecessary null characters
+# eliminated. Address information must not be
+# enclosed with "[]" characters.
+#
+# NOTE 2: use the cidr lookup table type to specify
# network/netmask patterns. See cidr_table(5) for
# details.
#
+# net:work:addr:ess
+#
+# net:work:addr
+#
+# net:work
+#
+# net Matches the specified IPv6 host address or subnet-
+# work. An IPv6 host address is a sequence of three
+# to eight hexadecimal octet pairs separated by ":".
+#
+# Subnetworks are matched by repeatedly truncating
+# the last ":octetpair" from the remote IPv6 host
+# address string until a match is found in the access
+# table, or until further truncation is not possible.
+#
+# NOTE 1: the truncation and comparison are done with
+# the string representation of the IPv6 host address.
+# Thus, not all the ":" subnetworks will be tried.
+#
+# NOTE 2: The information in the access map should be
+# in canonical form, with unnecessary null characters
+# eliminated. Address information must not be
+# enclosed with "[]" characters.
+#
+# NOTE 3: use the cidr lookup table type to specify
+# network/netmask patterns. See cidr_table(5) for
+# details.
+#
+# IPv6 support is available in Postfix 2.2 and later.
+#
# ACCEPT ACTIONS
# OK Accept the address etc. that matches the pattern.
#
# all-numerical
# An all-numerical result is treated as OK. This for-
-# mat is generated by address-based relay authoriza-
+# mat is generated by address-based relay authoriza-
# tion schemes.
#
# REJECT ACTIONS
# 4NN text
#
# 5NN text
-# Reject the address etc. that matches the pattern,
+# Reject the address etc. that matches the pattern,
# and respond with the numerical three-digit code and
-# text. 4NN means "try again later", while 5NN means
+# text. 4NN means "try again later", while 5NN means
# "do not try again".
#
# REJECT optional text...
-# Reject the address etc. that matches the pattern.
-# Reply with $reject_code optional text... when the
-# optional text is specified, otherwise reply with a
+# Reject the address etc. that matches the pattern.
+# Reply with $reject_code optional text... when the
+# optional text is specified, otherwise reply with a
# generic error response message.
#
# DEFER_IF_REJECT optional text...
-# Defer the request if some later restriction would
+# Defer the request if some later restriction would
# result in a REJECT action. Reply with "450 optional
# text... when the optional text is specified, other-
# wise reply with a generic error response message.
@@ -150,10 +190,10 @@
# This feature is available in Postfix 2.1 and later.
#
# DEFER_IF_PERMIT optional text...
-# Defer the request if some later restriction would
-# result in a an explicit or implicit PERMIT action.
-# Reply with "450 optional text... when the optional
-# text is specified, otherwise reply with a generic
+# Defer the request if some later restriction would
+# result in a an explicit or implicit PERMIT action.
+# Reply with "450 optional text... when the optional
+# text is specified, otherwise reply with a generic
# error response message.
#
# This feature is available in Postfix 2.1 and later.
@@ -164,131 +204,131 @@
# reject_unauth_destination, and so on).
#
# DISCARD optional text...
-# Claim successful delivery and silently discard the
-# message. Log the optional text if specified, oth-
+# Claim successful delivery and silently discard the
+# message. Log the optional text if specified, oth-
# erwise log a generic message.
#
-# Note: this action currently affects all recipients
+# Note: this action currently affects all recipients
# of the message.
#
# This feature is available in Postfix 2.0 and later.
#
-# DUNNO Pretend that the lookup key was not found. This
-# prevents Postfix from trying substrings of the
-# lookup key (such as a subdomain name, or a network
+# DUNNO Pretend that the lookup key was not found. This
+# prevents Postfix from trying substrings of the
+# lookup key (such as a subdomain name, or a network
# address subnetwork).
#
# This feature is available in Postfix 2.0 and later.
#
# FILTER transport:destination
-# After the message is queued, send the entire mes-
+# After the message is queued, send the entire mes-
# sage through the specified external content filter.
-# The transport:destination syntax is described in
-# the transport(5) manual page. More information
-# about external content filters is in the Postfix
+# The transport:destination syntax is described in
+# the transport(5) manual page. More information
+# about external content filters is in the Postfix
# FILTER_README file.
#
-# Note: this action overrides the main.cf con-
+# Note: this action overrides the main.cf con-
# tent_filter setting, and currently affects all
# recipients of the message.
#
# This feature is available in Postfix 2.0 and later.
#
# HOLD optional text...
-# Place the message on the hold queue, where it will
-# sit until someone either deletes it or releases it
-# for delivery. Log the optional text if specified,
+# Place the message on the hold queue, where it will
+# sit until someone either deletes it or releases it
+# for delivery. Log the optional text if specified,
# otherwise log a generic message.
#
-# Mail that is placed on hold can be examined with
-# the postcat(1) command, and can be destroyed or
+# Mail that is placed on hold can be examined with
+# the postcat(1) command, and can be destroyed or
# released with the postsuper(1) command.
#
-# Note: use "postsuper -r" to release mail that was
-# kept on hold for a significant fraction of $maxi-
+# Note: use "postsuper -r" to release mail that was
+# kept on hold for a significant fraction of $maxi-
# mal_queue_lifetime or $bounce_queue_lifetime, or
# longer.
#
-# Note: this action currently affects all recipients
+# Note: this action currently affects all recipients
# of the message.
#
# This feature is available in Postfix 2.0 and later.
#
# PREPEND headername: headervalue
-# Prepend the specified message header to the mes-
+# Prepend the specified message header to the mes-
# sage. When this action is used multiple times, the
-# first prepended header appears before the second
+# first prepended header appears before the second
# etc. prepended header.
#
-# Note: this action does not support multi-line mes-
+# Note: this action does not support multi-line mes-
# sage headers.
#
# This feature is available in Postfix 2.1 and later.
#
# REDIRECT user@domain
-# After the message is queued, send the message to
+# After the message is queued, send the message to
# the specified address instead of the intended
# recipient(s).
#
-# Note: this action overrides the FILTER action, and
+# Note: this action overrides the FILTER action, and
# currently affects all recipients of the message.
#
# This feature is available in Postfix 2.1 and later.
#
# WARN optional text...
# Log a warning with the optional text, together with
-# client information and if available, with helo,
+# client information and if available, with helo,
# sender, recipient and protocol information.
#
# This feature is available in Postfix 2.1 and later.
#
# REGULAR EXPRESSION TABLES
-# This section describes how the table lookups change when
+# This section describes how the table lookups change when
# the table is given in the form of regular expressions. For
-# a description of regular expression lookup table syntax,
+# a description of regular expression lookup table syntax,
# see regexp_table(5) or pcre_table(5).
#
-# Each pattern is a regular expression that is applied to
+# Each pattern is a regular expression that is applied to
# the entire string being looked up. Depending on the appli-
-# cation, that string is an entire client hostname, an
+# cation, that string is an entire client hostname, an
# entire client IP address, or an entire mail address. Thus,
# no parent domain or parent network search is done,
-# user@domain mail addresses are not broken up into their
+# user@domain mail addresses are not broken up into their
# user@ and domain constituent parts, nor is user+foo broken
# up into user and foo.
#
-# Patterns are applied in the order as specified in the
-# table, until a pattern is found that matches the search
+# Patterns are applied in the order as specified in the
+# table, until a pattern is found that matches the search
# string.
#
-# Actions are the same as with indexed file lookups, with
-# the additional feature that parenthesized substrings from
+# Actions are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from
# the pattern can be interpolated as $1, $2 and so on.
#
# TCP-BASED TABLES
-# This section describes how the table lookups change when
+# This section describes how the table lookups change when
# lookups are directed to a TCP-based server. For a descrip-
-# tion of the TCP client/server lookup protocol, see
-# tcp_table(5). This feature is not available in Postfix
+# tion of the TCP client/server lookup protocol, see
+# tcp_table(5). This feature is not available in Postfix
# version 2.1.
#
-# Each lookup operation uses the entire query string once.
-# Depending on the application, that string is an entire
+# Each lookup operation uses the entire query string once.
+# Depending on the application, that string is an entire
# client hostname, an entire client IP address, or an entire
-# mail address. Thus, no parent domain or parent network
-# search is done, user@domain mail addresses are not broken
-# up into their user@ and domain constituent parts, nor is
+# mail address. Thus, no parent domain or parent network
+# search is done, user@domain mail addresses are not broken
+# up into their user@ and domain constituent parts, nor is
# user+foo broken up into user and foo.
#
# Actions are the same as with indexed file lookups.
#
# EXAMPLE
-# The following example uses an indexed file, so that the
-# order of table entries does not matter. The example per-
-# mits access by the client at address 1.2.3.4 but rejects
-# all other clients in 1.2.3.0/24. Instead of hash lookup
-# tables, some systems use dbm. Use the command "postconf
-# -m" to find out what lookup tables Postfix supports on
+# The following example uses an indexed file, so that the
+# order of table entries does not matter. The example per-
+# mits access by the client at address 1.2.3.4 but rejects
+# all other clients in 1.2.3.0/24. Instead of hash lookup
+# tables, some systems use dbm. Use the command "postconf
+# -m" to find out what lookup tables Postfix supports on
# your system.
#
# /etc/postfix/main.cf:
@@ -303,7 +343,7 @@
# editing the file.
#
# BUGS
-# The table format does not understand quoting conventions.
+# The table format does not understand quoting conventions.
#
# SEE ALSO
# postmap(1), Postfix lookup table manager
@@ -312,13 +352,13 @@
# transport(5), transport:nexthop syntax
#
# README FILES
-# Use "postconf readme_directory" or "postconf html_direc-
+# Use "postconf readme_directory" or "postconf html_direc-
# tory" to locate this information.
# SMTPD_ACCESS_README, built-in SMTP server access control
# DATABASE_README, Postfix lookup table overview
#
# LICENSE
-# The Secure Mailer license must be distributed with this
+# The Secure Mailer license must be distributed with this
# software.
#
# AUTHOR(S)
diff --git a/postfix/conf/post-install b/postfix/conf/post-install
index abb106e8a..8a2f65aa9 100644
--- a/postfix/conf/post-install
+++ b/postfix/conf/post-install
@@ -564,22 +564,13 @@ EOF
}
done
- # With 20000 active queue files, the active queue directory should
- # be hashed, and so should the other directories, because they
- # can contain even more mail.
- #
- # Unfortunately, this sucks mailq performance on unloaded systems.
- #
- # If you don't want slow mailq, be sure to hash defer and deferred,
- # because those two directories can contain lots of files.
+ # File systems have improved since Postfix came out, and all we
+ # require now is that defer and deferred are hashed because those
+ # can contain lots of files.
found=`$POSTCONF -c $config_directory -h hash_queue_names`
missing=
- (echo "$found" | grep active >/dev/null) || missing="$missing active"
- (echo "$found" | grep bounce >/dev/null) || missing="$missing bounce"
(echo "$found" | grep defer >/dev/null) || missing="$missing defer"
- (echo "$found" | grep flush >/dev/null) || missing="$missing flush"
- (echo "$found" | grep incoming>/dev/null)|| missing="$missing incoming"
(echo "$found" | grep deferred>/dev/null)|| missing="$missing deferred"
test -n "$missing" && {
echo fixing main.cf hash_queue_names for missing $missing
diff --git a/postfix/conf/postfix-files b/postfix/conf/postfix-files
index d477ba474..e7f1e5b84 100644
--- a/postfix/conf/postfix-files
+++ b/postfix/conf/postfix-files
@@ -186,6 +186,7 @@ $sample_directory/sample-compatibility.cf:f:root:-:644:o
$sample_directory/sample-debug.cf:f:root:-:644:o
$sample_directory/sample-filter.cf:f:root:-:644:o:o
$sample_directory/sample-flush.cf:f:root:-:644:o
+$sample_directory/sample-ipv6.cf:f:root:-:644:o
$sample_directory/sample-ldap.cf:f:root:-:644:o
$sample_directory/sample-lmtp.cf:f:root:-:644:o
$sample_directory/sample-local.cf:f:root:-:644:o
@@ -224,6 +225,7 @@ $readme_directory/ETRN_README:f:root:-:644
$readme_directory/FILTER_README:f:root:-:644
$readme_directory/HOSTING_README:f:root:-:644:o
$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/LMTP_README:f:root:-:644
@@ -267,6 +269,7 @@ $html_directory/DEBUG_README.html:f:root:-:644
$html_directory/ETRN_README.html:f:root:-:644
$html_directory/FILTER_README.html:f:root:-:644
$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/LMTP_README.html:f:root:-:644
diff --git a/postfix/conf/postfix-script b/postfix/conf/postfix-script
index d3457d664..f18116473 100644
--- a/postfix/conf/postfix-script
+++ b/postfix/conf/postfix-script
@@ -90,10 +90,18 @@ start)
$FATAL the Postfix mail system is already running
exit 1
}
- $config_directory/postfix-script check || {
- $FATAL Postfix integrity check failed!
- exit 1
- }
+ if [ -f $queue_directory/quick-start ]
+ then
+ rm -f $queue_directory/quick-start
+ else
+ $config_directory/postfix-script check-fatal || {
+ $FATAL Postfix integrity check failed!
+ exit 1
+ }
+ # Warning checks proceed in the background.
+ $INFO starting background file permission checks in 60 seconds
+ (sleep 60; $config_directory/postfix-script check-warn) &
+ fi
$INFO starting the Postfix mail system
$daemon_directory/master &
;;
@@ -108,6 +116,12 @@ drain)
kill -9 `sed 1q pid/master.pid`
;;
+quick-stop)
+
+ $config_directory/postfix-script stop
+ touch $queue_directory/quick-start
+ ;;
+
stop)
$daemon_directory/master -t 2>/dev/null && {
@@ -151,6 +165,37 @@ flush)
check)
+ $config_directory/postfix-script check-fatal || exit 1
+ $config_directory/postfix-script check-warn
+ exit 0
+ ;;
+
+check-fatal)
+ # This command is NOT part of the public interface.
+
+ $SHELL $config_directory/post-install create-missing || {
+ $WARN unable to create missing queue directories
+ exit 1
+ }
+
+ # Look for incomplete installations.
+
+ test -f $config_directory/master.cf || {
+ $FATAL no $config_directory/master.cf file found
+ exit 1
+ }
+
+ # See if all queue files are in the right place. This is slow.
+ # We must scan all queues for mis-named queue files before the
+ # mail system can run.
+
+ $command_directory/postsuper || exit 1
+ exit 0
+ ;;
+
+check-warn)
+ # This command is NOT part of the public interface.
+
for dir in $daemon_directory $config_directory $queue_directory
do
ls -lLd $dir | (grep " root " >/dev/null ||
@@ -164,11 +209,6 @@ check)
\( -perm -020 -o -perm -002 \) -type f \
-exec $WARN group or other writable: {} \;
- $SHELL $config_directory/post-install create-missing || {
- $WARN unable to create missing queue directories
- exit 1
- }
-
find `ls -d $queue_directory/* | \
egrep '/(incoming|active|defer|deferred|bounce|hold|trace|corrupt|public|private|flush)$'` \
! \( -type p -o -type s \) ! -user $mail_owner \
@@ -207,19 +247,6 @@ check)
done
done
- # Look for incomplete installations.
-
- test -f $config_directory/master.cf || {
- $FATAL no $config_directory/master.cf file found
- exit 1
- }
-
- # See if all queue files are in the right place. This is slow.
- # We must scan all queues for mis-named queue files before the
- # mail system can run.
-
- $command_directory/postsuper || exit 1
-
find corrupt -type f -exec $WARN damaged message: {} \;
# XXX also: look for weird stuff, weird permissions, etc.
diff --git a/postfix/html/FILTER_README.html b/postfix/html/FILTER_README.html
index 0978d3384..7d61f4a59 100644
--- a/postfix/html/FILTER_README.html
+++ b/postfix/html/FILTER_README.html
@@ -802,7 +802,7 @@ content filtering turned on.
# (yes) (yes) (yes) (never) (100)
# =================================================================
1.2.3.5:smtp inet n - n - - smtpd
- -o content_filter=foo:bar
+ -o content_filter=filter-service:filter-destination
-o receive_override_options=no_address_mappings
@@ -828,14 +828,14 @@ address provides a different content filter service.
# service type private unpriv chroot wakeup maxproc command
# (yes) (yes) (yes) (never) (100)
# =================================================================
- # SMTP service for domains that are content filtered with foo:bar
+ # SMTP service for domains that are filtered with service1:dest1
1.2.3.4:smtp inet n - n - - smtpd
- -o content_filter=foo:bar
+ -o content_filter=service1:dest1
-o receive_override_options=no_address_mappings
- # SMTP service for domains that are content filtered with xxx:yyy
+ # SMTP service for domains that are filtered with service2:dest2
1.2.3.5:smtp inet n - n - - smtpd
- -o content_filter=xxx:yyy
+ -o content_filter=service2:dest2
-o receive_override_options=no_address_mappings
diff --git a/postfix/html/IPV6_README.html b/postfix/html/IPV6_README.html
new file mode 100644
index 000000000..91b41f397
--- /dev/null
+++ b/postfix/html/IPV6_README.html
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+Postfix IPv6 Support
+
+
+
+
+
+
+
+
Postfix
+IPv6 Support
+
+
+
+Introduction
+
+ Postfix 2.2 introduces support for the IPv6 (IP version 6)
+protocol, whose main feature of interest is that it uses 128-bit
+IP addresses instead of the 32-bit addresses used by IPv4.
+
+ With this, Postfix can use the same SMTP protocol over IPv6 as
+it already uses over the older IPv4 network, and Postfix can do
+AAAA record lookups in the DNS in addition to the older A records.
+Information about IPv6 can be found at http://www.ipv6.org/.
+
+ This document provides information on the following topics:
+
+
+
+
+
+
+ Postfix version 2.2 supports IPv4 and IPv6 on the following
+platforms:
+
+
+
+- AIX 5.1+
+
- Darwin 7.3+
+
- FreeBSD 4+
+
- Linux 2.4+
+
- NetBSD 1.5+
+
- OpenBSD 2+
+
- Solaris 8+
+
- Tru64Unix V5.1+
+
+
+
+ On other platforms Postfix will simply use IPv4 as it has always
+done.
+
+ See below for tips how to port Postfix
+IPv6 support to other environments.
+
+
+
+ Postfix IPv6 support introduces two new main.cf configuration
+parameters, and introduces an important change in address syntax
+notation in match lists such as mynetworks or
+debug_peer_list.
+
+ Postfix IPv6 address syntax is a little tricky, because there
+are a few places where you must enclose IPv6 address inside
+[] characters, and a few places where you must not. It is
+a good idea to use [] only in the few places where you
+have to. Check out the postconf(5) manual whenever you do IPv6
+related configuration work with Postfix.
+
+
+
+-
The new inet_protocols parameter specifies what
+IP protocols Postfix will use. This parameter also controls what
+DNS lookups Postfix will do.
+
+
+
+/etc/postfix/main.cf:
+ # You must stop/start Postfix after changing this parameter.
+ inet_protocols = ipv4 (DEFAULT: enable IPv4 only)
+ inet_protocols = all (enable both IPv4 and IPv6)
+ inet_protocols = ipv4, ipv6 (enable both IPv4 and IPv6)
+ inet_protocols = ipv6 (enable IPv6 only)
+
+
+
+ By default, Postfix uses IPv4 only, because most systems aren't
+attached to an IPv6 network.
+
+
+
+-
On systems with combined IPv4/IPv6 stacks, attempts to
+deliver mail via IPv6 would always fail with "network unreachable",
+and those attempts would only slow down Postfix.
+
+ -
Linux kernels don't even load IPv6 protocol support by
+default. Any attempt to use it would fail immediately.
+
+
+
+ Note 1: you must stop and start Postfix after changing the
+inet_protocols configuration parameter.
+
+ Note 2: if you see error messages like the following, then
+you're running Linux and need to turn on IPv6 in the kernel: see
+http://www.ipv6.org/ for hints and tips. Unlike other systems,
+Linux does not have a combined stack for IPv4 and IPv6, and IPv6
+protocol support is not loaded by default.
+
+
+
+postconf: warning: inet_protocols: IPv6 support is disabled: Address family not supported by protocol
+postconf: warning: inet_protocols: configuring for IPv4 support only
+
+
+
+ Note 3: on older Linux and Solaris systems, the setting
+"inet_protocols = ipv6" will not prevent Postfix from
+accepting IPv4 connections. Postfix will present the client IP
+addresses in IPv6 format, though. In all other cases, Postfix always
+presents IPv4 client IP addresses in the traditional dotted quad
+IPv4 format.
+
+ -
The other new parameter is smtp_bind_address6.
+This sets the local interface address for outgoing IPv6 SMTP
+connections, just like the smtp_bind_address parameter
+does for IPv4:
+
+
+
+/etc/postfix/main.cf:
+ smtp_bind_address6 = 2001:240:5c7:0:250:56ff:fe89:1
+
+
+
+ -
If you left the value of the mynetworks parameter at its
+default (i.e. no mynetworks setting in main.cf) Postfix will figure
+out by itself what its network addresses are. This is what a typical
+setting looks like:
+
+
+
+% postconf mynetworks
+mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [fe80::]/10 [2001:240:5c7::]/64
+
+
+
+ If you did specify the mynetworks parameter value in
+main.cf, you need update the mynetworks value to include
+the IPv6 networks the system is in. Be sure to specify IPv6 address
+information inside [], like this:
+
+
+
+/etc/postfix/main.cf:
+ mynetworks = ...IPv4 networks... [::1]/128 [2001:240:5c7::]/64 ...
+
+
+
+
+
+ NOTE: when configuring Postfix match lists such as
+mynetworks or debug_peer_list, you must specify
+IPv6 address information inside [] in the main.cf parameter
+value and in files specified with a "/file/name" pattern.
+IPv6 addresses contain the ":" character, and would otherwise be
+confused with a "type:table" pattern.
+
+
+
+
+
+-
The order of IPv6/IPv4 outgoing connection attempts is
+not yet configurable. Currently, IPv6 is tried before IPv4.
+
+ -
Postfix currently does not support DNSBL (real-time
+blackhole list) lookups for IPv6 client IP addresses; currently
+there are no blacklists that cover the IPv6 address space.
+
+ -
IPv6 does not have class A, B, C, etc. networks. With IPv6
+networks, the setting "mynetworks_style = class" has the
+same effect as the setting "mynetworks_style = subnet".
+
+
+ -
On Tru64Unix, Postfix can't figure out the local subnet mask
+and always assumes a /128 network. This is a problem only with
+"mynetworks_style = subnet" and no explicit mynetworks
+setting in main.cf.
+
+
+
+
+
+ Postfix version 2.2 IPv6 support is based on the Postfix/IPv6 patch
+by Dean Strik and others, but differs in a few minor ways.
+
+
+
+-
main.cf: The inet_interfaces parameter does not support
+the notation "ipv6:all" or "ipv4:all". Use the
+inet_protocols parameter instead.
+
+ -
main.cf: Specify "inet_protocols = all" or
+"inet_protocols = ipv4, ipv6" in order to enable both IPv4
+and IPv6 support.
+
+ -
main.cf: The inet_protocols parameter also controls
+what DNS lookups Postfix will attempt to make when delivering or
+receiving mail.
+
+ -
main.cf: Specify "inet_interfaces = loopback-only"
+to listen on loopback network interfaces only.
+
+ -
The lmtp_bind_address and lmtp_bind_address6
+features were omitted. The Postfix LMTP client will be absorbed
+into the SMTP client, so there is no reason to keep adding features
+to the LMTP client.
+
+ -
The SMTP server now requires that IPv6 addresses in SMTP
+commands are specified as [ipv6:ipv6address], as
+described in RFC 2821.
+
+ -
The IPv6 network address matching code was rewritten from
+the ground up, and is expected to be closer to the specification.
+The result may be incompatible with the Postfix/IPv6 patch.
+
+
+
+
+
+
+ Getting Postfix IPv6 working on other platforms involves the
+following steps:
+
+
+
+-
Specify how Postfix should find the local network interfaces.
+Postfix needs this information to avoid mailer loops and to find out
+if mail for user@[ipaddress] is a local or remote destination.
+
+ If your system has the getifaddrs() routine then add
+the following to your platform-specific section in
+src/util/sys_defs.h:
+
+
+
+#ifndef NO_IPV6
+# define HAS_IPV6
+# define HAVE_GETIFADDRS
+#endif
+
+
+
+ Otherwise, if your system has the SIOCGLIF ioctl()
+command in /usr/include/*/*.h, add the following to your
+platform-specific section in src/util/sys_defs.h:
+
+
+
+#ifndef NO_IPV6
+# define HAS_IPV6
+# define HAS_SIOCGLIF
+#endif
+
+
+
+ Otherwise, Postfix will have to use the old SIOCGIF commands
+and get along with reduced IPv6 functionality (it won't be able to
+figure out your IPv6 netmasks, which are needed for "mynetworks_style
+= subnet". Add this to your platform-specific section in
+src/util/sys_defs.h:
+
+
+
+#ifndef NO_IPV6
+# define HAS_IPV6
+#endif
+
+
+
+ -
Test if Postfix can figure out its interface information.
+
+ After compiling Postfix in the usual manner, step into the
+src/util directory and type "make inet_addr_local".
+Running this file by hand should produce all the interface addresses
+and network masks, for example:
+
+
+
+% make
+% cd src/util
+% make inet_addr_local
+[... some messages ...]
+% ./inet_addr_local
+[... some messages ...]
+./inet_addr_local: inet_addr_local: configured 2 IPv4 addresses
+./inet_addr_local: inet_addr_local: configured 4 IPv6 addresses
+168.100.189.2/255.255.255.224
+127.0.0.1/255.0.0.0
+fe80:1::2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+2001:240:5c7:0:2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+fe80:5::1/ffff:ffff:ffff:ffff::
+::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+
+
+
+ The above is for an old FreeBSD machine. Other systems produce
+slightly different results, but you get the idea.
+
+
+
+ If none of all this produces a usable result, send email to the
+postfix-users@postfix.org mailing list and we'll try to help you
+through this.
+
+
+
+ The following information is in part based on information that
+was compiled by Dean Strik.
+
+
+
+-
Mark Huizer wrote the original Postfix IPv6 patch.
+
+ -
Jun-ichiro 'itojun' Hagino of the KAME project made
+substantial improvements. Since then, we speak of the KAME patch.
+
+
+ -
The PLD Linux Distribution ported the code to other stacks
+(notably USAGI). We speak of the PLD patch. A very important
+feature of the PLD patch was that it can work with Lutz Jaenicke's
+TLS patch for Postfix.
+
+ -
Dean Strik extended IPv6 support to platforms other than
+KAME and USAGI, updated the patch to keep up with Postfix development,
+and provided a combined IPv6 + TLS patch. Information about his
+effort can be found on Dean Strik's Postfix website at
+http://www.ipnet6.org/postfix/.
+
+ -
Wietse Venema took Dean Strik's IPv6 patch, merged it into
+Postfix 2.2, and took the opportunity to eliminate all IPv4-specific
+code from Postfix that could be removed. For systems without IPv6
+support in the kernel and system libraries, Postfix has a simple
+compatibility layer, so that it will use IPv4 as before.
+
+
+
+
+
+
diff --git a/postfix/html/SASL_README.html b/postfix/html/SASL_README.html
index 355a503a5..2370362a0 100644
--- a/postfix/html/SASL_README.html
+++ b/postfix/html/SASL_README.html
@@ -34,7 +34,7 @@ the Postfix SMTP client to a remote SMTP server.
When receiving mail, Postfix logs the client-provided username,
authentication method, and sender address to the maillog file, and
-optionally grants mail access via the permit_sasl_authenticated
+optionally grants mail access via the permit_sasl_authenticated
UCE restriction.
Postfix does not record the client's SASL authentication
@@ -187,7 +187,7 @@ SMTP server
/etc/postfix/main.cf:
smtpd_recipient_restrictions =
- permit_mynetworks permit_sasl_authenticated ...
+ permit_mynetworks permit_sasl_authenticated ...
diff --git a/postfix/html/SMTPD_POLICY_README.html b/postfix/html/SMTPD_POLICY_README.html
index 3ee862527..8400be659 100644
--- a/postfix/html/SMTPD_POLICY_README.html
+++ b/postfix/html/SMTPD_POLICY_README.html
@@ -108,6 +108,10 @@ size=12345
either does not send the attribute, or sends the attribute with
an empty value ("name=").
+ The client address is an IPv4 dotted quad in the form
+ 1.2.3.4 or it is an IPv6 address in the form 1:2:3::4:5:6.
+
+
An attribute name must not contain "=", null or newline,
and an attribute value must not contain null or newline.
diff --git a/postfix/html/access.5.html b/postfix/html/access.5.html
index 96e15a7f7..b22042fff 100644
--- a/postfix/html/access.5.html
+++ b/postfix/html/access.5.html
@@ -20,7 +20,7 @@ ACCESS(5) ACCESS(5)
The optional access table directs the Postfix SMTP server
to selectively reject or accept mail. Access can be
allowed or denied for specific host names, domain names,
- networks, host network addresses or mail addresses.
+ networks, host addresses or mail addresses.
For an example, see the EXAMPLE section at the end of this
manual page.
@@ -116,39 +116,79 @@ ACCESS(5) ACCESS(5)
net.work
- net Matches any host address in the specified network.
- A network address is a sequence of one or more
- octets separated by ".".
+ net Matches the specified IPv4 host address or subnet-
+ work. An IPv4 host address is a sequence of four
+ decimal octets separated by ".".
- NOTE: use the cidr lookup table type to specify
+ Subnetworks are matched by repeatedly truncating
+ the last ".octet" from the remote IPv4 host address
+ string until a match is found in the access table,
+ or until further truncation is not possible.
+
+ NOTE 1: The information in the access map should be
+ in canonical form, with unnecessary null characters
+ eliminated. Address information must not be
+ enclosed with "[]" characters.
+
+ NOTE 2: use the cidr lookup table type to specify
network/netmask patterns. See cidr_table(5) for
details.
+ net:work:addr:ess
+
+ net:work:addr
+
+ net:work
+
+ net Matches the specified IPv6 host address or subnet-
+ work. An IPv6 host address is a sequence of three
+ to eight hexadecimal octet pairs separated by ":".
+
+ Subnetworks are matched by repeatedly truncating
+ the last ":octetpair" from the remote IPv6 host
+ address string until a match is found in the access
+ table, or until further truncation is not possible.
+
+ NOTE 1: the truncation and comparison are done with
+ the string representation of the IPv6 host address.
+ Thus, not all the ":" subnetworks will be tried.
+
+ NOTE 2: The information in the access map should be
+ in canonical form, with unnecessary null characters
+ eliminated. Address information must not be
+ enclosed with "[]" characters.
+
+ NOTE 3: use the cidr lookup table type to specify
+ network/netmask patterns. See cidr_table(5) for
+ details.
+
+ IPv6 support is available in Postfix 2.2 and later.
+
ACCEPT ACTIONS
OK Accept the address etc. that matches the pattern.
all-numerical
An all-numerical result is treated as OK. This for-
- mat is generated by address-based relay authoriza-
+ mat is generated by address-based relay authoriza-
tion schemes.
REJECT ACTIONS
4NN text
5NN text
- Reject the address etc. that matches the pattern,
+ Reject the address etc. that matches the pattern,
and respond with the numerical three-digit code and
- text. 4NN means "try again later", while 5NN means
+ text. 4NN means "try again later", while 5NN means
"do not try again".
REJECT optional text...
- Reject the address etc. that matches the pattern.
- Reply with $reject_code optional text... when the
- optional text is specified, otherwise reply with a
+ Reject the address etc. that matches the pattern.
+ Reply with $reject_code optional text... when the
+ optional text is specified, otherwise reply with a
generic error response message.
DEFER_IF_REJECT optional text...
- Defer the request if some later restriction would
+ Defer the request if some later restriction would
result in a REJECT action. Reply with "450 optional
text... when the optional text is specified, other-
wise reply with a generic error response message.
@@ -156,10 +196,10 @@ ACCESS(5) ACCESS(5)
This feature is available in Postfix 2.1 and later.
DEFER_IF_PERMIT optional text...
- Defer the request if some later restriction would
- result in a an explicit or implicit PERMIT action.
- Reply with "450 optional text... when the optional
- text is specified, otherwise reply with a generic
+ Defer the request if some later restriction would
+ result in a an explicit or implicit PERMIT action.
+ Reply with "450 optional text... when the optional
+ text is specified, otherwise reply with a generic
error response message.
This feature is available in Postfix 2.1 and later.
@@ -170,131 +210,131 @@ ACCESS(5) ACCESS(5)
reject_unauth_destination, and so on).
DISCARD optional text...
- Claim successful delivery and silently discard the
- message. Log the optional text if specified, oth-
+ Claim successful delivery and silently discard the
+ message. Log the optional text if specified, oth-
erwise log a generic message.
- Note: this action currently affects all recipients
+ Note: this action currently affects all recipients
of the message.
This feature is available in Postfix 2.0 and later.
- DUNNO Pretend that the lookup key was not found. This
- prevents Postfix from trying substrings of the
- lookup key (such as a subdomain name, or a network
+ DUNNO Pretend that the lookup key was not found. This
+ prevents Postfix from trying substrings of the
+ lookup key (such as a subdomain name, or a network
address subnetwork).
This feature is available in Postfix 2.0 and later.
FILTER transport:destination
- After the message is queued, send the entire mes-
+ After the message is queued, send the entire mes-
sage through the specified external content filter.
- The transport:destination syntax is described in
- the transport(5) manual page. More information
- about external content filters is in the Postfix
+ The transport:destination syntax is described in
+ the transport(5) manual page. More information
+ about external content filters is in the Postfix
FILTER_README file.
- Note: this action overrides the main.cf con-
+ Note: this action overrides the main.cf con-
tent_filter setting, and currently affects all
recipients of the message.
This feature is available in Postfix 2.0 and later.
HOLD optional text...
- Place the message on the hold queue, where it will
- sit until someone either deletes it or releases it
- for delivery. Log the optional text if specified,
+ Place the message on the hold queue, where it will
+ sit until someone either deletes it or releases it
+ for delivery. Log the optional text if specified,
otherwise log a generic message.
- Mail that is placed on hold can be examined with
- the postcat(1) command, and can be destroyed or
+ Mail that is placed on hold can be examined with
+ the postcat(1) command, and can be destroyed or
released with the postsuper(1) command.
- Note: use "postsuper -r" to release mail that was
- kept on hold for a significant fraction of $maxi-
+ Note: use "postsuper -r" to release mail that was
+ kept on hold for a significant fraction of $maxi-
mal_queue_lifetime or $bounce_queue_lifetime, or
longer.
- Note: this action currently affects all recipients
+ Note: this action currently affects all recipients
of the message.
This feature is available in Postfix 2.0 and later.
PREPEND headername: headervalue
- Prepend the specified message header to the mes-
+ Prepend the specified message header to the mes-
sage. When this action is used multiple times, the
- first prepended header appears before the second
+ first prepended header appears before the second
etc. prepended header.
- Note: this action does not support multi-line mes-
+ Note: this action does not support multi-line mes-
sage headers.
This feature is available in Postfix 2.1 and later.
REDIRECT user@domain
- After the message is queued, send the message to
+ After the message is queued, send the message to
the specified address instead of the intended
recipient(s).
- Note: this action overrides the FILTER action, and
+ Note: this action overrides the FILTER action, and
currently affects all recipients of the message.
This feature is available in Postfix 2.1 and later.
WARN optional text...
Log a warning with the optional text, together with
- client information and if available, with helo,
+ client information and if available, with helo,
sender, recipient and protocol information.
This feature is available in Postfix 2.1 and later.
REGULAR EXPRESSION TABLES
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
the table is given in the form of regular expressions. For
- a description of regular expression lookup table syntax,
+ a description of regular expression lookup table syntax,
see regexp_table(5) or pcre_table(5).
- Each pattern is a regular expression that is applied to
+ Each pattern is a regular expression that is applied to
the entire string being looked up. Depending on the appli-
- cation, that string is an entire client hostname, an
+ cation, that string is an entire client hostname, an
entire client IP address, or an entire mail address. Thus,
no parent domain or parent network search is done,
- user@domain mail addresses are not broken up into their
+ user@domain mail addresses are not broken up into their
user@ and domain constituent parts, nor is user+foo broken
up into user and foo.
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
- Actions are the same as with indexed file lookups, with
- the additional feature that parenthesized substrings from
+ Actions are the same as with indexed file lookups, with
+ the additional feature that parenthesized substrings from
the pattern can be interpolated as $1, $2 and so on.
TCP-BASED TABLES
- This section describes how the table lookups change when
+ This section describes how the table lookups change when
lookups are directed to a TCP-based server. For a descrip-
- tion of the TCP client/server lookup protocol, see
- tcp_table(5). This feature is not available in Postfix
+ tion of the TCP client/server lookup protocol, see
+ tcp_table(5). This feature is not available in Postfix
version 2.1.
- Each lookup operation uses the entire query string once.
- Depending on the application, that string is an entire
+ Each lookup operation uses the entire query string once.
+ Depending on the application, that string is an entire
client hostname, an entire client IP address, or an entire
- mail address. Thus, no parent domain or parent network
- search is done, user@domain mail addresses are not broken
- up into their user@ and domain constituent parts, nor is
+ mail address. Thus, no parent domain or parent network
+ search is done, user@domain mail addresses are not broken
+ up into their user@ and domain constituent parts, nor is
user+foo broken up into user and foo.
Actions are the same as with indexed file lookups.
EXAMPLE
- The following example uses an indexed file, so that the
- order of table entries does not matter. The example per-
- mits access by the client at address 1.2.3.4 but rejects
- all other clients in 1.2.3.0/24. Instead of hash lookup
- tables, some systems use dbm. Use the command "postconf
- -m" to find out what lookup tables Postfix supports on
+ The following example uses an indexed file, so that the
+ order of table entries does not matter. The example per-
+ mits access by the client at address 1.2.3.4 but rejects
+ all other clients in 1.2.3.0/24. Instead of hash lookup
+ tables, some systems use dbm. Use the command "postconf
+ -m" to find out what lookup tables Postfix supports on
your system.
/etc/postfix/main.cf:
@@ -309,7 +349,7 @@ ACCESS(5) ACCESS(5)
editing the file.
BUGS
- The table format does not understand quoting conventions.
+ The table format does not understand quoting conventions.
SEE ALSO
postmap(1), Postfix lookup table manager
@@ -322,7 +362,7 @@ ACCESS(5) ACCESS(5)
DATABASE_README, Postfix lookup table overview
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/html/cidr_table.5.html b/postfix/html/cidr_table.5.html
index 96f701bbc..bfdbe7d44 100644
--- a/postfix/html/cidr_table.5.html
+++ b/postfix/html/cidr_table.5.html
@@ -32,25 +32,31 @@ CIDR_TABLE(5) CIDR_TABLE(5)
network_address/network_mask result
When a search string matches the specified network
block, use the corresponding result value. Specify
- 0.0.0.0/0 to match every address.
+ 0.0.0.0/0 to match every IPv4 address, and ::/0 to
+ match every IPv6 address.
+
+ Note: address information may be enclosed inside
+ "[]" but this form is not recommended.
+
+ IPv6 support is available in Postfix 2.2 and later.
network_address result
- When a search string matches the specified network
+ When a search string matches the specified network
address, use the corresponding result value.
blank lines and comments
- Empty lines and whitespace-only lines are ignored,
- as are lines whose first non-whitespace character
+ Empty lines and whitespace-only lines are ignored,
+ as are lines whose first non-whitespace character
is a `#'.
multi-line text
- A logical line starts with non-whitespace text. A
- line that starts with whitespace continues a logi-
+ A logical line starts with non-whitespace text. A
+ line that starts with whitespace continues a logi-
cal line.
SEARCH ORDER
- Patterns are applied in the order as specified in the
- table, until a pattern is found that matches the search
+ Patterns are applied in the order as specified in the
+ table, until a pattern is found that matches the search
string.
EXAMPLE SMTPD ACCESS MAP
diff --git a/postfix/html/index.html b/postfix/html/index.html
index 61fe3ba8e..520e3bed6 100644
--- a/postfix/html/index.html
+++ b/postfix/html/index.html
@@ -38,6 +38,8 @@ configuration examples
SASL Authentication
+ IP Version 6 Support
+
Installation from source code
diff --git a/postfix/html/master.8.html b/postfix/html/master.8.html
index 81ef97709..8b4ad00d0 100644
--- a/postfix/html/master.8.html
+++ b/postfix/html/master.8.html
@@ -94,11 +94,6 @@ MASTER(8) MASTER(8)
postfix reload command after a configuration change.
RESOURCE AND RATE CONTROLS
- daemon_timeout (18000s)
- How much time a Postfix daemon process may take to
- handle a request before it is terminated by a
- built-in watchdog timer.
-
default_process_limit (100)
The default maximal number of Postfix child pro-
cesses that provide a given service.
@@ -133,9 +128,13 @@ MASTER(8) MASTER(8)
The network interface addresses that this mail sys-
tem receives mail on.
+ inet_protocols (ipv4)
+ The Internet protocols Postfix will attempt to use
+ when making or accepting connections.
+
import_environment (see 'postconf -d' output)
- The list of environment parameters that a Postfix
- process will import from a non-Postfix parent pro-
+ The list of environment parameters that a Postfix
+ process will import from a non-Postfix parent pro-
cess.
mail_owner (postfix)
@@ -143,22 +142,22 @@ MASTER(8) MASTER(8)
and most Postfix daemon processes.
process_id (read-only)
- The process ID of a Postfix command or daemon pro-
+ The process ID of a Postfix command or daemon pro-
cess.
process_name (read-only)
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
queue_directory (see 'postconf -d' output)
- The location of the Postfix top-level queue direc-
+ The location of the Postfix top-level queue direc-
tory.
syslog_facility (mail)
The syslog facility of Postfix logging.
syslog_name (postfix)
- The mail system name that is prepended to the pro-
+ The mail system name that is prepended to the pro-
cess name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
@@ -175,7 +174,7 @@ MASTER(8) MASTER(8)
syslogd(8), system logging
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html
index e771364c9..1b6ca7b5f 100644
--- a/postfix/html/postconf.5.html
+++ b/postfix/html/postconf.5.html
@@ -842,6 +842,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the authorized_verp_clients value, and in files
+specified with "/file/name". IP version 6 addresses contain the
+":" character, and would otherwise be confused with a "type:table"
+pattern.
+
@@ -2323,13 +2329,19 @@ execute the command "postfix reload".
hash_queue_names
-(default: see "postconf -d" output)
+(default: deferred, defer)
The names of queue directories that are split across multiple
subdirectory levels.
+ Before Postfix version 2.2, the default list of hashed queues
+was significantly larger. Claims about improvements in file system
+technology suggest that hashing of the incoming and active queues
+is no longer needed. Fewer hashed directories speed up the time
+needed to restart Postfix.
+
After changing the hash_queue_names or hash_queue_depth parameter,
execute the command "postfix reload".
@@ -2518,42 +2530,102 @@ Specify 0 to disable the feature. Valid delays are 0..10.
inet_interfaces
(default: all)
-
-The network interface addresses that this mail system receives mail
-on. By default, the software claims all active interfaces on the
-machine. The parameter also controls delivery of mail to
-user@[ip.address].
-
+ The network interface addresses that this mail system receives
+mail on. By default, the software claims all active interfaces on
+the machine; with Postfix 2.2 and later, specify "loopback-only"
+to select only local interfaces. The parameter also controls
+delivery of mail to user@[ip.address].
-When inet_interfaces consists of just one IP address that is not a
-loopback (net 127) address, the Postfix SMTP client will use this address
-as the IP source address for outbound mail.
+Note: you need to stop and start Postfix when this parameter changes.
+
+
+ When inet_interfaces specifies just one IPv4 and/or IPv6 address
+that is not a loopback address, the Postfix SMTP client will use
+this address as the IP source address for outbound mail.
On a multi-homed firewall with separate Postfix instances listening on the
"inside" and "outside" interfaces, this can prevent each instance from
being able to reach servers on the "other side" of the firewall. Setting
-smtp_bind_address to 0.0.0.0 avoids the potential problem.
+smtp_bind_address to 0.0.0.0 avoids the potential problem for
+IPv4, and setting smtp_bind_address6 to :: solves the problem
+for IPv6.
-A better solution is to leave inet_interfaces at the default value
+A better solution for multi-homed firewalls is to leave inet_interfaces
+at the default value
and instead use explicit IP addresses in master.cf. This preserves SMTP
loop detection, by ensuring that each side of the firewall knows that the
other IP address is still the same host. Setting $inet_interfaces to a
-single IP address is primarily useful with virtual hosting of domains on
+single IPv4 and/or IPV6 address is primarily useful with virtual
+hosting of domains on
secondary IP addresses, when each IP address serves a different domain
(and has a different $myhostname setting).
See also the proxy_interfaces parameter, for network addresses that
-are forwarded to us by way of a proxy or address translator.
+are forwarded to Postfix by way of a proxy or address translator.
-Note: you need to stop and start Postfix when this parameter changes.
+Examples:
+
+inet_interfaces = all (DEFAULT)
+inet_interfaces = loopback-only
+inet_interfaces = 127.0.0.1
+inet_interfaces = 192.168.1.2, 127.0.0.1
+
+
+
+
+
+inet_protocols
+(default: ipv4)
+
+ The Internet protocols Postfix will attempt to use when making
+or accepting connections. Specify one or more of "ipv4" or "ipv6",
+separated by whitespace or commas. The form "all" is equivalent to
+"ipv4, ipv6".
+
+ Note: you MUST stop and start Postfix after changing this
+parameter.
+
+ On systems that pre-date IPV6_V6ONLY support (RFC 3493), an
+IPv6 server will also accept IPv4 connections, even when IPv4 is
+turned off with the inet_protocols parameter. On systems with
+IPV6_V6ONLY support, Postfix will use separate server sockets for
+IPv6 and IPv4, and each will accept only connections for the
+corresponding protocol.
+
+ When IPv4 support is enabled via the inet_protocols parameter,
+Postfix will to DNS type A record lookups, and will convert
+IPv4-in-IPv6 client IP addresses (::ffff:1.2.3.4) to their original
+IPv4 form (1.2.3.4). The latter is needed on hosts that pre-date
+IPV6_V6ONLY support (RFC 3493).
+
+ When IPv6 support is enabled via the inet_protocols parameter,
+Postfix will do DNS type AAAA record lookups.
+
+ When both IPv4 and IPv6 support are enabled, the Postfix SMTP
+client will attempt to connect via IPv6 before attempting to use
+IPv4.
+
+ This feature is available in Postfix version 2.2 and later.
+
+
+Examples:
+
+
+
+inet_protocols = ipv4 (DEFAULT)
+inet_protocols = all
+inet_protocols = ipv6
+inet_protocols = ipv4, ipv6
+
+
@@ -4070,11 +4142,17 @@ lookup string (the lookup result is ignored).
first match. Specify "!pattern" to exclude an address or network
block from the list.
+ Note: IP version 6 address information must be specified inside
+[] in the mynetworks value, and in files specified with
+"/file/name". IP version 6 addresses contain the ":" character,
+and would otherwise be confused with a "type:table" pattern.
+
Examples:
-mynetworks = 168.100.189.0/28, 127.0.0.0/8
+mynetworks = 127.0.0.0/8 168.100.189.0/28
mynetworks = !192.168.0.1, 192.168.0.0/28
+mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:5c7::]/64
mynetworks = $config_directory/mynetworks
mynetworks = hash:/etc/postfix/network_table
@@ -5451,7 +5529,7 @@ the word "ESMTP" appears in the server greeting banner (example:
An optional numerical network address that the SMTP client should
-bind to when making a connection.
+bind to when making an IPv4 connection.
@@ -5465,11 +5543,47 @@ for example:
smtp ... smtp -o smtp_bind_address=11.22.33.44
-
Note: when inet_interfaces specifies exactly one address that
-is a non-loopback address, it is automatically used as the
-smtp_bind_address. This supports virtual IP hosting, but can be
-a problem on multi-homed firewalls. See the inet_interfaces
-documentation for more detail.
+ Note 1: when inet_interfaces specifies no more than one IPv4
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail.
+
+ Note 2: address information may be enclosed inside [],
+but this form is not recommended.
+
+
+
+
+smtp_bind_address6
+(default: empty)
+
+
+An optional numerical network address that the SMTP client should
+bind to when making an IPv6 connection.
+
+
+
+This can be specified in the main.cf file for all SMTP clients, or
+it can be specified in the master.cf file for a specific client,
+for example:
+
+
+
+ /etc/postfix/master.cf:
+ smtp ... smtp -o smtp_bind_address6=1:2:3:4:5:6:7:8
+
+
+ Note 1: when inet_interfaces specifies no more than one IPv6
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address6. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail.
+
+ Note 2: address information may be enclosed inside [],
+but this form is not recommended.
+
+ This feature is available in Postfix version 2.2 and later.
@@ -6211,6 +6325,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_verp_clients value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
@@ -6244,6 +6364,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_xclient_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
@@ -6276,6 +6402,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_xforward_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
@@ -6381,6 +6513,12 @@ list of network blocks, hostnames or .domain names (the initial
dot causes the domain to match any name below it).
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_client_event_limit_exceptions value, and
+in files specified with "/file/name". IP version 6 addresses
+contain the ":" character, and would otherwise be confused with a
+"type:table" pattern.
+
This feature is available in Postfix 2.2 and later.
@@ -7533,6 +7671,12 @@ contents; a "type:table" lookup table is matc
matches a lookup string (the lookup result is ignored). Continue
long lines by starting the next line with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_sasl_exceptions_networks value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
Example:
@@ -8664,7 +8808,7 @@ it will open the table directly. Before Postfix version 2.2, the
Optional lookup tables with a) names of domains for which all
addresses are aliased to addresses in other local or remote domains,
and b) addresses that are aliased to addresses in other local or
-remote domains. Available before Postfix version 2.0. With Postfix 2.1
+remote domains. Available before Postfix version 2.0. With Postfix 2.0
and later, this is replaced by separate controls: virtual_alias_domains
and virtual_alias_maps.
diff --git a/postfix/html/postqueue.1.html b/postfix/html/postqueue.1.html
index 0772461a8..46ff22d76 100644
--- a/postfix/html/postqueue.1.html
+++ b/postfix/html/postqueue.1.html
@@ -62,89 +62,92 @@ POSTQUEUE(1) POSTQUEUE(1)
-s site
Schedule immediate delivery of all mail that is
- queued for the named site. The site must be eligi-
- ble for the "fast flush" service. See flush(8) for
- more information about the "fast flush" service.
+ queued for the named site. A numerical site must be
+ specified as a valid RFC 2821 address literal
+ enclosed in [], just like in email addresses. The
+ site must be eligible for the "fast flush" service.
+ See flush(8) for more information about the "fast
+ flush" service.
- This option implements the traditional sendmail
+ This option implements the traditional sendmail
-qRsite command, by contacting the Postfix flush(8)
daemon.
-v Enable verbose logging for debugging purposes. Mul-
- tiple -v options make the software increasingly
+ tiple -v options make the software increasingly
verbose.
SECURITY
- This program is designed to run with set-group ID privi-
+ This program is designed to run with set-group ID privi-
leges, so that it can connect to Postfix daemon processes.
DIAGNOSTICS
- Problems are logged to syslogd(8) and to the standard
+ Problems are logged to syslogd(8) and to the standard
error stream.
ENVIRONMENT
MAIL_CONFIG
- Directory with the main.cf file. In order to avoid
- exploitation of set-group ID privileges, a non-
+ Directory with the main.cf file. In order to avoid
+ exploitation of set-group ID privileges, a non-
standard directory is allowed only if:
- o The name is listed in the standard main.cf
- file with the alternate_config_directories
+ o The name is listed in the standard main.cf
+ file with the alternate_config_directories
configuration parameter.
o The command is invoked by the super-user.
CONFIGURATION PARAMETERS
- The following main.cf parameters are especially relevant
+ The following main.cf parameters are especially relevant
to this program. The text below provides only a parameter
- summary. See postconf(5) for more details including exam-
+ summary. See postconf(5) for more details including exam-
ples.
alternate_config_directories (empty)
- A list of non-default Postfix configuration direc-
+ A list of non-default Postfix configuration direc-
tories that may be specified with "-c config_direc-
- tory" on the command line, or via the MAIL_CONFIG
+ tory" on the command line, or via the MAIL_CONFIG
environment parameter.
config_directory (see 'postconf -d' output)
- The default location of the Postfix main.cf and
+ The default location of the Postfix main.cf and
master.cf configuration files.
command_directory (see 'postconf -d' output)
- The location of all postfix administrative com-
+ The location of all postfix administrative com-
mands.
fast_flush_domains ($relay_domains)
Optional list of destinations that are eligible for
- per-destination logfiles with mail that is queued
+ per-destination logfiles with mail that is queued
to those destinations.
import_environment (see 'postconf -d' output)
- The list of environment parameters that a Postfix
- process will import from a non-Postfix parent pro-
+ The list of environment parameters that a Postfix
+ process will import from a non-Postfix parent pro-
cess.
queue_directory (see 'postconf -d' output)
- The location of the Postfix top-level queue direc-
+ The location of the Postfix top-level queue direc-
tory.
syslog_facility (mail)
The syslog facility of Postfix logging.
syslog_name (postfix)
- The mail system name that is prepended to the pro-
+ The mail system name that is prepended to the pro-
cess name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
trigger_timeout (10s)
- The time limit for sending a trigger to a Postfix
- daemon (for example, the pickup(8) or qmgr(8) dae-
+ The time limit for sending a trigger to a Postfix
+ daemon (for example, the pickup(8) or qmgr(8) dae-
mon).
Available in Postfix version 2.2 and later:
authorized_flush_users (static:anyone)
- List of users who are authorized to flush the
+ List of users who are authorized to flush the
queue.
authorized_mailq_users (static:anyone)
@@ -164,11 +167,11 @@ POSTQUEUE(1) POSTQUEUE(1)
ETRN_README, Postfix ETRN howto
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
HISTORY
- The postqueue command was introduced with Postfix version
+ The postqueue command was introduced with Postfix version
1.1.
AUTHOR(S)
diff --git a/postfix/html/qmqp-sink.1.html b/postfix/html/qmqp-sink.1.html
index d0fd4d953..99892adac 100644
--- a/postfix/html/qmqp-sink.1.html
+++ b/postfix/html/qmqp-sink.1.html
@@ -10,18 +10,24 @@ QMQP-SINK(1) QMQP-SINK(1)
qmqp-sink - multi-threaded QMQP test server
SYNOPSIS
- qmqp-sink [-cv] [-x time] [inet:][host]:port backlog
+ qmqp-sink [-46cv] [-x time] [inet:][host]:port backlog
- qmqp-sink [-cv] [-x time] unix:pathname backlog
+ qmqp-sink [-46cv] [-x time] unix:pathname backlog
DESCRIPTION
qmqp-sink listens on the named host (or address) and port.
It receives messages from the network and throws them
away. The purpose is to measure QMQP client performance,
not protocol compliance. Connections can be accepted on
- IPV4 endpoints or UNIX-domain sockets. IPV4 is the
- default. This program is the complement of the qmqp-
- source(1) program.
+ IPv4 or IPv6 endpoints, or on UNIX-domain sockets. IPv4
+ and IPv6 are the default. This program is the complement
+ of the qmqp-source(1) program.
+
+ -4 Support IPv4 only. This option has no effect when
+ Postfix is built without IPv6 support.
+
+ -6 Support IPv6 only. This option is not available
+ when Postfix is built without IPv6 support.
-c Display a running counter that is updated whenever
a delivery is completed.
diff --git a/postfix/html/qmqp-source.1.html b/postfix/html/qmqp-source.1.html
index ed8d3b6c9..49b22607a 100644
--- a/postfix/html/qmqp-source.1.html
+++ b/postfix/html/qmqp-source.1.html
@@ -18,11 +18,18 @@ QMQP-SOURCE(1) QMQP-SOURCE(1)
qmqp-source connects to the named host and TCP port
(default 628) and sends one or more messages to it, either
sequentially or in parallel. The program speaks the QMQP
- protocol. Connections can be made to UNIX-domain and IPV4
- servers. IPV4 is the default.
+ protocol. Connections can be made to UNIX-domain and IPv4
+ or IPv6 servers. IPv4 and IPv6 are the default.
Options:
+ -4 Connect to the server with IPv4. This option has no
+ effect when Postfix is built without IPv6 support.
+
+ -6 Connect to the server with IPv6. This option is not
+ available when Postfix is built without IPv6 sup-
+ port.
+
-c Display a running counter that is incremented each
time a delivery completes.
diff --git a/postfix/html/qmqpd.8.html b/postfix/html/qmqpd.8.html
index 26a06d764..bf94ce6c0 100644
--- a/postfix/html/qmqpd.8.html
+++ b/postfix/html/qmqpd.8.html
@@ -57,7 +57,7 @@ QMQPD(8) QMQPD(8)
receive_override_options (empty)
Enable or disable recipient validation, built-in
- content filtering, or address rewriting.
+ content filtering, or address mapping.
RESOURCE AND RATE CONTROLS
line_length_limit (2048)
diff --git a/postfix/html/sendmail.1.html b/postfix/html/sendmail.1.html
index 38e052cc5..39caa1660 100644
--- a/postfix/html/sendmail.1.html
+++ b/postfix/html/sendmail.1.html
@@ -153,6 +153,9 @@ SENDMAIL(1) SENDMAIL(1)
Non-default alias database. Specify pathname or
type:pathname. See postalias(1) for details.
+ -O option=value (ignored)
+ Backwards compatibility.
+
-o7 (ignored)
-o8 (ignored)
diff --git a/postfix/html/smtp-sink.1.html b/postfix/html/smtp-sink.1.html
index 41b36d94d..b131650e6 100644
--- a/postfix/html/smtp-sink.1.html
+++ b/postfix/html/smtp-sink.1.html
@@ -20,15 +20,22 @@ SMTP-SINK(1) SMTP-SINK(1)
away. The purpose is to measure client performance, not
protocol compliance.
- Connections can be accepted on IPV4 endpoints or UNIX-
- domain sockets. IPV4 is the default. This program is the
- complement of the smtp-source(1) program.
+ Connections can be accepted on IPv4 or IPv6 endpoints, or
+ on UNIX-domain sockets. IPv4 and IPv6 are the default.
+ This program is the complement of the smtp-source(1) pro-
+ gram.
Arguments:
+ -4 Support IPv4 only. This option has no effect when
+ Postfix is built without IPv6 support.
+
+ -6 Support IPv6 only. This option is not available
+ when Postfix is built without IPv6 support.
+
-a Do not announce SASL authentication support.
- -c Display a running counter that is updated whenever
+ -c Display a running counter that is updated whenever
an SMTP QUIT command is executed.
-C Disable XCLIENT support.
@@ -36,14 +43,14 @@ SMTP-SINK(1) SMTP-SINK(1)
-e Do not announce ESMTP support.
-f command,command,...
- Reject the specified commands with a hard (5xx)
+ Reject the specified commands with a hard (5xx)
error code.
-F Disable XFORWARD support.
-h hostname
- Use hostname in the SMTP greeting, in the HELO
- response, and in the EHLO response. The default
+ Use hostname in the SMTP greeting, in the HELO
+ response, and in the EHLO response. The default
hostname is "smtp-sink".
-L Enable LMTP instead of SMTP.
@@ -52,26 +59,26 @@ SMTP-SINK(1) SMTP-SINK(1)
Terminate after count sessions. This is for testing
purposes.
- -p Do not announce support for ESMTP command pipelin-
+ -p Do not announce support for ESMTP command pipelin-
ing.
- -P Change the server greeting so that it appears to
+ -P Change the server greeting so that it appears to
come through a CISCO PIX system. Implies -e.
-q command,command,...
- Disconnect (without replying) after receiving one
+ Disconnect (without replying) after receiving one
of the specified commands.
-r command,command,...
- Reject the specified commands with a soft (4xx)
+ Reject the specified commands with a soft (4xx)
error code.
-s command,command,...
- Log the named commands to syslogd. Examples of
- commands that can be logged are HELO, EHLO, LHLO,
- MAIL, RCPT, VRFY, RSET, NOOP, and QUIT. Separate
- command names by white space or commas, and use
- quotes to protect white space from the shell. Com-
+ Log the named commands to syslogd. Examples of
+ commands that can be logged are HELO, EHLO, LHLO,
+ MAIL, RCPT, VRFY, RSET, NOOP, and QUIT. Separate
+ command names by white space or commas, and use
+ quotes to protect white space from the shell. Com-
mand names are case-insensitive.
-v Show the SMTP conversations.
@@ -83,7 +90,7 @@ SMTP-SINK(1) SMTP-SINK(1)
-8 Do not announce 8BITMIME support.
[inet:][host]:port
- Listen on network interface host (default: any
+ Listen on network interface host (default: any
interface) TCP port port. Both host and port may be
specified in numeric or symbolic form.
@@ -91,14 +98,14 @@ SMTP-SINK(1) SMTP-SINK(1)
Listen on the UNIX-domain socket at pathname.
backlog
- The maximum length the queue of pending connec-
+ The maximum length the queue of pending connec-
tions, as defined by the listen(2) call.
SEE ALSO
smtp-source(1), SMTP/LMTP message generator
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/html/smtp-source.1.html b/postfix/html/smtp-source.1.html
index ca2477b07..df2e82141 100644
--- a/postfix/html/smtp-source.1.html
+++ b/postfix/html/smtp-source.1.html
@@ -18,33 +18,41 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
smtp-source connects to the named host and TCP port
(default: port 25) and sends one or more messages to it,
either sequentially or in parallel. The program speaks
- either SMTP (default) or LMTP. Connections can be made to
- UNIX-domain and IPV4 servers. IPV4 is the default.
+ either SMTP (default) or LMTP. Connections can be made to
+ UNIX-domain and IPv4 or IPv6 servers. IPv4 and IPv6 are
+ the default.
Arguments:
- -c Display a running counter that is incremented each
+ -4 Connect to the server with IPv4. This option has no
+ effect when Postfix is built without IPv6 support.
+
+ -6 Connect to the server with IPv6. This option is not
+ available when Postfix is built without IPv6 sup-
+ port.
+
+ -c Display a running counter that is incremented each
time an SMTP DATA command completes.
-C count
- When a host sends RESET instead of SYN|ACK, try
- count times before giving up. The default count is
+ When a host sends RESET instead of SYN|ACK, try
+ count times before giving up. The default count is
1. Specify a larger count in order to work around a
problem with TCP/IP stacks that send RESET when the
listen queue is full.
- -d Don't disconnect after sending a message; send the
+ -d Don't disconnect after sending a message; send the
next message over the same connection.
-f from
- Use the specified sender address (default:
+ Use the specified sender address (default:
<foo@myhostname>).
- -o Old mode: don't send HELO, and don't send message
+ -o Old mode: don't send HELO, and don't send message
headers.
-l length
- Send length bytes as message payload. The length
+ Send length bytes as message payload. The length
does not include message headers.
-L Speak LMTP rather than SMTP.
@@ -52,15 +60,15 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
-m message_count
Send the specified number of messages (default: 1).
- -N Prepend a non-repeating sequence number to each
- recipient address. This avoids the artificial 100%
- hit rate in the resolve and rewrite client caches
- and exercises the trivial-rewrite daemon, better
- approximating Postfix performance under real-life
+ -N Prepend a non-repeating sequence number to each
+ recipient address. This avoids the artificial 100%
+ hit rate in the resolve and rewrite client caches
+ and exercises the trivial-rewrite daemon, better
+ approximating Postfix performance under real-life
work-loads.
-r recipient_count
- Send the specified number of recipients per trans-
+ Send the specified number of recipients per trans-
action (default: 1). Recipient names are generated
by prepending a number to the recipient address.
@@ -69,15 +77,15 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
lel (default: 1).
-S subject
- Send mail with the named subject line (default:
+ Send mail with the named subject line (default:
none).
- -t to Use the specified recipient address (default:
+ -t to Use the specified recipient address (default:
<foo@myhostname>).
-R interval
Wait for a random period of time 0 <= n <= interval
- between messages. Suspending one thread does not
+ between messages. Suspending one thread does not
affect other delivery threads.
-w interval
@@ -85,7 +93,7 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
thread does not affect other delivery threads.
[inet:]host[:port]
- Connect via TCP to host host, port port. The
+ Connect via TCP to host host, port port. The
default port is smtp.
unix:pathname
@@ -98,7 +106,7 @@ SMTP-SOURCE(1) SMTP-SOURCE(1)
smtp-sink(1), SMTP/LMTP message dump
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html
index 2d764607d..de553093b 100644
--- a/postfix/html/smtp.8.html
+++ b/postfix/html/smtp.8.html
@@ -330,37 +330,47 @@ SMTP(8) SMTP(8)
The network interface addresses that this mail sys-
tem receives mail on.
+ inet_protocols (ipv4)
+ The Internet protocols Postfix will attempt to use
+ when making or accepting connections.
+
ipc_timeout (3600s)
The time limit for sending or receiving information
over an internal communication channel.
max_idle (100s)
- The maximum amount of time that an idle Postfix
- daemon process waits for the next service request
+ The maximum amount of time that an idle Postfix
+ daemon process waits for the next service request
before exiting.
max_use (100)
- The maximal number of connection requests before a
+ The maximal number of connection requests before a
Postfix daemon process terminates.
process_id (read-only)
- The process ID of a Postfix command or daemon pro-
+ The process ID of a Postfix command or daemon pro-
cess.
process_name (read-only)
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
proxy_interfaces (empty)
The network interface addresses that this mail sys-
- tem receives mail on by way of a proxy or network
+ tem receives mail on by way of a proxy or network
address translation unit.
smtp_bind_address (empty)
An optional numerical network address that the SMTP
- client should bind to when making a connection.
+ client should bind to when making an IPv4 connec-
+ tion.
- smtp_helo_name">smtp_helo_name ($myhostname)
+ smtp_bind_address6 (empty)
+ An optional numerical network address that the SMTP
+ client should bind to when making an IPv6 connec-
+ tion.
+
+ smtp_helo_name ($myhostname)
The hostname to send in the SMTP EHLO or HELO com-
mand.
diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html
index bc6fb70e4..112cb5ef7 100644
--- a/postfix/html/smtpd.8.html
+++ b/postfix/html/smtpd.8.html
@@ -323,182 +323,186 @@ SMTPD(8) SMTPD(8)
tem receives mail on by way of a proxy or network
address translation unit.
+ inet_protocols (ipv4)
+ The Internet protocols Postfix will attempt to use
+ when making or accepting connections.
+
local_recipient_maps (proxy:unix:passwd.byname
$alias_maps)
- Lookup tables with all names or addresses of local
- recipients: a recipient address is local when its
- domain matches $mydestination, $inet_interfaces or
+ Lookup tables with all names or addresses of local
+ recipients: a recipient address is local when its
+ domain matches $mydestination, $inet_interfaces or
$proxy_interfaces.
unknown_local_recipient_reject_code (550)
- The numerical Postfix SMTP server response code
- when a recipient address is local, and
- $local_recipient_maps specifies a list of lookup
+ The numerical Postfix SMTP server response code
+ when a recipient address is local, and
+ $local_recipient_maps specifies a list of lookup
tables that does not match the recipient.
- Parameters concerning known/unknown recipients of relay
+ Parameters concerning known/unknown recipients of relay
destinations:
relay_domains ($mydestination)
- What destination domains (and subdomains thereof)
+ What destination domains (and subdomains thereof)
this system will relay mail to.
relay_recipient_maps (empty)
- Optional lookup tables with all valid addresses in
+ Optional lookup tables with all valid addresses in
the domains that match $relay_domains.
unknown_relay_recipient_reject_code (550)
The numerical Postfix SMTP server reply code when a
- recipient address matches $relay_domains, and
- relay_recipient_maps specifies a list of lookup
+ recipient address matches $relay_domains, and
+ relay_recipient_maps specifies a list of lookup
tables that does not match the recipient address.
- Parameters concerning known/unknown recipients in virtual
+ Parameters concerning known/unknown recipients in virtual
alias domains:
virtual_alias_domains ($virtual_alias_maps)
Postfix is final destination for the specified list
- of virtual alias domains, that is, domains for
- which all addresses are aliased to addresses in
+ of virtual alias domains, that is, domains for
+ which all addresses are aliased to addresses in
other local or remote domains.
virtual_alias_maps ($virtual_maps)
- Optional lookup tables that alias specific mail
- addresses or domains to other local or remote
+ Optional lookup tables that alias specific mail
+ addresses or domains to other local or remote
address.
unknown_virtual_alias_reject_code (550)
The SMTP server reply code when a recipient address
- matches $virtual_alias_domains, and $vir-
- tual_alias_maps specifies a list of lookup tables
+ matches $virtual_alias_domains, and $vir-
+ tual_alias_maps specifies a list of lookup tables
that does not match the recipient address.
- Parameters concerning known/unknown recipients in virtual
+ Parameters concerning known/unknown recipients in virtual
mailbox domains:
virtual_mailbox_domains ($virtual_mailbox_maps)
Postfix is final destination for the specified list
- of domains; mail is delivered via the $vir-
+ of domains; mail is delivered via the $vir-
tual_transport mail delivery transport.
virtual_mailbox_maps (empty)
- Optional lookup tables with all valid addresses in
+ Optional lookup tables with all valid addresses in
the domains that match $virtual_mailbox_domains.
unknown_virtual_mailbox_reject_code (550)
The SMTP server reply code when a recipient address
- matches $virtual_mailbox_domains, and $vir-
+ matches $virtual_mailbox_domains, and $vir-
tual_mailbox_maps specifies a list of lookup tables
that does not match the recipient address.
RESOURCE AND RATE CONTROLS
- The following parameters limit resource usage by the SMTP
+ The following parameters limit resource usage by the SMTP
server and/or control client request rates.
line_length_limit (2048)
- Upon input, long lines are chopped up into pieces
- of at most this length; upon delivery, long lines
+ Upon input, long lines are chopped up into pieces
+ of at most this length; upon delivery, long lines
are reconstructed.
queue_minfree (0)
- The minimal amount of free space in bytes in the
+ The minimal amount of free space in bytes in the
queue file system that is needed to receive mail.
message_size_limit (10240000)
- The maximal size in bytes of a message, including
+ The maximal size in bytes of a message, including
envelope information.
smtpd_recipient_limit (1000)
- The maximal number of recipients that the Postfix
+ The maximal number of recipients that the Postfix
SMTP server accepts per message delivery request.
smtpd_timeout (300s)
- The time limit for sending a Postfix SMTP server
- response and for receiving a remote SMTP client
+ The time limit for sending a Postfix SMTP server
+ response and for receiving a remote SMTP client
request.
smtpd_history_flush_threshold (100)
- The maximal number of lines in the Postfix SMTP
- server command history before it is flushed upon
+ The maximal number of lines in the Postfix SMTP
+ server command history before it is flushed upon
receipt of EHLO, RSET, or end of DATA.
The per SMTP client connection count and request rate lim-
its are implemented in co-operation with the anvil(8) ser-
- vice, and are available in Postfix version 2.2 and later.
+ vice, and are available in Postfix version 2.2 and later.
smtpd_client_connection_count_limit (50)
- How many simultaneous connections any client is
+ How many simultaneous connections any client is
allowed to make to this service.
smtpd_client_connection_rate_limit (0)
The maximal number of connection attempts any
- client is allowed to make to this service per time
+ client is allowed to make to this service per time
unit.
smtpd_client_message_rate_limit (0)
- The maximal number of message delivery requests
- that any client is allowed to make to this service
+ The maximal number of message delivery requests
+ that any client is allowed to make to this service
per time unit, regardless of whether or not Postfix
actually accepts those messages.
smtpd_client_recipient_rate_limit (0)
- The maximal number of recipient addresses that any
- client is allowed to send to this service per time
+ The maximal number of recipient addresses that any
+ client is allowed to send to this service per time
unit, regardless of whether or not Postfix actually
accepts those recipients.
smtpd_client_event_limit_exceptions ($mynetworks)
- Clients that are excluded from connection count,
- connection rate, message rate or recipient rate
+ Clients that are excluded from connection count,
+ connection rate, message rate or recipient rate
restrictions.
TARPIT CONTROLS
- When a remote SMTP client makes errors, the Postfix SMTP
- server can insert delays before responding. This can help
- to slow down run-away software. The behavior is con-
- trolled by an error counter that counts the number of
- errors within an SMTP session that a client makes without
+ When a remote SMTP client makes errors, the Postfix SMTP
+ server can insert delays before responding. This can help
+ to slow down run-away software. The behavior is con-
+ trolled by an error counter that counts the number of
+ errors within an SMTP session that a client makes without
delivering mail.
smtpd_error_sleep_time (1s)
- With Postfix 2.1 and later: the SMTP server
- response delay after a client has made more than
- $smtpd_soft_error_limit errors, and fewer than
- $smtpd_hard_error_limit errors, without delivering
+ With Postfix 2.1 and later: the SMTP server
+ response delay after a client has made more than
+ $smtpd_soft_error_limit errors, and fewer than
+ $smtpd_hard_error_limit errors, without delivering
mail.
smtpd_soft_error_limit (10)
- The number of errors a remote SMTP client is
- allowed to make without delivering mail before the
+ The number of errors a remote SMTP client is
+ allowed to make without delivering mail before the
Postfix SMTP server slows down all its responses.
smtpd_hard_error_limit (20)
- The maximal number of errors a remote SMTP client
+ The maximal number of errors a remote SMTP client
is allowed to make without delivering mail.
smtpd_junk_command_limit (100)
- The number of junk commands (NOOP, VRFY, ETRN or
+ The number of junk commands (NOOP, VRFY, ETRN or
RSET) that a remote SMTP client can send before the
- Postfix SMTP server starts to increment the error
+ Postfix SMTP server starts to increment the error
counter with each junk command.
Available in Postfix version 2.1 and later:
smtpd_recipient_overshoot_limit (1000)
- The number of recipients that a remote SMTP client
- can send in excess of the limit specified with
+ The number of recipients that a remote SMTP client
+ can send in excess of the limit specified with
$smtpd_recipient_limit, before the Postfix SMTP
- server increments the per-session error count for
+ server increments the per-session error count for
each excess recipient.
ACCESS POLICY DELEGATION CONTROLS
- As of version 2.1, Postfix can be configured to delegate
- access policy decisions to an external server that runs
- outside Postfix. See the file SMTPD_POLICY_README for
+ As of version 2.1, Postfix can be configured to delegate
+ access policy decisions to an external server that runs
+ outside Postfix. See the file SMTPD_POLICY_README for
more information.
smtpd_policy_service_max_idle (300s)
- The time after which an idle SMTPD policy service
+ The time after which an idle SMTPD policy service
connection is closed.
smtpd_policy_service_max_ttl (1000s)
@@ -506,161 +510,161 @@ SMTPD(8) SMTPD(8)
connection is closed.
smtpd_policy_service_timeout (100s)
- The time limit for connecting to, writing to or
+ The time limit for connecting to, writing to or
receiving from a delegated SMTPD policy server.
ACCESS CONTROLS
- The SMTPD_ACCESS_README document gives an introduction to
+ The SMTPD_ACCESS_README document gives an introduction to
all the SMTP server access control features.
smtpd_delay_reject (yes)
- Wait until the RCPT TO command before evaluating
+ Wait until the RCPT TO command before evaluating
$smtpd_client_restrictions, $smtpd_helo_restric-
tions and $smtpd_sender_restrictions, or wait until
- the ETRN command before evaluating
+ the ETRN command before evaluating
$smtpd_client_restrictions and $smtpd_helo_restric-
tions.
- parent_domain_matches_subdomains (see 'postconf -d' out-
+ parent_domain_matches_subdomains (see 'postconf -d' out-
put)
What Postfix features match subdomains of
"domain.tld" automatically, instead of requiring an
explicit ".domain.tld" pattern.
smtpd_client_restrictions (empty)
- Optional SMTP server access restrictions in the
+ Optional SMTP server access restrictions in the
context of a client SMTP connection request.
smtpd_helo_required (no)
Require that a remote SMTP client introduces itself
- at the beginning of an SMTP session with the HELO
+ at the beginning of an SMTP session with the HELO
or EHLO command.
smtpd_helo_restrictions (empty)
- Optional restrictions that the Postfix SMTP server
+ Optional restrictions that the Postfix SMTP server
applies in the context of the SMTP HELO command.
smtpd_sender_restrictions (empty)
- Optional restrictions that the Postfix SMTP server
+ Optional restrictions that the Postfix SMTP server
applies in the context of the MAIL FROM command.
smtpd_recipient_restrictions (permit_mynetworks,
reject_unauth_destination)
The access restrictions that the Postfix SMTP
- server applies in the context of the RCPT TO com-
+ server applies in the context of the RCPT TO com-
mand.
smtpd_etrn_restrictions (empty)
- Optional SMTP server access restrictions in the
+ Optional SMTP server access restrictions in the
context of a client ETRN request.
allow_untrusted_routing (no)
- Forward mail with sender-specified routing
- (user[@%!]remote[@%!]site) from untrusted clients
+ Forward mail with sender-specified routing
+ (user[@%!]remote[@%!]site) from untrusted clients
to destinations matching $relay_domains.
smtpd_restriction_classes (empty)
- User-defined aliases for groups of access restric-
+ User-defined aliases for groups of access restric-
tions.
smtpd_null_access_lookup_key (<>)
- The lookup key to be used in SMTP access(5) tables
+ The lookup key to be used in SMTP access(5) tables
instead of the null sender address.
permit_mx_backup_networks (empty)
Restrict the use of the permit_mx_backup SMTP
- access feature to only domains whose primary MX
+ access feature to only domains whose primary MX
hosts match the listed networks.
Available in Postfix version 2.0 and later:
smtpd_data_restrictions (empty)
- Optional access restrictions that the Postfix SMTP
+ Optional access restrictions that the Postfix SMTP
server applies in the context of the SMTP DATA com-
mand.
smtpd_expansion_filter (see 'postconf -d' output)
- What characters are allowed in $name expansions of
+ What characters are allowed in $name expansions of
RBL reply templates.
Available in Postfix version 2.1 and later:
smtpd_reject_unlisted_sender (no)
- Request that the Postfix SMTP server rejects mail
- from unknown sender addresses, even when no
- explicit reject_unlisted_sender access restriction
+ Request that the Postfix SMTP server rejects mail
+ from unknown sender addresses, even when no
+ explicit reject_unlisted_sender access restriction
is specified.
smtpd_reject_unlisted_recipient (yes)
- Request that the Postfix SMTP server rejects mail
+ Request that the Postfix SMTP server rejects mail
for unknown recipient addresses, even when no
- explicit reject_unlisted_recipient access restric-
+ explicit reject_unlisted_recipient access restric-
tion is specified.
Available in Postfix version 2.2 and later:
smtpd_end_of_data_restrictions (empty)
- Optional access restrictions that the Postfix SMTP
- server applies in the context of the SMTP END-OF-
+ Optional access restrictions that the Postfix SMTP
+ server applies in the context of the SMTP END-OF-
DATA command.
SENDER AND RECIPIENT ADDRESS VERIFICATION CONTROLS
- Postfix version 2.1 introduces sender and recipient
- address verification. This feature is implemented by
- sending probe email messages that are not actually deliv-
- ered. This feature is requested via the reject_unveri-
- fied_sender and reject_unverified_recipient access
- restrictions. The status of verification probes is main-
+ Postfix version 2.1 introduces sender and recipient
+ address verification. This feature is implemented by
+ sending probe email messages that are not actually deliv-
+ ered. This feature is requested via the reject_unveri-
+ fied_sender and reject_unverified_recipient access
+ restrictions. The status of verification probes is main-
tained by the verify(8) server. See the file ADDRESS_VER-
- IFICATION_README for information about how to configure
+ IFICATION_README for information about how to configure
and operate the Postfix sender/recipient address verifica-
tion service.
address_verify_poll_count (3)
- How many times to query the verify(8) service for
- the completion of an address verification request
+ How many times to query the verify(8) service for
+ the completion of an address verification request
in progress.
address_verify_poll_delay (3s)
- The delay between queries for the completion of an
+ The delay between queries for the completion of an
address verification request in progress.
address_verify_sender (postmaster)
- The sender address to use in address verification
+ The sender address to use in address verification
probes.
unverified_sender_reject_code (450)
- The numerical Postfix SMTP server response code
- when a recipient address is rejected by the
+ The numerical Postfix SMTP server response code
+ when a recipient address is rejected by the
reject_unverified_sender restriction.
unverified_recipient_reject_code (450)
- The numerical Postfix SMTP server response when a
+ The numerical Postfix SMTP server response when a
recipient address is rejected by the reject_unveri-
fied_recipient restriction.
ACCESS CONTROL RESPONSES
- The following parameters control numerical SMTP reply
+ The following parameters control numerical SMTP reply
codes and/or text responses.
access_map_reject_code (554)
- The numerical Postfix SMTP server response code
- when a client is rejected by an access(5) map
+ The numerical Postfix SMTP server response code
+ when a client is rejected by an access(5) map
restriction.
defer_code (450)
- The numerical Postfix SMTP server response code
- when a remote SMTP client request is rejected by
+ The numerical Postfix SMTP server response code
+ when a remote SMTP client request is rejected by
the "defer" restriction.
invalid_hostname_reject_code (501)
- The numerical Postfix SMTP server response code
- when the client HELO or EHLO command parameter is
- rejected by the reject_invalid_hostname restric-
+ The numerical Postfix SMTP server response code
+ when the client HELO or EHLO command parameter is
+ rejected by the reject_invalid_hostname restric-
tion.
maps_rbl_reject_code (554)
- The numerical Postfix SMTP server response code
+ The numerical Postfix SMTP server response code
when a remote SMTP client request is blocked by the
reject_rbl_client, reject_rhsbl_client,
reject_rhsbl_sender or reject_rhsbl_recipient
@@ -668,47 +672,47 @@ SMTPD(8) SMTPD(8)
non_fqdn_reject_code (504)
The numerical Postfix SMTP server reply code when a
- client request is rejected by the
+ client request is rejected by the
reject_non_fqdn_hostname, reject_non_fqdn_sender or
reject_non_fqdn_recipient restriction.
reject_code (554)
- The numerical Postfix SMTP server response code
- when a remote SMTP client request is rejected by
+ The numerical Postfix SMTP server response code
+ when a remote SMTP client request is rejected by
the "reject" restriction.
relay_domains_reject_code (554)
- The numerical Postfix SMTP server response code
- when a client request is rejected by the
+ The numerical Postfix SMTP server response code
+ when a client request is rejected by the
reject_unauth_destination recipient restriction.
unknown_address_reject_code (450)
- The numerical Postfix SMTP server response code
- when a sender or recipient address is rejected by
+ The numerical Postfix SMTP server response code
+ when a sender or recipient address is rejected by
the reject_unknown_sender_domain or
reject_unknown_recipient_domain restriction.
unknown_client_reject_code (450)
- The numerical Postfix SMTP server response code
- when a client without valid address <=> name map-
- ping is rejected by the reject_unknown_client
+ The numerical Postfix SMTP server response code
+ when a client without valid address <=> name map-
+ ping is rejected by the reject_unknown_client
restriction.
unknown_hostname_reject_code (450)
- The numerical Postfix SMTP server response code
- when the hostname specified with the HELO or EHLO
- command is rejected by the reject_unknown_hostname
+ The numerical Postfix SMTP server response code
+ when the hostname specified with the HELO or EHLO
+ command is rejected by the reject_unknown_hostname
restriction.
Available in Postfix version 2.0 and later:
default_rbl_reply (see 'postconf -d' output)
- The default SMTP server response template for a
- request that is rejected by an RBL-based restric-
+ The default SMTP server response template for a
+ request that is rejected by an RBL-based restric-
tion.
multi_recipient_bounce_reject_code (550)
- The numerical Postfix SMTP server response code
+ The numerical Postfix SMTP server response code
when a remote SMTP client request is blocked by the
reject_multi_recipient_bounce restriction.
@@ -717,16 +721,16 @@ SMTPD(8) SMTPD(8)
MISCELLANEOUS CONTROLS
config_directory (see 'postconf -d' output)
- The default location of the Postfix main.cf and
+ The default location of the Postfix main.cf and
master.cf configuration files.
daemon_timeout (18000s)
- How much time a Postfix daemon process may take to
- handle a request before it is terminated by a
+ How much time a Postfix daemon process may take to
+ handle a request before it is terminated by a
built-in watchdog timer.
command_directory (see 'postconf -d' output)
- The location of all postfix administrative com-
+ The location of all postfix administrative com-
mands.
double_bounce_sender (double-bounce)
@@ -747,36 +751,36 @@ SMTPD(8) SMTPD(8)
and most Postfix daemon processes.
max_idle (100s)
- The maximum amount of time that an idle Postfix
- daemon process waits for the next service request
+ The maximum amount of time that an idle Postfix
+ daemon process waits for the next service request
before exiting.
max_use (100)
- The maximal number of connection requests before a
+ The maximal number of connection requests before a
Postfix daemon process terminates.
myhostname (see 'postconf -d' output)
The internet hostname of this mail system.
mynetworks (see 'postconf -d' output)
- The list of "trusted" SMTP clients that have more
+ The list of "trusted" SMTP clients that have more
privileges than "strangers".
myorigin ($myhostname)
The domain name that locally-posted mail appears to
- come from, and that locally posted mail is deliv-
+ come from, and that locally posted mail is deliv-
ered to.
process_id (read-only)
- The process ID of a Postfix command or daemon pro-
+ The process ID of a Postfix command or daemon pro-
cess.
process_name (read-only)
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
queue_directory (see 'postconf -d' output)
- The location of the Postfix top-level queue direc-
+ The location of the Postfix top-level queue direc-
tory.
recipient_delimiter (empty)
@@ -784,22 +788,22 @@ SMTPD(8) SMTPD(8)
sions (user+foo).
smtpd_banner ($myhostname ESMTP $mail_name)
- The text that follows the 220 status code in the
+ The text that follows the 220 status code in the
SMTP greeting banner.
syslog_facility (mail)
The syslog facility of Postfix logging.
syslog_name (postfix)
- The mail system name that is prepended to the pro-
+ The mail system name that is prepended to the pro-
cess name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
Available in Postfix version 2.2 and later:
smtpd_forbidden_commands (CONNECT, GET, POST)
- List of commands that causes the Postfix SMTP
- server to immediately terminate the session with a
+ List of commands that causes the Postfix SMTP
+ server to immediately terminate the session with a
221 code.
SEE ALSO
@@ -826,7 +830,7 @@ SMTPD(8) SMTPD(8)
XFORWARD_README, Postfix XFORWARD extension
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/makedefs b/postfix/makedefs
index 3065eab80..42a0528e8 100644
--- a/postfix/makedefs
+++ b/postfix/makedefs
@@ -125,6 +125,9 @@ case "$SYSTEM.$RELEASE" in
# Use the native compiler by default
: ${CC=cc}
: ${DEBUG="-g3"}
+ case $RELEASE in
+ V[0-4].*) CCARGS="$CCARGS -DNO_IPV6";;
+ esac
;;
SunOS.4*) SYSTYPE=SUNOS4
SYSLIBS=-lresolv
@@ -132,14 +135,17 @@ case "$SYSTEM.$RELEASE" in
SunOS.5*) SYSTYPE=SUNOS5
RANLIB=echo
SYSLIBS="-lresolv -lsocket -lnsl"
+ # Solaris 8 added usleep() and POSIX regular expressions
case $RELEASE in
- 5.[0-4]) CCARGS="$CCARGS -DMISSING_USLEEP";;
- *) CCARGS="$CCARGS -DHAS_POSIX_REGEXP";;
+ 5.[0-4]) CCARGS="$CCARGS -DMISSING_USLEEP -DNO_POSIX_REGEXP";;
+ esac
+ # Solaris 8 added IPv6
+ case $RELEASE in
+ 5.[0-7]) CCARGS="$CCARGS -DNO_IPV6";;
esac
- CCARGS="$CCARGS -DCANT_WRITE_BEFORE_SENDING_FD"
# Solaris 9 added closefrom()
case $RELEASE in
- 5.9*|5.[1-9][0-9]*) CCARGS="$CCARGS -DHAS_CLOSEFROM";;
+ 5.[0-8]) CCARGS="$CCARGS -DNO_CLOSEFROM";;
esac
# Work around broken str*casecmp(). Do it all here instead
# of having half the solution in the sys_defs.h file.
@@ -236,6 +242,9 @@ case "$SYSTEM.$RELEASE" in
}
done
done
+ case "$RELEASE" in
+ 2.[0-3].*) CCARGS="$CCARGS -DNO_IPV6";;
+ esac
;;
IRIX*.5.*) SYSTYPE=IRIX5
# Use the native compiler by default
@@ -280,8 +289,10 @@ Rhapsody.5*|Darwin.*)
: ${CC=cc}
case $RELEASE in
1.[0-3]) AWK=gawk
+ CCARGS="$CCARGS -DNO_IPV6"
;;
[2-6].*) AWK=awk
+ CCARGS="$CCARGS -DNO_IPV6"
SYSLIBS=-flat_namespace
;;
*) AWK=awk
diff --git a/postfix/man/man1/postqueue.1 b/postfix/man/man1/postqueue.1
index c5af91802..682fd4585 100644
--- a/postfix/man/man1/postqueue.1
+++ b/postfix/man/man1/postqueue.1
@@ -57,7 +57,9 @@ attempt will be made until the mail is taken off hold.
.RE
.IP "\fB-s \fIsite\fR"
Schedule immediate delivery of all mail that is queued for the named
-\fIsite\fR. The site must be eligible for the "fast flush" service.
+\fIsite\fR. A numerical site must be specified as a valid RFC 2821
+address literal enclosed in [], just like in email addresses.
+The site must be eligible for the "fast flush" service.
See \fBflush\fR(8) for more information about the "fast flush"
service.
diff --git a/postfix/man/man1/qmqp-sink.1 b/postfix/man/man1/qmqp-sink.1
index d80b28080..07f6ad0e5 100644
--- a/postfix/man/man1/qmqp-sink.1
+++ b/postfix/man/man1/qmqp-sink.1
@@ -9,10 +9,10 @@ multi-threaded QMQP test server
.na
.nf
.fi
-\fBqmqp-sink\fR [\fB-cv\fR] [\fB-x \fItime\fR]
+\fBqmqp-sink\fR [\fB-46cv\fR] [\fB-x \fItime\fR]
[\fBinet:\fR][\fIhost\fR]:\fIport\fR \fIbacklog\fR
-\fBqmqp-sink\fR [\fB-cv\fR] [\fB-x \fItime\fR]
+\fBqmqp-sink\fR [\fB-46cv\fR] [\fB-x \fItime\fR]
\fBunix:\fR\fIpathname\fR \fIbacklog\fR
.SH DESCRIPTION
.ad
@@ -21,9 +21,16 @@ multi-threaded QMQP test server
It receives messages from the network and throws them away.
The purpose is to measure QMQP client performance, not protocol
compliance.
-Connections can be accepted on IPV4 endpoints or UNIX-domain sockets.
-IPV4 is the default.
+Connections can be accepted on IPv4 or IPv6 endpoints, or on
+UNIX-domain sockets.
+IPv4 and IPv6 are the default.
This program is the complement of the \fBqmqp-source\fR(1) program.
+.IP \fB-4\fR
+Support IPv4 only. This option has no effect when
+Postfix is built without IPv6 support.
+.IP \fB-6\fR
+Support IPv6 only. This option is not available when
+Postfix is built without IPv6 support.
.IP \fB-c\fR
Display a running counter that is updated whenever a delivery
is completed.
diff --git a/postfix/man/man1/qmqp-source.1 b/postfix/man/man1/qmqp-source.1
index 8c09df5c7..31455c45d 100644
--- a/postfix/man/man1/qmqp-source.1
+++ b/postfix/man/man1/qmqp-source.1
@@ -18,10 +18,16 @@ multi-threaded QMQP test generator
\fBqmqp-source\fR connects to the named host and TCP port (default 628)
and sends one or more messages to it, either sequentially
or in parallel. The program speaks the QMQP protocol.
-Connections can be made to UNIX-domain and IPV4 servers.
-IPV4 is the default.
+Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
+IPv4 and IPv6 are the default.
Options:
+.IP \fB-4\fR
+Connect to the server with IPv4. This option has no effect when
+Postfix is built without IPv6 support.
+.IP \fB-6\fR
+Connect to the server with IPv6. This option is not available when
+Postfix is built without IPv6 support.
.IP \fB-c\fR
Display a running counter that is incremented each time
a delivery completes.
diff --git a/postfix/man/man1/sendmail.1 b/postfix/man/man1/sendmail.1
index f82837eeb..f35a4529b 100644
--- a/postfix/man/man1/sendmail.1
+++ b/postfix/man/man1/sendmail.1
@@ -125,6 +125,8 @@ Backwards compatibility.
Non-default alias database. Specify \fIpathname\fR or
\fItype\fR:\fIpathname\fR. See \fBpostalias\fR(1) for
details.
+.IP "\fB-O \fIoption=value\fR (ignored)"
+Backwards compatibility.
.IP "\fB-o7\fR (ignored)"
.IP "\fB-o8\fR (ignored)"
To send 8-bit or binary content, use an appropriate MIME encapsulation
diff --git a/postfix/man/man1/smtp-sink.1 b/postfix/man/man1/smtp-sink.1
index 6b1262dca..0a2ac7575 100644
--- a/postfix/man/man1/smtp-sink.1
+++ b/postfix/man/man1/smtp-sink.1
@@ -21,11 +21,18 @@ It takes SMTP messages from the network and throws them away.
The purpose is to measure client performance, not protocol
compliance.
-Connections can be accepted on IPV4 endpoints or UNIX-domain sockets.
-IPV4 is the default.
+Connections can be accepted on IPv4 or IPv6 endpoints, or on
+UNIX-domain sockets.
+IPv4 and IPv6 are the default.
This program is the complement of the \fBsmtp-source\fR(1) program.
Arguments:
+.IP \fB-4\fR
+Support IPv4 only. This option has no effect when
+Postfix is built without IPv6 support.
+.IP \fB-6\fR
+Support IPv6 only. This option is not available when
+Postfix is built without IPv6 support.
.IP \fB-a\fR
Do not announce SASL authentication support.
.IP \fB-c\fR
diff --git a/postfix/man/man1/smtp-source.1 b/postfix/man/man1/smtp-source.1
index 7ecff0351..2b588bdd2 100644
--- a/postfix/man/man1/smtp-source.1
+++ b/postfix/man/man1/smtp-source.1
@@ -19,10 +19,17 @@ multi-threaded SMTP/LMTP test generator
(default: port 25)
and sends one or more messages to it, either sequentially
or in parallel. The program speaks either SMTP (default) or
-LMTP. Connections can be made to UNIX-domain and IPV4 servers.
-IPV4 is the default.
+LMTP.
+Connections can be made to UNIX-domain and IPv4 or IPv6 servers.
+IPv4 and IPv6 are the default.
Arguments:
+.IP \fB-4\fR
+Connect to the server with IPv4. This option has no effect when
+Postfix is built without IPv6 support.
+.IP \fB-6\fR
+Connect to the server with IPv6. This option is not available when
+Postfix is built without IPv6 support.
.IP \fB-c\fR
Display a running counter that is incremented each time
an SMTP DATA command completes.
diff --git a/postfix/man/man5/access.5 b/postfix/man/man5/access.5
index 57e90dcdc..5a4c816aa 100644
--- a/postfix/man/man5/access.5
+++ b/postfix/man/man5/access.5
@@ -19,7 +19,7 @@ format of Postfix access table
The optional \fBaccess\fR table directs the Postfix SMTP server
to selectively reject or accept mail. Access can be allowed or
denied for specific host names, domain names, networks, host
-network addresses or mail addresses.
+addresses or mail addresses.
For an example, see the EXAMPLE section at the end of this
manual page.
@@ -110,11 +110,46 @@ order to match subdomains.
.IP \fInet.work.addr\fR
.IP \fInet.work\fR
.IP \fInet\fR
-Matches any host address in the specified network. A network
-address is a sequence of one or more octets separated by ".".
+Matches the specified IPv4 host address or subnetwork. An
+IPv4 host address is a sequence of four decimal octets
+separated by ".".
-NOTE: use the \fBcidr\fR lookup table type to specify
+Subnetworks are matched by repeatedly truncating the last
+".octet" from the remote IPv4 host address string until a
+match is found in the access table, or until further
+truncation is not possible.
+
+NOTE 1: The information in the access map should be in
+canonical form, with unnecessary null characters eliminated.
+Address information must not be enclosed with "[]" characters.
+
+NOTE 2: use the \fBcidr\fR lookup table type to specify
network/netmask patterns. See cidr_table(5) for details.
+.IP \fInet:work:addr:ess\fR
+.IP \fInet:work:addr\fR
+.IP \fInet:work\fR
+.IP \fInet\fR
+Matches the specified IPv6 host address or subnetwork. An
+IPv6 host address is a sequence of three to eight hexadecimal
+octet pairs separated by ":".
+
+Subnetworks are matched by repeatedly truncating the last
+":octetpair" from the remote IPv6 host address string until
+a match is found in the access table, or until further
+truncation is not possible.
+
+NOTE 1: the truncation and comparison are done with the
+string representation of the IPv6 host address. Thus, not
+all the ":" subnetworks will be tried.
+
+NOTE 2: The information in the access map should be in
+canonical form, with unnecessary null characters eliminated.
+Address information must not be enclosed with "[]" characters.
+
+NOTE 3: use the \fBcidr\fR lookup table type to specify
+network/netmask patterns. See cidr_table(5) for details.
+
+IPv6 support is available in Postfix 2.2 and later.
.SH "ACCEPT ACTIONS"
.na
.nf
diff --git a/postfix/man/man5/cidr_table.5 b/postfix/man/man5/cidr_table.5
index ae6ef06cc..7428a468d 100644
--- a/postfix/man/man5/cidr_table.5
+++ b/postfix/man/man5/cidr_table.5
@@ -33,7 +33,13 @@ The general form of a Postfix CIDR table is:
.IP "\fInetwork_address\fB/\fInetwork_mask result\fR"
When a search string matches the specified network block,
use the corresponding \fIresult\fR value. Specify
-0.0.0.0/0 to match every address.
+0.0.0.0/0 to match every IPv4 address, and ::/0 to match
+every IPv6 address.
+
+Note: address information may be enclosed inside "[]" but
+this form is not recommended.
+
+IPv6 support is available in Postfix 2.2 and later.
.IP "\fInetwork_address result\fR"
When a search string matches the specified network address,
use the corresponding \fIresult\fR value.
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index 3e1559eed..01dd03408 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -461,6 +461,12 @@ pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+.PP
+Note: IP version 6 address information must be specified inside
+[] in the authorized_verp_clients value, and in files
+specified with "/file/name". IP version 6 addresses contain the
+":" character, and would otherwise be confused with a "type:table"
+pattern.
.SH backwards_bounce_logfile_compatibility (default: yes)
Produce additional bounce(8) logfile records that can be read by
older Postfix versions. The current and more extensible "name =
@@ -1191,10 +1197,16 @@ the hash_queue_names parameter.
.PP
After changing the hash_queue_names or hash_queue_depth parameter,
execute the command "\fBpostfix reload\fR".
-.SH hash_queue_names (default: see "postconf -d" output)
+.SH hash_queue_names (default: deferred, defer)
The names of queue directories that are split across multiple
subdirectory levels.
.PP
+Before Postfix version 2.2, the default list of hashed queues
+was significantly larger. Claims about improvements in file system
+technology suggest that hashing of the incoming and active queues
+is no longer needed. Fewer hashed directories speed up the time
+needed to restart Postfix.
+.PP
After changing the hash_queue_names or hash_queue_depth parameter,
execute the command "\fBpostfix reload\fR".
.SH header_address_token_limit (default: 10240)
@@ -1276,32 +1288,93 @@ number of messages delivered per second.
.PP
Specify 0 to disable the feature. Valid delays are 0..10.
.SH inet_interfaces (default: all)
-The network interface addresses that this mail system receives mail
-on. By default, the software claims all active interfaces on the
-machine. The parameter also controls delivery of mail to
-user@[ip.address].
+The network interface addresses that this mail system receives
+mail on. By default, the software claims all active interfaces on
+the machine; with Postfix 2.2 and later, specify "\fBloopback-only\fR"
+to select only local interfaces. The parameter also controls
+delivery of mail to user@[ip.address].
.PP
-When inet_interfaces consists of just one IP address that is not a
-loopback (net 127) address, the Postfix SMTP client will use this address
-as the IP source address for outbound mail.
+Note: you need to stop and start Postfix when this parameter changes.
+.PP
+When inet_interfaces specifies just one IPv4 and/or IPv6 address
+that is not a loopback address, the Postfix SMTP client will use
+this address as the IP source address for outbound mail.
.PP
On a multi-homed firewall with separate Postfix instances listening on the
"inside" and "outside" interfaces, this can prevent each instance from
being able to reach servers on the "other side" of the firewall. Setting
-smtp_bind_address to 0.0.0.0 avoids the potential problem.
+smtp_bind_address to 0.0.0.0 avoids the potential problem for
+IPv4, and setting smtp_bind_address6 to :: solves the problem
+for IPv6.
.PP
-A better solution is to leave inet_interfaces at the default value
+A better solution for multi-homed firewalls is to leave inet_interfaces
+at the default value
and instead use explicit IP addresses in master.cf. This preserves SMTP
loop detection, by ensuring that each side of the firewall knows that the
other IP address is still the same host. Setting $inet_interfaces to a
-single IP address is primarily useful with virtual hosting of domains on
+single IPv4 and/or IPV6 address is primarily useful with virtual
+hosting of domains on
secondary IP addresses, when each IP address serves a different domain
(and has a different $myhostname setting).
.PP
See also the proxy_interfaces parameter, for network addresses that
-are forwarded to us by way of a proxy or address translator.
+are forwarded to Postfix by way of a proxy or address translator.
.PP
-Note: you need to stop and start Postfix when this parameter changes.
+Examples:
+.PP
+.nf
+.na
+.ft C
+inet_interfaces = all (DEFAULT)
+inet_interfaces = loopback-only
+inet_interfaces = 127.0.0.1
+inet_interfaces = 192.168.1.2, 127.0.0.1
+.fi
+.ad
+.ft R
+.SH inet_protocols (default: ipv4)
+The Internet protocols Postfix will attempt to use when making
+or accepting connections. Specify one or more of "ipv4" or "ipv6",
+separated by whitespace or commas. The form "all" is equivalent to
+"ipv4, ipv6".
+.PP
+Note: you MUST stop and start Postfix after changing this
+parameter.
+.PP
+On systems that pre-date IPV6_V6ONLY support (RFC 3493), an
+IPv6 server will also accept IPv4 connections, even when IPv4 is
+turned off with the inet_protocols parameter. On systems with
+IPV6_V6ONLY support, Postfix will use separate server sockets for
+IPv6 and IPv4, and each will accept only connections for the
+corresponding protocol.
+.PP
+When IPv4 support is enabled via the inet_protocols parameter,
+Postfix will to DNS type A record lookups, and will convert
+IPv4-in-IPv6 client IP addresses (::ffff:1.2.3.4) to their original
+IPv4 form (1.2.3.4). The latter is needed on hosts that pre-date
+IPV6_V6ONLY support (RFC 3493).
+.PP
+When IPv6 support is enabled via the inet_protocols parameter,
+Postfix will do DNS type AAAA record lookups.
+.PP
+When both IPv4 and IPv6 support are enabled, the Postfix SMTP
+client will attempt to connect via IPv6 before attempting to use
+IPv4.
+.PP
+This feature is available in Postfix version 2.2 and later.
+.PP
+Examples:
+.PP
+.nf
+.na
+.ft C
+inet_protocols = ipv4 (DEFAULT)
+inet_protocols = all
+inet_protocols = ipv6
+inet_protocols = ipv4, ipv6
+.fi
+.ad
+.ft R
.SH initial_destination_concurrency (default: 5)
The initial per-destination concurrency level for parallel delivery
to the same destination. This limit applies to delivery via smtp(8),
@@ -2150,13 +2223,19 @@ The list is matched left to right, and the search stops on the
first match. Specify "!pattern" to exclude an address or network
block from the list.
.PP
+Note: IP version 6 address information must be specified inside
+[] in the mynetworks value, and in files specified with
+"/file/name". IP version 6 addresses contain the ":" character,
+and would otherwise be confused with a "type:table" pattern.
+.PP
Examples:
.PP
.nf
.na
.ft C
-mynetworks = 168.100.189.0/28, 127.0.0.0/8
+mynetworks = 127.0.0.0/8 168.100.189.0/28
mynetworks = !192.168.0.1, 192.168.0.0/28
+mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:5c7::]/64
mynetworks = $config_directory/mynetworks
mynetworks = hash:/etc/postfix/network_table
.fi
@@ -2924,7 +3003,7 @@ the word "ESMTP" appears in the server greeting banner (example:
220 spike.porcupine.org ESMTP Postfix).
.SH smtp_bind_address (default: empty)
An optional numerical network address that the SMTP client should
-bind to when making a connection.
+bind to when making an IPv4 connection.
.PP
This can be specified in the main.cf file for all SMTP clients, or
it can be specified in the master.cf file for a specific client,
@@ -2939,11 +3018,41 @@ for example:
.ad
.ft R
.PP
-Note: when inet_interfaces specifies exactly one address that
-is a non-loopback address, it is automatically used as the
-smtp_bind_address. This supports virtual IP hosting, but can be
-a problem on multi-homed firewalls. See the inet_interfaces
-documentation for more detail.
+Note 1: when inet_interfaces specifies no more than one IPv4
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail.
+.PP
+Note 2: address information may be enclosed inside [],
+but this form is not recommended.
+.SH smtp_bind_address6 (default: empty)
+An optional numerical network address that the SMTP client should
+bind to when making an IPv6 connection.
+.PP
+This can be specified in the main.cf file for all SMTP clients, or
+it can be specified in the master.cf file for a specific client,
+for example:
+.PP
+.nf
+.na
+.ft C
+ /etc/postfix/master.cf:
+ smtp ... smtp -o smtp_bind_address6=1:2:3:4:5:6:7:8
+.fi
+.ad
+.ft R
+.PP
+Note 1: when inet_interfaces specifies no more than one IPv6
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address6. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail.
+.PP
+Note 2: address information may be enclosed inside [],
+but this form is not recommended.
+.PP
+This feature is available in Postfix version 2.2 and later.
.SH smtp_connect_timeout (default: 30s)
The SMTP client time limit for completing a TCP connection, or
zero (use the operating system built-in time limit).
@@ -3321,6 +3430,12 @@ pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+.PP
+Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_verp_clients value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
.SH smtpd_authorized_xclient_hosts (default: empty)
What SMTP clients are allowed to use the XCLIENT feature. This
command overrides SMTP client information that is used for access
@@ -3341,6 +3456,12 @@ pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+.PP
+Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_xclient_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
.SH smtpd_authorized_xforward_hosts (default: empty)
What SMTP clients are allowed to use the XFORWARD feature. This
command forwards information that is used to improve logging after
@@ -3360,6 +3481,12 @@ pattern is replaced by its contents; a "type:table" lookup table
is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+.PP
+Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_xforward_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
.SH smtpd_banner (default: $myhostname ESMTP $mail_name)
The text that follows the 220 status code in the SMTP greeting
banner. Some people like to see the mail version advertised. By
@@ -3420,6 +3547,12 @@ By default, clients in trusted networks are excluded. Specify a
list of network blocks, hostnames or .domain names (the initial
dot causes the domain to match any name below it).
.PP
+Note: IP version 6 address information must be specified inside
+[] in the smtpd_client_event_limit_exceptions value, and
+in files specified with "/file/name". IP version 6 addresses
+contain the ":" character, and would otherwise be confused with a
+"type:table" pattern.
+.PP
This feature is available in Postfix 2.2 and later.
.SH smtpd_client_message_rate_limit (default: 0)
The maximal number of message delivery requests that any client is
@@ -4140,6 +4273,12 @@ contents; a "type:table" lookup table is matched when a table entry
matches a lookup string (the lookup result is ignored). Continue
long lines by starting the next line with whitespace.
.PP
+Note: IP version 6 address information must be specified inside
+[] in the smtpd_sasl_exceptions_networks value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+.PP
Example:
.PP
.nf
@@ -4766,7 +4905,7 @@ virtual(8) delivery agent will terminate with a fatal error.
Optional lookup tables with a) names of domains for which all
addresses are aliased to addresses in other local or remote domains,
and b) addresses that are aliased to addresses in other local or
-remote domains. Available before Postfix version 2.0. With Postfix 2.1
+remote domains. Available before Postfix version 2.0. With Postfix 2.0
and later, this is replaced by separate controls: virtual_alias_domains
and virtual_alias_maps.
.SH virtual_minimum_uid (default: 100)
diff --git a/postfix/man/man8/master.8 b/postfix/man/man8/master.8
index 399f0a47c..6812e568a 100644
--- a/postfix/man/man8/master.8
+++ b/postfix/man/man8/master.8
@@ -92,9 +92,6 @@ Use the \fBpostfix reload\fR command after a configuration change.
.nf
.ad
.fi
-.IP "\fBdaemon_timeout (18000s)\fR"
-How much time a Postfix daemon process may take to handle a
-request before it is terminated by a built-in watchdog timer.
.IP "\fBdefault_process_limit (100)\fR"
The default maximal number of Postfix child processes that provide
a given service.
@@ -123,6 +120,9 @@ invoked with the -D option.
.IP "\fBinet_interfaces (all)\fR"
The network interface addresses that this mail system receives mail
on.
+.IP "\fBinet_protocols (ipv4)\fR"
+The Internet protocols Postfix will attempt to use when making
+or accepting connections.
.IP "\fBimport_environment (see 'postconf -d' output)\fR"
The list of environment parameters that a Postfix process will
import from a non-Postfix parent process.
diff --git a/postfix/man/man8/qmqpd.8 b/postfix/man/man8/qmqpd.8
index ab485206f..52f3d5701 100644
--- a/postfix/man/man8/qmqpd.8
+++ b/postfix/man/man8/qmqpd.8
@@ -65,7 +65,7 @@ The name of a mail delivery transport that filters mail after
it is queued.
.IP "\fBreceive_override_options (empty)\fR"
Enable or disable recipient validation, built-in content
-filtering, or address rewriting.
+filtering, or address mapping.
.SH "RESOURCE AND RATE CONTROLS"
.na
.nf
diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8
index 806325d56..303b11d94 100644
--- a/postfix/man/man8/smtp.8
+++ b/postfix/man/man8/smtp.8
@@ -279,8 +279,11 @@ Disable DNS lookups in the Postfix SMTP and LMTP clients.
Optional list of relay hosts for SMTP destinations that can't be
found or that are unreachable.
.IP "\fBinet_interfaces (all)\fR"
-The network interface addresses that this mail system receives mail
-on.
+The network interface addresses that this mail system receives
+mail on.
+.IP "\fBinet_protocols (ipv4)\fR"
+The Internet protocols Postfix will attempt to use when making
+or accepting connections.
.IP "\fBipc_timeout (3600s)\fR"
The time limit for sending or receiving information over an internal
communication channel.
@@ -299,7 +302,10 @@ The network interface addresses that this mail system receives mail
on by way of a proxy or network address translation unit.
.IP "\fBsmtp_bind_address (empty)\fR"
An optional numerical network address that the SMTP client should
-bind to when making a connection.
+bind to when making an IPv4 connection.
+.IP "\fBsmtp_bind_address6 (empty)\fR"
+An optional numerical network address that the SMTP client should
+bind to when making an IPv6 connection.
.IP "\fBsmtp_helo_name ($myhostname)\fR"
The hostname to send in the SMTP EHLO or HELO command.
.IP "\fBsmtp_host_lookup (dns)\fR"
diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8
index bc774a3ff..5a37a5c3d 100644
--- a/postfix/man/man8/smtpd.8
+++ b/postfix/man/man8/smtpd.8
@@ -290,11 +290,14 @@ Parameters concerning known/unknown local recipients:
The list of domains that are delivered via the $local_transport
mail delivery transport.
.IP "\fBinet_interfaces (all)\fR"
-The network interface addresses that this mail system receives mail
-on.
+The network interface addresses that this mail system receives
+mail on.
.IP "\fBproxy_interfaces (empty)\fR"
The network interface addresses that this mail system receives mail
on by way of a proxy or network address translation unit.
+.IP "\fBinet_protocols (ipv4)\fR"
+The Internet protocols Postfix will attempt to use when making
+or accepting connections.
.IP "\fBlocal_recipient_maps (proxy:unix:passwd.byname $alias_maps)\fR"
Lookup tables with all names or addresses of local recipients:
a recipient address is local when its domain matches $mydestination,
diff --git a/postfix/mantools/ccformat b/postfix/mantools/ccformat
index 83e1550b3..3573a6dc8 100755
--- a/postfix/mantools/ccformat
+++ b/postfix/mantools/ccformat
@@ -17,7 +17,7 @@ TMPF=/tmp/ccformat.$$
ERROR=
TROFF=
BCK=
-FLAGS="-st -di8 -npsl -bap -bad -bbb -bc -i4 -d0 -nip -nfc1 -cd41 -c49"
+FLAGS="-st -di8 -npsl -bap -bad -bbb -nbc -i4 -d0 -nip -nfc1 -cd41 -c49"
trap 'rm -f .ind.$$ $TMPF; exit 1' 1 2 3 15
diff --git a/postfix/mantools/makereadme b/postfix/mantools/makereadme
index e6a063d90..de066c1e0 100755
--- a/postfix/mantools/makereadme
+++ b/postfix/mantools/makereadme
@@ -4,7 +4,7 @@ sed '
s/<\/*table[^>]*>//g
s/<\/th[^>]*>//g
s/<\/td[^>]*>//g
- s/"\([A-Z_]*\)\.html">/&\1:/
+ s/"\([A-Z0-9_]*\)\.html">/&\1:/
s/All main.cf parameters/postconf(5): &/
/All Postfix manual pages/d
' "$@"
diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink
index 86fce3dcb..fcb5bda72 100755
--- a/postfix/mantools/postlink
+++ b/postfix/mantools/postlink
@@ -181,6 +181,7 @@ while (<>) {
s;\bimport_environment\b;$&;g;
s;\bin_flow_delay\b;$&;g;
s;\binet_interfaces\b;$&;g;
+ s;\binet_protocols\b;$&;g;
s;\binitial_destination_concurrency\b;$&;g;
s;\binvalid_hostname_reject_code\b;$&;g;
s;\bipc_idle\b;$&;g;
@@ -310,6 +311,7 @@ while (<>) {
s;\bshowq_service_name\b;$&;g;
s;\bsmtp_always_send_ehlo\b;$&;g;
s;\bsmtp_bind_address\b;$&;g;
+ s;\bsmtp_bind_address6\b;$&;g;
s;\bsmtp_connect_timeout\b;$&;g;
s;\bsmtp_connection_cache_on_demand\b;$&;g;
diff --git a/postfix/mantools/xpostdef b/postfix/mantools/xpostdef
index 053610734..b3820ddc2 100755
--- a/postfix/mantools/xpostdef
+++ b/postfix/mantools/xpostdef
@@ -40,7 +40,6 @@ execution_directory_expansion_filter
export_environment
forward_expansion_filter
forward_path
-hash_queue_names
html_directory
import_environment
mail_release_date
diff --git a/postfix/proto/FILTER_README.html b/postfix/proto/FILTER_README.html
index e2e410927..cdd9e5dfc 100644
--- a/postfix/proto/FILTER_README.html
+++ b/postfix/proto/FILTER_README.html
@@ -802,7 +802,7 @@ content filtering turned on.
# (yes) (yes) (yes) (never) (100)
# =================================================================
1.2.3.5:smtp inet n - n - - smtpd
- -o content_filter=foo:bar
+ -o content_filter=filter-service:filter-destination
-o receive_override_options=no_address_mappings
@@ -828,14 +828,14 @@ address provides a different content filter service.
# service type private unpriv chroot wakeup maxproc command
# (yes) (yes) (yes) (never) (100)
# =================================================================
- # SMTP service for domains that are content filtered with foo:bar
+ # SMTP service for domains that are filtered with service1:dest1
1.2.3.4:smtp inet n - n - - smtpd
- -o content_filter=foo:bar
+ -o content_filter=service1:dest1
-o receive_override_options=no_address_mappings
- # SMTP service for domains that are content filtered with xxx:yyy
+ # SMTP service for domains that are filtered with service2:dest2
1.2.3.5:smtp inet n - n - - smtpd
- -o content_filter=xxx:yyy
+ -o content_filter=service2:dest2
-o receive_override_options=no_address_mappings
diff --git a/postfix/proto/IPV6_README.html b/postfix/proto/IPV6_README.html
new file mode 100644
index 000000000..88cf5808b
--- /dev/null
+++ b/postfix/proto/IPV6_README.html
@@ -0,0 +1,370 @@
+
+
+
+
+
+
+Postfix IPv6 Support
+
+
+
+
+
+
+
+
Postfix
+IPv6 Support
+
+
+
+Introduction
+
+ Postfix 2.2 introduces support for the IPv6 (IP version 6)
+protocol, whose main feature of interest is that it uses 128-bit
+IP addresses instead of the 32-bit addresses used by IPv4.
+
+ With this, Postfix can use the same SMTP protocol over IPv6 as
+it already uses over the older IPv4 network, and Postfix can do
+AAAA record lookups in the DNS in addition to the older A records.
+Information about IPv6 can be found at http://www.ipv6.org/.
+
+ This document provides information on the following topics:
+
+
+
+
+
+
+ Postfix version 2.2 supports IPv4 and IPv6 on the following
+platforms:
+
+
+
+- AIX 5.1+
+
- Darwin 7.3+
+
- FreeBSD 4+
+
- Linux 2.4+
+
- NetBSD 1.5+
+
- OpenBSD 2+
+
- Solaris 8+
+
- Tru64Unix V5.1+
+
+
+
+ On other platforms Postfix will simply use IPv4 as it has always
+done.
+
+ See below for tips how to port Postfix
+IPv6 support to other environments.
+
+
+
+ Postfix IPv6 support introduces two new main.cf configuration
+parameters, and introduces an important change in address syntax
+notation in match lists such as mynetworks or
+debug_peer_list.
+
+ Postfix IPv6 address syntax is a little tricky, because there
+are a few places where you must enclose IPv6 address inside
+[] characters, and a few places where you must not. It is
+a good idea to use [] only in the few places where you
+have to. Check out the postconf(5) manual whenever you do IPv6
+related configuration work with Postfix.
+
+
+
+-
The new inet_protocols parameter specifies what
+IP protocols Postfix will use. This parameter also controls what
+DNS lookups Postfix will do.
+
+
+
+/etc/postfix/main.cf:
+ # You must stop/start Postfix after changing this parameter.
+ inet_protocols = ipv4 (DEFAULT: enable IPv4 only)
+ inet_protocols = all (enable both IPv4 and IPv6)
+ inet_protocols = ipv4, ipv6 (enable both IPv4 and IPv6)
+ inet_protocols = ipv6 (enable IPv6 only)
+
+
+
+ By default, Postfix uses IPv4 only, because most systems aren't
+attached to an IPv6 network.
+
+
+
+-
On systems with combined IPv4/IPv6 stacks, attempts to
+deliver mail via IPv6 would always fail with "network unreachable",
+and those attempts would only slow down Postfix.
+
+ -
Linux kernels don't even load IPv6 protocol support by
+default. Any attempt to use it would fail immediately.
+
+
+
+ Note 1: you must stop and start Postfix after changing the
+inet_protocols configuration parameter.
+
+ Note 2: if you see error messages like the following, then
+you're running Linux and need to turn on IPv6 in the kernel: see
+http://www.ipv6.org/ for hints and tips. Unlike other systems,
+Linux does not have a combined stack for IPv4 and IPv6, and IPv6
+protocol support is not loaded by default.
+
+
+
+postconf: warning: inet_protocols: IPv6 support is disabled: Address family not supported by protocol
+postconf: warning: inet_protocols: configuring for IPv4 support only
+
+
+
+ Note 3: on older Linux and Solaris systems, the setting
+"inet_protocols = ipv6" will not prevent Postfix from
+accepting IPv4 connections. Postfix will present the client IP
+addresses in IPv6 format, though. In all other cases, Postfix always
+presents IPv4 client IP addresses in the traditional dotted quad
+IPv4 format.
+
+ -
The other new parameter is smtp_bind_address6.
+This sets the local interface address for outgoing IPv6 SMTP
+connections, just like the smtp_bind_address parameter
+does for IPv4:
+
+
+
+/etc/postfix/main.cf:
+ smtp_bind_address6 = 2001:240:5c7:0:250:56ff:fe89:1
+
+
+
+ -
If you left the value of the mynetworks parameter at its
+default (i.e. no mynetworks setting in main.cf) Postfix will figure
+out by itself what its network addresses are. This is what a typical
+setting looks like:
+
+
+
+% postconf mynetworks
+mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [fe80::]/10 [2001:240:5c7::]/64
+
+
+
+ If you did specify the mynetworks parameter value in
+main.cf, you need update the mynetworks value to include
+the IPv6 networks the system is in. Be sure to specify IPv6 address
+information inside [], like this:
+
+
+
+/etc/postfix/main.cf:
+ mynetworks = ...IPv4 networks... [::1]/128 [2001:240:5c7::]/64 ...
+
+
+
+
+
+ NOTE: when configuring Postfix match lists such as
+mynetworks or debug_peer_list, you must specify
+IPv6 address information inside [] in the main.cf parameter
+value and in files specified with a "/file/name" pattern.
+IPv6 addresses contain the ":" character, and would otherwise be
+confused with a "type:table" pattern.
+
+
+
+
+
+-
The order of IPv6/IPv4 outgoing connection attempts is
+not yet configurable. Currently, IPv6 is tried before IPv4.
+
+ -
Postfix currently does not support DNSBL (real-time
+blackhole list) lookups for IPv6 client IP addresses; currently
+there are no blacklists that cover the IPv6 address space.
+
+ -
IPv6 does not have class A, B, C, etc. networks. With IPv6
+networks, the setting "mynetworks_style = class" has the
+same effect as the setting "mynetworks_style = subnet".
+
+
+ -
On Tru64Unix, Postfix can't figure out the local subnet mask
+and always assumes a /128 network. This is a problem only with
+"mynetworks_style = subnet" and no explicit mynetworks
+setting in main.cf.
+
+
+
+
+
+ Postfix version 2.2 IPv6 support is based on the Postfix/IPv6 patch
+by Dean Strik and others, but differs in a few minor ways.
+
+
+
+-
main.cf: The inet_interfaces parameter does not support
+the notation "ipv6:all" or "ipv4:all". Use the
+inet_protocols parameter instead.
+
+ -
main.cf: Specify "inet_protocols = all" or
+"inet_protocols = ipv4, ipv6" in order to enable both IPv4
+and IPv6 support.
+
+ -
main.cf: The inet_protocols parameter also controls
+what DNS lookups Postfix will attempt to make when delivering or
+receiving mail.
+
+ -
main.cf: Specify "inet_interfaces = loopback-only"
+to listen on loopback network interfaces only.
+
+ -
The lmtp_bind_address and lmtp_bind_address6
+features were omitted. The Postfix LMTP client will be absorbed
+into the SMTP client, so there is no reason to keep adding features
+to the LMTP client.
+
+ -
The SMTP server now requires that IPv6 addresses in SMTP
+commands are specified as [ipv6:ipv6address], as
+described in RFC 2821.
+
+ -
The IPv6 network address matching code was rewritten from
+the ground up, and is expected to be closer to the specification.
+The result may be incompatible with the Postfix/IPv6 patch.
+
+
+
+
+
+
+ Getting Postfix IPv6 working on other platforms involves the
+following steps:
+
+
+
+-
Specify how Postfix should find the local network interfaces.
+Postfix needs this information to avoid mailer loops and to find out
+if mail for user@[ipaddress] is a local or remote destination.
+
+ If your system has the getifaddrs() routine then add
+the following to your platform-specific section in
+src/util/sys_defs.h:
+
+
+
+#ifndef NO_IPV6
+# define HAS_IPV6
+# define HAVE_GETIFADDRS
+#endif
+
+
+
+ Otherwise, if your system has the SIOCGLIF ioctl()
+command in /usr/include/*/*.h, add the following to your
+platform-specific section in src/util/sys_defs.h:
+
+
+
+#ifndef NO_IPV6
+# define HAS_IPV6
+# define HAS_SIOCGLIF
+#endif
+
+
+
+ Otherwise, Postfix will have to use the old SIOCGIF commands
+and get along with reduced IPv6 functionality (it won't be able to
+figure out your IPv6 netmasks, which are needed for "mynetworks_style
+= subnet". Add this to your platform-specific section in
+src/util/sys_defs.h:
+
+
+
+#ifndef NO_IPV6
+# define HAS_IPV6
+#endif
+
+
+
+ -
Test if Postfix can figure out its interface information.
+
+ After compiling Postfix in the usual manner, step into the
+src/util directory and type "make inet_addr_local".
+Running this file by hand should produce all the interface addresses
+and network masks, for example:
+
+
+
+% make
+% cd src/util
+% make inet_addr_local
+[... some messages ...]
+% ./inet_addr_local
+[... some messages ...]
+./inet_addr_local: inet_addr_local: configured 2 IPv4 addresses
+./inet_addr_local: inet_addr_local: configured 4 IPv6 addresses
+168.100.189.2/255.255.255.224
+127.0.0.1/255.0.0.0
+fe80:1::2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+2001:240:5c7:0:2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+fe80:5::1/ffff:ffff:ffff:ffff::
+::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+
+
+
+ The above is for an old FreeBSD machine. Other systems produce
+slightly different results, but you get the idea.
+
+
+
+ If none of all this produces a usable result, send email to the
+postfix-users@postfix.org mailing list and we'll try to help you
+through this.
+
+
+
+ The following information is in part based on information that
+was compiled by Dean Strik.
+
+
+
+-
Mark Huizer wrote the original Postfix IPv6 patch.
+
+ -
Jun-ichiro 'itojun' Hagino of the KAME project made
+substantial improvements. Since then, we speak of the KAME patch.
+
+
+ -
The PLD Linux Distribution ported the code to other stacks
+(notably USAGI). We speak of the PLD patch. A very important
+feature of the PLD patch was that it can work with Lutz Jaenicke's
+TLS patch for Postfix.
+
+ -
Dean Strik extended IPv6 support to platforms other than
+KAME and USAGI, updated the patch to keep up with Postfix development,
+and provided a combined IPv6 + TLS patch. Information about his
+effort can be found on Dean Strik's Postfix website at
+http://www.ipnet6.org/postfix/.
+
+ -
Wietse Venema took Dean Strik's IPv6 patch, merged it into
+Postfix 2.2, and took the opportunity to eliminate all IPv4-specific
+code from Postfix that could be removed. For systems without IPv6
+support in the kernel and system libraries, Postfix has a simple
+compatibility layer, so that it will use IPv4 as before.
+
+
+
+
+
+
diff --git a/postfix/proto/Makefile.in b/postfix/proto/Makefile.in
index 2b8b84007..c5e18f55e 100644
--- a/postfix/proto/Makefile.in
+++ b/postfix/proto/Makefile.in
@@ -17,7 +17,8 @@ HTML = ../html/ADDRESS_CLASS_README.html \
../html/DATABASE_README.html ../html/DB_README.html \
../html/DEBUG_README.html \
../html/ETRN_README.html ../html/FILTER_README.html \
- ../html/INSTALL.html ../html/LDAP_README.html \
+ ../html/INSTALL.html ../html/IPV6_README.html \
+ ../html/LDAP_README.html \
../html/LINUX_README.html ../html/LMTP_README.html \
../html/LOCAL_RECIPIENT_README.html ../html/MAILDROP_README.html \
../html/MYSQL_README.html ../html/NFS_README.html \
@@ -48,7 +49,8 @@ README = ../README_FILES/ADDRESS_CLASS_README \
../README_FILES/DATABASE_README ../README_FILES/DB_README \
../README_FILES/DEBUG_README \
../README_FILES/ETRN_README ../README_FILES/FILTER_README \
- ../README_FILES/INSTALL ../README_FILES/LDAP_README \
+ ../README_FILES/INSTALL ../README_FILES/IPV6_README \
+ ../README_FILES/LDAP_README \
../README_FILES/LINUX_README ../README_FILES/LMTP_README \
../README_FILES/LOCAL_RECIPIENT_README ../README_FILES/MAILDROP_README \
../README_FILES/MYSQL_README ../README_FILES/NFS_README \
@@ -157,6 +159,9 @@ clobber:
../html/INSTALL.html: INSTALL.html
$(POSTLINK) $? >$@
+../html/IPV6_README.html: IPV6_README.html
+ $(POSTLINK) $? >$@
+
../html/LDAP_README.html: LDAP_README.html
$(POSTLINK) $? >$@
@@ -283,6 +288,9 @@ clobber:
../README_FILES/INSTALL: INSTALL.html
$(HT2READ) $? >$@
+../README_FILES/IPV6_README: IPV6_README.html
+ $(HT2READ) $? >$@
+
../README_FILES/LDAP_README: LDAP_README.html
$(HT2READ) $? >$@
diff --git a/postfix/proto/SMTPD_POLICY_README.html b/postfix/proto/SMTPD_POLICY_README.html
index 65ab323fa..8ba7c9c26 100644
--- a/postfix/proto/SMTPD_POLICY_README.html
+++ b/postfix/proto/SMTPD_POLICY_README.html
@@ -108,6 +108,10 @@ size=12345
either does not send the attribute, or sends the attribute with
an empty value ("name=").
+ The client address is an IPv4 dotted quad in the form
+ 1.2.3.4 or it is an IPv6 address in the form 1:2:3::4:5:6.
+
+
An attribute name must not contain "=", null or newline,
and an attribute value must not contain null or newline.
diff --git a/postfix/proto/SMTPD_PROXY_README.html b/postfix/proto/SMTPD_PROXY_README.html
index 7a39abe3e..58a04913f 100644
--- a/postfix/proto/SMTPD_PROXY_README.html
+++ b/postfix/proto/SMTPD_PROXY_README.html
@@ -315,7 +315,7 @@ can't control when the remote SMTP client times out.
smtpd_proxy_filter (syntax: host:port): The host and TCP
port of the before-queue content filter. When no host or host:
-is specified in client context, localhost is assumed.
+is specified here, localhost is assumed.
smtpd_proxy_timeout (default: 100s): Timeout for connecting
to the before-queue content filter and for sending and receiving
diff --git a/postfix/proto/access b/postfix/proto/access
index e4d3efb7a..cadcfdb81 100644
--- a/postfix/proto/access
+++ b/postfix/proto/access
@@ -13,7 +13,7 @@
# The optional \fBaccess\fR table directs the Postfix SMTP server
# to selectively reject or accept mail. Access can be allowed or
# denied for specific host names, domain names, networks, host
-# network addresses or mail addresses.
+# addresses or mail addresses.
#
# For an example, see the EXAMPLE section at the end of this
# manual page.
@@ -96,11 +96,46 @@
# .IP \fInet.work.addr\fR
# .IP \fInet.work\fR
# .IP \fInet\fR
-# Matches any host address in the specified network. A network
-# address is a sequence of one or more octets separated by ".".
+# Matches the specified IPv4 host address or subnetwork. An
+# IPv4 host address is a sequence of four decimal octets
+# separated by ".".
#
-# NOTE: use the \fBcidr\fR lookup table type to specify
+# Subnetworks are matched by repeatedly truncating the last
+# ".octet" from the remote IPv4 host address string until a
+# match is found in the access table, or until further
+# truncation is not possible.
+#
+# NOTE 1: The information in the access map should be in
+# canonical form, with unnecessary null characters eliminated.
+# Address information must not be enclosed with "[]" characters.
+#
+# NOTE 2: use the \fBcidr\fR lookup table type to specify
# network/netmask patterns. See cidr_table(5) for details.
+# .IP \fInet:work:addr:ess\fR
+# .IP \fInet:work:addr\fR
+# .IP \fInet:work\fR
+# .IP \fInet\fR
+# Matches the specified IPv6 host address or subnetwork. An
+# IPv6 host address is a sequence of three to eight hexadecimal
+# octet pairs separated by ":".
+#
+# Subnetworks are matched by repeatedly truncating the last
+# ":octetpair" from the remote IPv6 host address string until
+# a match is found in the access table, or until further
+# truncation is not possible.
+#
+# NOTE 1: the truncation and comparison are done with the
+# string representation of the IPv6 host address. Thus, not
+# all the ":" subnetworks will be tried.
+#
+# NOTE 2: The information in the access map should be in
+# canonical form, with unnecessary null characters eliminated.
+# Address information must not be enclosed with "[]" characters.
+#
+# NOTE 3: use the \fBcidr\fR lookup table type to specify
+# network/netmask patterns. See cidr_table(5) for details.
+#
+# IPv6 support is available in Postfix 2.2 and later.
# ACCEPT ACTIONS
# .ad
# .fi
diff --git a/postfix/proto/cidr_table b/postfix/proto/cidr_table
index 5a8df4c54..50e3a1e38 100644
--- a/postfix/proto/cidr_table
+++ b/postfix/proto/cidr_table
@@ -25,7 +25,13 @@
# .IP "\fInetwork_address\fB/\fInetwork_mask result\fR"
# When a search string matches the specified network block,
# use the corresponding \fIresult\fR value. Specify
-# 0.0.0.0/0 to match every address.
+# 0.0.0.0/0 to match every IPv4 address, and ::/0 to match
+# every IPv6 address.
+#
+# Note: address information may be enclosed inside "[]" but
+# this form is not recommended.
+#
+# IPv6 support is available in Postfix 2.2 and later.
# .IP "\fInetwork_address result\fR"
# When a search string matches the specified network address,
# use the corresponding \fIresult\fR value.
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index f1134870c..2cc9fa1d8 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -1406,13 +1406,19 @@ After changing the hash_queue_names or hash_queue_depth parameter,
execute the command "postfix reload".
-%PARAM hash_queue_names see "postconf -d" output
+%PARAM hash_queue_names deferred, defer
The names of queue directories that are split across multiple
subdirectory levels.
+ Before Postfix version 2.2, the default list of hashed queues
+was significantly larger. Claims about improvements in file system
+technology suggest that hashing of the incoming and active queues
+is no longer needed. Fewer hashed directories speed up the time
+needed to restart Postfix.
+
After changing the hash_queue_names or hash_queue_depth parameter,
execute the command "postfix reload".
@@ -1540,42 +1546,98 @@ Specify 0 to disable the feature. Valid delays are 0..10.
%PARAM inet_interfaces all
-
-The network interface addresses that this mail system receives mail
-on. By default, the software claims all active interfaces on the
-machine. The parameter also controls delivery of mail to
-user@[ip.address].
-
+ The network interface addresses that this mail system receives
+mail on. By default, the software claims all active interfaces on
+the machine; with Postfix 2.2 and later, specify "loopback-only"
+to select only local interfaces. The parameter also controls
+delivery of mail to user@[ip.address].
-When inet_interfaces consists of just one IP address that is not a
-loopback (net 127) address, the Postfix SMTP client will use this address
-as the IP source address for outbound mail.
+Note: you need to stop and start Postfix when this parameter changes.
+
+
+ When inet_interfaces specifies just one IPv4 and/or IPv6 address
+that is not a loopback address, the Postfix SMTP client will use
+this address as the IP source address for outbound mail.
On a multi-homed firewall with separate Postfix instances listening on the
"inside" and "outside" interfaces, this can prevent each instance from
being able to reach servers on the "other side" of the firewall. Setting
-smtp_bind_address to 0.0.0.0 avoids the potential problem.
+smtp_bind_address to 0.0.0.0 avoids the potential problem for
+IPv4, and setting smtp_bind_address6 to :: solves the problem
+for IPv6.
-A better solution is to leave inet_interfaces at the default value
+A better solution for multi-homed firewalls is to leave inet_interfaces
+at the default value
and instead use explicit IP addresses in master.cf. This preserves SMTP
loop detection, by ensuring that each side of the firewall knows that the
other IP address is still the same host. Setting $inet_interfaces to a
-single IP address is primarily useful with virtual hosting of domains on
+single IPv4 and/or IPV6 address is primarily useful with virtual
+hosting of domains on
secondary IP addresses, when each IP address serves a different domain
(and has a different $myhostname setting).
See also the proxy_interfaces parameter, for network addresses that
-are forwarded to us by way of a proxy or address translator.
+are forwarded to Postfix by way of a proxy or address translator.
-Note: you need to stop and start Postfix when this parameter changes.
+Examples:
+
+inet_interfaces = all (DEFAULT)
+inet_interfaces = loopback-only
+inet_interfaces = 127.0.0.1
+inet_interfaces = 192.168.1.2, 127.0.0.1
+
+
+%PARAM inet_protocols ipv4
+
+ The Internet protocols Postfix will attempt to use when making
+or accepting connections. Specify one or more of "ipv4" or "ipv6",
+separated by whitespace or commas. The form "all" is equivalent to
+"ipv4, ipv6".
+
+ Note: you MUST stop and start Postfix after changing this
+parameter.
+
+ On systems that pre-date IPV6_V6ONLY support (RFC 3493), an
+IPv6 server will also accept IPv4 connections, even when IPv4 is
+turned off with the inet_protocols parameter. On systems with
+IPV6_V6ONLY support, Postfix will use separate server sockets for
+IPv6 and IPv4, and each will accept only connections for the
+corresponding protocol.
+
+ When IPv4 support is enabled via the inet_protocols parameter,
+Postfix will to DNS type A record lookups, and will convert
+IPv4-in-IPv6 client IP addresses (::ffff:1.2.3.4) to their original
+IPv4 form (1.2.3.4). The latter is needed on hosts that pre-date
+IPV6_V6ONLY support (RFC 3493).
+
+ When IPv6 support is enabled via the inet_protocols parameter,
+Postfix will do DNS type AAAA record lookups.
+
+ When both IPv4 and IPv6 support are enabled, the Postfix SMTP
+client will attempt to connect via IPv6 before attempting to use
+IPv4.
+
+ This feature is available in Postfix version 2.2 and later.
+
+
+Examples:
+
+
+
+inet_protocols = ipv4 (DEFAULT)
+inet_protocols = all
+inet_protocols = ipv6
+inet_protocols = ipv4, ipv6
+
+
%PARAM initial_destination_concurrency 5
@@ -2530,11 +2592,17 @@ lookup string (the lookup result is ignored).
first match. Specify "!pattern" to exclude an address or network
block from the list.
+ Note: IP version 6 address information must be specified inside
+[] in the mynetworks value, and in files specified with
+"/file/name". IP version 6 addresses contain the ":" character,
+and would otherwise be confused with a "type:table" pattern.
+
Examples:
-mynetworks = 168.100.189.0/28, 127.0.0.0/8
+mynetworks = 127.0.0.0/8 168.100.189.0/28
mynetworks = !192.168.0.1, 192.168.0.0/28
+mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:5c7::]/64
mynetworks = $config_directory/mynetworks
mynetworks = hash:/etc/postfix/network_table
@@ -3256,7 +3324,7 @@ the word "ESMTP" appears in the server greeting banner (example:
An optional numerical network address that the SMTP client should
-bind to when making a connection.
+bind to when making an IPv4 connection.
@@ -3270,11 +3338,43 @@ for example:
smtp ... smtp -o smtp_bind_address=11.22.33.44
-
Note: when inet_interfaces specifies exactly one address that
-is a non-loopback address, it is automatically used as the
-smtp_bind_address. This supports virtual IP hosting, but can be
-a problem on multi-homed firewalls. See the inet_interfaces
-documentation for more detail.
+ Note 1: when inet_interfaces specifies no more than one IPv4
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail.
+
+ Note 2: address information may be enclosed inside [],
+but this form is not recommended.
+
+%PARAM smtp_bind_address6
+
+
+An optional numerical network address that the SMTP client should
+bind to when making an IPv6 connection.
+
+
+
+This can be specified in the main.cf file for all SMTP clients, or
+it can be specified in the master.cf file for a specific client,
+for example:
+
+
+
+ /etc/postfix/master.cf:
+ smtp ... smtp -o smtp_bind_address6=1:2:3:4:5:6:7:8
+
+
+ Note 1: when inet_interfaces specifies no more than one IPv6
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address6. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail.
+
+ Note 2: address information may be enclosed inside [],
+but this form is not recommended.
+
+ This feature is available in Postfix version 2.2 and later.
%PARAM smtp_connection_cache_time_limit 2s
@@ -3881,6 +3981,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the authorized_verp_clients value, and in files
+specified with "/file/name". IP version 6 addresses contain the
+":" character, and would otherwise be confused with a "type:table"
+pattern.
+
%PARAM smtpd_authorized_verp_clients $authorized_verp_clients
What SMTP clients are allowed to specify the XVERP command.
@@ -3902,6 +4008,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_verp_clients value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
%PARAM smtpd_authorized_xclient_hosts
@@ -3931,6 +4043,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_xclient_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
%PARAM smtpd_authorized_xforward_hosts
@@ -3959,6 +4077,12 @@ is matched when a table entry matches a lookup string (the lookup
result is ignored). Continue long lines by starting the next line
with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_authorized_xforward_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
%PARAM smtpd_banner $myhostname ESMTP $mail_name
@@ -4014,6 +4138,12 @@ list of network blocks, hostnames or .domain names (the initial
dot causes the domain to match any name below it).
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_client_event_limit_exceptions value, and
+in files specified with "/file/name". IP version 6 addresses
+contain the ":" character, and would otherwise be confused with a
+"type:table" pattern.
+
This feature is available in Postfix 2.2 and later.
@@ -4916,6 +5046,12 @@ contents; a "type:table" lookup table is matched when a table entry
matches a lookup string (the lookup result is ignored). Continue
long lines by starting the next line with whitespace.
+ Note: IP version 6 address information must be specified inside
+[] in the smtpd_sasl_exceptions_networks value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern.
+
Example:
@@ -7255,7 +7391,7 @@ parameter in the default main.cf file.
Optional lookup tables with a) names of domains for which all
addresses are aliased to addresses in other local or remote domains,
and b) addresses that are aliased to addresses in other local or
-remote domains. Available before Postfix version 2.0. With Postfix 2.1
+remote domains. Available before Postfix version 2.0. With Postfix 2.0
and later, this is replaced by separate controls: virtual_alias_domains
and virtual_alias_maps.
diff --git a/postfix/proto/stop b/postfix/proto/stop
index e7f75c98d..3cffb4fb5 100644
--- a/postfix/proto/stop
+++ b/postfix/proto/stop
@@ -835,3 +835,27 @@ Verisign
Verisign's
dd
itd
+AAAA
+DNSBL
+GETIFADDRS
+Hagino
+Huizer
+Jaenicke's
+Lutz
+PLD
+SIOCGIF
+SIOCGLIF
+Strik
+Strik's
+Tru
+USAGI
+compat
+ff
+ffff
+getifaddrs
+ichiro
+ifndef
+ipnet
+ipv
+itojun
+netmasks
diff --git a/postfix/src/anvil/Makefile.in b/postfix/src/anvil/Makefile.in
index 23d6d3062..911e49ef3 100644
--- a/postfix/src/anvil/Makefile.in
+++ b/postfix/src/anvil/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/bounce/Makefile.in b/postfix/src/bounce/Makefile.in
index 86030bf3d..64c4c4b5c 100644
--- a/postfix/src/bounce/Makefile.in
+++ b/postfix/src/bounce/Makefile.in
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in
index e2f2c8691..d2d4025bb 100644
--- a/postfix/src/cleanup/Makefile.in
+++ b/postfix/src/cleanup/Makefile.in
@@ -24,7 +24,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -189,7 +189,6 @@ cleanup_envelope.o: ../../include/mymalloc.h
cleanup_envelope.o: ../../include/stringops.h
cleanup_envelope.o: ../../include/nvtable.h
cleanup_envelope.o: ../../include/htable.h
-cleanup_envelope.o: ../../include/name_code.h
cleanup_envelope.o: ../../include/record.h
cleanup_envelope.o: ../../include/rec_type.h
cleanup_envelope.o: ../../include/cleanup_user.h
diff --git a/postfix/src/discard/Makefile.in b/postfix/src/discard/Makefile.in
index 7d5ef4c97..d59a3cf51 100644
--- a/postfix/src/discard/Makefile.in
+++ b/postfix/src/discard/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/dns/Makefile.in b/postfix/src/dns/Makefile.in
index bdbad7385..3cc0fb71a 100644
--- a/postfix/src/dns/Makefile.in
+++ b/postfix/src/dns/Makefile.in
@@ -1,13 +1,15 @@
SHELL = /bin/sh
-SRCS = dns_lookup.c dns_rr.c dns_strerror.c dns_strtype.c
-OBJS = dns_lookup.o dns_rr.o dns_strerror.o dns_strtype.o
+SRCS = dns_lookup.c dns_rr.c dns_strerror.c dns_strtype.c dns_rr_to_pa.c \
+ dns_sa_to_rr.c dns_rr_eq_sa.c dns_rr_to_sa.c
+OBJS = dns_lookup.o dns_rr.o dns_strerror.o dns_strtype.o dns_rr_to_pa.o \
+ dns_sa_to_rr.o dns_rr_eq_sa.o dns_rr_to_sa.o
HDRS = dns.h
TESTSRC = test_dns_lookup.c test_alias_token.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
INCL =
LIB = libdns.a
-TESTPROG= test_dns_lookup
+TESTPROG= test_dns_lookup dns_rr_to_pa dns_rr_to_sa dns_sa_to_rr dns_rr_eq_sa
LIBS = ../../lib/libutil.a
LIB_DIR = ../../lib
INC_DIR = ../../include
@@ -17,11 +19,12 @@ INC_DIR = ../../include
all: $(LIB)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
-tests: test
+tests: test dns_rr_to_pa_test dns_rr_to_sa_test dns_sa_to_rr_test \
+ dns_rr_eq_sa_test
$(LIB): $(OBJS)
$(AR) $(ARFL) $(LIB) $?
@@ -41,6 +44,46 @@ update: $(LIB_DIR)/$(LIB) $(HDRS)
test_dns_lookup: test_dns_lookup.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+dns_rr_to_pa: $(LIB) $(LIBS)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+ mv junk $@.o
+
+dns_rr_to_sa: $(LIB) $(LIBS)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+ mv junk $@.o
+
+dns_sa_to_rr: $(LIB) $(LIBS)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+ mv junk $@.o
+
+dns_rr_eq_sa: $(LIB) $(LIBS)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+ mv junk $@.o
+
+dns_rr_to_pa_test: dns_rr_to_pa dns_rr_to_pa.in dns_rr_to_pa.ref
+ ./dns_rr_to_pa `cat dns_rr_to_pa.in` >dns_rr_to_pa.tmp
+ diff dns_rr_to_pa.ref dns_rr_to_pa.tmp
+ rm -f dns_rr_to_pa.tmp
+
+dns_rr_to_sa_test: dns_rr_to_sa dns_rr_to_sa.in dns_rr_to_sa.ref
+ ./dns_rr_to_sa `cat dns_rr_to_sa.in` >dns_rr_to_sa.tmp
+ diff dns_rr_to_sa.ref dns_rr_to_sa.tmp
+ rm -f dns_rr_to_sa.tmp
+
+dns_sa_to_rr_test: dns_sa_to_rr dns_sa_to_rr.in dns_sa_to_rr.ref
+ ./dns_sa_to_rr `cat dns_sa_to_rr.in` >dns_sa_to_rr.tmp
+ diff dns_sa_to_rr.ref dns_sa_to_rr.tmp
+ rm -f dns_sa_to_rr.tmp
+
+dns_rr_eq_sa_test: dns_rr_eq_sa dns_rr_eq_sa.in dns_rr_eq_sa.ref
+ ./dns_rr_eq_sa `cat dns_rr_eq_sa.in` >dns_rr_eq_sa.tmp
+ diff dns_rr_eq_sa.ref dns_rr_eq_sa.tmp
+ rm -f dns_rr_eq_sa.tmp
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
@@ -76,6 +119,8 @@ dns_lookup.o: ../../include/msg.h
dns_lookup.o: ../../include/valid_hostname.h
dns_lookup.o: ../../include/stringops.h
dns_lookup.o: dns.h
+dns_lookup.o: ../../include/sock_addr.h
+dns_lookup.o: ../../include/myaddrinfo.h
dns_rr.o: dns_rr.c
dns_rr.o: ../../include/sys_defs.h
dns_rr.o: ../../include/msg.h
@@ -84,16 +129,54 @@ dns_rr.o: ../../include/myrand.h
dns_rr.o: dns.h
dns_rr.o: ../../include/vstring.h
dns_rr.o: ../../include/vbuf.h
+dns_rr.o: ../../include/sock_addr.h
+dns_rr.o: ../../include/myaddrinfo.h
+dns_rr_eq_sa.o: dns_rr_eq_sa.c
+dns_rr_eq_sa.o: ../../include/sys_defs.h
+dns_rr_eq_sa.o: ../../include/msg.h
+dns_rr_eq_sa.o: ../../include/sock_addr.h
+dns_rr_eq_sa.o: dns.h
+dns_rr_eq_sa.o: ../../include/vstring.h
+dns_rr_eq_sa.o: ../../include/vbuf.h
+dns_rr_eq_sa.o: ../../include/myaddrinfo.h
+dns_rr_to_pa.o: dns_rr_to_pa.c
+dns_rr_to_pa.o: ../../include/sys_defs.h
+dns_rr_to_pa.o: ../../include/msg.h
+dns_rr_to_pa.o: dns.h
+dns_rr_to_pa.o: ../../include/vstring.h
+dns_rr_to_pa.o: ../../include/vbuf.h
+dns_rr_to_pa.o: ../../include/sock_addr.h
+dns_rr_to_pa.o: ../../include/myaddrinfo.h
+dns_rr_to_sa.o: dns_rr_to_sa.c
+dns_rr_to_sa.o: ../../include/sys_defs.h
+dns_rr_to_sa.o: ../../include/msg.h
+dns_rr_to_sa.o: dns.h
+dns_rr_to_sa.o: ../../include/vstring.h
+dns_rr_to_sa.o: ../../include/vbuf.h
+dns_rr_to_sa.o: ../../include/sock_addr.h
+dns_rr_to_sa.o: ../../include/myaddrinfo.h
+dns_sa_to_rr.o: dns_sa_to_rr.c
+dns_sa_to_rr.o: ../../include/sys_defs.h
+dns_sa_to_rr.o: ../../include/msg.h
+dns_sa_to_rr.o: dns.h
+dns_sa_to_rr.o: ../../include/vstring.h
+dns_sa_to_rr.o: ../../include/vbuf.h
+dns_sa_to_rr.o: ../../include/sock_addr.h
+dns_sa_to_rr.o: ../../include/myaddrinfo.h
dns_strerror.o: dns_strerror.c
dns_strerror.o: ../../include/sys_defs.h
dns_strerror.o: ../../include/vstring.h
dns_strerror.o: ../../include/vbuf.h
dns_strerror.o: dns.h
+dns_strerror.o: ../../include/sock_addr.h
+dns_strerror.o: ../../include/myaddrinfo.h
dns_strtype.o: dns_strtype.c
dns_strtype.o: ../../include/sys_defs.h
dns_strtype.o: ../../include/vstring.h
dns_strtype.o: ../../include/vbuf.h
dns_strtype.o: dns.h
+dns_strtype.o: ../../include/sock_addr.h
+dns_strtype.o: ../../include/myaddrinfo.h
test_dns_lookup.o: test_dns_lookup.c
test_dns_lookup.o: ../../include/sys_defs.h
test_dns_lookup.o: ../../include/vstring.h
@@ -102,3 +185,5 @@ test_dns_lookup.o: ../../include/msg.h
test_dns_lookup.o: ../../include/msg_vstream.h
test_dns_lookup.o: ../../include/vstream.h
test_dns_lookup.o: dns.h
+test_dns_lookup.o: ../../include/sock_addr.h
+test_dns_lookup.o: ../../include/myaddrinfo.h
diff --git a/postfix/src/dns/dns.h b/postfix/src/dns/dns.h
index 014536b6e..90a45b82c 100644
--- a/postfix/src/dns/dns.h
+++ b/postfix/src/dns/dns.h
@@ -59,6 +59,8 @@
* Utility library.
*/
#include
+#include
+#include
/*
* Structure for fixed resource record data.
@@ -99,7 +101,8 @@ extern unsigned dns_type(const char *);
/*
* dns_rr.c
*/
-extern DNS_RR *dns_rr_create(const char *, DNS_FIXED *, unsigned,
+extern DNS_RR *dns_rr_create(const char *, ushort, ushort,
+ unsigned, unsigned,
const char *, unsigned);
extern void dns_rr_free(DNS_RR *);
extern DNS_RR *dns_rr_copy(DNS_RR *);
@@ -108,13 +111,54 @@ extern DNS_RR *dns_rr_sort(DNS_RR *, int (*) (DNS_RR *, DNS_RR *));
extern DNS_RR *dns_rr_shuffle(DNS_RR *);
extern DNS_RR *dns_rr_remove(DNS_RR *, DNS_RR *);
+ /*
+ * dns_rr_to_pa.c
+ */
+extern const char *dns_rr_to_pa(DNS_RR *, MAI_HOSTADDR_STR *);
+
+ /*
+ * dns_sa_to_rr.c
+ */
+extern DNS_RR *dns_sa_to_rr(const char *, unsigned, struct sockaddr *);
+
+ /*
+ * dns_rr_to_sa.c
+ */
+extern int dns_rr_to_sa(DNS_RR *, unsigned, struct sockaddr *, SOCKADDR_SIZE *);
+
+ /*
+ * dns_rr_eq_sa.c
+ */
+extern int dns_rr_eq_sa(DNS_RR *, struct sockaddr *);
+
+#ifdef HAS_IPV6
+#define DNS_RR_EQ_SA(rr, sa) \
+ ((SOCK_ADDR_IN_FAMILY(sa) == AF_INET && (rr)->type == T_A \
+ && SOCK_ADDR_IN_ADDR(sa).s_addr == IN_ADDR((rr)->data).s_addr) \
+ || (SOCK_ADDR_IN_FAMILY(sa) == AF_INET6 && (rr)->type == T_AAAA \
+ && memcmp((char *) &(SOCK_ADDR_IN6_ADDR(sa)), \
+ (rr)->data, (rr)->data_len) == 0))
+#else
+#define DNS_RR_EQ_SA(rr, sa) \
+ (SOCK_ADDR_IN_FAMILY(sa) == AF_INET && (rr)->type == T_A \
+ && SOCK_ADDR_IN_ADDR(sa).s_addr == IN_ADDR((rr)->data).s_addr)
+#endif
+
/*
* dns_lookup.c
*/
extern int dns_lookup(const char *, unsigned, unsigned, DNS_RR **,
VSTRING *, VSTRING *);
-extern int dns_lookup_types(const char *, unsigned, DNS_RR **,
- VSTRING *, VSTRING *,...);
+extern int dns_lookup_l(const char *, unsigned, DNS_RR **, VSTRING *,
+ VSTRING *, int,...);
+extern int dns_lookup_v(const char *, unsigned, DNS_RR **, VSTRING *,
+ VSTRING *, int, unsigned *);
+
+ /*
+ * Request flags.
+ */
+#define DNS_REQ_FLAG_ANY (1<<0)
+#define DNS_REQ_FLAG_ALL (1<<1)
/*
* Status codes. Failures must have negative codes so they will not collide
diff --git a/postfix/src/dns/dns_lookup.c b/postfix/src/dns/dns_lookup.c
index 03b4aaf5f..da1a14a50 100644
--- a/postfix/src/dns/dns_lookup.c
+++ b/postfix/src/dns/dns_lookup.c
@@ -6,21 +6,31 @@
/* SYNOPSIS
/* #include
/*
-/* int dns_lookup(name, type, flags, list, fqdn, why)
+/* int dns_lookup(name, type, rflags, list, fqdn, why)
/* const char *name;
/* unsigned type;
-/* unsigned flags;
+/* unsigned rflags;
/* DNS_RR **list;
/* VSTRING *fqdn;
/* VSTRING *why;
/*
-/* int dns_lookup_types(name, flags, list, fqdn, why, type, ...)
+/* int dns_lookup_l(name, rflags, list, fqdn, why, lflags, ltype, ...)
/* const char *name;
-/* unsigned flags;
+/* unsigned rflags;
/* DNS_RR **list;
/* VSTRING *fqdn;
/* VSTRING *why;
-/* unsigned type;
+/* int lflags;
+/* unsigned ltype;
+/*
+/* int dns_lookup_v(name, rflags, list, fqdn, why, lflags, ltype)
+/* const char *name;
+/* unsigned rflags;
+/* DNS_RR **list;
+/* VSTRING *fqdn;
+/* VSTRING *why;
+/* int lflags;
+/* unsigned *ltype;
/* DESCRIPTION
/* dns_lookup() looks up DNS resource records. When requested to
/* look up data other than type CNAME, it will follow a limited
@@ -29,10 +39,8 @@
/* All name results are validated by \fIvalid_hostname\fR();
/* an invalid name is reported as a transient error.
/*
-/* dns_lookup_types() allows the user to specify a null-terminated
-/* list of resource types. This function calls dns_lookup() for each
-/* listed type in the specified order, until the list is exhausted or
-/* until the search result becomes not equal to DNS_NOTFOUND.
+/* dns_lookup_l() and dns_lookup_v() allow the user to specify
+/* a list of resource types.
/* INPUTS
/* .ad
/* .fi
@@ -40,8 +48,8 @@
/* The name to be looked up in the domain name system.
/* .IP type
/* The resource record type to be looked up (T_A, T_MX etc.).
-/* .IP flags
-/* A bitwise OR of:
+/* .IP rflags
+/* Resolver flags. These are a bitwise OR of:
/* .RS
/* .IP RES_DEBUG
/* Print debugging information.
@@ -50,6 +58,23 @@
/* .IP RES_DEFNAMES
/* Append local domain to unqualified names.
/* .RE
+/* .IP lflags
+/* Multi-type request control for dns_lookup_l() and
+/* dns_lookup_v(). This is one of the following:
+/* .RS
+/* .IP DNS_REQ_FLAG_ANY
+/* Call dns_lookup() for each specified resource record type
+/* in the specified order, until the list is exhausted or
+/* until some result is DNS_OK.
+/* .IP DNS_REQ_FLAG_ALL
+/* Call dns_lookup() for all specified resource record types
+/* in the specified order, and merge their results.
+/* .RE
+/* .IP ltype
+/* The resource record types to be looked up. In the case of
+/* dns_lookup_l(), this is a null-terminated argument list.
+/* In the case of dns_lookup_v(), this is a null-terminated
+/* integer array.
/* OUTPUTS
/* .ad
/* .fi
@@ -97,8 +122,6 @@
#include
#include
-#include /* BSDI stdarg.h uses abort() */
-#include
#include
#include
@@ -109,7 +132,6 @@
#include
#include
#include
-#include
/* DNS library. */
@@ -375,7 +397,8 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
*dst = 0;
break;
}
- return (dns_rr_create(rr_name, fixed, pref, temp, data_len));
+ return (dns_rr_create(rr_name, fixed->type, fixed->class, fixed->ttl,
+ pref, temp, data_len));
}
/* dns_get_alias - extract CNAME from name server reply */
@@ -507,9 +530,9 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
int status;
/*
- * The Linux resolver misbehaves when given an invalid domain name.
+ * DJBDNS produces a bogus A record when given a numerical hostname.
*/
- if (!valid_hostname(name, DONT_GRIPE)) {
+ if (valid_hostaddr(name, DONT_GRIPE)) {
if (why)
vstring_sprintf(why,
"Name service error for %s: invalid host or domain name",
@@ -519,9 +542,9 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
}
/*
- * DJBDNS produces a bogus A record when given a numerical hostname.
+ * The Linux resolver misbehaves when given an invalid domain name.
*/
- if (valid_hostaddr(name, DONT_GRIPE)) {
+ if (!valid_hostname(name, DONT_GRIPE)) {
if (why)
vstring_sprintf(why,
"Name service error for %s: invalid host or domain name",
@@ -568,26 +591,70 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
return (DNS_NOTFOUND);
}
-/* dns_lookup_types - DNS lookup interface with multiple types */
+/* dns_lookup_l - DNS lookup interface with types list */
-int dns_lookup_types(const char *name, unsigned flags, DNS_RR **rrlist,
- VSTRING *fqdn, VSTRING *why,...)
+int dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
+ VSTRING *fqdn, VSTRING *why, int lflags,...)
{
va_list ap;
unsigned type;
int status = DNS_NOTFOUND;
+ DNS_RR *rr;
+ int non_err = 0;
int soft_err = 0;
- va_start(ap, why);
+ if (rrlist)
+ *rrlist = 0;
+ va_start(ap, lflags);
while ((type = va_arg(ap, unsigned)) != 0) {
if (msg_verbose)
- msg_info("lookup %s type %d flags %d", name, type, flags);
- status = dns_lookup(name, type, flags, rrlist, fqdn, why);
- if (status == DNS_OK)
- break;
- if (status == DNS_RETRY)
+ msg_info("lookup %s type %s flags %d",
+ name, dns_strtype(type), flags);
+ status = dns_lookup(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
+ fqdn, why);
+ if (status == DNS_OK) {
+ non_err = 1;
+ if (rrlist)
+ *rrlist = dns_rr_append(*rrlist, rr);
+ if (lflags == DNS_REQ_FLAG_ANY)
+ break;
+ } else if (status == DNS_RETRY) {
soft_err = 1;
+ }
}
va_end(ap);
- return ((status == DNS_OK || soft_err == 0) ? status : DNS_RETRY);
+ return (non_err ? DNS_OK : soft_err ? DNS_RETRY : status);
+}
+
+/* dns_lookup_v - DNS lookup interface with types vector */
+
+int dns_lookup_v(const char *name, unsigned flags, DNS_RR **rrlist,
+ VSTRING *fqdn, VSTRING *why, int lflags,
+ unsigned *types)
+{
+ unsigned type;
+ int status = DNS_NOTFOUND;
+ DNS_RR *rr;
+ int non_err = 0;
+ int soft_err = 0;
+
+ if (rrlist)
+ *rrlist = 0;
+ while ((type = *types++) != 0) {
+ if (msg_verbose)
+ msg_info("lookup %s type %s flags %d",
+ name, dns_strtype(type), flags);
+ status = dns_lookup(name, type, flags, rrlist ? &rr : (DNS_RR **) 0,
+ fqdn, why);
+ if (status == DNS_OK) {
+ non_err = 1;
+ if (rrlist)
+ *rrlist = dns_rr_append(*rrlist, rr);
+ if (lflags == DNS_REQ_FLAG_ANY)
+ break;
+ } else if (status == DNS_RETRY) {
+ soft_err = 1;
+ }
+ }
+ return (non_err ? DNS_OK : soft_err ? DNS_RETRY : status);
}
diff --git a/postfix/src/dns/dns_rr.c b/postfix/src/dns/dns_rr.c
index a00a738d0..a52d2813d 100644
--- a/postfix/src/dns/dns_rr.c
+++ b/postfix/src/dns/dns_rr.c
@@ -6,9 +6,12 @@
/* SYNOPSIS
/* #include
/*
-/* DNS_RR *dns_rr_create(name, fixed, preference, data, data_len)
+/* DNS_RR *dns_rr_create(name, type, class, ttl, preference,
+/* data, data_len)
/* const char *name;
-/* DNS_FIXED *fixed;
+/* unsigned short type;
+/* unsigned short class;
+/* unsigned int ttl;
/* unsigned preference;
/* const char *data;
/* unsigned len;
@@ -39,8 +42,6 @@
/*
/* dns_rr_create() creates and initializes one resource record.
/* The \fIname\fR record specifies the record name.
-/* The \fIfixed\fR argument specifies generic resource record
-/* information such as resource type and time to live;
/* \fIpreference\fR is used for MX records; \fIdata\fR is a null
/* pointer or specifies optional resource-specific data;
/* \fIdata_len\fR is the amount of resource-specific data.
@@ -90,16 +91,17 @@
/* dns_rr_create - fill in resource record structure */
-DNS_RR *dns_rr_create(const char *name, DNS_FIXED *fixed, unsigned pref,
+DNS_RR *dns_rr_create(const char *name, ushort type, ushort class,
+ unsigned int ttl, unsigned pref,
const char *data, unsigned data_len)
{
DNS_RR *rr;
rr = (DNS_RR *) mymalloc(sizeof(*rr) + data_len - 1);
rr->name = mystrdup(name);
- rr->type = fixed->type;
- rr->class = fixed->class;
- rr->ttl = fixed->ttl;
+ rr->type = type;
+ rr->class = class;
+ rr->ttl = ttl;
rr->pref = pref;
if (data && data_len > 0)
memcpy(rr->data, data, data_len);
@@ -255,7 +257,7 @@ DNS_RR *dns_rr_shuffle(DNS_RR *list)
DNS_RR *dns_rr_remove(DNS_RR *list, DNS_RR *record)
{
- if (list == 0)
+ if (list == 0)
msg_panic("dns_rr_remove: record not found");
if (list == record) {
diff --git a/postfix/src/dns/dns_rr_eq_sa.c b/postfix/src/dns/dns_rr_eq_sa.c
new file mode 100644
index 000000000..27495fca6
--- /dev/null
+++ b/postfix/src/dns/dns_rr_eq_sa.c
@@ -0,0 +1,137 @@
+/*++
+/* NAME
+/* dns_rr_eq_sa 3
+/* SUMMARY
+/* compare resource record with socket address
+/* SYNOPSIS
+/* #include
+/*
+/* int dns_rr_eq_sa(DNS_RR *rr, struct sockaddr *sa)
+/* DNS_RR *rr;
+/* struct sockaddr *sa;
+/*
+/* int DNS_RR_EQ_SA(DNS_RR *rr, struct sockaddr *sa)
+/* DNS_RR *rr;
+/* struct sockaddr *sa;
+/* DESCRIPTION
+/* dns_rr_eq_sa() compares a DNS resource record with a socket
+/* address. The result is non-zero when the resource type
+/* matches the socket address family, and when the network
+/* address information is identical.
+/*
+/* DNS_RR_EQ_SA() is an unsafe macro version for those who live fast.
+/*
+/* Arguments:
+/* .IP rr
+/* DNS resource record pointer.
+/* .IP sa
+/* Binary address pointer.
+/* DIAGNOSTICS
+/* Panic: unknown socket address family.
+/* 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 libraries. */
+
+#include
+
+/* Utility library. */
+
+#include
+#include
+
+/* DNS library. */
+
+#include
+
+/* dns_rr_eq_sa - compare resource record with socket address */
+
+int dns_rr_eq_sa(DNS_RR *rr, struct sockaddr * sa)
+{
+ const char *myname = "dns_rr_eq_sa";
+
+ if (sa->sa_family == AF_INET) {
+ return (rr->type == T_A
+ && SOCK_ADDR_IN_ADDR(sa).s_addr == IN_ADDR(rr->data).s_addr);
+#ifdef HAS_IPV6
+ } else if (sa->sa_family == AF_INET6) {
+ return (rr->type == T_AAAA
+ && memcmp((char *) &SOCK_ADDR_IN6_ADDR(sa),
+ rr->data, rr->data_len) == 0);
+#endif
+ } else {
+ msg_panic("%s: unsupported socket address family type: %d",
+ myname, sa->sa_family);
+ }
+}
+
+ /*
+ * Stand-alone test program.
+ */
+#ifdef TEST
+#include
+#include
+#include
+
+static const char *myname;
+
+static NORETURN usage(void)
+{
+ msg_fatal("usage: %s hostname address", myname);
+}
+
+int main(int argc, char **argv)
+{
+ MAI_HOSTADDR_STR hostaddr;
+ DNS_RR *rr;
+ struct addrinfo *res0;
+ struct addrinfo *res1;
+ struct addrinfo *res;
+ int aierr;
+
+ myname = argv[0];
+
+ if (argc < 3)
+ usage();
+
+ inet_proto_init(argv[0], INET_PROTO_NAME_ALL);
+
+ while (*++argv) {
+ if (argv[1] == 0)
+ usage();
+
+ if ((aierr = hostaddr_to_sockaddr(argv[1], (char *) 0, 0, &res1)) != 0)
+ msg_fatal("host address %s: %s", argv[1], MAI_STRERROR(aierr));
+ if ((rr = dns_sa_to_rr(argv[1], 0, res1->ai_addr)) == 0)
+ msg_fatal("dns_sa_to_rr: %m");
+ freeaddrinfo(res1);
+
+ if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0)
+ msg_fatal("host name %s: %s", argv[0], MAI_STRERROR(aierr));
+ for (res = res0; res != 0; res = res->ai_next) {
+ SOCKADDR_TO_HOSTADDR(res->ai_addr, res->ai_addrlen,
+ &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
+ vstream_printf("%s =?= %s\n", hostaddr.buf, argv[1]);
+ vstream_printf("tested by function: %s\n",
+ dns_rr_eq_sa(rr, res->ai_addr) ?
+ "yes" : "no");
+ vstream_printf("tested by macro: %s\n",
+ DNS_RR_EQ_SA(rr, res->ai_addr) ?
+ "yes" : "no");
+ }
+ dns_rr_free(rr);
+ freeaddrinfo(res0);
+ vstream_fflush(VSTREAM_OUT);
+ argv += 1;
+ }
+}
+
+#endif
diff --git a/postfix/src/dns/dns_rr_eq_sa.in b/postfix/src/dns/dns_rr_eq_sa.in
new file mode 100644
index 000000000..be10f967a
--- /dev/null
+++ b/postfix/src/dns/dns_rr_eq_sa.in
@@ -0,0 +1,4 @@
+spike.porcupine.org 168.100.189.2
+spike.porcupine.org 168.100.189.3
+spike.porcupine.org 2001:240:5c7:0:2d0:b7ff:fe88:2ca7
+spike.porcupine.org 2001:240:5c7:0:2d0:b7ff:febe:ca9f
diff --git a/postfix/src/dns/dns_rr_eq_sa.ref b/postfix/src/dns/dns_rr_eq_sa.ref
new file mode 100644
index 000000000..8df8d746d
--- /dev/null
+++ b/postfix/src/dns/dns_rr_eq_sa.ref
@@ -0,0 +1,24 @@
+2001:240:5c7:0:2d0:b7ff:fe88:2ca7 =?= 168.100.189.2
+tested by function: no
+tested by macro: no
+168.100.189.2 =?= 168.100.189.2
+tested by function: yes
+tested by macro: yes
+2001:240:5c7:0:2d0:b7ff:fe88:2ca7 =?= 168.100.189.3
+tested by function: no
+tested by macro: no
+168.100.189.2 =?= 168.100.189.3
+tested by function: no
+tested by macro: no
+2001:240:5c7:0:2d0:b7ff:fe88:2ca7 =?= 2001:240:5c7:0:2d0:b7ff:fe88:2ca7
+tested by function: yes
+tested by macro: yes
+168.100.189.2 =?= 2001:240:5c7:0:2d0:b7ff:fe88:2ca7
+tested by function: no
+tested by macro: no
+2001:240:5c7:0:2d0:b7ff:fe88:2ca7 =?= 2001:240:5c7:0:2d0:b7ff:febe:ca9f
+tested by function: no
+tested by macro: no
+168.100.189.2 =?= 2001:240:5c7:0:2d0:b7ff:febe:ca9f
+tested by function: no
+tested by macro: no
diff --git a/postfix/src/dns/dns_rr_to_pa.c b/postfix/src/dns/dns_rr_to_pa.c
new file mode 100644
index 000000000..bfd93a031
--- /dev/null
+++ b/postfix/src/dns/dns_rr_to_pa.c
@@ -0,0 +1,113 @@
+/*++
+/* NAME
+/* dns_rr_to_pa 3
+/* SUMMARY
+/* resource record to printable address
+/* SYNOPSIS
+/* #include
+/*
+/* const char *dns_rr_to_pa(rr, hostaddr)
+/* DNS_RR *rr;
+/* MAI_HOSTADDR_STR *hostaddr;
+/* DESCRIPTION
+/* dns_rr_to_pa() converts the address in a DNS resource record
+/* into printable form and returns a pointer to the result.
+/*
+/* Arguments:
+/* .IP rr
+/* The DNS resource record.
+/* .IP hostaddr
+/* Storage for the printable address.
+/* DIAGNOSTICS
+/* The result is null in case of problems, with errno set
+/* to indicate the nature of the problem.
+/* 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 libraries. */
+
+#include
+#include
+#include
+#include
+#include
+
+/* Utility library. */
+
+#include
+
+/* DNS library. */
+
+#include
+
+/* dns_rr_to_pa - resource record to printable address */
+
+const char *dns_rr_to_pa(DNS_RR *rr, MAI_HOSTADDR_STR *hostaddr)
+{
+ if (rr->type == T_A) {
+ return (inet_ntop(AF_INET, rr->data, hostaddr->buf,
+ sizeof(hostaddr->buf)));
+#ifdef HAS_IPV6
+ } else if (rr->type == T_AAAA) {
+ return (inet_ntop(AF_INET6, rr->data, hostaddr->buf,
+ sizeof(hostaddr->buf)));
+#endif
+ } else {
+ errno = EAFNOSUPPORT;
+ return (0);
+ }
+}
+
+ /*
+ * Stand-alone test program.
+ */
+#ifdef TEST
+#include
+#include
+
+static const char *myname;
+
+static NORETURN usage(void)
+{
+ msg_fatal("usage: %s dnsaddrtype hostname", myname);
+}
+
+int main(int argc, char **argv)
+{
+ DNS_RR *rr;
+ MAI_HOSTADDR_STR hostaddr;
+ VSTRING *why;
+ int type;
+
+ myname = argv[0];
+ if (argc < 3)
+ usage();
+ why = vstring_alloc(1);
+
+ while (*++argv) {
+ if (argv[1] == 0)
+ usage();
+ if ((type = dns_type(argv[0])) == 0)
+ usage();
+ if (dns_lookup(argv[1], type, 0, &rr, (VSTRING *) 0, why) != DNS_OK)
+ msg_fatal("%s: %s", argv[1], vstring_str(why));
+ if (dns_rr_to_pa(rr, &hostaddr) == 0)
+ msg_fatal("dns_rr_to_sa: %m");
+ vstream_printf("%s -> %s\n", argv[1], hostaddr.buf);
+ vstream_fflush(VSTREAM_OUT);
+ argv += 1;
+ dns_rr_free(rr);
+ }
+ vstring_free(why);
+ return (0);
+}
+
+#endif
diff --git a/postfix/src/dns/dns_rr_to_pa.in b/postfix/src/dns/dns_rr_to_pa.in
new file mode 100644
index 000000000..28d0e7713
--- /dev/null
+++ b/postfix/src/dns/dns_rr_to_pa.in
@@ -0,0 +1,2 @@
+a spike.porcupine.org
+aaaa spike.porcupine.org
diff --git a/postfix/src/dns/dns_rr_to_pa.ref b/postfix/src/dns/dns_rr_to_pa.ref
new file mode 100644
index 000000000..d32e21364
--- /dev/null
+++ b/postfix/src/dns/dns_rr_to_pa.ref
@@ -0,0 +1,2 @@
+spike.porcupine.org -> 168.100.189.2
+spike.porcupine.org -> 2001:240:5c7:0:2d0:b7ff:fe88:2ca7
diff --git a/postfix/src/dns/dns_rr_to_sa.c b/postfix/src/dns/dns_rr_to_sa.c
new file mode 100644
index 000000000..4611fdabc
--- /dev/null
+++ b/postfix/src/dns/dns_rr_to_sa.c
@@ -0,0 +1,163 @@
+/*++
+/* NAME
+/* dns_rr_to_sa 3
+/* SUMMARY
+/* resource record to socket address
+/* SYNOPSIS
+/* #include
+/*
+/* int dns_rr_to_sa(rr, port, sa, sa_len)
+/* DNS_RR *rr;
+/* unsigned port;
+/* struct sockaddr *sa;
+/* SOCKADDR_SIZE *sa_len;
+/* DESCRIPTION
+/* dns_rr_to_sa() converts the address in a DNS resource record into
+/* a socket address of the corresponding type.
+/*
+/* Arguments:
+/* .IP rr
+/* DNS resource record pointer.
+/* .IP port
+/* TCP or UDP port, network byte order.
+/* .IP sa
+/* Socket address pointer.
+/* .IP sa_len
+/* On input, the available socket address storage space.
+/* On output, the amount of space actually used.
+/* DIAGNOSTICS
+/* The result is non-zero in case of problems, with the
+/* error type returned via the errno variable.
+/* 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 libraries. */
+
+#include
+#include
+
+/* Utility library. */
+
+#include
+
+/* DNS library. */
+
+#include
+
+/* dns_rr_to_sa - resource record to socket address */
+
+int dns_rr_to_sa(DNS_RR *rr, unsigned port, struct sockaddr * sa,
+ SOCKADDR_SIZE *sa_len)
+{
+ SOCKADDR_SIZE sock_addr_len;
+
+ if (rr->type == T_A) {
+ if (rr->data_len != sizeof(SOCK_ADDR_IN_ADDR(sa))) {
+ errno = EINVAL;
+ return (-1);
+ } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN_PTR(sa))) > *sa_len) {
+ errno = ENOSPC;
+ return (-1);
+ } else {
+ memset((char *) SOCK_ADDR_IN_PTR(sa), 0, sock_addr_len);
+ SOCK_ADDR_IN_FAMILY(sa) = AF_INET;
+ SOCK_ADDR_IN_PORT(sa) = port;
+ SOCK_ADDR_IN_ADDR(sa) = IN_ADDR(rr->data);
+#ifdef HAS_SA_LEN
+ sa->sa_len = sock_addr_len;
+#endif
+ *sa_len = sock_addr_len;
+ return (0);
+ }
+#ifdef HAS_IPV6
+ } else if (rr->type == T_AAAA) {
+ if (rr->data_len != sizeof(SOCK_ADDR_IN6_ADDR(sa))) {
+ errno = EINVAL;
+ return (-1);
+ } else if ((sock_addr_len = sizeof(*SOCK_ADDR_IN6_PTR(sa))) > *sa_len) {
+ errno = ENOSPC;
+ return (-1);
+ } else {
+ memset((char *) SOCK_ADDR_IN6_PTR(sa), 0, sock_addr_len);
+ SOCK_ADDR_IN6_FAMILY(sa) = AF_INET6;
+ SOCK_ADDR_IN6_PORT(sa) = port;
+ SOCK_ADDR_IN6_ADDR(sa) = IN6_ADDR(rr->data);
+#ifdef HAS_SA_LEN
+ sa->sa_len = sock_addr_len;
+#endif
+ *sa_len = sock_addr_len;
+ return (0);
+ }
+#endif
+ } else {
+ errno = EAFNOSUPPORT;
+ return (-1);
+ }
+}
+
+ /*
+ * Stand-alone test program.
+ */
+#ifdef TEST
+#include
+
+#include
+#include
+#include
+
+static const char *myname;
+
+static NORETURN usage(void)
+{
+ msg_fatal("usage: %s dnsaddrtype hostname portnumber", myname);
+}
+
+int main(int argc, char **argv)
+{
+ DNS_RR *rr;
+ MAI_HOSTADDR_STR hostaddr;
+ MAI_SERVPORT_STR portnum;
+ struct sockaddr_storage ss;
+ struct sockaddr *sa = (struct sockaddr *) & ss;
+ SOCKADDR_SIZE sa_len = sizeof(ss);
+ VSTRING *why;
+ int type;
+ int port;
+
+ myname = argv[0];
+ if (argc < 4)
+ usage();
+ why = vstring_alloc(1);
+
+ while (*++argv) {
+ if (argv[1] == 0 || argv[2] == 0)
+ usage();
+ if ((type = dns_type(argv[0])) == 0)
+ usage();
+ if (!alldig(argv[2]) || (port = atoi(argv[2])) > 65535)
+ usage();
+ if (dns_lookup(argv[1], type, 0, &rr, (VSTRING *) 0, why) != DNS_OK)
+ msg_fatal("%s: %s", argv[1], vstring_str(why));
+ sa_len = sizeof(ss);
+ if (dns_rr_to_sa(rr, htons(port), sa, &sa_len) != 0)
+ msg_fatal("dns_rr_to_sa: %m");
+ SOCKADDR_TO_HOSTADDR(sa, sa_len, &hostaddr, &portnum, 0);
+ vstream_printf("%s %s -> %s %s\n",
+ argv[1], argv[2], hostaddr.buf, portnum.buf);
+ vstream_fflush(VSTREAM_OUT);
+ argv += 2;
+ dns_rr_free(rr);
+ }
+ vstring_free(why);
+ return (0);
+}
+
+#endif
diff --git a/postfix/src/dns/dns_rr_to_sa.in b/postfix/src/dns/dns_rr_to_sa.in
new file mode 100644
index 000000000..1fff6c0b9
--- /dev/null
+++ b/postfix/src/dns/dns_rr_to_sa.in
@@ -0,0 +1,2 @@
+a spike.porcupine.org 25
+aaaa spike.porcupine.org 25
diff --git a/postfix/src/dns/dns_rr_to_sa.ref b/postfix/src/dns/dns_rr_to_sa.ref
new file mode 100644
index 000000000..2f23cc613
--- /dev/null
+++ b/postfix/src/dns/dns_rr_to_sa.ref
@@ -0,0 +1,2 @@
+spike.porcupine.org 25 -> 168.100.189.2 25
+spike.porcupine.org 25 -> 2001:240:5c7:0:2d0:b7ff:fe88:2ca7 25
diff --git a/postfix/src/dns/dns_sa_to_rr.c b/postfix/src/dns/dns_sa_to_rr.c
new file mode 100644
index 000000000..da8aa9e1d
--- /dev/null
+++ b/postfix/src/dns/dns_sa_to_rr.c
@@ -0,0 +1,118 @@
+/*++
+/* NAME
+/* dns_sa_to_rr 3
+/* SUMMARY
+/* socket address to resource record
+/* SYNOPSIS
+/* #include
+/*
+/* DNS_RR *dns_sa_to_rr(hostname, pref, sa)
+/* const char *hostname;
+/* unsigned pref;
+/* struct sockaddr *sa;
+/* DESCRIPTION
+/* dns_sa_to_rr() converts a socket address into a DNS resource record.
+/*
+/* Arguments:
+/* .IP hostname
+/* The resource record host name.
+/* .IP pref
+/* The resource record MX host preference, if applicable.
+/* .IP sa
+/* Binary address.
+/* DIAGNOSTICS
+/* The result is a null pointer in case of problems, with the
+/* errno variable set to indicate the problem type.
+/* 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 libraries. */
+
+#include
+#include
+
+/* Utility library. */
+
+#include
+
+/* DNS library. */
+
+#include
+
+/* dns_sa_to_rr - socket address to resource record */
+
+DNS_RR *dns_sa_to_rr(const char *hostname, unsigned pref, struct sockaddr * sa)
+{
+#define DUMMY_TTL 0
+
+ if (sa->sa_family == AF_INET) {
+ return (dns_rr_create(hostname, T_A, C_IN, DUMMY_TTL, pref,
+ (char *) &SOCK_ADDR_IN_ADDR(sa),
+ sizeof(SOCK_ADDR_IN_ADDR(sa))));
+#ifdef HAS_IPV6
+ } else if (sa->sa_family == AF_INET6) {
+ return (dns_rr_create(hostname, T_AAAA, C_IN, DUMMY_TTL, pref,
+ (char *) &SOCK_ADDR_IN6_ADDR(sa),
+ sizeof(SOCK_ADDR_IN6_ADDR(sa))));
+#endif
+ } else {
+ errno = EAFNOSUPPORT;
+ return (0);
+ }
+}
+
+ /*
+ * Stand-alone test program.
+ */
+#ifdef TEST
+#include
+#include
+#include
+
+static const char *myname;
+
+static NORETURN usage(void)
+{
+ msg_fatal("usage: %s hostname", myname);
+}
+
+int main(int argc, char **argv)
+{
+ MAI_HOSTADDR_STR hostaddr;
+ struct addrinfo *res0;
+ struct addrinfo *res;
+ DNS_RR *rr;
+ int aierr;
+
+ myname = argv[0];
+ if (argc < 2)
+ usage();
+
+ inet_proto_init(argv[0], INET_PROTO_NAME_ALL);
+
+ while (*++argv) {
+ if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0)
+ msg_fatal("%s: %s", argv[0], MAI_STRERROR(aierr));
+ for (res = res0; res != 0; res = res->ai_next) {
+ if ((rr = dns_sa_to_rr(argv[0], 0, res->ai_addr)) == 0)
+ msg_fatal("dns_sa_to_rr: %m");
+ if (dns_rr_to_pa(rr, &hostaddr) == 0)
+ msg_fatal("dns_rr_to_pa: %m");
+ vstream_printf("%s -> %s\n", argv[0], hostaddr.buf);
+ vstream_fflush(VSTREAM_OUT);
+ dns_rr_free(rr);
+ }
+ freeaddrinfo(res0);
+ }
+ return (0);
+}
+
+#endif
diff --git a/postfix/src/dns/dns_sa_to_rr.in b/postfix/src/dns/dns_sa_to_rr.in
new file mode 100644
index 000000000..4f83a7d6f
--- /dev/null
+++ b/postfix/src/dns/dns_sa_to_rr.in
@@ -0,0 +1 @@
+spike.porcupine.org
diff --git a/postfix/src/dns/dns_sa_to_rr.ref b/postfix/src/dns/dns_sa_to_rr.ref
new file mode 100644
index 000000000..40f5fc86a
--- /dev/null
+++ b/postfix/src/dns/dns_sa_to_rr.ref
@@ -0,0 +1,2 @@
+spike.porcupine.org -> 2001:240:5c7:0:2d0:b7ff:fe88:2ca7
+spike.porcupine.org -> 168.100.189.2
diff --git a/postfix/src/dns/test_dns_lookup.c b/postfix/src/dns/test_dns_lookup.c
index aabdd98ec..8d32387e8 100644
--- a/postfix/src/dns/test_dns_lookup.c
+++ b/postfix/src/dns/test_dns_lookup.c
@@ -40,14 +40,19 @@
static void print_rr(DNS_RR *rr)
{
- struct in_addr addr;
+ MAI_HOSTADDR_STR host;
while (rr) {
printf("%s: ttl: %9d ", rr->name, rr->ttl);
switch (rr->type) {
case T_A:
- memcpy((char *) &addr.s_addr, rr->data, sizeof(addr.s_addr));
- printf("%s: %s\n", dns_strtype(rr->type), inet_ntoa(addr));
+#ifdef T_AAAA
+ case T_AAAA:
+#endif
+ if (dns_rr_to_pa(rr, &host) == 0)
+ msg_fatal("conversion error for resource record type %s: %m",
+ dns_strtype(rr->type));
+ printf("%s: %s\n", dns_strtype(rr->type), host.buf);
break;
case T_CNAME:
case T_MB:
@@ -85,7 +90,8 @@ int main(int argc, char **argv)
msg_fatal("invalid query type: %s", argv[1]);
name = argv[2];
msg_verbose = 1;
- switch (dns_lookup_types(name, RES_DEFNAMES | RES_DEBUG, &rr, fqdn, why, type, 0)) {
+ switch (dns_lookup_l(name, RES_DEFNAMES | RES_DEBUG, &rr, fqdn, why,
+ DNS_REQ_FLAG_ALL, type, 0)) {
default:
msg_fatal("%s", vstring_str(why));
case DNS_OK:
diff --git a/postfix/src/error/Makefile.in b/postfix/src/error/Makefile.in
index bbeb61947..166f7084d 100644
--- a/postfix/src/error/Makefile.in
+++ b/postfix/src/error/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/flush/Makefile.in b/postfix/src/flush/Makefile.in
index 194a56738..2092d48e5 100644
--- a/postfix/src/flush/Makefile.in
+++ b/postfix/src/flush/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/fsstone/Makefile.in b/postfix/src/fsstone/Makefile.in
index 995637800..a7f491a62 100644
--- a/postfix/src/fsstone/Makefile.in
+++ b/postfix/src/fsstone/Makefile.in
@@ -15,7 +15,7 @@ LIBS = ../../lib/libglobal.a ../../lib/libutil.a
all: $(PROG)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
fsstone: fsstone.o $(LIBS)
$(CC) $(CFLAGS) -o $@ fsstone.o $(LIBS) $(SYSLIBS)
diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in
index 6c8b786cc..b33801f42 100644
--- a/postfix/src/global/Makefile.in
+++ b/postfix/src/global/Makefile.in
@@ -24,7 +24,8 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
tok822_resolve.c tok822_rewrite.c tok822_tree.c trace.c verify.c \
verify_clnt.c verp_sender.c virtual8_maps.c xtext.c scache_single.c \
scache_clnt.c scache_multi.c user_acl.c mkmap_cdb.c mkmap_sdbm.c \
- ehlo_mask.c
+ ehlo_mask.c \
+ wildcard_inet_addr.c valid_mailhost_addr.c
OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
clnt_stream.o debug_peer.o debug_process.o defer.o \
@@ -50,7 +51,8 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
tok822_resolve.o tok822_rewrite.o tok822_tree.o trace.o verify.o \
verify_clnt.o verp_sender.o virtual8_maps.o xtext.o scache_single.o \
scache_clnt.o scache_multi.o user_acl.o mkmap_cdb.o mkmap_sdbm.o \
- ehlo_mask.o
+ ehlo_mask.o \
+ wildcard_inet_addr.o valid_mailhost_addr.o
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
debug_peer.h debug_process.h defer.h deliver_completed.h \
@@ -71,7 +73,8 @@ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
resolve_local.h rewrite_clnt.h sent.h smtp_stream.h split_addr.h \
string_list.h strip_addr.h sys_exits.h timed_ipc.h tok822.h \
trace.h verify.h verify_clnt.h verp_sender.h virtual8_maps.h \
- xtext.h scache.h user_acl.h ehlo_mask.h
+ xtext.h scache.h user_acl.h ehlo_mask.h \
+ wildcard_inet_addr.h valid_mailhost_addr.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -82,7 +85,8 @@ TESTPROG= domain_list dot_lockfile mail_addr_crunch mail_addr_find \
off_cvt quote_822_local rec2stream recdump resolve_clnt \
resolve_local rewrite_clnt stream2rec string_list tok822_parse \
quote_821_local mail_conf_time mime_state strip_addr \
- virtual8_maps verify_clnt xtext anvil_clnt scache ehlo_mask
+ virtual8_maps verify_clnt xtext anvil_clnt scache ehlo_mask \
+ valid_mailhost_addr
LIBS = ../../lib/libutil.a
LIB_DIR = ../../lib
@@ -94,7 +98,7 @@ MAKES =
all: $(LIB)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -256,9 +260,13 @@ scache: scache.c $(LIB) $(LIBS)
ehlo_mask: ehlo_mask.c $(LIB) $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+valid_mailhost_addr: valid_mailhost_addr.c $(LIB) $(LIBS)
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(LIBS) $(SYSLIBS)
+
tests: tok822_test mime_test mime_nest mime_8bit mime_dom mime_trunc \
mime_cvt mime_cvt2 mime_cvt3 strip_addr_test tok822_limit_test \
- virtual8_test xtext_test scache_multi_test ehlo_mask_test
+ virtual8_test xtext_test scache_multi_test ehlo_mask_test \
+ namadr_list_test
tok822_test: tok822_parse tok822_parse.in tok822_parse.ref
./tok822_parse tok822_parse.tmp 2>&1
@@ -362,6 +370,11 @@ ehlo_mask_test: ehlo_mask ehlo_mask.in ehlo_mask.ref
diff ehlo_mask.ref ehlo_mask.tmp
rm -f ehlo_mask.tmp
+namadr_list_test: namadr_list namadr_list.in namadr_list.ref
+ -sh namadr_list.in >namadr_list.tmp 2>&1
+ diff namadr_list.ref namadr_list.tmp
+ rm -f namadr_list.tmp
+
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck
@@ -896,6 +909,7 @@ mail_params.o: ../../include/dict_db.h
mail_params.o: ../../include/dict.h
mail_params.o: ../../include/vstream.h
mail_params.o: ../../include/argv.h
+mail_params.o: ../../include/inet_proto.h
mail_params.o: mynetworks.h
mail_params.o: mail_conf.h
mail_params.o: mail_version.h
@@ -903,6 +917,9 @@ mail_params.o: mail_proto.h
mail_params.o: ../../include/iostuff.h
mail_params.o: ../../include/attr.h
mail_params.o: verp_sender.h
+mail_params.o: own_inet_addr.h
+mail_params.o: ../../include/inet_addr_list.h
+mail_params.o: ../../include/myaddrinfo.h
mail_params.o: mail_params.h
mail_pathname.o: mail_pathname.c
mail_pathname.o: ../../include/sys_defs.h
@@ -1107,10 +1124,15 @@ mynetworks.o: ../../include/msg.h
mynetworks.o: ../../include/vstring.h
mynetworks.o: ../../include/vbuf.h
mynetworks.o: ../../include/inet_addr_list.h
+mynetworks.o: ../../include/myaddrinfo.h
mynetworks.o: ../../include/name_mask.h
+mynetworks.o: ../../include/mask_addr.h
+mynetworks.o: ../../include/argv.h
mynetworks.o: own_inet_addr.h
mynetworks.o: mail_params.h
mynetworks.o: mynetworks.h
+mynetworks.o: ../../include/sock_addr.h
+mynetworks.o: been_here.h
mypwd.o: mypwd.c
mypwd.o: ../../include/sys_defs.h
mypwd.o: ../../include/mymalloc.h
@@ -1140,11 +1162,14 @@ own_inet_addr.o: ../../include/sys_defs.h
own_inet_addr.o: ../../include/msg.h
own_inet_addr.o: ../../include/mymalloc.h
own_inet_addr.o: ../../include/inet_addr_list.h
+own_inet_addr.o: ../../include/myaddrinfo.h
own_inet_addr.o: ../../include/inet_addr_local.h
own_inet_addr.o: ../../include/inet_addr_host.h
own_inet_addr.o: ../../include/stringops.h
own_inet_addr.o: ../../include/vstring.h
own_inet_addr.o: ../../include/vbuf.h
+own_inet_addr.o: ../../include/sock_addr.h
+own_inet_addr.o: ../../include/inet_proto.h
own_inet_addr.o: mail_params.h
own_inet_addr.o: own_inet_addr.h
pipe_command.o: pipe_command.c
@@ -1259,10 +1284,13 @@ resolve_local.o: ../../include/mymalloc.h
resolve_local.o: string_list.h
resolve_local.o: ../../include/match_list.h
resolve_local.o: ../../include/match_ops.h
+resolve_local.o: ../../include/myaddrinfo.h
+resolve_local.o: valid_mailhost_addr.h
+resolve_local.o: ../../include/valid_hostname.h
resolve_local.o: mail_params.h
resolve_local.o: own_inet_addr.h
+resolve_local.o: ../../include/inet_addr_list.h
resolve_local.o: resolve_local.h
-resolve_local.o: match_parent_style.h
rewrite_clnt.o: rewrite_clnt.c
rewrite_clnt.o: ../../include/sys_defs.h
rewrite_clnt.o: ../../include/msg.h
@@ -1455,6 +1483,12 @@ user_acl.o: ../../include/match_ops.h
user_acl.o: mypwd.h
user_acl.o: mail_params.h
user_acl.o: user_acl.h
+valid_mailhost_addr.o: valid_mailhost_addr.c
+valid_mailhost_addr.o: ../../include/sys_defs.h
+valid_mailhost_addr.o: ../../include/msg.h
+valid_mailhost_addr.o: ../../include/myaddrinfo.h
+valid_mailhost_addr.o: valid_mailhost_addr.h
+valid_mailhost_addr.o: ../../include/valid_hostname.h
verify.o: verify.c
verify.o: ../../include/sys_defs.h
verify.o: ../../include/msg.h
@@ -1502,6 +1536,13 @@ virtual8_maps.o: ../../include/argv.h
virtual8_maps.o: mail_params.h
virtual8_maps.o: strip_addr.h
virtual8_maps.o: virtual8_maps.h
+wildcard_inet_addr.o: wildcard_inet_addr.c
+wildcard_inet_addr.o: ../../include/sys_defs.h
+wildcard_inet_addr.o: ../../include/msg.h
+wildcard_inet_addr.o: ../../include/inet_addr_list.h
+wildcard_inet_addr.o: ../../include/myaddrinfo.h
+wildcard_inet_addr.o: ../../include/inet_addr_host.h
+wildcard_inet_addr.o: wildcard_inet_addr.h
xtext.o: xtext.c
xtext.o: ../../include/sys_defs.h
xtext.o: ../../include/msg.h
diff --git a/postfix/src/global/mail_params.c b/postfix/src/global/mail_params.c
index abdd56bd1..b05755355 100644
--- a/postfix/src/global/mail_params.c
+++ b/postfix/src/global/mail_params.c
@@ -39,6 +39,7 @@
/* int var_dont_remove;
/* char *var_inet_interfaces;
/* char *var_proxy_interfaces;
+/* char *var_inet_protocols;
/* char *var_mynetworks;
/* char *var_double_bounce_sender;
/* int var_line_limit;
@@ -152,15 +153,17 @@
#ifdef HAS_DB
#include
#endif
+#include
/* Global library. */
-#include "mynetworks.h"
-#include "mail_conf.h"
-#include "mail_version.h"
-#include "mail_proto.h"
-#include "verp_sender.h"
-#include "mail_params.h"
+#include
+#include
+#include
+#include
+#include
+#include
+#include
/*
* Special configuration variables.
@@ -198,6 +201,7 @@ char *var_pid_dir;
int var_dont_remove;
char *var_inet_interfaces;
char *var_proxy_interfaces;
+char *var_inet_protocols;
char *var_mynetworks;
char *var_double_bounce_sender;
int var_line_limit;
@@ -428,6 +432,7 @@ void mail_params_init()
{
static CONFIG_STR_TABLE first_str_defaults[] = {
VAR_SYSLOG_FACILITY, DEF_SYSLOG_FACILITY, &var_syslog_facility, 1, 0,
+ VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 1, 0,
0,
};
static CONFIG_STR_FN_TABLE function_str_defaults[] = {
@@ -532,6 +537,7 @@ void mail_params_init()
0,
};
const char *cp;
+ INET_PROTO_INFO *proto_info;
/*
* Extract syslog_facility early, so that from here on all errors are
@@ -544,6 +550,12 @@ void mail_params_init()
var_config_dir, MAIN_CONF_FILE,
VAR_SYSLOG_FACILITY, var_syslog_facility);
+ /*
+ * What protocols should we attempt to support? The result is stored in
+ * the global inet_proto_table variable.
+ */
+ proto_info = inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
+
/*
* Variables whose defaults are determined at runtime. Some sites use
* short hostnames in the host table; some sites name their system after
@@ -582,6 +594,13 @@ void mail_params_init()
*/
get_mail_conf_str_fn_table(function_str_defaults_2);
+ /*
+ * FIX 200412 The IPv6 patch did not call own_inet_addr_list() before
+ * entering the chroot jail on Linux IPv6 systems. Linux has the IPv6
+ * interface list in /proc, which is not available after chrooting.
+ */
+ (void) own_inet_addr_list();
+
/*
* The PID variable cannot be set from the configuration file!!
*/
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index 14d1f0dd2..afcce39ac 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -146,7 +146,9 @@ extern char *var_error_rcpt;
* Virtual host support. Default is to listen on all machine interfaces.
*/
#define VAR_INET_INTERFACES "inet_interfaces" /* listen addresses */
-#define DEF_INET_INTERFACES "all"
+#define INET_INTERFACES_ALL "all"
+#define INET_INTERFACES_LOCAL "loopback-only"
+#define DEF_INET_INTERFACES INET_INTERFACES_ALL
extern char *var_inet_interfaces;
#define VAR_PROXY_INTERFACES "proxy_interfaces" /* proxies, NATs */
@@ -784,13 +786,22 @@ extern int var_debug_peer_level;
* subdirectories, and how deep the forest is.
*/
#define VAR_HASH_QUEUE_NAMES "hash_queue_names"
-#define DEF_HASH_QUEUE_NAMES "incoming, active, deferred, bounce, defer, flush, hold, trace"
+#define DEF_HASH_QUEUE_NAMES "deferred, defer"
extern char *var_hash_queue_names;
#define VAR_HASH_QUEUE_DEPTH "hash_queue_depth"
#define DEF_HASH_QUEUE_DEPTH 1
extern int var_hash_queue_depth;
+ /*
+ * Multi-protocol support.
+ */
+#define INET_PROTO_NAME_IPV4 "ipv4"
+#define INET_PROTO_NAME_IPV6 "ipv6"
+#define INET_PROTO_NAME_ALL "all"
+#define VAR_INET_PROTOCOLS "inet_protocols"
+extern char *var_inet_protocols;
+
/*
* SMTP client. Timeouts inspired by RFC 1123. The SMTP recipient limit
* determines how many recipient addresses the SMTP client sends along with
@@ -894,6 +905,10 @@ extern bool var_smtp_never_ehlo;
#define DEF_SMTP_BIND_ADDR ""
extern char *var_smtp_bind_addr;
+#define VAR_SMTP_BIND_ADDR6 "smtp_bind_address6"
+#define DEF_SMTP_BIND_ADDR6 ""
+extern char *var_smtp_bind_addr6;
+
#define VAR_SMTP_HELO_NAME "smtp_helo_name"
#define DEF_SMTP_HELO_NAME "$myhostname"
extern char *var_smtp_helo_name;
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index b0254a564..eeb73cdb4 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,7 +20,7 @@
* Patches change the patchlevel and the release date. Snapshots change the
* release date only.
*/
-#define MAIL_RELEASE_DATE "20041230"
+#define MAIL_RELEASE_DATE "20050117"
#define MAIL_VERSION_NUMBER "2.2"
#define VAR_MAIL_VERSION "mail_version"
diff --git a/postfix/src/global/mime_state.c b/postfix/src/global/mime_state.c
index 7beba3aab..f5bd56056 100644
--- a/postfix/src/global/mime_state.c
+++ b/postfix/src/global/mime_state.c
@@ -1086,7 +1086,7 @@ static void body_end(void *context)
vstream_fprintf(stream, "BODY END\n");
}
-static void err_print(void *context, int err_flag, const char *text)
+static void err_print(void *unused_context, int err_flag, const char *text)
{
msg_warn("%s: %.100s", mime_state_error(err_flag), text);
}
diff --git a/postfix/src/global/mynetworks.c b/postfix/src/global/mynetworks.c
index a40fea4d0..d698be7fc 100644
--- a/postfix/src/global/mynetworks.c
+++ b/postfix/src/global/mynetworks.c
@@ -28,6 +28,13 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Dean C. Strik
+/* Department ICT Services
+/* Eindhoven University of Technology
+/* P.O. Box 513
+/* 5600 MB Eindhoven, Netherlands
+/* E-mail:
/*--*/
/* System library. */
@@ -42,20 +49,23 @@
#define IN_CLASSD_NSHIFT 28
#endif
-#define BITS_PER_ADDR 32
-
/* Utility library. */
#include
#include
#include
#include
+#include
+#include
+#include
/* Global library. */
#include
#include
#include
+#include
+#include
/* Application-specific. */
@@ -80,13 +90,16 @@ const char *mynetworks(void)
char *myname = "mynetworks";
INET_ADDR_LIST *my_addr_list;
INET_ADDR_LIST *my_mask_list;
- unsigned long addr;
- unsigned long mask;
- struct in_addr net;
int shift;
int junk;
int i;
int mask_style;
+ struct sockaddr_storage *sa;
+ struct sockaddr_storage *ma;
+ int net_mask_count = 0;
+ ARGV *argv;
+ BH_TABLE *dup_filter;
+ char **cpp;
mask_style = name_mask("mynetworks mask style", mask_styles,
var_mynetworks_style);
@@ -106,59 +119,155 @@ const char *mynetworks(void)
my_addr_list = own_inet_addr_list();
my_mask_list = own_inet_mask_list();
- for (i = 0; i < my_addr_list->used; i++) {
- addr = ntohl(my_addr_list->addrs[i].s_addr);
- mask = ntohl(my_mask_list->addrs[i].s_addr);
+ for (sa = my_addr_list->addrs, ma = my_mask_list->addrs;
+ sa < my_addr_list->addrs + my_addr_list->used;
+ sa++, ma++) {
+ unsigned long addr;
+ unsigned long mask;
+ struct in_addr net;
- switch (mask_style) {
+ if (SOCK_ADDR_FAMILY(sa) == AF_INET) {
+ addr = ntohl(SOCK_ADDR_IN_ADDR(sa).s_addr);
+ mask = ntohl(SOCK_ADDR_IN_ADDR(ma).s_addr);
- /*
- * Natural mask. This is dangerous if you're customer of an
- * ISP who gave you a small portion of their network.
- */
- case MASK_STYLE_CLASS:
- if (IN_CLASSA(addr)) {
- mask = IN_CLASSA_NET;
- shift = IN_CLASSA_NSHIFT;
- } else if (IN_CLASSB(addr)) {
- mask = IN_CLASSB_NET;
- shift = IN_CLASSB_NSHIFT;
- } else if (IN_CLASSC(addr)) {
- mask = IN_CLASSC_NET;
- shift = IN_CLASSC_NSHIFT;
- } else if (IN_CLASSD(addr)) {
- mask = IN_CLASSD_NET;
- shift = IN_CLASSD_NSHIFT;
- } else {
- msg_fatal("%s: bad address class: %s",
- myname, inet_ntoa(my_addr_list->addrs[i]));
+ switch (mask_style) {
+
+ /*
+ * Natural mask. This is dangerous if you're customer of
+ * an ISP who gave you a small portion of their network.
+ */
+ case MASK_STYLE_CLASS:
+ if (IN_CLASSA(addr)) {
+ mask = IN_CLASSA_NET;
+ shift = IN_CLASSA_NSHIFT;
+ } else if (IN_CLASSB(addr)) {
+ mask = IN_CLASSB_NET;
+ shift = IN_CLASSB_NSHIFT;
+ } else if (IN_CLASSC(addr)) {
+ mask = IN_CLASSC_NET;
+ shift = IN_CLASSC_NSHIFT;
+ } else if (IN_CLASSD(addr)) {
+ mask = IN_CLASSD_NET;
+ shift = IN_CLASSD_NSHIFT;
+ } else {
+ msg_fatal("%s: unknown address class: %s",
+ myname, inet_ntoa(SOCK_ADDR_IN_ADDR(sa)));
+ }
+ break;
+
+ /*
+ * Subnet mask. This is less unsafe, but still bad if
+ * you're connected to a large subnet.
+ */
+ case MASK_STYLE_SUBNET:
+ for (junk = mask, shift = MAI_V4ADDR_BITS; junk != 0;
+ shift--, junk <<= 1)
+ /* void */ ;
+ break;
+
+ /*
+ * Host only. Do not relay authorize other hosts.
+ */
+ case MASK_STYLE_HOST:
+ mask = ~0;
+ shift = 0;
+ break;
+
+ default:
+ msg_panic("unknown mynetworks mask style: %s",
+ var_mynetworks_style);
}
- break;
-
- /*
- * Subnet mask. This is safe, but breaks backwards
- * compatibility when used as default setting.
- */
- case MASK_STYLE_SUBNET:
- for (junk = mask, shift = BITS_PER_ADDR; junk != 0; shift--, (junk <<= 1))
- /* void */ ;
- break;
-
- /*
- * Host only. Do not relay authorize other hosts.
- */
- case MASK_STYLE_HOST:
- mask = ~0;
- shift = 0;
- break;
-
- default:
- msg_panic("unknown mynetworks mask style: %s",
- var_mynetworks_style);
+ net.s_addr = htonl(addr & mask);
+ vstring_sprintf_append(result, "%s/%d ",
+ inet_ntoa(net), MAI_V4ADDR_BITS - shift);
+ net_mask_count++;
+ continue;
}
- net.s_addr = htonl(addr & mask);
- vstring_sprintf_append(result, "%s/%d ",
- inet_ntoa(net), BITS_PER_ADDR - shift);
+#ifdef HAS_IPV6
+ else if (SOCK_ADDR_FAMILY(sa) == AF_INET6) {
+ MAI_HOSTADDR_STR hostaddr;
+ unsigned char *ac;
+ unsigned char *end;
+ unsigned char ch;
+ struct sockaddr_in6 net6;
+
+ switch (mask_style) {
+
+ /*
+ * There are no classes for IPv6. We default to subnets
+ * instead.
+ */
+ case MASK_STYLE_CLASS:
+
+ /* FALLTHROUGH */
+
+ /*
+ * Subnet mask.
+ */
+ case MASK_STYLE_SUBNET:
+ ac = (unsigned char *) &SOCK_ADDR_IN6_ADDR(ma);
+ end = ac + sizeof(SOCK_ADDR_IN6_ADDR(ma));
+ shift = MAI_V6ADDR_BITS;
+ while (ac < end) {
+ if ((ch = *ac++) == (unsigned char) -1) {
+ shift -= CHAR_BIT;
+ continue;
+ } else {
+ while (ch != 0)
+ shift--, ch <<= 1;
+ break;
+ }
+ }
+ break;
+
+ /*
+ * Host only. Do not relay authorize other hosts.
+ */
+ case MASK_STYLE_HOST:
+ shift = 0;
+ break;
+
+ default:
+ msg_panic("unknown mynetworks mask style: %s",
+ var_mynetworks_style);
+ }
+ /* FIX 200501: IPv6 patch did not clear host bits. */
+ net6 = *SOCK_ADDR_IN6_PTR(sa);
+ mask_addr((unsigned char *) &net6.sin6_addr,
+ sizeof(net6.sin6_addr),
+ MAI_V6ADDR_BITS - shift);
+ SOCKADDR_TO_HOSTADDR(SOCK_ADDR_PTR(&net6), SOCK_ADDR_LEN(&net6),
+ &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
+ vstring_sprintf_append(result, "[%s]/%d ",
+ hostaddr.buf, MAI_V6ADDR_BITS - shift);
+ net_mask_count++;
+ continue;
+ }
+#endif
+ else {
+ msg_warn("%s: skipping unknown address family %d",
+ myname, SOCK_ADDR_FAMILY(sa));
+ continue;
+ }
+ }
+
+ /*
+ * FIX 200501 IPv6 patch produced repeated results. Some systems
+ * report the same interface multiple times, notably multi-homed
+ * systems with IPv6 link-local or site-local addresses. A
+ * straight-forward sort+uniq produces ugly results, though. Instead
+ * we preserve the original order and use a duplicate filter to
+ * suppress repeated information.
+ */
+ if (net_mask_count > 1) {
+ argv = argv_split(vstring_str(result), " ");
+ VSTRING_RESET(result);
+ dup_filter = been_here_init(net_mask_count, BH_FLAG_NONE);
+ for (cpp = argv->argv; cpp < argv->argv + argv->argc; cpp++)
+ if (!been_here_fixed(dup_filter, *cpp))
+ vstring_sprintf_append(result, "%s ", *cpp);
+ argv_free(argv);
+ been_here_free(dup_filter);
}
if (msg_verbose)
msg_info("%s: %s", myname, vstring_str(result));
@@ -167,17 +276,22 @@ const char *mynetworks(void)
}
#ifdef TEST
+#include
char *var_inet_interfaces;
char *var_mynetworks_style;
int main(int argc, char **argv)
{
- if (argc != 3)
- msg_fatal("usage: %s mask_style interface_list", argv[0]);
+ INET_PROTO_INFO *proto_info;
+
+ if (argc != 4)
+ msg_fatal("usage: %s protocols mask_style interface_list (e.g. \"all subnet all\")",
+ argv[0]);
msg_verbose = 10;
- var_inet_interfaces = argv[2];
- var_mynetworks_style = argv[1];
+ proto_info = inet_proto_init(argv[0], argv[1]);
+ var_mynetworks_style = argv[2];
+ var_inet_interfaces = argv[3];
mynetworks();
}
diff --git a/postfix/src/global/namadr_list.in b/postfix/src/global/namadr_list.in
new file mode 100644
index 000000000..a19a45263
--- /dev/null
+++ b/postfix/src/global/namadr_list.in
@@ -0,0 +1,17 @@
+./namadr_list 168.100.189.0/28 dummy 168.100.189.2
+./namadr_list 168.100.189.0/28 dummy 168.100.189.16
+./namadr_list 168.100.189.0/98 dummy 168.100.189.16
+./namadr_list 168.100.589.0/28 dummy 168.100.189.16
+./namadr_list 168.100.189.0/28 dummy 168.100.989.16
+./namadr_list 2001:240:5c7:0:2d0:b7ff:fe88:2ca7 dummy 2001:240:5c7:0:2d0:b7ff:fe88:2ca7
+./namadr_list '[2001:240:5c7:0:2d0:b7ff:fe88:2ca7]' dummy 2001:240:5c7:0:2d0:b7ff:fe88:2ca7
+./namadr_list '[2001:240:5c7:0:2d0:b7ff:fe88:2ca7]' dummy 2001:240:5c7:0:2d0:b7ff:fe88:2ca8
+./namadr_list '[2001:240:5c7:0:2d0:b7ff:fe88:2ca7]/64' dummy 2001:240:5c7:0:2d0:b7ff:fe88:2ca8
+./namadr_list '[2001:240:5c7::]/64' dummy 2001:240:5c7:0:2d0:b7ff:fe88:2ca8
+./namadr_list '[2001:240:5c7::]/64' dummy 2001:24:5c7:0:2d0:b7ff:fe88:2ca8
+./namadr_list '[2001:24:5c7:0:2d0:b7ff:fe88:2ca8]' dummy 2001:24:5c7:0:2d0:b7ff:fe88:2ca8
+./namadr_list '[2001:24:5c7:0:2d0:b7ff:fe88:2ca8]' dummy 2001:24:5c7:0:2d0:b7ff:fe88:2ca7
+./namadr_list 168.100.189.2 dummy 168.100.189.2
+./namadr_list 168.100.189.2 dummy 168.100.189.3
+./namadr_list '[168.100.189.2]' dummy 168.100.189.2
+./namadr_list '[168.100.189.2]' dummy 168.100.189.3
diff --git a/postfix/src/global/namadr_list.ref b/postfix/src/global/namadr_list.ref
new file mode 100644
index 000000000..fd6d70233
--- /dev/null
+++ b/postfix/src/global/namadr_list.ref
@@ -0,0 +1,17 @@
+dummy/168.100.189.2: YES
+dummy/168.100.189.16: NO
+./namadr_list: fatal: bad net/mask pattern: "168.100.189.0/98"
+./namadr_list: fatal: bad net/mask pattern: "168.100.589.0/28"
+dummy/168.100.989.16: NO
+./namadr_list: fatal: unsupported dictionary type: 2001
+dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca7: YES
+dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca8: NO
+./namadr_list: fatal: non-null host address bits in "2001:240:5c7:0:2d0:b7ff:fe88:2ca7/64", perhaps you should use "2001:240:5c7::/64" instead
+dummy/2001:240:5c7:0:2d0:b7ff:fe88:2ca8: YES
+dummy/2001:24:5c7:0:2d0:b7ff:fe88:2ca8: NO
+dummy/2001:24:5c7:0:2d0:b7ff:fe88:2ca8: YES
+dummy/2001:24:5c7:0:2d0:b7ff:fe88:2ca7: NO
+dummy/168.100.189.2: YES
+dummy/168.100.189.3: NO
+dummy/168.100.189.2: YES
+dummy/168.100.189.3: NO
diff --git a/postfix/src/global/own_inet_addr.c b/postfix/src/global/own_inet_addr.c
index 3239d6e56..d3b7d5aec 100644
--- a/postfix/src/global/own_inet_addr.c
+++ b/postfix/src/global/own_inet_addr.c
@@ -47,14 +47,8 @@
/* System library. */
#include
-#include
-#include
#include
-#ifdef STRCASECMP_IN_STRINGS_H
-#include
-#endif
-
/* Utility library. */
#include
@@ -63,6 +57,9 @@
#include
#include
#include
+#include
+#include
+#include
/* Global library. */
@@ -88,6 +85,9 @@ static void own_inet_addr_init(INET_ADDR_LIST *addr_list,
char *bufp;
int nvirtual;
int nlocal;
+ MAI_HOSTADDR_STR hostaddr;
+ struct sockaddr_storage *sa;
+ struct sockaddr_storage *ma;
inet_addr_list_init(addr_list);
inet_addr_list_init(mask_list);
@@ -96,14 +96,31 @@ static void own_inet_addr_init(INET_ADDR_LIST *addr_list,
* If we are listening on all interfaces (default), ask the system what
* the interfaces are.
*/
- if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
- if (inet_addr_local(addr_list, mask_list) == 0)
+ if (strcmp(var_inet_interfaces, INET_INTERFACES_ALL) == 0) {
+ if (inet_addr_local(addr_list, mask_list,
+ inet_proto_info()->ai_family_list) == 0)
msg_fatal("could not find any active network interfaces");
-#if 0
- if (addr_list->used == 1)
- msg_warn("found only one active network interface: %s",
- inet_ntoa(addr_list->addrs[0]));
-#endif
+ }
+
+ /*
+ * Select all loopback interfaces from the system's available interface
+ * list.
+ */
+ else if (strcmp(var_inet_interfaces, INET_INTERFACES_LOCAL) == 0) {
+ inet_addr_list_init(&local_addrs);
+ inet_addr_list_init(&local_masks);
+ if (inet_addr_local(&local_addrs, &local_masks,
+ inet_proto_info()->ai_family_list) == 0)
+ msg_fatal("could not find any active network interfaces");
+ for (sa = local_addrs.addrs, ma = local_masks.addrs;
+ sa < local_addrs.addrs + local_addrs.used; sa++, ma++) {
+ if (sock_addr_in_loopback(SOCK_ADDR_PTR(sa))) {
+ inet_addr_list_append(addr_list, SOCK_ADDR_PTR(sa));
+ inet_addr_list_append(mask_list, SOCK_ADDR_PTR(ma));
+ }
+ }
+ inet_addr_list_free(&local_addrs);
+ inet_addr_list_free(&local_masks);
}
/*
@@ -127,19 +144,29 @@ static void own_inet_addr_init(INET_ADDR_LIST *addr_list,
*/
inet_addr_list_uniq(addr_list);
+ /*
+ * Find out the netmask for each virtual interface, by looking it up
+ * among all the local interfaces.
+ */
inet_addr_list_init(&local_addrs);
inet_addr_list_init(&local_masks);
- if (inet_addr_local(&local_addrs, &local_masks) == 0)
+ if (inet_addr_local(&local_addrs, &local_masks,
+ inet_proto_info()->ai_family_list) == 0)
msg_fatal("could not find any active network interfaces");
for (nvirtual = 0; nvirtual < addr_list->used; nvirtual++) {
for (nlocal = 0; /* see below */ ; nlocal++) {
- if (nlocal >= local_addrs.used)
+ if (nlocal >= local_addrs.used) {
+ SOCKADDR_TO_HOSTADDR(
+ SOCK_ADDR_PTR(addr_list->addrs + nvirtual),
+ SOCK_ADDR_LEN(addr_list->addrs + nvirtual),
+ &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
msg_fatal("parameter %s: no local interface found for %s",
- VAR_INET_INTERFACES,
- inet_ntoa(addr_list->addrs[nvirtual]));
- if (addr_list->addrs[nvirtual].s_addr
- == local_addrs.addrs[nlocal].s_addr) {
- inet_addr_list_append(mask_list, &local_masks.addrs[nlocal]);
+ VAR_INET_INTERFACES, hostaddr.buf);
+ }
+ if (SOCK_ADDR_EQ_ADDR(addr_list->addrs + nvirtual,
+ local_addrs.addrs + nlocal)) {
+ inet_addr_list_append(mask_list,
+ SOCK_ADDR_PTR(local_masks.addrs + nlocal));
break;
}
}
@@ -151,7 +178,7 @@ static void own_inet_addr_init(INET_ADDR_LIST *addr_list,
/* own_inet_addr - is this my own internet address */
-int own_inet_addr(struct in_addr * addr)
+int own_inet_addr(struct sockaddr * addr)
{
int i;
@@ -159,7 +186,7 @@ int own_inet_addr(struct in_addr * addr)
own_inet_addr_init(&addr_list, &mask_list);
for (i = 0; i < addr_list.used; i++)
- if (addr->s_addr == addr_list.addrs[i].s_addr)
+ if (SOCK_ADDR_EQ_ADDR(addr, addr_list.addrs + i))
return (1);
return (0);
}
@@ -213,7 +240,7 @@ static void proxy_inet_addr_init(INET_ADDR_LIST *addr_list)
/* proxy_inet_addr - is this my proxy internet address */
-int proxy_inet_addr(struct in_addr * addr)
+int proxy_inet_addr(struct sockaddr * addr)
{
int i;
@@ -224,7 +251,7 @@ int proxy_inet_addr(struct in_addr * addr)
proxy_inet_addr_init(&proxy_list);
for (i = 0; i < proxy_list.used; i++)
- if (addr->s_addr == proxy_list.addrs[i].s_addr)
+ if (SOCK_ADDR_EQ_ADDR(addr, proxy_list.addrs + i))
return (1);
return (0);
}
diff --git a/postfix/src/global/own_inet_addr.h b/postfix/src/global/own_inet_addr.h
index 94fbac6a6..2f3d2f741 100644
--- a/postfix/src/global/own_inet_addr.h
+++ b/postfix/src/global/own_inet_addr.h
@@ -12,17 +12,17 @@
/* .nf
/*
- * System library.
+ * Utility library.
*/
-#include
+#include
/*
* External interface.
*/
-extern int own_inet_addr(struct in_addr *);
+extern int own_inet_addr(struct sockaddr *);
extern struct INET_ADDR_LIST *own_inet_addr_list(void);
extern struct INET_ADDR_LIST *own_inet_mask_list(void);
-extern int proxy_inet_addr(struct in_addr *);
+extern int proxy_inet_addr(struct sockaddr *);
extern struct INET_ADDR_LIST *proxy_inet_addr_list(void);
/* LICENSE
diff --git a/postfix/src/global/resolve_local.c b/postfix/src/global/resolve_local.c
index bad7abf12..830ad54c2 100644
--- a/postfix/src/global/resolve_local.c
+++ b/postfix/src/global/resolve_local.c
@@ -14,8 +14,8 @@
/* resolve_local() determines if the named domain resolves to the
/* local mail system, either by case-insensitive exact match
/* against the domains, files or tables listed in $mydestination,
-/* or by any of the network addresses listed in $inet_interfaces
-/* or in $proxy_interfaces.
+/* or by a match of an [address-literal] against of the network
+/* addresses listed in $inet_interfaces or in $proxy_interfaces.
/*
/* resolve_local_init() performs initialization. If this routine is
/* not called explicitly ahead of time, it will be called on the fly.
@@ -40,26 +40,20 @@
/* System library. */
#include
-#include
-#include
-#include
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
/* Utility library. */
#include
#include
#include
+#include
+#include
/* Global library. */
#include
#include
#include
-#include
/* Application-specific */
@@ -80,19 +74,26 @@ int resolve_local(const char *addr)
{
char *saved_addr = mystrdup(addr);
char *dest;
- struct in_addr ipaddr;
+ const char *bare_dest;
+ struct addrinfo *res0 = 0;
int len;
-#define RETURN(x) { myfree(saved_addr); return(x); }
+#define RETURN(x) \
+ do { \
+ myfree(saved_addr); \
+ if (res0) \
+ freeaddrinfo(res0); \
+ return(x); \
+ } while (0)
if (resolve_local_list == 0)
resolve_local_init();
/*
* Strip one trailing dot but not dot-dot.
- *
+ *
* XXX This should not be distributed all over the code. Problem is,
- * addresses can enter the system via multiple paths: networks, local
+ * addresses can enter the system via multiple paths: networks, local
* forward/alias/include files, even as the result of address rewriting.
*/
len = strlen(saved_addr);
@@ -113,14 +114,42 @@ int resolve_local(const char *addr)
/*
* Compare the destination against the list of interface addresses that
* we are supposed to listen on.
+ *
+ * The destination may be an IPv6 address literal that was buried somewhere
+ * inside a deeply recursively nested address. This information comes
+ * from an untrusted source, and Wietse is not confident that everyone's
+ * getaddrinfo() etc. implementation is sufficiently robust. The syntax
+ * is complex enough with null field compression and with IPv4-in-IPv6
+ * addresses that errors are likely.
+ *
+ * The solution below is ad-hoc. We neutralize the string as soon as we
+ * realize that its contents could be harmful. We neutralize the string
+ * here, instead of neutralizing it in every resolve_local() caller.
+ * That's because resolve_local knows how the address is going to be
+ * parsed and converted into binary form.
+ *
+ * There are several more structural solutions to this.
+ *
+ * - One solution is to disallow address literals. This is not as bad as it
+ * seems: I have never seen actual legitimate use of address literals.
+ *
+ * - Another solution is to label each string with a trustworthiness label
+ * and to expect that all Postfix infrastructure will exercise additional
+ * caution when given a string with untrusted content. This is not likely
+ * to happen.
+ *
+ * FIX 200501 IPv6 patch did not require "IPv6:" prefix in numerical
+ * addresses.
*/
dest = saved_addr;
if (*dest == '[' && dest[len - 1] == ']') {
dest++;
dest[len -= 2] = 0;
- if ((ipaddr.s_addr = inet_addr(dest)) != INADDR_NONE
- && (own_inet_addr(&ipaddr) || proxy_inet_addr(&ipaddr)))
- RETURN(1);
+ if ((bare_dest = valid_mailhost_addr(dest, DO_GRIPE)) != 0
+ && hostaddr_to_sockaddr(bare_dest, (char *) 0, 0, &res0) == 0) {
+ if (own_inet_addr(res0->ai_addr) || proxy_inet_addr(res0->ai_addr))
+ RETURN(1);
+ }
}
/*
diff --git a/postfix/src/global/smtp_stream.c b/postfix/src/global/smtp_stream.c
index aea0c1a4b..ba4b78e7c 100644
--- a/postfix/src/global/smtp_stream.c
+++ b/postfix/src/global/smtp_stream.c
@@ -225,7 +225,6 @@ void smtp_printf(VSTREAM *stream, const char *fmt,...)
int smtp_fgetc(VSTREAM *stream)
{
- int err;
int ch;
/*
diff --git a/postfix/src/global/valid_mailhost_addr.c b/postfix/src/global/valid_mailhost_addr.c
new file mode 100644
index 000000000..79a790018
--- /dev/null
+++ b/postfix/src/global/valid_mailhost_addr.c
@@ -0,0 +1,152 @@
+/*++
+/* NAME
+/* valid_mailhost_addr 3
+/* SUMMARY
+/* mailhost address syntax validation
+/* SYNOPSIS
+/* #include
+/*
+/* const char *valid_mailhost_addr(name, gripe)
+/* const char *name;
+/* int gripe;
+/*
+/* int valid_mailhost_literal(addr, gripe)
+/* const char *addr;
+/* int gripe;
+/* DESCRIPTION
+/* valid_mailhost_addr() requires that the input is a valid
+/* RFC 2821 string representation of an IPv4 or IPv6 network
+/* address. A valid IPv4 address is in dotted quad decimal
+/* form. A valid IPv6 address includes the "IPV6:" prefix as
+/* required by RFC 2821, and is in valid hexadecimal form or
+/* in valid IPv4-in-IPv6 form. The result value is the bare
+/* address in the input argument (i.e. text after "IPV6:"
+/* prefix, if any) in case of success, a null pointer in case
+/* of failure.
+/*
+/* valid_mailhost_literal() requires an address enclosed in
+/* []. The result is non-zero in case of success, zero in
+/* case of failure.
+/*
+/* These routines operate silently unless the gripe parameter
+/* specifies a non-zero value. The macros DO_GRIPE and DONT_GRIPE
+/* provide suitable constants.
+/*
+/* The IPV6_COL macro defines the "IPv6:" prefix.
+/* DIAGNOSTICS
+/* Warnings are logged with msg_warn().
+/* SEE ALSO
+/* valid_hostname(3)
+/* RFC 952, RFC 1123, RFC 1035, RFC 2821
+/* 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
+#include
+
+#ifdef STRCASECMP_IN_STRINGS_H
+#include
+#endif
+
+/* Utility library. */
+
+#include
+#include
+
+/* Global library. */
+
+#include
+
+/* Application-specific. */
+
+#define IPV6_COL_LEN (sizeof(IPV6_COL) - 1)
+#define HAS_IPV6_COL(str) (strncasecmp((str), IPV6_COL, IPV6_COL_LEN) == 0)
+#define SKIP_IPV6_COL(str) (HAS_IPV6_COL(str) ? (str) + IPV6_COL_LEN : (str))
+
+/* valid_mailhost_addr - validate RFC 2821 numerical address form */
+
+const char *valid_mailhost_addr(const char *addr, int gripe)
+{
+ const char *bare_addr;
+
+ bare_addr = SKIP_IPV6_COL(addr);
+ return ((bare_addr != addr ? valid_ipv6_hostaddr : valid_ipv4_hostaddr)
+ (bare_addr, gripe) ? bare_addr : 0);
+}
+
+/* valid_mailhost_literal - validate [RFC 2821 numerical address] form */
+
+int valid_mailhost_literal(const char *addr, int gripe)
+{
+ const char *myname = "valid_mailhost_literal";
+ MAI_HOSTADDR_STR hostaddr;
+ const char *last;
+ size_t address_bytes;
+
+ if (*addr != '[') {
+ if (gripe)
+ msg_warn("%s: '[' expected at start: %.100s", myname, addr);
+ return (0);
+ }
+ if ((last = strchr(addr, ']')) == 0) {
+ if (gripe)
+ msg_warn("%s: ']' expected at end: %.100s", myname, addr);
+ return (0);
+ }
+ if (last[1]) {
+ if (gripe)
+ msg_warn("%s: unexpected text after ']': %.100s", myname, addr);
+ return (0);
+ }
+ if ((address_bytes = last - addr - 1) >= sizeof(hostaddr.buf)) {
+ if (gripe)
+ msg_warn("%s: too much text: %.100s", myname, addr);
+ return (0);
+ }
+ strncpy(hostaddr.buf, addr + 1, address_bytes);
+ hostaddr.buf[address_bytes] = 0;
+ return (valid_mailhost_addr(hostaddr.buf, gripe) != 0);
+}
+
+#ifdef TEST
+
+ /*
+ * Test program - reads hostnames from stdin, reports invalid hostnames to
+ * stderr.
+ */
+#include
+
+#include
+#include
+#include
+#include
+
+int main(int unused_argc, char **argv)
+{
+ VSTRING *buffer = vstring_alloc(1);
+
+ msg_vstream_init(argv[0], VSTREAM_ERR);
+ msg_verbose = 1;
+
+ while (vstring_fgets_nonl(buffer, VSTREAM_IN)) {
+ msg_info("testing: \"%s\"", vstring_str(buffer));
+ if (vstring_str(buffer)[0] == '[')
+ valid_mailhost_literal(vstring_str(buffer), DO_GRIPE);
+ else
+ valid_mailhost_addr(vstring_str(buffer), DO_GRIPE);
+ }
+ exit(0);
+}
+
+#endif
diff --git a/postfix/src/global/valid_mailhost_addr.h b/postfix/src/global/valid_mailhost_addr.h
new file mode 100644
index 000000000..95630ae50
--- /dev/null
+++ b/postfix/src/global/valid_mailhost_addr.h
@@ -0,0 +1,38 @@
+#ifndef _VALID_MAILHOST_ADDR_H_INCLUDED_
+#define _VALID_MAILHOST_ADDR_H_INCLUDED_
+
+/*++
+/* NAME
+/* valid_mailhost_addr 3h
+/* SUMMARY
+/* mailhost address syntax validation
+/* SYNOPSIS
+/* #include
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include
+
+ /*
+ * External interface
+ */
+#define IPV6_COL "IPv6:" /* RFC 2821 */
+
+extern const char *valid_mailhost_addr(const char *, int);
+extern int valid_mailhost_literal(const char *, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/global/wildcard_inet_addr.c b/postfix/src/global/wildcard_inet_addr.c
new file mode 100644
index 000000000..97f6c4676
--- /dev/null
+++ b/postfix/src/global/wildcard_inet_addr.c
@@ -0,0 +1,68 @@
+/*++
+/* NAME
+/* wildcard_inet_addr 3
+/* SUMMARY
+/* expand wild-card address
+/* SYNOPSIS
+/* #include
+/*
+/* INET_ADDR_LIST *wildcard_inet_addr(void)
+/* DESCRIPTION
+/* wildcard_inet_addr() determines all wild-card addresses
+/* for all supported address families.
+/* DIAGNOSTICS
+/* Fatal errors: out of memory.
+/* SEE ALSO
+/* inet_addr_list(3) address list management
+/* 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
+/*
+/* Dean C. Strik
+/* Department ICT
+/* Eindhoven University of Technology
+/* P.O. Box 513
+/* 5600 MB Eindhoven, Netherlands
+/* E-mail:
+/*--*/
+
+/* System library. */
+
+#include
+
+/* Utility library. */
+
+#include
+#include
+#include
+
+/* Global library. */
+
+#include
+
+/* Application-specific. */
+
+static INET_ADDR_LIST wild_addr_list;
+
+static void wildcard_inet_addr_init(INET_ADDR_LIST *addr_list)
+{
+ inet_addr_list_init(addr_list);
+ if (inet_addr_host(addr_list, "") == 0)
+ msg_fatal("could not get list of wildcard addresses");
+}
+
+/* wildcard_inet_addr_list - return list of addresses */
+
+INET_ADDR_LIST *wildcard_inet_addr_list(void)
+{
+ if (wild_addr_list.used == 0)
+ wildcard_inet_addr_init(&wild_addr_list);
+
+ return (&wild_addr_list);
+}
diff --git a/postfix/src/global/wildcard_inet_addr.h b/postfix/src/global/wildcard_inet_addr.h
new file mode 100644
index 000000000..46b12e20f
--- /dev/null
+++ b/postfix/src/global/wildcard_inet_addr.h
@@ -0,0 +1,33 @@
+#ifndef _WILDCARD_INET_ADDR_H_INCLUDED_
+#define _WILDCARD_INET_ADDR_H_INCLUDED_
+
+/*++
+/* NAME
+/* wildcard_inet_addr 3h
+/* SUMMARY
+/* grab the list of wildcard IP addresses.
+/* SYNOPSIS
+/* #include
+/* DESCRIPTION
+/* .nf
+/*--*/
+
+ /*
+ * Utility library.
+ */
+#include
+
+ /*
+ * External interface.
+ */
+extern struct INET_ADDR_LIST *wildcard_inet_addr_list(void);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* foo
+/* AUTHOR(S)
+/* Jun-ichiro itojun Hagino
+/*--*/
+
+#endif
diff --git a/postfix/src/global/xtext.c b/postfix/src/global/xtext.c
index 959dd1aef..c711cafda 100644
--- a/postfix/src/global/xtext.c
+++ b/postfix/src/global/xtext.c
@@ -143,7 +143,7 @@ static int read_buf(VSTREAM *fp, VSTRING *buf)
return (len);
}
-main(int unused_argc, char **unused_argv)
+int main(int unused_argc, char **unused_argv)
{
VSTRING *unquoted = vstring_alloc(BUFLEN);
VSTRING *quoted = vstring_alloc(100);
diff --git a/postfix/src/lmtp/Makefile.in b/postfix/src/lmtp/Makefile.in
index 84c822c45..416ce71ed 100644
--- a/postfix/src/lmtp/Makefile.in
+++ b/postfix/src/lmtp/Makefile.in
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -86,7 +86,10 @@ lmtp_addr.o: ../../include/vstring.h
lmtp_addr.o: ../../include/vbuf.h
lmtp_addr.o: ../../include/mymalloc.h
lmtp_addr.o: ../../include/inet_addr_list.h
+lmtp_addr.o: ../../include/myaddrinfo.h
lmtp_addr.o: ../../include/stringops.h
+lmtp_addr.o: ../../include/sock_addr.h
+lmtp_addr.o: ../../include/inet_proto.h
lmtp_addr.o: ../../include/mail_params.h
lmtp_addr.o: ../../include/own_inet_addr.h
lmtp_addr.o: ../../include/dns.h
@@ -129,9 +132,13 @@ lmtp_connect.o: ../../include/timed_connect.h
lmtp_connect.o: ../../include/stringops.h
lmtp_connect.o: ../../include/host_port.h
lmtp_connect.o: ../../include/sane_connect.h
+lmtp_connect.o: ../../include/inet_addr_list.h
+lmtp_connect.o: ../../include/myaddrinfo.h
+lmtp_connect.o: ../../include/sock_addr.h
lmtp_connect.o: ../../include/mail_params.h
lmtp_connect.o: ../../include/mail_proto.h
lmtp_connect.o: ../../include/attr.h
+lmtp_connect.o: ../../include/own_inet_addr.h
lmtp_connect.o: ../../include/dns.h
lmtp_connect.o: lmtp.h
lmtp_connect.o: ../../include/argv.h
diff --git a/postfix/src/lmtp/lmtp_addr.c b/postfix/src/lmtp/lmtp_addr.c
index 6c6c3259e..1710f787d 100644
--- a/postfix/src/lmtp/lmtp_addr.c
+++ b/postfix/src/lmtp/lmtp_addr.c
@@ -67,10 +67,6 @@
#include
#include
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
/* Utility library. */
#include
@@ -78,6 +74,9 @@
#include
#include
#include
+#include
+#include
+#include
/* Global library. */
@@ -98,17 +97,16 @@
static void lmtp_print_addr(char *what, DNS_RR *addr_list)
{
DNS_RR *addr;
- struct in_addr in_addr;
+ MAI_HOSTADDR_STR hostaddr;
msg_info("begin %s address list", what);
for (addr = addr_list; addr; addr = addr->next) {
- if (addr->data_len > sizeof(addr)) {
- msg_warn("skipping address length %d", addr->data_len);
+ if (dns_rr_to_pa(addr, &hostaddr) == 0) {
+ msg_warn("skipping record type %s: %m", dns_strtype(addr->type));
} else {
- memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
msg_info("pref %4d host %s/%s",
addr->pref, addr->name,
- inet_ntoa(in_addr));
+ hostaddr.buf);
}
}
msg_info("end %s address list", what);
@@ -119,11 +117,13 @@ static void lmtp_print_addr(char *what, DNS_RR *addr_list)
static DNS_RR *lmtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
{
char *myname = "lmtp_addr_one";
- struct in_addr inaddr;
- DNS_FIXED fixed;
DNS_RR *addr = 0;
DNS_RR *rr;
- struct hostent *hp;
+ int aierr;
+ struct addrinfo *res0;
+ struct addrinfo *res;
+ INET_PROTO_INFO *proto_info = inet_proto_info();
+ int found;
if (msg_verbose)
msg_info("%s: host %s", myname, host);
@@ -131,42 +131,53 @@ static DNS_RR *lmtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI
/*
* Interpret a numerical name as an address.
*/
- if (ISDIGIT(host[0]) && (inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
- memset((char *) &fixed, 0, sizeof(fixed));
- return (dns_rr_append(addr_list,
- dns_rr_create(host, &fixed, pref,
- (char *) &inaddr, sizeof(inaddr))));
+ if (hostaddr_to_sockaddr(host, (char *) 0, 0, &res0) == 0
+ && strchr((char *) proto_info->sa_family_list, res0->ai_family) != 0) {
+ if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0)
+ msg_fatal("host %s: conversion error for address family %d: %m",
+ host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
+ addr_list = dns_rr_append(addr_list, addr);
+ freeaddrinfo(res0);
+ return (addr_list);
}
/*
- * Use gethostbyname() when DNS is disabled.
+ * Use native name service when DNS is disabled.
*/
+#define RETRY_AI_ERROR(e) \
+ ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
+
if (var_disable_dns) {
- memset((char *) &fixed, 0, sizeof(fixed));
- if ((hp = gethostbyname(host)) == 0) {
- vstring_sprintf(why, "%s: host not found", host);
- lmtp_errno = LMTP_FAIL;
- } else if (hp->h_addrtype != AF_INET) {
- vstring_sprintf(why, "%s: host not found", host);
- msg_warn("%s: unknown address family %d for %s",
- myname, hp->h_addrtype, host);
- lmtp_errno = LMTP_FAIL;
+ if ((aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0)) != 0) {
+ vstring_sprintf(why, "%s: %s", host, MAI_STRERROR(aierr));
+ lmtp_errno = (RETRY_AI_ERROR(aierr) ? LMTP_RETRY : LMTP_FAIL);
} else {
- while (hp->h_addr_list[0]) {
- addr_list = dns_rr_append(addr_list,
- dns_rr_create(host, &fixed, pref,
- hp->h_addr_list[0],
- sizeof(inaddr)));
- hp->h_addr_list++;
+ for (found = 0, res = res0; res != 0; res = res->ai_next) {
+ if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
+ msg_info("skipping address family %d for host %s",
+ res->ai_family, host);
+ continue;
+ }
+ found++;
+ if ((addr = dns_sa_to_rr(host, pref, res->ai_addr)) == 0)
+ msg_fatal("host %s: conversion error for address family %d: %m",
+ host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
+ addr_list = dns_rr_append(addr_list, addr);
}
+ freeaddrinfo(res0);
+ if (found == 0) {
+ vstring_sprintf(why, "%s: host not found", host);
+ lmtp_errno = LMTP_FAIL;
+ }
+ return (addr_list);
}
- return (addr_list);
}
/*
* Append the addresses for this host to the address list.
*/
- switch (dns_lookup(host, T_A, RES_DEFNAMES, &addr, (VSTRING *) 0, why)) {
+ switch (dns_lookup_v(host, RES_DEFNAMES, &addr, (VSTRING *) 0, why,
+ DNS_REQ_FLAG_ALL, proto_info->dns_atype_list)) {
case DNS_OK:
for (rr = addr; rr; rr = rr->next)
rr->pref = pref;
diff --git a/postfix/src/lmtp/lmtp_connect.c b/postfix/src/lmtp/lmtp_connect.c
index 36c19246c..e00a15114 100644
--- a/postfix/src/lmtp/lmtp_connect.c
+++ b/postfix/src/lmtp/lmtp_connect.c
@@ -94,16 +94,20 @@
#include
#include
#include
+#include
+#include
+#include
/* Global library. */
#include
#include
+#include
/* DNS library. */
#include
-
+
/* Application-specific. */
#include "lmtp.h"
@@ -168,14 +172,18 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
const char *destination, VSTRING *why)
{
char *myname = "lmtp_connect_addr";
- struct sockaddr_in sin;
+ struct sockaddr_storage ss;
+ struct sockaddr *sa = SOCK_ADDR_PTR(&ss);
+ SOCKADDR_SIZE salen = sizeof(ss);
+ MAI_HOSTADDR_STR hostaddr;
int sock;
/*
* Sanity checks.
*/
- if (addr->data_len > sizeof(sin.sin_addr)) {
- msg_warn("%s: skip address with length %d", myname, addr->data_len);
+ if (dns_rr_to_sa(addr, port, sa, &salen) != 0) {
+ msg_warn("%s: skip address type %s: %m",
+ myname, dns_strtype(addr->type));
lmtp_errno = LMTP_RETRY;
return (0);
}
@@ -183,25 +191,19 @@ static LMTP_SESSION *lmtp_connect_addr(DNS_RR *addr, unsigned port,
/*
* Initialize.
*/
- memset((char *) &sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
-
- if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
+ if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
msg_fatal("%s: socket: %m", myname);
/*
* Connect to the LMTP server.
*/
- sin.sin_port = port;
- memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
-
+ SOCKADDR_TO_HOSTADDR(sa, salen, &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
if (msg_verbose)
msg_info("%s: trying: %s[%s] port %d...",
- myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
+ myname, addr->name, hostaddr.buf, ntohs(port));
- return (lmtp_connect_sock(sock, (struct sockaddr *) & sin, sizeof(sin),
- addr->name, inet_ntoa(sin.sin_addr),
- destination, why));
+ return (lmtp_connect_sock(sock, sa, salen,
+ addr->name, hostaddr.buf, destination, why));
}
/* lmtp_connect_sock - connect a socket over some transport */
@@ -313,7 +315,7 @@ static char *lmtp_parse_destination(const char *destination, char *def_service,
* Parse the host/port information. We're working with a copy of the
* destination argument so the parsing can be destructive.
*/
- if ((err = host_port(buf, hostp, &service, def_service)) != 0)
+ if ((err = host_port(buf, hostp, (char *) 0, &service, def_service)) != 0)
msg_fatal("%s in LMTP server description: %s", err, destination);
/*
@@ -321,9 +323,11 @@ static char *lmtp_parse_destination(const char *destination, char *def_service,
* aren't going to have lmtp defined as a service, use a default value
* instead of just blowing up.
*/
- if (alldig(service) && (port = atoi(service)) != 0)
+ if (alldig(service)) {
+ if ((port = atoi(service)) >= 65536)
+ msg_fatal("bad numeric port in destination: %s", destination);
*portp = htons(port);
- else if ((sp = getservbyname(service, protocol)) != 0)
+ } else if ((sp = getservbyname(service, protocol)) != 0)
*portp = sp->s_port;
else
*portp = htons(var_lmtp_tcp_port);
diff --git a/postfix/src/local/Makefile.in b/postfix/src/local/Makefile.in
index a76c1dfdf..36feee0d1 100644
--- a/postfix/src/local/Makefile.in
+++ b/postfix/src/local/Makefile.in
@@ -22,7 +22,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -436,8 +436,8 @@ resolve.o: ../../include/mail_proto.h
resolve.o: ../../include/vstream.h
resolve.o: ../../include/iostuff.h
resolve.o: ../../include/attr.h
-resolve.o: ../../include/rewrite_clnt.h
resolve.o: ../../include/resolve_clnt.h
+resolve.o: ../../include/rewrite_clnt.h
resolve.o: ../../include/tok822.h
resolve.o: ../../include/mail_params.h
resolve.o: ../../include/defer.h
diff --git a/postfix/src/master/Makefile.in b/postfix/src/master/Makefile.in
index c444c9919..1b4ba9145 100644
--- a/postfix/src/master/Makefile.in
+++ b/postfix/src/master/Makefile.in
@@ -25,7 +25,7 @@ BIN_DIR = ../../libexec
all: $(PROG) $(LIB)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
$(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
@@ -106,6 +106,7 @@ master.o: ../../include/debug_process.h
master.o: ../../include/mail_task.h
master.o: ../../include/mail_conf.h
master.o: ../../include/open_lock.h
+master.o: ../../include/inet_proto.h
master.o: master.h
master_avail.o: master_avail.c
master_avail.o: ../../include/sys_defs.h
@@ -129,13 +130,15 @@ master_ent.o: ../../include/argv.h
master_ent.o: ../../include/stringops.h
master_ent.o: ../../include/readlline.h
master_ent.o: ../../include/inet_addr_list.h
-master_ent.o: ../../include/inet_util.h
+master_ent.o: ../../include/myaddrinfo.h
+master_ent.o: ../../include/host_port.h
master_ent.o: ../../include/inet_addr_host.h
master_ent.o: ../../include/mail_proto.h
master_ent.o: ../../include/iostuff.h
master_ent.o: ../../include/attr.h
master_ent.o: ../../include/mail_params.h
master_ent.o: ../../include/own_inet_addr.h
+master_ent.o: ../../include/wildcard_inet_addr.h
master_ent.o: master_proto.h
master_ent.o: master.h
master_flow.o: master_flow.c
@@ -154,8 +157,10 @@ master_listen.o: ../../include/stringops.h
master_listen.o: ../../include/vstring.h
master_listen.o: ../../include/vbuf.h
master_listen.o: ../../include/inet_addr_list.h
+master_listen.o: ../../include/myaddrinfo.h
master_listen.o: ../../include/set_eugid.h
master_listen.o: ../../include/set_ugid.h
+master_listen.o: ../../include/sock_addr.h
master_listen.o: ../../include/mail_params.h
master_listen.o: master.h
master_proto.o: master_proto.c
@@ -180,6 +185,8 @@ master_spawn.o: ../../include/msg.h
master_spawn.o: ../../include/binhash.h
master_spawn.o: ../../include/mymalloc.h
master_spawn.o: ../../include/events.h
+master_spawn.o: ../../include/vstring.h
+master_spawn.o: ../../include/vbuf.h
master_spawn.o: ../../include/argv.h
master_spawn.o: master_proto.h
master_spawn.o: master.h
diff --git a/postfix/src/master/master.c b/postfix/src/master/master.c
index 70c3c2fb1..9c1476243 100644
--- a/postfix/src/master/master.c
+++ b/postfix/src/master/master.c
@@ -78,9 +78,6 @@
/* RESOURCE AND RATE CONTROLS
/* .ad
/* .fi
-/* .IP "\fBdaemon_timeout (18000s)\fR"
-/* How much time a Postfix daemon process may take to handle a
-/* request before it is terminated by a built-in watchdog timer.
/* .IP "\fBdefault_process_limit (100)\fR"
/* The default maximal number of Postfix child processes that provide
/* a given service.
@@ -107,6 +104,9 @@
/* .IP "\fBinet_interfaces (all)\fR"
/* The network interface addresses that this mail system receives mail
/* on.
+/* .IP "\fBinet_protocols (ipv4)\fR"
+/* The Internet protocols Postfix will attempt to use when making
+/* or accepting connections.
/* .IP "\fBimport_environment (see 'postconf -d' output)\fR"
/* The list of environment parameters that a Postfix process will
/* import from a non-Postfix parent process.
@@ -181,6 +181,7 @@
#include
#include
#include
+#include
/* Application-specific. */
@@ -194,6 +195,13 @@ static void master_exit_event(int unused_event, char *unused_context)
exit(0);
}
+/* usage - show hint and terminate */
+
+static NORETURN usage(const char *me)
+{
+ msg_fatal("usage: %s [-c config_dir] [-e exit_time] [-D (debug)] [-t (test)] [-v]", me);
+}
+
/* main - main program */
int main(int argc, char **argv)
@@ -319,11 +327,17 @@ int main(int argc, char **argv)
msg_verbose++;
break;
default:
- msg_fatal("usage: %s [-c config_dir] [-e exit_time] [-D (debug)] [-t (test)] [-v]", argv[0]);
+ usage(argv[0]);
/* NOTREACHED */
}
}
+ /*
+ * This program takes no other arguments.
+ */
+ if (argc > optind)
+ usage(argv[0]);
+
/*
* Final initializations. Unfortunately, we must read the global Postfix
* configuration file after doing command-line processing, so that we get
@@ -332,6 +346,13 @@ int main(int argc, char **argv)
*/
master_vars_init();
+ /*
+ * In case of multi-protocol support. This needs to be done because
+ * master does not invoke mail_params_init() (it was written before that
+ * code existed).
+ */
+ (void) inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
+
/*
* Environment import filter, to enforce consistent behavior whether
* Postfix is started by hand, or at system boot time.
diff --git a/postfix/src/master/master_ent.c b/postfix/src/master/master_ent.c
index 8c22bb91c..adb6349a7 100644
--- a/postfix/src/master/master_ent.c
+++ b/postfix/src/master/master_ent.c
@@ -84,7 +84,7 @@
#include
#include
#include
-#include
+#include
#include
/* Global library. */
@@ -92,6 +92,7 @@
#include
#include
#include
+#include
/* Local stuff. */
@@ -234,6 +235,7 @@ MASTER_SERV *get_master_ent()
int n;
char *bufp;
char *atmp;
+ const char *parse_err;
static char *saved_interfaces = 0;
if (master_fp == 0)
@@ -297,7 +299,11 @@ MASTER_SERV *get_master_ent()
VAR_INET_INTERFACES);
}
serv->type = MASTER_SERV_TYPE_INET;
- atmp = inet_parse(name, &host, &port);
+ atmp = mystrdup(name);
+ if ((parse_err = host_port(atmp, &host, "", &port, (char *) 0)) != 0)
+ msg_fatal("%s: line %d: %s in \"%s\"",
+ VSTREAM_PATH(master_fp), master_line,
+ parse_err, name);
if (*host) {
serv->flags |= MASTER_FLAG_INETHOST;/* host:port */
MASTER_INET_ADDRLIST(serv) = (INET_ADDR_LIST *)
@@ -305,14 +311,14 @@ MASTER_SERV *get_master_ent()
inet_addr_list_init(MASTER_INET_ADDRLIST(serv));
if (inet_addr_host(MASTER_INET_ADDRLIST(serv), host) == 0)
msg_fatal("%s: line %d: bad hostname or network address: %s",
- VSTREAM_PATH(master_fp), master_line, host);
+ VSTREAM_PATH(master_fp), master_line, name);
inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
- } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) {
- MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
- serv->listen_fd_count = 1;
} else {
- MASTER_INET_ADDRLIST(serv) = own_inet_addr_list(); /* virtual */
+ MASTER_INET_ADDRLIST(serv) =
+ strcasecmp(saved_interfaces, INET_INTERFACES_ALL) ?
+ own_inet_addr_list() : /* virtual */
+ wildcard_inet_addr_list(); /* wild-card */
inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
}
diff --git a/postfix/src/master/master_listen.c b/postfix/src/master/master_listen.c
index 9ff3056d1..49d16d9e1 100644
--- a/postfix/src/master/master_listen.c
+++ b/postfix/src/master/master_listen.c
@@ -55,6 +55,8 @@
#include
#include
#include
+#include
+#include
/* Global library. */
@@ -71,6 +73,8 @@ void master_listen_init(MASTER_SERV *serv)
char *myname = "master_listen_init";
char *end_point;
int n;
+ MAI_HOSTADDR_STR hostaddr;
+ struct sockaddr *sa;
/*
* Find out what transport we should use, then create one or more
@@ -105,24 +109,22 @@ void master_listen_init(MASTER_SERV *serv)
/*
* INET-domain listener endpoints can be wildcarded (the default) or
* bound to specific interface addresses.
+ *
+ * With dual-stack IPv4/6 systems it does not matter, we have to specify
+ * the addresses anyway, either explicit or wild-card.
*/
case MASTER_SERV_TYPE_INET:
- if (MASTER_INET_ADDRLIST(serv) == 0) { /* wild-card */
- serv->listen_fd[0] =
- inet_listen(MASTER_INET_PORT(serv),
- serv->max_proc > var_proc_limit ?
- serv->max_proc : var_proc_limit, NON_BLOCKING);
- close_on_exec(serv->listen_fd[0], CLOSE_ON_EXEC);
- } else { /* virtual or host:port */
- for (n = 0; n < serv->listen_fd_count; n++) {
- end_point = concatenate(inet_ntoa(MASTER_INET_ADDRLIST(serv)->addrs[n]),
- ":", MASTER_INET_PORT(serv), (char *) 0);
- serv->listen_fd[n]
- = inet_listen(end_point, serv->max_proc > var_proc_limit ?
- serv->max_proc : var_proc_limit, NON_BLOCKING);
- close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
- myfree(end_point);
- }
+ for (n = 0; n < serv->listen_fd_count; n++) {
+ sa = SOCK_ADDR_PTR(MASTER_INET_ADDRLIST(serv)->addrs + n);
+ SOCKADDR_TO_HOSTADDR(sa, SOCK_ADDR_LEN(sa), &hostaddr,
+ (MAI_SERVPORT_STR *) 0, 0);
+ end_point = concatenate(hostaddr.buf,
+ ":", MASTER_INET_PORT(serv), (char *) 0);
+ serv->listen_fd[n]
+ = inet_listen(end_point, serv->max_proc > var_proc_limit ?
+ serv->max_proc : var_proc_limit, NON_BLOCKING);
+ close_on_exec(serv->listen_fd[n], CLOSE_ON_EXEC);
+ myfree(end_point);
}
break;
default:
diff --git a/postfix/src/master/master_vars.c b/postfix/src/master/master_vars.c
index d82ae49f9..53b37220b 100644
--- a/postfix/src/master/master_vars.c
+++ b/postfix/src/master/master_vars.c
@@ -45,6 +45,7 @@
/*
* Tunable parameters.
*/
+char *var_inet_protocols;
int var_proc_limit;
int var_throttle_time;
@@ -53,6 +54,10 @@ int var_throttle_time;
void master_vars_init(void)
{
char *path;
+ static CONFIG_STR_TABLE str_table[] = {
+ VAR_INET_PROTOCOLS, DEF_INET_PROTOCOLS, &var_inet_protocols, 1, 0,
+ 0,
+ };
static CONFIG_INT_TABLE int_table[] = {
VAR_PROC_LIMIT, DEF_PROC_LIMIT, &var_proc_limit, 1, 0,
0,
@@ -61,11 +66,20 @@ void master_vars_init(void)
VAR_THROTTLE_TIME, DEF_THROTTLE_TIME, &var_throttle_time, 1, 0,
0,
};
+ static char *saved_inet_protocols;
+ if (var_inet_protocols && !saved_inet_protocols)
+ saved_inet_protocols = mystrdup(var_inet_protocols);
mail_conf_read();
+ get_mail_conf_str_table(str_table);
get_mail_conf_int_table(int_table);
get_mail_conf_time_table(time_table);
path = concatenate(var_config_dir, "/", MASTER_CONF_FILE, (char *) 0);
fset_master_ent(path);
myfree(path);
+
+ if (saved_inet_protocols && strcmp(var_inet_protocols, saved_inet_protocols)) {
+ msg_warn("ignoring %s change", VAR_INET_PROTOCOLS);
+ msg_warn("to change %s, stop and start Postfix", VAR_INET_PROTOCOLS);
+ }
}
diff --git a/postfix/src/oqmgr/Makefile.in b/postfix/src/oqmgr/Makefile.in
index 4451a2d44..2a78eba16 100644
--- a/postfix/src/oqmgr/Makefile.in
+++ b/postfix/src/oqmgr/Makefile.in
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/pickup/Makefile.in b/postfix/src/pickup/Makefile.in
index 8d832721e..57282f9ac 100644
--- a/postfix/src/pickup/Makefile.in
+++ b/postfix/src/pickup/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/pipe/Makefile.in b/postfix/src/pipe/Makefile.in
index dd7066f10..affdcd9e5 100644
--- a/postfix/src/pipe/Makefile.in
+++ b/postfix/src/pipe/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/postalias/Makefile.in b/postfix/src/postalias/Makefile.in
index ff9363650..217e98e47 100644
--- a/postfix/src/postalias/Makefile.in
+++ b/postfix/src/postalias/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
update: ../../bin/$(PROG)
diff --git a/postfix/src/postcat/Makefile.in b/postfix/src/postcat/Makefile.in
index bacd2dd16..2d9fd3464 100644
--- a/postfix/src/postcat/Makefile.in
+++ b/postfix/src/postcat/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/postconf/Makefile.in b/postfix/src/postconf/Makefile.in
index 2910a674c..b7f93e86e 100644
--- a/postfix/src/postconf/Makefile.in
+++ b/postfix/src/postconf/Makefile.in
@@ -26,7 +26,7 @@ $(PROG): $(OBJS) $(LIBS)
./$(PROG) -d) |egrep -v '^(myhostname|mydomain|mynetworks) ' >$@
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -83,6 +83,7 @@ postconf.o: ../../include/mymalloc.h
postconf.o: ../../include/split_at.h
postconf.o: ../../include/vstring_vstream.h
postconf.o: ../../include/myflock.h
+postconf.o: ../../include/inet_proto.h
postconf.o: ../../include/mynetworks.h
postconf.o: ../../include/mail_conf.h
postconf.o: ../../include/mail_dict.h
diff --git a/postfix/src/postconf/postconf.c b/postfix/src/postconf/postconf.c
index 8da57e1e2..9d59dfcc9 100644
--- a/postfix/src/postconf/postconf.c
+++ b/postfix/src/postconf/postconf.c
@@ -195,6 +195,7 @@
#include
#include
#include
+#include
/* Global library. */
@@ -363,6 +364,7 @@ static const char *check_mydomainname(void)
static const char *check_mynetworks(void)
{
+ INET_PROTO_INFO *proto_info;
const char *junk;
if (var_inet_interfaces == 0) {
@@ -377,6 +379,13 @@ static const char *check_mynetworks(void)
junk = DEF_MYNETWORKS_STYLE;
var_mynetworks_style = mystrdup(junk);
}
+ if (var_inet_protocols == 0) {
+ if ((mode & SHOW_DEFS)
+ || !(junk = mail_conf_lookup_eval(VAR_INET_PROTOCOLS)))
+ junk = DEF_INET_PROTOCOLS;
+ var_inet_protocols = mystrdup(junk);
+ proto_info = inet_proto_init(VAR_INET_PROTOCOLS, var_inet_protocols);
+ }
return (mynetworks());
}
diff --git a/postfix/src/postdrop/Makefile.in b/postfix/src/postdrop/Makefile.in
index 48af4b903..06f79c548 100644
--- a/postfix/src/postdrop/Makefile.in
+++ b/postfix/src/postdrop/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/postfix/Makefile.in b/postfix/src/postfix/Makefile.in
index 4249375d6..31615b51b 100644
--- a/postfix/src/postfix/Makefile.in
+++ b/postfix/src/postfix/Makefile.in
@@ -17,7 +17,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/postkick/Makefile.in b/postfix/src/postkick/Makefile.in
index 3e63ead93..a5cc48b04 100644
--- a/postfix/src/postkick/Makefile.in
+++ b/postfix/src/postkick/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/postlock/Makefile.in b/postfix/src/postlock/Makefile.in
index 04c283f6c..071fe26aa 100644
--- a/postfix/src/postlock/Makefile.in
+++ b/postfix/src/postlock/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/postlog/Makefile.in b/postfix/src/postlog/Makefile.in
index e914094f1..586aa6109 100644
--- a/postfix/src/postlog/Makefile.in
+++ b/postfix/src/postlog/Makefile.in
@@ -17,7 +17,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/postmap/Makefile.in b/postfix/src/postmap/Makefile.in
index a598181f2..3f0798af6 100644
--- a/postfix/src/postmap/Makefile.in
+++ b/postfix/src/postmap/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
update: ../../bin/$(PROG)
diff --git a/postfix/src/postqueue/Makefile.in b/postfix/src/postqueue/Makefile.in
index 470f03c15..98ba568f7 100644
--- a/postfix/src/postqueue/Makefile.in
+++ b/postfix/src/postqueue/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -78,3 +78,4 @@ postqueue.o: ../../include/flush_clnt.h
postqueue.o: ../../include/smtp_stream.h
postqueue.o: ../../include/vstring.h
postqueue.o: ../../include/user_acl.h
+postqueue.o: ../../include/valid_mailhost_addr.h
diff --git a/postfix/src/postqueue/postqueue.c b/postfix/src/postqueue/postqueue.c
index dc2464c77..1d991ea49 100644
--- a/postfix/src/postqueue/postqueue.c
+++ b/postfix/src/postqueue/postqueue.c
@@ -51,7 +51,9 @@
/* .RE
/* .IP "\fB-s \fIsite\fR"
/* Schedule immediate delivery of all mail that is queued for the named
-/* \fIsite\fR. The site must be eligible for the "fast flush" service.
+/* \fIsite\fR. A numerical site must be specified as a valid RFC 2821
+/* address literal enclosed in [], just like in email addresses.
+/* The site must be eligible for the "fast flush" service.
/* See \fBflush\fR(8) for more information about the "fast flush"
/* service.
/*
@@ -187,6 +189,7 @@
#include
#include
#include
+#include
/* Application-specific. */
@@ -474,14 +477,10 @@ int main(int argc, char **argv)
*/
if (site_to_flush != 0) {
bad_site = 0;
- if (*site_to_flush == '['
- && *(last = site_to_flush + strlen(site_to_flush) - 1) == ']') {
- *last = 0;
- bad_site = !valid_hostaddr(site_to_flush + 1, DONT_GRIPE);
- *last = ']';
+ if (*site_to_flush == '[') {
+ bad_site = !valid_mailhost_literal(site_to_flush, DONT_GRIPE);
} else {
- bad_site = (!valid_hostname(site_to_flush, DONT_GRIPE)
- && !valid_hostaddr(site_to_flush, DONT_GRIPE));
+ bad_site = !valid_hostname(site_to_flush, DONT_GRIPE);
}
if (bad_site)
msg_fatal_status(EX_USAGE,
diff --git a/postfix/src/postsuper/Makefile.in b/postfix/src/postsuper/Makefile.in
index 98eb5f61a..1930af83d 100644
--- a/postfix/src/postsuper/Makefile.in
+++ b/postfix/src/postsuper/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/proxymap/Makefile.in b/postfix/src/proxymap/Makefile.in
index 42c9148fd..96c3b65b0 100644
--- a/postfix/src/proxymap/Makefile.in
+++ b/postfix/src/proxymap/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/qmgr/Makefile.in b/postfix/src/qmgr/Makefile.in
index e069952ae..0a7e2caad 100644
--- a/postfix/src/qmgr/Makefile.in
+++ b/postfix/src/qmgr/Makefile.in
@@ -22,7 +22,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/qmqpd/Makefile.in b/postfix/src/qmqpd/Makefile.in
index 3f24a9351..e1b3250a2 100644
--- a/postfix/src/qmqpd/Makefile.in
+++ b/postfix/src/qmqpd/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -100,12 +100,19 @@ qmqpd_peer.o: qmqpd_peer.c
qmqpd_peer.o: ../../include/sys_defs.h
qmqpd_peer.o: ../../include/msg.h
qmqpd_peer.o: ../../include/mymalloc.h
-qmqpd_peer.o: ../../include/valid_hostname.h
qmqpd_peer.o: ../../include/stringops.h
qmqpd_peer.o: ../../include/vstring.h
qmqpd_peer.o: ../../include/vbuf.h
-qmqpd_peer.o: qmqpd.h
+qmqpd_peer.o: ../../include/myaddrinfo.h
+qmqpd_peer.o: ../../include/sock_addr.h
+qmqpd_peer.o: ../../include/inet_proto.h
+qmqpd_peer.o: ../../include/mail_proto.h
qmqpd_peer.o: ../../include/vstream.h
+qmqpd_peer.o: ../../include/iostuff.h
+qmqpd_peer.o: ../../include/attr.h
+qmqpd_peer.o: ../../include/valid_mailhost_addr.h
+qmqpd_peer.o: ../../include/valid_hostname.h
+qmqpd_peer.o: qmqpd.h
qmqpd_peer.o: ../../include/mail_stream.h
qmqpd_state.o: qmqpd_state.c
qmqpd_state.o: ../../include/sys_defs.h
diff --git a/postfix/src/qmqpd/qmqpd.c b/postfix/src/qmqpd/qmqpd.c
index 0399e36a9..f86355f5e 100644
--- a/postfix/src/qmqpd/qmqpd.c
+++ b/postfix/src/qmqpd/qmqpd.c
@@ -49,7 +49,7 @@
/* it is queued.
/* .IP "\fBreceive_override_options (empty)\fR"
/* Enable or disable recipient validation, built-in content
-/* filtering, or address rewriting.
+/* filtering, or address mapping.
/* RESOURCE AND RATE CONTROLS
/* .ad
/* .fi
@@ -323,7 +323,7 @@ static void qmqpd_write_attributes(QMQPD_STATE *state)
MAIL_ATTR_CLIENT_NAME, state->name);
if (IS_AVAIL_CLIENT_ADDR(state->addr))
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
- MAIL_ATTR_CLIENT_ADDR, state->addr);
+ MAIL_ATTR_CLIENT_ADDR, state->rfc_addr);
if (IS_AVAIL_CLIENT_NAMADDR(state->namaddr))
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ORIGIN, state->namaddr);
@@ -402,7 +402,7 @@ static void qmqpd_write_content(QMQPD_STATE *state)
*/
rec_fputs(state->cleanup, REC_TYPE_MESG, "");
rec_fprintf(state->cleanup, REC_TYPE_NORM, "Received: from %s (%s [%s])",
- state->name, state->name, state->addr);
+ state->name, state->name, state->rfc_addr);
if (state->rcpt_count == 1 && state->recipient) {
rec_fprintf(state->cleanup, REC_TYPE_NORM,
"\tby %s (%s) with %s id %s",
diff --git a/postfix/src/qmqpd/qmqpd.h b/postfix/src/qmqpd/qmqpd.h
index f968eb72b..c782359b2 100644
--- a/postfix/src/qmqpd/qmqpd.h
+++ b/postfix/src/qmqpd/qmqpd.h
@@ -36,6 +36,7 @@ typedef struct {
char *name; /* client name */
char *addr; /* client IP address */
char *namaddr; /* name[addr] */
+ char *rfc_addr; /* RFC 2821 client IP address */
char *queue_id; /* queue file ID */
VSTREAM *cleanup; /* cleanup server */
MAIL_STREAM *dest; /* cleanup server */
diff --git a/postfix/src/qmqpd/qmqpd_peer.c b/postfix/src/qmqpd/qmqpd_peer.c
index 84c878dcb..d785d97ed 100644
--- a/postfix/src/qmqpd/qmqpd_peer.c
+++ b/postfix/src/qmqpd/qmqpd_peer.c
@@ -26,7 +26,7 @@
/* .IP namaddr
/* String of the form: "name[addr]".
/* .PP
-/* qmqpd_peer_reset() releases memory allocate by qmqpd_peer_init().
+/* qmqpd_peer_reset() releases memory allocated by qmqpd_peer_init().
/* LICENSE
/* .ad
/* .fi
@@ -49,36 +49,19 @@
#include
#include
- /*
- * Older systems don't have h_errno. Even modern systems don't have
- * hstrerror().
- */
-#ifdef NO_HERRNO
-
-static int h_errno = TRY_AGAIN;
-
-#define HSTRERROR(err) "Host not found"
-
-#else
-
-#define HSTRERROR(err) (\
- err == TRY_AGAIN ? "Host not found, try again" : \
- err == HOST_NOT_FOUND ? "Host not found" : \
- err == NO_DATA ? "Host name has no address" : \
- err == NO_RECOVERY ? "Name server failure" : \
- strerror(errno) \
- )
-#endif
-
/* Utility library. */
#include
#include
-#include
#include
+#include
+#include
+#include
/* Global library. */
+#include
+#include
/* Application-specific. */
@@ -88,16 +71,19 @@ static int h_errno = TRY_AGAIN;
void qmqpd_peer_init(QMQPD_STATE *state)
{
- struct sockaddr_in sin;
- SOCKADDR_SIZE len = sizeof(sin);
- struct hostent *hp;
- int i;
+ char *myname = "qmqpd_peer_init";
+ struct sockaddr_storage ss;
+ struct sockaddr *sa;
+ SOCKADDR_SIZE sa_len;
+ INET_PROTO_INFO *proto_info = inet_proto_info();
+
+ sa = (struct sockaddr *) & ss;
+ sa_len = sizeof(ss);
/*
* Look up the peer address information.
*/
- if (getpeername(vstream_fileno(state->client),
- (struct sockaddr *) & sin, &len) >= 0) {
+ if (getpeername(vstream_fileno(state->client), sa, &sa_len) >= 0) {
errno = 0;
}
@@ -105,54 +91,130 @@ void qmqpd_peer_init(QMQPD_STATE *state)
* If peer went away, give up.
*/
if (errno == ECONNRESET || errno == ECONNABORTED) {
- state->name = mystrdup(CLIENT_ATTR_UNKNOWN);
- state->addr = mystrdup(CLIENT_ATTR_UNKNOWN);
+ state->name = mystrdup(CLIENT_NAME_UNKNOWN);
+ state->addr = mystrdup(CLIENT_ADDR_UNKNOWN);
+ state->rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
}
/*
- * Look up and "verify" the client hostname.
+ * Convert the client address to printable address and hostname.
*/
- else if (errno == 0 && sin.sin_family == AF_INET) {
- state->addr = mystrdup(inet_ntoa(sin.sin_addr));
- hp = gethostbyaddr((char *) &(sin.sin_addr),
- sizeof(sin.sin_addr), AF_INET);
- if (hp == 0) {
- state->name = mystrdup(CLIENT_ATTR_UNKNOWN);
- } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
- state->name = mystrdup(CLIENT_ATTR_UNKNOWN);
+ else if (errno == 0
+ && strchr((char *) proto_info->sa_family_list, sa->sa_family)) {
+ MAI_HOSTNAME_STR client_name;
+ MAI_HOSTADDR_STR client_addr;
+ int aierr;
+ char *colonp;
+
+ /*
+ * Convert the client address to printable form.
+ */
+ if ((aierr = sockaddr_to_hostaddr(sa, sa_len, &client_addr,
+ (MAI_SERVPORT_STR *) 0, 0)) != 0)
+ msg_fatal("%s: cannot convert client address to string: %s",
+ myname, MAI_STRERROR(aierr));
+
+ /*
+ * We convert IPv4-in-IPv6 address to 'true' IPv4 address early on,
+ * but only if IPv4 support is enabled (why would anyone want to turn
+ * it off)? With IPv4 support enabled we have no need for the IPv6
+ * form in logging, hostname verification and access checks.
+ */
+#ifdef HAS_IPV6
+ if (sa->sa_family == AF_INET6) {
+ if (strchr((char *) proto_info->sa_family_list, AF_INET) != 0
+ && IN6_IS_ADDR_V4MAPPED(&SOCK_ADDR_IN6_ADDR(sa))
+ && (colonp = strrchr(client_addr.buf, ':')) != 0) {
+ struct addrinfo *res0;
+
+ if (msg_verbose > 1)
+ msg_info("%s: rewriting V4-mapped address \"%s\" to \"%s\"",
+ myname, client_addr.buf, colonp + 1);
+
+ state->addr = mystrdup(colonp + 1);
+ state->rfc_addr = mystrdup(colonp + 1);
+ aierr = hostaddr_to_sockaddr(state->addr, (char *) 0, 0, &res0);
+ if (aierr)
+ msg_fatal("%s: cannot convert %s from string to binary: %s",
+ myname, state->addr, MAI_STRERROR(aierr));
+ sa_len = res0->ai_addrlen;
+ memcpy((char *) sa, res0->ai_addr, sa_len);
+ freeaddrinfo(res0);
+ }
+
+ /*
+ * Following RFC 2821 section 4.1.3, an IPv6 address literal gets
+ * a prefix of 'IPv6:'. We do this consistently for all IPv6
+ * addresses that that appear in headers or envelopes. The fact
+ * that valid_mailhost_addr() enforces the form helps of course.
+ * We use the form without IPV6: prefix when doing access
+ * control, or when accessing the connection cache.
+ */
+ else {
+ state->addr = mystrdup(client_addr.buf);
+ state->rfc_addr =
+ concatenate(IPV6_COL, client_addr.buf, (char *) 0);
+ }
+ }
+
+ /*
+ * An IPv4 address is in dotted quad decimal form.
+ */
+ else
+#endif
+ {
+ state->addr = mystrdup(client_addr.buf);
+ state->rfc_addr = mystrdup(client_addr.buf);
+ }
+
+ /*
+ * Look up and sanity check the client hostname.
+ *
+ * It is unsafe to allow numeric hostnames, especially because there
+ * exists pressure to turn off the name->addr double check. In that
+ * case an attacker could trivally bypass access restrictions.
+ *
+ * sockaddr_to_hostname() already rejects malformed or numeric names.
+ */
+#define REJECT_PEER_NAME(state) { \
+ myfree(state->name); \
+ state->name = mystrdup(CLIENT_NAME_UNKNOWN); \
+ }
+
+ if ((aierr = sockaddr_to_hostname(sa, sa_len, &client_name,
+ (MAI_SERVNAME_STR *) 0, 0)) != 0) {
+ state->name = mystrdup(CLIENT_NAME_UNKNOWN);
} else {
- state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
+ struct addrinfo *res0;
+ struct addrinfo *res;
+
+ state->name = mystrdup(client_name.buf);
/*
* Reject the hostname if it does not list the peer address.
*/
-#define REJECT_PEER_NAME(state) { \
- myfree(state->name); \
- state->name = mystrdup(CLIENT_ATTR_UNKNOWN); \
- }
-
- hp = gethostbyname(state->name); /* clobbers hp->name!! */
- if (hp == 0) {
+ aierr = hostname_to_sockaddr(state->name, (char *) 0, 0, &res0);
+ if (aierr) {
msg_warn("%s: hostname %s verification failed: %s",
- state->addr, state->name, HSTRERROR(h_errno));
- REJECT_PEER_NAME(state);
- } else if (hp->h_length != sizeof(sin.sin_addr)) {
- msg_warn("%s: hostname %s verification failed: bad address size %d",
- state->addr, state->name, hp->h_length);
+ state->addr, state->name, MAI_STRERROR(aierr));
REJECT_PEER_NAME(state);
} else {
- for (i = 0; /* void */ ; i++) {
- if (hp->h_addr_list[i] == 0) {
+ for (res = res0; /* void */ ; res = res->ai_next) {
+ if (res == 0) {
msg_warn("%s: address not listed for hostname %s",
state->addr, state->name);
REJECT_PEER_NAME(state);
break;
}
- if (memcmp(hp->h_addr_list[i],
- (char *) &sin.sin_addr,
- sizeof(sin.sin_addr)) == 0)
+ if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
+ msg_info("skipping address family %d for host %s",
+ res->ai_family, state->name);
+ continue;
+ }
+ if (sock_addr_cmp_addr(res->ai_addr, sa) == 0)
break; /* keep peer name */
}
+ freeaddrinfo(res0);
}
}
}
@@ -164,6 +226,7 @@ void qmqpd_peer_init(QMQPD_STATE *state)
else {
state->name = mystrdup("localhost");
state->addr = mystrdup("127.0.0.1"); /* XXX bogus. */
+ state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */
}
/*
@@ -180,4 +243,5 @@ void qmqpd_peer_reset(QMQPD_STATE *state)
myfree(state->name);
myfree(state->addr);
myfree(state->namaddr);
+ myfree(state->rfc_addr);
}
diff --git a/postfix/src/scache/Makefile.in b/postfix/src/scache/Makefile.in
index 1fc319818..4d54015b4 100644
--- a/postfix/src/scache/Makefile.in
+++ b/postfix/src/scache/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/sendmail/Makefile.in b/postfix/src/sendmail/Makefile.in
index c3ae7d2c3..751db318a 100644
--- a/postfix/src/sendmail/Makefile.in
+++ b/postfix/src/sendmail/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/sendmail/sendmail.c b/postfix/src/sendmail/sendmail.c
index c1aa4aed3..8c47a6e59 100644
--- a/postfix/src/sendmail/sendmail.c
+++ b/postfix/src/sendmail/sendmail.c
@@ -119,6 +119,8 @@
/* Non-default alias database. Specify \fIpathname\fR or
/* \fItype\fR:\fIpathname\fR. See \fBpostalias\fR(1) for
/* details.
+/* .IP "\fB-O \fIoption=value\fR (ignored)"
+/* Backwards compatibility.
/* .IP "\fB-o7\fR (ignored)"
/* .IP "\fB-o8\fR (ignored)"
/* To send 8-bit or binary content, use an appropriate MIME encapsulation
@@ -941,7 +943,7 @@ int main(int argc, char **argv)
optind++;
continue;
}
- if ((c = GETOPT(argc, argv, "A:B:C:F:GIL:N:R:UV:X:b:ce:f:h:imno:p:r:q:tvx")) <= 0)
+ if ((c = GETOPT(argc, argv, "A:B:C:F:GIL:N:O:R:UV:X:b:ce:f:h:imno:p:r:q:tvx")) <= 0)
break;
switch (c) {
default:
diff --git a/postfix/src/showq/Makefile.in b/postfix/src/showq/Makefile.in
index ae0e476cf..66ed58fdc 100644
--- a/postfix/src/showq/Makefile.in
+++ b/postfix/src/showq/Makefile.in
@@ -16,7 +16,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in
index ad9795994..ffbc92ed3 100644
--- a/postfix/src/smtp/Makefile.in
+++ b/postfix/src/smtp/Makefile.in
@@ -20,7 +20,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -92,11 +92,13 @@ smtp_addr.o: ../../include/vstring.h
smtp_addr.o: ../../include/vbuf.h
smtp_addr.o: ../../include/mymalloc.h
smtp_addr.o: ../../include/inet_addr_list.h
+smtp_addr.o: ../../include/myaddrinfo.h
smtp_addr.o: ../../include/stringops.h
-smtp_addr.o: ../../include/myrand.h
+smtp_addr.o: ../../include/inet_proto.h
smtp_addr.o: ../../include/mail_params.h
smtp_addr.o: ../../include/own_inet_addr.h
smtp_addr.o: ../../include/dns.h
+smtp_addr.o: ../../include/sock_addr.h
smtp_addr.o: smtp.h
smtp_addr.o: ../../include/vstream.h
smtp_addr.o: ../../include/argv.h
@@ -146,11 +148,13 @@ smtp_connect.o: ../../include/vstring.h
smtp_connect.o: ../../include/split_at.h
smtp_connect.o: ../../include/mymalloc.h
smtp_connect.o: ../../include/inet_addr_list.h
+smtp_connect.o: ../../include/myaddrinfo.h
smtp_connect.o: ../../include/iostuff.h
smtp_connect.o: ../../include/timed_connect.h
smtp_connect.o: ../../include/stringops.h
smtp_connect.o: ../../include/host_port.h
smtp_connect.o: ../../include/sane_connect.h
+smtp_connect.o: ../../include/sock_addr.h
smtp_connect.o: ../../include/mail_params.h
smtp_connect.o: ../../include/own_inet_addr.h
smtp_connect.o: ../../include/deliver_pass.h
@@ -253,6 +257,8 @@ smtp_reuse.o: ../../include/maps.h
smtp_reuse.o: ../../include/dict.h
smtp_reuse.o: smtp_reuse.h
smtp_reuse.o: ../../include/dns.h
+smtp_reuse.o: ../../include/sock_addr.h
+smtp_reuse.o: ../../include/myaddrinfo.h
smtp_sasl_glue.o: smtp_sasl_glue.c
smtp_sasl_glue.o: ../../include/sys_defs.h
smtp_sasl_glue.o: ../../include/msg.h
@@ -371,6 +377,8 @@ smtp_unalias.o: ../../include/vstring.h
smtp_unalias.o: ../../include/vbuf.h
smtp_unalias.o: ../../include/msg.h
smtp_unalias.o: ../../include/dns.h
+smtp_unalias.o: ../../include/sock_addr.h
+smtp_unalias.o: ../../include/myaddrinfo.h
smtp_unalias.o: smtp.h
smtp_unalias.o: ../../include/vstream.h
smtp_unalias.o: ../../include/argv.h
diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c
index 997f80f32..9a09fcfd4 100644
--- a/postfix/src/smtp/smtp.c
+++ b/postfix/src/smtp/smtp.c
@@ -249,8 +249,11 @@
/* Optional list of relay hosts for SMTP destinations that can't be
/* found or that are unreachable.
/* .IP "\fBinet_interfaces (all)\fR"
-/* The network interface addresses that this mail system receives mail
-/* on.
+/* The network interface addresses that this mail system receives
+/* mail on.
+/* .IP "\fBinet_protocols (ipv4)\fR"
+/* The Internet protocols Postfix will attempt to use when making
+/* or accepting connections.
/* .IP "\fBipc_timeout (3600s)\fR"
/* The time limit for sending or receiving information over an internal
/* communication channel.
@@ -269,7 +272,10 @@
/* on by way of a proxy or network address translation unit.
/* .IP "\fBsmtp_bind_address (empty)\fR"
/* An optional numerical network address that the SMTP client should
-/* bind to when making a connection.
+/* bind to when making an IPv4 connection.
+/* .IP "\fBsmtp_bind_address6 (empty)\fR"
+/* An optional numerical network address that the SMTP client should
+/* bind to when making an IPv6 connection.
/* .IP "\fBsmtp_helo_name ($myhostname)\fR"
/* The hostname to send in the SMTP EHLO or HELO command.
/* .IP "\fBsmtp_host_lookup (dns)\fR"
@@ -385,6 +391,7 @@ char *var_smtp_sasl_passwd;
bool var_smtp_sasl_enable;
char *var_smtp_sasl_mechs;
char *var_smtp_bind_addr;
+char *var_smtp_bind_addr6;
bool var_smtp_rand_addr;
int var_smtp_pix_thresh;
int var_smtp_pix_delay;
@@ -498,11 +505,6 @@ static void post_init(char *unused_name, char **unused_argv)
0,
};
- /*
- * Turn on per-peer debugging.
- */
- debug_peer_init();
-
/*
* Select hostname lookup mechanisms.
*/
@@ -534,6 +536,11 @@ static void post_init(char *unused_name, char **unused_argv)
static void pre_init(char *unused_name, char **unused_argv)
{
+ /*
+ * Turn on per-peer debugging.
+ */
+ debug_peer_init();
+
/*
* SASL initialization.
*/
@@ -600,6 +607,7 @@ int main(int argc, char **argv)
VAR_SMTP_SASL_OPTS, DEF_SMTP_SASL_OPTS, &var_smtp_sasl_opts, 0, 0,
VAR_SMTP_SASL_MECHS, DEF_SMTP_SASL_MECHS, &var_smtp_sasl_mechs, 0, 0,
VAR_SMTP_BIND_ADDR, DEF_SMTP_BIND_ADDR, &var_smtp_bind_addr, 0, 0,
+ VAR_SMTP_BIND_ADDR6, DEF_SMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
VAR_SMTP_HELO_NAME, DEF_SMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
VAR_SMTP_HOST_LOOKUP, DEF_SMTP_HOST_LOOKUP, &var_smtp_host_lookup, 1, 0,
VAR_SMTP_CACHE_DEST, DEF_SMTP_CACHE_DEST, &var_smtp_cache_dest, 0, 0,
diff --git a/postfix/src/smtp/smtp_addr.c b/postfix/src/smtp/smtp_addr.c
index b7cf54ecf..477fe710e 100644
--- a/postfix/src/smtp/smtp_addr.c
+++ b/postfix/src/smtp/smtp_addr.c
@@ -46,11 +46,11 @@
/*
/* All routines either return a DNS_RR pointer, or return a null
/* pointer and set the \fIsmtp_errno\fR global variable accordingly:
-/* .IP SMTP_RETRY
+/* .IP SMTP_ERR_RETRY
/* The request failed due to a soft error, and should be retried later.
-/* .IP SMTP_FAIL
+/* .IP SMTP_ERR_FAIL
/* The request attempt failed due to a hard error.
-/* .IP SMTP_LOOP
+/* .IP SMTP_ERR_LOOP
/* The local machine is the best mail exchanger.
/* .PP
/* In addition, a textual description of the problem is made available
@@ -79,31 +79,6 @@
#include
#include
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
- /*
- * Older systems don't have h_errno. Even modern systems don't have
- * hstrerror().
- */
-#ifdef NO_HERRNO
-
-static int h_errno = TRY_AGAIN;
-
-#define HSTRERROR(err) "Host not found"
-
-#else
-
-#define HSTRERROR(err) (\
- err == TRY_AGAIN ? "Host not found, try again" : \
- err == HOST_NOT_FOUND ? "Host not found" : \
- err == NO_DATA ? "Host name has no address" : \
- err == NO_RECOVERY ? "Name server failure" : \
- strerror(errno) \
- )
-#endif
-
/* Utility library. */
#include
@@ -111,7 +86,8 @@ static int h_errno = TRY_AGAIN;
#include
#include
#include
-#include
+#include
+#include
/* Global library. */
@@ -132,17 +108,16 @@ static int h_errno = TRY_AGAIN;
static void smtp_print_addr(char *what, DNS_RR *addr_list)
{
DNS_RR *addr;
- struct in_addr in_addr;
+ MAI_HOSTADDR_STR hostaddr;
msg_info("begin %s address list", what);
for (addr = addr_list; addr; addr = addr->next) {
- if (addr->data_len > sizeof(addr)) {
- msg_warn("skipping address length %d", addr->data_len);
+ if (dns_rr_to_pa(addr, &hostaddr) == 0) {
+ msg_warn("skipping record type %s: %m", dns_strtype(addr->type));
} else {
- memcpy((char *) &in_addr, addr->data, sizeof(in_addr));
msg_info("pref %4d host %s/%s",
addr->pref, addr->name,
- inet_ntoa(in_addr));
+ hostaddr.buf);
}
}
msg_info("end %s address list", what);
@@ -153,11 +128,13 @@ static void smtp_print_addr(char *what, DNS_RR *addr_list)
static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRING *why)
{
char *myname = "smtp_addr_one";
- struct in_addr inaddr;
- DNS_FIXED fixed;
DNS_RR *addr = 0;
DNS_RR *rr;
- struct hostent *hp;
+ int aierr;
+ struct addrinfo *res0;
+ struct addrinfo *res;
+ INET_PROTO_INFO *proto_info = inet_proto_info();
+ int found;
if (msg_verbose)
msg_info("%s: host %s", myname, host);
@@ -165,18 +142,22 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI
/*
* Interpret a numerical name as an address.
*/
- if (ISDIGIT(host[0]) && (inaddr.s_addr = inet_addr(host)) != INADDR_NONE) {
- memset((char *) &fixed, 0, sizeof(fixed));
- return (dns_rr_append(addr_list,
- dns_rr_create(host, &fixed, pref,
- (char *) &inaddr, sizeof(inaddr))));
+ if (hostaddr_to_sockaddr(host, (char *) 0, 0, &res0) == 0
+ && strchr((char *) proto_info->sa_family_list, res0->ai_family) != 0) {
+ if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0)
+ msg_fatal("host %s: conversion error for address family %d: %m",
+ host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
+ addr_list = dns_rr_append(addr_list, addr);
+ freeaddrinfo(res0);
+ return (addr_list);
}
/*
* Use DNS lookup, but keep the option open to use native name service.
*/
if (smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS) {
- switch (dns_lookup(host, T_A, RES_DEFNAMES, &addr, (VSTRING *) 0, why)) {
+ switch (dns_lookup_v(host, RES_DEFNAMES, &addr, (VSTRING *) 0, why,
+ DNS_REQ_FLAG_ALL, proto_info->dns_atype_list)) {
case DNS_OK:
for (rr = addr; rr; rr = rr->next)
rr->pref = pref;
@@ -192,7 +173,7 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI
case DNS_NOTFOUND:
if (smtp_errno != SMTP_ERR_RETRY)
smtp_errno = SMTP_ERR_FAIL;
- /* maybe gethostbyname() will succeed */
+ /* maybe native naming service will succeed */
break;
}
}
@@ -200,29 +181,35 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref, VSTRI
/*
* Use the native name service which also looks in /etc/hosts.
*/
+#define RETRY_AI_ERROR(e) \
+ ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
+
if (smtp_host_lookup_mask & SMTP_HOST_FLAG_NATIVE) {
- memset((char *) &fixed, 0, sizeof(fixed));
- if ((hp = gethostbyname(host)) == 0) {
- vstring_sprintf(why, "%s: %s", host, HSTRERROR(h_errno));
+ if ((aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0)) != 0) {
+ vstring_sprintf(why, "%s: %s", host, MAI_STRERROR(aierr));
if (smtp_errno != SMTP_ERR_RETRY)
smtp_errno =
- (h_errno == TRY_AGAIN ? SMTP_ERR_RETRY : SMTP_ERR_FAIL);
- } else if (hp->h_addrtype != AF_INET) {
- vstring_sprintf(why, "%s: host not found", host);
- msg_warn("%s: unknown address family %d for %s",
- myname, hp->h_addrtype, host);
- if (smtp_errno != SMTP_ERR_RETRY)
- smtp_errno = SMTP_ERR_FAIL;
+ (RETRY_AI_ERROR(aierr) ? SMTP_ERR_RETRY : SMTP_ERR_FAIL);
} else {
- while (hp->h_addr_list[0]) {
- addr_list = dns_rr_append(addr_list,
- dns_rr_create(host, &fixed, pref,
- hp->h_addr_list[0],
- sizeof(inaddr)));
- hp->h_addr_list++;
+ for (found = 0, res = res0; res != 0; res = res->ai_next) {
+ if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
+ msg_info("skipping address family %d for host %s",
+ res->ai_family, host);
+ continue;
+ }
+ found++;
+ if ((addr = dns_sa_to_rr(host, pref, res->ai_addr)) == 0)
+ msg_fatal("host %s: conversion error for address family %d: %m",
+ host, ((struct sockaddr *) (res0->ai_addr))->sa_family);
+ addr_list = dns_rr_append(addr_list, addr);
}
+ freeaddrinfo(res0);
+ if (found == 0) {
+ vstring_sprintf(why, "%s: host not found", host);
+ smtp_errno = SMTP_ERR_FAIL;
+ }
+ return (addr_list);
}
- return (addr_list);
}
/*
@@ -266,8 +253,6 @@ static DNS_RR *smtp_find_self(DNS_RR *addr_list)
DNS_RR *addr;
int i;
-#define INADDRP(x) ((struct in_addr *) (x))
-
self = own_inet_addr_list();
proxy = proxy_inet_addr_list();
@@ -277,7 +262,7 @@ static DNS_RR *smtp_find_self(DNS_RR *addr_list)
* Find out if this mail system is listening on this address.
*/
for (i = 0; i < self->used; i++)
- if (INADDRP(addr->data)->s_addr == self->addrs[i].s_addr) {
+ if (DNS_RR_EQ_SA(addr, (struct sockaddr *) (self->addrs + i))) {
if (msg_verbose)
msg_info("%s: found self at pref %d", myname, addr->pref);
return (addr);
@@ -288,7 +273,7 @@ static DNS_RR *smtp_find_self(DNS_RR *addr_list)
* address.
*/
for (i = 0; i < proxy->used; i++)
- if (INADDRP(addr->data)->s_addr == proxy->addrs[i].s_addr) {
+ if (DNS_RR_EQ_SA(addr, (struct sockaddr *) (proxy->addrs + i))) {
if (msg_verbose)
msg_info("%s: found proxy at pref %d", myname, addr->pref);
return (addr);
@@ -330,7 +315,17 @@ static DNS_RR *smtp_truncate_self(DNS_RR *addr_list, unsigned pref)
static int smtp_compare_pref(DNS_RR *a, DNS_RR *b)
{
- return (a->pref - b->pref);
+ if (a->pref != b->pref)
+ return (a->pref - b->pref);
+#ifdef HAS_IPV6
+ if (a->type == b->type) /* 200412 */
+ return 0;
+ if (a->type == T_AAAA)
+ return (-1);
+ if (b->type == T_AAAA)
+ return (+1);
+#endif
+ return 0;
}
/* smtp_domain_addr - mail exchanger address lookup */
@@ -476,8 +471,13 @@ DNS_RR *smtp_host_addr(char *host, int misc_flags, VSTRING *why)
smtp_errno = SMTP_ERR_LOOP;
return (0);
}
- if (addr_list && addr_list->next && var_smtp_rand_addr)
- addr_list = dns_rr_shuffle(addr_list);
+ if (addr_list && addr_list->next) {
+ if (var_smtp_rand_addr)
+ addr_list = dns_rr_shuffle(addr_list);
+ /* The following changes the order of equal-preference hosts. */
+ if (inet_proto_info()->ai_family_list[1] != 0)
+ addr_list = dns_rr_sort(addr_list, smtp_compare_pref);
+ }
if (msg_verbose)
smtp_print_addr(host, addr_list);
return (addr_list);
diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c
index 564b8d42d..e2661e487 100644
--- a/postfix/src/smtp/smtp_connect.c
+++ b/postfix/src/smtp/smtp_connect.c
@@ -53,6 +53,7 @@
/* System library. */
#include
+#include
#include
#include
#include
@@ -64,14 +65,6 @@
#include
#include
-#ifdef STRCASECMP_IN_STRINGS_H
-#include
-#endif
-
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
#ifndef IPPORT_SMTP
#define IPPORT_SMTP 25
#endif
@@ -89,6 +82,8 @@
#include
#include
#include
+#include
+#include
/* Global library. */
@@ -116,22 +111,26 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
int sess_flags)
{
char *myname = "smtp_connect_addr";
- struct sockaddr_in sin;
+ struct sockaddr_storage ss; /* remote */
+ struct sockaddr *sa = (struct sockaddr *) & ss;
+ SOCKADDR_SIZE salen = sizeof(ss);
+ MAI_HOSTADDR_STR hostaddr;
int sock;
- INET_ADDR_LIST *addr_list;
int conn_stat;
int saved_errno;
VSTREAM *stream;
int ch;
- unsigned long inaddr;
+ char *bind_addr;
+ char *bind_var;
smtp_errno = SMTP_ERR_NONE; /* Paranoia */
/*
* Sanity checks.
*/
- if (addr->data_len > sizeof(sin.sin_addr)) {
- msg_warn("%s: skip address with length %d", myname, addr->data_len);
+ if (dns_rr_to_sa(addr, port, sa, &salen) != 0) {
+ msg_warn("%s: skip address type %s: %m",
+ myname, dns_strtype(addr->type));
smtp_errno = SMTP_ERR_RETRY;
return (0);
}
@@ -139,65 +138,90 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
/*
* Initialize.
*/
- memset((char *) &sin, 0, sizeof(sin));
- sin.sin_family = AF_INET;
-
- if ((sock = socket(sin.sin_family, SOCK_STREAM, 0)) < 0)
+ if ((sock = socket(sa->sa_family, SOCK_STREAM, 0)) < 0)
msg_fatal("%s: socket: %m", myname);
/*
* Allow the sysadmin to specify the source address, for example, as "-o
* smtp_bind_address=x.x.x.x" in the master.cf file.
*/
- if (*var_smtp_bind_addr) {
- sin.sin_addr.s_addr = inet_addr(var_smtp_bind_addr);
- if (sin.sin_addr.s_addr == INADDR_NONE)
- msg_fatal("%s: bad %s parameter: %s",
- myname, VAR_SMTP_BIND_ADDR, var_smtp_bind_addr);
- if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
- msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
- if (msg_verbose)
- msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
+#ifdef HAS_IPV6
+ if (sa->sa_family == AF_INET6) {
+ bind_addr = var_smtp_bind_addr6;
+ bind_var = VAR_SMTP_BIND_ADDR6;
+ } else
+#endif
+ if (sa->sa_family == AF_INET) {
+ bind_addr = var_smtp_bind_addr;
+ bind_var = VAR_SMTP_BIND_ADDR;
+ } else
+ bind_var = bind_addr = "";
+ if (*bind_addr) {
+ int aierr;
+ struct addrinfo *res0;
+
+ if ((aierr = hostaddr_to_sockaddr(bind_addr, (char *) 0, 0, &res0)) != 0)
+ msg_fatal("%s: bad %s parameter: %s: %s",
+ myname, bind_var, bind_addr, MAI_STRERROR(aierr));
+ if (bind(sock, res0->ai_addr, res0->ai_addrlen) < 0)
+ msg_warn("%s: bind %s: %m", myname, bind_addr);
+ else if (msg_verbose)
+ msg_info("%s: bind %s", myname, bind_addr);
+ freeaddrinfo(res0);
}
/*
* When running as a virtual host, bind to the virtual interface so that
* the mail appears to come from the "right" machine address.
+ *
+ * XXX The IPv6 patch expands the null host (as client endpoint) and uses
+ * the result as the loopback address list.
*/
- else if ((addr_list = own_inet_addr_list())->used == 1) {
- memcpy((char *) &sin.sin_addr, addr_list->addrs, sizeof(sin.sin_addr));
- inaddr = ntohl(sin.sin_addr.s_addr);
- if (!IN_CLASSA(inaddr)
- || !(((inaddr & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET)) {
- if (bind(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0)
- msg_warn("%s: bind %s: %m", myname, inet_ntoa(sin.sin_addr));
- if (msg_verbose)
- msg_info("%s: bind %s", myname, inet_ntoa(sin.sin_addr));
+ else {
+ int count = 0;
+ struct sockaddr *own_addr = 0;
+ INET_ADDR_LIST *addr_list = own_inet_addr_list();
+ struct sockaddr_storage *s;
+
+ for (s = addr_list->addrs; s < addr_list->addrs + addr_list->used; s++) {
+ if (SOCK_ADDR_FAMILY(s) == sa->sa_family) {
+ if (count++ > 0)
+ break;
+ own_addr = SOCK_ADDR_PTR(s);
+ }
+ }
+ if (count == 1 && !sock_addr_in_loopback(own_addr)) {
+ if (bind(sock, own_addr, SOCK_ADDR_LEN(own_addr)) < 0) {
+ SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
+ &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
+ msg_warn("%s: bind %s: %m", myname, hostaddr.buf);
+ } else if (msg_verbose) {
+ SOCKADDR_TO_HOSTADDR(own_addr, SOCK_ADDR_LEN(own_addr),
+ &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
+ msg_info("%s: bind %s", myname, hostaddr.buf);
+ }
}
}
/*
* Connect to the SMTP server.
*/
- sin.sin_port = port;
- memcpy((char *) &sin.sin_addr, addr->data, sizeof(sin.sin_addr));
-
+ SOCKADDR_TO_HOSTADDR(sa, salen, &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
if (msg_verbose)
msg_info("%s: trying: %s[%s] port %d...",
- myname, addr->name, inet_ntoa(sin.sin_addr), ntohs(port));
+ myname, addr->name, hostaddr.buf, ntohs(port));
if (var_smtp_conn_tmout > 0) {
non_blocking(sock, NON_BLOCKING);
- conn_stat = timed_connect(sock, (struct sockaddr *) & sin,
- sizeof(sin), var_smtp_conn_tmout);
+ conn_stat = timed_connect(sock, sa, salen, var_smtp_conn_tmout);
saved_errno = errno;
non_blocking(sock, BLOCKING);
errno = saved_errno;
} else {
- conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
+ conn_stat = sane_connect(sock, sa, salen);
}
if (conn_stat < 0) {
vstring_sprintf(why, "connect to %s[%s]: %m",
- addr->name, inet_ntoa(sin.sin_addr));
+ addr->name, hostaddr.buf);
smtp_errno = SMTP_ERR_RETRY;
close(sock);
return (0);
@@ -208,7 +232,7 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
*/
if (read_wait(sock, var_smtp_helo_tmout) < 0) {
vstring_sprintf(why, "connect to %s[%s]: read timeout",
- addr->name, inet_ntoa(sin.sin_addr));
+ addr->name, hostaddr.buf);
smtp_errno = SMTP_ERR_RETRY;
close(sock);
return (0);
@@ -220,14 +244,14 @@ static SMTP_SESSION *smtp_connect_addr(const char *dest, DNS_RR *addr,
stream = vstream_fdopen(sock, O_RDWR);
if ((ch = VSTREAM_GETC(stream)) == VSTREAM_EOF) {
vstring_sprintf(why, "connect to %s[%s]: server dropped connection without sending the initial SMTP greeting",
- addr->name, inet_ntoa(sin.sin_addr));
+ addr->name, hostaddr.buf);
smtp_errno = SMTP_ERR_RETRY;
vstream_fclose(stream);
return (0);
}
vstream_ungetc(stream, ch);
return (smtp_session_alloc(stream, dest, addr->name,
- inet_ntoa(sin.sin_addr), port, sess_flags));
+ hostaddr.buf, port, sess_flags));
}
/* smtp_parse_destination - parse destination */
@@ -249,13 +273,15 @@ static char *smtp_parse_destination(char *destination, char *def_service,
* Parse the host/port information. We're working with a copy of the
* destination argument so the parsing can be destructive.
*/
- if ((err = host_port(buf, hostp, &service, def_service)) != 0)
+ if ((err = host_port(buf, hostp, (char *) 0, &service, def_service)) != 0)
msg_fatal("%s in SMTP server description: %s", err, destination);
/*
* Convert service to port number, network byte order.
*/
- if (alldig(service) && (port = atoi(service)) != 0) {
+ if (alldig(service)) {
+ if ((port = atoi(service)) >= 65536)
+ msg_fatal("bad network port in destination: %s", destination);
*portp = htons(port);
} else {
if ((sp = getservbyname(service, protocol)) == 0)
@@ -315,19 +341,24 @@ static void smtp_cleanup_session(SMTP_STATE *state)
static void smtp_scrub_addr_list(HTABLE *cached_addr, DNS_RR **addr_list)
{
+ MAI_HOSTADDR_STR hostaddr;
DNS_RR *addr;
DNS_RR *next;
-#define INADDRP(x) ((struct in_addr *) (x))
-
+ /*
+ * XXX Extend the DNS_RR structure with fields for the printable address
+ * and/or binary sockaddr representations, so that we can avoid repeated
+ * binary->string transformations for the same address.
+ */
for (addr = *addr_list; addr; addr = next) {
next = addr->next;
- if (addr->type == T_A) {
- if (addr->data_len > sizeof(struct in_addr))
- continue;
- if (htable_locate(cached_addr, inet_ntoa(*INADDRP(addr->data))))
- *addr_list = dns_rr_remove(*addr_list, addr);
+ if (dns_rr_to_pa(addr, &hostaddr) == 0) {
+ msg_warn("cannot convert type %s resource record to socket address",
+ dns_strtype(addr->type));
+ continue;
}
+ if (htable_locate(cached_addr, hostaddr.buf))
+ *addr_list = dns_rr_remove(*addr_list, addr);
}
}
@@ -336,9 +367,10 @@ static void smtp_scrub_addr_list(HTABLE *cached_addr, DNS_RR **addr_list)
static void smtp_update_addr_list(DNS_RR **addr_list, const char *server_addr,
int session_count)
{
- struct in_addr server_in_addr;
DNS_RR *addr;
DNS_RR *next;
+ int aierr;
+ struct addrinfo *res0;
if (*addr_list == 0)
return;
@@ -359,18 +391,23 @@ static void smtp_update_addr_list(DNS_RR **addr_list, const char *server_addr,
*
* XXX smtp_reuse_session() breaks if we remove two or more adjacent list
* elements but do not truncate the list to zero length.
+ *
+ * XXX Extend the SMTP_SESSION structure with sockaddr information so that
+ * we can avoid repeated string->binary transformations for the same
+ * address.
*/
- server_in_addr.s_addr = inet_addr(server_addr);
- for (addr = *addr_list; addr; addr = next) {
- next = addr->next;
- if (addr->type == T_A) { /* NOT: switch */
- if (addr->data_len > sizeof(server_in_addr))
- continue;
- if (INADDRP(addr->data)->s_addr == server_in_addr.s_addr) {
+ if ((aierr = hostaddr_to_sockaddr(server_addr, (char *) 0, 0, &res0)) != 0) {
+ msg_warn("hostaddr_to_sockaddr %s: %s",
+ server_addr, MAI_STRERROR(aierr));
+ } else {
+ for (addr = *addr_list; addr; addr = next) {
+ next = addr->next;
+ if (DNS_RR_EQ_SA(addr, (struct sockaddr *) res0->ai_addr)) {
*addr_list = dns_rr_remove(*addr_list, addr);
break;
}
}
+ freeaddrinfo(res0);
}
}
diff --git a/postfix/src/smtp/smtp_reuse.c b/postfix/src/smtp/smtp_reuse.c
index f644ded94..f9fa6186b 100644
--- a/postfix/src/smtp/smtp_reuse.c
+++ b/postfix/src/smtp/smtp_reuse.c
@@ -225,11 +225,10 @@ SMTP_SESSION *smtp_reuse_domain(SMTP_STATE *state, int lookup_mx,
SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, DNS_RR *addr, unsigned port)
{
+ MAI_HOSTADDR_STR hostaddr;
SMTP_SESSION *session;
int fd;
-#define INADDRP(x) ((struct in_addr *) (x))
-
/*
* Look up the session by its IP address. This means that we have no
* destination-to-address binding properties.
@@ -237,11 +236,10 @@ SMTP_SESSION *smtp_reuse_addr(SMTP_STATE *state, DNS_RR *addr, unsigned port)
* Note: if the label needs to be made more specific (with e.g., SASL login
* information), just append the text with vstring_sprintf_append().
*/
- if (addr->data_len > sizeof(struct in_addr))
+ if (dns_rr_to_pa(addr, &hostaddr) == 0)
return (0);
vstring_sprintf(state->endp_label, SMTP_SCACHE_LABEL(NO_MX_LOOKUP),
- state->service, inet_ntoa(*INADDRP(addr->data)),
- ntohs(port));
+ state->service, hostaddr.buf, ntohs(port));
if ((fd = scache_find_endp(smtp_scache, STR(state->endp_label),
state->endp_prop)) < 0)
return (0);
diff --git a/postfix/src/smtp/smtp_session.c b/postfix/src/smtp/smtp_session.c
index 9eab20e54..7c391092b 100644
--- a/postfix/src/smtp/smtp_session.c
+++ b/postfix/src/smtp/smtp_session.c
@@ -312,7 +312,7 @@ SMTP_SESSION *smtp_session_activate(int fd, VSTRING *dest_prop,
* Allright, bundle up what we have sofar.
*/
session = smtp_session_alloc(vstream_fdopen(fd, O_RDWR),
- dest, host, addr, port, SMTP_SESS_FLAG_NONE);
+ dest, host, addr, port, SMTP_SESS_FLAG_NONE);
session->features = (features | SMTP_FEATURE_FROM_CACHE);
session->reuse_count = reuse_count - 1;
session->sndbufsize = sndbufsize;
diff --git a/postfix/src/smtp/smtp_unalias.c b/postfix/src/smtp/smtp_unalias.c
index 20abf3880..395fd695f 100644
--- a/postfix/src/smtp/smtp_unalias.c
+++ b/postfix/src/smtp/smtp_unalias.c
@@ -85,8 +85,12 @@ const char *smtp_unalias_name(const char *name)
*/
if ((result = htable_find(cache, name)) == 0) {
fqdn = vstring_alloc(10);
- if (dns_lookup_types(name, smtp_unalias_flags, (DNS_RR **) 0,
- fqdn, (VSTRING *) 0, T_MX, T_A, 0) != DNS_OK)
+ if (dns_lookup_l(name, smtp_unalias_flags, (DNS_RR **) 0, fqdn,
+ (VSTRING *) 0, DNS_REQ_FLAG_ANY, T_MX, T_A,
+#ifdef HAS_IPV6
+ T_AAAA,
+#endif
+ 0) != DNS_OK)
vstring_strcpy(fqdn, name);
htable_enter(cache, name, result = vstring_export(fqdn));
}
diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in
index 4229c19e2..f847ce1a4 100644
--- a/postfix/src/smtpd/Makefile.in
+++ b/postfix/src/smtpd/Makefile.in
@@ -21,7 +21,7 @@ $(PROG): $(OBJS) $(LIBS)
$(CC) $(CFLAGS) -o $@ $(OBJS) $(LIBS) $(SYSLIBS)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
test: $(TESTPROG)
@@ -154,6 +154,7 @@ smtpd.o: ../../include/anvil_clnt.h
smtpd.o: ../../include/attr_clnt.h
smtpd.o: ../../include/ehlo_mask.h
smtpd.o: ../../include/maps.h
+smtpd.o: ../../include/valid_mailhost_addr.h
smtpd.o: ../../include/mail_server.h
smtpd.o: smtpd_token.h
smtpd.o: smtpd.h
@@ -206,7 +207,10 @@ smtpd_check.o: ../../include/mac_expand.h
smtpd_check.o: ../../include/mac_parse.h
smtpd_check.o: ../../include/attr_clnt.h
smtpd_check.o: ../../include/attr.h
+smtpd_check.o: ../../include/myaddrinfo.h
+smtpd_check.o: ../../include/inet_proto.h
smtpd_check.o: ../../include/dns.h
+smtpd_check.o: ../../include/sock_addr.h
smtpd_check.o: ../../include/string_list.h
smtpd_check.o: ../../include/match_list.h
smtpd_check.o: ../../include/match_ops.h
@@ -221,6 +225,7 @@ smtpd_check.o: ../../include/mail_error.h
smtpd_check.o: ../../include/name_mask.h
smtpd_check.o: ../../include/resolve_local.h
smtpd_check.o: ../../include/own_inet_addr.h
+smtpd_check.o: ../../include/inet_addr_list.h
smtpd_check.o: ../../include/mail_conf.h
smtpd_check.o: ../../include/maps.h
smtpd_check.o: ../../include/mail_addr_find.h
@@ -236,6 +241,7 @@ smtpd_check.o: ../../include/deliver_request.h
smtpd_check.o: ../../include/recipient_list.h
smtpd_check.o: ../../include/input_transp.h
smtpd_check.o: ../../include/is_header.h
+smtpd_check.o: ../../include/valid_mailhost_addr.h
smtpd_check.o: smtpd.h
smtpd_check.o: ../../include/mail_stream.h
smtpd_check.o: smtpd_sasl_glue.h
@@ -244,14 +250,18 @@ smtpd_peer.o: smtpd_peer.c
smtpd_peer.o: ../../include/sys_defs.h
smtpd_peer.o: ../../include/msg.h
smtpd_peer.o: ../../include/mymalloc.h
-smtpd_peer.o: ../../include/valid_hostname.h
smtpd_peer.o: ../../include/stringops.h
smtpd_peer.o: ../../include/vstring.h
smtpd_peer.o: ../../include/vbuf.h
+smtpd_peer.o: ../../include/myaddrinfo.h
+smtpd_peer.o: ../../include/sock_addr.h
+smtpd_peer.o: ../../include/inet_proto.h
smtpd_peer.o: ../../include/mail_proto.h
smtpd_peer.o: ../../include/vstream.h
smtpd_peer.o: ../../include/iostuff.h
smtpd_peer.o: ../../include/attr.h
+smtpd_peer.o: ../../include/valid_mailhost_addr.h
+smtpd_peer.o: ../../include/valid_hostname.h
smtpd_peer.o: smtpd.h
smtpd_peer.o: ../../include/argv.h
smtpd_peer.o: ../../include/mail_stream.h
diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c
index 8b94bdc77..fb8aa610f 100644
--- a/postfix/src/smtpd/smtpd.c
+++ b/postfix/src/smtpd/smtpd.c
@@ -256,11 +256,14 @@
/* The list of domains that are delivered via the $local_transport
/* mail delivery transport.
/* .IP "\fBinet_interfaces (all)\fR"
-/* The network interface addresses that this mail system receives mail
-/* on.
+/* The network interface addresses that this mail system receives
+/* mail on.
/* .IP "\fBproxy_interfaces (empty)\fR"
/* The network interface addresses that this mail system receives mail
/* on by way of a proxy or network address translation unit.
+/* .IP "\fBinet_protocols (ipv4)\fR"
+/* The Internet protocols Postfix will attempt to use when making
+/* or accepting connections.
/* .IP "\fBlocal_recipient_maps (proxy:unix:passwd.byname $alias_maps)\fR"
/* Lookup tables with all names or addresses of local recipients:
/* a recipient address is local when its domain matches $mydestination,
@@ -704,6 +707,7 @@
#include
#include /* ehlo filter */
#include /* ehlo filter */
+#include
/* Single-threaded server skeleton. */
@@ -879,7 +883,7 @@ static void chat_reset(SMTPD_STATE *, int);
/*
* This filter is applied after printable().
*/
-#define NEUTER_CHARACTERS " <>()\\\";:@"
+#define NEUTER_CHARACTERS " <>()\\\";@"
/*
* Reasons for losing the client.
@@ -1806,7 +1810,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
out_fprintf(out_stream, REC_TYPE_NORM,
"Received: from %s (%s [%s])",
state->helo_name ? state->helo_name : state->name,
- state->name, state->addr);
+ state->name, state->rfc_addr);
if (state->rcpt_count == 1 && state->recipient) {
out_fprintf(out_stream, REC_TYPE_NORM,
state->cleanup ? "\tby %s (%s) with %s id %s" :
@@ -2119,9 +2123,15 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "500 Syntax: ETRN domain");
return (-1);
}
- if (!ISALNUM(argv[1].strval[0]))
- argv[1].strval++;
- if (!valid_hostname(argv[1].strval, DONT_GRIPE)) {
+ if (argv[1].strval[0] == '@' || argv[1].strval[0] == '#')
+ argv[1].strval++;
+
+ /*
+ * As an extension to RFC 1985 we also allow an RFC 2821 address literal
+ * enclosed in [].
+ */
+ if (!valid_hostname(argv[1].strval, DONT_GRIPE)
+ && !valid_mailhost_literal(argv[1].strval, DONT_GRIPE)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 Error: invalid parameter syntax");
return (-1);
@@ -2188,6 +2198,7 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
{
SMTPD_TOKEN *argp;
char *attr_value;
+ const char *bare_value;
char *attr_name;
int update_namaddr = 0;
int peer_code;
@@ -2254,8 +2265,7 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
if (peer_code != SMTPD_PEER_CODE_OK) {
attr_value = CLIENT_NAME_UNKNOWN;
} else {
- if (!valid_hostname(attr_value, DONT_GRIPE)
- || valid_hostaddr(attr_value, DONT_GRIPE)) {
+ if (!valid_hostname(attr_value, DONT_GRIPE)) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 Bad %s syntax: %s",
XCLIENT_NAME, attr_value);
@@ -2273,15 +2283,17 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
else if (STREQ(attr_name, XCLIENT_ADDR)) {
if (STREQ(attr_value, XCLIENT_UNAVAILABLE)) {
attr_value = CLIENT_ADDR_UNKNOWN;
+ bare_value = attr_value;
} else {
- if (!valid_hostaddr(attr_value, DONT_GRIPE)) {
+ if ((bare_value = valid_mailhost_addr(attr_value, DONT_GRIPE)) == 0) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
smtpd_chat_reply(state, "501 Bad %s syntax: %s",
XCLIENT_ADDR, attr_value);
return (-1);
}
}
- UPDATE_STR(state->addr, attr_value);
+ UPDATE_STR(state->addr, bare_value);
+ UPDATE_STR(state->rfc_addr, attr_value);
update_namaddr = 1;
}
@@ -2347,6 +2359,7 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
{
SMTPD_TOKEN *argp;
char *attr_value;
+ const char *bare_value;
char *attr_name;
int updated = 0;
static NAME_CODE xforward_flags[] = {
@@ -2429,6 +2442,12 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
attr_value = CLIENT_NAME_UNKNOWN;
} else {
neuter(attr_value, NEUTER_CHARACTERS, '?');
+ if (!valid_hostname(attr_value, DONT_GRIPE)) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "501 Bad %s syntax: %s",
+ XFORWARD_NAME, attr_value);
+ return (-1);
+ }
}
UPDATE_STR(state->xforward.name, attr_value);
break;
@@ -2441,10 +2460,18 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
case SMTPD_STATE_XFORWARD_ADDR:
if (STREQ(attr_value, XFORWARD_UNAVAILABLE)) {
attr_value = CLIENT_ADDR_UNKNOWN;
+ bare_value = attr_value;
} else {
neuter(attr_value, NEUTER_CHARACTERS, '?');
+ if ((bare_value = valid_mailhost_addr(attr_value, DONT_GRIPE)) == 0) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "501 Bad %s syntax: %s",
+ XFORWARD_ADDR, attr_value);
+ return (-1);
+ }
}
- UPDATE_STR(state->xforward.addr, attr_value);
+ UPDATE_STR(state->xforward.addr, bare_value);
+ UPDATE_STR(state->xforward.rfc_addr, attr_value);
break;
/*
@@ -2906,7 +2933,7 @@ static void post_jail_init(char *unused_name, char **unused_argv)
* recipient checks, address mapping, header_body_checks?.
*/
smtpd_input_transp_mask =
- input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
+ input_transp_mask(VAR_INPUT_TRANSP, var_input_transp);
/*
* Sanity checks. The queue_minfree value should be at least as large as
diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h
index 442bbc1c7..45b9c9c6f 100644
--- a/postfix/src/smtpd/smtpd.h
+++ b/postfix/src/smtpd/smtpd.h
@@ -50,6 +50,7 @@ typedef struct {
char *name; /* name for access control */
char *addr; /* address for access control */
char *namaddr; /* name[address] */
+ char *rfc_addr; /* address for RFC 2821 */
char *protocol; /* email protocol */
char *helo_name; /* helo/ehlo parameter */
char *ident; /* message identifier */
@@ -65,6 +66,7 @@ typedef struct SMTPD_STATE {
char *name; /* client hostname */
char *addr; /* client host address string */
char *namaddr; /* combined name and address */
+ char *rfc_addr; /* address for RFC 2821 */
int peer_code; /* 2=ok, 4=soft, 5=hard */
int error_count; /* reset after DOT */
int error_mask; /* client errors */
@@ -234,7 +236,7 @@ extern void smtpd_peer_reset(SMTPD_STATE *state);
(((s)->xforward.flags & SMTPD_STATE_XFORWARD_CLIENT_MASK) ? \
(s)->xforward.a : (s)->a)
-#define FORWARD_ADDR(s) FORWARD_CLIENT_ATTR((s), addr)
+#define FORWARD_ADDR(s) FORWARD_CLIENT_ATTR((s), rfc_addr)
#define FORWARD_NAME(s) FORWARD_CLIENT_ATTR((s), name)
#define FORWARD_NAMADDR(s) FORWARD_CLIENT_ATTR((s), namaddr)
#define FORWARD_PROTO(s) FORWARD_CLIENT_ATTR((s), protocol)
diff --git a/postfix/src/smtpd/smtpd_backup.in b/postfix/src/smtpd/smtpd_backup.in
new file mode 100644
index 000000000..84ba6ad6f
--- /dev/null
+++ b/postfix/src/smtpd/smtpd_backup.in
@@ -0,0 +1,20 @@
+#
+# Initialize.
+#
+#! ../bin/postmap smtpd_check_access
+#msg_verbose 1
+smtpd_delay_reject 0
+mynetworks 127.0.0.0/8,168.100.189.0/28
+#
+# MX backup
+#
+mydestination wzv.porcupine.org,localhost.porcupine.org
+inet_interfaces 168.100.189.7,127.0.0.1
+recipient_restrictions permit_mx_backup,reject
+rcpt wietse@wzv.porcupine.org
+rcpt wietse@fist.porcupine.org
+rcpt wietse@porcupine.org
+permit_mx_backup_networks 168.100.189.5
+rcpt wietse@fist.porcupine.org
+permit_mx_backup_networks 168.100.189.4
+rcpt wietse@fist.porcupine.org
diff --git a/postfix/src/smtpd/smtpd_backup.ref b/postfix/src/smtpd/smtpd_backup.ref
new file mode 100644
index 000000000..e783ac25b
--- /dev/null
+++ b/postfix/src/smtpd/smtpd_backup.ref
@@ -0,0 +1,34 @@
+>>> #
+>>> # Initialize.
+>>> #
+>>> #! ../bin/postmap smtpd_check_access
+>>> #msg_verbose 1
+>>> smtpd_delay_reject 0
+OK
+>>> mynetworks 127.0.0.0/8,168.100.189.0/28
+OK
+>>> #
+>>> # MX backup
+>>> #
+>>> mydestination wzv.porcupine.org,localhost.porcupine.org
+OK
+>>> inet_interfaces 168.100.189.7,127.0.0.1
+OK
+>>> recipient_restrictions permit_mx_backup,reject
+OK
+>>> rcpt wietse@wzv.porcupine.org
+OK
+>>> rcpt wietse@fist.porcupine.org
+OK
+>>> rcpt wietse@porcupine.org
+./smtpd_check: : reject: RCPT from localhost[127.0.0.1]: 554 : Recipient address rejected: Access denied; to= proto=SMTP
+554 : Recipient address rejected: Access denied
+>>> permit_mx_backup_networks 168.100.189.5
+OK
+>>> rcpt wietse@fist.porcupine.org
+./smtpd_check: : reject: RCPT from localhost[127.0.0.1]: 554 : Recipient address rejected: Access denied; to= proto=SMTP
+554 : Recipient address rejected: Access denied
+>>> permit_mx_backup_networks 168.100.189.4
+OK
+>>> rcpt wietse@fist.porcupine.org
+OK
diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c
index dca4fa5aa..47345514b 100644
--- a/postfix/src/smtpd/smtpd_check.c
+++ b/postfix/src/smtpd/smtpd_check.c
@@ -164,15 +164,12 @@
#include
#include
#include
+#include
#ifdef STRCASECMP_IN_STRINGS_H
#include
#endif
-#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffffff
-#endif
-
/* Utility library. */
#include
@@ -188,6 +185,8 @@
#include
#include
#include
+#include
+#include
/* DNS library. */
@@ -198,6 +197,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -219,6 +219,7 @@
#include
#include
#include
+#include
/* Application-specific. */
@@ -370,6 +371,8 @@ static void PRINTFLIKE(3, 4) defer_if(SMTPD_DEFER *, int, const char *,...);
defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2))
#define DEFER_IF_REJECT3(state, class, fmt, a1, a2, a3) \
defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2), (a3))
+#define DEFER_IF_REJECT4(state, class, fmt, a1, a2, a3, a4) \
+ defer_if(&(state)->defer_if_reject, (class), (fmt), (a1), (a2), (a3), (a4))
#define DEFER_IF_PERMIT2(state, class, fmt, a1, a2) do { \
if ((state)->warn_if_reject == 0) \
defer_if(&(state)->defer_if_permit, (class), (fmt), (a1), (a2)); \
@@ -944,14 +947,14 @@ static int reject_invalid_hostaddr(SMTPD_STATE *state, char *addr,
msg_info("%s: %s", myname, addr);
if (addr[0] == '[' && (len = strlen(addr)) > 2 && addr[len - 1] == ']') {
- test_addr = mystrndup(&addr[1], len - 2);
+ test_addr = mystrndup(addr + 1, len - 2);
} else
test_addr = addr;
/*
* Validate the address.
*/
- if (!valid_hostaddr(test_addr, DONT_GRIPE))
+ if (!valid_mailhost_addr(test_addr, DONT_GRIPE))
stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
"%d <%s>: %s rejected: invalid ip address",
var_bad_name_code, reply_name, reply_class);
@@ -987,7 +990,8 @@ static int reject_invalid_hostname(SMTPD_STATE *state, char *name,
/*
* Validate the hostname.
*/
- if (!valid_hostname(test_name, DONT_GRIPE))
+ if (!valid_hostname(test_name, DONT_GRIPE)
+ && !valid_hostaddr(test_name, DONT_GRIPE)) /* XXX back compat */
stat = smtpd_check_reject(state, MAIL_ERROR_POLICY,
"%d <%s>: %s rejected: Invalid name",
var_bad_name_code, reply_name, reply_class);
@@ -1056,8 +1060,9 @@ static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
#define RR_ADDR_TYPES T_A
#endif
- dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
- (VSTRING *) 0, RR_ADDR_TYPES, T_MX, 0);
+ dns_status = dns_lookup_l(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
+ (VSTRING *) 0, DNS_REQ_FLAG_ANY,
+ RR_ADDR_TYPES, T_MX, 0);
if (dns_status == DNS_NOTFOUND)
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
"%d <%s>: %s rejected: Host not found",
@@ -1081,8 +1086,9 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, const char *name,
if (msg_verbose)
msg_info("%s: %s", myname, name);
- dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
- (VSTRING *) 0, RR_ADDR_TYPES, T_MX, 0);
+ dns_status = dns_lookup_l(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
+ (VSTRING *) 0, DNS_REQ_FLAG_ANY,
+ RR_ADDR_TYPES, T_MX, 0);
if (dns_status == DNS_NOTFOUND)
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
"%d <%s>: %s rejected: Domain not found",
@@ -1238,7 +1244,7 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
const char *reply_name, const char *reply_class)
{
char *myname = "all_auth_mx_addr";
- struct in_addr addr;
+ MAI_HOSTADDR_STR hostaddr;
DNS_RR *rr;
DNS_RR *addr_list;
int dns_status;
@@ -1255,7 +1261,8 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
/*
* Verify that all host addresses are within permit_mx_backup_networks.
*/
- dns_status = dns_lookup(host, T_A, 0, &addr_list, (VSTRING *) 0, (VSTRING *) 0);
+ dns_status = dns_lookup_v(host, 0, &addr_list, (VSTRING *) 0, (VSTRING *) 0,
+ DNS_REQ_FLAG_ALL, inet_proto_info()->dns_atype_list);
if (dns_status != DNS_OK) {
DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
"450 <%s>: %s rejected: Unable to look up host %s as mail exchanger",
@@ -1263,16 +1270,15 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
return (NOPE);
}
for (rr = addr_list; rr != 0; rr = rr->next) {
- if (rr->data_len > sizeof(addr)) {
- msg_warn("%s: skipping address length %d for host %s",
- state->queue_id, rr->data_len, host);
+ if (dns_rr_to_pa(rr, &hostaddr) == 0) {
+ msg_warn("%s: skipping record type %s for host %s: %m",
+ myname, dns_strtype(rr->type), host);
continue;
}
- memcpy((char *) &addr, rr->data, sizeof(addr));
if (msg_verbose)
- msg_info("%s: checking: %s", myname, inet_ntoa(addr));
+ msg_info("%s: checking: %s", myname, hostaddr.buf);
- if (!namadr_list_match(perm_mx_networks, host, inet_ntoa(addr))) {
+ if (!namadr_list_match(perm_mx_networks, host, hostaddr.buf)) {
/*
* Reject: at least one IP address is not listed in
@@ -1280,7 +1286,7 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
*/
if (msg_verbose)
msg_info("%s: address %s for %s does not match %s",
- myname, inet_ntoa(addr), host, VAR_PERM_MX_NETWORKS);
+ myname, hostaddr.buf, host, VAR_PERM_MX_NETWORKS);
dns_rr_free(addr_list);
return (NOPE);
}
@@ -1295,9 +1301,11 @@ static int has_my_addr(SMTPD_STATE *state, const char *host,
const char *reply_name, const char *reply_class)
{
char *myname = "has_my_addr";
- struct in_addr addr;
- char **cpp;
- struct hostent *hp;
+ struct addrinfo *res;
+ struct addrinfo *res0;
+ int aierr;
+ MAI_HOSTADDR_STR hostaddr;
+ INET_PROTO_INFO *proto_info = inet_proto_info();
if (msg_verbose)
msg_info("%s: host %s", myname, host);
@@ -1308,30 +1316,36 @@ static int has_my_addr(SMTPD_STATE *state, const char *host,
#define YUP 1
#define NOPE 0
- if ((hp = gethostbyname(host)) == 0) {
- DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
- "450 <%s>: %s rejected: Unable to look up mail exchanger host %s",
- reply_name, reply_class, host);
+ aierr = hostname_to_sockaddr(host, (char *) 0, 0, &res0);
+ if (aierr) {
+ DEFER_IF_REJECT4(state, MAIL_ERROR_POLICY,
+ "450 <%s>: %s rejected: Unable to look up mail exchanger host %s: %s",
+ reply_name, reply_class, host, MAI_STRERROR(aierr));
return (NOPE);
}
- if (hp->h_addrtype != AF_INET || hp->h_length != sizeof(addr)) {
- msg_warn("address type %d length %d for %s",
- hp->h_addrtype, hp->h_length, host);
- return (NOPE);
- }
- for (cpp = hp->h_addr_list; *cpp; cpp++) {
- memcpy((char *) &addr, *cpp, sizeof(addr));
- if (msg_verbose)
- msg_info("%s: addr %s", myname, inet_ntoa(addr));
- if (own_inet_addr(&addr))
- return (YUP);
- if (proxy_inet_addr(&addr))
- return (YUP);
+#define HAS_MY_ADDR_RETURN(x) { freeaddrinfo(res0); return (x); }
+
+ for (res = res0; res != 0; res = res->ai_next) {
+ if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
+ if (msg_verbose)
+ msg_info("skipping address family %d for host %s",
+ res->ai_family, host);
+ continue;
+ }
+ if (msg_verbose) {
+ SOCKADDR_TO_HOSTADDR(res->ai_addr, res->ai_addrlen,
+ &hostaddr, (MAI_SERVPORT_STR *) 0, 0);
+ msg_info("%s: addr %s", myname, hostaddr.buf);
+ }
+ if (own_inet_addr(res->ai_addr))
+ HAS_MY_ADDR_RETURN(YUP);
+ if (proxy_inet_addr(res->ai_addr))
+ HAS_MY_ADDR_RETURN(YUP);
}
if (msg_verbose)
msg_info("%s: host %s: no match", myname, host);
- return (NOPE);
+ HAS_MY_ADDR_RETURN(NOPE);
}
/* i_am_mx - is this machine listed as MX relay */
@@ -1339,7 +1353,7 @@ static int has_my_addr(SMTPD_STATE *state, const char *host,
static int i_am_mx(SMTPD_STATE *state, DNS_RR *mx_list,
const char *reply_name, const char *reply_class)
{
- const char *myname = "permit_mx_backup";
+ const char *myname = "i_am_mx";
DNS_RR *mx;
/*
@@ -1376,9 +1390,13 @@ static int i_am_mx(SMTPD_STATE *state, DNS_RR *mx_list,
static int permit_mx_primary(SMTPD_STATE *state, DNS_RR *mx_list,
const char *reply_name, const char *reply_class)
{
+ const char *myname = "permit_mx_primary";
DNS_RR *mx;
unsigned int best_pref;
+ if (msg_verbose)
+ msg_info("%s", myname);
+
/*
* Find the preference of the primary MX hosts.
*/
@@ -2070,6 +2088,7 @@ static int check_addr_access(SMTPD_STATE *state, const char *table,
char *addr;
const char *value;
DICT *dict;
+ int delim;
if (msg_verbose)
msg_info("%s: %s", myname, address);
@@ -2080,6 +2099,12 @@ static int check_addr_access(SMTPD_STATE *state, const char *table,
#define CHK_ADDR_RETURN(x,y) { *found = y; return(x); }
addr = STR(vstring_strcpy(error_text, address));
+#ifdef HAS_IPV6
+ if (strchr(addr, ':') != 0)
+ delim = ':';
+ else
+#endif
+ delim = '.';
if ((dict = dict_handle(table)) == 0)
msg_panic("%s: dictionary not found: %s", myname, table);
@@ -2093,7 +2118,7 @@ static int check_addr_access(SMTPD_STATE *state, const char *table,
msg_fatal("%s: table lookup problem", table);
}
flags = PARTIAL;
- } while (split_at_right(addr, '.'));
+ } while (split_at_right(addr, delim));
CHK_ADDR_RETURN(SMTPD_CHECK_DUNNO, MISSED);
}
@@ -2151,12 +2176,12 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
DNS_RR *server_list;
DNS_RR *server;
int found = 0;
- struct in_addr addr;
- struct hostent *hp;
- char *addr_string;
+ MAI_HOSTADDR_STR addr_string;
+ int aierr;
+ struct addrinfo *res0;
+ struct addrinfo *res;
int status;
- char **cpp;
- static DNS_FIXED fixed;
+ INET_PROTO_INFO *proto_info;
/*
* Sanity check.
@@ -2189,7 +2214,7 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
(VSTRING *) 0, (VSTRING *) 0);
if (dns_status == DNS_NOTFOUND && h_errno == NO_DATA) {
if (type == T_MX) {
- server_list = dns_rr_create(domain, &fixed, 0,
+ server_list = dns_rr_create(domain, type, C_IN, 0, 0,
domain, strlen(domain) + 1);
dns_status = DNS_OK;
} else if (type == T_NS) {
@@ -2216,6 +2241,7 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
/*
* Check the hostnames first, then the addresses.
*/
+ proto_info = inet_proto_info();
for (server = server_list; server != 0; server = server->next) {
if (msg_verbose)
msg_info("%s: %s hostname check: %s",
@@ -2224,32 +2250,35 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
FULL, &found, reply_name, reply_class,
def_acl)) != 0 || found)
CHECK_SERVER_RETURN(status);
- SET_H_ERRNO(0);
- if ((hp = gethostbyname((char *) server->data)) == 0) {
+ if ((aierr = hostname_to_sockaddr((char *) server->data,
+ (char *) 0, 0, &res0)) != 0) {
msg_warn("Unable to look up %s host %s for %s %s: %s",
dns_strtype(type), (char *) server->data,
- reply_class, reply_name, dns_strerror(h_errno));
+ reply_class, reply_name, MAI_STRERROR(aierr));
continue;
}
- if (hp->h_addrtype != AF_INET || hp->h_length != sizeof(addr)) {
- if (msg_verbose)
- msg_warn("address type %d length %d for %s",
- hp->h_addrtype, hp->h_length, (char *) server->data);
- continue; /* XXX */
- }
+ /* Now we must also free the addrinfo result. */
if (msg_verbose)
msg_info("%s: %s host address check: %s",
myname, dns_strtype(type), (char *) server->data);
- for (cpp = hp->h_addr_list; *cpp; cpp++) {
- memcpy((char *) &addr, *cpp, sizeof(addr));
- addr_string = mystrdup(inet_ntoa(addr));
- status = check_addr_access(state, table, addr_string, FULL,
+ for (res = res0; res != 0; res = res->ai_next) {
+ if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
+ if (msg_verbose)
+ msg_info("skipping address family %d for host %s",
+ res->ai_family, server->data);
+ continue;
+ }
+ SOCKADDR_TO_HOSTADDR(res->ai_addr, res->ai_addrlen,
+ &addr_string, (MAI_SERVPORT_STR *) 0, 0);
+ status = check_addr_access(state, table, addr_string.buf, FULL,
&found, reply_name, reply_class,
def_acl);
- myfree(addr_string);
- if (status != 0 || found)
+ if (status != 0 || found) {
+ freeaddrinfo(res0); /* 200412 */
CHECK_SERVER_RETURN(status);
+ }
}
+ freeaddrinfo(res0); /* 200412 */
}
CHECK_SERVER_RETURN(SMTPD_CHECK_DUNNO);
}
@@ -2501,12 +2530,13 @@ static const char *smtpd_expand_lookup(const char *name, int unused_mode,
static void *rbl_pagein(const char *query, void *unused_context)
{
+ const char *myname = "rbl_pagein";
DNS_RR *txt_list;
VSTRING *why;
int dns_status;
SMTPD_RBL_STATE *rbl;
DNS_RR *addr_list;
- struct in_addr addr;
+ MAI_HOSTADDR_STR hostaddr;
DNS_RR *rr;
DNS_RR *next;
VSTRING *buf;
@@ -2516,6 +2546,8 @@ static void *rbl_pagein(const char *query, void *unused_context)
* Do the query. If the DNS lookup produces no definitive reply, give the
* requestor the benefit of the doubt. We can't block all email simply
* because an RBL server is unavailable.
+ *
+ * Don't do this for AAAA records. Yet.
*/
why = vstring_alloc(10);
dns_status = dns_lookup(query, T_A, 0, &addr_list, (VSTRING *) 0, why);
@@ -2552,8 +2584,11 @@ static void *rbl_pagein(const char *query, void *unused_context)
rbl->txt = 0;
rbl->a = argv_alloc(1);
for (rr = addr_list; rr != 0; rr = rr->next) {
- memcpy((char *) &addr.s_addr, addr_list->data, sizeof(addr.s_addr));
- argv_add(rbl->a, inet_ntoa(addr), ARGV_END);
+ if (dns_rr_to_pa(rr, &hostaddr) == 0)
+ msg_warn("%s: skipping record type %s for query %s: %m",
+ myname, dns_strtype(rr->type), query);
+ else
+ argv_add(rbl->a, hostaddr.buf, ARGV_END);
}
dns_rr_free(addr_list);
return ((void *) rbl);
@@ -2690,12 +2725,10 @@ static int reject_rbl_addr(SMTPD_STATE *state, const char *rbl_domain,
msg_info("%s: %s %s", myname, reply_class, addr);
/*
- * IPv4 only for now
+ * IPv4 / IPv6-mapped IPv4 (if supported) only for now
*/
-#ifdef INET6
- if (inet_pton(AF_INET, addr, &a) != 1)
+ if (valid_ipv6_hostaddr(addr, DONT_GRIPE))
return SMTPD_CHECK_DUNNO;
-#endif
/*
* Reverse the client IPV4 address, tack on the RBL domain name and query
@@ -3134,7 +3167,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
msg_warn("restriction %s is deprecated. Use %s instead",
PERMIT_NAKED_IP_ADDR, PERMIT_MYNETWORKS);
if (state->helo_name) {
- if (state->helo_name[strspn(state->helo_name, "0123456789.")] == 0
+ if (state->helo_name[strspn(state->helo_name, "0123456789.:")] == 0
&& (status = reject_invalid_hostaddr(state, state->helo_name,
state->helo_name, SMTPD_NAME_HELO)) == 0)
status = SMTPD_CHECK_OK;
@@ -4095,6 +4128,7 @@ char *var_mail_checks = "";
char *var_rcpt_checks = "";
char *var_etrn_checks = "";
char *var_data_checks = "";
+char *var_eod_checks = "";
char *var_relay_domains = "";
char *var_mynetworks = "";
char *var_notify_classes = "";
@@ -4106,6 +4140,7 @@ char *var_maps_rbl_domains;
char *var_myorigin;
char *var_mydest;
char *var_inet_interfaces;
+char *var_proxy_interfaces;
char *var_rcpt_delim;
char *var_rest_classes;
char *var_alias_maps;
@@ -4146,6 +4181,7 @@ static STRING_TABLE string_table[] = {
VAR_MYORIGIN, DEF_MYORIGIN, &var_myorigin,
VAR_MYDEST, DEF_MYDEST, &var_mydest,
VAR_INET_INTERFACES, DEF_INET_INTERFACES, &var_inet_interfaces,
+ VAR_PROXY_INTERFACES, DEF_PROXY_INTERFACES, &var_proxy_interfaces,
VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim,
VAR_REST_CLASSES, DEF_REST_CLASSES, &var_rest_classes,
VAR_ALIAS_MAPS, DEF_ALIAS_MAPS, &var_alias_maps,
@@ -4467,6 +4503,7 @@ int main(int argc, char **argv)
char *bp;
char *resp;
char *addr;
+ INET_PROTO_INFO *proto_info;
/*
* Initialization. Use dummies for client information.
@@ -4480,6 +4517,8 @@ int main(int argc, char **argv)
smtpd_state_init(&state, VSTREAM_IN, "smtpd");
state.queue_id = "";
+ proto_info = inet_proto_init(argv[0], INET_PROTO_NAME_ALL);
+
/*
* Main loop: update config parameters or test the client, helo, sender
* and recipient restrictions.
@@ -4567,35 +4606,36 @@ int main(int argc, char **argv)
resp = 0;
break;
}
- if (strcasecmp(args->argv[0], "local_recipient_maps") == 0) {
+ if (strcasecmp(args->argv[0], VAR_LOCAL_RCPT_MAPS) == 0) {
UPDATE_STRING(var_local_rcpt_maps, args->argv[1]);
UPDATE_MAPS(local_rcpt_maps, VAR_LOCAL_RCPT_MAPS,
var_local_rcpt_maps, DICT_FLAG_LOCK);
resp = 0;
break;
}
- if (strcasecmp(args->argv[0], "relay_recipient_maps") == 0) {
+ if (strcasecmp(args->argv[0], VAR_RELAY_RCPT_MAPS) == 0) {
UPDATE_STRING(var_relay_rcpt_maps, args->argv[1]);
UPDATE_MAPS(relay_rcpt_maps, VAR_RELAY_RCPT_MAPS,
var_relay_rcpt_maps, DICT_FLAG_LOCK);
resp = 0;
break;
}
- if (strcasecmp(args->argv[0], "canonical_maps") == 0) {
+ if (strcasecmp(args->argv[0], VAR_CANONICAL_MAPS) == 0) {
UPDATE_STRING(var_canonical_maps, args->argv[1]);
UPDATE_MAPS(canonical_maps, VAR_CANONICAL_MAPS,
var_canonical_maps, DICT_FLAG_LOCK);
resp = 0;
break;
}
- if (strcasecmp(args->argv[0], "rbl_reply_maps") == 0) {
+ if (strcasecmp(args->argv[0], VAR_RBL_REPLY_MAPS) == 0) {
UPDATE_STRING(var_rbl_reply_maps, args->argv[1]);
UPDATE_MAPS(rbl_reply_maps, VAR_RBL_REPLY_MAPS,
var_rbl_reply_maps, DICT_FLAG_LOCK);
resp = 0;
break;
}
- if (strcasecmp(args->argv[0], "mynetworks") == 0) {
+ if (strcasecmp(args->argv[0], VAR_MYNETWORKS) == 0) {
+ /* NOT: UPDATE_STRING */
namadr_list_free(mynetworks);
mynetworks =
namadr_list_init(match_parent_style(VAR_MYNETWORKS),
@@ -4603,7 +4643,8 @@ int main(int argc, char **argv)
resp = 0;
break;
}
- if (strcasecmp(args->argv[0], "relay_domains") == 0) {
+ if (strcasecmp(args->argv[0], VAR_RELAY_DOMAINS) == 0) {
+ /* NOT: UPDATE_STRING */
domain_list_free(relay_domains);
relay_domains =
domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
@@ -4611,6 +4652,15 @@ int main(int argc, char **argv)
resp = 0;
break;
}
+ if (strcasecmp(args->argv[0], VAR_PERM_MX_NETWORKS) == 0) {
+ UPDATE_STRING(var_perm_mx_networks, args->argv[1]);
+ domain_list_free(perm_mx_networks);
+ perm_mx_networks =
+ namadr_list_init(match_parent_style(VAR_PERM_MX_NETWORKS),
+ args->argv[1]);
+ resp = 0;
+ break;
+ }
if (strcasecmp(args->argv[0], "restriction_class") == 0) {
rest_class(args->argv[1]);
resp = 0;
diff --git a/postfix/src/smtpd/smtpd_check.in b/postfix/src/smtpd/smtpd_check.in
index 2b5605178..496fb67a2 100644
--- a/postfix/src/smtpd/smtpd_check.in
+++ b/postfix/src/smtpd/smtpd_check.in
@@ -34,6 +34,10 @@ helo random.bad.domain
helo friend.bad.domain
helo_restrictions reject_invalid_hostname,reject_unknown_hostname
helo 123.123.123.123
+helo [123.123.123.123]
+helo [::]
+helo [ipv6:::]
+helo [ipv6::::]
helo_restrictions permit_naked_ip_address,reject_invalid_hostname,reject_unknown_hostname
helo 123.123.123.123
#
diff --git a/postfix/src/smtpd/smtpd_check.ref b/postfix/src/smtpd/smtpd_check.ref
index 859e8b381..0b96f5f22 100644
--- a/postfix/src/smtpd/smtpd_check.ref
+++ b/postfix/src/smtpd/smtpd_check.ref
@@ -69,6 +69,16 @@ OK
>>> helo 123.123.123.123
./smtpd_check: : reject: HELO from foo[123.123.123.123]: 450 <123.123.123.123>: Helo command rejected: Host not found; proto=SMTP helo=<123.123.123.123>
450 <123.123.123.123>: Helo command rejected: Host not found
+>>> helo [123.123.123.123]
+OK
+>>> helo [::]
+./smtpd_check: : reject: HELO from foo[123.123.123.123]: 501 <[::]>: Helo command rejected: invalid ip address; proto=SMTP helo=<[::]>
+501 <[::]>: Helo command rejected: invalid ip address
+>>> helo [ipv6:::]
+OK
+>>> helo [ipv6::::]
+./smtpd_check: : reject: HELO from foo[123.123.123.123]: 501 <[ipv6::::]>: Helo command rejected: invalid ip address; proto=SMTP helo=<[ipv6::::]>
+501 <[ipv6::::]>: Helo command rejected: invalid ip address
>>> helo_restrictions permit_naked_ip_address,reject_invalid_hostname,reject_unknown_hostname
OK
>>> helo 123.123.123.123
diff --git a/postfix/src/smtpd/smtpd_peer.c b/postfix/src/smtpd/smtpd_peer.c
index 28c127f2a..41f627d1d 100644
--- a/postfix/src/smtpd/smtpd_peer.c
+++ b/postfix/src/smtpd/smtpd_peer.c
@@ -63,37 +63,19 @@
#include
#include
- /*
- * Older systems don't have h_errno. Even modern systems don't have
- * hstrerror().
- */
-#ifdef NO_HERRNO
-
-static int h_errno = TRY_AGAIN;
-
-#define HSTRERROR(err) "Host not found"
-
-#else
-
-#define HSTRERROR(err) (\
- err == TRY_AGAIN ? "Host not found, try again" : \
- err == HOST_NOT_FOUND ? "Host not found" : \
- err == NO_DATA ? "Host name has no address" : \
- err == NO_RECOVERY ? "Name server failure" : \
- strerror(errno) \
- )
-#endif
-
/* Utility library. */
#include
#include
-#include
#include
+#include
+#include
+#include
/* Global library. */
#include
+#include
/* Application-specific. */
@@ -103,21 +85,19 @@ static int h_errno = TRY_AGAIN;
void smtpd_peer_init(SMTPD_STATE *state)
{
- struct sockaddr_in sin;
- SOCKADDR_SIZE len = sizeof(sin);
- struct hostent *hp;
- int i;
+ char *myname = "smtpd_peer_init";
+ struct sockaddr_storage ss;
+ SOCKADDR_SIZE sa_len;
+ struct sockaddr *sa;
+ INET_PROTO_INFO *proto_info = inet_proto_info();
- /*
- * Avoid suprious complaints from Purify on Solaris.
- */
- memset((char *) &sin, 0, len);
+ sa = (struct sockaddr *) & ss;
+ sa_len = sizeof(ss);
/*
* Look up the peer address information.
*/
- if (getpeername(vstream_fileno(state->client),
- (struct sockaddr *) & sin, &len) >= 0) {
+ if (getpeername(vstream_fileno(state->client), sa, &sa_len) >= 0) {
errno = 0;
}
@@ -127,64 +107,137 @@ void smtpd_peer_init(SMTPD_STATE *state)
if (errno == ECONNRESET || errno == ECONNABORTED) {
state->name = mystrdup(CLIENT_NAME_UNKNOWN);
state->addr = mystrdup(CLIENT_ADDR_UNKNOWN);
+ state->rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
state->peer_code = SMTPD_PEER_CODE_PERM;
}
/*
- * Look up and "verify" the client hostname.
+ * Convert the client address to printable address and hostname.
*/
- else if (errno == 0 && sin.sin_family == AF_INET) {
- state->addr = mystrdup(inet_ntoa(sin.sin_addr));
- hp = gethostbyaddr((char *) &(sin.sin_addr),
- sizeof(sin.sin_addr), AF_INET);
- if (hp == 0) {
- state->name = mystrdup(CLIENT_NAME_UNKNOWN);
- state->peer_code = (h_errno == TRY_AGAIN ?
- SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
- } else if (valid_hostaddr(hp->h_name, DONT_GRIPE)) {
- msg_warn("numeric result %s in address->name lookup for %s",
- hp->h_name, state->addr);
- state->name = mystrdup(CLIENT_NAME_UNKNOWN);
- state->peer_code = SMTPD_PEER_CODE_PERM;
- } else if (!valid_hostname(hp->h_name, DONT_GRIPE)) {
- state->name = mystrdup(CLIENT_NAME_UNKNOWN);
- state->peer_code = SMTPD_PEER_CODE_PERM;
- } else {
- state->name = mystrdup(hp->h_name); /* hp->name is clobbered!! */
- state->peer_code = SMTPD_PEER_CODE_OK;
+ else if (errno == 0
+ && strchr((char *) proto_info->sa_family_list, sa->sa_family)) {
+ MAI_HOSTNAME_STR client_name;
+ MAI_HOSTADDR_STR client_addr;
+ int aierr;
+ char *colonp;
+
+ /*
+ * Convert the client address to printable form.
+ */
+ if ((aierr = sockaddr_to_hostaddr(sa, sa_len, &client_addr,
+ (MAI_SERVPORT_STR *) 0, 0)) != 0)
+ msg_fatal("%s: cannot convert client address to string: %s",
+ myname, MAI_STRERROR(aierr));
+
+ /*
+ * We convert IPv4-in-IPv6 address to 'true' IPv4 address early on,
+ * but only if IPv4 support is enabled (why would anyone want to turn
+ * it off)? With IPv4 support enabled we have no need for the IPv6
+ * form in logging, hostname verification and access checks.
+ */
+#ifdef HAS_IPV6
+ if (sa->sa_family == AF_INET6) {
+ if (strchr((char *) proto_info->sa_family_list, AF_INET) != 0
+ && IN6_IS_ADDR_V4MAPPED(&SOCK_ADDR_IN6_ADDR(sa))
+ && (colonp = strrchr(client_addr.buf, ':')) != 0) {
+ struct addrinfo *res0;
+
+ if (msg_verbose > 1)
+ msg_info("%s: rewriting V4-mapped address \"%s\" to \"%s\"",
+ myname, client_addr.buf, colonp + 1);
+
+ state->addr = mystrdup(colonp + 1);
+ state->rfc_addr = mystrdup(colonp + 1);
+ aierr = hostaddr_to_sockaddr(state->addr, (char *) 0, 0, &res0);
+ if (aierr)
+ msg_fatal("%s: cannot convert %s from string to binary: %s",
+ myname, state->addr, MAI_STRERROR(aierr));
+ sa_len = res0->ai_addrlen;
+ memcpy((char *) sa, res0->ai_addr, sa_len);
+ freeaddrinfo(res0); /* 200412 */
+ }
/*
- * Reject the hostname if it does not list the peer address.
+ * Following RFC 2821 section 4.1.3, an IPv6 address literal gets
+ * a prefix of 'IPv6:'. We do this consistently for all IPv6
+ * addresses that that appear in headers or envelopes. The fact
+ * that valid_mailhost_addr() enforces the form helps of course.
+ * We use the form without IPV6: prefix when doing access
+ * control, or when accessing the connection cache.
*/
+ else {
+ state->addr = mystrdup(client_addr.buf);
+ state->rfc_addr =
+ concatenate(IPV6_COL, client_addr.buf, (char *) 0);
+ }
+ }
+
+ /*
+ * An IPv4 address is in dotted quad decimal form.
+ */
+ else
+#endif
+ {
+ state->addr = mystrdup(client_addr.buf);
+ state->rfc_addr = mystrdup(client_addr.buf);
+ }
+
+ /*
+ * Look up and sanity check the client hostname.
+ *
+ * It is unsafe to allow numeric hostnames, especially because there
+ * exists pressure to turn off the name->addr double check. In that
+ * case an attacker could trivally bypass access restrictions.
+ *
+ * sockaddr_to_hostname() already rejects malformed or numeric names.
+ */
+#define TEMP_AI_ERROR(e) \
+ ((e) == EAI_AGAIN || (e) == EAI_MEMORY || (e) == EAI_SYSTEM)
+
#define REJECT_PEER_NAME(state, code) { \
myfree(state->name); \
state->name = mystrdup(CLIENT_NAME_UNKNOWN); \
state->peer_code = code; \
}
- hp = gethostbyname(state->name); /* clobbers hp->name!! */
- if (hp == 0) {
+ if ((aierr = sockaddr_to_hostname(sa, sa_len, &client_name,
+ (MAI_SERVNAME_STR *) 0, 0)) != 0) {
+ state->name = mystrdup(CLIENT_NAME_UNKNOWN);
+ state->peer_code = (TEMP_AI_ERROR(aierr) ?
+ SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM);
+ } else {
+ struct addrinfo *res0;
+ struct addrinfo *res;
+
+ state->name = mystrdup(client_name.buf);
+ state->peer_code = SMTPD_PEER_CODE_OK;
+
+ /*
+ * Reject the hostname if it does not list the peer address.
+ */
+ aierr = hostname_to_sockaddr(state->name, (char *) 0, 0, &res0);
+ if (aierr) {
msg_warn("%s: hostname %s verification failed: %s",
- state->addr, state->name, HSTRERROR(h_errno));
- REJECT_PEER_NAME(state, (h_errno == TRY_AGAIN ?
+ state->addr, state->name, MAI_STRERROR(aierr));
+ REJECT_PEER_NAME(state, (TEMP_AI_ERROR(aierr) ?
SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM));
- } else if (hp->h_length != sizeof(sin.sin_addr)) {
- msg_warn("%s: hostname %s verification failed: bad address size %d",
- state->addr, state->name, hp->h_length);
- REJECT_PEER_NAME(state, SMTPD_PEER_CODE_PERM);
} else {
- for (i = 0; /* void */ ; i++) {
- if (hp->h_addr_list[i] == 0) {
+ for (res = res0; /* void */ ; res = res->ai_next) {
+ if (res == 0) {
msg_warn("%s: address not listed for hostname %s",
state->addr, state->name);
REJECT_PEER_NAME(state, SMTPD_PEER_CODE_PERM);
break;
}
- if (memcmp(hp->h_addr_list[i],
- (char *) &sin.sin_addr,
- sizeof(sin.sin_addr)) == 0)
+ if (strchr((char *) proto_info->sa_family_list, res->ai_family) == 0) {
+ msg_info("skipping address family %d for host %s",
+ res->ai_family, state->name);
+ continue;
+ }
+ if (sock_addr_cmp_addr(res->ai_addr, sa) == 0)
break; /* keep peer name */
}
+ freeaddrinfo(res0);
}
}
}
@@ -196,6 +249,7 @@ void smtpd_peer_init(SMTPD_STATE *state)
else {
state->name = mystrdup("localhost");
state->addr = mystrdup("127.0.0.1"); /* XXX bogus. */
+ state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */
state->peer_code = SMTPD_PEER_CODE_OK;
}
@@ -213,4 +267,5 @@ void smtpd_peer_reset(SMTPD_STATE *state)
myfree(state->name);
myfree(state->addr);
myfree(state->namaddr);
+ myfree(state->rfc_addr);
}
diff --git a/postfix/src/smtpd/smtpd_xforward.c b/postfix/src/smtpd/smtpd_xforward.c
index d6a9638f7..614c96147 100644
--- a/postfix/src/smtpd/smtpd_xforward.c
+++ b/postfix/src/smtpd/smtpd_xforward.c
@@ -83,6 +83,7 @@ void smtpd_xforward_preset(SMTPD_STATE *state)
state->xforward.name = mystrdup(CLIENT_NAME_UNKNOWN);
state->xforward.addr = mystrdup(CLIENT_ADDR_UNKNOWN);
state->xforward.namaddr = mystrdup(CLIENT_NAMADDR_UNKNOWN);
+ state->xforward.rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
/* Leave helo at zero. */
state->xforward.protocol = mystrdup(CLIENT_PROTO_UNKNOWN);
/* Leave ident at zero. */
@@ -99,6 +100,7 @@ void smtpd_xforward_reset(SMTPD_STATE *state)
FREE_AND_WIPE(state->xforward.name);
FREE_AND_WIPE(state->xforward.addr);
FREE_AND_WIPE(state->xforward.namaddr);
+ FREE_AND_WIPE(state->xforward.rfc_addr);
FREE_AND_WIPE(state->xforward.protocol);
FREE_AND_WIPE(state->xforward.helo_name);
FREE_AND_WIPE(state->xforward.ident);
diff --git a/postfix/src/smtpstone/Makefile.in b/postfix/src/smtpstone/Makefile.in
index f3738bcc6..7091a797a 100644
--- a/postfix/src/smtpstone/Makefile.in
+++ b/postfix/src/smtpstone/Makefile.in
@@ -15,7 +15,7 @@ LIBS = ../../lib/libglobal.a ../../lib/libutil.a
all: $(PROG)
Makefile: Makefile.in
- (set -e; echo "# DO NOT EDIT"; $(OPTS) $(SHELL) ../../makedefs && cat $?) >$@
+ (echo "# DO NOT EDIT"; tail +2 ../../conf/makedefs.out; cat $?) >$@
smtp-sink: smtp-sink.o $(LIBS)
$(CC) $(CFLAGS) -o $@ smtp-sink.o $(LIBS) $(SYSLIBS)
@@ -85,6 +85,7 @@ qmqp-sink.o: ../../include/events.h
qmqp-sink.o: ../../include/mymalloc.h
qmqp-sink.o: ../../include/msg_vstream.h
qmqp-sink.o: ../../include/netstring.h
+qmqp-sink.o: ../../include/inet_proto.h
qmqp-sink.o: ../../include/qmqp_proto.h
qmqp-source.o: qmqp-source.c
qmqp-source.o: ../../include/sys_defs.h
@@ -99,9 +100,11 @@ qmqp-source.o: ../../include/connect.h
qmqp-source.o: ../../include/iostuff.h
qmqp-source.o: ../../include/mymalloc.h
qmqp-source.o: ../../include/events.h
-qmqp-source.o: ../../include/find_inet.h
qmqp-source.o: ../../include/netstring.h
qmqp-source.o: ../../include/sane_connect.h
+qmqp-source.o: ../../include/host_port.h
+qmqp-source.o: ../../include/myaddrinfo.h
+qmqp-source.o: ../../include/inet_proto.h
qmqp-source.o: ../../include/mail_date.h
qmqp-source.o: ../../include/qmqp_proto.h
smtp-sink.o: smtp-sink.c
@@ -119,6 +122,7 @@ smtp-sink.o: ../../include/mymalloc.h
smtp-sink.o: ../../include/msg_vstream.h
smtp-sink.o: ../../include/stringops.h
smtp-sink.o: ../../include/sane_accept.h
+smtp-sink.o: ../../include/inet_proto.h
smtp-sink.o: ../../include/smtp_stream.h
smtp-source.o: smtp-source.c
smtp-source.o: ../../include/sys_defs.h
@@ -134,7 +138,9 @@ smtp-source.o: ../../include/connect.h
smtp-source.o: ../../include/iostuff.h
smtp-source.o: ../../include/mymalloc.h
smtp-source.o: ../../include/events.h
-smtp-source.o: ../../include/find_inet.h
smtp-source.o: ../../include/sane_connect.h
+smtp-source.o: ../../include/host_port.h
+smtp-source.o: ../../include/myaddrinfo.h
+smtp-source.o: ../../include/inet_proto.h
smtp-source.o: ../../include/smtp_stream.h
smtp-source.o: ../../include/mail_date.h
diff --git a/postfix/src/smtpstone/qmqp-sink.c b/postfix/src/smtpstone/qmqp-sink.c
index 215498063..6517698b8 100644
--- a/postfix/src/smtpstone/qmqp-sink.c
+++ b/postfix/src/smtpstone/qmqp-sink.c
@@ -5,19 +5,26 @@
/* multi-threaded QMQP test server
/* SYNOPSIS
/* .fi
-/* \fBqmqp-sink\fR [\fB-cv\fR] [\fB-x \fItime\fR]
+/* \fBqmqp-sink\fR [\fB-46cv\fR] [\fB-x \fItime\fR]
/* [\fBinet:\fR][\fIhost\fR]:\fIport\fR \fIbacklog\fR
/*
-/* \fBqmqp-sink\fR [\fB-cv\fR] [\fB-x \fItime\fR]
+/* \fBqmqp-sink\fR [\fB-46cv\fR] [\fB-x \fItime\fR]
/* \fBunix:\fR\fIpathname\fR \fIbacklog\fR
/* DESCRIPTION
/* \fBqmqp-sink\fR listens on the named host (or address) and port.
/* It receives messages from the network and throws them away.
/* The purpose is to measure QMQP client performance, not protocol
/* compliance.
-/* Connections can be accepted on IPV4 endpoints or UNIX-domain sockets.
-/* IPV4 is the default.
+/* Connections can be accepted on IPv4 or IPv6 endpoints, or on
+/* UNIX-domain sockets.
+/* IPv4 and IPv6 are the default.
/* This program is the complement of the \fBqmqp-source\fR(1) program.
+/* .IP \fB-4\fR
+/* Support IPv4 only. This option has no effect when
+/* Postfix is built without IPv6 support.
+/* .IP \fB-6\fR
+/* Support IPv6 only. This option is not available when
+/* Postfix is built without IPv6 support.
/* .IP \fB-c\fR
/* Display a running counter that is updated whenever a delivery
/* is completed.
@@ -65,6 +72,7 @@
#include