/*
 * Note: this file originally auto-generated by mib2c using
 *       version : 1.19 $ of : mfd-data-set.m2c,v $
 *
 * $Id$
 *
 */
/*
 * standard Net-SNMP includes 
 */
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include <openssl/dh.h>

/*
 * include our parent header 
 */
#define NEED_USMDH_FUNCTIONS
#include "usmDHUserKeyTable.h"

int
usmDHUserCheckValue(struct usmUser *user, int for_auth_key,
                    char *val, size_t val_len)
{
    /*
     * The set value must be composed of 2 parts, the first being the
     * current value 
     */
    char           *current_value;
    size_t          current_value_len;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserCheckValue",
                "called\n"));
    usmDHGetUserKeyChange(user, for_auth_key,
                          &current_value, &current_value_len);

    if (!current_value)
        return MFD_ERROR;

    if (val_len != current_value_len * 2)
        return MFD_NOT_VALID_NOW;

    if (memcmp(current_value, val, current_value_len) != 0)
        return SNMP_ERR_WRONGVALUE;     /* mandated error string */

    return MFD_SUCCESS;
}

int
usmDHSetKey(struct usmUser *user, int for_auth_key,
            char *val, size_t val_len)
{
    DH             *dh;
    BIGNUM         *other_pub;
    char           *key;
    size_t          key_len;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHSetKey", "called\n"));
    /*
     * XXX: mem leaks on errors abound 
     */

    dh = usmDHGetUserDHptr(user, for_auth_key);
    if (!dh)
        return MFD_ERROR;

    other_pub = BN_bin2bn(val + val_len / 2, val_len / 2, NULL);
    if (!other_pub)
        return MFD_ERROR;

    /*
     * Set the new key for a user 
     */
    key_len = DH_size(dh);
    key = malloc(DH_size(dh));
    if (!key)
        return MFD_ERROR;

    if (DH_compute_key(key, other_pub, dh)) {
        u_char        **replkey;
        size_t          replkey_size;

        if (for_auth_key) {
            replkey_size = user->authKeyLen;
            replkey = &user->authKey;
        } else {
            replkey_size = user->privKeyLen;
            replkey = &user->privKey;
        }

        /*
         * is it large enough? 
         */
        if (key_len < replkey_size)
            return MFD_ERROR;

        /*
         * copy right most bits, per the object requirements 
         */
        SNMP_FREE(*replkey);
        memdup(replkey, key + key_len - replkey_size, replkey_size);

        return MFD_SUCCESS;
    }

    return MFD_ERROR;
}

/** @ingroup data_access 
 * @defgroup data_set data_set: Routines to set data
 *
 * These routines are used to set the value for individual objects. The
 * row context is passed, along with the new value.
 * 
 * @{
 */
/**********************************************************************
 **********************************************************************
 ***
 *** Table usmDHUserKeyTable
 ***
 **********************************************************************
 **********************************************************************/
/*
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyTable is subid 2 of usmDHPublicObjects.
 * Its status is Current.
 * OID: .1.3.6.1.3.101.1.1.2, length: 9
 */
    /*
     * NOTE: if you update this chart, please update the versions in
     *       local/mib2c-conf.d/parent-set.m2i
     *       agent/mibgroup/helpers/baby_steps.c
     * while you're at it.
     */
    /*
     ***********************************************************************
     * Baby Steps Flow Chart (2004.06.05)                                  *
     *                                                                     *
     * +--------------+    +================+    U = unconditional path    *
     * |optional state|    ||required state||    S = path for success      *
     * +--------------+    +================+    E = path for error        *
     ***********************************************************************
     *
     *                        +--------------+
     *                        |     pre      |
     *                        |   request    |
     *                        +--------------+
     *                               | U
     *                        +==============+
     *       +----------------||  object    ||
     *       |              E ||  lookup    ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |              E ||   check    ||
     *       |<---------------||   values   ||
     *       |                +==============+
     *       |                       | S
     *       |                +==============+
     *       |       +<-------||   undo     ||
     *       |       |      E ||   setup    ||
     *       |       |        +==============+
     *       |       |               | S
     *       |       |        +==============+
     *       |       |        ||    set     ||-------------------------->+
     *       |       |        ||   value    || E                         |
     *       |       |        +==============+                           |
     *       |       |               | S                                 |
     *       |       |        +--------------+                           |
     *       |       |        |    check     |-------------------------->|
     *       |       |        |  consistency | E                         |
     *       |       |        +--------------+                           |
     *       |       |               | S                                 |
     *       |       |        +==============+         +==============+  |
     *       |       |        ||   commit   ||-------->||     undo   ||  |
     *       |       |        ||            || E       ||    commit  ||  |
     *       |       |        +==============+         +==============+  |
     *       |       |               | S                     U |<--------+
     *       |       |        +--------------+         +==============+
     *       |       |        | irreversible |         ||    undo    ||
     *       |       |        |    commit    |         ||     set    ||
     *       |       |        +--------------+         +==============+
     *       |       |               | U                     U |
     *       |       +-------------->|<------------------------+
     *       |                +==============+
     *       |                ||   undo     ||
     *       |                ||  cleanup   ||
     *       |                +==============+
     *       +---------------------->| U
     *                        +--------------+
     *                        |    post      |
     *                        |   request    |
     *                        +--------------+
     *
     */

