Green Python

2 days ago I had a strange issue with Python getpass and Supervisor. Despite being ran with an unpriviledged user, getpass.getuser() always returned root, which was not what I expected.

My Supervisor configuration file launches the process with the system user fred, and sets the USER environment variable to fred as well. The problem comes from the order getpass.getuser() queries the environment variables to get the current user:

This function checks the environment variables LOGNAME, USER, LNAME and USERNAME, in order, and returns the value of the first one which is set to a non-empty string. If none are set, the login name from the password database is returned on systems which support the pwd module, otherwise, an exception is raised.

In my application, printing those variables gave LOGNAME: root, USER: fred, LNAME: None, USERNAME: Fred. Unless the variable is set in the process configuration file, it takes the environment variables already set for the user running Supervisor.

I was expecting getpass.getuser() to query the password database first, but this one is UNIX only. To avoid being forced to init all the environment variables getpass.getuser() is expecting, I’m now using the following code instead. Note the dirty hack to ensure portability.

try:
    import pwd
except ImportError:
    import winpwd as pwd
import os

user = pwd.getpwuid(os.getuid()).pw_name

This is less convenient than:

import getpass

user = getpass.getuser()

But at least, I have no more surprises because of environment variables.

Perry the Platypus wants you to subscribe now! Even if you don't visit my site on a regular basis, you can get the latest posts delivered to you for free via Email: