/*
 * usmUser.c
 */

#include <net-snmp/net-snmp-config.h>
#include <stdlib.h>

#if HAVE_STRING_H
#include <string.h>
#else
#include <strings.h>
#endif

#include <net-snmp/net-snmp-includes.h>
#include <net-snmp/agent/net-snmp-agent-includes.h>

#include "util_funcs/header_generic.h"
#include "usmUser.h"

int usmStatusCheck(struct usmUser *uptr);

struct variable4 usmUser_variables[] = {
    {USMUSERSPINLOCK, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 1, {1}},
    {USMUSERSECURITYNAME, ASN_OCTET_STR, NETSNMP_OLDAPI_RONLY,
     var_usmUser, 3, {2, 1, 3}},
    {USMUSERCLONEFROM, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 4}},
    {USMUSERAUTHPROTOCOL, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 5}},
    {USMUSERAUTHKEYCHANGE, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 6}},
    {USMUSEROWNAUTHKEYCHANGE, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 7}},
    {USMUSERPRIVPROTOCOL, ASN_OBJECT_ID, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 8}},
    {USMUSERPRIVKEYCHANGE, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 9}},
    {USMUSEROWNPRIVKEYCHANGE, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 10}},
    {USMUSERPUBLIC, ASN_OCTET_STR, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 11}},
    {USMUSERSTORAGETYPE, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 12}},
    {USMUSERSTATUS, ASN_INTEGER, NETSNMP_OLDAPI_RWRITE,
     var_usmUser, 3, {2, 1, 13}},

};

oid             usmUser_variables_oid[] = { 1, 3, 6, 1, 6, 3, 15, 1, 2 };


/*
 * needed for the write_ functions to find the start of the index 
 */
#define USM_MIB_LENGTH 12

static unsigned int usmUserSpinLock = 0;

void
init_usmUser(void)
{
    REGISTER_MIB("snmpv3/usmUser", usmUser_variables, variable4,
                 usmUser_variables_oid);
}

void
init_register_usmUser_context(const char *contextName) {
    register_mib_context("snmpv3/usmUser",
                         (struct variable *) usmUser_variables,
                         sizeof(struct variable4),
                         sizeof(usmUser_variables)/sizeof(struct variable4),
                         usmUser_variables_oid,
                         sizeof(usmUser_variables_oid)/sizeof(oid),
                         DEFAULT_MIB_PRIORITY, 0, 0, NULL,
                         contextName, -1, 0);
}

/*******************************************************************-o-******
 * usm_generate_OID
 *
 * Parameters:
 *	*prefix		(I) OID prefix to the usmUser table entry.
 *	 prefixLen	(I)
 *	*uptr		(I) Pointer to a user in the user list.
 *	*length		(O) Length of generated index OID.
 *      
 * Returns:
 *	Pointer to the OID index for the user (uptr)  -OR-
 *	NULL on failure.
 *
 *
 * Generate the index OID for a given usmUser name.  'length' is set to
 * the length of the index OID.
 *
 * Index OID format is:
 *
 *    <...prefix>.<engineID_length>.<engineID>.<user_name_length>.<user_name>
 */
oid            *
usm_generate_OID(oid * prefix, size_t prefixLen, struct usmUser *uptr,
                 size_t * length)
{
    oid            *indexOid;
    int             i;

    *length = 2 + uptr->engineIDLen + strlen(uptr->name) + prefixLen;
    indexOid = (oid *) malloc(*length * sizeof(oid));
    if (indexOid) {
        memmove(indexOid, prefix, prefixLen * sizeof(oid));

        indexOid[prefixLen] = uptr->engineIDLen;
        for (i = 0; i < (int) uptr->engineIDLen; i++)
            indexOid[prefixLen + 1 + i] = (oid) uptr->engineID[i];

        indexOid[prefixLen + uptr->engineIDLen + 1] = strlen(uptr->name);
        for (i = 0; i < (int) strlen(uptr->name); i++)
            indexOid[prefixLen + uptr->engineIDLen + 2 + i] =
                (oid) uptr->name[i];
    }
    return indexOid;

}                               /* end usm_generate_OID() */

/*
 * usm_parse_oid(): parses an index to the usmTable to break it down into
 * a engineID component and a name component.  The results are stored in:
 * 
 * **engineID:   a newly malloced string.
 * *engineIDLen: The length of the malloced engineID string above.
 * **name:       a newly malloced string.
 * *nameLen:     The length of the malloced name string above.
 * 
 * returns 1 if an error is encountered, or 0 if successful.
 */
int
usm_parse_oid(oid * oidIndex, size_t oidLen,
              unsigned char **engineID, size_t * engineIDLen,
              unsigned char **name, size_t * nameLen)
{
    int             nameL;
    int             engineIDL;
    int             i;

    /*
     * first check the validity of the oid 
     */
    if ((oidLen <= 0) || (!oidIndex)) {
        DEBUGMSGTL(("usmUser",
                    "parse_oid: null oid or zero length oid passed in\n"));
        return 1;
    }
    engineIDL = *oidIndex;      /* initial engineID length */
    if ((int) oidLen < engineIDL + 2) {
        DEBUGMSGTL(("usmUser",
                    "parse_oid: invalid oid length: less than the engineIDLen\n"));
        return 1;
    }
    nameL = oidIndex[engineIDL + 1];    /* the initial name length */
    if ((int) oidLen != engineIDL + nameL + 2) {
        DEBUGMSGTL(("usmUser",
                    "parse_oid: invalid oid length: length is not exact\n"));
        return 1;
    }

    /*
     * its valid, malloc the space and store the results 
     */
    if (engineID == NULL || name == NULL) {
        DEBUGMSGTL(("usmUser",
                    "parse_oid: null storage pointer passed in.\n"));
        return 1;
    }

    *engineID = (unsigned char *) malloc(engineIDL);
    if (*engineID == NULL) {
        DEBUGMSGTL(("usmUser",
                    "parse_oid: malloc of the engineID failed\n"));
        return 1;
    }
    *engineIDLen = engineIDL;

    *name = (unsigned char *) malloc(nameL + 1);
    if (*name == NULL) {
        DEBUGMSGTL(("usmUser", "parse_oid: malloc of the name failed\n"));
        free(*engineID);
        return 1;
    }
    *nameLen = nameL;

    for (i = 0; i < engineIDL; i++) {
        if (oidIndex[i + 1] > 255) {
            goto UPO_parse_error;
        }
        engineID[0][i] = (unsigned char) oidIndex[i + 1];
    }

    for (i = 0; i < nameL; i++) {
        if (oidIndex[i + 2 + engineIDL] > 255) {
          UPO_parse_error:
            free(*engineID);
            free(*name);
            return 1;
        }
        name[0][i] = (unsigned char) oidIndex[i + 2 + engineIDL];
    }
    name[0][nameL] = 0;

    return 0;

}                               /* end usm_parse_oid() */

/*******************************************************************-o-******
 * usm_parse_user
 *
 * Parameters:
 *	*name		Complete OID indexing a given usmUser entry.
 *	 name_length
 *      
 * Returns:
 *	Pointer to a usmUser  -OR-
 *	NULL if name does not convert to a usmUser.
 * 
 * Convert an (full) OID and return a pointer to a matching user in the
 * user list if one exists.
 */
struct usmUser *
usm_parse_user(oid * name, size_t name_len)
{
    struct usmUser *uptr;

    char           *newName;
    u_char         *engineID;
    size_t          nameLen, engineIDLen;

    /*
     * get the name and engineID out of the incoming oid 
     */
    if (usm_parse_oid(&name[USM_MIB_LENGTH], name_len - USM_MIB_LENGTH,
                      &engineID, &engineIDLen, (u_char **) & newName,
                      &nameLen))
        return NULL;

    /*
     * Now see if a user exists with these index values 
     */
    uptr = usm_get_user(engineID, engineIDLen, newName);
    free(engineID);
    free(newName);

    return uptr;

}                               /* end usm_parse_user() */

/*******************************************************************-o-******
 * var_usmUser
 *
 * Parameters:
 *	  *vp	   (I)     Variable-binding associated with this action.
 *	  *name	   (I/O)   Input name requested, output name found.
 *	  *length  (I/O)   Length of input and output oid's.
 *	   exact   (I)     TRUE if an exact match was requested.
 *	  *var_len (O)     Length of variable or 0 if function returned.
 *	(**write_method)   Hook to name a write method (UNUSED).
 *      
 * Returns:
 *	Pointer to (char *) containing related data of length 'length'
 *	  (May be NULL.)
 *
 *
 * Call-back function passed to the agent in order to return information
 * for the USM MIB tree.
 *
 *
 * If this invocation is not for USMUSERSPINLOCK, lookup user name
 * in the usmUser list.
 *
 * If the name does not match any user and the request
 * is for an exact match, -or- if the usmUser list is empty, create a 
 * new list entry.
 *
 * Finally, service the given USMUSER* var-bind.  A NULL user generally
 * results in a NULL return value.
 */
u_char         *
var_usmUser(struct variable * vp,
            oid * name,
            size_t * length,
            int exact, size_t * var_len, WriteMethod ** write_method)
{
    struct usmUser *uptr = NULL, *nptr;
    int             i, rtest, result;
    oid            *indexOid;
    size_t          len;

    /*
     * variables we may use later 
     */
    static long     long_ret;
    static u_char   string[1];
    static oid      objid[2];   /* for .0.0 */

    if (!vp || !name || !length || !var_len)
        return NULL;

    *write_method = (WriteMethod*)0;    /* assume it isnt writable for the time being */
    *var_len = sizeof(long_ret);        /* assume an integer and change later if not */

    if (vp->magic != USMUSERSPINLOCK) {
        oid             newname[MAX_OID_LEN];
        len = (*length < vp->namelen) ? *length : vp->namelen;
        rtest = snmp_oid_compare(name, len, vp->name, len);
        if (rtest > 0 ||
            /*
             * (rtest == 0 && !exact && (int) vp->namelen+1 < (int) *length) || 
             */
            (exact == 1 && rtest != 0)) {
            if (var_len)
                *var_len = 0;
            return NULL;
        }
        memset(newname, 0, sizeof(newname));
        if (((int) *length) <= (int) vp->namelen || rtest == -1) {
            /*
             * oid is not within our range yet 
             */
            /*
             * need to fail if not exact 
             */
            uptr = usm_get_userList();

        } else {
            for (nptr = usm_get_userList(), uptr = NULL;
                 nptr != NULL; nptr = nptr->next) {
                indexOid =
                    usm_generate_OID(vp->name, vp->namelen, nptr, &len);
                result = snmp_oid_compare(name, *length, indexOid, len);
                DEBUGMSGTL(("usmUser", "Checking user: %s - ",
                            nptr->name));
                for (i = 0; i < (int) nptr->engineIDLen; i++) {
                    DEBUGMSG(("usmUser", " %x", nptr->engineID[i]));
                }
                DEBUGMSG(("usmUser", " - %d \n  -> OID: ", result));
                DEBUGMSGOID(("usmUser", indexOid, len));
                DEBUGMSG(("usmUser", "\n"));

                free(indexOid);

                if (exact) {
                    if (result == 0) {
                        uptr = nptr;
                    }
                } else {
                    if (result == 0) {
                        /*
                         * found an exact match.  Need the next one for !exact 
                         */
                        uptr = nptr->next;
                    } else if (result == -1) {
                        uptr = nptr;
                        break;
                    }
                }
            }
        }                       /* endif -- name <= vp->name */

        /*
         * if uptr is NULL and exact we need to continue for creates 
         */
        if (uptr == NULL && !exact)
            return (NULL);

        if (uptr) {
            indexOid = usm_generate_OID(vp->name, vp->namelen, uptr, &len);
            *length = len;
            memmove(name, indexOid, len * sizeof(oid));
            DEBUGMSGTL(("usmUser", "Found user: %s - ", uptr->name));
            for (i = 0; i < (int) uptr->engineIDLen; i++) {
                DEBUGMSG(("usmUser", " %x", uptr->engineID[i]));
            }
            DEBUGMSG(("usmUser", "\n  -> OID: "));
            DEBUGMSGOID(("usmUser", indexOid, len));
            DEBUGMSG(("usmUser", "\n"));

            free(indexOid);
        }
    } else {
        if (header_generic(vp, name, length, exact, var_len, write_method))
            return NULL;
    }                           /* endif -- vp->magic != USMUSERSPINLOCK */

    switch (vp->magic) {
    case USMUSERSPINLOCK:
        *write_method = write_usmUserSpinLock;
        long_ret = usmUserSpinLock;
        return (unsigned char *) &long_ret;

    case USMUSERSECURITYNAME:
        if (uptr) {
            *var_len = strlen(uptr->secName);
            return (unsigned char *) uptr->secName;
        }
        return NULL;

    case USMUSERCLONEFROM:
        *write_method = write_usmUserCloneFrom;
        if (uptr) {
            objid[0] = 0;       /* "When this object is read, the ZeroDotZero OID */
            objid[1] = 0;       /*  is returned." */
            *var_len = sizeof(oid) * 2;
            return (unsigned char *) objid;
        }
        return NULL;

    case USMUSERAUTHPROTOCOL:
        *write_method = write_usmUserAuthProtocol;
        if (uptr) {
            *var_len = uptr->authProtocolLen * sizeof(oid);
            return (u_char *) uptr->authProtocol;
        }
        return NULL;

    case USMUSERAUTHKEYCHANGE:
    case USMUSEROWNAUTHKEYCHANGE:
        /*
         * we treat these the same, and let the calling module
         * distinguish between them 
         */
        *write_method = write_usmUserAuthKeyChange;
        if (uptr) {
            *string = 0;        /* always return a NULL string */
            *var_len = 0;
            return string;
        }
        return NULL;

    case USMUSERPRIVPROTOCOL:
        *write_method = write_usmUserPrivProtocol;
        if (uptr) {
            *var_len = uptr->privProtocolLen * sizeof(oid);
            return (u_char *) uptr->privProtocol;
        }
        return NULL;

    case USMUSERPRIVKEYCHANGE:
    case USMUSEROWNPRIVKEYCHANGE:
        /*
         * we treat these the same, and let the calling module
         * distinguish between them 
         */
        *write_method = write_usmUserPrivKeyChange;
        if (uptr) {
            *string = 0;        /* always return a NULL string */
            *var_len = 0;
            return string;
        }
        return NULL;

    case USMUSERPUBLIC:
        *write_method = write_usmUserPublic;
        if (uptr) {
            if (uptr->userPublicString) {
                *var_len = uptr->userPublicStringLen;
                return uptr->userPublicString;
            }
            *string = 0;
            *var_len = 0;       /* return an empty string if the public
                                 * string hasn't been defined yet */
            return string;
        }
        return NULL;

    case USMUSERSTORAGETYPE:
        *write_method = write_usmUserStorageType;
        if (uptr) {
            long_ret = uptr->userStorageType;
            return (unsigned char *) &long_ret;
        }
        return NULL;

    case USMUSERSTATUS:
        *write_method = write_usmUserStatus;
        if (uptr) {
            long_ret = uptr->userStatus;
            return (unsigned char *) &long_ret;
        }
        return NULL;

    default:
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_usmUser\n",
                    vp->magic));
    }
    return NULL;

}                               /* end var_usmUser() */

/*
 * write_usmUserSpinLock(): called when a set is performed on the
 * usmUserSpinLock object 
 */
int
write_usmUserSpinLock(int action,
                      u_char * var_val,
                      u_char var_val_type,
                      size_t var_val_len,
                      u_char * statP, oid * name, size_t name_len)
{
    /*
     * variables we may use later 
     */
    static long     long_ret;

    if (var_val_type != ASN_INTEGER) {
        DEBUGMSGTL(("usmUser",
                    "write to usmUserSpinLock not ASN_INTEGER\n"));
        return SNMP_ERR_WRONGTYPE;
    }
    if (var_val_len > sizeof(long_ret)) {
        DEBUGMSGTL(("usmUser", "write to usmUserSpinLock: bad length\n"));
        return SNMP_ERR_WRONGLENGTH;
    }
    long_ret = *((long *) var_val);
    if (long_ret != (long) usmUserSpinLock)
        return SNMP_ERR_INCONSISTENTVALUE;
    if (action == COMMIT) {
        if (usmUserSpinLock == 2147483647)
            usmUserSpinLock = 0;
        else
            usmUserSpinLock++;
    }
    return SNMP_ERR_NOERROR;
}                               /* end write_usmUserSpinLock() */

/*******************************************************************-o-******
 * write_usmUserCloneFrom
 *
 * Parameters:
 *	 action
 *	*var_val
 *	 var_val_type
 *	 var_val_len
 *	*statP		(UNUSED)
 *	*name		OID of user to clone from.
 *	 name_len
 *      
 * Returns:
 *	SNMP_ERR_NOERROR		On success  -OR-  If user exists
 *					  and has already been cloned.
 *	SNMP_ERR_GENERR			Local function call failures.
 *	SNMP_ERR_INCONSISTENTNAME	'name' does not exist in user list
 *					  -OR-  user to clone from != RS_ACTIVE.
 *	SNMP_ERR_WRONGLENGTH		OID length > than local buffer size.
 *	SNMP_ERR_WRONGTYPE		ASN_OBJECT_ID is wrong.
 *
 *
 * XXX:  should handle action=UNDO's.
 */
int
write_usmUserCloneFrom(int action,
                       u_char * var_val,
                       u_char var_val_type,
                       size_t var_val_len,
                       u_char * statP, oid * name, size_t name_len)
{
    struct usmUser *uptr, *cloneFrom;

    if (action == RESERVE1) {
        if (var_val_type != ASN_OBJECT_ID) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserCloneFrom not ASN_OBJECT_ID\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > USM_LENGTH_OID_MAX * sizeof(oid) ||
            var_val_len % sizeof(oid) != 0) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserCloneFrom: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            /*
             * We don't allow creations here.  
             */
            return SNMP_ERR_INCONSISTENTNAME;
        }

        /*
         * Has the user already been cloned?  If so, writes to this variable
         * are defined to have no effect and to produce no error.  
         */
        if (uptr->cloneFrom != NULL) {
            return SNMP_ERR_NOERROR;
        }

        cloneFrom =
            usm_parse_user((oid *) var_val, var_val_len / sizeof(oid));
        if (cloneFrom == NULL || cloneFrom->userStatus != SNMP_ROW_ACTIVE) {
            return SNMP_ERR_INCONSISTENTNAME;
        }
        uptr->cloneFrom = snmp_duplicate_objid((oid *) var_val,
                                               var_val_len / sizeof(oid));
        usm_cloneFrom_user(cloneFrom, uptr);

        if (usmStatusCheck(uptr) && uptr->userStatus == SNMP_ROW_NOTREADY) {
            uptr->userStatus = SNMP_ROW_NOTINSERVICE;
        }
    }

    return SNMP_ERR_NOERROR;
}

/*******************************************************************-o-******
 * write_usmUserAuthProtocol
 *
 * Parameters:
 *	 action
 *	*var_val	OID of auth transform to set.
 *	 var_val_type
 *	 var_val_len
 *	*statP
 *	*name		OID of user upon which to perform set operation.
 *	 name_len
 *      
 * Returns:
 *	SNMP_ERR_NOERROR		On success.
 *	SNMP_ERR_GENERR
 *	SNMP_ERR_INCONSISTENTVALUE
 *	SNMP_ERR_NOSUCHNAME
 *	SNMP_ERR_WRONGLENGTH
 *	SNMP_ERR_WRONGTYPE
 */
int
write_usmUserAuthProtocol(int action,
                          u_char * var_val,
                          u_char var_val_type,
                          size_t var_val_len,
                          u_char * statP, oid * name, size_t name_len)
{
    static oid     *optr;
    static size_t   olen;
    static int      resetOnFail;
    struct usmUser *uptr;

    if (action == RESERVE1) {
        resetOnFail = 0;
        if (var_val_type != ASN_OBJECT_ID) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserAuthProtocol not ASN_OBJECT_ID\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > USM_LENGTH_OID_MAX * sizeof(oid) ||
            var_val_len % sizeof(oid) != 0) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserAuthProtocol: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        }

        if (uptr->userStatus == RS_ACTIVE
            || uptr->userStatus == RS_NOTREADY
            || uptr->userStatus == RS_NOTINSERVICE) {
            /*
             * The authProtocol is already set.  It is only legal to CHANGE it
             * to usmNoAuthProtocol...  
             */
            if (snmp_oid_compare
                ((oid *) var_val, var_val_len / sizeof(oid),
                 usmNoAuthProtocol,
                 sizeof(usmNoAuthProtocol) / sizeof(oid)) == 0) {
                /*
                 * ... and then only if the privProtocol is equal to
                 * usmNoPrivProtocol.  
                 */
                if (snmp_oid_compare
                    (uptr->privProtocol, uptr->privProtocolLen,
                     usmNoPrivProtocol,
                     sizeof(usmNoPrivProtocol) / sizeof(oid)) != 0) {
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
                optr = uptr->authProtocol;
                olen = uptr->authProtocolLen;
                resetOnFail = 1;
                uptr->authProtocol = snmp_duplicate_objid((oid *) var_val,
                                                          var_val_len /
                                                          sizeof(oid));
                if (uptr->authProtocol == NULL) {
                    return SNMP_ERR_RESOURCEUNAVAILABLE;
                }
                uptr->authProtocolLen = var_val_len / sizeof(oid);
            } else
                if (snmp_oid_compare
                    ((oid *) var_val, var_val_len / sizeof(oid),
                     uptr->authProtocol, uptr->authProtocolLen) == 0) {
                /*
                 * But it's also okay to set it to the same thing as it
                 * currently is.  
                 */
                return SNMP_ERR_NOERROR;
            } else {
                return SNMP_ERR_INCONSISTENTVALUE;
            }
        } else {
            /*
             * This row is under creation.  It's okay to set
             * usmUserAuthProtocol to any valid authProtocol but it will be
             * overwritten when usmUserCloneFrom is set (so don't write it if
             * that has already been set).  
             */

            if (snmp_oid_compare
                ((oid *) var_val, var_val_len / sizeof(oid),
                 usmNoAuthProtocol,
                 sizeof(usmNoAuthProtocol) / sizeof(oid)) == 0
#ifndef NETSNMP_DISABLE_MD5
                || snmp_oid_compare((oid *) var_val,
                                    var_val_len / sizeof(oid),
                                    usmHMACMD5AuthProtocol,
                                    sizeof(usmHMACMD5AuthProtocol) /
                                    sizeof(oid)) == 0
#endif
                || snmp_oid_compare((oid *) var_val,
                                    var_val_len / sizeof(oid),
                                    usmHMACSHA1AuthProtocol,
                                    sizeof(usmHMACSHA1AuthProtocol) /
                                    sizeof(oid)) == 0) {
                if (uptr->cloneFrom != NULL) {
                    optr = uptr->authProtocol;
                    olen = uptr->authProtocolLen;
                    resetOnFail = 1;
                    uptr->authProtocol =
                        snmp_duplicate_objid((oid *) var_val,
                                             var_val_len / sizeof(oid));
                    if (uptr->authProtocol == NULL) {
                        return SNMP_ERR_RESOURCEUNAVAILABLE;
                    }
                    uptr->authProtocolLen = var_val_len / sizeof(oid);
                }
            } else {
                /*
                 * Unknown authentication protocol.  
                 */
                return SNMP_ERR_WRONGVALUE;
            }
        }
    } else if (action == COMMIT) {
        SNMP_FREE(optr);
        optr = NULL;
    } else if (action == FREE || action == UNDO) {
        if ((uptr = usm_parse_user(name, name_len)) != NULL) {
            if (resetOnFail) {
                SNMP_FREE(uptr->authProtocol);
                uptr->authProtocol = optr;
                uptr->authProtocolLen = olen;
            }
        }
    }
    return SNMP_ERR_NOERROR;
}                               /* end write_usmUserAuthProtocol() */

/*******************************************************************-o-******
 * write_usmUserAuthKeyChange
 *
 * Parameters:
 *	 action		
 *	*var_val	Octet string representing new KeyChange value.
 *	 var_val_type
 *	 var_val_len
 *	*statP		(UNUSED)
 *	*name		OID of user upon which to perform set operation.
 *	 name_len
 *      
 * Returns:
 *	SNMP_ERR_NOERR		Success.
 *	SNMP_ERR_WRONGTYPE	
 *	SNMP_ERR_WRONGLENGTH	
 *	SNMP_ERR_NOSUCHNAME	
 *	SNMP_ERR_GENERR
 *
 * Note: This function handles both the usmUserAuthKeyChange and
 *       usmUserOwnAuthKeyChange objects.  We are not passed the name
 *       of the user requseting the keychange, so we leave this to the
 *       calling module to verify when and if we should be called.  To
 *       change this would require a change in the mib module API to
 *       pass in the securityName requesting the change.
 *
 * XXX:  should handle action=UNDO's.
 */
int
write_usmUserAuthKeyChange(int action,
                           u_char * var_val,
                           u_char var_val_type,
                           size_t var_val_len,
                           u_char * statP, oid * name, size_t name_len)
{
    struct usmUser *uptr;
    unsigned char   buf[SNMP_MAXBUF_SMALL];
    size_t          buflen = SNMP_MAXBUF_SMALL;
    const char      fnAuthKey[] = "write_usmUserAuthKeyChange";
    const char      fnOwnAuthKey[] = "write_usmUserOwnAuthKeyChange";
    const char     *fname;
    static unsigned char *oldkey;
    static size_t   oldkeylen;
    static int      resetOnFail;

    if (name[USM_MIB_LENGTH - 1] == 6) {
        fname = fnAuthKey;
    } else {
        fname = fnOwnAuthKey;
    }

    if (action == RESERVE1) {
        resetOnFail = 0;
        if (var_val_type != ASN_OCTET_STR) {
            DEBUGMSGTL(("usmUser", "write to %s not ASN_OCTET_STR\n",
                        fname));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len == 0) {
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
#ifndef NETSNMP_DISABLE_MD5
            if (snmp_oid_compare(uptr->authProtocol, uptr->authProtocolLen,
                                 usmHMACMD5AuthProtocol,
                                 sizeof(usmHMACMD5AuthProtocol) /
                                 sizeof(oid)) == 0) {
                if (var_val_len != 0 && var_val_len != 32) {
                    return SNMP_ERR_WRONGLENGTH;
                }
            } else
#endif
                if (snmp_oid_compare
                    (uptr->authProtocol, uptr->authProtocolLen,
                     usmHMACSHA1AuthProtocol,
                     sizeof(usmHMACSHA1AuthProtocol) / sizeof(oid)) == 0) {
                if (var_val_len != 0 && var_val_len != 40) {
                    return SNMP_ERR_WRONGLENGTH;
                }
            }
        }
    } else if (action == ACTION) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        }
        if (uptr->cloneFrom == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        }
        if (snmp_oid_compare(uptr->authProtocol, uptr->authProtocolLen,
                             usmNoAuthProtocol,
                             sizeof(usmNoAuthProtocol) / sizeof(oid)) ==
            0) {
            /*
             * "When the value of the corresponding usmUserAuthProtocol is
             * usmNoAuthProtocol, then a set is successful, but effectively
             * is a no-op."  
             */
            DEBUGMSGTL(("usmUser",
                        "%s: noAuthProtocol keyChange... success!\n",
                        fname));
            return SNMP_ERR_NOERROR;
        }

        /*
         * Change the key.  
         */
        DEBUGMSGTL(("usmUser", "%s: changing auth key for user %s\n",
                    fname, uptr->secName));

        if (decode_keychange(uptr->authProtocol, uptr->authProtocolLen,
                             uptr->authKey, uptr->authKeyLen,
                             var_val, var_val_len,
                             buf, &buflen) != SNMPERR_SUCCESS) {
            DEBUGMSGTL(("usmUser", "%s: ... failed\n", fname));
            return SNMP_ERR_GENERR;
        }
        DEBUGMSGTL(("usmUser", "%s: ... succeeded\n", fname));
        resetOnFail = 1;
        oldkey = uptr->authKey;
        oldkeylen = uptr->authKeyLen;
        memdup(&uptr->authKey, buf, buflen);
        if (uptr->authKey == NULL) {
            return SNMP_ERR_RESOURCEUNAVAILABLE;
        }
        uptr->authKeyLen = buflen;
    } else if (action == COMMIT) {
        SNMP_FREE(oldkey);
        oldkey = NULL;
    } else if (action == UNDO) {
        if ((uptr = usm_parse_user(name, name_len)) != NULL && resetOnFail) {
            SNMP_FREE(uptr->authKey);
            uptr->authKey = oldkey;
            uptr->authKeyLen = oldkeylen;
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* end write_usmUserAuthKeyChange() */

int
write_usmUserPrivProtocol(int action,
                          u_char * var_val,
                          u_char var_val_type,
                          size_t var_val_len,
                          u_char * statP, oid * name, size_t name_len)
{
    static oid     *optr;
    static size_t   olen;
    static int      resetOnFail;
    struct usmUser *uptr;

    if (action == RESERVE1) {
        resetOnFail = 0;
        if (var_val_type != ASN_OBJECT_ID) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserPrivProtocol not ASN_OBJECT_ID\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len > USM_LENGTH_OID_MAX * sizeof(oid) ||
            var_val_len % sizeof(oid) != 0) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserPrivProtocol: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        }

        if (uptr->userStatus == RS_ACTIVE
            || uptr->userStatus == RS_NOTREADY
            || uptr->userStatus == RS_NOTINSERVICE) {
            /*
             * The privProtocol is already set.  It is only legal to CHANGE it
             * to usmNoPrivProtocol.  
             */
            if (snmp_oid_compare
                ((oid *) var_val, var_val_len / sizeof(oid),
                 usmNoPrivProtocol,
                 sizeof(usmNoPrivProtocol) / sizeof(oid)) == 0) {
                resetOnFail = 1;
                optr = uptr->privProtocol;
                olen = uptr->privProtocolLen;
                uptr->privProtocol = snmp_duplicate_objid((oid *) var_val,
                                                          var_val_len /
                                                          sizeof(oid));
                if (uptr->privProtocol == NULL) {
                    return SNMP_ERR_RESOURCEUNAVAILABLE;
                }
                uptr->privProtocolLen = var_val_len / sizeof(oid);
            } else
                if (snmp_oid_compare
                    ((oid *) var_val, var_val_len / sizeof(oid),
                     uptr->privProtocol, uptr->privProtocolLen) == 0) {
                /*
                 * But it's also okay to set it to the same thing as it
                 * currently is.  
                 */
                return SNMP_ERR_NOERROR;
            } else {
                return SNMP_ERR_INCONSISTENTVALUE;
            }
        } else {
            /*
             * This row is under creation.  It's okay to set
             * usmUserPrivProtocol to any valid privProtocol with the proviso
             * that if usmUserAuthProtocol is set to usmNoAuthProtocol, it may
             * only be set to usmNoPrivProtocol.  The value will be overwritten
             * when usmUserCloneFrom is set (so don't write it if that has
             * already been set).  
             */
            if (snmp_oid_compare(uptr->authProtocol, uptr->authProtocolLen,
                                 usmNoAuthProtocol,
                                 sizeof(usmNoAuthProtocol) /
                                 sizeof(oid)) == 0) {
                if (snmp_oid_compare
                    ((oid *) var_val, var_val_len / sizeof(oid),
                     usmNoPrivProtocol,
                     sizeof(usmNoPrivProtocol) / sizeof(oid)) != 0) {
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
            } else {
                if (snmp_oid_compare
                    ((oid *) var_val, var_val_len / sizeof(oid),
                     usmNoPrivProtocol,
                     sizeof(usmNoPrivProtocol) / sizeof(oid)) != 0
#ifndef NETSNMP_DISABLE_DES
                 && snmp_oid_compare
                    ((oid *) var_val, var_val_len / sizeof(oid),
                     usmDESPrivProtocol,
                     sizeof(usmDESPrivProtocol) / sizeof(oid)) != 0
#endif
                 && snmp_oid_compare
                    ((oid *) var_val, var_val_len / sizeof(oid),
                     usmAESPrivProtocol,
                     sizeof(usmAESPrivProtocol) / sizeof(oid)) != 0) {
                    return SNMP_ERR_WRONGVALUE;
                }
            }
            resetOnFail = 1;
            optr = uptr->privProtocol;
            olen = uptr->privProtocolLen;
            uptr->privProtocol = snmp_duplicate_objid((oid *) var_val,
                                                      var_val_len /
                                                      sizeof(oid));
            if (uptr->privProtocol == NULL) {
                return SNMP_ERR_RESOURCEUNAVAILABLE;
            }
            uptr->privProtocolLen = var_val_len / sizeof(oid);
        }
    } else if (action == COMMIT) {
        SNMP_FREE(optr);
        optr = NULL;
    } else if (action == FREE || action == UNDO) {
        if ((uptr = usm_parse_user(name, name_len)) != NULL) {
            if (resetOnFail) {
                SNMP_FREE(uptr->privProtocol);
                uptr->privProtocol = optr;
                uptr->privProtocolLen = olen;
            }
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* end write_usmUserPrivProtocol() */

/*
 * Note: This function handles both the usmUserPrivKeyChange and
 *       usmUserOwnPrivKeyChange objects.  We are not passed the name
 *       of the user requseting the keychange, so we leave this to the
 *       calling module to verify when and if we should be called.  To
 *       change this would require a change in the mib module API to
 *       pass in the securityName requesting the change.
 *
 */
int
write_usmUserPrivKeyChange(int action,
                           u_char * var_val,
                           u_char var_val_type,
                           size_t var_val_len,
                           u_char * statP, oid * name, size_t name_len)
{
    struct usmUser *uptr;
    unsigned char   buf[SNMP_MAXBUF_SMALL];
    size_t          buflen = SNMP_MAXBUF_SMALL;
    const char      fnPrivKey[] = "write_usmUserPrivKeyChange";
    const char      fnOwnPrivKey[] = "write_usmUserOwnPrivKeyChange";
    const char     *fname;
    static unsigned char *oldkey;
    static size_t   oldkeylen;
    static int      resetOnFail;

    if (name[USM_MIB_LENGTH - 1] == 9) {
        fname = fnPrivKey;
    } else {
        fname = fnOwnPrivKey;
    }

    if (action == RESERVE1) {
        resetOnFail = 0;
        if (var_val_type != ASN_OCTET_STR) {
            DEBUGMSGTL(("usmUser", "write to %s not ASN_OCTET_STR\n",
                        fname));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len == 0) {
            return SNMP_ERR_WRONGLENGTH;
        }
    } else if (action == RESERVE2) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        } else {
#ifndef NETSNMP_DISABLE_DES
            if (snmp_oid_compare(uptr->privProtocol, uptr->privProtocolLen,
                                 usmDESPrivProtocol,
                                 sizeof(usmDESPrivProtocol) /
                                 sizeof(oid)) == 0) {
                if (var_val_len != 0 && var_val_len != 32) {
                    return SNMP_ERR_WRONGLENGTH;
                }
            }
#endif
            if (snmp_oid_compare(uptr->privProtocol, uptr->privProtocolLen,
                                 usmAESPrivProtocol,
                                 sizeof(usmAESPrivProtocol) /
                                 sizeof(oid)) == 0) {
                if (var_val_len != 0 && var_val_len != 32) {
                    return SNMP_ERR_WRONGLENGTH;
                }
            }
        }
    } else if (action == ACTION) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        }
        if (uptr->cloneFrom == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        }
        if (snmp_oid_compare(uptr->privProtocol, uptr->privProtocolLen,
                             usmNoPrivProtocol,
                             sizeof(usmNoPrivProtocol) / sizeof(oid)) ==
            0) {
            /*
             * "When the value of the corresponding usmUserPrivProtocol is
             * usmNoPrivProtocol, then a set is successful, but effectively
             * is a no-op."  
             */
            DEBUGMSGTL(("usmUser",
                        "%s: noPrivProtocol keyChange... success!\n",
                        fname));
            return SNMP_ERR_NOERROR;
        }

        /*
         * Change the key. 
         */
        DEBUGMSGTL(("usmUser", "%s: changing priv key for user %s\n",
                    fname, uptr->secName));

        if (decode_keychange(uptr->authProtocol, uptr->authProtocolLen,
                             uptr->privKey, uptr->privKeyLen,
                             var_val, var_val_len,
                             buf, &buflen) != SNMPERR_SUCCESS) {
            DEBUGMSGTL(("usmUser", "%s: ... failed\n", fname));
            return SNMP_ERR_GENERR;
        }
        DEBUGMSGTL(("usmUser", "%s: ... succeeded\n", fname));
        resetOnFail = 1;
        oldkey = uptr->privKey;
        oldkeylen = uptr->privKeyLen;
        memdup(&uptr->privKey, buf, buflen);
        if (uptr->privKey == NULL) {
            return SNMP_ERR_RESOURCEUNAVAILABLE;
        }
        uptr->privKeyLen = buflen;
    } else if (action == COMMIT) {
        SNMP_FREE(oldkey);
        oldkey = NULL;
    } else if (action == UNDO) {
        if ((uptr = usm_parse_user(name, name_len)) != NULL && resetOnFail) {
            SNMP_FREE(uptr->privKey);
            uptr->privKey = oldkey;
            uptr->privKeyLen = oldkeylen;
        }
    }

    return SNMP_ERR_NOERROR;
}                               /* end write_usmUserPrivKeyChange() */

