Ejemplo n.º 1
0
void
shutdown_snmp_logging(void)
{
   snmp_disable_log();
   while(NULL != logh_head)
      netsnmp_remove_loghandler( logh_head );
}
Ejemplo n.º 2
0
int
snmp_log_options(char *optarg, int argc, char *const *argv)
{
    char           *cp = optarg;
        /*
	 * Hmmm... this doesn't seem to work.
	 * The main agent 'getopt' handling assumes
	 *   that the -L option takes an argument,
	 *   and objects if this is missing.
	 * Trying to differentiate between
	 *   new-style "-Lx", and old-style "-L xx"
	 *   is likely to be a major headache.
	 */
    char            missing_opt = 'e';	/* old -L is new -Le */
    int             priority = LOG_DEBUG;
    int             pri_max  = LOG_EMERG;
    int             inc_optind = 0;
    netsnmp_log_handler *logh;

    DEBUGMSGT(("logging:options", "optarg: '%s', argc %d, argv '%s'\n",
               optarg, argc, argv ? argv[0] : "NULL"));
    optarg++;
    if (!*cp)
        cp = &missing_opt;

    /*
     * Support '... -Lx=value ....' syntax
     */
    if (*optarg == '=') {
        optarg++;
    }
    /*
     * and '.... "-Lx value" ....'  (*with* the quotes)
     */
    while (*optarg && isspace((unsigned char)(*optarg))) {
        optarg++;
    }
    /*
     * Finally, handle ".... -Lx value ...." syntax
     *   (*without* surrounding quotes)
     */
    if ((!*optarg) && (NULL != argv)) {
        /*
         * We've run off the end of the argument
         *  so move on to the next.
         * But we might not actually need it, so don't
	 *  increment optind just yet!
         */
        optarg = argv[optind];
        inc_optind = 1;
    }

    DEBUGMSGT(("logging:options", "*cp: '%c'\n", *cp));
    switch (*cp) {

#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_STDIO
    /*
     * Log to Standard Error
     */
    case 'E':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1)  return -1;
        if (inc_optind)
            optind++;
        /* Fallthrough */
    case 'e':
        logh = netsnmp_register_stdio_loghandler(0, priority, pri_max, "stderr");
        break;

    /*
     * Log to Standard Output
     */
    case 'O':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1)  return -1;
        if (inc_optind)
            optind++;
        /* Fallthrough */
    case 'o':
        logh = netsnmp_register_stdio_loghandler( 1, priority, pri_max, "stdout" );
        break;
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_STDIO */

    /*
     * Log to a named file
     */
#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_FILE
    case 'F':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1) return -1;
        while (*optarg == ' ') optarg++;
        if (!*optarg && !argv) return -1;
        else if (!*optarg) optarg = argv[++optind];
        /* FALL THROUGH */
    case 'f':
        if (inc_optind)
            optind++;
        if (!optarg) {
            fprintf(stderr, "Missing log file\n");
            return -1;
        }
        DEBUGMSGTL(("logging:options", "%d-%d: '%s'\n", priority, pri_max, optarg));
        logh = netsnmp_register_filelog_handler(optarg, priority, pri_max,
                                                   -1);
        break;
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_FILE */

#ifndef NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG
    /*
     * Log to syslog
     */
    case 'S':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1 || !argv)  return -1;
        if (!optarg[0]) {
            /* The command line argument with priority does not contain log
             * facility. The facility must be in next argument then. */
            optind++;
            if (optind < argc)
                optarg = argv[optind];
        }
        /* Fallthrough */
    case 's':
        if (inc_optind)
            optind++;
        if (!optarg) {
            fprintf(stderr, "Missing syslog facility\n");
            return -1;
        }
        logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_SYSLOG, priority);
        if (logh) {
            int facility = decode_facility(optarg);
            if (facility == -1) {
                netsnmp_remove_loghandler(logh);
                return -1;
            }
            logh->pri_max = pri_max;
            logh->token   = strdup(snmp_log_syslogname(NULL));
            logh->magic   = (void *)(intptr_t)facility;
	    snmp_enable_syslog_ident(snmp_log_syslogname(NULL), facility);
	}
        break;
