/* * SNMPv3 View-based Access Control Model */ /* Portions of this file are subject to the following copyright(s). See * the Net-SNMP's COPYING file for more details and other copyrights * that may apply: */ /* * Portions of this file are copyrighted by: * Copyright © 2003 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms specified in the COPYING file * distributed with the Net-SNMP package. */ #include #if HAVE_STDLIB_H #include #endif #if HAVE_UNISTD_H #include #endif #if HAVE_STRING_H #include #else #include #endif #if HAVE_MALLOC_H #include #endif #include #include #if HAVE_NETINET_IN_H #include #endif #if HAVE_ARPA_INET_H #include #endif #if HAVE_DMALLOC_H #include #endif #if HAVE_NETDB_H #include #endif #if HAVE_WINSOCK_H #include #endif #include #include #include #include "vacm_conf.h" #include "util_funcs.h" #ifdef USING_MIBII_SYSORTABLE_MODULE #if TIME_WITH_SYS_TIME # ifdef WIN32 # include # else # include # endif # include #else # if HAVE_SYS_TIME_H # include # else # include # endif #endif #include "sysORTable.h" #endif void init_vacm_conf(void) { snmpd_register_config_handler("group", vacm_parse_group, vacm_free_group, "name v1|v2c|usm|... security"); snmpd_register_config_handler("access", vacm_parse_access, vacm_free_access, "name context model level prefx read write notify"); snmpd_register_config_handler("view", vacm_parse_view, vacm_free_view, "name type subtree [mask]"); #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) snmpd_register_config_handler("rwcommunity", vacm_parse_simple, NULL, "community [default|hostname|network/bits [oid]]"); snmpd_register_config_handler("rocommunity", vacm_parse_simple, NULL, "community [default|hostname|network/bits [oid]]"); #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN snmpd_register_config_handler("rwcommunity6", vacm_parse_simple, NULL, "community [default|hostname|network/bits [oid]]"); snmpd_register_config_handler("rocommunity6", vacm_parse_simple, NULL, "community [default|hostname|network/bits [oid]]"); #endif #endif /* support for community based SNMP */ snmpd_register_config_handler("rwuser", vacm_parse_simple, NULL, "user [noauth|auth|priv [oid]]"); snmpd_register_config_handler("rouser", vacm_parse_simple, NULL, "user [noauth|auth|priv [oid]]"); snmpd_register_config_handler("vacmView", vacm_parse_config_view, NULL, NULL); snmpd_register_config_handler("vacmGroup", vacm_parse_config_group, NULL, NULL); snmpd_register_config_handler("vacmAccess", vacm_parse_config_access, NULL, NULL); /* * register ourselves to handle access control */ snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK, vacm_in_view_callback, NULL); snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK_INITIAL, vacm_in_view_callback, NULL); snmp_register_callback(SNMP_CALLBACK_APPLICATION, SNMPD_CALLBACK_ACM_CHECK_SUBTREE, vacm_in_view_callback, NULL); snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_POST_READ_CONFIG, vacm_warn_if_not_configured, NULL); } void vacm_parse_group(const char *token, char *param) { char *group, *model, *security; int imodel; struct vacm_groupEntry *gp = NULL; char *st; group = strtok_r(param, " \t\n", &st); model = strtok_r(NULL, " \t\n", &st); security = strtok_r(NULL, " \t\n", &st); if (group == NULL || *group == 0) { config_perror("missing GROUP parameter"); return; } if (model == NULL || *model == 0) { config_perror("missing MODEL parameter"); return; } if (security == NULL || *security == 0) { config_perror("missing SECURITY parameter"); return; } if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1; else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c; else if (strcasecmp(model, "any") == 0) { config_perror ("bad security model \"any\" should be: v1, v2c, usm or a registered security plugin name - installing anyway"); imodel = SNMP_SEC_MODEL_ANY; } else { if ((imodel = se_find_value_in_slist("snmp_secmods", model)) == SE_DNE) { config_perror ("bad security model, should be: v1, v2c or usm or a registered security plugin name"); return; } } if (strlen(security) + 1 > sizeof(gp->groupName)) { config_perror("security name too long"); return; } gp = vacm_createGroupEntry(imodel, security); if (!gp) { config_perror("failed to create group entry"); return; } strncpy(gp->groupName, group, sizeof(gp->groupName)); gp->groupName[ sizeof(gp->groupName)-1 ] = 0; gp->storageType = SNMP_STORAGE_PERMANENT; gp->status = SNMP_ROW_ACTIVE; free(gp->reserved); gp->reserved = NULL; } void vacm_free_group(void) { vacm_destroyAllGroupEntries(); } void vacm_parse_access(const char *token, char *param) { char *name, *context, *model, *level, *prefix, *readView, *writeView, *notify; int imodel, ilevel, iprefix; struct vacm_accessEntry *ap; char *st; name = strtok_r(param, " \t\n", &st); if (!name) { config_perror("missing NAME parameter"); return; } context = strtok_r(NULL, " \t\n", &st); if (!context) { config_perror("missing CONTEXT parameter"); return; } model = strtok_r(NULL, " \t\n", &st); if (!model) { config_perror("missing MODEL parameter"); return; } level = strtok_r(NULL, " \t\n", &st); if (!level) { config_perror("missing LEVEL parameter"); return; } prefix = strtok_r(NULL, " \t\n", &st); if (!prefix) { config_perror("missing PREFIX parameter"); return; } readView = strtok_r(NULL, " \t\n", &st); if (!readView) { config_perror("missing readView parameter"); return; } writeView = strtok_r(NULL, " \t\n", &st); if (!writeView) { config_perror("missing writeView parameter"); return; } notify = strtok_r(NULL, " \t\n", &st); if (!notify) { config_perror("missing notifyView parameter"); return; } if (strcmp(context, "\"\"") == 0) *context = 0; if (strcasecmp(model, "any") == 0) imodel = SNMP_SEC_MODEL_ANY; else if (strcasecmp(model, "v1") == 0) imodel = SNMP_SEC_MODEL_SNMPv1; else if (strcasecmp(model, "v2c") == 0) imodel = SNMP_SEC_MODEL_SNMPv2c; else { if ((imodel = se_find_value_in_slist("snmp_secmods", model)) == SE_DNE) { config_perror ("bad security model, should be: v1, v2c or usm or a registered security plugin name"); return; } } if (strcasecmp(level, "noauth") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH; else if (strcasecmp(level, "noauthnopriv") == 0) ilevel = SNMP_SEC_LEVEL_NOAUTH; else if (strcasecmp(level, "auth") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV; else if (strcasecmp(level, "authnopriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHNOPRIV; else if (strcasecmp(level, "priv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV; else if (strcasecmp(level, "authpriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV; else { config_perror ("bad security level (noauthnopriv, authnopriv, authpriv)"); return; } if (strcmp(prefix, "exact") == 0) iprefix = 1; else if (strcmp(prefix, "prefix") == 0) iprefix = 2; else if (strcmp(prefix, "0") == 0) { config_perror ("bad prefix match parameter \"0\", should be: exact or prefix - installing anyway"); iprefix = 1; } else { config_perror ("bad prefix match parameter, should be: exact or prefix"); return; } if (strlen(readView) + 1 > sizeof(ap->readView)) { config_perror("readView too long"); return; } if (strlen(writeView) + 1 > sizeof(ap->writeView)) { config_perror("writeView too long"); return; } if (strlen(notify) + 1 > sizeof(ap->notifyView)) { config_perror("notifyView too long"); return; } ap = vacm_createAccessEntry(name, context, imodel, ilevel); if (!ap) { config_perror("failed to create access entry"); return; } strcpy(ap->readView, readView); strcpy(ap->writeView, writeView); strcpy(ap->notifyView, notify); ap->contextMatch = iprefix; ap->storageType = SNMP_STORAGE_PERMANENT; ap->status = SNMP_ROW_ACTIVE; free(ap->reserved); ap->reserved = NULL; } void vacm_free_access(void) { vacm_destroyAllAccessEntries(); } void vacm_parse_view(const char *token, char *param) { char *name, *type, *subtree, *mask; int inclexcl; struct vacm_viewEntry *vp; oid suboid[MAX_OID_LEN]; size_t suboid_len = 0; u_char viewMask[sizeof(vp->viewMask)]; int i; char *st; name = strtok_r(param, " \t\n", &st); if (!name) { config_perror("missing NAME parameter"); return; } type = strtok_r(NULL, " \n\t", &st); if (!type) { config_perror("missing TYPE parameter"); return; } subtree = strtok_r(NULL, " \t\n", &st); if (!subtree) { config_perror("missing SUBTREE parameter"); return; } mask = strtok_r(NULL, "\0", &st); if (strcmp(type, "included") == 0) inclexcl = SNMP_VIEW_INCLUDED; else if (strcmp(type, "excluded") == 0) inclexcl = SNMP_VIEW_EXCLUDED; else { config_perror("TYPE must be included/excluded?"); return; } suboid_len = strlen(subtree)-1; if (subtree[suboid_len] == '.') subtree[suboid_len] = '\0'; /* stamp on a trailing . */ suboid_len = MAX_OID_LEN; if (!snmp_parse_oid(subtree, suboid, &suboid_len)) { config_perror("bad SUBTREE object id"); return; } if (mask) { int val; i = 0; for (mask = strtok_r(mask, " .:", &st); mask; mask = strtok_r(NULL, " .:", &st)) { if (i >= sizeof(viewMask)) { config_perror("MASK too long"); return; } if (sscanf(mask, "%x", &val) == 0) { config_perror("invalid MASK"); return; } viewMask[i] = val; i++; } } else { for (i = 0; i < sizeof(viewMask); i++) viewMask[i] = 0xff; } vp = vacm_createViewEntry(name, suboid, suboid_len); if (!vp) { config_perror("failed to create view entry"); return; } memcpy(vp->viewMask, viewMask, sizeof(viewMask)); vp->viewType = inclexcl; vp->viewStorageType = SNMP_STORAGE_PERMANENT; vp->viewStatus = SNMP_ROW_ACTIVE; free(vp->reserved); vp->reserved = NULL; } void vacm_free_view(void) { vacm_destroyAllViewEntries(); } void vacm_parse_simple(const char *token, char *confline) { char line[SPRINT_MAX_LEN]; char community[COMMUNITY_MAX_LEN]; char theoid[SPRINT_MAX_LEN]; char viewname[SPRINT_MAX_LEN]; #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) char addressname[SPRINT_MAX_LEN]; #endif const char *rw = "none"; char model[SPRINT_MAX_LEN]; char *cp; static int num = 0; char secname[SPRINT_MAX_LEN]; char authtype[SPRINT_MAX_LEN]; /* * init */ strcpy(model, "any"); /* * community name or user name */ cp = copy_nword(confline, community, sizeof(community)); if (strcmp(token, "rouser") == 0 || strcmp(token, "rwuser") == 0) { /* * maybe security model type */ if (strcmp(community, "-s") == 0) { /* * -s model ... */ if (cp) cp = copy_nword(cp, model, sizeof(authtype)); if (!cp) { config_perror("illegal line"); return; } if (cp) cp = copy_nword(cp, community, sizeof(community)); } else { strcpy(model, "usm"); } /* * authentication type */ if (cp && *cp) cp = copy_nword(cp, authtype, sizeof(authtype)); else strcpy(authtype, "auth"); DEBUGMSGTL((token, "setting auth type: \"%s\"\n", authtype)); #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) } else { /* * source address */ if (cp && *cp) { cp = copy_nword(cp, addressname, sizeof(addressname)); } else { strcpy(addressname, "default"); } /* * authtype has to be noauth */ strcpy(authtype, "noauth"); #endif /* support for community based SNMP */ } /* * oid they can touch */ if (cp && *cp) { cp = copy_nword(cp, theoid, sizeof(theoid)); } else { strcpy(theoid, ".1"); } if ( #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) strcmp(token, "rwcommunity") == 0 || #endif /* support for community based SNMP */ strcmp(token, "rwuser") == 0) rw = viewname; #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN if (strcmp(token, "rwcommunity6") == 0) rw = viewname; #endif if (strcmp(token, "rwcommunity") == 0 || strcmp(token, "rocommunity") == 0) { /* * com2sec mapping */ /* * com2sec anonymousSecNameNUM ADDRESS COMMUNITY */ sprintf(secname, "comm%.27s", community); sprintf(viewname,"viewComm%.23s",community); snprintf(line, sizeof(line), "%s %s '%s'", secname, addressname, community); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "com2sec", line)); netsnmp_udp_parse_security("com2sec", line); #ifdef SNMP_TRANSPORT_UNIX_DOMAIN snprintf(line, sizeof(line), "%s %s '%s'", secname, addressname, community); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "com2secunix", line)); netsnmp_unix_parse_security("com2secunix", line); #endif /* * sec->group mapping */ /* * group anonymousGroupNameNUM any anonymousSecNameNUM */ snprintf(line, sizeof(line), "grp%.28s v1 %s", secname, secname); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "group", line)); vacm_parse_group("group", line); snprintf(line, sizeof(line), "grp%.28s v2c %s", secname, secname); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "group", line)); vacm_parse_group("group", line); #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN } else if (strcmp(token, "rwcommunity6") == 0 || strcmp(token, "rocommunity6") == 0) { /* * com2sec6 mapping */ /* * com2sec6 anonymousSecNameNUM ADDRESS COMMUNITY */ sprintf(secname, "comm%.27s", community); sprintf(viewname,"viewComm%.23s",community); snprintf(line, sizeof(line), "%s %s '%s'", secname, addressname, community); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "com2sec6", line)); netsnmp_udp6_parse_security("com2sec6", line); /* * sec->group mapping */ /* * group anonymousGroupNameNUM any anonymousSecNameNUM */ snprintf(line, sizeof(line), "grp%.28s v1 %s", secname, secname); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "group", line)); vacm_parse_group("group", line); snprintf(line, sizeof(line), "grp%.28s v2c %s", secname, secname); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "group", line)); vacm_parse_group("group", line); #endif } else #endif /* support for community based SNMP */ { sprintf(viewname,"viewUSM%.24s",community); strncpy(secname, community, sizeof(secname)); secname[ sizeof(secname)-1 ] = 0; /* * sec->group mapping */ /* * group anonymousGroupNameNUM any anonymousSecNameNUM */ snprintf(line, sizeof(line), "grp%.28s %s %s", secname, model, secname); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "group", line)); vacm_parse_group("group", line); } /* * view definition */ /* * view anonymousViewNUM included OID */ snprintf(line, sizeof(line), "%s included %s", viewname, theoid); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "view", line)); vacm_parse_view("view", line); /* * map everything together */ /* * access anonymousGroupNameNUM "" MODEL AUTHTYPE prefix anonymousViewNUM [none/anonymousViewNUM] [none/anonymousViewNUM] */ snprintf(line, sizeof(line), "grp%.28s \"\" %s %s prefix %s %s %s", secname, model, authtype, viewname, rw, rw); line[ sizeof(line)-1 ] = 0; DEBUGMSGTL((token, "passing: %s %s\n", "access", line)); vacm_parse_access("access", line); num++; } int vacm_warn_if_not_configured(int majorID, int minorID, void *serverarg, void *clientarg) { const char * name = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_APPTYPE); if (NULL==name) name = "snmpd"; if (!vacm_is_configured() && !strcmp( name, "snmpd" )) { snmp_log(LOG_WARNING, "Warning: no access control information configured.\n It's " "unlikely this agent can serve any useful purpose in this " "state.\n Run \"snmpconf -g basic_setup\" to help you " "configure the %s.conf file for this agent.\n", name ); } return SNMP_ERR_NOERROR; } int vacm_in_view_callback(int majorID, int minorID, void *serverarg, void *clientarg) { struct view_parameters *view_parms = (struct view_parameters *) serverarg; int retval; if (view_parms == NULL) return 1; retval = vacm_in_view(view_parms->pdu, view_parms->name, view_parms->namelen, view_parms->check_subtree); if (retval != 0) view_parms->errorcode = retval; return retval; } /*******************************************************************-o-****** * vacm_in_view * * Parameters: * *pdu * *name * namelen * check_subtree * * Returns: * 0 On success. * 1 Missing security name. * 2 Missing group * 3 Missing access * 4 Missing view * 5 Not in view * 6 No Such Context * 7 When testing an entire subtree, UNKNOWN (ie, the entire * subtree has both allowed and disallowed portions) * * Debug output listed as follows: * */ int vacm_in_view(netsnmp_pdu *pdu, oid * name, size_t namelen, int check_subtree) { struct vacm_accessEntry *ap; struct vacm_groupEntry *gp; struct vacm_viewEntry *vp; char vacm_default_context[1] = ""; char *contextName = vacm_default_context; char *vn; char *sn = NULL; /* * len defined by the vacmContextName object */ #define CONTEXTNAMEINDEXLEN 32 char contextNameIndex[CONTEXTNAMEINDEXLEN + 1]; #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c) { if (snmp_get_do_debugging()) { char *buf; if (pdu->community) { buf = (char *) malloc(1 + pdu->community_len); memcpy(buf, pdu->community, pdu->community_len); buf[pdu->community_len] = '\0'; } else { DEBUGMSGTL(("mibII/vacm_vars", "NULL community")); buf = strdup("NULL"); } DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: ver=%d, community=%s\n", pdu->version, buf)); free(buf); } /* * Okay, if this PDU was received from a UDP or a TCP transport then * ask the transport abstraction layer to map its source address and * community string to a security name for us. */ if (pdu->tDomain == netsnmpUDPDomain #ifdef SNMP_TRANSPORT_TCP_DOMAIN || pdu->tDomain == netsnmp_snmpTCPDomain #endif ) { if (!netsnmp_udp_getSecName(pdu->transport_data, pdu->transport_data_length, (char *) pdu->community, pdu->community_len, &sn, &contextName)) { /* * There are no com2sec entries. */ sn = NULL; } /* force the community -> context name mapping here */ SNMP_FREE(pdu->contextName); pdu->contextName = strdup(contextName); pdu->contextNameLen = strlen(contextName); #ifdef SNMP_TRANSPORT_UDPIPV6_DOMAIN } else if (pdu->tDomain == netsnmp_UDPIPv6Domain #ifdef SNMP_TRANSPORT_TCPIPV6_DOMAIN || pdu->tDomain == netsnmp_TCPIPv6Domain #endif ) { if (!netsnmp_udp6_getSecName(pdu->transport_data, pdu->transport_data_length, (char *) pdu->community, pdu->community_len, &sn, &contextName)) { /* * There are no com2sec entries. */ sn = NULL; } /* force the community -> context name mapping here */ SNMP_FREE(pdu->contextName); pdu->contextName = strdup(contextName); pdu->contextNameLen = strlen(contextName); #endif #ifdef SNMP_TRANSPORT_UNIX_DOMAIN } else if (pdu->tDomain == netsnmp_UnixDomain){ if (!netsnmp_unix_getSecName(pdu->transport_data, pdu->transport_data_length, (char *) pdu->community, pdu->community_len, &sn, &contextName)) { sn = NULL; } /* force the community -> context name mapping here */ SNMP_FREE(pdu->contextName); pdu->contextName = strdup(contextName); pdu->contextNameLen = strlen(contextName); #endif } else { /* * Map other pairs to security names * here. For now just let non-IPv4 transport always succeed. * * WHAAAATTTT. No, we don't let non-IPv4 transports * succeed! You must fix this to make it usable, sorry. * From a security standpoint this is insane. -- Wes */ /** @todo alternate com2sec mappings for non v4 transports. Should be implemented via registration */ sn = NULL; } } else #endif /* support for community based SNMP */ if (find_sec_mod(pdu->securityModel)) { /* * any legal defined v3 security model */ DEBUGMSG(("mibII/vacm_vars", "vacm_in_view: ver=%d, model=%d, secName=%s\n", pdu->version, pdu->securityModel, pdu->securityName)); sn = pdu->securityName; contextName = pdu->contextName; } else { sn = NULL; } if (sn == NULL) { #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) snmp_increment_statistic(STAT_SNMPINBADCOMMUNITYNAMES); #endif DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: No security name found\n")); return 1; } if (pdu->contextNameLen > CONTEXTNAMEINDEXLEN) { DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: bad ctxt length %d\n", pdu->contextNameLen)); return 6; } /* * NULL termination of the pdu field is ugly here. Do in PDU parsing? */ if (pdu->contextName) strncpy(contextNameIndex, pdu->contextName, pdu->contextNameLen); else contextNameIndex[0] = '\0'; contextNameIndex[pdu->contextNameLen] = '\0'; if (!netsnmp_subtree_find_first(contextNameIndex)) { /* * rfc2575 section 3.2, step 1 * no such context here; return no such context error */ DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: no such ctxt \"%s\"\n", contextNameIndex)); return 6; } DEBUGMSGTL(("mibII/vacm_vars", "vacm_in_view: sn=%s", sn)); gp = vacm_getGroupEntry(pdu->securityModel, sn); if (gp == NULL) { DEBUGMSG(("mibII/vacm_vars", "\n")); return 2; } DEBUGMSG(("mibII/vacm_vars", ", gn=%s", gp->groupName)); ap = vacm_getAccessEntry(gp->groupName, contextNameIndex, pdu->securityModel, pdu->securityLevel); if (ap == NULL) { DEBUGMSG(("mibII/vacm_vars", "\n")); return 3; } if (name == 0) { /* only check the setup of the vacm for the request */ DEBUGMSG(("mibII/vacm_vars", ", Done checking setup\n")); return 0; } switch (pdu->command) { case SNMP_MSG_GET: case SNMP_MSG_GETNEXT: case SNMP_MSG_GETBULK: vn = ap->readView; break; case SNMP_MSG_SET: vn = ap->writeView; break; case SNMP_MSG_TRAP: case SNMP_MSG_TRAP2: case SNMP_MSG_INFORM: vn = ap->notifyView; break; default: snmp_log(LOG_ERR, "bad msg type in vacm_in_view: %d\n", pdu->command); vn = ap->readView; } DEBUGMSG(("mibII/vacm_vars", ", vn=%s", vn)); if (check_subtree) { DEBUGMSG(("mibII/vacm_vars", "\n")); return vacm_checkSubtree(vn, name, namelen); } vp = vacm_getViewEntry(vn, name, namelen, VACM_MODE_FIND); if (vp == NULL) { DEBUGMSG(("mibII/vacm_vars", "\n")); return 4; } DEBUGMSG(("mibII/vacm_vars", ", vt=%d\n", vp->viewType)); if (vp->viewType == SNMP_VIEW_EXCLUDED) { #if !defined(DISABLE_SNMPV1) || !defined(DISABLE_SNMPV2C) if (pdu->version == SNMP_VERSION_1 || pdu->version == SNMP_VERSION_2c) { snmp_increment_statistic(STAT_SNMPINBADCOMMUNITYUSES); } #endif return 5; } return 0; } /* end vacm_in_view() */