int
write_usmUserPublic(int action,
                    u_char * var_val,
                    u_char var_val_type,
                    size_t var_val_len,
                    u_char * statP, oid * name, size_t name_len)
{
    struct usmUser *uptr = NULL;

    if (var_val_type != ASN_OCTET_STR) {
        DEBUGMSGTL(("usmUser",
                    "write to usmUserPublic not ASN_OCTET_STR\n"));
        return SNMP_ERR_WRONGTYPE;
    }
    if (var_val_len > 32) {
        DEBUGMSGTL(("usmUser", "write to usmUserPublic: bad length\n"));
        return SNMP_ERR_WRONGLENGTH;
    }
    if (action == COMMIT) {
        /*
         * don't allow creations here 
         */
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_NOSUCHNAME;
        }
        if (uptr->userPublicString)
            free(uptr->userPublicString);
        uptr->userPublicString = (u_char *) malloc(var_val_len);
        if (uptr->userPublicString == NULL) {
            return SNMP_ERR_GENERR;
        }
        memcpy(uptr->userPublicString, var_val, var_val_len);
        uptr->userPublicStringLen = var_val_len;
        DEBUGMSG(("usmUser", "setting public string: %d - ", (int)var_val_len));
        DEBUGMSGHEX(("usmUser", uptr->userPublicString, var_val_len));
        DEBUGMSG(("usmUser", "\n"));
    }
    return SNMP_ERR_NOERROR;
}                               /* end write_usmUserPublic() */

