Share via

MS Strategy for Lightweight Directory Access Protocol (LDAP)

Archived content. No warranty is made as to technical accuracy. Content may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.


This paper provides detailed information on how Active Directory, Microsoft's implementation of a heirarchical, extensible Directory Service, supports the Lightweight Directory Access Protocol (LDAP) as defined by the Internet Engineering Task Force (IETF). It will detail how Active Directory interoperates with products from other vendors that support LDAP. It also includes a discussion of the APIs for accessing Directory Services that support LDAP and Microsoft's contribution and plans for the future of LDAP.

Executive Summary

Enterprise Computing Environments have a need to store information in a centralized data store so that it can be added to, deleted, modified, and queried by users and applications. The information stored could be user accounts, e-mail addresses, digital certificates, component object names, network names, and so on. There is a need to access this information both from within the enterprise and from the Internet. The amount of information stored varies greatly with the customer. This data store has come to be known as a Directory Service.

In order to succeed, IT organizations must choose Directory Services that are:

  • Flexible enough to store a range of information types

  • Secure when accessing from both the Internet and intranet

  • Scalable from a small business to the largest enterprise

  • Extensible as business needs change

In addition, the Directory Service must be accessible via an open, standards-based protocol. Using an open protocol enables the information in the Directory Service to be accessible from clients from different vendors. Directory Services from different vendors communicating using an open protocol can exchange information with each other to create aggregated directories.

The Lightweight Directory Access Protocol (LDAP) is a protocol for clients to query and manage information in a Directory Service over a TCP connection ( port 389 ). The LDAP protocol was designed by University of Michigan to provide access to the X.500 Directory while not incurring the resource requirements of the Directory Access Protocol (DAP). This makes it very suitable for use on the Internet.

Active Directory is a Directory Service integrated with the Microsoft® Windows NT® Server operating system that offers the hierarchical view, extensibility, scalability, and distributed security required by all customers. Microsoft has provided support for LDAP in Active Directory and enabled it to be integrated with the Internet. With this LDAP support, customers can deploy Active Directory in a corporate computing environment and interoperate with LDAP clients from multiple vendors.

An LDAP provider for the Active Directory API (aka OLE-DS) provides access to an LDAP Directory Service from different vendors to a client application written to the Active Directory APIs.

By supporting the LDAP protocol in Active Directory, Microsoft provides the infrastructure within its operating systems to provide user-empowering interoperability within a heterogeneous computing environment.

On This Page

History of LDAP
Microsoft Directory Services Strategy
Lightweight Directory Access Protocol (LDAP) Overview
Microsoft's Perspective on LDAP
Microsoft's Support for LDAP
APIs to access LDAP Directory Services
Future of LDAP


Microsoft is committed to implementing open standards that benefit its customers. By incorporating technologies based on open standards into Active Directory, Microsoft has created the building blocks that will allow it to integrate into a heterogeneous environment.

This paper provides information about the Internet Engineering Task Force's (IETF) Lightweight Directory Access Protocol (LDAP) specification rfc1777 and discusses the way Microsoft has implemented the critical components of the specification in the Active Directory and other products. Finally, the paper examines technologies Microsoft is working on today that will extend the capabilities of LDAP beyond the version 2 specification and contributions it is making to the version 3 specification. It also discusses the APIs used for accessing Directory Services that support the LDAP protocol.

History of LDAP

X.500, the OSI directory standard, defines a comprehensive Directory Service, including an information model, namespace, functional model, and authentication framework. X.500 also defines the Directory Access Protocol (DAP) used by clients to access the directory. DAP is a full OSI protocol that contains extensive functionality, much of which is not used by most applications.

DAP is significantly more complicated than the more prevalent TCP/IP stack implementations and requires more code and computing horsepower to run. The size and complexity of DAP makes it difficult to run on thin clients, such as the PC and Macintosh where TCP/IP functionality often comes with the machine. DAP stack implementations are cumbersome to administer, thus limiting the acceptance of X.500. Hence in 1993, the folks at University of Michigan, with help from the ISODE Consortium, designed and developed a protocol that would work over TCP/IP and was small enough when implemented to run on a thin client like PC's running the Windows® operating system or the Macintosh.

The LDAP version 1 Specification was published in March of 1994. The LDAP version 2 Specification was published as rfc 1777 by the Access Searching and Indexing of Directories (ASID) working group in the IETF in March of 1995. In April of 1996, 40 companies including Microsoft, Netscape, and Novell separately announced support for LDAP protocol in their Directory Services products in order that they may in turn operate with each other and integrate with the Internet. LDAP version 3.0 has gone through several drafts but at this time is not finished.

Microsoft Directory Services Strategy

The computing strategies of corporations focus on providing immediate delivery of valuable information to users from any location and stored in any format. This concept, named "Information at Your Fingertips" by Bill Gates, is the primary business mission of Microsoft Corporation. It is to serve this goal that Microsoft has developed all of its technologies and tools.

Microsoft views Directory Services to be a critical component in a system that finds and delivers that information. Directory Services are a store for information on the organization, for example, phone/mail address book; the computing environment of an organization, for example, user accounts, printers, objects and so forth; and other miscellaneous information that needs to be located in a location independent manner.

Most Enterprise computing environments use widely differing information technology systems from different vendors. This variation, often caused by differing needs within a corporation, causes complexity when integrating a computing infrastructure. Microsoft's mission is to enable customers to effectively integrate Microsoft products and technologies with a variety computing environments. This includes Directory Services.

Microsoft has built the Active Directory to support a number of different industry standards so that it may integrate with products that support any of these standards. These standards include:

  • Subsets of the 1993 Directory Access Protocol (DAP)

  • 1993 Directory System Protocol (DSP)

  • Directory Information Shadowing Protocol (DISP)

  • Lightweight Directory Access Protocol (LDAP)

Microsoft will continue to develop and support standards that are required to integrate Directory Services with products and technologies that are prevalent in organizations. Microsoft will continue to work with standards bodies to incorporate features into their Directory Services products so that they can integrate seamlessly with products from other vendors that support those features. It is to this end that Microsoft is working with the IETF on the draft of LDAP v3 and other draft RFCs.

Lightweight Directory Access Protocol (LDAP) Overview

LDAP defines the following components:

  • A Data Model—which defines the syntax of the data in the directory

  • An organizational model—which defines how the data is organized in the directory

  • A Security Model—which defines how the information in the directory is accessed in a secure manner

  • The Functional Model—which defines the operations for querying and modifying the directory.

  • The Topological Model – which defines how the directory service integrates with other directory services to form a global directory service on the internet.

The Data Model

The data model is centered around entries, which are composed of attributes. Each attribute has a type and one or more distinct values. This defines what kind of information is allowed in the values. LDAP data elements are string types. LDAP relegates the knowledge of a value's syntax to the application program rather than lower-level protocol routines.

Which attributes are required and allowed in an entry are controlled by a special objectClass attribute in every entry. The values of this attribute identify the type of entry (for example, commonName, organization, and so on). The type of entry determines which attributes are required, and which are optional. For example, the object class commonName requires the surname and FirstName attributes, but description, and others are optional.


Figure 1:

The Organization Model

Entries are organized in a Directory Information Tree and divided among servers in a geographical and organizational distribution. Each entry except the root has a parent entry. Each entry has a fully qualified name, the Distinguished Name (DN). Each component of the DN is called a Relative Distinguished Name (RDN). The Distinguished Name for any entry is constructed by concatenating the Relative Distinguished Names of the entry's ancestors.

Figure 1 depicts the relationship between entries, attributes, and values and shows how entries are arranged into a tree.

LDAP uses string encodings for representing distinguished names. In the above figure the Relative Distinguished Name for the entry Mohan Cavale is "cn=Mohan Cavale" and a Distinguished Name of "cn=Mohan, o=Microsoft,c=US".

The Functional Model

The functional model in LDAP defines the operations for querying and modifying the directory. It defines the operations for :

  • Adding an entry from the directory

  • Deleting an entry from the directory

  • Modifying an already existing entry

  • Change the name of an existing entry

  • Querying for an entry in some portion of the directory based on a criteria specified by a query filter.

A typical search operation may involve searching the entire tree under the Organization Microsoft for people with the name Mohan Cavale, retrieving the e-mail address for each entry found. RFC-1558, " A String Representation of LDAP Search Filters," specifies the syntax for the filters that define the search.

The Security Model

LDAP version 2 defines an authentication model based on clear text passwords or Kerberos V4.1. LDAP version 3 defines an extensible model based on the Simple Authentication and Security Layer (SASL). SASL uses a layered architecture for using different security providers. The Generic Security Service Application Program Interface (GSSAPI) is used as one of SASL's principal providers. GSSAPI is a security interface which defines a common interoperable security system for the Internet. LDAP version 3 defines the packet formats of the SASL requests and responses between the LDAP client and server. It supports both security authentication and encryption using different SASL and GSSAPI mechanisms.

In addition to SASL, LDAP version 3 also supports secure connections using the Secure Sockets Layer (SSL) protocol. LDAP SSL connections use port 636, whereas connections using SASL authentication and encryption use port 389.

The Topological Model

A major part of LDAP is that you can build a global directory structure using LDAP. It is essentially a directory Web in much the same way that HTTP and HTML are used to define and implement the global hypertext Web. One or more LDAP servers together make up the directory tree. An LDAP client connects to an LDAP server and makes a request. If the information is available locally, the server attempts to connect to another LDAP server that can fulfill the request. LDAP uses this referral capability to implement a global directory structure of independent LDAP servers that appear to a client to be a single LDAP server.

LDAP C-Binding API

RFC 1823 specifies the C-binding APIs for a client to access a Directory Service that supports the LDAP protocol. This API set is extremely simple and supports both synchronous and asynchronous calls to the server.

An application generally uses the LDAP API in four simple steps.

  • Open a connection to an LDAP server. The ldap_open() call returns a handle to the connection, allowing multiple connections to be open at once.

  • Authenticate to the LDAP server and/or the X.500 DSA. The ldap_bind() call and friends support a variety of authentication methods.

  • Perform some LDAP operations and obtain some results ldap_search() and friends return results which can be parsed by ldap_result2error(), ldap_first_entry(), ldap_next_entry(), and so forth

  • Close the connection. The ldap_unbind() call closes the connection.

Operations can be performed either synchronously or asynchronously. Synchronous calls end in _s. For example, a synchronous search can be completed by calling ldap_search_s(). An asynchronous search can be initiated by calling ldap_search(). All synchronous routines return an indication of the outcome of the operation (for example, the constant LDAP_SUCCESS or some other error code). The asynchronous routines return the message ID of the operation initiated. This ID can be used in subsequent calls to ldap_result() to obtain the result(s) of the operation. An asynchronous operation can be abandoned by calling ldap_abandon().

Here is a list of the LDAP API calls:

API Name



Opens a connection to an LDAP server


This API and its friends are used to authenticate to the directory


This is used to unbind from the directory and close the connection.


This API and friends are used to search the LDAP directory

ldap_modify, ldap_modify_s

These routines are used to modify an existing LDAP entry

ldap_modrdn, ldap_modrdn_s

These routines are used to change the name of an LDAP entry


These are used to add entries to the LDAP directory


These are used to delete entries from the LDAP directory


This is used to abandon an operation in progress


This is used to obtain the result of a previous asynchronously initiated operation

ldap_result2error, ldap_err2string and ldap_perror

These APIs are used to interpret errors returned by other APIs


These routines are used to step through a set of entries in a search result


This is used to count the number of entries returned

ldap_first_attribute and ldap_next_attribute

These APIs are used to step through the list of attribute types returned with an entry

ldap_get_values and ldap_get_values_len

These APIs are used to retrieve the values of a given attribute from an entry


This is used to retrieve the name of an entry


This is used to break up the name into its component parts


This API converts the DN into the user friendly format.

Microsoft's Perspective on LDAP

Today's customers demand multivendor integration. Core network level inter-operability is extremely important for multivendor integration of services. Microsoft supports the LDAP specification in RFC-1823 which defines C- binding APIs to access the LDAP Directory Services.

The complexity of writing applications to the LDAP API set results in increased development time and costs when compared with the higher-level component systems. For this reason, Microsoft believes that application developers will, over time, use the higher-level abstractions that are becoming available on the market rather than coding directly to low-level API sets. Microsoft is committed to providing support for LDAP APIs and other technologies within a component architecture model that will enable rapid development of applications that leverage LDAP-based Directory Services.

It is with this view that Microsoft has built an LDAP provider for the Microsoft Active Directory API set. Microsoft Active Directory API set permits an application to access directories from different vendors based on different standards to be accessed using a single API set as COM components or Automation objects.