/**
 * Setup up context with information needed to undo a set request.
 *
 * This function will be called before the individual node undo setup
 * functions are called. If you need to do any undo setup that is not
 * related to a specific column, you can do it here.
 *
 * Note that the undo context has been allocated with
 * usmDHUserKeyTable_allocate_data(), but may need extra
 * initialization similar to what you may have done in
 * usmDHUserKeyTable_rowreq_ctx_init().
 * Note that an individual node's undo_setup function will only be called
 * if that node is being set to a new value.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in the node's undo_setup
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
usmDHUserKeyTable_undo_setup(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo_setup",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    /*
     * TODO:451:M: |-> Setup usmDHUserKeyTable undo.
     * set up usmDHUserKeyTable undo information, in preparation for a set.
     * Undo storage is in (* usmDHUserOwnPrivKeyChange_val_ptr_ptr )*
     */

    return rc;
}                               /* usmDHUserKeyTable_undo_setup */

/**
 * Undo a set request.
 *
 * This function will be called before the individual node undo
 * functions are called. If you need to do any undo that is not
 * related to a specific column, you can do it here.
 *
 * Note that an individual node's undo function will only be called
 * if that node is being set to a new value.
 *
 * If there is anything  specific to a particular column (e.g. releasing
 * memory for a string), you should do that setup in the node's undo
 * function, so it won't be done unless it is necessary.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 */
int
usmDHUserKeyTable_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:451:M: |-> usmDHUserKeyTable undo.
     * usmDHUserKeyTable undo information, in response to a failed set.
     * Undo storage is in (* usmDHUserOwnPrivKeyChange_val_ptr_ptr )*
     */

    return rc;
}                               /* usmDHUserKeyTable_undo_setup */

/**
 * Cleanup up context undo information.
 *
 * This function will be called after set/commit processing. If you
 * allocated any resources in undo_setup, this is the place to release
 * those resources.
 *
 * This function is called regardless of the success or failure of the set
 * request. If you need to perform different steps for cleanup depending
 * on success or failure, you can add a flag to the rowreq_ctx.
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
usmDHUserKeyTable_undo_cleanup(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo_cleanup",
                "called\n"));
    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:452:M: |-> Cleanup usmDHUserKeyTable undo.
     * Undo storage is in (* usmDHUserOwnPrivKeyChange_val_ptr_ptr )*
     */

    return rc;
}                               /* usmDHUserKeyTable_undo_cleanup */

/**
 * commit new values.
 *
 * At this point, you should have done everything you can to ensure that
 * this commit will not fail.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * usmDHUserKeyTable_oids.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
usmDHUserKeyTable_commit(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             save_flags;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_commit",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * nothing to do; we wait for the irreversible commit
     */

    /*
     * if we successfully commited this row, set the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags |= MFD_ROW_DIRTY;
    }

    return rc;
}                               /* usmDHUserKeyTable_commit */

/**
 * undo commit new values.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * usmDHUserKeyTable_oids.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error
 */
int
usmDHUserKeyTable_undo_commit(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    int             rc = MFD_SUCCESS;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_undo_commit",
                "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:485:M: |-> Undo usmDHUserKeyTable commit.
     * check the column's flag in rowreq_ctx->column_set_flags to see
     * if it was set during commit, then undo it.
     *
     * eg: if (rowreq_ctx->column_set_flags & COLUMN__FLAG) {}
     */


    /*
     * if we successfully un-commited this row, clear the dirty flag.
     */
    if (MFD_SUCCESS == rc) {
        rowreq_ctx->rowreq_flags &= ~MFD_ROW_DIRTY;
    }

    return rc;
}                               /* usmDHUserKeyTable_undo_commit */