int
write_usmUserStorageType(int action,
                         u_char * var_val,
                         u_char var_val_type,
                         size_t var_val_len,
                         u_char * statP, oid * name, size_t name_len)
{
    long            long_ret = *((long *) var_val);
    static long     oldValue;
    struct usmUser *uptr;
    static int      resetOnFail;

    if (action == RESERVE1) {
        resetOnFail = 0;
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserStorageType not ASN_INTEGER\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long)) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserStorageType: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
        if (long_ret < 1 || long_ret > 5) {
            return SNMP_ERR_WRONGVALUE;
        }
    } else if (action == RESERVE2) {
        if ((uptr = usm_parse_user(name, name_len)) == NULL) {
            return SNMP_ERR_INCONSISTENTNAME;
        }
        if ((long_ret == ST_VOLATILE || long_ret == ST_NONVOLATILE) &&
            (uptr->userStorageType == ST_VOLATILE ||
             uptr->userStorageType == ST_NONVOLATILE)) {
            oldValue = uptr->userStorageType;
            uptr->userStorageType = long_ret;
            resetOnFail = 1;
        } else {
            /*
             * From RFC2574:
             * 
             * "Note that any user who employs authentication or privacy must
             * allow its secret(s) to be updated and thus cannot be 'readOnly'.
             * 
             * If an initial set operation tries to set the value to 'readOnly'
             * for a user who employs authentication or privacy, then an
             * 'inconsistentValue' error must be returned.  Note that if the
             * value has been previously set (implicit or explicit) to any
             * value, then the rules as defined in the StorageType Textual
             * Convention apply.  
             */
            DEBUGMSGTL(("usmUser",
                        "long_ret %ld uptr->st %d uptr->status %d\n",
                        long_ret, uptr->userStorageType,
                        uptr->userStatus));

            if (long_ret == ST_READONLY &&
                uptr->userStorageType != ST_READONLY &&
                (uptr->userStatus == RS_ACTIVE ||
                 uptr->userStatus == RS_NOTINSERVICE)) {
                return SNMP_ERR_WRONGVALUE;
            } else if (long_ret == ST_READONLY &&
                       (snmp_oid_compare
                        (uptr->privProtocol, uptr->privProtocolLen,
                         usmNoPrivProtocol,
                         sizeof(usmNoPrivProtocol) / sizeof(oid)) != 0
                        || snmp_oid_compare(uptr->authProtocol,
                                            uptr->authProtocolLen,
                                            usmNoAuthProtocol,
                                            sizeof(usmNoAuthProtocol) /
                                            sizeof(oid)) != 0)) {
                return SNMP_ERR_INCONSISTENTVALUE;
            } else {
                return SNMP_ERR_WRONGVALUE;
            }
        }
    } else if (action == UNDO || action == FREE) {
        if ((uptr = usm_parse_user(name, name_len)) != NULL && resetOnFail) {
            uptr->userStorageType = oldValue;
        }
    }
    return SNMP_ERR_NOERROR;
}                               /* end write_usmUserStorageType() */

/*
 * Return 1 if enough objects have been set up to transition rowStatus to
 * notInService(2) or active(1).  
 */

int
usmStatusCheck(struct usmUser *uptr)
{
    if (uptr == NULL) {
        return 0;
    } else {
        if (uptr->cloneFrom == NULL) {
            return 0;
        }
    }
    return 1;
}

/*******************************************************************-o-******
 * write_usmUserStatus
 *
 * Parameters:
 *	 action
 *	*var_val
 *	 var_val_type
 *	 var_val_len
 *	*statP
 *	*name
 *	 name_len
 *      
 * Returns:
 *	SNMP_ERR_NOERROR		On success.
 *	SNMP_ERR_GENERR	
 *	SNMP_ERR_INCONSISTENTNAME
 *	SNMP_ERR_INCONSISTENTVALUE
 *	SNMP_ERR_WRONGLENGTH
 *	SNMP_ERR_WRONGTYPE
 */
