4.1.7.3 Server Behavior of the IDL_DRSFinishDemotion Method

Informative summary of behavior: The IDL_DRSFinishDemotion method either performs one or more steps toward the complete removal of a DC from an AD LDS forest, or it undoes the effects of the first phase of removal (performed by IDL_DRSInitDemotion).<16>

 ULONG
 IDL_DRSFinishDemotion(
     [in, ref] DRS_HANDLE hDrs,
     [in] DWORD dwInVersion,
     [in, ref, switch_is(dwInVersion)] 
         DRS_MSG_FINISH_DEMOTIONREQ* pmsgIn,
     [out, ref] DWORD *pdwOutVersion,
     [out, ref, switch_is(*pdwOutVersion)] 
         DRS_MSG_FINISH_DEMOTIONREPLY* pmsgOut
     )
  
 msgIn: DRS_MSG_FINISH_DEMOTIONREQ_V1
 msgOut: DRS_MSG_FINISH_DEMOTIONREPLY_V1
 ret: DWORD
 res: boolean
  
 ValidateDRSInput(hDrs, 27)
  
 if dwInVersion ≠ 1 then
   return ERROR_INVALID_PARAMETER
 endif
  
 if pmsgIn = null then
   return ERROR_INVALID_PARAMETER
 endif
  
 msgIn := pmsgIn^.V1
 if DS_DEMOTE_OPT_FAIL_ON_UNKNOWN_OP in msgIn.dwOperations then
   /* unknown operation bit is set */
   return ERROR_INVALID_PARAMETER
 endif
 if DS_DEMOTE_UNREGISTER_SPNS in msgIn.dwOperations
     and msgIn.szScriptBase = null then
   /* szScriptBase must be specified when UNREGISTER_SPN is
    * requested */
   return ERROR_INVALID_PARAMETER
 endif
 if not IsMemberOfBuiltinAdminGroup() then
   /* only BA is allowed to demote an AD LDS service */
   return ERROR_DS_DRA_ACCESS_DENIED
 endif
  
 pdwOutVersion^ := 1
 msgOut.dwOperationDone := 0
 msgOut.dwOpFailed := 0
 msgOut.dwOpError := ERROR_SUCCESS
  
 if DS_DEMOTE_ROLLBACK_DEMOTE in msgIn.dwOperations then
   /* Begin operations corresponding to dwOperations value of DS_DEMOTE_ROLLBACK_DEMOTE */
  
   /* undo the effects of IDL_DRSInitDemotion */
  
   dc.fEnableUpdates := TRUE
  
   msgOut.dwOperationDone := 
       msgOut.dwOperationDone + {DS_DEMOTE_ROLLBACK_DEMOTE}    
  
   msgOut.dwOpError := ERROR_SUCCESS
   /* no other operations are allowed on rollback */
   /* End operations corresponding to dwOperations value of DS_DEMOTE_ROLLBACK_DEMOTE */
  
 else
   if DS_DEMOTE_COMMIT_DEMOTE in msgIn.dwOperations then
   /* Begin operations corresponding to dwOperations value of DS_DEMOTE_COMMIT_DEMOTE */
     
     After this call to IDL_DRSFinishDemotion completes, the server must discontinue being a DC, which for AD LDS means stopping the MS-DRSR protocol, the MS-DSSP protocol, the LDAP protocol, and if they are already enabled also the MS-ADCAP protocol, the WS-Enumeration protocol, the WS-Transfer protocol, the MS-WSTIM protocol, the MS-WSDS protocol, and the MS-WSPELD protocol.  In addition, the state model, constraints and processing rules, and so on, in MS-ADTS must also be stopped.
  
       msgOut.dwOperationDone := 
         msgOut.dwOperationDone + {DS_DEMOTE_COMMIT_DEMOTE}
     
     msgOut.dwOpError := ERROR_SUCCESS
   /* End operations corresponding to dwOperations value of DS_DEMOTE_COMMIT_DEMOTE */
   endif
   if DS_DEMOTE_DELETE_CSMETA in msgIn.dwOperations then
   /* Begin operations corresponding to dwOperations value of DS_DEMOTE_DELETE_CSMETA */
  
     ret := RemoveADLDSServer()
     if ret = ERROR_SUCCESS then
       msgOut.dwOperationDone := 
         msgOut.dwOperationDone + {DS_DEMOTE_DELETE_CSMETA}
     else
       msgOut.dwOpFailed = 
         msgOut.dwOpFailed + {DS_DEMOTE_DELETE_CSMETA}
       if msgOut.dwOpError = ERROR_SUCCESS then
         msgOut.dwOpError := ret
       endif
     endif
   /* End operations corresponding to dwOperations value of DS_DEMOTE_DELETE_CSMETA */
   endif
   if DS_DEMOTE_UNREGISTER_SCPS in msgIn.dwOperations then
   /* Begin operations corresponding to dwOperations value of DS_DEMOTE_UNREGISTER_SCPS */
     ret := RemoveADLDSSCP()
     if ret = ERROR_SUCCESS then
       msgOut.dwOperationDone := 
         msgOut.dwOperationDone + {DS_DEMOTE_UNREGISTER_SCPS}
     else
       msgOut.dwOpFailed = 
         msgOut.dwOpFailed + {DS_DEMOTE_UNREGISTER_SCPS}
       if msgOut.dwOpError = ERROR_SUCCESS then
         msgOut.dwOpError := ret
       endif
     endif
   /* End operations corresponding to dwOperations value of DS_DEMOTE_UNREGISTER_SCPS */
   endif
   if DS_DEMOTE_UNREGISTER_SPNS in msgIn.dwOperations then
   /* Begin operations corresponding to dwOperations value of DS_DEMOTE_UNREGISTER_SPNS */
     res := RemoveADLDSSPNs(msgIn.szScriptBase)
     if res = TRUE then
       msgOut.dwOperationDone := 
         msgOut.dwOperationDone + {DS_DEMOTE_UNREGISTER_SPNS}
     else
       msgOut.dwOpFailed = 
         msgOut.dwOpFailed + {DS_DEMOTE_UNREGISTER_SPNS}
     endif
   /* End operations corresponding to dwOperations value of DS_DEMOTE_UNREGISTER_SPNS */
   endif
 endif
 pmsgOut^ := msgOut
 pdwMsgOut^ := 1
 return ERROR_SUCCESS