#endif /* NETSNMP_FEATURE_REMOVE_LOGGING_SYSLOG */

    /*
     * Don't log 
     */
    case 'N':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1)  return -1;
        if (inc_optind)
            optind++;
        /* Fallthrough */
    case 'n':
        /*
         * disable all logs to clean them up (close files, etc),
         * remove all log handlers, then register a null handler.
         */
        snmp_disable_log();
        while(NULL != logh_head)
            netsnmp_remove_loghandler( logh_head );
        logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_NONE, priority);
        if (logh) {
            logh->pri_max = pri_max;
	}
        break;

    default:
        fprintf(stderr, "Unknown logging option passed to -L: %c.\n", *cp);
        return -1;
    }
    return 0;
}
Ejemplo n.º 3
0
int
snmp_log_options(char *optarg, int argc, char *const *argv)
{
    char           *cp = optarg;
        /*
	 * Hmmm... this doesn't seem to work.
	 * The main agent 'getopt' handling assumes
	 *   that the -L option takes an argument,
	 *   and objects if this is missing.
	 * Trying to differentiate between
	 *   new-style "-Lx", and old-style "-L xx"
	 *   is likely to be a major headache.
	 */
    char            missing_opt = 'e';	/* old -L is new -Le */
    int             priority = LOG_DEBUG;
    int             pri_max  = LOG_EMERG;
    int             inc_optind = 0;
    netsnmp_log_handler *logh;

    optarg++;
    if (!*cp)
        cp = &missing_opt;

    /*
     * Support '... -Lx=value ....' syntax
     */
    if (*optarg == '=') {
        optarg++;
    }
    /*
     * and '.... "-Lx value" ....'  (*with* the quotes)
     */
    while (*optarg && isspace(*optarg)) {
        optarg++;
    }
    /*
     * Finally, handle ".... -Lx value ...." syntax
     *   (*without* surrounding quotes)
     */
    if ((!*optarg) && (NULL != argv)) {
        /*
         * We've run off the end of the argument
         *  so move on to the next.
         * But we might not actually need it, so don't
	 *  increment optind just yet!
         */
        optarg = argv[optind];
        inc_optind = 1;
    }

    switch (*cp) {

    /*
     * Log to Standard Error
     */
    case 'E':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1)  return -1;
        if (inc_optind)
            optind++;
        /* Fallthrough */
    case 'e':
        logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_STDERR, priority);
        if (logh) {
            logh->pri_max = pri_max;
            logh->token   = strdup("stderr");
	}
        break;

    /*
     * Log to Standard Output
     */
    case 'O':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1)  return -1;
        if (inc_optind)
            optind++;
        /* Fallthrough */
    case 'o':
        logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_STDERR, priority);
        if (logh) {
            logh->pri_max = pri_max;
            logh->token   = strdup("stdout");
            logh->imagic  = 1;	    /* stdout, not stderr */
	}
        break;

    /*
     * Log to a named file
     */
    case 'F':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1 || !argv)  return -1;
        optarg = argv[++optind];
        /* Fallthrough */
    case 'f':
        if (inc_optind)
            optind++;
        if (!optarg) {
            fprintf(stderr, "Missing log file\n");
            return -1;
        }
        logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_FILE, priority);
        if (logh) {
            logh->pri_max = pri_max;
            logh->token   = strdup(optarg);
            netsnmp_enable_filelog(logh,
                                   netsnmp_ds_get_boolean(NETSNMP_DS_LIBRARY_ID,
                                                          NETSNMP_DS_LIB_APPEND_LOGFILES));
	}
        break;

    /*
     * Log to syslog
     */
    case 'S':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1 || !argv)  return -1;
        if (!optarg[0]) {
            /* The command line argument with priority does not contain log
             * facility. The facility must be in next argument then. */
            optind++;
            if (optind < argc)
                optarg = argv[optind];
        }
        /* Fallthrough */
    case 's':
        if (inc_optind)
            optind++;
        if (!optarg) {
            fprintf(stderr, "Missing syslog facility\n");
            return -1;
        }
        logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_SYSLOG, priority);
        if (logh) {
            int facility = decode_facility(optarg);
            if (facility == -1)  return -1;
            logh->pri_max = pri_max;
            logh->token   = strdup(snmp_log_syslogname(0));
            logh->magic   = (void *)(intptr_t)facility;
	    snmp_enable_syslog_ident(snmp_log_syslogname(0), facility);
	}
        break;

    /*
     * Don't log 
     */
    case 'N':
        priority = decode_priority( &optarg, &pri_max );
        if (priority == -1)  return -1;
        if (inc_optind)
            optind++;
        /* Fallthrough */
    case 'n':
        /*
         * disable all logs to clean them up (close files, etc),
         * remove all log handlers, then register a null handler.
         */
        snmp_disable_log();
        while(NULL != logh_head)
            netsnmp_remove_loghandler( logh_head );
        logh = netsnmp_register_loghandler(NETSNMP_LOGHANDLER_NONE, priority);
        if (logh) {
            logh->pri_max = pri_max;
	}
        break;

    default:
        fprintf(stderr, "Unknown logging option passed to -L: %c.\n", *cp);
        return -1;
    }
    return 0;
}
Ejemplo n.º 4
0
int
handle_nsLoggingTable(netsnmp_mib_handler *handler,
                netsnmp_handler_registration *reginfo,
                netsnmp_agent_request_info *reqinfo,
                netsnmp_request_info *requests)
{
    long temp;
    netsnmp_request_info       *request     = NULL;
    netsnmp_table_request_info *table_info  = NULL;
    netsnmp_log_handler        *logh        = NULL;
    netsnmp_variable_list      *idx         = NULL;

    switch (reqinfo->mode) {

    case MODE_GET:
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                if (!logh) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		temp = logh->type;
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&temp,
                                            sizeof(temp));
	        break;

            case NSLOGGING_MAXLEVEL:
                if (!logh) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		temp = logh->pri_max;
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&temp,
                                            sizeof(temp));
	        break;

            case NSLOGGING_STATUS:
                if (!logh) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHINSTANCE);
                    continue;
		}
		temp = (logh->type ?
	                   (logh->enabled ?
	                      RS_ACTIVE:
	                      RS_NOTINSERVICE) :
	                    RS_NOTREADY);
	        snmp_set_var_typed_value(request->requestvb, ASN_INTEGER,
                                         (u_char*)&temp, sizeof(temp));
	        break;

            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                continue;
	    }
	}
	break;


