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