Microsoft recognizes that there are customers that need to develop that use LDAP Directory Services today with an option to migrate to using Directory Services based on other emerging standards later. The Microsoft Active Directory API set with its provider/client architecture enables an application that is using those APIs to use different Directory Services, both proprietary and standards-based, with very little changes to an application.

Microsoft's Support for LDAP

Active Directory

Active Directory combines the best of the DNS as a locator service and X.500 and uses LDAP as its core protocol thus being able to work with Directory Services from other vendors working on non-Microsoft operating systems. This Directory Service can support more than 10 million objects offering unparalleled scalability. The Active Directory also support the following protocols

  • Subsets of the 1993 Directory Access Protocol (DAP)

  • 1993 Directory System Protocol (DSP)

  • Directory Information Shadowing Protocol (DISP)

  • Lightweight Directory Access Protocol (LDAP)

Active Directory is the store for security principals in Windows NT including user accounts, groups, and domains. They replace the registry account database and are a trusted component of the Local Security Authority (LSA).

Active Directories are extensible through a schema mechanism by defining their own object types.

Security in Active Directory

Active Directory permits both authenticated and unauthenticated access to the Directory Service for clients talking over LDAP. With unauthenticated access clients can access objects that have ACLs that allow Everyone (or unauthenticated users) to access them. Active Directory allows administrators to set ACLs on entries as a whole and on attributes within entries.

Authenticated access of the Active Directory over LDAP supports both private key and public key-based authentication. The MIT Kerberos V5 authentication protocol is supported with extensions for public key-based authentication in addition to password-based authentication. Internet clients can also be authenticated using X.509 v3 Public Key Certificates. Active Directory supports impersonation after a client is authenticated using appropriate authentication scheme. This provides for a tight integration with rest of the Windows NT security system.

LDAP and Security in Active Directory

Security Support Provider Interface is Microsoft's implementation of GSSAPI and is based on a provider client architecture so that applications writing to these APIs can use different Security Providers. Microsoft's LDAP client and Windows NT Active Directory use the Security Support Provider Interface (SSPI) APIs for authentication and security, and hence, can use any SSPI providers for establishing and conducting a secure LDAP session. The next major release of Windows NT will ship with SSPI providers for SSL 3.0, Kerberos v5, and Windows NT SSP.


Figure 2:

APIs to access LDAP Directory Services

LDAP C-Binding API

Microsoft supports RFC 1823 which specifies the C-binding APIs for a client to access a Directory Service that supports the LDAP protocol. LDAP client support will be included in all future versions of the Active Directory SDK. The LDAP client is supported on the following platforms

  • Windows NT 3.51, 4.0, and 5.0

  • Windows 95

The LDAP client works over both WinSock 1.1 and Winsock 2.0. The LDAP client library supports both synchronous and asynchronous calls as defined in RFC 1823 and is thread-safe. The header file that needs to be included is WinLDAP.H. The LDAP client support for all platforms ships as a DLL in WLDAP32.DLL. The library to import when using the LDAP client API is WLDAP32.LIB.

Active Directory API or Active Directory Interfaces

The Active Directory API is a central part of the Open Directory Services Interface (ODSI), a WOSA architecture for manipulating and querying Directory Services from different vendors. The Active Directory architecture is based on a client/provider model.


Figure 3:

An Active Directory Interfaces provider maintains the implementation of objects and dependent objects for a particular namespace. Figure 3 demonstrates that clients are concerned only with getting and using interfaces on an object, and not with the details of where and how the software of an object is implemented.

The Active Directory Interfaces SDK providers are available for the following Directory Services:

  • Windows NT 4.x

  • Novell NetWare 3.x and 4.x

  • Active Directory

  • Any Directory Service that supports LDAP RFC-1777.

Active Directory Interfaces components are designed to meet the needs of traditional C and C++ programmers, system administrators, and sophisticated end users. With Active Directory Interfaces components, development of directory enabled applications is fast and easy. Active Directory Interfaces components present the directory as a set of COM objects, which provide behavior in addition to data. For example, an application can use an Active Directory Interfaces PrintQueue object to retrieve data, such as characteristics of the queue, and also to pause the queue. In the Visual Basic® programming systems, this is as easy as:

