New upstream release 8.7, consolidate PAM support with SUSE (#622700)
This commit is contained in:
parent
c07997606c
commit
9170895a87
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
||||
coreutils-8.5.tar.xz
|
||||
/coreutils-8.6.tar.xz
|
||||
/coreutils-8.7.tar.xz
|
||||
|
@ -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
428
coreutils-8.5-pam.patch
Normal 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
|
@ -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,
|
@ -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 @@
|
||||
+Apple@10
|
||||
+Banana@5
|
||||
+Citrus@20
|
||||
+Cherry@30
|
||||
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 @@
|
||||
+Banana@5
|
||||
+Apple@10
|
||||
+Citrus@20
|
||||
+Cherry@30
|
||||
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 @@
|
||||
+Apple@AA10@@20
|
||||
+Banana@AA5@@30
|
||||
+Citrus@AA20@@5
|
||||
+Cherry@AA30@@10
|
||||
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 @@
|
||||
+Citrus@AA20@@5
|
||||
+Cherry@AA30@@10
|
||||
+Apple@AA10@@20
|
||||
+Banana@AA5@@30
|
||||
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
|
||||
|
@ -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);
|
||||
}
|
@ -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.
|
||||
|
@ -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. */
|
||||
|
@ -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{}]
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user