Do a better job at determining the username of the login session.

When multiple users share the same UID, the old code will simply pick an
arbitrary username to attach to the utmpx entries. Make the code a bit
more accurate by first checking whether getlogin() returns a username
which corresponds to the uid of the calling process. If this fails,
simply fall back to picking an arbitrary username.

Reported by:	saurik on GitHub
MFC after:	2 weeks
This commit is contained in:
Ed Schouten 2012-04-19 21:12:08 +00:00
parent 52116a1cb9
commit 1d2276c873
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=234469

View file

@ -46,6 +46,28 @@ __FBSDID("$FreeBSD$");
* username. It does allow users to log arbitrary hostnames.
*/
static const char *
get_username(void)
{
const struct passwd *pw;
const char *login;
uid_t uid;
/*
* Attempt to determine the username corresponding to this login
* session. First, validate the results of getlogin() against
* the password database. If getlogin() returns invalid data,
* return an arbitrary username corresponding to this uid.
*/
uid = getuid();
if ((login = getlogin()) != NULL && (pw = getpwnam(login)) != NULL &&
pw->pw_uid == uid)
return (login);
if ((pw = getpwuid(uid)) != NULL)
return (pw->pw_name);
return (NULL);
}
int
main(int argc, char *argv[])
{
@ -57,7 +79,7 @@ main(int argc, char *argv[])
if ((argc == 2 || argc == 3) && strcmp(argv[1], "login") == 0) {
/* Username. */
user = user_from_uid(getuid(), 1);
user = get_username();
if (user == NULL)
return (EX_OSERR);