void vacm_parse_setaccess(const char *token, char *param) { char *name, *context, *viewname, *viewval; int imodel, ilevel, iprefix; int viewnum; char *st; struct vacm_accessEntry *ap; if (_vacm_parse_access_common(token, param, &st, &name, &context, &imodel, &ilevel, &iprefix) == PARSE_FAIL) { return; } viewname = strtok_r(NULL, " \t\n", &st); if (!viewname) { config_perror("missing viewname parameter"); return; } viewval = strtok_r(NULL, " \t\n", &st); if (!viewval) { config_perror("missing viewval parameter"); return; } if (strlen(viewval) + 1 > sizeof(ap->views[VACM_VIEW_NOTIFY])) { config_perror("View value too long"); return; } viewnum = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, viewname); if (viewnum < 0 || viewnum >= VACM_MAX_VIEWS) { config_perror("Illegal view name"); return; } ap = vacm_getAccessEntry(name, context, imodel, ilevel); if (!ap) { ap = vacm_createAccessEntry(name, context, imodel, ilevel); DEBUGMSGTL(("vacm:conf:setaccess", "no existing access found; creating a new one\n")); } else { DEBUGMSGTL(("vacm:conf:setaccess", "existing access found, using it\n")); } if (!ap) { config_perror("failed to create access entry"); return; } strcpy(ap->views[viewnum], viewval); ap->contextMatch = iprefix; ap->storageType = SNMP_STORAGE_PERMANENT; ap->status = SNMP_ROW_ACTIVE; free(ap->reserved); ap->reserved = NULL; }
void vacm_parse_access(const char *token, char *param) { char *name, *context, *readView, *writeView, *notify; int imodel, ilevel, iprefix; struct vacm_accessEntry *ap; char *st; if (_vacm_parse_access_common(token, param, &st, &name, &context, &imodel, &ilevel, &iprefix) == PARSE_FAIL) { 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 (strlen(readView) + 1 > sizeof(ap->views[VACM_VIEW_READ])) { config_perror("readView too long"); return; } if (strlen(writeView) + 1 > sizeof(ap->views[VACM_VIEW_WRITE])) { config_perror("writeView too long"); return; } if (strlen(notify) + 1 > sizeof(ap->views[VACM_VIEW_NOTIFY])) { 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->views[VACM_VIEW_READ], readView); strcpy(ap->views[VACM_VIEW_WRITE], writeView); strcpy(ap->views[VACM_VIEW_NOTIFY], notify); ap->contextMatch = iprefix; ap->storageType = SNMP_STORAGE_PERMANENT; ap->status = SNMP_ROW_ACTIVE; free(ap->reserved); ap->reserved = NULL; }
void vacm_parse_config_access(const char *token, char *line) { struct vacm_accessEntry access; struct vacm_accessEntry *aptr; char *contextPrefix = (char *) &access.contextPrefix; char *groupName = (char *) &access.groupName; char *readView, *writeView, *notifyView; size_t len; access.status = atoi(line); line = skip_token(line); access.storageType = atoi(line); line = skip_token(line); access.securityModel = atoi(line); line = skip_token(line); access.securityLevel = atoi(line); line = skip_token(line); access.contextMatch = atoi(line); line = skip_token(line); line = read_config_read_octet_string(line, (u_char **) & groupName, &len); line = read_config_read_octet_string(line, (u_char **) & contextPrefix, &len); aptr = vacm_createAccessEntry(access.groupName, access.contextPrefix, access.securityModel, access.securityLevel); if (!aptr) return; aptr->status = access.status; aptr->storageType = access.storageType; aptr->securityModel = access.securityModel; aptr->securityLevel = access.securityLevel; aptr->contextMatch = access.contextMatch; readView = (char *) aptr->readView; line = read_config_read_octet_string(line, (u_char **) & readView, &len); writeView = (char *) aptr->writeView; line = read_config_read_octet_string(line, (u_char **) & writeView, &len); notifyView = (char *) aptr->notifyView; line = read_config_read_octet_string(line, (u_char **) & notifyView, &len); }
char * _vacm_parse_config_access_common(struct vacm_accessEntry **aptr, char *line) { struct vacm_accessEntry access; char *cPrefix = (char *) &access.contextPrefix; char *gName = (char *) &access.groupName; size_t len; access.status = atoi(line); line = skip_token(line); access.storageType = atoi(line); line = skip_token(line); access.securityModel = atoi(line); line = skip_token(line); access.securityLevel = atoi(line); line = skip_token(line); access.contextMatch = atoi(line); line = skip_token(line); len = sizeof(access.groupName); line = read_config_read_octet_string(line, (u_char **) &gName, &len); len = sizeof(access.contextPrefix); line = read_config_read_octet_string(line, (u_char **) &cPrefix, &len); *aptr = vacm_getAccessEntry(access.groupName, access.contextPrefix, access.securityModel, access.securityLevel); if (!*aptr) *aptr = vacm_createAccessEntry(access.groupName, access.contextPrefix, access.securityModel, access.securityLevel); if (!*aptr) return NULL; (*aptr)->status = access.status; (*aptr)->storageType = access.storageType; (*aptr)->securityModel = access.securityModel; (*aptr)->securityLevel = access.securityLevel; (*aptr)->contextMatch = access.contextMatch; return line; }
/** handles requests for the nsVacmAccessTable table */ int nsVacmAccessTable_handler(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) { netsnmp_request_info *request; netsnmp_table_request_info *table_info; netsnmp_variable_list *idx; struct vacm_accessEntry *entry; char atype[20]; int viewIdx, ret; char *gName, *cPrefix; int model, level; switch (reqinfo->mode) { /* * Read-support (also covers GetNext requests) */ case MODE_GET: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); /* Extract the authType token from the list of indexes */ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable; memset(atype, 0, sizeof(atype)); memcpy(atype, (char *)idx->val.string, idx->val_len); viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype); DEBUGMSGTL(("nsVacm", "GET %s (%d)\n", idx->val.string, viewIdx)); if (!entry || viewIdx < 0) continue; switch (table_info->colnum) { case COLUMN_NSVACMCONTEXTMATCH: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->contextMatch); break; case COLUMN_NSVACMVIEWNAME: snmp_set_var_typed_value(request->requestvb, ASN_OCTET_STR, (u_char *)entry->views[ viewIdx ], strlen(entry->views[ viewIdx ])); break; case COLUMN_VACMACCESSSTORAGETYPE: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->storageType); break; case COLUMN_NSVACMACCESSSTATUS: snmp_set_var_typed_integer(request->requestvb, ASN_INTEGER, entry->status); break; } } break; #ifndef NETSNMP_NO_WRITE_SUPPORT /* * Write-support */ case MODE_SET_RESERVE1: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); ret = SNMP_ERR_NOERROR; switch (table_info->colnum) { case COLUMN_NSVACMCONTEXTMATCH: ret = netsnmp_check_vb_int_range(request->requestvb, 1, 2); break; case COLUMN_NSVACMVIEWNAME: ret = netsnmp_check_vb_type_and_max_size(request->requestvb, ASN_OCTET_STR, VACM_MAX_STRING); break; case COLUMN_VACMACCESSSTORAGETYPE: ret = netsnmp_check_vb_storagetype(request->requestvb, (/*entry ? entry->storageType :*/ SNMP_STORAGE_NONE)); break; case COLUMN_NSVACMACCESSSTATUS: /* * The usual 'check_vb_rowstatus' call is too simplistic * to be used here. Because we're implementing a table * within an existing table, it's quite possible for a * the vacmAccessTable entry to exist, even if this is * a "new" nsVacmAccessEntry. * * We can check that the value being assigned is suitable * for a RowStatus syntax object, but the transition * checks need to be done explicitly. */ ret = netsnmp_check_vb_rowstatus_value(request->requestvb); if ( ret != SNMP_ERR_NOERROR ) break; /* * Extract the authType token from the list of indexes */ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable; memset(atype, 0, sizeof(atype)); memcpy(atype, (char *)idx->val.string, idx->val_len); viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype); if ( viewIdx < 0 ) { ret = SNMP_ERR_NOCREATION; break; } switch ( *request->requestvb->val.integer ) { case RS_ACTIVE: case RS_NOTINSERVICE: /* Check that this particular view is already set */ if ( !entry || !entry->views[viewIdx][0] ) ret = SNMP_ERR_INCONSISTENTVALUE; break; case RS_CREATEANDWAIT: case RS_CREATEANDGO: /* Check that this particular view is not yet set */ if ( entry && entry->views[viewIdx][0] ) ret = SNMP_ERR_INCONSISTENTVALUE; break; } break; } /* switch(colnum) */ if ( ret != SNMP_ERR_NOERROR ) { netsnmp_set_request_error(reqinfo, request, ret); return SNMP_ERR_NOERROR; } } break; case MODE_SET_RESERVE2: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); switch (table_info->colnum) { case COLUMN_NSVACMACCESSSTATUS: switch (*request->requestvb->val.integer) { case RS_CREATEANDGO: case RS_CREATEANDWAIT: if (!entry) { idx = table_info->indexes; gName = (char*)idx->val.string; idx = idx->next_variable; cPrefix = (char*)idx->val.string; idx = idx->next_variable; model = *idx->val.integer; idx = idx->next_variable; level = *idx->val.integer; entry = vacm_createAccessEntry( gName, cPrefix, model, level ); entry->storageType = ST_NONVOLATILE; netsnmp_insert_iterator_context(request, (void*)entry); } } } } break; case MODE_SET_FREE: case MODE_SET_UNDO: /* XXX - TODO */ break; case MODE_SET_ACTION: /* ??? Empty ??? */ break; case MODE_SET_COMMIT: for (request = requests; request; request = request->next) { entry = (struct vacm_accessEntry *) netsnmp_extract_iterator_context(request); table_info = netsnmp_extract_table_info(request); if ( !entry ) continue; /* Shouldn't happen */ /* Extract the authType token from the list of indexes */ idx = table_info->indexes->next_variable->next_variable->next_variable->next_variable; memset(atype, 0, sizeof(atype)); memcpy(atype, (char *)idx->val.string, idx->val_len); viewIdx = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, atype); if (viewIdx < 0) continue; switch (table_info->colnum) { case COLUMN_NSVACMCONTEXTMATCH: entry->contextMatch = *request->requestvb->val.integer; break; case COLUMN_NSVACMVIEWNAME: memset( entry->views[viewIdx], 0, VACMSTRINGLEN ); memcpy( entry->views[viewIdx], request->requestvb->val.string, request->requestvb->val_len); break; case COLUMN_VACMACCESSSTORAGETYPE: entry->storageType = *request->requestvb->val.integer; break; case COLUMN_NSVACMACCESSSTATUS: switch (*request->requestvb->val.integer) { case RS_DESTROY: memset( entry->views[viewIdx], 0, VACMSTRINGLEN ); break; } break; } } break; #endif /* !NETSNMP_NO_WRITE_SUPPORT */ } return SNMP_ERR_NOERROR; }
void vacm_parse_access (char *token, char *param) { char *name, *context, *model, *level, *prefix, *readView, *writeView, *notify; int imodel, ilevel; struct vacm_accessEntry *ap; name = strtok(param, " \t\n"); if (!name) { config_perror("missing NAME parameter"); return; } context = strtok(NULL, " \t\n"); if (!context) { config_perror("missing CONTEXT parameter"); return; } model = strtok(NULL, " \t\n"); if (!model) { config_perror("missing MODEL parameter"); return; } level = strtok(NULL, " \t\n"); if (!level) { config_perror("missing LEVEL parameter"); return; } prefix = strtok(NULL, " \t\n"); if (!prefix) { config_perror("missing PREFIX parameter"); return; } readView = strtok(NULL, " \t\n"); if (!readView) { config_perror("missing readView parameter"); return; } writeView = strtok(NULL, " \t\n"); if (!writeView) { config_perror("missing writeView parameter"); return; } notify = strtok(NULL, " \t\n"); 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 (strcasecmp(model, "v2p") == 0) imodel = SNMP_SEC_MODEL_SNMPv2p; else if (strcasecmp(model, "usm") == 0) imodel = SNMP_SEC_MODEL_USM; else { config_perror("bad security model"); 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(model, "priv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV; else if (strcasecmp(model, "authpriv") == 0) ilevel = SNMP_SEC_LEVEL_AUTHPRIV; else { config_perror("bad security level"); return; } ap = vacm_createAccessEntry (name, context, imodel, ilevel); strcpy(ap->readView, readView); strcpy(ap->writeView, writeView); strcpy(ap->notifyView, notify); ap->storageType = SNMP_STORAGE_PERMANENT; ap->status = SNMP_ROW_ACTIVE; free (ap->reserved); ap->reserved = NULL; }
void vacm_parse_authaccess(const char *token, char *confline) { char *group, *view, *tmp; const char *context; int model = SNMP_SEC_MODEL_ANY; int level, prefix; int i; char *st; struct vacm_accessEntry *ap; int viewtypes = vacm_parse_authtokens(token, &confline); if (viewtypes == -1) return; group = strtok_r(confline, " \t\n", &st); if (!group) { config_perror("missing GROUP parameter"); return; } view = strtok_r(NULL, " \t\n", &st); if (!view) { config_perror("missing VIEW parameter"); return; } /* * Check for security model option */ if ( strcasecmp(view, "-s") == 0 ) { tmp = strtok_r(NULL, " \t\n", &st); if (tmp) { if (strcasecmp(tmp, "any") == 0) model = SNMP_SEC_MODEL_ANY; else if (strcasecmp(tmp, "v1") == 0) model = SNMP_SEC_MODEL_SNMPv1; else if (strcasecmp(tmp, "v2c") == 0) model = SNMP_SEC_MODEL_SNMPv2c; else { model = se_find_value_in_slist("snmp_secmods", tmp); if (model == SE_DNE) { config_perror ("bad security model, should be: v1, v2c or usm or a registered security plugin name"); return; } } } else { config_perror("missing SECMODEL parameter"); return; } view = strtok_r(NULL, " \t\n", &st); if (!view) { config_perror("missing VIEW parameter"); return; } } if (strlen(view) >= VACMSTRINGLEN ) { config_perror("View value too long"); return; } /* * Now parse optional fields, or provide default values */ tmp = strtok_r(NULL, " \t\n", &st); if (tmp) { if (strcasecmp(tmp, "noauth") == 0) level = SNMP_SEC_LEVEL_NOAUTH; else if (strcasecmp(tmp, "noauthnopriv") == 0) level = SNMP_SEC_LEVEL_NOAUTH; else if (strcasecmp(tmp, "auth") == 0) level = SNMP_SEC_LEVEL_AUTHNOPRIV; else if (strcasecmp(tmp, "authnopriv") == 0) level = SNMP_SEC_LEVEL_AUTHNOPRIV; else if (strcasecmp(tmp, "priv") == 0) level = SNMP_SEC_LEVEL_AUTHPRIV; else if (strcasecmp(tmp, "authpriv") == 0) level = SNMP_SEC_LEVEL_AUTHPRIV; else { config_perror ("bad security level (noauthnopriv, authnopriv, authpriv)"); return; } } else { /* What about SNMP_SEC_MODEL_ANY ?? */ if ( model == SNMP_SEC_MODEL_SNMPv1 || model == SNMP_SEC_MODEL_SNMPv2c ) level = SNMP_SEC_LEVEL_NOAUTH; else level = SNMP_SEC_LEVEL_AUTHNOPRIV; } context = tmp = strtok_r(NULL, " \t\n", &st); if (tmp) { tmp = (tmp + strlen(tmp)-1); if (tmp && *tmp == '*') { *tmp = '\0'; prefix = 2; } else { prefix = 1; } } else { context = ""; prefix = 1; /* Or prefix(2) ?? */ } /* * Now we can create the access entry */ ap = vacm_getAccessEntry(group, context, model, level); if (!ap) { ap = vacm_createAccessEntry(group, context, model, level); DEBUGMSGTL(("vacm:conf:authaccess", "no existing access found; creating a new one\n")); } else { DEBUGMSGTL(("vacm:conf:authaccess", "existing access found, using it\n")); } if (!ap) { config_perror("failed to create access entry"); return; } for (i = 0; i <= VACM_MAX_VIEWS; i++) { if (viewtypes & (1 << i)) { strcpy(ap->views[i], view); } } ap->contextMatch = prefix; ap->storageType = SNMP_STORAGE_PERMANENT; ap->status = SNMP_ROW_ACTIVE; if (ap->reserved) free(ap->reserved); ap->reserved = NULL; }