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