📄 usmuser.c
字号:
/* * usmUser.c */#include <config.h>#include <stdlib.h>#if HAVE_STRING_H#include <string.h>#else#include <strings.h>#endif#if HAVE_WINSOCK_H#include <winsock.h>#endif#include "mibincl.h"#include "snmpusm.h"#include "snmpv3.h"#include "snmp-tc.h"#include "read_config.h"#include "agent_read_config.h"#include "util_funcs.h"#include "keytools.h"#include "tools.h"#include "scapi.h"#include "usmUser.h"#include "transform_oids.h"struct variable4 usmUser_variables[] = { { USMUSERSPINLOCK , ASN_INTEGER , RWRITE, var_usmUser, 1, { 1 } }, { USMUSERSECURITYNAME , ASN_OCTET_STR , RONLY , var_usmUser, 3, { 2,1,3 } }, { USMUSERCLONEFROM , ASN_OBJECT_ID , RWRITE, var_usmUser, 3, { 2,1,4 } }, { USMUSERAUTHPROTOCOL , ASN_OBJECT_ID , RWRITE, var_usmUser, 3, { 2,1,5 } }, { USMUSERAUTHKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,6 } }, { USMUSEROWNAUTHKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,7 } }, { USMUSERPRIVPROTOCOL , ASN_OBJECT_ID , RWRITE, var_usmUser, 3, { 2,1,8 } }, { USMUSERPRIVKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,9 } }, { USMUSEROWNPRIVKEYCHANGE, ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,10 } }, { USMUSERPUBLIC , ASN_OCTET_STR , RWRITE, var_usmUser, 3, { 2,1,11 } }, { USMUSERSTORAGETYPE , ASN_INTEGER , RWRITE, var_usmUser, 3, { 2,1,12 } }, { USMUSERSTATUS , ASN_INTEGER , 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 12static unsigned int usmUserSpinLock=0;voidinit_usmUser(void){ snmpd_register_config_handler("usmUser", usm_parse_config_usmUser, NULL, NULL); snmpd_register_config_handler("createUser", usm_parse_create_usmUser, NULL, "username (MD5|SHA) passphrase [DES] [passphrase]"); /* we need to be called back later */ snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_STORE_DATA, usm_store_users, NULL); REGISTER_MIB("snmpv3/usmUser", usmUser_variables, variable4, usmUser_variables_oid);}/*******************************************************************-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, *pptr; 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 */ *write_method = 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 0; } 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(), pptr = NULL, uptr = NULL; nptr != NULL; pptr = nptr, 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; } } } } /* 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 0; } /* endif -- vp->magic != USMUSERSPINLOCK */ switch(vp->magic) { case USMUSERSPINLOCK: *write_method = write_usmUserSpinLock; long_ret = usmUserSpinLock; return (unsigned char *) &long_ret;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -