[ Team LiB ] Previous Section Next Section

9.5 Metadirectories

The term metadirectory describes just about any solution that joins distinct, isolated data sources into a single logical volume. There are several popular metadirectory products on the market:

For the sake of this section, we'll assume that a metadirectory is any directory service that presents an alternate view of a data source. OpenLDAP's proxy backend provides a simple means of translating one directory server's schema into a different view, suitable for particular client applications. There is no replication or synchronization of data because the proxy provides only an alternate view of the target directory; the OpenLDAP server providing the proxy doesn't actually store the data.

Imagine an email client that expects a directory service to provide an email address using the mail attribute type. Now consider that every user in an Active Directory domain is automatically assigned a Kerberos principal name of the form username@domain. If the email domain is configured so that each user's email address and Kerberos principal name (userPrincipalName) are synchronized (perhaps using an LDAP proxy service), then it makes no sense to duplicate this information just to provide a directory-based address book for a picky email application.

This scenario glosses over some details, such as where the mail domain stores email addresses.

Before you can successfully create a proxy server, the Active Directory domain must meet the following requirements:

  • The Active Directory domain must be configured for the DNS domain ad.plainjoe.org.

  • The DNS name ad.plainjoe.org must resolve to the IP address of an Active Directory domain controller for that domain.

  • An account named ldap-proxy must be created in the Active Directory domain for use by the proxy server when binding to a Windows domain controller.

The OpenLDAP proxy feature isn't enabled by default; it must be enabled at compile time by specifying the 容nable-ldap and 容nable-rewrite options to the configure script for slapd:

$ configure --enable-ldap --enable-rewrite

After compiling and installing the new slapd executable, create the new LDAP database in slapd.conf. Remember that a partition in slapd.conf begins with the database directive and continues until the next database section or the end of the file. The new proxy section begins with the declaration:

## Proxy backend to access Active Directory.
database        ldap

This declaration tells slapd to acquire its data from another LDAP server, allowing it to act as a proxy for that server. If OpenLDAP complains that ldap is not a valid database type, verify that 容nable-ldap and 容nable-rewrite were actually used when compiling the server. Even though OpenLDAP will not store any actual data for this partition, slapd must still be given the naming context of the database (ou=windows,dc=plainjoe,dc=org) using the standard suffix paramete:.

suffix          ou=windows,dc=plainjoe,dc=org

This is an arbitrary suffix; it does not correspond to the DN of users' container in Active Directory. The uri and suffixmassage parameters tell slapd about the target directory (the directory being proxied) and the request rewrite rules. Your server must replace the suffix ou=windows,dc=plainjoe,dc=org with cn=users,dc=ad,dc=plainjoe,dc=org before passing any request to the target server. If no rewriting should be performed, the suffixmassage directive can be omitted.

uri             ldap://ad.plainjoe.org/
suffixmassage   ou=windows,dc=plainjoe,dc=org    
                cn=users,dc=ad,dc=plainjoe,dc=org

The binddn and bindpw parameters provide a means of specifying the credentials to use when contacting the remote LDAP directory. Here you use a simple bind. If your proxy server and remote server existed on opposite sites on an insecure, or hostile, network, it would be prudent to modify the uri parameter to use LDAPS:

## Active Directory also allows the userPrincipalName value to be used in LDAP binds,
## so this could be ldap-proxy@ad.plainjoe.org.
binddn    cn=ldap-proxy,cn=users,dc=ad,dc=plainjoe,dc=org
bindpw    proxy-secret

OpenLDAP's proxy code only provides a way to map attributes and object classes defined by its local schema to those stored in the target directory. The syntax for defining a mapping is:

map  attribute|objectclass [local_name|*] foreign_name|*

A map must define whether it applies to an attribute or an objectclass. The name of the local attribute or object class is optional, but remote names are required. The asterisk (*) character can be used to match any name. Your proxy server should map Active Directory's sAMAccountName, name, and userPrincipalName attributes to the locally defined uid, cn, and mail attributes. You also need to map the local account object class to the target user object class. Here are the map statements that perform the mapping:

