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.
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:
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
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:
HOWTO: Query Exchange 5.x Anonymously Through ADSI