Sun logo      Previous      Contents      Index      Next     

Sun ONE Messaging Server 6.0 Administrator's Guide

Chapter 12
LMTP Delivery

The Sun™ ONE Messaging Server’s MTA can use LMTP (Local Mail Transfer Protocol, defined in RFC 2033) for delivery to the message store in situations where a multi-tier messaging server deployment is used. In these scenarios, where you are using inbound relays and back end message stores, the relays become responsible for address expansion and delivery methods such as autoreply and forwarding and also for mailing list expansion. Delivery to the back end stores historically has been over SMTP which requires the back end system to look up the recipient addresses in the LDAP directory again, thereby engaging the full machinery of the MTA. For speed and efficiency, the MTA can use LMTP rather than SMTP to deliver messages to the back end store. The Sun ONE Messaging Server’s LMTP server is not intended as a general purpose LMTP server, but rather as a private protocol between the relays and the back end message stores. For simplicity of discussion, examples involving two-tier deployments are used.


Note

By design, LMTP is intended for use in multi-tier deployments. It is not possible to use LMTP with single-system deployments.


This chapter consits of the following sections:


LMTP Delivery Features

The MTA’s LMTP server is more efficient for delivering to the back end message store because it:


Messaging Processing in a Two-Tier Deployment Without LMTP

Figure 12-1 presents in pictorial form the following discussion of message processing in a two-tier deployment scenario without LMTP.

Figure 12-1  Two Tier Deployment Without LMTP

Figure 12-1 presents in pictorial form the following discussion of message processing in a two-tier deployment scenario without LMTP.

Without LMTP, in a two level deployment with relays in front of the store systems, the processing of an inbound message begins with a connection on the SMTP port picked up by the dispatcher on the relay machine and handed off to a tcp_smtp_server process. This process does a number of things with the inbound message including:

The smtp_client process then picks up the mail message from the queue and sends it to the mailhost. On the mailhost, some very similar processing takes place. A connection on the SMTP port is picked up by the dispatcher and handed off to a tcp_smtp_server process. This process does a number of things to the message, including:

Then the ims_ms process picks up the mail message and attempts to deliver it to the store.

In this scenario, the enqueuing processing is performed twice, and the MTAs each perform an LDAP lookup.


Messaging Processing in a Two-Tier Deployment With LMTP

Figure 12-2 presents in pictorial form the following discussion of message processing in a two-tier deployment scenario with LMTP.

Figure 12-2  Two Tier Deployment With LMTP

Figure 12-2 presents in pictorial form the following discussion of message processing in a two-tier deployment scenario with LMTP.

With LMTP in place, a connection on the SMTP port of the relay machine is picked up by the dispatcher and handed off to a tcp_smtp_server process. This process does a number of things with the inbound message including:

Addresses of the format user@domain.LMTP and user@domain.LMTPNATIVE are routed to the message store system via a tcp_lmtp channel or a tcp_lmtpnative channel respectively. These channels communicate with the back end message store using LMTP instead of SMTP. On the store machine, a connection to the LMTP port is received by the dispatcher and handed off to the lmtp_server process. The LMTP server then inserts the message into the user's mailbox or into the UNIX native mailbox. If message delivery is successful, the message is dequeued on the relay machine. If unsuccessful, the message remains on the relay machine. Note that the LMTP process on the message store does not engage any MTA machinery for processing addresses or messages.


LMTP Overview

For the most part, the MTA itself can be basically absent from the back end server. The only necessary MTA components are:

While the dispatcher requires MTA configuration files, these files can be very short. The dispatcher must run on the back end server so that it can start the LMTP servers which run under it. Because the dispatcher and the LMTP server use various functions of libimta, this needs to be present on the back end server as well.

The LMTP server does not perform any of the usual MTA enqueuing or dequeuing functions, header processing, or address translations. The relay system performs all the manipulation of the content of the messages and addresses which then presents to the LMTP server the message in exactly the form to be delivered to the message store and with the delivery address already in the form required by the store. Additional recipient information that is usually available as a message is delivered to the store, such as the user’s quota, is presented along with the recipient address as LMTP parameters. Should a delivery attempt fail, the message is left enqueued in the LMTP queue on the relay system.


LMTP Protocol as Implemented

This section provides a sample LMTP dialogue with an explanation of what is seen in that dialogue. The LMTP client on the relay uses standard LMTP protocol to talk to the LMTP server on the back end store. However the protocol is used in specific ways. For example:

---> LHLO
<--- 250 OK

No action is taken on the LHLO message. The reply is always 250 OK.

---> MAIL FROM: address size=messageSizeInBytes
<--- 250 OK

No checks or conversions are made on the originator address. The size= parameter gives a size in bytes for the message that is to be delivered. This is the size of the message exactly as it appears in the protocol. It is not necessarily the exact size of the message, but the actual message size will not exceed this size. The LMTP server allocates a memory buffer of this size to receive the message.

