RMA-Win CreateProcess Bug

When you post information about some problem, please include the following details: - OS version (e.g. Windows 2000 Professional SP3); HostMonitor version; problem description.
Post Reply
achillis
Posts: 2
Joined: Sun Jul 20, 2014 8:08 am

RMA-Win CreateProcess Bug

Post by achillis »

HM Version: 9.50
OS Version: Windows Server 2003 SP2 x86

Advice 1: RMA CreateProcess problem
I installed RMA-Win on My Server as a service to Monitor other services and processes.
And I configured the RMA to restart process when it found the process exited.
But there is a problem, when rma call function CreateProcess to run a process,
it does not use the right session,token and current directory parameters.
So , when process get started , it can't found its configure file or other things because it didn't know what is the right Current Direcotry.
As rma is running as a service , the process it created is not using the logon user's token,but using SYSTEM.

SO, I advice that rma can create process with right session,token,and current directory.
The function below maybe helpful to do this.

Code: Select all

DWORD _stdcall LaunchAppIntoDifferentSession( LPTSTR lpCommand )
{
    DWORD dwRet = 0;
    PROCESS_INFORMATION pi;
    STARTUPINFO si;
    DWORD dwSessionId;
    HANDLE hUserToken = NULL;
    HANDLE hUserTokenDup = NULL;
    HANDLE hPToken = NULL;
    HANDLE hProcess = NULL;
    DWORD dwCreationFlags;
    char szCurrentDir[MAX_PATH];


    // Log the client on to the local computer.
  typedef DWORD (WINAPI *PGetCSID)();
  PGetCSID pGetCID = (PGetCSID)GetProcAddress(GetModuleHandle("Kernel32.dll"),"WTSGetActiveConsoleSessionId");
  if (pGetCID == NULL)
  {
     gLogger.debug("[CRule::StartHotfixAgent] Get pointer faild WTSGetActiveConsoleSessionId " );
     return 0;
  }
  dwSessionId = pGetCID();


    do
    {
        WTSQueryUserToken( dwSessionId,&hUserToken );
        dwCreationFlags = NORMAL_PRIORITY_CLASS | CREATE_NEW_CONSOLE;
        ZeroMemory( &si, sizeof( STARTUPINFO ) );
        si.cb= sizeof( STARTUPINFO );
        si.lpDesktop = "winsta0\\default";
        ZeroMemory( &pi, sizeof(pi) );
        TOKEN_PRIVILEGES tp;
        LUID luid;


        if( !::OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
                                                        | TOKEN_DUPLICATE | TOKEN_ASSIGN_PRIMARY | TOKEN_ADJUST_SESSIONID
                                                        | TOKEN_READ | TOKEN_WRITE, &hPToken ) )
        {
            dwRet = GetLastError();
            break;
        }
        else;


        if ( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luid ) )
        {
            dwRet = GetLastError();
            break;
        }
        else;
        tp.PrivilegeCount =1;
        tp.Privileges[0].Luid =luid;
        tp.Privileges[0].Attributes =SE_PRIVILEGE_ENABLED;


        if( !DuplicateTokenEx( hPToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hUserTokenDup ) )
        {
            dwRet = GetLastError();
            break;
        }
        else;


        //Adjust Token privilege
        if( !SetTokenInformation( hUserTokenDup,TokenSessionId,(void*)&dwSessionId,sizeof(DWORD) ) )
        {
            dwRet = GetLastError();
            break;
        }
        else;


        if( !AdjustTokenPrivileges( hUserTokenDup, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES)NULL, NULL ) )
        {
            dwRet = GetLastError();
            break;
        }
        else;


        LPVOID pEnv =NULL;
        if( CreateEnvironmentBlock( &pEnv, hUserTokenDup, TRUE ) )
        {
            dwCreationFlags|=CREATE_UNICODE_ENVIRONMENT;
        }
        else pEnv=NULL;

        
        //CurrentDirectory ,build form the CommondLine
        lstrcpy(szCurrentDir,lpCommand);
        char *pFinder = strrchr(szCurrentDir,'\\');
        if(pFinder != NULL)
        {
          *pFinder = '\0';
        }
        
        // Launch the process in the client's logon session.
        if( CreateProcessAsUser(    hUserTokenDup,    // client's access token
                                    NULL,        // file to execute
                                    lpCommand,        // command line
                                    NULL,            // pointer to process SECURITY_ATTRIBUTES
                                    NULL,            // pointer to thread SECURITY_ATTRIBUTES
                                    FALSE,            // handles are not inheritable
                                    dwCreationFlags,// creation flags
                                    pEnv,          // pointer to new environment block
                                    NULL,          // name of current directory
                                    &si,            // pointer to STARTUPINFO structure
                                    &pi            // receives information about new process
                                    ) )
        {
        }
        else
        {
            dwRet = GetLastError();
            break;
        }
    }
    while( 0 );


    //Perform All the Close Handles task
    if( NULL != hUserToken )
    {
        CloseHandle( hUserToken );
    }
    else;


    if( NULL != hUserTokenDup)
    {
        CloseHandle( hUserTokenDup );
    }
    else;


    if( NULL != hPToken )
    {
        CloseHandle( hPToken );
    }
    else;
   
    return dwRet;
}


Advise 2: Add Export Configure Function for backup
When I add something to monitor and save the configure, I got a hml file
I thout a hml file contain everything configure in the hml list ,but I am wrong.
There action configuration is saved in another file .
Once I reinstalled the HostMonitor on another computer, and only copied the hml file to another computer,when I load the hml file to HostMonitor,
all the items is correct, but the action is all wrong.
SO, I advice that the action for hml saved with the same name ,for example , MyMonitor.hml with and Action configure file named MyMonitor.action
and I saw that the hml file is saved with a private format, so you can also save the action configures in this file.
If you can provide a tool to export and import all configuration about an hml file , that's also good.

Advice 3: Rma for solaris could not list all processes
Just as the topic of this section , I could not found some process that I want to monitor on the server.
KS-Soft
Posts: 12869
Joined: Wed Apr 03, 2002 6:00 pm
Location: USA
Contact:

Post by KS-Soft »

it does not use the right session,token and current directory parameters.
What exactly means "right session"?
I assume you are using "Execute external program" action? "Execute external program" action method does not offer options like
- run as specific user
- working directory
Yes, I think we can add such options in future versions but its not a bug.
Once I reinstalled the HostMonitor on another computer, and only copied the hml file to another computer,when I load the hml file to HostMonitor,
all the items is correct, but the action is all wrong.
Yes, you should copy ALL configuration files.
Please check the following article
http://www.ks-soft.net/cgi-bin/phpBB/vi ... php?t=1099
SO, I advice that the action for hml saved with the same name ,for example , MyMonitor.hml with and Action configure file named MyMonitor.action
and I saw that the hml file is saved with a private format, so you can also save the action configures in this file.
Sorry, I don't think we will implement such option.
Rma for solaris could not list all processes
Just as the topic of this section , I could not found some process that I want to monitor on the server.
I assume you are using Process test method?
Solaris version?
You may check and modify 2 files located in RMA folder
- proccnt.sh
- proclist.sh
You need to modify single line in each file.
For SunOS it looks like
SunOS) PLIST='ps -eo fname';;

Regards
Alex
achillis
Posts: 2
Joined: Sun Jul 20, 2014 8:08 am

Post by achillis »

About the first question:
Yes,I am using the "Execute external program" action.
For example ,the server is Windows 2008, I installed rma.exe as service, and it run with user SYSTEM and session 0 .
When I logon into the Server with user Administrator , and run a process named test.exe who has an GUI ,this process run with user Administrator and session 1.
So, you can see that the two processes were running with different user and different sessions.
I used the "Check Process" test to monitor the process test.exe and configured an action "Execute external program" to restart the process if it stopped unexpectly.
Once test.exe exit, rma.exe restart it , but now the test.exe is running with user SYSTEM and session 0 , because it inherited this from parent process rma.exe .
Now I COULD NOT see the UI of process test.exe because it is running in session 0 , in a different workstation and desktop.
That's what I mean "Right Session" .
And the user of the process was different , that's what I mean "Right User".
And also the CURRENT DIRECTORY in process test.exe was the directory of rma.exe ,but not of test.exe ,it could not load the configure file in the same directory.
So, the process test.exe may not work correctly as it run before.
That's what I mean "Right Directory".

As you say, you can provide parameter RUN AS USER and WORKING DIRECOTORY for user to configure , that will make your software working better.
Thanks for your software.
Post Reply