New upstream release 8.7, consolidate PAM support with SUSE (#622700)

This commit is contained in:
Ondřej Vašík 2010-11-15 13:16:04 +01:00
parent c07997606c
commit 9170895a87
11 changed files with 674 additions and 806 deletions

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
coreutils-8.5.tar.xz
/coreutils-8.6.tar.xz
/coreutils-8.7.tar.xz

View File

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

428
coreutils-8.5-pam.patch Normal file
View File

@ -0,0 +1,428 @@
From ea2d050b1952feb99f86c98255280beb6e589d8c Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
Date: Tue, 17 Aug 2010 13:21:44 +0200
Subject: [PATCH 1/7] pam support for su
---
configure.ac | 14 +++
src/Makefile.am | 4 +-
src/su.c | 266 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 278 insertions(+), 6 deletions(-)
diff --git a/configure.ac b/configure.ac
index b07a52b..1fb5839 100644
--- a/configure.ac
+++ b/configure.ac
@@ -128,6 +128,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 --git a/src/Makefile.am b/src/Makefile.am
index db5359b..154a5ed 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -363,8 +363,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 --git a/src/su.c b/src/su.c
index f8f5b61..811aad7 100644
--- a/src/su.c
+++ b/src/su.c
@@ -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"
@@ -111,7 +128,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;
@@ -125,6 +144,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'},
@@ -200,7 +224,164 @@ log_su (struct passwd const *pw, bool successful)
}
#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;
+ 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))
+ {
+ kill (getpid (), SIGSTOP);
+ /* 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. */
@@ -208,10 +389,52 @@ log_su (struct passwd const *pw, bool successful)
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)
@@ -232,6 +455,7 @@ correct_password (const struct passwd *pw)
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
@@ -274,19 +498,41 @@ modify_environment (const struct passwd *pw, const char *shell)
}
}
}
+
+#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))
@@ -500,9 +746,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);
--
1.7.1
diff -urNp coreutils-8.7-orig/doc/coreutils.texi coreutils-8.7/doc/coreutils.texi
--- coreutils-8.7-orig/doc/coreutils.texi 2010-11-15 12:47:03.529922880 +0100
+++ coreutils-8.7/doc/coreutils.texi 2010-11-15 12:49:55.945171380 +0100
@@ -15180,7 +15180,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{}]
@@ -15259,7 +15261,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

View File

