8

Is there a difference between using os.getlogin() and os.environ for getting the current user's username on Linux?

At different times I've seen someone recommend looking at the environment variables $USER or $LOGNAME, and other times os.getlogin() was recommended.

So I'm curious: is one preferred, or are there situations where you would use one over the other, or are they simply two ways of doing the same thing?

jpyams
  • 4,030
  • 9
  • 41
  • 66

3 Answers3

19

Update: use getpass.getuser()

getpass.getuser() conveniently searches through the various user environment variables to get the username. This avoids the issues with os.getlogin() enumerated below.

If you're worried about people modifying the environment variables, then use pwd.getpwuid(os.getuid())[0].

From the docs:

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 general, this function should be preferred over os.getlogin().

From the Python docs for os.getlogin():

For most purposes, it is more useful to use getpass.getuser() since the latter checks the environment variables LOGNAME or USERNAME to find out who the user is, and falls back to pwd.getpwuid(os.getuid())[0] to get the login name of the current real user id.

Old Answer: Problems with os.getlogin()

TL;DR

os.getlogin() can throw errors when run in certain situations. Using the LOGNAME, USER, USERNAME, etc. environment variables (after checking that they exist) is the safer option. If you're really worried about people changing the environment variables, then you can pull the username from the current process ID using pwd.getpwuid(os.getuid())[0].

Longer explaination

One issue with os.getlogin() is that you can`t run it without a controlling terminal. From the docs:

os.getlogin()

Return the name of the user logged in on the controlling terminal of the process. For most purposes, it is more useful to use the environment variables LOGNAME or USERNAME to find out who the user is, or pwd.getpwuid(os.getuid())[0] to get the login name of the current real user id.

If you try to call os.getlogin() without a controlling terminal, you will get

OSError: [Errno 25] Inappropriate ioctl for device

So using the LOGNAME, USER, USERNAME, etc. environment variables is safer than os.getlogin(). If you're really worried about people changing the environment variables, then you can use pwd.getpwuid(os.getuid())[0].

Community
  • 1
  • 1
jpyams
  • 4,030
  • 9
  • 41
  • 66
5

os.environ['USER'] can lie, with no security controls at all, os.getlogin doesn't have that problem.

If you're using the ID check for security purposes of any kind, don't rely on the environment.

Example, running as user lowpriv, checking the environment would tell you you're root when run like so in bash:

USER=root myscript.py
ShadowRanger
  • 143,180
  • 12
  • 188
  • 271
  • Should it be `USER=root python myscript.py`? – Akavall Jan 30 '18 at 19:08
  • 1
    @Akavall: If the script has the execute bit set and has a shebang line (e.g. `#!/usr/bin/env python`), you don't need to explicitly run `python`, the script shebang would handle it for you (you might need to provide a relative path if the directory containing `myscript.py` isn't in your `PATH`). I usually assume "main" Python scripts are set up with shebangs and the execute bit just for brevity, but sure, `USER=root python myscript.py` also works. – ShadowRanger Jan 30 '18 at 21:44
  • @ShadowRanger: Your answer is valid, but you should still recommend using `getpass.getuser()` or `pwd.getpwuid(os.getuid())[0]`. Regarding your answer to Akavall, it is true on UNIX/Linux, not on Windows. – Thomas Guyot-Sionnest Feb 16 '19 at 08:30
  • A normal user can always use `LD_PRELOAD` to trick an application into seeing things differently, so the point about security is a bit moot. In the end, it's what the user can do that mater, not the way it is done. – Thomas Guyot-Sionnest Feb 16 '19 at 08:37
0

I guess in UNIX based systems it really just comes down to personal preference. I'd use os.getlogin() if I plan to write the code for other platforms such as windows. Moreover, enviroment variables and easier be manipulated. so it's more secure to use it in cases where security is a priority.

valerius21
  • 423
  • 5
  • 14