Active Directory and Security

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.

Opening an ADSI Session

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.

Table 12.1. ADSI Providers That Are Provided with the ADSI Interface
Provider Description
WinNT: This provider allows you to communicate with an NT 4 Domain Controller (either primary or backup).
LDAP: This provider enables you to communicate with any LDAP servers, including Exchange 5.x and Windows 2000 Active Directory.
NDS: This provider allows you to communicate with any Novell Directory Services server.
NWCOMPAT: This provider enables you to communicate with any Novell 3.x NetWare server.

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:

Dim obj As Object

Set obj = GetObject("WinNT://TheDomain/DomainController/Bill")
					

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.

Table 12.2. Some Possible Interface Classes
Class Description
user A user account on the computer or in the domain
group A group on the computer or in the domain
domain A domain in the namespace
computer A computer in the domain
organization An organization in the domain
organizationalUnit An organizational unit or department within the organization
fileShare A file share on a computer
printQueue A printer or print queue in the domain

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:

Dim obj As Object
Set obj = GetObject("WinNT://Pond/Frog/Davis,user")
					

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:

Set obj = GetObject("WinNT://frog.pond.com/Davis,user")
						


LDAP Active Directory Path

LDAP Active Directory paths always start with the specification of the LDAP provider, as follows:

LDAP:
						

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.

Table 12.3. X.500 Distinguished Name Fields
Code Description
DC Domain Component—Identifies a part of an object's network domain.
CN Common Name—The user's name, or if this is a request for a certificate for a server, the fully qualified hostname/URL.
O Organization—The name of the organization or company for which the certificate is being requested. This should be the legal name for the company or organization.
OU Organizational Unit—This is used to differentiate divisions within an organization or company. This can also be used to specify a DBA (Doing Business As) name for the certificate.
L Locality—The city in which the organization or person resides.
S State—The state in which the organization or person resides.
C Country—The country in which the organization or person resides. The X.500 naming scheme limits this to a two-character country code. The code for the United States is "US" and the code for Canada is "CA."
E Email Address—The email address for the person requesting the certificate (this is an optional element).

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.

WinNT Active Directory Path

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:

WinNT://MyDomain/MyComputer/MyPrinter,printQueue
						

NDS Active Directory Path

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

NWCOMPAT Active Directory Path

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

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.

Table 12.4. IADs Properties
Property Description
Name The name of this object
Class The interface class of this object
GUID The Globally Unique ID (GUID) of this object
AdsPath The Active Directory path for this object that uniquely identifies this object within the directory
Parent The Active Directory path for the parent of this object
Schema The Active Directory path for the schema object that describes this object (you'll learn about schema objects later in this chapter).

Getting Any Property Value

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.


Setting a Property Value

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.

Updating the Active Directory

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
						

Refreshing the Property Values

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

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.

Table 12.5. IADsContainer Properties
Property Description
Count The number of objects contained within this object.
Filter A variant array of object classes that will be available for enumeration. Setting this property enables you to limit the enumeration to objects of a specific class.
Hints A variant array of names of properties for each enumerated object.

Getting a Specific Object

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:

Dim objUser As Object

Set objUser = objContainer.GetObject("user", "CN=Bob")
						

Creating an Object

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.

Deleting an Object

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.

Copying an Object

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")
						

Moving an Object

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 IADsNamespaces Object Interface

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.

Table 12.6. IADsNamespaces Properties
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.

Code Listing 12.1. Enumerating the Namespaces
Private Sub GetNamespaces()
'*************************************************************
'* Written By: Davis Chapman
'* Date:       February 12, 2000
'*
'* Syntax:     GetNamespaces
'*
'* Parameters: None
'*
'* Purpose: This subroutine builds a list of all the names
'*          in the ADS namespace.
'*************************************************************
    Dim objNameSpaces As Object
    Dim nsSpaces As Object
    Dim strMsg As String

    On Error Resume Next
    '--- Get the root object for the name spaces
    Set objNameSpaces = GetObject("ADs:")
    '--- Initialize the display string
    strMsg = ""
    '--- Loop through all the names in the namespaces
    For Each nsSpaces In objNameSpaces
        '--- Add the name to the list
        strMsg = strMsg + nsSpaces.Name + vbCrLf
    Next
    '--- Display the information for the user
    MsgBox strMsg
End Sub
					

ADSI Security and Authentication

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.

Table 12.7. OpenDSObject Authentication Flags
Flag Value Description
ADS_SECURE_ AUTHENTICATION &H1 Causes ADSI to perform secure authentication. The authentication method used depends on the provider being used. The WinNT provider uses the NT Lan Manager (NTLM) authentication. The Active Directory provider uses Kerberos, if possible, or NTLM if not. If the NULL string (vbNullString) is passed in place of the username and password (second and third parameters), the current security context is used.
ADS_USE_ENCRYPTION &H2 Causes ADSI to use encryption on all data transfers across the network.
ADS_USE_SSL &H2 Causes the data to be encrypted using SSL, if available. Certificate Services must be installed for Active Directory to use SSL.
ADS_READONLY_SERVER &H4 With a WinNT provider, this flag causes ADSI to bind to either a primary domain controller or a backup domain controller. With an Active Directory provider, this flag allows a read-only server to be used.
ADS_PROMPT_CREDENTIALS &H8 This flag causes the Security Support Provider Interface (SSPI) to prompt the user for authentication credentials, assuming that the selected SSPI provides a user interface for this.
ADS_NO_AUTHENTICATION &H10 This flag requests that an anonymous connection be made, providing the user with limited access to the Active Directory.
ADS_FAST_BIND &H20 This flag will not provide all the properties and methods for objects, but will provide only the base properties and methods that are available to all ADSI objects.
ADS_USE_SIGNING &H40 This flag causes all data sent between the Active Directory server and the client to be signed so that the data is verified to not change in the transfer. This flag can be used only with the ADS_SECURE_AUTHENTICATION flag.
ADS_USE_SEALING &H80 This flag causes all the data transferred to be encrypted using Kerberos. This flag can be used only with the ADS_SECURE_AUTHENTICATION flag.

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:

   "LDAP://CN=John Smith,CN=Users,DC=myDomain,DC=com"
						


..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset