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:
MaXware MetaCenter (http://www.maxware.com/)
Siemens DirXmetahub (http://www.siemens.ie/fixedoperators/CarrierNetworks/Meta/dirxmetahub.htm)
Sun Microsystems SunOne MetaDirectory (http://wwws.sun.com/software/products/meta_directory/home_meta_dir.html)
Novell’s eDirectory and DirXML combination (http://www.novell.com/products/edirectory/)
Microsoft Metadirectory Services (http://www.microsoft.com/windows2000/technologies/directory/MMS)
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.
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 —enable-ldap and —enable-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
—enable-ldap and
—enable-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 [email protected]. 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:
mapattribute
|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 [email protected] -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=orgobjectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
objectGUID:: NDHKI8oYFkqN8da3Gl9a5Q= = objectSid:: AQUAAAAAAAUVAAAAEcNfczJiHypDFwoyUwQAAA= = primaryGroupID: 513 pwdLastSet: 126784120014273696name: Kristi Carter
sAMAccountName: kristi
sAMAccountType: 805306368 sn: Carter userAccountControl: 66048userPrincipalName: [email protected]
uSNChanged: 2963 uSNCreated: 2957 whenChanged: 20021006210839.0Z whenCreated: 20021006210637.0Z
Now, issue a similar query to the proxy server—except 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: [email protected]
When you compare the two results, you will see that:
objectClass: user name: Kristi Carter sAMAccountName: kristi userPrincipalName: [email protected]
has been mapped to:
objectClass: account cn: Kristi Carter uid: kristi mail: [email protected]
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: [email protected] 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.