Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Mar 2017 16:14:21 -0700
From:      Conrad Meyer <cem@freebsd.org>
To:        Chris Sinjakli <chris@sinjakli.co.uk>
Cc:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Subject:   Re: A historical curiosity in su(1)
Message-ID:  <CAG6CVpUM05yoZa=dQLp1R2D6sbcBHDo2ggkX8MM0p%2BN6EaySmA@mail.gmail.com>
In-Reply-To: <CAN-H%2BybmipbPq59HGVsfouS_8v-ezDbU%2B4PKtiTwj3tv-LjOyw@mail.gmail.com>
References:  <CAN-H%2BybmipbPq59HGVsfouS_8v-ezDbU%2B4PKtiTwj3tv-LjOyw@mail.gmail.com>

next in thread | previous in thread | raw e-mail | index | archive | help
Hi Chris,

You might be interested in FreeBSD's copy of the CSRG repository.[0]
Some of this logic was changed by karels@ in "r45520"[1] (of course it
wasn't Subversion at the time).  The previous change[2] message
includes "use new getlogin()."  Prior to that change, su did not use
getlogin/getpwnam.

The "BUGS" section of the getlogin(2) manual page says:

     In earlier versions of the system, getlogin() failed unless the process
     was associated with a login terminal.  The current implementation (using
     setlogin()) allows getlogin to succeed even when the process has no con-
     trolling terminal. In earlier versions of the system, the value returned
     by getlogin() could not be trusted without checking the user ID.  Porta-
     ble programs should probably still make this check.

That might explain it?

Best,
Conrad

[0]: https://svnweb.freebsd.org/csrg/usr.bin/su/su.c?view=annotate
[1]: https://svnweb.freebsd.org/csrg?view=revision&revision=45520
[2]: https://svnweb.freebsd.org/csrg?view=revision&revision=45127

On Tue, Mar 21, 2017 at 3:57 PM, Chris Sinjakli <chris@sinjakli.co.uk> wrote:
> Hi folks,
>
> I'm doing some digging for a talk I'm working on for PGConf US[1].
>
> The talk is one I've given before[2], and last time I gave it I left an open
> question right near the end. This time, I'd love to be able to answer it!
>
> As a heads-up, this is a behaviour I encountered through Ubuntu, but the code
> involved is present in a very similar form in FreeBSD, and probably originated
> here or in a shared ancestor (the trail goes cold at a 1994 import from BSD
> 4.4).
>
> The open question revolves around the way su(1) determines the user it is being
> invoked by. Specifically, it does this using a combination of the result of
> getuid and getlogin[3][4].
>
> If calling getpwnam on the result of getlogin returns a passwd struct, and the
> uid in that struct matches the uid returned by getuid, it returns that passwd
> struct.
>
> If the getpwnam approach fails for either reason, it falls back to using the
> result of getpwuid on the result of getuid.
>
> The thing I'm curious about is why it goes to the trouble of trying to use the
> result of getpwnam/getlogin at all. The only time it will return something
> different from getpwuid/getuid is if there are two users with the same uid but
> different information in the rest of their passwd entry.
>
> Are there cases where you might want to set up a system this way? I've always
> avoided assigning the same uid to multiple users - it seems like a bad idea!
>
> Jumping back to the point I made in the talk, the result of getlogin can often
> be surprising. For example, a daemon restarted by a supervisor (e.g. upstart)
> will be associated with the user that issued the restart (i.e. getlogin would
> return "chris" if I restarted it, rather than something like "daemon-user"). Any
> daemon that calls su will run into this behaviour.
>
> If, as we do at my current employer, you store your human users in LDAP and your
> system users locally, that means a network round-trip every time su is called,
> just because a human happened to restart a daemon!
>
> For what it's worth, this isn't new behaviour. You can find extremely similar
> code in FreeBSD's su implementation, and it's been there since at least 1994[5],
> with something similar existing in the current code[6].
>
> It seems likely to me that all of this behaviour needs to be preserved because
> somewhere out there, something will depend on it in a strange way. That said, if
> someone knows why it behaves like this, I'd be really interested to know, and to
> share the answer as part of my talk!
>
> Many thanks for reading this, and entertaining a historical itch.
>
> Chris
>
>
> [1]: http://www.pgconf.us/conferences/2017
>
> [2]: https://www.youtube.com/watch?v=Tu-cf-Jki60
>
> [3]:
> https://github.com/shadow-maint/shadow/blob/db57db52cfd99069c33604eb4a0fee56eb659133/src/su.c#L731
>
> [4]:
> https://github.com/shadow-maint/shadow/blob/db57db52cfd99069c33604eb4a0fee56eb659133/libmisc/myname.c#L44
>
> [5]:
> https://github.com/freebsd/freebsd/blob/f9ab90d9d6d02989a075d0f0074496d5b1045e4b/usr.bin/su/su.c#L125
>
> [6]:
> https://github.com/freebsd/freebsd/blob/d8179bc9ec98d230e00546e4afa2a244e2f123ed/usr.bin/su/su.c#L255
> _______________________________________________
> freebsd-hackers@freebsd.org mailing list
> https://lists.freebsd.org/mailman/listinfo/freebsd-hackers
> To unsubscribe, send any mail to "freebsd-hackers-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAG6CVpUM05yoZa=dQLp1R2D6sbcBHDo2ggkX8MM0p%2BN6EaySmA>