From deb76fe23dcf27a67ec00295494c7c4728e3b110 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Tue, 9 Jun 2009 00:56:36 +0200 Subject: [PATCH] Tests for module 'idpriv-drop'. --- ChangeLog | 6 ++ modules/idpriv-drop-tests | 19 +++++ tests/test-idpriv-drop.c | 163 +++++++++++++++++++++++++++++++++++++++++++ tests/test-idpriv-drop.sh | 33 +++++++++ tests/test-idpriv-drop.su.sh | 52 ++++++++++++++ 5 files changed, 273 insertions(+) create mode 100644 modules/idpriv-drop-tests create mode 100644 tests/test-idpriv-drop.c create mode 100755 tests/test-idpriv-drop.sh create mode 100755 tests/test-idpriv-drop.su.sh diff --git a/ChangeLog b/ChangeLog index 88cb906e8..efb3a7782 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2009-06-08 Bruno Haible + Tests for module 'idpriv-drop'. + * modules/idpriv-drop-tests: New file. + * tests/test-idpriv-drop.sh: New file. + * tests/test-idpriv-drop.su.sh: New file. + * tests/test-idpriv-drop.c: New file. + New module 'idpriv-drop'. * lib/idpriv.h: New file. * lib-idpriv-drop.c: New file. diff --git a/modules/idpriv-drop-tests b/modules/idpriv-drop-tests new file mode 100644 index 000000000..2a9c99900 --- /dev/null +++ b/modules/idpriv-drop-tests @@ -0,0 +1,19 @@ +Notice: +The 'idpriv-drop-tests' module asks the user for the root password. It is +therefore not suitable for all environments. To disable it, pass option +'--avoid=idpriv-drop-tests' to gnulib-tool. + +Files: +tests/test-idpriv-drop.sh +tests/test-idpriv-drop.su.sh +tests/test-idpriv-drop.c + +Depends-on: +stdbool + +configure.ac: + +Makefile.am: +TESTS += test-idpriv-drop.sh +TESTS_ENVIRONMENT += EXEEXT='@EXEEXT@' srcdir='$(srcdir)' +check_PROGRAMS += test-idpriv-drop diff --git a/tests/test-idpriv-drop.c b/tests/test-idpriv-drop.c new file mode 100644 index 000000000..0da443fc3 --- /dev/null +++ b/tests/test-idpriv-drop.c @@ -0,0 +1,163 @@ +/* Test of dropping uid/gid privileges of the current process permanently. + Copyright (C) 2009 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 . */ + +#include + +#include "idpriv.h" + +#include +#include +#include +#include +#include + +#define ASSERT(expr) \ + do \ + { \ + if (!(expr)) \ + { \ + fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \ + fflush (stderr); \ + abort (); \ + } \ + } \ + while (0) + +static void +show_uids () +{ +#if HAVE_GETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */ + uid_t real; + uid_t effective; + uid_t saved; + ASSERT (getresuid (&real, &effective, &saved) >= 0); + printf ("uids: real=%d effective=%d saved=%d", + (int) real, (int) effective, (int) saved); +#elif HAVE_GETEUID + printf ("uids: real=%d effective=%d", + (int) getuid (), (int) geteuid()); +#elif HAVE_GETUID + printf ("uids: real=%d", + (int) getuid ()); +#endif +} + +static void +show_gids () +{ +#if HAVE_GETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */ + gid_t real; + gid_t effective; + gid_t saved; + ASSERT (getresgid (&real, &effective, &saved) >= 0); + printf ("gids: real=%d effective=%d saved=%d", + (int) real, (int) effective, (int) saved); +#elif HAVE_GETEGID + printf ("gids: real=%d effective=%d", + (int) getgid (), (int) getegid()); +#elif HAVE_GETGID + printf ("gids: real=%d", + (int) getgid ()); +#endif +} + +static void +show (const char *prefix) +{ + printf ("%s ", prefix); + show_uids (); + printf (" "); + show_gids (); + printf ("\n"); +} + +int +main (int argc, char *argv[]) +{ + bool verbose = false; + int i; + +#if HAVE_GETUID + int uid = getuid (); +#endif +#if HAVE_GETGID + int gid = getgid (); +#endif + + /* Parse arguments. + -v enables verbose output. + */ + for (i = 1; i < argc; i++) + { + const char *arg = argv[i]; + if (strcmp (arg, "-v") == 0) + verbose = true; + } + + if (verbose) + show ("before drop:"); + + ASSERT (idpriv_drop () == 0); + + if (verbose) + show ("after drop: "); + + /* Verify that the privileges have really been dropped. */ +#if HAVE_GETRESUID /* glibc, FreeBSD, OpenBSD, HP-UX */ + { + uid_t real; + uid_t effective; + uid_t saved; + if (getresuid (&real, &effective, &saved) < 0 + || real != uid + || effective != uid + || saved != uid) + abort (); + } +#else +# if HAVE_GETEUID + if (geteuid () != uid) + abort (); +# endif +# if HAVE_GETUID + if (getuid () != uid) + abort (); +# endif +#endif +#if HAVE_GETRESGID /* glibc, FreeBSD, OpenBSD, HP-UX */ + { + gid_t real; + gid_t effective; + gid_t saved; + if (getresgid (&real, &effective, &saved) < 0 + || real != gid + || effective != gid + || saved != gid) + abort (); + } +#else +# if HAVE_GETEGID + if (getegid () != gid) + abort (); +# endif +# if HAVE_GETGID + if (getgid () != gid) + abort (); +# endif +#endif + + return 0; +} diff --git a/tests/test-idpriv-drop.sh b/tests/test-idpriv-drop.sh new file mode 100755 index 000000000..c5689b16b --- /dev/null +++ b/tests/test-idpriv-drop.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +# A POSIX compliant 'id' program. +if test -f /usr/xpg4/bin/id; then + ID=/usr/xpg4/bin/id +else + ID=id +fi + +# The user's original uid and gid. +uid=`$ID -u` +gid=`$ID -g` + +if test `$ID -u` = 0; then + # No need to ask for a password. + "${srcdir}/test-idpriv-drop.su.sh" "$uid" "$gid" +else + echo "Need root privileges for the 'test-idpriv-drop' test. Deny if you don't trust." > /dev/tty + if (type sudo) > /dev/null 2>&1; then + # Use the 'sudo' program. + sudo "${srcdir}/test-idpriv-drop.su.sh" "$uid" "$gid" + else + # Use the 'su' program. + su root -c "${srcdir}/test-idpriv-drop.su.sh \"$uid\" \"$gid\"" + fi + result=$? + case $result in + 0) exit 0;; + 77) exit 77;; + 13) exit 1;; + *) echo "Skipping test: root privileges not granted"; exit 77;; + esac +fi diff --git a/tests/test-idpriv-drop.su.sh b/tests/test-idpriv-drop.su.sh new file mode 100755 index 000000000..5dadc24a1 --- /dev/null +++ b/tests/test-idpriv-drop.su.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# This script must be run as superuser. + +origuid=$1 +origgid=$2 + +# A POSIX compliant 'id' program. +if test -f /usr/xpg4/bin/id; then + ID=/usr/xpg4/bin/id +else + ID=id +fi + +if test `$ID -u` != 0; then + echo "Skipping test: not superuser" + exit 77 +fi + +./test-idpriv-drop${EXEEXT} || exit 13 # normal + +chown root:root test-idpriv-drop${EXEEXT} 2>/dev/null || \ +chown root:wheel test-idpriv-drop${EXEEXT} 2>/dev/null || \ + { echo "Skipping test: root privilege not sufficient on this file system" + exit 77 + } +chmod 4755 test-idpriv-drop${EXEEXT} +./test-idpriv-drop${EXEEXT} || exit 13 # setuid root +chmod 2755 test-idpriv-drop${EXEEXT} +./test-idpriv-drop${EXEEXT} || exit 13 # setgid root +chmod 6755 test-idpriv-drop${EXEEXT} +./test-idpriv-drop${EXEEXT} || exit 13 # setuid and setgid root + +if chown nobody test-idpriv-drop${EXEEXT} 2>/dev/null; then + chmod 4755 test-idpriv-droptemp${EXEEXT} + ./test-idpriv-droptemp${EXEEXT} || exit 13 # setuid nobody + chmod 2755 test-idpriv-droptemp${EXEEXT} + ./test-idpriv-droptemp${EXEEXT} || exit 13 # setgid root + chmod 6755 test-idpriv-droptemp${EXEEXT} + ./test-idpriv-droptemp${EXEEXT} || exit 13 # setuid nobody and setgid root +fi + +if chown root:nobody test-idpriv-drop${EXEEXT} 2>/dev/null; then + chmod 4755 test-idpriv-drop${EXEEXT} + ./test-idpriv-drop${EXEEXT} || exit 13 # setuid root + chmod 2755 test-idpriv-drop${EXEEXT} + ./test-idpriv-drop${EXEEXT} || exit 13 # setgid nobody + chmod 6755 test-idpriv-drop${EXEEXT} + ./test-idpriv-drop${EXEEXT} || exit 13 # setuid root and setgid nobody +fi + +chown "$origuid:$origgid" test-idpriv-drop${EXEEXT} +chmod 755 test-idpriv-drop${EXEEXT} -- 2.11.0