Esempio n. 1
0
int
vacm_parse_authtokens(const char *token, char **confline)
{
    char authspec[SNMP_MAXBUF_MEDIUM];
    char *strtok_state;
    char *type;
    int viewtype, viewtypes = 0;

    *confline = copy_nword(*confline, authspec, sizeof(authspec));
    
    DEBUGMSGTL(("vacm_parse_authtokens","parsing %s",authspec));
    if (!*confline) {
        config_perror("Illegal configuration line: missing fields");
        return -1;
    }

    type = strtok_r(authspec, ",|:", &strtok_state);
    while(type && *type != '\0') {
        viewtype = se_find_value_in_slist(VACM_VIEW_ENUM_NAME, type);
        if (viewtype < 0 || viewtype >= VACM_MAX_VIEWS) {
            config_perror("Illegal view name");
        } else {
            viewtypes |= (1 << viewtype);
        }
        type = strtok_r(NULL, ",|:", &strtok_state);
    }
    DEBUGMSG(("vacm_parse_authtokens","  .. result = 0x%x\n",viewtypes));
    return viewtypes;
}
Esempio n. 2
0
static int
set_default_secmod(int major, int minor, void *serverarg, void *clientarg)
{
    netsnmp_session *sess = (netsnmp_session *) serverarg;
    char           *cptr;
    int             model;

    if (!sess)
        return SNMPERR_GENERR;
    if (sess->securityModel == SNMP_DEFAULT_SECMODEL) {
        if ((cptr = netsnmp_ds_get_string(NETSNMP_DS_LIBRARY_ID, 
					  NETSNMP_DS_LIB_SECMODEL)) != NULL) {
            if ((model = se_find_value_in_slist("snmp_secmods", cptr))
		!= SE_DNE) {
                sess->securityModel = model;
            } else {
                snmp_log(LOG_ERR,
                         "unknown security model name: %s.  Forcing USM instead.\n",
                         cptr);
                sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL;
                return SNMPERR_GENERR;
            }
        } else {
            sess->securityModel = NETSNMP_SECMOD_DEFAULT_MODEL;
        }
    }
    return SNMPERR_SUCCESS;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
void
vacm_parse_group(const char *token, char *param)
{
    char            group[VACMSTRINGLEN], model[VACMSTRINGLEN], security[VACMSTRINGLEN];
    int             imodel;
    struct vacm_groupEntry *gp = NULL;
    char           *st;

    st = copy_nword(param, group, sizeof(group)-1);
    st = copy_nword(st, model, sizeof(model)-1);
    st = copy_nword(st, security, sizeof(security)-1);

    if (group[0] == 0) {
        config_perror("missing GROUP parameter");
        return;
    }
    if (model[0] == 0) {
        config_perror("missing MODEL parameter");
        return;
    }
    if (security[0] == 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;
}
Esempio n. 5
0
static void
_access_interface_entry_save_name(const char *name, oid index)
{
    int tmp;

    if(NULL == name)
        return;

    tmp = se_find_value_in_slist("interfaces", name);
    if (tmp == SE_DNE) {
        se_add_pair_to_slist("interfaces", strdup(name), index);
        DEBUGMSGTL(("access:interface:ifIndex",
                    "saved ifIndex %" NETSNMP_PRIo "u for %s\n",
                    index, name));
    }
    else
        if (index != (oid)tmp) {
            NETSNMP_LOGONCE((LOG_ERR, "IfIndex of an interface changed. Such " \
                         "interfaces will appear multiple times in IF-MIB.\n"));
            DEBUGMSGTL(("access:interface:ifIndex",
                        "index %" NETSNMP_PRIo "u != tmp for %s\n",
                        index, name));
        }
}
Esempio n. 6
0
/** 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;
}
Esempio n. 7
0
static int
_load_ipv6(netsnmp_container* container, u_long *index )
{
    FILE           *in;
    char            line[256];
    netsnmp_route_entry *entry = NULL;
    static int      log_open_err = 1;

    DEBUGMSGTL(("access:route:container",
                "route_container_arch_load ipv6\n"));

    netsnmp_assert(NULL != container);

    /*
     * fetch routes from the proc file-system:
     */
    if (!(in = fopen("/proc/net/ipv6_route", "r"))) {
        if (1 == log_open_err) {
            NETSNMP_LOGONCE((LOG_ERR, "cannot open /proc/net/ipv6_route\n"));
            log_open_err = 0;
        }
        return -2;
    }
    /*
     * if we turned off logging of open errors, turn it back on now that
     * we have been able to open the file.
     */
    if (0 == log_open_err)
        log_open_err = 1;
    fgets(line,sizeof(line),in); /* skip header */
    while (fgets(line, sizeof(line), in)) {
        char            c_name[IFNAMSIZ+1];
        char            c_dest[33], c_src[33], c_next[33];
        int             rc;
        unsigned int    dest_pfx, flags;
        size_t          buf_len, buf_offset;
        u_char          *temp_uchar_ptr;

        entry = netsnmp_access_route_entry_create();

        /*
         * based on /usr/src/linux/net/ipv6/route.c, kernel 2.6.7:
         *
         * [        Dest addr /         plen ]
         * fe80000000000000025056fffec00008 80 \
         *
         * [ (?subtree) : src addr/plen : 0/0]
         * 00000000000000000000000000000000 00 \
         *
         * [        next hop              ][ metric ][ref ctn][ use   ]
         * 00000000000000000000000000000000 00000000 00000000 00000000 \
         *
         * [ flags ][dev name]
         * 80200001       lo
         */
        rc = sscanf(line, "%32s %2x %32s %*x %32s %x %*x %*x %x %"
                    SNMP_MACRO_VAL_TO_STR(IFNAMSIZ) "s\n",
                    c_dest, &dest_pfx, c_src, /*src_pfx,*/ c_next,
                    &entry->rt_metric1, /** ref,*/ /* use, */ &flags, c_name);
        DEBUGMSGTL(("9:access:route:container", "line |%s|\n", line));
        if (7 != rc) {
            snmp_log(LOG_ERR,
                     "/proc/net/ipv6_route data format error (%d!=8), "
                     "line ==|%s|", rc, line);
            continue;
        }

        /*
         * temporary null terminated name
         */
        c_name[ sizeof(c_name)-1 ] = 0;
        entry->if_index = se_find_value_in_slist("interfaces", c_name);
        if(SE_DNE == entry->if_index) {
            snmp_log(LOG_ERR,"unknown interface in /proc/net/ipv6_route "
                     "('%s')\n", c_name);
            netsnmp_access_route_entry_free(entry);
            continue;
        }
        /*
         * arbitrary index
         */
        entry->ns_rt_index = ++(*index);

#ifdef USING_IP_FORWARD_MIB_IPCIDRROUTETABLE_IPCIDRROUTETABLE_MODULE
        /** entry->rt_mask = mask; */ /* IPv4 only */
        /** entry->rt_tos = XXX; */
        /** rt info ?? */
#endif
        /*
         * convert hex addresses to binary
         */
        entry->rt_dest_type = INETADDRESSTYPE_IPV6;
        entry->rt_dest_len = 16;
        buf_len = sizeof(entry->rt_dest);
        buf_offset = 0;
        temp_uchar_ptr = entry->rt_dest;
        netsnmp_hex_to_binary(&temp_uchar_ptr, &buf_len, &buf_offset, 0,
                              c_dest, NULL);

        entry->rt_nexthop_type = INETADDRESSTYPE_IPV6;
        entry->rt_nexthop_len = 16;
        buf_len = sizeof(entry->rt_nexthop);
        buf_offset = 0;
        temp_uchar_ptr = entry->rt_nexthop;
        netsnmp_hex_to_binary(&temp_uchar_ptr, &buf_len, &buf_offset, 0,
                              c_next, NULL);

        entry->rt_pfx_len = dest_pfx;

#ifdef USING_IP_FORWARD_MIB_INETCIDRROUTETABLE_INETCIDRROUTETABLE_MODULE
        /*
    inetCidrRoutePolicy OBJECT-TYPE 
        SYNTAX     OBJECT IDENTIFIER 
        MAX-ACCESS not-accessible 
        STATUS     current 
        DESCRIPTION 
               "This object is an opaque object without any defined 
                semantics.  Its purpose is to serve as an additional 
                index which may delineate between multiple entries to 
                the same destination.  The value { 0 0 } shall be used 
                as the default value for this object."
        */
        /*
         * on linux, default routes all look alike, and would have the same
         * indexed based on dest and next hop. So we use our arbitrary index
         * as the policy, to distinguish between them.
         */
        entry->rt_policy = calloc(3, sizeof(oid));
        entry->rt_policy[2] = entry->ns_rt_index;
        entry->rt_policy_len = sizeof(oid)*3;
#endif

        /*
         * get protocol and type from flags
         */
        entry->rt_type = _type_from_flags(flags);
        
        entry->rt_proto = (flags & RTF_DYNAMIC)
            ? IANAIPROUTEPROTOCOL_ICMP : IANAIPROUTEPROTOCOL_LOCAL;

        /*
         * insert into container
         */
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);
    return 0;
}
Esempio n. 8
0
STORE_AND_COMPARE(1, 1, "enum 1:1 1:hi 2:there 3:" LONG_STRING " 4:" LONG_STRING
                 " 5:" LONG_STRING " 6:" LONG_STRING " 7:" LONG_STRING
                 " 8:" LONG_STRING " 9:" LONG_STRING "|"
                 "enum 1:1 10:" LONG_STRING "|");

OK(se_find_value(1, 1, "hi") == 1,
   "lookup by number #1 should be the proper string");
OK(strcmp(se_find_label(1, 1, 2), "there") == 0,
   "lookup by string #1 should be the proper number");


se_add_pair_to_slist("testing", strdup(STRING1), 42);
se_add_pair_to_slist("testing", strdup(STRING2), 2);
se_add_pair_to_slist("testing", strdup(STRING3), 2);
    
OK(se_find_value_in_slist("testing", STRING1) == 42,
   "lookup by number should be the proper string");
OK(strcmp(se_find_label_in_slist("testing", 2), STRING2) == 0,
   "lookup by string should be the proper number");

se_clear_slist("testing");


se_read_conf("enum",
             NETSNMP_REMOVE_CONST(char *, "2:3 1:apple 2:pear 3:kiwifruit"));
OK(se_find_list(2, 3), "list (2, 3) should be present");
if (se_find_list(2, 3)) {
  OK(se_find_value(2, 3, "kiwifruit") == 3,
     "lookup by string should return the proper value");
  se_find_result = se_find_label(2, 3, 2);
  OK(se_find_result && strcmp(se_find_result, "pear") == 0,
Esempio n. 9
0
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;
}
Esempio n. 10
0
int
_vacm_parse_access_common(const char *token, char *param, char **st,
                          char **name, char **context, int *imodel,
                          int *ilevel, int *iprefix)
{
    char *model, *level, *prefix;

    *name = strtok_r(param, " \t\n", st);
    if (!*name) {
        config_perror("missing NAME parameter");
        return PARSE_FAIL;
    }
    *context = strtok_r(NULL, " \t\n", st);
    if (!*context) {
        config_perror("missing CONTEXT parameter");
        return PARSE_FAIL;
    }

    model = strtok_r(NULL, " \t\n", st);
    if (!model) {
        config_perror("missing MODEL parameter");
        return PARSE_FAIL;
    }
    level = strtok_r(NULL, " \t\n", st);
    if (!level) {
        config_perror("missing LEVEL parameter");
        return PARSE_FAIL;
    }
    prefix = strtok_r(NULL, " \t\n", st);
    if (!prefix) {
        config_perror("missing PREFIX parameter");
        return PARSE_FAIL;
    }

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

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

    return PARSE_CONT;
}
/**
 * load cache data
 *
 * @param container container to which items should be inserted
 *
 * @retval MFD_SUCCESS              : success.
 * @retval MFD_RESOURCE_UNAVAILABLE : Can't access data source
 * @retval MFD_ERROR                : other error.
 *
 *  This function is called to cache the index(es) (and data, optionally)
 *  for the every row in the data set.
 *
 * @remark
 *  While loading the cache, the only important thing is the indexes.
 *  If access to your data is cheap/fast (e.g. you have a pointer to a
 *  structure in memory), it would make sense to update the data here.
 *  If, however, the accessing the data invovles more work (e.g. parsing
 *  some other existing data, or peforming calculations to derive the data),
 *  then you can limit yourself to setting the indexes and saving any
 *  information you will need later. Then use the saved information in
 *  ifTable_row_prep() for populating data.
 *
 * @note
 *  If you need consistency between rows (like you want statistics
 *  for each row to be from the same time frame), you should set all
 *  data here.
 *
 */
int
ifTable_cache_load(netsnmp_container * container)
{
    ifTable_rowreq_ctx *rowreq_ctx;
    int rc = MFD_SUCCESS;

    /*
     * this example code is based on a data source that is a
     * text file to be read and parsed.
     */
    FILE           *filep;
    char            line[MAX_LINE_SIZE];
    int             fd;

    /*
     * temporary storage for index values
     */
    /*
     * ifIndex(1)/InterfaceIndex/ASN_INTEGER/long(long)//l/A/w/e/R/d/H
     */
    long            ifIndex;

    DEBUGMSGTL(("verbose:ifTable_cache_load", "called\n"));

    /*
     ***************************************************
     ***             START EXAMPLE CODE              ***
     ***---------------------------------------------***/
    /*
     * open our data file.
     */
    filep = fopen("/proc/net/dev", "r");
    if (NULL == filep) {
        return MFD_RESOURCE_UNAVAILABLE;
    }

    /*
     * create socket for ioctls
     */
    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if(fd < 0) {
        fclose(filep);
        return MFD_RESOURCE_UNAVAILABLE;
    }

    /*
     * ignore header lines
     */
    fgets(line, sizeof(line), filep);
    fgets(line, sizeof(line), filep);

    /*
     ***---------------------------------------------***
     ***              END  EXAMPLE CODE              ***
     ***************************************************/
    /*
     * TODO: update container
     *
     * loop over your data, allocate, set index, insert into the container
     */
    /*
     * The rest of the file provides the statistics for an interface.
     * Read in each line in turn, isolate the interface name
     *   and retrieve (or create) the corresponding data structure.
     */
    while (1) {
        struct ifreq    ifrq;
        int             scan_count;
        char           *stats, *ifstart;
        unsigned long   rec_pkt, rec_oct, rec_err, rec_drop;
        unsigned long   snd_pkt, snd_oct, snd_err, snd_drop, coll;

        /*
         ***************************************************
         ***             START EXAMPLE CODE              ***
         ***---------------------------------------------***/
        /*
         * get a line (skip blank lines)
         */
        do {
            if (!fgets(line, sizeof(line), filep)) {
                /*
                 * we're done 
                 */
                fclose(filep);
                filep = NULL;
            }
        } while (filep && (line[0] == '\n'));

        /*
         * check for end of data
         */
        if (NULL == filep)
            break;

        /*
         * TODO: parse line
         * parse line into variables
         */
        ifstart = line;
        while (*ifstart && *ifstart == ' ')
            ifstart++;
        if ((!*ifstart) || ((stats = strrchr(ifstart, ':')) == NULL)) {
            snmp_log(LOG_ERR,
                     "interface data format error 1, line ==|%s|\n",
                     line);
            DEBUGMSGTL(("ifTable", "found '%s'\n", ifstart));
            continue;
        }

        /*
         * If we've met this interface before, use the same index.
         * Otherwise find an unused index value and use that.
         */
        *stats++ = 0; /* null terminate name */
        ifIndex = se_find_value_in_slist("interfaces", ifstart);
        if (ifIndex == SE_DNE) {
            ifIndex = se_find_free_value_in_slist("interfaces");
            if (ifIndex == SE_DNE)
                ifIndex = 1;       /* Completely new list! */
            se_add_pair_to_slist("interfaces",
                                 strdup(ifstart), ifIndex);
            DEBUGMSGTL(("ifTable:ifIndex", "new ifIndex %d for %s\n",
                        ifIndex, ifstart));
        }
        if ((NULL == ifstart) || (0 == ifIndex)) {
            rc = MFD_END_OF_DATA;
            break;
        }

        /*
         ***---------------------------------------------***
         ***              END  EXAMPLE CODE              ***
         ***************************************************/

        /*
         * allocate an row context and set the index(es)
         */
        rowreq_ctx = ifTable_allocate_rowreq_ctx();
        if (NULL == rowreq_ctx) {
            snmp_log(LOG_ERR, "memory allocation failed\n");
            return MFD_RESOURCE_UNAVAILABLE;
        }
        if (MFD_SUCCESS != ifTable_indexes_set(rowreq_ctx, ifIndex)) {
            snmp_log(LOG_ERR, "error setting index while loading "
                     "ifTable cache.\n");
            ifTable_release_rowreq_ctx(rowreq_ctx);
            continue;
        }

        rec_pkt = rec_oct = rec_err = rec_drop = 0;
        snd_pkt = snd_oct = snd_err = snd_drop = coll = 0;
        if (scan_line_to_use == scan_line_2_2) {
            scan_count = sscanf(stats, scan_line_to_use,
                                &rec_oct, &rec_pkt, &rec_err, &rec_drop,
                                &snd_oct, &snd_pkt, &snd_err, &snd_drop,
                                &coll);
        } else {
            scan_count = sscanf(stats, scan_line_to_use,
                                &rec_pkt, &rec_err,
                                &snd_pkt, &snd_err, &coll);
        }
        if(scan_count != scan_expected) {
            snmp_log(LOG_ERR,
                     "error scanning interface data (expected %d, got %d)\n",
                     scan_expected, scan_count);
            rc = MFD_ERROR;
            break;
        }
        if (scan_line_to_use != scan_line_2_2) {
            rec_oct = rec_pkt * 308;
            snd_oct = snd_pkt * 308;
        }

        /*
         * TODO: populate data context
         */
        /*
         * TRANSIENT or semi-TRANSIENT data:
         * copy data or save any info needed to do it in row_prep.
         */
        /*
         * TODO: setup/save data for ifDescr
         * ifDescr(2)/DisplayString/ASN_OCTET_STR/char(char)//L/A/w/e/R/d/H
         */
        /** no code to get description yet */
        rowreq_ctx->data.ifDescr[0] = 0;
        rowreq_ctx->data.ifDescr_len = 0;

        /*
         * TODO: setup/save data for ifMtu
         * ifMtu(4)/INTEGER32/ASN_INTEGER/long(long)//l/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifSpeed
         * ifSpeed(5)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifPhysAddress
         * ifPhysAddress(6)/PhysAddress/ASN_OCTET_STR/char(char)//L/A/w/e/r/d/H
         */
        /*
         * make sure there is enough space for data
         */
        if (sizeof(rowreq_ctx->data.ifPhysAddress) < 6) {
            snmp_log(LOG_ERR, "not enough space for address while loading "
                         "ifTable cache.\n");
            ifTable_release_rowreq_ctx(rowreq_ctx);
            continue;
        }
        rowreq_ctx->data.ifPhysAddress_len = 6;
        strncpy(ifrq.ifr_name, ifstart, sizeof(ifrq.ifr_name));
        ifrq.ifr_name[ sizeof(ifrq.ifr_name)-1 ] = 0;
        if (ioctl(fd, SIOCGIFHWADDR, &ifrq) < 0)
            memset(rowreq_ctx->data.ifPhysAddress, (0), 6);
        else {
            memcpy(rowreq_ctx->data.ifPhysAddress,
                   ifrq.ifr_hwaddr.sa_data, 6);
        }

        /*
         * TODO: setup/save data for ifType
         * ifType(3)/IANAifType/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */
        if (MFD_SUCCESS !=
            ifType_map(&rowreq_ctx->data.ifType,
                       ifrq.ifr_hwaddr.sa_family)) {
            snmp_log(LOG_ERR, "error mapping ifType while loading "
                     "ifTable cache.\n");
            ifTable_release_rowreq_ctx(rowreq_ctx);
            continue;
        }

        /*
         * TODO: setup/save data for ifAdminStatus
         * ifAdminStatus(7)/INTEGER/ASN_INTEGER/long(u_long)//l/A/W/E/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifOperStatus
         * ifOperStatus(8)/INTEGER/ASN_INTEGER/long(u_long)//l/A/w/E/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifLastChange
         * ifLastChange(9)/TICKS/ASN_TIMETICKS/u_long(u_long)//l/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifInOctets
         * ifInOctets(10)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifInOctets = rec_oct;

        /*
         * TODO: setup/save data for ifInUcastPkts
         * ifInUcastPkts(11)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifInUcastPkts = rec_pkt;

        /*
         * TODO: setup/save data for ifInNUcastPkts
         * ifInNUcastPkts(12)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifInDiscards
         * ifInDiscards(13)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifInDiscards = rec_drop;

        /*
         * TODO: setup/save data for ifInErrors
         * ifInErrors(14)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifInErrors = rec_err;

        /*
         * TODO: setup/save data for ifInUnknownProtos
         * ifInUnknownProtos(15)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifOutOctets
         * ifOutOctets(16)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifOutOctets = snd_oct;

        /*
         * TODO: setup/save data for ifOutUcastPkts
         * ifOutUcastPkts(17)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifOutUcastPkts = snd_pkt;

        /*
         * TODO: setup/save data for ifOutNUcastPkts
         * ifOutNUcastPkts(18)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifOutDiscards
         * ifOutDiscards(19)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifOutDiscards = snd_drop;

        /*
         * TODO: setup/save data for ifOutErrors
         * ifOutErrors(20)/COUNTER/ASN_COUNTER/u_long(u_long)//l/A/w/e/r/d/h
         */
        rowreq_ctx->data.ifOutErrors = snd_err;

        /*
         * TODO: setup/save data for ifOutQLen
         * ifOutQLen(21)/GAUGE/ASN_GAUGE/u_long(u_long)//l/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */

        /*
         * TODO: setup/save data for ifSpecific
         * ifSpecific(22)/OBJECTID/ASN_OBJECT_ID/oid(oid)//L/A/w/e/r/d/h
         */
        /*
         * TODO:
         * value mapping
         */
        /*
         * it is hard to autogenerate code for mapping types that are not simple
         * integers, so here is an idea of what you might need to do. It may
         * need some tweaking to get right. 
         */
        /*
         * NOTE: this code would replace the memcpy below.
         *
         * if(MFD_SUCCESS !=
         *    ifSpecific_map(&rowreq_ctx->data.ifSpecific, &rowreq_ctx->data.ifSpecific_len,
         *                TODO_FIND_ifSpecific, TODO_FIND_ifSpecific_len, 0)) {
         *    return MFD_ERROR;
         * }
         */
        /*
         * TODO:
         * update, replace or delete, if needed.
         */
        /*
         * make sure there is enough space for data
         */
        /** not implemented */

        /*
         * insert into table container
         */
        CONTAINER_INSERT(container, rowreq_ctx);
    }

    /*
     ***************************************************
     ***             START EXAMPLE CODE              ***
     ***---------------------------------------------***/
    close(fd);
    if (NULL != filep)
        fclose(filep);
    /*
     ***---------------------------------------------***
     ***              END  EXAMPLE CODE              ***
     ***************************************************/

    return rc;
}