Directory Services

Binding With ADsOpenObject and IADsOpenDSObject::OpenDSObject

The ADsOpenObject function and the IADsOpenDSObject::OpenDSObject method are used to bind to directory service objects when alternate credentials must be specified and when data encryption is required.

The credentials of the calling thread should be used when possible. However, if alternate credentials must be used, the ADsOpenObject function or the IADsOpenDSObject::OpenDSObject method must be used. If alternate credentials are used, it is important to not cache the password. Multiple bind operations can be performed by specifying the user name and password for the first bind operation and then specifying only the user name in subsequent binds. The system sets up a session on the first call and uses the same session on subsequent bind calls as long as the following conditions are met:

ADsOpenObject and IADsOpenDSObject::OpenDSObject use the Windows NT Security Support Provider Interfaces (SSPI) to allow flexibility in authentication options. The major advantage of using these interfaces is to provide different types of authentication to Active Directory clients and to encrypt the session. Currently, ADSI does not allow certificates to be passed in. Therefore, you can use SSL for encryption and then Kerberos, NTLM, or simple authentication, depending on how the flags are set on the dwReserved parameter.

You cannot request a specific SSPI provider in ADSI, although you always get the highest preference protocol. In the case of a Windows 2000 client binding to a Windows 2000 server, the protocol is Kerberos. For a Windows NT 4.0 client binding to a Windows 2000 server, the protocol is NTLM. Not allowing a certificate for authentication is acceptable in the case of a Web page because authentication occurs prior to running the Web page.

Although Open operations allow you to specify a user and password, you should not do so. Instead, do not specify any credentials and implicitly use the credentials of the caller's security context. To bind to a directory object using the caller's credentials with ADsOpenObject or IADsOpenDSObject::OpenDSObject, specify NULL for both username and password.

Finally, to bind with no authentication, use the ADS_NO_AUTHENTICATION flag. No authentication indicates that ADSI attempts to bind as an anonymous user to the target object and performs no authentication. This is equivalent to requesting anonymous binding in LDAP and indicates that "everyone" is the security context.

If the authentication flags are set to zero, ADSI performs a simple bind, sent as plaintext.

Warning  If a username and password are specified without specifying authentication flags, the username and password are transmitted over the network as plain text, which is a security breach. Do not specify a username and password without specifying authentication flags.

Examples

The following Visual Basic code example shoes how to use the IADsOpenDSObject::OpenDSObject method.

Dim openDS As IADsOpenDSObject
Dim usr As IADsUser
 
Set openDS = GetObject("LDAP:")
 
openDS.OpenDSObject("LDAP://CN=jeffsmith,DC=fabrikam,DC=com",
	NULL, 
	NULL,
	ADS_SECURE_AUTHENTICATION)

The following C++ code example shows how to use the ADsOpenObject function.

IADs *pObject;
HRESULT hr;

hr = ADsOpenObject(L"LDAP://CN=jeffsmith,DC=fabrikam,DC=com",
	NULL, 
	NULL,
	ADS_SECURE_AUTHENTICATION, 
	IID_IADs,
	(void**)&pObject);
if(SUCCEEDED(hr))
{
	// Use the object.

	// Release the object.
	pObject->Release()
}

The IADsOpenDSObject interface can also be used in C++, but it duplicates the functionality of the ADsOpenObject function. The following C++ code example shows how to use the IADsOpenDSObject interface to perform the same bind operation as the example above.

IADsOpenDSObject *pDSO;
HRESULT hr;
 
hr = ADsGetObject(L"LDAP:", IID_IADsOpenDSObject, (void**)&pDSO);
if(SUCCEEDED(hr))
{
	IDispatch *pDisp;

	hr = pDSO->OpenDSObject(CComBSTR("LDAP://CN=jeffsmith,DC=fabrikam,DC=com"),
		NULL,
		NULL,
		ADS_SECURE_AUTHENTICATION, 
		&pDisp);
	if(SUCCEEDED(hr))
	{
		IADs *pObject;

		hr = pDisp->QueryInterface(IID_IADs, (void**) &pObject);
		if(SUCCEEDED(hr))
		{
			// Use the object.

			// Release the object.
			pObject->Release();
	}

		pDisp->Release();
}

	pDSO->Release();
}