coreutils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] tests: use chroot --user rather than internal setuidgid tool


From: Pádraig Brady
Subject: [PATCH] tests: use chroot --user rather than internal setuidgid tool
Date: Mon, 19 May 2014 18:31:03 +0100

* init.cfg (require_root_): Adjust to use chroot, and make
`require_built_ chroot` implicit when chroot used in the test.
* po/POTFILES.in: Remove reference to setuidgid tool.
* src/.gitignore: Likewise.
* src/local.mk: Likewise.
* src/setuidgid.c: Remove.
* tests/cp/preserve-gid.sh: s/setuidgid/chroot --user/.
* tests/cp/special-bits.sh: Likewise.
* tests/id/setgid.sh: Likewise.
* tests/misc/truncate-owned-by-other.sh
* tests/mv/sticky-to-xpart.sh: Likewise.
* tests/rm/fail-2eperm.sh: Likewise.
* tests/rm/no-give-up.sh: Likewise.
* tests/touch/now-owned-by-other.sh: Likewise.
* tests/misc/chroot-fail.sh: Skip if chroot not built.
---
 init.cfg                              |   14 ++-
 po/POTFILES.in                        |    1 -
 src/.gitignore                        |    1 -
 src/local.mk                          |    4 +-
 src/setuidgid.c                       |  215 ---------------------------------
 tests/cp/preserve-gid.sh              |    5 +-
 tests/cp/special-bits.sh              |    2 +-
 tests/id/setgid.sh                    |    3 +-
 tests/misc/chroot-fail.sh             |    1 +
 tests/misc/truncate-owned-by-other.sh |    3 +-
 tests/mv/sticky-to-xpart.sh           |    4 +-
 tests/rm/fail-2eperm.sh               |    4 +-
 tests/rm/no-give-up.sh                |    3 +-
 tests/touch/now-owned-by-other.sh     |    3 +-
 14 files changed, 26 insertions(+), 237 deletions(-)
 delete mode 100644 src/setuidgid.c

diff --git a/init.cfg b/init.cfg
index bf1887f..e225bd6 100644
--- a/init.cfg
+++ b/init.cfg
@@ -393,12 +393,14 @@ or use the shortcut target of the toplevel Makefile,
   fi
 }
 
-# Test whether we can run our just-built rm setuidgid-to-root,
+# Test whether we can run our just-built root owned rm,
 # i.e., that $NON_ROOT_USERNAME has access to the build directory.
