New upstream release 8.19, remove everything related to su/runuser

This commit is contained in:
Ondřej Vašík 2012-08-20 12:07:28 +02:00
parent 89d1aa92a0
commit 7ee630cc50
11 changed files with 6 additions and 947 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@
/coreutils-8.16.tar.xz
/coreutils-8.17.tar.xz
/coreutils-8.18.tar.xz
/coreutils-8.19.tar.xz

View File

@ -1,11 +0,0 @@
diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am
--- coreutils-8.4-orig/src/Makefile.am 2010-09-03 17:34:43.399747649 +0200
+++ coreutils-8.4/src/Makefile.am 2010-09-03 17:36:13.005765125 +0200
@@ -367,6 +367,7 @@ factor_LDADD += $(LIB_GMP)
# for crypt and pam
su_LDADD += $(LIB_CRYPT) $(PAM_LIBS)
+su_LDFLAGS = -pie -Wl,-z,relro,-z,now
# for various ACL functions
copy_LDADD += $(LIB_ACL)

View File

@ -1,422 +0,0 @@
diff -urNp coreutils-8.16-orig/configure.ac coreutils-8.16/configure.ac
--- coreutils-8.16-orig/configure.ac 2012-03-24 19:22:13.000000000 +0100
+++ coreutils-8.16/configure.ac 2012-03-26 17:59:07.900139497 +0200
@@ -185,6 +185,20 @@ fi
AC_FUNC_FORK
+AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam],
+ [Disable PAM support in su (default=auto)]), , [enable_pam=yes])
+if test "x$enable_pam" != xno; then
+ AC_CHECK_LIB([pam], [pam_start], [enable_pam=yes], [enable_pam=no])
+ AC_CHECK_LIB([pam_misc], [misc_conv], [:], [enable_pam=no])
+ if test "x$enable_pam" != xno; then
+ AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM])
+ PAM_LIBS="-lpam -lpam_misc"
+ AC_SUBST(PAM_LIBS)
+ fi
+fi
+AC_MSG_CHECKING([whether to enable PAM support in su])
+AC_MSG_RESULT([$enable_pam])
+
optional_bin_progs=
AC_CHECK_FUNCS([chroot],
gl_ADD_PROG([optional_bin_progs], [chroot]))
diff -urNp coreutils-8.16-orig/doc/coreutils.texi coreutils-8.16/doc/coreutils.texi
--- coreutils-8.16-orig/doc/coreutils.texi 2012-03-26 17:58:27.624763998 +0200
+++ coreutils-8.16/doc/coreutils.texi 2012-03-26 17:59:07.907138599 +0200
@@ -15804,7 +15804,9 @@ the exit status of @var{command} otherwi
@command{su} allows one user to temporarily become another user. It runs a
command (often an interactive shell) with the real and effective user
-ID, group ID, and supplemental groups of a given @var{user}. Synopsis:
+ID, group ID, and supplemental groups of a given @var{user}. When the -l
+option is given, the su-l PAM file is used instead of the default su PAM file.
+Synopsis:
@example
su [@var{option}]@dots{} [@var{user} [@var{arg}]@dots{}]
@@ -15883,7 +15885,8 @@ environment variables except @env{TERM},
(which are set, even for the super-user, as described above), and set
@env{PATH} to a compiled-in default value. Change to @var{user}'s home
directory. Prepend @samp{-} to the shell's name, intended to make it
-read its login startup file(s).
+read its login startup file(s). When this option is given, /etc/pam.d/su-l
+PAM file is used instead of the default one.
@item -m
@itemx -p
diff -urNp coreutils-8.16-orig/src/Makefile.am coreutils-8.16/src/Makefile.am
--- coreutils-8.16-orig/src/Makefile.am 2012-03-24 19:22:13.000000000 +0100
+++ coreutils-8.16/src/Makefile.am 2012-03-26 17:59:07.928142551 +0200
@@ -357,8 +357,8 @@ factor_LDADD += $(LIB_GMP)
# for getloadavg
uptime_LDADD += $(GETLOADAVG_LIBS)
-# for crypt
-su_LDADD += $(LIB_CRYPT)
+# for crypt and pam
+su_LDADD += $(LIB_CRYPT) $(PAM_LIBS)
# for various ACL functions
copy_LDADD += $(LIB_ACL)
diff -urNp coreutils-8.16-orig/src/su.c coreutils-8.16/src/su.c
--- coreutils-8.16-orig/src/su.c 2012-03-26 17:58:27.629764055 +0200
+++ coreutils-8.16/src/su.c 2012-03-26 17:59:07.931138998 +0200
@@ -37,6 +37,16 @@
restricts who can su to UID 0 accounts. RMS considers that to
be fascist.
+#ifdef USE_PAM
+
+ Actually, with PAM, su has nothing to do with whether or not a
+ wheel group is enforced by su. RMS tries to restrict your access
+ to a su which implements the wheel group, but PAM considers that
+ to be fascist, and gives the user/sysadmin the opportunity to
+ enforce a wheel group by proper editing of /etc/pam.d/su
+
+#endif
+
Compile-time options:
-DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog.
-DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog.
@@ -52,6 +62,13 @@
#include <sys/types.h>
#include <pwd.h>
#include <grp.h>
+#ifdef USE_PAM
+#include <security/pam_appl.h>
+#include <security/pam_misc.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/fsuid.h>
+#endif
#include "system.h"
#include "getpass.h"
@@ -120,7 +137,9 @@
/* The user to become if none is specified. */
#define DEFAULT_USER "root"
+#ifndef USE_PAM
char *crypt (char const *key, char const *salt);
+#endif
static void run_shell (char const *, char const *, char **, size_t)
ATTRIBUTE_NORETURN;
@@ -134,6 +153,11 @@ static bool simulate_login;
/* If true, change some environment vars to indicate the user su'd to. */
static bool change_environment;
+#ifdef USE_PAM
+static bool _pam_session_opened;
+static bool _pam_cred_established;
+#endif
+
static struct option const longopts[] =
{
{"command", required_argument, NULL, 'c'},
@@ -212,7 +236,174 @@ log_su (struct passwd const *pw, bool su
}
#endif
+#ifdef USE_PAM
+#define PAM_SERVICE_NAME PROGRAM_NAME
+#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l"
+static sig_atomic_t volatile caught_signal = false;
+static pam_handle_t *pamh = NULL;
+static int retval;
+static struct pam_conv conv =
+{
+ misc_conv,
+ NULL
+};
+
+#define PAM_BAIL_P(a) \
+ if (retval) \
+ { \
+ pam_end (pamh, retval); \
+ a; \
+ }
+
+static void
+cleanup_pam (int retcode)
+{
+ if (_pam_session_opened)
+ pam_close_session (pamh, 0);
+
+ if (_pam_cred_established)
+ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT);
+
+ pam_end(pamh, retcode);
+}
+
+/* Signal handler for parent process. */
+static void
+su_catch_sig (int sig)
+{
+ caught_signal = true;
+}
+
+/* Export env variables declared by PAM modules. */
+static void
+export_pamenv (void)
+{
+ char **env;
+
+ /* This is a copy but don't care to free as we exec later anyways. */
+ env = pam_getenvlist (pamh);
+ while (env && *env)
+ {
+ if (putenv (*env) != 0)
+ xalloc_die ();
+ env++;
+ }
+}
+
+static void
+create_watching_parent (void)
+{
+ pid_t child;
+ sigset_t ourset, blockset;
+ int status = 0;
+
+ retval = pam_open_session (pamh, 0);
+ if (retval != PAM_SUCCESS)
+ {
+ cleanup_pam (retval);
+ error (EXIT_FAILURE, 0, _("cannot not open session: %s"),
+ pam_strerror (pamh, retval));
+ }
+ else
+ _pam_session_opened = 1;
+
+ child = fork ();
+ if (child == (pid_t) -1)
+ {
+ cleanup_pam (PAM_ABORT);
+ error (EXIT_FAILURE, errno, _("cannot create child process"));
+ }
+
+ /* the child proceeds to run the shell */
+ if (child == 0)
+ return;
+
+ /* In the parent watch the child. */
+
+ /* su without pam support does not have a helper that keeps
+ sitting on any directory so let's go to /. */
+ if (chdir ("/") != 0)
+ error (0, errno, _("warning: cannot change directory to %s"), "/");
+
+ sigfillset (&ourset);
+ if (sigprocmask (SIG_BLOCK, &ourset, NULL))
+ {
+ error (0, errno, _("cannot block signals"));
+ caught_signal = true;
+ }
+ if (!caught_signal)
+ {
+ struct sigaction action;
+ action.sa_handler = su_catch_sig;
+ sigemptyset (&action.sa_mask);
+ action.sa_flags = 0;
+ sigemptyset (&ourset);
+ if (sigaddset (&ourset, SIGTERM)
+ || sigaddset (&ourset, SIGALRM)
+ || sigaction (SIGTERM, &action, NULL)
+ || sigprocmask (SIG_UNBLOCK, &ourset, NULL))
+ {
+ error (0, errno, _("cannot set signal handler"));
+ caught_signal = true;
+ }
+ }
+ if (!caught_signal)
+ {
+ pid_t pid;
+ for (;;)
+ {
+ pid = waitpid (child, &status, WUNTRACED);
+
+ if (pid != (pid_t)-1 && WIFSTOPPED (status))
+ {
+ /* tcsh sends SIGTSTP to the process group, and so is already pending */
+ kill (getpid (), SIGSTOP);
+ if (WSTOPSIG(status) != SIGSTOP) {
+ sigemptyset(&blockset);
+ if (sigaddset(&blockset, WSTOPSIG(status)) ||
+ sigprocmask(SIG_UNBLOCK, &blockset, &ourset) ||
+ sigprocmask(SIG_SETMASK, &ourset, NULL))
+ {
+ error (0, errno, _("cannot set signal handler"));
+ }
+ }
+ /* once we get here, we must have resumed */
+ kill (pid, SIGCONT);
+ }
+ else
+ break;
+ }
+ if (pid != (pid_t)-1)
+ if (WIFSIGNALED (status))
+ status = WTERMSIG (status) + 128;
+ else
+ status = WEXITSTATUS (status);
+ else
+ status = 1;
+ }
+ else
+ status = 1;
+
+ if (caught_signal)
+ {
+ fprintf (stderr, _("\nSession terminated, killing shell..."));
+ kill (child, SIGTERM);
+ }
+
+ cleanup_pam (PAM_SUCCESS);
+
+ if (caught_signal)
+ {
+ sleep (2);
+ kill (child, SIGKILL);
+ fprintf (stderr, _(" ...killed.\n"));
+ }
+ exit (status);
+}
+#endif
+
/* Ask the user for a password.
+ If PAM is in use, let PAM ask for the password if necessary.
Return true if the user gives the correct password for entry PW,
false if not. Return true without asking for a password if run by UID 0
or if PW has an empty password. */
@@ -220,10 +411,52 @@ log_su (struct passwd const *pw, bool su
static bool
correct_password (const struct passwd *pw)
{
+#ifdef USE_PAM
+ const struct passwd *lpw;
+ const char *cp;
+
+ retval = pam_start (simulate_login ? PAM_SERVICE_NAME_L : PAM_SERVICE_NAME,
+ pw->pw_name, &conv, &pamh);
+ PAM_BAIL_P (return false);
+
+ if (isatty (0) && (cp = ttyname (0)) != NULL)
+ {
+ const char *tty;
+
+ if (strncmp (cp, "/dev/", 5) == 0)
+ tty = cp + 5;
+ else
+ tty = cp;
+ retval = pam_set_item (pamh, PAM_TTY, tty);
+ PAM_BAIL_P (return false);
+ }
+#if 0 /* Manpage discourages use of getlogin. */
+ cp = getlogin ();
+ if (!(cp && *cp && (lpw = getpwnam (cp)) != NULL && lpw->pw_uid == getuid ()))
+#endif
+ lpw = getpwuid (getuid ());
+ if (lpw && lpw->pw_name)
+ {
+ retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name);
+ PAM_BAIL_P (return false);
+ }
+ retval = pam_authenticate (pamh, 0);
+ PAM_BAIL_P (return false);
+ retval = pam_acct_mgmt (pamh, 0);
+ if (retval == PAM_NEW_AUTHTOK_REQD)
+ {
+ /* Password has expired. Offer option to change it. */
+ retval = pam_chauthtok (pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
+ PAM_BAIL_P (return false);
+ }
+ PAM_BAIL_P (return false);
+ /* Must be authenticated if this point was reached. */
+ return true;
+#else /* !USE_PAM */
char *unencrypted, *encrypted, *correct;
#if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP
/* Shadow passwd stuff for SVR3 and maybe other systems. */
- struct spwd *sp = getspnam (pw->pw_name);
+ const struct spwd *sp = getspnam (pw->pw_name);
endspent ();
if (sp)
@@ -244,6 +477,7 @@ correct_password (const struct passwd *p
encrypted = crypt (unencrypted, correct);
memset (unencrypted, 0, strlen (unencrypted));
return STREQ (encrypted, correct);
+#endif /* !USE_PAM */
}
/* Update 'environ' for the new shell based on PW, with SHELL being
@@ -286,19 +520,41 @@ modify_environment (const struct passwd
}
}
}
+
+#ifdef USE_PAM
+ export_pamenv ();
+#endif
}
/* Become the user and group(s) specified by PW. */
static void
-change_identity (const struct passwd *pw)
+init_groups (const struct passwd *pw)
{
#ifdef HAVE_INITGROUPS
errno = 0;
if (initgroups (pw->pw_name, pw->pw_gid) == -1)
- error (EXIT_CANCELED, errno, _("cannot set groups"));
+ {
+#ifdef USE_PAM
+ cleanup_pam (PAM_ABORT);
+#endif
+ error (EXIT_FAILURE, errno, _("cannot set groups"));
+ }
endgrent ();
#endif
+
+#ifdef USE_PAM
+ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED);
+ if (retval != PAM_SUCCESS)
+ error (EXIT_FAILURE, 0, "%s", pam_strerror (pamh, retval));
+ else
+ _pam_cred_established = 1;
+#endif
+}
+
+static void
+change_identity (const struct passwd *pw)
+{
if (setgid (pw->pw_gid))
error (EXIT_CANCELED, errno, _("cannot set group id"));
if (setuid (pw->pw_uid))
@@ -511,9 +767,21 @@ main (int argc, char **argv)
shell = NULL;
}
shell = xstrdup (shell ? shell : pw->pw_shell);
- modify_environment (pw, shell);
+
+ init_groups (pw);
+
+#ifdef USE_PAM
+ create_watching_parent ();
+ /* Now we're in the child. */
+#endif
change_identity (pw);
+
+ /* Set environment after pam_open_session, which may put KRB5CCNAME
+ into the pam_env, etc. */
+
+ modify_environment (pw, shell);
+
if (simulate_login && chdir (pw->pw_dir) != 0)
error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);

View File

@ -1,338 +0,0 @@
diff -urNp coreutils-8.7-orig/AUTHORS coreutils-8.7/AUTHORS
--- coreutils-8.7-orig/AUTHORS 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/AUTHORS 2010-11-15 10:08:04.222078001 +0100
@@ -65,6 +65,7 @@ readlink: Dmitry V. Levin
rm: Paul Rubin, David MacKenzie, Richard M. Stallman, Jim Meyering
rmdir: David MacKenzie
runcon: Russell Coker
+runuser: David MacKenzie, Dan Walsh
seq: Ulrich Drepper
sha1sum: Ulrich Drepper, Scott Miller, David Madore
sha224sum: Ulrich Drepper, Scott Miller, David Madore
diff -urNp coreutils-8.7-orig/man/help2man coreutils-8.7/man/help2man
--- coreutils-8.7-orig/man/help2man 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/man/help2man 2010-11-15 10:08:51.331054884 +0100
@@ -555,6 +555,9 @@ while (length)
$include{$sect} .= $content;
}
+# There is no info documentation for runuser (shared with su).
+$opt_no_info = 1 if $program eq 'runuser';
+
# Refer to the real documentation.
unless ($opt_no_info)
{
diff -urNp coreutils-8.7-orig/man/Makefile.am coreutils-8.7/man/Makefile.am
--- coreutils-8.7-orig/man/Makefile.am 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/man/Makefile.am 2010-11-15 10:09:21.768922182 +0100
@@ -94,6 +94,7 @@ readlink.1: $(common_dep) $(srcdir)/read
rm.1: $(common_dep) $(srcdir)/rm.x ../src/rm.c
rmdir.1: $(common_dep) $(srcdir)/rmdir.x ../src/rmdir.c
runcon.1: $(common_dep) $(srcdir)/runcon.x ../src/runcon.c
+runuser.1: $(common_dep) $(srcdir)/runuser.x ../src/su.c
seq.1: $(common_dep) $(srcdir)/seq.x ../src/seq.c
sha1sum.1: $(common_dep) $(srcdir)/sha1sum.x ../src/md5sum.c
sha224sum.1: $(common_dep) $(srcdir)/sha224sum.x ../src/md5sum.c
diff -urNp coreutils-8.7-orig/man/runuser.x coreutils-8.7/man/runuser.x
--- coreutils-8.7-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.7/man/runuser.x 2010-11-15 10:09:57.437939015 +0100
@@ -0,0 +1,12 @@
+[NAME]
+runuser \- run a shell with substitute user and group IDs
+[DESCRIPTION]
+.\" Add any additional description here
+[SEE ALSO]
+.TP
+More detailed Texinfo documentation could be found by command
+.TP
+\t\fBinfo coreutils \(aqsu invocation\(aq\fR\t
+.TP
+since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR.
+.br
diff -urNp coreutils-8.7-orig/README coreutils-8.7/README
--- coreutils-8.7-orig/README 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/README 2010-11-15 10:10:43.002922253 +0100
@@ -11,8 +11,8 @@ The programs that can be built with this
factor false fmt fold groups head hostid hostname id install join kill
link ln logname ls md5sum mkdir mkfifo mknod mktemp mv nice nl nohup
nproc od paste pathchk pinky pr printenv printf ptx pwd readlink realpath
- rm rmdir runcon seq sha1sum sha224sum sha256sum sha384sum sha512sum shred
- shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test
+ rm rmdir runcon runuser seq sha1sum sha224sum sha256sum sha384sum sha512sum
+ shred shuf sleep sort split stat stdbuf stty su sum sync tac tail tee test
timeout touch tr true truncate tsort tty uname unexpand uniq unlink
uptime users vdir wc who whoami yes
diff -urNp coreutils-8.7-orig/src/Makefile.am coreutils-8.7/src/Makefile.am
--- coreutils-8.7-orig/src/Makefile.am 2010-11-15 10:07:07.339171659 +0100
+++ coreutils-8.7/src/Makefile.am 2010-11-15 10:12:14.847094550 +0100
@@ -100,6 +100,7 @@ EXTRA_PROGRAMS = \
rm \
rmdir \
runcon \
+ runuser \
seq \
sha1sum \
sha224sum \
@@ -300,6 +301,10 @@ cp_LDADD += $(copy_LDADD)
ginstall_LDADD += $(copy_LDADD)
mv_LDADD += $(copy_LDADD)
+runuser_SOURCES = su.c
+runuser_CFLAGS = -DRUNUSER -DAUTHORS="\"David MacKenzie, Dan Walsh\""
+runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS)
+
remove_LDADD =
mv_LDADD += $(remove_LDADD)
rm_LDADD += $(remove_LDADD)
@@ -395,7 +400,7 @@ RELEASE_YEAR = \
`sed -n '/.*COPYRIGHT_YEAR = \([0-9][0-9][0-9][0-9]\) };/s//\1/p' \
$(top_srcdir)/lib/version-etc.c`
-all-local: su$(EXEEXT)
+all-local: su$(EXEEXT) runuser
installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'`
diff -urNp coreutils-8.7-orig/src/su.c coreutils-8.7/src/su.c
--- coreutils-8.7-orig/src/su.c 2010-11-15 10:07:07.372933288 +0100
+++ coreutils-8.7/src/su.c 2010-11-15 10:42:12.569159230 +0100
@@ -100,9 +100,15 @@
#include "error.h"
/* The official name of this program (e.g., no 'g' prefix). */
+#ifndef RUNUSER
#define PROGRAM_NAME "su"
+#else
+#define PROGRAM_NAME "runuser"
+#endif
+#ifndef AUTHORS
#define AUTHORS proper_name ("David MacKenzie")
+#endif
#if HAVE_PATHS_H
# include <paths.h>
@@ -140,6 +146,9 @@
#ifndef USE_PAM
char *crypt (char const *key, char const *salt);
#endif
+#ifndef CHECKPASSWD
+#define CHECKPASSWD 1
+#endif
static void run_shell (char const *, char const *, char **, size_t)
ATTRIBUTE_NORETURN;
@@ -169,6 +178,10 @@ static struct option const longopts[] =
{"login", no_argument, NULL, 'l'},
{"preserve-environment", no_argument, NULL, 'p'},
{"shell", required_argument, NULL, 's'},
+#ifdef RUNUSER
+ {"group", required_argument, NULL, 'g'},
+ {"supp-group", required_argument, NULL, 'G'},
+#endif
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -444,6 +457,11 @@ correct_password (const struct passwd *p
retval = pam_set_item (pamh, PAM_RUSER, (const void *) lpw->pw_name);
PAM_BAIL_P (return false);
}
+#ifdef RUNUSER
+ if (getuid() != geteuid())
+ /* safety net: deny operation if we are suid by accident */
+ error(EXIT_FAILURE, 1, "runuser may not be setuid");
+#else
retval = pam_authenticate (pamh, 0);
PAM_BAIL_P (return false);
retval = pam_acct_mgmt (pamh, 0);
@@ -454,6 +472,7 @@ correct_password (const struct passwd *p
PAM_BAIL_P (return false);
}
PAM_BAIL_P (return false);
+#endif
/* Must be authenticated if this point was reached. */
return true;
#else /* !USE_PAM */
@@ -533,11 +552,22 @@ modify_environment (const struct passwd
/* Become the user and group(s) specified by PW. */
static void
-init_groups (const struct passwd *pw)
+init_groups (const struct passwd *pw
+#ifdef RUNUSER
+ , gid_t *groups, int num_groups
+#endif
+ )
{
#ifdef HAVE_INITGROUPS
+ int rc = 0;
errno = 0;
- if (initgroups (pw->pw_name, pw->pw_gid) == -1)
+#ifdef RUNUSER
+ if (num_groups)
+ rc = setgroups(num_groups, groups);
+ else
+#endif
+ rc = initgroups(pw->pw_name, pw->pw_gid);
+ if (rc == -1)
{
#ifdef USE_PAM
cleanup_pam (PAM_ABORT);
@@ -639,6 +669,28 @@ usage (int status)
else
{
printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
+#ifdef RUNUSER
+ printf (_("\
+Change the effective user id and group id to that of USER. Only session PAM\n\
+hooks are run, and there is no password prompt. This command is useful only\n\
+when run as the root user. If run as a non-root user without privilege\n\
+to set user ID, the command will fail as the binary is not setuid.\n\
+As %s doesn't run auth and account PAM hooks, it runs with lower overhead\n\
+than su.\n\
+\n\
+ -, -l, --login make the shell a login shell, uses runuser-l\n\
+ PAM file instead of default one\n\
+ -g --group=group specify the primary group\n\
+ -G --supp-group=group specify a supplemental group\n\
+ -c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\
+ and do not create a new session\n\
+ -f, --fast pass -f to the shell (for csh or tcsh)\n\
+ -m, --preserve-environment do not reset environment variables\n\
+ -p same as -m\n\
+ -s, --shell=SHELL run SHELL if /etc/shells allows it\n\
+"), program_name);
+#else
fputs (_("\
Change the effective user id and group id to that of USER.\n\
\n\
@@ -651,6 +703,7 @@ Change the effective user id and group i
-p same as -m\n\
-s, --shell=SHELL run SHELL if /etc/shells allows it\n\
"), stdout);
+#endif
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
@@ -672,6 +725,12 @@ main (int argc, char **argv)
char *shell = NULL;
struct passwd *pw;
struct passwd pw_copy;
+#ifdef RUNUSER
+ struct group *gr;
+ gid_t groups[NGROUPS_MAX];
+ int num_supp_groups = 0;
+ int use_gid = 0;
+#endif
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -686,7 +745,11 @@ main (int argc, char **argv)
simulate_login = false;
change_environment = true;
- while ((optc = getopt_long (argc, argv, "c:flmps:", longopts, NULL)) != -1)
+ while ((optc = getopt_long (argc, argv, "c:flmps:"
+#ifdef RUNUSER
+ "g:G:"
+#endif
+ , longopts, NULL)) != -1)
{
switch (optc)
{
@@ -716,6 +779,28 @@ main (int argc, char **argv)
shell = optarg;
break;
+#ifdef RUNUSER
+ case 'g':
+ gr = getgrnam(optarg);
+ if (!gr)
+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
+ use_gid = 1;
+ groups[0] = gr->gr_gid;
+ break;
+
+ case 'G':
+ num_supp_groups++;
+ if (num_supp_groups >= NGROUPS_MAX)
+ error (EXIT_FAILURE, 0,
+ _("Can't specify more than %d supplemental groups"),
+ NGROUPS_MAX - 1);
+ gr = getgrnam(optarg);
+ if (!gr)
+ error (EXIT_FAILURE, 0, _("group %s does not exist"), optarg);
+ groups[num_supp_groups] = gr->gr_gid;
+ break;
+#endif
+
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -754,7 +839,20 @@ main (int argc, char **argv)
: DEFAULT_SHELL);
endpwent ();
- if (!correct_password (pw))
+#ifdef RUNUSER
+ if (num_supp_groups && !use_gid)
+ {
+ pw->pw_gid = groups[1];
+ memmove (groups, groups + 1, sizeof(gid_t) * num_supp_groups);
+ }
+ else if (use_gid)
+ {
+ pw->pw_gid = groups[0];
+ num_supp_groups++;
+ }
+#endif
+
+ if (CHECKPASSWD && !correct_password (pw))
{
#ifdef SYSLOG_FAILURE
log_su (pw, false);
@@ -784,7 +882,11 @@ main (int argc, char **argv)
}
shell = xstrdup (shell ? shell : pw->pw_shell);
- init_groups (pw);
+ init_groups (pw
+#ifdef RUNUSER
+ , groups, num_supp_groups
+#endif
+ );
#ifdef USE_PAM
create_watching_parent ();
diff -urNp coreutils-8.7-orig/tests/misc/help-version coreutils-8.7/tests/misc/help-version
--- coreutils-8.7-orig/tests/misc/help-version 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/tests/misc/help-version 2010-11-15 10:45:18.473682325 +0100
@@ -32,6 +32,7 @@ expected_failure_status_nohup=125
expected_failure_status_stdbuf=125
expected_failure_status_su=125
expected_failure_status_timeout=125
+expected_failure_status_runuser=125
expected_failure_status_printenv=2
expected_failure_status_tty=3
expected_failure_status_sort=2
@@ -209,6 +210,7 @@ seq_setup () { args=10; }
sleep_setup () { args=0; }
su_setup () { args=--version; }
stdbuf_setup () { args="-oL true"; }
+runuser_setup () { args=--version; }
timeout_setup () { args=--version; }
# I'd rather not run sync, since it spins up disks that I've
diff -urNp coreutils-8.7-orig/tests/misc/invalid-opt coreutils-8.7/tests/misc/invalid-opt
--- coreutils-8.7-orig/tests/misc/invalid-opt 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/tests/misc/invalid-opt 2010-11-15 10:45:46.451938873 +0100
@@ -37,6 +37,7 @@ my %exit_status =
sort => 2,
stdbuf => 125,
su => 125,
+ runuser => 125,
test => 0,
timeout => 125,
true => 0,

View File

@ -1,4 +0,0 @@
#%PAM-1.0
auth include runuser
session optional pam_keyinit.so force revoke
session include runuser

View File

@ -1,5 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
session optional pam_keyinit.so revoke
session required pam_limits.so
session required pam_unix.so

View File

@ -1,102 +0,0 @@
diff -urNp coreutils-8.6-orig/src/su.c coreutils-8.6/src/su.c
--- coreutils-8.6-orig/src/su.c 2010-11-03 13:56:11.679069689 +0100
+++ coreutils-8.6/src/su.c 2010-11-03 13:56:45.304325661 +0100
@@ -153,6 +153,9 @@ static bool simulate_login;
/* If true, change some environment vars to indicate the user su'd to. */
static bool change_environment;
+/* If true, then don't call setsid() with a command. */
+int same_session = 0;
+
#ifdef USE_PAM
static bool _pam_session_opened;
static bool _pam_cred_established;
@@ -161,6 +164,7 @@ static bool _pam_cred_established;
static struct option const longopts[] =
{
{"command", required_argument, NULL, 'c'},
+ {"session-command", required_argument, NULL, 'C'},
{"fast", no_argument, NULL, 'f'},
{"login", no_argument, NULL, 'l'},
{"preserve-environment", no_argument, NULL, 'p'},
@@ -335,14 +339,27 @@ create_watching_parent (void)
sigemptyset (&action.sa_mask);
action.sa_flags = 0;
sigemptyset (&ourset);
- if (sigaddset (&ourset, SIGTERM)
- || sigaddset (&ourset, SIGALRM)
- || sigaction (SIGTERM, &action, NULL)
- || sigprocmask (SIG_UNBLOCK, &ourset, NULL))
- {
+ if (!same_session)
+ {
+ if (sigaddset(&ourset, SIGINT) || sigaddset(&ourset, SIGQUIT))
+ {
+ error (0, errno, _("cannot set signal handler"));
+ caught_signal = true;
+ }
+ }
+ if (!caught_signal && (sigaddset(&ourset, SIGTERM)
+ || sigaddset(&ourset, SIGALRM)
+ || sigaction(SIGTERM, &action, NULL)
+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) {
error (0, errno, _("cannot set signal handler"));
caught_signal = true;
}
+ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL)
+ || sigaction(SIGQUIT, &action, NULL)))
+ {
+ error (0, errno, _("cannot set signal handler"));
+ caught_signal = true;
+ }
}
if (!caught_signal)
{
@@ -627,6 +644,8 @@ Change the effective user id and group i
\n\
-, -l, --login make the shell a login shell\n\
-c, --command=COMMAND pass a single COMMAND to the shell with -c\n\
+ --session-command=COMMAND pass a single COMMAND to the shell with -c\n\
+ and do not create a new session\n\
-f, --fast pass -f to the shell (for csh or tcsh)\n\
-m, --preserve-environment do not reset environment variables\n\
-p same as -m\n\
@@ -649,6 +668,7 @@ main (int argc, char **argv)
int optc;
const char *new_user = DEFAULT_USER;
char *command = NULL;
+ int request_same_session = 0;
char *shell = NULL;
struct passwd *pw;
struct passwd pw_copy;
@@ -674,6 +694,11 @@ main (int argc, char **argv)
command = optarg;
break;
+ case 'C':
+ command = optarg;
+ request_same_session = 1;
+ break;
+
case 'f':
fast_startup = true;
break;
@@ -743,6 +768,9 @@ main (int argc, char **argv)
}
#endif
+ if (request_same_session || !command || !pw->pw_uid)
+ same_session = 1;
+
if (!shell && !change_environment)
shell = getenv ("SHELL");
if (shell && getuid () != 0 && restricted_shell (pw->pw_shell))
@@ -764,6 +792,8 @@ main (int argc, char **argv)
#endif
change_identity (pw);
+ if (!same_session)
+ setsid ();
/* Set environment after pam_open_session, which may put KRB5CCNAME
into the pam_env, etc. */

View File

@ -1,6 +0,0 @@
#%PAM-1.0
auth include su
account include su
password include su
session optional pam_keyinit.so force revoke
session include su

View File

@ -1,14 +0,0 @@
#%PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
#auth required pam_wheel.so use_uid
auth include system-auth
auth include postlogin
account sufficient pam_succeed_if.so uid = 0 use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session include postlogin
session optional pam_xauth.so

View File

@ -1,6 +1,6 @@
Summary: A set of basic GNU tools commonly used in shell scripts
Name: coreutils
Version: 8.18
Version: 8.19
Release: 1%{?dist}
License: GPLv3+
Group: System Environment/Base
@ -12,10 +12,6 @@ Source102: coreutils-DIR_COLORS.lightbgcolor
Source103: coreutils-DIR_COLORS.256color
Source105: coreutils-colorls.sh
Source106: coreutils-colorls.csh
Source200: coreutils-su.pamd
Source201: coreutils-runuser.pamd
Source202: coreutils-su-l.pamd
Source203: coreutils-runuser-l.pamd
# From upstream
@ -36,27 +32,15 @@ Patch107: coreutils-8.4-mkdir-modenote.patch
# sh-utils
#add info about TZ envvar to date manpage
Patch703: sh-utils-2.0.11-dateman.patch
#set paths for su explicitly, don't get influenced by paths.h
#Patch704: sh-utils-1.16-paths.patch
# RMS will never accept the PAM patch because it removes his historical
# rant about Twenex and the wheel group, so we'll continue to maintain
# it here indefinitely. Patch is now the same in Fedora and SUSE.
#Patch706: coreutils-8.5-pam.patch
Patch713: coreutils-4.5.3-langinfo.patch
# (sb) lin18nux/lsb compliance - multibyte functionality patch
Patch800: coreutils-i18n.patch
#Call setsid() in su under some circumstances (bug #173008).
#Patch900: coreutils-setsid.patch
#make runuser binary based on su.c
#Patch907: coreutils-8.7-runuser.patch
#getgrouplist() patch from Ulrich Drepper.
Patch908: coreutils-getgrouplist.patch
#Prevent buffer overflow in who(1) (bug #158405).
Patch912: coreutils-overflow.patch
#compile su with pie flag and RELRO protection
#Patch917: coreutils-8.4-su-pie.patch
#SELINUX Patch - implements Redhat changes
#(upstream did some SELinux implementation unlike with RedHat patch)
@ -93,12 +77,10 @@ Provides: /bin/rmdir
Provides: /bin/sleep
Provides: /bin/sort
Provides: /bin/stty
Provides: /bin/su
Provides: /bin/sync
Provides: /bin/touch
Provides: /bin/true
Provides: /bin/uname
Provides: /sbin/runuser
BuildRequires: libselinux-devel
BuildRequires: libacl-devel
@ -106,7 +88,6 @@ BuildRequires: gettext bison
BuildRequires: texinfo
BuildRequires: autoconf
BuildRequires: automake
#%{?!nopam:BuildRequires: pam-devel}
BuildRequires: libcap-devel
BuildRequires: libattr-devel
BuildRequires: gmp-devel
@ -117,7 +98,6 @@ Requires(pre): /sbin/install-info
Requires(preun): /sbin/install-info
Requires(post): /sbin/install-info
Requires(post): grep
#%{?!nopam:Requires: pam >= 1.1.3-7}
Requires: ncurses
Requires: gmp
@ -155,19 +135,14 @@ the old GNU fileutils, sh-utils, and textutils packages.
# sh-utils
%patch703 -p1 -b .dateman
#%patch704 -p1 -b .paths
#%patch706 -p1 -b .pam
%patch713 -p1 -b .langinfo
# li18nux/lsb
%patch800 -p1 -b .i18n
# Coreutils
#%patch900 -p1 -b .setsid
#%patch907 -p1 -b .runuser
%patch908 -p1 -b .getgrouplist
%patch912 -p1 -b .overflow
#%patch917 -p1 -b .pie
#SELinux
%patch950 -p1 -b .selinux
@ -226,7 +201,6 @@ bzip2 -9f ChangeLog
# let be compatible with old fileutils, sh-utils and textutils packages :
mkdir -p $RPM_BUILD_ROOT{%{_bindir},%{_sbindir}}
#%{?!nopam:mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/pam.d}
# chroot was in /usr/sbin :
mv $RPM_BUILD_ROOT{%_bindir,%_sbindir}/chroot
@ -238,22 +212,11 @@ install -p -c -m644 %SOURCE103 $RPM_BUILD_ROOT%{_sysconfdir}/DIR_COLORS.256color
install -p -c -m644 %SOURCE105 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.sh
install -p -c -m644 %SOURCE106 $RPM_BUILD_ROOT%{_sysconfdir}/profile.d/colorls.csh
# su
#install -m 4755 src/su $RPM_BUILD_ROOT/%{_bindir}
#%{?!norunuser:install -m 755 src/runuser $RPM_BUILD_ROOT/%{_sbindir}}
# do not ship runuser in /usr/bin/runuser
#rm -rf $RPM_BUILD_ROOT/%{_bindir}/runuser || :
# These come from util-linux and/or procps.
for i in hostname uptime kill ; do
rm $RPM_BUILD_ROOT{%{_bindir}/$i,%{_mandir}/man1/$i.1}
done
#%{?!nopam:install -p -m 644 %SOURCE200 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su}
#%{?!nopam:install -p -m 644 %SOURCE202 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/su-l}
#%{?!nopam:install -p -m 644 %SOURCE201 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser}
#%{?!nopam:install -p -m 644 %SOURCE203 $RPM_BUILD_ROOT%{_sysconfdir}/pam.d/runuser-l}
# Compress ChangeLogs from before the fileutils/textutils/etc merge
bzip2 -f9 old/*/C*
@ -304,10 +267,6 @@ fi
%dir %{_datadir}/locale/*/LC_TIME
%config(noreplace) %{_sysconfdir}/DIR_COLORS*
%config(noreplace) %{_sysconfdir}/profile.d/*
#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su}
#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/su-l}
#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser}
#%{?!nopam:%config(noreplace) %{_sysconfdir}/pam.d/runuser-l}
%doc COPYING ABOUT-NLS ChangeLog.bz2 NEWS README THANKS TODO old/*
%{_bindir}/arch
%{_bindir}/basename
@ -337,7 +296,6 @@ fi
%{_bindir}/sleep
%{_bindir}/sort
%{_bindir}/stty
#%attr(4755,root,root) %{_bindir}/su
%{_bindir}/sync
%{_bindir}/mktemp
%{_bindir}/touch
@ -414,9 +372,11 @@ fi
%{_libexecdir}/coreutils*
%{_mandir}/man*/*
%{_sbindir}/chroot
#%{?!norunuser:%{_sbindir}/runuser}
%changelog
* Mon Aug 20 2012 Ondrej Vasik <ovasik@redhat.com> 8.19-1
- new upstream release 8.19
* Sun Aug 12 2012 Ondrej Vasik <ovasik@redhat.com> 8.18-1
- new upstream release 8.18
- su/runuser moved to util-linux

View File

@ -1 +1 @@
74712fbb0e0dfcb883c90eab91982780 coreutils-8.18.tar.xz
1a01231a2f3ed37c0efc073ccdda9375 coreutils-8.19.tar.xz