summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJimmy Bergman2012-09-24 08:41:36 +0200
committerJimmy Bergman2012-09-24 08:41:36 +0200
commite61137c1d2fc50b52951a995de516b35fd977ffb (patch)
tree14ae1f93a9c4f0887d0a8eca0ca921e9d18f2dd1
parenta3516893922c74b88f71ce62227adf5a683baa00 (diff)
downloadmailman-e61137c1d2fc50b52951a995de516b35fd977ffb.tar.gz
mailman-e61137c1d2fc50b52951a995de516b35fd977ffb.tar.zst
mailman-e61137c1d2fc50b52951a995de516b35fd977ffb.zip
-rw-r--r--src/mailman/docs/MTA.rst17
-rw-r--r--src/mailman/mta/postfix.py60
2 files changed, 73 insertions, 4 deletions
diff --git a/src/mailman/docs/MTA.rst b/src/mailman/docs/MTA.rst
index c6d2230c4..940668c36 100644
--- a/src/mailman/docs/MTA.rst
+++ b/src/mailman/docs/MTA.rst
@@ -102,17 +102,26 @@ file::
hash:/path-to-mailman/var/data/postfix_lmtp
local_recipient_maps =
hash:/path-to-mailman/var/data/postfix_lmtp
+ relay_domains =
+ hash:/path-to-mailman/var/data/postfix_domains
where `path-to-mailman` is replaced with the actual path that you're running
Mailman from. Setting `local_recipient_maps` as well as `transport_maps`
allows Postfix to properly reject all messages destined for non-existent local
-users.
+users. Setting `relay_domains` means postfix will start to accept mails for
+newly added domains even if they are not part of `mydestination`.
-Virtual domains
----------------
+Postfix documentation
+---------------------
-TBD: figure out how virtual domains interact with the transport maps.
+For more information regarding how to configure Postfix, please see
+the postfix documentation at:
+
+.. _`The official Postfix documentation`:
+ http://www.postfix.org/documentation.html
+.. _`The reference page for all Postfix configuration parameters`:
+ http://www.postfix.org/postconf.5.html
Sendmail
diff --git a/src/mailman/mta/postfix.py b/src/mailman/mta/postfix.py
index c04e38f02..4fc097ffc 100644
--- a/src/mailman/mta/postfix.py
+++ b/src/mailman/mta/postfix.py
@@ -64,6 +64,7 @@ class LMTP:
# We can ignore the mlist argument because for LMTP delivery, we just
# generate the entire file every time.
self.regenerate()
+ self.regenerate_domain()
delete = create
@@ -107,6 +108,46 @@ class LMTP:
log.error(msg, command, status, errstr)
raise RuntimeError(msg % (command, status, errstr))
+ def regenerate_domain(self, output=None):
+ """The map for all list domains
+
+ The format for Postfix's LMTP transport map is defined here:
+ http://www.postfix.org/transport.5.html
+ """
+ # Acquire a lock file to prevent other processes from racing us here.
+ lock_file = os.path.join(config.LOCK_DIR, 'mta')
+ with Lock(lock_file):
+ # If output is a filename, open up a backing file and write the
+ # output there, then do the atomic rename dance. First though, if
+ # it's None, we use a calculated path.
+ if output is None:
+ path = os.path.join(config.DATA_DIR, 'postfix_domains')
+ path_new = path + '.new'
+ elif isinstance(output, basestring):
+ path = output
+ path_new = output + '.new'
+ else:
+ path = path_new = None
+ if path_new is None:
+ self._do_write_file_domains(output)
+ # There's nothing to rename, and we can't generate the .db
+ # file, so we're done.
+ return
+ # Write the file.
+ with open(path_new, 'w') as fp:
+ self._do_write_file_domains(fp)
+ # Atomically rename to the intended path.
+ os.rename(path + '.new', path)
+ # Now that the new file is in place, we must tell Postfix to
+ # generate a new .db file.
+ command = config.mta.postfix_map_cmd + ' ' + path
+ status = (os.system(command) >> 8) & 0xff
+ if status:
+ msg = 'command failure: %s, %s, %s'
+ errstr = os.strerror(status)
+ log.error(msg, command, status, errstr)
+ raise RuntimeError(msg % (command, status, errstr))
+
def _do_write_file(self, fp):
"""Do the actual file writes for list creation."""
# Sort all existing mailing list names first by domain, then by local
@@ -137,3 +178,22 @@ class LMTP:
for alias in aliases:
print(ALIASTMPL.format(alias, config, width), file=fp)
print(file=fp)
+
+ def _do_write_file_domains(self, fp):
+ """Do the actual file writes of the domain map for list creation."""
+ # Sort all existing mailing list names first by domain, then my local
+ # part. For postfix we need a dummy entry for the domain.
+ by_domain = []
+ for list_name, mail_host in getUtility(IListManager).name_components:
+ by_domain.append(mail_host)
+ print("""\
+# AUTOMATICALLY GENERATED BY MAILMAN ON {0}
+#
+# This file is generated by Mailman, and is kept in sync with the binary hash
+# file. YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you know what you're
+# doing, and can keep the two files properly in sync. If you screw it up,
+# you're on your own.
+""".format(now().replace(microsecond=0)), file=fp)
+ for domain in sorted(by_domain):
+ print("""{0} {0}""".format(domain), file=fp)
+