@ -1,6 +1,6 @@
diff -urNp coreutils-8.1-orig/AUTHORS coreutils-8.1/AUTHORS
--- coreutils-8.1-orig/AUTHORS 2009-11-06 18:04:10.000000000 +0100
+++ coreutils-8.1/AUTHORS 2009-11-20 13:06:26.000000000 +0100
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
@ -9,10 +9,10 @@ diff -urNp coreutils-8.1-orig/AUTHORS coreutils-8.1/AUTHORS
seq: Ulrich Drepper
sha1sum: Ulrich Drepper, Scott Miller, David Madore
sha224sum: Ulrich Drepper, Scott Miller, David Madore
diff -urNp coreutils-8.1-orig/man/help2man coreutils-8.1/man/help2man
--- coreutils-8.1-orig/man/help2man 2009-09-23 10:25:44.000000000 +0200
+++ coreutils-8.1/man/help2man 2009-11-20 13:06:26.000000000 +0100
@@ -556,6 +556,9 @@ while (length)
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;
}
@ -22,9 +22,9 @@ diff -urNp coreutils-8.1-orig/man/help2man coreutils-8.1/man/help2man
# Refer to the real documentation.
unless ($opt_no_info)
{
diff -urNp coreutils-8.1-orig/man/Makefile.am coreutils-8.1/man/Makefile.am
--- coreutils-8.1-orig/man/Makefile.am 2009-11-06 18:04:10.000000000 +0100
+++ coreutils-8.1/man/Makefile.am 2009-11-20 13:06:26.000000000 +0100
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
@ -33,9 +33,9 @@ diff -urNp coreutils-8.1-orig/man/Makefile.am coreutils-8.1/man/Makefile.am
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.1-orig/man/runuser.x coreutils-8.1/man/runuser.x
--- coreutils-8.1-orig/man/runuser.x 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.1/man/runuser.x 2009-11-20 13:06:26.000000000 +0100
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
@ -49,9 +49,9 @@ diff -urNp coreutils-8.1-orig/man/runuser.x coreutils-8.1/man/runuser.x
+.TP
+since the command \fBrunuser\fR is trimmed down version of command \fBsu\fR.
+.br
diff -urNp coreutils-8.1-orig/README coreutils-8.1/README
--- coreutils-8.1-orig/README 2009-11-06 18:04:10.000000000 +0100
+++ coreutils-8.1/README 2009-11-20 13:06:26.000000000 +0100
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
@@ -12,10 +12,10 @@ 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
@ -67,29 +67,29 @@ diff -urNp coreutils-8.1-orig/README coreutils-8.1/README
See the file NEWS for a list of major changes in the current release.
diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am
--- coreutils-8.1-orig/src/Makefile.am 2009-11-20 13:06:00.000000000 +0100
+++ coreutils-8.1/src/Makefile.am 2009-11-20 13:06:26.000000000 +0100
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 \
+ runuser \
seq \
sha1sum \
sha224sum \
@@ -296,6 +297,10 @@ cp_LDADD += $(copy_LDADD)
@@ -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) @LIB_PAM@
+runuser_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS)
+
remove_LDADD =
mv_LDADD += $(remove_LDADD)
rm_LDADD += $(remove_LDADD)
@@ -396,7 +401,7 @@ RELEASE_YEAR = \
@@ -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`
@ -98,10 +98,10 @@ diff -urNp coreutils-8.1-orig/src/Makefile.am coreutils-8.1/src/Makefile.am
installed_su = $(DESTDIR)$(bindir)/`echo su|sed '$(transform)'`
diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
--- coreutils-8.1-orig/src/su.c 2009-11-20 13:06:00.000000000 +0100
+++ coreutils-8.1/src/su.c 2009-11-20 13:06:26.000000000 +0100
@@ -102,9 +102,15 @@
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). */
@ -117,7 +117,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
#if HAVE_PATHS_H
# include <paths.h>
@@ -142,9 +148,16 @@
@@ -140,6 +146,9 @@
#ifndef USE_PAM
char *crypt (char const *key, char const *salt);
#endif
@ -125,17 +125,9 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
+#define CHECKPASSWD 1
+#endif
static void run_shell (char const *, char const *, char **, size_t,
- const struct passwd *)
+ const struct passwd *
+#ifdef RUNUSER
+ , gid_t *groups, int num_groups
+#endif
+ )
#ifdef USE_PAM
;
#else
@@ -171,6 +184,10 @@ static struct option const longopts[] =
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'},
@ -146,45 +138,27 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
{NULL, 0, NULL, 0}
@@ -272,10 +289,12 @@ correct_password (const struct passwd *p
retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh);
PAM_BAIL_P;
+#ifndef RUNUSER
if (getuid() != 0 && !isatty(0)) {
fprintf(stderr, "standard in must be a tty\n");
exit(1);
}
+#endif
caller = getpwuid(getuid());
if(caller != NULL && caller->pw_name != NULL) {
@@ -292,6 +311,11 @@ correct_password (const struct passwd *p
retval = pam_set_item(pamh, PAM_TTY, tty_name);
PAM_BAIL_P;
}
@@ -444,8 +457,14 @@ 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;
retval = pam_acct_mgmt(pamh, 0);
@@ -301,6 +325,7 @@ correct_password (const struct passwd *p
PAM_BAIL_P;
}
PAM_BAIL_P;
retval = pam_authenticate (pamh, 0);
PAM_BAIL_P (return false);
+#endif
/* must be authenticated if this point was reached */
return 1;
#else /* !USE_PAM */
@@ -382,11 +407,22 @@ modify_environment (const struct passwd
retval = pam_acct_mgmt (pamh, 0);
if (retval == PAM_NEW_AUTHTOK_REQD)
{
@@ -533,11 +552,22 @@ modify_environment (const struct passwd
/* Become the user and group(s) specified by PW. */
static void
-change_identity (const struct passwd *pw)
+change_identity (const struct passwd *pw
-init_groups (const struct passwd *pw)
+init_groups (const struct passwd *pw
+#ifdef RUNUSER
+ , gid_t *groups, int num_groups
+#endif
@ -193,44 +167,18 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
#ifdef HAVE_INITGROUPS
+ int rc = 0;
errno = 0;
- if (initgroups (pw->pw_name, pw->pw_gid) == -1) {
- 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) {
+ if (rc == -1)
{
#ifdef USE_PAM
pam_close_session(pamh, 0);
pam_end(pamh, PAM_ABORT);
@@ -433,7 +469,11 @@ pam_copyenv (pam_handle_t *pamh)
static void
run_shell (char const *shell, char const *command, char **additional_args,
- size_t n_additional_args, const struct passwd *pw)
+ size_t n_additional_args, const struct passwd *pw
+#ifdef RUNUSER
+ , gid_t *groups, int num_groups
+#endif
+ )
{
size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1;
char const **args = xnmalloc (n_args, sizeof *args);
@@ -464,7 +504,11 @@ run_shell (char const *shell, char const
child = fork();
if (child == 0) { /* child shell */
- change_identity (pw);
+ change_identity (pw
+#ifdef RUNUSER
+ , groups, num_groups
+#endif
+ );
pam_end(pamh, 0);
if (!same_session)
setsid ();
@@ -608,6 +652,28 @@ usage (int status)
cleanup_pam (PAM_ABORT);
@@ -639,6 +669,28 @@ usage (int status)
else
{
printf (_("Usage: %s [OPTION]... [-] [USER [ARG]...]\n"), program_name);
@ -259,7 +207,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
fputs (_("\
Change the effective user id and group id to that of USER.\n\
\n\
@@ -620,6 +686,7 @@ Change the effective user id and group i
@@ -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);
@ -267,7 +215,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
fputs (_("\
@@ -641,6 +708,12 @@ main (int argc, char **argv)
@@ -672,6 +725,12 @@ main (int argc, char **argv)
char *shell = NULL;
struct passwd *pw;
struct passwd pw_copy;
@ -280,7 +228,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
initialize_main (&argc, &argv);
set_program_name (argv[0]);
@@ -655,7 +728,11 @@ main (int argc, char **argv)
@@ -686,7 +745,11 @@ main (int argc, char **argv)
simulate_login = false;
change_environment = true;
@ -293,7 +241,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
{
switch (optc)
{
@@ -685,6 +762,28 @@ main (int argc, char **argv)
@@ -716,6 +779,28 @@ main (int argc, char **argv)
shell = optarg;
break;
@ -322,7 +270,7 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
case_GETOPT_HELP_CHAR;
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);
@@ -723,7 +822,20 @@ main (int argc, char **argv)
@@ -754,7 +839,20 @@ main (int argc, char **argv)
: DEFAULT_SHELL);
endpwent ();
@ -344,34 +292,23 @@ diff -urNp coreutils-8.1-orig/src/su.c coreutils-8.1/src/su.c
{
#ifdef SYSLOG_FAILURE
log_su (pw, false);
@@ -755,7 +867,11 @@ main (int argc, char **argv)
modify_environment (pw, shell);
@@ -784,7 +882,11 @@ main (int argc, char **argv)
}
shell = xstrdup (shell ? shell : pw->pw_shell);
#ifndef USE_PAM
- change_identity (pw);
+ change_identity (pw
- init_groups (pw);
+ init_groups (pw
+#ifdef RUNUSER
+ , groups, num_supp_groups
+#endif
+ );
#endif
+ );
/* error() flushes stderr, but does not check for write failure.
@@ -766,5 +882,9 @@ main (int argc, char **argv)
if (ferror (stderr))
exit (EXIT_CANCELED);
- run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw);
+ run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw
+#ifdef RUNUSER
+ , groups, num_supp_groups
+#endif
+ );
}
diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/help-version
--- coreutils-8.1-orig/tests/misc/help-version 2009-11-14 15:01:44.000000000 +0100
+++ coreutils-8.1/tests/misc/help-version 2009-11-20 13:06:26.000000000 +0100
@@ -34,6 +34,7 @@ expected_failure_status_nohup=125
#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
@ -379,7 +316,7 @@ diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/h
expected_failure_status_printenv=2
expected_failure_status_tty=3
expected_failure_status_sort=2
@@ -153,6 +154,7 @@ seq_args=10
@@ -209,6 +210,7 @@ seq_setup () { args=10; }
sleep_setup () { args=0; }
su_setup () { args=--version; }
stdbuf_setup () { args="-oL true"; }
@ -387,9 +324,9 @@ diff -urNp coreutils-8.1-orig/tests/misc/help-version coreutils-8.1/tests/misc/h
timeout_setup () { args=--version; }
# I'd rather not run sync, since it spins up disks that I've
diff -urNp coreutils-8.1-orig/tests/misc/invalid-opt coreutils-8.1/tests/misc/invalid-opt
--- coreutils-8.1-orig/tests/misc/invalid-opt 2009-10-26 10:05:25.000000000 +0100
+++ coreutils-8.1/tests/misc/invalid-opt 2009-11-20 13:06:26.000000000 +0100
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,

View File

@ -1,24 +1,6 @@
lib/linebuffer.h | 8 +
src/cut.c | 420 +++++++++++++++++++++++++--
src/expand.c | 160 ++++++++++-
src/fold.c | 309 ++++++++++++++++++--
src/join.c | 347 +++++++++++++++++++---
src/pr.c | 431 +++++++++++++++++++++++++---
src/sort.c | 722 +++++++++++++++++++++++++++++++++++++++++++---
src/unexpand.c | 226 ++++++++++++++-
src/uniq.c | 259 ++++++++++++++++-
tests/Makefile.am | 5 +
tests/misc/cut | 4 +-
tests/misc/mb1.I | 4 +
tests/misc/mb1.X | 4 +
tests/misc/mb2.I | 4 +
tests/misc/mb2.X | 4 +
tests/misc/sort-mb-tests | 58 ++++
16 files changed, 2783 insertions(+), 182 deletions(-)
diff -urNp coreutils-8.6-orig/lib/linebuffer.h coreutils-8.6/lib/linebuffer.h
--- coreutils-8.6-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200
+++ coreutils-8.6/lib/linebuffer.h 2010-10-18 15:18:11.932209034 +0200
diff -urNp coreutils-8.7-orig/lib/linebuffer.h coreutils-8.7/lib/linebuffer.h
--- coreutils-8.7-orig/lib/linebuffer.h 2010-06-10 18:45:26.000000000 +0200
+++ coreutils-8.7/lib/linebuffer.h 2010-11-15 09:59:36.974172148 +0100
@@ -21,6 +21,11 @@
# include <stdio.h>
@ -41,9 +23,9 @@ diff -urNp coreutils-8.6-orig/lib/linebuffer.h coreutils-8.6/lib/linebuffer.h
};
/* Initialize linebuffer LINEBUFFER for use. */
diff -urNp coreutils-8.6-orig/src/cut.c coreutils-8.6/src/cut.c
--- coreutils-8.6-orig/src/cut.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/cut.c 2010-10-18 15:18:11.933208545 +0200
diff -urNp coreutils-8.7-orig/src/cut.c coreutils-8.7/src/cut.c
--- coreutils-8.7-orig/src/cut.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/cut.c 2010-11-15 09:59:36.976171659 +0100
@@ -28,6 +28,11 @@
#include <assert.h>
#include <getopt.h>
@ -634,9 +616,9 @@ diff -urNp coreutils-8.6-orig/src/cut.c coreutils-8.6/src/cut.c
}
if (optind == argc)
diff -urNp coreutils-8.6-orig/src/expand.c coreutils-8.6/src/expand.c
--- coreutils-8.6-orig/src/expand.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/expand.c 2010-10-18 15:18:11.937209243 +0200
diff -urNp coreutils-8.7-orig/src/expand.c coreutils-8.7/src/expand.c
--- coreutils-8.7-orig/src/expand.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/expand.c 2010-11-15 09:59:36.977172637 +0100
@@ -38,12 +38,29 @@
#include <stdio.h>
#include <getopt.h>
@ -824,9 +806,9 @@ diff -urNp coreutils-8.6-orig/src/expand.c coreutils-8.6/src/expand.c
if (have_read_stdin && fclose (stdin) != 0)
error (EXIT_FAILURE, errno, "-");
diff -urNp coreutils-8.6-orig/src/fold.c coreutils-8.6/src/fold.c
--- coreutils-8.6-orig/src/fold.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/fold.c 2010-10-18 15:18:11.938208475 +0200
diff -urNp coreutils-8.7-orig/src/fold.c coreutils-8.7/src/fold.c
--- coreutils-8.7-orig/src/fold.c 2010-10-16 13:28:01.000000000 +0200
+++ coreutils-8.7/src/fold.c 2010-11-15 09:59:36.979181926 +0100
@@ -22,12 +22,34 @@
#include <getopt.h>
#include <sys/types.h>
@ -956,7 +938,7 @@ diff -urNp coreutils-8.6-orig/src/fold.c coreutils-8.6/src/fold.c
- return false;
- }
fadvise (stdin, FADVISE_SEQUENTIAL);
fadvise (istream, FADVISE_SEQUENTIAL);
@@ -171,6 +199,15 @@ fold_file (char const *filename, size_t
bool found_blank = false;
@ -1225,9 +1207,9 @@ diff -urNp coreutils-8.6-orig/src/fold.c coreutils-8.6/src/fold.c
break;
case 's': /* Break at word boundaries. */
diff -urNp coreutils-8.6-orig/src/join.c coreutils-8.6/src/join.c
--- coreutils-8.6-orig/src/join.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/join.c 2010-10-18 15:18:11.940208824 +0200
diff -urNp coreutils-8.7-orig/src/join.c coreutils-8.7/src/join.c
--- coreutils-8.7-orig/src/join.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/join.c 2010-11-15 09:59:36.980181716 +0100
@@ -22,18 +22,32 @@
#include <sys/types.h>
#include <getopt.h>
@ -1710,9 +1692,9 @@ diff -urNp coreutils-8.6-orig/src/join.c coreutils-8.6/src/join.c
break;
case NOCHECK_ORDER_OPTION:
diff -urNp coreutils-8.6-orig/src/pr.c coreutils-8.6/src/pr.c
--- coreutils-8.6-orig/src/pr.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/pr.c 2010-10-18 15:18:11.942208964 +0200
diff -urNp coreutils-8.7-orig/src/pr.c coreutils-8.7/src/pr.c
--- coreutils-8.7-orig/src/pr.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/pr.c 2010-11-15 09:59:36.983181856 +0100
@@ -312,6 +312,32 @@
#include <getopt.h>
@ -2435,10 +2417,9 @@ diff -urNp coreutils-8.6-orig/src/pr.c coreutils-8.6/src/pr.c
/* We've just printed some files and need to clean up things before
looking for more options and printing the next batch of files.
diff --git a/src/sort.c b/src/sort.c
index 7e25f6a..d3f8915 100644
--- a/src/sort.c
+++ b/src/sort.c
diff -urNp coreutils-8.7-orig/src/sort.c coreutils-8.7/src/sort.c
--- coreutils-8.7-orig/src/sort.c 2010-10-25 12:07:57.000000000 +0200
+++ coreutils-8.7/src/sort.c 2010-11-15 09:59:36.987932380 +0100
@@ -22,11 +22,20 @@
#include <config.h>
@ -2569,7 +2550,7 @@ index 7e25f6a..d3f8915 100644
static int
struct_month_cmp (void const *m1, void const *m2)
@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void const *m2)
@@ -1220,7 +1289,7 @@ struct_month_cmp (void const *m1, void c
/* Initialize the character class tables. */
static void
@ -2587,7 +2568,7 @@ index 7e25f6a..d3f8915 100644
/* If we're not in the "C" locale, read different names for months. */
if (hard_LC_TIME)
{
@@ -1314,6 +1383,84 @@ specify_nmerge (int oi, char c, char const *s)
@@ -1314,6 +1383,84 @@ specify_nmerge (int oi, char c, char con
xstrtol_fatal (e, oi, c, long_options, s);
}
@ -2672,7 +2653,7 @@ index 7e25f6a..d3f8915 100644
/* Specify the amount of main memory to use when sorting. */
static void
specify_sort_size (int oi, char c, char const *s)
@@ -1540,7 +1687,7 @@ buffer_linelim (struct buffer const *buf)
@@ -1540,7 +1687,7 @@ buffer_linelim (struct buffer const *buf
by KEY in LINE. */
static char *
@ -2681,7 +2662,7 @@ index 7e25f6a..d3f8915 100644
{
char *ptr = line->text, *lim = ptr + line->length - 1;
size_t sword = key->sword;
@@ -1549,10 +1696,10 @@ begfield (struct line const *line, struct keyfield const *key)
@@ -1549,10 +1696,10 @@ begfield (struct line const *line, struc
/* The leading field separator itself is included in a field when -t
is absent. */
@ -2694,7 +2675,7 @@ index 7e25f6a..d3f8915 100644
++ptr;
if (ptr < lim)
++ptr;
@@ -1578,11 +1725,70 @@ begfield (struct line const *line, struct keyfield const *key)
@@ -1578,11 +1725,70 @@ begfield (struct line const *line, struc
return ptr;
}
@ -2766,7 +2747,7 @@ index 7e25f6a..d3f8915 100644
{
char *ptr = line->text, *lim = ptr + line->length - 1;
size_t eword = key->eword, echar = key->echar;
@@ -1597,10 +1803,10 @@ limfield (struct line const *line, struct keyfield const *key)
@@ -1597,10 +1803,10 @@ limfield (struct line const *line, struc
`beginning' is the first character following the delimiting TAB.
Otherwise, leave PTR pointing at the first `blank' character after
the preceding field. */
@ -2779,7 +2760,7 @@ index 7e25f6a..d3f8915 100644
++ptr;
if (ptr < lim && (eword || echar))
++ptr;
@@ -1646,10 +1852,10 @@ limfield (struct line const *line, struct keyfield const *key)
@@ -1646,10 +1852,10 @@ limfield (struct line const *line, struc
*/
/* Make LIM point to the end of (one byte past) the current field. */
@ -2792,7 +2773,7 @@ index 7e25f6a..d3f8915 100644
if (newlim)
lim = newlim;
}
@@ -1680,6 +1886,130 @@ limfield (struct line const *line, struct keyfield const *key)
@@ -1680,6 +1886,130 @@ limfield (struct line const *line, struc
return ptr;
}
@ -2923,7 +2904,7 @@ index 7e25f6a..d3f8915 100644
/* Fill BUF reading from FP, moving buf->left bytes from the end
of buf->buf to the beginning first. If EOF is reached and the
file wasn't terminated by a newline, supply one. Set up BUF's line
@@ -1766,8 +2096,22 @@ fillbuf (struct buffer *buf, FILE *fp, char const *file)
@@ -1766,8 +2096,22 @@ fillbuf (struct buffer *buf, FILE *fp, c
else
{
if (key->skipsblanks)
@ -2948,7 +2929,7 @@ index 7e25f6a..d3f8915 100644
line->keybeg = line_start;
}
}
@@ -1888,7 +2232,7 @@ human_numcompare (char const *a, char const *b)
@@ -1888,7 +2232,7 @@ human_numcompare (char const *a, char co
hideously fast. */
static int
@ -2957,7 +2938,7 @@ index 7e25f6a..d3f8915 100644
{
while (blanks[to_uchar (*a)])
a++;
@@ -1898,6 +2242,25 @@ numcompare (char const *a, char const *b)
@@ -1898,6 +2242,25 @@ numcompare (char const *a, char const *b
return strnumcmp (a, b, decimal_point, thousands_sep);
}
@ -2983,7 +2964,7 @@ index 7e25f6a..d3f8915 100644
static int
general_numcompare (char const *sa, char const *sb)
{
@@ -1930,7 +2293,7 @@ general_numcompare (char const *sa, char const *sb)
@@ -1930,7 +2293,7 @@ general_numcompare (char const *sa, char
Return 0 if the name in S is not recognized. */
static int
@ -2992,7 +2973,7 @@ index 7e25f6a..d3f8915 100644
{
size_t lo = 0;
size_t hi = MONTHS_PER_YEAR;
@@ -2204,13 +2567,12 @@ debug_key (struct line const *line, struct keyfield const *key)
@@ -2204,13 +2567,12 @@ debug_key (struct line const *line, stru
{
char saved = *lim; *lim = '\0';
@ -3008,7 +2989,7 @@ index 7e25f6a..d3f8915 100644
else if (key->general_numeric)
ignore_value (strtold (beg, &tighter_lim));
else if (key->numeric || key->human_numeric)
@@ -2354,7 +2716,7 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
@@ -2354,7 +2716,7 @@ key_warnings (struct keyfield const *gke
bool maybe_space_aligned = !hard_LC_COLLATE && default_key_compare (key)
&& !(key->schar || key->echar);
bool line_offset = key->eword == 0 && key->echar != 0; /* -k1.x,1.y */
@ -3017,7 +2998,7 @@ index 7e25f6a..d3f8915 100644
&& ((!key->skipsblanks && !(implicit_skip || maybe_space_aligned))
|| (!key->skipsblanks && key->schar)
|| (!key->skipeblanks && key->echar)))
@@ -2412,11 +2774,83 @@ key_warnings (struct keyfield const *gkey, bool gkey_only)
@@ -2412,11 +2774,83 @@ key_warnings (struct keyfield const *gke
error (0, 0, _("option `-r' only applies to last-resort comparison"));
}
@ -3102,7 +3083,7 @@ index 7e25f6a..d3f8915 100644
{
struct keyfield *key = keylist;
@@ -2501,7 +2935,7 @@ keycompare (struct line const *a, struct line const *b)
@@ -2501,7 +2935,7 @@ keycompare (struct line const *a, struct
else if (key->human_numeric)
diff = human_numcompare (ta, tb);
else if (key->month)
@ -3111,7 +3092,7 @@ index 7e25f6a..d3f8915 100644
else if (key->random)
diff = compare_random (ta, tlena, tb, tlenb);
else if (key->version)
@@ -2617,6 +3051,179 @@ keycompare (struct line const *a, struct line const *b)
@@ -2617,6 +3051,179 @@ keycompare (struct line const *a, struct
return key->reverse ? -diff : diff;
}
@ -3384,9 +3365,9 @@ index 7e25f6a..d3f8915 100644
}
break;
diff -urNp coreutils-8.6-orig/src/unexpand.c coreutils-8.6/src/unexpand.c
--- coreutils-8.6-orig/src/unexpand.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/unexpand.c 2010-10-18 15:18:11.949208684 +0200
diff -urNp coreutils-8.7-orig/src/unexpand.c coreutils-8.7/src/unexpand.c
--- coreutils-8.7-orig/src/unexpand.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/unexpand.c 2010-11-15 09:59:36.989931891 +0100
@@ -39,12 +39,29 @@
#include <stdio.h>
#include <getopt.h>
@ -3640,9 +3621,9 @@ diff -urNp coreutils-8.6-orig/src/unexpand.c coreutils-8.6/src/unexpand.c
if (have_read_stdin && fclose (stdin) != 0)
error (EXIT_FAILURE, errno, "-");
diff -urNp coreutils-8.6-orig/src/uniq.c coreutils-8.6/src/uniq.c
--- coreutils-8.6-orig/src/uniq.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/uniq.c 2010-10-18 15:18:11.950208754 +0200
diff -urNp coreutils-8.7-orig/src/uniq.c coreutils-8.7/src/uniq.c
--- coreutils-8.7-orig/src/uniq.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/uniq.c 2010-11-15 09:59:36.992922043 +0100
@@ -21,6 +21,16 @@
#include <getopt.h>
#include <sys/types.h>
@ -4009,10 +3990,10 @@ diff -urNp coreutils-8.6-orig/src/uniq.c coreutils-8.6/src/uniq.c
skip_chars = 0;
skip_fields = 0;
check_chars = SIZE_MAX;
diff -urNp coreutils-8.6-orig/tests/Makefile.am coreutils-8.6/tests/Makefile.am
--- coreutils-8.6-orig/tests/Makefile.am 2010-10-18 15:17:40.112459208 +0200
+++ coreutils-8.6/tests/Makefile.am 2010-10-18 15:18:11.957208754 +0200
@@ -229,6 +229,7 @@ TESTS = \
diff -urNp coreutils-8.7-orig/tests/Makefile.am coreutils-8.7/tests/Makefile.am
--- coreutils-8.7-orig/tests/Makefile.am 2010-11-15 09:58:44.197937898 +0100
+++ coreutils-8.7/tests/Makefile.am 2010-11-15 09:59:36.993932170 +0100
@@ -231,6 +231,7 @@ TESTS = \
misc/sort-debug-keys \
misc/sort-debug-warn \
misc/sort-files0-from \
@ -4020,7 +4001,7 @@ diff -urNp coreutils-8.6-orig/tests/Makefile.am coreutils-8.6/tests/Makefile.am
misc/sort-float \
misc/sort-merge \
misc/sort-merge-fdlimit \
@@ -486,6 +487,10 @@ TESTS = \
@@ -490,6 +491,10 @@ TESTS = \
$(root_tests)
pr_data = \
@ -4031,9 +4012,9 @@ diff -urNp coreutils-8.6-orig/tests/Makefile.am coreutils-8.6/tests/Makefile.am
pr/0F \
pr/0FF \
pr/0FFnt \
diff -urNp coreutils-8.6-orig/tests/misc/cut coreutils-8.6/tests/misc/cut
--- coreutils-8.6-orig/tests/misc/cut 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/tests/misc/cut 2010-10-18 15:18:11.957208754 +0200
diff -urNp coreutils-8.7-orig/tests/misc/cut coreutils-8.7/tests/misc/cut
--- coreutils-8.7-orig/tests/misc/cut 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/tests/misc/cut 2010-11-15 09:59:36.994932100 +0100
@@ -26,7 +26,7 @@ use strict;
my $prog = 'cut';
my $try = "Try \`$prog --help' for more information.\n";
@ -4052,41 +4033,41 @@ diff -urNp coreutils-8.6-orig/tests/misc/cut coreutils-8.6/tests/misc/cut
['inval2', qw(-f -), {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
['inval3', '-f', '4,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
['inval4', '-f', '1-2,-', {IN=>''}, {OUT=>''}, {EXIT=>1}, {ERR=>$no_endpoint}],
diff -urNp coreutils-8.6-orig/tests/misc/mb1.I coreutils-8.6/tests/misc/mb1.I
--- coreutils-8.6-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.6/tests/misc/mb1.I 2010-10-18 15:18:11.958209243 +0200
diff -urNp coreutils-8.7-orig/tests/misc/mb1.I coreutils-8.7/tests/misc/mb1.I
--- coreutils-8.7-orig/tests/misc/mb1.I 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.7/tests/misc/mb1.I 2010-11-15 09:59:36.995931961 +0100
@@ -0,0 +1,4 @@
+Apple10
+Banana5
+Citrus20
+Cherry30
diff -urNp coreutils-8.6-orig/tests/misc/mb1.X coreutils-8.6/tests/misc/mb1.X
--- coreutils-8.6-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.6/tests/misc/mb1.X 2010-10-18 15:18:11.958209243 +0200
diff -urNp coreutils-8.7-orig/tests/misc/mb1.X coreutils-8.7/tests/misc/mb1.X
--- coreutils-8.7-orig/tests/misc/mb1.X 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.7/tests/misc/mb1.X 2010-11-15 09:59:36.995931961 +0100
@@ -0,0 +1,4 @@
+Banana5
+Apple10
+Citrus20
+Cherry30
diff -urNp coreutils-8.6-orig/tests/misc/mb2.I coreutils-8.6/tests/misc/mb2.I
--- coreutils-8.6-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.6/tests/misc/mb2.I 2010-10-18 15:18:11.959208405 +0200
diff -urNp coreutils-8.7-orig/tests/misc/mb2.I coreutils-8.7/tests/misc/mb2.I
--- coreutils-8.7-orig/tests/misc/mb2.I 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.7/tests/misc/mb2.I 2010-11-15 09:59:36.996933777 +0100
@@ -0,0 +1,4 @@
+Apple1020
+Banana530
+Citrus205
+Cherry3010
diff -urNp coreutils-8.6-orig/tests/misc/mb2.X coreutils-8.6/tests/misc/mb2.X
--- coreutils-8.6-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.6/tests/misc/mb2.X 2010-10-18 15:18:11.960208894 +0200
diff -urNp coreutils-8.7-orig/tests/misc/mb2.X coreutils-8.7/tests/misc/mb2.X
--- coreutils-8.7-orig/tests/misc/mb2.X 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.7/tests/misc/mb2.X 2010-11-15 09:59:36.997922462 +0100
@@ -0,0 +1,4 @@
+Citrus205
+Cherry3010
+Apple1020
+Banana530
diff -urNp coreutils-8.6-orig/tests/misc/sort-mb-tests coreutils-8.6/tests/misc/sort-mb-tests
--- coreutils-8.6-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.6/tests/misc/sort-mb-tests 2010-10-18 15:18:11.960208894 +0200
diff -urNp coreutils-8.7-orig/tests/misc/sort-mb-tests coreutils-8.7/tests/misc/sort-mb-tests
--- coreutils-8.7-orig/tests/misc/sort-mb-tests 1970-01-01 01:00:00.000000000 +0100
+++ coreutils-8.7/tests/misc/sort-mb-tests 2010-11-15 09:59:36.997922462 +0100
@@ -0,0 +1,58 @@
+#! /bin/sh
+case $# in

View File

@ -1,428 +0,0 @@
diff -urNp coreutils-8.4-orig/configure.ac coreutils-8.4/configure.ac
--- coreutils-8.4-orig/configure.ac 2010-01-11 18:20:42.000000000 +0100
+++ coreutils-8.4/configure.ac 2010-02-12 10:17:46.000000000 +0100
@@ -126,6 +126,13 @@ if test "$gl_gcc_warnings" = yes; then
AC_SUBST([GNULIB_TEST_WARN_CFLAGS])
fi
+dnl Give the chance to enable PAM
+AC_ARG_ENABLE(pam, dnl
+[ --enable-pam Enable use of the PAM libraries],
+[AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM])
+LIB_PAM="-ldl -lpam -lpam_misc"
+AC_SUBST(LIB_PAM)])
+
AC_FUNC_FORK
optional_bin_progs=
diff -urNp coreutils-8.4-orig/doc/coreutils.texi coreutils-8.4/doc/coreutils.texi
--- coreutils-8.4-orig/doc/coreutils.texi 2010-01-03 18:06:20.000000000 +0100
+++ coreutils-8.4/doc/coreutils.texi 2010-02-12 10:17:46.000000000 +0100
@@ -15081,8 +15081,11 @@ to certain shells, etc.).
@findex syslog
@command{su} can optionally be compiled to use @code{syslog} to report
failed, and optionally successful, @command{su} attempts. (If the system
-supports @code{syslog}.) However, GNU @command{su} does not check if the
-user is a member of the @code{wheel} group; see below.
+supports @code{syslog}.)
+
+This version of @command{su} has support for using PAM for
+authentication. You can edit @file{/etc/pam.d/su} to customize its
+behaviour.
The program accepts the following options. Also see @ref{Common options}.
@@ -15124,6 +15127,8 @@ environment variables except @env{TERM},
@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).
+Additionaly @env{DISPLAY} and @env{XAUTHORITY} environment variables
+are preserved as well for PAM functionality.
@item -m
@itemx -p
@@ -15163,33 +15168,6 @@ Exit status:
the exit status of the subshell otherwise
@end display
-@cindex wheel group, not supported
-@cindex group wheel, not supported
-@cindex fascism
-@subsection Why GNU @command{su} does not support the @samp{wheel} group
-
-(This section is by Richard Stallman.)
-
-@cindex Twenex
-@cindex MIT AI lab
-Sometimes a few of the users try to hold total power over all the
-rest. For example, in 1984, a few users at the MIT AI lab decided to
-seize power by changing the operator password on the Twenex system and
-keeping it secret from everyone else. (I was able to thwart this coup
-and give power back to the users by patching the kernel, but I
-wouldn't know how to do that in Unix.)
-
-However, occasionally the rulers do tell someone. Under the usual
-@command{su} mechanism, once someone learns the root password who
-sympathizes with the ordinary users, he or she can tell the rest. The
-``wheel group'' feature would make this impossible, and thus cement the
-power of the rulers.
-
-I'm on the side of the masses, not that of the rulers. If you are
-used to supporting the bosses and sysadmins in whatever they do, you
-might find this idea strange at first.
-
-
@node timeout invocation
@section @command{timeout}: Run a command with a time limit
diff -urNp coreutils-8.4-orig/src/Makefile.am coreutils-8.4/src/Makefile.am
--- coreutils-8.4-orig/src/Makefile.am 2010-01-03 18:06:20.000000000 +0100
+++ coreutils-8.4/src/Makefile.am 2010-02-12 10:17:46.000000000 +0100
@@ -361,7 +361,7 @@ factor_LDADD += $(LIB_GMP)
uptime_LDADD += $(GETLOADAVG_LIBS)
# for crypt
-su_LDADD += $(LIB_CRYPT)
+su_LDADD += $(LIB_CRYPT) @LIB_PAM@
# for various ACL functions
copy_LDADD += $(LIB_ACL)
diff -urNp coreutils-8.4-orig/src/su.c coreutils-8.4/src/su.c
--- coreutils-8.4-orig/src/su.c 2010-02-12 10:15:15.000000000 +0100
+++ coreutils-8.4/src/su.c 2010-02-12 10:24:29.000000000 +0100
@@ -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.conf
+
+#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.
@@ -53,6 +63,15 @@
#include <pwd.h>
#include <grp.h>
+#ifdef USE_PAM
+# include <signal.h>
+# include <sys/wait.h>
+# include <sys/fsuid.h>
+# include <unistd.h>
+# include <security/pam_appl.h>
+# include <security/pam_misc.h>
+#endif /* USE_PAM */
+
#include "system.h"
#include "getpass.h"
@@ -120,10 +139,17 @@
/* 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)
+static void run_shell (char const *, char const *, char **, size_t,
+ const struct passwd *)
+#ifdef USE_PAM
+ ;
+#else
ATTRIBUTE_NORETURN;
+#endif
/* If true, pass the `-f' option to the subshell. */
static bool fast_startup;
@@ -209,7 +235,26 @@ log_su (struct passwd const *pw, bool su
}
#endif
+#ifdef USE_PAM
+static pam_handle_t *pamh = NULL;
+static int retval;
+static struct pam_conv conv = {
+ misc_conv,
+ NULL
+};
+
+#define PAM_BAIL_P if (retval) { \
+ pam_end(pamh, PAM_SUCCESS); \
+ return 0; \
+}
+#define PAM_BAIL_P_VOID if (retval) { \
+ pam_end(pamh, PAM_SUCCESS); \
+return; \
+}
+#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. */
@@ -217,6 +262,44 @@ log_su (struct passwd const *pw, bool su
static bool
correct_password (const struct passwd *pw)
{
+#ifdef USE_PAM
+ struct passwd *caller;
+ char *tty_name, *ttyn;
+ retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh);
+ PAM_BAIL_P;
+
+ if (getuid() != 0 && !isatty(0)) {
+ fprintf(stderr, "standard in must be a tty\n");
+ exit(1);
+ }
+
+ caller = getpwuid(getuid());
+ if(caller != NULL && caller->pw_name != NULL) {
+ retval = pam_set_item(pamh, PAM_RUSER, caller->pw_name);
+ PAM_BAIL_P;
+ }
+
+ ttyn = ttyname(0);
+ if (ttyn) {
+ if (strncmp(ttyn, "/dev/", 5) == 0)
+ tty_name = ttyn+5;
+ else
+ tty_name = ttyn;
+ retval = pam_set_item(pamh, PAM_TTY, tty_name);
+ PAM_BAIL_P;
+ }
+ retval = pam_authenticate(pamh, 0);
+ PAM_BAIL_P;
+ 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;
+ }
+ PAM_BAIL_P;
+ /* must be authenticated if this point was reached */
+ return 1;
+#else /* !USE_PAM */
char *unencrypted, *encrypted, *correct;
#if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP
/* Shadow passwd stuff for SVR3 and maybe other systems. */
@@ -241,6 +324,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
@@ -254,12 +338,18 @@ modify_environment (const struct passwd
/* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
Unset all other environment variables. */
char const *term = getenv ("TERM");
+ char const *display = getenv ("DISPLAY");
+ char const *xauthority = getenv ("XAUTHORITY");
if (term)
term = xstrdup (term);
environ = xmalloc ((6 + !!term) * sizeof (char *));
environ[0] = NULL;
if (term)
xsetenv ("TERM", term);
+ if (display)
+ xsetenv ("DISPLAY", display);
+ if (xauthority)
+ xsetenv ("XAUTHORITY", xauthority);
xsetenv ("HOME", pw->pw_dir);
xsetenv ("SHELL", shell);
xsetenv ("USER", pw->pw_name);
@@ -292,8 +382,13 @@ change_identity (const struct passwd *pw
{
#ifdef HAVE_INITGROUPS
errno = 0;
- if (initgroups (pw->pw_name, pw->pw_gid) == -1)
+ if (initgroups (pw->pw_name, pw->pw_gid) == -1) {
+#ifdef USE_PAM
+ pam_close_session(pamh, 0);
+ pam_end(pamh, PAM_ABORT);
+#endif
error (EXIT_CANCELED, errno, _("cannot set groups"));
+ }
endgrent ();
#endif
if (setgid (pw->pw_gid))
@@ -302,6 +397,31 @@ change_identity (const struct passwd *pw
error (EXIT_CANCELED, errno, _("cannot set user id"));
}
+#ifdef USE_PAM
+static int caught=0;
+/* Signal handler for parent process later */
+static void su_catch_sig(int sig)
+{
+ ++caught;
+}
+
+int
+pam_copyenv (pam_handle_t *pamh)
+{
+ char **env;
+
+ env = pam_getenvlist(pamh);
+ if(env) {
+ while(*env) {
+ if (putenv (*env))
+ xalloc_die ();
+ env++;
+ }
+ }
+ return(0);
+}
+#endif
+
/* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
If COMMAND is nonzero, pass it to the shell with the -c option.
Pass ADDITIONAL_ARGS to the shell as more arguments; there
@@ -309,17 +429,49 @@ change_identity (const struct passwd *pw
static void
run_shell (char const *shell, char const *command, char **additional_args,
- size_t n_additional_args)
+ size_t n_additional_args, const struct passwd *pw)
{
size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1;
char const **args = xnmalloc (n_args, sizeof *args);
size_t argno = 1;
+#ifdef USE_PAM
+ int child;
+ sigset_t ourset;
+ int status;
+
+ retval = pam_open_session(pamh,0);
+ if (retval != PAM_SUCCESS) {
+ fprintf (stderr, "could not open session\n");
+ exit (1);
+ }
+
+/* do this at the last possible moment, because environment variables may
+ be passed even in the session phase
+*/
+ if(pam_copyenv(pamh) != PAM_SUCCESS)
+ fprintf (stderr, "error copying PAM environment\n");
+
+ /* Credentials should be set in the parent */
+ if (pam_setcred(pamh, PAM_ESTABLISH_CRED) != PAM_SUCCESS) {
+ pam_close_session(pamh, 0);
+ fprintf(stderr, "could not set PAM credentials\n");
+ exit(1);
+ }
+
+ child = fork();
+ if (child == 0) { /* child shell */
+ change_identity (pw);
+ pam_end(pamh, 0);
+#endif
if (simulate_login)
{
char *arg0;
char *shell_basename;
+ if(chdir(pw->pw_dir))
+ error(0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);
+
shell_basename = last_component (shell);
arg0 = xmalloc (strlen (shell_basename) + 2);
arg0[0] = '-';
@@ -344,6 +496,67 @@ run_shell (char const *shell, char const
error (0, errno, "%s", shell);
exit (exit_status);
}
+#ifdef USE_PAM
+ } else if (child == -1) {
+ fprintf(stderr, "can not fork user shell: %s", strerror(errno));
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
+ pam_close_session(pamh, 0);
+ pam_end(pamh, PAM_ABORT);
+ exit(1);
+ }
+ /* parent only */
+ sigfillset(&ourset);
+ if (sigprocmask(SIG_BLOCK, &ourset, NULL)) {
+ fprintf(stderr, "%s: signal malfunction\n", PROGRAM_NAME);
+ caught = 1;
+ }
+ if (!caught) {
+ 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)) {
+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME);
+ caught = 1;
+ }
+ }
+ if (!caught) {
+ do {
+ int pid;
+
+ pid = waitpid(-1, &status, WUNTRACED);
+
+ if (((pid_t)-1 != pid) && (0 != WIFSTOPPED (status))) {
+ kill(getpid(), WSTOPSIG(status));
+ /* once we get here, we must have resumed */
+ kill(pid, SIGCONT);
+ }
+ } while (0 != WIFSTOPPED(status));
+ }
+
+ if (caught) {
+ fprintf(stderr, "\nSession terminated, killing shell...");
+ kill (child, SIGTERM);
+ }
+ /* Not checking retval on this because we need to call close session */
+ pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT);
+ retval = pam_close_session(pamh, 0);
+ PAM_BAIL_P_VOID;
+ retval = pam_end(pamh, PAM_SUCCESS);
+ PAM_BAIL_P_VOID;
+ if (caught) {
+ sleep(2);
+ kill(child, SIGKILL);
+ fprintf(stderr, " ...killed.\n");
+ exit(-1);
+ }
+ exit ((0 != WIFEXITED (status)) ? WEXITSTATUS (status)
+ : WTERMSIG (status) + 128);
+#endif /* USE_PAM */
}
/* Return true if SHELL is a restricted shell (one not returned by
@@ -511,9 +724,9 @@ main (int argc, char **argv)
shell = xstrdup (shell ? shell : pw->pw_shell);
modify_environment (pw, shell);
+#ifndef USE_PAM
change_identity (pw);
- if (simulate_login && chdir (pw->pw_dir) != 0)
- error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);
+#endif
/* error() flushes stderr, but does not check for write failure.
Normally, we would catch this via our atexit() hook of
@@ -523,5 +736,5 @@ main (int argc, char **argv)
if (ferror (stderr))
exit (EXIT_CANCELED);
- run_shell (shell, command, argv + optind, MAX (0, argc - optind));
+ run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw);
}

View File

@ -1,9 +1,9 @@
diff -urNp coreutils-8.6-orig/configure.ac coreutils-8.6/configure.ac
--- coreutils-8.6-orig/configure.ac 2010-10-18 13:46:01.319460047 +0200
+++ coreutils-8.6/configure.ac 2010-10-18 14:36:46.348209592 +0200
@@ -140,6 +140,13 @@ AC_ARG_ENABLE(pam, dnl
LIB_PAM="-ldl -lpam -lpam_misc"
AC_SUBST(LIB_PAM)])
diff -urNp coreutils-8.7-orig/configure.ac coreutils-8.7/configure.ac
--- coreutils-8.7-orig/configure.ac 2010-11-15 10:03:39.636171519 +0100
+++ coreutils-8.7/configure.ac 2010-11-15 10:04:08.161930423 +0100
@@ -133,6 +133,13 @@ if test "$gl_gcc_warnings" = yes; then
AC_SUBST([GNULIB_TEST_WARN_CFLAGS])
fi
+dnl Give the chance to enable SELINUX
+AC_ARG_ENABLE(selinux, dnl
@ -14,19 +14,19 @@ diff -urNp coreutils-8.6-orig/configure.ac coreutils-8.6/configure.ac
+
AC_FUNC_FORK
optional_bin_progs=
diff -urNp coreutils-8.6-orig/man/chcon.x coreutils-8.6/man/chcon.x
--- coreutils-8.6-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200
+++ coreutils-8.6/man/chcon.x 2010-10-18 14:36:46.348209592 +0200
AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam],
diff -urNp coreutils-8.7-orig/man/chcon.x coreutils-8.7/man/chcon.x
--- coreutils-8.7-orig/man/chcon.x 2009-09-01 13:01:16.000000000 +0200
+++ coreutils-8.7/man/chcon.x 2010-11-15 10:04:08.161930423 +0100
@@ -1,4 +1,4 @@
[NAME]
-chcon \- change file security context
+chcon \- change file SELinux security context
[DESCRIPTION]
.\" Add any additional description here
diff -urNp coreutils-8.6-orig/man/runcon.x coreutils-8.6/man/runcon.x
--- coreutils-8.6-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200
+++ coreutils-8.6/man/runcon.x 2010-10-18 14:36:46.349211548 +0200
diff -urNp coreutils-8.7-orig/man/runcon.x coreutils-8.7/man/runcon.x
--- coreutils-8.7-orig/man/runcon.x 2009-09-01 13:01:16.000000000 +0200
+++ coreutils-8.7/man/runcon.x 2010-11-15 10:04:08.162922322 +0100
@@ -1,5 +1,5 @@
[NAME]
-runcon \- run command with specified security context
@ -34,10 +34,10 @@ diff -urNp coreutils-8.6-orig/man/runcon.x coreutils-8.6/man/runcon.x
[DESCRIPTION]
Run COMMAND with completely-specified CONTEXT, or with current or
transitioned security context modified by one or more of LEVEL,
diff -urNp coreutils-8.6-orig/src/copy.c coreutils-8.6/src/copy.c
--- coreutils-8.6-orig/src/copy.c 2010-10-12 13:13:16.000000000 +0200
+++ coreutils-8.6/src/copy.c 2010-10-18 14:36:46.350209243 +0200
@@ -1923,6 +1923,8 @@ copy_internal (char const *src_name, cha
diff -urNp coreutils-8.7-orig/src/copy.c coreutils-8.7/src/copy.c
--- coreutils-8.7-orig/src/copy.c 2010-10-28 12:31:17.000000000 +0200
+++ coreutils-8.7/src/copy.c 2010-11-15 10:04:08.165921553 +0100
@@ -1924,6 +1924,8 @@ copy_internal (char const *src_name, cha
{
/* Here, we are crossing a file system boundary and cp's -x option
is in effect: so don't copy the contents of this directory. */
@ -46,9 +46,9 @@ diff -urNp coreutils-8.6-orig/src/copy.c coreutils-8.6/src/copy.c
}
else
{
diff -urNp coreutils-8.6-orig/src/copy.h coreutils-8.6/src/copy.h
--- coreutils-8.6-orig/src/copy.h 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/copy.h 2010-10-18 14:36:46.352209243 +0200
diff -urNp coreutils-8.7-orig/src/copy.h coreutils-8.7/src/copy.h
--- coreutils-8.7-orig/src/copy.h 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/copy.h 2010-11-15 10:04:08.166925814 +0100
@@ -158,6 +158,9 @@ struct cp_options
bool preserve_mode;
bool preserve_timestamps;
@ -59,9 +59,9 @@ diff -urNp coreutils-8.6-orig/src/copy.h coreutils-8.6/src/copy.h
/* Enabled for mv, and for cp by the --preserve=links option.
If true, attempt to preserve in the destination files any
logical hard links between the source files. If used with cp's
diff -urNp coreutils-8.6-orig/src/cp.c coreutils-8.6/src/cp.c
--- coreutils-8.6-orig/src/cp.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/cp.c 2010-10-18 14:36:46.353209453 +0200
diff -urNp coreutils-8.7-orig/src/cp.c coreutils-8.7/src/cp.c
--- coreutils-8.7-orig/src/cp.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/cp.c 2010-11-15 10:04:08.168931890 +0100
@@ -141,6 +141,7 @@ static struct option const long_opts[] =
{"target-directory", required_argument, NULL, 't'},
{"update", no_argument, NULL, 'u'},
@ -150,9 +150,9 @@ diff -urNp coreutils-8.6-orig/src/cp.c coreutils-8.6/src/cp.c
case 'S':
make_backups = true;
backup_suffix_string = optarg;
diff -urNp coreutils-8.6-orig/src/chcon.c coreutils-8.6/src/chcon.c
--- coreutils-8.6-orig/src/chcon.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/chcon.c 2010-10-18 14:36:46.356209523 +0200
diff -urNp coreutils-8.7-orig/src/chcon.c coreutils-8.7/src/chcon.c
--- coreutils-8.7-orig/src/chcon.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/chcon.c 2010-11-15 10:04:08.169922391 +0100
@@ -356,7 +356,7 @@ Usage: %s [OPTION]... CONTEXT FILE...\n\
"),
program_name, program_name, program_name);
@ -162,9 +162,9 @@ diff -urNp coreutils-8.6-orig/src/chcon.c coreutils-8.6/src/chcon.c
With --reference, change the security context of each FILE to that of RFILE.\n\
\n\
-h, --no-dereference affect symbolic links instead of any referenced file\n\
diff -urNp coreutils-8.6-orig/src/id.c coreutils-8.6/src/id.c
--- coreutils-8.6-orig/src/id.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/id.c 2010-10-18 14:36:46.357221466 +0200
diff -urNp coreutils-8.7-orig/src/id.c coreutils-8.7/src/id.c
--- coreutils-8.7-orig/src/id.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/id.c 2010-11-15 10:04:08.170933217 +0100
@@ -107,7 +107,7 @@ int
main (int argc, char **argv)
{
@ -174,9 +174,9 @@ diff -urNp coreutils-8.6-orig/src/id.c coreutils-8.6/src/id.c
/* If true, output the list of all group IDs. -G */
bool just_group_list = false;
diff -urNp coreutils-8.6-orig/src/install.c coreutils-8.6/src/install.c
--- coreutils-8.6-orig/src/install.c 2010-10-14 08:20:20.000000000 +0200
+++ coreutils-8.6/src/install.c 2010-10-18 14:36:46.358209103 +0200
diff -urNp coreutils-8.7-orig/src/install.c coreutils-8.7/src/install.c
--- coreutils-8.7-orig/src/install.c 2010-10-15 21:56:29.000000000 +0200
+++ coreutils-8.7/src/install.c 2010-11-15 10:04:08.171921693 +0100
@@ -283,6 +283,7 @@ cp_option_init (struct cp_options *x)
x->data_copy_required = true;
x->require_preserve = false;
@ -232,9 +232,9 @@ diff -urNp coreutils-8.6-orig/src/install.c coreutils-8.6/src/install.c
"), stdout);
fputs (HELP_OPTION_DESCRIPTION, stdout);
diff -urNp coreutils-8.6-orig/src/ls.c coreutils-8.6/src/ls.c
--- coreutils-8.6-orig/src/ls.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/ls.c 2010-10-18 14:36:46.361209872 +0200
diff -urNp coreutils-8.7-orig/src/ls.c coreutils-8.7/src/ls.c
--- coreutils-8.7-orig/src/ls.c 2010-10-25 12:07:57.000000000 +0200
+++ coreutils-8.7/src/ls.c 2010-11-15 10:04:08.175921763 +0100
@@ -159,7 +159,8 @@ enum filetype
symbolic_link,
sock,
@ -597,9 +597,9 @@ diff -urNp coreutils-8.6-orig/src/ls.c coreutils-8.6/src/ls.c
fputs (HELP_OPTION_DESCRIPTION, stdout);
fputs (VERSION_OPTION_DESCRIPTION, stdout);
emit_size_note ();
diff -urNp coreutils-8.6-orig/src/mkdir.c coreutils-8.6/src/mkdir.c
--- coreutils-8.6-orig/src/mkdir.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/mkdir.c 2010-10-18 14:36:46.363209243 +0200
diff -urNp coreutils-8.7-orig/src/mkdir.c coreutils-8.7/src/mkdir.c
--- coreutils-8.7-orig/src/mkdir.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/mkdir.c 2010-11-15 10:04:08.177942716 +0100
@@ -38,6 +38,7 @@
static struct option const longopts[] =
{
@ -608,9 +608,9 @@ diff -urNp coreutils-8.6-orig/src/mkdir.c coreutils-8.6/src/mkdir.c
{"mode", required_argument, NULL, 'm'},
{"parents", no_argument, NULL, 'p'},
{"verbose", no_argument, NULL, 'v'},
diff -urNp coreutils-8.6-orig/src/mknod.c coreutils-8.6/src/mknod.c
--- coreutils-8.6-orig/src/mknod.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/mknod.c 2010-10-18 14:36:46.363209243 +0200
diff -urNp coreutils-8.7-orig/src/mknod.c coreutils-8.7/src/mknod.c
--- coreutils-8.7-orig/src/mknod.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/mknod.c 2010-11-15 10:04:08.177942716 +0100
@@ -35,7 +35,7 @@
static struct option const longopts[] =
@ -620,9 +620,9 @@ diff -urNp coreutils-8.6-orig/src/mknod.c coreutils-8.6/src/mknod.c
{"mode", required_argument, NULL, 'm'},
{GETOPT_HELP_OPTION_DECL},
{GETOPT_VERSION_OPTION_DECL},
diff -urNp coreutils-8.6-orig/src/mv.c coreutils-8.6/src/mv.c
--- coreutils-8.6-orig/src/mv.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/mv.c 2010-10-18 14:36:46.364217485 +0200
diff -urNp coreutils-8.7-orig/src/mv.c coreutils-8.7/src/mv.c
--- coreutils-8.7-orig/src/mv.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/mv.c 2010-11-15 10:04:08.179924138 +0100
@@ -118,6 +118,7 @@ cp_option_init (struct cp_options *x)
x->preserve_mode = true;
x->preserve_timestamps = true;
@ -631,9 +631,9 @@ diff -urNp coreutils-8.6-orig/src/mv.c coreutils-8.6/src/mv.c
x->reduce_diagnostics = false;
x->data_copy_required = true;
x->require_preserve = false; /* FIXME: maybe make this an option */
diff -urNp coreutils-8.6-orig/src/runcon.c coreutils-8.6/src/runcon.c
--- coreutils-8.6-orig/src/runcon.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/src/runcon.c 2010-10-18 14:36:46.365209103 +0200
diff -urNp coreutils-8.7-orig/src/runcon.c coreutils-8.7/src/runcon.c
--- coreutils-8.7-orig/src/runcon.c 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/src/runcon.c 2010-11-15 10:04:08.180922252 +0100
@@ -86,7 +86,7 @@ Usage: %s CONTEXT COMMAND [args]\n\
or: %s [ -c ] [-u USER] [-r ROLE] [-t TYPE] [-l RANGE] COMMAND [args]\n\
"), program_name, program_name);
@ -643,10 +643,10 @@ diff -urNp coreutils-8.6-orig/src/runcon.c coreutils-8.6/src/runcon.c
With neither CONTEXT nor COMMAND, print the current security context.\n\
\n\
CONTEXT Complete security context\n\
diff -urNp coreutils-8.6-orig/tests/init.cfg coreutils-8.6/tests/init.cfg
--- coreutils-8.6-orig/tests/init.cfg 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/tests/init.cfg 2010-10-18 13:49:14.383904033 +0200
@@ -214,8 +214,8 @@ skip_if_()
diff -urNp coreutils-8.7-orig/tests/init.cfg coreutils-8.7/tests/init.cfg
--- coreutils-8.7-orig/tests/init.cfg 2010-11-08 14:10:20.000000000 +0100
+++ coreutils-8.7/tests/init.cfg 2010-11-15 10:04:08.181922042 +0100
@@ -216,8 +216,8 @@ skip_if_()
require_selinux_()
{
@ -657,9 +657,9 @@ diff -urNp coreutils-8.6-orig/tests/init.cfg coreutils-8.6/tests/init.cfg
skip_test_ "this system (or maybe just" \
"the current file system) lacks SELinux support"
;;
diff -urNp coreutils-8.6-orig/tests/misc/selinux coreutils-8.6/tests/misc/selinux
--- coreutils-8.6-orig/tests/misc/selinux 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.6/tests/misc/selinux 2010-10-18 14:36:46.365209103 +0200
diff -urNp coreutils-8.7-orig/tests/misc/selinux coreutils-8.7/tests/misc/selinux
--- coreutils-8.7-orig/tests/misc/selinux 2010-10-11 19:35:11.000000000 +0200
+++ coreutils-8.7/tests/misc/selinux 2010-11-15 10:04:08.181922042 +0100
@@ -44,7 +44,7 @@ chcon $ctx f d p ||
# inspect that context with both ls -Z and stat.

View File

@ -1,12 +1,17 @@
--- coreutils-6.7/src/su.c.setsid 2007-01-09 17:26:26.000000000 +0000
+++ coreutils-6.7/src/su.c 2007-01-09 17:26:57.000000000 +0000
@@ -176,9 +176,13 @@
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'},
@ -14,48 +19,40 @@
{"fast", no_argument, NULL, 'f'},
{"login", no_argument, NULL, 'l'},
{"preserve-environment", no_argument, NULL, 'p'},
@@ -478,6 +482,8 @@
if (child == 0) { /* child shell */
change_identity (pw);
pam_end(pamh, 0);
+ if (!same_session)
+ setsid ();
#endif
if (simulate_login)
@@ -532,13 +538,27 @@
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)) {
@@ -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))
+ {
+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME);
+ caught = 1;
+ error (0, errno, _("cannot set signal handler"));
+ caught_signal = true;
+ }
+ }
+ if (!caught && (sigaddset(&ourset, SIGTERM)
+ if (!caught_signal && (sigaddset(&ourset, SIGTERM)
+ || sigaddset(&ourset, SIGALRM)
+ || sigaction(SIGTERM, &action, NULL)
+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL))) {
fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME);
caught = 1;
}
+ if (!caught && !same_session && (sigaction(SIGINT, &action, NULL)
error (0, errno, _("cannot set signal handler"));
caught_signal = true;
}
+ if (!caught_signal && !same_session && (sigaction(SIGINT, &action, NULL)
+ || sigaction(SIGQUIT, &action, NULL)))
+ {
+ fprintf(stderr, "%s: signal masking malfunction\n", PROGRAM_NAME);
+ caught = 1;
+ error (0, errno, _("cannot set signal handler"));
+ caught_signal = true;
+ }
}
if (!caught) {
do {
@@ -609,6 +629,8 @@
}
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\
@ -64,7 +61,7 @@
-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\
@@ -631,6 +653,7 @@
@@ -649,6 +668,7 @@ main (int argc, char **argv)
int optc;
const char *new_user = DEFAULT_USER;
char *command = NULL;
@ -72,7 +69,7 @@
char *shell = NULL;
struct passwd *pw;
struct passwd pw_copy;
@@ -656,6 +679,11 @@
@@ -674,6 +694,11 @@ main (int argc, char **argv)
command = optarg;
break;
@ -84,7 +81,7 @@
case 'f':
fast_startup = true;
break;
@@ -725,6 +753,9 @@
@@ -743,6 +768,9 @@ main (int argc, char **argv)
}
#endif
@ -94,3 +91,12 @@
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,57 +0,0 @@
diff -uNrp -x '*~' coreutils-5.97-orig/src/su.c coreutils-5.97/src/su.c
--- coreutils-5.97-orig/src/su.c 2006-07-13 12:14:40.000000000 +0100
+++ coreutils-5.97/src/su.c 2006-07-13 12:24:33.000000000 +0100
@@ -131,11 +131,15 @@
#include "error.h"
-/* The official name of this program (e.g., no `g' prefix). */
+/* The official name of this program (e.g., no `g' prefix).
+ * - Add a "-l" to the name passed to PAM if this is a login simulation
+ */
#ifndef RUNUSER
#define PROGRAM_NAME "su"
+#define PROGRAM_NAME_L "su-l"
#else
#define PROGRAM_NAME "runuser"
+#define PROGRAM_NAME_L "runuser-l"
#endif
#ifndef AUTHORS
@@ -310,7 +314,8 @@ correct_password (const struct passwd *p
#ifdef USE_PAM
struct passwd *caller;
char *tty_name, *ttyn;
- retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh);
+ retval = pam_start(simulate_login ? PROGRAM_NAME_L : PROGRAM_NAME,
+ pw->pw_name, &conv, &pamh);
PAM_BAIL_P;
#ifndef RUNUSER
diff -urp coreutils-6.10-orig/doc/coreutils.info coreutils-6.10/doc/coreutils.info
--- coreutils-6.10-orig/doc/coreutils.info 2008-01-22 00:32:44.000000000 +0100
+++ coreutils-6.10/doc/coreutils.info 2008-01-24 17:17:04.000000000 +0100
@@ -11006,7 +11006,8 @@ options::.
set, even for the super-user, as described above), and set `PATH'
to a compiled-in default value. Change to USER's home directory.
Prepend `-' to the shell's name, intended to make it read its
- login startup file(s).
+ login startup file(s). When this option is given, /etc/pam.d/su-l
+ PAM file is used instead of the default one.
`-m'
`-p'
diff -urp coreutils-6.10-orig/doc/coreutils.texi coreutils-6.10/doc/coreutils.texi
--- coreutils-6.10-orig/doc/coreutils.texi 2008-01-24 16:50:57.000000000 +0100
+++ coreutils-6.10/doc/coreutils.texi 2008-01-24 17:12:58.000000000 +0100
@@ -13670,7 +13670,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{}]

View File

@ -1,7 +1,7 @@
Summary: A set of basic GNU tools commonly used in shell scripts
Name: coreutils
Version: 8.6
Release: 3%{?dist}
Version: 8.7
Release: 1%{?dist}
License: GPLv3+
Group: System Environment/Base
Url: http://www.gnu.org/software/coreutils/
@ -42,8 +42,8 @@ Patch703: sh-utils-2.0.11-dateman.patch
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.
Patch706: coreutils-pam.patch
# 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
@ -52,14 +52,11 @@ 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-5.2.1-runuser.patch
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
#split the PAM scripts for "su -l"/"runuser -l" from that of normal "su" and
#"runuser" (#198639)
Patch915: coreutils-split-pam.patch
#compile su with pie flag and RELRO protection
Patch917: coreutils-8.4-su-pie.patch
@ -142,7 +139,6 @@ Libraries for coreutils package.
%patch907 -p1 -b .runuser
%patch908 -p1 -b .getgrouplist
%patch912 -p1 -b .overflow
%patch915 -p1 -b .splitl
%patch917 -p1 -b .pie
#SELinux
@ -336,6 +332,10 @@ fi
%{_libdir}/coreutils
%changelog
* Wed Nov 03 2010 Ondrej Vasik <ovasik@redhat.com> - 8.7-1
- new upstream release coreutils-8.7
- pam support in su consolidation with SUSE(#622700)
* Wed Nov 03 2010 Kamil Dudka <kdudka@redhat.com> - 8.6-3
- prevent sort from assertion failure in case LC_CTYPE does not match LC_TIME
(#647938)

View File

@ -1 +1 @@
17d693d282ac57c62b241a045e7b511c coreutils-8.6.tar.xz
6e21df02e7f5c5d86372de4c6d873275 coreutils-8.7.tar.xz