Previous Section Next Section

ldap (was ldapx)

The Lightweight Directory Access Protocol V8.8 and above

LDAP stands for Lightweight Directory Access Protocol and provides access to a new service based on X.500. Additional information about LDAP is available from http://www.ldapman.org/.

The ldap database-map type is used to look up items in that directory service. (Prior to V8.10, this was called ldapx to reflect its experimental condition at the time. That prior name still works but is deprecated.) The ldap database-map type is declared like this:

Kname ldap  switches  

Lookups via LDAP are defined entirely by the switches specified. To illustrate, consider the following X.500 entry:

cn=Full Name, o=Organization, c=US
sn=Name
uid=yourname
mail=yourname@mailhub.your.domain
objectclass=person
objectclass=deptperson

To look up a login name in this database and have the official email address for that user returned, you might use a declaration such as this:

Kgetname ldap -k"uid=%s" -v"mail" -hldap_host -b"o=Organization, c=US"

Here we use only three switches:

  • The -k switch is in the form of an ldap_search(3) filter. Here, the key will replace the %s and then the whole expression will be searched using the new key.

  • The -b switch is necessary if you wish to specify the base from which to search.

  • The -h switch is required to specify the host to contact to perform the lookup.

The -k, -h, and -v switches are mandatory.

You can omit selected switches from the K configuration command by defining them with the LDAPDefaultSpec option (LDAPDefaultSpec). In general, this option is used to define the -b and -h switch settings. You can, however, use it to define any number of defaults that you wish.

The following rule can be used with the preceding declaration to look up the preferred mail address for a user:

R $* <@ $=w . > $*       $: $(getname $1 $: $1<@$2>$3 $)

Here we presume that this rule was preceded by a call to the canonify rule set 3 to focus on the host part of the address. If the lookup succeeds, the new (unfocused) address is returned from the mail= line in the database. Otherwise, the original address is returned.

This ldap type has more database switches available for it than most other types. They are all listed in Table 23-16.

Table 23-16. The ldap database-map type K command switches

Switch

§

Description

-1

See this section

Consider successful only if one key is matched

-A

-A

Append values for duplicate keys

-a

-a

Append tag on successful match

-b

See this section

Base from which to begin the search

-D

-D

Don't use this database map if DeliveryMode=defer

-d

See this section

DN to bind to server as

-f

-f

Don't fold keys to lowercase

-h

See this section

Hosts that serve this network database (required)

-k

See this section

The search query (required)

-l

-l (lowercase L)

Set a timeout for the lookup

-M

See this section

The method to use for binding

-m

-m

Suppress replacement on match

-n

See this section

Retrieve attribute names only, not values

-o

-o

The database map is optional

-P

See this section

The secret password to use for binding

-p

See this section

Port to use when connecting to host

-q

-q

Don't strip quotes from key

-R

See this section

Don't autochase referrals

-r

See this section

Allow dereferencing of aliases

-S

-S

Space replacement character

-s

See this section

Search scope of "base," "one," or "sub"

-T

-T

Suffix to append on temporary failure

-t

-t

Ignore temporary errors

-V

See this section

Specify a separator (V8.12 and above)

-v

See this section

Specify the list of attributes to return (required)

-z

See this section

Specify return value delimiter

-Z

See this section

Limit the number of matches to return

Although some of these switches are also used by other database-map types, many of them are unique to this ldap database-map type. In addition to setting switches with the K command, you can also preset selected switches with the LDAPDefaultSpec option (LDAPDefaultSpec).

Each successful lookup can cause a line such as the following to be logged via syslog(3) when the LogLevel option (LogLevel) is greater than 9:

qid: ldap  key  =>  value

Note that the ldap type can be used only if the LDAPMAP compile-time macro was defined when sendmail was compiled (LDAPMAP). Also note that the USING_NETSCAPE_LDAP compile-time macro (USING_NETSCAPE_LDAP) will need to be defined if your ldap libraries are from Netscape or are derived from Netscape's libraries.

The -1 ldap database-map switch

The -1 switch prevents LDAP from returning multiple values when only one is sought. This can be used to save the server from extra work. If -1 is specified, sendmail tells the LDAP server to examine only enough records to determine if there is a single match. That is, if there is more than one match, and if this -1 switch is specified, the lookup will return that no matches were found.

Note the difference between the -Z and -1 switches. A -Z1 (See this section) will return only the first match, while ignoring the rest of the matches. A -1 returns failure if there is more than one match.

The -b ldap database-map switch

The -b switch is used to specify the base tree from which to search. In general, if specified, it should ensure that sendmail will always get a unique result:

-b"o=Organization, c=US"

If the base contains a space character, the entire expression should be quoted. Here, the search will include only records under the tree shown. Essentially, this -b tree specification is prepended to each -k query value just before it is looked up.

The -d ldap database-map switch

