This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: redesign Windows os.getlogin, and add os.getuser
Type: enhancement Stage: resolved
Components: Library (Lib), Windows Versions: Python 3.8
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: Nosy List: eryksun, paul.moore, steve.dower, tim.golden, zach.ware
Priority: normal Keywords:

Created on 2018-01-26 01:17 by eryksun, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (1)
msg310724 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2018-01-26 01:17
os.getlogin() is supposed to return the name of the user logged in on the "controlling terminal" of the process. Windows doesn't have POSIX terminals; however, every process does belong to a terminal/desktop session that can be connected either to the physical console or a remote desktop. A standard user can call WTSQuerySessionInformation (an RPC to the Local Session Manager) to get the user name (i.e. WTSUserName) for the current session. ISTM that this is the closest analog to POSIX getlogin() that exists in Windows.

A caveat is that session 0 ("services") is never connected to the physical console. Thus there's no associated user account name.

os.getlogin() currently calls GetUserName (an RPC to the Local Security Authority), which returns the user name from the caller's effective token. If os.getlogin() is changed to return the session user, posixmodule.c could still wrap GetUserName privately as nt._getusername(). 

If the calling thread is impersonating, nt._getusername should temporarily revert to the process token (i.e. the real user), since this will usually be consistent with USERNAME. That said, getting the effective user can be useful for logging, so there should also be an option to return the effective user instead of the real user.

Note that the user name of the SYSTEM logon (and thus the USERNAME environment variable in a SYSTEM process) is actually "%COMPUTERNAME%$". It's noteworthy that GetUserName instead returns "SYSTEM" for this case. The "NETWORK SERVICE" logon also uses "%COMPUTERNAME%$", but in this case GetUserName returns "%COMPUTERNAME%$" instead of "NETWORK SERVICE".

A pair of high-level Python functions named getuser() and geteuser() could be added in os.py. These functions would return the real and effective user name of the caller, respectively. In Windows, os.getuser() would return the USERNAME environment variable and otherwise fall back on nt._getusername(). In POSIX, it would return the value of the first defined variable among LOGNAME, USER, and LNAME, and otherwise fall back on pwd.getpwuid(os.getuid()).pw_name. In Windows, os.geteuser() would return nt_getusername(effective=True). In POSIX it would return pwd.getpwuid(os.geteuid()).pw_name.

Currently getpass.getuser() always looks for environment variables named LOGNAME, USER, LNAME, and finally USERNAME. This is an odd choice on Windows. I wouldn't expect Windows users to know about and respect the special status of the first 3 variable names. getpass.getuser() also falls back on using the pwd module, which is another odd choice on Windows. It isn't worth removing or modifying this function, but the docs could encourage using the proposed os.getuser() and os.geteuser() functions on Windows and new code.
History
Date User Action Args
2022-04-11 14:58:57adminsetgithub: 76852
2021-03-30 19:08:31eryksunsetstatus: open -> closed
resolution: rejected
stage: test needed -> resolved
2018-01-26 01:17:24eryksuncreate