---> RCPT TO: uid+folder@domain xquota=size,number xdflg=xxx
<--- 250 OK

No checks are made on the recipient addresses at the time they are received, but a list of recipients is built for later use. Note that the @domain part of the address is omitted for uids in the primary domain, and that the +folder part is optional. This is the same address format used by the message store channel in the MTA.

The xquota= parameter gives the user’s message quotas which consist of the maximum total size and the maximum number of messages. The MTA provides this information which it retrieves while performing an LDAP lookup on the user to do the address translation. This information is used to keep the quota information in the message store synchronized with the directory. Getting the quota information does not result in an additional performance hit.

The xdflg= parameter specifies a number which is interpreted as a bit field. These bits control how the message is delivered. For example, the bit whose value is 2, if set, guarantees delivery of the message even if the user is over quota.

This interaction may be repeated many times, once for each recipient.

--->DATA
---> <the message text>
--->.

The LMTP client then sends the entire message, dot-stuffed, just as SMTP does. The message finishes with a dot (.) alone on a line. If the message size is exceeded the LMTP server sends:

<--- 500 message too big

and ends the connection.

Assuming that the message is received correctly, the LMTP server then sends back to the LMTP client the status for each recipient given in the RCPT TO: lines. For instance, if the message is delivered successfully, the response is:

<--- 250 2.5.0 address OK

where address is exactly as it appeared on the RCPT TO: line.

The conversation can either repeat with another MAIL FROM: line or end with the following interaction:

---> quit
<--- 221 OK

Table 12-1 shows the possible status codes for each recipient. This three-column table shows the short code in the first column, its long-code equivalent in the second column and the status text in the third column. 2.x.x status codes are success codes, 4.x.x codes are retryable errors, 5.x.x codes are non retryable errors.

Table 12-1  LMTP Status Codes for Recipients 

Short Code

Long Code

Status Text

250

2.5.0

OK

420

4.2.0

Mailbox Locked

422

4.2.2

Quota Exceeded

420

4.2.0

Mailbox Bad Formats

420

4.2.0

Mailbox not supported

430

4.3.0

IMAP IOERROR

522

5.2.2

Persistent Quota Exceeded

523

5.2.3

Message too large

511

5.1.1

mailbox nonexistent

560

5.6.0

message contains null

560

5.6.0

message contains nl

560

5.6.0

message has bad header

560

5.6.0

message has no blank line


Configuring LMTP Delivery

Configuring the LMTP delivery mechanism requires configuration on both the relay machines and on the back end stores. On the relays, the DELIVERY_OPTIONS MTA option (in option.dat) has to be changed so that messages being delivered to the stores are passed to the LMTP channel. The back end store must be configured with the dispatcher but does not need the job controller. The dispatcher must be configured to run the LMTP server.

Configuring the Relays

The default configuration is appropriate for a server which has an MTA and a message store on the same system. In this scenario, the delivery method defined for the user’s message store mailbox constructs an address from the userid and hosted domain and routes the mail to the ims_ms channel. For a relay with an LMTP back end store, the relay must be configured to handle mail even for users which are provisioned on other systems. This is achieved by putting # in front of almost all the rules. The other changes that must be made are related to the methods that have to be performed on the mail store system by proxy over LMTP. These are message store mailbox, native (and, therefore, UNIX), and file.

The value of DELIVERY_OPTIONS must be changed. The current default for delivery options is:

DELIVERY_OPTIONS=\
  *mailbox=$M%$\$2I$_+$2S@ims-ms-daemon,\
  &members=*,\
  *native=$M@native-daemon,\
  *unix=$M@native-daemon,\
  /hold=$L%$D@hold-daemon,\
  &file=+$F@native-daemon,\
  &@members_offline=*,\
  program=$M%$P@pipe-daemon,\
  #forward=**,\
  *^!autoreply=$M+$D@bitbucket

You must change this to:

DELIVERY_OPTIONS=\
  #*mailbox=@$X.LMTP:$M$_+$2S%$\$2I@ims-ms-daemon,\
  #&members=*,\
  #*native=@$X.lmtpnative:$M,\
  #*unix=@$X.lmtpnative:$M,\
  #/hold=$L%$D@hold,\
  #*file=@$X.lmtpnative:+$F,\
  #&@members_offline=*,\
  #program=$M%$P@pipe-daemon,\
  #forward=**,\
  #*^!autoreply=$M+$D@bitbucket

Note that all delivery options have the # prefix character so they can be evaluated on the relay node. Otherwise, there are changes to the delivery options for mailbox, native (and, therefore, UNIX), and file. The object of these rules is to generate addresses that will cause the messages to be sent through the appropriate LMTP channel to the back end servers. The addresses generated are source routed addresses of the form:

@sourceroute:localpart@domain

This causes the message to be routed based on a sourceroute, but the address presented to the remote machine to be independent of that routing. The $X substitution inserts the value of the mailhost attribute for the user. The source route generated, mailhost.lmtp or mailhost.lmtpn, will match either .lmtp or .lmtpn rules that must be added to the imta.cnf file. These take the message to one of the two LMTP channels, one for message store delivery, the other for native delivery. Those rewrite rules strip off the .lmtp or .lmtpn component of the domain name specified in the source route, so the message gets delivered by the right LMTP channel to the right mailhost. The address that gets sent to the LMTP server is defined by the substitution pattern to the right of the source routing address, that is, after the ‘:’. In the case of the mailbox pattern this is $M$_+$2S$\@$2I. This becomes the userid, followed by a ‘+’ and the folder name if there is a folder name in the original address, followed by a ‘@’ and the hosted domain unless the domain is the principle domain for the mail deployment. Note that the file method uses the lmtpnative channel, but that program delivery method causes delivery on the relay machines. If that is not adequate, you will have to configure the MTA on the back end servers. That does not preclude the use of LMTP, but is another option, and is described later.

Note the change in the pattern for the mailbox delivery option. Note also that the autoreply delivery option is now preceded by the character # to force action on the relay machine. Note also that for native and unix file and program delivery methods to be useful, the MTA must be running on the target machine.

You must modify the imta.cnf file to include a.lmtp* rewrite rules in the rewrite rule section of the file. For example:

! Rewrite rules
!
! lmtp
.lmtp $U%$H@lmtpcs-daemon
!
! lmtpn
.lmtpn $U%$H@lmtpcn-daemon

Note that by default, the LMTP rewrite rules are commented out. You must uncomment them if you want LMTP to work.

You must also include channel definitions for the lmtp and lmtpn channels in the channel definition section of the imta.cnf file. For example:

! tcp_lmtpcs (LMTP client - store)
tcp_lmtpcs defragment lmtp port 225 nomx single_sys subdirs 20 maxjobs 7 pool SMTP_POOL dequeue_removeroute
lmtpcs-daemon

!
! tcp_lmtpcn (LMTP client - native)
tcp_lmtpcn defragment lmtp port 226 nomx single_sys subdirs 20 maxjobs 7 pool SMTP_POOL dequeue_removeroute
!lmtpcn-daemon


Note

Be sure to use the lmtp channel keyword on LMTP channels. Do not use both smtp and lmtp channel keywords on LMTP channels.


Note that by default, the LMTP channel definitions are commented out. You must uncomment them if you want LMTP to work.

Finally, you need to set the service.http.smtphost configutil parameter, which defaults to localhost, to the machine name of the LMTP host. You also need to set the alarm.msgalarmnoticehost configutil parameter, which defaults to localhost, to the machine name of the LMTP host for cases when you send a message to the postmaster.

Configuring the Back End Stores with LMTP and No MTA

The back end stores need no MTA if they are receiving messages over LMTP. This means that they have no job controller, and none of the address rewriting machinery associated with the MTA. They do however still require a dispatcher and a simple MTA configuration. In particular they need a dispatcher.cnf file and a mappings file which comprise the only significant part of the MTA configuration.

The dispatcher.cnf file must contain the following:

! rfc 2033 LMTP server - store
!
[SERVICE=LMTPSS]
PORT=225
IMAGE=IMTA_BIN:tcp_lmtp_server
LOGFILE=IMTA_LOG:tcp_lmtpss_server.log
PARAMETER=CHANNEL=tcp_lmtpss
STACKSIZE=2048000
! Uncomment the following line and set INTERFACE_ADDRESS to an appropriate
! host IP (dotted quad) if the dispatcher needs to listen on a specific
! interface (e.g. in a HA environment).
!INTERFACE_ADDRESS=
!
! rfc 2033 LMTP server - native
!
[SERVICE=LMTPSN]
PORT=226
IMAGE=IMTA_BIN:tcp_lmtpn_server
LOGFILE=IMTA_LOG:tcp_lmtpsn_server.log
PARAMETER=CHANNEL=tcp_lmtpsn
STACKSIZE=2048000
! Uncomment the following line and set INTERFACE_ADDRESS to an appropriate
! host IP (dotted quad) if the dispatcher needs to listen on a specific
! interface (e.g. in a HA environment).
!INTERFACE_ADDRESS=
!

Note that by default, the LMTP services in the dispatcher.cnf file are commented out. You must uncomment them to get LMTP to work.

The normal dispatcher options of MAX_CONNS, MAX_PROCS, MAX_LIFE_CONNS, and MAX_LIFE_TIME can also be set, but need to be set appropriately for your hardware.

