LDAP can be used for aliases, maps, and classes by either specifying your own LDAP map specification or using the built-in default LDAP map specification. The built-in default specifications all provide lookups which match against either the machine's fully qualified hostname (${j}) or a "cluster". The cluster allows you to share LDAP entries among a large number of machines without having to enter each of the machine names into each LDAP entry. To set the LDAP cluster name to use for a particular machine or set of machines, set the confLDAP_CLUSTER m4 variable to a unique name. For example:


define(`confLDAP_CLUSTER', `Servers')


Here, the word `Servers' will be the cluster name. As an example, assume that smtp.sendmail.org, etrn.sendmail.org, and mx.sendmail.org all belong to the Servers cluster.


Some of the LDAP LDIF examples shown below will make use of the Servers cluster. Every entry must have either a sendmailMTAHost or sendmailMTACluster attribute or it will be ignored. Be careful as mixing clusters and individual host records can have surprising results (see the CAUTION sections below).


See the file cf/sendmail.schema for the actual LDAP schemas. Note that this schema (and therefore the lookups and examples below) is experimental at this point as it has had little public review. Therefore, it may change in future versions. Sending feedback via sendmail-YYYY@support.sendmail.org is encouraged (replace YYYY with the current year, e.g., 2005).


Aliases


The ALIAS_FILE (O AliasFile) option can be set to use LDAP for alias lookups. To use the default schema, simply use:


define(`ALIAS_FILE', `ldap:')


By doing so, you will use the default schema which expands to a map declared as follows:


ldap -k (&(objectClass=sendmailMTAAliasObject)
(sendmailMTAAliasGrouping=aliases)
(|(sendmailMTACluster=${sendmailMTACluster})
(sendmailMTAHost=$j))
(sendmailMTAKey=%0))
-v sendmailMTAAliasValue,sendmailMTAAliasSearch:FILTER:sendmailMTAAliasObject,sendmailMTAAliasURL:URL:sendmailMTAAliasObject


NOTE: The macros shown above ${sendmailMTACluster} and $j are not actually used when the binary expands the `ldap:' token as the AliasFile option is not actually macro-expanded when read from the sendmail.cf file.


Example LDAP LDIF entries might be:


dn: sendmailMTAKey=sendmail-list, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAAlias
objectClass: sendmailMTAAliasObject
sendmailMTAAliasGrouping: aliases
sendmailMTAHost: etrn.sendmail.org
sendmailMTAKey: sendmail-list
sendmailMTAAliasValue: ca@example.org
sendmailMTAAliasValue: eric
sendmailMTAAliasValue: gshapiro@example.com


dn: sendmailMTAKey=owner-sendmail-list, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAAlias
objectClass: sendmailMTAAliasObject
sendmailMTAAliasGrouping: aliases
sendmailMTAHost: etrn.sendmail.org
sendmailMTAKey: owner-sendmail-list
sendmailMTAAliasValue: eric


dn: sendmailMTAKey=postmaster, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAAlias
objectClass: sendmailMTAAliasObject
sendmailMTAAliasGrouping: aliases
sendmailMTACluster: Servers
sendmailMTAKey: postmaster
sendmailMTAAliasValue: eric


Here, the aliases sendmail-list and owner-sendmail-list will be available only on etrn.sendmail.org but the postmaster alias will be available on every machine in the Servers cluster (including etrn.sendmail.org).


CAUTION: aliases are additive so that entries like these:


dn: sendmailMTAKey=bob, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAAlias
objectClass: sendmailMTAAliasObject
sendmailMTAAliasGrouping: aliases
sendmailMTACluster: Servers
sendmailMTAKey: bob
sendmailMTAAliasValue: eric


dn: sendmailMTAKey=bobetrn, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAAlias
objectClass: sendmailMTAAliasObject
sendmailMTAAliasGrouping: aliases
sendmailMTAHost: etrn.sendmail.org
sendmailMTAKey: bob
sendmailMTAAliasValue: gshapiro


would mean that on all of the hosts in the cluster, mail to bob would go to eric EXCEPT on etrn.sendmail.org in which case it would go to BOTH eric and gshapiro.


If you prefer not to use the default LDAP schema for your aliases, you can specify the map parameters when setting ALIAS_FILE. For example:


define(`ALIAS_FILE', `ldap:-k (&(objectClass=mailGroup)(mail=%0)) -v mgrpRFC822MailMember')


Maps


FEATURE()'s which take an optional map definition argument (e.g., access, mailertable, virtusertable, etc.) can instead take the special keyword `LDAP', e.g.:


FEATURE(`access_db', `LDAP')
FEATURE(`virtusertable', `LDAP')


When this keyword is given, that map will use LDAP lookups consisting of the objectClass sendmailMTAClassObject, the attribute sendmailMTAMapName with the map name, a search attribute of sendmailMTAKey, and the value attribute sendmailMTAMapValue.


The values for sendmailMTAMapName are:

FEATURE()		sendmailMTAMapName
---------		------------------
access_db		access
authinfo		authinfo
bitdomain		bitdomain
domaintable		domain
genericstable		generics
mailertable		mailer
uucpdomain		uucpdomain
virtusertable		virtuser


For example, FEATURE(`mailertable', `LDAP') would use the map definition:


Kmailertable ldap -k (&(objectClass=sendmailMTAMapObject)
(sendmailMTAMapName=mailer)
(|(sendmailMTACluster=${sendmailMTACluster})
(sendmailMTAHost=$j))
(sendmailMTAKey=%0))
-1 -v sendmailMTAMapValue,sendmailMTAMapSearch:FILTER:sendmailMTAMapObject,sendmailMTAMapURL:URL:sendmailMTAMapObject


An example LDAP LDIF entry using this map might be:


dn: sendmailMTAMapName=mailer, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAMap
sendmailMTACluster: Servers
sendmailMTAMapName: mailer


dn: sendmailMTAKey=example.com, sendmailMTAMapName=mailer, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAMap
objectClass: sendmailMTAMapObject
sendmailMTAMapName: mailer
sendmailMTACluster: Servers
sendmailMTAKey: example.com
sendmailMTAMapValue: relay:[smtp.example.com]


CAUTION: If your LDAP database contains the record above and *ALSO* a host specific record such as:


dn: sendmailMTAKey=example.com@etrn, sendmailMTAMapName=mailer, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAMap
objectClass: sendmailMTAMapObject
sendmailMTAMapName: mailer
sendmailMTAHost: etrn.sendmail.org
sendmailMTAKey: example.com
sendmailMTAMapValue: relay:[mx.example.com]


then these entries will give unexpected results. When the lookup is done on etrn.sendmail.org, the effect is that there is *NO* match at all as maps require a single match. Since the host etrn.sendmail.org is also in the Servers cluster, LDAP would return two answers for the example.com map key in which case sendmail would treat this as no match at all.


If you prefer not to use the default LDAP schema for your maps, you can specify the map parameters when using the FEATURE(). For example:


FEATURE(`access_db', `ldap:-1 -k (&(objectClass=mapDatabase)(key=%0)) -v value')


Classes


Normally, classes can be filled via files or programs. As of 8.12, they can also be filled via map lookups using a new syntax:


F{ClassName}mapkey@mapclass:mapspec


mapkey is optional and if not provided the map key will be empty. This can be used with LDAP to read classes from LDAP. Note that the lookup is only done when sendmail is initially started. Use the special value `@LDAP' to use the default LDAP schema. For example:


RELAY_DOMAIN_FILE(`@LDAP')


would put all of the attribute sendmailMTAClassValue values of LDAP records with objectClass sendmailMTAClass and an attribute sendmailMTAClassName of 'R' into class $={R}. In other words, it is equivalent to the LDAP map specification:


F{R}@ldap:-k (&(objectClass=sendmailMTAClass)
(sendmailMTAClassName=R)
(|(sendmailMTACluster=${sendmailMTACluster})
(sendmailMTAHost=$j)))
-v sendmailMTAClassValue,sendmailMTAClassSearch:FILTER:sendmailMTAClass,sendmailMTAClassURL:URL:sendmailMTAClass


NOTE: The macros shown above ${sendmailMTACluster} and $j are not actually used when the binary expands the `@LDAP' token as class declarations are not actually macro-expanded when read from the sendmail.cf file.


This can be used with class related commands such as RELAY_DOMAIN_FILE(), MASQUERADE_DOMAIN_FILE(), etc:


Command				sendmailMTAClassName
-------				--------------------
CANONIFY_DOMAIN_FILE()		Canonify
EXPOSED_USER_FILE()		E
GENERICS_DOMAIN_FILE()		G
LDAPROUTE_DOMAIN_FILE()		LDAPRoute
LDAPROUTE_EQUIVALENT_FILE()	LDAPRouteEquiv
LOCAL_USER_FILE()		L
MASQUERADE_DOMAIN_FILE()	M
MASQUERADE_EXCEPTION_FILE()	N
RELAY_DOMAIN_FILE()		R
VIRTUSER_DOMAIN_FILE()		VirtHost


You can also add your own as any 'F'ile class of the form:


F{ClassName}@LDAP
  ^^^^^^^^^


will use "ClassName" for the sendmailMTAClassName.


An example LDAP LDIF entry would look like:


dn: sendmailMTAClassName=R, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAClass
sendmailMTACluster: Servers
sendmailMTAClassName: R
sendmailMTAClassValue: sendmail.org
sendmailMTAClassValue: example.com
sendmailMTAClassValue: 10.56.23


CAUTION: If your LDAP database contains the record above and *ALSO* a host specific record such as:


dn: sendmailMTAClassName=R@etrn.sendmail.org, dc=sendmail, dc=org
objectClass: sendmailMTA
objectClass: sendmailMTAClass
sendmailMTAHost: etrn.sendmail.org
sendmailMTAClassName: R
sendmailMTAClassValue: example.com


the result will be similar to the aliases caution above. When the lookup is done on etrn.sendmail.org, $={R} would contain all of the entries (from both the cluster match and the host match). In other words, the effective is additive.


If you prefer not to use the default LDAP schema for your classes, you can specify the map parameters when using the class command. For example:


VIRTUSER_DOMAIN_FILE(`@ldap:-k (&(objectClass=virtHosts)(host=*)) -v host')


Remember, macros can not be used in a class declaration as the binary does not expand them.


LDAP ROUTING


FEATURE(`ldap_routing') can be used to implement the IETF Internet Draft LDAP Schema for Intranet Mail Routing (draft-lachman-laser-ldap-mail-routing-01). This feature enables LDAP-based rerouting of a particular address to either a different host or a different address. The LDAP lookup is first attempted on the full address (e.g., user@example.com) and then on the domain portion (e.g., @example.com). Be sure to setup your domain for LDAP routing using LDAPROUTE_DOMAIN(), e.g.:


LDAPROUTE_DOMAIN(`example.com')


Additionally, you can specify equivalent domains for LDAP routing using LDAPROUTE_EQUIVALENT() and LDAPROUTE_EQUIVALENT_FILE(). 'Equivalent' hostnames are mapped to $M (the masqueraded hostname for the server) before the LDAP query. For example, if the mail is addressed to user@host1.example.com, normally the LDAP lookup would only be done for 'user@host1.example.com' and '@host1.example.com'. However, if LDAPROUTE_EQUIVALENT(`host1.example.com') is used, the lookups would also be done on 'user@example.com' and '@example.com' after attempting the host1.example.com lookups.


By default, the feature will use the schemas as specified in the draft and will not reject addresses not found by the LDAP lookup. However, this behavior can be changed by giving additional arguments to the FEATURE() command:


FEATURE(`ldap_routing', <mailHost>, <mailRoutingAddress>, <bounce>,
<detail>, <nodomain>, <tempfail>)


where <mailHost> is a map definition describing how to lookup an alternative mail host for a particular address;


<mailRoutingAddress> is a map definition describing how to lookup an alternative address for a particular address;


the <bounce> argument, if present and not the word "passthru", dictates that mail should be bounced if neither a mailHost nor mailRoutingAddress is found, if set to "sendertoo", the sender will be rejected if not found in LDAP;


and <detail> indicates what actions to take if the address contains +detail information -- `strip' tries the lookup with the +detail and if no matches are found, strips the +detail and tries the lookup again; `preserve', does the same as `strip' but if a mailRoutingAddress match is found, the +detail information is copied to the new address;


the <nodomain> argument, if present, will prevent the @domain lookup if the full address is not found in LDAP;


the <tempfail> argument, if set to "tempfail", instructs the rules to give an SMTP 4XX temporary error if the LDAP server gives the MTA a temporary failure, or if set to "queue" (the default), the MTA will locally queue the mail.


The default <mailHost> map definition is:


ldap -1 -T<TMPF> -v mailHost -k (&(objectClass=inetLocalMailRecipient)
(mailLocalAddress=%0))


The default <mailRoutingAddress> map definition is:


ldap -1 -T<TMPF> -v mailRoutingAddress
-k (&(objectClass=inetLocalMailRecipient)
(mailLocalAddress=%0))


Note that neither includes the LDAP server hostname (-h server) or base DN (-b o=org,c=COUNTRY), both necessary for LDAP queries. It is presumed that your .mc file contains a setting for the confLDAP_DEFAULT_SPEC option with these settings. If this is not the case, the map definitions should be changed as described above. The "-T<TMPF>" is required in any user specified map definition to catch temporary errors.


The following possibilities exist as a result of an LDAP lookup on an address:


mailHost is	mailRoutingAddress is	Results in
-----------	---------------------	----------

set to a	set			mail delivered to
"local" host				mailRoutingAddress

set to a	not set			delivered to
"local" host				original address

set to a	set			mailRoutingAddress
remote host				relayed to mailHost

set to a	not set			original address
remote host				relayed to mailHost

not set		set			mail delivered to
					mailRoutingAddress

not set		not set			delivered to
					original address *OR*
					bounced as unknown user


The term "local" host above means the host specified is in class {w}. If the result would mean sending the mail to a different host, that host is looked up in the mailertable before delivery.


Note that the last case depends on whether the third argument is given to the FEATURE() command. The default is to deliver the message to the original address.


The LDAP entries should be set up with an objectClass of inetLocalMailRecipient and the address be listed in a mailLocalAddress attribute. If present, there must be only one mailHost attribute and it must contain a fully qualified host name as its value. Similarly, if present, there must be only one mailRoutingAddress attribute and it must contain an RFC 822 compliant address. Some example LDAP records (in LDIF format):


dn: uid=tom, o=example.com, c=US
objectClass: inetLocalMailRecipient
mailLocalAddress: tom@example.com
mailRoutingAddress: thomas@mailhost.example.com


This would deliver mail for tom@example.com to thomas@mailhost.example.com.


dn: uid=dick, o=example.com, c=US
objectClass: inetLocalMailRecipient
mailLocalAddress: dick@example.com
mailHost: eng.example.com


This would relay mail for dick@example.com to the same address but redirect the mail to MX records listed for the host eng.example.com (unless the mailertable overrides).


dn: uid=harry, o=example.com, c=US
objectClass: inetLocalMailRecipient
mailLocalAddress: harry@example.com
mailHost: mktmail.example.com
mailRoutingAddress: harry@mkt.example.com


This would relay mail for harry@example.com to the MX records listed for the host mktmail.example.com using the new address harry@mkt.example.com when talking to that host.


dn: uid=virtual.example.com, o=example.com, c=US
objectClass: inetLocalMailRecipient
mailLocalAddress: @virtual.example.com
mailHost: server.example.com
mailRoutingAddress: virtual@example.com


This would send all mail destined for any username @virtual.example.com to the machine server.example.com's MX servers and deliver to the address virtual@example.com on that relay machine.


LDAP Recursion


LDAP Recursion allows you to add types to the search attributes on an LDAP map specification. The syntax is:


-v ATTRIBUTE[:TYPE[:OBJECTCLASS[|OBJECTCLASS|...]]]


The new TYPEs are:


NORMAL - This attribute type specifies the attribute to add to the results string. This is the default.


DN - Any matches for this attribute are expected to have a value of a fully qualified distinguished name. Sendmail will lookup that DN and apply the attributes requested to the returned DN record.


FILTER - Any matches for this attribute are expected to have a value of an LDAP search filter. Sendmail will perform a lookup with the same parameters as the original search but replaces the search filter with the one specified here.


URL - Any matches for this attribute are expected to have a value of an LDAP URL. Sendmail will perform a lookup of that URL and use the results from the attributes named in that URL. Note however that the search is done using the current LDAP connection, regardless of what is specified as the scheme, LDAP host, and LDAP port in the LDAP URL.


Any untyped attributes are considered NORMAL attributes as described above.


The optional OBJECTCLASS (| separated) list contains the objectClass values for which that attribute applies. If the list is given, the attribute named will only be used if the LDAP record being returned is a member of that object class. Note that if these new value attribute TYPEs are used in an AliasFile option setting, it will need to be double quoted to prevent sendmail from misparsing the colons.


Note that LDAP recursion attributes which do not ultimately point to an LDAP record are not considered an error.


Example


Since examples usually help clarify, here is an example which uses all four of the new types:


O LDAPDefaultSpec=-h ldap.example.com -b dc=example,dc=com


Kexample ldap
-z,
-k (&(objectClass=sendmailMTAAliasObject)(sendmailMTAKey=%0))
-v sendmailMTAAliasValue,mail:NORMAL:inetOrgPerson,
uniqueMember:DN:groupOfUniqueNames,
sendmailMTAAliasSearch:FILTER:sendmailMTAAliasObject,
sendmailMTAAliasURL:URL:sendmailMTAAliasObject


That definition specifies that:


Any value in a sendmailMTAAliasValue attribute will be added to the result string regardless of object class.


The mail attribute will be added to the result string if the LDAP record is a member of the inetOrgPerson object class.


The uniqueMember attribute is a recursive attribute, used only in groupOfUniqueNames records, and should contain an LDAP DN pointing to another LDAP record. The desire here is to return the mail attribute from those DNs.


The sendmailMTAAliasSearch attribute and sendmailMTAAliasURL are both used only if referenced in a sendmailMTAAliasObject. They are both recursive, the first for a new LDAP search string and the latter for an LDAP URL.


Next Section: DNS and Sendmail - 29 of 32



This Web Site Copyright © 1997 - 2008
by Alan Pae - All Rights Reserved