示例#1
0
/**
 * Iterate over all persistent pipes and close those pipes of which the
 * associated process has stopped.
 */
static void check_persist_pipes(unsigned clientreg, void *clientarg)
{
    int             i;

    if (!persist_pipes)
        return;

    for (i = 0; i <= numpersistpassthrus; i++) {
        if (process_stopped(i)) {
            snmp_log(LOG_INFO, "pass_persist[%d]: child process stopped - closing pipe\n", i);
            close_persist_pipe(i);
        }
    }
}
示例#2
0
/*
 * Destruct our persistent pipes
 *
 */
static void
destruct_persist_pipes(void)
{
    int             i;

    /*
     * Return if there are no pipes 
     */
    if (!persist_pipes) {
        return;
    }

    for (i = 0; i <= numpersistpassthrus; i++) {
        close_persist_pipe(i);
    }

    free(persist_pipes);
    persist_pipes = (struct persist_pipe_type *) 0;
}
示例#3
0
void
pass_persist_free_config(void)
{
    struct extensible *etmp, *etmp2;
    int i;

    for (etmp = persistpassthrus; etmp != NULL;) {
        etmp2 = etmp;
        etmp = etmp->next;
        unregister_mib_priority(etmp2->miboid, etmp2->miblen, etmp2->mibpriority);
        free(etmp2);
    }
    if (persist_pipes) {
        for (i = 0; i <= numpersistpassthrus; i++) {
            close_persist_pipe(i);
        }
    }
    persistpassthrus = NULL;
    numpersistpassthrus = 0;
}
示例#4
0
static int
write_persist_pipe(int iindex, const char *data)
{
#if HAVE_SIGNAL
    struct sigaction sa, osa;
    int             wret = 0, werrno = 0;

    /*
     * Don't write to a non-existant process 
     */
    if (persist_pipes[iindex].pid == NETSNMP_NO_SUCH_PROCESS) {
        DEBUGMSGTL(("ucd-snmp/pass_persist",
                    "write_persist_pipe: not writing %s, process is non-existent",
                    data));
        return 0;
    }

    /*
     * Setup our signal action to ignore SIGPIPEs 
     */
    sa.sa_handler = SIG_IGN;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGPIPE, &sa, &osa)) {
        DEBUGMSGTL(("ucd-snmp/pass_persist",
                    "write_persist_pipe: sigaction failed: %d", errno));
    }

    /*
     * Do the write 
     */
    wret = write(persist_pipes[iindex].fdOut, data, strlen(data));
    werrno = errno;

    /*
     * Reset the signal handler 
     */
    sigaction(SIGPIPE, &osa, (struct sigaction *) 0);

    if (wret < 0) {
        if (werrno != EPIPE) {
            DEBUGMSGTL(("ucd-snmp/pass_persist",
                        "write_persist_pipe: write returned unknown error %d (%s)\n",
                        werrno, strerror(werrno)));
        }
        close_persist_pipe(iindex);
        return 0;
    }
#endif                          /* HAVE_SIGNAL */
#if defined(WIN32) && !defined (mingw32) && !defined (HAVE_SIGNAL)
/* We have no signal here (maybe we can make a Thread?) so write may block, 
 * but probably never will.
 */
    int wret = 0, werrno = 0;

    /*
     * Do the write 
     */
    wret = write(persist_pipes[iindex].fdOut, data,strlen(data));
    werrno = errno;
    
    if (wret < 0) {
      if (werrno != EINTR) {
        DEBUGMSGTL(("ucd-snmp/pass_persist", "write_persist_pipe: write returned unknown error %d\n",errno));
      }
      close_persist_pipe(iindex);
      return 0;
    }
#endif                          /* WIN32 */
    return 1;
}
示例#5
0
/*
 * returns 0 on failure, 1 on success 
 */
