Search code examples
javapythontomcatdebianexec

Why is Runtime.getRuntime().exec forking a process as root in Tomcat?


I am using Runtime.getRuntime().exec(...) to execute a python script from within a Tomcat webapp. Everything goes fine when I am in my development environment (Eclipse running my local Tomcat (located at /home/me/opt/tomcat) through the Sysdeo-Plugin). The issue occurs when I run my webapp in the production environment (= Debian Squeeze).

I am using tomcat6 from the official debian packages. It is started automatically through /etc/init.d using the user "tomcat6" (verified with "ps aux | grep tomcat6"). I am executing my simple python script:

Process p = Runtime.getRuntime().exec("python /home/me/exec-test.py")
p.waitFor();
//read the stdout and stderr

The python script is straightforward:

#!/usr/bin/python
import sys, os, getpass

def main(argv):
    print "Working dir: " +os.getcwd()
    userShell = os.environ.get('SHELL')
    print "$SHELL set to: " +userShell
    print "Executing as user: "+getpass.getuser()

if __name__ == "__main__":
    main(sys.argv[1:])

The output if running tomcat from eclipse is:

Working dir: /home/me/opt/tomcat
$SHELL set to: /bin/bash
Executing as user: me

When running using the tomcat6 from debian packages:

Working dir: /var/lib/tomcat6
$SHELL set to: /bin/bash
Executing as user: root

Why is the forked execution of the python script run as "root"? Shouldn't it be the same user which is owning the tomcat6 process (= running the JVM)? Am I missing something or perhaps the python call to get the process' user is not correct?

I have also tried using Apache Commons Exec with the same results.

The consequence is, that when I use a more complex python script which calls a local application (/usr/local/bin/local-app), it fails in the production environment. It is somehow not able to access local-app. Again, everything works fine in my development environment. Is this related to my observations?


Solution

  • getpass.getuser() first looks at the environment variables 'LOGNAME', 'USER', 'LNAME', 'USERNAME' (in that order) before trying anything else, maybe one of then is set incorrectly.

    Try using os.getuid() or pwd.getpwuid(os.getuid()) - that should give you another result.

    I find it highly improbable that the process somehow gained root privileges.