Some POP/IMAP servers use nonstandard message stores. Since it would be unreasonable to expect MTAs such as Postfix to understand many different proprietary formats, the Local Mail Transfer Protocol (LMTP) provides a way to pass email messages from one local mail service to another without depending on a common message store. LMTP is based on, and is a simplified version of, SMTP. With LMTP, the server can either accept an email message immediately or it cannot accept it at all. There is no attempt by the LMTP server to queue or redeliver a message that cannot be delivered immediately.
When an MTA makes a delivery to an SMTP server, where the message is destined for multiple recipients, and one or more recipients cannot accept the message for some reason, the SMTP server takes the responsibility of queuing the message to deliver it later, and reports an overall successful delivery to the MTA. LMTP servers do not queue messages, so they must return an individual status reply for every recipient of a particular email message. For those recipients that could not be delivered, the MTA, and not the LMTP server, takes the responsibility of queuing the message and attempting redelivery.
LMTP conversations can occur between mail subsystems on the same machine or on different machines on a local area network. It is not recommended for wide area networks, since the protocol depends on a quick response to indicate whether the message was delivered. With SMTP there is a recognized synchronization problem between sending and receiving mail systems that sometimes causes duplicate messages to be delivered. It is believed that LMTP over wide area networks would make the problem worse.
Apart from delivery to nonstandard message stores, a real benefit of the LMTP protocol is that it allows for a highly scalable and reliable mail system. One or more Postfix servers can receive mail from the public Internet and make deliveries to multiple LMTP backend systems. As the load increases, it is a simple matter to add more boxes to the front- or backend systems.
The most common implementation of LMTP delivery is the Cyrus IMAP server from Carnegie Mellon University. It is available from the Project Cyrus web page at http://asg.web.cmu.edu/cyrus/. Cyrus IMAP uses its own message store, as shown in Figure 7-2. This section looks at how Postfix can use the LMTP protocol to hand off messages to Cyrus IMAP. For more information about configuring Cyrus IMAP, see Managing IMAP by Dianna Mullet and Kevin Mullet (O’Reilly).
Cyrus IMAP is intended to run on servers that provide POP/IMAP access only, where users do not need a shell account. If you are creating a mail server for existing users on a system, you will probably want to use another simpler POP/IMAP solution, such as Qualcomm’s Qpopper (POP access only) or the University of Washington’s IMAP Toolkit, which doesn’t require any special configuration to work with Postfix. This section deals with configuration issues for getting Postfix to work together with Cyrus IMAP.
Cyrus IMAP can listen for LMTP deliveries using either Unix-domain sockets or TCP sockets. You must know which method you are using so that you can configure Postfix appropriately. If you want to use Unix-domain sockets, both Postfix and the Cyrus IMAP server must be on the same machine. If you use TCP sockets, the Cyrus IMAP server could be on the same system or any other system on your network. LMTP delivery is configured in your main.cf file or in a transport map.
For Postfix to accept messages to be delivered locally to Cyrus
IMAP, the destination domain name of the email address must be listed
in the mydestination parameter.
(You may also want to configure Cyrus deliveries via the virtual transport. See Chapter 8.) Then you must configure
Postfix to pass messages to Cyrus IMAP. Use the mailbox_transport, local_transport, or fallback_transport parameter to tell Postfix
how much local processing to do before handing off messages to Cyrus.
If you are using local_transport or
fallback_transport, make sure that
Postfix knows about all of the Cyrus users, by including the usernames
in a lookup table listed with the local_recipient_maps parameter.
mailbox_transportThe mail message is given to the local delivery agent first. The local delivery agent checks for and expands any aliases or entries in .forward files. After expansion of the original address, the message is delegated to the Postfix LMTP client, which delivers it to the LMTP server.
local_transportWhen you specify that the local transport should be LMTP, Postfix transfers the message directly to the Postfix LMTP client. The normal local delivery agent does not process the message at all, so there is no expansion of aliases or .forward files.
fallback_transportWhen the fallback transport is LMTP, Postfix gives the
message to its local delivery agent first. The normal aliases
and .forward files are
expanded, and if the recipient has a normal account on the
system, delivery is made to the appropriate mail store on the
system. If no such account exists, delivery is delegated to the
Postfix LMTP client for delivery to the LMTP server. If you have
actual accounts on the system that should receive email messages
in the conventional message store, and the rest of your email
users do not have system accounts but do receive mail through
the Cyrus IMAP server, you should configure the fallback_transport to use LMTP
delivery.
Specify your chosen transport type using the following format:
xxx_transport =service:socket_type[:/path/to/socket]
For LMTP delivery, service
must be lmtp, which refers to the
lmtp service in the /etc/postfix/master.cf file. The socket_type is either unix or
inet for Unix domain, or TCP sockets, respectively. The
default is inet, which means that
if your LMTP server uses an inet
socket, you can simply specify the service as:
local_transport = lmtp
A typical LMTP transport configuration in /etc/postfix/main.cf using local_transport and a Unix domain socket looks like the
following:
local_transport = lmtp:unix:/var/imap/socket/lmtp
To build Cyrus IMAP, you need the Cyrus SASL library, which is used to authenticate users for the IMAP server.[1] You must first build and install the Cyrus SASL library, and then you can build the Cyrus IMAP server. The Cyrus software requires at least Version 3 of Berkeley DB. If you were using a version of Berkeley DB prior to Version 3, you may need to update your entire system. Having different versions of Berkeley DB intermixed on your system will likely lead to problems that can be difficult to track down. If you have to upgrade your libraries, consider rebuilding other packages that use Berkeley DB (such as Perl and Postfix), so that everything on your system uses the same version of the library.
Follow the instructions in the Cyrus SASL and IMAP distributions to compile and install them correctly on your system. There might be binary distributions available for your platform. Check your normal software sources to see if you can save yourself the trouble of building the Cyrus software.
For this example, assume that you have a Postfix server
receiving mail for the domain example.com. All of
the email accounts are set up within the Cyrus IMAP server running on
the same system, so there are very few actual login accounts on the
system. However, you want mail destined for the root account or postmaster alias to be sent
to the correct person, which means that you need to expand local
aliases before handing off messages to the Cyrus IMAP server. To
achieve this, set the mailbox_transport parameter to point to the
lmtp delivery agent, which will be
configured to deliver mail to the Cyrus IMAP server:
Complete the installation and configuration of Cyrus IMAP on your system. Check the Cyrus configuration file (normally /etc/cyrus.conf) to make sure that it is configured to use Unix-domain sockets, and note the location of the socket file. You should see an entry that resembles the following:
SERVICES {
# add or remove based on preferences
imap cmd="imapd" listen="imap" prefork=0
pop3 cmd="pop3d" listen="pop3" prefork=0
# LMTP is required for delivery
lmtpunix cmd="lmtpd" listen="/var/imap/socket/lmtp" prefork=0
}The lmtpunix entry shows
the correct path to the socket file.
Follow the documentation that came with your package to add users to your Cyrus IMAP server.
Check the /etc/postfix/master.cf to make sure
that the lmtp service is set up
correctly. The line should look like the following:
lmtp unix - - n - - lmtp
If you have a default Postfix installation, the lmtp line will already be in the file,
as shown in the example. The fifth column indicates whether the
LMTP delivery agent should run within a chrooted environment. In
this example, the Postfix LMTP delivery agent must read the socket
file created by the Cyrus IMAP server, so leave this column with
the value n.[2]
Check the main.cf file
to make sure that the domain you are receiving mail for is listed
in the mydestination parameter.
It might be listed explicitly:
mydestination = $myhostname, localhost.$mydomain, $mydomain, example.com
or it might come from the $mydomain variable:
mydomain = example.com mydestination = $myhostname, localhost.$mydomain, $mydomain
Specify that the mailbox_transport parameter should use
the lmtp service from the
master.cf file, and point to
the Cyrus IMAP socket file whose path you determined from the
Cyrus configuration file (see item 1):
mailbox_transport = lmtp:unix:/var/imap/socket/lmtp
# postfix reload[1] It is the same library that is used to add authentication support for Postfix. See Chapter 12 for more information on adding SMTP authentication support to Postfix.
[2] It is possible to set up your system in such a way that allows the LMTP delivery agent to read the socket file even from within the Postfix chroot environment, but it is probably not necessary.