#ifndef NETSNMP_NO_WRITE_SUPPORT
    case MODE_SET_RESERVE1:
        for (request=requests; request; request=request->next) {
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                if ( request->requestvb->type != ASN_INTEGER ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                if (*request->requestvb->val.integer < 0 ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
		/*
		 * It's OK to create a new logging entry
		 *  (either in one go, or built up using createAndWait)
		 *  but it's not possible to change the type of an entry
		 *  once it's been created.
		 */
                if (logh && logh->type) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_NOTWRITABLE);
                    return SNMP_ERR_NOTWRITABLE;
		}
	        break;

            case NSLOGGING_MAXLEVEL:
                if ( request->requestvb->type != ASN_INTEGER ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
                if (*request->requestvb->val.integer < 0 ||
                    *request->requestvb->val.integer > 7 ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
	        break;

            case NSLOGGING_STATUS:
                if ( request->requestvb->type != ASN_INTEGER ) {
                    netsnmp_set_request_error(reqinfo, request, SNMP_ERR_WRONGTYPE);
                    return SNMP_ERR_WRONGTYPE;
                }
		switch ( *request->requestvb->val.integer ) {
                case RS_ACTIVE:
                case RS_NOTINSERVICE:
                    /*
		     * Can only work on existing rows
		     */
                    if (!logh) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
                    }
	            break;

                case RS_CREATEANDWAIT:
                case RS_CREATEANDGO:
                    /*
		     * Can only work with new rows
		     */
                    if (logh) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
                    }

                    /*
                     *  Normally, we'd create the row at a later stage
                     *   (probably during the RESERVE2 or ACTION passes)
                     *
                     *  But we need to check that the values are
                     *   consistent during the ACTION pass (which is the
                     *   latest that an error can be safely handled),
                     *   so the values all need to be set up before this
                     *      (i.e. during the RESERVE2 pass)
                     *  So the new row needs to be created before that
                     *   in order to have somewhere to put them.
                     *
                     *  That's why we're doing this here.
                     */
                    idx = table_info->indexes;
	            logh = netsnmp_register_loghandler(
				    /* not really, but we need a valid type */
				    NETSNMP_LOGHANDLER_STDOUT,
				    *idx->val.integer);
                    if (!logh) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_GENERR); /* ??? */
                        return SNMP_ERR_GENERR;
                    }
                    idx = idx->next_variable;
	            logh->type  = 0;
	            logh->token = strdup((char *) idx->val.string);
                    netsnmp_insert_iterator_context(request, (void*)logh);
	            break;

                case RS_DESTROY:
                    /*
		     * Can work with new or existing rows
		     */
                    break;

                case RS_NOTREADY:
		default:
                    netsnmp_set_request_error(reqinfo, request,
                                              SNMP_ERR_WRONGVALUE);
                    return SNMP_ERR_WRONGVALUE;
                }
                break;

            default:
                netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT);
                return SNMP_NOSUCHOBJECT;
	    }
	}
	break;


    case MODE_SET_RESERVE2:
        for (request=requests; request; request=request->next) {
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                /*
		 * If we're creating a row using createAndGo,
		 * we need to set the type early, so that we
		 * can validate it in the ACTION pass.
		 *
		 * Remember that we need to be able to reverse this
		 */
                if ( logh )
                    logh->type = *request->requestvb->val.integer;
	        break;
            /*
	     * Don't need to handle nsLogToken or nsLogStatus in this pass
	     */
	    }
	}
	break;

    case MODE_SET_ACTION:
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_STATUS:
                /*
		 * This is where we can check the internal consistency
		 * of the request.  Basically, for a row to be marked
		 * 'active', then there needs to be a valid type value.
		 */
		switch ( *request->requestvb->val.integer ) {
                case RS_ACTIVE:
                case RS_CREATEANDGO:
                    if ( !logh || !logh->type ) {
                        netsnmp_set_request_error(reqinfo, request,
                                                  SNMP_ERR_INCONSISTENTVALUE);
                        return SNMP_ERR_INCONSISTENTVALUE;
		    }
	            break;
		}
	        break;
            /*
	     * Don't need to handle nsLogToken or nsLogType in this pass
	     */
	    }
	}
	break;

    case MODE_SET_FREE:
    case MODE_SET_UNDO:
        /*
         * If any resources were allocated in either of the
         *  two RESERVE passes, they need to be released here,
         *  and any assignments (in RESERVE2) reversed.
         *
         * Nothing additional will have been done during ACTION
         *  so this same code can do for UNDO as well.
         */
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_TYPE:
                /*
		 * If we've been setting the type, and the request
		 * has failed, then revert to an unset type.
		 *
		 * We need to be careful here - if the reason it failed is
		 *  that the type was already set, then we shouldn't "undo"
		 *  the assignment (since it won't actually have been made).
		 *
		 * Check the current value against the 'new' one.  If they're
		 * the same, then this is probably a successful assignment,
		 * and the failure was elsewhere, so we need to undo it.
		 *  (Or else there was an attempt to write the same value!)
		 */
                if ( logh && logh->type == *request->requestvb->val.integer )
                    logh->type = 0;
	        break;

            case NSLOGGING_STATUS:
                temp = *request->requestvb->val.integer;
                if ( logh && ( temp == RS_CREATEANDGO ||
                               temp == RS_CREATEANDWAIT)) {
		    netsnmp_remove_loghandler( logh );
		}
	        break;
            /*
	     * Don't need to handle nsLogToken in this pass
	     */
	    }
	}
	break;


    case MODE_SET_COMMIT:
        for (request=requests; request; request=request->next) {
            if (request->processed != 0)
                continue;
            if ( request->status != 0 ) {
                return SNMP_ERR_NOERROR;	/* Already got an error */
            }
            logh = (netsnmp_log_handler*)netsnmp_extract_iterator_context(request);
            if (!logh) {
                netsnmp_set_request_error(reqinfo, request, SNMP_ERR_COMMITFAILED);
                return SNMP_ERR_COMMITFAILED;	/* Shouldn't happen! */
            }
            table_info  =                 netsnmp_extract_table_info(request);

            switch (table_info->colnum) {
            case NSLOGGING_MAXLEVEL:
                logh->pri_max = *request->requestvb->val.integer;
	        break;

            case NSLOGGING_STATUS:
                switch (*request->requestvb->val.integer) {
                    case RS_ACTIVE:
                    case RS_CREATEANDGO:
                        netsnmp_enable_this_loghandler(logh);
                        break;
                    case RS_NOTINSERVICE:
                    case RS_CREATEANDWAIT:
                        netsnmp_disable_this_loghandler(logh);
                        break;
		    case RS_DESTROY:
		        netsnmp_remove_loghandler( logh );
                        break;
		}
	        break;
	    }
	}
	break;
#endif /* !NETSNMP_NO_WRITE_SUPPORT */
    }

    return SNMP_ERR_NOERROR;
}