Check out the new USENIX Web site. next up previous
Next: Performance Observations Up: Title Page Previous: Simple LDAP Query Via

Sendmail Enhancements Using LDAP

When Sendmail Version 8[3,4] is compiled with UMich LDAP-3.3 or OpenLDAP (or possibly Netscape Directory Server) libraries, it has direct access to an LDAP database. Sendmail[4,5] also comes with sendmail.cf configuration file examples for using this LDAP access. While Sendmail configuration programming is considered a black art in some cases, the enhancements discussed later used only a small number of additions or changes to the sendmail.cf file to provide the LDAP services previously mentioned.

In addition to Sendmail source code that provides access to LDAP databases, both the UMich LDAP-3.3 and OpenLDAP distributions include useful and important LDAP client contributions, one of which is related to electronic mail and Sendmail: mail500. Mail500[12] is used to provide external access to an LDAP database. Sendmail passes pending messages off to mail500 which does all of the work of extracting e-mail addresses from the LDAP server. Mail500 then passes the messages back to Sendmail for final delivery with the LDAP extracted e-mail addresses in place.

Sendmail can make use of many user-defined databases, which usually are either regular ``flat files,'' or ``hash mapped'' database files. Using LDAP is not necessary to provide for virtual e-mail users, but makes the process more flexible as well as eliminating constant changes to Sendmail configurations and/or databases.

To use the LDAP function from within Sendmail, an LDAP ``database map'' and ``relay host macro'' definition is added to the sendmail.cf configuration file, along with a few additional lines in Sendmail's rule set #5. Using the external LDAP function via mail500 required a one-line addition to Sendmail's rule set #98 and a two-line ``mailer'' definition for the mail500 external ``mailer'' program. The sendmail.cf ``rule sets'' are the means by which Sendmail determines what to do with any given piece of mail.

Each set of additional lines defined a specific character string which when matched to a supplied e-mail address, would invoke the respective LDAP-enabled service. Many trigger combinations are possible, but this implementation limited itself to just the two sets detailed later. The intent is to provide a simple yet effective means of selecting e-mail addresses from a fixed set of virtual e-mail users.

Virtual users, in the context of this facility, are considered to be users whose e-mail addresses map to the local Sendmail server but whose userids (left-hand portion of each of the e-mail addresses) are not found in the Sendmail server's password file. With the modifications mentioned in place, if Sendmail fails to resolve a local userid via its password file, it then calls upon the defined LDAP server to retrieve an e-mail address from the LDAP database. In this manner, many users who have an LDAP entry based on a userid or other attribute which matches the left-hand portion of an e-mail address, and who have an LDAP e-mail attribute defined, can be considered as local to the Sendmail server.

With the aid of LDAP, the number of the e-mail users, their identities, and their final e-mail addresses to be used for mail delivery need not be known in advance by Sendmail, thus obviating work required to create ``static'' user definitions for special purposes. No additional Sendmail configuration is necessary other than what has already been mentioned. Nor is any additional Sendmail configuration necessary when virtual e-mail users change, so long as the required LDAP attribute names do not change.

In Sendmail's rule set #5, one rule compares the given e-mail address with a specific format that separates the left-hand side of the address from the rest. This rule set is used to perform some specific tests on e-mail addresses that are determined to be local to the Sendmail server. One part of it attempts to locate the userid extracted from the e-mail address in the mail server's password database. This occurs in the section labelled as, ``send unrecognized local users to a relay host.'' If the userid is not found, it will later be passed to another Sendmail rule which will attempt to send the pending mail to another mail server, defined as a mail relay.

This implementation inserts a Sendmail rule after the above section to then attempt to look up the userid in the defined LDAP database. Here, the modified Sendmail program itself is the LDAP client. If the database search returns an e-mail address, Sendmail then uses it in place of the original address and eventually attempts to deliver the pending mail to the new e-mail address. This provides for a virtual user who is not directly associated with or defined on the host running the Sendmail server but whose e-mail address conforms to the normal format for that particular server.

In rule set #98, a new rule was added to select processing by the mail500 program. This rule set is part of the Sendmail logic used to determine how the actual mail delivery will be completed, and by which program. As a part of this processing, an external program, such as mail500, may be selected to complete the mail delivery.

In this implementation, the rule added to rule set #98 selects mail based on the following pattern, which matches one of the LDAP cn entries as shown in Figure 4:

<firstname>.<lastname>@<Sendmail server E-mail domain>

Now, mail with the indicated address format will be directed to mail500 for a simple LDAP CN attribute lookup based on the <firstname>.<lastname> portion. If a corresponding mail attribute is found, mail500 will then formulate a new address and pass the mail back to Sendmail for final delivery. This is expected to return a single e-mail address for one person.

Another rule, added later on to rule set #98, selects mail based on the next pattern to extract multiple e-mail addresses associated with a mailing list.

<mailing list name>.mlist@<Sendmail server E-mail domain>

The rule strips off just the mailing list name, and passes it to mail500, along with the contents of the message. Mail500 then searches for a CN attribute belonging to an LDAP rfc822MailGroup object that matches the mailing list name. If found, it then scans the LDAP object for all mail and member attributes, using the corresponding e-mail addresses to form a single mailing list. When all of the addresses are found, mail500 passes the message back to Sendmail with the list of new addresses, and Sendmail finishes the mail delivery, assuming no other matching process occurs with the new e-mail address list.

Part of an LDAP entry that works with these methods might look something like the following:

Figure 4: Sample LDAP Entry For Sendmail Use
\begin{figure}
{\small\begin{verbatim}dn: cn=Jim Dutton, ou=<deparment>,
ou=...
...<userid>
mail: <userid>@<hostname>\end{verbatim}}
\vspace{-0.20in}
\end{figure}

For the LDAP database lookups this facility chose to use the LDAP Common Name (CN) attribute to search for an entry that would have a mail attribute defined. The left-hand side of the e-mail address is extracted via the applicable Sendmail rules. This is then used as the key value for the LDAP CN search. The LDAP search will then return the value of the mail attribute if the corresponding CN attribute is located and it has a mail attribute defined. Another LDAP attribute could have been used to provide the LDAP search key, but it must be related to an LDAP entry which will return a valid e-mail address.

With LDAP, some attributes can have multiple instances whereas others normally cannot. The Common Name attribute is one that is normally allowed to have multiple instances, or occurances, of attribute values. Since this does not require any special LDAP configuration to use, it is easy to make use of in this facility, and in other situations. In the above sample, multiple CN attributes are defined including one with the specific <firstname>. <lastname> format. This provides for multiple versions of a ``name'' attribute which can be used to locate a specific LDAP object, which doesn't necessarily have to be a person.

While an LDAP server also provides for internal substring matching of search keys, thus providing for entry matches based upon part of an attribute value but which can be quite costly to perform, using multiple CNs provides for a set of easily matched and defined qualifiers that may be considered alternative spellings of a primary Common Name. The use of multiple CNs, and some other attributes, increases the probability of an LDAP search hit including the possibility of providing for misspellings of the primary attribute. This becomes very apparent when a user's name as used for the LDAP DN is not the same as the user's name as used in practice. Without additional search qualifiers (i.e., multiple attributes), searches for the specified DN may indeed become difficult and frustrating. This is one of the important benefits of the LDAP data structure and usability.


Subsections
next up previous
Next: Performance Observations Up: Title Page Previous: Simple LDAP Query Via
Jim Dutton
2000-04-24