Microsoft KB Archive/251195

{|
 * width="100%"|

INFO: How to Use ADSI to Query a Third-Party LDAP Server

 * }

Q251195

-

The information in this article applies to:


 * Microsoft Active Directory Service Interfaces, version 2.5

-

SUMMARY
The Lightweight Directory Access Protocol (LDAP) provider for Active Directory Service Interfaces (ADSI) is used to retrieve information from third-party LDAP servers. This article describes several problems that may arise, and how to overcome them.

MORE INFORMATION
When you use ADSI to retrieve information from a third-party LDAP server, you need to:


 * Determine the availability of schema information.
 * Obtain the correct authentication.
 * Prevent a search on a nonexistent container.

Determine the Availability of Schema Information
In accordance with the Request for Comments (RFC) 2251, LDAP version 3 servers are expected to expose a subSchemaSubEntry attribute off the root of the directory service enterprise (the rootDSE). ADSI uses this attribute to locate subschema information, which it then attempts to validate and cache.

For additional information on how ADSI caches the subschema, click the article number below to view the article in the Microsoft Knowledge Base:

"Q251189 INFO: Locating an LDAP Server Schema Cached by ADSI" ADSI uses the subschema information to expose the proper interfaces for a given class, and to retrieve attributes in the correct syntax from the property cache.

If ADSI is unable to locate or properly validate the subschema information, it uses the default LDAP version 2 schema. Because LDAP version 2 servers do not expose a subschema, ADSI maintains schema information internally about many standard attributes and classes. If ADSI uses the default version 2 schema, it does not have access to nonstandard schema information, including custom classes or attributes that have been created on the server.

If no schema information about an attribute's syntax is available, ADSI is unable to retrieve the attribute from the property cache. In this case, you can use the IADsPropertyList.GetPropertyItem method to specify a syntax for the attribute of the requested property. When you specify an ADsTYPE value, you avoid the need for syntax information about that attribute.

If you use Microsoft ActiveX Data Objects (ADO), and you do not have schema information available, you need to retrieve the ADsPath string of the object, bind to the object in the directory, and then use the IADsPropertyList.GetPropertyItem method. There is no workaround for using ADO directly without schema information.

Obtain Correct Authentication
There are several ways to authenticate an LDAP client to an LDAP server with ADSI. Among these methods, only a simple bind is supported natively by LDAP to convey credentials to the server. In other cases, the client and server must agree on the method, usually with the use of another security authority or proprietary protocol.

For instance, the GetObject method (or the ADsGetObject function in C) uses the ADS_SECURE_AUTHENTICATION flag, which may result in an LDAP bind that uses Microsoft Windows NT Challenge/Response (NTLM). This bind is likely to fail because many third-party servers do not accept NTLM. If the authentication fails, the secure bind is downgraded to an anonymous bind; for example, a simple bind without any user credentials. At this point, the application may have access only to a subset of information (or even to no information) depending on the server configuration.

To prevent this situation, perform a simple bind by using the OpenDSObject method (or the ADsOpenObject function in C) and specify zero (no flags) or ADS_FAST_BIND (described below) for the lnReserved parameter. With the simple bind, pass a valid attributed username (cn=Username,cn=...) and password to the LDAP server for verification. To achieve a simple bind with ADO, set the Encrypt Password property of the ADODB.Connection object to FALSE, and assign the attributed username and password to the User ID and Password properties respectively.

Prevent a Search on a Nonexistent Container
By default, ADSI performs a objectClass search of the base object specified in a query or bind. This search fails if the distinguished name that is given does not exist in the directory.

For instance, suppose that a search is set to begin at "o=Corp,c=US" for all users in the directory. The structure of the directory is such that there is no actual "Corp" container, but rather two objects at the root of the directory with the distinguished names of "ou=NorthAmerica,o=Corp,c=US" and "ou=Europe,o=Corp,c=US". ADSI issues an objectClass search for "o=Corp,c=US" which fails, stopping the search for users before it starts.

The easiest solution to this problem is to specify a base object that actually exists in the directory. If it is not possible, due to the directory implementation, to perform the desired search with a valid base object, you must prevent ADSI from performing an initial objectClass search.

To prevent an objectClass search on the object, pass the ADS_FAST_BIND flag in the lnReserved parameter of the OpenDSObject method (or the ADsOpenObject function in C). Because this flag determines ADSI's actions after the bind has occurred, it does not affect proper authentication. Note that this flag is not available prior to ADSI version 2.5.

The ADO provider for Microsoft Windows 2000 exposes ADSI Flag properties on the ADODB.Connection object. You can set the ADS_FAST_BIND flag for this property to prevent ADO queries from performing an objectClass search. The ADSI Flag property is not present in ADSI version 2.5 for Microsoft Windows NT version 4.0 or Microsoft Windows 9x. For a possible solution, see the following article:

"Q223049 HOWTO: Query Exchange 5.x Anonymously Through ADSI"