Ejemplo n.º 1
0
u_char         *
var_extensible_shell(struct variable * vp,
                     oid * name,
                     size_t * length,
                     int exact,
                     size_t * var_len, WriteMethod ** write_method)
{

    static struct extensible *exten = 0;
    static long     long_ret;
    int len;

    if (header_simple_table
        (vp, name, length, exact, var_len, write_method, numextens))
        return (NULL);

    if ((exten = get_exten_instance(extens, name[*length - 1]))) {
        switch (vp->magic) {
        case MIBINDEX:
            long_ret = name[*length - 1];
            return ((u_char *) (&long_ret));
        case ERRORNAME:        /* name defined in config file */
            *var_len = strlen(exten->name);
            return ((u_char *) (exten->name));
        case SHELLCOMMAND:
            *var_len = strlen(exten->command);
            return ((u_char *) (exten->command));
        case ERRORFLAG:        /* return code from the process */
            len = sizeof(exten->output);
            if (exten->type == EXECPROC) {
                exten->result = run_exec_command( exten->command, NULL,
                                                  exten->output, &len);
	    } else {
                exten->result = run_shell_command(exten->command, NULL,
                                                  exten->output, &len);
	    }
            long_ret = exten->result;
            return ((u_char *) (&long_ret));
        case ERRORMSG:         /* first line of text returned from the process */
            len = sizeof(exten->output);
            if (exten->type == EXECPROC) {
                exten->result = run_exec_command( exten->command, NULL,
                                                  exten->output, &len);
	    } else {
                exten->result = run_shell_command(exten->command, NULL,
                                                  exten->output, &len);
	    }
            *var_len = strlen(exten->output);
            if (exten->output[*var_len - 1] == '\n')
                exten->output[--(*var_len)] = '\0';
            return ((u_char *) (exten->output));
        case ERRORFIX:
            *write_method = fixExecError;
            long_return = 0;
            return ((u_char *) & long_return);

        case ERRORFIXCMD:
            *var_len = strlen(exten->fixcmd);
            return ((u_char *) exten->fixcmd);
        }
        return NULL;
    }
    return NULL;
}
Ejemplo n.º 2
0
u_char         *
var_extensible_relocatable(struct variable *vp,
                           oid * name,
                           size_t * length,
                           int exact,
                           size_t * var_len, WriteMethod ** write_method)
{

    int             i;
    int             len;
    struct extensible *exten = 0;
    static long     long_ret;
    static char     errmsg[STRMAX];
    char            *cp, *cp1;
    struct variable myvp;
    oid             tname[MAX_OID_LEN];

    memcpy(&myvp, vp, sizeof(struct variable));

    long_ret = *length;
    for (i = 1; i <= (int) numrelocs; i++) {
        exten = get_exten_instance(relocs, i);
        if (!exten)
            continue;
        if ((int) exten->miblen == (int) vp->namelen - 1) {
            memcpy(myvp.name, exten->miboid, exten->miblen * sizeof(oid));
            myvp.namelen = exten->miblen;
            *length = vp->namelen;
            memcpy(tname, vp->name, vp->namelen * sizeof(oid));
            if (!header_simple_table
                (&myvp, tname, length, -1, var_len, write_method, -1))
                break;
            else
                exten = NULL;
        }
    }
    if (i > (int) numrelocs || exten == NULL) {
        *length = long_ret;
        *var_len = 0;
        *write_method = NULL;
        return (NULL);
    }

    *length = long_ret;
    if (header_simple_table(vp, name, length, exact, var_len, write_method,
                            ((vp->magic == ERRORMSG) ? MAXMSGLINES : 1)))
        return (NULL);

    switch (vp->magic) {
    case MIBINDEX:
        long_ret = name[*length - 1];
        return ((u_char *) (&long_ret));
    case ERRORNAME:            /* name defined in config file */
        *var_len = strlen(exten->name);
        return ((u_char *) (exten->name));
    case SHELLCOMMAND:
        *var_len = strlen(exten->command);
        return ((u_char *) (exten->command));
    case ERRORFLAG:            /* return code from the process */
        len = sizeof(exten->output);
        if (exten->type == EXECPROC)
            exten->result = run_exec_command( exten->command, NULL,
                                              exten->output, &len);
	else
            exten->result = run_shell_command(exten->command, NULL,
                                              exten->output, &len);
        long_ret = exten->result;
        return ((u_char *) (&long_ret));
    case ERRORMSG:             /* first line of text returned from the process */
        len = sizeof(exten->output);
        if (exten->type == EXECPROC)
            exten->result = run_exec_command( exten->command, NULL,
                                              exten->output, &len);
	else
            exten->result = run_shell_command(exten->command, NULL,
                                              exten->output, &len);

        /*
         *  Pick the output string apart into individual lines,
         *  and extract the one being asked for....
         */
        cp1 = exten->output;
        for (i = 1; i != (int) name[*length - 1]; i++) {
            cp = strchr(cp1, '\n');
            if (!cp) {
	        *var_len = 0;
	        /* wait_on_exec(exten);		??? */
	        return NULL;
	    }
	    cp1 = ++cp;
	}
        /*
         *  ... and quit if we've run off the end of the output
         */
        if (!*cp1) {
            *var_len = 0;
	    return NULL;
	}
        cp = strchr(cp1, '\n');
        if (cp)
            *cp = 0;
        strlcpy(errmsg, cp1, sizeof(errmsg));
        *var_len = strlen(errmsg);
        if (errmsg[*var_len - 1] == '\n')
            errmsg[--(*var_len)] = '\0';
        return ((u_char *) (errmsg));
    case ERRORFIX:
        *write_method = fixExecError;
        long_return = 0;
        return ((u_char *) & long_return);

    case ERRORFIXCMD:
        *var_len = strlen(exten->fixcmd);
        return ((u_char *) exten->fixcmd);
    }
    return NULL;
}
Ejemplo n.º 3
0
int
get_exec_output(struct extensible *ex)
{
#if HAVE_EXECV && HAVE_FORK
    char            cachefile[STRMAX];
    char            cache[NETSNMP_MAXCACHESIZE];
    ssize_t         cachebytes;
    int             cfd;
#ifdef NETSNMP_EXCACHETIME
    long            curtime;
    static char     lastcmd[STRMAX];
    static int      lastresult;
#endif

    DEBUGMSGTL(("exec:get_exec_output","calling %s\n", ex->command));

    sprintf(cachefile, "%s/%s", get_persistent_directory(), NETSNMP_CACHEFILE);
#ifdef NETSNMP_EXCACHETIME
    curtime = time(NULL);
    if (curtime > (cachetime + NETSNMP_EXCACHETIME) ||
        strcmp(ex->command, lastcmd) != 0) {
        strcpy(lastcmd, ex->command);
        cachetime = curtime;
#endif

        cachebytes = NETSNMP_MAXCACHESIZE;
        ex->result = run_exec_command( ex->command, NULL, cache, &cachebytes );

        unlink(cachefile);
            /*
             * XXX  Use SNMP_FILEMODE_CLOSED instead of 644? 
             */
        if ((cfd = open(cachefile, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) {
                snmp_log(LOG_ERR,"can not create cache file\n");
                setPerrorstatus(cachefile);
                cachetime = 0;
                return -1;
        }
        if (cachebytes > 0)
            write(cfd, (void *) cache, cachebytes);
        close(cfd);
#ifdef NETSNMP_EXCACHETIME
        lastresult = ex->result;
    } else {
        ex->result = lastresult;
    }
#endif
    DEBUGMSGTL(("exec:get_exec_output","using cached value\n"));
    if ((cfd = open(cachefile, O_RDONLY)) < 0) {
        snmp_log(LOG_ERR,"can not open cache file\n");
        setPerrorstatus(cachefile);
        return -1;
    }
    return (cfd);
#else                           /* !HAVE_EXECV || !HAVE_FORK */
#if defined(WIN32) && !defined(HAVE_EXECV)
/* MSVC and MinGW.  Cygwin already works as it has execv and fork */
    int         fd;   
    
    /* Reference:  MS tech note: 190351 */
    HANDLE hOutputReadTmp, hOutputRead, hOutputWrite = NULL;
        
    HANDLE hErrorWrite;
    SECURITY_ATTRIBUTES sa;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    
    sa.nLength= sizeof(SECURITY_ATTRIBUTES);
    sa.lpSecurityDescriptor = NULL;
    sa.bInheritHandle = TRUE;

    DEBUGMSGTL(("exec:get_exec_output","calling %s\n", ex->command));
    
    /* Child temporary output pipe with Inheritance on (sa.bInheritHandle is true) */    
    if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0)) {
      DEBUGMSGTL(("util_funcs", "get_exec_pipes CreatePipe ChildOut: %d\n",
            GetLastError()));
      return -1;
    }
    
    /* Copy the stdout handle to the stderr handle in case the child closes one of 
     * its stdout handles. */
    if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite, GetCurrentProcess(),
          &hErrorWrite,0, TRUE,DUPLICATE_SAME_ACCESS)) {
      DEBUGMSGTL(("util_funcs", "get_exec_output DuplicateHandle: %d\n", GetLastError()));
      return -1;
    }

    /* Create new copies of the input and output handles but set bInheritHandle to 
     * FALSE so the new handle can not be inherited.  Otherwise the handles can not
     * be closed.  */
    if (!DuplicateHandle(GetCurrentProcess(), hOutputReadTmp, GetCurrentProcess(),
          &hOutputRead, 0, FALSE, DUPLICATE_SAME_ACCESS)) {
      DEBUGMSGTL(("util_funcs", "get_exec_output DupliateHandle ChildOut: %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      return -1;
    }   

    /* Close the temporary output and input handles */
    if (!CloseHandle(hOutputReadTmp)) {
      DEBUGMSGTL(("util_funcs", "get_exec_output CloseHandle (hOutputReadTmp): %d\n", GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      return -1;
    }
    
    /* Associates a C run-time file descriptor with an existing operating-system file handle. */
    fd = _open_osfhandle((long) hOutputRead, 0);
    
    /* Set up STARTUPINFO for CreateProcess with the handles and have it hide the window
     * for the new process. */
    ZeroMemory(&si,sizeof(STARTUPINFO));
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
    si.hStdOutput = hOutputWrite;
    si.hStdError = hErrorWrite;
    si.wShowWindow = SW_HIDE;
   
    /* Launch the process that you want to redirect.  Example snmpd.conf pass_persist:
     * pass_persist    .1.3.6.1.4.1.2021.255  c:/perl/bin/perl c:/temp/pass_persisttest
    */
    if (!CreateProcess(NULL, ex->command, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) {
      DEBUGMSGTL(("util_funcs","get_exec_output CreateProcess:'%s' %d\n",ex->command, GetLastError()));
      CloseHandle(hErrorWrite);
      CloseHandle(hOutputRead);
      return -1;
    }
    
    /* Set global child process handle */
    ex->pid = (int)pi.hProcess;
    ex->tid = (int)pi.hThread;

    /* Close pipe handles to make sure that no handles to the write end of the
     * output pipe are maintained in this process or else the pipe will
     * not close when the child process exits and any calls to ReadFile 
     * will hang.
     */

    if (!CloseHandle(hOutputWrite)){
      DEBUGMSGTL(("util_funcs","get_exec_output CloseHandle hOutputWrite: %d\n",ex->command, GetLastError()));
      return -1;
    }
    if (!CloseHandle(hErrorWrite)) {
      DEBUGMSGTL(("util_funcs","get_exec_output CloseHandle hErrorWrite: %d\n",ex->command, GetLastError()));
      return -1;
    }
    return fd;
#endif                          /* WIN32 */
    return -1;
#endif
}