4.1.20.2 Server Behavior of the IDL_DRSReplicaDel Method

Informative summary of behavior: When DRS_NO_SOURCE is not specified, the server removes a value from the repsFrom of the specified NC replica. If ulOptions contains DRS_ASYNC_OP, the server processes the request asynchronously. The client has to include DRS_WRIT_REP in ulOptions if the specified NC replica is a writable replica. The server removes the value from repsFrom whose serverAddress matches pszDsaSrc. If ulOptions does not contain DRS_LOCAL_ONLY, the server sends a request to the DC specified by pszDsaSrc to remove this DC from the values in repsTo of the specified NC replica by calling IDL_DRSUpdateRefs.

When DRS_NO_SOURCE is specified, the server expunges the NC replica and all its children. This operation returns an error and the expunge does not occur if the repsFrom or repsTo attributes are present on the NC replica. However, if ulOptions contains DRS_REF_OK, it is permitted for repsTo to be present. If ulOptions contains DRS_ASYNC_OP, the server processes the request asynchronously. The client has to include DRS_WRIT_REP in ulOptions if the specified NC replica is writable. If ulOptions contains DRS_ASYNC_REP, the server expunges the objects asynchronously.

 ULONG
 IDL_DRSReplicaDel(
   [in, ref] DRS_HANDLE hDrs,
   [in] DWORD dwVersion,
   [in, ref, switch_is(dwVersion)] DRS_MSG_REPDEL *pmsgDel);
  
 options: DRS_OPTIONS
 nc: DSName
 cr: DSName
 srcDSA: DSName
 hDrsSrc: DRS_HANDLE
 rf: RepsFrom
 msgIn: DRS_MSG_REPDEL_V1
 updRefs: DRS_MSG_UPDREFS /* See IDL_DRSUpdateRefs structures. */
 rt: ULONG
  
 ValidateDRSInput(hDrs, 6)
  
 msgIn := pmsgDel^.V1
  
 /* Validate the NC */
 if msgIn.pNC = null then
   return ERROR_DS_DRA_INVALID_PARAMETER
 endif
  
 nc := msgIn.pNC^
  
 if not ObjExists(nc) then
   return ERROR_DS_DRA_BAD_NC
 endif
  
 if not AccessCheckCAR(nc, DS-Replication-Manage-Topology) then
   return ERROR_DS_DRA_ACCESS_DENIED
 endif
  
 options := msgIn.ulOptions
  
 /* Any request that includes invalid options is rejected. */ 
 if options - {DRS_ASYNC_OP, DRS_WRIT_REP, DRS_MAIL_REP,DRS_ASYNC_REP, 
     DRS_IGNORE_ERROR, DRS_LOCAL_ONLY, DRS_NO_SOURCE, DRS_REF_OK} ≠ {} then
   return ERROR_DS_DRA_INVALID_PARAMETER
 endif
  
 if DRS_NO_SOURCE in options then
   /* Expunging local copy of an NC. */
  
   /* Do not permit removal of nonroot or uninstantiated NCs. */
   if (IT_NC_HEAD not in nc!instanceType or
       IT_UNINSTANT in nc!instanceType) then
     return ERROR_DS_DRA_BAD_NC
   endif
  
   /* NC must not replicate from any other DC. */
   if (select one v from nc!repsFrom where (true)) ≠ null then
     return ERROR_DS_DRA_INVALID_PARAMETER
   endif
  
   /* NC must not replicate to any other DC. */
   if (select one v from nc!repsTo where (true)) ≠ null
      and (not DRS_REF_OK in options) then
     return ERROR_DS_DRA_OBJ_IS_REP_SOURCE
   endif
  
   /* Do not permit removal of important NCs. */
   if IT_WRITE in nc!instanceType
      and (nc = DefaultNC()
           or nc = ConfigNC()
           or nc = SchemaNC()) then
     return ERROR_DS_DRA_INVALID_PARAMETER
   endif
  
   if DRS_ASYNC_REP in options then
     Asynchronous Processing: Initiate a logical thread of control
      to process the remainder of this request asynchronously
     return 0
   endif
  
   /* Expunge the subtree rooted at dn and pertaining to the same NC.
    * If the subtree includes a sub-ref object for a locally instantiated NC,
    * remove the IT_NC_ABOVE flag from the sub-ref object instanceType
    * attribute.
    *
    */
   foreach o in (select all v from subtree nc where GetObjectNC(v) = nc)
     if(IT_NC_HEAD in o!instanceType and
        IT_UNINSTANT not in o!instanceType) then
        o!instanceType = o!instanceType – {IT_NC_ABOVE}
     else
        Expunge(o)
     endif
   endfor
  
   /* If the root of the NC being expunged is a sub-ref object itself, then it
    * might need to be preserved.
   */
  
   /* Check whether there is stil a crossref object for the given nc. */
   cr := select one v from subtree ConfigNC() 
      where v!ncName = nc and crossRef in v!objectClass
  
   if(cr == NULL)
      if(IT_NC_ABOVE in nc!instanceType) then
         nc!instanceType = {IT_NC_ABOVE, IT_UNINSTANT,IT_NC_HEAD}
      endif
      rt := RemoveObj(nc,false)
      if rt ≠ 0 then
         return rt
      endif
   else
      if(IT_NC_ABOVE in nc!instanceType) then
         nc!instanceType = {IT_NC_ABOVE, IT_UNINSTANT,IT_NC_HEAD}
      else
         Expunge(nc)
      endif
    endif
  
   return 0
  
 else /* not DRS_NO_SOURCE in options */
   /* Removing a single source from repsFrom, but leaving NC replica
    * on DC. */
  
   if msgIn.pszDsaSrc = null or
   msgIn.pszDsaSrc^ = "" or
   (IsAdlds() and
   GetDSNameFromNetworkAddress(msgIn.pszDsaSrc^) = null) then
     return ERROR_DS_DRA_INVALID_PARAMETER
   endif
  
   if DRS_ASYNC_OP in options then
      Asynchronous Processing: Initiate a logical thread of control
      to process the remainder of this request asynchronously
     return 0
   endif
  
   rf := select one v from nc!repsFrom
         where (v.serverAddress = msgIn.pszDsaSrc)
   if rf = null then
     return ERROR_DS_DRA_NO_REPLICA
   endif
   nc!repsFrom := nc!repsFrom - {rf}
  
   if (not DRS_LOCAL_ONLY in options)
      and (not DRS_MAIL_REP in rf.options) then
     /* Disable replication notifications by requesting the server DC
      * specified by msgIn.pszDsaSrc to remove this DC
      * from its repsTo. */
     updRefs.pNC^ := ADR(nc)
     updRefs.pszDsaDest := NetworkAddress of this DC
     updRefs.uuidDsaDest := dc.serverGuid
     updRefs.ulOptions := {DRS_ASYNC_OP, DRS_DEL_REF}
     if DRS_WRIT_REP in msgIn.ulOptions then
       updRefs.ulOptions := updRefs.ulOptions + {DRS_WRIT_REP}
     endif
     srcDSA := GetDSNameFromNetworkAddr(msgnIn.pszDsaSrc)
     hDrsSrc := BindToDSA(srcDSA)
     if hDrsSrc ≠ null then
       ret := IDL_DRSUpdateRefs(hDrsSrc, 1, ADR(updRefs))
       UnbindFromDSA(hDrsSrc)
     endif
  
  
   endif
   return 0
 endif