-setuidgid_has_perm_()
+nonroot_has_perm_()
 {
+  require_built_ chroot
+
   local rm_version=$(
-    setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm --version |
+    chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm --version |
     sed -n '1s/.* //p'
   )
   case ":$rm_version:" in
@@ -413,10 +415,10 @@ require_root_()
   NON_ROOT_USERNAME=${NON_ROOT_USERNAME=nobody}
   NON_ROOT_GROUP=${NON_ROOT_GROUP=$(id -g $NON_ROOT_USERNAME)}
 
-  # When the current test invokes setuidgid, call setuidgid_has_perm_
+  # When the current test invokes chroot, call nonroot_has_perm_
   # to check for a common problem.
-  grep '^[ ]*setuidgid' "../$0" \
-    && { setuidgid_has_perm_ \
+  grep '^[ ]*chroot' "../$0" \
+    && { nonroot_has_perm_ \
            || skip_ "user $NON_ROOT_USERNAME lacks execute permissions"; }
 }
 
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 54386a9..07bbdd8 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -108,7 +108,6 @@ src/rmdir.c
 src/runcon.c
 src/selinux.c
 src/seq.c
-src/setuidgid.c
 src/shred.c
 src/shuf.c
 src/sleep.c
diff --git a/src/.gitignore b/src/.gitignore
index 25573df..e273bb8 100644
--- a/src/.gitignore
+++ b/src/.gitignore
@@ -75,7 +75,6 @@ rm
 rmdir
 runcon
 seq
-setuidgid
 sha1sum
 sha224sum
 sha256sum
diff --git a/src/local.mk b/src/local.mk
index 40798d6..1d7abf6 100644
--- a/src/local.mk
+++ b/src/local.mk
@@ -37,8 +37,7 @@ pkglibexec_PROGRAMS = @pkglibexec_PROGRAMS@
 # Needed by the testsuite.
 noinst_PROGRAMS =              \
   src/getlimits                        \
-  src/make-prime-list          \
-  src/setuidgid
+  src/make-prime-list
 
 noinst_HEADERS =               \
   src/chown-core.h             \
@@ -166,7 +165,6 @@ src_rm_LDADD = $(LDADD)
 src_rmdir_LDADD = $(LDADD)
 src_runcon_LDADD = $(LDADD)
 src_seq_LDADD = $(LDADD)
-src_setuidgid_LDADD = $(LDADD)
 src_sha1sum_LDADD = $(LDADD)
 src_sha224sum_LDADD = $(LDADD)
 src_sha256sum_LDADD = $(LDADD)
diff --git a/src/setuidgid.c b/src/setuidgid.c
deleted file mode 100644
index 9aadb7f..0000000
--- a/src/setuidgid.c
+++ /dev/null
@@ -1,215 +0,0 @@
-/* setuidgid - run a command with the UID and GID of a specified user
-   Copyright (C) 2003-2014 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 <http://www.gnu.org/licenses/>.  */
-
-/* Written by Jim Meyering  */
-
-#include <config.h>
-#include <getopt.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <pwd.h>
-#include <grp.h>
-
-#include "system.h"
-
-#include "error.h"
-#include "long-options.h"
-#include "mgetgroups.h"
-#include "quote.h"
-#include "xstrtol.h"
-
-#define PROGRAM_NAME "setuidgid"
-
-/* I wrote this program from scratch, based on the description of
-   D.J. Bernstein's program: http://cr.yp.to/daemontools/setuidgid.html.  */
-#define AUTHORS proper_name ("Jim Meyering")
-
-#define SETUIDGID_FAILURE 111
-
-void
-usage (int status)
-{
-  if (status != EXIT_SUCCESS)
-    emit_try_help ();
-  else
-    {
-      printf (_("\
-Usage: %s [SHORT-OPTION]... USER COMMAND [ARGUMENT]...\n\
-  or:  %s LONG-OPTION\n\
-"),
-              program_name, program_name);
-
-      fputs (_("\
-Drop any supplemental groups, assume the user-ID and group-ID of the specified\
-\n\
-USER (numeric ID or user name), and run COMMAND with any specified 
ARGUMENTs.\n\
-Exit with status 111 if unable to assume the required user and group ID.\n\
-Otherwise, exit with the exit status of COMMAND.\n\
-This program is useful only when run by root (user ID zero).\n\
-\n\
-"), stdout);
-      fputs (_("\
-  -g GID[,GID1...]  also set the primary group-ID to the numeric GID, and\n\
-                      (if specified) supplemental group IDs to GID1, ...\n\
-"), stdout);
-      fputs (HELP_OPTION_DESCRIPTION, stdout);
-      fputs (VERSION_OPTION_DESCRIPTION, stdout);
-      emit_ancillary_info ();
-    }
-  exit (status);
-}
-
-int
-main (int argc, char **argv)
-{
-  uid_t uid;
-  GETGROUPS_T *gids = NULL;
-  size_t n_gids = 0;
-  size_t n_gids_allocated = 0;
-  gid_t primary_gid;
-
-  initialize_main (&argc, &argv);
-  set_program_name (argv[0]);
-  setlocale (LC_ALL, "");
-  bindtextdomain (PACKAGE, LOCALEDIR);
-  textdomain (PACKAGE);
-
-  initialize_exit_failure (SETUIDGID_FAILURE);
-  atexit (close_stdout);
-
-  parse_long_options (argc, argv, PROGRAM_NAME, PACKAGE_NAME, Version,
-                      usage, AUTHORS, (char const *) NULL);
-  {
-    int c;
-    while ((c = getopt_long (argc, argv, "+g:", NULL, NULL)) != -1)
-      {
-        switch (c)
-          {
-            case 'g':
-              {
-                unsigned long int tmp_ul;
-                char *gr = optarg;
-                char *ptr;
-                while (true)
-                  {
-                    if (! (xstrtoul (gr, &ptr, 10, &tmp_ul, NULL) == LONGINT_OK
-                           && tmp_ul <= GID_T_MAX))
-                      error (SETUIDGID_FAILURE, 0, _("invalid group %s"),
-                             quote (gr));
-                    if (n_gids == n_gids_allocated)
-                      gids = X2NREALLOC (gids, &n_gids_allocated);
-                    gids[n_gids++] = tmp_ul;
-
-                    if (*ptr == '\0')
-                      break;
-                    if (*ptr != ',')
-                      {
-                        error (0, 0, _("invalid group %s"), quote (gr));
-                        usage (SETUIDGID_FAILURE);
-                      }
-                    gr = ptr + 1;
-                  }
-                break;
-              }
-
-            default:
-              usage (SETUIDGID_FAILURE);
-          }
-      }
-  }
-
-  if (argc <= optind + 1)
-    {
-      if (argc < optind + 1)
-        error (0, 0, _("missing operand"));
-      else
-        error (0, 0, _("missing operand after %s"), quote (argv[optind]));
-      usage (SETUIDGID_FAILURE);
-    }
-
-  {
-    const struct passwd *pwd;
-    unsigned long int tmp_ul;
-    char *user = argv[optind];
-    char *ptr;
-    bool have_uid = false;
-
-    if (xstrtoul (user, &ptr, 10, &tmp_ul, "") == LONGINT_OK
-        && tmp_ul <= UID_T_MAX)
-      {
-        uid = tmp_ul;
-        have_uid = true;
-      }
-
-    if (!have_uid)
-      {
-        pwd = getpwnam (user);
-        if (pwd == NULL)
-          {
-            error (0, errno, _("unknown user-ID: %s"), quote (user));
-            usage (SETUIDGID_FAILURE);
-          }
-        uid = pwd->pw_uid;
-      }
-    else if (n_gids == 0)
-      {
-        pwd = getpwuid (uid);
-        if (pwd == NULL)
-          {
-            error (0, errno,
-                   _("to use user-ID %s you need to use -g too"), quote 
(user));
-            usage (SETUIDGID_FAILURE);
-          }
-      }
-
-#if HAVE_SETGROUPS
-    if (n_gids == 0)
-      {
-        int n = xgetgroups (pwd->pw_name, pwd->pw_gid, &gids);
-        if (n <= 0)
-          error (SETUIDGID_FAILURE, errno,
-                 _("failed to get groups for user %s"), quote (pwd->pw_name));
-        n_gids = n;
-      }
-
-    if (setgroups (n_gids, gids))
-      error (SETUIDGID_FAILURE, errno,
-             _("failed to set supplemental group(s)"));
-
-    primary_gid = gids[0];
-#else
-    primary_gid = pwd->pw_gid;
-#endif
-  }
-
-  if (setgid (primary_gid))
-    error (SETUIDGID_FAILURE, errno,
-           _("cannot set group-ID to %lu"), (unsigned long int) primary_gid);
-
-  if (setuid (uid))
-    error (SETUIDGID_FAILURE, errno,
-           _("cannot set user-ID to %lu"), (unsigned long int) uid);
-
-  {
-    char **cmd = argv + optind + 1;
-    int exit_status;
-    execvp (*cmd, cmd);
-    exit_status = (errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE);
-
-    error (0, errno, _("failed to run command %s"), quote (*cmd));
-    exit (exit_status);
-  }
-}
diff --git a/tests/cp/preserve-gid.sh b/tests/cp/preserve-gid.sh
index 77dcdb6..f141ac1 100755
--- a/tests/cp/preserve-gid.sh
+++ b/tests/cp/preserve-gid.sh
@@ -117,8 +117,9 @@ t1() {
   u=$1; shift
   g=$1; shift
   t0 "$f" "$u" "$g" \
-      setuidgid -g "$nameless_gid1,$nameless_gid2" \
-      "$nameless_uid" env PATH="$tmp_path" "$@"
+      chroot --user=+$nameless_uid:+$nameless_gid1 \
+             --groups="+$nameless_gid1,+$nameless_gid2" \
+        / env PATH="$tmp_path" "$@"
 }
 
 t1 a0 "$nameless_uid" "$nameless_gid1" cp
diff --git a/tests/cp/special-bits.sh b/tests/cp/special-bits.sh
index 60d26a9..a55eea2 100755
--- a/tests/cp/special-bits.sh
+++ b/tests/cp/special-bits.sh
@@ -42,7 +42,7 @@ set _ $(ls -l b); shift; p1=$1
 set _ $(ls -l b2); shift; p2=$1
 test $p1 = $p2 || fail=1
 
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" cp -p c c2 || fail=1
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" cp -p c c2 || fail=1
 set _ $(ls -l c); shift; p1=$1
 set _ $(ls -l c2); shift; p2=$1
 test $p1 = $p2 && fail=1
diff --git a/tests/id/setgid.sh b/tests/id/setgid.sh
index 9da3538..aa43ea3 100755
--- a/tests/id/setgid.sh
+++ b/tests/id/setgid.sh
@@ -27,7 +27,8 @@ gp1=$(expr $g + 1)
 
 echo $gp1 > exp || framework_failure_
 
-setuidgid -g $gp1 $NON_ROOT_USERNAME env PATH="$PATH" id -G > out || fail=1
+chroot --user=$NON_ROOT_USERNAME:$gp1 --groups='' / env PATH="$PATH" \
+  id -G > out || fail=1
 compare exp out || fail=1
 # With coreutils-8.16 and earlier, id -G would print both: $gp1 $g
 
diff --git a/tests/misc/chroot-fail.sh b/tests/misc/chroot-fail.sh
index b171ec4..a84826f 100755
--- a/tests/misc/chroot-fail.sh
+++ b/tests/misc/chroot-fail.sh
@@ -20,6 +20,7 @@
 . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
 print_ver_ chroot
 
+require_built_ chroot
 
 # These tests verify exact status of internal failure; since none of
 # them actually run a command, we don't need root privileges
diff --git a/tests/misc/truncate-owned-by-other.sh 
b/tests/misc/truncate-owned-by-other.sh
index 9f269ed..e93b7f1 100755
--- a/tests/misc/truncate-owned-by-other.sh
+++ b/tests/misc/truncate-owned-by-other.sh
@@ -31,6 +31,7 @@ chmod g+w root-owned
 # Ensure that the current directory is searchable by $NON_ROOT_USERNAME.
 chmod g+x .
 
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" truncate -s0 root-owned || fail=1
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \
+  truncate -s0 root-owned || fail=1
 
 Exit $fail
diff --git a/tests/mv/sticky-to-xpart.sh b/tests/mv/sticky-to-xpart.sh
index ea5948e..e0c99e9 100755
--- a/tests/mv/sticky-to-xpart.sh
+++ b/tests/mv/sticky-to-xpart.sh
@@ -42,7 +42,7 @@ chmod go+x . || framework_failure_
 
 # Ensure that $NON_ROOT_USERNAME can access the required version of mv.
 version=$(
-  setuidgid $NON_ROOT_USERNAME env PATH="$PATH" mv --version |
+  chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" mv --version |
   sed -n '1s/.* //p'
 )
 case $version in
@@ -50,7 +50,7 @@ case $version in
   *) skip_ "cannot access just-built mv as user $NON_ROOT_USERNAME";;
 esac
 
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" \
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \
   mv t/root-owned "$other_partition_tmpdir" 2> out-t && fail=1
 
 # On some systems, we get 'Not owner'.  Convert it.
diff --git a/tests/rm/fail-2eperm.sh b/tests/rm/fail-2eperm.sh
index e040d00..6e8ce9b 100755
--- a/tests/rm/fail-2eperm.sh
+++ b/tests/rm/fail-2eperm.sh
@@ -32,14 +32,14 @@ touch a/b || framework_failure_
 # Try to ensure that $NON_ROOT_USERNAME can access
 # the required version of rm.
 rm_version=$(
-  setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm --version |
+  chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm --version |
   sed -n '1s/.* //p'
 )
 case $rm_version in
   $PACKAGE_VERSION) ;;
   *) skip_ "cannot access just-built rm as user $NON_ROOT_USERNAME";;
 esac
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm -rf a 2> out-t && fail=1
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" rm -rf a 2> out-t && fail=1
 
 # On some systems, we get 'Not owner'.  Convert it.
 # On other systems (HPUX), we get 'Permission denied'.  Convert it, too.
