/*
 * 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;
        uptr->authKey = netsnmp_memdup(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;
        uptr->privKey = netsnmp_memdup(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
