Sun Java System Messaging Server 6 2005Q4 Administration Guide

Domain Locality Determination

Starting with an address of the form user@domain, the address translation and routing process first checks to see if domain is local.

Rewrite Rule Machinery

A facility has been added to the MTA rewrite rule machinery to check a given string to see if it is a domain we need to handle locally. This new facility is activated by a $V or $Z metacharacter. These new metacharacters are syntactically similar to the existing $N, $M, $Q, and $C metacharacters, that is, they are followed by a pattern string. In the case of $N, $M, $Q, and $C the pattern is matched against either the source or destination channel. In the case of $V and $Z the pattern is a domain and the check is to see whether or not it is local. $V causes a rule failure for a nonlocal domain and $Z causes a rule failure for a local domain.

The handling of these metacharacters is implemented as the following procedure:

  1. Messaging Server checks to see if the current domain matches a valid domain entry in the directory. Go to step 3 if no entry exists.

  2. If the domain has an entry in the directory, the attribute specified by the LDAP_DOMAIN_ATTR_ROUTING_HOSTS MTA option (default mailRoutingHosts) is retrieved from the domain entry. If this attribute is present, it lists the set of hosts able to handle users in this domain. This list is compared against the host specified by the local.hostname configutil parameter and the list of hosts specified by the local.imta.hostnamealiases configutil parameter. These options can be overridden by the LDAP_LOCAL_HOST and LDAP_HOST_ALIAS_LIST MTA options, respectively. If there is a match or the attribute is not present on the domain, the domain is local. If no match occurs, the domain is nonlocal.

    The handling of domains considered to be nonlocal because of the mailRoutingHosts attribute depends on the setting of the ROUTE_TO_ROUTING_HOST MTA option. If the option is set to 0 (the default), the address is simply treated as nonlocal and MTA rewrite rules are used to determine routing. If the option is set to 1, a source route consisting of the first value listed in the LDAP_DOMAIN_ATTR_ROUTING_HOSTS MTA option is prepended to the address.

  3. If no domain entry can be found, remove a component from the left hand side of the domain and go to Step 1. If no components remain continue to Step 4.

    A consequence of this backtracking up the domain tree is that if siroe.com is recognized as local, any subdomain of siroe.com will be recognized as local. Situations may arise where this is undesirable, so an MTA option, DOMAIN_UPLEVEL, is provided to control this behavior. Specifically, bit 0 (value = 1) of DOMAIN_UPLEVEL, if clear, disables retries with domain components removed. The default value of DOMAIN_UPLEVEL is 0.

  4. Vanity domain checking now needs to be performed. Vanity domains do not have domain entries, rather, they are specified by attaching special domain attributes to one or more user entries. The vanity domain check is done by instituting an LDAP search using the LDAP URL specified by the DOMAIN_MATCH_URL MTA option. The value of this option should be set to:

    ldap:///$B?msgVanityDomain?sub?(msgVanityDomain=$D)

    $B substitutes the value of the local.ugldapbasedn configutil parameter; this is the base of the user tree in the directory. The LDAP_USER_ROOT MTA option can be used to override the value of this configutil option specifically for the MTA.

    The actual return value from this search does not matter. What matters is if there is a value to return. If there is a return value the domain is considered to be local, if not it is considered to be nonlocal.

Domain Map Determination of Domain Locality

It is also instructive to note what steps are performed to find valid domain entries in the directory. The steps are schema-level specific. In the case of Sun LDAP Schema 1, they are:

  1. Convert the domain to a base DN in the domain tree. This is done by converting the domain into a series of dc components and then adding a domain root suffix. The default suffix is obtained from the service.dcroot configutil parameter. The default suffix is o=internet. So a domain of the form a.b.c.d would typically be converted into dc=a,dc=b,dc=c,dc=d,o=internet. The service.dcroot configutil parameter can be overridden by setting the LDAP_DOMAIN_ROOT MTA option.

  2. Look for an entry with the base DN found in Step 1 and an object class of either inetDomain or inetDomainAlias. The search filter used for this purpose can be overridden by setting the LDAP_DOMAIN_FILTER_SCHEMA1 MTA option which defaults to (|(objectclass=inetDomain)(objectclass=inetdomainalias)).

  3. Exit with a failure if nothing is found.

  4. If the object class of the entry found is inetDomain, check to make sure the entry has an inetDomainBaseDn attribute associated with the domain entry. If it is present, it is saved for use in subsequent searches for user entries and processing terminates. If it is not present, the entry is assumed to be a domain alias and processing continues with step 5. The MTA option LDAP_DOMAIN_ATTR_BASEDN can be used to override the use of inetDomainBaseDN.

  5. The entry must be a domain alias; look up the new entry referenced by the aliasedObjectName attribute and return to step 4. Processing terminates with a failure if the no aliasedObjectName attribute is present. An alternative to the use of aliasedObjectName attribute can be specified with the MTA option LDAP_DOMAIN_ATTR_ALIAS.

    Note that processing can return to step 4 at most once; domain aliases pointing at domain aliases are not allowed.

