Chapter 23. The K (Database-Map) Configuration Command

Database-maps can be used to look up information in databases, to perform transformations (such as dequoting), to perform computations, and to store values into macros.

What’s New with V8.13

V8.13 sendmail has expanded the roles of database-maps in the following ways:

  • Two new ldap database-map switches have been added: -w (Section 23.1.1.1 [V8.13]) allows you to specify the LDAP API/protocol version to use; -H (Section 23.1.1.2 [V8.13]) allows you to specify an LDAP URI instead of specifying the LDAP server with both the -h host (23.7.11.4[3ed]) and -p port (23.7.11.9[3ed]).[30]

  • LDAP Recursion has been added (Section 23.1.2[V8.13]) with support for the AliasFile option (24.9.1[3ed]) and class macros.

  • The ldap_routing feature’s third argument may now be a literal sendertoo to reject nonexistent envelope sender addresses. (Section 23.1.3 [V8.13])

  • The ldap_routing feature has had its arguments expanded from four to six. Support has been added to suppress an extra lookup of part of an unmatched address and to specify how to handle connection errors to and temporary failures from the LDAP server (Section 23.1.4 [V8.13]).

  • The dnsbl feature (7.2.1[3ed]) no longer uses the host database-map type to look up addresses. Instead, it now uses the dns database-map type (Section 9.1.1 [V8.13]). The DNSBL_MAP_OPT mc macro (Section 9.1.1 [V8.13]) has been added to help tune the use of the dns database-map type with the dnsbl feature. (These new items are described in Chapter 9.)

  • The new socket database-map type (Section 23.1.5 [V8.13]) allows queries to be made over Unix-domain and TCP/IP sockets.

  • The ph database-map type (23.7.18[3ed]) -v switch (formerly deprecated) has been removed. Use the -k switch, instead, which is (and has been) the official replacement switch.

New LDAP Database-Map Switches

V8.13 sendmail has added two new switches to the ldap database-map type: -w and -H.

New LDAP -w database-map switch

When you build sendmail, you can include support for the ldap database-map type by adding -DLDAPMAP to confMAPDEF in your Build m4 file:

APPENDDEF(`confMAPDEF´, `-DLDAPMAP´)

If your LDAP library returns one API version, but your LDAP server uses a different one, you can insist that sendmail use the version on the server by supplying this new -w switch with your ldap database-type declaration. For example, to look up a login name in an LDAP database and have the official email address for that user returned, you might use a declaration like this:

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

Note that the trailing argument to this K configuration line is the new -w switch, which specifies your wish to use LDAP API Version 3 with the server running on host.

If your system’s <ldap.h> include file defines a maximum API version, and you exceed that maximum with -w, the following error will print:

LDAP version specified exceeds max of max in map name

If your system’s <ldap.h> include file defines a minimum API version, and you specify too low a minimum with -w, the following error will print:

LDAP version specified is lower than min in map name

Either error will cause the API version specified with -w to be ignored. For example, on Solaris 9, with Sun supplied LDAP, the minimum and maximum are both set to 3.

New LDAP -H database-match switch

Modern versions of LDAP allow you to specify Universal Resource Identifiers (URI) in place of host and port combinations when specifying an LDAP server. Beginning with V8.13 sendmail, you may specify an LDAP URI by utilizing the new -H database-map switch. For example, prior to V8.13 sendmail, you might have used an mc configuration statement like this:

define(`confLDAP_DEFAULT_SPEC´, `-h ldap.example.gov -p 8389´)

Here, -h specifies the LDAP server host and -p specifies the nonstandard port 8389. Beginning with V8.13, you can simplify this declaration by using the new -H database-map switch:

define(`confLDAP_DEFAULT_SPEC´, `-H ldap://ldap.example.gov:8389´)

One advantage to using -H is that it allows you to fetch the URI from a secure server by using ldaps:// instead of ldap://—for example:

define(`confLDAP_DEFAULT_SPEC´, `-H ldaps://ldap.example.gov -b dc=example,dc=gov´)

Here, the -b LDAP database-map switch (23.7.11.2[3ed]) specifies the base from which to begin the search. If, rather than reading from a TCP/IP socket, your LDAP server uses a Unix-domain socket, you may use ldapi:// instead of ldap://, to access that Unix-domain socket:[31]

define(`confLDAP_DEFAULT_SPEC´, `-H ldapi:// -b dc=example,dc=gov´)

Note that, when you build sendmail with LDAP support, the sendmail source determines whether you have a working ldap_init( ) function in your LDAP library. If you do (and all modern versions of LDAP do), you will be allowed to use the new -H database-map switch. If not, you will see the following warning when you attempt to use it:

Must compile with -DUSE_LDAP_INIT to use LDAP URIs (-H) in map name

If you believe sendmail interpreted your LDAP setup wrongly, you may define USE_LDAP_INIT when building to correct the error.

LDAP Recursion

Prior to V8.13, LDAP lookups could only return the actual data sought, rather than information that would automatically result in another lookup. Beginning with V8.13, lookups are allowed to be recursive. LDAP recursion allows a query to return either: a new query; a Distinguished Name (DN); or an LDAP URL. When any of these are returned, they result in another lookup.

LDAP recursion is requested with the -v ldap database-map switch (23.7.11.14[3ed]), which specifies the list of attributes to return. Recursion is caused by specifying attributes like this:

-v attribute:type:objectclass|objectclass|...

Here, the type can be one of four literal values: NORMAL, DN, FILTER, or URL.

The NORMAL type says that the attribute will be added to the result of the lookup if the record found is a member of the objectclass specified. This is the default type if type is omitted.

The DN type expects that any matches of the attribute have a fully qualified distinguished name. The sendmail program will perform a second lookup of the attribute using the returned DN record.

The FILTER type requires that any matches of the attribute have the value of an LDAP search filter. The sendmail program will perform the same lookup again but will replace the original search filter with the new filter returned.

The URL type expects that the lookup will return a URL. The sendmail program will perform a lookup using the returned URL and will then use the resulting attributes returned.

The objectclass list is optional and, if present, contains the object-class values for which the attribute applies. If there is more than one object-class value, each must be separated from the next by a vertical bar character (|). If object-class values are listed, the attribute will only be used if the LDAP record returned by a lookup is a member of any of the object-class values listed.

Note that recursion is liberal. It is not an error if recursion ultimately fails to lead to an LDAP record. The lookup will simply fail in the same manner as it would if a record does not exist.

To illustrate, consider the following mc configuration file lines.

define(`confLDAP_DEFAULT_SPEC´, `-H ldaps://ldap.example.gov -b dc=example,dc=gov´)

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

First, we use -H when defining confLDAP_DEFAULT_SPEC. The use of ldaps://, instead of ldap://, allows us to connect to the secure server, ldap.example.gov.

Second, under the LOCAL_CONFIG part of our mc configuration file, we define a database map using the K configuration command. We give the database-map the name getname and the type ldap. The -k LDAP database-map switch specifies the LDAP search query to use.

The -v ldap database-map switch illustrates LDAP recursion. There are five statements following -v, each on its own line for clarity and each separated from the next by a comma. The first statement is a lone attribute named sendmailMTAAliasValue. Because it lacks a colon-keyword type, it is presumed to be type NORMAL. Here, any value in the sendmailMTAAliasValue attribute will be added to any result-string regardless of any object-classes (because the attribute has no object-classes).

The second statement shows an attribute named mail, defined to be the type NORMAL, with a single object-class called inetOrgPerson. The value in the attribute mail will be added to the result string only if the LDAP record that is looked up is a member of the inetOrgPerson object-class. The type NORMAL is not recursive. Only a single lookup is performed and only a single result is added to the string.

The third statement shows an attribute named uniqueMember, defined to be the type DN, with a single object-class called groupOfUniqueNames. The type DN makes the action associated with the attribute uniqueMember recursive. When uniqueMember is looked up, the return value may contain zero or more DN records that belong to the object-class groupOfUniqueNames. Each of those returned DN records will again be searched to find any of the attributes listed in the -v line.

The forth statement shows an attribute named sendmailMTAAliasSearch, defined to be the type FILTER, with an object-class sendmailMTAAliasObject. The type FILTER makes the attribute sendmailMTAAliasSearch recursive. A lookup is made using the initial search (the -k line) to find any new filters that are in the object-class sendmailMTAAliasObject. For any that are found, a second lookup is performed using each new filter, to return any records that contain any of the attributes listed in the -v line.

The fifth statement shows an attribute named sendmailMTAAliasURL, defined to be the type URL, with an object-class called sendmailMTAAliasObject. The type URL makes the attribute sendmailMTAAliasURL recursive. A lookup is made using the default URL to find any new URLs that are in the object-class sendmailMTAAliasObject. For any that are found, a second lookup is performed using each new URL to return records that contain the attributes requested in the original search.

LDAP default schema for aliases includes recursion

As of V8.13, the default schema for alias lookups using LDAP has been changed to include LDAP recursion support. Recall that you declare alias lookups with LDAP like this:

define('ALIAS_FILE´, `ldap:´)

This causes aliases to be looked up using LDAP and the following default schema:

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

See Section 23.1.2 [V8.13] for a description of this schema.

Note that sendmail macros (such as $j just shown) are not expanded when the default schema is first defined. Rather, they are expanded each time an LDAP lookup is performed.

In the event you wish to use your own schema rather than the default, you may do so by appending it to the ldap: when defining ALIAS_FILE:

define(`ALIAS_FILE´, `ldap:-k (&objectClass=mg)(mail=%0) -v mmember´)

Here, we replaced the long, recursive default schema above with a much shorter and nonrecursive schema of our own design.

See cf/README in the sendmail source distribution for an additional discussion of the default schema and how to use it.

LDAP default schema for classes includes recursion

As of V8.13, the default schema for class macro assignments using LDAP has been changed to include LDAP recursion support. Recall (22.1.3.2[3ed]) that you declare classes with LDAP, for example, like this:

                  RELAY_DOMAIN_FILE(`@LDAP´)

This causes the class $=R (see 7.4.1.2[3ed]) to be filled with values that match a sendmailMTAClassName with the value R. More generally, for any class X, the following default schema will be used:

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

Note that sendmail macros (such as $j shown earlier) are not expanded when the default schema is first defined. Rather, they are expanded each time an LDAP lookup is performed.

See 7.4.1.2[3ed] for a discussion of how to define you own default schema when declaring a class. Also, see cf/README in the sendmail source distribution for additional discussion of this default schema and how to use it.

ldap_routing Reviews Envelope Sender

Recall that the ldap_routing feature (23.7.11.17[3ed]) is used like this:

FEATURE(`ldap_routing´, `newldapmh
               ´, ` 
               newldapmra
               ´,  `
                  bounce                
               ´,  `
                  detail                
´)

Prior to V8.13, the third argument (bounce) could only be one of two literal words: bounce or passthru. If the third argument was present and was neither an empty string nor the literal string passthru, failed lookups would bounce.

Beginning with V8.13, a new literal word, sendertoo, may be used in place of either bounce or passthru. When you specify sendertoo, you cause the envelope sender to also be rejected if that address is not found in LDAP. Thus, sendertoo acts as if bounce was also specified (that is, both not-found recipients and senders will be rejected).

The ldap_routing Feature Offers More

Recall that the ldap_routing feature (23.7.11.17[3ed]) is used like this:

FEATURE(`ldap_routing´, `newldapmh
               ´, ` 
               newldapmra
               ´,  `
                  bounce                
               ´, `detail
               ´)

Beginning with V8.13, two more arguments are now available for your use:

FEATURE(`ldap_routing´, `newldapmh´, ` 
               newldapmra´,  `
                  bounce                
´, `detail´, ` 
               
                  nodomain                
´,  `
                  tempfail                
´)

The new fifth argument, nodomain, is an argument with no special word required (nodomain, no, and UncleBob, for example, will all work). Without this new argument, a failed lookup of an address ([email protected]) will cause the @host.doman part of the address to also be looked up in LDAP. Now, the presence of a nodomain argument prevents that secondary lookup.

The new sixth argument, tempfail, can be one of two possible literal expressions: tempfail or queue. These tell sendmail what do if sendmail cannot connect to the LDAP server, and what to do if the LDAP lookup fails because of a temporary LDAP failure. If the sixth argument is missing or if it is the queue literal, the message will be queued for a later attempt. If the sixth argument is the tempfail literal, the message will be temporarily rejected with a 4yz reply code. We recommend you use queue rather than omitting the sixth argument (relying on the default) to make your intent clear.

The socket Database-Map Type

Beginning with V8.13 sendmail, a new database-map type called socket is available for your use.[32] Declare an socket database-map type like this:

Kname socket type:port@host

Here, name is the identifier that you will later use in rule sets. The type:port@host is declared in the same fashion as a Milter is declared, by using the X configuration command (7.6.2[3ed]). For example:

Ktrustedip socket inet:[email protected]

Here, lookups can be made in rule sets using the database-map trustedip. The sendmail program will make an IPv4 connection (the inet) to port 8020 on the host db5.example.gov. Once the connection has been made, lookups are performed using a simple dialogue that looks like this:

               sendmail sends:     database_map_name key
sendmail receives:   status datum

Note that neither what is sent nor received may end in a carriage-return/linefeed pair, or in a carriage-return only, or in a linefeed only. Also note that the two parts of each dialogue are separated by a single space character.

Both the sent request and the received reply begin and end with characters that denote their length and termination.[33] The length is an ASCII representation of the number of characters sent or received, stated as a prefix and a colon. The entire sent or received message is terminated by a comma. The length prefix does not include the comma. For example:

               sendmail sends:    17:trustedip 1.2.3.4,
sendmail receives:  14:OK VERYTRUSTED,

The sendmail program sends the database-map name declared earlier using a K configuration command. In our example, this is the database-map named trustedip. That name is followed by a single space and then the key to look up in the database. Again, the entire request is prefixed with the length and a colon and terminated with a comma (and excludes any terminating newline or carriage-return characters).

The connected-to host replies with one of the keywords shown in Table 23-1. Each must be completely uppercase. The keyword is followed by a single space, then information appropriate to the keyword (for OK, this is the sought datum). The entire reply is prefixed with a length and a colon and terminated with a comma.

Table 23-1. The socket database-map reply keywords

Keyword

Description

OK

The key was found in the database, and the datum is the value sought.

NOTFOUND

The key was not found in the database, and the datum is empty.

TEMP

A temporary failure occurred while performing the lookup. The datum may contain an explanatory message.

TIMEOUT

The lookup timed out. The datum may contain an explanatory message.

PERM

A permanent failure occurred while performing the lookup. The datum may contain an explanatory message.

To illustrate, consider the need to look up the name of the central mail server for your department. If such a database-map were called mailservers, you could use the following configuration file line to look up your domain in that database-map:

Kmailservers socket -o inet:[email protected]
...
R $* <@ $+ > $*          $: $1<@$2>$3 <$(mailservers $2 $)>
R $* <@ $+ > $* <$+>     $#smtp $@ $4 $: $1 < @ $2 > $3
...

Here, we look up the host part of an address ($2) in the mailservers database on the host db4.example.gov. The -o makes the existence of the database-map optional. If the host part is found, it is rewritten to be the name of the mail server for that host. In the last rule, we forward the original address to that server.

Only a few database switches are available with this socket database-map type. They are shown in Table 23-2.

Table 23-2. The socket database-map type K command switches

Switch

sendmail text reference

Description

-a

23.3.2[3ed]

Append tag on successful match

-D

23.3.3[3ed]

Don’t use this database map if DeliveryMode=defer

-f

23.3.4[3ed]

Don’t fold keys to lowercase

-m

23.3.7[3ed]

Suppress replacement on match

-N

23.3.8[3ed]

Append a null byte to all keys

-O

23.3.9[3ed]

Never add a null byte

-o

23.3.10[3ed]

This database map is optional

-q

23.3.11[3ed]

Don’t strip quotes from key

-S

23.3.12[3ed]

Space replacement character

-T

23.3.13[3ed]

Suffix to return on temporary failure

-t

23.3.14[3ed]

Ignore temporary errors

Note that the socket database-map type is available only if sendmail is compiled with the SOCKETMAP compile-time macro (Section 3.1.1 [V8.13]) defined when you build sendmail (which is normally not done by default).

For examples of how to use this new socket database-map type, see the files contrib/socketmapServer.pl and contrib/socketmapClient.pl.



[30] These new ldap switches allow the use of ldapi and ldaps (if supported by the underlying LDAP libraries).

[31] Note, however, in order to use Unix domain sockets, your underlying LDAP library must support Unix-domain sockets.

[32] The sendmail program needs to be built with SOCKETMAP defined (Section 3.1.1 [V8.13]) in order to use this new database-map type. NETUNIX is required to use Unix-domain sockets but is generally defined by default.

[33] The protocol for socketmap uses the “netstring” format invented by D.J. Bernstein. This format is described at http://cr.yp.to/proto/netstrings.txt.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.216.11