/* * Free a heap Attribute * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function; * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs' */ VOID VmDirFreeAttribute( PVDIR_ATTRIBUTE pAttr ) { if (!pAttr) { return; } // pAttr->type is always store in place and has NO bvnorm_val. no need to free here. if (!dequeIsEmpty(&pAttr->valueMetaDataToAdd)) { VmDirFreeAttrValueMetaDataDequeueContent(&pAttr->valueMetaDataToAdd); } if (!dequeIsEmpty(&pAttr->valueMetaDataToDelete)) { VmDirFreeAttrValueMetaDataDequeueContent(&pAttr->valueMetaDataToDelete); } VmDirFreeMetaData(pAttr->pMetaData); VmDirFreeBervalContent(&pAttr->type); VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals); VMDIR_SAFE_FREE_MEMORY(pAttr->vals); VMDIR_SAFE_FREE_MEMORY(pAttr); }
DWORD VmDirEntryAttributeRemoveValue( PVDIR_ATTRIBUTE pAttr, PCSTR pszValue ) { DWORD dwError = 0; DWORD dwCnt = 0; DWORD dwBervSize = 0; PVDIR_BERVALUE pNewBerv = NULL; if (!pAttr || !pszValue) { BAIL_WITH_VMDIR_ERROR(dwError, ERROR_INVALID_PARAMETER); } //Actual size of pAttr->vals size is pAttr->numVals+1 dwError = VmDirAllocateMemory(sizeof(VDIR_BERVALUE) * (pAttr->numVals), (PVOID*)&pNewBerv); BAIL_ON_VMDIR_ERROR(dwError); for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++) { if (VmDirStringCompareA(pszValue, pAttr->vals[dwCnt].lberbv_val, FALSE) != 0) { pNewBerv[dwBervSize] = pAttr->vals[dwCnt]; memset(pAttr->vals + dwCnt, 0, sizeof(VDIR_BERVALUE)); dwBervSize++; } } VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals); VMDIR_SAFE_FREE_MEMORY(pAttr->vals); pAttr->vals = pNewBerv; pAttr->numVals = dwBervSize; pNewBerv = NULL; cleanup: return dwError; error: VmDirFreeBervalArrayContent(pNewBerv, dwBervSize); VMDIR_SAFE_FREE_MEMORY(pNewBerv); VMDIR_LOG_ERROR(VMDIR_LOG_MASK_ALL, "failed, error (%d)", dwError); goto cleanup; }
void VmDirModificationFree( PVDIR_MODIFICATION pMod ) { if (pMod != NULL) { VmDirFreeBervalArrayContent( pMod->attr.vals, pMod->attr.numVals ); VMDIR_SAFE_FREE_MEMORY( pMod->attr.vals ); VMDIR_SAFE_FREE_MEMORY( pMod ); } }
/* * Free a heap Attribute * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function; * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs' */ VOID VmDirFreeAttribute( PVDIR_ATTRIBUTE pAttr ) { if (!pAttr) { return; } // pAttr->type is always store in place and has NO bvnorm_val. no need to free here. VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals); VMDIR_SAFE_FREE_MEMORY(pAttr->vals); VMDIR_SAFE_FREE_MEMORY(pAttr); }
/* * Free a heap Attribute * (ATTENTION: if the pAttr is within a pEntry, only when pEntry is constructed as * ENTRY_STORAGE_FORMAT_NORMAL allocation type, its attribute can be freed using this function; * otherwise, an entry's attribute free is taken care of by 'pEntry->bvs' */ VOID VmDirFreeAttribute( PVDIR_ATTRIBUTE pAttr ) { if (!pAttr) { return; } VmDirFreeBervalContent(&pAttr->type); VmDirFreeBervalArrayContent(pAttr->vals, pAttr->numVals); VMDIR_SAFE_FREE_MEMORY(pAttr->vals); VMDIR_SAFE_FREE_MEMORY(pAttr); }
/* * reorder value of objectclass in pOCAttr->vals * 1. structureOC->parentOC->parentOC->....->TOP(not included) * expand parent objectclass if not supplied. * 2. aux OCs * We then store its values in this order in backend. */ static DWORD _VmDirSchemaReorderObjectClassAttr( PVDIR_ATTRIBUTE pOCAttr, PVDIR_SCHEMA_OC_DESC pStructureOCDesc, PVDIR_SCHEMA_OC_DESC* ppAuxOCDesc) { DWORD dwError = 0; int iCnt = 0; int iAUXCnt = 0; int iTotal = 0; PVDIR_BERVALUE pBerv = NULL; PVDIR_SCHEMA_OC_DESC pLocalDesc = pStructureOCDesc; if ( !pOCAttr || !pStructureOCDesc ) { dwError = ERROR_INVALID_PARAMETER; BAIL_ON_VMDIR_ERROR(dwError); } // number of structure objectclass (except top) for (iCnt = 0; pLocalDesc != NULL; pLocalDesc = pLocalDesc->pStructSupOC, iCnt++) {} // number of aux objectclass for (iAUXCnt = 0; ppAuxOCDesc && ppAuxOCDesc[iAUXCnt] != NULL; iAUXCnt++) {}; iTotal = iCnt + iAUXCnt; dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * (iTotal + 1), (PVOID*)&pBerv); BAIL_ON_VMDIR_ERROR(dwError); // start with leaf structure objectclass and walk up the tree to top (NOT included) for (iCnt = 0, pLocalDesc = pStructureOCDesc; pLocalDesc != NULL; pLocalDesc = pLocalDesc->pStructSupOC, iCnt++) { PCSTR pszOrgName = NULL; unsigned int iTmp = 0; for (iTmp = 0; iTmp < pOCAttr->numVals; iTmp++) { if (VmDirStringCompareA( pLocalDesc->pszName, pOCAttr->vals[iTmp].lberbv_val, FALSE) == 0) { // keep whatever value provided from clients pszOrgName = pOCAttr->vals[iTmp].lberbv_val; break; } } dwError = VmDirAllocateStringA( pszOrgName ? pszOrgName : pLocalDesc->pszName, &(pBerv[iCnt].lberbv_val) ); BAIL_ON_VMDIR_ERROR(dwError); pBerv[iCnt].lberbv_len = VmDirStringLenA(pBerv[iCnt].lberbv_val); pBerv[iCnt].bOwnBvVal = TRUE; // TODO, Do we need to normalize value here? } // append aux objectclasses after structure objectclasses for (iAUXCnt = 0; ppAuxOCDesc && ppAuxOCDesc[iAUXCnt] != NULL; iAUXCnt++, iCnt++) { PCSTR pszOrgName = NULL; unsigned int iTmp = 0; for (iTmp = 0; iTmp < pOCAttr->numVals; iTmp++) { if (VmDirStringCompareA( ppAuxOCDesc[iAUXCnt]->pszName, pOCAttr->vals[iTmp].lberbv_val, FALSE) == 0) { // keep whatever value provided from clients pszOrgName = pOCAttr->vals[iTmp].lberbv_val; break; } } dwError = VmDirAllocateStringA( pszOrgName ? pszOrgName : ppAuxOCDesc[iAUXCnt]->pszName, &(pBerv[iCnt].lberbv_val) ); BAIL_ON_VMDIR_ERROR(dwError); pBerv[iCnt].lberbv_len = VmDirStringLenA(pBerv[iCnt].lberbv_val); pBerv[iCnt].bOwnBvVal = TRUE; // TODO, Do we need to normalize value here? } VmDirFreeBervalArrayContent( pOCAttr->vals, pOCAttr->numVals ); VMDIR_SAFE_FREE_MEMORY( pOCAttr->vals ); pOCAttr->vals = pBerv; pOCAttr->numVals = iTotal; cleanup: return dwError; error: VmDirFreeBervalArrayContent( pBerv, iTotal ); VMDIR_SAFE_FREE_MEMORY( pBerv ); goto cleanup; }
void VmDirFreeEntryContent( VDIR_ENTRY * e ) { VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: Begin" ); if ( e ) { VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: DN = %s", e ? (e->dn.lberbv.bv_val ? e->dn.lberbv.bv_val : "") : "" ); if (e->pParentEntry) { VmDirFreeEntryContent(e->pParentEntry); VMDIR_SAFE_FREE_MEMORY(e->pParentEntry); } VmDirFreeLDAPDNContent( &(e->ldapDN) ); VmDirFreeBervalContent( &(e->dn) ); VmDirFreeBervalContent( &(e->pdn) ); VmDirFreeBervalContent( &(e->newpdn) ); if (e->allocType == ENTRY_STORAGE_FORMAT_PACK) { PVDIR_ATTRIBUTE pCurrAttr = NULL; PVDIR_ATTRIBUTE pTempAttr = NULL; pCurrAttr = e->attrs; while(pCurrAttr != NULL) { pTempAttr = pCurrAttr->next; VmDirFreeMetaData(pCurrAttr->pMetaData); pCurrAttr = pTempAttr; } VMDIR_SAFE_FREE_MEMORY( e->encodedEntry ); VmDirFreeBervalArrayContent(e->bvs, e->usNumBVs); VMDIR_SAFE_FREE_MEMORY( e->bvs ); VMDIR_SAFE_FREE_MEMORY( e->savedAttrsPtr ); } else if (e->allocType == ENTRY_STORAGE_FORMAT_NORMAL) { VDIR_ATTRIBUTE * currAttr = NULL; VDIR_ATTRIBUTE * tmpAttr = NULL; VMDIR_SAFE_FREE_MEMORY( e->encodedEntry ); for (currAttr = e->attrs; currAttr != NULL; ) { tmpAttr = currAttr->next; VmDirFreeAttribute(currAttr); currAttr = tmpAttr; } } if (e->pComputedAttrs) { VDIR_ATTRIBUTE * currAttr = NULL; VDIR_ATTRIBUTE * tmpAttr = NULL; for (currAttr = e->pComputedAttrs; currAttr != NULL; ) { tmpAttr = currAttr->next; VmDirFreeAttribute(currAttr); currAttr = tmpAttr; } } VmDirSchemaCtxRelease(e->pSchemaCtx); VmDirAclCtxContentFree(e->pAclCtx); VMDIR_SAFE_FREE_MEMORY(e->pAclCtx); VMDIR_SAFE_FREE_MEMORY(e->pszGuid); memset(e, 0, sizeof(*e)); } VmDirLog( LDAP_DEBUG_TRACE, "DeleteEntry: End" ); }
/* * Tweak indices entry to append building flag to newly added values. * e.g. user add a new index attribute "myuid eq unique" * we want to save it as "myuid eq unique (buildingflag)" instead. */ DWORD VdirIndexingEntryAppendFlag( VDIR_MODIFICATION* pMods, PVDIR_ENTRY pEntry) { DWORD dwError = 0; DWORD dwCnt = 0; PSTR pszNewStr = NULL; PVDIR_ATTRIBUTE pAttr = NULL; assert(pMods && pEntry && pEntry->allocType == ENTRY_STORAGE_FORMAT_NORMAL); // unpack entry, so we can manipulate its contents. dwError = VmDirEntryUnpack(pEntry); BAIL_ON_VMDIR_ERROR(dwError); pAttr = VmDirFindAttrByName(pEntry, ATTR_INDEX_DESC); if (!pAttr) { dwError = ERROR_INVALID_ENTRY; BAIL_ON_VMDIR_ERROR(dwError); } for (dwCnt = 0; dwCnt < pAttr->numVals; dwCnt++) { DWORD iIdx = 0; for (iIdx = 0; iIdx < pMods->attr.numVals; iIdx++) { if (0 == VmDirStringCompareA(pAttr->vals[dwCnt].lberbv.bv_val, pMods->attr.vals[iIdx].lberbv.bv_val, FALSE)) { dwError = VmDirAllocateStringAVsnprintf( &pszNewStr, "%s %s", pAttr->vals[dwCnt].lberbv.bv_val, ATTR_INDEX_BUILDING_FLAG); BAIL_ON_VMDIR_ERROR(dwError); VmDirFreeBervalArrayContent(&pAttr->vals[dwCnt], 1); pAttr->vals[dwCnt].lberbv.bv_val = pszNewStr; pszNewStr = NULL; pAttr->vals[dwCnt].bOwnBvVal = TRUE; pAttr->vals[dwCnt].lberbv.bv_len = VmDirStringLenA(pAttr->vals[dwCnt].lberbv.bv_val); dwError = VmDirSchemaBervalNormalize( pEntry->pSchemaCtx, pAttr->pATDesc, &pAttr->vals[dwCnt]); BAIL_ON_VMDIR_ERROR(dwError); } } } cleanup: return dwError; error: VMDIR_SAFE_FREE_MEMORY(pszNewStr); goto cleanup; }
void VmDirSendLdapReferralResult( VDIR_OPERATION * op, PCSTR pszRefSuffix, PBOOLEAN pbRefSent ) { DWORD dwError = 0; BerElementBuffer berbuf; BerElement * ber = (BerElement *) &berbuf; ber_int_t msgId = 0; PCSTR pszSocketInfo = NULL; PSTR pszLeader = NULL; PSTR pszRef = NULL; PVDIR_BERVALUE pBerv = NULL; BOOLEAN bIsLdaps = FALSE; *pbRefSent = FALSE; (void) memset( (char *)&berbuf, '\0', sizeof( BerElementBuffer )); msgId = op->msgId; ber_init2( ber, NULL, LBER_USE_DER ); if (op->conn) { pszSocketInfo = op->conn->szClientIP; } dwError = VmDirRaftGetLeader(&pszLeader); BAIL_ON_VMDIR_ERROR(dwError); if (pszLeader == NULL) { //server self is a raft leader or leader cannot determined (e.g. in voting stage). goto done; } if (op->conn->dwServerPort == VmDirGetLdapsPort()) { bIsLdaps = TRUE; } dwError = VmDirAllocateStringPrintf(&pszRef, "%s://%s/%s", bIsLdaps ? "ldaps":"ldap", pszLeader, pszRefSuffix ); BAIL_ON_VMDIR_ERROR(dwError); op->ldapResult.errCode = 0; if ((op->reqCode == LDAP_REQ_SEARCH && gVmdirGlobals.dwEnableRaftReferral & VMDIR_RAFT_SEARCH_REFERRAL_ERROR_CODE) || ((op->reqCode == LDAP_REQ_ADD || op->reqCode == LDAP_REQ_DELETE || op->reqCode == LDAP_REQ_MODIFY || op->reqCode == LDAP_REQ_MODDN) && gVmdirGlobals.dwEnableRaftReferral & VMDIR_RAFT_ENABLE_UPDATE_ERROR_CODE)) { op->ldapResult.errCode = LDAP_REFERRAL; } dwError = VmDirAllocateMemory( sizeof(VDIR_BERVALUE) * 2, (PVOID*)&pBerv); BAIL_ON_VMDIR_ERROR(dwError); pBerv[0].lberbv_len = VmDirStringLenA(pszRef); pBerv[0].lberbv_val = pszRef; pBerv[0].bOwnBvVal = TRUE; pBerv[1].lberbv_val = NULL; pBerv[1].lberbv_len = 0; dwError = ber_printf(ber, "{it{W}N}{it{ess}N}", msgId, LDAP_RES_SEARCH_REFERENCE, pBerv, msgId, GetResultTag(op->reqCode), op->ldapResult.errCode, "", ""); BAIL_ON_LBER_ERROR(dwError); dwError = WriteBerOnSocket( op->conn, ber ); BAIL_ON_VMDIR_ERROR(dwError); *pbRefSent = TRUE; VMDIR_LOG_INFO(VMDIR_LOG_MASK_ALL, "VmDirSendLdapReferralResult: sent with referral %s", pszRef); done: ber_free_buf( ber ); VmDirFreeBervalArrayContent(pBerv, 1); VMDIR_SAFE_FREE_MEMORY(pBerv); VMDIR_SAFE_FREE_MEMORY(pszLeader); return; error: goto done; }