static int
open_persist_pipe(int iindex, char *command)
{
    static int      recurse = 0;        /* used to allow one level of recursion */

    DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe(%d,'%s') recurse=%d\n",
                iindex, command, recurse));
    /*
     * Open if it's not already open 
     */
    if (persist_pipes[iindex].pid == NETSNMP_NO_SUCH_PROCESS) {
        int             fdIn, fdOut;
        netsnmp_pid_t   pid;

        /*
         * Did we fail? 
         */
        if ((0 == get_exec_pipes(command, &fdIn, &fdOut, &pid)) ||
            (pid == NETSNMP_NO_SUCH_PROCESS)) {
            DEBUGMSGTL(("ucd-snmp/pass_persist",
                        "open_persist_pipe: pid == -1\n"));
            recurse = 0;
            return 0;
        }

        /*
         * If not, fill out our structure 
         */
        persist_pipes[iindex].pid = pid;
        persist_pipes[iindex].fdIn = fdIn;
        persist_pipes[iindex].fdOut = fdOut;
        persist_pipes[iindex].fIn = fdopen(fdIn, "r");
        persist_pipes[iindex].fOut = fdopen(fdOut, "w");

        /*
         * Setup our -non-buffered-io- 
         */
        setbuf(persist_pipes[iindex].fOut, (char *) 0);
        DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: opened the pipes\n"));
    }

    /*
     * Send test packet always so we can self-catch 
     */
    {
        char            buf[SNMP_MAXBUF];
        /*
         * Should catch SIGPIPE around this call! 
         */
        if (!write_persist_pipe(iindex, "PING\n")) {
            DEBUGMSGTL(("ucd-snmp/pass_persist",
                        "open_persist_pipe: Error writing PING\n"));
            close_persist_pipe(iindex);

            /*
             * Recurse one time if we get a SIGPIPE 
             */
            if (!recurse) {
                DEBUGMSGTL(("ucd-snmp/pass_persist", "open_persist_pipe: recursing to reopen\n"));
                recurse = 1;
                return open_persist_pipe(iindex, command);
            }
            recurse = 0;
            return 0;
        }
        if (fgets(buf, sizeof(buf), persist_pipes[iindex].fIn) == NULL) {
            DEBUGMSGTL(("ucd-snmp/pass_persist",
                        "open_persist_pipe: Error reading for PONG\n"));
            close_persist_pipe(iindex);
            recurse = 0;
            return 0;
        }
        if (strncmp(buf, "PONG", 4)) {
            DEBUGMSGTL(("ucd-snmp/pass_persist",
                        "open_persist_pipe: Got %s instead of PONG!\n", buf));
            close_persist_pipe(iindex);
            recurse = 0;
            return 0;
        }
    }

    recurse = 0;
    return 1;
}
示例#6
0
int
setPassPersist(int action,
               u_char * var_val,
               u_char var_val_type,
               size_t var_val_len,
               u_char * statP, oid * name, size_t name_len)
{
    int             i, rtest;
    struct extensible *persistpassthru;

    char            buf[SNMP_MAXBUF], buf2[SNMP_MAXBUF];

    /*
     * Make sure that our basic pipe structure is malloced 
     */
    init_persist_pipes();

    for (i = 1; i <= numpersistpassthrus; i++) {
        persistpassthru = get_exten_instance(persistpassthrus, i);
        rtest = snmp_oidtree_compare(name, name_len,
                                     persistpassthru->miboid,
                                     persistpassthru->miblen);
        if (rtest <= 0) {
            if (action != ACTION)
                return SNMP_ERR_NOERROR;
            /*
             * setup args 
             */
            if (persistpassthru->miblen >= name_len || rtest < 0)
                sprint_mib_oid(buf, persistpassthru->miboid,
                               persistpassthru->miblen);
            else
                sprint_mib_oid(buf, name, name_len);
            snprintf(persistpassthru->command,
                     sizeof(persistpassthru->command), "set\n%s\n", buf);
            persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0;
            netsnmp_internal_pass_set_format(buf, var_val, var_val_type, var_val_len);
            strlcat(persistpassthru->command, buf,
                    sizeof(persistpassthru->command));
            persistpassthru->command[ sizeof(persistpassthru->command)-2 ] = '\n';
            persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0;

            if (!open_persist_pipe(i, persistpassthru->name)) {
                return SNMP_ERR_NOTWRITABLE;
            }

            DEBUGMSGTL(("ucd-snmp/pass_persist",
                        "persistpass-writing:  %s\n",
                        persistpassthru->command));
            if (!write_persist_pipe(i, persistpassthru->command)) {
                close_persist_pipe(i);
                return SNMP_ERR_NOTWRITABLE;
            }

            if (fgets(buf, sizeof(buf), persist_pipes[i].fIn) == NULL) {
                close_persist_pipe(i);
                return SNMP_ERR_NOTWRITABLE;
            }

            return netsnmp_internal_pass_str_to_errno(buf);
        }
    }
    if (snmp_get_do_debugging()) {
        sprint_mib_oid(buf2, name, name_len);
        DEBUGMSGTL(("ucd-snmp/pass_persist", "persistpass-notfound:  %s\n",
                    buf2));
    }
    return SNMP_ERR_NOSUCHNAME;
}
示例#7
0
u_char         *
var_extensible_pass_persist(struct variable *vp,
                            oid * name,
                            size_t * length,
                            int exact,
                            size_t * var_len, WriteMethod ** write_method)
{
    oid             newname[MAX_OID_LEN];
    int             i, rtest, newlen;
    char            buf[SNMP_MAXBUF];
    static char     buf2[SNMP_MAXBUF];
    struct extensible *persistpassthru;
    FILE           *file;

    /*
     * Make sure that our basic pipe structure is malloced 
     */
    init_persist_pipes();

    for (i = 1; i <= numpersistpassthrus; i++) {
        persistpassthru = get_exten_instance(persistpassthrus, i);
        rtest = snmp_oidtree_compare(name, *length,
                                     persistpassthru->miboid,
                                     persistpassthru->miblen);
        if ((exact && rtest == 0) || (!exact && rtest <= 0)) {
            /*
             * setup args 
             */
            if (persistpassthru->miblen >= *length || rtest < 0)
                sprint_mib_oid(buf, persistpassthru->miboid,
                               persistpassthru->miblen);
            else
                sprint_mib_oid(buf, name, *length);

            /*
             * Open our pipe if necessary 
             */
            if (!open_persist_pipe(i, persistpassthru->name)) {
                return (NULL);
            }

            if (exact)
                snprintf(persistpassthru->command,
                  sizeof(persistpassthru->command), "get\n%s\n", buf);
            else
                snprintf(persistpassthru->command,
                  sizeof(persistpassthru->command), "getnext\n%s\n", buf);
            persistpassthru->command[ sizeof(persistpassthru->command)-1 ] = 0;

            DEBUGMSGTL(("ucd-snmp/pass_persist",
                        "persistpass-sending:\n%s",
                        persistpassthru->command));
            if (!write_persist_pipe(i, persistpassthru->command)) {
                *var_len = 0;
                /*
                 * close_persist_pipes is called in write_persist_pipe 
                 */
                return (NULL);
            }

            /*
             * valid call.  Exec and get output 
             */
		
            if ((file = persist_pipes[i].fIn)) {
                if (fgets(buf, sizeof(buf), file) == NULL) {
                    *var_len = 0;
                    close_persist_pipe(i);
                    return (NULL);
                }
                /*
                 * persistent scripts return "NONE\n" on invalid items 
                 */
                if (!strncmp(buf, "NONE", 4)) {
                    if (exact) {
                        *var_len = 0;
                        return (NULL);
                    }
                    continue;
                }
                newlen = parse_miboid(buf, newname);

                /*
                 * its good, so copy onto name/length 
                 */
                memcpy((char *) name, (char *) newname,
                       (int) newlen * sizeof(oid));
                *length = newlen;

                /*
                 * set up return pointer for setable stuff 
                 */
                *write_method = setPassPersist;

                if (newlen == 0 || fgets(buf, sizeof(buf), file) == NULL
                    || fgets(buf2, sizeof(buf2), file) == NULL) {
                    *var_len = 0;
                    close_persist_pipe(i);
                    return (NULL);
                }
                return netsnmp_internal_pass_parse(buf, buf2, var_len, vp);
            }
            *var_len = 0;
            return (NULL);
        }
    }
    if (var_len)
        *var_len = 0;
    *write_method = NULL;
    return (NULL);
}