Active Directory Cookbook for windows server 2003- P10 pps

10 367 0
Active Directory Cookbook for windows server 2003- P10 pps

Đang tải... (xem toàn văn)

Thông tin tài liệu

101 Chapter 4. Searching and Manipulating Objects Introduction Recipe 4.1. Viewing the RootDSE Recipe 4.2. Viewing the Attributes of an Object Recipe 4.3. Using LDAP Controls Recipe 4.4. Using a Fast or Concurrent Bind Recipe 4.5. Searching for Objects in a Domain Recipe 4.6. Searching the Global Catalog Recipe 4.7. Searching for a Large Number of Objects Recipe 4.8. Searching with an Attribute-Scoped Query Recipe 4.9. Searching with a Bitwise Filter Recipe 4.10. Creating an Object Recipe 4.11. Modifying an Object Recipe 4.12. Modifying a Bit-Flag Attribute Recipe 4.13. Dynamically Linking an Auxiliary Class Recipe 4.14. Creating a Dynamic Object Recipe 4.15. Refreshing a Dynamic Object Recipe 4.16. Modifying the Default TTL Settings for Dynamic Objects Recipe 4.17. Moving an Object to a Different OU or Container Recipe 4.18. Moving an Object to a Different Domain Recipe 4.19. Renaming an Object 102 Recipe 4.20. Deleting an Object Recipe 4.21. Deleting a Container That Has Child Objects Recipe 4.22. Viewing the Created and Last Modified Timestamp of an Object Recipe 4.23. Modifying the Default LDAP Query Policy Recipe 4.24. Exporting Objects to an LDIF File Recipe 4.25. Importing Objects Using an LDIF File Recipe 4.26. Exporting Objects to a CSV File Recipe 4.27. Importing Objects Using a CSV File Introduction Active Directory is based on the Lightweight Directory Access Protocol (LDAP) and supports the LDAP v3 specification defined in RFC 2251. And while many of the AD tools and interfaces, such as ADSI, abstract and streamline LDAP operations to make things easier, any good AD administrator or developer must have a thorough understanding of LDAP to fully utilize Active Directory. This chapter will cover the some of the basic LDAP-related tasks you may need to do with Active Directory, along with other items related to searching and manipulating objects in the directory. The Anatomy of an Object The Active Directory schema is composed of a hierarchy of classes. These classes support inheritance, which enables reuse of existing class definitions. At the top of the inheritance tree is the top class, from which every class in the schema is derived. Table 4-1 contains a list of some of the attributes that are available from the top class, and subsequently are defined on every object that is created in Active Directory. Table 4-1. Common attributes of objects Attribute Description cn Relative distinguished name (RDN) attribute for most object classes createTimestamp Timestamp when the object was created. See Recipe 4.22 for more information description Multivalued attribute that can be used as a generic field for storing a description of the object 103 Table 4-1. Common attributes of objects Attribute Description displayName Name of the object displayed in administrative interfaces distinguishedName Distinguished name of the object modifyTimestamp Timestamp when the object was last changed. See Recipe 4.22 for more information name RDN of the object. The value of this attribute will mirror the naming attribute (e.g., cn, ou, dc) nTSecurityDescriptor Security descriptor assigned to the object objectCategory Used as a grouping mechanism for objects with a similar purpose (e.g., Person) objectClass List of classes from which the object's class was derived objectGUID Globally unique identifier for the object uSNChanged Update sequence number (USN) assigned by the local server after the last change to the object (can include creation) uSNCreated USN assigned when the object was created Recipe 4.1 Viewing the RootDSE 4.1.1 Problem You want to view attributes of the RootDSE, which can be useful for discovering basic information about a forest, domain, or domain controller. 4.1.2 Solution 4.1.2.1 Using a graphical user interface 1. Open LDP. 2. From the menu, select Connection Connect. 3. For Server, enter a domain controller, domain name, or leave blank to do a serverless bind. 4. For Port, enter 389. 5. Click OK. 6. The contents of the RootDSE will be shown in the right pane. 4.1.2.2 Using a command-line interface > enumprop "LDAP://RootDSE" 104 4.1.2.3 Using VBScript ' This code prints the attributes of the RootDSE set objRootDSE = GetObject("LDAP://RootDSE") objRootDSE.GetInfo for i = 0 to objRootDSE.PropertyCount - 1 set strProp = objRootDSE.Item(i) WScript.Echo strProp.Name & " " for each strPropval in strProp.Values WScript.Echo " " & strPropval.CaseIgnoreString next next 4.1.3 Discussion The RootDSE was originally defined in RFC 2251 as part of the LDAPv3 specification. It is not part of the Active Directory namespace per se. It is a synthetic object that is maintained separately by each domain controller. The RootDSE can be accessed anonymously, and in fact, none of the three solutions used credentials. In the CLI and VBScript solutions, I used serverless binds against the RootDSE. In that case, the DC Locator process is used to find a domain controller in the domain you authenticate against. This can also be accomplished with LDP by not entering a server name from the Connect dialog box. The RootDSE is key to writing portable AD-enabled applications. It provides a mechanism to programmatically determine the distinguished names of the various naming contexts among other things, which means you do not need to hardcode that information in scripts and programs. Here is an example from LDP when run against a Windows Server 2003-based domain controller: ld = ldap_open("dc01", 389); Established connection to dc01. Retrieving base DSA information . . . Result <0>: (null) Matched DNs: Getting 1 entries: >> Dn: 1> currentTime: 05/26/2003 15:29:42 Pacific Standard Time Pacific Daylight Time; 1> subschemaSubentry:CN=Aggregate,CN=Schema,CN=Configuration,DC=rallencorp,DC=co m; 1> dsServiceName: CN=NTDS Settings,CN=DC01,CN=Servers,CN=Default-First-Site- Name,CN=Sites,CN=Configuration,DC=rallencorp,DC=com; 5> namingContexts: DC=rallencorp,DC=com; CN=Configuration,DC=rallencorp,DC=com; CN=Schema,CN=Configuration,DC=rallencorp,DC=com; DC=DomainDnsZones,DC=rallencorp,DC=com; DC=ForestDnsZones,DC=rallencorp,DC=com; 105 1> defaultNamingContext: DC=rallencorp,DC=com; 1> schemaNamingContext: CN=Schema,CN=Configuration,DC=rallencorp,DC=com; 1> configurationNamingContext: CN=Configuration,DC=rallencorp,DC=com; 1> rootDomainNamingContext: DC=rallencorp,DC=com; 21> supportedControl: 1.2.840.113556.1.4.319; 1.2.840.113556.1.4.801; 1.2.840.113556. 1.4.473; 1.2.840.113556.1.4.528; 1.2.840.113556.1.4.417; 1.2.840.113556.1.4.619; 1.2. 840.113556.1.4.841; 1.2.840.113556.1.4.529; 1.2.840.113556.1.4.805; 1.2.840.113556.1. 4.521; 1.2.840.113556.1.4.970; 1.2.840.113556.1.4.1338; 1.2.840.113556.1.4.474; 1.2. 840.113556.1.4.1339; 1.2.840.113556.1.4.1340; 1.2.840.113556.1.4.1413; 2.16.840.1. 113730.3.4.9; 2.16.840.1.113730.3.4.10; 1.2.840.113556.1.4.1504; 1.2.840.113556.1.4. 1852; 1.2.840.113556.1.4.802; 2> supportedLDAPVersion: 3; 2; 12> supportedLDAPPolicies: MaxPoolThreads; MaxDatagramRecv; MaxReceiveBuffer; InitRecvTimeout; MaxConnections; MaxConnIdleTime; MaxPageSize; MaxQueryDuration; MaxTempTableSize; MaxResultSetSize; MaxNotificationPerConn; MaxValRange; 1> highestCommittedUSN: 53242; 4> supportedSASLMechanisms: GSSAPI; GSS-SPNEGO; EXTERNAL; DIGEST-MD5; 1> dnsHostName: dc01.rallencorp.com; 1> ldapServiceName: rallencorp.com:dc01$@RALLENCORP.COM; 1> serverName: CN=DC01,CN=Servers,CN=Default-First-Site- Name,CN=Sites,CN=Configuration,DC=rallencorp,DC=com; 3> supportedCapabilities: 1.2.840.113556.1.4.800; 1.2.840.113556.1.4.1670; 1.2.840. 113556.1.4.1791; 1> isSynchronized: TRUE; 1> isGlobalCatalogReady: TRUE; 1> domainFunctionality: 0 = ( DS_BEHAVIOR_WIN2000 ); 1> forestFunctionality: 0 = ( DS_BEHAVIOR_WIN2000 ); 1> domainControllerFunctionality: 2 = ( DS_BEHAVIOR_WIN2003 ); 4.1.3.1 Using VBScript 106 All attributes of the RootDSE were retrieved and displayed. Typically, you will need only a few of the attributes; in which case, you'll want to use Get or GetEx as in the following example: strDefaultNC = objRootDSE.Get("defaultNamingContext") Or if want to get an object based on the distinguished name (DN) of one of the naming contexts, you can call GetObject using an ADsPath: set objUser = GetObject("LDAP://cn=administrator,cn=users," & _ objRootDSE.Get("defaultNamingContext") ) 4.1.4 See Also RFC 2251, MS KB 219005 (Windows 2000: LDAPv3 RootDSE), MSDN: IADsPropertyEntry, MSDN: IADsProperty Value, MSDN: IADs::Get, and MSDN: IADs::GetEx Recipe 4.2 Viewing the Attributes of an Object 4.2.1 Problem You want to view one or more attributes of an object. 4.2.2 Solution 4.2.2.1 Using a graphical user interface 1. Open LDP. 2. From the menu, select Connection Connect. 3. For Server, enter the name of a domain controller or domain that contains the object. 4. For Port, enter 389. 5. Click OK. 6. From the menu, select Connection Bind. 7. Enter credentials of a user that can view the object (if necessary). 8. Click OK. 9. From the menu, select View Tree. 10. For BaseDN, type the DN of the object you want to view. 11. For Scope, select Base. 12. Click OK. 4.2.2.2 Using a command-line interface > dsquery * "<ObjectDN>" -scope base -attr * For Windows 2000, use this command: > enumprop "LDAP://<ObjectDN>" 4.2.2.3 Using VBScript 107 ' This code prints all attributes for the specified object. ' SCRIPT CONFIGURATION strObjectDN = "<ObjectDN>" ' e.g. cn=jsmith,cn=users,dc=rallencorp,dc=com ' END CONFIGURATION DisplayAttributes("LDAP://" & strObjectDN) Function DisplayAttributes( strObjectADsPath ) set objObject = GetObject(strObjectADsPath) objObject.GetInfo 'Declare the hash (dictionary), constants and variables 'Values taken from ADSTYPEENUM set dicADsType = CreateObject("Scripting.Dictionary") dicADsType.Add 0, "INVALID" dicADsType.Add 1, "DN_STRING" dicADsType.Add 2, "CASE_EXACT_STRING" dicADsType.Add 3, "CASE_IGNORE_STRING" dicADsType.Add 4, "PRINTABLE_STRING" dicADsType.Add 5, "NUMERIC_STRING" dicADsType.Add 6, "BOOLEAN" dicADsType.Add 7, "INTEGER" dicADsType.Add 8, "OCTET_STRING" dicADsType.Add 9, "UTC_TIME" dicADsType.Add 10, "LARGE_INTEGER" dicADsType.Add 11, "PROV_SPECIFIC" dicADsType.Add 12, "OBJECT_CLASS" dicADsType.Add 13, "CASEIGNORE_LIST" dicADsType.Add 14, "OCTET_LIST" dicADsType.Add 15, "PATH" dicADsType.Add 16, "POSTALADDRESS" dicADsType.Add 17, "TIMESTAMP" dicADsType.Add 18, "BACKLINK" dicADsType.Add 19, "TYPEDNAME" dicADsType.Add 20, "HOLD" dicADsType.Add 21, "NETADDRESS" dicADsType.Add 22, "REPLICAPOINTER" dicADsType.Add 23, "FAXNUMBER" dicADsType.Add 24, "EMAIL" dicADsType.Add 25, "NT_SECURITY_DESCRIPTOR" dicADsType.Add 26, "UNKNOWN" dicADsType.Add 27, "DN_WITH_BINARY" dicADsType.Add 28, "DN_WITH_STRING" for intIndex = 0 To (objObject.PropertyCount - 1) set objPropEntry = objObject.Item(intIndex) for Each objPropValue In objPropEntry.Values value = "" if (dicADsType(objPropValue.ADsType) = "DN_STRING") then value = objPropValue.DNString elseIf (dicADsType(objPropValue.ADsType) = "CASE_EXACT_STRING") then value = objPropValue.CaseExactString 108 elseIf (dicADsType(objPropValue.ADsType) = "CASE_IGNORE_STRING") then value = objPropValue.CaseIgnoreString elseIf (dicADsType(objPropValue.ADsType) = "PRINTABLE_STRING") then value = objPropValue.PrintableString elseIf (dicADsType(objPropValue.ADsType) = "NUMERIC_STRING") then value = objPropValue.NumericString elseIf (dicADsType(objPropValue.ADsType) = "BOOLEAN") then value = CStr(objPropValue.Boolean) elseIf (dicADsType(objPropValue.ADsType) = "INTEGER") then value = objPropValue.Integer elseIf (dicADsType(objPropValue.ADsType) = "LARGE_INTEGER") then set objLargeInt = objPropValue.LargeInteger value = objLargeInt.HighPart * 2^32 + objLargeInt.LowPart elseIf (dicADsType(objPropValue.ADsType) = "UTC_TIME") then value = objPropValue.UTCTime else value = "<" & dicADsType.Item(objPropEntry.ADsType) & ">" end if WScript.Echo objPropEntry.Name & " : " & value next next End Function 4.2.3 Discussion Objects in Active Directory are made up of a collection of attributes. Attributes can be single- or multivalued. Each attribute also has an associated syntax that is defined in the schema. See Recipe 10.7 for a complete list of syntaxes. 4.2.3.1 Using a graphical user interface You can customize the list of attributes returned from a search with LDP by modifying the Attributes: field under Options Search. To include all attributes enter *. For a subset enter a semicolon-separated list of attributes. 4.2.3.2 Using a command-line interface The - attr option for the dsquery command accepts a whitespace-separated list of attributes to display. Using a * will return all attributes. For the enumprop command, you can use the /ATTR option and a comma-separated list of attributes to return. In the following example, only the name and whenCreated attributes would be returned: 109 > enumprop /ATTR:name,whenCreated "LDAP://<ObjectDN>" 4.2.3.3 Using VBScript The DisplayAttributes function prints the attributes that contain values for the object passed in. After using GetObject to bind to the object, I used the IADs::GetInfo method to populate the local property cache with all of the object's attributes from AD. In order to print each value of a property, I have to know its type or syntax. The ADsType method returns an integer from the ADSTYPEENUM enumeration that corresponds with a particular syntax (e.g., boolean). Based on the syntax, I call a specific method (e.g., Boolean) that can properly print the value. If I didn't incorporate this logic and tried to print all values using the CaseIgnoreString method for example, an error would get generated when the script encountered an octet string because octet strings (i.e., binary data) do not have a CaseIgnoreString representation. I stored the values from the ADSTYPEENUM enumeration in key/value pairs in a dictionary object (i.e., Scripting.Dictionary). In the dictionary object, the key for the dictionary is the ADSTYPEENUM integer, and the value is a textual version of the syntax. I used the dictionary object so I could print the textual syntax of each attribute. I iterated over all the properties in the property cache using IADsPropertyList and IADsPropertyEntry objects, which are instantiated with the IADsPropertyList::Item method. The DisplayAttributes function is used throughout the book in examples where the attributes for a given type of object are displayed. 4.2.4 See Also Chapter 19, IADs and the Property Cache, from Active Directory, Second Edition, MSDN: IADsPropertyEntry, MSDN: IADsPropertyList, MSDN: ADSTYPEENUM, and MSDN: IADs::GetInfo Recipe 4.3 Using LDAP Controls 4.3.1 Problem You want to use an LDAP control as part of an LDAP operation. 4.3.2 Solution 4.3.2.1 Using a graphical user interface 1. Open LDP. 2. From the menu, select Options Controls. 3. For the Windows Server 2003 version of LDP, select the control you want to use under Load Predefined. The control should automatically be added to the list of Active Controls. 110 For the Windows 2000 version of LDP, you'll need to type the object identifier (OID) of the control under Object Identifier. 4. Enter the value for the control under Value. 5. Select whether the control is server- or client-side under Control Type. 6. Check the box beside Critical if the control is critical. 7. Click the Check-in button. 8. Click OK. 9. At this point, you will need to invoke the LDAP operation (for example, Search) that will use the control. In the dialog box for any operation, be sure that the "Extended" option is checked before initiating the operation. 4.3.2.2 Using VBScript None of the ADSI automation interfaces directly expose LDAP controls. That means they cannot be utilized from VBScript. On the other hand, many of the controls, such as paged searching or deleting a subtree, are wrapped within their own ADSI methods that can be used within VBScript. Any LDAP-based API, such as the Perl Net::LDAP modules, can be used to set controls as part of LDAP operations. 4.3.3 Discussion LDAP controls were defined in the LDAPv3 specification as a way to extend LDAP and its operations without breaking the protocol. Many controls have been implemented, some of which are used when searching the directory (e.g., paged searching, VLV, finding deleted objects, and attribute scoped query), and some are needed to do certain modifications to the directory (e.g., cross-domain object moves, tree delete, and permissive modify). Controls can be marked as critical, which means they must be processed with the request, or an error is returned. If an unsupported control is not flagged as critical, the server can continue to process the request and ignore the control. The complete list of controls supported by Active Directory is included in Table 4-2 . Table 4-2. LDAP controls supported by Active Directory Name OID Description Paged Results 1.2.840.113556.1.4.319 Instructs the server to return search results in "pages." Cross Domain Move 1.2.840.113556.1.4.521 Used to move objects between domains. DIRSYNC 1.2.840.113556.1.4.841 Used to find objects that have changed over a . 3. For the Windows Server 2003 version of LDP, select the control you want to use under Load Predefined. The control should automatically be added to the list of Active Controls. 110 For. 2. From the menu, select Connection Connect. 3. For Server, enter a domain controller, domain name, or leave blank to do a serverless bind. 4. For Port, enter 389. 5. Click OK. 6. The contents. which means you do not need to hardcode that information in scripts and programs. Here is an example from LDP when run against a Windows Server 2003-based domain controller: ld = ldap_open("dc01",

Ngày đăng: 05/07/2014, 08:20

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan