On Wed, Apr 02, 2014 at 04:54:13PM -0400, Phil Pennock wrote:
On 2014-04-01 at 19:50 -0500, Erik Johnson wrote:The whole point of "su -" (and "su -l", which are equivalent), is to make the session a login session.Then it's su's responsibility to clear/reset/set environment variables associated with the login. In fact, SUSv4 is pretty clear on this: ----------------------------8< cut here >8------------------------------ LOGNAME The system shall initialize this variable at the time of login to be the user's login name. See <pwd.h> . For a value of LOGNAME to be portable across implementations of POSIX.1-2008, the value should be composed of characters from the portable filename character set. ----------------------------8< cut here >8------------------------------ Note "at the time of login". The fact that zsh will fix up a _missing_ LOGNAME variable is a shell convenience, for a broken system which didn't do what it should have done at login time. So either su is leaving LOGNAME set across the security boundary, or libc's getlogin() continues to report the old value after the su. In another sub-thread, you perform a bunch of tests with python2's getpass.getuser() function, but please note that this function preferentially uses environment variables and doesn't report which variable it sourced from, so is problematic for tracing the source of a problem. That function will try, in turn: LOGNAME USER LNAME USERNAME; after that, it uses a passwd lookup of the current uid, _not_ getlogin(). Thus the evidence purporting to show that it "just works" in other shells isn't actually showing that. Running >> env - bash --login << I see that I have a login shell and that LOGNAME is not set, thus bash is not performing any such fixup and if you see correct values in your tests, what you're seeing is likely Python's getpass.getuser() reaching the pwd.getpwuid(os.getuid())[0] step.
Good point: erik@virtubsd:~% sudo chpass -s /bin/csh root Password: chpass: user information updated erik@virtubsd:~% su - Password: virtubsd# echo $LOGNAME root virtubsd# logout erik@virtubsd:~% sudo chpass -s /bin/tcsh root chpass: user information updated erik@virtubsd:~% su - Password: virtubsd# echo $LOGNAME root virtubsd# logout erik@virtubsd:~% sudo chpass -s /usr/local/bin/bash root chpass: user information updated erik@virtubsd:~% su - Password: [root@virtubsd ~]# echo $LOGNAME [root@virtubsd ~]# logout erik@virtubsd:~% sudo chpass -s /usr/local/bin/ksh93 root chpass: user information updated erik@virtubsd:~% su - Password: # echo $LOGNAME # ^D erik@virtubsd:~% sudo chpass -s /usr/local/bin/zsh root chpass: user information updated erik@virtubsd:~% su - Password: virtubsd# echo $LOGNAME erik virtubsd#
So yes, in such a scenario you'll get a different result from zsh which fixes up the missing LOGNAME from the libc getlogin(), thus returns whatever the OS's concept of "the user's login name" is. -Phil
-- -Erik "For me, it is far better to grasp the universe as it really is than to persist in delusion, however satisfying and reassuring." --Carl Sagan
Attachment:
pgpDOG3sc1dnq.pgp
Description: PGP signature