Binding to Objects in the Active Directory

   

Binding to Objects in the Active Directory

Although the Active Directory transforms the way we think about user domains and other enterprise entities, operations at the workstation and member server level continue to use the Windows NT (WinNT:) ADSI service provider. For example, to create a user account on a member server, you can follow the same code used to create accounts in the Windows NT model. When you want to create a user account that would have once resided in the user domain, you should instead use the ADSI LDAP service provider to add an object to the Active Directory.

Use the code segments in this chapter as a guide to update the binding string used for any code that manipulates user accounts, computer accounts, groups, or print queues in a Windows 2000 directory. In most cases, only the binding string must be changed to specify the object's location in the Active Directory's hierarchical data structure.

Using ADSI Edit to Examine the Active Directory

Using the ADSI Edit MMC snap-in, you can view and edit objects in the Active Directory at an extremely low level. This tool duplicates much of the functionality provided by the MMC snap-ins included in the Administrative Tools folder. ADSI Edit is also extremely useful for viewing the object classes and mandatory and optional properties for each object class, as well as for viewing the contents and hierarchical structure of the domain naming context, schema, and configuration containers.


Binding to the Root DS Entry (RootDSE) Using Visual Basic

As part of RFC 2251, the LDAP standard requires all LDAP directories to maintain a set of properties that any user can query to find various key characteristics about the directory. These characteristics include the server's current time, the LDAP server name, and the server's DNS host name . This information is stored in the RootDSE and maintains each property as an attribute of the object.

To view these properties using Visual Basic, use the following code segment:

 Dim RootDSE As IADs Set RootDSE = GetObject("LDAP://RootDSE") Debug.Print "Current Time: " & RootDSE.Get("CurrentTime") Debug.Print "SubSchemaSubEntry: " & RootDSE.Get("SubSchemaSubEntry") Debug.Print "DsServiceName: " & RootDSE.Get("DsServiceName") For Each Item In RootDSE.Get("NamingContexts")      Debug.Print "Naming Context: " & Item Next Debug.Print "Default Naming Context: " & RootDSE.Get("DefaultNamingContext") Debug.Print "Schema Naming Context: " & RootDSE.Get("SchemaNamingContext") Debug.Print "Configuration Naming Context: " & RootDSE.Get("ConfigurationNamingContext") Debug.Print "Root Domain Naming Context: " & RootDSE.Get("RootDomainNamingContext") For Each Item In RootDSE.Get("SupportedControl")      Debug.Print "Supported Control: " & Item Next For Each Item In RootDSE.Get("SupportedLDAPVersion")      Debug.Print "Supported LDAP Version: " & Item Next Debug.Print "Highest Committed USN: " & RootDSE.Get("HighestCommittedUSN") For Each Item In RootDSE.Get("SupportedSASLMechanisms")      Debug.Print "Supported SASL Mechanism: " & Item Next Debug.Print "DNS Host Name: " & RootDSE.Get("DnsHostName") Debug.Print "LDAP Service Name: " & RootDSE.Get("LdapServiceName") Debug.Print "Server Name: " & RootDSE.Get("ServerName") 
Using the RootDSE DefaultNamingContext Attribute to Bind to an Active Directory Object Using Current Credentials in Visual Basic

To avoid having to hard-code distinguished names in your code, you can often use the default naming context to derive the name of the domain you are logged in to at run-time.

The following Visual Basic code will return the distinguished name of the current user's domain at run-time:

 Dim DefaultDomain as IADs Dim RootDSE as IADs Set RootDSE = GetObject("LDAP://RootDSE") Set DefaultDomain = GetObject("LDAP://" & RootDSE.Get("DefaultNamingContext")) 

Tip

This code should form the basis for all binding operations performed on the current user's domain; it eliminates the need for the user to specify a server/domain name or credentials at run-time.


Note

In the previous example, you establish a binding at the domain level. However, you can specify any point in the hierarchy by inserting the relative distinguished names of the structure between the LDAP:// string and the RootDSE.Get statement.


Binding to an Active Directory Object Using Alternate Credentials