The -d switch specifies the distinguished name (DN) to bind to the server as.[11] In general, such names contain spaces and other special characters, and therefore should be quoted. For example:

[11] Under LDAP, to bind to a server is sort of like "logging in" to a Unix machine.

-d"cn=Directory Manager, o=igloo CA, l=Melbourne, st=Victoria, c=AU"

There is no default, and this switch is optional. (See also the -P (See this section) and -M (See this section) switches.)

The -h ldap database-map switch

The -h is mandatory. It specifies the host, or hosts, to which to connect for the LDAP lookup. If you wish to specify a sequence of hosts, you can do so by listing them, each separated from the others by space characters:

-h"hostA hostB"

Here, because a space is the separator, this expression must be quoted. The lookup will cause sendmail to connect to hostA first. If it connects, and if a successful match is found, the lookup terminates and that value is returned. If the lookup fails, no further hosts are connected. If the connection cannot be established, a connection to the next host in the sequence (hostB) is tried, and if successful, the lookup is made on that host. This continues until all connections to all hosts have failed, or until a connection can be made.

In the event that you need to specify a port for a host different from that specified by the LDAP_PORT macro in the LDAP source, you can do so by using the -p switch (See this section), or by adding a port specification to one or more hosts. You add a port specification to a host by appending a colon, and then the port number:

-h"hostA hostB:463"

Here, hostA is contacted on the default port, and hostB is contacted on port 463.

In general, the hosts specified should be fully qualified hostnames:

-h ldaphost              not this
-h ldaphost.your.domain  this is preferred

The -k ldap database-map switch

The -k switch is mandatory. It is used to specify the key to look up. The lookup key is in the form of an ldap_search(3), which can be simple:

-k uid=%s

or complex (note that we split the line to fit the page):

-k (&(objectClass=sendmailMTAClass)(sendmailMTAClassName=ClassName)
   (|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j)))

See your LDAP documentation to learn about the special meaning of some characters (such as % and *) in lookup keys, and how to correctly formulate key lookup expressions.

The -M ldap database-map switch

The -M switch specifies the method to use for binding. It can be one of three case-insensitive, literal expressions that specify the method: none, simple, or krbv4. Or it can be any of these with an LDAP_AUTH_ prefix. If it is any other expression or word, the following error is printed and logged when sendmail starts:

Method for binding must be [none|simple|krbv4] (not bad word) in map name 

The default method is none, which means anonymous access to LDAP. This switch is optional. See also the -P switch (See this section), for simple and krbr4, and the -d switch (See this section), for simple only.

The -n ldap database-map switch

The -n switch is used to limit the returned information to attributes only. An attribute is the information to the left of the = in an X.500 entry:

cn=Full Name,  o=Organization,   c=US  
sn=Name
uid=yourname
mailfrom=youraddress

One use for this switch might be to look up an address to see if it is associated with a mailfrom or mailto attribute. If the address is not found, neither attribute will be returned. Otherwise, the attribute that defines the address will be returned.

The -P ldap database-map switch

The -P switch specifies the secret password to use when authenticating the distinguished name set by the -d switch (See this section). For the simple method (see -M; See this section), this is the pathname of the file containing the secret key. For the krbv4 method, this is the name of the Kerberos ticket file.

The -p ldap database-map switch

The -p switch specifies the port to which to connect on the LDAP server. The default port is defined by LDAP_PORT in the LDAP source. See also the -h switch (See this section) to see how a port number can be associated with individual hosts.

The -R ldap database-map switch

The -R switch is used to enable V2 and above LDAP to follow referrals. If the contacted server does not have the information sought, it can return a referral to one or more other servers that might have the information. With this -R switch specified, sendmail will follow referrals until either the information sought is found, or until no more referrals are given. The -R switch can be used only if sendmail was compiled with the LDAP_REFERRALS compile-time macro defined.

The -r ldap database-map switch

The -r switch specifies how LDAP aliases are dereferenced. In LDAP, you can set a leaf entry (such as ou=hardware) to point to another object in the same name space (such as ou=engineering). This is called an alias entry. When you perform a lookup using an alias, the alias is dereferenced so that what is returned is the value of the object pointed to by the alias. For example, if your company once had two departments:

ou=hardware
ou=software