The PORT_ACCESS mapping is important. The LMTP implementation for the back end servers is intended as a private protocol between Sun ONE Messaging Server relays and back end stores. You must use the PORT_ACCESS mapping to make sure that only such relays can connect to these services. Your mapping file should look like this:

PORT_ACCESS

  TCP|*|225|1.2.3.4|* $Y
  TCP|*|226|1.2.3.4|* $Y
  TCP|*|225|1.2.3.5|* $Y
  TCP|*|226|1.2.3.5|* $Y
  TCP|*|*|*|* $N500$ Do$ not$ connect$ to$ this$ machine

You should replace the sample IP addresses specified in the PORT_ACCESS mapping table here with the IP addresses of your relays on the network that connect to the back end stores.

There has to be an imta.cnf file, but it is there merely to make the configuration complete. A minimal imta.cnf file consists of the following channel definitions:

! tcp_lmtpss (LMTP server - store)
tcp_lmtpss lmtp subdirs 20
tcp_lmtpss-daemon

!
! tcp_lmtpsn (LMTP server - native)
tcp_lmtpsn lmtp subdirs 20
tcp_lmtpsn-daemon

Note that by default, the LMTP channel definitions are commented out. You must uncomment them if you want LMTP to work.

Configuring Relays for Sending Messages Via LMTP to Back End Systems with Message Stores and Full MTAs

There are situations where you might want the back end stores to have the full capabilities of the MTA but still to have the load savings of using LMTP. For example, you might want program delivery on the back end store. In this case the relays should be configured as described above for relays using LMTP to deliver to the back end store, but with the following for DELIVERY_OPTIONS:

DELIVERY_OPTIONS=\
  #*mailbox=@$X.LMTP:$M$_+$2S%$\$2I@ims-ms-daemon,\
  &members=*,\
  #*native=@$X.lmtpnative:$M,\
  #*unix=@$X.lmtpnative:$M,\
  /hold=$L%$D@hold,\
  #*file=@$X.lmtpnative:+$F,\
  &@members_offline=*,\
  program=$M%$P@pipe-daemon,\
  #forward=**,\
  #*^!autoreply=$M+$D@bitbucket

The only difference is that the # (evaluate on this machine) prefix has gone from some of the rules. For members and members_offline, this means that the logic reverts to the old logic whereby mailing lists are expanded on relays only if there is no mailhost attribute defined for them. For hold, it means that messages for users in the .HELD state will be held in the hold queue on the back end store instead of on the various relays, and for program, it means that the requested programs will be run on the users' mailhosts.

The following shows the DELIVERY_OPTIONS settings that you would use if you are using both SMTP and LMTP in addition to the full MTA on the store system.

DELIVERY_OPTIONS=\
  *mailbox=$M%$\$2I$_+$2S@ims-ms-daemon,\
  &members=*,\
  *native=$M@native-daemon,\
  hold=$M?$I@hold-daemon,\
  *unix=$M@native-daemon,\
  &file=+$F@native-daemon,\
  &@members_offline=*,\
  program=$M%$P@pipe-daemon,\
  forward=**,\
  *^!autoreply=$M+$D@bitbucket

Configuring LMTP on Back End Message Store Systems Having Full MTAs

The only changes from the configuration of a back end store messaging system to one with LMTP direct delivery to the store are that the following lines need to be added to the end of the dispatcher.cnf file:

! rfc 2033 LMTP server - store
!
[SERVICE=LMTPSS]
PORT=225
IMAGE=IMTA_BIN:tcp_lmtp_server
LOGFILE=IMTA_LOG:tcp_lmtpss_server.log
PARAMETER=CHANNEL=tcp_lmtpss
STACKSIZE=2048000
! Uncomment the following line and set INTERFACE_ADDRESS to an appropriate
! host IP (dotted quad) if the dispatcher needs to listen on a specific
! interface (e.g. in a HA environment).
!INTERFACE_ADDRESS=
!
! rfc 2033 LMTP server - native
!
[SERVICE=LMTPSN]
PORT=226
IMAGE=IMTA_BIN:tcp_lmtpn_server
LOGFILE=IMTA_LOG:tcp_lmtpsn_server.log
PARAMETER=CHANNEL=tcp_lmtpsn
STACKSIZE=2048000
! Uncomment the following line and set INTERFACE_ADDRESS to an appropriate
! host IP (dotted quad) if the dispatcher needs to listen on a specific
! interface (e.g. in a HA environment).
!INTERFACE_ADDRESS=
!

Note that by default, the LMTP services in the dispatcher.cnf file are commented out. You must uncomment them to get LMTP to work. Also, the LMTP port numbers are just examples, and can be anything you choose.

This is the same as the whole dispatcher.cnf file described above for when the back end store is configured only for LMTP. The mappings file also requires the PORT_ACCESS mappings as described for LMTP only back end stores.



Previous      Contents      Index      Next     


Copyright 2003 Sun Microsystems, Inc. All rights reserved.