From bd8300ce108db78ca379aa84aedd9db278d87c5d Mon Sep 17 00:00:00 2001
From: eabdullin
Date: Wed, 14 May 2025 15:25:48 +0000
Subject: [PATCH] import UBI postfix-3.8.5-8.el10
---
.gitignore | 4 +-
.postfix.metadata | 2 -
...dHat.txt => README-Postfix-SASL-RedHat.txt | 0
SOURCES/README-RedHat.txt | 65 -
SOURCES/postfix-3.5.8-SRV-resolve.patch | 1586 -----------------
SOURCES/postfix-3.5.8-back-compat-3.3.1.patch | 158 --
SOURCES/postfix-3.5.8-makedefs.patch | 32 -
.../postfix-3.5.8-whitespace-name-fix.patch | 13 -
SOURCES/postfix.aliasesdb | 20 -
...lc.patch => pflogsumm-1.1.5-datecalc.patch | 0
...=> pflogsumm-1.1.5-ipv6-warnings-fix.patch | 0
...umm-1.1.5-syslog-name-underscore-fix.patch | 0
....patch => postfix-3.3.3-alternatives.patch | 0
...0-files.patch => postfix-3.4.0-files.patch | 0
... => postfix-3.4.4-chroot-example-fix.patch | 0
...config.patch => postfix-3.8.0-config.patch | 20 +-
...e-fs.patch => postfix-3.8.0-large-fs.patch | 4 +-
postfix-3.8.5-openssl-no-engine.patch | 12 +
...fix-chroot-update => postfix-chroot-update | 0
postfix-etc-init.d-postfix | 169 ++
SOURCES/postfix-pam.conf => postfix-pam.conf | 0
.../postfix-sasl.conf => postfix-sasl.conf | 0
postfix.aliasesdb | 25 +
SOURCES/postfix.service => postfix.service | 0
SPECS/postfix.spec => postfix.spec | 543 +++++-
postfix.sysusers | 3 +
sources | 2 +
27 files changed, 676 insertions(+), 1982 deletions(-)
delete mode 100644 .postfix.metadata
rename SOURCES/README-Postfix-SASL-RedHat.txt => README-Postfix-SASL-RedHat.txt (100%)
delete mode 100644 SOURCES/README-RedHat.txt
delete mode 100644 SOURCES/postfix-3.5.8-SRV-resolve.patch
delete mode 100644 SOURCES/postfix-3.5.8-back-compat-3.3.1.patch
delete mode 100644 SOURCES/postfix-3.5.8-makedefs.patch
delete mode 100644 SOURCES/postfix-3.5.8-whitespace-name-fix.patch
delete mode 100644 SOURCES/postfix.aliasesdb
rename SOURCES/pflogsumm-1.1.5-datecalc.patch => pflogsumm-1.1.5-datecalc.patch (100%)
rename SOURCES/pflogsumm-1.1.5-ipv6-warnings-fix.patch => pflogsumm-1.1.5-ipv6-warnings-fix.patch (100%)
rename SOURCES/pflogsumm-1.1.5-syslog-name-underscore-fix.patch => pflogsumm-1.1.5-syslog-name-underscore-fix.patch (100%)
rename SOURCES/postfix-3.3.3-alternatives.patch => postfix-3.3.3-alternatives.patch (100%)
rename SOURCES/postfix-3.4.0-files.patch => postfix-3.4.0-files.patch (100%)
rename SOURCES/postfix-3.4.4-chroot-example-fix.patch => postfix-3.4.4-chroot-example-fix.patch (100%)
rename SOURCES/postfix-3.5.0-config.patch => postfix-3.8.0-config.patch (90%)
rename SOURCES/postfix-3.4.0-large-fs.patch => postfix-3.8.0-large-fs.patch (92%)
create mode 100644 postfix-3.8.5-openssl-no-engine.patch
rename SOURCES/postfix-chroot-update => postfix-chroot-update (100%)
create mode 100644 postfix-etc-init.d-postfix
rename SOURCES/postfix-pam.conf => postfix-pam.conf (100%)
rename SOURCES/postfix-sasl.conf => postfix-sasl.conf (100%)
create mode 100644 postfix.aliasesdb
rename SOURCES/postfix.service => postfix.service (100%)
rename SPECS/postfix.spec => postfix.spec (79%)
create mode 100644 postfix.sysusers
create mode 100644 sources
diff --git a/.gitignore b/.gitignore
index e27edc8..8d56b58 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
-SOURCES/pflogsumm-1.1.5.tar.gz
-SOURCES/postfix-3.5.8.tar.gz
+pflogsumm-1.1.5.tar.gz
+postfix-3.8.5.tar.gz
diff --git a/.postfix.metadata b/.postfix.metadata
deleted file mode 100644
index 32c6f41..0000000
--- a/.postfix.metadata
+++ /dev/null
@@ -1,2 +0,0 @@
-d18daa19d725e64c2b7e6c8da458b2d563272645 SOURCES/pflogsumm-1.1.5.tar.gz
-1dfb10729498be5d387dc730117c2a845dd93ac0 SOURCES/postfix-3.5.8.tar.gz
diff --git a/SOURCES/README-Postfix-SASL-RedHat.txt b/README-Postfix-SASL-RedHat.txt
similarity index 100%
rename from SOURCES/README-Postfix-SASL-RedHat.txt
rename to README-Postfix-SASL-RedHat.txt
diff --git a/SOURCES/README-RedHat.txt b/SOURCES/README-RedHat.txt
deleted file mode 100644
index 713eaf6..0000000
--- a/SOURCES/README-RedHat.txt
+++ /dev/null
@@ -1,65 +0,0 @@
-This Postfix build behaves differently from the upstream postfix-3.5.8.
-It's because in RHEL-8 backward compatibility is kept to postfix-3.3.1.
-
-For the upstream postfix-3.5.8 behavior either run the following commands:
-
-# postconf info_log_address_format=external
-# postconf smtpd_discard_ehlo_keywords=
-# postconf rhel_ipv6_normalize=yes
-
-Or go through the following steps:
-
-1. Change the configuration option 'info_log_address_format' to 'external'.
-In RHEL-8 it's by default set to 'internal' to mitigate [Incompat 20191109].
-
-2. Change the configuration option 'smtpd_discard_ehlo_keywords' to ''.
-In RHEL-8 it's by default set to 'chunking' to mitigate [Incompat 20180826].
-
-3. Add RHEL-8 specific configuration option 'rhel_ipv6_normalize' and set it
-to 'yes'. In RHEL-8 this option was added to mitigate [Incompat 20190427].
-
-Details from the upstream RELEASE_NOTES:
-
-[Incompat 20191109]
-Postfix daemon processes now log the from= and
-to= addresses in external (quoted) form in non-debug logging (info,
-warning, etc.). This means that when an address localpart contains
-spaces or other special characters, the localpart will be quoted,
-for example:
-
- from=<"name with spaces"@example.com>
-
-Older Postfix versions would log the internal (unquoted) form:
-
- from=
-
-The external and internal forms are identical for the vast majority
-of email addresses that contain no spaces or other special characters
-in the localpart.
-
-Specify "info_log_address_format = internal" for backwards
-compatibility.
-
-The logging in external form is consistent with the address form
-that Postfix 3.2 and later prefer for table lookups. It is therefore
-the more useful form for non-debug logging.
-
-[Incompat 20180826]
-The Postfix SMTP server announces CHUNKING (BDAT
-command) by default. In the unlikely case that this breaks some
-important remote SMTP client, disable the feature as follows:
-
-/etc/postfix/main.cf:
- # The logging alternative:
- smtpd_discard_ehlo_keywords = chunking
- # The non-logging alternative:
- smtpd_discard_ehlo_keywords = chunking, silent_discard
-
-See BDAT_README for more.
-
-[Incompat 20190427]
-Postfix now normalizes IP addresses received
-with XCLIENT, XFORWARD, or with the HaProxy protocol, for consistency
-with direct connections to Postfix. This may change the appearance
-of logging, and the way that check_client_access will match subnets
-of an IPv6 address.
diff --git a/SOURCES/postfix-3.5.8-SRV-resolve.patch b/SOURCES/postfix-3.5.8-SRV-resolve.patch
deleted file mode 100644
index 88a388e..0000000
--- a/SOURCES/postfix-3.5.8-SRV-resolve.patch
+++ /dev/null
@@ -1,1586 +0,0 @@
-commit 4b486868473462f9b65cc3ad44c48c2e68ee45ee
-Author: Tomas Korbar
-Date: Wed May 17 13:17:30 2023 +0200
-
- Backport SRV record resolution feature
-
-diff --git a/mantools/postlink b/mantools/postlink
-index 46f187e..f738fd3 100755
---- a/mantools/postlink
-+++ b/mantools/postlink
-@@ -1128,6 +1128,10 @@ while (<>) {
- s;\bpostlog_service_name\b;$&;g;
- s;\bpostlogd_watchdog_timeout\b;$&;g;
-
-+ s;\buse_srv_lookup\b;$&;g;
-+ s;\ballow_srv_lookup_fallback\b;$&;g;
-+ s;\bignore_srv_lookup_error\b;$&;g;
-+
- # Service-defined parameters...
-
- s;\bpolicy_time_limit\b;$&;g;
-diff --git a/proto/postconf.proto b/proto/postconf.proto
-index 3d53657..29d0aa5 100644
---- a/proto/postconf.proto
-+++ b/proto/postconf.proto
-@@ -17698,3 +17698,111 @@ with quotes and backslashes. An attacker should not be able to use
- such games to circumvent Postfix access policies.
-
- This feature is available in Postfix 3.5 and later.
-+
-+
-+%PARAM use_srv_lookup
-+
-+ Enables discovery for the specified service(s) using DNS SRV
-+records. For example, with "use_srv_lookup = submission" and
-+"relayhost = example.com:submission", the Postfix SMTP client will
-+look up DNS SRV records for _submission._tcp.example.com, and will
-+relay email through the hosts and ports that are specified with
-+those records. See RFC 2782 for details of the host selection
-+process.
-+
-+ Specify zero or more service names separated by comma and/or
-+whitespace. Any name in the services(5) database may be specified,
-+though in practice only submission, submissions, and smtp make
-+sense.
-+
-+ When SRV record lookup is enabled with use_srv_lookup, you can
-+enclose a domain name in "[]" to force IP address lookup instead
-+of SRV record lookup.
-+
-+ Example 1: MUA-to-MTA submission using SRV record lookup for
-+the "submission" service for domain "example.com". This uses the
-+default SMTP delivery agent with STARTTLS, and looks up SRV records
-+for "_submission._tcp.example.com".
-+
-+
-+/etc/postfix/main.cf:
-+ use_srv_lookup = submission
-+ relayhost = example.com:submission
-+ smtp_tls_security_level = may
-+ ...see SASL_README for sasl configuration...
-+
-+
-+ Example 2: MUA-to-MTA submission using SRV record lookup for
-+the "submissions" service for domain "example.org". This uses a
-+dedicated SMTP delivery agent (smtp-wraptls) with tls_wrappermode
-+turned on, and looks up SRV records for "_submissions._tcp.example.org".
-+
-+
-+ Note: specify the older name "smtps" instead of "submissions"
-+when a provider has DNS SRV records like "_smtps._tcp.example.org"
-+instead of "_submissions._tcp.example.org".
-+
-+
-+/etc/postfix/main.cf:
-+ use_srv_lookup = submissions
-+ default_transport = smtp-wraptls:example.org:submissions
-+ ...see SASL_README for sasl configuration...
-+
-+
-+
-+/etc/postfix/master.cf:
-+ smtp-wraptls unix ... ... ... ... ... smtp
-+ -o { smtp_tls_wrappermode = yes }
-+ -o { smtp_tls_security_level = encrypt }
-+
-+
-+ Example 3: Sender-dependent selection for a combination of
-+MUA-to-MTA submission services. This combines examples 1 and 2 with
-+examples of how to disable SRV and look up IP address records for
-+"smtp-relay.example.net" and "smtp-relay.other.example". Again,
-+specify the older name "smtps" instead of "submissions" when a
-+provider has DNS SRV records like "_smtps._tcp.example.org" instead
-+of "_submissions._tcp.example.org".
-+
-+
-+/etc/postfix/main.cf:
-+ use_srv_lookup = submission, submissions
-+ sender_dependent_default_transport_maps = inline:{
-+ # Destinations that support SRV record lookup.
-+ { user1@example.com = smtp:example.com:submission }
-+ { user2@example.org = smtp-wraptls:example.org:submissions }
-+ # Use [destination] to force IP address lookups.
-+ { user3@example.net = smtp:[smtp-relay.example.net]:submission }
-+ { user4@other.example =
-+ smtp-wraptls:[smtp-relay.other.example]:submissions } }
-+ ...see SASL_README for sasl configuration...
-+
-+
-+ Example 4: MTA-to-MTA traffic, using SRV record lookup for the
-+SMTP service. This is useful for Postfix tests, and may be useful
-+in environments where ports are dynamically assigned to servers.
-+
-+
-+
-+/etc/postfix/main.cf:
-+ use_srv_lookup = smtp
-+ # Fall back to MX record lookup when SRV records are unavailable.
-+ #allow_srv_lookup_fallback = yes
-+ #ignore_srv_lookup_error = yes
-+
-+
-+ This feature was backported from Postfix 3.8.
-+
-+%PARAM ignore_srv_lookup_error no
-+
-+ When SRV record lookup fails, fall back to MX or IP address
-+lookup as if SRV record lookup was not enabled.
-+
-+ This feature was backported from Postfix 3.8.
-+
-+%PARAM allow_srv_lookup_fallback no
-+
-+ When SRV record lookup fails or no SRV record exists, fall back
-+to MX or IP address lookup as if SRV record lookup was not enabled.
-+
-+
This feature was backported from Postfix 3.8.
-diff --git a/src/dns/dns.h b/src/dns/dns.h
-index b8c4c4a..aac3ca9 100644
---- a/src/dns/dns.h
-+++ b/src/dns/dns.h
-@@ -147,10 +147,12 @@ typedef struct DNS_RR {
- unsigned short class; /* C_IN, etc. */
- unsigned int ttl; /* always */
- unsigned int dnssec_valid; /* DNSSEC validated */
-- unsigned short pref; /* T_MX only */
-+ unsigned short pref; /* T_MX and T_SRV record related */
-+ unsigned short weight; /* T_SRV related, defined in rfc2782 */
-+ unsigned short port; /* T_SRV related, defined in rfc2782 */
- struct DNS_RR *next; /* linkage */
- size_t data_len; /* actual data size */
-- char data[1]; /* actually a bunch of data */
-+ char *data; /* a bunch of data */
- } DNS_RR;
-
- /*
-@@ -172,14 +174,29 @@ extern char *dns_strrecord(VSTRING *, DNS_RR *);
- /*
- * dns_rr.c
- */
-+#define DNS_RR_NOPREF (0)
-+#define DNS_RR_NOWEIGHT (0)
-+#define DNS_RR_NOPORT (0)
-+
-+#define dns_rr_create_noport(qname, rname, type, class, ttl, pref, data, \
-+ data_len) \
-+ dns_rr_create((qname), (rname), (type), (class), (ttl), \
-+ (pref), DNS_RR_NOWEIGHT, DNS_RR_NOPORT, (data), (data_len))
-+
-+#define dns_rr_create_nopref(qname, rname, type, class, ttl, data, data_len) \
-+ dns_rr_create_noport((qname), (rname), (type), (class), (ttl), \
-+ DNS_RR_NOPREF, (data), (data_len))
-+
- extern DNS_RR *dns_rr_create(const char *, const char *,
- ushort, ushort,
- unsigned, unsigned,
-+ unsigned, unsigned,
- const char *, size_t);
- extern void dns_rr_free(DNS_RR *);
- extern DNS_RR *dns_rr_copy(DNS_RR *);
- extern DNS_RR *dns_rr_append(DNS_RR *, DNS_RR *);
- extern DNS_RR *dns_rr_sort(DNS_RR *, int (*) (DNS_RR *, DNS_RR *));
-+extern DNS_RR *dns_srv_rr_sort(DNS_RR *);
- extern int dns_rr_compare_pref_ipv6(DNS_RR *, DNS_RR *);
- extern int dns_rr_compare_pref_ipv4(DNS_RR *, DNS_RR *);
- extern int dns_rr_compare_pref_any(DNS_RR *, DNS_RR *);
-@@ -278,8 +295,9 @@ extern int dns_lookup_rv(const char *, unsigned, DNS_RR **, VSTRING *,
- * Below is the precedence order. The order between DNS_RETRY and DNS_NOTFOUND
- * is arbitrary.
- */
--#define DNS_RECURSE (-7) /* internal only: recursion needed */
--#define DNS_NOTFOUND (-6) /* query ok, data not found */
-+#define DNS_RECURSE (-8) /* internal only: recursion needed */
-+#define DNS_NOTFOUND (-7) /* query ok, data not found */
-+#define DNS_NULLSRV (-6) /* query ok, service unavailable */
- #define DNS_NULLMX (-5) /* query ok, service unavailable */
- #define DNS_FAIL (-4) /* query failed, don't retry */
- #define DNS_INVAL (-3) /* query ok, malformed reply */
-diff --git a/src/dns/dns_lookup.c b/src/dns/dns_lookup.c
-index 11c9281..1aa97a4 100644
---- a/src/dns/dns_lookup.c
-+++ b/src/dns/dns_lookup.c
-@@ -688,6 +688,8 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
- int comp_len;
- ssize_t data_len;
- unsigned pref = 0;
-+ unsigned weight = 0;
-+ unsigned port = 0;
- unsigned char *src;
- unsigned char *dst;
- int ch;
-@@ -713,6 +715,18 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
- return (DNS_INVAL);
- data_len = strlen(temp) + 1;
- break;
-+ case T_SRV:
-+ GETSHORT(pref, pos);
-+ GETSHORT(weight, pos);
-+ GETSHORT(port, pos);
-+ if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
-+ return (DNS_RETRY);
-+ if (*temp == 0)
-+ return (DNS_NULLSRV);
-+ if (!valid_rr_name(temp, "resource data", fixed->type, reply))
-+ return (DNS_INVAL);
-+ data_len = strlen(temp) + 1;
-+ break;
- case T_MX:
- GETSHORT(pref, pos);
- if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
-@@ -808,7 +822,7 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
- break;
- }
- *list = dns_rr_create(orig_name, rr_name, fixed->type, fixed->class,
-- fixed->ttl, pref, tempbuf, data_len);
-+ fixed->ttl, pref, weight, port, tempbuf, data_len);
- return (DNS_OK);
- }
-
-@@ -906,7 +920,7 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
- resource_found++;
- rr->dnssec_valid = *maybe_secure ? reply->dnssec_ad : 0;
- *rrlist = dns_rr_append(*rrlist, rr);
-- } else if (status == DNS_NULLMX) {
-+ } else if (status == DNS_NULLMX || status == DNS_NULLSRV) {
- CORRUPT(status); /* TODO: use better name */
- } else if (not_found_status != DNS_RETRY)
- not_found_status = status;
-@@ -1032,6 +1046,12 @@ int dns_lookup_x(const char *name, unsigned type, unsigned flags,
- name);
- SET_H_ERRNO(NO_DATA);
- return (status);
-+ case DNS_NULLSRV:
-+ if (why)
-+ vstring_sprintf(why, "Domain %s does not support SRV requests",
-+ name);
-+ SET_H_ERRNO(NO_DATA);
-+ return (status);
- case DNS_OK:
- if (rrlist && dns_rr_filter_maps) {
- if (dns_rr_filter_execute(rrlist) < 0) {
-diff --git a/src/dns/dns_rr.c b/src/dns/dns_rr.c
-index b550788..15b5dee 100644
---- a/src/dns/dns_rr.c
-+++ b/src/dns/dns_rr.c
-@@ -7,13 +7,15 @@
- /* #include
- /*
- /* DNS_RR *dns_rr_create(qname, rname, type, class, ttl, preference,
--/* data, data_len)
-+/* weight, port, data, data_len)
- /* const char *qname;
- /* const char *rname;
- /* unsigned short type;
- /* unsigned short class;
- /* unsigned int ttl;
- /* unsigned preference;
-+/* unsigned weight;
-+/* unsigned port;
- /* const char *data;
- /* size_t data_len;
- /*
-@@ -49,6 +51,30 @@
- /* DNS_RR *dns_rr_remove(list, record)
- /* DNS_RR *list;
- /* DNS_RR *record;
-+/*
-+/* DNS_RR *dns_srv_rr_sort(list)
-+/* DNS_RR *list;
-+/* AUXILIARY FUNCTIONS
-+/* DNS_RR *dns_rr_create_nopref(qname, rname, type, class, ttl,
-+/* data, data_len)
-+/* const char *qname;
-+/* const char *rname;
-+/* unsigned short type;
-+/* unsigned short class;
-+/* unsigned int ttl;
-+/* const char *data;
-+/* size_t data_len;
-+/*
-+/* DNS_RR *dns_rr_create_noport(qname, rname, type, class, ttl,
-+/* preference, data, data_len)
-+/* const char *qname;
-+/* const char *rname;
-+/* unsigned short type;
-+/* unsigned short class;
-+/* unsigned int ttl;
-+/* unsigned preference;
-+/* const char *data;
-+/* size_t data_len;
- /* DESCRIPTION
- /* The routines in this module maintain memory for DNS resource record
- /* information, and maintain lists of DNS resource records.
-@@ -56,10 +82,14 @@
- /* dns_rr_create() creates and initializes one resource record.
- /* The \fIqname\fR field specifies the query name.
- /* The \fIrname\fR field specifies the reply name.
--/* \fIpreference\fR is used for MX records; \fIdata\fR is a null
-+/* \fIpreference\fR is used for MX and SRV records; \fIweight\fR
-+/* and \fIport\fR are used for SRV records; \fIdata\fR is a null
- /* pointer or specifies optional resource-specific data;
- /* \fIdata_len\fR is the amount of resource-specific data.
- /*
-+/* dns_rr_create_nopref() and dns_rr_create_noport() are convenience
-+/* wrappers around dns_rr_create() that take fewer arguments.
-+/*
- /* dns_rr_free() releases the resource used by of zero or more
- /* resource records.
- /*
-@@ -81,6 +111,9 @@
- /* dns_rr_remove() removes the specified record from the specified list.
- /* The updated list is the result value.
- /* The record MUST be a list member.
-+/*
-+/* dns_srv_rr_sort() sorts a list of SRV records according to
-+/* their priority and weight as described in RFC 2782.
- /* LICENSE
- /* .ad
- /* .fi
-@@ -113,11 +146,15 @@
- DNS_RR *dns_rr_create(const char *qname, const char *rname,
- ushort type, ushort class,
- unsigned int ttl, unsigned pref,
-+ unsigned weight, unsigned port,
- const char *data, size_t data_len)
- {
- DNS_RR *rr;
-
-- rr = (DNS_RR *) mymalloc(sizeof(*rr) + data_len - 1);
-+ /*
-+ * Note: if this function is changed, update dns_rr_copy().
-+ */
-+ rr = (DNS_RR *) mymalloc(sizeof(*rr));
- rr->qname = mystrdup(qname);
- rr->rname = mystrdup(rname);
- rr->type = type;
-@@ -125,8 +162,14 @@ DNS_RR *dns_rr_create(const char *qname, const char *rname,
- rr->ttl = ttl;
- rr->dnssec_valid = 0;
- rr->pref = pref;
-- if (data && data_len > 0)
-+ rr->weight = weight;
-+ rr->port = port;
-+ if (data_len != 0) {
-+ rr->data = mymalloc(data_len);
- memcpy(rr->data, data, data_len);
-+ } else {
-+ rr->data = 0;
-+ }
- rr->data_len = data_len;
- rr->next = 0;
- return (rr);
-@@ -141,6 +184,8 @@ void dns_rr_free(DNS_RR *rr)
- dns_rr_free(rr->next);
- myfree(rr->qname);
- myfree(rr->rname);
-+ if (rr->data)
-+ myfree(rr->data);
- myfree((void *) rr);
- }
- }
-@@ -149,16 +194,17 @@ void dns_rr_free(DNS_RR *rr)
-
- DNS_RR *dns_rr_copy(DNS_RR *src)
- {
-- ssize_t len = sizeof(*src) + src->data_len - 1;
- DNS_RR *dst;
-
- /*
-- * Combine struct assignment and data copy in one block copy operation.
-+ * Note: struct copy, because dns_rr_create() would not copy all fields.
- */
-- dst = (DNS_RR *) mymalloc(len);
-- memcpy((void *) dst, (void *) src, len);
-+ dst = (DNS_RR *) mymalloc(sizeof(*dst));
-+ *dst = *src;
- dst->qname = mystrdup(src->qname);
- dst->rname = mystrdup(src->rname);
-+ if (dst->data)
-+ dst->data = mymemdup(src->data, src->data_len);
- dst->next = 0;
- return (dst);
- }
-@@ -247,6 +293,12 @@ DNS_RR *dns_rr_sort(DNS_RR *list, int (*compar) (DNS_RR *, DNS_RR *))
- int len;
- int i;
-
-+ /*
-+ * Avoid mymalloc() panic.
-+ */
-+ if (list == 0)
-+ return (list);
-+
- /*
- * Save state and initialize.
- */
-@@ -293,6 +345,12 @@ DNS_RR *dns_rr_shuffle(DNS_RR *list)
- int i;
- int r;
-
-+ /*
-+ * Avoid mymalloc() panic.
-+ */
-+ if (list == 0)
-+ return (list);
-+
- /*
- * Build linear array with pointers to each list element.
- */
-@@ -345,3 +403,141 @@ DNS_RR *dns_rr_remove(DNS_RR *list, DNS_RR *record)
- }
- return (list);
- }
-+
-+/* weight_order - sort equal-priority records by weight */
-+
-+static void weight_order(DNS_RR **array, int count)
-+{
-+ int unordered_weights;
-+ int i;
-+
-+ /*
-+ * Compute the sum of record weights. If weights are not supplied then
-+ * this function would be a noop. In fact this would be a noop when all
-+ * weights have the same value, whether that weight is zero or not. There
-+ * is no need to give special treatment to zero weights.
-+ */
-+ for (unordered_weights = 0, i = 0; i < count; i++)
-+ unordered_weights += array[i]->weight;
-+ if (unordered_weights == 0)
-+ return;
-+
-+ /*
-+ * The record ordering code below differs from RFC 2782 when the input
-+ * contains a mix of zero and non-zero weights: the code below does not
-+ * give special treatment to zero weights. Instead, it treats a zero
-+ * weight just like any other small weight. Fewer special cases make for
-+ * code that is simpler and more robust.
-+ */
-+ for (i = 0; i < count - 1; i++) {
-+ int running_sum;
-+ int threshold;
-+ int k;
-+ DNS_RR *temp;
-+
-+ /*
-+ * Choose a random threshold [0..unordered_weights] inclusive.
-+ */
-+ threshold = myrand() % (unordered_weights + 1);
-+
-+ /*
-+ * Move the first record with running_sum >= threshold to the ordered
-+ * list, and update unordered_weights.
-+ */
-+ for (running_sum = 0, k = i; k < count; k++) {
-+ running_sum += array[k]->weight;
-+ if (running_sum >= threshold) {
-+ unordered_weights -= array[k]->weight;
-+ temp = array[i];
-+ array[i] = array[k];
-+ array[k] = temp;
-+ break;
-+ }
-+ }
-+ }
-+}
-+
-+/* dns_srv_rr_sort - sort resource record list */
-+
-+DNS_RR *dns_srv_rr_sort(DNS_RR *list)
-+{
-+ int (*saved_user) (DNS_RR *, DNS_RR *);
-+ DNS_RR **rr_array;
-+ DNS_RR *rr;
-+ int len;
-+ int i;
-+ int r;
-+ int cur_pref;
-+ int left_bound; /* inclusive */
-+ int right_bound; /* non-inclusive */
-+
-+ /*
-+ * Avoid mymalloc() panic, or rr_array[0] fence-post error.
-+ */
-+ if (list == 0)
-+ return (list);
-+
-+ /*
-+ * Save state and initialize.
-+ */
-+ saved_user = dns_rr_sort_user;
-+ dns_rr_sort_user = dns_rr_compare_pref_any;
-+
-+ /*
-+ * Build linear array with pointers to each list element.
-+ */
-+ for (len = 0, rr = list; rr != 0; len++, rr = rr->next)
-+ /* void */ ;
-+ rr_array = (DNS_RR **) mymalloc(len * sizeof(*rr_array));
-+ for (len = 0, rr = list; rr != 0; len++, rr = rr->next)
-+ rr_array[len] = rr;
-+
-+ /*
-+ * Shuffle resource records. Every element has an equal chance of landing
-+ * in slot 0. After that every remaining element has an equal chance of
-+ * landing in slot 1, ... This is exactly n! states for n! permutations.
-+ */
-+ for (i = 0; i < len - 1; i++) {
-+ r = i + (myrand() % (len - i)); /* Victor&Son */
-+ rr = rr_array[i];
-+ rr_array[i] = rr_array[r];
-+ rr_array[r] = rr;
-+ }
-+
-+ /* First order the records by preference. */
-+ qsort((void *) rr_array, len, sizeof(*rr_array), dns_rr_sort_callback);
-+
-+ /*
-+ * Walk through records and sort the records in every same-preference
-+ * partition according to their weight. Note that left_bound is
-+ * inclusive, and that right-bound is non-inclusive.
-+ */
-+ left_bound = 0;
-+ cur_pref = rr_array[left_bound]->pref; /* assumes len > 0 */
-+
-+ for (right_bound = 1; /* see below */ ; right_bound++) {
-+ if (right_bound == len || rr_array[right_bound]->pref != cur_pref) {
-+ if (right_bound - left_bound > 1)
-+ weight_order(rr_array + left_bound, right_bound - left_bound);
-+ if (right_bound == len)
-+ break;
-+ left_bound = right_bound;
-+ cur_pref = rr_array[left_bound]->pref;
-+ }
-+ }
-+
-+ /*
-+ * Fix the links.
-+ */
-+ for (i = 0; i < len - 1; i++)
-+ rr_array[i]->next = rr_array[i + 1];
-+ rr_array[i]->next = 0;
-+ list = rr_array[0];
-+
-+ /*
-+ * Cleanup.
-+ */
-+ myfree((void *) rr_array);
-+ dns_rr_sort_user = saved_user;
-+ return (list);
-+}
-diff --git a/src/dns/dns_sa_to_rr.c b/src/dns/dns_sa_to_rr.c
-index 6b9efcc..b5dee20 100644
---- a/src/dns/dns_sa_to_rr.c
-+++ b/src/dns/dns_sa_to_rr.c
-@@ -55,14 +55,14 @@ 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, hostname, T_A, C_IN, DUMMY_TTL, pref,
-- (char *) &SOCK_ADDR_IN_ADDR(sa),
-- sizeof(SOCK_ADDR_IN_ADDR(sa))));
-+ return (dns_rr_create_noport(hostname, 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, hostname, T_AAAA, C_IN, DUMMY_TTL, pref,
-- (char *) &SOCK_ADDR_IN6_ADDR(sa),
-- sizeof(SOCK_ADDR_IN6_ADDR(sa))));
-+ return (dns_rr_create_noport(hostname, hostname, T_AAAA, C_IN, DUMMY_TTL,
-+ pref, (char *) &SOCK_ADDR_IN6_ADDR(sa),
-+ sizeof(SOCK_ADDR_IN6_ADDR(sa))));
- #endif
- } else {
- errno = EAFNOSUPPORT;
-@@ -121,7 +121,7 @@ int main(int argc, char **argv)
- resv[len++] = res;
- qsort((void *) resv, len, sizeof(*resv), compare_family);
- for (n = 0; n < len; n++) {
-- if ((rr = dns_sa_to_rr(argv[0], 0, resv[n]->ai_addr)) == 0)
-+ if ((rr = dns_sa_to_rr(argv[0], DNS_RR_NOPREF, resv[n]->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");
-diff --git a/src/dns/dns_strrecord.c b/src/dns/dns_strrecord.c
-index 6b8e989..1e3b743 100644
---- a/src/dns/dns_strrecord.c
-+++ b/src/dns/dns_strrecord.c
-@@ -80,6 +80,10 @@ char *dns_strrecord(VSTRING *buf, DNS_RR *rr)
- case T_MX:
- vstring_sprintf_append(buf, "%u %s.", rr->pref, rr->data);
- break;
-+ case T_SRV:
-+ vstring_sprintf_append(buf, "%u %u %u %s.", rr->pref, rr->weight,
-+ rr->port, rr->data);
-+ break;
- case T_TLSA:
- if (rr->data_len >= 3) {
- uint8_t *ip = (uint8_t *) rr->data;
-diff --git a/src/dns/dns_strtype.c b/src/dns/dns_strtype.c
-index 70e59ac..7eebe3c 100644
---- a/src/dns/dns_strtype.c
-+++ b/src/dns/dns_strtype.c
-@@ -180,6 +180,9 @@ static struct dns_type_map dns_type_map[] = {
- #ifdef T_ANY
- T_ANY, "ANY",
- #endif
-+#ifdef T_SRV
-+ T_SRV, "SRV",
-+#endif
- };
-
- /* dns_strtype - translate DNS query type to string */
-diff --git a/src/global/mail_params.h b/src/global/mail_params.h
-index 74459d9..f8bb550 100644
---- a/src/global/mail_params.h
-+++ b/src/global/mail_params.h
-@@ -4206,6 +4206,21 @@ extern char *var_info_log_addr_form;
- #define DEF_RHEL_IPV6_NORMALIZE 0
- extern bool var_rhel_ipv6_normalize;
-
-+ /*
-+ * SRV lookup support.
-+ */
-+#define VAR_USE_SRV_LOOKUP "use_srv_lookup"
-+#define DEF_USE_SRV_LOOKUP ""
-+extern char *var_use_srv_lookup;
-+
-+#define VAR_IGN_SRV_LOOKUP_ERR "ignore_srv_lookup_error"
-+#define DEF_IGN_SRV_LOOKUP_ERR 0
-+extern bool var_ign_srv_lookup_err;
-+
-+#define VAR_ALLOW_SRV_FALLBACK "allow_srv_lookup_fallback"
-+#define DEF_ALLOW_SRV_FALLBACK 0
-+extern bool var_allow_srv_fallback;
-+
- /* LICENSE
- /* .ad
- /* .fi
-diff --git a/src/posttls-finger/posttls-finger.c b/src/posttls-finger/posttls-finger.c
-index a3a9946..b428cb3 100644
---- a/src/posttls-finger/posttls-finger.c
-+++ b/src/posttls-finger/posttls-finger.c
-@@ -236,6 +236,8 @@
- /* is encountered, up to 5 times or as specified with the \fB-m\fR option.
- /* By default reconnection is disabled, specify a positive delay to
- /* enable this behavior.
-+/* .IP "\fB-R\fR"
-+/* Use SRV lookup instead of MX.
- /* .IP "\fB-s \fIservername\fR"
- /* The server name to send with the TLS Server Name Indication (SNI)
- /* extension. When the server has DANE TLSA records, this parameter
-@@ -466,6 +468,7 @@ typedef struct STATE {
- DNS_RR *mx; /* MX RRset qname, rname, valid */
- int pass; /* Pass number, 2 for reconnect */
- int nochat; /* disable chat logging */
-+ int dosrv; /* look up SRV records instead of MX */
- char *helo; /* Server name from EHLO reply */
- DSN_BUF *why; /* SMTP-style error message */
- VSTRING *buffer; /* Response buffer */
-@@ -1150,7 +1153,7 @@ static VSTREAM *connect_addr(STATE *state, DNS_RR *addr)
- /* addr_one - address lookup for one host name */
-
- static DNS_RR *addr_one(STATE *state, DNS_RR *addr_list, const char *host,
-- int res_opt, unsigned pref)
-+ int res_opt, unsigned pref, unsigned port)
- {
- static const char *myname = "addr_one";
- DSN_BUF *why = state->why;
-@@ -1173,6 +1176,8 @@ static DNS_RR *addr_one(STATE *state, DNS_RR *addr_list, const char *host,
- 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->pref = pref;
-+ addr->port = port;
- addr_list = dns_rr_append(addr_list, addr);
- freeaddrinfo(res0);
- return (addr_list);
-@@ -1189,8 +1194,10 @@ static DNS_RR *addr_one(STATE *state, DNS_RR *addr_list, const char *host,
- why->reason, DNS_REQ_FLAG_NONE,
- proto_info->dns_atype_list)) {
- case DNS_OK:
-- for (rr = addr; rr; rr = rr->next)
-+ for (rr = addr; rr; rr = rr->next) {
- rr->pref = pref;
-+ rr->port = port;
-+ }
- addr_list = dns_rr_append(addr_list, addr);
- return (addr_list);
- default:
-@@ -1277,15 +1284,15 @@ static DNS_RR *mx_addr_list(STATE *state, DNS_RR *mx_names)
- #endif
-
- for (rr = mx_names; rr; rr = rr->next) {
-- if (rr->type != T_MX)
-+ if (rr->type != T_MX && rr->type != T_SRV)
- msg_panic("%s: bad resource type: %d", myname, rr->type);
- addr_list = addr_one(state, addr_list, (char *) rr->data, res_opt,
-- rr->pref);
-+ rr->pref, rr->port);
- }
- return (addr_list);
- }
-
--/* smtp_domain_addr - mail exchanger address lookup */
-+/* domain_addr - mail exchanger address lookup */
-
- static DNS_RR *domain_addr(STATE *state, char *domain)
- {
-@@ -1350,6 +1357,74 @@ static DNS_RR *domain_addr(STATE *state, char *domain)
- return (addr_list);
- }
-
-+/* service_addr - mail exchanger address lookup */
-+
-+static DNS_RR *service_addr(STATE *state, const char *domain,
-+ const char *service)
-+{
-+ VSTRING *srv_qname = vstring_alloc(100);
-+ char *str_srv_qname;
-+ DNS_RR *srv_names;
-+ DNS_RR *addr_list = 0;
-+ int r = 0; /* Resolver flags */
-+ const char *aname;
-+
-+ dsb_reset(state->why);
-+
-+#if (RES_USE_DNSSEC != 0) && (RES_USE_EDNS0 != 0)
-+ r |= RES_USE_DNSSEC;
-+#endif
-+
-+ vstring_sprintf(srv_qname, "_%s._tcp.%s", service, domain);
-+ str_srv_qname = STR(srv_qname);
-+
-+ /*
-+ * IDNA support.
-+ */
-+#ifndef NO_EAI
-+ if (!allascii(str_srv_qname)
-+ && (aname = midna_domain_to_ascii(str_srv_qname)) != 0) {
-+ msg_info("%s asciified to %s", str_srv_qname, aname);
-+ } else
-+#endif
-+ aname = str_srv_qname;
-+
-+ switch (dns_lookup(aname, T_SRV, r, &srv_names, (VSTRING *) 0,
-+ state->why->reason)) {
-+ default:
-+ dsb_status(state->why, "4.4.3");
-+ break;
-+ case DNS_INVAL:
-+ dsb_status(state->why, "5.4.4");
-+ break;
-+ case DNS_NULLMX:
-+ dsb_status(state->why, "5.1.0");
-+ break;
-+ case DNS_FAIL:
-+ dsb_status(state->why, "5.4.3");
-+ break;
-+ case DNS_OK:
-+ /* Shuffle then sort the SRV rr records by priority and weight. */
-+ srv_names = dns_srv_rr_sort(srv_names);
-+ addr_list = mx_addr_list(state, srv_names);
-+ state->mx = dns_rr_copy(srv_names);
-+ dns_rr_free(srv_names);
-+ if (addr_list == 0) {
-+ msg_warn("no SRV host for %s has a valid address record",
-+ str_srv_qname);
-+ break;
-+ }
-+ /* TODO: sort by priority, weight, and address family preference. */
-+ break;
-+ case DNS_NOTFOUND:
-+ dsb_status(state->why, "5.4.4");
-+ break;
-+ }
-+
-+ vstring_free(srv_qname);
-+ return (addr_list);
-+}
-+
- /* host_addr - direct host lookup */
-
- static DNS_RR *host_addr(STATE *state, const char *host)
-@@ -1376,7 +1451,8 @@ static DNS_RR *host_addr(STATE *state, const char *host)
- ahost = host;
-
- #define PREF0 0
-- addr_list = addr_one(state, (DNS_RR *) 0, ahost, res_opt, PREF0);
-+#define NOPORT 0
-+ addr_list = addr_one(state, (DNS_RR *) 0, ahost, res_opt, PREF0, NOPORT);
- if (addr_list && addr_list->next) {
- addr_list = dns_rr_shuffle(addr_list);
- if (inet_proto_info()->ai_family_list[1] != 0)
-@@ -1465,7 +1541,8 @@ static int dane_host_level(STATE *state, DNS_RR *addr)
- /* parse_destination - parse host/port destination */
-
- static char *parse_destination(char *destination, char *def_service,
-- char **hostp, unsigned *portp)
-+ char **hostp, char **servicep,
-+ unsigned *portp)
- {
- char *buf = mystrdup(destination);
- char *service;
-@@ -1481,12 +1558,13 @@ static char *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, (char *) 0, &service, def_service)) != 0)
-+ if ((err = host_port(buf, hostp, (char *) 0, servicep, def_service)) != 0)
- msg_fatal("%s in server description: %s", err, destination);
-
- /*
- * Convert service to port number, network byte order.
- */
-+ service = *servicep;
- if (alldig(service)) {
- if ((port = atoi(service)) >= 65536 || port == 0)
- msg_fatal("bad network port in destination: %s", destination);
-@@ -1507,17 +1585,21 @@ static char *parse_destination(char *destination, char *def_service,
- static void connect_remote(STATE *state, char *dest)
- {
- DNS_RR *addr;
-- char *buf;
-- char *domain;
-
- /* When reconnecting use IP address of previous session */
- if (state->addr == 0) {
-+ char *buf;
-+ char *domain;
-+ char *service;
-+
- buf = parse_destination(dest, state->smtp ? "smtp" : "24",
-- &domain, &state->port);
-+ &domain, &service, &state->port);
- if (!state->nexthop)
- state->nexthop = mystrdup(domain);
- if (state->smtp == 0 || *dest == '[')
- state->addr = host_addr(state, domain);
-+ else if (state->dosrv)
-+ state->addr = service_addr(state, domain, service);
- else
- state->addr = domain_addr(state, domain);
- myfree(buf);
-@@ -1531,10 +1613,14 @@ static void connect_remote(STATE *state, char *dest)
- for (addr = state->addr; addr; addr = addr->next) {
- int level = dane_host_level(state, addr);
-
-+ if (addr->port) /* SRV port override */
-+ state->port = htons(addr->port);
-+
- if (level == TLS_LEV_INVALID
- || (state->stream = connect_addr(state, addr)) == 0) {
-- msg_info("Failed to establish session to %s via %s: %s",
-- dest, HNAME(addr), vstring_str(state->why->reason));
-+ msg_info("Failed to establish session to %s via %s:%u: %s",
-+ dest, HNAME(addr), addr->port,
-+ vstring_str(state->why->reason));
- continue;
- }
- /* We have a connection */
-@@ -1819,6 +1905,7 @@ static void parse_options(STATE *state, int argc, char *argv[])
-
- state->smtp = 1;
- state->pass = 1;
-+ state->dosrv = 0;
- state->reconnect = -1;
- state->max_reconnect = 5;
- state->wrapper_mode = 0;
-@@ -1829,7 +1916,7 @@ static void parse_options(STATE *state, int argc, char *argv[])
- memset((void *) &state->options, 0, sizeof(state->options));
- state->options.host_lookup = mystrdup("dns");
-
--#define OPTS "a:ch:o:St:T:v"
-+#define OPTS "a:ch:o:RSt:T:v"
- #ifdef USE_TLS
- #define TLSOPTS "A:Cd:fF:g:H:k:K:l:L:m:M:p:P:r:s:wX"
-
-@@ -1868,6 +1955,9 @@ static void parse_options(STATE *state, int argc, char *argv[])
- case 'o':
- override(optarg);
- break;
-+ case 'R':
-+ state->dosrv = 1;
-+ break;
- case 'S':
- state->smtp = 0;
- break;
-diff --git a/src/smtp/lmtp_params.c b/src/smtp/lmtp_params.c
-index 973cb5d..ff074cd 100644
---- a/src/smtp/lmtp_params.c
-+++ b/src/smtp/lmtp_params.c
-@@ -64,6 +64,7 @@
- VAR_LMTP_DSN_FILTER, DEF_LMTP_DSN_FILTER, &var_smtp_dsn_filter, 0, 0,
- VAR_LMTP_DNS_RE_FILTER, DEF_LMTP_DNS_RE_FILTER, &var_smtp_dns_re_filter, 0, 0,
- VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0,
-+ VAR_USE_SRV_LOOKUP, DEF_USE_SRV_LOOKUP, &var_use_srv_lookup, 0, 0,
- 0,
- };
- static const CONFIG_TIME_TABLE lmtp_time_table[] = {
-@@ -126,5 +127,7 @@
- VAR_LMTP_REC_DEADLINE, DEF_LMTP_REC_DEADLINE, &var_smtp_rec_deadline,
- VAR_LMTP_DUMMY_MAIL_AUTH, DEF_LMTP_DUMMY_MAIL_AUTH, &var_smtp_dummy_mail_auth,
- VAR_LMTP_BALANCE_INET_PROTO, DEF_LMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto,
-+ VAR_IGN_SRV_LOOKUP_ERR, DEF_IGN_SRV_LOOKUP_ERR, &var_ign_srv_lookup_err,
-+ VAR_ALLOW_SRV_FALLBACK, DEF_ALLOW_SRV_FALLBACK, &var_allow_srv_fallback,
- 0,
- };
-diff --git a/src/smtp/smtp.c b/src/smtp/smtp.c
-index 6ca2d5c..f402876 100644
---- a/src/smtp/smtp.c
-+++ b/src/smtp/smtp.c
-@@ -146,6 +146,7 @@
- /* RFC 2046 (MIME: Media Types)
- /* RFC 2554 (AUTH command)
- /* RFC 2821 (SMTP protocol)
-+/* RFC 2782 (SRV resource records)
- /* RFC 2920 (SMTP Pipelining)
- /* RFC 3207 (STARTTLS command)
- /* RFC 3461 (SMTP DSN Extension)
-@@ -330,6 +331,17 @@
- /* .IP "\fBinfo_log_address_format (external)\fR"
- /* The email address form that will be used in non-debug logging
- /* (info, warning, etc.).
-+/* .PP
-+/* Backported from Postfix version 3.8:
-+/* .IP "\fBuse_srv_lookup (empty)\fR"
-+/* Enables discovery for the specified service(s) using DNS SRV
-+/* records.
-+/* .IP "\fBignore_srv_lookup_error (no)\fR"
-+/* When SRV record lookup fails, fall back to MX or IP address
-+/* lookup as if SRV record lookup was not enabled.
-+/* .IP "\fBallow_srv_lookup_fallback (no)\fR"
-+/* When SRV record lookup fails or no SRV record exists, fall back
-+/* to MX or IP address lookup as if SRV record lookup was not enabled.
- /* MIME PROCESSING CONTROLS
- /* .ad
- /* .fi
-@@ -1046,6 +1058,9 @@ bool var_smtp_dummy_mail_auth;
- char *var_smtp_dsn_filter;
- char *var_smtp_dns_re_filter;
- bool var_smtp_balance_inet_proto;
-+char *var_use_srv_lookup;
-+bool var_ign_srv_lookup_err;
-+bool var_allow_srv_fallback;
-
- /* Special handling of 535 AUTH errors. */
- char *var_smtp_sasl_auth_cache_name;
-@@ -1068,6 +1083,7 @@ MAPS *smtp_pix_bug_maps;
- HBC_CHECKS *smtp_header_checks; /* limited header checks */
- HBC_CHECKS *smtp_body_checks; /* limited body checks */
- SMTP_CLI_ATTR smtp_cli_attr; /* parsed command-line */
-+STRING_LIST *smtp_use_srv_lookup;
-
- #ifdef USE_TLS
-
-@@ -1351,6 +1367,14 @@ static void post_init(char *unused_name, char **argv)
- * the process lifetime.
- */
- get_cli_attr(&smtp_cli_attr, argv);
-+
-+ /*
-+ * Service discovery with SRV record lookup.
-+ */
-+ if (*var_use_srv_lookup)
-+ smtp_use_srv_lookup = string_list_init(VAR_USE_SRV_LOOKUP,
-+ MATCH_FLAG_RETURN,
-+ var_use_srv_lookup);
- }
-
- /* pre_init - pre-jail initialization */
-diff --git a/src/smtp/smtp.h b/src/smtp/smtp.h
-index 281cfe4..3f4c209 100644
---- a/src/smtp/smtp.h
-+++ b/src/smtp/smtp.h
-@@ -84,6 +84,14 @@ typedef struct SMTP_ITERATOR {
- vstring_strcpy((iter)->dest, STR((iter)->saved_dest)); \
- } while (0)
-
-+#define SMTP_ITER_UPDATE_HOST(iter, _host, _addr, _rr) do { \
-+ vstring_strcpy((iter)->host, (_host)); \
-+ vstring_strcpy((iter)->addr, (_addr)); \
-+ (iter)->rr = (_rr); \
-+ if ((_rr)->port) \
-+ (iter)->port = htons((_rr)->port); /* SRV port override */ \
-+ } while (0)
-+
- /*
- * TLS Policy support.
- */
-@@ -261,6 +269,7 @@ typedef struct SMTP_STATE {
- #define SMTP_MISC_FLAG_COMPLETE_SESSION (1<<7)
- #define SMTP_MISC_FLAG_PREF_IPV6 (1<<8)
- #define SMTP_MISC_FLAG_PREF_IPV4 (1<<9)
-+#define SMTP_MISC_FLAG_FALLBACK_SRV_TO_MX (1<<10)
-
- #define SMTP_MISC_FLAG_CONN_CACHE_MASK \
- (SMTP_MISC_FLAG_CONN_LOAD | SMTP_MISC_FLAG_CONN_STORE)
-@@ -300,6 +309,8 @@ extern MAPS *smtp_generic_maps; /* make internal address valid */
- extern int smtp_ext_prop_mask; /* address externsion propagation */
- extern unsigned smtp_dns_res_opt; /* DNS query flags */
-
-+extern STRING_LIST *smtp_use_srv_lookup;/* services with SRV record lookup */
-+
- #ifdef USE_TLS
-
- extern TLS_APPL_STATE *smtp_tls_ctx; /* client-side TLS engine */
-diff --git a/src/smtp/smtp_addr.c b/src/smtp/smtp_addr.c
-index 2210ff7..7f20838 100644
---- a/src/smtp/smtp_addr.c
-+++ b/src/smtp/smtp_addr.c
-@@ -17,6 +17,15 @@
- /* char *name;
- /* int misc_flags;
- /* DSN_BUF *why;
-+/*
-+/* DNS_RR *smtp_service_addr(name, service, mxrr, misc_flags, why,
-+/* found_myself)
-+/* const char *name;
-+/* const char *service;
-+/* DNS_RR **mxrr;
-+/* int misc_flags;
-+/* DSN_BUF *why;
-+/* int *found_myself;
- /* DESCRIPTION
- /* This module implements Internet address lookups. By default,
- /* lookups are done via the Internet domain name service (DNS).
-@@ -33,6 +42,8 @@
- /* destination. If MX records were found, the rname, qname,
- /* and dnssec validation status of the MX RRset are returned
- /* via mxrr, which the caller must free with dns_rr_free().
-+/* Fallback from MX to address lookups is governed by RFC 2821,
-+/* and by local policy (var_ign_mx_lookup_err).
- /*
- /* When no mail exchanger is listed in the DNS for \fIname\fR, the
- /* request is passed to smtp_host_addr().
-@@ -44,8 +55,18 @@
- /* host. The host can be specified as a numerical Internet network
- /* address, or as a symbolic host name.
- /*
--/* Results from smtp_domain_addr() or smtp_host_addr() are
--/* destroyed by dns_rr_free(), including null lists.
-+/* smtp_service_addr() looks up addresses for hosts specified
-+/* in SRV records for the specified domain and service. This
-+/* supports the features of smtp_domain_addr() except that
-+/* the order of SRV records is determined by RFC 2782, and
-+/* that address records are not sorted by IP address family
-+/* preference. Fallback from SRV to MX or address lookups is
-+/* governed by local policy (var_ign_mx_lookup_err and
-+/* var_allow_srv_fallback).
-+/*
-+/* Results from smtp_domain_addr(), smtp_host_addr(), and
-+/* smtp_service_addr() are destroyed by dns_rr_free(), including
-+/* null lists.
- /* DIAGNOSTICS
- /* Panics: interface violations. For example, calling smtp_domain_addr()
- /* when DNS lookups are explicitly disabled.
-@@ -130,7 +151,8 @@ static void smtp_print_addr(const char *what, DNS_RR *addr_list)
- /* smtp_addr_one - address lookup for one host name */
-
- static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host, int res_opt,
-- unsigned pref, DSN_BUF *why)
-+ unsigned pref, unsigned port,
-+ DSN_BUF *why)
- {
- const char *myname = "smtp_addr_one";
- DNS_RR *addr = 0;
-@@ -153,6 +175,8 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host, int res_opt,
- if ((addr = dns_sa_to_rr(host, pref, res0->ai_addr)) == 0)
- msg_fatal("host %s: conversion error for address family "
- "%d: %m", host, res0->ai_addr->sa_family);
-+ addr->pref = pref;
-+ addr->port = port;
- addr_list = dns_rr_append(addr_list, addr);
- freeaddrinfo(res0);
- return (addr_list);
-@@ -172,8 +196,10 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host, int res_opt,
- why->reason, DNS_REQ_FLAG_NONE,
- proto_info->dns_atype_list)) {
- case DNS_OK:
-- for (rr = addr; rr; rr = rr->next)
-+ for (rr = addr; rr; rr = rr->next) {
- rr->pref = pref;
-+ rr->port = port;
-+ }
- addr_list = dns_rr_append(addr_list, addr);
- return (addr_list);
- default:
-@@ -283,10 +309,10 @@ static DNS_RR *smtp_addr_list(DNS_RR *mx_names, DSN_BUF *why)
- * tweaking the in-process resolver flags.
- */
- for (rr = mx_names; rr; rr = rr->next) {
-- if (rr->type != T_MX)
-+ if (rr->type != T_MX && rr->type != T_SRV)
- msg_panic("smtp_addr_list: bad resource type: %d", rr->type);
- addr_list = smtp_addr_one(addr_list, (char *) rr->data, res_opt,
-- rr->pref, why);
-+ rr->pref, rr->port, why);
- }
- return (addr_list);
- }
-@@ -669,7 +695,7 @@ DNS_RR *smtp_host_addr(const char *host, int misc_flags, DSN_BUF *why)
- * address to internal form. Otherwise, the host is specified by name.
- */
- #define PREF0 0
-- addr_list = smtp_addr_one((DNS_RR *) 0, ahost, res_opt, PREF0, why);
-+ addr_list = smtp_addr_one((DNS_RR *) 0, ahost, res_opt, PREF0, 0, why);
- if (addr_list
- && (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
- && smtp_find_self(addr_list) != 0) {
-@@ -691,3 +717,135 @@ DNS_RR *smtp_host_addr(const char *host, int misc_flags, DSN_BUF *why)
- smtp_print_addr(host, addr_list);
- return (addr_list);
- }
-+
-+/* smtp_service_addr - service address lookup */
-+
-+DNS_RR *smtp_service_addr(const char *name, const char *service, DNS_RR **mxrr,
-+ int misc_flags, DSN_BUF *why,
-+ int *found_myself)
-+{
-+ static VSTRING *srv_qname = 0;
-+ const char *str_srv_qname;
-+ DNS_RR *srv_names = 0;
-+ DNS_RR *addr_list = 0;
-+ DNS_RR *self = 0;
-+ unsigned best_pref;
-+ unsigned best_found;
-+ int r = 0;
-+ const char *aname;
-+ int allow_non_srv_fallback = var_allow_srv_fallback;
-+
-+ dsb_reset(why);
-+
-+ /*
-+ * Sanity check.
-+ */
-+ if (smtp_dns_support == SMTP_DNS_DISABLED)
-+ msg_panic("smtp_service_addr: DNS lookup is disabled");
-+
-+ if (smtp_dns_support == SMTP_DNS_DNSSEC) {
-+ r |= RES_USE_DNSSEC;
-+ }
-+ if (srv_qname == 0)
-+ srv_qname = vstring_alloc(100);
-+ vstring_sprintf(srv_qname, "_%s._tcp.%s", service, name);
-+ str_srv_qname = STR(srv_qname);
-+
-+ /*
-+ * IDNA support.
-+ */
-+#ifndef NO_EAI
-+ if (!allascii(str_srv_qname)
-+ && (aname = midna_domain_to_ascii(str_srv_qname)) != 0) {
-+ if (msg_verbose)
-+ msg_info("%s asciified to %s", str_srv_qname, aname);
-+ } else
-+#endif
-+ aname = str_srv_qname;
-+
-+ switch (dns_lookup(aname, T_SRV, r, &srv_names, (VSTRING *) 0,
-+ why->reason)) {
-+ default:
-+ dsb_status(why, "4.4.3");
-+ allow_non_srv_fallback |= var_ign_srv_lookup_err;
-+ break;
-+ case DNS_INVAL:
-+ dsb_status(why, "5.4.4");
-+ allow_non_srv_fallback |= var_ign_srv_lookup_err;
-+ break;
-+ case DNS_POLICY:
-+ dsb_status(why, "4.7.0");
-+ break;
-+ case DNS_FAIL:
-+ dsb_status(why, "5.4.3");
-+ allow_non_srv_fallback |= var_ign_srv_lookup_err;
-+ break;
-+ case DNS_NULLSRV:
-+ dsb_status(why, "5.1.0");
-+ break;
-+ case DNS_OK:
-+ /* Shuffle then sort the SRV rr records by priority and weight. */
-+ srv_names = dns_srv_rr_sort(srv_names);
-+ best_pref = (srv_names ? srv_names->pref : IMPOSSIBLE_PREFERENCE);
-+ addr_list = smtp_addr_list(srv_names, why);
-+ if (mxrr)
-+ *mxrr = dns_rr_copy(srv_names); /* copies one record! */
-+ dns_rr_free(srv_names);
-+ if (addr_list == 0) {
-+ msg_warn("no SRV host for %s has a valid address record",
-+ str_srv_qname);
-+ break;
-+ }
-+ /* Optional loop prevention, similar to smtp_domain_addr(). */
-+ best_found = (addr_list ? addr_list->pref : IMPOSSIBLE_PREFERENCE);
-+ if (msg_verbose)
-+ smtp_print_addr(aname, addr_list);
-+ if ((misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
-+ && (self = smtp_find_self(addr_list)) != 0) {
-+ addr_list = smtp_truncate_self(addr_list, self->pref);
-+ if (addr_list == 0) {
-+ if (best_pref != best_found) {
-+ dsb_simple(why, "4.4.4",
-+ "unable to find primary relay for %s",
-+ str_srv_qname);
-+ } else {
-+ dsb_simple(why, "5.4.6", "mail for %s loops back to myself",
-+ str_srv_qname);
-+ }
-+ }
-+ }
-+ /* TODO: sort by priority, weight, and address family preference. */
-+
-+ /* Optional address family balancing, as in smtp_domain_addr(). */
-+ if (addr_list && addr_list->next) {
-+ if (var_smtp_mxaddr_limit > 0 && var_smtp_balance_inet_proto)
-+ addr_list = smtp_balance_inet_proto(addr_list, misc_flags,
-+ var_smtp_mxaddr_limit);
-+ }
-+ break;
-+ case DNS_NOTFOUND:
-+ dsb_status(why, "5.4.4");
-+ break;
-+ }
-+
-+ /*
-+ * If permitted, fall back to non-SRV record lookups.
-+ */
-+ if (addr_list == 0 && allow_non_srv_fallback) {
-+ msg_info("skipping SRV lookup for %s: %s",
-+ str_srv_qname, STR(why->reason));
-+ if (misc_flags & SMTP_MISC_FLAG_FALLBACK_SRV_TO_MX)
-+ addr_list = smtp_domain_addr(name, mxrr, misc_flags, why,
-+ found_myself);
-+ else
-+ addr_list = smtp_host_addr(name, misc_flags, why);
-+ }
-+
-+ /*
-+ * Only if we're not falling back.
-+ */
-+ else {
-+ *found_myself |= (self != 0);
-+ }
-+ return (addr_list);
-+}
-diff --git a/src/smtp/smtp_addr.h b/src/smtp/smtp_addr.h
-index 8f20961..3d70413 100644
---- a/src/smtp/smtp_addr.h
-+++ b/src/smtp/smtp_addr.h
-@@ -18,6 +18,7 @@
- */
- extern DNS_RR *smtp_host_addr(const char *, int, DSN_BUF *);
- extern DNS_RR *smtp_domain_addr(const char *, DNS_RR **, int, DSN_BUF *, int *);
-+extern DNS_RR *smtp_service_addr(const char *, const char *, DNS_RR **, int, DSN_BUF *, int *);
-
- /* LICENSE
- /* .ad
-diff --git a/src/smtp/smtp_connect.c b/src/smtp/smtp_connect.c
-index 4d48883..4b3153f 100644
---- a/src/smtp/smtp_connect.c
-+++ b/src/smtp/smtp_connect.c
-@@ -28,7 +28,8 @@
- /* destinations may be specified as "unix:pathname", "inet:host"
- /* or "inet:host:port".
- /*
--/* With SMTP, the Internet domain name service is queried for mail
-+/* With SMTP, or with SRV record lookup enabled, the Internet
-+/* domain name service is queried for mail
- /* exchanger hosts. Quote the domain name with `[' and `]' to
- /* suppress mail exchanger lookups.
- /*
-@@ -333,7 +334,8 @@ static SMTP_SESSION *smtp_connect_sock(int sock, struct sockaddr *sa,
- /* smtp_parse_destination - parse host/port destination */
-
- static char *smtp_parse_destination(char *destination, char *def_service,
-- char **hostp, unsigned *portp)
-+ char **hostp, char **servicep,
-+ unsigned *portp)
- {
- char *buf = mystrdup(destination);
- char *service;
-@@ -349,12 +351,13 @@ 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, (char *) 0, &service, def_service)) != 0)
-+ if ((err = host_port(buf, hostp, (char *) 0, servicep, def_service)) != 0)
- msg_fatal("%s in server description: %s", err, destination);
-
- /*
- * Convert service to port number, network byte order.
- */
-+ service = *servicep;
- if (alldig(service)) {
- if ((port = atoi(service)) >= 65536 || port == 0)
- msg_fatal("bad network port in destination: %s", destination);
-@@ -635,6 +638,9 @@ static void smtp_update_addr_list(DNS_RR **addr_list, const char *server_addr,
- * XXX Extend the SMTP_SESSION structure with sockaddr information so that
- * we can avoid repeated string->binary transformations for the same
- * address.
-+ *
-+ * XXX SRV support: this should match the port, too, otherwise we may
-+ * eliminate too many list entries.
- */
- if ((aierr = hostaddr_to_sockaddr(server_addr, (char *) 0, 0, &res0)) != 0) {
- msg_warn("hostaddr_to_sockaddr %s: %s",
-@@ -665,6 +671,18 @@ static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
- DSN_BUF *why = state->why;
-
- /*
-+ * This code is called after server address/port lookup, before
-+ * iter->host, iter->addr, iter->rr and iter->mx are assigned concrete
-+ * values, and while iter->port still corresponds to the nexthop service,
-+ * or the default service configured with smtp_tcp_port or lmtp_tcp_port.
-+ *
-+ * When a connection is reused by nexthop/service or by server address/port,
-+ * iter->host, iter->addr and iter->port are updated with actual values
-+ * from the cached session. Additionally, when a connection is searched
-+ * by nexthop/service, iter->rr remains null, and when a connection is
-+ * searched by server address/port, iter->rr is updated with an actual
-+ * server address/port before the search is made.
-+ *
- * First, search the cache by delivery request nexthop. We truncate the
- * server address list when all the sessions for this destination are
- * used up, to reduce the number of variables that need to be checked
-@@ -731,9 +749,7 @@ static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
- /* XXX Assume there is no code at the end of this loop. */
- continue;
- }
-- vstring_strcpy(iter->addr, hostaddr.buf);
-- vstring_strcpy(iter->host, SMTP_HNAME(addr));
-- iter->rr = addr;
-+ SMTP_ITER_UPDATE_HOST(iter, SMTP_HNAME(addr), hostaddr.buf, addr);
- #ifdef USE_TLS
- if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
- msg_warn("TLS policy lookup error for %s/%s: %s",
-@@ -818,6 +834,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
- char *dest_buf;
- char *domain;
- unsigned port;
-+ char *service;
- DNS_RR *addr_list;
- DNS_RR *addr;
- DNS_RR *next;
-@@ -825,6 +842,8 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
- int sess_count;
- SMTP_SESSION *session;
- int lookup_mx;
-+ int non_dns_or_literal;
-+ int i_am_mx;
- unsigned domain_best_pref;
- MAI_HOSTADDR_STR hostaddr;
-
-@@ -834,8 +853,28 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
- /*
- * Parse the destination. If no TCP port is specified, use the port
- * that is reserved for the protocol (SMTP or LMTP).
-+ *
-+ * The 'service' variable corresponds to the remote service specified
-+ * with the nexthop, or the default service configured with
-+ * smtp_tcp_port or lmtp_tcp_port. The 'port' variable and
-+ * SMTP_ITERATOR.port initially correspond to that service. This
-+ * determines what loop prevention will be in effect.
-+ *
-+ * The SMTP_ITERATOR.port will be overwritten after SRV record lookup.
-+ * This guarantees that the connection cache key contains the correct
-+ * port value when caching and retrieving a connection by its server
-+ * address (and port).
-+ *
-+ * By design, the connection cache key contains NO port information when
-+ * caching or retrieving a connection by its nexthop destination.
-+ * Instead, the cache key contains the master.cf service name (a
-+ * proxy for all the parameter settings including the default service
-+ * from smtp_tcp_port or lmtp_tcp_port), together with the nexthop
-+ * destination and sender-dependent info. This should be sufficient
-+ * to avoid cross talk between mail streams that should be separated.
- */
-- dest_buf = smtp_parse_destination(dest, def_service, &domain, &port);
-+ dest_buf = smtp_parse_destination(dest, def_service, &domain,
-+ &service, &port);
- if (var_helpful_warnings && var_smtp_tls_wrappermode == 0
- && ntohs(port) == 465) {
- msg_info("SMTPS wrappermode (TCP port 465) requires setting "
-@@ -848,32 +887,48 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
- SMTP_ITER_INIT(iter, dest, NO_HOST, NO_ADDR, port, state);
-
- /*
-- * Resolve an SMTP or LMTP server. In the case of SMTP, skip mail
-- * exchanger lookups when a quoted host is specified or when DNS
-- * lookups are disabled.
-+ * Resolve an SMTP or LMTP server. Skip MX or SRV lookups when a
-+ * quoted domain is specified or when DNS lookups are disabled.
- */
- if (msg_verbose)
-- msg_info("connecting to %s port %d", domain, ntohs(port));
-+ msg_info("connecting to %s service %s", domain, service);
-+ non_dns_or_literal = (smtp_dns_support == SMTP_DNS_DISABLED
-+ || *dest == '[');
- if (smtp_mode) {
- if (ntohs(port) == IPPORT_SMTP)
- state->misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
- else
- state->misc_flags &= ~SMTP_MISC_FLAG_LOOP_DETECT;
-- lookup_mx = (smtp_dns_support != SMTP_DNS_DISABLED && *dest != '[');
-+ lookup_mx = !non_dns_or_literal;
- } else
- lookup_mx = 0;
-- if (!lookup_mx) {
-+
-+ /*
-+ * Look up SRV and address records and fall back to non-SRV lookups
-+ * if permitted by configuration settings, or look up MX and address
-+ * records, or look up address records only.
-+ */
-+ i_am_mx = 0;
-+ addr_list = 0;
-+ if (!non_dns_or_literal && smtp_use_srv_lookup
-+ && string_list_match(smtp_use_srv_lookup, service)) {
-+ if (lookup_mx)
-+ state->misc_flags |= SMTP_MISC_FLAG_FALLBACK_SRV_TO_MX;
-+ else
-+ state->misc_flags &= ~SMTP_MISC_FLAG_FALLBACK_SRV_TO_MX;
-+ addr_list = smtp_service_addr(domain, service, &iter->mx,
-+ state->misc_flags, why, &i_am_mx);
-+ } else if (!lookup_mx) {
-+ /* Non-DNS, literal, or non-SMTP service */
- addr_list = smtp_host_addr(domain, state->misc_flags, why);
- /* XXX We could be an MX host for this destination... */
- } else {
-- int i_am_mx = 0;
--
- addr_list = smtp_domain_addr(domain, &iter->mx, state->misc_flags,
- why, &i_am_mx);
-- /* If we're MX host, don't connect to non-MX backups. */
-- if (i_am_mx)
-- state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
- }
-+ /* If we're MX host, don't connect to non-MX backups. */
-+ if (i_am_mx)
-+ state->misc_flags |= SMTP_MISC_FLAG_FINAL_NEXTHOP;
-
- /*
- * Don't try fall-back hosts if mail loops to myself. That would just
-@@ -966,9 +1021,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
- /* XXX Assume there is no code at the end of this loop. */
- continue;
- }
-- vstring_strcpy(iter->addr, hostaddr.buf);
-- vstring_strcpy(iter->host, SMTP_HNAME(addr));
-- iter->rr = addr;
-+ SMTP_ITER_UPDATE_HOST(iter, SMTP_HNAME(addr), hostaddr.buf, addr);
- #ifdef USE_TLS
- if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
- msg_warn("TLS policy lookup for %s/%s: %s",
-diff --git a/src/smtp/smtp_params.c b/src/smtp/smtp_params.c
-index 561f6a0..b893a76 100644
---- a/src/smtp/smtp_params.c
-+++ b/src/smtp/smtp_params.c
-@@ -65,6 +65,7 @@
- VAR_SMTP_DSN_FILTER, DEF_SMTP_DSN_FILTER, &var_smtp_dsn_filter, 0, 0,
- VAR_SMTP_DNS_RE_FILTER, DEF_SMTP_DNS_RE_FILTER, &var_smtp_dns_re_filter, 0, 0,
- VAR_TLSPROXY_SERVICE, DEF_TLSPROXY_SERVICE, &var_tlsproxy_service, 1, 0,
-+ VAR_USE_SRV_LOOKUP, DEF_USE_SRV_LOOKUP, &var_use_srv_lookup, 0, 0,
- 0,
- };
- static const CONFIG_TIME_TABLE smtp_time_table[] = {
-@@ -130,5 +131,7 @@
- VAR_SMTP_REC_DEADLINE, DEF_SMTP_REC_DEADLINE, &var_smtp_rec_deadline,
- VAR_SMTP_DUMMY_MAIL_AUTH, DEF_SMTP_DUMMY_MAIL_AUTH, &var_smtp_dummy_mail_auth,
- VAR_SMTP_BALANCE_INET_PROTO, DEF_SMTP_BALANCE_INET_PROTO, &var_smtp_balance_inet_proto,
-+ VAR_IGN_SRV_LOOKUP_ERR, DEF_IGN_SRV_LOOKUP_ERR, &var_ign_srv_lookup_err,
-+ VAR_ALLOW_SRV_FALLBACK, DEF_ALLOW_SRV_FALLBACK, &var_allow_srv_fallback,
- 0,
- };
-diff --git a/src/smtp/smtp_session.c b/src/smtp/smtp_session.c
-index 1b3a20e..3ac4ccc 100644
---- a/src/smtp/smtp_session.c
-+++ b/src/smtp/smtp_session.c
-@@ -129,6 +129,7 @@
- #define SESS_ATTR_DEST "destination"
- #define SESS_ATTR_HOST "host_name"
- #define SESS_ATTR_ADDR "host_addr"
-+#define SESS_ATTR_PORT "host_port"
- #define SESS_ATTR_DEST_FEATURES "destination_features"
-
- #define SESS_ATTR_TLS_LEVEL "tls_level"
-@@ -258,6 +259,7 @@ int smtp_session_passivate(SMTP_SESSION *session, VSTRING *dest_prop,
- SEND_ATTR_STR(SESS_ATTR_DEST, STR(iter->dest)),
- SEND_ATTR_STR(SESS_ATTR_HOST, STR(iter->host)),
- SEND_ATTR_STR(SESS_ATTR_ADDR, STR(iter->addr)),
-+ SEND_ATTR_UINT(SESS_ATTR_PORT, iter->port),
- SEND_ATTR_INT(SESS_ATTR_DEST_FEATURES,
- session->features & SMTP_FEATURE_DESTINATION_MASK),
- ATTR_TYPE_END) != 0
-@@ -397,9 +399,10 @@ SMTP_SESSION *smtp_session_activate(int fd, SMTP_ITERATOR *iter,
- RECV_ATTR_STR(SESS_ATTR_DEST, iter->dest),
- RECV_ATTR_STR(SESS_ATTR_HOST, iter->host),
- RECV_ATTR_STR(SESS_ATTR_ADDR, iter->addr),
-+ RECV_ATTR_UINT(SESS_ATTR_PORT, &iter->port),
- RECV_ATTR_INT(SESS_ATTR_DEST_FEATURES,
- &dest_features),
-- ATTR_TYPE_END) != 4
-+ ATTR_TYPE_END) != 5
- || vstream_fclose(mp) != 0) {
- msg_warn("smtp_session_passivate: bad cached dest properties");
- SMTP_SESSION_ACTIVATE_ERR_RETURN();
-diff --git a/src/smtpd/smtpd_check.c b/src/smtpd/smtpd_check.c
-index 85d5944..a60e878 100644
---- a/src/smtpd/smtpd_check.c
-+++ b/src/smtpd/smtpd_check.c
-@@ -3056,8 +3056,8 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
- || type == T_AAAA
- #endif
- ) {
-- server_list = dns_rr_create(domain, domain, T_MX, C_IN, 0, 0,
-- domain, strlen(domain) + 1);
-+ server_list = dns_rr_create_nopref(domain, domain, T_MX, C_IN, 0,
-+ domain, strlen(domain) + 1);
- } else {
- dns_status = dns_lookup(domain, type, 0, &server_list,
- (VSTRING *) 0, (VSTRING *) 0);
-@@ -3065,8 +3065,8 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
- return (SMTPD_CHECK_DUNNO);
- if (dns_status == DNS_NOTFOUND /* Not: h_errno == NO_DATA */ ) {
- if (type == T_MX) {
-- server_list = dns_rr_create(domain, domain, type, C_IN, 0, 0,
-- domain, strlen(domain) + 1);
-+ server_list = dns_rr_create_nopref(domain, domain, type, C_IN,
-+ 0, domain, strlen(domain) + 1);
- dns_status = DNS_OK;
- } else if (type == T_NS /* && h_errno == NO_DATA */ ) {
- while ((domain = strchr(domain, '.')) != 0 && domain[1]) {
-diff --git a/src/util/attr.h b/src/util/attr.h
-index dc6f9f7..a890a5b 100644
---- a/src/util/attr.h
-+++ b/src/util/attr.h
-@@ -61,6 +61,7 @@ typedef int (*ATTR_PRINT_SLAVE_FN) (ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *
- * for documentation.
- */
- #define SEND_ATTR_INT(name, val) ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, int, (val))
-+#define SEND_ATTR_UINT(name, val) ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_VAL(ATTR, unsigned, (val))
- #define SEND_ATTR_STR(name, val) ATTR_TYPE_STR, CHECK_CPTR(ATTR, char, (name)), CHECK_CPTR(ATTR, char, (val))
- #define SEND_ATTR_HASH(val) ATTR_TYPE_HASH, CHECK_CPTR(ATTR, HTABLE, (val))
- #define SEND_ATTR_NV(val) ATTR_TYPE_NV, CHECK_CPTR(ATTR, NVTABLE, (val))
-@@ -69,6 +70,7 @@ typedef int (*ATTR_PRINT_SLAVE_FN) (ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *
- #define SEND_ATTR_FUNC(func, val) ATTR_TYPE_FUNC, CHECK_VAL(ATTR, ATTR_PRINT_SLAVE_FN, (func)), CHECK_CPTR(ATTR, void, (val))
-
- #define RECV_ATTR_INT(name, val) ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, int, (val))
-+#define RECV_ATTR_UINT(name, val) ATTR_TYPE_INT, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, unsigned, (val))
- #define RECV_ATTR_STR(name, val) ATTR_TYPE_STR, CHECK_CPTR(ATTR, char, (name)), CHECK_PTR(ATTR, VSTRING, (val))
- #define RECV_ATTR_HASH(val) ATTR_TYPE_HASH, CHECK_PTR(ATTR, HTABLE, (val))
- #define RECV_ATTR_NV(val) ATTR_TYPE_NV, CHECK_PTR(ATTR, NVTABLE, (val))
-@@ -79,9 +81,11 @@ typedef int (*ATTR_PRINT_SLAVE_FN) (ATTR_PRINT_MASTER_FN, VSTREAM *, int, void *
- CHECK_VAL_HELPER_DCL(ATTR, ssize_t);
- CHECK_VAL_HELPER_DCL(ATTR, long);
- CHECK_VAL_HELPER_DCL(ATTR, int);
-+CHECK_VAL_HELPER_DCL(ATTR, unsigned);
- CHECK_PTR_HELPER_DCL(ATTR, void);
- CHECK_PTR_HELPER_DCL(ATTR, long);
- CHECK_PTR_HELPER_DCL(ATTR, int);
-+CHECK_PTR_HELPER_DCL(ATTR, unsigned);
- CHECK_PTR_HELPER_DCL(ATTR, VSTRING);
- CHECK_PTR_HELPER_DCL(ATTR, NVTABLE);
- CHECK_PTR_HELPER_DCL(ATTR, HTABLE);
diff --git a/SOURCES/postfix-3.5.8-back-compat-3.3.1.patch b/SOURCES/postfix-3.5.8-back-compat-3.3.1.patch
deleted file mode 100644
index c444912..0000000
--- a/SOURCES/postfix-3.5.8-back-compat-3.3.1.patch
+++ /dev/null
@@ -1,158 +0,0 @@
-diff --git a/src/global/mail_params.c b/src/global/mail_params.c
-index 91c70f7..483613c 100644
---- a/src/global/mail_params.c
-+++ b/src/global/mail_params.c
-@@ -379,6 +379,8 @@ int warn_compat_break_smtputf8_enable;
- int warn_compat_break_chroot;
- int warn_compat_break_relay_restrictions;
-
-+bool var_rhel_ipv6_normalize;
-+
- /* check_myhostname - lookup hostname and validate */
-
- static const char *check_myhostname(void)
-@@ -825,6 +827,7 @@ void mail_params_init()
- VAR_LONG_QUEUE_IDS, DEF_LONG_QUEUE_IDS, &var_long_queue_ids,
- VAR_STRICT_SMTPUTF8, DEF_STRICT_SMTPUTF8, &var_strict_smtputf8,
- VAR_ENABLE_ORCPT, DEF_ENABLE_ORCPT, &var_enable_orcpt,
-+ VAR_RHEL_IPV6_NORMALIZE, DEF_RHEL_IPV6_NORMALIZE, &var_rhel_ipv6_normalize,
- 0,
- };
- const char *cp;
-diff --git a/src/global/mail_params.h b/src/global/mail_params.h
-index e4358ca..74459d9 100644
---- a/src/global/mail_params.h
-+++ b/src/global/mail_params.h
-@@ -3153,7 +3153,7 @@ extern char *var_local_rwr_clients;
- * EHLO keyword filter.
- */
- #define VAR_SMTPD_EHLO_DIS_WORDS "smtpd_discard_ehlo_keywords"
--#define DEF_SMTPD_EHLO_DIS_WORDS ""
-+#define DEF_SMTPD_EHLO_DIS_WORDS "chunking"
- extern char *var_smtpd_ehlo_dis_words;
-
- #define VAR_SMTPD_EHLO_DIS_MAPS "smtpd_discard_ehlo_keyword_address_maps"
-@@ -4199,9 +4199,13 @@ extern int var_postlogd_watchdog;
- #define INFO_LOG_ADDR_FORM_NAME_INTERNAL "internal"
-
- #define VAR_INFO_LOG_ADDR_FORM "info_log_address_format"
--#define DEF_INFO_LOG_ADDR_FORM INFO_LOG_ADDR_FORM_NAME_EXTERNAL
-+#define DEF_INFO_LOG_ADDR_FORM INFO_LOG_ADDR_FORM_NAME_INTERNAL
- extern char *var_info_log_addr_form;
-
-+#define VAR_RHEL_IPV6_NORMALIZE "rhel_ipv6_normalize"
-+#define DEF_RHEL_IPV6_NORMALIZE 0
-+extern bool var_rhel_ipv6_normalize;
-+
- /* LICENSE
- /* .ad
- /* .fi
-diff --git a/src/smtpd/smtpd.c b/src/smtpd/smtpd.c
-index da7227f..53e640e 100644
---- a/src/smtpd/smtpd.c
-+++ b/src/smtpd/smtpd.c
-@@ -4334,6 +4334,7 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
- SMTPD_TOKEN *argp;
- char *raw_value;
- char *attr_value;
-+ const char *bare_value;
- char *attr_name;
- int update_namaddr = 0;
- int name_status;
-@@ -4481,15 +4482,31 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
- UPDATE_STR(state->addr, attr_value);
- UPDATE_STR(state->rfc_addr, attr_value);
- } else {
-- neuter(attr_value, NEUTER_CHARACTERS, '?');
-- if (normalize_mailhost_addr(attr_value, &state->rfc_addr,
-+ if (var_rhel_ipv6_normalize) {
-+ neuter(attr_value, NEUTER_CHARACTERS, '?');
-+ }
-+ if ((var_rhel_ipv6_normalize &&
-+ normalize_mailhost_addr(attr_value, &state->rfc_addr,
- &state->addr,
-- &state->addr_family) < 0) {
-+ &state->addr_family) < 0) ||
-+ (!var_rhel_ipv6_normalize &&
-+ (bare_value = valid_mailhost_addr(attr_value, DONT_GRIPE)) == 0)) {
- state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
- XCLIENT_ADDR, attr_value);
- return (-1);
- }
-+ if (!var_rhel_ipv6_normalize) {
-+ UPDATE_STR(state->addr, bare_value);
-+ UPDATE_STR(state->rfc_addr, attr_value);
-+#ifdef HAS_IPV6
-+ if (strncasecmp(attr_value, INET_PROTO_NAME_IPV6 ":",
-+ sizeof(INET_PROTO_NAME_IPV6 ":") - 1) == 0)
-+ state->addr_family = AF_INET6;
-+ else
-+#endif
-+ state->addr_family = AF_INET;
-+ }
- }
- update_namaddr = 1;
- }
-@@ -4569,17 +4586,25 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
- attr_value = SERVER_ADDR_UNKNOWN;
- UPDATE_STR(state->dest_addr, attr_value);
- } else {
-+ if (var_rhel_ipv6_normalize) {
- #define NO_NORM_RFC_ADDR ((char **) 0)
- #define NO_NORM_ADDR_FAMILY ((int *) 0)
-- neuter(attr_value, NEUTER_CHARACTERS, '?');
-- if (normalize_mailhost_addr(attr_value, NO_NORM_RFC_ADDR,
-+ neuter(attr_value, NEUTER_CHARACTERS, '?');
-+ }
-+ if ((var_rhel_ipv6_normalize &&
-+ normalize_mailhost_addr(attr_value, NO_NORM_RFC_ADDR,
- &state->dest_addr,
-- NO_NORM_ADDR_FAMILY) < 0) {
-+ NO_NORM_ADDR_FAMILY) < 0) ||
-+ (!var_rhel_ipv6_normalize &&
-+ (bare_value = valid_mailhost_addr(attr_value, DONT_GRIPE)) == 0)) {
- state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
- XCLIENT_DESTADDR, attr_value);
- return (-1);
- }
-+ if (!var_rhel_ipv6_normalize) {
-+ UPDATE_STR(state->dest_addr, bare_value);
-+ }
- }
- /* XXX Require same address family as client address. */
- }
-@@ -4690,6 +4715,7 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
- SMTPD_TOKEN *argp;
- char *raw_value;
- char *attr_value;
-+ const char *bare_value;
- char *attr_name;
- int updated = 0;
- static const NAME_CODE xforward_flags[] = {
-@@ -4808,15 +4834,22 @@ static int xforward_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
- UPDATE_STR(state->xforward.addr, attr_value);
- } else {
- neuter(attr_value, NEUTER_CHARACTERS, '?');
-- if (normalize_mailhost_addr(attr_value,
-+ if ((var_rhel_ipv6_normalize &&
-+ normalize_mailhost_addr(attr_value,
- &state->xforward.rfc_addr,
- &state->xforward.addr,
-- NO_NORM_ADDR_FAMILY) < 0) {
-+ NO_NORM_ADDR_FAMILY) < 0) ||
-+ (!var_rhel_ipv6_normalize &&
-+ (bare_value = valid_mailhost_addr(attr_value, DONT_GRIPE)) == 0)) {
- state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
- XFORWARD_ADDR, attr_value);
- return (-1);
- }
-+ if (!var_rhel_ipv6_normalize) {
-+ UPDATE_STR(state->xforward.addr, bare_value);
-+ UPDATE_STR(state->xforward.rfc_addr, attr_value);
-+ }
- }
- break;
-
diff --git a/SOURCES/postfix-3.5.8-makedefs.patch b/SOURCES/postfix-3.5.8-makedefs.patch
deleted file mode 100644
index 24b0ea5..0000000
--- a/SOURCES/postfix-3.5.8-makedefs.patch
+++ /dev/null
@@ -1,32 +0,0 @@
-commit 9c7bcf991e2dd69d517be84d9594411c47e04562
-Author: Tomas Korbar
-Date: Fri May 5 12:48:21 2023 +0200
-
- Fix build with kernel 6
-
-diff --git a/makedefs b/makedefs
-index aea15d6..ad93a5f 100644
---- a/makedefs
-+++ b/makedefs
-@@ -557,7 +557,7 @@ EOF
- : ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"}
- : ${PLUGIN_LD="${CC-gcc} -shared"}
- ;;
-- Linux.[345].*) SYSTYPE=LINUX$RELEASE_MAJOR
-+ Linux.[3456].*) SYSTYPE=LINUX$RELEASE_MAJOR
- case "$CCARGS" in
- *-DNO_DB*) ;;
- *-DHAS_DB*) ;;
-diff --git a/src/util/sys_defs.h b/src/util/sys_defs.h
-index f3a3b26..e9d3546 100644
---- a/src/util/sys_defs.h
-+++ b/src/util/sys_defs.h
-@@ -749,7 +749,7 @@ extern int initgroups(const char *, int);
- /*
- * LINUX.
- */
--#if defined(LINUX2) || defined(LINUX3) || defined(LINUX4) || defined(LINUX5)
-+#if defined(LINUX2) || defined(LINUX3) || defined(LINUX4) || defined(LINUX5) || defined(LINUX6)
- #define SUPPORTED
- #define UINT32_TYPE unsigned int
- #define UINT16_TYPE unsigned short
diff --git a/SOURCES/postfix-3.5.8-whitespace-name-fix.patch b/SOURCES/postfix-3.5.8-whitespace-name-fix.patch
deleted file mode 100644
index c45035e..0000000
--- a/SOURCES/postfix-3.5.8-whitespace-name-fix.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/src/cleanup/cleanup_message.c b/src/cleanup/cleanup_message.c
-index 391c711..be5ce42 100644
---- a/src/cleanup/cleanup_message.c
-+++ b/src/cleanup/cleanup_message.c
-@@ -773,6 +773,8 @@ static void cleanup_header_done_callback(void *context)
- /* Normalize whitespace. */
- token = tok822_scan_limit(state->fullname, &dummy_token,
- var_token_limit);
-+ if (!token)
-+ token = tok822_alloc(TOK822_QSTRING, state->fullname);
- } else {
- token = tok822_alloc(TOK822_QSTRING, state->fullname);
- }
diff --git a/SOURCES/postfix.aliasesdb b/SOURCES/postfix.aliasesdb
deleted file mode 100644
index 8c0156e..0000000
--- a/SOURCES/postfix.aliasesdb
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-
-ALIASESDB_STAMP=/var/lib/misc/postfix.aliasesdb-stamp
-
-make_aliasesdb() {
- if [ "$(/usr/sbin/postconf -h alias_database)" == "hash:/etc/aliases" ]
- then
- # /etc/aliases.db may be used by other MTA, make sure nothing
- # has touched it since our last newaliases call
- [ /etc/aliases -nt /etc/aliases.db ] ||
- [ "$ALIASESDB_STAMP" -nt /etc/aliases.db ] ||
- [ "$ALIASESDB_STAMP" -ot /etc/aliases.db ] || return 0
- /usr/bin/newaliases
- touch -r /etc/aliases.db "$ALIASESDB_STAMP"
- else
- /usr/bin/newaliases
- fi
-}
-
-make_aliasesdb
diff --git a/SOURCES/pflogsumm-1.1.5-datecalc.patch b/pflogsumm-1.1.5-datecalc.patch
similarity index 100%
rename from SOURCES/pflogsumm-1.1.5-datecalc.patch
rename to pflogsumm-1.1.5-datecalc.patch
diff --git a/SOURCES/pflogsumm-1.1.5-ipv6-warnings-fix.patch b/pflogsumm-1.1.5-ipv6-warnings-fix.patch
similarity index 100%
rename from SOURCES/pflogsumm-1.1.5-ipv6-warnings-fix.patch
rename to pflogsumm-1.1.5-ipv6-warnings-fix.patch
diff --git a/SOURCES/pflogsumm-1.1.5-syslog-name-underscore-fix.patch b/pflogsumm-1.1.5-syslog-name-underscore-fix.patch
similarity index 100%
rename from SOURCES/pflogsumm-1.1.5-syslog-name-underscore-fix.patch
rename to pflogsumm-1.1.5-syslog-name-underscore-fix.patch
diff --git a/SOURCES/postfix-3.3.3-alternatives.patch b/postfix-3.3.3-alternatives.patch
similarity index 100%
rename from SOURCES/postfix-3.3.3-alternatives.patch
rename to postfix-3.3.3-alternatives.patch
diff --git a/SOURCES/postfix-3.4.0-files.patch b/postfix-3.4.0-files.patch
similarity index 100%
rename from SOURCES/postfix-3.4.0-files.patch
rename to postfix-3.4.0-files.patch
diff --git a/SOURCES/postfix-3.4.4-chroot-example-fix.patch b/postfix-3.4.4-chroot-example-fix.patch
similarity index 100%
rename from SOURCES/postfix-3.4.4-chroot-example-fix.patch
rename to postfix-3.4.4-chroot-example-fix.patch
diff --git a/SOURCES/postfix-3.5.0-config.patch b/postfix-3.8.0-config.patch
similarity index 90%
rename from SOURCES/postfix-3.5.0-config.patch
rename to postfix-3.8.0-config.patch
index da42263..f77cdc3 100644
--- a/SOURCES/postfix-3.5.0-config.patch
+++ b/postfix-3.8.0-config.patch
@@ -1,8 +1,8 @@
diff --git a/conf/main.cf b/conf/main.cf
-index 7af8bde..495e346 100644
+index 2ee7996..336bd7b 100644
--- a/conf/main.cf
+++ b/conf/main.cf
-@@ -132,6 +132,10 @@ mail_owner = postfix
+@@ -136,6 +136,10 @@ mail_owner = postfix
#inet_interfaces = all
#inet_interfaces = $myhostname
#inet_interfaces = $myhostname, localhost
@@ -13,7 +13,7 @@ index 7af8bde..495e346 100644
# The proxy_interfaces parameter specifies the network interface
# addresses that this mail system receives mail on by way of a
-@@ -176,7 +180,7 @@ mail_owner = postfix
+@@ -180,7 +184,7 @@ mail_owner = postfix
#
# See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
#
@@ -22,7 +22,7 @@ index 7af8bde..495e346 100644
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
#mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain,
# mail.$mydomain, www.$mydomain, ftp.$mydomain
-@@ -398,7 +402,7 @@ unknown_local_recipient_reject_code = 550
+@@ -407,7 +411,7 @@ unknown_local_recipient_reject_code = 550
# "postfix reload" to eliminate the delay.
#
#alias_maps = dbm:/etc/aliases
@@ -31,7 +31,7 @@ index 7af8bde..495e346 100644
#alias_maps = hash:/etc/aliases, nis:mail.aliases
#alias_maps = netinfo:/aliases
-@@ -409,7 +413,7 @@ unknown_local_recipient_reject_code = 550
+@@ -418,7 +422,7 @@ unknown_local_recipient_reject_code = 550
#
#alias_database = dbm:/etc/aliases
#alias_database = dbm:/etc/mail/aliases
@@ -40,7 +40,7 @@ index 7af8bde..495e346 100644
#alias_database = hash:/etc/aliases, hash:/opt/majordomo/aliases
# ADDRESS EXTENSIONS (e.g., user+foo)
-@@ -479,7 +483,27 @@ unknown_local_recipient_reject_code = 550
+@@ -488,7 +492,27 @@ unknown_local_recipient_reject_code = 550
#
# Cyrus IMAP over LMTP. Specify ``lmtpunix cmd="lmtpd"
# listen="/var/imap/socket/lmtp" prefork=0'' in cyrus.conf.
@@ -69,7 +69,7 @@ index 7af8bde..495e346 100644
#
# Cyrus IMAP via command line. Uncomment the "cyrus...pipe" and
# subsequent line in master.cf.
-@@ -499,8 +523,7 @@ unknown_local_recipient_reject_code = 550
+@@ -508,8 +532,7 @@ unknown_local_recipient_reject_code = 550
# the main.cf file, otherwise the SMTP server will reject mail for
# non-UNIX accounts with "User unknown in local recipient table".
#
@@ -79,7 +79,7 @@ index 7af8bde..495e346 100644
#fallback_transport =
# The luser_relay parameter specifies an optional destination address
-@@ -673,4 +696,41 @@ sample_directory =
+@@ -682,4 +705,41 @@ sample_directory =
# readme_directory: The location of the Postfix README files.
#
readme_directory =
@@ -123,10 +123,10 @@ index 7af8bde..495e346 100644
+#
+smtp_tls_security_level = may
diff --git a/conf/master.cf b/conf/master.cf
-index c0f2508..05c5d07 100644
+index fd282dd..8d969c6 100644
--- a/conf/master.cf
+++ b/conf/master.cf
-@@ -98,14 +98,14 @@ postlog unix-dgram n - n - 1 postlogd
+@@ -112,14 +112,14 @@ postlog unix-dgram n - n - 1 postlogd
# Also specify in main.cf: cyrus_destination_recipient_limit=1
#
#cyrus unix - n n - - pipe
diff --git a/SOURCES/postfix-3.4.0-large-fs.patch b/postfix-3.8.0-large-fs.patch
similarity index 92%
rename from SOURCES/postfix-3.4.0-large-fs.patch
rename to postfix-3.8.0-large-fs.patch
index fbc55f1..b0c7933 100644
--- a/SOURCES/postfix-3.4.0-large-fs.patch
+++ b/postfix-3.8.0-large-fs.patch
@@ -21,10 +21,10 @@ index 50a4aa7..beef3db 100644
if (msg_verbose)
msg_info("%s: %s: block size %lu, blocks free %lu",
diff --git a/src/util/sys_defs.h b/src/util/sys_defs.h
-index a8d2571..ad07498 100644
+index 1fb449d..bcaac27 100644
--- a/src/util/sys_defs.h
+++ b/src/util/sys_defs.h
-@@ -769,8 +769,8 @@ extern int initgroups(const char *, int);
+@@ -783,8 +783,8 @@ extern int initgroups(const char *, int);
#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin"
#define FIONREAD_IN_TERMIOS_H
diff --git a/postfix-3.8.5-openssl-no-engine.patch b/postfix-3.8.5-openssl-no-engine.patch
new file mode 100644
index 0000000..8efb0e6
--- /dev/null
+++ b/postfix-3.8.5-openssl-no-engine.patch
@@ -0,0 +1,12 @@
+diff --git a/src/posttls-finger/posttls-finger.c b/src/posttls-finger/posttls-finger.c
+index b9a4699..29e6ec1 100644
+--- a/src/posttls-finger/posttls-finger.c
++++ b/src/posttls-finger/posttls-finger.c
+@@ -405,7 +405,6 @@
+
+ #ifdef USE_TLS
+ #include
+-#include
+ #endif
+
+ /*
diff --git a/SOURCES/postfix-chroot-update b/postfix-chroot-update
similarity index 100%
rename from SOURCES/postfix-chroot-update
rename to postfix-chroot-update
diff --git a/postfix-etc-init.d-postfix b/postfix-etc-init.d-postfix
new file mode 100644
index 0000000..52bd7bd
--- /dev/null
+++ b/postfix-etc-init.d-postfix
@@ -0,0 +1,169 @@
+#!/bin/bash
+#
+# postfix Postfix Mail Transfer Agent
+#
+# chkconfig: - 80 30
+# description: Postfix is a Mail Transport Agent, which is the program \
+# that moves mail from one machine to another.
+# processname: master
+# pidfile: /var/spool/postfix/pid/master.pid
+# config: /etc/postfix/main.cf
+# config: /etc/postfix/master.cf
+#
+# Based on startup script from Simon J Mudd
+# 25/02/99: Mostly s/sendmail/postfix/g by John A. Martin
+# 23/11/00: Changes & suggestions by Ajay Ramaswamy
+# 20/01/01: Changes to fall in line with RedHat 7.0 style
+# 23/02/01: Fix a few untidy problems with help from Daniel Roesen.
+
+### BEGIN INIT INFO
+# Provides: postfix $mail-transfer-agent
+# Required-Start: $local_fs $network $remote_fs
+# Required-Stop: $local_fs $network $remote_fs
+# Short-Description: start and stop postfix
+# Description: Postfix is a Mail Transport Agent, which is the program that
+# moves mail from one machine to another.
+### END INIT INFO
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+RETVAL=0
+prog="postfix"
+lockfile=/var/lock/subsys/$prog
+pidfile=/var/spool/postfix/pid/master.pid
+
+ALIASESDB_STAMP=/var/lib/misc/postfix.aliasesdb-stamp
+
+# Script to update chroot environment
+CHROOT_UPDATE=/etc/postfix/chroot-update
+
+status -p $pidfile -l $(basename $lockfile) master >/dev/null 2>&1
+running=$?
+
+conf_check() {
+ [ -x /usr/sbin/postfix ] || exit 5
+ [ -d /etc/postfix ] || exit 6
+ [ -d /var/spool/postfix ] || exit 5
+}
+
+make_aliasesdb() {
+ local MAP=""
+ local ALIASESDB="$(/usr/sbin/postconf -h alias_database)"
+ [ "$ALIASESDB" = "hash:/etc/aliases" ] && MAP="db"
+ [ "$ALIASESDB" = "lmdb:/etc/aliases" ] && MAP="lmdb"
+
+ if [ "$MAP" = "db" -o "$MAP" = "lmdb" ]
+ then
+ # /etc/aliases.db|lmdb may be used by other MTA, make sure nothing
+ # has touched it since our last newaliases call
+ [ /etc/aliases -nt /etc/aliases.$MAP ] ||
+ [ "$ALIASESDB_STAMP" -nt /etc/aliases.$MAP ] ||
+ [ "$ALIASESDB_STAMP" -ot /etc/aliases.$MAP ] || return
+ /usr/bin/newaliases
+ touch -r /etc/aliases.$MAP "$ALIASESDB_STAMP"
+ else
+ /usr/bin/newaliases
+ fi
+}
+
+start() {
+ [ "$EUID" != "0" ] && exit 4
+ # Check that networking is up.
+ [ ${NETWORKING} = "no" ] && exit 1
+ conf_check
+ # Start daemons.
+ echo -n $"Starting postfix: "
+ make_aliasesdb >/dev/null 2>&1
+ [ -x $CHROOT_UPDATE ] && $CHROOT_UPDATE
+ /usr/sbin/postfix start 2>/dev/null 1>&2 && success || failure $"$prog start"
+ RETVAL=$?
+ [ $RETVAL -eq 0 ] && touch $lockfile
+ echo
+ return $RETVAL
+}
+
+stop() {
+ [ "$EUID" != "0" ] && exit 4
+ conf_check
+ # Stop daemons.
+ echo -n $"Shutting down postfix: "
+ /usr/sbin/postfix stop 2>/dev/null 1>&2 && success || failure $"$prog stop"
+ RETVAL=$?
+ [ $RETVAL -eq 0 ] && rm -f $lockfile $pidfile
+ echo
+ return $RETVAL
+}
+
+reload() {
+ conf_check
+ echo -n $"Reloading postfix: "
+ [ -x $CHROOT_UPDATE ] && $CHROOT_UPDATE
+ /usr/sbin/postfix reload 2>/dev/null 1>&2 && success || failure $"$prog reload"
+ RETVAL=$?
+ echo
+ return $RETVAL
+}
+
+abort() {
+ conf_check
+ /usr/sbin/postfix abort 2>/dev/null 1>&2 && success || failure $"$prog abort"
+ return $?
+}
+
+flush() {
+ conf_check
+ /usr/sbin/postfix flush 2>/dev/null 1>&2 && success || failure $"$prog flush"
+ return $?
+}
+
+check() {
+ conf_check
+ /usr/sbin/postfix check 2>/dev/null 1>&2 && success || failure $"$prog check"
+ return $?
+}
+
+# See how we were called.
+case "$1" in
+ start)
+ [ $running -eq 0 ] && exit 0
+ start
+ ;;
+ stop)
+ [ $running -eq 0 ] || exit 0
+ stop
+ ;;
+ restart|force-reload)
+ stop
+ start
+ ;;
+ reload)
+ [ $running -eq 0 ] || exit 7
+ reload
+ ;;
+ abort)
+ abort
+ ;;
+ flush)
+ flush
+ ;;
+ check)
+ check
+ ;;
+ status)
+ status -p $pidfile -l $(basename $lockfile) master
+ ;;
+ condrestart)
+ [ $running -eq 0 ] || exit 0
+ stop
+ start
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|restart|reload|abort|flush|check|status|condrestart}"
+ exit 2
+esac
+
+exit $?
diff --git a/SOURCES/postfix-pam.conf b/postfix-pam.conf
similarity index 100%
rename from SOURCES/postfix-pam.conf
rename to postfix-pam.conf
diff --git a/SOURCES/postfix-sasl.conf b/postfix-sasl.conf
similarity index 100%
rename from SOURCES/postfix-sasl.conf
rename to postfix-sasl.conf
diff --git a/postfix.aliasesdb b/postfix.aliasesdb
new file mode 100644
index 0000000..863b405
--- /dev/null
+++ b/postfix.aliasesdb
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+ALIASESDB_STAMP=/var/lib/misc/postfix.aliasesdb-stamp
+
+make_aliasesdb() {
+ local MAP=""
+ local ALIASESDB="$(/usr/sbin/postconf -h alias_database)"
+ [ "$ALIASESDB" = "hash:/etc/aliases" ] && MAP="db"
+ [ "$ALIASESDB" = "lmdb:/etc/aliases" ] && MAP="lmdb"
+
+ if [ "$MAP" = "db" -o "$MAP" = "lmdb" ]
+ then
+ # /etc/aliases.db|lmdb may be used by other MTA, make sure nothing
+ # has touched it since our last newaliases call
+ [ /etc/aliases -nt /etc/aliases.$MAP ] ||
+ [ "$ALIASESDB_STAMP" -nt /etc/aliases.$MAP ] ||
+ [ "$ALIASESDB_STAMP" -ot /etc/aliases.$MAP ] || return 0
+ /usr/bin/newaliases
+ touch -r /etc/aliases.$MAP "$ALIASESDB_STAMP"
+ else
+ /usr/bin/newaliases
+ fi
+}
+
+make_aliasesdb
diff --git a/SOURCES/postfix.service b/postfix.service
similarity index 100%
rename from SOURCES/postfix.service
rename to postfix.service
diff --git a/SPECS/postfix.spec b/postfix.spec
similarity index 79%
rename from SPECS/postfix.spec
rename to postfix.spec
index 805c1bf..8960fce 100644
--- a/SPECS/postfix.spec
+++ b/postfix.spec
@@ -1,6 +1,11 @@
# plugins have unresolvable symbols in compile time
%undefine _strict_symbol_defs_build
+%if 0%{?rhel} < 10
+%bcond_without db
+%else
+%bcond_with db
+%endif
%bcond_without mysql
%bcond_without pgsql
%bcond_without sqlite
@@ -13,6 +18,12 @@
%bcond_without ipv6
%bcond_without pflogsumm
+%if %{without db} && %{with lmdb}
+%global defmap_lmdb 1
+%else
+%global defmap_lmdb 0
+%endif
+
%global sysv2systemdnvr 2.8.12-2
# hardened build if not overrided
@@ -21,12 +32,9 @@
# Postfix requires one exlusive uid/gid and a 2nd exclusive gid for its own
# use. Let me know if the second gid collides with another package.
# Be careful: Redhat's 'mail' user & group isn't unique!
-%define postfix_uid 89
+# It's now handled by systemd-sysusers.
%define postfix_user postfix
-%define postfix_gid 89
-%define postfix_group postfix
%define maildrop_group postdrop
-%define maildrop_gid 90
%define postfix_config_dir %{_sysconfdir}/postfix
%define postfix_daemon_dir %{_libexecdir}/postfix
@@ -48,18 +56,14 @@
Name: postfix
Summary: Postfix Mail Transport Agent
-Version: 3.5.8
-Release: 7%{?dist}
+Version: 3.8.5
+Release: 8%{?dist}
Epoch: 2
-Group: System Environment/Daemons
URL: http://www.postfix.org
-License: (IBM and GPLv2+) or (EPL-2.0 and GPLv2+)
-Requires(post): systemd hostname
+License: (IPL-1.0 OR EPL-2.0) AND GPL-2.0-or-later AND BSD-4-Clause-UC
+Requires(post): systemd systemd-sysv hostname
Requires(post): %{_sbindir}/alternatives
Requires(post): %{_bindir}/openssl
-Requires(post): %{_bindir}/hostname
-Requires(pre): %{_sbindir}/groupadd
-Requires(pre): %{_sbindir}/useradd
Requires(preun): %{_sbindir}/alternatives
Requires(preun): systemd
Requires(postun): systemd
@@ -71,11 +75,12 @@ Requires: policycoreutils
Provides: MTA smtpd smtpdaemon server(smtp)
Source0: ftp://ftp.porcupine.org/mirrors/postfix-release/official/%{name}-%{version}.tar.gz
+Source1: postfix-etc-init.d-postfix
Source2: postfix.service
Source3: README-Postfix-SASL-RedHat.txt
Source4: postfix.aliasesdb
Source5: postfix-chroot-update
-Source6: README-RedHat.txt
+Source6: postfix.sysusers
# Sources 50-99 are upstream [patch] contributions
@@ -91,48 +96,71 @@ Source101: postfix-pam.conf
# Patches
-Patch1: postfix-3.5.0-config.patch
+Patch1: postfix-3.8.0-config.patch
Patch2: postfix-3.4.0-files.patch
Patch3: postfix-3.3.3-alternatives.patch
-Patch4: postfix-3.4.0-large-fs.patch
+# probably rhbz#428996
+Patch4: postfix-3.8.0-large-fs.patch
Patch9: pflogsumm-1.1.5-datecalc.patch
# rhbz#1384871, sent upstream
Patch10: pflogsumm-1.1.5-ipv6-warnings-fix.patch
Patch11: postfix-3.4.4-chroot-example-fix.patch
-Patch12: postfix-3.5.8-back-compat-3.3.1.patch
-Patch13: postfix-3.5.8-whitespace-name-fix.patch
# rhbz#1931403, sent upstream
-Patch14: pflogsumm-1.1.5-syslog-name-underscore-fix.patch
-# rhbz#1787010, patch backported from upstream
-Patch15: postfix-3.5.8-SRV-resolve.patch
-# rhbz#2196577, ZUUL CI uses kernel 6 and we have to add this to postfix
-Patch16: postfix-3.5.8-makedefs.patch
+Patch13: pflogsumm-1.1.5-syslog-name-underscore-fix.patch
+Patch14: postfix-3.8.5-openssl-no-engine.patch
# Optional patches - set the appropriate environment variables to include
# them when building the package/spec file
# Determine the different packages required for building postfix
-BuildRequires: libdb-devel, perl-generators, pkgconfig, zlib-devel
-BuildRequires: systemd-units, libicu-devel, libnsl2-devel
-BuildRequires: gcc, m4, findutils
+BuildRequires: make
+BuildRequires: perl-generators
+BuildRequires: pkgconfig
+BuildRequires: zlib-devel
+BuildRequires: systemd-units
+BuildRequires: libicu-devel
+BuildRequires: gcc
+BuildRequires: m4
+BuildRequires: findutils
+BuildRequires: systemd-rpm-macros
+BuildRequires: sed
+%if 0%{?rhel} < 9
+BuildRequires: libnsl2-devel
+%endif
+%{?with_db:BuildRequires: libdb-devel}
%{?with_ldap:BuildRequires: openldap-devel}
%{?with_lmdb:BuildRequires: lmdb-devel}
%{?with_sasl:BuildRequires: cyrus-sasl-devel}
-%{?with_pcre:BuildRequires: pcre-devel}
+%{?with_pcre:BuildRequires: pcre2-devel}
%{?with_mysql:BuildRequires: mariadb-connector-c-devel}
-%{?with_pgsql:BuildRequires: postgresql-devel}
+%{?with_pgsql:BuildRequires: libpq-devel}
%{?with_sqlite:BuildRequires: sqlite-devel}
%{?with_cdb:BuildRequires: tinycdb-devel}
%{?with_tls:BuildRequires: openssl-devel}
+%if 0%{?defmap_lmdb}
+Requires: %{name}-lmdb%{?_isa} = %{epoch}:%{version}-%{release}
+%endif
+
%description
Postfix is a Mail Transport Agent (MTA).
+%if 0%{?fedora} < 23 && 0%{?rhel} < 9
+%package sysvinit
+Summary: SysV initscript for postfix
+BuildArch: noarch
+Requires: %{name} = %{epoch}:%{version}-%{release}
+Requires(preun): chkconfig
+Requires(post): chkconfig
+
+%description sysvinit
+This package contains the SysV initscript.
+%endif
+
%package perl-scripts
Summary: Postfix utilities written in perl
-Group: Applications/System
Requires: %{name} = %{epoch}:%{version}-%{release}
# perl-scripts introduced in 2:2.5.5-2
Obsoletes: postfix < 2:2.5.5-2
@@ -242,24 +270,39 @@ pushd pflogsumm-%{pflogsumm_ver}
popd
%endif
%patch11 -p1 -b .chroot-example-fix
-# Improve backward compatibility with postfix-3.3.1,
-# for details see rhbz#1688389
-%patch12 -p1 -b .back-compat-3.3.1
-# rhbz#1977732, sent upstream
-%patch13 -p1 -b .whitespace-name-fix
-%patch14 -p1 -b .pflogsumm-1.1.5-syslog-name-underscore-fix
-%patch15 -p1 -b .SRV-resolve
-%patch16 -p1 -b .makedefs
+%patch13 -p1 -b .pflogsumm-1.1.5-syslog-name-underscore-fix
+%patch14 -p1 -b .openssl-no-engine
+
+# Backport 3.8-20221006 fix for uname -r detection
+sed -i makedefs -e '\@Linux\.@s|345|3456|'
+sed -i src/util/sys_defs.h -e 's@defined(LINUX5)@defined(LINUX5) || defined(LINUX6)@'
for f in README_FILES/TLS_{LEGACY_,}README TLS_ACKNOWLEDGEMENTS; do
iconv -f iso8859-1 -t utf8 -o ${f}{_,} &&
touch -r ${f}{,_} && mv -f ${f}{_,}
done
+# fix default maps
+%if 0%{?defmap_lmdb}
+ sed -i '/^\s*alias_maps\s*=\s*hash:\/etc\/aliases/ s|hash:|lmdb:|g' conf/main.cf
+ sed -i '/^\s*alias_database\s*=\s*hash:\/etc\/aliases/ s|hash:|lmdb:|g' conf/main.cf
+ echo >> conf/main.cf
+ echo "default_database_type = lmdb" >> conf/main.cf
+%endif
+
%build
+%set_build_flags
unset AUXLIBS AUXLIBS_LDAP AUXLIBS_LMDB AUXLIBS_PCRE AUXLIBS_MYSQL AUXLIBS_PGSQL AUXLIBS_SQLITE AUXLIBS_CDB
CCARGS="-fPIC -fcommon"
+%if 0%{?rhel} >= 9
+AUXLIBS=""
+%else
AUXLIBS="-lnsl"
+%endif
+
+%if %{without db}
+ CCARGS="${CCARGS} -DNO_DB"
+%endif
%ifarch s390 s390x ppc
CCARGS="${CCARGS} -fsigned-char"
@@ -274,9 +317,8 @@ CCARGS="${CCARGS} -fsigned-char"
AUXLIBS_LMDB="-llmdb"
%endif
%if %{with pcre}
- # -I option required for pcre 3.4 (and later?)
- CCARGS="${CCARGS} -DHAS_PCRE -I%{_includedir}/pcre"
- AUXLIBS_PCRE="-lpcre"
+ CCARGS="${CCARGS} -DHAS_PCRE=2 `pcre2-config --cflags`"
+ AUXLIBS_PCRE=`pcre2-config --libs8`
%endif
%if %{with mysql}
CCARGS="${CCARGS} -DHAS_MYSQL -I%{_includedir}/mysql"
@@ -314,8 +356,10 @@ CCARGS="${CCARGS} -fsigned-char"
CCARGS="${CCARGS} -DDEF_CONFIG_DIR=\\\"%{postfix_config_dir}\\\""
CCARGS="${CCARGS} $(getconf LFS_CFLAGS)"
-
-LDFLAGS="%{?__global_ldflags} %{?_hardened_build:-Wl,-z,relro,-z,now}"
+%if 0%{?rhel} >= 9
+ CCARGS="${CCARGS} -DNO_NIS"
+%endif
+LDFLAGS="$LDFLAGS %{?_hardened_build:-Wl,-z,relro,-z,now}"
# SHLIB_RPATH is needed to find private libraries
# LDFLAGS are added to SHLIB_RPATH because the postfix build system
@@ -328,7 +372,7 @@ make -f Makefile.init makefiles shared=yes dynamicmaps=yes \
AUXLIBS_PGSQL="${AUXLIBS_PGSQL}" AUXLIBS_SQLITE="${AUXLIBS_SQLITE}" \
AUXLIBS_CDB="${AUXLIBS_CDB}" \
DEBUG="" SHLIB_RPATH="-Wl,-rpath,%{postfix_shlib_dir} $LDFLAGS" \
- OPT="$RPM_OPT_FLAGS -fno-strict-aliasing -Wno-comment" \
+ OPT="$CFLAGS -fno-strict-aliasing -Wno-comment" \
POSTFIX_INSTALL_OPTS=-keep-build-mtime
%make_build
@@ -361,12 +405,21 @@ make non-interactive-package \
sample_directory=%{postfix_sample_dir} \
readme_directory=%{postfix_readme_dir} || exit 1
+%if 0%{?fedora} < 23 && 0%{?rhel} < 9
+# This installs into the /etc/rc.d/init.d directory
+mkdir -p $RPM_BUILD_ROOT%{_initrddir}
+install -c %{SOURCE1} $RPM_BUILD_ROOT%{_initrddir}/postfix
+%endif
+
# Systemd
mkdir -p %{buildroot}%{_unitdir}
install -m 644 %{SOURCE2} %{buildroot}%{_unitdir}
install -m 755 %{SOURCE4} %{buildroot}%{postfix_daemon_dir}/aliasesdb
install -m 755 %{SOURCE5} %{buildroot}%{postfix_daemon_dir}/chroot-update
+# systemd-sysusers
+install -p -D -m 0644 %{SOURCE6} %{buildroot}%{_sysusersdir}/postfix.conf
+
install -c auxiliary/rmail/rmail $RPM_BUILD_ROOT%{_bindir}/rmail.postfix
for i in active bounce corrupt defer deferred flush incoming private saved maildrop public pid saved trace; do
@@ -396,7 +449,7 @@ install -m 644 %{SOURCE101} $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/smtp.postfix
# prepare documentation
mkdir -p $RPM_BUILD_ROOT%{postfix_doc_dir}
-cp -p %{SOURCE3} %{SOURCE6} COMPATIBILITY LICENSE TLS_ACKNOWLEDGEMENTS TLS_LICENSE $RPM_BUILD_ROOT%{postfix_doc_dir}
+cp -p %{SOURCE3} COMPATIBILITY LICENSE TLS_ACKNOWLEDGEMENTS TLS_LICENSE $RPM_BUILD_ROOT%{postfix_doc_dir}
mkdir -p $RPM_BUILD_ROOT%{postfix_doc_dir}/examples{,/chroot-setup}
cp -pr examples/{qmail-local,smtpd-policy} $RPM_BUILD_ROOT%{postfix_doc_dir}/examples
@@ -502,7 +555,7 @@ fi
# Create self-signed SSL certificate
if [ ! -f %{sslkey} ]; then
umask 077
- %{_bindir}/openssl genrsa 4096 > %{sslkey} 2> /dev/null
+ %{_bindir}/openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out %{sslkey} 2>/dev/null || echo "openssl genpkey failed"
fi
if [ ! -f %{sslcert} ]; then
@@ -511,8 +564,10 @@ if [ ! -f %{sslcert} ]; then
FQDN=localhost.localdomain
fi
- %{_bindir}/openssl req -new -key %{sslkey} -x509 -sha256 -days 365 -set_serial $RANDOM -out %{sslcert} \
- -subj "/C=--/ST=SomeState/L=SomeCity/O=SomeOrganization/OU=SomeOrganizationalUnit/CN=${FQDN}/emailAddress=root@${FQDN}"
+ req_cmd="%{_bindir}/openssl req -new -key %{sslkey} -x509 -sha256 -days 365 -set_serial $RANDOM -out %{sslcert} \
+ -subj /C=--/ST=SomeState/L=SomeCity/O=SomeOrganization/OU=SomeOrganizationalUnit/CN=${FQDN}/emailAddress=root@${FQDN}"
+# openssl-3.0 and fallback for backward compatibility with openssl < 3.0
+ $req_cmd -noenc -copy_extensions none 2>/dev/null || $req_cmd 2>/dev/null || echo "openssl req failed"
chmod 644 %{sslcert}
fi
@@ -520,10 +575,7 @@ exit 0
%pre
# Add user and groups if necessary
-%{_sbindir}/groupadd -g %{maildrop_gid} -r %{maildrop_group} 2>/dev/null
-%{_sbindir}/groupadd -g %{postfix_gid} -r %{postfix_group} 2>/dev/null
-%{_sbindir}/groupadd -g 12 -r mail 2>/dev/null
-%{_sbindir}/useradd -d %{postfix_queue_dir} -s /sbin/nologin -g %{postfix_group} -G mail -M -r -u %{postfix_uid} %{postfix_user} 2>/dev/null
+%sysusers_create_compat %{SOURCE6}
# hack, to turn man8/smtpd.8.gz into alternatives symlink (part of the rhbz#1051180 fix)
# this could be probably dropped in f23+
@@ -544,6 +596,23 @@ exit 0
%postun
%systemd_postun_with_restart %{name}.service
+%if 0%{?fedora} < 23 && 0%{?rhel} < 9
+%post sysvinit
+/sbin/chkconfig --add postfix >/dev/null 2>&1 ||:
+
+%preun sysvinit
+if [ "$1" = 0 ]; then
+ %{_initrddir}/postfix stop >/dev/null 2>&1 ||:
+ /sbin/chkconfig --del postfix >/dev/null 2>&1 ||:
+fi
+
+%postun sysvinit
+[ "$1" -ge 1 ] && %{_initrddir}/postfix condrestart >/dev/null 2>&1 ||:
+
+%triggerpostun -n postfix-sysvinit -- postfix < %{sysv2systemdnvr}
+/sbin/chkconfig --add postfix >/dev/null 2>&1 || :
+%endif
+
%triggerun -- postfix < %{sysv2systemdnvr}
%{_bindir}/systemd-sysv-convert --save postfix >/dev/null 2>&1 ||:
%{_bindir}/systemd-sysv-convert --apply postfix >/dev/null 2>&1 ||:
@@ -637,7 +706,7 @@ exit 0
%attr(0755, root, root) %{postfix_command_dir}/postfix
%attr(0755, root, root) %{postfix_command_dir}/postkick
%attr(0755, root, root) %{postfix_command_dir}/postlock
-%attr(0755, root, root) %{postfix_command_dir}/postlog
+%attr(2755, root, %{maildrop_group}) %{postfix_command_dir}/postlog
%attr(0755, root, root) %{postfix_command_dir}/postmap
%attr(0755, root, root) %{postfix_command_dir}/postmulti
%attr(2755, root, %{maildrop_group}) %{postfix_command_dir}/postqueue
@@ -690,6 +759,14 @@ exit 0
%ghost %attr(0644, root, root) %{_var}/lib/misc/postfix.aliasesdb-stamp
+# systemd-sysusers
+%{_sysusersdir}/postfix.conf
+
+%if 0%{?fedora} < 23 && 0%{?rhel} < 9
+%files sysvinit
+%{_initrddir}/postfix
+%endif
+
%files perl-scripts
%attr(0755, root, root) %{postfix_command_dir}/qshape
%attr(0644, root, root) %{_mandir}/man1/qshape*
@@ -763,68 +840,350 @@ exit 0
%endif
%changelog
-* Mon Aug 14 2023 Jaroslav Škarvada - 2:3.5.8-7
+* Tue Oct 29 2024 Troy Dawson - 2:3.8.5-8
+- Bump release for October 2024 mass rebuild:
+ Resolves: RHEL-64018
+
+* Sun Aug 25 2024 Jaroslav Škarvada - 2:3.8.5-7
+- Dropped mail group configuration / creation, it is provided by setup
+ Resolves: RHEL-27174
+
+* Thu Jul 25 2024 Jaroslav Škarvada - 2:3.8.5-6
+- Fixed postlog RPM verification
+ Resolves: RHEL-50584
+
+* Thu Jul 25 2024 Jaroslav Škarvada - 2:3.8.5-5
+- Explicitly set default_database_type if lmdb map is used
+ Resolves: RHEL-50557
+
+* Mon Jun 24 2024 Troy Dawson - 2:3.8.5-4
+- Bump release for June 2024 mass rebuild
+
+* Thu Feb 01 2024 Pete Walter - 2:3.8.5-3
+- Rebuild for ICU 74
+
+* Thu Jan 25 2024 Fedora Release Engineering - 2:3.8.5-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Mon Jan 22 2024 Jaroslav Škarvada - 2:3.8.5-1
+- New version
+ Resolves: rhbz#2259469
+
+* Sun Jan 21 2024 Fedora Release Engineering - 2:3.8.4-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild
+
+* Tue Jan 2 2024 Jaroslav Škarvada - 2:3.8.4-1
+- New version
+ Resolves: rhbz#2255641
+- Fixed SMTP smuggling vulnerability
+ Resolves: CVE-2023-51764
+
+* Tue Dec 12 2023 Jaroslav Škarvada - 2:3.8.3-2
+- Converted license tag to SPDX
+
+* Thu Nov 2 2023 Jaroslav Škarvada - 2:3.8.3-1
+- New version
+ Resolves: rhbz#2247553
+
+* Mon Oct 9 2023 Jaroslav Škarvada - 2:3.8.2-2
+- Drop libdb for RHEL>9
+ Related: rhbz#1788480
+
+* Tue Sep 5 2023 Jaroslav Škarvada - 2:3.8.2-1
+- New version
+ Resolves: rhbz#2236828
+
+* Mon Aug 14 2023 Jaroslav Škarvada - 2:3.8.1-5
+- Use systemd-sysusers, original patch by
+ Jonathan Wright
+
+* Fri Jul 21 2023 Fedora Release Engineering - 2:3.8.1-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild
+
+* Tue Jul 11 2023 František Zatloukal - 2:3.8.1-3
+- Rebuilt for ICU 73.2
+
+* Tue Jul 11 2023 Jaroslav Škarvada - 2:3.8.1-2
- Fixed possible warning when postfix is restarted
- Resolves: rhbz#2162659
+ Resolves: rhbz#2218058
-* Wed May 17 2023 Tomas Korbar - 2:3.5.8-6
-- Fix patch for SRV record resolution feature
- Related: rhbz#1787010
+* Tue Jun 6 2023 Jaroslav Škarvada - 2:3.8.1-1
+- New version
+ Resolves: rhbz#2212596
-* Thu May 04 2023 Tomas Korbar - 2:3.5.8-5
-- Backport dns SRV record resolution feature (RFC6186)
- Resolves: rhbz#1787010
-- Fix building in ZUUL CI
- Resolves: rhbz#2196577
+* Thu May 25 2023 Tomas Korbar - 2:3.8.0-3
+- Fix freed memory access
-* Thu Feb 17 2022 Jaroslav Škarvada - 2:3.5.8-4
-- Added SELinux workound for systemd service to work after 'postfix start'
- Resolves: rhbz#2028015
+* Wed Apr 26 2023 Jaroslav Škarvada - 2:3.8.0-2
+- Dropped whitespace-name-fix patch, not needed
-* Mon Jan 17 2022 Jaroslav Škarvada - 2:3.5.8-3
+* Wed Apr 26 2023 Jaroslav Škarvada - 2:3.8.0-1
+- New version
+ Resolves: rhbz#2187121
+
+* Wed Jan 25 2023 Jaroslav Škarvada - 2:3.7.4-1
+- New version
+ Resolves: rhbz#2162932
+
+* Fri Jan 20 2023 Fedora Release Engineering - 2:3.7.3-4
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild
+
+* Sat Dec 31 2022 Mamoru TASAKA - 2:3.7.3-3
+- Backport upstream fix for uname -r detection with kernel 6.x
+
+* Sat Dec 31 2022 Pete Walter - 2:3.7.3-2
+- Rebuild for ICU 72
+
+* Mon Oct 10 2022 Jaroslav Škarvada - 2:3.7.3-1
+- New version
+ Resolves: rhbz#2133120
+
+* Mon Aug 01 2022 Frantisek Zatloukal - 2:3.7.2-4
+- Rebuilt for ICU 71.1
+
+* Sat Jul 23 2022 Stewart Smith - 2:3.7.2-3
+- Build with pcre2 instead of the deprecated pcre library
+
+* Fri Jul 22 2022 Fedora Release Engineering - 2:3.7.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild
+
+* Thu Apr 28 2022 Jaroslav Škarvada - 2:3.7.2-1
+- New version
+ Resolves: rhbz#2079634
+
+* Tue Apr 19 2022 Jaroslav Škarvada - 2:3.7.1-1
+- New version
+ Resolves: rhbz#2076317
+
+* Tue Feb 22 2022 Jaroslav Škarvada - 2:3.7.0-1
+- New version
+ Resolves: rhbz#2051046
+
+* Thu Jan 20 2022 Jaroslav Škarvada - 2:3.6.4-1
+- New version
+ Resolves: rhbz#2040977
+- Suppressed openssl output during SSL certificates generation
+ Resolves: rhbz#2041589
+
+* Mon Jan 17 2022 Jaroslav Škarvada - 2:3.6.3-5
- Fixed pflogsumm to allow underscores in the syslog_name
Resolves: rhbz#1931403
-* Thu Aug 5 2021 Jaroslav Škarvada - 2:3.5.8-2
-- Fixed cleanup crash when processing messages with whitespace only fullname
- Resolves: rhbz#1977732
+* Tue Dec 14 2021 Jaroslav Škarvada - 2:3.6.3-4
+- Added SELinux workound for systemd service to work after 'postfix start'
-* Fri Nov 13 2020 Jaroslav Škarvada - 2:3.5.8-1
+* Wed Dec 08 2021 Timm Bäder - 2:3.6.3-3
+- Use %%set_build_flags to set all build flags
+
+* Fri Nov 12 2021 Björn Esser - 2:3.6.3-2
+- Rebuild(libnsl2)
+
+* Wed Nov 10 2021 Jaroslav Škarvada - 2:3.6.3-1
- New version
- Resolves: rhbz#1688389
+ Resolves: rhbz#2020984
-* Mon Dec 16 2019 Jaroslav Škarvada - 2:3.3.1-12
+* Tue Sep 14 2021 Sahana Prasad - 2:3.6.2-6
+- Rebuilt with OpenSSL 3.0.0
+
+* Thu Aug 5 2021 Jaroslav Škarvada - 2:3.6.2-5
+- Fixed cleanup crash when processing messages with whitespace only fullname
+- Fixed whitespaces in the glibc-234-build-fix patch
+
+* Thu Aug 5 2021 Jaroslav Škarvada - 2:3.6.2-4
+- Updated patch fixing FTBFS with the glibc-2.34
+
+* Tue Aug 3 2021 Jaroslav Škarvada - 2:3.6.2-3
+- Fixed openssl req parameters
+
+* Mon Aug 2 2021 Jaroslav Škarvada - 2:3.6.2-2
+- Fixed scriptlets to work with openssl-3.0
+
+* Thu Jul 29 2021 Jaroslav Škarvada - 2:3.6.2-1
+- New version
+ Resolves: rhbz#1985778
+
+* Fri Jul 23 2021 Fedora Release Engineering - 2:3.6.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild
+
+* Fri Jul 2 2021 Jaroslav Škarvada - 2:3.6.1-2
+- Fixed build on rhel < 9
+
+* Mon Jun 14 2021 Jaroslav Škarvada - 2:3.6.1-1
+- New version
+ Resolves: rhbz#1971363
+
+* Thu May 20 2021 Pete Walter - 2:3.6.0-3
+- Rebuild for ICU 69
+
+* Wed May 19 2021 Pete Walter - 2:3.6.0-2
+- Rebuild for ICU 69
+
+* Fri Apr 30 2021 Jaroslav Škarvada - 2:3.6.0-1
+- New version
+ Resolves: rhbz#1955369
+
+* Thu Apr 22 2021 Jaroslav Škarvada - 2:3.5.10-2
+- Fixed NIS build requirements
+
+* Mon Apr 12 2021 Jaroslav Škarvada - 2:3.5.10-1
+- New version
+ Resolves: rhbz#1948306
+
+* Thu Mar 25 2021 Jaroslav Škarvada - 2:3.5.9-7
+- Simplified macros related to NIS
+
+* Wed Mar 24 2021 Jaroslav Škarvada - 2:3.5.9-6
+- Disable NIS support for RHEL9+ (patch from fjanus@redhat.com)
+
+* Tue Mar 02 2021 Zbigniew Jędrzejewski-Szmek - 2:3.5.9-5
+- Rebuilt for updated systemd-rpm-macros
+ See https://pagure.io/fesco/issue/2583.
+
+* Fri Feb 19 2021 Jaroslav Škarvada - 2:3.5.9-4
+- Fixed sysvinit conditionals for RHEL
+ Resolves: rhbz#1930709
+
+* Mon Feb 08 2021 Pavel Raiskup - 2:3.5.9-3
+- rebuild for libpq ABI fix rhbz#1908268
+
+* Wed Jan 27 2021 Fedora Release Engineering - 2:3.5.9-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_34_Mass_Rebuild
+
+* Mon Jan 18 2021 Jaroslav Škarvada - 2:3.5.9-1
+- New version
+ Resolves: rhbz#1917155
+
+* Mon Nov 9 2020 Jaroslav Škarvada - 2:3.5.8-1
+- New version
+ Resolves: rhbz#1895644
+
+* Mon Aug 31 2020 Jaroslav Škarvada - 2:3.5.7-1
+- New version
+ Resolves: rhbz#1873857
+
+* Thu Aug 6 2020 Jaroslav Škarvada - 2:3.5.6-2
+- Minor spec cleanup
+- Added posttls-finger test tool
+ Resolves: rhbz#1865701
+
+* Tue Jul 28 2020 Jaroslav Škarvada - 2:3.5.6-1
+- New version
+ Resolves: rhbz#1860547
+
+* Tue Jul 14 2020 Tom Stellard - 2:3.5.4-3
+- Use make macros
+- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro
+
+* Wed Jul 8 2020 Jaroslav Škarvada - 2:3.5.4-2
+- Added support for LMDB maps
+
+* Mon Jun 29 2020 Jaroslav Škarvada - 2:3.5.4-1
+- New version
+ Resolves: rhbz#1851650
+
+* Mon Jun 15 2020 Jaroslav Škarvada - 2:3.5.3-1
+- New version
+ Resolves: rhbz#1846939
+
+* Tue May 19 2020 Jaroslav Škarvada - 2:3.5.2-1
+- New version
+ Resolves: rhbz#1836653
+
+* Fri May 15 2020 Pete Walter - 2:3.5.1-2
+- Rebuild for ICU 67
+
+* Mon Apr 20 2020 Jaroslav Škarvada - 2:3.5.1-1
+- New version
+ Resolves: rhbz#1825547
+
+* Mon Mar 16 2020 Jaroslav Škarvada - 2:3.5.0-1
+- New version
+ Resolves: rhbz#1813740
+
+* Thu Mar 12 2020 Jaroslav Škarvada - 2:3.4.10-1
+- New version
+ Resolves: rhbz#1812987
+
+* Mon Feb 3 2020 Jaroslav Škarvada - 2:3.4.9-1
+- New version
+ Resolves: rhbz#1797383
+- Dropped ref-search patch (upstreamed)
+- Built with -fcommon to overcome FTBFS with gcc-10, problem reported upstream
+
+* Thu Jan 30 2020 Fedora Release Engineering - 2:3.4.8-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild
+
+* Mon Dec 16 2019 Jaroslav Škarvada - 2:3.4.8-2
- Fixed DNS resolver to use ref_search instead of ref_query
Resolves: rhbz#1723950
-* Tue Dec 10 2019 Jaroslav Škarvada - 2:3.3.1-11
-- Added hostname requirement
- Resolves: rhbz#1666244
+* Mon Nov 25 2019 Jaroslav Škarvada - 2:3.4.8-1
+- New version
+ Resolves: rhbz#1776033
-* Wed Nov 6 2019 Jaroslav Škarvada - 2:3.3.1-10
-- Release bump and rebuild for relengs to be able to ship postfix-pcre,
- postfix-cdb, postfix-sqlite
- Resolves: rhbz#1745321
+* Fri Nov 01 2019 Pete Walter - 2:3.4.7-3
+- Rebuild for ICU 65
-* Tue Aug 6 2019 Jaroslav Škarvada - 2:3.3.1-9
-- Release bump and rebuild for relengs to be able to ship postfix-ldap
- Resolves: rhbz#1686721
+* Wed Sep 25 2019 Jaroslav Škarvada - 2:3.4.7-2
+- Added hostname as explicit requirement for the post scriptlet
-* Tue Dec 4 2018 Jaroslav Škarvada - 2:3.3.1-8
+* Mon Sep 23 2019 Jaroslav Škarvada - 2:3.4.7-1
+- New version
+ Resolves: rhbz#1754198
+
+* Fri Jul 26 2019 Fedora Release Engineering - 2:3.4.6-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild
+
+* Mon Jul 8 2019 Jaroslav Škarvada - 2:3.4.6-1
+- New version
+ Resolves: rhbz#1726462
+
+* Fri May 3 2019 Jaroslav Škarvada - 2:3.4.4-4
+- Fixed FTBFS with new glibc due to dropped RES macros
+
+* Fri May 3 2019 Jaroslav Škarvada - 2:3.4.4-3
+- Added findutils as explicit requirement
+ Resolves: rhbz#1629057
+
+* Tue Mar 26 2019 Jaroslav Škarvada - 2:3.4.4-2
+- Fixed example chroot-update script
+ Resolves: rhbz#1398910
+
+* Fri Mar 15 2019 Jaroslav Škarvada - 2:3.4.4-1
+- New version
+ Resolves: rhbz#1689029
+
+* Mon Mar 11 2019 Jaroslav Škarvada - 2:3.4.3-1
+- New version
+ Resolves: rhbz#1687208
+
+* Fri Mar 8 2019 Jaroslav Škarvada - 2:3.4.1-1
+- New version
+ Resolves: rhbz#1686673
+
+* Fri Mar 1 2019 Jaroslav Škarvada - 2:3.4.0-1
+- New version
+ Resolves: rhbz#1683855
+
+* Wed Feb 27 2019 Jaroslav Škarvada - 2:3.3.3-1
+- New version
+ Resolves: rhbz#1683487
+
+* Sat Feb 02 2019 Fedora Release Engineering - 2:3.3.1-9
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild
+
+* Wed Jan 23 2019 Pete Walter - 2:3.3.1-8
+- Rebuild for ICU 63
+
+* Mon Dec 3 2018 Jaroslav Škarvada - 2:3.3.1-7
- Fixed posttls-finger to work with unix domains
- Resolves: rhbz#1602663
-* Wed Nov 28 2018 Jaroslav Škarvada - 2:3.3.1-7
-- Added m4 to BuildRequires
- Resolves: rhbz#1619187
-
-* Tue Nov 20 2018 Jaroslav Škarvada - 2:3.3.1-6
+* Mon Nov 19 2018 Jaroslav Škarvada - 2:3.3.1-6
- Used _prefix macro for /usr and _includedir macro for /usr/include
- Resolves: rhbz#1645239
-* Thu Nov 1 2018 Jaroslav Škarvada - 2:3.3.1-5
-- Dropped sysv support from the spec
- Resolves: rhbz#1636961
+* Mon Aug 20 2018 Jaroslav Škarvada - 2:3.3.1-5
+- Added m4 to BuildRequires
+ Resolves: rhbz#1619111
* Tue Jul 24 2018 Robert Scheck - 2:3.3.1-4
- Add basic postfix TLS configuration by default (#1608050)
diff --git a/postfix.sysusers b/postfix.sysusers
new file mode 100644
index 0000000..7778edf
--- /dev/null
+++ b/postfix.sysusers
@@ -0,0 +1,3 @@
+u postfix 89 - /var/spool/postfix /sbin/nologin
+g postdrop 90
+m postfix mail
diff --git a/sources b/sources
new file mode 100644
index 0000000..3e616c5
--- /dev/null
+++ b/sources
@@ -0,0 +1,2 @@
+SHA512 (pflogsumm-1.1.5.tar.gz) = 994d660692dfea38a1dd9866d15f15035657e85131c1f5a2cd82baa5bd4ad987a00939cb5233f316d2090014c52ae68ef20db0c893f8634969484e0e74678f4d
+SHA512 (postfix-3.8.5.tar.gz) = 26005da5750e7af742f4fc7596ae8320467176e069546c3487418c663b54f56734b4a6541665b8d72d94df2e0fd4f68a2bcc44c50a6d950334d5a5fb2293dff4