and those departments were merged into a single one called ou=engineering, you could achieve backward compatibility by turning the two, old leaf entries into aliases pointing to the new one. When sendmail encounters an LDAP alias it has four choices that are reflected by four possible, case-insensitive settings for the -r switch: never means to not follow aliases and instead to return a failed lookup; always means to follow aliases (the default); search means to perform a lookup first and to follow an alias only if the lookup succeeded; and find means to follow an alias only if all attributes match (that is, for example, the alias "cn=x, ou=y" won't be followed if only ou= is looked up). These four keywords can also be prefixed with a literal LDAP_DEREF_ exp+ression. If another word or expression is used, the following error is printed and logged:

Deref must be [never|always|search|find] (not badword) in map name 

The -s ldap database-map switch

The -s switch is used to specify the scope of the search to perform on the LDAP server. There are three allowable scopes and, thus, three settings for the -s switch. They are: base (the default), which retrieves information only about the base distinguished name specified (with the -b switch, See this section); one, which retrieves information about entries one level below the base distinguished name, where the base entry is not included in this scope; and sub which retrieves information about entries at all levels below the base distinguished name, where the base entry is included in this scope. The scope can also be any of these three keywords with an LDAP_SCOPE_ prefix. If it is any other word or expression, the following error is printed and logged when sendmail starts:

Scope must be [base|one|sub] (not badword) in map name 

The -V ldap database-map switch

The -V switch (new with V8.12) allows you to specify a separator such that a lookup can return both an attribute and value separated by that separator. Without this switch, only values are returned. With this switch, attributes/value pairs are returned. For example:

-V=

might cause a successful return to appear like this:

user=bob

The -v ldap database-map switch

The -v switch specifies a list of attributes to return. The attributes must be separated from each other by commas. If the attributes contain spaces, the entire expression must be quoted:

-voc,ou
-v"oc, ou"

If more than one attribute is requested (and if the -z switch (See this section) is omitted), only the first attribute value returned from the LDAP server is given to the rule set. If the -z switch is used to specify a delimiter, all the attributes returned from the LDAP server are returned to the rule that did the lookup, each value separated from the others by that delimiter. For the earlier -v example, and a -z:, the following values might be returned to the rule that did the lookup:

foo:org:bar

When you query multiple attributes from the LDAP server, it can be of benefit to also specify a -V switch (See this section), which causes the attribute name to be returned along with each value. For a -V= (along with the earlier -z:), for example, the following attribute names and returned values might be returned to the rule that did the lookup:

oc=foo:ou=org:oc=bar

Note that if you list too many attributes with -v (usually more than 64), the following error will print and log:

Too many return attributes in name (max 64) 

The -z ldap database-map switch

By default, if a single query matches multiple values, only the first value will be returned unless the -z database-map switch is specified. The -z switch specifies a separator (delimiter) character that will separate one return value from the next when multiple values are returned:

-zchar

Here, char is a single, printable character. If you wish to specify a newline, tab, or backslash, you can do so using backslash-escaped notation (\n for newline, \t for tab, and \ for a backslash). In general, the character selected should not be one that you expect to be part of a returned value. No internal check is made to ensure that the character chosen by you makes sense for your values.

The -Z ldap database-map switch

The -Z switch is used to limit the number of entries returned on a single query. The default is unlimited.

Note the difference between the -Z and -1 switches. A -Z1 will return only the first match, while ignoring the rest of the matches. A -1 (See this section) returns failure if there is more than one match.

The ldap_routing feature

When using ldap, it can be desirable to reroute an address to another host or a different email address. To accomplish this, V8.10 sendmail introduced the ldap_routing feature. In its simplest form it is declared in your mc configuration file like this:

FEATURE(`ldap_routing')

This declaration causes two ldap-type database maps to be defined:

Kldapmh ldap -1 -v mailHost
       -k (&(objectClass=inetLocalMailRecipient)(mailLocalAddress=%0))
Kldapmra ldap -1 -v mailRoutingAddress
       -k (&(objectClass=inetLocalMailRecipient)(mailLocalAddress=%0))

Here, the ldapmh stands for LDAP mail host, and the ldapmra stands for LDAP mail routing address.

Note that the LDAP server's hostname (set with -h) and the base of the lookup (set with -b) were both omitted. This feature presumes you will set those values with the confLDAP_DEFAULT_SPEC option (LDAPDefaultSpec) in your mc configuration file. If you don't, this feature will fail.

For an example of how these database maps work, consider the following partial listing of an LDAP record:

mailLocalAddress: alice@your.domain
mailHost: another.domain
mailRoutingAddress: alice@another.domain

Assume that a rule set first checks to see if the recipients domain is in the class $={LDAPRoute} (See this section). If it isn't, it skips these lookups. Otherwise, the first database map, the ldapmh, looks up the attribute mailLocalAddress, and if the value following that item matches, it looks for the attribute mailHost. If that attribute is found, returns that field's value. The second database map, the ldapmra, also looks up the attribute mailLocalAddress, and if the value following that item matches, it looks for the attribute mailRoutingAddress. If that is found, it returns that field's value.

The preceding two K configuration commands can be replaced with ones of your own design by adding extra arguments to this feature:

                            replaces the declaration following Kldapmh
                             
 
 FEATURE(`ldap_routing', `newldapmh', ` newldapmra')  
                                          
                      replaces the declaration following Kldapmra

For example, the following declaration:

FEATURE(`ldap_routing', `ldap -1 -T<TMPF> -v relayHub
        -k (&(objectClass=inetLocalMailRecipient)(mailLocalAddress=%0))')

would result in this new ldapmh K configuration line:

Kldapmh ldap -1 -v relayHub
       -k (&(objectClass=inetLocalMailRecipient)(mailLocalAddress=%0))

For backward compatibility, this feature will not bounce addresses that fail to be found with a lookup. Instead, they will be delivered as is. If you want to bounce those failed lookups, you can add a third argument to the preceding declaration:

FEATURE(`ldap_routing', `newldapmh', ` newldapmra',  `bounce')

If the third argument is present and is neither an empty string nor the string passthru, failed lookups will bounce. To make your meaning clear, we recommend you restrict your choices to the twoliteral words bounce or passthru. Table 23-17 shows the relationship between the two database maps and the lack or presence of a bounce.

Table 23-17. The ldap_routing feature lookup relationships

Value of mailHost

Value of mailRoutingAddress

Result

Is a local host

Exists

Deliver to mailRoutingAddress address

Is a local host

Does not exist

Deliver to original address

Isis a remote host

Exists

mailRoutingAddress is relayed via mailHost

Is a remote host

Does not exist

Original address is relayed via mailHost

does not exist

Exists

Deliver to mailRoutingAddress address

does not exist

Does not exist

If bounce defined, bounce as "User Unknown." Otherwise, deliver to original address.

If you wish to define how +detail addresses (Section 12.4.4) are handled, you can do so by adding a fourth argument to this feature. That fourth argument must be either a literal strip or a literal preserve:

FEATURE(`ldap_routing', `newldapmh', ` newldapmra',  `bounce', `strip')

If an address contains a +detail (such as george+nospam), strip causes the address to first be looked up with the +detail attached, and if no match is found, strip removes the +detail and looks up the address again. A preserve is the same as strip except that if a mail routing address match is found (with ldapmra), the +detail is copied from the original address and appended to the new address. If neither preserve nor strip is specified, the address is looked up only with the +detail attached.

For this feature to work, you need to set your LDAP entries with an objectClass of inetLocalMailRecipient. If present, there must be only one mailHost attribute, and it must contain a fully qualified hostname as its value. If present, there must be only one mailRoutingAddress attribute, and it must contain a legal RFC2822 address as its value. For example:

dn: uid=alice, o=your.domain, c=US
uid: alice
objectClass: inetLocalMailRecipient
mailLocalAddress: alice@your.domain
mailRoutingAddress: alice@another.domain

This entry would cause mail destined for alice@your.domain to be delivered to the new address alice@another.domain.

The flow of this ldap_routing feature through the parse rule set 0 looks like this:

  1. Basic canonicalization (list syntax, delete local host, etc.)

  2. LOCAL_RULE_0 (Section 4.3.3.2)

  3. FEATURE(ldap_routing)

  4. FEATURE(virtusertable) (FEATURE(virtusertable))

  5. Addresses of the form user@$=w passed to local delivery agent (Section 19.5)

  6. FEATURE(mailertable) (FEATURE(mailertable))

  7. UUCP, BITNET_RELAY ($B), etc.

  8. LOCAL_NET_CONFIG (Section 4.3.3.7)

  9. SMART_HOST (Section 4.3.3.6)

  10. SMTP, local, etc. delivery agents

LDAPROUTE_DOMAIN and LDAPROUTE_DOMAIN_FILE

The ldap_route feature (explained earlier) only looks up addresses with domains that are listed with the $={LDAPRoute} class. The mc configuration technique provides two macros that facilitate the process of adding domains to the $={LDAPRoute} class:

LDAPROUTE_DOMAIN(`list of domains')
LDAPROUTE_DOMAIN_FILE(`file')

The first form directly adds the list of domains to the $={LDAPRoute} class by creating a C configuration file command. The second indirectly adds domains to the $={LDAPRoute} class by reading them from a file. It does this by creating a F configuration file command.

LDAPROUTE_EQUIVALENT and LDAPROUTE_EQUIVALENT_FILE

In addition to looking up hosts in the $={LDAPRoute} class (explained earlier), the ldap_route feature will also look up hosts in the $={LDAPRouteEquiv} class. The difference is that hosts in this $={LDAPRouteEquiv} class are converted into the MASQUERADE_AS (Section 4.4.2) host's name just before the lookup.

The mc configuration technique provides two macros that facilitate the process of adding hosts to the $={LDAPRouteEquiv} class:

LDAPROUTE_EQUIVALENT(`list of domains')
LDAPROUTE_EQUIVALENT_FILE(`file')

The first form directly adds the list of domains to the class by creating a C configuration-file command. The second indirectly adds domains to it by reading them from a file. It does this by creating an F configuration file command.

Previous Section Next Section