ProblemYour enterprise wants to use the IETF Internet Draft LDAP Schema for Intranet Mail Routing . You have been asked to configure sendmail to use the IETF draft schema and to read internal mail routing information from the LDAP server. SolutionThis solution requires collaboration between the LDAP administrator and the sendmail administrator. Instructions for the LDAP administratorLocate a copy of the IETF draft schema for intranet mail routing. The schema is documented in the draft-lachman-laser-ldap-mail-routing-02 file available from the IETF. The schema is defined as part of the misc.schema file provided with the OpenLDAP distribution. Include the schema file in the LDAP configuration by adding the following include command to the slapd.conf file: include /etc/openldap/schema/misc.schema See the Discussion section for information on a possible conflict between the misc.schema file and other schema. Additionally, the sendmail.schema file should be copied to the proper path and included in the LDAP configuration, as described in Recipe 1.3. Restart LDAP to ensure that the IETF draft schema and the sendmail schema are available for use. Here is an example: # ps -ax grep slapd 1426 ? S 0:00 /usr/sbin/slapd -u ldap # kill -TERM 1426 # /usr/sbin/slapd -u ldap Create an LDIF file containing the mail routing information. Use the inetLocalMailRecipient object class from the IETF draft schema to format the mail routing data in the LDIF file. Run ldapadd to add the data to the LDAP database. The Discussion section shows an example of this step. sendmail applies LDAP routing to a recipient address when the host portion of that address is listed in class $={LDAPRoute} . To store the $={LDAPRoute} class values on the LDAP server, create an LDIF file containing a sendmailMTAClass record, which is an object class defined in the sendmail.schema file. Set the sendmailMTAClassName attribute to LDAPRoute and define the values for that class using sendmailMTAClassValue attributes. Use ldapadd to convert the LDIF file and add the data to the LDAP database. Instructions for the sendmail administratorDirect sendmail to use LDAP intranet mail routing by adding the ldap_routing feature to the configuration. Add the LDAPROUTE_DOMAIN_FILE macro to load class $={LDAPRoute} , which can be loaded from the LDAP server. Lines, such as the following, should be added to the sendmail configuration: dnl Stop Build from complaining define(`confLDAP_DEFAULT_SPEC', ` -h ldserver -b dc=wrotethebook,dc=com') dnl Identify the recipient hosts that require LDAP mail routing LDAPROUTE_DOMAIN_FILE(`@LDAP') dnl Enable the ldap_routing feature FEATURE(`ldap_routing') Rebuild and reinstall the sendmail.cf file, and restart sendmail as described in Recipe 1.8. DiscussionThis discussion covers both LDAP and sendmail configuration. LDAP configurationFor a query to succeed, sendmail and LDAP must use and understand the same schema. The ldap_routing feature depends on a mail routing schema defined in a draft IETF document. That schema, which is available in the misc.schema file provided with the OpenLDAP distribution, must be included in the LDAP configuration in order for that LDAP to understand the mail routing queries coming from sendmail.
Include the sendmail.schema file in the LDAP configuration to provide support for the other LDAP records used by sendmail. For example, the sendmail configuration in this recipe reads LDAP records to load the $={LDAPRoute} class, which requires the sendmail schema. After the schema files are added to the slapd.conf file, restart slapd to ensure that the schema files have been read and are ready to be used. Add the records required by the ldap_routing feature to the LDAP database using the draft IETF schema. This example shows three possible variations of the LDAP routing record: # cat > ldap-routing dn: uid=kathy, dc=wrotethebook, dc=com objectClass: inetLocalMailRecipient mailLocalAddress: kathy@rodent.wrotethebook.com mailRoutingAddress: kathy@chef.wrotethebook.com dn: uid=alana, dc=wrotethebook, dc=com objectClass: inetLocalMailRecipient mailLocalAddress: alana@wrotethebook.com mailHost: chef.wrotethebook.com dn: uid=craig, dc=wrotethebook, dc=com objectClass: inetLocalMailRecipient mailLocalAddress: craig@horseshoe.wrotethebook.com mailHost: chef.wrotethebook.com mailRoutingAddress: craig@crab.wrotethebook.com Ctrl-D # ldapadd -x -D "cn=Manager,dc=wrotethebook,dc=com" \ > -W -f ldap-routing Enter LDAP Password: SecretLDAPpassword adding new entry "uid=kathy, dc=wrotethebook, dc=com" adding new entry "uid=alana, dc=wrotethebook, dc=com" adding new entry "uid=craig, dc=wrotethebook, dc=com" The object class of the records is inetLocalMailRecipient . Each record contains a mailLocalAddress attribute that sendmail uses as the database key. Records may contain one or both of the attributes mailHost and mailRoutingAddress , which are the values returned to sendmail by the LDAP database. The example shows how these values are first used to build an LDIF file that is then processed by ldapadd to add the records to the LDAP database. Once added to the database, the records can be viewed with ldapsearch : # ldapsearch -LLL -x '(objectClass=inetLocalMailRecipient)' \ > mailLocalAddress mailHost mailRoutingAddress dn: uid=kathy, dc=wrotethebook, dc=com mailLocalAddress: kathy@rodent.wrotethebook.com mailRoutingAddress: kathy@chef.wrotethebook.com dn: uid=alana, dc=wrotethebook, dc=com mailLocalAddress: alana@wrotethebook.com mailHost: chef.wrotethebook.com dn: uid=craig, dc=wrotethebook, dc=com mailLocalAddress: craig@horseshoe.wrotethebook.com mailHost: chef.wrotethebook.com mailRoutingAddress: craig@crab.wrotethebook.com sendmail only queries the LDAP server for routing information if the host portion of the recipient address is listed in the $={LDAPRoute} class. Values in this class can be individually defined using LDAPROUTE_DOMAIN macros or they can be read from a file using the LDAPROUTE_DOMAIN_FILE macro. The sendmail configuration in this recipe uses the LDAPROUTE_DOMAIN_FILE macro and reads the list of values for the $={LDAPRoute} class from the LDAP server. The following example shows how the LDAP administrator might store the $={LDAPRoute} data on the LDAP server so that sendmail can retrieve it later: # cat > ldap-route-domains dn: sendmailMTAClassName=LDAPRoute, dc=wrotethebook, dc=com objectClass: sendmailMTA objectClass: sendmailMTAClass sendmailMTAHost: rodent.wrotethebook.com sendmailMTAClassName: LDAPRoute sendmailMTAClassValue: rodent.wrotethebook.com sendmailMTAClassValue: wrotethebook.com sendmailMTAClassValue: horseshoe.wrotethebook.com Ctrl-D # ldapadd -x -D "cn=Manager,dc=wrotethebook,dc=com" \ > -W -f ldap-route-domains Enter LDAP Password: SecretLDAPpassword adding new entry "sendmailMTAClassName=LDAPRoute, dc=wrotethebook, dc=com" The sample LDIF file contains a sendmailMTAClass record, which is an object class defined in the sendmail.schema file. The record sets the sendmailMTAClassName attribute to LDAPRoute and defines the values for that class using sendmailMTAClassValue attributes. After the LDIF file is converted and added to the LDAP database using the ldapadd command, an ldapsearch command shows the content of the LDAP record: # ldapsearch -LLL -x '(sendmailMTAClassName=LDAPRoute)' sendmailMTAClassValue dn: sendmailMTAClassName=LDAPRoute, dc=wrotethebook, dc=com sendmailMTAClassValue: rodent.wrotethebook.com sendmailMTAClassValue: wrotethebook.com sendmailMTAClassValue: horseshoe.wrotethebook.com LDAP is ready; now sendmail needs to be configured. sendmail configurationThree commands in this recipe's sendmail configuration help sendmail use the LDAP records that we have just created: the confLDAP_DEFAULT_SPEC define, the LDAPROUTE_DOMAIN_FILE macro, and the ldap_routing feature. The confLDAP_DEFAULT_SPEC define sets default values that sendmail uses to access the LDAP database. For many sendmail configurations that use LDAP, the confLDAP_DEFAULT_SPEC define is not required because the default values are correct. The confLDAP_DEFAULT_SPEC define is used in this recipe to prevent sendmail from displaying a warning message. When sendmail is configured with the ldap_routing feature, it complains every time it is run if the configuration does not also contain a confLDAP_DEFAULT_SPEC define. For example: WARNING: Using default FEATURE(ldap_routing) map definition(s) without setting confLDAP_DEFAULT_SPEC option. Adding the confLDAP_DEFAULT_SPEC define to this recipe's configuration eliminates this warning, but, of course, care must be taken to set the correct values for the define. If the values in the confLDAP_DEFAULT_SPEC define are incorrect, sendmail will not be able to query the LDAP server successfully. The sample confLDAP_DEFAULT_SPEC define in the Solution section contains two values:
The values defined by the confLDAP_DEFAULT_SPEC define appear in the sendmail.cf file on the LDAPDefaultSpec option line, as this grep shows: # grep LDAPDefaultSpec sendmail.cf O LDAPDefaultSpec= -h ldserver -b dc=wrotethebook,dc=com Use ldapsearch to test the -h and -b values, as in this example: # ldapsearch -LLL -x -h ldserver \ > -b 'dc=wrotethebook,dc=com' \ > '(objectClass=inetLocalMailRecipient)' mailLocalAddress dn: uid=kathy, dc=wrotethebook, dc=com mailLocalAddress: kathy@rodent.wrotethebook.com dn: uid=alana, dc=wrotethebook, dc=com mailLocalAddress: alana@wrotethebook.com dn: uid=craig, dc=wrotethebook, dc=com mailLocalAddress: craig@horseshoe.wrotethebook.com If the -h and -b arguments work with ldapsearch , they should work for sendmail. The @LDAP string used in place of the file path for the LDAPROUTE_DOMAIN_FILE macro tells sendmail to load the $={LDAPRoute} class from the LDAP server. Either an LDAPROUTE_DOMAIN_FILE macro or some LDAPROUTE_DOMAIN macros must appear in the configuration file when the ldap_routing feature is used because sendmail only uses LDAP routing for hosts listed in the $={LDAPRoute} class. Finally, the ldap_routing FEATURE macro is added to the configuration. The sendmail configuration in the Solution section uses the simplest form of this command, which contains no optional arguments; however, in this form, the ldap_routing feature defines two database maps using two sendmail.cf K commands:
Testing the resultsA few simple tests show the impact of this recipe. First, a sendmail -bt command tests that sendmail is successfully reading the LDAP data: # sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > $={LDAPRoute} rodent.wrotethebook.com horseshoe.wrotethebook.com wrotethebook.com > /map ldapmh alana@wrotethebook.com map_lookup: ldapmh (alana@wrotethebook.com) returns chef.wrotethebook.com (0) > /map ldapmra kathy@rodent.wrotethebook.com map_lookup: ldapmra (kathy@rodent.wrotethebook.com) returns kathy@chef.wrotethebook. com (0) > /quit The $={LDAPRoute} command shows that sendmail successfully loaded this class from the LDAP server. The /map commands show that sendmail can read LDAP routing data from both the ldapmh and the ldapmra maps. Next, sendmail -bv is used to show how the mail delivery triples are rewritten for recipient addresses that contain hostnames listed in $={LDAPRoute} : # sendmail -bv kathy@rodent.wrotethebook.com kathy@rodent.wrotethebook.com... deliverable: mailer esmtp, host chef.wrotethebook. com., user kathy@chef.wrotethebook.com # sendmail -bv alana@wrotethebook.com alana@wrotethebook.com... deliverable: mailer relay, host chef.wrotethebook.com, user alana@wrotethebook.com # sendmail -bv craig@horseshoe.wrotethebook.com craig@horseshoe.wrotethebook.com... deliverable: mailer relay, host chef. wrotethebook.com, user craig@crab.wrotethebook.com Refer back to the ldapsearch shown in an earlier example. You'll see that:
The sendmail -bv tests show how these various return values impact the mail delivery triple:
LDAP routing is only one step in the delivery process. The virtusertable and the mailertable are both applied after LDAP routing, and if the mailer used to deliver to the host returned by LDAP has the F=A flag set, aliasing is also applied. [6] If the mail is relayed to a remote host, that host also processes the address. The sendmail -bv test results clearly show the impact of LDAP routing, but only in part, because this recipe does not perform any subsequent processing on these addresses. On a production system with a more complex configuration, sendmail -bv may not provide such clear results. However, it is possible to test the impact of LDAP rulesets more directly.
The ldap_routing feature adds the LDAPExpand ruleset to query LDAP and process the return value, and it adds two rules to the Parse1 ruleset to call the new ruleset. Use sendmail -bt to check whether or not LDAP routing is applied to a specific address and to see the delivery triple returned for that address. Here is an example: # sendmail -bt ADDRESS TEST MODE (ruleset 3 NOT automatically invoked) Enter <ruleset> <address> > Parse1 craig<@horseshoe.wrotethebook.com.> Parse1 input: craig < @ horseshoe . wrotethebook . com . > LDAPExpand input: < craig < @ horseshoe . wrotethebook . com . > > < craig @ horseshoe . wrotethebook . com > < > canonify input: craig @ crab . wrotethebook . com Canonify2 input: craig < @ crab . wrotethebook . com > Canonify2 returns: craig < @ crab . wrotethebook . com . > canonify returns: craig < @ crab . wrotethebook . com . > LDAPExpand returns: $# relay $@ chef . wrotethebook . com $: craig < @ crab . wrotethebook . com . > Parse1 returns: $# relay $@ chef . wrotethebook . com $: craig < @ crab . wrotethebook . com . > > /quit Recipe 5.10 provides another example of testing the ldap_routing feature by passing an address to Parse1 . [7] See Recipe 5.10 for more details about this ruleset.
The ldap_routing featureThe ldap_routing FEATURE command used in this recipe is the simplest form of the command. The command accepts up to four optional arguments. Here is the complete syntax: FEATURE(ldap_routing, mhmap , mramap , bounce , detail ) The four optional arguments are:
See AlsoThe sendmail book covers the LDAPROUTE_DOMAIN_FILE macro in Section 23.7.11.18, the ldap_routing feature in Section 23.7.11.17, and the arguments available for the confLDAP_DEFAULT_SPEC define in Section 21.7.11. The Using LDAP for Aliases, Maps, and Classes section of the cf/README file also provides important information. |