vacm_vars.c
上传用户:cxs890
上传日期:2021-05-22
资源大小:347k
文件大小:69k
源码类别:

SNMP编程

开发平台:

C/C++

  1. /*
  2.  * SNMPv3 View-based Access Control Model
  3.  */
  4. #include <config.h>
  5. #if HAVE_STDLIB_H
  6. #include <stdlib.h>
  7. #endif
  8. #if HAVE_UNISTD_H
  9. #include <unistd.h>
  10. #endif
  11. #if HAVE_STRING_H
  12. #include <string.h>
  13. #else
  14. #include <strings.h>
  15. #endif
  16. #if HAVE_MALLOC_H
  17. #include <malloc.h>
  18. #endif
  19. #include <ctype.h>
  20. #include <sys/types.h>
  21. #if HAVE_NETINET_IN_H
  22. #include <netinet/in.h>
  23. #endif
  24. #if HAVE_ARPA_INET_H
  25. #include <arpa/inet.h>
  26. #endif
  27. #if HAVE_DMALLOC_H
  28. #include <dmalloc.h>
  29. #endif
  30. #if HAVE_NETDB_H
  31. #include <netdb.h>
  32. #endif
  33. #if HAVE_WINSOCK_H
  34. #include <ip/socket.h>
  35. #endif
  36. #include <ip/netdb.h>
  37. #include <ip/inet.h>
  38. #include <ipacl/ipacl.h>
  39. #include "mibincl.h"
  40. #include "read_config.h"
  41. #include "agent_read_config.h"
  42. #include "system.h"
  43. #include "vacm.h"
  44. #include "callback.h"
  45. #include "agent_registry.h"
  46. #include "agent_callbacks.h"
  47. #include "vacm_vars.h"
  48. #include "util_funcs.h"
  49. #include "system.h"
  50. #ifdef USING_MIBII_SYSORTABLE_MODULE
  51. #if TIME_WITH_SYS_TIME
  52. # ifdef WIN32
  53. #  include <sys/timeb.h>
  54. # else
  55. #  include <time.h>
  56. # endif
  57. # include <time.h>
  58. #else
  59. # if HAVE_SYS_TIME_H
  60. #  include <sys/time.h>
  61. # else
  62. #  include <time.h>
  63. # endif
  64. #endif
  65. #include "sysORTable.h"
  66. #endif
  67. static unsigned int vacmViewSpinLockValue = 420420;
  68. extern int strcasecmp(const char*, const char*);
  69. void
  70. init_vacm_vars (void) 
  71. {
  72. #ifdef USING_MIBII_SYSORTABLE_MODULE
  73. static oid reg[] = {SNMP_OID_SNMPMODULES,16,2,2,1};
  74. #endif
  75. #define PRIVRW (SNMPV2ANY | 0x5000)
  76. struct variable2 vacmViewSpinLock_variables[] = {
  77. {VACMVIEWSPINLOCK, ASN_INTEGER, RWRITE, var_vacmViewSpinLock, 1, {1}},
  78. };
  79. struct variable2 vacm_sec2group[] = {
  80. {SECURITYGROUP, ASN_OCTET_STR, RWRITE, var_vacm_sec2group, 1, {3}},
  81. {SECURITYSTORAGE, ASN_INTEGER, RWRITE, var_vacm_sec2group, 1, {4}},
  82. {SECURITYSTATUS, ASN_INTEGER, RWRITE, var_vacm_sec2group, 1, {5}},
  83. };
  84. struct variable2 vacm_access[] = {
  85. {ACCESSMATCH, ASN_INTEGER, RWRITE, var_vacm_access, 1, {4}},
  86. {ACCESSREAD, ASN_OCTET_STR, RWRITE, var_vacm_access, 1, {5}},
  87. {ACCESSWRITE, ASN_OCTET_STR, RWRITE, var_vacm_access, 1, {6}},
  88. {ACCESSNOTIFY, ASN_OCTET_STR, RWRITE, var_vacm_access, 1, {7}},
  89. {ACCESSSTORAGE, ASN_INTEGER, RWRITE, var_vacm_access, 1, {8}},
  90. {ACCESSSTATUS, ASN_INTEGER, RWRITE, var_vacm_access, 1, {9}},
  91. };
  92. struct variable2 vacm_view[] = {
  93. {VIEWMASK, ASN_OCTET_STR, RWRITE, var_vacm_view, 1, {3}},
  94. {VIEWTYPE, ASN_INTEGER, RWRITE, var_vacm_view, 1, {4}},
  95. {VIEWSTORAGE, ASN_INTEGER, RWRITE, var_vacm_view, 1, {5}},
  96. {VIEWSTATUS, ASN_INTEGER, RWRITE, var_vacm_view, 1, {6}},
  97. };
  98. /* Define the OID pointer to the top of the mib tree that we're
  99. registering underneath */
  100. oid vacm_sec2group_oid[] = { OID_VACMGROUPENTRY };
  101. oid vacm_access_oid[] = { OID_VACMACCESSENTRY};
  102. oid vacm_view_oid[] = { OID_VACMVIEWENTRY };
  103. oid vacm_spinLock_oid[] = {OID_VACMSPINLOCK};
  104. /* register ourselves with the agent to handle our mib tree */
  105. REGISTER_MIB("mibII/vacm:spinLock", vacmViewSpinLock_variables, variable2, vacm_spinLock_oid);
  106. REGISTER_MIB("mibII/vacm:sec2group", vacm_sec2group, variable2, 
  107. vacm_sec2group_oid);
  108. REGISTER_MIB("mibII/vacm:access", vacm_access, variable2, vacm_access_oid);
  109. REGISTER_MIB("mibII/vacm:view", vacm_view, variable2, vacm_view_oid);
  110. snmpd_register_config_handler("com2sec", vacm_parse_security,
  111. vacm_free_security,"name source community");
  112. snmpd_register_config_handler("group", vacm_parse_group, vacm_free_group,
  113. "name v1|v2c|usm security");
  114. snmpd_register_config_handler("access", vacm_parse_access, vacm_free_access,
  115. "name context model level prefx read write notify");
  116. snmpd_register_config_handler("view", vacm_parse_view, vacm_free_view,
  117. "name type subtree [mask]");
  118. snmpd_register_config_handler("rwcommunity", vacm_parse_simple,
  119. NULL,"community [default|hostname|network/bits] [oid]");
  120. snmpd_register_config_handler("rocommunity", vacm_parse_simple,
  121. NULL,"community [default|hostname|network/bits] [oid]");
  122. snmpd_register_config_handler("rwuser", vacm_parse_simple,
  123. NULL,"user [noauth|auth|priv] [oid]");
  124. snmpd_register_config_handler("rouser", vacm_parse_simple,
  125. NULL,"user [noauth|auth|priv] [oid]");
  126. #ifdef USING_MIBII_SYSORTABLE_MODULE
  127. register_sysORTable(reg,10,"View-based Access Control Model for SNMP.");
  128. #endif
  129. /* register ourselves to handle access control */
  130. snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK,
  131. vacm_in_view_callback, NULL);
  132. snmp_register_callback(SNMP_CALLBACK_APPLICATION,
  133. SNMPD_CALLBACK_ACM_CHECK_INITIAL,
  134. vacm_in_view_callback, NULL);
  135. }
  136. static struct vacm_securityEntry *securityFirst =0, *securityLast =0;
  137. #define EXAMPLE_NETWORK "NETWORK"
  138. #define EXAMPLE_COMMUNITY "COMMUNITY"
  139. /*added by sxf for print the configuration community*/
  140. BOOL vacm_walkThrSecEntry (void (*thrMethod)(struct vacm_securityEntry*))
  141. {
  142. struct vacm_securityEntry *sp;
  143. if (securityFirst == NULL)
  144. return FALSE;
  145. for (sp = securityFirst; sp != NULL; sp = sp->next)
  146. {
  147. thrMethod (sp);
  148. }
  149. return TRUE;
  150. }
  151. void
  152. vacm_destroySecurityEntry(const char *commName)
  153. {
  154.     struct vacm_securityEntry *sp, *lastsp = NULL;
  155.     if (securityFirst && !strcmp(securityFirst->community, commName))
  156. {
  157. sp = securityFirst;
  158. if (sp == securityLast)
  159. securityLast = NULL;
  160. securityFirst = securityFirst->next;
  161.     } else {
  162. for (sp = securityFirst; sp != NULL; sp = sp->next){
  163. if (!strcmp(sp->community, commName))
  164. break;
  165. lastsp = sp;
  166. }
  167. if (!sp)
  168. return;
  169. if (sp == securityLast)
  170. securityLast = lastsp;
  171. lastsp->next = sp->next;
  172.     }
  173. if (sp != NULL)
  174. free(sp);
  175.     return;
  176. }
  177. struct vacm_securityEntry *vacm_FindSecEntryByCommName (char *name)
  178. {
  179. struct vacm_securityEntry *vp;
  180. for (vp = securityFirst; vp != NULL; vp = vp->next)
  181. {
  182. if (strcmp (vp->community, name) == 0)
  183. {
  184. return vp;
  185. }
  186. }
  187. return NULL;
  188. }
  189. void vacm_DestroyCommunity (char *commName)
  190. {
  191. char line[134];
  192. struct vacm_viewEntry *vp;
  193. struct vacm_securityEntry *sp;
  194. sp = vacm_FindSecEntryByCommName (commName);
  195. if (sp == NULL)
  196. {
  197. return;
  198. }
  199. sprintf (line, "__sn%s", commName);
  200. vacm_destroyGroupEntry (SNMP_SEC_MODEL_SNMPv1, line);
  201. vacm_destroyGroupEntry (SNMP_SEC_MODEL_SNMPv2c, line);
  202. sprintf (line, "__gn%s", commName);
  203. vacm_destroyAccessEntry(line, "", SNMP_SEC_MODEL_ANY, SNMP_SEC_LEVEL_NOAUTH);
  204. if ((sp->viewname)[0] == '')
  205. {
  206. sprintf (line, "__vn%s", commName);
  207. vp = vacm_findViewEntryByName (line);
  208. vacm_destroyViewEntry (vp->viewName+1, vp->viewSubtree, vp->viewSubtreeLen);
  209. }
  210. vacm_destroySecurityEntry (commName);
  211. }
  212. void vacm_DestroyCommunityAll (void)
  213. {
  214. struct vacm_securityEntry *vp, *vp_next;
  215. for (vp = securityFirst; vp != NULL;)
  216. {
  217. vp_next = vp->next;
  218. vacm_DestroyCommunity (vp->community);
  219. vp = vp_next;
  220. }
  221. }
  222. void vacm_parse_security (const char *token, 
  223.   char *param)
  224. {
  225.     char *name, *source, *community;
  226.     const char *mask;
  227.     char *cp;
  228.     struct vacm_securityEntry *sp, se;
  229.     unsigned int maskLength, maskBit;
  230.     struct soaddr_in *srcIp, *srcMask;
  231.     char null[] = "";
  232.     memset (&se, 0 , sizeof se);
  233.     name = strtok(param, "tn ");
  234.     if (!name) {
  235. config_perror("missing NAME parameter");
  236. return;
  237.     }
  238.     source = strtok(NULL, "tn ");
  239.     if (!source) {
  240. config_perror("missing SOURCE parameter");
  241. return;
  242.     }
  243.     if ( !strncmp( source, EXAMPLE_NETWORK, strlen(EXAMPLE_NETWORK)) ) {
  244. config_perror("Example config NETWORK not properly configured");
  245. return; /* or exit(1); */
  246.     }
  247.     community = strtok(NULL, "tn ");
  248.     if (!community) {
  249. config_perror("missing COMMUNITY parameter");
  250. return;
  251.     }
  252.     if ( !strncmp( community, EXAMPLE_COMMUNITY, strlen(EXAMPLE_COMMUNITY)) ) {
  253. config_perror("Example config COMMUNITY not properly configured");
  254. return; /* or exit(1); */
  255.     }
  256.     srcIp   = (struct soaddr_in*)&(se.sourceIp);
  257.     srcMask = (struct soaddr_in*)&(se.sourceMask);
  258.     cp = strchr(source, '/');
  259.     if (cp == NULL) cp = null;
  260.     else *cp++ = 0;
  261.     mask = cp;
  262.     if (strcmp("default", source) == 0 || strcmp("0.0.0.0", source) == 0) {
  263. memset(&(srcIp->sin_addr), 0, sizeof(struct in_addr));
  264. mask = "0.0.0.0";
  265.     }
  266.     else if ((srcIp->sin_addr.s_addr = inet_addr (source)) == (unsigned) -1) {
  267. struct hostent *hp = gethostbyname(source);
  268. if (hp != NULL) {
  269.     memcpy(&(srcIp->sin_addr), hp->h_addr, 4);
  270. }
  271. else {
  272.     config_perror ("bad source address");
  273.     return;
  274. }
  275.     }
  276.     if (*mask == 0) memset (&(srcMask->sin_addr), 0xff, sizeof(struct in_addr));
  277.     else {
  278. if (strchr(mask, '.')) {
  279.     if ((srcMask->sin_addr.s_addr = inet_addr(mask)) == (unsigned)-1) {
  280. config_perror("bad mask");
  281. return;
  282.     }
  283. }
  284. else {
  285.     maskLength = atoi(mask);
  286.     if (maskLength <= 0 || maskLength > 32) {
  287. config_perror("bad mask length");
  288. return;
  289.     }
  290.     maskBit = 0x80000000L;
  291.     srcMask->sin_addr.s_addr = 0;
  292.     while (maskLength--) {
  293. srcMask->sin_addr.s_addr |= maskBit;
  294. maskBit >>= 1;
  295.     }
  296.     srcMask->sin_addr.s_addr = htonl(srcMask->sin_addr.s_addr);
  297. }
  298.     }
  299.     if ((srcIp->sin_addr.s_addr & ~srcMask->sin_addr.s_addr) != 0) {
  300. config_perror("source/mask mismatch");
  301. return;
  302.     }
  303.     if (strlen(name)+1 > sizeof(se.securityName)) {
  304.      config_perror("security name too long");
  305. return;
  306.     }
  307.     if (strlen(community)+1 > sizeof(se.community)) {
  308.      config_perror("community name too long");
  309. return;
  310.     }
  311.     strcpy(se.securityName, name);
  312.     strcpy(se.community, community);
  313.     sp = (struct vacm_securityEntry *)malloc (sizeof *sp);
  314.     if (sp == NULL) {
  315.      config_perror("memory error");
  316. return;
  317.     }
  318.     *sp = se;
  319.     if (securityFirst != NULL) {
  320. securityLast->next = sp;
  321. securityLast = sp;
  322.     }
  323.     else {
  324. securityFirst = securityLast = sp;
  325.     }
  326. }
  327. void vacm_free_security (void)
  328. {
  329.     struct vacm_securityEntry *sp;
  330.     while ((sp = securityFirst) != NULL) {
  331. securityFirst = sp->next;
  332. free(sp);
  333.     }
  334. }
  335. void vacm_parse_group (const char *token, 
  336.        char *param)
  337. {
  338.     char *group, *model, *security;
  339.     int imodel;
  340.     struct vacm_groupEntry *gp;
  341.     group = strtok (param, " tn");
  342.     model = strtok (NULL, " tn");
  343.     security = strtok (NULL, " tn");
  344.     if (group == NULL || *group == 0) {
  345. config_perror("missing GROUP parameter");
  346. return;
  347.     }
  348.     if (model == NULL || *model == 0) {
  349. config_perror("missing MODEL parameter");
  350. return;
  351.     }
  352.     if (security == NULL || *security == 0) {
  353. config_perror("missing SECURITY parameter");
  354. return;
  355.     }
  356.     if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1;
  357.     else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c;
  358.     else if (strcasecmp(model, "usm") == 0) imodel = SNMP_SEC_MODEL_USM;
  359.     else if (strcasecmp(model, "any") == 0) {
  360. config_perror("bad security model "any" should be: v1, v2c or usm - installing anyway");
  361. imodel = SNMP_SEC_MODEL_ANY;
  362.     }
  363.     else {
  364. config_perror("bad security model, should be: v1, v2c or usm");
  365. return;
  366.     }
  367.     if (strlen(security)+1 > sizeof(gp->groupName)) {
  368.      config_perror("security name too long");
  369. return;
  370.     }
  371.     gp = vacm_createGroupEntry(imodel, security);
  372.     if (!gp) {
  373. config_perror("failed to create group entry");
  374. return;
  375.     }
  376.     strcpy (gp->groupName, group);
  377.     gp->storageType = SNMP_STORAGE_PERMANENT;
  378.     gp->status = SNMP_ROW_ACTIVE;
  379.     free (gp->reserved);
  380.     gp->reserved = NULL;
  381. }
  382. void vacm_free_group (void)
  383. {
  384.     vacm_destroyAllGroupEntries();
  385. }
  386. void vacm_parse_access (const char *token, char *param)
  387. {
  388.     char *name, *context, *model, *level, *prefix, *readView, *writeView, *notify;
  389.     int imodel, ilevel, iprefix;
  390.     struct vacm_accessEntry *ap;
  391.     name = strtok(param, " tn");
  392.     if (!name) {
  393. config_perror("missing NAME parameter");
  394. return;
  395.     }
  396.     context = strtok(NULL, " tn");
  397.     if (!context) {
  398. config_perror("missing CONTEXT parameter");
  399. return;
  400.     }
  401.     model = strtok(NULL, " tn");
  402.     if (!model) {
  403. config_perror("missing MODEL parameter");
  404. return;
  405.     }
  406.     level = strtok(NULL, " tn");
  407.     if (!level) {
  408. config_perror("missing LEVEL parameter");
  409. return;
  410.     }
  411.     prefix = strtok(NULL, " tn");
  412.     if (!prefix) {
  413. config_perror("missing PREFIX parameter");
  414. return;
  415.     }
  416.     readView = strtok(NULL, " tn");
  417.     if (!readView) {
  418. config_perror("missing readView parameter");
  419. return;
  420.     }
  421.     writeView = strtok(NULL, " tn");
  422.     if (!writeView) {
  423. config_perror("missing writeView parameter");
  424. return;
  425.     }
  426.     notify = strtok(NULL, " tn");
  427.     if (!notify) {
  428. config_perror("missing notifyView parameter");
  429. return;
  430.     }
  431.     if (strcmp(context, """") == 0) *context = 0;
  432.     if (strcasecmp(model, "any") == 0) imodel = SNMP_SEC_MODEL_ANY;
  433.     else if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1;
  434.     else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c;
  435.     else if (strcasecmp(model, "usm") == 0) imodel = SNMP_SEC_MODEL_USM;
  436.     else {
  437. config_perror("bad security model (any, v1, v2c, usm)");
  438. return;
  439.     }
  440.     if (strcasecmp(level, "noauth") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH;
  441.     else if (strcasecmp(level, "noauthnopriv") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH;
  442.     else if (strcasecmp(level, "auth") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
  443.     else if (strcasecmp(level, "authnopriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV;
  444.     else if (strcasecmp(level, "priv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV;
  445.     else if (strcasecmp(level, "authpriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV;
  446.     else {
  447. config_perror("bad security level (noauthnopriv, authnopriv, authpriv)");
  448. return;
  449.     }
  450.     if (strcmp(prefix,"exact") == 0) iprefix = 1;
  451.     else if (strcmp(prefix,"prefix") == 0) iprefix = 2;
  452.     else if (strcmp(prefix,"0") == 0) {
  453. config_perror("bad prefix match parameter "0", should be: exact or prefix - installing anyway");
  454. iprefix = 1;
  455.     }
  456.     else {
  457. config_perror("bad prefix match parameter, should be: exact or prefix");
  458. return;
  459.     }
  460.     if (strlen(readView)+1 > sizeof(ap->readView)) {
  461.      config_perror("readView too long");
  462. return;
  463.     }
  464.     if (strlen(writeView)+1 > sizeof(ap->writeView)) {
  465.      config_perror("writeView too long");
  466. return;
  467.     }
  468.     if (strlen(notify)+1 > sizeof(ap->notifyView)) {
  469.      config_perror("notifyView too long");
  470. return;
  471.     }
  472.     ap = vacm_createAccessEntry (name, context, imodel, ilevel);
  473.     if (!ap) {
  474. config_perror("failed to create access entry");
  475. return;
  476.     }
  477.     strcpy(ap->readView, readView);
  478.     strcpy(ap->writeView, writeView);
  479.     strcpy(ap->notifyView, notify);
  480.     ap->contextMatch = iprefix;
  481.     ap->storageType = SNMP_STORAGE_PERMANENT;
  482.     ap->status = SNMP_ROW_ACTIVE;
  483.     free (ap->reserved);
  484.     ap->reserved = NULL;
  485. }
  486. void vacm_free_access (void)
  487. {
  488.     vacm_destroyAllAccessEntries();
  489. }
  490. void vacm_parse_view (const char *token, 
  491.       char *param)
  492. {
  493.     char *name, *type, *subtree, *mask;
  494.     int inclexcl;
  495.     struct vacm_viewEntry *vp;
  496.     oid suboid[MAX_OID_LEN];
  497.     int suboid_len = 0;
  498.     u_char viewMask[sizeof (vp->viewMask)];
  499.     int i;
  500.     name = strtok (param, " tn");
  501.     if (!name) {
  502. config_perror("missing NAME parameter");
  503. return;
  504.     }
  505.     type = strtok (NULL, " nt");
  506.     if (!type) {
  507. config_perror("missing TYPE parameter");
  508. return;
  509.     }
  510.     subtree = strtok(NULL, " tn");
  511.     if (!subtree) {
  512. config_perror("missing SUBTREE parameter");
  513. return;
  514.     }
  515.     mask = strtok(NULL, " tn");
  516.     if (strcmp(type, "included") == 0) inclexcl = SNMP_VIEW_INCLUDED;
  517.     else if (strcmp(type, "excluded") == 0) inclexcl = SNMP_VIEW_EXCLUDED;
  518.     else {
  519. config_perror("TYPE must be included/excluded?");
  520. return;
  521.     }
  522.     suboid_len = MAX_OID_LEN;
  523.     if (!read_objid(subtree, suboid, (size_t*)&suboid_len)) {
  524. config_perror("bad SUBTREE object id");
  525. return;
  526.     }
  527.     if (mask) {
  528. int val;
  529. i = 0;
  530. for (mask = strtok(mask, ".:"); mask; mask = strtok(NULL, ".:")) {
  531.     if (i >= sizeof(viewMask)) {
  532. config_perror("MASK too long");
  533. return;
  534.     }
  535.     if (sscanf(mask, "%x", &val) == 0) {
  536. config_perror("invalid MASK");
  537. return;
  538.     }
  539.     viewMask[i] = (u_char)val;
  540.     i++;
  541. }
  542.     }
  543.     else {
  544. for (i = 0; i < sizeof(viewMask); i++)
  545.     viewMask[i] = 0xff;
  546.     }
  547.     vp = vacm_createViewEntry(name, suboid, suboid_len);
  548.     if (!vp) {
  549. config_perror("failed to create view entry");
  550. return;
  551.     }
  552.     memcpy(vp->viewMask, viewMask, sizeof(viewMask));
  553.     vp->viewType = inclexcl;
  554.     vp->viewStorageType = SNMP_STORAGE_PERMANENT;
  555.     vp->viewStatus = SNMP_ROW_ACTIVE;
  556.     free (vp->reserved);
  557.     vp->reserved = NULL;
  558. }
  559. void vacm_free_view (void)
  560. {
  561.     vacm_destroyAllViewEntries();
  562. }
  563. void vacm_parse_simple(const char *token, char *confline) {
  564.   char line[SPRINT_MAX_LEN];
  565.   char community[COMMUNITY_MAX_LEN];
  566.   char theoid[SPRINT_MAX_LEN];
  567.   char viewname[SPRINT_MAX_LEN];
  568.   char addressname[SPRINT_MAX_LEN];
  569.   const char *rw = "none";
  570.   const char *model = "any";
  571.   char *cp;
  572.   static int num = 0;
  573.   char secname[SPRINT_MAX_LEN];
  574.   char authtype[SPRINT_MAX_LEN];
  575.   /* community name or user name */
  576.   cp = copy_word(confline, community);
  577.   if (strcmp(token,"rouser") == 0 || strcmp(token,"rwuser") == 0) {
  578.     /* authentication type */
  579.     if (cp && *cp)
  580.       cp = copy_word(cp, authtype);
  581.     else
  582.       strcpy(authtype, "auth");
  583.     DEBUGMSGTL((token, "setting auth type: "%s"n",authtype));
  584.     model = "usm";
  585.   } else {
  586.     /* source address */
  587.     if (cp && *cp) {
  588.       cp = copy_word(cp, addressname);
  589.     } else {
  590.       strcpy(addressname, "default");
  591.     }
  592.     /* authtype has to be noauth */
  593.     strcpy(authtype, "noauth");
  594.   }
  595.   /* oid they can touch */
  596.   if (cp && *cp) {
  597.     cp = copy_word(cp, theoid);
  598.   } else {
  599.     strcpy(theoid, ".1");
  600.   }
  601.   if (strcmp(token,"rwcommunity") == 0 || strcmp(token,"rwuser") == 0)
  602.     rw = viewname;
  603.   if (strcmp(token,"rwcommunity") == 0 || strcmp(token,"rocommunity") == 0) {
  604.     /* com2sec mapping */
  605.     /* com2sec anonymousSecNameNUM    ADDRESS  COMMUNITY */
  606.     sprintf(secname, "anonymousSecName%03d", num);
  607.     sprintf(line,"%s %s %s", secname, addressname, community);
  608.     DEBUGMSGTL((token,"passing: %s %sn", "com2sec", line));
  609.     vacm_parse_security("com2sec",line);
  610.     /* sec->group mapping */
  611.     /* group   anonymousGroupNameNUM  any      anonymousSecNameNUM */
  612.     sprintf(line,"anonymousGroupName%03d v1 %s", num, secname);
  613.     DEBUGMSGTL((token,"passing: %s %sn", "group", line));
  614.     vacm_parse_group("group",line);
  615.     sprintf(line,"anonymousGroupName%03d v2c %s", num, secname);
  616.     DEBUGMSGTL((token,"passing: %s %sn", "group", line));
  617.     vacm_parse_group("group",line);
  618.   } else {
  619.     strcpy(secname, community);
  620.     /* sec->group mapping */
  621.     /* group   anonymousGroupNameNUM  any      anonymousSecNameNUM */
  622.     sprintf(line,"anonymousGroupName%03d usm %s", num, secname);
  623.     DEBUGMSGTL((token,"passing: %s %sn", "group", line));
  624.     vacm_parse_group("group",line);
  625.   }
  626.   /* view definition */
  627.   /* view    anonymousViewNUM       included OID */
  628.   sprintf(viewname,"anonymousView%03d",num);
  629.   sprintf(line,"%s included %s", viewname, theoid);
  630.   DEBUGMSGTL((token,"passing: %s %sn", "view", line));
  631.   vacm_parse_view("view",line);
  632.   /* map everything together */
  633.   /* access  anonymousGroupNameNUM  "" MODEL AUTHTYPE exact anonymousViewNUM [none/anonymousViewNUM] [none/anonymousViewNUM] */
  634.   sprintf(line, "anonymousGroupName%03d  "" %s %s exact %s %s %s", num,
  635.           model, authtype, viewname, rw, rw);
  636.   DEBUGMSGTL((token,"passing: %s %sn", "access", line));
  637.   vacm_parse_access("access",line);
  638.   num++;
  639. }
  640. int
  641. vacm_in_view_callback(int majorID, int minorID, void *serverarg,
  642.                       void *clientarg) {
  643.   struct view_parameters *view_parms = (struct view_parameters *) serverarg;
  644.   int retval;
  645.   
  646.   if (view_parms == NULL)
  647.     return 1;
  648.   retval = vacm_in_view(view_parms->pdu, view_parms->name,
  649.                         view_parms->namelen);
  650.   if (retval != 0)
  651.     view_parms->errorcode = retval;
  652.   return retval;
  653. }
  654. extern int snmp_check_ipacl(char *ipacl, int ipaddr);
  655. /*******************************************************************-o-******
  656.  * vacm_in_view
  657.  *
  658.  * Parameters:
  659.  * *pdu
  660.  * *name
  661.  *  namelen
  662.  *      
  663.  * Returns:
  664.  * 0 On success.
  665.  * 1 Missing security name.
  666.  * 2 Missing group
  667.  * 3 Missing access
  668.  * 4 Missing view
  669.  * 5 Not in view
  670.  *
  671.  * Debug output listed as follows:
  672.  * <securityName> <groupName> <viewName> <viewType>
  673.  */
  674. int vacm_in_view (struct snmp_pdu *pdu,
  675.   oid *name,
  676.   size_t namelen)
  677. {
  678.     struct vacm_securityEntry *sp = securityFirst;
  679.     struct vacm_accessEntry *ap;
  680.     struct vacm_groupEntry *gp;
  681.     struct vacm_viewEntry *vp;
  682.     struct soaddr_in *pduIp = (struct soaddr_in*)&(pdu->address);
  683.     struct soaddr_in *srcIp, *srcMask;
  684.     char *vn;
  685.     char *sn;
  686.     char *ipacl = NULL;
  687.     int b_flag=0;/*判断是不是PDU的ip不匹配,用于判断统计STAT_SNMPINBADCOMMUNITYNAMES*/
  688.     if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c) {
  689. if (snmp_get_do_debugging()) {
  690.             char buf[256];
  691.             if (pdu->community) {
  692.                 memcpy(buf, pdu->community, pdu->community_len>200?200:pdu->community_len);
  693.                 buf[pdu->community_len] = '';
  694.             } else {
  695.                 DEBUGMSGTL(("mibII/vacm_vars", "NULL community"));
  696. strcpy (buf, "NULL");
  697.             }
  698.             
  699.     DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: ver=%d, source=%.8x, community=%sn", pdu->version, pduIp->sin_addr.s_addr, buf));
  700. }
  701. while (sp) {
  702. srcIp   = (struct soaddr_in *)&(sp->sourceIp);
  703. srcMask = (struct soaddr_in *)&(sp->sourceMask);
  704. if ((pduIp->sin_addr.s_addr & srcMask->sin_addr.s_addr)== srcIp->sin_addr.s_addr)
  705. {
  706. b_flag = 1;
  707.                if (strlen(sp->community) == pdu->community_len
  708. && !strncmp(sp->community, (char *)pdu->community, pdu->community_len))
  709. break;
  710. }
  711.     sp = sp->next;
  712. }
  713. if (sp == NULL) 
  714. {
  715. if (b_flag) 
  716. snmp_increment_statistic (STAT_SNMPINBADCOMMUNITYNAMES);
  717. return 1;
  718. }
  719. /*
  720. if (sp->access_list[0] != '')
  721. {
  722. if (ipacl_find (sp->access_list) != NULL)
  723. {
  724. acl_info.src_ip = pduIp->sin_addr.s_addr;
  725. if (ipacl_check(&acl_info,sp->access_list)!=IP_PERMIT)
  726. return -1;
  727. }
  728.         int rc;
  729.         acl_info.src_ip = pduIp->sin_addr.s_addr;
  730.         rc = ipacl_check(&acl_info, sp->access_list);
  731.         if ((rc & IP_PERMIT) == 0)
  732.             return -1;
  733. }
  734. */
  735.     ipacl = sp->access_list;
  736. sn = sp->securityName;
  737.     } else if (pdu->securityModel == SNMP_SEC_MODEL_USM) {
  738.       DEBUGMSG (("mibII/vacm_vars",
  739.                  "vacm_in_view: ver=%d, model=%d, secName=%sn",
  740.                  pdu->version, pdu->securityModel, pdu->securityName));
  741.       sn = pdu->securityName;
  742.     } else {
  743. sn = NULL;
  744.     }
  745.     if (sn == NULL) return 1;
  746.     DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: sn=%s", sn));
  747.     gp = vacm_getGroupEntry(pdu->securityModel, sn);
  748.     if (gp == NULL) { DEBUGMSG(("mibII/vacm_vars", "n")); return 2; }
  749.     DEBUGMSG (("mibII/vacm_vars", ", gn=%s", gp->groupName));
  750.     ap = vacm_getAccessEntry(gp->groupName, "", pdu->securityModel,
  751.                              pdu->securityLevel);
  752.     if (ap == NULL) { DEBUGMSG(("mibII/vacm_vars", "n")); return 3; }
  753.     if (name == 0) { /* only check the setup of the vacm for the request */
  754.         DEBUGMSG(("mibII/vacm_vars", ", Done checking setupn"));
  755.         return 0;
  756.     }
  757.     if (pdu->securityModel == SNMP_SEC_MODEL_USM) {
  758.         ipacl = ap->access_list;
  759.     }
  760. if (snmp_check_ipacl(ipacl, pduIp->sin_addr.s_addr))
  761. {
  762. snmp_increment_statistic (STAT_SNMPINBADCOMMUNITYUSES);
  763.      return -1;
  764. }
  765.     switch (pdu->command) {
  766.       case SNMP_MSG_GET:
  767.       case SNMP_MSG_GETNEXT:
  768.       case SNMP_MSG_GETBULK:
  769. vn = ap->readView;
  770. break;
  771.       case SNMP_MSG_SET:
  772. vn = ap->writeView;
  773. break;
  774.       case SNMP_MSG_TRAP:
  775.       case SNMP_MSG_TRAP2:
  776.       case SNMP_MSG_INFORM:
  777. vn = ap->notifyView;
  778. break;
  779.       default:
  780.         snmp_log(LOG_ERR, "bad msg type in vacm_in_view: %dn", pdu->command);
  781. vn = ap->readView;
  782.     }
  783.     DEBUGMSG (("mibII/vacm_vars", ", vn=%s", vn));
  784.     vp = vacm_getViewEntry (vn, name, namelen);
  785.     if (vp == NULL) 
  786.     { 
  787.      DEBUGMSG(("mibII/vacm_vars", "n")); 
  788.      return 4; 
  789.     }
  790.     DEBUGMSG(("mibII/vacm_vars", ", vt=%dn", vp->viewType));
  791.     if (vp->viewType == SNMP_VIEW_EXCLUDED) 
  792.     {
  793.       if (pdu->version == SNMP_VERSION_1
  794.             || pdu->version == SNMP_VERSION_2c) {
  795.             snmp_increment_statistic(STAT_SNMPINBADCOMMUNITYUSES);
  796.         }
  797.      return 5;
  798.     }
  799.     return 0;
  800. }  /* end vacm_in_view() */
  801. u_char *var_vacm_sec2group(struct variable *vp,
  802.    oid *name,
  803.    int *length,
  804.    int exact,
  805.    int *var_len,
  806.    WriteMethod **write_method)
  807. {
  808.     struct vacm_groupEntry *gp;
  809.     oid *groupSubtree;
  810. oid name_cpy[MAX_OID_LEN];
  811. int name_len;
  812.     int groupSubtreeLen;
  813.     int secmodel;
  814.     char secname[128], *cp;
  815.     *write_method = NULL;
  816. name_len = (*length > MAX_OID_LEN)?MAX_OID_LEN:*length;
  817. memcpy (name_cpy, name, name_len*sizeof(oid));
  818.     if (memcmp(name_cpy, vp->name, sizeof(oid)*vp->namelen) != 0) {
  819. memcpy(name_cpy, vp->name, sizeof(oid)*vp->namelen);
  820. name_len = vp->namelen;
  821.     }
  822.     if (exact) {
  823. if (name_len < 13) return NULL;
  824. secmodel = name_cpy[11];
  825. groupSubtree = name_cpy+13;
  826. groupSubtreeLen = name_len - 13;
  827. cp = secname;
  828. while (groupSubtreeLen-- > 0) {
  829.             if (*groupSubtree > 255)
  830.               return 0; /* illegal value */
  831.     *cp++ = (char) *groupSubtree++;
  832. }
  833. *cp = 0;
  834. gp = vacm_getGroupEntry(secmodel, secname);
  835.     }
  836.     else {
  837. secmodel = name_len > 11 ? name[11] : 0;
  838. groupSubtree = name_cpy+12;
  839. groupSubtreeLen = name_len - 12;
  840. cp = secname;
  841. while (groupSubtreeLen-- > 0) {
  842.             if (*groupSubtree > 255)
  843.               return 0; /* illegal value */
  844.     *cp++ = (char) *groupSubtree++;
  845. }
  846. *cp = 0;
  847. vacm_scanGroupInit();
  848. while ((gp = vacm_scanGroupNext()) != NULL) {
  849.     if (gp->securityModel > secmodel ||
  850. (gp->securityModel == secmodel && strcmp(gp->securityName, secname) > 0))
  851. break;
  852. }
  853. if (gp) {
  854.     name_cpy[11] = gp->securityModel;
  855.     name_len = 12;
  856.     cp = gp->securityName;
  857.     while (*cp) {
  858. name_cpy[(name_len)++] = *cp++;
  859.     }
  860. memcpy (name, name_cpy, name_len*sizeof(oid));
  861. *length = name_len;
  862. }
  863.     }
  864.     if (!gp) {
  865.     if (vp->magic == SECURITYSTATUS)  {
  866. *write_method = write_vacmSecurity2GroupStatus;
  867. }
  868. return NULL;
  869. }
  870.     *var_len =sizeof(long_return);
  871.     switch (vp->magic) {
  872.     case SECURITYMODEL:
  873. long_return = gp->securityModel;
  874. return (u_char *)&long_return;
  875.     case SECURITYNAME:
  876. *var_len = gp->securityName[0];
  877. return (u_char *)&gp->securityName[1];
  878.     case SECURITYGROUP:
  879. *var_len = strlen(gp->groupName);
  880. *write_method = write_vacmGroupName;
  881. return (u_char *)gp->groupName;
  882.     case SECURITYSTORAGE:
  883. long_return = gp->storageType;
  884. *write_method = write_vacmSecurityToGroupStorageType;
  885. return (u_char *)&long_return;
  886.     case SECURITYSTATUS:
  887. long_return = gp->status;
  888. *write_method = write_vacmSecurity2GroupStatus;
  889. return (u_char *)&long_return;
  890.     }
  891.     return NULL;
  892. }
  893. u_char *var_vacm_access(struct variable *vp,
  894. oid *name,
  895. int *length,
  896. int exact,
  897. int *var_len,
  898. WriteMethod **write_method)
  899. {
  900.     struct vacm_accessEntry *gp;
  901.     int secmodel;
  902.     int seclevel;
  903.     char groupName[32];
  904.     char contextPrefix[32];
  905.     oid *op, new_name[MAX_OID_LEN];
  906.     int len, new_len;
  907.     char *cp;
  908.     int cmp;
  909.     *write_method = NULL;
  910. new_len = (*length > MAX_OID_LEN)?MAX_OID_LEN:*length;
  911. memcpy (new_name, name, new_len*sizeof(oid));
  912.     if (memcmp(new_name, vp->name, sizeof(oid)*vp->namelen) != 0) {
  913. memcpy(new_name, vp->name, sizeof(oid)*vp->namelen);
  914. new_len = vp->namelen;
  915.     }
  916.     if (exact) {
  917. if (new_len < 15) return NULL;
  918. op = new_name+11;
  919. len = *op++;
  920. cp = groupName;
  921. while (len-- > 0) {
  922.             if (*op > 255)
  923. return 0; /* illegal value */
  924. *cp++ = (char) *op++;
  925. }
  926. *cp = 0;
  927. len = *op++;
  928. cp = contextPrefix;
  929. while (len-- > 0) {
  930.             if (*op > 255)
  931. return 0; /* illegal value */
  932. *cp++ = (char) *op++;
  933. }
  934. *cp = 0;
  935. secmodel = *op++;
  936. seclevel = *op++;
  937. if (op != new_name + new_len) {
  938. return NULL;
  939. }
  940. gp = vacm_getAccessEntry(groupName, contextPrefix, secmodel, seclevel);
  941.     }
  942.     else {
  943. secmodel = seclevel = 0;
  944. groupName[0] = 0;
  945. contextPrefix[0] = 0;
  946. op = new_name+11;
  947. if (op >= new_name + new_len) {
  948. }
  949. else {
  950. len = *op;
  951. cp = groupName;
  952. while (len-- >= 0) {
  953.                 if (*op > 255)
  954. return 0; /* illegal value */
  955. *cp++ = (char) *op++;
  956. }
  957. *cp = 0;
  958. }
  959. if (op >= new_name + new_len) {
  960. }
  961. else {
  962. len = *op;
  963. cp = contextPrefix;
  964. while (len-- >= 0) {
  965.                 if (*op > 255)
  966. return 0; /* illegal value */
  967. *cp++ = (char) *op++;
  968. }
  969. *cp = 0;
  970. }
  971. if (op >= new_name + new_len) {
  972. }
  973. else {
  974. secmodel = *op++;
  975. }
  976. if (op >= new_name + new_len) {
  977. }
  978. else {
  979. seclevel = *(op);
  980. }
  981. vacm_scanAccessInit();
  982. while ((gp = vacm_scanAccessNext()) != NULL) {
  983. cmp = strcmp(gp->groupName, groupName);
  984. if (cmp > 0) break;
  985. if (cmp < 0) continue;
  986. cmp = strcmp(gp->contextPrefix, contextPrefix);
  987. if (cmp > 0) break;
  988. if (cmp < 0) continue;
  989. if (gp->securityModel > secmodel) break;
  990. if (gp->securityModel < secmodel) continue;
  991. if (gp->securityLevel > seclevel) break;
  992. }
  993. if (gp) {
  994. new_len = 11;
  995. cp = gp->groupName;
  996. do {
  997. new_name[(new_len)++] = *cp++;
  998. } while (*cp);
  999. cp = gp->contextPrefix;
  1000. do {
  1001. new_name[new_len++] = *cp++;
  1002. } while (*cp);
  1003. new_name[new_len++] = gp->securityModel;
  1004. new_name[new_len++] = gp->securityLevel;
  1005. *length = new_len;
  1006. memcpy (name, new_name, new_len*sizeof(oid));
  1007. }
  1008.     }
  1009.     if (!gp) {
  1010.     if (vp->magic == ACCESSSTATUS)  {
  1011. *write_method = write_vacmAccessStatus;
  1012. }
  1013. return NULL;
  1014. }
  1015.     *var_len =sizeof(long_return);
  1016.     switch (vp->magic) {
  1017.     case ACCESSMATCH:
  1018. long_return = gp->contextMatch;
  1019. *write_method = write_vacmAccessContextMatch;
  1020. return (u_char *)&long_return;
  1021.     case ACCESSLEVEL:
  1022. long_return = gp->securityLevel;
  1023. return (u_char *)&long_return;
  1024.     case ACCESSMODEL:
  1025. long_return = gp->securityModel;
  1026. return (u_char *)&long_return;
  1027.     case ACCESSPREFIX:
  1028. *var_len = *gp->contextPrefix;
  1029. return (u_char *)&gp->contextPrefix[1];
  1030.     case ACCESSREAD:
  1031. *var_len = strlen(gp->readView);
  1032. *write_method = write_vacmAccessReadViewName;
  1033. return (u_char *)gp->readView;
  1034.     case ACCESSWRITE:
  1035. *var_len = strlen(gp->writeView);
  1036. *write_method = write_vacmAccessWriteViewName;
  1037. return (u_char *)gp->writeView;
  1038.     case ACCESSNOTIFY:
  1039. *var_len = strlen(gp->notifyView);
  1040. *write_method = write_vacmAccessNotifyViewName;
  1041. return (u_char *)gp->notifyView;
  1042.     case ACCESSSTORAGE:
  1043. long_return = gp->storageType;
  1044. *write_method = write_vacmAccessStorageType;
  1045. return (u_char *)&long_return;
  1046.     case ACCESSSTATUS:
  1047. long_return = gp->status;
  1048. *write_method = write_vacmAccessStatus;
  1049. return (u_char *)&long_return;
  1050.     }
  1051.     return NULL;
  1052. }
  1053. u_char *var_vacm_view(struct variable *vp,
  1054.   oid *name,
  1055.   int *length,
  1056.   int exact,
  1057.   int *var_len,
  1058.   WriteMethod **write_method)
  1059. {
  1060.     struct vacm_viewEntry *gp;
  1061.     char viewName[32];
  1062.     oid subtree[MAX_OID_LEN], new_name[MAX_OID_LEN];
  1063.     int subtreeLen = 0, new_len;
  1064.     oid *op, *op1;
  1065.     int len;
  1066.     char *cp;
  1067.     int cmp;
  1068.     *write_method = NULL;
  1069. new_len = (*length > MAX_OID_LEN)?MAX_OID_LEN:*length;
  1070. memcpy (new_name, name, new_len*sizeof(oid));
  1071.     if (memcmp(new_name, vp->name, sizeof(oid)*vp->namelen) != 0) {
  1072. memcpy(new_name, vp->name, sizeof(oid)*vp->namelen);
  1073. new_len = vp->namelen;
  1074.     }
  1075.     if (exact) {
  1076. if (new_len < 15) return NULL;
  1077. op = new_name+12;
  1078. len = *op++;
  1079. if (len > new_len)
  1080. return NULL;
  1081. cp = viewName;
  1082. while (len-- > 0) {
  1083.             if (*op > 255)
  1084. return 0; /* illegal value */
  1085. *cp++ = (char) *op++;
  1086. }
  1087. *cp = 0;
  1088. len = *op++;
  1089. if (len > new_len)
  1090. return NULL;
  1091. op1 = subtree;
  1092. while (len-- > 0) {
  1093. *op1++ = *op++;
  1094. subtreeLen++;
  1095. }
  1096. if (op != new_name + new_len) {
  1097. return NULL;
  1098. }
  1099. gp = vacm_getViewEntry(viewName, subtree, subtreeLen);
  1100.     }
  1101.     else {
  1102. viewName[0] = 0;
  1103. op = new_name+12;
  1104. if (op >= new_name + new_len) {
  1105. }
  1106. else {
  1107. len = *op;
  1108. if (len > new_len)
  1109. return NULL;
  1110. cp = viewName;
  1111. while (len-- >= 0) {
  1112.                 if (*op > 255)
  1113. return 0; /* illegal value */
  1114. *cp++ = (char) *op++;
  1115. }
  1116. *cp = 0;
  1117. }
  1118. if (op >= new_name + new_len) {
  1119. }
  1120. else {
  1121. len = *op++;
  1122. op1 = subtree;
  1123. while (len-- > 0) {
  1124. *op1++ = *op++;
  1125. subtreeLen++;
  1126. }
  1127. }
  1128. vacm_scanViewInit();
  1129. while ((gp = vacm_scanViewNext()) != NULL) {
  1130. cmp = strcmp(gp->viewName, viewName);
  1131. if (cmp > 0) break;
  1132. if (cmp < 0) continue;
  1133. }
  1134. if (gp) {
  1135. new_len = 12;
  1136. cp = gp->viewName;
  1137. do {
  1138. new_name[(new_len)++] = *cp++;
  1139. } while (*cp);
  1140. op1 = gp->viewSubtree;
  1141. len = gp->viewSubtreeLen;
  1142. new_name[(new_len)++] = len;
  1143. while (len-- > 0){
  1144. new_name[(new_len)++] = *op1++;
  1145. }
  1146. memcpy (name, new_name, new_len*sizeof(oid));
  1147. *length = new_len;
  1148. }
  1149.     }
  1150.     if (!gp) {
  1151.     if (vp->magic == VIEWSTATUS)  {
  1152. *write_method = vacmViewTreeFamilyStatus;
  1153. }
  1154. return NULL;
  1155. }
  1156.     *var_len =sizeof(long_return);
  1157.     switch (vp->magic) {
  1158.     case VIEWNAME:
  1159. *var_len = gp->viewName[0];
  1160. return (u_char *)&gp->viewName[1];
  1161.     case VIEWSUBTREE:
  1162. *var_len = gp->viewSubtreeLen*sizeof(oid);
  1163. return (u_char *)gp->viewSubtree;
  1164.     case VIEWMASK:
  1165. *var_len = (gp->viewSubtreeLen + 7) / 8;
  1166. *write_method = write_vacmViewTreeFamilyMask;
  1167. return (u_char *)gp->viewMask;
  1168.     case VIEWTYPE:
  1169. long_return = gp->viewType;
  1170. *write_method = write_vacmViewTreeFamilyType;
  1171. return (u_char *)&long_return;
  1172.     case VIEWSTORAGE:
  1173. long_return = gp->viewStorageType;
  1174. *write_method = write_vacmViewTreeFamilyStorageType;
  1175. return (u_char *)&long_return;
  1176.     case VIEWSTATUS:
  1177. long_return = gp->viewStatus;
  1178. *write_method = vacmViewTreeFamilyStatus;
  1179. return (u_char *)&long_return;
  1180.     }
  1181.     return NULL;
  1182. }
  1183. /*****************************************************
  1184. *The following functions are added by sxf 2k-12-29 
  1185. * for snmp set operation.
  1186. *****************************************************/
  1187. /****************************************************
  1188. *WriteMethods for vacmSecurityToGroup
  1189. ****************************************************/
  1190. int
  1191. write_vacmGroupName(
  1192.    int      action,
  1193.    u_char   *var_val,
  1194.    u_char   var_val_type,
  1195.    int var_val_len,
  1196.    u_char   *statP,
  1197.    oid      *name,
  1198.    int name_len)
  1199. {
  1200. static unsigned char string[VACMSTRINGLEN];
  1201. int size;
  1202.     struct vacm_groupEntry *gp;
  1203.     oid *groupSubtree;
  1204.     int groupSubtreeLen;
  1205.     int secmodel;
  1206.     char secname[32], *cp;
  1207. if (var_val_type != ASN_OCTET_STR) {
  1208. DEBUGMSGTL(("vacmSecurityToGroup","write to vacmGroupName not ASN_OCTET_STRn"));
  1209. return SNMP_ERR_WRONGTYPE;
  1210. }
  1211. if (var_val_len > sizeof(string) - 1|| var_val_len <= 0) {
  1212. DEBUGMSGTL(("vacmSecurityToGroup","write to vacmGroupName: bad lengthn"));
  1213. return SNMP_ERR_WRONGLENGTH;
  1214. }
  1215. /* spec check, ??? */
  1216. size = var_val_len;
  1217. memcpy(string, var_val, var_val_len);
  1218. /* Find the struct in the linked list and check status */
  1219. if (name_len < 13) return SNMP_ERR_INCONSISTENTVALUE;
  1220. secmodel = name[11];
  1221. groupSubtree = name+13;
  1222. groupSubtreeLen = name_len - 13;
  1223. cp = secname;
  1224. while (groupSubtreeLen-- > 0) {
  1225. if (*groupSubtree > 255)
  1226. return 0; /* illegal value */
  1227. *cp++ = (char) *groupSubtree++;
  1228. }
  1229. *cp = 0;
  1230. gp = vacm_getGroupEntry(secmodel, secname);
  1231. if ( gp == NULL) {
  1232. DEBUGMSGTL(("vacmSecurityToGroup","write to vacmGroupName : BAD OID!n"));
  1233. return SNMP_ERR_NOSUCHNAME;
  1234. }
  1235. /* row exists, check if it is changeable */
  1236. if (gp->storageType == SNMP_STORAGE_READONLY) {
  1237. DEBUGMSGTL(("vacmSecurityToGroup","write to vacmGroupName : row is read onlyn"));
  1238. return SNMP_ERR_READONLY;
  1239. }
  1240. if (gp->status == SNMP_ROW_ACTIVE && strcmp (gp->groupName, string) != 0)
  1241. return SNMP_ERR_INCONSISTENTVALUE;
  1242. /* Finally, we're golden, check if we should save value */
  1243. if (action == COMMIT)  {    
  1244. memcpy(gp->groupName, string, size);
  1245. gp->groupName[size] = '';
  1246. /* If row is new, check if its status can be updated */
  1247. if ( gp->status == SNMP_ROW_NOTREADY)
  1248. gp->status = SNMP_ROW_NOTINSERVICE;
  1249. }
  1250. return SNMP_ERR_NOERROR;
  1251. }  /* write_vacmGroupName */
  1252. int
  1253. write_vacmSecurityToGroupStorageType(
  1254.  int      action,
  1255.  u_char   *var_val,
  1256.  u_char   var_val_type,
  1257.  int   var_val_len,
  1258.  u_char   *statP,
  1259.  oid      *name,
  1260.  int   name_len)
  1261. {
  1262. static long long_ret;
  1263.     struct vacm_groupEntry *gp;
  1264.     oid *groupSubtree;
  1265.     int groupSubtreeLen;
  1266.     int secmodel;
  1267.     char secname[32], *cp;
  1268. if (var_val_type != ASN_INTEGER) {
  1269. DEBUGMSGTL(("vacmSecurityToGroup","write to vacmSecurityToGroupStorageType not ASN_INTEGERn"));
  1270. return SNMP_ERR_WRONGTYPE;
  1271. }
  1272. if (var_val_len > sizeof(long_ret)) {
  1273. DEBUGMSGTL(("vacmSecurityToGroupEntry","write to vacmSecurityToGroupStorageType: bad lengthn"));
  1274. return SNMP_ERR_WRONGLENGTH;
  1275. }
  1276. long_ret = *((long *) var_val);
  1277. if ( (long_ret != SNMP_STORAGE_OTHER) && (long_ret != SNMP_STORAGE_VOLATILE) &&
  1278. (long_ret != SNMP_STORAGE_NONVOLATILE) )  {
  1279. DEBUGMSGTL(("vacmSecurityToGroupEntry", "write to vacmSecurityToGroupStorageType : attempted storage type not a valid"));
  1280. DEBUGMSG(("vacmSecurityToGroupEntry", "  value of other(%d), volatile(%d), or nonvolatile(%d)n", 
  1281. SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE, SNMP_STORAGE_NONVOLATILE));
  1282. return SNMP_ERR_INCONSISTENTVALUE;
  1283. }
  1284. /* Find the struct in the linked list and check status */
  1285. if (name_len < 13) return SNMP_ERR_INCONSISTENTVALUE;
  1286. secmodel = name[11];
  1287. groupSubtree = name+13;
  1288. groupSubtreeLen = name_len - 13;
  1289. cp = secname;
  1290. while (groupSubtreeLen-- > 0) {
  1291. if (*groupSubtree > 255)
  1292. return 0; /* illegal value */
  1293. *cp++ = (char) *groupSubtree++;
  1294. }
  1295. *cp = 0;
  1296. gp = vacm_getGroupEntry(secmodel, secname);
  1297. if (gp == NULL ) {
  1298. DEBUGMSGTL(("vacmSecurityToGroupEntry","write to vacmSecurityToGroupStorageType : BAD OIDn"));
  1299. return SNMP_ERR_NOSUCHNAME;
  1300. }
  1301. if ( (gp->storageType == SNMP_STORAGE_PERMANENT) || 
  1302. (gp->storageType == SNMP_STORAGE_READONLY) )  {
  1303. DEBUGMSGTL(("vacmSecurityToGroupEntry", "write to vacmSecurityToGroupStorageType : row has unchangeable storage status: %dn",
  1304. gp->storageType));
  1305. return SNMP_ERR_INCONSISTENTVALUE;
  1306. }
  1307. /* Finally, we're golden, check if we should save new value */
  1308. if (action == COMMIT) {      
  1309. gp->storageType = long_ret;
  1310. }
  1311. return SNMP_ERR_NOERROR;
  1312. }  /* write_vacmSecurityToGroupStorageType */
  1313. /* Assign a value to the Row Status variable */
  1314. int
  1315. write_vacmSecurity2GroupStatus(
  1316.    int      action,
  1317.    u_char   *var_val,
  1318.    u_char   var_val_type,
  1319.    int   var_val_len,
  1320.    u_char   *statP,
  1321.    oid      *name,
  1322.    int   name_len)
  1323. {
  1324. enum commit_action_enum        {NOTHING, DESTROY, CREATE, CHANGE};
  1325. enum commit_action_enum        onCommitDo; 
  1326. static long                    long_ret;
  1327.     struct vacm_groupEntry *gp;
  1328.     oid *groupSubtree;
  1329.     int groupSubtreeLen;
  1330.     int secmodel;
  1331.     char secname[32], *cp;
  1332. if (var_val_type != ASN_INTEGER) {
  1333. DEBUGMSGTL(("vacmSecurityToGroup","write to vacmSecurity2GroupStatus not ASN_INTEGERn"));
  1334. return SNMP_ERR_WRONGTYPE;
  1335. }
  1336. if (var_val_len > sizeof(long_ret)) {
  1337. DEBUGMSGTL(("vacmSecurityToGroup","write to vacmSecurityToGroupStatus: bad lengthn"));
  1338. return SNMP_ERR_WRONGLENGTH;
  1339. }
  1340. long_ret = *((long *) var_val);
  1341. /* search for struct in linked list */
  1342. if (name_len < 13) return SNMP_ERR_INCONSISTENTVALUE;
  1343. secmodel = name[11];
  1344. groupSubtree = name+13;
  1345. groupSubtreeLen = name_len - 13;
  1346. cp = secname;
  1347. while (groupSubtreeLen-- > 0) {
  1348. if (*groupSubtree > 255)
  1349. return 0; /* illegal value */
  1350. *cp++ = (char) *groupSubtree++;
  1351. }
  1352. *cp = 0;
  1353. gp = vacm_getGroupEntry(secmodel, secname);
  1354. if (gp == NULL) {
  1355. /* row doesn't exist, check valid possibilities */
  1356. if (long_ret == SNMP_ROW_DESTROY)  
  1357. /* re: RFC 1903, destroying a non-existent row is noError, whatever */
  1358. onCommitDo = NOTHING;
  1359. /* check if this is for a new row creation */
  1360. else if (long_ret == SNMP_ROW_CREATEANDGO || long_ret == SNMP_ROW_CREATEANDWAIT) 
  1361. onCommitDo = CREATE;
  1362. else /* no valid sets for no row being found so... */
  1363. return SNMP_ERR_NOSUCHNAME;
  1364. }
  1365. else {  /* row exists */
  1366. /* check if it is changeable */
  1367. if (gp->storageType == SNMP_STORAGE_READONLY) {
  1368. DEBUGMSGTL(("vacmSecurity2Group","write to vacmSecurity2GroupStatus : row is read onlyn"));
  1369. return SNMP_ERR_READONLY;
  1370. }    
  1371. /* check if row is to be destroyed (note: it is ok to destroy notReady row!) */
  1372. else if (long_ret == SNMP_ROW_DESTROY)  {
  1373. if (gp->storageType == SNMP_STORAGE_PERMANENT) {
  1374. DEBUGMSGTL(("vacmSecurity2Group","write to vacmSecurity2GroupStatus : unable to destroy permanent rown"));
  1375. return SNMP_ERR_INCONSISTENTVALUE;
  1376. }
  1377. else  {
  1378. onCommitDo = DESTROY;
  1379. }
  1380. }
  1381. /* check if row is new and can be changed from notready yet */
  1382. else if (gp->status == SNMP_ROW_NOTREADY) {
  1383. DEBUGMSGTL(("vacmSecurity2Group","write to vacmSecurity2GroupStatus : unable to change from NOTREADYn"));
  1384. return SNMP_ERR_INCONSISTENTVALUE;
  1385. }  
  1386. /* we now know the row status can be set, check for the two valid settings left*/
  1387. else if ( (long_ret == SNMP_ROW_ACTIVE) || 
  1388. (long_ret == SNMP_ROW_NOTINSERVICE) ) {
  1389. onCommitDo = CHANGE;
  1390. }
  1391. /* not a valid setting */
  1392. else  {
  1393. DEBUGMSGTL(("vacmSecurity2Group","write to vacmSecurity2GroupStatus : Bad value for setn"));
  1394. return SNMP_ERR_INCONSISTENTVALUE;
  1395. }
  1396. } /* if row exist */
  1397. /* if this is a commit, do expected action */
  1398. if (action == COMMIT) {
  1399. switch(onCommitDo) { 
  1400. case CREATE :
  1401. if (vacm_createGroupEntry(secmodel, secname) == 0) {
  1402. DEBUGMSGTL(("vacmSecurity2Group", "write to vacmSecurity2GroupStatus : "));
  1403. DEBUGMSG(("vacmSecurity2Group","failed new row creation, bad OID/index value n"));
  1404. return SNMP_ERR_GENERR;
  1405. }
  1406. break;
  1407. case DESTROY:
  1408. vacm_destroyGroupEntry(secmodel, secname);
  1409. break;
  1410. case CHANGE:
  1411. gp->status = long_ret;
  1412. break;
  1413. case NOTHING:
  1414. default:
  1415. break;
  1416. }
  1417. }
  1418. return SNMP_ERR_NOERROR;
  1419. }  /* write_vacmSecurity2GroupStatus */
  1420. /******************************************************************
  1421. *WriteMethods for vacmAccess
  1422. *****************************************************************/
  1423. int check_accessEntryStatus (struct vacm_accessEntry *ap)
  1424. {
  1425. if (ap->contextMatch == 1 || ap->contextMatch == 2)
  1426. {
  1427. if (ap->readView[0] != '' || ap->writeView[0] != '' || ap->notifyView[0] != '')
  1428. {
  1429. return SNMP_ROW_NOTINSERVICE;
  1430. }
  1431. }
  1432. return SNMP_ROW_NOTREADY;
  1433. }
  1434. int get_accessEntryFromName (oid *name, int name_len,  struct vacm_accessEntry **gpp)
  1435. {
  1436.     int secmodel;
  1437.     int seclevel;
  1438.     char groupName[32];
  1439.     char contextPrefix[32];
  1440.     oid *op;
  1441.     int len;
  1442.     char *cp;
  1443. *gpp = NULL;
  1444. /* search for struct in linked list */
  1445. if (name_len < 15) return SNMP_ERR_INCONSISTENTVALUE;
  1446. op = name+11;
  1447. len = *op++;
  1448. cp = groupName;
  1449. if (len > 128)
  1450. return SNMP_ERR_INCONSISTENTVALUE;
  1451. while (len-- > 0) {
  1452. if (*op > 255)
  1453. return 0; /* illegal value */
  1454. *cp++ = (char) *op++;
  1455. }
  1456. *cp = 0;
  1457. len = *op++;
  1458. cp = contextPrefix;
  1459. if (len > 128)
  1460. return SNMP_ERR_INCONSISTENTVALUE;
  1461. while (len-- > 0) {
  1462. if (*op > 255)
  1463. return 0; /* illegal value */
  1464. *cp++ = (char) *op++;
  1465. }
  1466. *cp = 0;
  1467. secmodel = *op++;
  1468. seclevel = *op++;
  1469. if (op != name + name_len) {
  1470. return SNMP_ERR_INCONSISTENTVALUE;
  1471. }
  1472. *gpp = vacm_getAccessEntry(groupName, contextPrefix, secmodel, seclevel);
  1473. return SNMP_ERR_NOERROR;
  1474. }
  1475. int
  1476. write_vacmAccessContextMatch(
  1477.  int action,
  1478.  u_char *var_val,
  1479.  u_char var_val_type,
  1480.  int var_val_len,
  1481.  u_char *statP,
  1482.  oid *name,
  1483.  int name_len)
  1484. {
  1485. /* variables we may use later */
  1486. static long                 long_ret;
  1487. int return_val;
  1488.     struct vacm_accessEntry *gp;
  1489. if (var_val_type != ASN_INTEGER) {
  1490. DEBUGMSGTL(("vacmAccess","write to vacmAccessContextMatch not ASN_INTEGERn"));
  1491. return SNMP_ERR_WRONGTYPE;
  1492. }
  1493. if (var_val_len > sizeof(long_ret)) {
  1494. DEBUGMSGTL(("vacmAccess","write to vacmAccessContextMatch: bad lengthn"));
  1495. return SNMP_ERR_WRONGLENGTH;
  1496. }
  1497. long_ret = *((long *) var_val);
  1498. if (long_ret != 1 && long_ret != 2)
  1499. {
  1500. DEBUGMSGTL(("vacmAccess","write to vacmAccessContextMatch : Bad value for setn"));
  1501. return SNMP_ERR_INCONSISTENTVALUE; 
  1502. }
  1503. /* spec check range, no spec check */
  1504. /* Find row in linked list and check pertinent status... */
  1505. if ((return_val = get_accessEntryFromName (name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1506. return return_val;
  1507. if (gp == NULL) {
  1508. DEBUGMSGTL(("vacmAccess","write to vacmAccessContextMatch: BAD OIDn"));
  1509. return SNMP_ERR_NOSUCHNAME;
  1510. }
  1511. if (gp->storageType == SNMP_STORAGE_READONLY) {
  1512. DEBUGMSGTL(("vacmAccess","write to vacmAccessContextMatch: row is read onlyn"));
  1513. return SNMP_ERR_READONLY;
  1514. }
  1515. if (gp->status == SNMP_ROW_ACTIVE && gp->contextMatch != long_ret)
  1516. return SNMP_ERR_INCONSISTENTVALUE;
  1517. /* Finally, we're golden, should we save value? */
  1518. if (action == COMMIT)  {
  1519. gp->contextMatch = long_ret;
  1520. if ( gp->status == SNMP_ROW_NOTREADY)
  1521. gp->status = check_accessEntryStatus (gp);
  1522. }
  1523. return SNMP_ERR_NOERROR;
  1524. }  /* write_vacmAccessContextMatch */
  1525. int
  1526. write_vacmAccessReadViewName(
  1527.    int      action,
  1528.    u_char   *var_val,
  1529.    u_char   var_val_type,
  1530.    int var_val_len,
  1531.    u_char   *statP,
  1532.    oid      *name,
  1533.    int name_len)
  1534. {
  1535. static unsigned char string[VACMSTRINGLEN];
  1536. int size, return_val;
  1537.     struct vacm_accessEntry *gp;
  1538. if (var_val_type != ASN_OCTET_STR) {
  1539. DEBUGMSGTL(("vacmAccess","write to vacmAccessReadViewName not ASN_OCTET_STRn"));
  1540. return SNMP_ERR_WRONGTYPE;
  1541. }
  1542. if (var_val_len > sizeof(string) - 1|| var_val_len <= 0) {
  1543. DEBUGMSGTL(("vacmAccess","write to vacmAccessReadViewName: bad lengthn"));
  1544. return SNMP_ERR_WRONGLENGTH;
  1545. }
  1546. /* spec check, ??? */
  1547. size = var_val_len;
  1548. memcpy(string, var_val, var_val_len);
  1549. if ((return_val = get_accessEntryFromName (name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1550. return return_val;
  1551. if ( gp == NULL) {
  1552. DEBUGMSGTL(("vacmAccess","write to vacmAccessReadViewName: BAD OID!n"));
  1553. return SNMP_ERR_NOSUCHNAME;
  1554. }
  1555. /* row exists, check if it is changeable */
  1556. if (gp->storageType == SNMP_STORAGE_READONLY) {
  1557. DEBUGMSGTL(("vacmAccess","write to vacmAccessReadViewName: row is read onlyn"));
  1558. return SNMP_ERR_READONLY;
  1559. }
  1560. if (gp->status == SNMP_ROW_ACTIVE && strcmp (gp->readView, string) != 0)
  1561. return SNMP_ERR_INCONSISTENTVALUE;
  1562. /* Finally, we're golden, check if we should save value */
  1563. if (action == COMMIT)  {    
  1564. memcpy(gp->readView, string, size);
  1565. gp->readView[size] = '';
  1566. /* If row is new, check if its status can be updated */
  1567. if ( gp->status == SNMP_ROW_NOTREADY)
  1568. gp->status = check_accessEntryStatus (gp);
  1569. }
  1570. return SNMP_ERR_NOERROR;
  1571. }  /* write_vacmAccessReadViewName */
  1572. int
  1573. write_vacmAccessWriteViewName(
  1574.    int      action,
  1575.    u_char   *var_val,
  1576.    u_char   var_val_type,
  1577.    int var_val_len,
  1578.    u_char   *statP,
  1579.    oid      *name,
  1580.    int name_len)
  1581. {
  1582. static unsigned char string[VACMSTRINGLEN];
  1583. int size, return_val;
  1584.     struct vacm_accessEntry *gp;
  1585. if (var_val_type != ASN_OCTET_STR) {
  1586. DEBUGMSGTL(("vacmAccess","write to vacmAccessWriteViewName not ASN_OCTET_STRn"));
  1587. return SNMP_ERR_WRONGTYPE;
  1588. }
  1589. if (var_val_len > sizeof(string) - 1|| var_val_len <= 0) {
  1590. DEBUGMSGTL(("vacmAccess","write to vacmAccessWriteViewName: bad lengthn"));
  1591. return SNMP_ERR_WRONGLENGTH;
  1592. }
  1593. /* spec check, ??? */
  1594. size = var_val_len;
  1595. memcpy(string, var_val, var_val_len);
  1596. if ((return_val = get_accessEntryFromName (name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1597. return return_val;
  1598. if ( gp == NULL) {
  1599. DEBUGMSGTL(("vacmAccess","write to vacmAccessWriteViewName: BAD OID!n"));
  1600. return SNMP_ERR_NOSUCHNAME;
  1601. }
  1602. /* row exists, check if it is changeable */
  1603. if (gp->storageType == SNMP_STORAGE_READONLY) {
  1604. DEBUGMSGTL(("vacmAccess","write to vacmAccessWriteViewName: row is read onlyn"));
  1605. return SNMP_ERR_READONLY;
  1606. }
  1607. if (gp->status == SNMP_ROW_ACTIVE && strcmp (gp->writeView, string) != 0)
  1608. return SNMP_ERR_INCONSISTENTVALUE;
  1609. /* Finally, we're golden, check if we should save value */
  1610. if (action == COMMIT)  {    
  1611. memcpy(gp->writeView, string, size);
  1612. gp->writeView[size] = '';
  1613. /* If row is new, check if its status can be updated */
  1614. if ( gp->status == SNMP_ROW_NOTREADY)
  1615. gp->status = check_accessEntryStatus (gp);
  1616. }
  1617. return SNMP_ERR_NOERROR;
  1618. }  /* write_vacmAccessWriteViewName */
  1619. int
  1620. write_vacmAccessNotifyViewName(
  1621.    int      action,
  1622.    u_char   *var_val,
  1623.    u_char   var_val_type,
  1624.    int var_val_len,
  1625.    u_char   *statP,
  1626.    oid      *name,
  1627.    int name_len)
  1628. {
  1629. static unsigned char string[VACMSTRINGLEN];
  1630. int size, return_val;
  1631.     struct vacm_accessEntry *gp;
  1632. if (var_val_type != ASN_OCTET_STR) {
  1633. DEBUGMSGTL(("vacmAccess","write to vacmAccessNotifyViewName not ASN_OCTET_STRn"));
  1634. return SNMP_ERR_WRONGTYPE;
  1635. }
  1636. if (var_val_len > sizeof(string) - 1|| var_val_len <= 0) {
  1637. DEBUGMSGTL(("vacmAccess","write to vacmAccessNotifyViewName: bad lengthn"));
  1638. return SNMP_ERR_WRONGLENGTH;
  1639. }
  1640. /* spec check, ??? */
  1641. size = var_val_len;
  1642. memcpy(string, var_val, var_val_len);
  1643. if ((return_val = get_accessEntryFromName (name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1644. return return_val;
  1645. if ( gp == NULL) {
  1646. DEBUGMSGTL(("vacmAccess","write to vacmAccessNotifyViewName: BAD OID!n"));
  1647. return SNMP_ERR_NOSUCHNAME;
  1648. }
  1649. /* row exists, check if it is changeable */
  1650. if (gp->storageType == SNMP_STORAGE_READONLY) {
  1651. DEBUGMSGTL(("vacmAccess","write to vacmAccessNotifyViewName: row is read onlyn"));
  1652. return SNMP_ERR_READONLY;
  1653. }
  1654. if (gp->status == SNMP_ROW_ACTIVE && strcmp (gp->notifyView, string) != 0)
  1655. return SNMP_ERR_INCONSISTENTVALUE;
  1656. /* Finally, we're golden, check if we should save value */
  1657. if (action == COMMIT)  {    
  1658. memcpy(gp->notifyView, string, size);
  1659. gp->notifyView[size] = '';
  1660. /* If row is new, check if its status can be updated */
  1661. if ( gp->status == SNMP_ROW_NOTREADY)
  1662. gp->status = check_accessEntryStatus (gp);
  1663. }
  1664. return SNMP_ERR_NOERROR;
  1665. }  /* write_vacmAccessNotifyViewName */
  1666. int
  1667. write_vacmAccessStorageType(
  1668.  int      action,
  1669.  u_char   *var_val,
  1670.  u_char   var_val_type,
  1671.  int   var_val_len,
  1672.  u_char   *statP,
  1673.  oid      *name,
  1674.  int   name_len)
  1675. {
  1676. static long long_ret;
  1677.     struct vacm_accessEntry *gp;
  1678. int return_val;
  1679. if (var_val_type != ASN_INTEGER) {
  1680. DEBUGMSGTL(("vacmAccess","write to vacmAccessStorageType not ASN_INTEGERn"));
  1681. return SNMP_ERR_WRONGTYPE;
  1682. }
  1683. if (var_val_len > sizeof(long_ret)) {
  1684. DEBUGMSGTL(("vacmAccess","write to vacmAccessStorageType: bad lengthn"));
  1685. return SNMP_ERR_WRONGLENGTH;
  1686. }
  1687. long_ret = *((long *) var_val);
  1688. if ( (long_ret != SNMP_STORAGE_OTHER) && (long_ret != SNMP_STORAGE_VOLATILE) &&
  1689. (long_ret != SNMP_STORAGE_NONVOLATILE) )  {
  1690. DEBUGMSGTL(("vacmAccess", "write to vacmAccessStorageType : attempted storage type not a valid"));
  1691. DEBUGMSG(("vacmAccess", "  value of other(%d), volatile(%d), or nonvolatile(%d)n", 
  1692. SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE, SNMP_STORAGE_NONVOLATILE));
  1693. return SNMP_ERR_INCONSISTENTVALUE;
  1694. }
  1695. /* Find the struct in the linked list and check status */
  1696. if ((return_val = get_accessEntryFromName (name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1697. return return_val;
  1698. if (gp == NULL ) {
  1699. DEBUGMSGTL(("vacmAccess","write to vacmAccessStorageType : BAD OIDn"));
  1700. return SNMP_ERR_NOSUCHNAME;
  1701. }
  1702. if ( (gp->storageType == SNMP_STORAGE_PERMANENT) || 
  1703. (gp->storageType == SNMP_STORAGE_READONLY) )  {
  1704. DEBUGMSGTL(("vacmAccess", "write to vacmAccessStorageType : row has unchangeable storage status: %dn",
  1705. gp->storageType));
  1706. return SNMP_ERR_INCONSISTENTVALUE;
  1707. }
  1708. /* Finally, we're golden, check if we should save new value */
  1709. if (action == COMMIT) {      
  1710. gp->storageType = long_ret;
  1711. }
  1712. return SNMP_ERR_NOERROR;
  1713. }  /* write_vacmAccessStorageType */
  1714. /* Assign a value to the Row Status variable */
  1715. int
  1716. write_vacmAccessStatus(
  1717.    int      action,
  1718.    u_char   *var_val,
  1719.    u_char   var_val_type,
  1720.    int var_val_len,
  1721.    u_char   *statP,
  1722.    oid      *name,
  1723.    int name_len)
  1724. {
  1725. enum commit_action_enum {NOTHING, DESTROY, CREATE, CHANGE};
  1726. enum commit_action_enum onCommitDo; 
  1727. static long long_ret;
  1728.     struct vacm_accessEntry *gp;
  1729.     int secmodel;
  1730.     int seclevel;
  1731.     char groupName[32];
  1732.     char contextPrefix[32];
  1733.     oid *op;
  1734.     int len;
  1735.     char *cp;
  1736. if (var_val_type != ASN_INTEGER) {
  1737. DEBUGMSGTL(("vacmAccess","write to vacmAccessStatus not ASN_INTEGERn"));
  1738. return SNMP_ERR_WRONGTYPE;
  1739. }
  1740. if (var_val_len > sizeof(long_ret)) {
  1741. DEBUGMSGTL(("vacmAccess","write to vacmAccessStatus: bad lengthn"));
  1742. return SNMP_ERR_WRONGLENGTH;
  1743. }
  1744. long_ret = *((long *) var_val);
  1745. /* search for struct in linked list */
  1746. op = name+11;
  1747. len = *op++;
  1748. cp = groupName;
  1749. if (len > 128)
  1750. return SNMP_ERR_INCONSISTENTVALUE;
  1751. while (len-- > 0) {
  1752. if (*op > 255)
  1753. return 0; /* illegal value */
  1754. *cp++ = (char) *op++;
  1755. }
  1756. *cp = 0;
  1757. len = *op++;
  1758. cp = contextPrefix;
  1759. if (len > 128)
  1760. return SNMP_ERR_INCONSISTENTVALUE;
  1761. while (len-- > 0) {
  1762. if (*op > 255)
  1763. return 0; /* illegal value */
  1764. *cp++ = (char) *op++;
  1765. }
  1766. *cp = 0;
  1767. secmodel = *op++;
  1768. seclevel = *op++;
  1769. if (op != name + name_len) {
  1770. return SNMP_ERR_INCONSISTENTVALUE;
  1771. }
  1772. gp = vacm_getAccessEntry(groupName, contextPrefix, secmodel, seclevel);
  1773. if (gp == NULL) {
  1774. /* row doesn't exist, check valid possibilities */
  1775. if (long_ret == SNMP_ROW_DESTROY)  
  1776. /* re: RFC 1903, destroying a non-existent row is noError, whatever */
  1777. onCommitDo = NOTHING;
  1778. /* check if this is for a new row creation */
  1779. else if (long_ret == SNMP_ROW_CREATEANDGO || long_ret == SNMP_ROW_CREATEANDWAIT) 
  1780. onCommitDo = CREATE;
  1781. else /* no valid sets for no row being found so... */
  1782. return SNMP_ERR_NOSUCHNAME;
  1783. }
  1784. else {  /* row exists */
  1785. /* check if it is changeable */
  1786. if (gp->storageType == SNMP_STORAGE_READONLY) {
  1787. DEBUGMSGTL(("vacmAccess","write to vacmAccessStatus : row is read onlyn"));
  1788. return SNMP_ERR_READONLY;
  1789. }    
  1790. /* check if row is to be destroyed (note: it is ok to destroy notReady row!) */
  1791. else if (long_ret == SNMP_ROW_DESTROY)  {
  1792. if (gp->storageType == SNMP_STORAGE_PERMANENT) {
  1793. DEBUGMSGTL(("vacmAccess","write to vacmAccessStatus : unable to destroy permanent rown"));
  1794. return SNMP_ERR_INCONSISTENTVALUE;
  1795. }
  1796. else  {
  1797. onCommitDo = DESTROY;
  1798. }
  1799. }
  1800. /* check if row is new and can be changed from notready yet */
  1801. else if (gp->status == SNMP_ROW_NOTREADY) {
  1802. DEBUGMSGTL(("vacmAccess","write to vacmAccessStatus : unable to change from NOTREADYn"));
  1803. return SNMP_ERR_INCONSISTENTVALUE;
  1804. }  
  1805. /* we now know the row status can be set, check for the two valid settings left*/
  1806. else if ( (long_ret == SNMP_ROW_ACTIVE) || 
  1807. (long_ret == SNMP_ROW_NOTINSERVICE) ) {
  1808. onCommitDo = CHANGE;
  1809. }
  1810. /* not a valid setting */
  1811. else  {
  1812. DEBUGMSGTL(("vacmAccess","write to vacmAccessStatus : Bad value for setn"));
  1813. return SNMP_ERR_INCONSISTENTVALUE;
  1814. }
  1815. } /* if row exist */
  1816. /* if this is a commit, do expected action */
  1817. if (action == COMMIT) {
  1818. switch(onCommitDo) { 
  1819. case CREATE :
  1820. if (vacm_createAccessEntry(groupName, contextPrefix,secmodel, seclevel) == 0) {
  1821. DEBUGMSGTL(("vacmAccess", "write to vacmAccessStatus : "));
  1822. DEBUGMSG(("vacmAccess","failed new row creation, bad OID/index value n"));
  1823. return SNMP_ERR_GENERR;
  1824. }
  1825. break;
  1826. case DESTROY:
  1827. vacm_destroyAccessEntry(groupName, contextPrefix,secmodel, seclevel);
  1828. break;
  1829. case CHANGE:
  1830. gp->status = long_ret;
  1831. break;
  1832. case NOTHING:
  1833. default:
  1834. break;
  1835. }
  1836. }
  1837. return SNMP_ERR_NOERROR;
  1838. }  /* write_vacmAccessStatus */
  1839. /******************************************************************
  1840. *WriteMethods for vacmViewTreeFamily
  1841. *****************************************************************/
  1842. int get_viewEntryFromName (oid *name, int name_len, struct vacm_viewEntry **gpp)
  1843. {
  1844.     char viewName[32];
  1845.     oid subtree[MAX_OID_LEN];
  1846.     int subtreeLen = 0;
  1847.     oid *op, *op1;
  1848.     int len;
  1849.     char *cp;
  1850. *gpp = NULL;
  1851. if (name_len < 15) return SNMP_ERR_INCONSISTENTVALUE;
  1852. op = name+12;
  1853. len = *op++;
  1854. if (len > name_len)
  1855. return SNMP_ERR_INCONSISTENTVALUE;
  1856. cp = viewName;
  1857. while (len-- > 0) {
  1858. if (*op > 255)
  1859. return 0; /* illegal value */
  1860. *cp++ = (char) *op++;
  1861. }
  1862. *cp = 0;
  1863. len = *op++;
  1864. if (len > name_len)
  1865. return SNMP_ERR_INCONSISTENTVALUE;
  1866. op1 = subtree;
  1867. while (len-- > 0) {
  1868. *op1++ = *op++;
  1869. subtreeLen++;
  1870. }
  1871. if (op != name + name_len) {
  1872. return SNMP_ERR_INCONSISTENTVALUE;
  1873. }
  1874. *gpp = vacm_getViewEntry(viewName, subtree, subtreeLen);
  1875. return SNMP_ERR_NOERROR;
  1876. }
  1877. int
  1878. write_vacmViewTreeFamilyMask(
  1879.    int      action,
  1880.    u_char   *var_val,
  1881.    u_char   var_val_type,
  1882.    int var_val_len,
  1883.    u_char   *statP,
  1884.    oid      *name,
  1885.    int name_len)
  1886. {
  1887. static unsigned char string[VACMSTRINGLEN];
  1888. int size, return_val;
  1889. struct vacm_viewEntry *gp;
  1890. if (var_val_type != ASN_OCTET_STR) {
  1891. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyMask not ASN_OCTET_STRn"));
  1892. return SNMP_ERR_WRONGTYPE;
  1893. }
  1894. if (var_val_len > 16 /*the mask is less than 16 bytes*/|| var_val_len <= 0) {
  1895. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyMask: bad lengthn"));
  1896. return SNMP_ERR_WRONGLENGTH;
  1897. }
  1898. /* spec check, ??? */
  1899. size = var_val_len;
  1900. memcpy(string, var_val, var_val_len);
  1901. if ((return_val = get_viewEntryFromName (name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1902. return return_val;
  1903. if ( gp == NULL) {
  1904. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyMask: BAD OID!n"));
  1905. return SNMP_ERR_NOSUCHNAME;
  1906. }
  1907. /* row exists, check if it is changeable */
  1908. if (gp->viewStorageType == SNMP_STORAGE_READONLY) {
  1909. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyMask: row is read onlyn"));
  1910. return SNMP_ERR_READONLY;
  1911. }
  1912. /* Finally, we're golden, check if we should save value */
  1913. if (action == COMMIT)  {    
  1914. memcpy(gp->viewMask, string, size);
  1915. gp->viewMask[size] = '';
  1916. gp->viewMaskLen = size;
  1917. }
  1918. return SNMP_ERR_NOERROR;
  1919. }  /* write_vacmViewTreeFamilyMask */
  1920. int
  1921. write_vacmViewTreeFamilyType(
  1922.  int action,
  1923.  u_char *var_val,
  1924.  u_char var_val_type,
  1925.  int var_val_len,
  1926.  u_char *statP,
  1927.  oid *name,
  1928.  int name_len)
  1929. {
  1930. /* variables we may use later */
  1931. static long                 long_ret;
  1932. int return_val;
  1933. struct vacm_viewEntry *gp;
  1934. if (var_val_type != ASN_INTEGER) {
  1935. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyType not ASN_INTEGERn"));
  1936. return SNMP_ERR_WRONGTYPE;
  1937. }
  1938. if (var_val_len > sizeof(long_ret)) {
  1939. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyType: bad lengthn"));
  1940. return SNMP_ERR_WRONGLENGTH;
  1941. }
  1942. long_ret = *((long *) var_val);
  1943. if (long_ret != 1/*include*/ && long_ret != 2/*exclude*/)
  1944. {
  1945. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyType : Bad value for setn"));
  1946. return SNMP_ERR_INCONSISTENTVALUE; 
  1947. }
  1948. /* spec check range, no spec check */
  1949. /* Find row in linked list and check pertinent status... */
  1950. if ((return_val = get_viewEntryFromName (name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1951. return return_val;
  1952. if (gp == NULL) {
  1953. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyType: BAD OIDn"));
  1954. return SNMP_ERR_NOSUCHNAME;
  1955. }
  1956. if (gp->viewStorageType == SNMP_STORAGE_READONLY) {
  1957. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyType: row is read onlyn"));
  1958. return SNMP_ERR_READONLY;
  1959. }
  1960. /* Finally, we're golden, should we save value? */
  1961. if (action == COMMIT)  {
  1962. gp->viewType = long_ret;
  1963. }
  1964. return SNMP_ERR_NOERROR;
  1965. }  /* write_vacmViewTreeFamilyType */
  1966. int
  1967. write_vacmViewTreeFamilyStorageType(
  1968. int      action,
  1969. u_char   *var_val,
  1970. u_char   var_val_type,
  1971. int   var_val_len,
  1972. u_char   *statP,
  1973. oid      *name,
  1974. int   name_len)
  1975. {
  1976. static long long_ret;
  1977. struct vacm_viewEntry *gp;
  1978. int return_val;
  1979. if (var_val_type != ASN_INTEGER) {
  1980. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStorageType not ASN_INTEGERn"));
  1981. return SNMP_ERR_WRONGTYPE;
  1982. }
  1983. if (var_val_len > sizeof(long_ret)) {
  1984. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStorageType: bad lengthn"));
  1985. return SNMP_ERR_WRONGLENGTH;
  1986. }
  1987. long_ret = *((long *) var_val);
  1988. if ( (long_ret != SNMP_STORAGE_OTHER) && (long_ret != SNMP_STORAGE_VOLATILE) &&
  1989. (long_ret != SNMP_STORAGE_NONVOLATILE) )  {
  1990. DEBUGMSGTL(("vacmViewTreeFamily", "write to vacmViewTreeFamilyStorageType : attempted storage type not a valid"));
  1991. DEBUGMSG(("vacmViewTreeFamily", "  value of other(%d), volatile(%d), or nonvolatile(%d)n", 
  1992. SNMP_STORAGE_OTHER, SNMP_STORAGE_VOLATILE, SNMP_STORAGE_NONVOLATILE));
  1993. return SNMP_ERR_INCONSISTENTVALUE;
  1994. }
  1995. /* Find the struct in the linked list and check status */
  1996. if ((return_val = get_viewEntryFromName(name, name_len, &gp)) != SNMP_ERR_NOERROR)
  1997. return return_val;
  1998. if (gp == NULL ) {
  1999. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStorageType : BAD OIDn"));
  2000. return SNMP_ERR_NOSUCHNAME;
  2001. }
  2002. if ( (gp->viewStorageType == SNMP_STORAGE_PERMANENT) || 
  2003. (gp->viewStorageType == SNMP_STORAGE_READONLY) )  {
  2004. DEBUGMSGTL(("vacmViewTreeFamily", "write to vacmViewTreeFamilyStorageType : row has unchangeable storage status: %dn",
  2005. gp->viewStorageType));
  2006. return SNMP_ERR_INCONSISTENTVALUE;
  2007. }
  2008. /* Finally, we're golden, check if we should save new value */
  2009. if (action == COMMIT) {      
  2010. gp->viewStorageType = long_ret;
  2011. }
  2012. return SNMP_ERR_NOERROR;
  2013. }  /* write_vacmViewTreeFamilyStorageType */
  2014. /* Assign a value to the Row Status variable */
  2015. int
  2016. vacmViewTreeFamilyStatus(
  2017.    int      action,
  2018.    u_char   *var_val,
  2019.    u_char   var_val_type,
  2020.    int var_val_len,
  2021.    u_char   *statP,
  2022.    oid      *name,
  2023.    int name_len)
  2024. {
  2025. enum commit_action_enum {NOTHING, DESTROY, CREATE, CHANGE};
  2026. enum commit_action_enum onCommitDo; 
  2027. static long long_ret;
  2028. struct vacm_viewEntry *gp;
  2029. char viewName[32];
  2030.     oid subtree[MAX_OID_LEN];
  2031.     int subtreeLen = 0;
  2032.     oid *op, *op1;
  2033.     int len;
  2034.     char *cp;
  2035. if (var_val_type != ASN_INTEGER) {
  2036. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStatus not ASN_INTEGERn"));
  2037. return SNMP_ERR_WRONGTYPE;
  2038. }
  2039. if (var_val_len > sizeof(long_ret)) {
  2040. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStatus: bad lengthn"));
  2041. return SNMP_ERR_WRONGLENGTH;
  2042. }
  2043. long_ret = *((long *) var_val);
  2044. /* search for struct in linked list */
  2045. if (name_len < 15) return SNMP_ERR_INCONSISTENTVALUE;
  2046. op = name+12;
  2047. len = *op++;
  2048. if (len > name_len)
  2049. return SNMP_ERR_INCONSISTENTVALUE;
  2050. cp = viewName;
  2051. while (len-- > 0) {
  2052. if (*op > 255)
  2053. return 0; /* illegal value */
  2054. *cp++ = (char) *op++;
  2055. }
  2056. *cp = 0;
  2057. len = *op++;
  2058. if (len > name_len)
  2059. return SNMP_ERR_INCONSISTENTVALUE;
  2060. op1 = subtree;
  2061. while (len-- > 0) {
  2062. *op1++ = *op++;
  2063. subtreeLen++;
  2064. }
  2065. if (op != name + name_len) {
  2066. return SNMP_ERR_INCONSISTENTVALUE;
  2067. }
  2068. gp = vacm_getViewEntry(viewName, subtree, subtreeLen);
  2069. if (gp == NULL) {
  2070. /* row doesn't exist, check valid possibilities */
  2071. if (long_ret == SNMP_ROW_DESTROY)  
  2072. /* re: RFC 1903, destroying a non-existent row is noError, whatever */
  2073. onCommitDo = NOTHING;
  2074. /* check if this is for a new row creation */
  2075. else if (long_ret == SNMP_ROW_CREATEANDGO || long_ret == SNMP_ROW_CREATEANDWAIT) 
  2076. onCommitDo = CREATE;
  2077. else /* no valid sets for no row being found so... */
  2078. return SNMP_ERR_NOSUCHNAME;
  2079. }
  2080. else {  /* row exists */
  2081. /* check if it is changeable */
  2082. if (gp->viewStorageType == SNMP_STORAGE_READONLY) {
  2083. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStatus: row is read onlyn"));
  2084. return SNMP_ERR_READONLY;
  2085. }    
  2086. /* check if row is to be destroyed (note: it is ok to destroy notReady row!) */
  2087. else if (long_ret == SNMP_ROW_DESTROY)  {
  2088. if (gp->viewStorageType == SNMP_STORAGE_PERMANENT) {
  2089. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStatus: unable to destroy permanent rown"));
  2090. return SNMP_ERR_INCONSISTENTVALUE;
  2091. }
  2092. else  {
  2093. onCommitDo = DESTROY;
  2094. }
  2095. }
  2096. /* check if row is new and can be changed from notready yet */
  2097. else if (gp->viewStatus == SNMP_ROW_NOTREADY) {
  2098. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStatus: unable to change from NOTREADYn"));
  2099. return SNMP_ERR_INCONSISTENTVALUE;
  2100. }  
  2101. /* we now know the row status can be set, check for the two valid settings left*/
  2102. else if ( (long_ret == SNMP_ROW_ACTIVE) || 
  2103. (long_ret == SNMP_ROW_NOTINSERVICE) ) {
  2104. onCommitDo = CHANGE;
  2105. }
  2106. /* not a valid setting */
  2107. else  {
  2108. DEBUGMSGTL(("vacmViewTreeFamily","write to vacmViewTreeFamilyStatus: Bad value for setn"));
  2109. return SNMP_ERR_INCONSISTENTVALUE;
  2110. }
  2111. } /* if row exist */
  2112. /* if this is a commit, do expected action */
  2113. if (action == COMMIT) {
  2114. switch(onCommitDo) { 
  2115. case CREATE :
  2116. if (vacm_createViewEntry(viewName, subtree, (size_t)subtreeLen) == 0) {
  2117. DEBUGMSGTL(("vacmViewTreeFamily", "write to vacmViewTreeFamilyStatus: "));
  2118. DEBUGMSG(("vacmViewTreeFamily","failed new row creation, bad OID/index value n"));
  2119. return SNMP_ERR_GENERR;
  2120. }
  2121. break;
  2122. case DESTROY:
  2123. vacm_destroyViewEntry(viewName, subtree, subtreeLen);
  2124. break;
  2125. case CHANGE:
  2126. gp->viewStatus = long_ret;
  2127. break;
  2128. case NOTHING:
  2129. default:
  2130. break;
  2131. }
  2132. }
  2133. return SNMP_ERR_NOERROR;
  2134. }  /* vacmViewTreeFamilyStatus */
  2135. /**************************************************
  2136. *Spin Lock
  2137. **************************************************/
  2138. u_char *
  2139. var_vacmViewSpinLock(
  2140.     struct variable *vp,
  2141.     oid     *name,
  2142.     int  *length,
  2143.     int     exact,
  2144.     int  *var_len,
  2145.     WriteMethod **write_method)
  2146. {
  2147. static long long_ret;
  2148. *write_method = NULL;
  2149. if (header_generic(vp,name,length,exact,var_len,write_method) == MATCH_FAILED)
  2150. return NULL;
  2151. switch(vp->magic) {
  2152.     case VACMVIEWSPINLOCK:
  2153.       *write_method = write_vacmViewSpinLock;
  2154.       long_ret = vacmViewSpinLockValue;
  2155.   *var_len = sizeof (long);
  2156.       return (unsigned char *) &long_ret;
  2157. default:
  2158. snmp_trace ("SNMP in var_vacmViewSpinLock: unknown suboidn");
  2159. }
  2160. return NULL;
  2161. }
  2162.  
  2163. int write_vacmViewSpinLock(
  2164.    int      action,
  2165.    u_char   *var_val,
  2166.    u_char   var_val_type,
  2167.    int   var_val_len,
  2168.    u_char   *statP,
  2169.    oid      *name,
  2170.    int   name_len)
  2171. {
  2172.   /* variables we may use later */
  2173.   static long long_ret;
  2174.   if (var_val_type != ASN_INTEGER){
  2175.       DEBUGMSGTL(("usmUser","write to usmUserSpinLock not ASN_INTEGERn"));
  2176.       return SNMP_ERR_WRONGTYPE;
  2177.   }
  2178.   if (var_val_len > sizeof(long_ret)){
  2179.       DEBUGMSGTL(("usmUser","write to usmUserSpinLock: bad lengthn"));
  2180.       return SNMP_ERR_WRONGLENGTH;
  2181.   }
  2182.   long_ret = *((long *) var_val);
  2183.   if (long_ret != (long)vacmViewSpinLockValue)
  2184.     return SNMP_ERR_INCONSISTENTVALUE;
  2185.   if (action == COMMIT) {
  2186.     if (vacmViewSpinLockValue == 2147483647)
  2187.       vacmViewSpinLockValue = 0;
  2188.     else
  2189.       vacmViewSpinLockValue++;
  2190.   }
  2191.   return SNMP_ERR_NOERROR;
  2192. }  /* end write_usmUserSpinLock() */