/*
 * usmUser.c
 */

#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-features.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"

#ifndef NETSNMP_NO_WRITE_SUPPORT 
int usmStatusCheck(struct usmUser *uptr);
#endif  /* !NETSNMP_NO_WRITE_SUPPORT */

netsnmp_feature_child_of(usmuser_all, libnetsnmpmibs)
netsnmp_feature_child_of(init_register_usmuser_context, usmuser_all)

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);
}

#ifndef NETSNMP_FEATURE_REMOVE_INIT_REGISTER_USMUSER_CONTEXT
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);
}
#endif /* NETSNMP_FEATURE_REMOVE_INIT_REGISTER_USMUSER_CONTEXT */

/*******************************************************************-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;

    /* assume it isnt writable for the time being */
    *write_method = (WriteMethod*)0;    

    /* assume an integer and change later if not */
    *var_len = sizeof(long_ret);

    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) {
#ifndef NETSNMP_NO_WRITE_SUPPORT 
    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));
#else /* !NETSNMP_NO_WRITE_SUPPORT */ 
    default:
        DEBUGMSGTL(("snmpd", "no write support for var_usmUser\n"));
#endif /* !NETSNMP_NO_WRITE_SUPPORT */ 
    }
    return NULL;

}                               /* end var_usmUser() */


#ifndef NETSNMP_NO_WRITE_SUPPORT 

/*
 * 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);
    } 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);
    } 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);
    } 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);
    } 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;
}  /* write_usmUserStatus */

#endif /* !NETSNMP_NO_WRITE_SUPPORT */ 

#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