diff --git a/tests/rm/no-give-up.sh b/tests/rm/no-give-up.sh
index 8742859..41070c9 100755
--- a/tests/rm/no-give-up.sh
+++ b/tests/rm/no-give-up.sh
@@ -30,7 +30,8 @@ chmod go=x . || framework_failure_
 
 
 # This must fail, since '.' is not writable by $NON_ROOT_USERNAME.
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" rm -rf d 2>/dev/null && fail=1
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \
+  rm -rf d 2>/dev/null && fail=1
 
 # d must remain.
 test -d d || fail=1
diff --git a/tests/touch/now-owned-by-other.sh 
b/tests/touch/now-owned-by-other.sh
index 3b5c368..f5eeda6 100755
--- a/tests/touch/now-owned-by-other.sh
+++ b/tests/touch/now-owned-by-other.sh
@@ -30,6 +30,7 @@ chmod g+w root-owned
 # Ensure that the current directory is searchable by $NON_ROOT_USERNAME.
 chmod g+x .
 
-setuidgid $NON_ROOT_USERNAME env PATH="$PATH" touch -d now root-owned || fail=1
+chroot --user=$NON_ROOT_USERNAME / env PATH="$PATH" \
+  touch -d now root-owned || fail=1
 
 Exit $fail
-- 
1.7.7.6




reply via email to

[Prev in Thread] Current Thread [Next in Thread]