ldbm_config_modify_entry_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *e, int *returncode, char *returntext, void *arg)
{
    int i;
    char *attr_name;
    LDAPMod **mods;
    Slapi_Mods smods_moved;
    int rc = LDAP_SUCCESS;
    int apply_mod = 0;
    struct ldbminfo *li = (struct ldbminfo *)arg;
    int reapply_mods = 0;
    int move_mods = 0;
    int idx = 0;
    int internal_op = 0;
    Slapi_Operation *operation = NULL;

    /* This lock is probably way too conservative, but we don't expect much
     * contention for it. */
    PR_Lock(li->li_config_mutex);

    dblayer_private *priv = (dblayer_private *)li->li_dblayer_private;
    slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
    slapi_mods_init(&smods_moved, 0);

    slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
    internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL);

    returntext[0] = '\0';

    slapi_log_err(SLAPI_LOG_CONFIG, "ldbm_config_modify_entry_callback", "Executing for entry (%s) with flags (%d) operation is internal: %d\n",
                    slapi_entry_get_dn_const(e), li->li_flags, internal_op);
    /*
     * First pass: set apply mods to 0 so only input validation will be done;
     * 2nd pass: set apply mods to 1 to apply changes to internal storage
     */
    for (apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++) {
        for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
            attr_name = mods[i]->mod_type;

            /* There are some attributes that we don't care about, like modifiersname. */
            if (ldbm_config_ignored_attr(attr_name)) {
                if (apply_mod) {
                    Slapi_Attr *origattr = NULL;
                    Slapi_ValueSet *origvalues = NULL;
                    mods[idx++] = mods[i];
                    /* we also need to restore the entryAfter e to its original
                       state, because the dse code will attempt to reapply
                       the mods again */
                    slapi_entry_attr_find(entryBefore, attr_name, &origattr);
                    if (NULL != origattr) {
                        slapi_attr_get_valueset(origattr, &origvalues);
                        if (NULL != origvalues) {
                            slapi_entry_add_valueset(e, attr_name, origvalues);
                            slapi_valueset_free(origvalues);
                        }
                    }
                    reapply_mods = 1; /* there is at least one mod we removed */
                }
                continue;
            }


            if (ldbm_config_moved_attr(attr_name) && !internal_op) {
                rc = priv->dblayer_config_set_fn(li, attr_name, apply_mod, mods[i]->mod_op,
                                            CONFIG_PHASE_RUNNING,
                                            (mods[i]->mod_bvalues == NULL) ? NULL
                                            : mods[i]->mod_bvalues[0]->bv_val);
                if (apply_mod) {
                    slapi_entry_attr_delete(e, attr_name);
                    slapi_mods_add_ldapmod(&smods_moved, mods[i]);
                    move_mods++;
                    reapply_mods = 1; /* there is at least one mod we removed */
                }
                continue;
            }
            /* when deleting a value, and this is the last or only value, set
               the config param to its default value
               when adding a value, if the value is set to its default value, replace
               it with the new value - otherwise, if it is single valued, reject the
               operation with TYPE_OR_VALUE_EXISTS */
            /* This assumes there is only one bval for this mod. */
            rc = ldbm_config_set((void *)li, attr_name, ldbm_config,
                                 (mods[i]->mod_bvalues == NULL) ? NULL
                                                                : mods[i]->mod_bvalues[0],
                                 returntext,
                                 ((li->li_flags & LI_FORCE_MOD_CONFIG) ? CONFIG_PHASE_INTERNAL : CONFIG_PHASE_RUNNING),
                                 apply_mod, mods[i]->mod_op);
            if (rc) {
                slapi_log_err(SLAPI_LOG_ERR, "ldbm_config_modify_entry_callback", "Modifying config attribute %s failed (err=%d)\n", attr_name, rc);
            }
            if (apply_mod) {
                mod_free(mods[i]);
                mods[i] = NULL;
            }
        }
    }

    PR_Unlock(li->li_config_mutex);

    if (reapply_mods) {
        mods[idx] = NULL;
        slapi_pblock_set(pb, SLAPI_DSE_REAPPLY_MODS, &reapply_mods);
    }

    if (move_mods) {
        char *dn = slapi_ch_smprintf("cn=bdb,%s",CONFIG_LDBM_DN);
        Slapi_PBlock *mod_pb = slapi_pblock_new();
        slapi_modify_internal_set_pb(mod_pb, dn,
                                     slapi_mods_get_ldapmods_byref(&smods_moved),
                                     NULL, NULL, li->li_identity, 0);
        slapi_modify_internal_pb(mod_pb);
        slapi_pblock_destroy(mod_pb);
        slapi_ch_free_string(&dn);
        slapi_mods_done(&smods_moved);
    }

    *returncode = rc;
    if (LDAP_SUCCESS == rc) {
        return SLAPI_DSE_CALLBACK_OK;
    } else {
        return SLAPI_DSE_CALLBACK_ERROR;
    }
}
ldbm_config_modify_entry_callback(Slapi_PBlock *pb, Slapi_Entry *entryBefore, Slapi_Entry *e, int *returncode, char *returntext, void *arg)
{
    int i;
    char *attr_name;
    LDAPMod **mods;
    Slapi_Mods smods_moved;
    int rc = LDAP_SUCCESS;
    int apply_mod = 0;
    struct ldbminfo *li = (struct ldbminfo *)arg;
    int reapply_mods = 0;
    int move_mods = 0;
    int idx = 0;
    int internal_op = 0;
    Slapi_Operation *operation = NULL;

     
    PR_Lock(li->li_config_mutex);

    dblayer_private *priv = (dblayer_private *)li->li_dblayer_private;
    slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
    slapi_mods_init(&smods_moved, 0);

    slapi_pblock_get(pb, SLAPI_OPERATION, &operation);
    internal_op = operation_is_flag_set(operation, OP_FLAG_INTERNAL);

    returntext[0] = '\0';

    slapi_log_err(SLAPI_LOG_CONFIG, "ldbm_config_modify_entry_callback", "Executing for entry (%s) with flags (%d) operation is internal: %d\n",
                    slapi_entry_get_dn_const(e), li->li_flags, internal_op);
     
    for (apply_mod = 0; apply_mod <= 1 && LDAP_SUCCESS == rc; apply_mod++) {
        for (i = 0; mods && mods[i] && LDAP_SUCCESS == rc; i++) {
            attr_name = mods[i]->mod_type;

             
            if (ldbm_config_ignored_attr(attr_name)) {
                if (apply_mod) {
                    Slapi_Attr *origattr = NULL;
                    Slapi_ValueSet *origvalues = NULL;
                    mods[idx++] = mods[i];
                     
                    slapi_entry_attr_find(entryBefore, attr_name, &origattr);
                    if (NULL != origattr) {
                        slapi_attr_get_valueset(origattr, &origvalues);
                        if (NULL != origvalues) {
                            slapi_entry_add_valueset(e, attr_name, origvalues);
                            slapi_valueset_free(origvalues);
                        }
                    }
                    reapply_mods = 1;  
                }
                continue;
            }


            if (ldbm_config_moved_attr(attr_name) && !internal_op) {
                rc = priv->dblayer_config_set_fn(li, attr_name, apply_mod, mods[i]->mod_op,
                                            CONFIG_PHASE_RUNNING,
                                            (mods[i]->mod_bvalues == NULL) ? NULL
                                            : mods[i]->mod_bvalues[0]->bv_val);
                if (apply_mod) {
                    slapi_entry_attr_delete(e, attr_name);
                    slapi_mods_add_ldapmod(&smods_moved, mods[i]);
                    move_mods++;
                    reapply_mods = 1;  
                }
                continue;
            }
             
             
            rc = ldbm_config_set((void *)li, attr_name, ldbm_config,
                                 (mods[i]->mod_bvalues == NULL) ? NULL
                                                                : mods[i]->mod_bvalues[0],
                                 returntext,
                                 ((li->li_flags & LI_FORCE_MOD_CONFIG) ? CONFIG_PHASE_INTERNAL : CONFIG_PHASE_RUNNING),
                                 apply_mod, mods[i]->mod_op);
            if (rc) {
                slapi_log_err(SLAPI_LOG_ERR, "ldbm_config_modify_entry_callback", "Modifying config attribute %s failed (err=%d)\n", attr_name, rc);
            }
            if (apply_mod) {
                mod_free(mods[i]);
                mods[i] = NULL;
            }
        }
    }

    PR_Unlock(li->li_config_mutex);

    if (reapply_mods) {
        mods[idx] = NULL;
        slapi_pblock_set(pb, SLAPI_DSE_REAPPLY_MODS, &reapply_mods);
    }

    if (move_mods) {
        char *dn = slapi_ch_smprintf("cn=bdb,%s",CONFIG_LDBM_DN);
        Slapi_PBlock *mod_pb = slapi_pblock_new();
        slapi_modify_internal_set_pb(mod_pb, dn,
                                     slapi_mods_get_ldapmods_byref(&smods_moved),
                                     NULL, NULL, li->li_identity, 0);
        slapi_modify_internal_pb(mod_pb);
        slapi_pblock_destroy(mod_pb);
        slapi_ch_free_string(&dn);
        slapi_mods_done(&smods_moved);
    }

    *returncode = rc;
    if (LDAP_SUCCESS == rc) {
        return SLAPI_DSE_CALLBACK_OK;
    } else {
        return SLAPI_DSE_CALLBACK_ERROR;
    }
}