Partager via


4.1.1.2.2 CreateCrossRef

 procedure CreateCrossRef(
   hDrs: DRS_HANDLE,
   e: ENTINF,
   pmsgOut: ADDRESS OF DRS_MSG_ADDENTRYREPLY,
   ver: DWORD,
   info: ADDRESS OF ADDENTRY_REPLY_INFO): boolean

Informative summary of behavior: This procedure creates a crossRef object. If the crossRef object exists already in a disabled state, it will mark the crossRef object as enabled.

  
 ulSysFlags, err: DWORD
 ncNameV: DSName
 trustParentV, rootTrustV, dnsRootV: unicodestring
 cr: DSName
 prefixTable: PrefixTable
  
 /* Only attributes and classes in the base schema can be specified.*/
 prefixTable := NewPrefixTable()
  
 ulSysFlags := ENTINF_GetValue(e, systemFlags, prefixTable)
 ncNameV := ENTINF_GetValue(e, ncName, prefixTable)
  
 /* Check whether the crossRef object for the given ncName exists. */
 cr := select one v from subtree ConfigNC() 
     where v!ncName = ncNameV and crossRef in v!objectClass
  
 if (cr = null) or not (FLAG_CR_NTDS_DOMAIN in ulSysFlags) then
   if FLAG_CR_NTDS_NC in ulSysFlags then
     SetErrorData(SV_PROBLEM_WILL_NOT_PERFORM, serviceError, 
                  ERROR_DS_MISSING_EXPECTED_ATT, pmsgOut, ver)
     return false
   endif
  
   /* Add the crossRef object as a regular operation; this is subject
    * to an access check and will succeed only if the server is the
    * Partition Naming Master FSMO role owner. */
   err := PerformAddOperation(e, cr, dc.prefixTable, TRUE)
   if err ≠ 0 then
     /* Pick up the error information from the previous call. */
     SetErrorData(0, 0, 0, pmsgOut, ver)
     return false
   endif
  
   /* Set the systemFlags because PerformAddOperation does not set it.
    */
   cr!systemFlags := ulSysFlags
  
   /* Return the objectGUID of the new crossRef object. */
   info^.objGuid := cr.guid;
 else 
   /* crossRef already exists; enable it. */
  
   /* The crossRef is expected to be disabled. */
   if cr!enabled = null or cr!enabled = true then
     SetErrorData(SV_PROBLEM_DIR_ERROR,
                  serviceError,
                  ERROR_DUP_DOMAINNAME,
                  pmsgOut, ver)
     return false
   endif
  
   /* Only allow certain client IP to make the change. */
   if not (ClientIpMatch(hDrs, cr!dnsRoot)) then
     SetErrorData(SE_PROBLEM_INAPPROPRIATE_AUTH, securityError, 
         ERROR_DS_INTERNAL_FAILURE, pmsgOut, ver)
     return false
   endif
       
   /* dnsRoot must be set in the given ENTINF. */
   dnsRootV := ENTINF_GetValue(e, dnsRoot, prefixTable)
   if dnsRootV = null then
     SetErrorData(PR_PROBLEM_NO_ATTRIBUTE_OR_VAL, attributeError,
         ERROR_DS_MISSING_REQUIRED_ATT, pmsgOut, ver)
     return false
   endif
  
   cr!dnsRoot := dnsRootV
  
   /* Two more attributes can be set; the rest are ignored. */
   trustParentV := ENTINF_GetValue(e, trustParent, prefixTable)
   if trustParentV ≠ null then
     cr!trustParent := trustParentV
   endif
   rootTrustV := ENTINF_GetValue(e, rootTrust, prefixTable)
   if rootTrustV ≠ null then
     cr!rootTrust := rootTrustV
   endif
  
   /* Update the systemFlags and enable the crossRef. */
   cr!systemFlags := {FLAG_CR_NTDS_NC, FLAG_CR_NTDS_DOMAIN}
   cr!enabled := null
  
   /* return the guid of the crossRef object */
   info^.objGuid := cr.guid
 endif
  
 /*The cross ref was created/enabled. Ensure that the respective
   sub-ref object is created */
 AddSubRef(cr!ncName)
  
 return true