Was this page helpful?
Your feedback about this content is important. Let us know what you think.
Additional feedback?
1500 characters remaining Server Behavior of the IDL_DRSAddCloneDC Method Server Behavior of the IDL_DRSAddCloneDC Method

Informative summary of behavior: The IDL_DRSAddCloneDC method is used to create a new domain controller (DC) by duplicating the states of the original DC. The states of a DC are composed of computer, server, NTDS settings, FRS, DFSR, and connection objects that are maintained for each DC. When duplicating an object, this RPC method replaces all references to the original DC with corresponding objects of the new DC. The caller must have the control access right DS-Clone-Domain-Controller on the default NC. When called, this RPC method:

  1. Validates that the caller has permission to perform the operation.

  2. Creates new account and other objects for the new domain controller account by copying information from the existing domain controller.

  3. Returns the name, site, and password for the new domain controller to the client.

  4.  ULONG
         [in, ref] DRS_HANDLE hDrs,
         [in] DWORD dwInVersion,
         [in, ref, switch_is(dwInVersion)] 
             DRS_MSG_ADDCLONEDCREQ *pmsgIn,
         [out, ref] DWORD *pdwOutVersion,
         [out, ref, switch_is(*pdwOutVersion)] 
             DRS_MSG_ADDCLONEDCREPLY *pmsgOut)
     clientCreds: ClientAuthorizationInfo
     tlInfo: TranslationInfo
     callerSid: SID
     isRodc: boolean
     computerObj: DSName
     originalDCSrvObj: DSName
     originalDCSiteObj: DSName
     originalDCServersObj: DSName
     originalDSAObj: DSName
     newDCComputerObj: DSName
     newDCSiteObj: DSName
     newDCServersObj: DSName
     newDCServerObj: DSName
     newDSAObj: DSName
     ValidateDRSInput(hDrs, 28)
     pdwOutVersion^ := 1
     pmsgOut^.V1.pwszCloneDCName := null
     pmsgOut^.V1.pwszSite := null
     pmsgOut^.V1.cPasswordLength := 0
     pmsgOut^.V1.pwsNewDCAccountPassword := null
     if dwInVersion ≠ 1 then
     msgIn := pmsgIn^.V1
     if GetKeyLength(hDrs) < 128 then
     if not AccessCheckCAR(DefaultNC(), DS-Clone-Domain-Controller) then
     /* Check that the caller (the "source" DC) is actually a DC by
      * checking Enterprise Domain Controllers or Enterprise Read-Only Domain 
      * Controllers SID in its token. */
     clientCreds := GetCallerAuthorizationInfo()
     if not CheckGroupMembership(clientCreds, SidFromStringSid("S-1-5-9")) then
         if not CheckGroupMembership(clientCreds, SidFromStringSid("S-1-5-498"))
             return ERROR_DS_DRA_ACCESS_DENIED
             isRodc := true
     /* The DC must own the PDC role */
     if GetFSMORoleOwner(FSMO_PDC) ≠ DSAObj() then
     callerSid := GetPrincipalSid(clientCreds)
     /* get the original DC computer object */
     computerObj := select one obj from all where
                  (obj!objectSid = callerSid)
     tlInfo.OriginalDC.Name := computerObj!sAMAccountName.Remove('$')
     /* generate cloned DC name if not specified */
     if (msgIn.pwszCloneDCName = null)
         found : boolean 
         newDCName : string
         /* Generate new name by appendling '–CL' and 4 digits to the original
          * DC name */
         found := false
         For suffix = 0000 to 9999 do
            newDCName := tlInfo.OriginalDC.Name[0 .. 8] + '-CL' + suffix 
            if not exists(
                select o from all where o!sAMAccountName = (newDCName + '$')
            ) then
                found := true
         if not found then 
         tlInfo.newDC.Name := newDCName
         tlInfo.newDC.Name := msgIn.pwszCloneDCName
     tlInfo.OriginalDC.Sid := computerObj!objectSid
     tlInfo.OriginalDC.dnsHostName := computerObj!dNSHostName
     if isRodc then
         newKrbTgtAcct : DSName
         newKrbTgtAcct := GenerateNewKrbTgtAcct()
         tlInfo.objMap[computerObj!msDS-KrbTgtLink] := newKrbTgtAcct
     /* Duplicate original DC computer object */
     newDCComputerObj := DuplicateObject(computerObj, computerObj!parent,
                             "cn=" + tlInfo.newDC.Name, tlInfo)
     tlInfo.objMap[compuerObj!distinguishedName] :=
     tlInfo.NewDC.Sid := newDCComputerObj!objectSid
     tlInfo.NewDC.dnsHostName := newDCComputerObj!dNSHostName
     /* Get the original DC server object */
     originalDCSrvObj := select one v from ConfigNC()
       where v.dn in computerObj!serverReferenceBL
     originalDCServersObj := originalDCSrvObj!parent
     originalDCSiteObj := originalDCSrvObj!parent
     /* use the specified site for the new DC.
      * use the original DC site if the site is not specified */
     if (msgIn.pwszSite ≠ null) then
         siteContainer: DSName 
         siteContainer := DescendantObject(ConfigNC(), "CN=Sites,")
         newDCSiteObj := select one v from siteContainer!children
             where v!name = msgIn.pwszSite
         if newDCSiteObj = null
             return ERROR_NO_SUCH_SITE
         newDCSiteObj := originalDCSiteObj
     newDCServersObj := DescendantObject(newDCSiteObj, "CN=Servers")
     /* Duplicate the original DC servers object if the servers object is not 
      * present in the new DC site */
     if not exists newDCServersObj then
         newDCServersObj := DuplicateObject(originalDCServersObj, 
                    newDCSiteObj, "CN=Servers", tlInfo)
     tlInfo.objMap[originalDCServersObj!distinguishedName] :=
     /* Duplicate the server object */
     newDCServerObj := DescendantObject(newDCServersObj,
         "CN=" + tlInfo.newDC.Name)
     if not exists newDCServerObj then
         newDCServerObj := DuplicateObject(originalDCSrvObj, newDCServersObj,
                 "CN=" + tlInfo.newDC.Name, tlInfo)
     tlInfo.objMap[originalDCSrvObj!distinguishedName] :=
     /* Duplicate the NTDS settings object */
     originalDSAObj := DescendantObject(originalDCSrvObj,
         "CN=NTDS Settings")
     newDSAObj := DuplicateObject(originalDSAObj, newDCServerObj,
         "CN=NTDS Settings", tlInfo)
     tlInfo.objMap[originalDSAObj!distinguishedName] :=
     if isRodc then
         newConnObj: DSName
         topologyObj: DSName
         originalDFSRObj: DSName
         newDFSRObj: DSName
         frsSysvolObj: DSName
         originalFRSObj: DSName
         newfrsObj : DSName
         foreach obj in originalDSAObj!children where
           obj!objectClass = "ntdsConnection"
             newConnObj := DuplicateObject(obj, newDSAObj,
                 "CN=" + tlInfo.newDC.Name, tlInfo)
             objMap[obj!distinguishedName] := newConnObj!distinguishedName
         /* Duplicate DFSR topology object */
         topologyObj := DescendantObject(DefaultNC(),
           "CN=Topology,CN=Domain System Volume,CN=DFSR-GlobalSettings,CN=System")
         originalDFSRObj := DescendantObject(topologyObj,
             "CN=" + tlInfo.OriginalDC.Name)
         if originalDFSRObj ≠ null then 
             newDFSRObj = DuplicateObject(originalDFSRObj, topologyObj,
                 "CN="+ tlInfo.newDC.Name, tlInfo)
         /* Duplicate FRS object */
         frsSysvolObj = DescendantObject(DefaultNC(),
           "CN=Domain System Volume (SYSVOL     share),CN=File Replication Service,CN=System")
         originalFRSObj = DescendantObject(frsSysvolObj,
             "CN=" + tlInfo.OriginalDC.Name)
         if originalFRSObj ≠ null then
             newfrsObj = DuplicateObject(originalFRSObj, frsSysVolObj,
                 "CN=" + tlInfo.newDC.Name, tlInfo)
     pmsgOut^.V1.pwszCloneDCname := tlInfo.newDC.Name
     pmsgOut^.V1.cPasswordLength := 120
     pmsgOut^.V1.pwsNewDCAccountPassword:= a 120-byte sequence of randomly
       generated characters between ASCII 32 (space) and ASCII 122 ('z')
     pmsgOut^.V1.pwszSite := newDCSiteObj!name
     return 0
© 2015 Microsoft