예제 #1
0
int CEclAgentExecutionServer::executeWorkunit(const char * wuid)
{
    //build eclagent command line
    StringBuffer command;

#ifdef _WIN32
    command.append(".\\eclagent.exe");
#else
    command.append("start_eclagent");
#endif

    StringBuffer cmdLine = command;
    cmdLine.append(" WUID=").append(wuid).append(" DALISERVERS=").append(daliServers);

    DWORD runcode;
    PROGLOG("AgentExec: Executing '%s'", cmdLine.str());
#ifdef _WIN32
    bool success = invoke_program(cmdLine.str(), runcode, false, NULL, NULL);
#else
    //specify "wait" to eliminate linux zombies. Waits for the startup script to 
    //complete (not eclagent), because script starts eclagent in the background
    bool success = invoke_program(cmdLine.str(), runcode, true, NULL, NULL);
#endif
    if (success)
    { 
        if (runcode != 0)
            PROGLOG("Process failed during execution: %s error(%"I64F"i)", cmdLine.str(), (unsigned __int64) runcode);
        else
            PROGLOG("Execution started");
    }
    else
    {
        Owned<IWorkUnitFactory> factory = getWorkUnitFactory();
        Owned<IWorkUnit> workunit = factory->updateWorkUnit(wuid);
        if (workunit)
        {
            workunit->setState(WUStateFailed);
            workunit->commit();
        }
        PROGLOG("Process failed to start: %s", cmdLine.str());
    }

    return success && runcode == 0;
}
예제 #2
0
int newagent::start_process(const char *command,int & error_code,const char * local_dir,const char * user,const char * password) {
    error_code=0;
#ifdef _WIN32
    PROCESS_INFORMATION process;
    STARTUPINFO si;
    HANDLE res=0;
    bool ok=false;
    HANDLE other_user=0;
#ifdef _DEBUG
    if (!strcmp(command,"forceerror")) *((int *)0)=5;
#endif
    memset(&si,0,sizeof(si));
    si.cb          = sizeof(si);
    si.lpTitle     = (char*)command;
    si.wShowWindow = SW_SHOWDEFAULT;
    si.dwFlags     = STARTF_USESHOWWINDOW;
    si.wShowWindow = SW_SHOWNORMAL;
    char current_dir[256]=" ;103<;01",c_dir[256];
    if (local_dir&&*local_dir) {
        strcpy(c_dir,local_dir);
    }
    else {    
        if (!is_debug_session&&read_key("03",(unsigned char *)current_dir,sizeof(current_dir))) {
            char * finger=current_dir;
            int bs=4;
            while (*finger&&bs) {
                if (*finger=='\\') bs--;
                finger++;
            }
            if (*finger) sprintf(c_dir,maped_drive"\\%s",finger); else sprintf(c_dir,maped_drive"\\");
        } 
        else 
            strcpy(c_dir,".");
        
    }
    if (is_debug_session) {
        ok=(bool)CreateProcess(NULL,(char*)command,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,c_dir,&si,&process);
        if (!ok) error_code=GetLastError();
    } 
    else {
        if (!local_dir&&!drive_maped) do_map_drive(error_code);
        if(!error_code) {
            HANDLE uh=server_user;
            if (user&&*user) {
                logonu(other_user,unscr((char*)user),unscr((char*)password),error_code);
                uh=other_user;
            }
            if (!error_code) {
                if (!ImpersonateLoggedOnUser(uh)) error_code=GetLastError();
                if (!error_code) {
                    char saved_dir[256];
                    if (!GetCurrentDirectory(sizeof(saved_dir),saved_dir)) {
                        logfile("GetCurrentDirectory failed\r\n");
                        error_code=GetLastError();
                    }
                    else {
                        if (!SetCurrentDirectory(c_dir)) {
                            error_code=GetLastError();
                            if (error_code==2) error_code=267;
                            logfile ("SetCurrentDirectory failed %s %i\r\n",c_dir,error_code);
                        }
                        else {
                            ok=(bool)CreateProcessAsUser( uh,NULL,(char*)command,NULL,NULL,TRUE,NORMAL_PRIORITY_CLASS,NULL,c_dir,&si,&process);
                            if (!ok) error_code=GetLastError();
                            if (ok&&!SetCurrentDirectory(saved_dir))  {
                                logfile("restore current dirctory failed %s\r\n",saved_dir);
                                error_code=GetLastError();
                            }
                        } 
                    }             
                    RevertToSelf();
                }
            }
        }
    }
    if (ok) {
        res=process.hProcess;
        CloseHandle(process.hThread);
        logfile("Process started: %s\r\n",command);
    }
    else {
        logfile("Process failed: %s error(%i) %s\r\n",command,error_code,c_dir);
    }
    if (other_user) CloseHandle(other_user);
    if (ok) 
        return (int)res;
    else
        return 0;
    
#else
    //  if (is_debug_session)
    {
        long res;
        _chdir(cur_dir);
        pid_t pid;
        if (invoke_program(command, res, false, NULL, NULL, &pid))
            return pid;
        printf("invoke_program error %d\n", res);
        error_code=res;
        logfile("Process failed: %s error(%i) %s\r\n",command,error_code,cur_dir);
        /* not sure these should be freed here
        free(user);
        free(password);
        */
        return 0;
    }
#endif
}
   virtual void doWork()
   {
      try
      {
         StringBuffer cmdLine;
         StringBuffer userId;
         StringBuffer password;
         bool bLinux;
         int exitCode = -1;

            if (m_sConfigAddress.length() < 1)
            {
                m_pService->getAccountAndPlatformInfo(m_sAddress.str(), userId, password, bLinux);
            }
            else
            {
                m_pService->getAccountAndPlatformInfo(m_sConfigAddress.str(), userId, password, bLinux);
            }

            if (m_userId.length() < 1 || m_userId.length() < 1)
            {
                //BUG: 9825 - remote execution on linux needs to use individual accounts
                //use userid/password in ESP context for remote execution...
                if (bLinux)
                {
                    userId.clear();
                    password.clear();
                    m_context.getUserID(userId);
                    m_context.getPassword(password);
                }
            }
            else
            {
                userId.clear().append(m_userId);
                password.clear().append(m_password);
            }

#ifdef _WIN32
///#define CHECK_LINUX_COMMAND
#ifndef CHECK_LINUX_COMMAND
#define popen  _popen
#define pclose _pclose

         // Use psexec as default remote control program
         if (bLinux)
         {         
            if (!checkFileExists(".\\plink.exe"))
               throw MakeStringException(ECLWATCH_PLINK_NOT_INSTALLED, "Invalid ESP installation: missing plink.exe to execute the remote program!");

            m_sCommand.replace('\\', '/');//replace all '\\' by '/'

            /* 
            note that if we use plink (cmd line ssh client) for the first time with a computer,
            it generates the following message:

            The server's host key is not cached in the registry. You have no guarantee that the 
            server is the computer you think it is.  The server's key fingerprint is:
            1024 aa:bb:cc:dd:ee:ff:gg:hh:ii:jj:kk:ll:mm:nn:oo:pp
            If you trust this host, enter "y" to add the key to
            PuTTY's cache and carry on connecting.  If you want to carry on connecting just once, 
            without adding the key to the cache, enter "n".If you do not trust this host, press 
            Return to abandon the connection.

            To get around this, we pipe "n" to plink without using its -batch parameter.  We need
            help from cmd.exe to do this though...
            */
                if (!m_useDefaultSSHUserID)
                {
                    cmdLine.appendf("cmd /c \"echo y | .\\plink.exe -ssh -l espuser -i id_rsa.ppk %s bash -c '%s' 2>&1\"",
                        m_sAddress.str(), m_sCommand.str());
                }
                else
                {
                    cmdLine.appendf("cmd /c \"echo y | .\\plink.exe -ssh -l %s -pw %s %s sudo bash -c '%s' 2>&1\"",
                        userId.str(), password.str(), m_sAddress.str(), m_sCommand.str());
                }
         }
         else
         {
            if (!checkFileExists(".\\psexec.exe"))
               throw MakeStringException(ECLWATCH_PSEXEC_NOT_INSTALLED, "Invalid ESP installation: missing psexec.exe to execute the remote program!");

            cmdLine.appendf(".\\psexec \\\\%s -u %s -p %s %s cmd /c %s 2>&1", 
               m_sAddress.str(), userId.str(), password.str(), 
               m_bWait ? "" : "-d", m_sCommand.str());
         }
#else
         if (bLinux)
         {
                if (!m_useDefaultSSHUserID)
                {
                    m_sCommand.replace('\\', '/');//replace all '\\' by '/'
                    cmdLine.appendf("ssh -o StrictHostKeyChecking=no -i /home/espuser/.ssh/id_rsa espuser@%s '%s'", m_sAddress.str(), m_sCommand.str());
                }
                else
                {
                    m_sCommand.replace('\\', '/');//replace all '\\' by '/'
                    cmdLine.appendf("ssh -o StrictHostKeyChecking=no %s '%s'", m_sAddress.str(), m_sCommand.str());
                }
         }
         else
         {
            setResponse("Remote execution from Linux to Windows is not supported!");
            exitCode = 1;
         }
#endif
#else
         if (bLinux)
         {
                if (!m_useDefaultSSHUserID)
                {
                    m_sCommand.replace('\\', '/');//replace all '\\' by '/'
                    cmdLine.appendf("ssh -o StrictHostKeyChecking=no -i /home/espuser/.ssh/id_rsa espuser@%s '%s'", m_sAddress.str(), m_sCommand.str());
                }
                else
                {
                    m_sCommand.replace('\\', '/');//replace all '\\' by '/'
                    cmdLine.appendf("ssh -o StrictHostKeyChecking=no %s '%s'", m_sAddress.str(), m_sCommand.str());
                }
         }
         else
         {
            setResponse("Remote execution from Linux to Windows is not supported!");
            exitCode = 1;
         }
#endif

         if (*cmdLine.str())
         {
            if (m_bWait)
            {
               StringBuffer response, response1;
               exitCode = invoke_program(cmdLine, response);
                    if (exitCode < 0)
                        response1.append("Failed in executing a system command.\n");
                    else
                        response1.append("System command(s) has been executed.\n");

               //remove \n at the end
               int len = response.length();
               if (len > 0 && response.charAt(--len) == '\n')
                  response.setLength(len);

               setResponse(response1.str());
            }
            else
            {
               DWORD runCode;
               ::invoke_program(cmdLine, runCode, false);
               exitCode = (int) runCode;
            }
         }

         setResultCode(exitCode);
      }
      catch(IException* e)
      {
         StringBuffer buf;
         e->errorMessage(buf);
         setResponse(buf.str());
         setResultCode(e->errorCode());
      }
#ifndef NO_CATCHALL
      catch(...)
      {
         setResponse("An unknown exception occurred!");
         setResultCode(-1);
      }
#endif
   }//doWork()