Export (0) Print
Expand All
This topic has not yet been rated - Rate this topic

4.1.10.5.2 GetReplChanges

procedure GetReplChanges(
  hDrs: DRS_HANDLE,
  searchFilter: LDAPString,
  dirSyncFlags: ULONG,
  msgIn: DRS_MSG_GETCHGREQ_V10,
  var msgOut: DRS_MSG_GETCHGREPLY_V6): ULONG

Informative summary of behavior: The GetReplChanges procedure processes an LDAP Search request with LDAP_SERVER_DIRSYNC_OID control or a normal replication request; that is, an IDL_DRSGetNCChanges request that is not a FSMO role request. It adds changed objects and link values to the response, subject to the scope (msgIn.pNC^, msgIn.ulFlags), filter criteria (msgIn.pUpToDateVecDest, msgIn.ulFlags, msgIn.pPartialAttrSet, msgIn.pPartialAttrSetEx, searchFilter, dirSyncFlags), response limits (msgIn.cMaxObjects, msgIn.cMaxBytes), and the previous server cookie (msgIn.usnvecFrom) in the request. It returns 0 if successful, otherwise a Windows error code.

err: ULONG 
ncRoot: DSName
pUtd: ADDRESS OF UPTODATE_VECTOR_V1_EXT
scope: set of DSName
attribute: ATTRTYP
partialAttrs: set of ATTRTYP
partialAttrsEx: set of ATTRTYP
changedObjs: set of ObjAtts
changedLinks: set of ObjAttVal
responseObjs: set of ObjAtts
responseLinks: set of ObjAttVal
anc: ObjAtts
clientDSA : DSName
updRefs: DRS_MSG_UPDREFS_V1 /* See IDL_DRSUpdateRefs structures. */
tgt: DSName

if AmIRODC() then
  return ERROR_DS_DRA_SOURCE_DISABLED
endif

/* check whether outbound replication is disabled */
/* NTDSDSA_OPT_DISABLE_OUTBOUND_REPL defined in
 * [MS-ADTS] section 6.1.1.2.2.1.2.1.1, "nTDSDSA Object" */

if NTDSDSA_OPT_DISABLE_OUTBOUND_REPL in DSAObj()!options and
   not DRS_SYNC_FORCED in msgIn.ulFlags and
   not dirSyncFlags then
  return ERROR_DS_DRA_SOURCE_DISABLED
endif
ncRoot := GetObjectNC(msgIn.pNC^)

/* Determine stamp filter to apply to the response. */
if DRS_FULL_SYNC_PACKET in msgIn.ulFlags then
  pUtd := null
else
  pUtd := msgIn.pUpToDateVecDest
endif

/* Determine attribute filters to apply to the response. */
if msgIn.pPartialAttrSet = null
  partialAttrs := null
else
  partialAttrs := {}
  foreach id in msgIn.pPartialAttrSet
    attribute := LocalAttidFromRemoteAttid(msgIn.PrefixTableDest, id)
    if (not IT_WRITE in ncRoot!instanceType) and
       (not attribute in ncRoot!partialAttributeSet) then
      return ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET
    endif
    partialAttrs := partialAttrs + { attribute }
  endfor
endif
if msgIn.pPartialAttrSetEx = null
  partialAttrsEx := null
else
  partialAttrsEx := {}
  foreach id in msgIn.pPartialAttrSetEx
    attribute := LocalAttidFromRemoteAttid(msgIn.PrefixTableDest, id)
    if (not IT_WRITE in ncRoot!instanceType) and
       (not attribute in ncRoot!partialAttributeSet) then
      return ERROR_DS_DRA_INCOMPATIBLE_PARTIAL_SET
    endif
    partialAttrsEx:= partialAttrsEx + { attribute }
  endfor
endif

/* Get nTDSDSA of the client */
clientDSA := select one o from ConfigNC() where
             o!objectGUID = msgIn.uuidDsaObjDest

/* Get the set of all objects that are in scope. */
scope := GetReplScope(msgIn, searchFilter)

/* Get object and link value changes in scope. */
GetChangesInScope(scope, pUtd, msgIn.ulExtendedOp, partialAttrs,
    partialAttrsEx, dirSyncFlags, changedObjs, changedLinks)

