/* MdbDeleteEntry: Deletes an entry in the MDB DBs. * * Returns: BE error codes. * */ DWORD VmDirMDBDeleteEntry( PVDIR_BACKEND_CTX pBECtx, PVDIR_MODIFICATION pMods, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; VDIR_MODIFICATION * mod = NULL; PVDIR_DB_TXN pTxn = NULL; assert( pBECtx && pBECtx->pBEPrivate && pMods && pEntry ); pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate; // Delete child from the parentId index dwError = MDBDeleteParentIdIndex( pBECtx, &(pEntry->pdn), pEntry->eId ); BAIL_ON_VMDIR_ERROR(dwError); for (mod = pMods; mod != NULL; mod = mod->next) { switch (mod->operation) { case MOD_OP_DELETE: if ((dwError = MdbUpdateIndicesForAttr( pBECtx->pBE, pTxn, &(pEntry->dn), &(mod->attr.type), mod->attr.vals, mod->attr.numVals, pEntry->eId, BE_INDEX_OP_TYPE_DELETE )) != 0) { dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); } break; default: assert( FALSE ); } } // Delete Entry Blob if ((dwError = MDBDeleteEntryBlob(pBECtx, pEntry->eId)) != 0) { dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "MDBDeleteEntryBlob"); BAIL_ON_VMDIR_ERROR( dwError ); } cleanup: return dwError; error: VMDIR_SET_BACKEND_ERROR(dwError); // if dwError no in BE space, set to ERROR_BACKEND_ERROR VMDIR_LOG_ERROR(LDAP_DEBUG_BACKEND, "VmDirMDBDeleteEntry: failed: error=%d,DN=%s", dwError, VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val)); goto cleanup; }
/* MdbDeleteEntry: Deletes an entry in the MDB DBs. * * Returns: BE error codes. * */ DWORD VmDirMDBDeleteEntry( PVDIR_BACKEND_CTX pBECtx, PVDIR_MODIFICATION pMods, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; assert( pBECtx && pBECtx->pBEPrivate && pEntry ); // Delete child from the parentId index dwError = MDBDeleteParentIdIndex( pBECtx, &(pEntry->pdn), pEntry->eId ); BAIL_ON_VMDIR_ERROR(dwError); dwError = VmDirMDBModifyEntry( pBECtx, pMods, pEntry); BAIL_ON_VMDIR_ERROR( dwError ); if ((dwError = MDBCreateParentIdIndex( pBECtx, &(gVmdirServerGlobals.delObjsContainerDN), pEntry->eId )) != 0) { dwError = MDBToBackendError(dwError, ERROR_BACKEND_ENTRY_NOTFOUND, ERROR_BACKEND_PARENT_NOTFOUND, pBECtx, "CreateParentIdIndex"); BAIL_ON_VMDIR_ERROR( dwError ); } cleanup: return dwError; error: VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "BEDeleteEntry DN (%s) failed, (%u)(%s)", VDIR_SAFE_STRING( pEntry->dn.bvnorm_val), dwError, VDIR_SAFE_STRING(pBECtx->pszBEErrorMsg) ); VMDIR_SET_BACKEND_ERROR(dwError); // if dwError no in BE space, set to ERROR_BACKEND_ERROR goto cleanup; }
/* MdbModifyEntry: Updates an entry in the MDB DBs. * * Returns: BE error codes. * */ DWORD VmDirMDBModifyEntry( PVDIR_BACKEND_CTX pBECtx, VDIR_MODIFICATION* pMods, PVDIR_ENTRY pEntry ) { DWORD dwError = 0; VDIR_BERVALUE newEncodedEntry = VDIR_BERVALUE_INIT; VDIR_MODIFICATION * mod = NULL; PVDIR_DB_TXN pTxn = NULL; assert( pBECtx && pBECtx->pBE && pBECtx->pBEPrivate && pMods && pEntry ); pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate; dwError = VmDirEncodeEntry( pEntry, &newEncodedEntry ); BAIL_ON_VMDIR_ERROR(dwError); pEntry->encodedSize = newEncodedEntry.lberbv.bv_len; VMDIR_SAFE_FREE_MEMORY( pEntry->encodedEntry ); // entry takes over the responsibility to free newEncodedEntry.lberbv.bv_val pEntry->encodedEntry = (unsigned char *)newEncodedEntry.lberbv.bv_val; // Delete child from the parentId index if (pEntry->newpdn.lberbv.bv_len) { dwError = MDBDeleteParentIdIndex( pBECtx, &(pEntry->pdn), pEntry->eId ); BAIL_ON_VMDIR_ERROR(dwError); } // Create/Delete appropriate indices for DN first in case DN is already in use for (mod = pMods; mod != NULL; mod = mod->next) { if (mod->ignore) { continue; } if (VmDirStringCompareA(mod->attr.type.lberbv.bv_val, ATTR_DN, FALSE) == 0) { switch (mod->operation) { case MOD_OP_ADD: if ((dwError = MdbUpdateIndicesForAttr( pBECtx->pBE, pTxn, &(pEntry->dn), &(mod->attr.type), mod->attr.vals, mod->attr.numVals, pEntry->eId, BE_INDEX_OP_TYPE_CREATE)) != 0) { dwError = MDBToBackendError( dwError, MDB_KEYEXIST, ERROR_BACKEND_CONSTRAINT, pBECtx, VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); } break; case MOD_OP_DELETE: if ((dwError = MdbUpdateIndicesForAttr( pBECtx->pBE, pTxn, &(pEntry->dn), &(mod->attr.type), mod->attr.vals, mod->attr.numVals, pEntry->eId, BE_INDEX_OP_TYPE_DELETE )) != 0) { dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); } break; case MOD_OP_REPLACE: default: assert( FALSE ); } if ((dwError = MdbUpdateAttrMetaData( pBECtx->pBE, pTxn, &(mod->attr), pEntry->eId, BE_INDEX_OP_TYPE_UPDATE )) != 0) { dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); } } } // Create/Delete appropriate indices for DN for (mod = pMods; mod != NULL; mod = mod->next) { if (mod->ignore) { continue; } if (VmDirStringCompareA(mod->attr.type.lberbv.bv_val, ATTR_DN, FALSE) != 0) { switch (mod->operation) { case MOD_OP_ADD: if ((dwError = MdbUpdateIndicesForAttr( pBECtx->pBE, pTxn, &(pEntry->dn), &(mod->attr.type), mod->attr.vals, mod->attr.numVals, pEntry->eId, BE_INDEX_OP_TYPE_CREATE)) != 0) { dwError = MDBToBackendError( dwError, MDB_KEYEXIST, ERROR_BACKEND_CONSTRAINT, pBECtx, VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); } break; case MOD_OP_DELETE: if ((dwError = MdbUpdateIndicesForAttr( pBECtx->pBE, pTxn, &(pEntry->dn), &(mod->attr.type), mod->attr.vals, mod->attr.numVals, pEntry->eId, BE_INDEX_OP_TYPE_DELETE )) != 0) { dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); } break; case MOD_OP_REPLACE: default: assert( FALSE ); } if ((dwError = MdbUpdateAttrMetaData( pBECtx->pBE, pTxn, &(mod->attr), pEntry->eId, BE_INDEX_OP_TYPE_UPDATE )) != 0) { dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, VDIR_SAFE_STRING(mod->attr.type.lberbv.bv_val)); BAIL_ON_VMDIR_ERROR( dwError ); } } } // Update Entry DB. if ((dwError = MdbCreateEIDIndex(pBECtx->pBE, pTxn, pEntry->eId, &newEncodedEntry, FALSE /* update current eId key */)) != 0) { dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "CreateEIDIndex"); BAIL_ON_VMDIR_ERROR( dwError ); } if (pEntry->newpdn.lberbv.bv_len) { if ((dwError = MDBCreateParentIdIndex(pBECtx, &(pEntry->newpdn), pEntry->eId)) != 0) { dwError = MDBToBackendError(dwError, ERROR_BACKEND_ENTRY_NOTFOUND, ERROR_BACKEND_PARENT_NOTFOUND, pBECtx, "CreateParentIdIndex"); BAIL_ON_VMDIR_ERROR( dwError ); } } cleanup: return dwError; error: VMDIR_SET_BACKEND_ERROR(dwError); // if dwError no in BE space, set to ERROR_BACKEND_ERROR VMDIR_LOG_ERROR(LDAP_DEBUG_BACKEND, "ModifyEntry failed: error=%d,DN=%s", dwError, VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_val)); goto cleanup; }