>From 237ea098c82e141713964931f96a37fa6d6cda12 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 10 Jul 2017 11:56:48 -0700 Subject: [PATCH] =?UTF-8?q?getlogin:=20don=E2=80=99t=20assume=20one=20name?= =?UTF-8?q?=20per=20uid?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem reported by Wolfgang F. Muthmann (Bug#27640). * modules/getlogin-tests (Files): Add tests/test-getlogin_r.c. (ttyname): Remove test. * modules/getlogin_r-tests (ttyname): Remove test. * tests/test-getlogin.c: Replace this near-clone of test-getlogin_r.c with ‘#define TEST_LOGIN’ followed by ‘#include "test-getlogin_r.c"’. * tests/test-getlogin_r.c: If TEST_GETLOGIN is defined, test getlogin rather than getlogin_r. This avoids code duplication. (main): Use isatty and fstat rather than ttyname and stat. Use getpwnam instead of getpwuid, to be portable to test platforms that have multiple login names for the same uid. --- ChangeLog | 15 +++++++ modules/getlogin-tests | 2 +- modules/getlogin_r-tests | 1 - tests/test-getlogin.c | 112 +---------------------------------------------- tests/test-getlogin_r.c | 35 +++++++++------ 5 files changed, 39 insertions(+), 126 deletions(-) diff --git a/ChangeLog b/ChangeLog index af99a9c..e5bfb7e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2017-07-10 Paul Eggert + + getlogin: don’t assume one name per uid + Problem reported by Wolfgang F. Muthmann (Bug#27640). + * modules/getlogin-tests (Files): Add tests/test-getlogin_r.c. + (ttyname): Remove test. + * modules/getlogin_r-tests (ttyname): Remove test. + * tests/test-getlogin.c: Replace this near-clone of test-getlogin_r.c + with ‘#define TEST_LOGIN’ followed by ‘#include "test-getlogin_r.c"’. + * tests/test-getlogin_r.c: If TEST_GETLOGIN is defined, test + getlogin rather than getlogin_r. This avoids code duplication. + (main): Use isatty and fstat rather than ttyname and stat. + Use getpwnam instead of getpwuid, to be portable to test platforms + that have multiple login names for the same uid. + 2017-07-10 Tim Rühsen Bruno Haible diff --git a/modules/getlogin-tests b/modules/getlogin-tests index c8cdb05..d7d6aea 100644 --- a/modules/getlogin-tests +++ b/modules/getlogin-tests @@ -1,12 +1,12 @@ Files: tests/test-getlogin.c +tests/test-getlogin_r.c tests/signature.h tests/macros.h Depends-on: configure.ac: -AC_CHECK_FUNCS_ONCE([ttyname]) Makefile.am: TESTS += test-getlogin diff --git a/modules/getlogin_r-tests b/modules/getlogin_r-tests index 868b1b6..845658f 100644 --- a/modules/getlogin_r-tests +++ b/modules/getlogin_r-tests @@ -6,7 +6,6 @@ tests/macros.h Depends-on: configure.ac: -AC_CHECK_FUNCS_ONCE([ttyname]) Makefile.am: TESTS += test-getlogin_r diff --git a/tests/test-getlogin.c b/tests/test-getlogin.c index 86b2a9e..6a6d269 100644 --- a/tests/test-getlogin.c +++ b/tests/test-getlogin.c @@ -1,110 +1,2 @@ -/* Test of getting user name. - Copyright (C) 2010-2017 Free Software Foundation, Inc. - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . */ - -/* Written by Bruno Haible , 2010. */ - -#include - -#include - -#include "signature.h" -SIGNATURE_CHECK (getlogin, char *, (void)); - -#include -#include -#include -#include -#include -#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) -# include -#endif - -#include -#include - -#include "macros.h" - -int -main (void) -{ - char *buf; - - /* Test value. */ - buf = getlogin (); - if (buf == NULL) - { - if (errno == ENOENT) - { - /* This can happen on GNU/Linux. */ - fprintf (stderr, "Skipping test: no entry in utmp file.\n"); - return 77; - } - - /* getlogin() fails when stdin is not connected to a tty. */ - ASSERT (errno == ENOTTY - || errno == EINVAL /* seen on Linux/SPARC */ - || errno == ENXIO - ); -#if !defined __hpux /* On HP-UX 11.11 it fails anyway. */ - ASSERT (! isatty (0)); -#endif - fprintf (stderr, "Skipping test: stdin is not a tty.\n"); - return 77; - } - - /* Compare against the value from the environment. */ -#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) - /* Unix platform */ - { -# if HAVE_TTYNAME - const char *tty; - struct stat stat_buf; - struct passwd *pwd; - - tty = ttyname (STDIN_FILENO); - if (tty == NULL) - { - fprintf (stderr, "Skipping test: stdin is not a tty.\n"); - return 77; - } - - ASSERT (stat (tty, &stat_buf) == 0); - - pwd = getpwuid (stat_buf.st_uid); - if (! pwd) - { - long int uid = stat_buf.st_uid; - fprintf (stderr, "Skipping test: no name found for uid %ld\n", uid); - return 77; - } - - ASSERT (strcmp (pwd->pw_name, buf) == 0); -# endif - } -#endif -#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ - /* Native Windows platform. - Note: This test would fail on Cygwin in an ssh session, because sshd - sets USERNAME=SYSTEM. */ - { - const char *name = getenv ("USERNAME"); - if (name != NULL && name[0] != '\0') - ASSERT (strcmp (buf, name) == 0); - } -#endif - - return 0; -} +#define TEST_GETLOGIN +#include "test-getlogin_r.c" diff --git a/tests/test-getlogin_r.c b/tests/test-getlogin_r.c index f7cdc3a..0a7e105 100644 --- a/tests/test-getlogin_r.c +++ b/tests/test-getlogin_r.c @@ -21,7 +21,11 @@ #include #include "signature.h" +#ifdef TEST_GETLOGIN +SIGNATURE_CHECK (getlogin, char *, (void)); +#else SIGNATURE_CHECK (getlogin_r, int, (char *, size_t)); +#endif #include #include @@ -40,11 +44,17 @@ SIGNATURE_CHECK (getlogin_r, int, (char *, size_t)); int main (void) { + /* Test value. */ +#ifdef TEST_GETLOGIN + char *buf = getlogin (); + int err = buf ? 0 : errno; + ASSERT (buf || err); +#else /* Test with a large enough buffer. */ char buf[1024]; - int err; + int err = getlogin_r (buf, sizeof buf); +#endif - err = getlogin_r (buf, sizeof (buf)); if (err != 0) { if (err == ENOENT) @@ -54,7 +64,7 @@ main (void) return 77; } - /* getlogin_r() fails when stdin is not connected to a tty. */ + /* It fails when stdin is not connected to a tty. */ ASSERT (err == ENOTTY || err == EINVAL /* seen on Linux/SPARC */ || err == ENXIO @@ -70,30 +80,25 @@ main (void) #if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__) /* Unix platform */ { -# if HAVE_TTYNAME - const char *tty; struct stat stat_buf; struct passwd *pwd; - tty = ttyname (STDIN_FILENO); - if (tty == NULL) + if (!isatty (STDIN_FILENO)) { fprintf (stderr, "Skipping test: stdin is not a tty.\n"); return 77; } - ASSERT (stat (tty, &stat_buf) == 0); + ASSERT (fstat (STDIN_FILENO, &stat_buf) == 0); - pwd = getpwuid (stat_buf.st_uid); + pwd = getpwnam (buf); if (! pwd) { - fprintf (stderr, "Skipping test: no name found for uid %d\n", - stat_buf.st_uid); - return 77; + fprintf (stderr, "Skipping test: %s: no such user\n", buf); + return 77; } - ASSERT (strcmp (pwd->pw_name, buf) == 0); -# endif + ASSERT (pwd->pw_uid == stat_buf.st_uid); } #endif #if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__ @@ -107,6 +112,7 @@ main (void) } #endif +#ifndef TEST_GETLOGIN /* Test with a small buffer. */ { char smallbuf[1024]; @@ -130,6 +136,7 @@ main (void) ASSERT (getlogin_r (hugebuf, sizeof (hugebuf)) == 0); ASSERT (strcmp (hugebuf, buf) == 0); } +#endif return 0; } -- 2.9.4