Open Directory and Active Directory, Part 1

Editor's Note: For the last number of months, Michael Bartosh has
been working on a series of articles for Mac DevCenter readers which
examines Mac OS X's Directory Services architecture in depth and
explores how to integrate these services with Microsoft's Active
Directory. We're looking at three, maybe four installments that will
run about 10 days apart. These articles represent a tremendous amount
of work, and I want to be the first to thank him for this tremendous
effort. Michael will also be sharing his knowledge in person at the
O'Reilly Mac OS X Conference in his session titled, Mac
OS X and Active Directory: A Study in Directory Integration. If
you haven't registered
for this event yet, this article will give you a good idea of the
quality content that will be presented there.

Mac OS X marks a significant first for Apple, an enterprise-capable
operating system. Built from the ground up based on open standards with
powerful
Unix-like underpinnings, it's moving Apple further into the
infrastructures of business and academic computing than ever
before. Critical to this trend is its ability to make use of
enterprise directories, that is, centralized network repositories for
users, groups, security policy and other administrative data. Due to
its ubiquitous nature, Microsoft's Active Directory plays a
particularly important role.

Participants in this session will be exposed to Mac OS X's directory services infrastructure in depth, and will learn to leverage its capabilities to maximize end user satisfaction while minimizing impact on enterprise systems. While Active Directory is the primary example, these strategies are applicable to almost any directory service.

Mac OS X's integration into Active Directory is an interesting phenomenon
since it's not a product of any formalized cooperation between Apple
and Microsoft. Rather, it's a product of open standards, the product
of two vendors conforming to an established specification for
directory services protocols. Out of this ecosystem, rich IT
infrastructures evolve. End users and IT managers alike can take
advantage of Mac OS X's robust feature set while utilizing their
enterprise directory data and providing a single sign on for both
Windows and Mac environments.

However, cross platform directory services are complex, and planning
and implementing integration between Active Directory and Mac OS X has
proven to be a formidable challenge for both Windows and Mac
administrators. Although it's easy to prototype a generalized
infrastructure, adopting that infrastructure to sophisticated,
deployed environments is difficult without a good understanding of
directory services in general, Active Directory, and the capabilities
and data requirements of Mac OS X.

Rather than provide a cookie-cutter recipe for Directory Services integration,
this series of articles seeks to examine Mac OS X's Directory Services
architecture in depth, providing a solid conceptual framework on which
the reader may build services that minimize impact on existing
infrastructure while still providing a good end user experience. While
our deployment target will be Active Directory, the more general
architectural features and capabilities can be easily applied to other
environments as well.

Active Directory integration has been fundamentally changed in Panther,
Mac OS X 10.3. We're working with Apple right now in order to
determine what we can say and when we can say about it. Beyond the
NDAs, though, Jaguar is still very relevant. Apple's OS releases tend
to be wide in scope, resulting in a significant lag between
introduction and deployment while support infrastructures are
updated. In many larger environments, Panther won't be rolled out
until spring or summer of 2004. Because of this, Jaguar maintains its
importance.

Open Directory

In order to understand Mac OS X's place in an enterprise directory,
we first need to understand its capabilities, processes and
configuration. Apple's Directory Services Architecture is known
as Open Directory. You can think of Open Directory as Mac OS X's
Rosetta Stone. Open Directory knows how to talk to LDAP
directories so that specific Mac OS X applications (like Apache or
loginwindow) don't have to. In a very general sense, the process
looks something like this:

Fig 1.1 Open Directory

Open Directory can be accessed both via traditional libc calls (getpwnam(),
gethostbyname(), etc) and also via the Directory Service
framework, which is documented here
(although some portions of that documentation appear to be out of
date).

More specifically, Open Directory has a dual name service
architecture; that is, requests may be serviced by one of two specific
subsystems, lookupd or DirectoryService. libc requests are dispatched
to lookupd while the Directory Service API communicates with
DirectoryService (a daemon designed to integrate with directory
services...the naming can be quite circular).

In NextStep 1.0 there was only lookupd. NeXT, opting to store its
administrative data in a directory (NetInfo) rather than the
traditional Unix flat
files, knew that there should be a flexible, modular method for
supporting lookups, so that administrative data might not always
be stored in NetInfo. Out of this specification, lookupd was
born. It could reply to queries based on data from a number of
backing stores, including NetInfo, flat files, NIS, DNS and
(eventually) LDAP. Each backing store had, and has, an associated
agent, which could be configured for use based on the query
type. lookupd has been steadily improved over the years and was
overhauled for NextStep 3.3. Since then, it has remained mostly
unchanged and currently has an extensive man page.

lookupd had some limitations, though. Designed in a time when libc
calls expected to return full user records -- including crypt()
passwords -- it has no specific authentication support. It is,
additionally, a read-only architecture. While this is the norm for
libc interfaces, it makes sense that in a world of evolving
directory services to support write operations. Finally, lookupd
is relatively difficult to extend. While third party lookupd
agents were written, they were the exception rather than the
rule.

DirectoryService was designed to meet these limitations. It's
highly extensible and licensed as open
source. Its API is well documented and supports write
operations as well as multiple authentication methods. Due to
these features, DirectoryService is the primary method for
accessing enterprise directories. Apple has chosen to continue
support of lookupd, presumably to maintain the stability of libc,
on which much of the OS relies. The resulting architecture looks
like this:

Fig 1.2 Open Directory architecture

In order for libc clients (most cross platform Unix utilities: for
instance sshd, ls, pwd, etc.) to access DirectoryService
data, Apple built a specialized lookupd agent, DSAgent, beginning
in 10.1. DSAgent uses the DirectoryService API to provide access
to enterprise directories to lookupd clients, including
libc. Because lookupd has no authentication support, libc clients
must be pam-enabled. pam, in turn, is able to access
DirectoryService authenticating methods, like
dsDoDirNodeAuth. This isn't the end of the story, however. lookupd
is still Mac OS X's resolver, so host resolution (gethostby*())
will generally be answered by its FFAgent or DNSAgent. In addition, lookupd will, for
performance reasons, query the local NetInfo directory itself
rather than dispatch that query to DSAgent (and hence
DirectoryService) although this behavior is configurable.