In Sun LDAP Schema 2, the action taken is much simpler: The directory is searched for an entry with the object class sunManagedOrganization where the domain appears as a value of either the sunPreferredDomain or associatedDomain attribute. If need be, the use of the sunPreferredDomain and associatedDomain attributes for this purpose can be overridden with the respective MTA options LDAP_ATTR_DOMAIN1_SCHEMA2 and LDAP_ATTR_DOMAIN2_SCHEMA2. The search is done under the root specified by the service.dcroot configutil parameter. The service.dcroot configutil parameter can be overridden by setting the LDAP_DOMAIN_ROOT MTA option. Additionally, domain entries in Schema 2 are not required to have inetDomainBaseDn attributes; if they do not, the base of the user tree is assumed to be the domain entry itself.

Caching Of Domain Locality Information

Due to the frequency with which domain rewrite operations are performed and the expense of the directory queries (especially the vanity domain check) both negative and positive indications about domains need to be cached. This is implemented with an in-memory open-chained dynamically-expanded hash table. The maximum size of the cache is set by the DOMAIN_MATCH_CACHE_SIZE MTA option (default 100000) and the timeout for entries in the cache is set by the DOMAIN_MATCH_CACHE_TIMEOUT MTA option (default 600 seconds).

Error Handling

Temporary server failures during this process have to be handled carefully, since when they occur, it is impossible to know whether or not a given domain is local. Basically two outcomes are possible in such a case:

  1. Return a temporary (4xx) error to the client telling it to try the address again later.

  2. Accept the address but queue it to the reprocessing channel so it can be retried locally later.

Neither of these options is appropriate in all cases. For example, outcome 1 is appropriate when talking to a remote SMTP relay. But outcome 2 is appropriate when dealing with an SMTP submission from a local user.

While it would be possible in theory to handle temporary failures by using multiple rules with the same pattern, the overhead of repeating such queries, even with a cache in place, is unacceptable. For these reasons, the simple success/fall-through-to-the-next-rule matching model of domain rewriting is inadequate. Instead, a special template, specified by the MTA option DOMAIN_FAILURE, is used in the event of a domain lookup failure. When a $V operation fails, this template replaces the remainder of the current rewrite rule template being processed.

Pattern for Domain Check Rewrite Rule

This domain check needs to be performed before other rewrite rules have a chance to operate. This ordering is insured by using the special $* on the left hand side in the rule. The $* pattern is checked prior to any other rules.

Putting It All Together

Taking all the machinery described so far into account, the new rewrite rule we need in the imta.cnf is:

$*     $E$F$U%$H$V$H@localhost

and the value of the DOMAIN_FAILURE MTA option in the option.dat file needs to be:

reprocess-daemon$Mtcp_local$1M$1~-error$4000000?Temporary lookup failure

In this rewrite rule, localhost is the host name associated with the local channel. The value of the DOMAIN_FAILURE option shown here is the default value so it does not need to appear in option.dat under normal circumstances.

The ordering here is especially tricky. The MTA checks $V after the address is rebuilt but before the route is added. This lets the MTA to change the route in the event of a temporary lookup failure. Pending channel match checks are applied any time the insertion point changes, so the @ after the second $H invokes the check. If the check succeeds, the remainder of the template applies and rewrite processing concludes. If the check fails, the rewrite fails and rewriting continues with the next applicable rewrite rule. If the check cannot be performed due to a temporary failure, template processing continues with the value specified by the DOMAIN_FAILURE MTA option. The value of this template first sets the routing host to reprocess-daemon. Then the template checks to see whether or not the MTA is dealing with a reprocessing channel of some sort or tcp_local. If the MTA is dealing with such a channel, the rule continues, making the routing host illegal and specifying a temporary failure as the outcome. If the MTA is not dealing with such a channel, the rule is truncated and successfully terminated, thereby rewriting the address to the reprocess channel.