The Active Directory Security Interface (ADSI) goes well beyond the Active Directory in Windows 2000. Using ADSI, you can access not only Active Directory, but also Novell's NDS directory service, any X.500 directory service, Microsoft's Exchange directory, NT 4 directory, and several others. The Active Directory directory service is accessed through the Lightweight Directory Access Protocol (LDAP), the protocol that is also used to access Exchange and X.500 directories. In this chapter, you'll be working with the NT 4 directory service (WinNT), and the Active Directory service (LDAP), but you can also just as easily work with Novell NetWare 3.x (NWCOMPAT), or Novell NetWare Directory Service (NDS) using the same objects and methods.
Binding to an ADSI object interface opens all ADSI sessions. All ADSI object interfaces can be bound to an object by using the GetObject function. This function is declared as
GetObject("URL [, class]") As Object
The URL parameter to the GetObject function consists of two parts. The first part specifies the provider to user. The provider can be one of the default providers listed in Table 12.1 or any additional providers that are installed on the client machine.
The second part of the URL parameter is the path to the object. If you are trying to bind to a domain controller, this is the name of the domain. If you are trying to bind to a specific user on the domain, you specify the domain, the domain controller, and the username, as follows:
The second parameter (class) specifies the object class for the object that you are trying to bind to. This specifies the type of object interface that you are wanting to bind to and will thus determine what properties and methods you have available to you after you retrieve the object interface. Some of the possible interface classes that are available are listed in Table 12.2.
The way that you might bind to a specific class interface using the GetObject function would work like this: If you were wanting to bind to a user account Davis on the domain controller Frog in the domain Pond, your call to GetObject would look something like this:
Note
Be sure to take note that, even though these are technically two different parame ters, they are passed as part of the same string.
Caution
Any spaces in the string being passed to the GetObject function will result in an automation error. You need to be sure that you don't include any spaces between the parameters within the string.
Tip
If you have trouble connecting to your domain by just using the domain name in the GetObject parameter string, as in the following:
Set obj = GetObject("WinNT://Pond/Frog/Davis,user")
you might need to use the fully qualified Internet name for the machine, as follows:
LDAP Active Directory paths always start with the specification of the LDAP provider, as follows:
If you are just initializing the LDAP provider and will be binding to specific objects using a secure connection, the preceding LDAP specification may be all that is in the initial call to the GetObject function. If you are needing to bind to a specific object within the Active Directory service, you'll need to add some additional elements to the specification.
The rest of the LDAP path resembles a combination of a URL and the X.500 Distinguished Name Fields that you learned about in Chapter 5, "Requesting and Receiving Certificates." The reason for this is that they are the same Distinguished Name Fields, as listed in Table 12.3.
If you look closely, you'll notice that this table begins with an element that wasn't in this table in Chapter 5. The Domain Component (DC) element was added for specifying pieces of a domain. For instance, if your Active Directory domain is mydomain.com, you would bind to the domain using the following LDAP binding string:
LDAP://DC=mydomain,DC=com
If you want to bind to the user davis in the organizational unit authors, you might use the LDAP path as
LDAP://CN=davis,OU=authors,DC=mydomain,DC=com
You might also define the LDAP path as follows:
LDAP://DC=mydomain,DC=com/OU=authors/CN=davis
Basically, you are defining the path through the Active Directory tree to the object that you are looking for. In Chapter 13, "Active Directory Security and Searching," you'll build a utility that will build the entire Active Directory tree for the specified domain. Examine the Active Directory path properties for the various objects in the tree, analyzing them to understand how the path is constructed.
The NT 4 Active Directory path is more like a standard URL than the LDAP path. It starts by specifying the provider as WinNT, and then gives the path through the directory tree starting with the domain, as follows:
WinNT://MyDomain/davis
You can also include the class on the end of the path for a NT 4 path, separated by a comma, as follows:
WinNT://MyDomain/davis,user
WinNT paths may include a specific computer in the domain for the paths to printers and other objects associated with a computer, as follows:
The NDS Active Directory path is virtually the same as the LDAP paths, only with the NDS provider specified, as follows:
NDS://DC=mydomain,DC=com/OU=authors/CN=davis
The Novell 3.x Active Directory path is virtually the same as the LDAP paths, only with the NWCOMPAT provider specified, as follows:
NWCOMPAT://DC=mydomain,DC=com/OU=authors/CN=davis
The IADs object interface is the base interface that all ADSI objects support. All the methods and properties available in the IADs object interface are available in all the ADSI objects. The available properties in this interface are listed in Table 12.4.
Any property of an object can be retrieved using the Get method. This method can be used on the IADs object interface even if the property being retrieved is not one available through the IADs interface. The syntax for the Get method is as follows:
object.Get(strName As String) As Variant
The one parameter (strName) to this method is the name of the property that you want to retrieve. For instance, you could retrieve the name of an IADs object in either of two ways. You could use the property to get the name, as follows:
Dim obj As IADs Dim strName As String Set obj = GetObject("WinNT://TheDomain/DomainController/Bill") strName = obj.Name
You could also use the Get method to retrieve the same property, as follows:
Dim obj As IADs Dim strName As Variant Set obj = GetObject("WinNT://TheDomain/DomainController/Bill") strName = obj.Get("cn")
Tip
If you are using the Get method to retrieve properties of an object, you'll need to use the internal name for the property. The internal names of properties are often different from the exposed property name for those properties that are externally visible. For instance, externally exposed Name property may have an internal name of objectName, cn (Common Name), Name, or any other internal name the object designer decided to use.
Assuming that you have the proper authorization, you can set the value of various properties of an object using the Put method. The syntax for the Put method is as follows:
object.Put(strName As String, varValue As Variant)
The first parameter (strName) to this method is the name of the property that you are wanting to update. The second parameter (varValue) is the value that you are setting for the property. The value has to be in the form of a Variant value.
If you have changed the values of any of the properties of an ADSI object, you need to flush those changes to the Active Directory server. You do this with the SetInfo method. This method doesn't take any parameters and should be called only after all the properties that are being updated have been set. An example of how you might use this method is as follows:
Dim obj As IADs obj.Put(property1, value1) obj.Put(property2, value2) obj.Put(property3, value3) obj.SetInfo
If there is any chance that some of the property values of an object have been changed, you can refresh the properties from the Active Directory server using the GetInfo method. If you have updated some properties and don't want to save these changes to the Active Directory server, you can also use the GetInfo method to reset the object properties to their initial settings. Like the SetInfo method, the GetInfo method doesn't take any parameters.
The IADsContainer object interface is available for all objects that contain other objects within the Active Directory tree. The objects contained within IADsContainer objects can be enumerated using a For Each loop. The available properties in the IADsContainer object interface are listed in Table 12.5.
If you know the object that you want to get from the collection, you can use the GetObject method. The syntax for this method is as follows:
object.GetObject(strClass As String, strRelativeName As String) As Object
The first parameter (strClass) is the class of the object that you are wanting to retrieve. The second parameter (strRelativeName) is the relative path from the container object for the object that you want to retrieve. This method returns an Active Directory object interface for the object requested.
For instance, if you have an IADsContainer object that contains users, and you want to retrieve a user named Bob, you could retrieve it using the following code:
If you need to create a new object as a member of the collection, you'll use the Create method. This syntax for this method is
object.Create(strClass As String, strRelativeName As String) As Object
This method takes the same parameters as the GetObject method examined earlier. It returns the object that has been created.
If you need to delete an object from a collection, you can use the Delete method. The syntax for this method is the following:
object.Delete(strClass As String, strRelativeName As String)
The parameters for this method are the same as for the Create and GetObject methods.
If you need to copy an object from anywhere in the Active Directory namespace into the current collection, you can use the CopyHere method. The syntax for this method is as follows:
object.CopyHere(strPath As String, strNewName As String) As Object
The first parameter (strPath) to this method is the Active Directory path to the current object that is being copied. The second parameter (strNewName) is the name for the new copy of the object to be added to the current collection.
This method returns the new object that has been added to the current collection. An example of how this method might be used is as follows:
Dim objUser As Object Set objUser = objContainer.CopyHere( _ "LDAP://CN=JohnSmith,OU=myDepartment,O=myCompany,DC=mDomain,DC=com", _ "CN=BobSmith")
If you need to move or rename an object, you can use the MoveHere method. The syntax for this method is as follows:
object.MoveHere(strPath As String, strNewName As String) As Object
The parameters and return value for this method are the same as for the CopyHere method. If you just need to move an object into the current collection without renaming the object, you can pass the NULL string (vbNullString) as the second parameter (strNewName).
The highest level object in the Active Directory tree is the IADsNamespaces object. The IADsNamespaces object is a collection of providers that are currently installed in the Active Directory namespace. The IADsNamespaces object has a single property beyond those provided by the IADs and IADsContainer interfaces. This property is listed in Table 12.6.
Property | Description |
---|---|
DefaultContainer | The Active Directory path to the base container for the current user. |
You can bind to the IADsNamespaces object interface by calling the GetObject function, specifying the ADs provider, as follows:
Dim obj As IADsNamespaces Set obj = GetObject("ADs:")
After you have opened an instance of the IADsNamespaces object, you can use it to enumerate all the namespaces available to you. This can be done using a For Each loop, listing the Name property of each object contained in the IADsNamespaces object, as shown in Listing 12.1.
If you need to have a secure connection to the Active Directory service that you are connected to, you can use the IADsOpenDSObject interface. This object has a single method, OpenDSObject, that is used to authenticate the user and then maintain the security context for the session. The syntax for this method is as follows:
object.OpenDSObject(strPath As String, strUserName As String, _ strPassword As String, lAuthFlags As Long) As Object
The first parameter (strPath) is the Active Directory path to the object to be opened. The second parameter (strUserName) is the user account name to use. The third parameter (strPassword) is the password for the account specified in the second parameter. The fourth parameter (lAuthFlags) specifies how the connection is made, how the user is authenticated, and how the session is maintained. The possible values to be used for this parameter are listed in Table 12.7.
The IADsOpenDSObject object is retrieved using the GetObject function, passing in just the namespace to be used. An example of how this might be used shown in the following:
Dim openDS As IADsOpenDSObject Dim obj As IADs '--- Open the LDAP interface Set openDS = GetObject("LDAP:") '--- Open the security context using secure authentication Set obj = openDS.OpenDSObject( _ "LDAP://CN=JohnSmith,OU=myDepartment,O=myCompany,DC=myDomain,DC=com", _ "davis", "password", ADS_SECURE_AUTHENTICATION)
Note
The specific syntax used in the example above depends on how your Active Directory is organized. The syntax above will retrieve a user or contact from an organizational unit. This will only work if you have an organizational unit set up and configured in your Active Directory. If you are on an Active Directory that only has users and groups, then you might try a syntax like the following: