Mailing List Archive

Repost, with added information, Postfix+MySQL+DBMail
I mentioned that we've simplified adding domains to our mail server,
in part because our customers keep giving us domains to add... B-)

Most of what follows was posted originally on 19 January, but, as
Eelco says the older archives are not all that great, I'm reposting
it, and embellishing it.

----- Old stuff -----

The following assumes that your Postfix installation is compiled with
MySQL support. If you are running a pre-configured executable, such as
supplied with RedHat, Mandrake, or other Linux distribution, this will
not be true; you must recompile from the source code to add it. This
is a separate issue, which I will not address here, other than to say
you must have the MySQL development library and headers installed, as
well as those for any other options Postfix uses, such as the DBM
package.

Create a file to control the Postfix/MySQL interface for the transport
table. I called mine 'my_trans.cf', and it is placed in the
/etc/postfix directory. This file contains the information necessary
for Postfix to connect to the database and table, and what fields to
use to retrieve information.

my_trans.cf contents:
---
user = postfix
password = [password]
dbname = forwarder
table = mytransport
hosts = 192.168.2.142
select_field = transport
where_field = domain
---

This table will do two things for us in DBMail; it will tell Postfix
that it is the final destination for domains (replacing
'mydestination'), as well as how to handle that mail after it is
received. Here is the structure of the table I use:

#
# Table structure for table 'mytransport'
#

CREATE TABLE mytransport (
id int(7) NOT NULL auto_increment,
domain varchar(40) NOT NULL,
transport varchar(40) NOT NULL,
comment varchar(40),
PRIMARY KEY (id)
);

You may wish to resize the domain and transport fields to suit your
needs, such as if you have a long domain name to handle OR you have
one or more domains that require more complex routing.

Postfix needs to be told to use the transport table; this is done with
the following lines added to main.cf:

Excerpt from main.cf:
---
mydestination = mysql:/etc/postfix/my_trans.cf
transport_maps = mysql:/etc/postfix/my_trans.cf
---

Below are sample contents of my forwarder.mytransport table:

---
id domain transport comment
1 csrye.org dbmail: First Test
2 espi.com dbmail: Second test victim
3 cruftware.com dbmail:
4 dididahdahdidit.com dbmail:
---

Using this configuration, Postfix consults the mytransport table each
time a message arrives to see if it is the final destination for that
domain. If it is, it then accesses it again to see how to dispose of
the message... in this case, hand it over to dbmail.

The Postfix documentation on this subject is confusing at best. You
are told to NOT use 'mydestination' for virtual domains, because that
is what virtual maps are for. However, when I put the virtual domains
into a VIRTUAL table, Postfix insisted on then checking the virtual
table for translation information for the individual users. Not
finding it, it bounced the mail, rather than handing it over to
dbmail.

Eelco put me onto the path of using 'mydestination' instead, and it
works. I refined it to use a MySQL table, which allows me to add
domains without restarting Postfix.

----- New stuff -----

To add a domain to the above system requires two queries, one to the
Postfix transport table, the other to DBMail's aliases table. The PHP
code snippets below assume the following conditions (your installation
will vary):

Postfix control database = forwarder
Postfix transport table = mytransport
DBMail database = dbmail
New domain name in the variable $domain
Postmaster account entry = 1

(everyone puts the postmaster in as their first account, right? B-)

<?
// insert domain into transport table
$query= "insert into forwarder.mytransport (domain,transport) ";
$query= $query . "values ('$domain','dbmail:')";
mysql_query($query,$dbconnection);
// insert postmaster entry into aliases table
$query= "insert into dbmail.aliases (alias,deliver_to) ";
$query= $query . "values ('postmaster@$domain','1')";
mysql_query($query,$dbconnection);
?>

Using the setup from the first section, Postfix will find the new
domain immediately, and start accepting mail for it. The same table
tells Postfix to turn it over to DBMail for delivery. The domain also
is now set up to receive mail directed to the postmaster, making it
compliant with RFCs.

One side note on all of the above - we're debating using the 'id'
field from the mytransport table for the 'client_id' field in
dbmail.user and dbmail.aliases, allowing us to sort reports by
domain... it is simpler than doing multiple queries for matching
domain names, and I'm assuming that is why 'client_id' exists...

--
Jeff Brenton
President,
Engineered Software Products, Inc
http://espi.com
Questionable web page: http://dididahdahdidit.com