Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: LOGNAME not properly set on FreeBSD



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



Messages sorted by: Reverse Date, Date, Thread, Author