3.1.1.5.4.2.3 Processing Specifics

Once the previously described constraint checking is done, the server performs the move operation on the target DC as specified below. The server then performs the cleanup operation as specified below. Constraint checking and cleanup operation are performed in two separate local transactions.

The caller specifies the DNS hostname of the target DC in the controlValue field of LDAP_SERVER_CROSSDOM_MOVE_TARGET_OID LDAP control.

If the controlValue field is empty, then the server performs only constraints checking as mentioned previously. It returns success if it passes all the constraints.

Invoke move operation on target DC:

Let S be the nTDSDSA object of the server.

Let NN be the root of NC replica where NP exists.

Let pmsgIn be a reference to a structure of type DRS_MSG_MOVEREQ.

Set pmsgIn->V2.pSrcDSA to dsname of S.

pmsgIn->V2.pSrcObject is a reference to a structure of type ENTINF. Define ENTINF for O as described later in this section.

Set pmsgIn->V2.pDstName to dsname of NewDN.

Set pmsgIn->V2.pExpectedTargetNC to dsname of NN.

pmsgIn->V2.pClientCreds is a reference to DRS_SecBuffer structure. It is set to the GSS Kerberos authentication token (see [RFC1964]) derived from the security context of the caller.

Set pmsgIn->V2.PrefixTable to dc.prefixTable, as specified in section 3.1.1.1.9.

Set pmsgIn->V2.ulFlags to 0.

Let H be the bind handle derived by calling IDL_DRSBind method against target DC.

Let pdwOutVersion be a reference to dwOutversion of type integer.

Let pmsgOut be a reference to DRS_MSG_MOVEREPLY structure.

Call IDL_DRSInterDomainMove(H, 2, pmsgIn, pdwOutVersion, pmsgOut). If the method returns an error, then the server returns LDAP error unavailable.

If (dwOutVersion ≠ 2), then the server returns LDAP error operationsError.

If (pmsgOut->v2.win32Error ≠ 0), then the server returns LDAP error unwillingToPerform.

Create proxy object and perform cleanup

The proxiedObjectName attribute is present on the infrastructureUpdate object that is used to communicate the cross-domain move from the originating NC replica to other replicas of the NC. The proxiedObjectName attribute is also present on an object that has been moved across domain, as specified in [MS-DRSR] section 4.1.15.3.

The proxiedObjectName attribute has syntax Object(DN-Binary); see section 3.1.1.2.2.2.3 for the specification of this syntax, which contains the fields char_count, binary_value, and object_DN. The binary_value part of a proxiedObjectName value is 16 characters. Bytes 0 to 7 contain the character string "00000001" for a cross-domain move. Bytes 8 to 15 contain the hexadecimal representation of a number called the cross-domain move epoch.

The cross-domain move epoch E of the proxiedObjectName attribute on an infrastructureUpdate object is determined as follows:

  • If O!proxiedObjectName is present, then let B be the binary_value of O!proxiedObjectName. Let E be value given by the least significant 32 bits of B.

  • Otherwise, let E be 0.

Create an attribute value K of type Object (DN-Binary). Set K.char_count to 16. Let J be a string of eight characters that is the hexadecimal representation of value E. Set K.binary_value to the concatenation of the strings "00000001" and J. Set object_DN part of K to NewDN.

Expunge object O from NC replica.

Let I = GetWellknownObject(default NC, GUID_INFRASTRUCTURE_CONTAINER_W).

Create an infrastructureUpdate object L such that L!parent = I and L!name is any name unique among the children of I and L!proxiedObjectName = K and L!systemFlags = (FLAG_DOMAIN_DISALLOW_RENAME | FLAG_DISALLOW_MOVE_ON_DELETE | FLAG_DOMAIN_DISALLOW_MOVE).

Delete L and turn it into a tombstone object.

Defining ENTINF structure for object O

Let t be the prefix table dc.prefixTable specified in section 3.1.1.1.9.

Let AttsSet be the set of all attributes (represented as ATTRTYP) of object O.

Let Atts be a sequence of ATTRTYP whose elements are elements of AttsSet.

Let EntInf be a structure of type ENTINF.

Set EntInf.pName to the dsname of O.

Set EntInf.ulFlags to 0.

Let AttrBlock be a structure of type ATTRBLOCK of length Atts.length.

Give AttrBlock.pAttr[i] a value determined by Atts[i] as follows, for all i in [0...Atts.length) (in any order)

  • Let K be the attributeSchema object SchemaObj(Atts[i]). SchemaObj is specified in [MS-DRSR] section 5.183.

  • Let syntax be K!attributeSyntax.

  • Let AttrBlock.pAttr[i].AttribTyp be the value returned by MakeAttid(t, oid).

  • Let Vals be the sequence of values O.Atts[i].

  • Let AttrBlock.pAttr[i].AttrVal be a structure of type ATTRVALBLOCK of length Vals.length.

  • Set AttrBlock.pAttr[i].AttrVal.valCount = Vals.length.

  • Give AttrBlock.pAttr[i].AttrVal.pAVal[j] a value determined by Vals[j] as follows, for all j in [0..Vals.length) (in any order).

    • Set AttrBlock.pAttr[i].AttrVal.pAVal[j] = ATTRVALFromValue(Vals[j], syntax, t)