int
write_usmUserStatus(int action,
                    u_char * var_val,
                    u_char var_val_type,
                    size_t var_val_len,
                    u_char * statP, oid * name, size_t name_len)
{
    /*
     * variables we may use later 
     */
    static long     long_ret;
    unsigned char  *engineID;
    size_t          engineIDLen;
    char           *newName;
    size_t          nameLen;
    struct usmUser *uptr = NULL;

    if (action == RESERVE1) {
        if (var_val_type != ASN_INTEGER) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserStatus not ASN_INTEGER\n"));
            return SNMP_ERR_WRONGTYPE;
        }
        if (var_val_len != sizeof(long_ret)) {
            DEBUGMSGTL(("usmUser",
                        "write to usmUserStatus: bad length\n"));
            return SNMP_ERR_WRONGLENGTH;
        }
        long_ret = *((long *) var_val);
        if (long_ret == RS_NOTREADY || long_ret < 1 || long_ret > 6) {
            return SNMP_ERR_WRONGVALUE;
        }

        /*
         * See if we can parse the oid for engineID/name first.  
         */
        if (usm_parse_oid(&name[USM_MIB_LENGTH], name_len - USM_MIB_LENGTH,
                          &engineID, &engineIDLen, (u_char **) & newName,
                          &nameLen)) {
            DEBUGMSGTL(("usmUser",
                        "can't parse the OID for engineID or name\n"));
            return SNMP_ERR_INCONSISTENTNAME;
        }

        if (engineIDLen < 5 || engineIDLen > 32 || nameLen < 1
            || nameLen > 32) {
            SNMP_FREE(engineID);
            SNMP_FREE(newName);
            return SNMP_ERR_NOCREATION;
        }

        /*
         * Now see if a user already exists with these index values. 
         */
        uptr = usm_get_user(engineID, engineIDLen, newName);

        if (uptr != NULL) {
            if (long_ret == RS_CREATEANDGO || long_ret == RS_CREATEANDWAIT) {
                SNMP_FREE(engineID);
                SNMP_FREE(newName);
                long_ret = RS_NOTREADY;
                return SNMP_ERR_INCONSISTENTVALUE;
            }
            SNMP_FREE(engineID);
            SNMP_FREE(newName);
        } else {
            if (long_ret == RS_ACTIVE || long_ret == RS_NOTINSERVICE) {
                SNMP_FREE(engineID);
                SNMP_FREE(newName);
                return SNMP_ERR_INCONSISTENTVALUE;
            }
            if (long_ret == RS_CREATEANDGO || long_ret == RS_CREATEANDWAIT) {
                if ((uptr = usm_create_user()) == NULL) {
                    SNMP_FREE(engineID);
                    SNMP_FREE(newName);
                    return SNMP_ERR_RESOURCEUNAVAILABLE;
                }
                uptr->engineID = engineID;
                uptr->name = newName;
                uptr->secName = strdup(uptr->name);
                if (uptr->secName == NULL) {
                    usm_free_user(uptr);
                    return SNMP_ERR_RESOURCEUNAVAILABLE;
                }
                uptr->engineIDLen = engineIDLen;

                /*
                 * Set status to createAndGo or createAndWait so we can tell
                 * that this row is under creation.  
                 */

                uptr->userStatus = long_ret;

                /*
                 * Add to the list of users (we will take it off again
                 * later if something goes wrong).  
                 */

                usm_add_user(uptr);
            } else {
                SNMP_FREE(engineID);
                SNMP_FREE(newName);
            }
        }
    } else if (action == ACTION) {
        usm_parse_oid(&name[USM_MIB_LENGTH], name_len - USM_MIB_LENGTH,
                      &engineID, &engineIDLen, (u_char **) & newName,
                      &nameLen);
        uptr = usm_get_user(engineID, engineIDLen, newName);
        SNMP_FREE(engineID);
        SNMP_FREE(newName);

        if (uptr != NULL) {
            if (long_ret == RS_CREATEANDGO || long_ret == RS_ACTIVE) {
                if (usmStatusCheck(uptr)) {
                    uptr->userStatus = RS_ACTIVE;
                } else {
                    SNMP_FREE(engineID);
                    SNMP_FREE(newName);
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
            } else if (long_ret == RS_CREATEANDWAIT) {
                if (usmStatusCheck(uptr)) {
                    uptr->userStatus = RS_NOTINSERVICE;
                } else {
                    uptr->userStatus = RS_NOTREADY;
                }
            } else if (long_ret == RS_NOTINSERVICE) {
                if (uptr->userStatus == RS_ACTIVE ||
                    uptr->userStatus == RS_NOTINSERVICE) {
                    uptr->userStatus = RS_NOTINSERVICE;
                } else {
                    return SNMP_ERR_INCONSISTENTVALUE;
                }
            }
        }
    } else if (action == COMMIT) {
        usm_parse_oid(&name[USM_MIB_LENGTH], name_len - USM_MIB_LENGTH,
                      &engineID, &engineIDLen, (u_char **) & newName,
                      &nameLen);
        uptr = usm_get_user(engineID, engineIDLen, newName);
        SNMP_FREE(engineID);
        SNMP_FREE(newName);

        if (uptr != NULL) {
            if (long_ret == RS_DESTROY) {
                usm_remove_user(uptr);
                usm_free_user(uptr);
            }
        }
    } else if (action == UNDO || action == FREE) {
        if (usm_parse_oid(&name[USM_MIB_LENGTH], name_len - USM_MIB_LENGTH,
                      &engineID, &engineIDLen, (u_char **) & newName,
                      &nameLen)) {
            /* Can't extract engine info from the OID - nothing to undo */
            return SNMP_ERR_NOERROR;
        }
        uptr = usm_get_user(engineID, engineIDLen, newName);
        SNMP_FREE(engineID);
        SNMP_FREE(newName);

        if (long_ret == RS_CREATEANDGO || long_ret == RS_CREATEANDWAIT) {
            usm_remove_user(uptr);
            usm_free_user(uptr);
        }
    }

    return SNMP_ERR_NOERROR;
}

#if 0

    /*
     * see if we can parse the oid for engineID/name first 
     */
if (usm_parse_oid(&name[USM_MIB_LENGTH], name_len - USM_MIB_LENGTH,
                  &engineID, &engineIDLen, (u_char **) & newName,
                  &nameLen))
    return SNMP_ERR_INCONSISTENTNAME;

    /*
     * Now see if a user already exists with these index values 
     */
uptr = usm_get_user(engineID, engineIDLen, newName);


if (uptr) {                     /* If so, we set the appropriate value... */
    free(engineID);
    free(newName);
    if (long_ret == RS_CREATEANDGO || long_ret == RS_CREATEANDWAIT) {
        return SNMP_ERR_INCONSISTENTVALUE;
    }
    if (long_ret == RS_DESTROY) {
        usm_remove_user(uptr);
        usm_free_user(uptr);
    } else {
        uptr->userStatus = long_ret;
    }

} else {                        /* ...else we create a new user */
    /*
     * check for a valid status column set 
     */
    if (long_ret == RS_ACTIVE || long_ret == RS_NOTINSERVICE) {
        free(engineID);
        free(newName);
        return SNMP_ERR_INCONSISTENTVALUE;
    }
    if (long_ret == RS_DESTROY) {
        /*
         * destroying a non-existent row is actually legal 
         */
        free(engineID);
        free(newName);
        return SNMP_ERR_NOERROR;
    }

    /*
     * generate a new user 
     */
    if ((uptr = usm_create_user()) == NULL) {
        free(engineID);
        free(newName);
        return SNMP_ERR_GENERR;
    }

    /*
     * copy in the engineID 
     */
    uptr->engineID = (unsigned char *) malloc(engineIDLen);
    if (uptr->engineID == NULL) {
        free(engineID);
        free(newName);
        usm_free_user(uptr);
        return SNMP_ERR_GENERR;
    }
    uptr->engineIDLen = engineIDLen;
    memcpy(uptr->engineID, engineID, engineIDLen);
    free(engineID);

    /*
     * copy in the name and secname 
     */
    if ((uptr->name = strdup(newName)) == NULL) {
        free(newName);
        usm_free_user(uptr);
        return SNMP_ERR_GENERR;
    }
    free(newName);
    if ((uptr->secName = strdup(uptr->name)) == NULL) {
        usm_free_user(uptr);
        return SNMP_ERR_GENERR;
    }

    /*
     * set the status of the row based on the request 
     */
    if (long_ret == RS_CREATEANDGO)
        uptr->userStatus = RS_ACTIVE;
    else if (long_ret == RS_CREATEANDWAIT)
        uptr->userStatus = RS_NOTINSERVICE;

    /*
     * finally, add it to our list of users 
     */
    usm_add_user(uptr);

}                               /* endif -- uptr */
}                               /* endif -- action==COMMIT */

return SNMP_ERR_NOERROR;

}                               /* end write_usmUserStatus() */
#endif