/* Choose subsets of changedObjs and changedLinks to include in this
 * response. Set usnvecTo and fMoreData in out to indicate the
 * subset to return in the next response, if any. */
GetResponseSubset(msgIn, changedObjs, changedLinks, msgOut,
    responseObjs, responseLinks)

/* Add responseObjs to response. */
foreach o in responseObjs
  if DRS_GET_ANC in msgIn.ulFlags then
    /* Ancestors predicate: insert any changes to parent before any
     * changes to child. */
    foreach n in Ancestors of o.obj, most distant ancestor first
      anc := select one a from changedObjs where a.obj = n
      if anc ≠ null then
        err := AddObjToResponse(
          hDrs, anc, ncRoot, msgIn.ulFlags, 0, clientDSA, msgOut)
        if err ≠ 0 then
          return err
        endif
      endif
    endfor
  endif
  err := AddObjToResponse(
    hDrs, o, ncRoot, msgIn.ulFlags, 0, clientDSA, msgOut)
  if err ≠ 0 then 
    return err
  endif
endfor

/* Add responseLinks to response. */
foreach v in responseLinks
  if DRS_GET_ANC in msgIn.ulFlags then
    /* Ancestors predicate: insert any changes to object before any
     * changes to its link values. */
    anc := select one a from changedObjs where a.obj = v.obj
    if anc ≠ null then
      err := AddObjToResponse(hDrs, anc, ncRoot,
                       msgIn.ulFlags, 0, clientDSA, msgOut)
      if err ≠ 0 then
        return err
      endif
    endif
  endif
  if DRS_GET_TGT in msgIn.ulMoreFlags then
    /* Target predicate: insert any changes to the target object 
     * before any changes to the link value. */
    tgt := GetDSNameFromAttrVal(v.att, v.val)
    if DRS_GET_ANC in msgIn.ulFlags then
       /* Ancestors predicate: insert any changes to the ancestors of 
        * the target before any changes to the target. */
       foreach n in Ancestors of tgt, most distant ancestor first
         anc := select one a from changedObjs where a.obj = n
         if anc ≠ null then
           err := AddObjToResponse(hDrs, anc, ncRoot,
                            msgIn.ulFlags, 0, clientDSA, msgOut)
           if err ≠ 0 then
             return err
           endif
         endif
       endfor
    endif
    err := AddObjToResponse(hDrs, tgt, ncRoot,
                     msgIn.ulFlags, 0, clientDSA, msgOut)
    if err ≠ 0 then 
      return err
    endif
  endif
  AddLinkToResponse(v, msgIn, msgOut)
endfor

if not msgOut.fMoreData
  msgOut.pUpToDateVecSrc := The cycle goal, as specified in
      section 4.1.10.1.2.
endif

if DRS_GET_NC_SIZE in msgIn.ulFlags then
  msgOut.cNumNcSizeObjects := Approximate number of objects in
      NC replica msgIn.pNC^
  msgOut.cNumNcSizeValues := Approximate number of link values
      with stamps in NC replica msgIn.pNC^
endif

if (DRS_ADD_REF in msgIn.ulFlags and msgIn.uuidDsaObjDest ≠ NULLGUID) then
  /* Client has requested the server to add a repsTo entry. */
  updRefs.uuidDsaDes := msgIn.uuidDsaObjDest
  updRefs.pNC := msgIn.pNC^
  updRefs.pszDsaDest := NetworkAddress of DC corresponding to 
                        msgIn.uuidDsaObjDest
  updRefs.ulOptions := {DRS_ADD_REF, DRS_ASYNC_OP, 
                        DRS_GETCHG_CHECK} +
                       { msgIn.ulFlags ∩ {DRS_WRIT_REP, DRS_REF_GCSPN}}

  /* Using updRefs, perform repsTo add to the specified NC replica, 
   * the result value is a Windows error code or 0.
  err := UpdateRefs(updRefs^.V1) 
  if(err ≠ 0) then
     return err
  endif
endif

return 0
 
Did you find this helpful?
(1500 characters remaining)
Thank you for your feedback
Show:
© 2014 Microsoft. All rights reserved.