dse_delete(Slapi_PBlock *pb) /* JCM There should only be one exit point from this function! */
{
    int rc = -1;
    int dont_write_file = 0; /* default */
    struct dse *pdse = NULL;
    int returncode = LDAP_SUCCESS;
    char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
    char *entry_str = "entry";
    char *errbuf = NULL;
    char *attrs[2] = {NULL, NULL};
    Slapi_DN *sdn = NULL;
    Slapi_Entry *ec = NULL; /* copy of entry to delete */
    Slapi_Entry *orig_entry = NULL;
    int need_be_postop = 0;
    PRBool global_lock_owned = PR_FALSE;

    /*
     * Get the database and the dn
     */
    if (slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &pdse) < 0 ||
        slapi_pblock_get(pb, SLAPI_DELETE_TARGET_SDN, &sdn) < 0 ||
        (pdse == NULL)) {
        returncode = LDAP_OPERATIONS_ERROR;
        goto done;
    }

    slapi_pblock_get(pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &dont_write_file);
    if (!dont_write_file && dse_check_for_readonly_error(pb, pdse)) {
        return (rc); /* result already sent */
    }

    ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK);
    if (ec == NULL) {
        returncode = LDAP_NO_SUCH_OBJECT;
        goto done;
    }

    /*
     * Check if this node has any children.
     */
    if (dse_numsubordinates(ec) > 0) {
        returncode = LDAP_NOT_ALLOWED_ON_NONLEAF;
        goto done;
    }

    /*
     * Check the access
     */
    attrs[0] = entry_str;
    attrs[1] = NULL;
    returncode = plugin_call_acl_plugin(pb, ec, attrs, NULL, SLAPI_ACL_DELETE, ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
    if (returncode != LDAP_SUCCESS) {
        if (errbuf && errbuf[0]) {
            PL_strncpyz(returntext, errbuf, sizeof(returntext));
        }
        slapi_ch_free_string(&errbuf);
        goto done;
    }

    /* Possibly acquire the global backend lock */
    if (global_backend_lock_requested()) {
        global_backend_lock_lock();
        global_lock_owned = PR_TRUE;
    }

    if (dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, ec, NULL, &returncode, returntext) == SLAPI_DSE_CALLBACK_OK) {
        slapi_pblock_set(pb, SLAPI_DELETE_BEPREOP_ENTRY, ec);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &returncode);
        plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN);
        need_be_postop = 1;
        if (!returncode) {
            slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
        }
        if (!returncode) {
            plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_PRE_DELETE_FN);
            if (!returncode) {
                slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
            }
            if (!returncode) {
                if (dse_delete_entry(pdse, pb, ec) == 0) {
                    returncode = LDAP_OPERATIONS_ERROR;
                }
            }
        }
        /* Setting SLAPI_ENTRY_PRE_OP here,
         * since some betxn postop may need the pre op entry. */
        slapi_pblock_set(pb, SLAPI_ENTRY_PRE_OP, slapi_entry_dup(ec));
    } else {
        goto done;
    }

    dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, ec, NULL, &returncode, returntext);
done:
    slapi_pblock_get(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, &orig_entry);
    slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec);
    /* make sure OPRETURN and RESULT_CODE are set */
    slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc);
    if (returncode || rc) {
        if (!rc) {
            slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &returncode);
        }
        if (!returncode) {
            returncode = rc;
        }
    }
    if (need_be_postop) {
        plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN);
        if (!returncode) {
            slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
        }

        /* finally, give the be plugins a crack at it */
        plugin_call_plugins(pb, SLAPI_PLUGIN_BE_POST_DELETE_FN);
        if (!returncode) {
            slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
        }
    }
    if (global_lock_owned) {
        global_backend_lock_unlock();
    }
    if (returncode && !returntext[0]) {
        char *ldap_result_message = NULL;
        slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
        if (ldap_result_message && ldap_result_message[0]) {
            PL_strncpyz(returntext, ldap_result_message, sizeof(returntext));
        }
    }
    /*
     * Check if we are deleting a plugin
     */
    if (returncode == LDAP_SUCCESS) {
        if (dse_delete_plugin(ec, returntext)) {
            rc = LDAP_UNWILLING_TO_PERFORM;
        }
    }
    slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry);
    slapi_send_ldap_result(pb, returncode, NULL, returntext, 0, NULL);
    return dse_delete_return(returncode, ec);
}
dse_delete(Slapi_PBlock *pb)  
{
    int rc = -1;
    int dont_write_file = 0;  
    struct dse *pdse = NULL;
    int returncode = LDAP_SUCCESS;
    char returntext[SLAPI_DSE_RETURNTEXT_SIZE] = "";
    char *entry_str = "entry";
    char *errbuf = NULL;
    char *attrs[2] = {NULL, NULL};
    Slapi_DN *sdn = NULL;
    Slapi_Entry *ec = NULL;  
    Slapi_Entry *orig_entry = NULL;
    int need_be_postop = 0;
    PRBool global_lock_owned = PR_FALSE;

     
    if (slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &pdse) < 0 ||
        slapi_pblock_get(pb, SLAPI_DELETE_TARGET_SDN, &sdn) < 0 ||
        (pdse == NULL)) {
        returncode = LDAP_OPERATIONS_ERROR;
        goto done;
    }

    slapi_pblock_get(pb, SLAPI_DSE_DONT_WRITE_WHEN_ADDING, &dont_write_file);
    if (!dont_write_file && dse_check_for_readonly_error(pb, pdse)) {
        return (rc);  
    }

    ec = dse_get_entry_copy(pdse, sdn, DSE_USE_LOCK);
    if (ec == NULL) {
        returncode = LDAP_NO_SUCH_OBJECT;
        goto done;
    }

     
    if (dse_numsubordinates(ec) > 0) {
        returncode = LDAP_NOT_ALLOWED_ON_NONLEAF;
        goto done;
    }

     
    attrs[0] = entry_str;
    attrs[1] = NULL;
    returncode = plugin_call_acl_plugin(pb, ec, attrs, NULL, SLAPI_ACL_DELETE, ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
    if (returncode != LDAP_SUCCESS) {
        if (errbuf && errbuf[0]) {
            PL_strncpyz(returntext, errbuf, sizeof(returntext));
        }
        slapi_ch_free_string(&errbuf);
        goto done;
    }

     
    if (global_backend_lock_requested()) {
        global_backend_lock_lock();
        global_lock_owned = PR_TRUE;
    }

    if (dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_PREOP, ec, NULL, &returncode, returntext) == SLAPI_DSE_CALLBACK_OK) {
        slapi_pblock_set(pb, SLAPI_DELETE_BEPREOP_ENTRY, ec);
        slapi_pblock_set(pb, SLAPI_RESULT_CODE, &returncode);
        plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN);
        need_be_postop = 1;
        if (!returncode) {
            slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
        }
        if (!returncode) {
            plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_PRE_DELETE_FN);
            if (!returncode) {
                slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
            }
            if (!returncode) {
                if (dse_delete_entry(pdse, pb, ec) == 0) {
                    returncode = LDAP_OPERATIONS_ERROR;
                }
            }
        }
         
        slapi_pblock_set(pb, SLAPI_ENTRY_PRE_OP, slapi_entry_dup(ec));
    } else {
        goto done;
    }

    dse_call_callback(pdse, pb, SLAPI_OPERATION_DELETE, DSE_FLAG_POSTOP, ec, NULL, &returncode, returntext);
done:
    slapi_pblock_get(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, &orig_entry);
    slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, ec);
     
    slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc);
    if (returncode || rc) {
        if (!rc) {
            slapi_pblock_set(pb, SLAPI_PLUGIN_OPRETURN, &returncode);
        }
        if (!returncode) {
            returncode = rc;
        }
    }
    if (need_be_postop) {
        plugin_call_plugins(pb, SLAPI_PLUGIN_BE_TXN_POST_DELETE_FN);
        if (!returncode) {
            slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
        }

         
        plugin_call_plugins(pb, SLAPI_PLUGIN_BE_POST_DELETE_FN);
        if (!returncode) {
            slapi_pblock_get(pb, SLAPI_RESULT_CODE, &returncode);
        }
    }
    if (global_lock_owned) {
        global_backend_lock_unlock();
    }
    if (returncode && !returntext[0]) {
        char *ldap_result_message = NULL;
        slapi_pblock_get(pb, SLAPI_PB_RESULT_TEXT, &ldap_result_message);
        if (ldap_result_message && ldap_result_message[0]) {
            PL_strncpyz(returntext, ldap_result_message, sizeof(returntext));
        }
    }
     
    if (returncode == LDAP_SUCCESS) {
        if (dse_delete_plugin(ec, returntext)) {
            rc = LDAP_UNWILLING_TO_PERFORM;
        }
    }
    slapi_pblock_set(pb, SLAPI_DELETE_BEPOSTOP_ENTRY, orig_entry);
    slapi_send_ldap_result(pb, returncode, NULL, returntext, 0, NULL);
    return dse_delete_return(returncode, ec);
}