diff --git a/coreutils-5.0-pam-env.patch b/coreutils-5.0-pam-env.patch deleted file mode 100644 index 151bbb2..0000000 --- a/coreutils-5.0-pam-env.patch +++ /dev/null @@ -1,38 +0,0 @@ ---- coreutils-5.3.0/src/su.c -+++ coreutils-5.3.0/src/su.c -@@ -521,6 +521,21 @@ - } - - /* child shell */ -+ -+ /* Export env variables declared by PAM modules */ -+ { -+ const char *const *env; -+ -+ env = (const char *const *) pam_getenvlist (pamh); -+ while (env && *env) -+ { -+ -+ if (putenv (*env) != 0) -+ xalloc_die (); -+ env++; -+ } -+ } -+ - pam_end (pamh, 0); - #endif - -@@ -726,9 +741,12 @@ - shell = NULL; - } - shell = xstrdup (shell ? shell : pw->pw_shell); -+ change_identity (pw); -+ -+ /* Set environment after pam_open_session, which may put KRB5CCNAME -+ into the pam_env, etc. */ - modify_environment (pw, shell); - -- change_identity (pw); - if (simulate_login && chdir (pw->pw_dir) != 0) - error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); - diff --git a/coreutils-5.3.0-pie.diff b/coreutils-5.3.0-pie.diff deleted file mode 100644 index af27733..0000000 --- a/coreutils-5.3.0-pie.diff +++ /dev/null @@ -1,21 +0,0 @@ ---- lib/Makefile.am -+++ lib/Makefile.am -@@ -20,6 +20,7 @@ - include gnulib.mk - - AM_CFLAGS = $(WARNING_CFLAGS) $(WERROR_CFLAGS) -+AM_CFLAGS += -fpie - - noinst_PROGRAMS = t-fpending - LDADD = $(noinst_LIBRARIES) ---- src/Makefile.am -+++ src/Makefile.am -@@ -105,6 +105,8 @@ - - su_SOURCES = su.c getdef.c - su_LDADD = $(LDADD) $(LIB_CRYPT) -lpam -lpam_misc -ldl -+su_CFLAGS = -fpie -+su_LDFLAGS = -pie - - dir_LDADD += $(LIB_ACL) - ls_LDADD += $(LIB_ACL) diff --git a/coreutils-6.8-su.diff b/coreutils-6.8-su.diff new file mode 100644 index 0000000..e4c7efb --- /dev/null +++ b/coreutils-6.8-su.diff @@ -0,0 +1,751 @@ +Index: src/Makefile.am +=================================================================== +--- src/Makefile.am.orig ++++ src/Makefile.am +@@ -102,7 +102,8 @@ tail_LDADD = $(nanosec_libs) + # If necessary, add -lm to resolve use of pow in lib/strtod.c. + uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS) + +-su_LDADD = $(LDADD) $(LIB_CRYPT) ++su_SOURCES = su.c getdef.c ++su_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS) + + dir_LDADD += $(LIB_ACL) + ls_LDADD += $(LIB_ACL) +Index: src/getdef.c +=================================================================== +--- /dev/null ++++ src/getdef.c +@@ -0,0 +1,257 @@ ++/* Copyright (C) 2003, 2004, 2005 Thorsten Kukuk ++ Author: Thorsten Kukuk ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software Foundation, ++ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#define _GNU_SOURCE ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include "getdef.h" ++ ++struct item { ++ char *name; /* name of the option. */ ++ char *value; /* value of the option. */ ++ struct item *next; /* pointer to next option. */ ++}; ++ ++static struct item *list = NULL; ++ ++void ++free_getdef_data (void) ++{ ++ struct item *ptr; ++ ++ ptr = list; ++ while (ptr != NULL) ++ { ++ struct item *tmp; ++ tmp = ptr->next; ++ free (ptr->name); ++ free (ptr->value); ++ free (ptr); ++ ptr = tmp; ++ } ++ ++ list = NULL; ++} ++ ++/* Add a new entry to the list. */ ++static void ++store (const char *name, const char *value) ++{ ++ struct item *new = malloc (sizeof (struct item)); ++ ++ if (new == NULL) ++ abort (); ++ ++ if (name == NULL) ++ abort (); ++ ++ new->name = strdup (name); ++ new->value = strdup (value?:""); ++ new->next = list; ++ list = new; ++} ++ ++/* search a special entry in the list and return the value. */ ++static const char * ++search (const char *name) ++{ ++ struct item *ptr; ++ ++ ptr = list; ++ while (ptr != NULL) ++ { ++ if (strcasecmp (name, ptr->name) == 0) ++ return ptr->value; ++ ptr = ptr->next; ++ } ++ ++ return NULL; ++} ++ ++/* Load the login.defs file (/etc/login.defs) */ ++static void ++load_defaults_internal (const char *filename) ++{ ++ FILE *fp; ++ char *buf = NULL; ++ size_t buflen = 0; ++ ++ fp = fopen (filename, "r"); ++ if (NULL == fp) ++ return; ++ ++ while (!feof (fp)) ++ { ++ char *tmp, *cp; ++#if defined(HAVE_GETLINE) ++ ssize_t n = getline (&buf, &buflen, fp); ++#elif defined (HAVE_GETDELIM) ++ ssize_t n = getdelim (&buf, &buflen, '\n', fp); ++#else ++ ssize_t n; ++ ++ if (buf == NULL) ++ { ++ buflen = 8096; ++ buf = malloc (buflen); ++ } ++ buf[0] = '\0'; ++ fgets (buf, buflen - 1, fp); ++ if (buf != NULL) ++ n = strlen (buf); ++ else ++ n = 0; ++#endif /* HAVE_GETLINE / HAVE_GETDELIM */ ++ cp = buf; ++ ++ if (n < 1) ++ break; ++ ++ tmp = strchr (cp, '#'); /* remove comments */ ++ if (tmp) ++ *tmp = '\0'; ++ while (isspace ((int)*cp)) /* remove spaces and tabs */ ++ ++cp; ++ if (*cp == '\0') /* ignore empty lines */ ++ continue; ++ ++ if (cp[strlen (cp) - 1] == '\n') ++ cp[strlen (cp) - 1] = '\0'; ++ ++ tmp = strsep (&cp, " \t="); ++ if (cp != NULL) ++ while (isspace ((int)*cp) || *cp == '=') ++ ++cp; ++ ++ store (tmp, cp); ++ } ++ fclose (fp); ++ ++ if (buf) ++ free (buf); ++} ++ ++static void ++load_defaults (void) ++{ ++ load_defaults_internal ("/etc/default/su"); ++ load_defaults_internal ("/etc/login.defs"); ++} ++ ++int ++getdef_bool (const char *name, int dflt) ++{ ++ const char *val; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ val = search (name); ++ ++ if (val == NULL) ++ return dflt; ++ ++ return (strcasecmp (val, "yes") == 0); ++} ++ ++long ++getdef_num (const char *name, long dflt) ++{ ++ const char *val; ++ char *cp; ++ long retval; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ val = search (name); ++ ++ if (val == NULL) ++ return dflt; ++ ++ retval = strtol (val, &cp, 0); ++ if (*cp != '\0' || ++ ((retval == LONG_MAX || retval == LONG_MIN) && errno == ERANGE)) ++ { ++ fprintf (stderr, ++ "%s contains invalid numerical value: %s!\n", ++ name, val); ++ retval = dflt; ++ } ++ return retval; ++} ++ ++unsigned long ++getdef_unum (const char *name, unsigned long dflt) ++{ ++ const char *val; ++ char *cp; ++ unsigned long retval; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ val = search (name); ++ ++ if (val == NULL) ++ return dflt; ++ ++ retval = strtoul (val, &cp, 0); ++ if (*cp != '\0' || (retval == ULONG_MAX && errno == ERANGE)) ++ { ++ fprintf (stderr, ++ "%s contains invalid numerical value: %s!\n", ++ name, val); ++ retval = dflt; ++ } ++ return retval; ++} ++ ++const char * ++getdef_str (const char *name, const char *dflt) ++{ ++ const char *retval; ++ ++ if (list == NULL) ++ load_defaults (); ++ ++ retval = search (name); ++ ++ return retval ?: dflt; ++} ++ ++#if defined(TEST) ++ ++int ++main () ++{ ++ printf ("CYPT=%s\n", getdef_str ("cRypt", "no")); ++ printf ("LOG_UNKFAIL_ENAB=%s\n", getdef_str ("log_unkfail_enab","")); ++ printf ("DOESNOTEXIST=%s\n", getdef_str ("DOESNOTEXIST","yes")); ++ return 0; ++} ++ ++#endif +Index: src/getdef.h +=================================================================== +--- /dev/null ++++ src/getdef.h +@@ -0,0 +1,29 @@ ++/* Copyright (C) 2003, 2005 Thorsten Kukuk ++ Author: Thorsten Kukuk ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License version 2 as ++ published by the Free Software Foundation. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software Foundation, ++ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ++ ++#ifndef _GETDEF_H_ ++ ++#define _GETDEF_H_ 1 ++ ++extern int getdef_bool (const char *name, int dflt); ++extern long getdef_num (const char *name, long dflt); ++extern unsigned long getdef_unum (const char *name, unsigned long dflt); ++extern const char *getdef_str (const char *name, const char *dflt); ++ ++/* Free all data allocated by getdef_* calls before. */ ++extern void free_getdef_data (void); ++ ++#endif /* _GETDEF_H_ */ +Index: src/su.c +=================================================================== +--- src/su.c.orig ++++ src/su.c +@@ -38,6 +38,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. +@@ -53,6 +63,13 @@ + #include + #include + #include ++#ifdef USE_PAM ++#include ++#include ++#include ++#include ++#include ++#endif + + /* Hide any system prototype for getusershell. + This is necessary because some Cray systems have a conflicting +@@ -66,6 +83,9 @@ + + #if HAVE_SYSLOG_H && HAVE_SYSLOG + # include ++# define SYSLOG_SUCCESS 1 ++# define SYSLOG_FAILURE 1 ++# define SYSLOG_NON_ROOT 1 + #else + # undef SYSLOG_SUCCESS + # undef SYSLOG_FAILURE +@@ -99,19 +119,13 @@ + # include + #endif + ++#include "getdef.h" ++ + /* The default PATH for simulated logins to non-superuser accounts. */ +-#ifdef _PATH_DEFPATH +-# define DEFAULT_LOGIN_PATH _PATH_DEFPATH +-#else +-# define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin" +-#endif ++#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin" + + /* The default PATH for simulated logins to superuser accounts. */ +-#ifdef _PATH_DEFPATH_ROOT +-# define DEFAULT_ROOT_LOGIN_PATH _PATH_DEFPATH_ROOT +-#else +-# define DEFAULT_ROOT_LOGIN_PATH "/usr/ucb:/bin:/usr/bin:/etc" +-#endif ++#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin:/usr/X11R6/bin" + + /* The shell to run if none is given in the user's passwd entry. */ + #define DEFAULT_SHELL "/bin/sh" +@@ -119,13 +133,22 @@ + /* The user to become if none is specified. */ + #define DEFAULT_USER "root" + ++#ifndef USE_PAM + char *crypt (); ++#endif + char *getusershell (); + void endusershell (); + void setusershell (); + + extern char **environ; + ++#ifdef USE_PAM ++static bool _pam_session_opened; ++static bool _pam_cred_established; ++static void export_pamenv(void); ++static void create_watching_parent(void); ++#endif ++ + static void run_shell (char const *, char const *, char **, size_t) + ATTRIBUTE_NORETURN; + +@@ -216,7 +239,162 @@ log_su (struct passwd const *pw, bool su + } + #endif + ++#ifdef USE_PAM ++#define PAM_SERVICE_NAME PROGRAM_NAME ++#define PAM_SERVICE_NAME_L PROGRAM_NAME "-l" ++static bool 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_cred_established) ++ pam_setcred (pamh, PAM_DELETE_CRED | PAM_SILENT); ++ ++ if (_pam_session_opened) ++ pam_close_session (pamh, 0); ++ ++ 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; ++ ++ /* 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"), "/"); ++ ++ retval = pam_open_session (pamh,0); ++ if (retval != PAM_SUCCESS) ++ { ++ cleanup_pam(retval); ++ error (EXIT_FAIL, 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 */ ++ 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) ++ { ++ for (;;) ++ { ++ pid_t pid; ++ ++ pid = waitpid (child, &status, WUNTRACED); ++ ++ if (WIFSTOPPED (status)) ++ { ++ kill (getpid (), SIGSTOP); ++ /* once we get here, we must have resumed */ ++ kill (pid, SIGCONT); ++ } ++ else ++ break; ++ } ++ if (WIFSIGNALED (status)) ++ status = WTERMSIG (status) + 128; ++ else ++ status = WEXITSTATUS (status); ++ } ++ 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. */ +@@ -224,10 +402,52 @@ log_su (struct passwd const *pw, bool su + static bool + correct_password (const struct passwd *pw) + { ++#ifdef USE_PAM ++ const struct passwd *lpw; ++ const char *cp; ++ ++ retval = pam_start (simulate_login ? PAM_SERVICE_NAME : PAM_SERVICE_NAME_L, ++ 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) +@@ -248,6 +468,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 +@@ -272,8 +493,8 @@ modify_environment (const struct passwd + xsetenv ("USER", pw->pw_name); + xsetenv ("LOGNAME", pw->pw_name); + xsetenv ("PATH", (pw->pw_uid +- ? DEFAULT_LOGIN_PATH +- : DEFAULT_ROOT_LOGIN_PATH)); ++ ? getdef_str ("PATH", DEFAULT_LOGIN_PATH) ++ : getdef_str ("SUPATH", DEFAULT_ROOT_LOGIN_PATH))); + } + else + { +@@ -283,6 +504,12 @@ modify_environment (const struct passwd + { + xsetenv ("HOME", pw->pw_dir); + xsetenv ("SHELL", shell); ++ if (getdef_bool ("ALWAYS_SET_PATH", 0)) ++ xsetenv ("PATH", (pw->pw_uid ++ ? getdef_str ("PATH", ++ DEFAULT_LOGIN_PATH) ++ : getdef_str ("SUPATH", ++ DEFAULT_ROOT_LOGIN_PATH))); + if (pw->pw_uid) + { + xsetenv ("USER", pw->pw_name); +@@ -290,19 +517,41 @@ modify_environment (const struct passwd + } + } + } ++ ++#ifdef USE_PAM ++ export_pamenv(); ++#endif + } + + /* Become the user and group(s) specified by PW. */ + + static void +-change_identity (const struct passwd *pw) ++init_groups (const struct passwd *pw) + { + #ifdef HAVE_INITGROUPS + errno = 0; + if (initgroups (pw->pw_name, pw->pw_gid) == -1) +- error (EXIT_FAIL, errno, _("cannot set groups")); ++ { ++#ifdef USE_PAM ++ cleanup_pam(PAM_ABORT); ++#endif ++ error (EXIT_FAIL, errno, _("cannot set groups")); ++ } + endgrent (); + #endif ++ ++#ifdef USE_PAM ++ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); ++ if (retval != PAM_SUCCESS) ++ error (EXIT_FAIL, 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_FAIL, errno, _("cannot set group id")); + if (setuid (pw->pw_uid)) +@@ -495,6 +744,7 @@ main (int argc, char **argv) + #ifdef SYSLOG_FAILURE + log_su (pw, false); + #endif ++ sleep (getdef_num ("FAIL_DELAY", 1)); + error (EXIT_FAIL, 0, _("incorrect password")); + } + #ifdef SYSLOG_SUCCESS +@@ -516,9 +766,21 @@ main (int argc, char **argv) + shell = NULL; + } + shell = xstrdup (shell ? shell : pw->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); + +- change_identity (pw); + if (simulate_login && chdir (pw->pw_dir) != 0) + error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); + +Index: configure.ac +=================================================================== +--- configure.ac.orig ++++ configure.ac +@@ -41,6 +41,20 @@ coreutils_MACROS + + AC_FUNC_FORK + ++AC_ARG_ENABLE(pam, AS_HELP_STRING([--disable-pam],dnl ++ [Enable 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]) ++ + AC_CHECK_FUNCS(uname, + OPTIONAL_BIN_PROGS="$OPTIONAL_BIN_PROGS uname\$(EXEEXT)" + MAN="$MAN uname.1") diff --git a/coreutils-6.8.0-pie.diff b/coreutils-6.8.0-pie.diff new file mode 100644 index 0000000..49cc8d0 --- /dev/null +++ b/coreutils-6.8.0-pie.diff @@ -0,0 +1,25 @@ +Index: lib/Makefile.am +=================================================================== +--- lib/Makefile.am.orig ++++ lib/Makefile.am +@@ -20,6 +20,7 @@ + include gnulib.mk + + AM_CFLAGS = $(WARNING_CFLAGS) $(WERROR_CFLAGS) ++AM_CFLAGS += -fpie + + noinst_PROGRAMS = t-fpending + LDADD = $(noinst_LIBRARIES) +Index: src/Makefile.am +=================================================================== +--- src/Makefile.am.orig ++++ src/Makefile.am +@@ -104,6 +104,8 @@ uptime_LDADD = $(LDADD) $(POW_LIB) $(GET + + su_SOURCES = su.c getdef.c + su_LDADD = $(LDADD) $(LIB_CRYPT) $(PAM_LIBS) ++su_CFLAGS = -fpie ++su_LDFLAGS = -pie + + dir_LDADD += $(LIB_ACL) + ls_LDADD += $(LIB_ACL) diff --git a/coreutils-6.8.diff b/coreutils-6.8.diff index f8ac5dd..8a91e94 100644 --- a/coreutils-6.8.diff +++ b/coreutils-6.8.diff @@ -1,4 +1,6 @@ ---- doc/coreutils.texi +Index: doc/coreutils.texi +=================================================================== +--- doc/coreutils.texi.orig +++ doc/coreutils.texi @@ -64,8 +64,6 @@ * fold: (coreutils)fold invocation. Wrap long input lines. @@ -9,7 +11,7 @@ * id: (coreutils)id invocation. Print user identity. * install: (coreutils)install invocation. Copy and change attributes. * join: (coreutils)join invocation. Join lines on a common field. -@@ -398,8 +396,6 @@ +@@ -399,8 +397,6 @@ System context * date invocation:: Print or set system date and time * uname invocation:: Print system information @@ -18,7 +20,7 @@ @command{date}: Print or set system date and time -@@ -12190,8 +12186,6 @@ +@@ -12299,8 +12295,6 @@ information. @menu * date invocation:: Print or set system date and time. * uname invocation:: Print system information. @@ -27,7 +29,7 @@ @end menu -@@ -12949,55 +12943,6 @@ +@@ -13058,55 +13052,6 @@ Print the kernel version. @exitstatus @@ -83,313 +85,11 @@ @node Modified command invocation @chapter Modified command invocation ---- src/Makefile.am -+++ src/Makefile.am -@@ -103,7 +103,8 @@ - # If necessary, add -lm to resolve use of pow in lib/strtod.c. - uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS) - --su_LDADD = $(LDADD) $(LIB_CRYPT) -+su_SOURCES = su.c getdef.c -+su_LDADD = $(LDADD) $(LIB_CRYPT) -lpam -lpam_misc -ldl - - dir_LDADD += $(LIB_ACL) - ls_LDADD += $(LIB_ACL) ---- src/getdef.c -+++ src/getdef.c -@@ -0,0 +1,257 @@ -+/* Copyright (C) 2003, 2004, 2005 Thorsten Kukuk -+ Author: Thorsten Kukuk -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License version 2 as -+ published by the Free Software Foundation. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software Foundation, -+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#define _GNU_SOURCE -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "getdef.h" -+ -+struct item { -+ char *name; /* name of the option. */ -+ char *value; /* value of the option. */ -+ struct item *next; /* pointer to next option. */ -+}; -+ -+static struct item *list = NULL; -+ -+void -+free_getdef_data (void) -+{ -+ struct item *ptr; -+ -+ ptr = list; -+ while (ptr != NULL) -+ { -+ struct item *tmp; -+ tmp = ptr->next; -+ free (ptr->name); -+ free (ptr->value); -+ free (ptr); -+ ptr = tmp; -+ } -+ -+ list = NULL; -+} -+ -+/* Add a new entry to the list. */ -+static void -+store (const char *name, const char *value) -+{ -+ struct item *new = malloc (sizeof (struct item)); -+ -+ if (new == NULL) -+ abort (); -+ -+ if (name == NULL) -+ abort (); -+ -+ new->name = strdup (name); -+ new->value = strdup (value?:""); -+ new->next = list; -+ list = new; -+} -+ -+/* search a special entry in the list and return the value. */ -+static const char * -+search (const char *name) -+{ -+ struct item *ptr; -+ -+ ptr = list; -+ while (ptr != NULL) -+ { -+ if (strcasecmp (name, ptr->name) == 0) -+ return ptr->value; -+ ptr = ptr->next; -+ } -+ -+ return NULL; -+} -+ -+/* Load the login.defs file (/etc/login.defs) */ -+static void -+load_defaults_internal (const char *filename) -+{ -+ FILE *fp; -+ char *buf = NULL; -+ size_t buflen = 0; -+ -+ fp = fopen (filename, "r"); -+ if (NULL == fp) -+ return; -+ -+ while (!feof (fp)) -+ { -+ char *tmp, *cp; -+#if defined(HAVE_GETLINE) -+ ssize_t n = getline (&buf, &buflen, fp); -+#elif defined (HAVE_GETDELIM) -+ ssize_t n = getdelim (&buf, &buflen, '\n', fp); -+#else -+ ssize_t n; -+ -+ if (buf == NULL) -+ { -+ buflen = 8096; -+ buf = malloc (buflen); -+ } -+ buf[0] = '\0'; -+ fgets (buf, buflen - 1, fp); -+ if (buf != NULL) -+ n = strlen (buf); -+ else -+ n = 0; -+#endif /* HAVE_GETLINE / HAVE_GETDELIM */ -+ cp = buf; -+ -+ if (n < 1) -+ break; -+ -+ tmp = strchr (cp, '#'); /* remove comments */ -+ if (tmp) -+ *tmp = '\0'; -+ while (isspace ((int)*cp)) /* remove spaces and tabs */ -+ ++cp; -+ if (*cp == '\0') /* ignore empty lines */ -+ continue; -+ -+ if (cp[strlen (cp) - 1] == '\n') -+ cp[strlen (cp) - 1] = '\0'; -+ -+ tmp = strsep (&cp, " \t="); -+ if (cp != NULL) -+ while (isspace ((int)*cp) || *cp == '=') -+ ++cp; -+ -+ store (tmp, cp); -+ } -+ fclose (fp); -+ -+ if (buf) -+ free (buf); -+} -+ -+static void -+load_defaults (void) -+{ -+ load_defaults_internal ("/etc/default/su"); -+ load_defaults_internal ("/etc/login.defs"); -+} -+ -+int -+getdef_bool (const char *name, int dflt) -+{ -+ const char *val; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ val = search (name); -+ -+ if (val == NULL) -+ return dflt; -+ -+ return (strcasecmp (val, "yes") == 0); -+} -+ -+long -+getdef_num (const char *name, long dflt) -+{ -+ const char *val; -+ char *cp; -+ long retval; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ val = search (name); -+ -+ if (val == NULL) -+ return dflt; -+ -+ retval = strtol (val, &cp, 0); -+ if (*cp != '\0' || -+ ((retval == LONG_MAX || retval == LONG_MIN) && errno == ERANGE)) -+ { -+ fprintf (stderr, -+ "%s contains invalid numerical value: %s!\n", -+ name, val); -+ retval = dflt; -+ } -+ return retval; -+} -+ -+unsigned long -+getdef_unum (const char *name, unsigned long dflt) -+{ -+ const char *val; -+ char *cp; -+ unsigned long retval; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ val = search (name); -+ -+ if (val == NULL) -+ return dflt; -+ -+ retval = strtoul (val, &cp, 0); -+ if (*cp != '\0' || (retval == ULONG_MAX && errno == ERANGE)) -+ { -+ fprintf (stderr, -+ "%s contains invalid numerical value: %s!\n", -+ name, val); -+ retval = dflt; -+ } -+ return retval; -+} -+ -+const char * -+getdef_str (const char *name, const char *dflt) -+{ -+ const char *retval; -+ -+ if (list == NULL) -+ load_defaults (); -+ -+ retval = search (name); -+ -+ return retval ?: dflt; -+} -+ -+#if defined(TEST) -+ -+int -+main () -+{ -+ printf ("CYPT=%s\n", getdef_str ("cRypt", "no")); -+ printf ("LOG_UNKFAIL_ENAB=%s\n", getdef_str ("log_unkfail_enab","")); -+ printf ("DOESNOTEXIST=%s\n", getdef_str ("DOESNOTEXIST","yes")); -+ return 0; -+} -+ -+#endif ---- src/getdef.h -+++ src/getdef.h -@@ -0,0 +1,29 @@ -+/* Copyright (C) 2003, 2005 Thorsten Kukuk -+ Author: Thorsten Kukuk -+ -+ This program is free software; you can redistribute it and/or modify -+ it under the terms of the GNU General Public License version 2 as -+ published by the Free Software Foundation. -+ -+ This program is distributed in the hope that it will be useful, -+ but WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ GNU General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software Foundation, -+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -+ -+#ifndef _GETDEF_H_ -+ -+#define _GETDEF_H_ 1 -+ -+extern int getdef_bool (const char *name, int dflt); -+extern long getdef_num (const char *name, long dflt); -+extern unsigned long getdef_unum (const char *name, unsigned long dflt); -+extern const char *getdef_str (const char *name, const char *dflt); -+ -+/* Free all data allocated by getdef_* calls before. */ -+extern void free_getdef_data (void); -+ -+#endif /* _GETDEF_H_ */ ---- src/install.c +Index: src/install.c +=================================================================== +--- src/install.c.orig +++ src/install.c -@@ -572,7 +572,8 @@ +@@ -571,7 +571,8 @@ strip (char const *name) while (pid != wait (&status)) /* Wait for kid to finish. */ /* Do nothing. */ ; if (status) @@ -399,339 +99,11 @@ break; } } ---- src/su.c -+++ src/su.c -@@ -38,6 +38,12 @@ - restricts who can su to UID 0 accounts. RMS considers that to - be fascist. - -+ 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 -+ - 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 +59,13 @@ - #include - #include - #include -+#ifdef USE_PAM -+#include -+#include -+#include -+#include -+#include -+#endif - - /* Hide any system prototype for getusershell. - This is necessary because some Cray systems have a conflicting -@@ -66,6 +79,9 @@ - - #if HAVE_SYSLOG_H && HAVE_SYSLOG - # include -+# define SYSLOG_SUCCESS 1 -+# define SYSLOG_FAILURE 1 -+# define SYSLOG_NON_ROOT 1 - #else - # undef SYSLOG_SUCCESS - # undef SYSLOG_FAILURE -@@ -99,19 +115,13 @@ - # include - #endif - -+#include "getdef.h" -+ - /* The default PATH for simulated logins to non-superuser accounts. */ --#ifdef _PATH_DEFPATH --# define DEFAULT_LOGIN_PATH _PATH_DEFPATH --#else --# define DEFAULT_LOGIN_PATH ":/usr/ucb:/bin:/usr/bin" --#endif -+#define DEFAULT_LOGIN_PATH "/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin" - - /* The default PATH for simulated logins to superuser accounts. */ --#ifdef _PATH_DEFPATH_ROOT --# define DEFAULT_ROOT_LOGIN_PATH _PATH_DEFPATH_ROOT --#else --# define DEFAULT_ROOT_LOGIN_PATH "/usr/ucb:/bin:/usr/bin:/etc" --#endif -+#define DEFAULT_ROOT_LOGIN_PATH "/usr/sbin:/bin:/usr/bin:/sbin:/usr/X11R6/bin" - - /* The shell to run if none is given in the user's passwd entry. */ - #define DEFAULT_SHELL "/bin/sh" -@@ -119,7 +129,9 @@ - /* The user to become if none is specified. */ - #define DEFAULT_USER "root" - -+#ifndef USE_PAM - char *crypt (); -+#endif - char *getusershell (); - void endusershell (); - void setusershell (); -@@ -216,7 +228,26 @@ - } - #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(a) \ -+ if (retval) \ -+ { \ -+ pam_end (pamh, PAM_SUCCESS); \ -+ a; \ -+ } -+#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. */ -@@ -224,10 +255,49 @@ - static bool - correct_password (const struct passwd *pw) - { -+#ifdef USE_PAM -+ const struct passwd *lpw; -+ const char *cp; -+ -+ retval = pam_start ("su", 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); -+ } -+ cp = getlogin (); -+ if (!(cp && *cp && (lpw = getpwnam (cp)) != NULL && lpw->pw_uid == getuid ())) -+ lpw = getpwuid (getuid ()); -+ if (lpw) -+ { -+ 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) -@@ -248,6 +318,7 @@ - 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 -@@ -272,8 +343,8 @@ - xsetenv ("USER", pw->pw_name); - xsetenv ("LOGNAME", pw->pw_name); - xsetenv ("PATH", (pw->pw_uid -- ? DEFAULT_LOGIN_PATH -- : DEFAULT_ROOT_LOGIN_PATH)); -+ ? getdef_str ("PATH", DEFAULT_LOGIN_PATH) -+ : getdef_str ("SUPATH", DEFAULT_ROOT_LOGIN_PATH))); - } - else - { -@@ -283,6 +354,12 @@ - { - xsetenv ("HOME", pw->pw_dir); - xsetenv ("SHELL", shell); -+ if (getdef_bool ("ALWAYS_SET_PATH", 0)) -+ xsetenv ("PATH", (pw->pw_uid -+ ? getdef_str ("PATH", -+ DEFAULT_LOGIN_PATH) -+ : getdef_str ("SUPATH", -+ DEFAULT_ROOT_LOGIN_PATH))); - if (pw->pw_uid) - { - xsetenv ("USER", pw->pw_name); -@@ -303,12 +380,35 @@ - error (EXIT_FAIL, errno, _("cannot set groups")); - endgrent (); - #endif -+#ifdef USE_PAM -+ retval = pam_setcred (pamh, PAM_ESTABLISH_CRED); -+ if (retval != PAM_SUCCESS) -+ error (EXIT_FAIL, 0, "%s", pam_strerror (pamh, retval)); -+ -+ retval = pam_open_session (pamh,0); -+ if (retval != PAM_SUCCESS) -+ { -+ pam_setcred (pamh, PAM_DELETE_CRED); -+ error (EXIT_FAIL, 0, "could not open session: %s", -+ pam_strerror (pamh, retval)); -+ } -+#endif /* USE_PAM */ - if (setgid (pw->pw_gid)) - error (EXIT_FAIL, errno, _("cannot set group id")); - if (setuid (pw->pw_uid)) - error (EXIT_FAIL, errno, _("cannot set user id")); - } - -+#ifdef USE_PAM -+static bool caught = false; -+/* Signal handler for parent process later */ -+static void -+su_catch_sig (int sig) -+{ -+ caught = true; -+} -+#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 -@@ -321,6 +421,88 @@ - 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 -+ pid_t child; -+ sigset_t ourset; -+ int status; -+ -+ child = fork (); -+ if (child == (pid_t) -1) -+ error (EXIT_FAILURE, errno, "cannot fork"); -+ -+ if (child != 0) -+ { -+ /* parent only */ -+ sigfillset (&ourset); -+ if (sigprocmask (SIG_BLOCK, &ourset, NULL)) -+ { -+ error (0, errno, "cannot block signals"); -+ caught = true; -+ } -+ 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)) -+ { -+ error (0, errno, "cannot set signal handler"); -+ caught = true; -+ } -+ } -+ if (!caught) -+ { -+ for (;;) -+ { -+ pid_t pid; -+ -+ pid = waitpid (child, &status, WUNTRACED); -+ -+ if (WIFSTOPPED (status)) -+ { -+ kill (getpid (), SIGSTOP); -+ /* once we get here, we must have resumed */ -+ kill (pid, SIGCONT); -+ } -+ else -+ break; -+ } -+ if (WIFSIGNALED (status)) -+ status = WTERMSIG (status) + 128; -+ else -+ status = WEXITSTATUS (status); -+ } -+ else -+ status = 1; -+ -+ if (caught) -+ { -+ fprintf (stderr, "\nSession terminated, killing shell..."); -+ kill (child, SIGTERM); -+ } -+ retval = pam_setcred (pamh, PAM_DELETE_CRED); -+ PAM_BAIL_P (exit (EXIT_FAILURE)); -+ retval = pam_close_session (pamh, 0); -+ PAM_BAIL_P (exit (EXIT_FAILURE)); -+ retval = pam_end (pamh, PAM_SUCCESS); -+ PAM_BAIL_P (exit (EXIT_FAILURE)); -+ if (caught) -+ { -+ sleep (2); -+ kill (child, SIGKILL); -+ fprintf (stderr, " ...killed.\n"); -+ } -+ exit (status); -+ } -+ -+ /* child shell */ -+ pam_end (pamh, 0); -+#endif - - if (simulate_login) - { -@@ -339,6 +521,11 @@ - args[argno++] = "-f"; - if (command) - { -+ if (simulate_login) -+ /* Bash 2.0 have to be invoked as `-su'. See the comments in -+ `shell.c (run_startup_files)'. */ -+ args[0] = "-su"; -+ - args[argno++] = "-c"; - args[argno++] = command; - } -@@ -495,6 +682,9 @@ - #ifdef SYSLOG_FAILURE - log_su (pw, false); - #endif -+#ifdef USE_PAM -+ sleep (getdef_num ("FAIL_DELAY", 1)); -+#endif - error (EXIT_FAIL, 0, _("incorrect password")); - } - #ifdef SYSLOG_SUCCESS ---- src/system.h +Index: src/system.h +=================================================================== +--- src/system.h.orig +++ src/system.h -@@ -173,7 +173,7 @@ +@@ -168,7 +168,7 @@ enum # define DEV_BSIZE BBSIZE #endif #ifndef DEV_BSIZE @@ -740,9 +112,11 @@ #endif /* Extract or fake data from a `struct stat'. ---- tests/help-version +Index: tests/help-version +=================================================================== +--- tests/help-version.orig +++ tests/help-version -@@ -190,7 +190,7 @@ +@@ -197,7 +197,7 @@ lbracket_args=": ]" for i in $all_programs; do # Skip these. @@ -751,9 +125,11 @@ rm -rf $tmp_in $tmp_in2 $tmp_dir $tmp_out echo > $tmp_in ---- tests/other-fs-tmpdir +Index: tests/other-fs-tmpdir +=================================================================== +--- tests/other-fs-tmpdir.orig +++ tests/other-fs-tmpdir -@@ -44,6 +44,8 @@ +@@ -44,6 +44,8 @@ for d in $CANDIDATE_TMP_DIRS; do fi done diff --git a/coreutils.changes b/coreutils.changes index ffc84b7..b97d3eb 100644 --- a/coreutils.changes +++ b/coreutils.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Fri Mar 2 13:47:35 CET 2007 - lnussel@suse.de + +- split off and rework PAM patch for su: + * run pam_open_session as root (#245706) + * use separate pam configs for "su" and "su -" (RedHat #198639) + * detect pam libs in configure script, add option to disable it + * don't set argv[0] to "-su", use upstream behavior instead + * don't use getlogin() for setting PAM_RUSER + ------------------------------------------------------------------- Sun Feb 25 10:58:58 CET 2007 - schwab@suse.de diff --git a/coreutils.spec b/coreutils.spec index 3529cd9..0e273dc 100644 --- a/coreutils.spec +++ b/coreutils.spec @@ -21,7 +21,7 @@ Obsoletes: libselinux <= 1.23.11-3 libselinux-32bit >= 9 libselinux-64bit = Autoreqprov: on PreReq: %{install_info_prereq} Version: 6.8 -Release: 1 +Release: 3 Summary: GNU Core Utilities Source: coreutils-%{version}.tar.bz2 Source1: su.pamd @@ -32,13 +32,13 @@ Patch30: coreutils-changelog.diff Patch4: coreutils-5.3.0-i18n-0.1.patch Patch5: i18n-uninit.diff Patch6: i18n-infloop.diff -Patch7: coreutils-5.0-pam-env.patch Patch8: coreutils-sysinfo.diff Patch11: i18n-monthsort.diff Patch16: invalid-ids.diff Patch17: no-no.diff -Patch20: coreutils-5.3.0-pie.diff -Patch21: coreutils-5.3.0-sbin4su.diff +Patch20: coreutils-6.8-su.diff +Patch21: coreutils-6.8.0-pie.diff +Patch22: coreutils-5.3.0-sbin4su.diff BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -98,18 +98,18 @@ Authors: %patch5 %patch6 %patch -%patch7 -p1 %patch8 -p1 %patch11 %patch16 -p1 %patch17 %patch20 %patch21 +%patch22 rm -f po/no.* %build AUTOPOINT=true autoreconf -fi -./configure CFLAGS="-DUSE_PAM $RPM_OPT_FLAGS -Wall" \ +./configure CFLAGS="$RPM_OPT_FLAGS -Wall" \ DEFAULT_POSIX2_VERSION=199209 \ --prefix=%{_prefix} --mandir=%{_mandir} \ --infodir=%{_infodir} --without-included-regex @@ -139,6 +139,7 @@ done > bin.files ln -sf ../../bin/basename ../../bin/sort ../../bin/touch $RPM_BUILD_ROOT%{_bindir} install -d -m 755 $RPM_BUILD_ROOT/etc/pam.d install -m 644 $RPM_SOURCE_DIR/su.pamd $RPM_BUILD_ROOT/etc/pam.d/su +install -m 644 $RPM_SOURCE_DIR/su.pamd $RPM_BUILD_ROOT/etc/pam.d/su-l install -d -m 755 $RPM_BUILD_ROOT/etc/default install -m 644 $RPM_SOURCE_DIR/su.default $RPM_BUILD_ROOT/etc/default/su ln -sf /bin/su $RPM_BUILD_ROOT%{_bindir}/sux @@ -162,6 +163,7 @@ rm -rf $RPM_BUILD_ROOT %defattr(-,root,root) %doc README NEWS %config /etc/pam.d/su +%config /etc/pam.d/su-l %config(noreplace) /etc/default/su %{_bindir}/* %doc %{_infodir}/coreutils.info*.gz @@ -169,6 +171,13 @@ rm -rf $RPM_BUILD_ROOT %dir %{_prefix}/share/locale/*/LC_TIME %changelog +* Fri Mar 02 2007 - lnussel@suse.de +- split off and rework PAM patch for su: + * run pam_open_session as root (#245706) + * use separate pam configs for "su" and "su -" (RedHat #198639) + * detect pam libs in configure script, add option to disable it + * don't set argv[0] to "-su", use upstream behavior instead + * don't use getlogin() for setting PAM_RUSER * Sun Feb 25 2007 - schwab@suse.de - Update to coreutils 6.8. ** Bug fixes