Using LDAP For Aliases, Maps, And Classes
- Aliases
- Maps
- Classes
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 below show 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. Feedback via sendmail@sendmail.org is encouraged.
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
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')
FEATURE()'s which take an optional map definition argument (e.g.,
mailertable,
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:
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
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')
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
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.
|