//Add one more single value replace mod onto the LdapOp's mods DWORD VmDirAddModSingleAttributeReplace( PVDIR_OPERATION pLdapOp, PCSTR pszNormDN, PCSTR pszAttrName, PVDIR_BERVALUE pBervAttrValue ) { DWORD dwError = 0; PVDIR_MODIFICATION pMod = NULL; if (!pszNormDN || !pszAttrName || !pBervAttrValue) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } pLdapOp->reqDn.lberbv.bv_val = (PSTR)pszNormDN; pLdapOp->reqDn.lberbv.bv_len = VmDirStringLenA(pszNormDN); dwError = VmDirAllocateMemory(sizeof(*pMod)*1, (PVOID)&pMod); BAIL_ON_VMDIR_ERROR(dwError); pMod->operation = MOD_OP_REPLACE; dwError = VmDirModAddSingleValueAttribute( pMod, pLdapOp->pSchemaCtx, pszAttrName, pBervAttrValue->lberbv.bv_val, pBervAttrValue->lberbv.bv_len); BAIL_ON_VMDIR_ERROR(dwError); pLdapOp->request.modifyReq.dn.lberbv.bv_val = (PSTR)pszNormDN; pLdapOp->request.modifyReq.dn.lberbv.bv_len = VmDirStringLenA(pszNormDN); pMod->next = pLdapOp->request.modifyReq.mods; pLdapOp->request.modifyReq.mods = pMod; pLdapOp->request.modifyReq.numMods++; pMod = NULL; cleanup: if (pMod) { VmDirModificationFree(pMod); } return dwError; error: goto cleanup; }
void DeleteMods( ModifyReq * modReq) { VDIR_MODIFICATION * currMod = NULL; VDIR_MODIFICATION * tmpMod = NULL; for (currMod = modReq->mods; currMod != NULL; ) { tmpMod = currMod->next; VmDirModificationFree(currMod); currMod = tmpMod; } modReq->numMods = 0; }
/* * Add a ModifyRequest to pOperation with- * 1. modOp * 2. create attribute with values from pBerValue * * i.e. this function call is equivalent of a modify section in LDIF file * changetype: modify * add/delete/replace: attributeXYZ <<<<<<<<<<<<<<<< modOp * attributeXYZ: value1 <<<<<<<<<<<<<<<<<<<<<<<<<<<<< pBervalue * attributeXYZ: valueN <<<<<<<<<<<<<<<<<<<<<<<<<<<<< iBerValueSize */ DWORD VmDirOperationAddModReq( PVDIR_OPERATION pOperation, int modOp, char * pszAttrName, PVDIR_BERVALUE pBerValue, size_t iBerValueSize ) { DWORD dwError = 0; PSTR pszLocalErrMsg = NULL; VDIR_MODIFICATION * pMod = NULL; ModifyReq * pModReq = &(pOperation->request.modifyReq); size_t iCnt = 0; if ( !pOperation || !pszAttrName || !pBerValue ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirAllocateMemory( sizeof( *pMod ), (PVOID *)&(pMod) ); BAIL_ON_VMDIR_ERROR( dwError ); pMod->operation = modOp; pMod->attr.next = NULL; pMod->attr.pATDesc = VmDirSchemaAttrNameToDesc( pOperation->pSchemaCtx, pszAttrName); if ( !pMod->attr.pATDesc ) { dwError = ERROR_NO_SUCH_ATTRIBUTE; BAIL_ON_VMDIR_ERROR_WITH_MSG( dwError, pszLocalErrMsg, "attibute (%s) not defined", pszAttrName ); } // attribute.type.lberbv use (schema cache) inplace memory (we don't fee it). pMod->attr.type.lberbv.bv_val = pMod->attr.pATDesc->pszName; pMod->attr.type.lberbv.bv_len = VmDirStringLenA(pMod->attr.pATDesc->pszName); dwError = VmDirAllocateMemory( sizeof( VDIR_BERVALUE ) * (iBerValueSize + 1 ), (PVOID *)&(pMod->attr.vals) ); BAIL_ON_VMDIR_ERROR( dwError ); for (iCnt = 0; iCnt < iBerValueSize; iCnt++) { dwError = VmDirAllocateAndCopyMemory( pBerValue[iCnt].lberbv_val, pBerValue[iCnt].lberbv_len, (PVOID *)&(pMod->attr.vals[iCnt].lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); pMod->attr.vals[iCnt].lberbv.bv_len = pBerValue[iCnt].lberbv_len; pMod->attr.vals[iCnt].bOwnBvVal = TRUE; pMod->attr.numVals++; } pMod->next = pModReq->mods; pModReq->mods = pMod; // pOpeartion->request.modifyRequest takes over pMod pModReq->numMods++; cleanup: VMDIR_SAFE_FREE_MEMORY(pszLocalErrMsg); return dwError; error: if (pMod) { VmDirModificationFree( pMod ); } VMDIR_SET_LDAP_RESULT_ERROR( &(pOperation->ldapResult), dwError, pszLocalErrMsg ); goto cleanup; }
/* * Convenient function to replace ONE single value attribute via InternalModifyEntry * ***************************************************************************** * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING * You should NOT call this function while in a backend txn/ctx. * ***************************************************************************** * This may not be easy to determine as we could call this in different places, which * may be nested in external and internal OPERATION. * A better approach is to pass in pOperation and use the same beCtx if exists. * However, this could also cause logic error, e.g. you could lost track if entry/data * has already been changed by beCtx and reread them. * ***************************************************************************** */ DWORD VmDirInternalEntryAttributeReplace( PVDIR_SCHEMA_CTX pSchemaCtx, PCSTR pszNormDN, PCSTR pszAttrName, PVDIR_BERVALUE pBervAttrValue ) { DWORD dwError = 0; VDIR_OPERATION ldapOp = {0}; PVDIR_MODIFICATION pMod = NULL; if (!pszNormDN || !pszAttrName || !pBervAttrValue) { dwError = VMDIR_ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } dwError = VmDirInitStackOperation( &ldapOp, VDIR_OPERATION_TYPE_INTERNAL, LDAP_REQ_MODIFY, pSchemaCtx); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.pBEIF = VmDirBackendSelect(pszNormDN); assert(ldapOp.pBEIF); ldapOp.reqDn.lberbv.bv_val = (PSTR)pszNormDN; ldapOp.reqDn.lberbv.bv_len = VmDirStringLenA(pszNormDN); dwError = VmDirAllocateMemory(sizeof(*pMod)*1, (PVOID)&pMod); BAIL_ON_VMDIR_ERROR(dwError); pMod->next = NULL; pMod->operation = MOD_OP_REPLACE; dwError = VmDirModAddSingleValueAttribute( pMod, ldapOp.pSchemaCtx, pszAttrName, pBervAttrValue->lberbv.bv_val, pBervAttrValue->lberbv.bv_len); BAIL_ON_VMDIR_ERROR(dwError); ldapOp.request.modifyReq.dn.lberbv.bv_val = (PSTR)pszNormDN; ldapOp.request.modifyReq.dn.lberbv.bv_len = VmDirStringLenA(pszNormDN); ldapOp.request.modifyReq.mods = pMod; pMod = NULL; ldapOp.request.modifyReq.numMods = 1; dwError = VmDirInternalModifyEntry(&ldapOp); BAIL_ON_VMDIR_ERROR(dwError); cleanup: VmDirFreeOperationContent(&ldapOp); if (pMod) { VmDirModificationFree(pMod); } return dwError; error: goto cleanup; }