To bind to the Active Directory using a set of credentials other than those used on the client, you can use the IADsOpenDSObject interface to bind with an alternate username and password, as shown in the following Visual Basic code segment:

 Dim DSO As IADsOpenDSObject Dim Obj As IADs Dim AdsPath As String Dim AlternateUser_UPN As String Dim AlternateUser_Password As String AdsPath = "LDAP://Server_Name.ResearchDevelopment.TestInfra/cn=Users, graphics/ccc.gif dc=ResearchDevelopment  ,dc=TestInfra" AlternateUser_UPN = "thomas.eck@ResearchDevelopment.TestInfra" AlternateUser_Password = "P0l1t1c@l@rs0ni$t" Set DSO = GetObject("LDAP:") Set Obj = DSO.OpenDSObject(AdsPath, AlternateUser_UPN, AlternateUser_Password, graphics/ccc.gif ADS_SECURE_AUTHENTICATION) 

Note

In the preceding example, you are binding to a completely different domain, although you can use the same code to specify an alternate user who can access restricted attributes in the same domain. Whenever possible, derive the default naming context programmatically, as shown in this example.

In some cases, you might want to use alternate credentials only after a call to GetObject has failed due to the user's credentials. To implement such a scenario, use a conditional to test whether Err.Number equals 0. If Err.Number returns anything other than a 0 after the binding is attempted, you can execute the above code, prompting the user for his credentials at run-time.


Searching the Entire Forest Using the Global Catalog and Visual Basic

If you are unsure of a specific item's location in the forest, you can use the following Visual Basic code to perform a search of the Global Catalog:

 Dim Container As IADsContainer Dim GC As IADs Dim ADsPath As String Dim Obj As Variant Dim Conn As ADODB.Connection Dim Command As ADODB.Command Dim RS As ADODB.Recordset Dim SQLStmt As String 'Change the SQL statement below to display objects that reflect the specified criteria SQLStmt = "SELECT cn, distinguishedName FROM '" & AdsPath & "' WHERE objectCategory = 'person' AND objectClass = 'user'" Set Container = GetObject("GC:") For Each Obj In Container Set GC = Obj Next ADsPath = GC.ADsPath Set Conn = New ADODB.Connection Set Command = New ADODB.Command Conn.Provider = "ADsDSOObject" Conn.Open Set Command.ActiveConnection = Conn Set RS = Conn.Execute(SQLStmt) While Not RS.EOF Debug.Print RS.Fields("cn") & vbTab & RS.Fields("distinguishedName") RS.MoveNext Wend RS.Close Conn.Close 

By simply changing the SQL statement, you can return the ADsPath of any desired object anywhere in the forest.

Determining Which Object Attributes Are Replicated to the Global Catalog Using Visual Basic

To find out which attributes are replicated to the global catalog, use ADO to query the schema container for all objects maintaining a True Boolean condition for the isMemberOfPartialAttributeSet attribute .

The following Visual Basic code segment exemplifies this process:

 Dim Connection As ADODB.Connection Dim RS As ADODB.Recordset Dim Entry As String Dim Index As Long Dim RootDSE As IADs Dim SchemaContainer As IADs Index = 0 Set Connection = New ADODB.Connection Connection.Provider = "ADsDSOObject" Connection.Open "ADSI" Set RootDSE = GetObject("LDAP://RootDSE") Set SchemaContainer = GetObject("LDAP://" & RootDSE.Get("SchemaNamingContext")) Set RS = Connection.Execute("SELECT cn FROM '" & SchemaContainer.AdsPath & "' where graphics/ccc.gif isMemberOfPartialAttributeSet = TRUE AND objectCategory = 'attributeSchema'") While Not RS.EOF     For i = 0 To RS.Fields.Count - 1         If RS.Fields(i).Type = adVariant And Not (IsNull(RS.Fields(i).Value)) Then             For j = LBound(RS.Fields(i).Value) To UBound(RS.Fields(i).Value)                Entry = Entry & RS.Fields(i).Value(j) & vbTab             Next j         Else              Entry = Entry & RS.Fields(i).Value & vbTab         End If         If Index = RS.Fields.Count - 1 Then             Debug.Print Entry         End If         Index = Index + 1     Next i     Entry = ""     Index = 0     RS.MoveNext  Wend ; 

Note

You must set a reference to the Microsoft ActiveX Data Objects type library before running the preceding code!



   
Top


Windows NT. 2000 ADSI Scripting for System Administration
Windows NT/2000 ADSI Scripting for System Administration
ISBN: 1578702194
EAN: 2147483647
Year: 2000
Pages: 194
Authors: Thomas Eck

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net