521 23. For Attribute, enter <ManadatoryAttribute>. 24. For Values, enter <MandatoryAttributeValue>. 25. For Operation, select Add. 26. Check the box beside Extended. 27. Click Run. 28. The results will be displayed in the right pane. 16.17.3 Discussion Windows Server 2003 supports restoring tombstone (deleted) objects, which have not expired. This is an alternative to performing an authoritative restore for an object that was accidentally deleted. The downside to this approach is that since most attributes that you care about (excluding those in Table 16-1) are not populated on tombstone objects, the restored deleted object will only be a shadow of its former self. Here are the basic steps to restore a deleted object: 1. Enable the Return Deleted Objects control (1.2.840.113556.1.4.417). 2. Remove the isDeleted attribute of the object (do not simply set to FALSE). 3. Replace the distinguishedName attribute with its new location in the tree. 4. Restore any mandatory attributes. This should all be done in a single LDAP operation. After the object has been restored, you can repopulate any optional attributes that were set previously. By default only members of the administrator groups can restore deleted objects. You can delegate control over restoring deleted objects by granting the Reanimate Tombstone extended right to a user or group. The user or group will also need rights to modify attributes of the restored object including the ability to create child objects in the container the object is restored to. Granting the privilege to restore objects should be done with caution. A user could restore a user object and after setting the password, login with the account. This could give the user access to resources he was not suppose to have. 16.17.4 See Also Recipe 16.16 for searching for deleted objects and MSDN: Restoring Deleted Objects 522 Recipe 16.18 Modifying the Tombstone Lifetime for a Domain 16.18.1 Problem You want to change the default tombstone lifetime for a domain. 16.18.2 Solution 16.18.2.1 Using a graphical user interface 1. Open ADSI Edit. 2. In the left pane, expand cn=Configuration cn=Services cn=Windows NT. 3. Right-click on cn=Directory Service and select Properties. 4. Set the tombstoneLifetime attribute to the number of days that tombstone objects should remain in Active Directory before getting removed completely (the default is 60 days). 5. Click OK. 16.18.2.2 Using a command-line interface Create an LDIF file called change_tombstone_lifetime.ldf with the following contents: dn: cn=Directory Service,cn=Windows NT,cn=Services,cn=Configuration,<ForestRootDN> changetype: modify replace: tombstoneLifetime tombstoneLifetime: <NumberOfDays> - then run the following command: > ldifde -v -i -f change_tombstone_lifetime.ldf 16.18.2.3 Using VBScript ' This code modifies the default tombstone lifetime ' SCRIPT CONFIGURATION intTombstoneLifetime = <NumberOfDays> ' END CONFIGURATION set objRootDSE = GetObject("LDAP://RootDSE") set objDSCont = GetObject("LDAP://cn=Directory Service,cn=Windows NT," & _ "cn=Services," & objRootDSE.Get("configurationNamingContext") ) objDSCont.Put "tombstoneLifetime", intTombstoneLifetime objDSCont.SetInfo WScript.Echo "Successfully set the tombstone lifetime to " & _ intTombstoneLifetime 523 16.18.3 Discussion It is not recommended that you change this setting unless you have a very good reason. Lowering this value below the 60-day default, also lowers the length of time a backup of Active Directory is good for. See Introduction in Chapter 16 and Recipe 16.16 for more information on tombstone (deleted) objects and the tombstone lifetime. 16.18.4 See Also Recipe 16.13 for more on the garbage collection process, MS KB 198793 (The Active Directory Database Garbage Collection Process), MS KB 216993 (Backup of the Active Directory Has 60- Day Useful Life), and MS KB 314282 (Lingering Objects May Remain After You Bring an Out- of-Date Global Catalog Server Back Online) 524 Chapter 17. Application Partitions Introduction Recipe 17.1. Creating and Deleting an Application Partition Recipe 17.2. Finding the Application Partitions in a Forest Recipe 17.3. Adding or Removing a Replica Server for an Application Partition Recipe 17.4. Finding the Replica Servers for an Application Partition Recipe 17.5. Finding the Application Partitions Hosted by a Server Recipe 17.6. Verifying Application Partitions Are Instantiated on a Server Correctly Recipe 17.7. Setting the Replication Notification Delay for an Application Partition Recipe 17.8. Setting the Reference Domain for an Application Partition Recipe 17.9. Delegating Control of Managing an Application Partition Introduction Active Directory domain controllers host exactly three predefined partitions. The configuration naming context is replicated to all domain controllers in the forest and contains information that is forest-wide, such as the site topology and LDAP query policies. The schema-naming context is also replicated forest-wide and contains all of the schema objects that define how data is stored and structured in Active Directory. The third partition is the domain naming context, which is replicated to all of the domain controllers that host a particular domain. Windows Server 2003 introduces a new type of partition called an application partition, which is very similar to the other naming contexts except you can configure which domain controllers in the forest replicate the data contained within it. This capability gives administrators much more flexibility over how they can store and replicate data contained in Active Directory. If you need to replicate a certain set of data to only two different sites, you can create an application partition that will only replicate the data to the domain controllers in those two sites. For more details on application partitions, see Chapter 3 in Active Directory, Second Edition (O'Reilly). 525 Application Partitions are new to Windows Server 2003, so this entire chapter applies only to Windows Server 2003 domain controllers. Windows 2000 domain controllers cannot host application partitions. The Anatomy of an Application Partition Application partitions are stored in Active Directory similar to domains. In fact, they consist of the same two objects as domains, a domainDNS object and a crossRef object that resides under the Partitions container in the Configuration Naming Context (CNC). Application partitions are named like domains and can be virtually anything you want. You can create an application partition that uses the current namespace within the forest. For example, in the rallencorp.com (dc=rallencorp,dc=com) forest, you could create an apps.rallencorp.com (dc=apps,dc=rallencorp,dc=com) application partition. Alternatively, a name that is part of a new tree can also be used, for example, apps.local (dc=apps,dc=local). Application partitions can also be subordinate to other application partitions. Table 17-1 and Table 17-2 contain some of the interesting attributes of domainDNS and crossRef objects as they apply to application partitions. Table 17-1. Attributes of domainDNS objects Attribute Description dc Relative distinguished name of the application partition. instanceType This attribute must be set to 5 when creating an application partition. See Recipe 17.1 for more information. msDs- masteredBy List of nTDSDSA object DNs of the domain controllers that replicate the application partition. See Recipe 17.4 for more information. Table 17-2. Attributes of crossRef objects Attribute Description cn Relative distinguished name of the crossRef object. This value is generally a GUID for application partitions. dnsRoot Fully qualified DNS name of the application partition. msDS-NC-Replica- Locations List of nTDSDSA object DNs of the domain controllers that replicate the application partition. See Recipe 17.4 for more information. msDS- SDReferenceDomain Domain used for security descriptor translation. See Recipe 17.8 for more information. nCName Distinguished name of the application partition's corresponding domainDNS object. 526 Table 17-2. Attributes of crossRef objects Attribute Description systemFlags Bit flag that identifies if the crossRef represents an application. See Recipe 17.2 for more information. Recipe 17.1 Creating and Deleting an Application Partition 17.1.1 Problem You want to create or delete an application partition. Application partitions are useful if you need to replicate data to a subset of locations where you have domain controllers. Instead of replicating the application data to all domain controllers in a domain, you can use an application partition to only replicate the data to the domain controllers of your choosing. 17.1.2 Solution 17.1.2.1 Using a graphical user interface To create an application partition, do the following: 1. Open ADSI Edit. 2. Connect to the domain of which the new application partition will be a child. 3. In the left pane, right-click on the domain and select New Object. 4. Select domainDNS and click Next. 5. For Value, enter the name of the application partition and click Next. 6. Click on More Attributes. 7. Select Both for which properties to view. 8. Select instanceType for property to view. 9. For the Edit Attribute field, enter 5. 10. Click the Set button. 11. Click OK. 12. Click Finish. To delete an application, do the following: 1. Open ADSI Edit. 2. Connect to the configuration naming context of the forest the application partition is in, if it is not already present in the left pane. 3. Expand the configuration naming context and click on the Partitions container. 4. In the right pane, right-click on the crossRef object that represents the application partition and select Delete. 5. Click Yes to confirm. 527 17.1.2.2 Using a command-line interface Use the following command to create an application partition on a domain controller: > ntdsutil "dom man" conn "co to se <DomainControllerName>" q "create nc[RETURN] <AppPartitionDN> NULL" q q Use the following command to delete an application partition: > ntdsutil "dom man" conn "co to se <DomainControllerName>" q "delete nc[RETURN] <AppPartitionFQDN>" q q 17.1.2.3 Using VBScript ' This code creates an application partition off of the ' root of the default forest. ' SCRIPT CONFIGURATION strAppPart = "<AppPartitionName>" ' DN of the app partition to delete strServer = "<DomainControllerName>" ' DNS name of DC to host app partition strDescr = "<Description>" ' Descriptive text about the app partition ' END CONFIGURATION set objRootDSE = GetObject("LDAP://" & strServer & "/RootDSE") set objLDAP = GetObject("LDAP://" & strServer & "/" & _ objRootDSE.Get("rootDomainNamingContext") ) set objAppPart = objLDAP.Create("domainDNS", "dc=" & strAppPart) objAppPart.Put "instancetype", 5 objAppPart.Put "description", strDescr objAppPart.SetInfo WScript.Echo "Created application partition: " & strAppPart ' This code deletes the specified application partition ' SCRIPT CONFIGURATION strAppPart = "<AppPartitionDN>" ' DN of the app partition to delete ' END CONFIGURATION set objRootDSE = GetObject("LDAP://RootDSE") strBase = "<LDAP://cn=Partitions," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=crossRef)(nCName=" & _ strAppPart & "));" strAttrs = "cn,distinguishedName;" strScope = "onelevel" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) if objRS.RecordCount <> 1 then WScript.Echo "Did not find a match for " & strAppPart else objRS.MoveLast set objAppPart = GetObject("LDAP://" & _ objRS.Fields("distinguishedName").Value ) 528 objAppPart.DeleteObject(0) Wscript.Echo "Deleted " & objRS.Fields("distinguishedName").Value end if 17.1.3 Discussion To create an application partition, you need to create a domainDNS object that serves as the root container for the partition. A crossRef object is automatically created in the Partitions container in the CNC. Conversely, when removing an application partition, you only need to remove the crossRef object and the domainDNS is automatically deleted. When you delete an application partition, all objects within the partition also get deleted. Tombstone objects are not created for any of the objects within the application partition or for the application partition itself. 17.1.4 See Also MS KB 322669 (HOW TO: Manage the Application Directory Partition and Replicas in Windows Server 2003), and MSDN: Creating an Application Directory Partition, and MSDN: Deleting an Application Directory Partition Recipe 17.2 Finding the Application Partitions in a Forest 17.2.1 Problem You want to find the application partitions that have been created in a forest. 17.2.2 Solution 17.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 DC. 4. For Port, enter 389. 5. Click OK. 6. From the menu, select Connection Bind. 7. Enter a user and password with the necessary credentials. 8. Click OK. 9. From the menu, select Browse Search. 10. For BaseDN, type the DN of the Partitions container (e.g., cn=partitions,cn=configuration,dc=rallencorp, dc=com). 11. For Filter, enter: (&(objectcategory=crossRef)(systemFlags:1.2.840.113556.1.4.803:=5)) 12. For Scope, select One Level. 529 13. Click the Options button. 14. For Attributes, type dnsRoot. 15. Click OK. 16. Click Run. 17.2.2.2 Using a command-line interface Use the following command to find all of the application partitions in a forest: > dsquery * cn=partitions,cn=configuration,<ForestDN> -filter[RETURN] "(&(objectcategory=crossRef)(systemFlags:1.2.840.113556.1.4.803:=5))"[RETURN] -scope onelevel -attr dnsRoot 17.2.2.3 Using VBScript ' This code displays the application partitions contained in the ' default forest set objRootDSE = GetObject("LDAP://RootDSE") strBase = "<LDAP://cn=Partitions," & _ objRootDSE.Get("ConfigurationNamingContext") & ">;" strFilter = "(&(objectcategory=crossRef)" & _ "(systemFlags:1.2.840.113556.1.4.803:=5));" strAttrs = "cn,ncName;" strScope = "onelevel" set objConn = CreateObject("ADODB.Connection") objConn.Provider = "ADsDSOObject" objConn.Open "Active Directory Provider" set objRS = objConn.Execute(strBase & strFilter & strAttrs & strScope) objRS.MoveFirst while not objRS.EOF Wscript.Echo objRS.Fields("nCName").Value objRS.MoveNext wend 17.2.3 Discussion The method I used in the Solution to get the list of application partitions was to query all crossRef objects in the Partitions container that have the systemFlags attribute with the 0101 bits set (5 in decimal). To do this, I used a logical AND bit-wise filter. See Recipe 4.9 for more on searching with a bitwise filter. You can take a shortcut by not including the bitwise OID in the search filter, and changing it to systemFlags=5. This currently produces the same results in my test forest as with the bitwise filter, but there are no guarantees since it is a bit-flag attribute. There may exist special circumstances when an application partition would have another bit set in systemFlags that would yield a different value. 530 In each solution, I printed the dnsRoot attribute for each application partition, which contains the DNS name of the application partition. You can also retrieve the nCName attribute, which contains the distinguished name of the application partition. Recipe 17.3 Adding or Removing a Replica Server for an Application Partition 17.3.1 Problem You want to add or remove a replica server for an application partition. After you've created an application partition, you should make at least one other server a replica server in case the first server fails. 17.3.2 Solution 17.3.2.1 Using a command-line interface Use the following command to add a replica server for an application partition: > ntdsutil "dom man" conn "co to se <DomainControllerName>" q "add nc replica[RETURN] <AppPartitionDN> <DomainControllerName>" q q Use the following command to remove a replica server for an application partition: > ntdsutil "dom man" conn "co to se <DomainControllerName>" q "remove nc replica[RETURN] <AppPartitionDN> <DomainControllerName>" q q 17.3.2.2 Using VBScript ' This code adds or removes a replica server for the ' specified application partition ' SCRIPT CONFIGURATION strAppPart = "<AppPartitionFQDN>" ' DNS name of the application partition ' Hostname of server to add as replica for app partition. ' This needs to match the common name for the DC's server object. strServer = "<DomainControllerName>" ' e.g. dc01 ' Set to True to add server as new replica or False to remove boolAdd = True ' END CONFIGURATION ' Constants taken from ADS_PROPERTY_OPERATION_ENUM const ADS_PROPERTY_APPEND = 3 const ADS_PROPERTY_DELETE = 4 set objRootDSE = GetObject("LDAP://RootDSE") ' . default, also lowers the length of time a backup of Active Directory is good for. See Introduction in Chapter 16 and Recipe 16.16 for more information on tombstone (deleted) objects and the tombstone. Also Recipe 16.13 for more on the garbage collection process, MS KB 198793 (The Active Directory Database Garbage Collection Process), MS KB 216993 (Backup of the Active Directory Has 60- Day. the Application Partitions in a Forest Recipe 17.3. Adding or Removing a Replica Server for an Application Partition Recipe 17.4. Finding the Replica Servers for an Application Partition Recipe