示例#1
0
文件: entry.c 项目: vmware/lightwave
/* 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;
}
示例#2
0
/* 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->pBEPrivate && pMods && pEntry );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    dwError = VmDirEncodeEntry( pEntry, &newEncodedEntry );
    BAIL_ON_VMDIR_ERROR(dwError);

    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;

    // Create/Delete appropriate indices for indexed attributes.
    for (mod = pMods; mod != NULL; mod = mod->next)
    {
        if (mod->ignore)
        {
            continue;
        }
        switch (mod->operation)
        {
            case MOD_OP_ADD:
                if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(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( pTxn, &(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( 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(pTxn, pEntry->eId, &newEncodedEntry, FALSE /* update current eId key */)) != 0)
    {
        dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "CreateEIDIndex");
        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;
}
示例#3
0
/* MdbAddEntry: Creates an entry in the MDB DBs.
 *
 * Returns: BE error codes.
 *
 */
DWORD
VmDirMDBAddEntry(
    PVDIR_BACKEND_CTX   pBECtx,
    PVDIR_ENTRY         pEntry)
{
    DWORD             dwError = 0;
    ENTRYID           entryId = 0;
    VDIR_DB_TXN*      pTxn = NULL;
    VDIR_BERVALUE     encodedEntry = VDIR_BERVALUE_INIT;
    VDIR_ATTRIBUTE *  nextAttr = NULL;

    assert( pEntry && pBECtx && pBECtx->pBEPrivate );

    pTxn = (PVDIR_DB_TXN)pBECtx->pBEPrivate;

    dwError = VmDirEncodeEntry( pEntry, &encodedEntry );
    BAIL_ON_VMDIR_ERROR(dwError);

    if (pEntry->eId != 0)    // Reserved entries have eId already
    {
        entryId = pEntry->eId;
    }
    else
    {
        VDIR_DB_DBT     EIDkey = {0};
        VDIR_DB_DBT     EIDvalue  = {0};
        unsigned char   EIDKeyBytes[sizeof( ENTRYID )] = {0};
        unsigned char   EIDValueBytes[sizeof( ENTRYID )] = {0};

        EIDkey.mv_data = &EIDKeyBytes[0];
        MDBEntryIdToDBT(BE_MDB_ENTRYID_SEQ_KEY, &EIDkey);

        dwError =  mdb_get(pTxn, gVdirMdbGlobals.mdbSeqDBi, &EIDkey, &EIDvalue);
        BAIL_ON_VMDIR_ERROR(dwError);

        assert( EIDvalue.mv_size == sizeof(ENTRYID) );
        entryId = *((ENTRYID*)EIDvalue.mv_data);

        *((ENTRYID*)&EIDValueBytes[0]) = entryId + 1;
        EIDvalue.mv_data = &EIDValueBytes[0];
        EIDvalue.mv_size = sizeof(ENTRYID);

        dwError =  mdb_put(pTxn, gVdirMdbGlobals.mdbSeqDBi, &EIDkey, &EIDvalue, BE_DB_FLAGS_ZERO);
        BAIL_ON_VMDIR_ERROR(dwError);
    }

    assert( entryId > 0 );

    if ((dwError = MDBCreateParentIdIndex(pBECtx, &(pEntry->pdn), entryId)) != 0)
    {
        dwError = MDBToBackendError(dwError, ERROR_BACKEND_ENTRY_NOTFOUND,
                                    ERROR_BACKEND_PARENT_NOTFOUND, pBECtx, "CreateParentIdIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

    // Update DN index first. this make sure we always return ERROR_BACKEND_ENTRY_EXISTS in such case.
    for (nextAttr = pEntry->attrs; nextAttr != NULL; nextAttr = nextAttr->next)
    {
        if (VmDirStringCompareA(nextAttr->type.lberbv.bv_val, ATTR_DN, FALSE) == 0)
        {
            // make sure we store normalized DN value.
            dwError = VmDirNormalizeDN( &(nextAttr->vals[0]), pEntry->pSchemaCtx );
            BAIL_ON_VMDIR_ERROR(dwError);

            if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(nextAttr->type), nextAttr->vals, nextAttr->numVals,
                                                    entryId, BE_INDEX_OP_TYPE_CREATE)) != 0)
            {
                dwError = MDBToBackendError( dwError,
                                             MDB_KEYEXIST,
                                             ERROR_BACKEND_ENTRY_EXISTS,
                                             pBECtx,
                                             VDIR_SAFE_STRING(nextAttr->vals[0].bvnorm_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
            if ((dwError = MdbUpdateAttrMetaData( pTxn, nextAttr, entryId, BE_INDEX_OP_TYPE_CREATE )) != 0)
            {
                dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx, "UpdateDNAttrMetaData");
                BAIL_ON_VMDIR_ERROR( dwError );
            }
        }
    }

    // Update remaining indices
    for (nextAttr = pEntry->attrs; nextAttr != NULL; nextAttr = nextAttr->next)
    {
        if (VmDirStringCompareA(nextAttr->type.lberbv.bv_val, ATTR_DN, FALSE) != 0)
        {
            if ((dwError = MdbUpdateIndicesForAttr( pTxn, &(nextAttr->type), nextAttr->vals, nextAttr->numVals,
                                                    entryId, BE_INDEX_OP_TYPE_CREATE)) != 0)
            {
                dwError = MDBToBackendError( dwError,
                                             MDB_KEYEXIST,
                                             ERROR_BACKEND_CONSTRAINT,
                                             pBECtx,
                                             VDIR_SAFE_STRING(nextAttr->type.lberbv.bv_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
            if ((dwError = MdbUpdateAttrMetaData( pTxn, nextAttr, entryId, BE_INDEX_OP_TYPE_CREATE )) != 0)
            {
                dwError = MDBToBackendError(dwError, 0, ERROR_BACKEND_ERROR, pBECtx,
                                            VDIR_SAFE_STRING(nextAttr->type.lberbv.bv_val));
                BAIL_ON_VMDIR_ERROR( dwError );
            }
        }
    }

    // Update entry/blob database
    if ((dwError = MdbCreateEIDIndex(pTxn, entryId, &encodedEntry, TRUE /* 1st time new entry creation */)) != 0)
    {
        dwError = MDBToBackendError(dwError, MDB_KEYEXIST, ERROR_BACKEND_CONSTRAINT, pBECtx, "CreateEIDIndex");
        BAIL_ON_VMDIR_ERROR( dwError );
    }

cleanup:

    VMDIR_SAFE_FREE_MEMORY( encodedEntry.lberbv.bv_val );

    return dwError;

error:
    // TODO set pBECtx->pszBEErrorMsg?
    VMDIR_LOG_ERROR( LDAP_DEBUG_BACKEND, "BEAddEntry DN (%s),  (%u)(%s)", VDIR_SAFE_STRING(pEntry->dn.lberbv.bv_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;
}