Export (0) Print
Expand All

4.1.10.5 Server Behavior of the IDL_DRSGetNCChanges Method

Informative summary of behavior: The IDL_DRSGetNCChanges method returns a response for a single request in a cycle.

This method is invoked through the drsuapi RPC interface. It is also invoked as a local procedure for requests that are received using the SMTP transport ([MS-SRPL]).

ULONG
IDL_DRSGetNCChanges(
    [in, ref] DRS_HANDLE hDrs,
    [in] DWORD dwInVersion,
    [in, ref, switch_is(dwInVersion)]
        DRS_MSG_GETCHGREQ *pmsgIn,
    [out, ref] DWORD *pdwOutVersion,
    [out, ref, switch_is(*pdwOutVersion)]
        DRS_MSG_GETCHGREPLY *pmsgOut)

err: ULONG
msgIn: DRS_MSG_GETCHGREQ_V10
ncRoot: DSName
obj: DSName
msgOut: DRS_MSG_GETCHGREPLY_V6
schemaSignature: sequence of BYTE
prefixEntry: PrefixTableEntry
responseSmtpAddress: unicodestring
fullReplicaFlags: set of integer
fullReplicaRequest : boolean

ValidateDRSInput(hDrs, 3)

pdwOutVersion^ := 1
pmsgOut^ := 0

err := TransformInput(hDrs, dwInVersion, pmsgIn^, msgIn,
    pdwOutVersion, responseSmtpAddress)
if err ≠ 0 then
  return err
endif

/* Perform access checks. */
if msgIn.pNC = null then
  return ERROR_DS_DRA_INVALID_PARAMETER
endif
ncRoot := GetObjectNC(msgIn.pNC^)

if ncRoot = null then
  return ERROR_DS_CANT_FIND_EXPECTED_NC
endif

if IsGetNCChangesPermissionGranted(msgIn) == FALSE then
  return ERROR_DRA_ACCESS_DENIED
endif

/* Validate inputs. */
obj := msgIn.pNC^
if AmILHServer() = false then  
  /* Downlevel OS does not understand
     DRS_SPECIAL_SECRET_PROCESSING flags. They just ignore it.
   */
  msgIn.ulFlags := msgIn.ulFlags - {DRS_SPECIAL_SECRET_PROCESSING}
endif

if msgIn.ulExtendedOp = 0 then
  /* Validate normal replication request. */
  if not FullReplicaExists(obj) and not PartialGCReplicaExists(obj) 
      then
    return ERROR_DS_CANT_FIND_EXPECTED_NC
  endif
else
  /* Validate extended operation request. */
  if not ObjExists(obj) then
    return ERROR_DS_CANT_FIND_EXPECTED_NC
  endif
endif

if AmILHServer() then 
  if (msgIn.pPartialAttrSet = null and
      msgIn.pPartialAttrSetEx = null) then
    fullReplicaRequest := true
  else
    fullReplicaRequest := false
  endif
else
  if (DRS_WRITE_REP in msgIn.ulFlags) then
    fullReplicaRequest := true
  else
    fullReplicaRequest := false
  endif
endif

if (fullReplicaRequest) then
  /* Validate Full Replica request. */
  if not IT_WRITE in obj!instanceType then
    return ERROR_DRA_SOURCE_IS_PARTIAL
  endif
  if DRS_SYNC_PAS in msgIn.ulFlags then
    return ERROR_INVALID_PARAMETER
  endif
else
  /* Validate Partial Replica request. */
  if msgIn.pPartialAttrSet = null
      or msgIn.pPartialAttrSet.cAttrs = 0 then
    return ERROR_INVALID_PARAMETER
  endif
  if DRS_SYNC_PAS in msgIn.ulFlags and
      (msgIn.pPartialAttrSetEx = null
          or msgIn.pPartialAttrSetEx.cAttrs = 0) then
    return ERROR_INVALID_PARAMETER
  endif
  if msgIn.PrefixTableDest.PrefixCount = 0 then
    return ERROR_INVALID_PARAMETER
  endif
endif

if IT_NC_GOING in ncRoot!instanceType
  /* NC replica is no longer accepting requests. */
  return ERROR_DRA_NO_REPLICA
endif

if msgIn.uuidInvocIdSrc ≠ DSAObj()!invocationId then
  msgIn.usnvecFrom := 0
endif

/* Construct response. */
if msgIn.ulExtendedOp = 0 then
  /* Perform normal replication. */
  err := GetReplChanges(hDrs, null, null, msgIn, msgOut)

else
  /* Perform extended operation. Errors are returned in
   * msgOut.ulExtendedErr. */
  ProcessFsmoRoleRequest(hDrs, msgIn, msgOut)
  err := 0
endif
if err = 0 then
  msgOut.pNC := msgIn.pNC
  msgOut.usnvecFrom := msgIn.usnvecFrom
  msgOut.uuidDsaObjSrc := dc.serverGuid
  msgOut.PrefixTableSrc := ConcretePTFromAbstractPT(dc.prefixTable)
  msgOut.uuidInvocIdSrc := DSAObj()!invocationId

  /* Sort msgOut.rgValues into ascending order. */
  SortResponseLinks(msgOut)
  
  /* Add schema signature to msgOut.PrefixTableSrc. */
  schemaSignature := SchemaNC()!schemaInfo
  prefixEntry.ndx := 0
  prefixEntry.prefix.length := schemaSignature.length
  prefixEntry.prefix.element := elements of schemaSignature
  Append prefixEntry to msgOut.PrefixTableSrc.pPrefixEntry
  msgOut.PrefixTableSrc.PrefixCount :=
      msgOut.PrefixTableSrc.PrefixCount+1

  err := TransformOutput(msgOut, msgIn.ulFlags, pdwOutVersion^,
                         pmsgOut)
endif

if responseSmtpAddress ≠ null then
  Send the response using using the SMTP transport to
      responseSmtpAddress
endif

return err
 
Show:
© 2014 Microsoft