Dim MyQueue as IOleDsPrintQueue
set MyQueue = Getobject("DS://Myco.Com/Division/Product/Printers/MyPrinter")

Because Active Directory Interfaces components are available for many popular Directory Services, Active Directory Interfaces components are an ideal tool for building applications that will work with multiple directories.

Active Directory Interfaces components are designed to meet the needs of three main audiences:

  • C/C++ Application Developers—Typically, this audience will use the Active Directory Interfaces components with a compiled language such as C++, although Microsoft Visual Basic can be used for prototyping the application. For example, a developer could write a mail application that accesses the Directory Service for storing and retrieving e-mail addresses.

  • System administrators—System administrators would like to access the Directory Service through a simple scripting language. With Active Directory Interfaces an administrator could write a Visual Basic scripting edition to add 100 new users to the system and set Access Control Lists on the users.

  • **End users—**Like the system administrators, this audience will access the Active Directory API components through a scripting language. For example, an end user might write a script to locate all of their print jobs in a group of print queues and display the status of each.


C-Binding API

Here is sample code using the C-Binding APIs. This application connects to an LDAP Server that is supplied as the first parameter in a command line. The application binds to the server using a user name and password that are supplied as the second and third command line parameters and prints all the attributes of all the entries in the directory tree.

#include <winldap.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int _CRTAPI1 main( int   cArgs,
char  *pArgs[] )
LDAP *ldapConnection = NULL;
INT err;
LDAPMessage *results = NULL;
PCHAR result1;
printf( "\n" );
if (cArgs > 1) {
pHost = pArgs[1];
if (cArgs > 2) {
userDN = pArgs[2];
if (cArgs > 3) {
pw = pArgs[3];
printf( "Connecting to server %s....\n," pHost );
ldapConnection = ldap_open( pHost, 0 );
if ( ldapConnection == NULL ) {
printf( "ldapConnection failed with 0x%x.\n," GetLastError() );
goto FatalExit0;
ldapConnection->ld_lberoptions = 0;
printf( "Binding with userName %s, password %s....\n," userDN, pw );
err = ldap_simple_bind_s( ldapConnection, userDN, pw );
printf( "simple bind returned 0x%x\n," err );
//  while (err != LDAP_SERVER_DOWN) {
err = ldap_search_s(    ldapConnection,
printf( "search tree returned 0x%x\n," err );
if (results != NULL) {
LDAPMessage *message;
PCHAR attribute;
PVOID opaque;
ULONG notypes = 0;
message = ldap_first_entry( ldapConnection, results );
while (message != NULL) {
PCHAR *explodedDN = NULL;
PCHAR friendlyDN = NULL;
dn = ldap_get_dn( ldapConnection, message );
printf( "Distinguished Name is : %s\n," dn );
friendlyDN = ldap_dn2ufn( dn );
printf( "Friendly DN is : %s\n," friendlyDN );
explodedDN = ldap_explode_dn( dn, notypes );notypes = ( notypes ? 0 : 1 );  
// reverse on every one
ldap_memfree( dn );
ldap_memfree( friendlyDN );
if (ldap_count_values(explodedDN) > 1) {
ULONG count, total;
printf( "ExplodedDN is :\n" );
total = ldap_count_values(explodedDN);
for (count = 0; count < total; count++ ) {
printf( "\t%s\n," explodedDN[count] );
} else {
if (explodedDN != NULL) {
printf( "ExplodedDN is %s\n," *explodedDN );
} else {
printf( "ExplodedDN is null.\n" );
ldap_value_free( explodedDN );
attribute = ldap_first_attribute( ldapConnection,
while (attribute != NULL) {
PCHAR *value = NULL;
value = ldap_get_values(    ldapConnection,
if (ldap_count_values(value) > 1) {
ULONG count, total;
printf( "Attribute %s is :\n," attribute );
total = ldap_count_values(value);
for (count = 0; count < total; count++ ) {
printf( "\t%s\n," value[count] );
} else {
printf( "Attribute %s is %s\n," attribute, *value );
ldap_value_free( value );
attribute = ldap_next_attribute(  ldapConnection,
message = ldap_next_entry( ldapConnection, message );
ldap_msgfree( results );
if (ldapConnection) {
ldap_unbind( ldapConnection );
return 0;
}   // main

Active Directory Services API

This sample lists the required and optional attributes of a specific user—Mohan Cavale in the organization Microsoft and Organizational Unit AD.

Private Sub display_user_properties()
Dim user as IADs
Dim uclass As IADsClass
Dim usyntax As IADsSyntax
Dim uprop As IADsProperty
Dim v As Variant
Dim value as Variant
Set user = GetObject("LDAP:// Cavale")
Set uclass = GetObject(user.Schema)
;The following code displays mandatory properties (required attributes)
Debug.Print "******Mandatory Properties********"
For Each v In uclass.MandatoryProperties
    Set uprop = GetObject("LDAP://" + v)
    user.Get(v, value)
    DebugPrint  v + usyntax.OleAutoDataType + value
Next v
Debug.Print  "*****Optional Properties*******"
For Each v In uclass.OptionalProperties
    Set uprop = GetObject("LDAP://CHUCKC1/SCHEMA/" + v)
    user.Get(v, value)
    Debug.Print v + " syntax: " + uprop.OleAutoDataType + value
Next v
End Sub

To perform the task above using the LDAP APIs as defined in RFC 1823 an application would need to perform the following steps:

  • Bind to the LDAP Server

  • Perform an LDAP ldap_search_s for cn=Mohan Cavale

  • Get back an LDAPMessage structure ( struct berval) using a handle as was returned above

  • Unmarshall the structure into the appropriate properties based on the type of the property by parsing through the structure using the APIs ldap_first_attribute, ldap_next_attribute, and ldap_count_entries.

Future of LDAP

Microsoft is actively working with the IETF on defining the LDAP v3 specification and will support LDAP v3 and later versions in the Active Directory when the specification becomes available as an RFC.


Microsoft views connectivity to disparate computing platforms as a basic right. Fundamentally, if you are buying networked systems from different vendors, products must contain core services to ensure interoperability. To provide this support, Microsoft supports a variety of standards and protocols, and works with third parties to insure support for even more standards and protocols on Microsoft platforms. This support includes LDAP, and its technologies that provide interoperation. Microsoft clients and servers are also designed to interoperate with other products that support LDAP.

LDAP interoperability is just part of Microsoft's broad work toward a single system image, in which users and administrators do not have to be aware of the differences between systems on a multivendor network. Microsoft is committed to providing support for both open and vendor-specific standards to give customers the inter-operation they need to truly enable computing for competitive advantage.

Programming your application to a standard set of APIs does not make your application portable. Portability is achieved through a carefully defined implementation within a layered services architecture. These layers are known as abstraction layers that are used to segregate critical services. These abstraction layers let developers change application components and platforms, without necessarily affecting the application or other components. Microsoft's Active Directory APIs are based on this layered architecture where an application developer can change the provider and Directory Service that the application is using without going through major changes. Programming to these APIs is easier and achieves greater application portability.

For More Information

For the latest information on Active Directory, check out our World Wide Web site at\_ds.htm.


J. Reynolds, C. Weider, "Executive Introduction to Directory Services Using the X.500 Protocol," Internet RFC 1308, December 1992 .

S. Heker, J. Reynolds, C. Weider, "Technical Overview of Directory Services Using the X.500 Protocol," RFC 1309, December 1992.

Howes T., "A String Representation of LDAP Search Filters," Internet RFC 1558 University of Michigan, December 1993.

W. Yeong, T. Howes, S. Kille, "Lightweight Directory Access Protocol," Internet RFC-1777, Performance Systems International, University of Michigan, ISODE Consortium, March 1995

T. Howes, S. Kille, W. Yeong, "The String Representation of Standard Attribute Syntaxes," University of Michigan, ISODE Consortium, Performance Systems International, NeXor Ltd., Internet RFC 1778, March 1995

Kille, S., "A String Representation of Distinguished Names," Internet RFC-1779, ISODE Consortium, March 1995.

T. Howes, M. Smith, "The LDAP Application Program Interface," Internet RFC-1823, University of Michigan, August 1995.

The information contained in this document represents the current view of Microsoft Corporation on the issues discussed as of the date of publication. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication.

This White Paper is for informational purposes only. MICROSOFT MAKES NO WARRANTIES, EXPRESS OR IMPLIED, IN THIS DOCUMENT.