4.1.30.3 Server Behavior of the IDL_DRSWriteNgcKey Method

Informative summary of behavior: The IDL_DRSWriteNgcKey method sets the msDS-KeyCredentialLink attribute of an object. The IDL_DRSWriteNgcKey method replaces any existing msDS-KeyCredentialLink attributes on the object with a new value. In this new value, the DN portion is the portion set to the account and the binary portion is set to a KEYCREDENTIALLINK_BLOB with the following KEYCREDENTIALLINK_ENTRY entries set. (See [MS-ADTS] section 2.2.20 for structures and constants.)

  • KeyID – Value set to a SHA256 hash of the pNgcKey.

  • KeyHash – Value set as defined in [MS-ADTS] section 2.2.20.6.

  • KeyMaterial – Value set to the pNgcKey array.

  • KeyUsage  - Value set to KEY_USAGE_NGC.

  • KeySource – Value set to KEY_SOURCE_AD.

  • KeyApproximateLastLogonTimeStamp – Value set to the current time.

  • KeyCreationTime – Value set to the current time.

The effect of this method can be achieved by an LDAP Modify operation to the msDS-KeyCredentialLink attribute of an object.

 ULONG IDL_DRSWriteNgcKey(
   [in, ref] DRS_HANDLE hDrs,
   [in] DWORD dwInVersion,
   [in, ref, switch_is(dwInVersion)] 
     DRS_MSG_WRITENGCKEYREQ* pmsgIn,
   [out, ref] DWORD* pdwOutVersion,
   [out, ref, switch_is(*pdwOutVersion)] 
     DRS_MSG_WRITENGCKEYREPLY* pmsgOut);
  
 accountDN: unicodestring
 account: DSName
 keyValue : array of UCHAR
 err: DWORD
 key: DNBinary
  
 ValidateDRSInput(hDrs, 29)
  
 pdwOutVersion^ := 1
 pmsgOut^.V1.retVal := 0
  
 /* Input parameter validation */
 if dwInVersion ≠ 1 then
   pmsgOut^.V1.retVal := ERROR_INVALID_PARAMETER
   return ERROR_INVALID_PARAMETER
 endif
  
 /* Input parameter validation */
 if ClientUUID(hDrs) ≠ NTDSAPI_CLIENT_GUID
   pmsgOut^.V1.retVal := ERROR_INVALID_PARAMETER
   return ERROR_INVALID_PARAMETER
 endif
  
 accountDN := pmsgIn^.V1.pwszAccount
 keyValue := pmsgIn^.V1.pNgcKey
  
 if accountDN = null or accountDN = "" then
   pmsgOut^.V1.retVal := ERROR_INVALID_PARAMETER
   return ERROR_INVALID_PARAMETER
 endif
  
 account := GetDSNameFromDN(accountDN);
 if not ObjExists(account) then
   pmsgOut^.V1.retVal := ERROR_DS_OBJ_NOT_FOUND
   return ERROR_DS_OBJ_NOT_FOUND
 endif
  
 /* Perform access checks */
 err = AccessCheckWriteToKeyCredentialLinkAttribute(account, true)
 if err ≠ ERROR_SUCCESS then
   pmsgOut^.V1.retVal := err
   return err
 endif
 key := ComposeKeyCredentialLinkForComputer(account, keyValue);
 account!msDS-KeyCredentialLink := key
  
 return 0