/**
 * perform commit actions that are not reversible
 *
 * THERE IS NO ATTEMPT AT RECOVERY FOR ERRORS FROM THIS STATE!
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : other error
 */
int
usmDHUserKeyTable_irreversible_commit(usmDHUserKeyTable_rowreq_ctx *
                                      rowreq_ctx)
{
    struct usmUser *user;
    int             flags;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserKeyTable_irreversible_commit", "called\n"));

    /** we should have a non-NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:495:o: Irreversible usmDHUserKeyTable commit.
     */
    user = rowreq_ctx->data;
    flags = rowreq_ctx->column_set_flags;

    if (flags & COLUMN_USMDHUSERAUTHKEYCHANGE_FLAG ||
        flags & COLUMN_USMDHUSEROWNAUTHKEYCHANGE_FLAG) {
        /*
         * free the keychange objects so they reset to new values 
         */
        DH_free(user->usmDHUserAuthKeyChange);
        user->usmDHUserAuthKeyChange = NULL;
    }

    if (flags & COLUMN_USMDHUSERPRIVKEYCHANGE_FLAG ||
        flags & COLUMN_USMDHUSEROWNPRIVKEYCHANGE_FLAG) {
        /*
         * free the keychange objects so they reset to new values 
         */
        DH_free(user->usmDHUserPrivKeyChange);
        user->usmDHUserPrivKeyChange = NULL;
    }

    return MFD_SUCCESS;
}                               /* usmDHUserKeyTable_irreversible_commit */

/*
 * TODO:440:M: Implement usmDHUserKeyTable node value checks.
 * TODO:450:M: Implement usmDHUserKeyTable undo functions.
 * TODO:460:M: Implement usmDHUserKeyTable set functions.
 * TODO:480:M: Implement usmDHUserKeyTable commit functions.
 */
/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserAuthKeyChange
 * usmDHUserAuthKeyChange is subid 1 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.1
 * Description:
The object used to change any given user's Authentication Key
    using a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserAuthProtocol, are installed as the operational
    authentication key for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserAuthKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserAuthKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                   rowreq_ctx,
                                   char *usmDHUserAuthKeyChange_val_ptr,
                                   size_t
                                   usmDHUserAuthKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserAuthKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserAuthKeyChange value.
     */
    return usmDHUserCheckValue(rowreq_ctx->data, 1,
                               usmDHUserAuthKeyChange_val_ptr,
                               usmDHUserAuthKeyChange_val_ptr_len);
}                               /* usmDHUserAuthKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserAuthKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                  rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserAuthKeyChange undo.
     */
    /*
     * copy usmDHUserAuthKeyChange and usmDHUserAuthKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserAuthKeyChange from rowreq_ctx->data->usmDHUserAuthKeyChange
     */
    undouser = rowreq_ctx->undo;

    undouser->authKeyLen = rowreq_ctx->data->authKeyLen;
    memdup(&undouser->authKey, rowreq_ctx->data->authKey,
           rowreq_ctx->data->authKeyLen);

    return MFD_SUCCESS;
}                               /* usmDHUserAuthKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserAuthKeyChange_val_ptr
 */
int
usmDHUserAuthKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                           char *usmDHUserAuthKeyChange_val_ptr,
                           size_t usmDHUserAuthKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserAuthKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserAuthKeyChange value.
     * set usmDHUserAuthKeyChange value in rowreq_ctx->data
     */
    usmDHSetKey(rowreq_ctx->data, 1,
                usmDHUserAuthKeyChange_val_ptr,
                usmDHUserAuthKeyChange_val_ptr_len);

    return MFD_SUCCESS;
}                               /* usmDHUserAuthKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserAuthKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserAuthKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserAuthKeyChange undo.
     */
    /*
     * copy usmDHUserAuthKeyChange and usmDHUserAuthKeyChange_len data
     * set rowreq_ctx->data->usmDHUserAuthKeyChange from rowreq_ctx->undo->usmDHUserAuthKeyChange
     */
    undouser = rowreq_ctx->undo;

    undouser->authKeyLen = rowreq_ctx->data->authKeyLen;
    SNMP_FREE(rowreq_ctx->data->authKey);
    rowreq_ctx->data->authKey = undouser->authKey;
    undouser->authKey = NULL;

    return MFD_SUCCESS;
}                               /* usmDHUserAuthKeyChange_undo */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserOwnAuthKeyChange
 * usmDHUserOwnAuthKeyChange is subid 2 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.2
 * Description:
The object used to change the agents own Authentication Key
    using a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserAuthProtocol, are installed as the operational
    authentication key for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserOwnAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnAuthKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserOwnAuthKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                      rowreq_ctx, char
                                      *usmDHUserOwnAuthKeyChange_val_ptr, size_t
                                      usmDHUserOwnAuthKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnAuthKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserOwnAuthKeyChange value.
     */
    return
        usmDHUserAuthKeyChange_check_value(rowreq_ctx,
                                           usmDHUserOwnAuthKeyChange_val_ptr,
                                           usmDHUserOwnAuthKeyChange_val_ptr_len);
}                               /* usmDHUserOwnAuthKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserOwnAuthKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserOwnAuthKeyChange undo.
     */
    /*
     * copy usmDHUserOwnAuthKeyChange and usmDHUserOwnAuthKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserOwnAuthKeyChange from rowreq_ctx->data->usmDHUserOwnAuthKeyChange
     */
    return usmDHUserAuthKeyChange_undo_setup(rowreq_ctx);
}                               /* usmDHUserOwnAuthKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserOwnAuthKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnAuthKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnAuthKeyChange_val_ptr
 */
int
usmDHUserOwnAuthKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              char *usmDHUserOwnAuthKeyChange_val_ptr,
                              size_t usmDHUserOwnAuthKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnAuthKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserOwnAuthKeyChange value.
     * set usmDHUserOwnAuthKeyChange value in rowreq_ctx->data
     */
    return usmDHUserAuthKeyChange_set(rowreq_ctx,
                                      usmDHUserOwnAuthKeyChange_val_ptr,
                                      usmDHUserOwnAuthKeyChange_val_ptr_len);
}                               /* usmDHUserOwnAuthKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserOwnAuthKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnAuthKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserOwnAuthKeyChange undo.
     */
    /*
     * copy usmDHUserOwnAuthKeyChange and usmDHUserOwnAuthKeyChange_len data
     * set rowreq_ctx->data->usmDHUserOwnAuthKeyChange from rowreq_ctx->undo->usmDHUserOwnAuthKeyChange
     */
    return usmDHUserAuthKeyChange_undo(rowreq_ctx);
}                               /* usmDHUserOwnAuthKeyChange_undo */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserPrivKeyChange
 * usmDHUserPrivKeyChange is subid 3 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.3
 * Description:
The object used to change any given user's Privacy Key using
    a Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserPrivProtocol, are installed as the operational privacy key
    for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserPrivKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserPrivKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                   rowreq_ctx,
                                   char *usmDHUserPrivKeyChange_val_ptr,
                                   size_t
                                   usmDHUserPrivKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserPrivKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserPrivKeyChange value.
     */
    return usmDHUserCheckValue(rowreq_ctx->data, 0,
                               usmDHUserPrivKeyChange_val_ptr,
                               usmDHUserPrivKeyChange_val_ptr_len);
}                               /* usmDHUserPrivKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserPrivKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                  rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserPrivKeyChange undo.
     */
    /*
     * copy usmDHUserPrivKeyChange and usmDHUserPrivKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserPrivKeyChange from rowreq_ctx->data->usmDHUserPrivKeyChange
     */
    undouser = rowreq_ctx->undo;

    undouser->privKeyLen = rowreq_ctx->data->privKeyLen;
    memdup(&undouser->privKey, rowreq_ctx->data->privKey,
           rowreq_ctx->data->privKeyLen);

    return MFD_SUCCESS;
}                               /* usmDHUserPrivKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserPrivKeyChange_val_ptr
 */
int
usmDHUserPrivKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                           char *usmDHUserPrivKeyChange_val_ptr,
                           size_t usmDHUserPrivKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserPrivKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserPrivKeyChange value.
     * set usmDHUserPrivKeyChange value in rowreq_ctx->data
     */
    usmDHSetKey(rowreq_ctx->data, 0,
                usmDHUserPrivKeyChange_val_ptr,
                usmDHUserPrivKeyChange_val_ptr_len);

    return MFD_SUCCESS;
}                               /* usmDHUserPrivKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserPrivKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{
    struct usmUser *undouser;

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserPrivKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserPrivKeyChange undo.
     */
    /*
     * copy usmDHUserPrivKeyChange and usmDHUserPrivKeyChange_len data
     * set rowreq_ctx->data->usmDHUserPrivKeyChange from rowreq_ctx->undo->usmDHUserPrivKeyChange
     */
    undouser = rowreq_ctx->undo;

    /** uncopy priv key */
    undouser->privKeyLen = rowreq_ctx->data->privKeyLen;
    SNMP_FREE(rowreq_ctx->data->privKey);
    rowreq_ctx->data->privKey = undouser->privKey;
    undouser->privKey = NULL;

    return MFD_SUCCESS;
}                               /* usmDHUserPrivKeyChange_undo */

/*---------------------------------------------------------------------
 * SNMP-USM-DH-OBJECTS-MIB::usmDHUserKeyEntry.usmDHUserOwnPrivKeyChange
 * usmDHUserOwnPrivKeyChange is subid 4 of usmDHUserKeyEntry.
 * Its status is Current, and its access level is Create.
 * OID: .1.3.6.1.3.101.1.1.2.1.4
 * Description:
The object used to change the agent's own Privacy Key using a
    Diffie-Hellman key exchange.

    The right-most n bits of the shared secret 'sk', where 'n' is the
    number of bits required for the protocol defined by
    usmUserPrivProtocol, are installed as the operational privacy key
    for this row after a successful SET.
 *
 * Attributes:
 *   accessible 1     isscalar 0     enums  0      hasdefval 0
 *   readable   1     iscolumn 1     ranges 0      hashint   0
 *   settable   1
 *
 *
 * Its syntax is DHKeyChange (based on perltype OCTETSTR)
 * The net-snmp type is ASN_OCTET_STR. The C type decl is char (char)
 * This data type requires a length.
 */
/**
 * Check that the proposed new value is potentially valid.
 *
 * @param rowreq_ctx
 *        Pointer to the row request context.
 * @param usmDHUserOwnPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnPrivKeyChange_val_ptr
 *
 * @retval MFD_SUCCESS        : incoming value is legal
 * @retval MFD_NOT_VALID_NOW  : incoming value is not valid now
 * @retval MFD_NOT_VALID_EVER : incoming value is never valid
 *
 * This is the place to check for requirements that are not
 * expressed in the mib syntax (for example, a requirement that
 * is detailed in the description for an object).
 *
 * Since you aren't using a generated data context, you also need to
 * check the length, to make sure you don't overflow your storage space.
 *
 * You should check that the requested change between the undo value and the
 * new value is legal (ie, the transistion from one value to another
 * is legal).
 *      
 *@note
 * This check is only to determine if the new value
 * is \b potentially valid. This is the first check of many, and
 * is one of the simplest ones.
 * 
 *@note
 * this is not the place to do any checks for values
 * which depend on some other value in the mib. Those
 * types of checks should be done in the
 * usmDHUserKeyTable_check_dependencies() function.
 *
 * The following checks have already been done for you:
 *    The syntax is ASN_OCTET_STR
 *
 * If there a no other checks you need to do, simply return MFD_SUCCESS.
 *
 */
int
usmDHUserOwnPrivKeyChange_check_value(usmDHUserKeyTable_rowreq_ctx *
                                      rowreq_ctx, char
                                      *usmDHUserOwnPrivKeyChange_val_ptr, size_t
                                      usmDHUserOwnPrivKeyChange_val_ptr_len)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_check_value", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnPrivKeyChange_val_ptr);

    /*
     * TODO:441:o: |-> Check for valid usmDHUserOwnPrivKeyChange value.
     */
    return
        usmDHUserPrivKeyChange_check_value(rowreq_ctx,
                                           usmDHUserOwnPrivKeyChange_val_ptr,
                                           usmDHUserOwnPrivKeyChange_val_ptr_len);
}                               /* usmDHUserOwnPrivKeyChange_check_value */

/**
 * Save old value information
 *
 * @param rowreq_ctx
 *        Pointer to the table context (usmDHUserKeyTable_rowreq_ctx)
 *
 * @retval MFD_SUCCESS : success
 * @retval MFD_ERROR   : error. set will fail.
 *
 * This function will be called after the table level undo setup function
 * usmDHUserKeyTable_undo_setup has been called.
 *
 *@note
 * this function will only be called if a new value is set for this column.
 *
 * If there is any setup specific to a particular column (e.g. allocating
 * memory for a string), you should do that setup in this function, so it
 * won't be done unless it is necessary.
 */
int
usmDHUserOwnPrivKeyChange_undo_setup(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx)
{
    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_undo_setup", "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:455:o: |-> Setup usmDHUserOwnPrivKeyChange undo.
     */
    /*
     * copy usmDHUserOwnPrivKeyChange and usmDHUserOwnPrivKeyChange_len data
     * set rowreq_ctx->undo->usmDHUserOwnPrivKeyChange from rowreq_ctx->data->usmDHUserOwnPrivKeyChange
     */
    return usmDHUserPrivKeyChange_undo_setup(rowreq_ctx);
}                               /* usmDHUserOwnPrivKeyChange_undo_setup */

/**
 * Set the new value.
 *
 * @param rowreq_ctx
 *        Pointer to the users context. You should know how to
 *        manipulate the value from this object.
 * @param usmDHUserOwnPrivKeyChange_val_ptr
 *        A char containing the new value.
 * @param usmDHUserOwnPrivKeyChange_val_ptr_len
 *        The size (in bytes) of the data pointed to by usmDHUserOwnPrivKeyChange_val_ptr
 */
int
usmDHUserOwnPrivKeyChange_set(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx,
                              char *usmDHUserOwnPrivKeyChange_val_ptr,
                              size_t usmDHUserOwnPrivKeyChange_val_ptr_len)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_set",
                "called\n"));

    /** should never get a NULL pointer */
    netsnmp_assert(NULL != rowreq_ctx);
    netsnmp_assert(NULL != usmDHUserOwnPrivKeyChange_val_ptr);

    /*
     * TODO:461:M: |-> Set usmDHUserOwnPrivKeyChange value.
     * set usmDHUserOwnPrivKeyChange value in rowreq_ctx->data
     */
    return usmDHUserPrivKeyChange_set(rowreq_ctx,
                                      usmDHUserOwnPrivKeyChange_val_ptr,
                                      usmDHUserOwnPrivKeyChange_val_ptr_len);
}                               /* usmDHUserOwnPrivKeyChange_set */

/**
 * undo the previous set.
 *
 * @param rowreq_ctx
 *        Pointer to the users context.
 */
int
usmDHUserOwnPrivKeyChange_undo(usmDHUserKeyTable_rowreq_ctx * rowreq_ctx)
{

    DEBUGMSGTL(("verbose:usmDHUserKeyTable:usmDHUserOwnPrivKeyChange_undo",
                "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:456:o: |-> Clean up usmDHUserOwnPrivKeyChange undo.
     */
    /*
     * copy usmDHUserOwnPrivKeyChange and usmDHUserOwnPrivKeyChange_len data
     * set rowreq_ctx->data->usmDHUserOwnPrivKeyChange from rowreq_ctx->undo->usmDHUserOwnPrivKeyChange
     */
    return usmDHUserPrivKeyChange_undo(rowreq_ctx);
}                               /* usmDHUserOwnPrivKeyChange_undo */

/**
 * check dependencies
 *
 * This is useful for for tables which have dependencies between columns
 * (or rows, or tables). For example, two columns allocating a percentage
 * of something add up 100%.
 *
 * Should you need different behavior depending on which columns were
 * set, rowreq_ctx->column_set_flags will indicate which writeable columns were
 * set. The definitions for the COLUMN_*_FLAG bits can be found in
 * usmDHUserKeyTable_oids.h.
 * A new row will have the MFD_ROW_CREATED bit set in rowreq_flags.
 *
 * @retval MFD_SUCCESS all the changes to the row are legal
 * @retval MFD_ERROR   one or more changes are not legal
 *
 * (see README-table-usmDHUserKeyTable if you don't have dependencies)
 */
int
usmDHUserKeyTable_check_dependencies(usmDHUserKeyTable_rowreq_ctx *
                                     rowreq_ctx)
{
    int             rc = MFD_SUCCESS;
    int             flags;

    DEBUGMSGTL(("internal:usmDHUserKeyTable:usmDHUserKeyTable_check_dependencies", "called\n"));

    netsnmp_assert(NULL != rowreq_ctx);

    /*
     * TODO:470:o: Check usmDHUserKeyTable row dependencies.
     * check that all new value are legal and consistent with each other
     */
    flags = rowreq_ctx->column_set_flags;

    if (flags & COLUMN_USMDHUSERAUTHKEYCHANGE_FLAG &&
        flags & COLUMN_USMDHUSEROWNAUTHKEYCHANGE_FLAG) {
        return MFD_ERROR;
    }

    if (flags & COLUMN_USMDHUSERPRIVKEYCHANGE_FLAG &&
        flags & COLUMN_USMDHUSEROWNPRIVKEYCHANGE_FLAG) {
        return MFD_ERROR;
    }

    return rc;
}                               /* usmDHUserKeyTable_check_dependencies */

/** @} */
