Run a program as certain user from service on Windows XP

At work we are collecting data about different production lines. We use Windows XP (yes, I know) machines. On them we have a server which connects to sensors. We access the server with our Python script and use data for further processing.

Pretty simple, right? Well it gets little more complicated. We have a service (Quartz.net) to call our Python script every 5 seconds. Everything works great, but there is one little problem.

The problem

The server is very unstable and crashes a lot. There is no log to check what is the problem. We have no idea how to make it more robust. But good thing is that when server crashes, all you have to do is login to the machine and restart it (doubleclick the icon to start the program again).

So the idea was just to automatically start the server program when we detect crash. But it’s not so simple.

Solution #1

First we need to know one thing. The Quartz.net service is running as SYSTEM. It calls the Python script as SYSTEM user. That means that everything we call from script, it will run under SYSTEM user.

Our first solution was to simply call the server program from our Python script.

As mentioned before, this will run server.exe as SYSTEM user. Not a good thing, because quickly we got problems with too much instances and memory leaks. If user manually started the server, it ran 2 instances under different users.

Solution #2

We cannot run program as SYSTEM user, but as logged in user – Mike. Idea was to use some Python pywin32 extensions to control the system. There is a nice code where you pass user credentials with program path and it works. Then you use the code to run the process as another user.

The code does not work for me. I tried different variations, but not success. Someone also mentioned that I need to change some permissions. Even though I changed them, it still did not work. Even if it did, it would be really tricky to make this kind of changes if they require admin permissions.

Solution #3

Let’s forget running a program from Python script and maybe use some other way. Of course, here comes the Windows Batch. There is a really nice command runas. The command takes the login credentials and path to executable program.

This works only if your user doesn’t have password. But out Mike user has password, so we couldn’t use it.

The problem is that when you start the batch script which calls runas, it will prompt you for a password. There is a parameter /savecred. Basically you enter only password the first time and it memorizes it. But in our case, the service calls the Python script and Python script calls the batch file which calls runas. But when runas prompts for a password, the service cannot enter it. So nothing happens and this also does not work.

Solution #4

Reading online, these is a really nice program called PsExec. This allows you to login to the computer (mostly used for accessing remote computer, but also works for local) as certain user and execute program.

First I tried to run it without -l parameter and nothing happened. But when I added, it still ran as SYSTEM user instead of user Mike. -l parameter actually means Run process as limited user, which explains the problem. Again, did not work for us.

Solution #5 – The working one

The working solution is really interesting and uses built in features of Windows. It’s called Task Scheduler.

Windows has builtin command called schtasks. With this command we can schedule a new task, define the frequency, manually start it and on the end even delete it.

Creating a scheduled task has few problems. First is that scheduled tasks are executed every minute (even though we can define start time /st with seconds). In our case, we need to define that task runs few seconds after we created it. But if we define it to run at 16:00:05, it will actually never run. Because all times from 16:00:00 to 16:00:59 will actually run at 16:00:00. We could add a minute to the time, or example 16:01:00, but in worse case scenario we would need to wait almost a minute for scheduled task to run. At the same time, adding minutes to time in bat script is not really easy.

Our solution actually says to run at end of the day (time actually doesn’t even matter), but then we manually execute it. There is a ping method, which is actually similar to sleep. We wait for 3 seconds for task to finish and then delete it.

In short, our code created a task to run under user Mike, manually runs the task, waits for it to finish and then deletes the task. The end result in that our program finally starts under user Mike.

But beware of the on really crazy thing. The /sc parameter defines the frequency of the task. We can define or to run task every day or week and so on. But the parameter is language dependent. So in English is ONCE, in Slovenian is ENKRAT, in German EINMAL and so on. Strange, right?

OpenVPN and TAP-Windows adapter ClientVPN not found fix

The other day I wanted to access company network, so I had to install OpenVPN. The network administrator sent me all the files (certificates and some other configuration files). I installed the certificates and ran the config file. It was actually some executable file and it opened the command prompt. It was doing something, but on the end it yield error.

Because I’m not a network or VPN expert, I had not idea what to do?

Solution

I Googled around and didn’t find any useful. I contacted the network administrator with this problem. He replied with a very simple solution. OpenVPN actually adds a new network connection. For some reason, it wasn’t named correctly. All I had to do was to rename that connection to ClientVPN and bang, it started to work.

google-http-java-client and java.lang.NumberFormatException: For input string: ” 0″ bug

I was developing a Java app to fetch a JSON data and process it. Because the the app will be running on GAE, I had to use GAE URL Fetch Java API. google-http-java-client library has this supported with UrlFetchTransport so it’s a clear signal to use it.

I wrote the simple script, tested it locally and uploaded to GAE. Tried it for the first time and it worked. Tried the second time, it failed. Tried few times more and it was failing at random interval. Full stack trace:

I had no idea what is going on. So I tried to investigate it:

1. Checked if I’m using latest versions -> Yes
2. Checked online if anyone else had same problem -> No
3. Tried to use same examples as in docs -> Same error
4. Made a request to some other servers -> It worked

The last one gave me a signal that something is wrong with the server I’m making requests to. So I made a test:

1. Make a request to some other server (which works)
2. Make request to primary server (which does not work)

I compared response headers. At first I didn’t notice it, but response from primary server was not returning Cache-Control header. Problem? I knew that primary server was using apache and mod_proxy. Main app that is returning JSON is behind a proxy server. So I had to update settings and updated the app which returns JSON to also send Cache-Control: private.

Private indicates that all or part of the response message is intended for a single user and MUST NOT be cached by a shared cache, such as a proxy server.

So the solution is actually pretty simple. Just make sure the Cache-Control: private is included in the response headers.