## Map these.
map     attribute       uid     sAMAccountName
map     attribute       cn      name
map     attribute       mail    userPrincipalName
map     objectclass     account user

The proxy server can filter out any remaining attributes by mapping any remaining remote attributes to nothing:

## Remove the rest.
map     attribute       *

To see the results of this mapping, compare the entry returned by querying Active Directory directly to the result obtained by going through the OpenLDAP proxy. Here's what happens when you query Active Directory; the items that will be provided by the proxy server are shown in bold:

$ ldapsearch -H ldap://ad.plainjoe.org -x  \
  -D ldap-proxy@ad.plainjoe.org -w proxy-secret -x \
  -b "cn=users,dc=ad,dc=plainjoe,dc=org" -LLL \   
  "(sAMAccountName=kristi)"
       
dn: CN=Kristi Carter,CN=Users,DC=ad,DC=plainjoe,DC=org
accountExpires: 9223372036854775807
badPasswordTime: 0
badPwdCount: 0
codePage: 0
cn: Kristi Carter
countryCode: 0
displayName: Kristi Carter
givenName: Joe
instanceType: 4
lastLogoff: 0
lastLogon: 0
logonCount: 0
distinguishedName: CN=Kristi Carter,CN=Users,DC=ad,DC=plainjoe,DC=org
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=ad,DC=plainjoe,DC=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
objectGUID:: NDHKI8oYFkqN8da3Gl9a5Q=  =
objectSid:: AQUAAAAAAAUVAAAAEcNfczJiHypDFwoyUwQAAA=  =
primaryGroupID: 513
pwdLastSet: 126784120014273696
name: Kristi Carter
sAMAccountName: kristi
sAMAccountType: 805306368
sn: Carter
userAccountControl: 66048
userPrincipalName: kristi@ad.plainjoe.org
uSNChanged: 2963
uSNCreated: 2957
whenChanged: 20021006210839.0Z
whenCreated: 20021006210637.0Z

Now, issue a similar query to the proxy server容xcept that you'll look up a uid rather than an Active Directory sAMAccountName, and the root of your search will be the DN that you've assigned to the proxy. This time, the search can be done anonymously. Here's the result:

$ ldapsearch -H ldap://ldap.plainjoe.org -x  \
  -b "ou=windows,dc=plainjoe,dc=org" -LLL "(uid=kristi)"
       
dn: CN=Kristi Carter,ou=windows,dc=plainjoe,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: account
cn: Kristi Carter
uid: kristi
mail: kristi@ad.plainjoe.org

When you compare the two results, you will see that:

objectClass: user
name: Kristi Carter
sAMAccountName: kristi
userPrincipalName: kristi@ad.plainjoe.org

has been mapped to:

objectClass: account
cn: Kristi Carter
uid: kristi
mail: kristi@ad.plainjoe.org

The proxy server returns something slightly different if you remove the directive that filters all the attributes that aren't explicitly mapped (map attribute *):

$ ldapsearch -H ldap://ldap.plainjoe.org -x  \
  -b "ou=windows,dc=plainjoe,dc=org" -LLL "(uid=kristi)"
       
dn: CN=Kristi Carter,ou=windows,dc=plainjoe,dc=org
cn: Kristi Carter
displayName: Kristi Carter
mail: kristi@ad.plainjoe.org
givenName: Kristi
distinguishedName: CN=Kristi Carter,ou=windows,dc=plainjoe,dc=org
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: account
cn: Kristi Carter
uid: kristi
sn: Carter

While this query returns more information than the previous one, it is obvious that slapd is still filtering some of the attributes from the target entry. This filtering occurs because the attributes returned by the query are still controlled by the local schema defined in slapd.conf. If the OpenLDAP installation does not understand a given attribute or object class (for example, userAccountControl), and it has not been mapped to a known local schema item, the unknown value is filtered out.

The LDAP proxy backend supports updating the target directory, should you require it. It also supports local ACLs in the LDAP database section; these ACLs can be used to control access to an LDAP proxy that presents a view of the company's internal directory services to external clients. The slapd-ldap(5) manpage has more details on both of these configuration possibilities.

    [ Team LiB ] Previous Section Next Section