From a11614b169d153abd7efa2585cdcd5a34fa1604d Mon Sep 17 00:00:00 2001
From: MSVSphere Packaging Team
Date: Fri, 22 Sep 2023 19:28:57 +0300
Subject: [PATCH] import postfix-3.5.9-24.el9
---
.gitignore | 2 +
.postfix.metadata | 2 +
SOURCES/README-Postfix-SASL-RedHat.txt | 440 ++++
SOURCES/pflogsumm-1.1.5-datecalc.patch | 15 +
.../pflogsumm-1.1.5-ipv6-warnings-fix.patch | 13 +
...umm-1.1.5-syslog-name-underscore-fix.patch | 18 +
SOURCES/postfix-3.3.3-alternatives.patch | 22 +
SOURCES/postfix-3.4.0-files.patch | 63 +
SOURCES/postfix-3.4.0-large-fs.patch | 37 +
.../postfix-3.4.4-chroot-example-fix.patch | 35 +
SOURCES/postfix-3.5.0-config.patch | 145 ++
SOURCES/postfix-3.5.9-SRV-resolve.patch | 1586 ++++++++++++++
SOURCES/postfix-3.5.9-coverity-fix.patch | 17 +
.../postfix-3.5.9-glibc-234-build-fix.patch | 12 +
SOURCES/postfix-3.5.9-makedefs.patch | 32 +
.../postfix-3.5.9-whitespace-name-fix.patch | 13 +
SOURCES/postfix-chroot-update | 4 +
SOURCES/postfix-etc-init.d-postfix | 164 ++
SOURCES/postfix-pam.conf | 3 +
SOURCES/postfix-sasl.conf | 2 +
SOURCES/postfix.aliasesdb | 20 +
SOURCES/postfix.service | 22 +
SOURCES/postfix.sysusers | 4 +
SPECS/postfix.spec | 1936 +++++++++++++++++
24 files changed, 4607 insertions(+)
create mode 100644 .gitignore
create mode 100644 .postfix.metadata
create mode 100644 SOURCES/README-Postfix-SASL-RedHat.txt
create mode 100644 SOURCES/pflogsumm-1.1.5-datecalc.patch
create mode 100644 SOURCES/pflogsumm-1.1.5-ipv6-warnings-fix.patch
create mode 100644 SOURCES/pflogsumm-1.1.5-syslog-name-underscore-fix.patch
create mode 100644 SOURCES/postfix-3.3.3-alternatives.patch
create mode 100644 SOURCES/postfix-3.4.0-files.patch
create mode 100644 SOURCES/postfix-3.4.0-large-fs.patch
create mode 100644 SOURCES/postfix-3.4.4-chroot-example-fix.patch
create mode 100644 SOURCES/postfix-3.5.0-config.patch
create mode 100644 SOURCES/postfix-3.5.9-SRV-resolve.patch
create mode 100644 SOURCES/postfix-3.5.9-coverity-fix.patch
create mode 100644 SOURCES/postfix-3.5.9-glibc-234-build-fix.patch
create mode 100644 SOURCES/postfix-3.5.9-makedefs.patch
create mode 100644 SOURCES/postfix-3.5.9-whitespace-name-fix.patch
create mode 100644 SOURCES/postfix-chroot-update
create mode 100644 SOURCES/postfix-etc-init.d-postfix
create mode 100644 SOURCES/postfix-pam.conf
create mode 100644 SOURCES/postfix-sasl.conf
create mode 100644 SOURCES/postfix.aliasesdb
create mode 100644 SOURCES/postfix.service
create mode 100644 SOURCES/postfix.sysusers
create mode 100644 SPECS/postfix.spec
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..cf537d1
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+SOURCES/pflogsumm-1.1.5.tar.gz
+SOURCES/postfix-3.5.9.tar.gz
diff --git a/.postfix.metadata b/.postfix.metadata
new file mode 100644
index 0000000..f0ea2fe
--- /dev/null
+++ b/.postfix.metadata
@@ -0,0 +1,2 @@
+d18daa19d725e64c2b7e6c8da458b2d563272645 SOURCES/pflogsumm-1.1.5.tar.gz
+f7caa483ebbb7f7b4f912dcfb879a5f1017c327e SOURCES/postfix-3.5.9.tar.gz
diff --git a/SOURCES/README-Postfix-SASL-RedHat.txt b/SOURCES/README-Postfix-SASL-RedHat.txt
new file mode 100644
index 0000000..5fa994c
--- /dev/null
+++ b/SOURCES/README-Postfix-SASL-RedHat.txt
@@ -0,0 +1,440 @@
+Quick Start to Authenticate with SASL and PAM:
+----------------------------------------------
+
+If you don't need the details and are an experienced system
+administrator you can just do this, otherwise read on.
+
+1) Edit /etc/postfix/main.cf and set this:
+
+smtpd_sasl_auth_enable = yes
+smtpd_sasl_security_options = noanonymous
+broken_sasl_auth_clients = yes
+
+smtpd_recipient_restrictions =
+ permit_sasl_authenticated,
+ permit_mynetworks,
+ reject_unauth_destination
+
+2) Turn on saslauthd:
+
+ /sbin/chkconfig --level 345 saslauthd on
+ /sbin/service saslauthd start
+
+3) Edit /etc/sysconfig/saslauthd and set this:
+
+ MECH=pam
+
+4) Restart Postfix:
+
+ /sbin/service postfix restart
+
+A crash course in using SASL with Postfix:
+------------------------------------------
+
+Red Hat's Postfix RPMs include support for both SASL and TLS. SASL, the
+Simple Authentication and Security Layer, allows Postfix to implement RFC
+2554, which defines an extension to ESMTP, SMTP AUTH, which compliant
+ESMTP clients can use to authenticate themselves to ESMTP servers.
+Typically, this is used to allow roaming users to relay mail through a
+server safely without configuring the SMTP server to be an open relay.
+Inclusion of TLS support allows Postfix to implement RFC 2487, which
+defines an extension to ESMTP, SMTP STARTTLS, which compliant ESMTP
+clients and servers can use to encrypt the SMTP session. This is a
+security enhancement -- normally SMTP is transmitted as cleartext over the
+wire, making it vulnerable to both passive sniffing and active alteration
+via monkey-in-the-middle attacks. In addition, STARTTLS can also be
+used by either or both server and client to verify the identity of the
+other end, making it useful for the same sorts of purposes as SMTP AUTH.
+The two can even be combined. Typically, this is done by first starting
+TLS, to encrypt the SMTP session, and then issuing the SMTP AUTH command,
+to authenticate the client; this combination ensures that the username
+and password transferred as part of the SMTP AUTH are protected by the
+TLS encrypted session.
+
+SMTP AUTH is implemented using SASL, an abstraction layer which can
+authenticate against a variety of sources. On Red Hat, SASL can use
+the /etc/shadow file, or it can use PAM libraries, or it can use its own
+password database (/etc/sasldb), or it can do various more exotic things.
+
+Authentication raises a number of security concerns for obvious
+reasons. As a consequence authentication services on Red Hat systems
+are restricted to processes running with root privileges. However for
+security reasons it is also essential that a mail server such as
+Postfix run without root privileges so that mail operations cannot
+compromise the host system. This means that Postfix cannot directly
+use authentication services because it does not execute with root
+privileges. The answer to this this problem is to introduce an
+intermediary process that runs with root privileges which Postfix can
+communicate with and will perform authentication on behalf of
+Postfix. The SASL package includes an authentication daemon called
+saslauthd which provided this service, think of it as an
+authentication proxy.
+
+Using Saslauthd:
+----------------
+
+To use saslauthd there are several things you must assure are
+configured.
+
+Selecting an Authentication Method:
+-----------------------------------
+
+Recall that it is saslauthd which is authenticating, not
+Postfix. To start with you must tell Postfix to use saslauthd, in
+main.cf edit this configuration parameter:
+
+ smtpd_sasl_auth_enable = yes
+
+It is also recommended that you disable anonymous logins otherwise
+you've left your system open, so also add this configuration
+parameter.
+
+ smtpd_sasl_security_options = noanonymous
+
+Now you must tell saslauthd which authentication method to use. To
+determine the authentication methods currently supported by saslauthd
+invoke saslauthd with the -v parameter, it will print its version and
+its list of methods and then exit, for example:
+
+ /usr/sbin/saslauthd -v
+ saslauthd 2.1.10
+ authentication mechanisms: getpwent kerberos5 pam rimap shadow
+
+When saslauthd starts up it reads its configuration options from the
+file /etc/sysconfig/saslauthd. Currently there are two parameters
+which can be set in this file, MECH and FLAGS. MECH is the
+authentication mechanism and FLAGS is any command line flags you may
+wish to pass to saslauthd. To tell saslauthd to use a specific
+mechanism edit /etc/sysconfig/saslauthd and set the MECH parameter,
+for example to use PAM it would look like this:
+
+ MECH=pam
+
+Of course you may use any of the other authentication mechanisms that
+saslauthd reported it supports. PAM is an excellent choice as PAM
+supports many of the same authentication methods that saslauthd does,
+but by using PAM you will have centralized all of your authentication
+configuration under PAM which is one of PAM's greatest assets.
+
+How Postfix Interacts with SASL to Name its Authentication Services:
+--------------------------------------------------------------------
+
+It can be very helpful to understand how Postfix communicates with
+SASL to name its authentication services. Knowing this will let you
+identify the configuration files the various components will access.
+
+When Postfix invokes SASL it must give SASL an application name that
+SASL will use among other things to locate a configuration file for
+the application. The application name Postfix identifies itself as is
+"smtpd". SASL will append ".conf" to the application name and look for
+a config file in its library and config directories. Thus SASL will
+read Postfix's configuration from
+
+ /etc/sasl2/smtpd.conf
+
+This file names the authentication method SASL will use for Postfix
+(actually for smtpd, other MTA's such as sendmail may use the same
+file). Because we want to use the saslauthd authentication proxy
+daemon the contents of this file is:
+
+ pwcheck_method: saslauthd
+
+This tells SASL when being invoked to authentication for Postfix that
+it should use saslauthd. Saslauthd's mechanism is set in
+/etc/sysconfig/saslauthd (see below).
+
+When Postfix calls on SASL to authenticate it passes to SASL a service
+name. This service name is used in authentication method specific
+way. The service name Postfix passes to SASL is "smtp" (note this is
+not the same as the application name which is "smtpd"). To understand
+this better consider the case of using PAM authentication. When SASL,
+or in our case saslauthd, invokes PAM it passes the service name of
+"smtp" to PAM which means that when PAM wants to read configuration
+information for this client it will find it under the name of "smtp".
+
+Turning on the Authentication Daemon:
+-------------------------------------
+
+Red Hat security policy is not to automatically enable services
+belonging to a package when the package is installed. The system
+administrator must explicitly enable the service. To enable saslauthd
+do the following:
+
+1) Tell the init process to launch saslauthd when entering various run
+ levels. Assuming you want saslauthd to run at run levels 3,4,5
+ invoke chkconfig.
+
+ /sbin/chkconfig --level 345 saslauthd on
+
+2) You will probably want to start saslauthd now without having to
+ reboot, to do this:
+
+ /sbin/service saslauthd start
+
+Trouble Shooting Authentication:
+--------------------------------
+
+The best way to debug authentication problems is to examine log
+messages from the authentication components. However, normally these
+log messages are suppressed. There are two principle reasons the
+messages are suppressed. The first is that they are typically logged
+at the DEBUG logging priority level which is the lowest priority and
+the syslog configuration typically logs only higher priority
+messages. The second reason is that for security reasons authentication
+logging is considered a risk. Authentication logging has been divided
+into two different facilities, auth and authpriv. authpriv is private
+and is typically shunted off to a different log file with higher
+protection. You will want to be able to see both auth and authpriv
+messages at all priorities. To do this as root edit /etc/syslog.conf
+file, find the following line
+
+authpriv.* /var/log/secure
+
+edit the line to:
+
+authpriv.*;auth.* /var/log/secure
+
+Then restart syslogd so the syslog configuration changes will be
+picked up:
+
+ /sbin/service syslog restart
+
+Now all authentication messages at all priorities will log to
+/var/log/secure.
+
+Using PAM to Authenticate:
+--------------------------
+
+Edit /etc/sysconfig/saslauthd and set MECH to PAM like this:
+
+ MECH=pam
+
+When PAM is invoked via SASL it is passed a service name of
+"smtp". This means that PAM will read its configuration parameters for
+Postfix from the file: /etc/pam.d/smtp. By default this file is set to
+refer to the global system PAM authentication policy, thus by default
+you'll get whatever PAM authentication your system is configured for
+and virtually all applications use. Configuring PAM authentication is
+beyond the scope of this document, please refer to the PAM
+documentation if you which to modify PAM.
+
+Trouble Shooting PAM Authentication:
+------------------------------------
+
+1) One possible reason PAM may fail to authenticate even if the user
+is known to the system is if PAM fails to find the service
+configuration file in /etc/pam.d. Service configuration files are not
+required by PAM, if it does not find a service configuration file it
+will default to "other". Since PAM does not consider the absence of a
+service configuration file a problem it does not log anything nor does
+it return an error to the calling application. In other words it is
+completely silent about the fact it did not find a service
+configuration file. On Red Hat system the default implementation of
+"other" for PAM is to deny access. This means on Red Hat systems the
+absence of a PAM service configuration file will mean PAM will
+silently fail authentication. The PAM service configuration file for
+postfix is /etc/pam.d/smtp and is intalled by the Red Hat Postfix rpm
+and put under control of "alternatives" with name mta. Alternatives
+allows one to select between the sendmail and postfix MTA's and
+manages symbolic links for files the two MTA's share. /etc/pam.d/smtp
+is one such file, if you have not selected Postfix as your prefered
+MTA the link to this file will not be present. To select Postfix as
+your MTA do this: "/usr/sbin/alternatives --config mta" and follow the
+prompt to select postfix.
+
+2) Is SASL appending a realm or domain to a username? PAM
+ authentication requires a bare username and password, other
+ authentication methods require the username to be qualified with a
+ realm. Typically the username will be rewritten as user@realm
+ (e.g. user@foo.com) PAM does not understand a username with
+ "@realm" appended to it and will fail the authentication with the
+ message that the user is unknown. If the log files shows saslauthd
+ usernames with "@realm" appended to it then the
+ smtpd_sasl_local_domain configuration parameter is likely set in
+ /etc/postfix/main.cf file, make sure its either not set or set it
+ to an empty string. Restart postfix and test authtentication again,
+ the log file should show only a bare username.
+
+
+
+Using saslpasswd to Authenticate:
+---------------------------------
+
+SASL can maintain its own password database independent of the host
+system's authentication setup, it is called saslpasswd. You may wish
+to use saslpasswd if you want to isolate who can smtp authenticate
+from general system users. However, it does add another password
+database that a system administrator must maintain.
+
+To authenticate against sasldb, you'll first have to create accounts.
+These accounts are entirely separate from system accounts, and are used
+only by connecting SMTP clients to authenticate themselves. Use the
+saslpassword command:
+
+saslpasswd -u `postconf -h myhostname` -c user
+
+to create an account named user which can log into realm. For the
+realm, make absolutely certain that you use the same value as is set for
+myhostname in /etc/postfix/main.cf. If you don't, it likely won't work.
+
+Also, be aware that saslpasswd is somewhat buggy. The first time you
+run it, it may generate an error message while initializing the sasldb.
+If it does, just add that user a second time.
+
+You'll need to set permissions on the SASL password database so that
+the Postfix daemons can read it:
+
+ chgrp postfix /etc/sasldb
+ chmod g+r /etc/sasldb
+
+Now, you'll need to modify /etc/postfix/main.cf to tell it to
+support SASL. The complete options you might want to use are in the
+sample-auth.cf file in the Postfix documentation directory. An option
+you will definitely need is:
+
+# enable SASL support
+smtpd_sasl_auth_enable = yes
+
+You might also need to set the SASL authentication realm to whatever
+realm you used when you created your sasldb; by default, this is set to
+$myhostname, but you instead might need something like:
+
+# set SASL realm to domain instead
+smtpd_sasl_local_domain = $mydomain
+
+Other Postfix Authentication Parameters:
+----------------------------------------
+
+If you want to allow your already configured users to still use your SMTP
+server, and to allow users authenticated via SMTP AUTH to use your server
+as well, then modify your existing smtpd_recipient_restrictions line to;
+
+# also allow authenticated (RFC 2554) users
+smtpd_recipient_restrictions = permit_sasl_authenticated ...
+
+If you want to restrict use of your server to just authenticated clients
+(Note: this is a bad idea for public mail servers), then instead use:
+
+# restrict server access to authenticated (RFC 2554) clients
+smtpd_delay_reject = yes
+smtpd_client_restrictions = permit_sasl_authenticated ...
+
+SASL supports several password types which have differing security
+properties. Different SMTP clients may support some or all of these
+password types. When the client issues an EHLO command, the server
+tells it which types it supports:
+
+$ telnet station6 25
+Trying 10.100.0.6...
+Connected to station6.example.com.
+Escape character is '^]'.
+220 station6.example.com ESMTP Postfix
+ehlo station7
+250-station6.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-VRFY
+250-ETRN
+250-STARTTLS
+250-AUTH PLAIN LOGIN DIGEST-MD5 CRAM-MD5
+250-XVERP
+250 8BITMIME
+
+Here, the server supports PLAIN, LOGIN, DIGEST-MD5, and CRAM-MD5 password
+methods.
+
+The client then chooses the first of these listed methods which it also
+supports, and issues an SMTP AUTH request.
+
+For security, PLAIN and LOGIN methods are typically disabled. These two
+methods use trivially decryptable encryption, making the username and
+password issued by the client vulnerable to interception via a sniffer
+in between the server and client. Unfortunately, they can't always
+be disabled. Some popular SMTP clients, including MS Outlook 5.x,
+only support PLAIN authentication, for example.
+
+To limit the login methods offered by the server:
+
+# disable unsafe password methods
+smtpd_sasl_security_options = noplaintext noanonymous
+
+Available options are:
+
+noplaintext, which disables LOGIN and PLAIN
+noanonymous, which disables disables ANON
+nodictionary, which disables methods vulnerable to dictionary attacks
+noactive, which disables methods vulnerable to active attacks
+
+The last two are rarely used, since almost all supported methods are
+vulnerable to those attacks ;-).
+
+Also be aware that some broken clients mis-implement the SMTP AUTH
+protocol, and send commands using incorrect syntax (AUTH=foo instead of
+the correct AUTH foo). MS Outlook 4.x clients have this bug, among
+a legion of others.... If you need to support these clients, use:
+
+# support braindead MS products
+broken_sasl_auth_clients = yes
+
+To help prevent spoofing, you can also create a map file of SASL login
+names which are allowed to use specific envelope sender (MAIL FROM)
+addresses. If you choose to do this, you also have to tell Postfix to
+reject addresses which don't match login names:
+
+# prevent spoofing by authenticated users
+reject_sender_login_mismatch
+smtpd_sender_login_maps=type:/path/to/file
+
+Configuration of SASL clients is much simpler. Postfix itself can be
+made a SASL client; this is typically useful when roaming users run Linux
+on their laptop and need to relay mail back through the organization's
+main server.
+
+To enable Postfix to act as an SMTP AUTH client, simply add to
+/etc/postfix/main.cf:
+
+# support authentication (RFC 2557) when relaying through a server
+smtp_sasl_auth_enable = yes
+
+and tell Postfix where to find the usernames and passwords it should
+use to authenticate:
+
+# location of passwords for authentication client
+smtp_sasl_password_maps = type:/path/to/file
+
+The file itself should have the format:
+
+destination username:password
+
+where destination is the name of the server, and username:password are
+the username and password which should be presented to that server to
+authenticate when connecting to it as a client.
+
+Optionally, the authentication methods to be used can be specified for
+the Postfix client, just as they can be for the Postfix server:
+
+# disable plaintext and anonymous
+smtp_sasl_security_options = noplaintext noanonymous
+
+Many popular end-user MUAs can also be configured as SMTP AUTH clients.
+Clients capable of this supplied with Red Hat include pine, Netscape,
+and Mozilla.
+
+Other Sources of Documentation:
+-------------------------------
+
+/usr/share/doc/postfix-/README_FILES/SASL_README
+
+Local configuration examples:
+
+/usr/share/doc/postfix-*/samples
+
+Postfix Howtos, Guides and Tips by Ralf Hildebrandt and Patrick
+Koetter can be found at: http://postfix.state-of-mind.de
+
+------------------------------------------------------------------------------
+
+Please send any comments / corrections to Chris Ricker
+. This material can be freely modified and
+redistributed. Additional material provided by John Dennis
+ and Dax Kelson .
diff --git a/SOURCES/pflogsumm-1.1.5-datecalc.patch b/SOURCES/pflogsumm-1.1.5-datecalc.patch
new file mode 100644
index 0000000..77ca806
--- /dev/null
+++ b/SOURCES/pflogsumm-1.1.5-datecalc.patch
@@ -0,0 +1,15 @@
+diff --git pflogsumm-1.1.5/pflogsumm.pl pflogsumm-1.1.5/pflogsumm.pl
+index 31de5bd..36384dd 100755
+--- pflogsumm-1.1.5/pflogsumm.pl
++++ pflogsumm-1.1.5/pflogsumm.pl
+@@ -398,8 +398,8 @@ Copyright (C) 1998-2010 by James S. Seymour, Release 1.1.5
+ use strict;
+ use locale;
+ use Getopt::Long;
+-eval { require Date::Calc };
+-my $hasDateCalc = $@ ? 0 : 1;
++require Date::Calc;
++my $hasDateCalc = 1;
+
+ my $mailqCmd = "mailq";
+ my $release = "1.1.5";
diff --git a/SOURCES/pflogsumm-1.1.5-ipv6-warnings-fix.patch b/SOURCES/pflogsumm-1.1.5-ipv6-warnings-fix.patch
new file mode 100644
index 0000000..51e759e
--- /dev/null
+++ b/SOURCES/pflogsumm-1.1.5-ipv6-warnings-fix.patch
@@ -0,0 +1,13 @@
+diff --git pflogsumm-1.1.5/pflogsumm.pl pflogsumm-1.1.5/pflogsumm.pl
+index 36384dd..eb527d0 100755
+--- pflogsumm-1.1.5/pflogsumm.pl
++++ pflogsumm-1.1.5/pflogsumm.pl
+@@ -1536,7 +1536,7 @@ sub gimme_domain {
+ # split domain/ipaddr into separates
+ # newer versions of Postfix have them "dom.ain[i.p.add.ress]"
+ # older versions of Postfix have them "dom.ain/i.p.add.ress"
+- unless((($domain, $ipAddr) = /^([^\[]+)\[((?:\d{1,3}\.){3}\d{1,3})\]/) == 2 ||
++ unless((($domain, $ipAddr) = /^([^\[]+)\[((?:\d{1,3}\.){3}\d{1,3}|[0-9a-f:]+)\]/) == 2 ||
+ (($domain, $ipAddr) = /^([^\/]+)\/([0-9a-f.:]+)/i) == 2) {
+ # more exhaustive method
+ ($domain, $ipAddr) = /^([^\[\(\/]+)[\[\(\/]([^\]\)]+)[\]\)]?:?\s*$/;
diff --git a/SOURCES/pflogsumm-1.1.5-syslog-name-underscore-fix.patch b/SOURCES/pflogsumm-1.1.5-syslog-name-underscore-fix.patch
new file mode 100644
index 0000000..9279bcc
--- /dev/null
+++ b/SOURCES/pflogsumm-1.1.5-syslog-name-underscore-fix.patch
@@ -0,0 +1,18 @@
+diff --git a/pflogsumm-1.1.5/pflogsumm.pl b/pflogsumm-1.1.5/pflogsumm.pl
+index eb527d0..7e26206 100755
+--- a/pflogsumm-1.1.5/pflogsumm.pl
++++ b/pflogsumm-1.1.5/pflogsumm.pl
+@@ -503,7 +503,12 @@ $usageMsg =
+ # Accept either "_"s or "-"s in --switches
+ foreach (@ARGV) {
+ last if($_ eq "--");
+- tr/_/-/ if(/^--\w/);
++ if (/^--\w/)
++ {
++ my @argspl = split("=", $_, 2);
++ $argspl[0] =~ tr/_/-/;
++ $_ = join("=", @argspl);
++ }
+ }
+
+ # Some pre-inits for convenience
diff --git a/SOURCES/postfix-3.3.3-alternatives.patch b/SOURCES/postfix-3.3.3-alternatives.patch
new file mode 100644
index 0000000..2c3ba18
--- /dev/null
+++ b/SOURCES/postfix-3.3.3-alternatives.patch
@@ -0,0 +1,22 @@
+diff --git a/conf/post-install b/conf/post-install
+index 25ef7e6..4fd6434 100644
+--- a/conf/post-install
++++ b/conf/post-install
+@@ -537,6 +537,17 @@ test -n "$create" && {
+ case $path in
+ no|no/*) continue;;
+ esac
++ # Munge paths for alternatives.
++ case $path in
++ /usr/bin/mailq) path=$path.postfix ;;
++ /usr/bin/newaliases) path=$path.postfix ;;
++ /usr/bin/rmail) path=$path.postfix ;;
++ /usr/sbin/sendmail) path=$path.postfix ;;
++ /usr/share/man/man1/mailq.1.gz) path=/usr/share/man/man1/mailq.postfix.1.gz ;;
++ /usr/share/man/man1/newaliases.1.gz) path=/usr/share/man/man1/newaliases.postfix.1.gz ;;
++ /usr/share/man/man5/aliases.5.gz) path=/usr/share/man/man5/aliases.postfix.5.gz ;;
++ /usr/share/man/man8/smtpd.8.gz) path=/usr/share/man/man8/smtpd.postfix.8.gz ;;
++ esac
+ # Pick up the flags.
+ case $flags in *u*) upgrade_flag=1;; *) upgrade_flag=;; esac
+ case $flags in *c*) create_flag=1;; *) create_flag=;; esac
diff --git a/SOURCES/postfix-3.4.0-files.patch b/SOURCES/postfix-3.4.0-files.patch
new file mode 100644
index 0000000..ad73553
--- /dev/null
+++ b/SOURCES/postfix-3.4.0-files.patch
@@ -0,0 +1,63 @@
+diff --git a/conf/postfix-files b/conf/postfix-files
+index 4ed9d1f..19711d2 100644
+--- a/conf/postfix-files
++++ b/conf/postfix-files
+@@ -83,7 +83,6 @@ $shlib_directory/${LIB_PREFIX}sqlite${LIB_SUFFIX}:f:root:-:755
+ $meta_directory/dynamicmaps.cf.d:d:root:-:755
+ $meta_directory/dynamicmaps.cf:f:root:-:644
+ $meta_directory/main.cf.proto:f:root:-:644
+-$meta_directory/makedefs.out:f:root:-:644
+ $meta_directory/master.cf.proto:f:root:-:644
+ $meta_directory/postfix-files.d:d:root:-:755
+ $meta_directory/postfix-files:f:root:-:644
+@@ -141,18 +140,13 @@ $command_directory/postqueue:f:root:$setgid_group:2755:u
+ $sendmail_path:f:root:-:755
+ $newaliases_path:l:$sendmail_path
+ $mailq_path:l:$sendmail_path
+-$config_directory/LICENSE:f:root:-:644:1
+-$config_directory/TLS_LICENSE:f:root:-:644:1
+ $config_directory/access:f:root:-:644:p1
+-$config_directory/aliases:f:root:-:644:p1
+-$config_directory/bounce.cf.default:f:root:-:644:1
+ $config_directory/canonical:f:root:-:644:p1
+ $config_directory/cidr_table:f:root:-:644:o
+ $config_directory/generic:f:root:-:644:p1
+ $config_directory/generics:f:root:-:644:o
+ $config_directory/header_checks:f:root:-:644:p1
+ $config_directory/install.cf:f:root:-:644:o
+-$config_directory/main.cf.default:f:root:-:644:1
+ $config_directory/main.cf:f:root:-:644:p
+ $config_directory/master.cf:f:root:-:644:p
+ $config_directory/pcre_table:f:root:-:644:o
+@@ -165,8 +159,8 @@ $config_directory/postfix-script:f:root:-:755:o
+ $config_directory/postfix-script-sgid:f:root:-:755:o
+ $config_directory/postfix-script-nosgid:f:root:-:755:o
+ $config_directory/post-install:f:root:-:755:o
+-$manpage_directory/man1/mailq.1:f:root:-:644
+-$manpage_directory/man1/newaliases.1:f:root:-:644
++$manpage_directory/man1/mailq.postfix.1:f:root:-:644
++$manpage_directory/man1/newaliases.postfix.1:f:root:-:644
+ $manpage_directory/man1/postalias.1:f:root:-:644
+ $manpage_directory/man1/postcat.1:f:root:-:644
+ $manpage_directory/man1/postconf.1:f:root:-:644
+@@ -180,9 +174,9 @@ $manpage_directory/man1/postmap.1:f:root:-:644
+ $manpage_directory/man1/postmulti.1:f:root:-:644
+ $manpage_directory/man1/postqueue.1:f:root:-:644
+ $manpage_directory/man1/postsuper.1:f:root:-:644
+-$manpage_directory/man1/sendmail.1:f:root:-:644
++$manpage_directory/man1/sendmail.postfix.1:f:root:-:644
+ $manpage_directory/man5/access.5:f:root:-:644
+-$manpage_directory/man5/aliases.5:f:root:-:644
++$manpage_directory/man5/aliases.postfix.5:f:root:-:644
+ $manpage_directory/man5/body_checks.5:f:root:-:644
+ $manpage_directory/man5/bounce.5:f:root:-:644
+ $manpage_directory/man5/canonical.5:f:root:-:644
+@@ -230,7 +224,7 @@ $manpage_directory/man8/qmqpd.8:f:root:-:644
+ $manpage_directory/man8/scache.8:f:root:-:644
+ $manpage_directory/man8/showq.8:f:root:-:644
+ $manpage_directory/man8/smtp.8:f:root:-:644
+-$manpage_directory/man8/smtpd.8:f:root:-:644
++$manpage_directory/man8/smtpd.postfix.8:f:root:-:644
+ $manpage_directory/man8/spawn.8:f:root:-:644
+ $manpage_directory/man8/tlsproxy.8:f:root:-:644
+ $manpage_directory/man8/tlsmgr.8:f:root:-:644
diff --git a/SOURCES/postfix-3.4.0-large-fs.patch b/SOURCES/postfix-3.4.0-large-fs.patch
new file mode 100644
index 0000000..fbc55f1
--- /dev/null
+++ b/SOURCES/postfix-3.4.0-large-fs.patch
@@ -0,0 +1,37 @@
+diff --git a/src/util/fsspace.c b/src/util/fsspace.c
+index 50a4aa7..beef3db 100644
+--- a/src/util/fsspace.c
++++ b/src/util/fsspace.c
+@@ -91,8 +91,15 @@ void fsspace(const char *path, struct fsspace * sp)
+
+ if (statvfs(path, &fsbuf) < 0)
+ msg_fatal("statvfs %s: %m", path);
+- sp->block_size = fsbuf.f_frsize;
+- sp->block_free = fsbuf.f_bavail;
++ if (fsbuf.f_frsize > 0)
++ sp->block_size = fsbuf.f_frsize;
++ else
++ sp->block_size = fsbuf.f_bsize;
++ /* 4G of FS blocks is surely enough space to put a mail in */
++ sp->block_free = 0;
++ sp->block_free = ~sp->block_free;
++ if (fsbuf.f_bavail < sp->block_free)
++ sp->block_free = fsbuf.f_bavail;
+ #endif
+ 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
+--- a/src/util/sys_defs.h
++++ b/src/util/sys_defs.h
+@@ -769,8 +769,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
+-#define USE_STATFS
+-#define STATFS_IN_SYS_VFS_H
++#define USE_STATVFS
++#define STATVFS_IN_SYS_STATVFS_H
+ #define PREPEND_PLUS_TO_OPTSTRING
+ #define HAS_POSIX_REGEXP
+ #define HAS_DLOPEN
diff --git a/SOURCES/postfix-3.4.4-chroot-example-fix.patch b/SOURCES/postfix-3.4.4-chroot-example-fix.patch
new file mode 100644
index 0000000..5870b4c
--- /dev/null
+++ b/SOURCES/postfix-3.4.4-chroot-example-fix.patch
@@ -0,0 +1,35 @@
+--- a/examples/chroot-setup/LINUX2 2006-01-01 15:53:58.000000000 -0800
++++ b/examples/chroot-setup/LINUX2 2016-11-27 00:45:52.145301784 -0800
+@@ -45,14 +45,14 @@
+ # 20060101 /lib64 support by Keith Owens.
+ #
+
+-CP="cp -p"
++CP="cp -p -Z"
+
+ cond_copy() {
+ # find files as per pattern in $1
+ # if any, copy to directory $2
+ dir=`dirname "$1"`
+ pat=`basename "$1"`
+- lr=`find "$dir" -maxdepth 1 -name "$pat"`
++ lr=`find "$dir/" -maxdepth 1 -name "$pat"`
+ if test ! -d "$2" ; then exit 1 ; fi
+ if test "x$lr" != "x" ; then $CP $1 "$2" ; fi
+ }
+@@ -63,8 +63,8 @@
+ POSTFIX_DIR=${POSTFIX_DIR-/var/spool/postfix}
+ cd ${POSTFIX_DIR}
+
+-mkdir -p etc lib usr/lib/zoneinfo
+-test -d /lib64 && mkdir -p lib64
++mkdir -p -Z etc lib usr/lib/zoneinfo
++test -d /lib64 && mkdir -p -Z lib64
+
+ # find localtime (SuSE 5.3 does not have /etc/localtime)
+ lt=/etc/localtime
+@@ -88,4 +88,3 @@
+ cond_copy '/lib64/libdb.so*' lib64
+ fi
+
+-postfix reload
diff --git a/SOURCES/postfix-3.5.0-config.patch b/SOURCES/postfix-3.5.0-config.patch
new file mode 100644
index 0000000..da42263
--- /dev/null
+++ b/SOURCES/postfix-3.5.0-config.patch
@@ -0,0 +1,145 @@
+diff --git a/conf/main.cf b/conf/main.cf
+index 7af8bde..495e346 100644
+--- a/conf/main.cf
++++ b/conf/main.cf
+@@ -132,6 +132,10 @@ mail_owner = postfix
+ #inet_interfaces = all
+ #inet_interfaces = $myhostname
+ #inet_interfaces = $myhostname, localhost
++inet_interfaces = localhost
++
++# Enable IPv4, and IPv6 if supported
++inet_protocols = all
+
+ # 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
+ #
+ # See also below, section "REJECTING MAIL FOR UNKNOWN LOCAL USERS".
+ #
+-#mydestination = $myhostname, localhost.$mydomain, localhost
++mydestination = $myhostname, localhost.$mydomain, localhost
+ #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
+ # "postfix reload" to eliminate the delay.
+ #
+ #alias_maps = dbm:/etc/aliases
+-#alias_maps = hash:/etc/aliases
++alias_maps = hash:/etc/aliases
+ #alias_maps = hash:/etc/aliases, nis:mail.aliases
+ #alias_maps = netinfo:/aliases
+
+@@ -409,7 +413,7 @@ unknown_local_recipient_reject_code = 550
+ #
+ #alias_database = dbm:/etc/aliases
+ #alias_database = dbm:/etc/mail/aliases
+-#alias_database = hash:/etc/aliases
++alias_database = hash:/etc/aliases
+ #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
+ #
+ # Cyrus IMAP over LMTP. Specify ``lmtpunix cmd="lmtpd"
+ # listen="/var/imap/socket/lmtp" prefork=0'' in cyrus.conf.
+-#mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
++#mailbox_transport = lmtp:unix:/var/lib/imap/socket/lmtp
++
++# If using the cyrus-imapd IMAP server deliver local mail to the IMAP
++# server using LMTP (Local Mail Transport Protocol), this is prefered
++# over the older cyrus deliver program by setting the
++# mailbox_transport as below:
++#
++# mailbox_transport = lmtp:unix:/var/lib/imap/socket/lmtp
++#
++# The efficiency of LMTP delivery for cyrus-imapd can be enhanced via
++# these settings.
++#
++# local_destination_recipient_limit = 300
++# local_destination_concurrency_limit = 5
++#
++# Of course you should adjust these settings as appropriate for the
++# capacity of the hardware you are using. The recipient limit setting
++# can be used to take advantage of the single instance message store
++# capability of Cyrus. The concurrency limit can be used to control
++# how many simultaneous LMTP sessions will be permitted to the Cyrus
++# message store.
+ #
+ # 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
+ # the main.cf file, otherwise the SMTP server will reject mail for
+ # non-UNIX accounts with "User unknown in local recipient table".
+ #
+-#fallback_transport = lmtp:unix:/file/name
+-#fallback_transport = cyrus
++#fallback_transport = lmtp:unix:/var/lib/imap/socket/lmtp
+ #fallback_transport =
+
+ # The luser_relay parameter specifies an optional destination address
+@@ -673,4 +696,41 @@ sample_directory =
+ # readme_directory: The location of the Postfix README files.
+ #
+ readme_directory =
+-inet_protocols = ipv4
++
++# TLS CONFIGURATION
++#
++# Basic Postfix TLS configuration by default with self-signed certificate
++# for inbound SMTP and also opportunistic TLS for outbound SMTP.
++
++# The full pathname of a file with the Postfix SMTP server RSA certificate
++# in PEM format. Intermediate certificates should be included in general,
++# the server certificate first, then the issuing CA(s) (bottom-up order).
++#
++smtpd_tls_cert_file = /etc/pki/tls/certs/postfix.pem
++
++# The full pathname of a file with the Postfix SMTP server RSA private key
++# in PEM format. The private key must be accessible without a pass-phrase,
++# i.e. it must not be encrypted.
++#
++smtpd_tls_key_file = /etc/pki/tls/private/postfix.key
++
++# Announce STARTTLS support to remote SMTP clients, but do not require that
++# clients use TLS encryption (opportunistic TLS inbound).
++#
++smtpd_tls_security_level = may
++
++# Directory with PEM format Certification Authority certificates that the
++# Postfix SMTP client uses to verify a remote SMTP server certificate.
++#
++smtp_tls_CApath = /etc/pki/tls/certs
++
++# The full pathname of a file containing CA certificates of root CAs
++# trusted to sign either remote SMTP server certificates or intermediate CA
++# certificates.
++#
++smtp_tls_CAfile = /etc/pki/tls/certs/ca-bundle.crt
++
++# Use TLS if this is supported by the remote SMTP server, otherwise use
++# plaintext (opportunistic TLS outbound).
++#
++smtp_tls_security_level = may
+diff --git a/conf/master.cf b/conf/master.cf
+index c0f2508..05c5d07 100644
+--- a/conf/master.cf
++++ b/conf/master.cf
+@@ -98,14 +98,14 @@ postlog unix-dgram n - n - 1 postlogd
+ # Also specify in main.cf: cyrus_destination_recipient_limit=1
+ #
+ #cyrus unix - n n - - pipe
+-# flags=DRX user=cyrus argv=/cyrus/bin/deliver -e -r ${sender} -m ${extension} ${user}
++# flags=DRX user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -r ${sender} -m ${extension} ${user}
+ #
+ # ====================================================================
+ #
+ # Old example of delivery via Cyrus.
+ #
+ #old-cyrus unix - n n - - pipe
+-# flags=R user=cyrus argv=/cyrus/bin/deliver -e -m ${extension} ${user}
++# flags=R user=cyrus argv=/usr/lib/cyrus-imapd/deliver -e -m ${extension} ${user}
+ #
+ # ====================================================================
+ #
diff --git a/SOURCES/postfix-3.5.9-SRV-resolve.patch b/SOURCES/postfix-3.5.9-SRV-resolve.patch
new file mode 100644
index 0000000..f04e43a
--- /dev/null
+++ b/SOURCES/postfix-3.5.9-SRV-resolve.patch
@@ -0,0 +1,1586 @@
+commit 3a64b35100aa150ce80957dc56f0db7fbdb07017
+Author: Tomas Korbar
+Date: Wed May 17 10:01:21 2023 +0200
+
+ Backport SRV record resolution feature
+
+diff --git a/mantools/postlink b/mantools/postlink
+index 490d028..a093c0a 100755
+--- a/mantools/postlink
++++ b/mantools/postlink
+@@ -1129,6 +1129,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 89f9e9b..ca8899f 100644
+--- a/proto/postconf.proto
++++ b/proto/postconf.proto
+@@ -17760,3 +17760,111 @@ value to disable the feature.
+
+ This feature was backported from Postfix 3.6 to Postfix versions
+ 3.5.9, 3.4.19, 3.3.16. 3.2.21.
++
++%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 3631d23..2af1ee2 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 *);
+@@ -283,8 +300,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 4e3e647..93694d9 100644
+--- a/src/dns/dns_lookup.c
++++ b/src/dns/dns_lookup.c
+@@ -691,6 +691,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;
+@@ -716,6 +718,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)
+@@ -811,7 +825,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);
+ }
+
+@@ -911,7 +925,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;
+@@ -1045,6 +1059,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 27b17d5..e8d9c28 100644
+--- a/src/global/mail_params.h
++++ b/src/global/mail_params.h
+@@ -4209,6 +4209,21 @@ extern char *var_info_log_addr_form;
+ #define DEF_DNSSEC_PROBE "ns:."
+ extern char *var_dnssec_probe;
+
++ /*
++ * 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..60bf047 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 e46ebd6..2cc9e2f 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)
+@@ -336,6 +337,17 @@
+ /* The DNS query type (default: "ns") and DNS query name (default:
+ /* ".") that Postfix may use to determine whether DNSSEC validation
+ /* is available.
++/* .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
+@@ -1052,6 +1064,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;
+@@ -1074,6 +1089,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
+
+@@ -1357,6 +1373,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.9-coverity-fix.patch b/SOURCES/postfix-3.5.9-coverity-fix.patch
new file mode 100644
index 0000000..4f94baa
--- /dev/null
+++ b/SOURCES/postfix-3.5.9-coverity-fix.patch
@@ -0,0 +1,17 @@
+diff --git a/src/util/dict_inline.c b/src/util/dict_inline.c
+index a416d7c..72339b2 100644
+--- a/src/util/dict_inline.c
++++ b/src/util/dict_inline.c
+@@ -113,9 +113,9 @@ DICT *dict_inline_open(const char *name, int open_flags, int dict_flags)
+ dict = dict_open3(DICT_TYPE_HT, name, open_flags, dict_flags);
+ dict_type_override(dict, DICT_TYPE_INLINE);
+ while ((nameval = mystrtokq(&cp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
+- if ((nameval[0] != CHARS_BRACE[0]
+- || (err = free_me = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP)) == 0)
+- && (err = split_qnameval(nameval, &vname, &value)) != 0)
++ if (nameval[0] == CHARS_BRACE[0])
++ err = free_me = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP);
++ if (err != 0 || (err = split_qnameval(nameval, &vname, &value)) != 0)
+ break;
+
+ if ((dict->flags & DICT_FLAG_SRC_RHS_IS_FILE) != 0) {
diff --git a/SOURCES/postfix-3.5.9-glibc-234-build-fix.patch b/SOURCES/postfix-3.5.9-glibc-234-build-fix.patch
new file mode 100644
index 0000000..5fb9aeb
--- /dev/null
+++ b/SOURCES/postfix-3.5.9-glibc-234-build-fix.patch
@@ -0,0 +1,12 @@
+diff --git a/src/util/sys_defs.h b/src/util/sys_defs.h
+index 99bec9b..95c78ec 100644
+--- a/src/util/sys_defs.h
++++ b/src/util/sys_defs.h
+@@ -802,6 +803,7 @@ extern int initgroups(const char *, int);
+ #define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
+ #endif
+ #endif
++#define HAS_CLOSEFROM
+ #include
+ #if !defined(KERNEL_VERSION)
+ #define KERNEL_VERSION(a,b,c) (LINUX_VERSION_CODE + 1)
diff --git a/SOURCES/postfix-3.5.9-makedefs.patch b/SOURCES/postfix-3.5.9-makedefs.patch
new file mode 100644
index 0000000..24b0ea5
--- /dev/null
+++ b/SOURCES/postfix-3.5.9-makedefs.patch
@@ -0,0 +1,32 @@
+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.9-whitespace-name-fix.patch b/SOURCES/postfix-3.5.9-whitespace-name-fix.patch
new file mode 100644
index 0000000..c45035e
--- /dev/null
+++ b/SOURCES/postfix-3.5.9-whitespace-name-fix.patch
@@ -0,0 +1,13 @@
+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-chroot-update b/SOURCES/postfix-chroot-update
new file mode 100644
index 0000000..9fa0b08
--- /dev/null
+++ b/SOURCES/postfix-chroot-update
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+[ -x /etc/postfix/chroot-update ] && exec /etc/postfix/chroot-update
+exit 0
diff --git a/SOURCES/postfix-etc-init.d-postfix b/SOURCES/postfix-etc-init.d-postfix
new file mode 100644
index 0000000..c609b0a
--- /dev/null
+++ b/SOURCES/postfix-etc-init.d-postfix
@@ -0,0 +1,164 @@
+#!/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() {
+ 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
+ /usr/bin/newaliases
+ touch -r /etc/aliases.db "$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/SOURCES/postfix-pam.conf
new file mode 100644
index 0000000..73e5348
--- /dev/null
+++ b/SOURCES/postfix-pam.conf
@@ -0,0 +1,3 @@
+#%PAM-1.0
+auth include password-auth
+account include password-auth
diff --git a/SOURCES/postfix-sasl.conf b/SOURCES/postfix-sasl.conf
new file mode 100644
index 0000000..18d7308
--- /dev/null
+++ b/SOURCES/postfix-sasl.conf
@@ -0,0 +1,2 @@
+pwcheck_method: saslauthd
+mech_list: plain login
diff --git a/SOURCES/postfix.aliasesdb b/SOURCES/postfix.aliasesdb
new file mode 100644
index 0000000..8c0156e
--- /dev/null
+++ b/SOURCES/postfix.aliasesdb
@@ -0,0 +1,20 @@
+#!/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/postfix.service b/SOURCES/postfix.service
new file mode 100644
index 0000000..1016ac3
--- /dev/null
+++ b/SOURCES/postfix.service
@@ -0,0 +1,22 @@
+[Unit]
+Description=Postfix Mail Transport Agent
+After=syslog.target network.target
+Conflicts=sendmail.service exim.service
+
+[Service]
+Type=forking
+PIDFile=/var/spool/postfix/pid/master.pid
+EnvironmentFile=-/etc/sysconfig/network
+PrivateTmp=true
+CapabilityBoundingSet=~ CAP_NET_ADMIN CAP_SYS_ADMIN CAP_SYS_BOOT CAP_SYS_MODULE
+ProtectSystem=true
+PrivateDevices=true
+ExecStartPre=-/usr/sbin/restorecon -R /var/spool/postfix/pid
+ExecStartPre=-/usr/libexec/postfix/aliasesdb
+ExecStartPre=-/usr/libexec/postfix/chroot-update
+ExecStart=/usr/sbin/postfix start
+ExecReload=/usr/sbin/postfix reload
+ExecStop=/usr/sbin/postfix stop
+
+[Install]
+WantedBy=multi-user.target
diff --git a/SOURCES/postfix.sysusers b/SOURCES/postfix.sysusers
new file mode 100644
index 0000000..876b305
--- /dev/null
+++ b/SOURCES/postfix.sysusers
@@ -0,0 +1,4 @@
+u postfix 89 - /var/spool/postfix /sbin/nologin
+g postdrop 90
+g mail 12
+m postfix mail
diff --git a/SPECS/postfix.spec b/SPECS/postfix.spec
new file mode 100644
index 0000000..f7b5df9
--- /dev/null
+++ b/SPECS/postfix.spec
@@ -0,0 +1,1936 @@
+# plugins have unresolvable symbols in compile time
+%undefine _strict_symbol_defs_build
+
+%bcond_without mysql
+%bcond_without pgsql
+%bcond_without sqlite
+%bcond_without cdb
+%bcond_without ldap
+%bcond_without lmdb
+%bcond_without pcre
+%bcond_without sasl
+%bcond_without tls
+%bcond_without ipv6
+%bcond_without pflogsumm
+
+%global sysv2systemdnvr 2.8.12-2
+
+# hardened build if not overrided
+%{!?_hardened_build:%global _hardened_build 1}
+
+# 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!
+# It's now handled by systemd-sysusers.
+%define postfix_user postfix
+%define maildrop_group postdrop
+
+%define postfix_config_dir %{_sysconfdir}/postfix
+%define postfix_daemon_dir %{_libexecdir}/postfix
+%define postfix_shlib_dir %{_libdir}/postfix
+%define postfix_command_dir %{_sbindir}
+%define postfix_queue_dir %{_var}/spool/postfix
+%define postfix_data_dir %{_var}/lib/postfix
+%define postfix_doc_dir %{?_pkgdocdir}%{!?_pkgdocdir:%{_docdir}/%{name}-%{version}}
+%define postfix_sample_dir %{postfix_doc_dir}/samples
+%define postfix_readme_dir %{postfix_doc_dir}/README_FILES
+
+%global sslcert %{_sysconfdir}/pki/tls/certs/postfix.pem
+%global sslkey %{_sysconfdir}/pki/tls/private/postfix.key
+
+# Filter private libraries
+%global _privatelibs libpostfix-.+\.so.*
+%global __provides_exclude ^(%{_privatelibs})$
+%global __requires_exclude ^(%{_privatelibs})$
+
+Name: postfix
+Summary: Postfix Mail Transport Agent
+Version: 3.5.9
+Release: 24%{?dist}
+Epoch: 2
+URL: http://www.postfix.org
+License: (IBM and GPLv2+) or (EPL-2.0 and GPLv2+)
+Requires(post): systemd systemd-sysv hostname
+Requires(post): %{_sbindir}/alternatives
+Requires(post): %{_bindir}/openssl
+Requires(preun): %{_sbindir}/alternatives
+Requires(preun): systemd
+Requires(postun): systemd
+# Required by /usr/libexec/postfix/postfix-script
+Requires: diffutils
+Requires: findutils
+# for restorecon
+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: postfix.sysusers
+
+# Sources 50-99 are upstream [patch] contributions
+
+%define pflogsumm_ver 1.1.5
+
+# Postfix Log Entry Summarizer: http://jimsun.linxnet.com/postfix_contrib.html
+Source53: http://jimsun.linxnet.com/downloads/pflogsumm-%{pflogsumm_ver}.tar.gz
+
+# Sources >= 100 are config files
+
+Source100: postfix-sasl.conf
+Source101: postfix-pam.conf
+
+# Patches
+
+Patch1: postfix-3.5.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
+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
+# unconditional glibc-2.34 API assumption, because it seems
+# in RHEL-9 this feature was also backported to 2.33,
+# upstream uses conditional check for 2.34 API
+Patch12: postfix-3.5.9-glibc-234-build-fix.patch
+# rhbz#1978901, sent upstream
+Patch13: postfix-3.5.9-whitespace-name-fix.patch
+Patch14: pflogsumm-1.1.5-syslog-name-underscore-fix.patch
+# rhbz#1938847, backported from upstream
+Patch15: postfix-3.5.9-coverity-fix.patch
+# rhbz#2134789, backported feature from upstream
+Patch16: postfix-3.5.9-SRV-resolve.patch
+# rhbz#2193363 ZUUL CI uses kernel 6 and we have to add this to postfix
+Patch17: postfix-3.5.9-makedefs.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: make
+BuildRequires: libdb-devel, perl-generators, pkgconfig, zlib-devel
+BuildRequires: systemd-units, libicu-devel
+BuildRequires: gcc, m4, findutils
+BuildRequires: systemd-rpm-macros
+%if 0%{?rhel} < 9
+BuildRequires: libnsl2-devel
+%endif
+
+%{?with_ldap:BuildRequires: openldap-devel}
+%{?with_lmdb:BuildRequires: lmdb-devel}
+%{?with_sasl:BuildRequires: cyrus-sasl-devel}
+%{?with_pcre:BuildRequires: pcre-devel}
+%{?with_mysql:BuildRequires: mariadb-connector-c-devel}
+%{?with_pgsql:BuildRequires: libpq-devel}
+%{?with_sqlite:BuildRequires: sqlite-devel}
+%{?with_cdb:BuildRequires: tinycdb-devel}
+%{?with_tls:BuildRequires: openssl-devel}
+
+%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
+Requires: %{name} = %{epoch}:%{version}-%{release}
+# perl-scripts introduced in 2:2.5.5-2
+Obsoletes: postfix < 2:2.5.5-2
+%if %{with pflogsumm}
+Provides: postfix-pflogsumm = %{epoch}:%{version}-%{release}
+Obsoletes: postfix-pflogsumm < 2:2.5.5-2
+%endif
+%description perl-scripts
+This package contains perl scripts pflogsumm and qshape.
+
+Pflogsumm is a log analyzer/summarizer for the Postfix MTA. It is
+designed to provide an over-view of Postfix activity. Pflogsumm
+generates summaries and, in some cases, detailed reports of mail
+server traffic volumes, rejected and bounced email, and server
+warnings, errors and panics.
+
+qshape prints Postfix queue domain and age distribution.
+
+%if %{with mysql}
+%package mysql
+Summary: Postfix MySQL map support
+Requires: %{name} = %{epoch}:%{version}-%{release}
+
+%description mysql
+This provides support for MySQL maps in Postfix. If you plan to use MySQL
+maps with Postfix, you need this.
+%endif
+
+%if %{with pgsql}
+%package pgsql
+Summary: Postfix PostgreSQL map support
+Requires: %{name} = %{epoch}:%{version}-%{release}
+
+%description pgsql
+This provides support for PostgreSQL maps in Postfix. If you plan to use
+PostgreSQL maps with Postfix, you need this.
+%endif
+
+%if %{with sqlite}
+%package sqlite
+Summary: Postfix SQLite map support
+Requires: %{name} = %{epoch}:%{version}-%{release}
+
+%description sqlite
+This provides support for SQLite maps in Postfix. If you plan to use SQLite
+maps with Postfix, you need this.
+%endif
+
+%if %{with cdb}
+%package cdb
+Summary: Postfix CDB map support
+Requires: %{name} = %{epoch}:%{version}-%{release}
+
+%description cdb
+This provides support for CDB maps in Postfix. If you plan to use CDB
+maps with Postfix, you need this.
+%endif
+
+%if %{with ldap}
+%package ldap
+Summary: Postfix LDAP map support
+Requires: %{name} = %{epoch}:%{version}-%{release}
+
+%description ldap
+This provides support for LDAP maps in Postfix. If you plan to use LDAP
+maps with Postfix, you need this.
+%endif
+
+%if %{with lmdb}
+%package lmdb
+Summary: Postfix LDMB map support
+Requires: %{name} = %{epoch}:%{version}-%{release}
+
+%description lmdb
+This provides support for LMDB maps in Postfix. If you plan to use LMDB
+maps with Postfix, you need this.
+%endif
+
+%if %{with pcre}
+%package pcre
+Summary: Postfix PCRE map support
+Requires: %{name} = %{epoch}:%{version}-%{release}
+
+%description pcre
+This provides support for PCRE maps in Postfix. If you plan to use PCRE
+maps with Postfix, you need this.
+%endif
+
+%prep
+%setup -q
+# Apply obligatory patches
+%patch1 -p1 -b .config
+%patch2 -p1 -b .files
+%patch3 -p1 -b .alternatives
+%patch4 -p1 -b .large-fs
+
+# Change DEF_SHLIB_DIR according to build host
+sed -i \
+'s|^\(\s*#define\s\+DEF_SHLIB_DIR\s\+\)"/usr/lib/postfix"|\1"%{_libdir}/postfix"|' \
+src/global/mail_params.h
+
+%if %{with pflogsumm}
+gzip -dc %{SOURCE53} | tar xf -
+pushd pflogsumm-%{pflogsumm_ver}
+%patch9 -p1 -b .datecalc
+%patch10 -p1 -b .ipv6-warnings-fix
+popd
+%endif
+%patch11 -p1 -b .chroot-example-fix
+%patch12 -p1 -b .glibc-234-build-fix
+%patch13 -p1 -b .whitespace-name-fix
+%patch14 -p1 -b .pflogsumm-1.1.5-syslog-name-underscore-fix
+%patch15 -p1 -b .coverity-fix
+%patch16 -p1 -b .SRV-resolution
+%patch17 -p1 -b .makedefs
+
+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
+
+%build
+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
+
+%ifarch s390 s390x ppc
+CCARGS="${CCARGS} -fsigned-char"
+%endif
+
+%if %{with ldap}
+ CCARGS="${CCARGS} -DHAS_LDAP -DLDAP_DEPRECATED=1 %{?with_sasl:-DUSE_LDAP_SASL}"
+ AUXLIBS_LDAP="-lldap -llber"
+%endif
+%if %{with lmdb}
+ CCARGS="${CCARGS} -DHAS_LMDB"
+ 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"
+%endif
+%if %{with mysql}
+ CCARGS="${CCARGS} -DHAS_MYSQL -I%{_includedir}/mysql"
+ AUXLIBS_MYSQL="-L%{_libdir}/mariadb -lmysqlclient -lm"
+%endif
+%if %{with pgsql}
+ CCARGS="${CCARGS} -DHAS_PGSQL -I%{_includedir}/pgsql"
+ AUXLIBS_PGSQL="-lpq"
+%endif
+%if %{with sqlite}
+ CCARGS="${CCARGS} -DHAS_SQLITE `pkg-config --cflags sqlite3`"
+ AUXLIBS_SQLITE="`pkg-config --libs sqlite3`"
+%endif
+%if %{with cdb}
+ CCARGS="${CCARGS} -DHAS_CDB `pkg-config --cflags libcdb`"
+ AUXLIBS_CDB="`pkg-config --libs libcdb`"
+%endif
+%if %{with sasl}
+ CCARGS="${CCARGS} -DUSE_SASL_AUTH -DUSE_CYRUS_SASL -I%{_includedir}/sasl"
+ AUXLIBS="${AUXLIBS} -L%{_libdir}/sasl2 -lsasl2"
+ %global sasl_config_dir %{_sysconfdir}/sasl2
+%endif
+%if %{with tls}
+ if pkg-config openssl ; then
+ CCARGS="${CCARGS} -DUSE_TLS `pkg-config --cflags openssl`"
+ AUXLIBS="${AUXLIBS} `pkg-config --libs openssl`"
+ else
+ CCARGS="${CCARGS} -DUSE_TLS -I%{_includedir}/openssl"
+ AUXLIBS="${AUXLIBS} -lssl -lcrypto"
+ fi
+%endif
+%if ! %{with ipv6}
+ CCARGS="${CCARGS} -DNO_IPV6"
+%endif
+
+CCARGS="${CCARGS} -DDEF_CONFIG_DIR=\\\"%{postfix_config_dir}\\\""
+CCARGS="${CCARGS} $(getconf LFS_CFLAGS)"
+%if 0%{?rhel} >= 9
+ CCARGS="${CCARGS} -DNO_NIS"
+%endif
+LDFLAGS="%{?__global_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
+# ignores them. Adding LDFLAGS to SHLIB_RPATH is currently the only
+# way how to get them in
+make -f Makefile.init makefiles shared=yes dynamicmaps=yes \
+ %{?_hardened_build:pie=yes} CCARGS="${CCARGS}" AUXLIBS="${AUXLIBS}" \
+ AUXLIBS_LDAP="${AUXLIBS_LDAP}" AUXLIBS_LMDB="${AUXLIBS_LMDB}" \
+ AUXLIBS_PCRE="${AUXLIBS_PCRE}" AUXLIBS_MYSQL="${AUXLIBS_MYSQL}" \
+ 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" \
+ POSTFIX_INSTALL_OPTS=-keep-build-mtime
+
+%make_build
+
+%install
+# install postfix into $RPM_BUILD_ROOT
+
+# Move stuff around so we don't conflict with sendmail
+for i in man1/mailq.1 man1/newaliases.1 man1/sendmail.1 man5/aliases.5 man8/smtpd.8; do
+ dest=$(echo $i | sed 's|\.[1-9]$|.postfix\0|')
+ mv man/$i man/$dest
+ sed -i "s|^\.so $i|\.so $dest|" man/man?/*.[1-9]
+done
+
+make non-interactive-package \
+ install_root=$RPM_BUILD_ROOT \
+ config_directory=%{postfix_config_dir} \
+ meta_directory=%{postfix_config_dir} \
+ shlib_directory=%{postfix_shlib_dir} \
+ daemon_directory=%{postfix_daemon_dir} \
+ command_directory=%{postfix_command_dir} \
+ queue_directory=%{postfix_queue_dir} \
+ data_directory=%{postfix_data_dir} \
+ sendmail_path=%{postfix_command_dir}/sendmail.postfix \
+ newaliases_path=%{_bindir}/newaliases.postfix \
+ mailq_path=%{_bindir}/mailq.postfix \
+ mail_owner=%{postfix_user} \
+ setgid_group=%{maildrop_group} \
+ manpage_directory=%{_mandir} \
+ sample_directory=%{postfix_sample_dir} \
+ readme_directory=%{postfix_readme_dir} || exit 1
+
+# 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
+ mkdir -p $RPM_BUILD_ROOT%{postfix_queue_dir}/$i
+done
+
+# install performance benchmark and test tools by hand
+for i in smtp-sink smtp-source posttls-finger ; do
+ install -c -m 755 bin/$i $RPM_BUILD_ROOT%{postfix_command_dir}/
+ install -c -m 755 man/man1/$i.1 $RPM_BUILD_ROOT%{_mandir}/man1/
+done
+
+## RPM compresses man pages automatically.
+## - Edit postfix-files to reflect this, so post-install won't get confused
+## when called during package installation.
+sed -i -r "s#(/man[158]/.*.[158]):f#\1.gz:f#" $RPM_BUILD_ROOT%{postfix_config_dir}/postfix-files
+
+cat $RPM_BUILD_ROOT%{postfix_config_dir}/postfix-files
+%if %{with sasl}
+# Install the smtpd.conf file for SASL support.
+mkdir -p $RPM_BUILD_ROOT%{sasl_config_dir}
+install -m 644 %{SOURCE100} $RPM_BUILD_ROOT%{sasl_config_dir}/smtpd.conf
+%endif
+
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d
+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} 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
+cp -p examples/chroot-setup/LINUX2 $RPM_BUILD_ROOT%{postfix_doc_dir}/examples/chroot-setup
+
+cp conf/{main,bounce}.cf.default $RPM_BUILD_ROOT%{postfix_doc_dir}
+sed -i 's#%{postfix_config_dir}\(/bounce\.cf\.default\)#%{postfix_doc_dir}\1#' $RPM_BUILD_ROOT%{_mandir}/man5/bounce.5
+rm -f $RPM_BUILD_ROOT%{postfix_config_dir}/{TLS_,}LICENSE
+
+find $RPM_BUILD_ROOT%{postfix_doc_dir} -type f | xargs chmod 644
+find $RPM_BUILD_ROOT%{postfix_doc_dir} -type d | xargs chmod 755
+
+%if %{with pflogsumm}
+install -c -m 644 pflogsumm-%{pflogsumm_ver}/pflogsumm-faq.txt $RPM_BUILD_ROOT%{postfix_doc_dir}/pflogsumm-faq.txt
+install -c -m 644 pflogsumm-%{pflogsumm_ver}/pflogsumm.1 $RPM_BUILD_ROOT%{_mandir}/man1/pflogsumm.1
+install -c pflogsumm-%{pflogsumm_ver}/pflogsumm.pl $RPM_BUILD_ROOT%{postfix_command_dir}/pflogsumm
+%endif
+
+# install qshape
+mantools/srctoman - auxiliary/qshape/qshape.pl > qshape.1
+install -c qshape.1 $RPM_BUILD_ROOT%{_mandir}/man1/qshape.1
+install -c auxiliary/qshape/qshape.pl $RPM_BUILD_ROOT%{postfix_command_dir}/qshape
+
+# remove alias file
+rm -f $RPM_BUILD_ROOT%{postfix_config_dir}/aliases
+
+# create /usr/lib/sendmail
+mkdir -p $RPM_BUILD_ROOT%{_prefix}/lib
+pushd $RPM_BUILD_ROOT%{_prefix}/lib
+ln -sf ../sbin/sendmail.postfix .
+popd
+
+mkdir -p $RPM_BUILD_ROOT%{_var}/lib/misc
+touch $RPM_BUILD_ROOT%{_var}/lib/misc/postfix.aliasesdb-stamp
+
+# prepare alternatives ghosts
+for i in %{postfix_command_dir}/sendmail %{_bindir}/{mailq,newaliases,rmail} \
+ %{_sysconfdir}/pam.d/smtp %{_prefix}/lib/sendmail \
+ %{_mandir}/{man1/{mailq.1,newaliases.1},man5/aliases.5,man8/{sendmail.8,smtpd.8}}
+do
+ touch $RPM_BUILD_ROOT$i
+done
+
+# helper for splitting content of dynamicmaps.cf and postfix-files
+function split_file
+{
+# "|| :" to silently skip non existent records
+ grep "$1" "$3" >> "$3.d/$2" || :
+ sed -i "\|$1| d" "$3" || :
+}
+
+# split global dynamic maps configuration to individual sub-packages
+pushd $RPM_BUILD_ROOT%{postfix_config_dir}
+for map in %{?with_mysql:mysql} %{?with_pgsql:pgsql} %{?with_sqlite:sqlite} \
+%{?with_cdb:cdb} %{?with_ldap:ldap} %{?with_lmdb:lmdb} %{?with_pcre:pcre}; do
+ rm -f dynamicmaps.cf.d/"$map" "postfix-files.d/$map"
+ split_file "^\s*$map\b" "$map" dynamicmaps.cf
+ sed -i "s|postfix-$map\\.so|%{postfix_shlib_dir}/\\0|" "dynamicmaps.cf.d/$map"
+ split_file "^\$shlib_directory/postfix-$map\\.so:" "$map" postfix-files
+ split_file "^\$manpage_directory/man5/${map}_table\\.5" "$map" postfix-files
+ map_upper=`echo $map | tr '[:lower:]' '[:upper:]'`
+ split_file "^\$readme_directory/${map_upper}_README:" "$map" postfix-files
+done
+popd
+
+%post -e
+%systemd_post %{name}.service
+
+# upgrade configuration files if necessary
+%{_sbindir}/postfix set-permissions upgrade-configuration \
+ daemon_directory=%{postfix_daemon_dir} \
+ command_directory=%{postfix_command_dir} \
+ mail_owner=%{postfix_user} \
+ setgid_group=%{maildrop_group} \
+ manpage_directory=%{_mandir} \
+ sample_directory=%{postfix_sample_dir} \
+ readme_directory=%{postfix_readme_dir} &> /dev/null
+
+ALTERNATIVES_DOCS=""
+[ "%%{_excludedocs}" = 1 ] || ALTERNATIVES_DOCS='--slave %{_mandir}/man1/mailq.1.gz mta-mailqman %{_mandir}/man1/mailq.postfix.1.gz
+ --slave %{_mandir}/man1/newaliases.1.gz mta-newaliasesman %{_mandir}/man1/newaliases.postfix.1.gz
+ --slave %{_mandir}/man8/sendmail.8.gz mta-sendmailman %{_mandir}/man1/sendmail.postfix.1.gz
+ --slave %{_mandir}/man5/aliases.5.gz mta-aliasesman %{_mandir}/man5/aliases.postfix.5.gz
+ --slave %{_mandir}/man8/smtpd.8.gz mta-smtpdman %{_mandir}/man8/smtpd.postfix.8.gz'
+
+%{_sbindir}/alternatives --install %{postfix_command_dir}/sendmail mta %{postfix_command_dir}/sendmail.postfix 60 \
+ --slave %{_bindir}/mailq mta-mailq %{_bindir}/mailq.postfix \
+ --slave %{_bindir}/newaliases mta-newaliases %{_bindir}/newaliases.postfix \
+ --slave %{_sysconfdir}/pam.d/smtp mta-pam %{_sysconfdir}/pam.d/smtp.postfix \
+ --slave %{_bindir}/rmail mta-rmail %{_bindir}/rmail.postfix \
+ --slave %{_prefix}/lib/sendmail mta-sendmail %{_prefix}/lib/sendmail.postfix \
+ $ALTERNATIVES_DOCS \
+ --initscript postfix
+
+%if %{with sasl}
+# Move sasl config to new location
+if [ -f %{_libdir}/sasl2/smtpd.conf ]; then
+ mv -f %{_libdir}/sasl2/smtpd.conf %{sasl_config_dir}/smtpd.conf
+ /sbin/restorecon %{sasl_config_dir}/smtpd.conf 2> /dev/null
+fi
+%endif
+
+# Create self-signed SSL certificate
+if [ ! -f %{sslkey} ]; then
+ umask 077
+ %{_bindir}/openssl genpkey -algorithm RSA -pkeyopt rsa_keygen_bits:4096 -out %{sslkey} 2>/dev/null || echo "openssl genpkey failed"
+fi
+
+if [ ! -f %{sslcert} ]; then
+ FQDN=`hostname`
+ if [ "x${FQDN}" = "x" ]; then
+ FQDN=localhost.localdomain
+ fi
+
+ 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
+
+exit 0
+
+%pre
+# Add user and groups if necessary
+%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+
+if [ -e %{_mandir}/man8/smtpd.8.gz ]; then
+ [ -h %{_mandir}/man8/smtpd.8.gz ] || rm -f %{_mandir}/man8/smtpd.8.gz
+fi
+
+exit 0
+
+%preun
+%systemd_preun %{name}.service
+
+if [ "$1" = 0 ]; then
+ %{_sbindir}/alternatives --remove mta %{postfix_command_dir}/sendmail.postfix
+fi
+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 ||:
+/sbin/chkconfig --del postfix >/dev/null 2>&1 || :
+/bin/systemctl try-restart postfix.service >/dev/null 2>&1 || :
+
+
+
+
+%files
+
+# For correct directory permissions check postfix-install script.
+# It reads the file postfix-files which defines the ownership
+# and permissions for all files postfix installs.
+
+%defattr(-, root, root, -)
+
+# Config files not part of upstream
+
+%if %{with sasl}
+%config(noreplace) %{sasl_config_dir}/smtpd.conf
+%endif
+%config(noreplace) %{_sysconfdir}/pam.d/smtp.postfix
+%{_unitdir}/postfix.service
+
+# Documentation
+
+%{postfix_doc_dir}
+%if %{with pflogsumm}
+%exclude %{postfix_doc_dir}/pflogsumm-faq.txt
+%endif
+
+# Exclude due to dynamic maps subpackages
+%exclude %{_mandir}/man5/mysql_table.5*
+%exclude %{postfix_doc_dir}/README_FILES/MYSQL_README
+%exclude %{_mandir}/man5/pgsql_table.5*
+%exclude %{postfix_doc_dir}/README_FILES/PGSQL_README
+%exclude %{_mandir}/man5/sqlite_table.5*
+%exclude %{postfix_doc_dir}/README_FILES/SQLITE_README
+%exclude %{postfix_doc_dir}/README_FILES/CDB_README
+%exclude %{_mandir}/man5/ldap_table.5*
+%exclude %{postfix_doc_dir}/README_FILES/LDAP_README
+%exclude %{_mandir}/man5/lmdb_table.5*
+%exclude %{postfix_doc_dir}/README_FILES/LMDB_README
+%exclude %{_mandir}/man5/pcre_table.5*
+%exclude %{postfix_doc_dir}/README_FILES/PCRE_README
+
+# Misc files
+
+%dir %attr(0755, root, root) %{postfix_config_dir}
+%dir %attr(0755, root, root) %{postfix_daemon_dir}
+%dir %attr(0755, root, root) %{postfix_queue_dir}
+%dir %attr(0755, root, root) %{postfix_shlib_dir}
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/active
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/bounce
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/corrupt
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/defer
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/deferred
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/flush
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/hold
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/incoming
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/saved
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/trace
+%dir %attr(0730, %{postfix_user}, %{maildrop_group}) %{postfix_queue_dir}/maildrop
+%dir %attr(0755, root, root) %{postfix_queue_dir}/pid
+%dir %attr(0700, %{postfix_user}, root) %{postfix_queue_dir}/private
+%dir %attr(0710, %{postfix_user}, %{maildrop_group}) %{postfix_queue_dir}/public
+%dir %attr(0700, %{postfix_user}, root) %{postfix_data_dir}
+%dir %attr(0755, root, root) %{postfix_config_dir}/dynamicmaps.cf.d
+%dir %attr(0755, root, root) %{postfix_config_dir}/postfix-files.d
+
+%attr(0644, root, root) %{_mandir}/man1/post*.1*
+%attr(0644, root, root) %{_mandir}/man1/smtp*.1*
+%attr(0644, root, root) %{_mandir}/man1/*.postfix.1*
+%attr(0644, root, root) %{_mandir}/man5/access.5*
+%attr(0644, root, root) %{_mandir}/man5/[b-v]*.5*
+%attr(0644, root, root) %{_mandir}/man5/*.postfix.5*
+%attr(0644, root, root) %{_mandir}/man8/[a-qt-v]*.8*
+%attr(0644, root, root) %{_mandir}/man8/s[ch-lnp]*.8*
+%attr(0644, root, root) %{_mandir}/man8/smtp.8*
+%attr(0644, root, root) %{_mandir}/man8/smtpd.postfix.8*
+
+%attr(0755, root, root) %{postfix_command_dir}/smtp-sink
+%attr(0755, root, root) %{postfix_command_dir}/smtp-source
+%attr(0755, root, root) %{postfix_command_dir}/posttls-finger
+
+%attr(0755, root, root) %{postfix_command_dir}/postalias
+%attr(0755, root, root) %{postfix_command_dir}/postcat
+%attr(0755, root, root) %{postfix_command_dir}/postconf
+%attr(2755, root, %{maildrop_group}) %{postfix_command_dir}/postdrop
+%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(0755, root, root) %{postfix_command_dir}/postmap
+%attr(0755, root, root) %{postfix_command_dir}/postmulti
+%attr(2755, root, %{maildrop_group}) %{postfix_command_dir}/postqueue
+%attr(0755, root, root) %{postfix_command_dir}/postsuper
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/access
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/canonical
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/generic
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/header_checks
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/main.cf
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/main.cf.proto
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/master.cf
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/master.cf.proto
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/relocated
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/transport
+%attr(0644, root, root) %config(noreplace) %{postfix_config_dir}/virtual
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf
+%attr(0755, root, root) %{postfix_daemon_dir}/[^mp]*
+%attr(0755, root, root) %{postfix_daemon_dir}/master
+%attr(0755, root, root) %{postfix_daemon_dir}/pickup
+%attr(0755, root, root) %{postfix_daemon_dir}/pipe
+%attr(0755, root, root) %{postfix_daemon_dir}/post-install
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files
+%attr(0755, root, root) %{postfix_daemon_dir}/postfix-script
+%attr(0755, root, root) %{postfix_daemon_dir}/postfix-tls-script
+%attr(0755, root, root) %{postfix_daemon_dir}/postfix-wrapper
+%attr(0755, root, root) %{postfix_daemon_dir}/postmulti-script
+%attr(0755, root, root) %{postfix_daemon_dir}/postscreen
+%attr(0755, root, root) %{postfix_daemon_dir}/postlogd
+%attr(0755, root, root) %{postfix_daemon_dir}/proxymap
+%attr(0755, root, root) %{postfix_shlib_dir}/libpostfix-*.so
+%{_bindir}/mailq.postfix
+%{_bindir}/newaliases.postfix
+%attr(0755, root, root) %{_bindir}/rmail.postfix
+%attr(0755, root, root) %{_sbindir}/sendmail.postfix
+%{_prefix}/lib/sendmail.postfix
+
+%ghost %{_sysconfdir}/pam.d/smtp
+
+%ghost %{_mandir}/man1/mailq.1.gz
+%ghost %{_mandir}/man1/newaliases.1.gz
+%ghost %{_mandir}/man5/aliases.5.gz
+%ghost %{_mandir}/man8/sendmail.8.gz
+%ghost %{_mandir}/man8/smtpd.8.gz
+
+%ghost %attr(0755, root, root) %{_bindir}/mailq
+%ghost %attr(0755, root, root) %{_bindir}/newaliases
+%ghost %attr(0755, root, root) %{_bindir}/rmail
+%ghost %attr(0755, root, root) %{_sbindir}/sendmail
+%ghost %attr(0755, root, root) %{_prefix}/lib/sendmail
+
+%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*
+%if %{with pflogsumm}
+%doc %{postfix_doc_dir}/pflogsumm-faq.txt
+%attr(0644, root, root) %{_mandir}/man1/pflogsumm.1.gz
+%attr(0755, root, root) %{postfix_command_dir}/pflogsumm
+%endif
+
+%if %{with mysql}
+%files mysql
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf.d/mysql
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files.d/mysql
+%attr(0755, root, root) %{postfix_shlib_dir}/postfix-mysql.so
+%attr(0644, root, root) %{_mandir}/man5/mysql_table.5*
+%attr(0644, root, root) %{postfix_doc_dir}/README_FILES/MYSQL_README
+
+%endif
+
+%if %{with pgsql}
+%files pgsql
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf.d/pgsql
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files.d/pgsql
+%attr(0755, root, root) %{postfix_shlib_dir}/postfix-pgsql.so
+%attr(0644, root, root) %{_mandir}/man5/pgsql_table.5*
+%attr(0644, root, root) %{postfix_doc_dir}/README_FILES/PGSQL_README
+%endif
+
+%if %{with sqlite}
+%files sqlite
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf.d/sqlite
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files.d/sqlite
+%attr(0755, root, root) %{postfix_shlib_dir}/postfix-sqlite.so
+%attr(0644, root, root) %{_mandir}/man5/sqlite_table.5*
+%attr(0644, root, root) %{postfix_doc_dir}/README_FILES/SQLITE_README
+%endif
+
+%if %{with cdb}
+%files cdb
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf.d/cdb
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files.d/cdb
+%attr(0755, root, root) %{postfix_shlib_dir}/postfix-cdb.so
+%attr(0644, root, root) %{postfix_doc_dir}/README_FILES/CDB_README
+%endif
+
+%if %{with ldap}
+%files ldap
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf.d/ldap
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files.d/ldap
+%attr(0755, root, root) %{postfix_shlib_dir}/postfix-ldap.so
+%attr(0644, root, root) %{_mandir}/man5/ldap_table.5*
+%attr(0644, root, root) %{postfix_doc_dir}/README_FILES/LDAP_README
+%endif
+
+%if %{with lmdb}
+%files lmdb
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf.d/lmdb
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files.d/lmdb
+%attr(0755, root, root) %{postfix_shlib_dir}/postfix-lmdb.so
+%attr(0644, root, root) %{_mandir}/man5/lmdb_table.5*
+%attr(0644, root, root) %{postfix_doc_dir}/README_FILES/LMDB_README
+%endif
+
+%if %{with pcre}
+%files pcre
+%attr(0644, root, root) %{postfix_config_dir}/dynamicmaps.cf.d/pcre
+%attr(0644, root, root) %{postfix_config_dir}/postfix-files.d/pcre
+%attr(0755, root, root) %{postfix_shlib_dir}/postfix-pcre.so
+%attr(0644, root, root) %{_mandir}/man5/pcre_table.5*
+%attr(0644, root, root) %{postfix_doc_dir}/README_FILES/PCRE_README
+%endif
+
+%changelog
+* Fri Sep 22 2023 MSVSphere Packaging Team - 2:3.5.9-24
+- Rebuilt for MSVSphere 9.3 beta
+
+* Mon Aug 14 2023 Jaroslav Škarvada - 2:3.5.9-24
+- Fixed possible warning when postfix is restarted
+ Resolves: rhbz#2075571
+
+* Mon Aug 14 2023 Jaroslav Škarvada - 2:3.5.9-23
+- Spec cleanup
+ Related: rhbz#2095454
+
+* Wed Jul 05 2023 Jonathan Wright - 2:3.5.9-22
+- Use systemd-sysusers
+ Resolves: rhbz#2095454
+
+* Wed May 17 2023 Tomas Korbar - 2:3.5.9-21
+- Fix patch for SRV record resolution feature
+ Related: rhbz#2134789
+
+* Thu May 04 2023 Tomas Korbar - 2:3.5.9-20
+- Backport dns SRV record resolution feature (RFC6186)
+ Resolves: rhbz#2134789
+- Fix building in ZUUL CI
+ Resolves: rhbz#2193363
+
+* Fri Aug 19 2022 Jaroslav Škarvada - 2:3.5.9-19
+- Suppressed openssl output during SSL certificates generation
+ Resolves: rhbz#2041589
+
+* Tue Feb 22 2022 Jaroslav Škarvada - 2:3.5.9-18
+- Added SELinux workound for systemd service to work after 'postfix start'
+ Resolves: rhbz#2055915
+
+* Tue Feb 15 2022 Jaroslav Škarvada - 2:3.5.9-17
+- Fixed problem in the dict_inline found by coverity
+ Resolves: rhbz#1938847
+
+* Fri Jan 28 2022 Jaroslav Škarvada - 2:3.5.9-16
+- Fixed pflogsumm to allow underscores in the syslog_name
+ Resolves: rhbz#2043059
+
+* Tue Aug 10 2021 Mohan Boddu - 2:3.5.9-15
+- Rebuilt for IMA sigs, glibc 2.34, aarch64 flags
+ Related: rhbz#1991688
+
+* Thu Aug 5 2021 Jaroslav Škarvada - 2:3.5.9-14
+- Fixed cleanup crash when processing messages with whitespace only fullname
+ Resolves: rhbz#1978901
+
+* Thu Aug 5 2021 Jaroslav Škarvada - 2:3.5.9-13
+- Used upstream patch for fixing FTBFS with glibc-2.34
+ Related: rhbz#1984045
+
+* Tue Aug 3 2021 Jaroslav Škarvada - 2:3.5.9-12
+- Fixed openssl req command parameter
+ Related: rhbz#1985918
+
+* Tue Aug 3 2021 Jaroslav Škarvada - 2:3.5.9-11
+- Fixed FTBFS with glibc-2.34
+ Resolves: rhbz#1984045
+
+* Mon Aug 2 2021 Jaroslav Škarvada - 2:3.5.9-10
+- Fixed scriptlets to work with openssl-3.0
+ Resolves: rhbz#1985918
+
+* Wed Jun 16 2021 Mohan Boddu - 2:3.5.9-9
+- Rebuilt for RHEL 9 BETA for openssl 3.0
+ Related: rhbz#1971065
+
+* Thu Apr 22 2021 Jaroslav Škarvada - 2:3.5.9-8
+- Fixed NIS build requirements
+ Resolves: rhbz#1942369
+
+* Fri Apr 16 2021 Mohan Boddu - 2:3.5.9-7
+- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937
+
+* 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
+
+* Mon Nov 25 2019 Jaroslav Škarvada - 2:3.4.8-1
+- New version
+ Resolves: rhbz#1776033
+
+* Fri Nov 01 2019 Pete Walter - 2:3.4.7-3
+- Rebuild for ICU 65
+
+* Wed Sep 25 2019 Jaroslav Škarvada - 2:3.4.7-2
+- Added hostname as explicit requirement for the post scriptlet
+
+* 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
+
+* Mon Nov 19 2018 Jaroslav Škarvada - 2:3.3.1-6
+- Used _prefix macro for /usr and _includedir macro for /usr/include
+
+* 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)
+
+* Fri Jul 13 2018 Fedora Release Engineering - 2:3.3.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild
+
+* Tue Jul 10 2018 Pete Walter - 2:3.3.1-2
+- Rebuild for ICU 62
+
+* Mon Jul 9 2018 Jaroslav Škarvada - 2:3.3.1-1
+- New version
+ Resolves: rhbz#1548222
+- Updated libnsl2 library and header paths
+ Resolves: rhbz#1543928
+- Updated license for dual licensing
+
+* Mon Apr 30 2018 Pete Walter - 2:3.2.5-5
+- Rebuild for ICU 61.1
+
+* Mon Feb 26 2018 Jaroslav Škarvada - 2:3.2.5-4
+- Owned /usr/lib64/postfix directory
+ Resolves: rhbz#1548686
+
+* Mon Feb 19 2018 Ondřej Lysoněk - 2:3.2.5-3
+- Add gcc to BuildRequires
+
+* Fri Feb 09 2018 Fedora Release Engineering - 2:3.2.5-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_28_Mass_Rebuild
+
+* Mon Jan 29 2018 Jaroslav Škarvada - 2:3.2.5-1
+- New version
+ Resolves: rhbz#1539465
+- Switched to libnsl2, because nsl is no longer provided by glibc
+- Macro workaround not to check symbols during compilation, because
+ plugins have symbols which are unresolvable during compile time
+
+* Thu Nov 30 2017 Pete Walter - 2:3.2.4-3
+- Rebuild for ICU 60.1
+
+* Thu Nov 2 2017 Jaroslav Škarvada - 2:3.2.4-2
+- Used mariadb-connector-c-devel instead of mysql-devel
+ Resolves: rhbz#1493655
+
+* Wed Nov 1 2017 Jaroslav Škarvada - 2:3.2.4-1
+- New version
+ Resolves: rhbz#1508234
+
+* Thu Oct 5 2017 Jaroslav Škarvada - 2:3.2.3-1
+- New version
+ Resolves: rhbz#1495033
+
+* Thu Aug 03 2017 Fedora Release Engineering - 2:3.2.2-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild
+
+* Thu Jul 27 2017 Fedora Release Engineering - 2:3.2.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild
+
+* Wed Jun 14 2017 Jaroslav Škarvada - 2:3.2.2-1
+- New version
+ Resolves: rhbz#1461224
+
+* Tue Jun 13 2017 Jaroslav Škarvada - 2:3.2.1-1
+- New version
+ Resolves: rhbz#1460474
+- Updated pflogsumm to 1.1.5
+- Fixed warnings if IPv6 addresses are in the log
+ Resolves: rhbz#1384871
+
+* Thu Mar 2 2017 Jaroslav Škarvada - 2:3.2.0-1
+- New version
+ Resolves: rhbz#1427860
+- De-fuzzified patches
+- Dropped timestamps patch (upstreamed)
+
+* Sat Feb 11 2017 Fedora Release Engineering - 2:3.1.4-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild
+
+* Mon Jan 2 2017 Jaroslav Škarvada - 2:3.1.4-1
+- New version
+ Resolves: rhbz#1409447
+
+* Wed Oct 5 2016 Ondřej Lysoněk - 2:3.1.3-2
+- Preserve timestamps during 'make install'
+ Resolves: rhbz#1307064
+
+* Mon Oct 3 2016 Jaroslav Škarvada - 2:3.1.3-1
+- New version
+ Resolves: rhbz#1381077
+
+* Wed Aug 31 2016 Jaroslav Škarvada - 2:3.1.2-1
+- New version
+ Resolves: rhbz#1370899
+- Dropped timestamps patch (upstream rejected)
+- Fixed minor whitespace problem
+
+* Thu Aug 04 2016 Ondřej Lysoněk - 2:3.1.1-3
+- Preserve timestamps during 'make install'
+ Patch provided by Robert Scheck
+ Resolves: rhbz#1307064
+
+* Wed Jun 29 2016 Jaroslav Škarvada - 2:3.1.1-2
+- Hardened systemd unit file
+ Resolves: rhbz#1350941
+
+* Mon May 16 2016 Jaroslav Škarvada - 2:3.1.1-1
+- New version
+ Resolves: rhbz#1336245
+
+* Fri Apr 15 2016 David Tardon - 2:3.1.0-2
+- rebuild for ICU 57.1
+
+* Thu Feb 25 2016 Jaroslav Škarvada - 2:3.1.0-1
+- New version
+ Resolves: rhbz#1311968
+- Defuzzified files, large-fs, and alternatives patches
+
+* Mon Feb 22 2016 Jaroslav Škarvada - 2:3.0.4-1
+- New version
+ Resolves: rhbz#1310481
+
+* Thu Feb 04 2016 Fedora Release Engineering - 2:3.0.3-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild
+
+* Fri Jan 29 2016 Jaroslav Škarvada - 2:3.0.3-4
+- Increased alternatives priority, it is desirable to prefer postfix
+ to e.g. ssmtp
+ Resolves: rhbz#1255131
+
+* Mon Jan 11 2016 Jaroslav Škarvada - 2:3.0.3-3
+- Added support for installation with _excludedocs
+ Resolves: rhbz#1227824
+
+* Wed Oct 28 2015 David Tardon - 2:3.0.3-2
+- rebuild for ICU 56.1
+
+* Mon Oct 12 2015 Jaroslav Škarvada - 2:3.0.3-1
+- New version
+ Resolves: rhbz#1270577
+- Dropped reset-errno-before-readdir patch (upstreamed)
+
+* Mon Sep 14 2015 Jaroslav Škarvada - 2:3.0.2-2
+- Fixed sysvinit conditionals
+
+* Wed Jul 22 2015 Jaroslav Škarvada - 2:3.0.2-1
+- New version
+ Resolves: rhbz#1245183
+- Dropped linux4 patch (not needed)
+- Defuzzified alternatives patch
+
+* Thu Jun 18 2015 Fedora Release Engineering - 2:3.0.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild
+
+* Sun Apr 26 2015 Dodji Seketeli - 2:3.0.1-2
+- Avoid spurious errors by re-setting errno to 0 before calling that readdir()
+ Resolves: rhbz#1204139
+- Add a patch to support compiling on Linux 4.*
+
+* Mon Apr 13 2015 Jaroslav Škarvada - 2:3.0.1-1
+- New version
+
+* Tue Mar 24 2015 Jaroslav Škarvada - 2:3.0.0-5
+- Overriden DEF_SHLIB_DIR according to build host
+ Resolves: rhbz#1202921
+
+* Fri Mar 13 2015 Jaroslav Škarvada - 2:3.0.0-4
+- Switched to dynamically loaded libraries and database plugins
+- Enabled PostgreSQL support by default
+- Added SQLite support
+- Added CDB support
+
+* Fri Mar 13 2015 Jaroslav Škarvada - 2:3.0.0-3
+- Rebuilt with libicu for SMTPUTF8
+
+* Tue Mar 10 2015 Adam Jackson 2:3.0.0-2
+- Drop sysvinit subpackage in F23+
+
+* Thu Mar 5 2015 Jaroslav Škarvada - 2:3.0.0-1
+- New version
+ Resolves: rhbz#1190797
+- Defuzzified alternatives, config, large-fs patches
+- Rebased files patch
+
+* Mon Oct 20 2014 Jaroslav Škarvada - 2:2.11.3-1
+- New version
+ Resolves: rhbz#1154587
+
+* Tue Oct 14 2014 Jaroslav Škarvada - 2:2.11.2-1
+- New version
+ Resolves: rhbz#1152488
+
+* Sun Aug 17 2014 Fedora Release Engineering - 2:2.11.1-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild
+
+* Sat Jun 07 2014 Fedora Release Engineering - 2:2.11.1-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild
+
+* Fri May 9 2014 Jaroslav Škarvada - 2:2.11.1-1
+- New version
+ Resolves: rhbz#1095655
+
+* Fri Mar 28 2014 Jaroslav Škarvada - 2:2.11.0-2
+- Added man8/smtpd.8.gz to alternatives
+ Resolves: rhbz#1051180
+
+* Wed Feb 12 2014 Jaroslav Škarvada - 2:2.11.0-1
+- New version
+ Resolves: rhbz#1054116
+- Updated / de-fuzzified patches
+- Compiled with USE_LDAP_SASL if both "ldap" and "sasl" options are enabled.
+ Patch provided by Davide Principi
+ Resolves: rhbz#1052958
+
+* Thu Jan 2 2014 Jaroslav Škarvada - 2:2.10.2-3
+- Rebuilt regarding ECDHE
+
+* Wed Oct 23 2013 Jaroslav Škarvada - 2:2.10.2-2
+- Rebuilt against ECDHE enabled openssl
+ Resolves: rhbz#1019254
+
+* Mon Sep 16 2013 Jaroslav Škarvada - 2:2.10.2-1
+- New version
+ Resolves: rhbz#1006005
+- Defuzzified patches
+
+* Mon Aug 12 2013 Jaroslav Škarvada - 2:2.10.1-7
+- Minor changes to macros regarding hardened build
+
+* Tue Aug 6 2013 Jaroslav Škarvada - 2:2.10.1-6
+- Fixed license (pflogsumm)
+
+* Sat Aug 03 2013 Petr Pisar - 2:2.10.1-5
+- Perl 5.18 rebuild
+
+* Fri Jul 26 2013 Ville Skyttä - 2:2.10.1-4
+- Install docs to %%{_pkgdocdir} where available.
+
+* Wed Jul 17 2013 Petr Pisar - 2:2.10.1-3
+- Perl 5.18 rebuild
+
+* Thu Jul 4 2013 Jaroslav Škarvada - 2:2.10.1-2
+- Added diffutils as explicit requirement
+ Resolves: rhbz#830540
+
+* Mon Jun 24 2013 Jaroslav Škarvada - 2:2.10.1-1
+- New version
+ Resolves: rhbz#977273
+
+* Thu May 23 2013 Jaroslav Škarvada - 2:2.10.0-2
+- Fixed systemd error message regarding chroot-update, patch provided
+ by John Heidemann
+ Resolves: rhbz#917463
+
+* Thu Mar 21 2013 Jaroslav Škarvada - 2:2.10.0-1
+- New version
+- Re-enabled IPv6 in the config
+ Resolves: rhbz#863140
+
+* Tue Feb 26 2013 Jaroslav Škarvada - 2:2.10.0-0.3.rc1
+- Added systemd-sysv to requires
+
+* Mon Feb 25 2013 Jaroslav Škarvada - 2:2.10.0-0.2.rc1
+- Switched to systemd-rpm macros
+ Resolves: rhbz#850276
+
+* Fri Feb 8 2013 Jaroslav Škarvada - 2:2.10.0-0.1.rc1
+- New version
+
+* Tue Feb 5 2013 Jaroslav Škarvada - 2:2.9.6-1
+- New version
+ Resolves: rhbz#907803
+
+* Tue Jan 8 2013 Jaroslav Škarvada - 2:2.9.5-2
+- Rebuilt with -fno-strict-aliasing
+
+* Thu Dec 13 2012 Jaroslav Škarvada - 2:2.9.5-1
+- New version
+ Resolves: rhbz#886804
+
+* Thu Sep 6 2012 Jaroslav Škarvada - 2:2.9.4-3
+- Fixed systemd error message about missing chroot-update
+ Resolves: rhbz#832742
+
+* Fri Aug 3 2012 Jaroslav Škarvada - 2:2.9.4-2
+- Fixed sysv2systemd upgrade from f16
+
+* Thu Aug 2 2012 Jaroslav Škarvada - 2:2.9.4-1
+- New version
+ Resolves: rhbz#845298
+- Dropped biff-cloexec patch (upstreamed)
+
+* Sat Jul 21 2012 Fedora Release Engineering - 2:2.9.3-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild
+
+* Tue Jul 03 2012 Jaroslav Škarvada - 2:2.9.3-2
+- Fixed FD leak in biff
+
+* Tue Jun 5 2012 Jaroslav Škarvada - 2:2.9.3-1
+- New version
+ Resolves: rhbz#828242
+ Fixed sysv2systemd upgrade from f16
+
+* Wed Apr 25 2012 Jaroslav Škarvada - 2:2.9.2-2
+- Fixed sysv2systemd upgrade from f15 / f16
+
+* Wed Apr 25 2012 Jaroslav Škarvada - 2:2.9.2-1
+- New version
+ Resolves: rhbz#816139
+
+* Fri Apr 6 2012 Jaroslav Škarvada - 2:2.9.1-2
+- Rebuilt with libdb-5.2
+
+* Mon Feb 20 2012 Jaroslav Škarvada - 2:2.9.1-1
+- New version
+ Resolves: rhbz#794976
+
+* Fri Feb 10 2012 Petr Pisar - 2:2.9.0-2
+- Rebuild against PCRE 8.30
+
+* Fri Feb 3 2012 Jaroslav Škarvada - 2:2.9.0-1
+- New version
+ Resolves: rhbz#786792
+
+* Sat Jan 14 2012 Fedora Release Engineering - 2:2.8.7-5
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild
+
+* Thu Nov 10 2011 Jaroslav Škarvada - 2:2.8.7-4
+- Added epoch to sysvinit subpackage requires
+
+* Tue Nov 8 2011 Jaroslav Škarvada - 2:2.8.7-3
+- Fixed sysvinit preun scriptlet
+
+* Tue Nov 8 2011 Jaroslav Škarvada - 2:2.8.7-2
+- Introduce systemd unit file, thanks to Jóhann B. Guðmundsson
+ Resolves: rhbz#718793
+
+* Mon Nov 7 2011 Jaroslav Škarvada - 2:2.8.7-1
+- Update to 2.8.7
+ Resolves: rhbz#751622
+
+* Mon Oct 24 2011 Jaroslav Škarvada - 2:2.8.6-1
+- Update to 2.8.6
+ Resolves: rhbz#748389
+
+* Mon Sep 12 2011 Jaroslav Škarvada - 2:2.8.5-1
+- Update to 2.8.5
+ Resolves: rhbz#735543
+
+* Tue Aug 30 2011 Jaroslav Škarvada - 2:2.8.4-4
+- Enable override of hardened build settings
+
+* Tue Aug 30 2011 Jaroslav Škarvada - 2:2.8.4-3
+- Hardened build, rebuilt with full relro
+
+* Tue Aug 30 2011 Jaroslav Škarvada - 2:2.8.4-2
+- Rebuilt with libdb-5.1
+ Resolves: rhbz#734084
+
+* Thu Jul 07 2011 Jaroslav Škarvada - 2:2.8.4-1
+- update to 2.8.4
+
+* Mon May 09 2011 Jaroslav Škarvada - 2:2.8.3-1
+- update to 2.8.3
+- fix CVE-2011-1720
+
+* Wed Mar 23 2011 Dan Horák - 2:2.8.2-2
+- rebuilt for mysql 5.5.10 (soname bump in libmysqlclient)
+
+* Tue Mar 22 2011 Jaroslav Škarvada - 2:2.8.2-1
+- update to 2.8.2
+
+* Wed Feb 23 2011 Miroslav Lichvar 2:2.8.1-1
+- update to 2.8.1
+
+* Wed Feb 09 2011 Fedora Release Engineering - 2:2.8.0-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild
+
+* Mon Feb 07 2011 Miroslav Lichvar 2:2.8.0-2
+- don't set config_directory when upgrading configuration (#675654)
+
+* Wed Jan 26 2011 Miroslav Lichvar 2:2.8.0-1
+- update to 2.8.0
+
+* Fri Nov 26 2010 Miroslav Lichvar 2:2.7.2-1
+- update to 2.7.2
+- change LSB init header to provide $mail-transport-agent (#627411)
+
+* Thu Jun 10 2010 Miroslav Lichvar 2:2.7.1-1
+- update to 2.7.1
+- update pflogsumm to 1.1.3
+
+* Wed Mar 17 2010 Miroslav Lichvar 2:2.7.0-2
+- follow guidelines for alternatives (#570801)
+- move sasl config to /etc/sasl2 (#574434)
+- drop sasl v1 support
+- remove unnecessary requirements
+- use bcond macros
+
+* Fri Feb 26 2010 Miroslav Lichvar 2:2.7.0-1
+- update to 2.7.0
+
+* Fri Jan 29 2010 Miroslav Lichvar 2:2.6.5-3
+- fix init script LSB compliance (#528151)
+- update pflogsumm to 1.1.2
+- require Date::Calc for pflogsumm (#536678)
+- fix some rpmlint warnings
+
+* Wed Sep 16 2009 Tomas Mraz - 2:2.6.5-2
+- use password-auth common PAM configuration instead of system-auth
+
+* Tue Sep 01 2009 Miroslav Lichvar 2:2.6.5-1
+- update to 2.6.5
+
+* Fri Aug 21 2009 Tomas Mraz - 2:2.6.2-3
+- rebuilt with new openssl
+
+* Sun Jul 26 2009 Fedora Release Engineering - 2:2.6.2-2
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
+
+* Thu Jun 18 2009 Miroslav Lichvar 2:2.6.2-1
+- update to 2.6.2
+
+* Tue May 26 2009 Miroslav Lichvar 2:2.6.1-1
+- update to 2.6.1
+- move non-config files out of /etc/postfix (#490983)
+- fix multilib conflict in postfix-files (#502211)
+- run chroot-update script in init script (#483186)
+- package examples (#251677)
+- provide all alternatives files
+- suppress postfix output in post script
+
+* Thu Feb 26 2009 Fedora Release Engineering - 2:2.5.6-3
+- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild
+
+* Fri Jan 23 2009 Miroslav Lichvar 2:2.5.6-2
+- rebuild for new mysql
+
+* Thu Jan 22 2009 Miroslav Lichvar 2:2.5.6-1
+- update to 2.5.6 (#479108)
+- rebuild /etc/aliases.db only when necessary (#327651)
+- convert doc files to UTF-8
+
+* Thu Nov 20 2008 Miroslav Lichvar 2:2.5.5-2
+- enable Large file support on 32-bit archs (#428996)
+- fix mailq(1) and newaliases(1) man pages (#429501)
+- move pflogsumm and qshape to -perl-scripts subpackage (#467529)
+- update pflogsumm to 1.1.1
+- fix large-fs patch
+- drop open_define patch
+- add -Wno-comment to CFLAGS
+
+* Wed Sep 17 2008 Thomas Woerner 2:2.5.5-1
+- new version 2.5.5
+ fixes CVE-2008-2936, CVE-2008-2937 and CVE-2008-3889 (rhbz#459101)
+
+* Thu Aug 28 2008 Tom "spot" Callaway 2:2.5.1-4
+- fix license tag
+
+* Thu Aug 14 2008 Thomas Woerner 2:2.5.1-3
+- fixed postfix privilege problem with symlinks in the mail spool directory
+ (CVE-2008-2936) (rhbz#459101)
+
+* Wed Mar 12 2008 Thomas Woerner 2:2.5.1-2
+- fixed fix for enabling IPv6 support (rhbz#437024)
+- added new postfix data directory (rhbz#437042)
+
+* Thu Feb 21 2008 Thomas Woerner 2:2.5.1-1
+- new verison 2.5.1
+
+* Wed Feb 20 2008 Fedora Release Engineering - 2:2.4.6-3
+- Autorebuild for GCC 4.3
+
+* Thu Dec 06 2007 Release Engineering - 2.4.6-2
+- Rebuild for deps
+
+* Wed Nov 28 2007 Thomas Woerner 2:2.4.6-1
+- new verison 2.4.6
+- added virtual server(smtp) provide (rhbz#380631)
+- enabling IPv6 support (rhbz#197105)
+- made the MYSQL and PGSQL defines overloadable as build argument
+
+* Wed Nov 7 2007 Thomas Woerner 2:2.4.5-3
+- fixed multilib conflict for makedefs.out: rename to makedefs.out-%%{_arch}
+ (rhbz#342941)
+- enabled mysql support
+
+* Thu Oct 4 2007 Thomas Woerner 2:2.4.5-2
+- made init script lsb conform (#243286, rhbz#247025)
+- added link to postfix sasl readme into Postfix-SASL-RedHat readme
+
+* Mon Aug 13 2007 Thomas Woerner 2:2.4.5-1
+- new version 2.4.5
+- fixed compile proplem with glibc-2.6.90+
+
+* Fri Jun 15 2007 Thomas Woerner 2:2.4.3-3
+- added missing epoch in requirement of pflogsumm sub package
+
+* Thu Jun 14 2007 Thomas Woerner 2:2.4.3-2
+- diabled mysql support again (rhbz#185515)
+- added support flag for PostgreSQL build (rhbz#180579)
+ Ben: Thanks for the patch
+- Fixed remaining rewiew problems (rhbz#226307)
+
+* Tue Jun 5 2007 Thomas Woerner 2:2.4.3-1
+- allow to build without LDAP but SASL2 support (rhbz#216792)
+
+* Tue Jun 5 2007 Thomas Woerner 2:2.4.3-1
+- new stable version 2.4.3
+- enabled mysql support (rhbz#185515)
+- dropped build requirements for gawk, ed and sed
+
+* Tue Jan 23 2007 Thomas Woerner 2:2.3.6-1
+- new version 2.3.6
+- limiting SASL mechanisms to plain login for sasl with saslauthd (#175259)
+- dropped usage of ed in the install stage
+
+* Tue Nov 7 2006 Thomas Woerner 2:2.3.4-1
+- new version 2.3.4
+
+* Fri Sep 1 2006 Thomas Woerner 2:2.3.3-2
+- fixed upgrade procedure (#202357)
+
+* Fri Sep 1 2006 Thomas Woerner 2:2.3.3-1
+- new version 2.3.3
+- fixed permissions of TLS_LICENSE file
+
+* Fri Aug 18 2006 Jesse Keating - 2:2.3.2-2
+- rebuilt with latest binutils to pick up 64K -z commonpagesize on ppc*
+ (#203001)
+
+* Mon Jul 31 2006 Thomas Woerner 2:2.3.2-1
+- new version 2.3.2 with major upstream fixes:
+ - corrupted queue file after a request to modify a short message header
+ - panic after spurious Milter request when a client was rejected
+ - maked the Milter more tolerant for redundant "data cleanup" requests
+- applying pflogsumm-conn-delays-dsn-patch from postfix tree to pflogsumm
+
+* Fri Jul 28 2006 Thomas Woerner 2:2.3.1-1
+- new version 2.3.1
+- fixes problems with TLS and Milter support
+
+* Tue Jul 25 2006 Thomas Woerner 2:2.3.0-2
+- fixed SASL build (#200079)
+ thanks to Kaj J. Niemi for the patch
+
+* Mon Jul 24 2006 Thomas Woerner 2:2.3.0-1
+- new version 2.3.0
+- dropped hostname-fqdn patch
+
+* Wed Jul 12 2006 Jesse Keating - 2:2.2.10-2.1
+- rebuild
+
+* Wed May 10 2006 Thomas Woerner 2:2.2.10-2
+- added RELRO security protection
+
+* Tue Apr 11 2006 Thomas Woerner 2:2.2.10-1
+- new version 2.2.10
+- added option LDAP_DEPRECATED to support deprecated ldap functions for now
+- fixed build without pflogsumm support (#188470)
+
+* Fri Feb 10 2006 Jesse Keating - 2:2.2.8-1.2
+- bump again for double-long bug on ppc(64)
+
+* Tue Feb 07 2006 Jesse Keating - 2:2.2.8-1.1
+- rebuilt for new gcc4.1 snapshot and glibc changes
+
+* Tue Jan 24 2006 Florian Festi 2:2.2.8-1
+- new version 2.2.8
+
+* Tue Dec 13 2005 Thomas Woerner 2:2.2.7-1
+- new version 2.2.7
+
+* Fri Dec 09 2005 Jesse Keating
+- rebuilt
+
+* Fri Nov 11 2005 Thomas Woerner 2:2.2.5-2.1
+- replaced postconf and postalias call in initscript with newaliases (#156358)
+- fixed initscripts messages (#155774)
+- fixed build problems when sasl is disabled (#164773)
+- fixed pre-definition of mailbox_transport lmtp socket path (#122910)
+
+* Thu Nov 10 2005 Tomas Mraz 2:2.2.5-2
+- rebuilt against new openssl
+
+* Fri Oct 7 2005 Tomas Mraz
+- use include instead of pam_stack in pam config
+
+* Thu Sep 8 2005 Thomas Woerner 2:2.2.5-1
+- new version 2.2.5
+
+* Thu May 12 2005 Thomas Woerner 2:2.2.3-1
+- new version 2.2.3
+- compiling all binaries PIE, dropped old pie patch
+
+* Wed Apr 20 2005 Tomas Mraz 2:2.2.2-2
+- fix fsspace on large filesystems (>2G blocks)
+
+* Tue Apr 12 2005 Thomas Woerner 2:2.2.2-1
+- new version 2.2.2
+
+* Fri Mar 18 2005 Thomas Woerner 2:2.2.1-1
+- new version 2.2.1
+- allow to start postfix without alias_database (#149657)
+
+* Fri Mar 11 2005 Thomas Woerner 2:2.2.0-1
+- new version 2.2.0
+- cleanup of spec file: removed external TLS and IPV6 patches, removed
+ smtp_sasl_proto patch
+- dropped samples directory till there are good examples again (was TLS and
+ IPV6)
+- v2.2.0 fixes code problems: #132798 and #137858
+
+* Fri Feb 11 2005 Thomas Woerner 2:2.1.5-5.1
+- fixed open relay bug in postfix ipv6 patch: new version 1.26 (#146731)
+- fixed permissions on doc directory (#147280)
+- integrated fixed fqdn patch from Joseph Dunn (#139983)
+
+* Tue Nov 23 2004 Thomas Woerner 2:2.1.5-4.1
+- removed double quotes from postalias call, second fix for #138354
+
+* Thu Nov 11 2004 Jeff Johnson 2:2.1.5-4
+- rebuild against db-4.3.21.
+- remove Requires: db4, the soname linkage dependency is sufficient.
+
+* Thu Nov 11 2004 Thomas Woerner 2:2.1.5-3.1
+- fixed problem with multiple alias maps (#138354)
+
+* Tue Oct 26 2004 Thomas Woerner 2:2.1.5-3
+- fixed wrong path for cyrus-imapd (#137074)
+
+* Mon Oct 18 2004 Thomas Woerner 2:2.1.5-2.2
+- automated postalias call in init script
+- removed postconf call from spec file: moved changes into patch
+
+* Fri Oct 15 2004 Thomas Woerner 2:2.1.5-2.1
+- removed aliases from postfix-files (#135840)
+- fixed postalias call in init script
+
+* Thu Oct 14 2004 Thomas Woerner 2:2.1.5-2
+- switched over to system aliases file and database in /etc/ (#117661)
+- new reuires and buildrequires for setup >= 2.5.36-1
+
+* Mon Oct 4 2004 Thomas Woerner 2:2.1.5-1
+- new version 2.1.5
+- new ipv6 and tls+ipv6 patches: 1.25-pf-2.1.5
+
+* Thu Aug 5 2004 Thomas Woerner 2:2.1.4-1
+- new version 2.1.4
+- new ipv6 and tls+ipv6 patches: 1.25-pf-2.1.4
+- new pfixtls-0.8.18-2.1.3-0.9.7d patch
+
+* Mon Jun 21 2004 Thomas Woerner 2:2.1.1-3.1
+- fixed directory permissions in %%doc (#125406)
+- fixed missing spool dirs (#125460)
+- fixed verify problem for aliases.db (#125461)
+- fixed bogus upgrade warning (#125628)
+- more spec file cleanup
+
+* Tue Jun 15 2004 Elliot Lee
+- rebuilt
+
+* Sun Jun 06 2004 Florian La Roche
+- make sure pflog files have same permissions even if in multiple
+ sub-rpms
+
+* Fri Jun 4 2004 Thomas Woerner 2:2.1.1-1
+- new version 2.1.1
+- compiling postfix PIE
+- new alternatives slave for /usr/lib/sendmail
+
+* Wed Mar 31 2004 John Dennis 2:2.0.18-4
+- remove version from pflogsumm subpackage, it was resetting the
+ version used in the doc directory, fixes bug 119213
+
+* Tue Mar 30 2004 Bill Nottingham 2:2.0.18-3
+- add %%defattr for pflogsumm package
+
+* Tue Mar 16 2004 John Dennis 2:2.0.18-2
+- fix sendmail man page (again), make pflogsumm a subpackage
+
+* Mon Mar 15 2004 John Dennis 2:2.0.18-1
+- bring source up to upstream release 2.0.18
+- include pflogsumm, fixes bug #68799
+- include smtp-sink, smtp-source man pages, fixes bug #118163
+
+* Tue Mar 02 2004 Elliot Lee
+- rebuilt
+
+* Tue Feb 24 2004 John Dennis 2:2.0.16-14
+- fix bug 74553, make alternatives track sendmail man page
+
+* Tue Feb 24 2004 John Dennis 2:2.0.16-13
+- remove /etc/sysconfig/saslauthd from rpm, fixes bug 113975
+
+* Wed Feb 18 2004 John Dennis
+- set sasl back to v2 for mainline, this is good for fedora and beyond,
+ for RHEL3, we'll branch and set set sasl to v1 and turn off ipv6
+
+* Tue Feb 17 2004 John Dennis
+- revert back to v1 of sasl because LDAP still links against v1 and we can't
+- bump revision for build
+ have two different versions of the sasl library loaded in one load image at
+ the same time. How is that possible? Because the sasl libraries have different
+ names (libsasl.so & libsasl2.so) but export the same symbols :-(
+ Fixes bugs 115249 and 111767
+
+* Fri Feb 13 2004 Elliot Lee
+- rebuilt
+
+* Wed Jan 21 2004 John Dennis 2:2.0.16-7
+- fix bug 77216, support snapshot builds
+
+* Tue Jan 20 2004 John Dennis 2:2.0.16-6
+- add support for IPv6 via Dean Strik's patches, fixes bug 112491
+
+* Tue Jan 13 2004 John Dennis 2:2.0.16-4
+- remove mysqlclient prereq, fixes bug 101779
+- remove md5 verification override, this fixes bug 113370. Write parse-postfix-files
+ script to generate explicit list of all upstream files with ownership, modes, etc.
+ carefully add back in all other not upstream files, files list is hopefully
+ rock solid now.
+
+* Mon Jan 12 2004 John Dennis 2:2.0.16-3
+- add zlib-devel build prereq, fixes bug 112822
+- remove copy of resolve.conf into chroot jail, fixes bug 111923
+
+* Tue Dec 16 2003 John Dennis
+- bump release to build 3.0E errata update
+
+* Sat Dec 13 2003 Jeff Johnson