forked from pool/coreutils
This commit is contained in:
parent
a28cf68879
commit
4860603e7b
@ -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);
|
|
||||||
|
|
@ -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)
|
|
751
coreutils-6.8-su.diff
Normal file
751
coreutils-6.8-su.diff
Normal file
@ -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 <kukuk@suse.de>
|
||||||
|
+
|
||||||
|
+ 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 <config.h>
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#define _GNU_SOURCE
|
||||||
|
+
|
||||||
|
+#include <errno.h>
|
||||||
|
+#include <ctype.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <limits.h>
|
||||||
|
+
|
||||||
|
+#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 <kukuk@suse.de>
|
||||||
|
+
|
||||||
|
+ 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 <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
|
||||||
|
|
||||||
|
/* 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 <syslog.h>
|
||||||
|
+# 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 <paths.h>
|
||||||
|
#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")
|
25
coreutils-6.8.0-pie.diff
Normal file
25
coreutils-6.8.0-pie.diff
Normal file
@ -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)
|
@ -1,4 +1,6 @@
|
|||||||
--- doc/coreutils.texi
|
Index: doc/coreutils.texi
|
||||||
|
===================================================================
|
||||||
|
--- doc/coreutils.texi.orig
|
||||||
+++ doc/coreutils.texi
|
+++ doc/coreutils.texi
|
||||||
@@ -64,8 +64,6 @@
|
@@ -64,8 +64,6 @@
|
||||||
* fold: (coreutils)fold invocation. Wrap long input lines.
|
* fold: (coreutils)fold invocation. Wrap long input lines.
|
||||||
@ -9,7 +11,7 @@
|
|||||||
* id: (coreutils)id invocation. Print user identity.
|
* id: (coreutils)id invocation. Print user identity.
|
||||||
* install: (coreutils)install invocation. Copy and change attributes.
|
* install: (coreutils)install invocation. Copy and change attributes.
|
||||||
* join: (coreutils)join invocation. Join lines on a common field.
|
* 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
|
* date invocation:: Print or set system date and time
|
||||||
* uname invocation:: Print system information
|
* uname invocation:: Print system information
|
||||||
@ -18,7 +20,7 @@
|
|||||||
|
|
||||||
@command{date}: Print or set system date and time
|
@command{date}: Print or set system date and time
|
||||||
|
|
||||||
@@ -12190,8 +12186,6 @@
|
@@ -12299,8 +12295,6 @@ information.
|
||||||
@menu
|
@menu
|
||||||
* date invocation:: Print or set system date and time.
|
* date invocation:: Print or set system date and time.
|
||||||
* uname invocation:: Print system information.
|
* uname invocation:: Print system information.
|
||||||
@ -27,7 +29,7 @@
|
|||||||
@end menu
|
@end menu
|
||||||
|
|
||||||
|
|
||||||
@@ -12949,55 +12943,6 @@
|
@@ -13058,55 +13052,6 @@ Print the kernel version.
|
||||||
@exitstatus
|
@exitstatus
|
||||||
|
|
||||||
|
|
||||||
@ -83,313 +85,11 @@
|
|||||||
@node Modified command invocation
|
@node Modified command invocation
|
||||||
@chapter Modified command invocation
|
@chapter Modified command invocation
|
||||||
|
|
||||||
--- src/Makefile.am
|
Index: src/install.c
|
||||||
+++ src/Makefile.am
|
===================================================================
|
||||||
@@ -103,7 +103,8 @@
|
--- src/install.c.orig
|
||||||
# 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 <kukuk@suse.de>
|
|
||||||
+
|
|
||||||
+ 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 <config.h>
|
|
||||||
+#endif
|
|
||||||
+
|
|
||||||
+#define _GNU_SOURCE
|
|
||||||
+
|
|
||||||
+#include <errno.h>
|
|
||||||
+#include <ctype.h>
|
|
||||||
+#include <stdio.h>
|
|
||||||
+#include <stdlib.h>
|
|
||||||
+#include <string.h>
|
|
||||||
+#include <limits.h>
|
|
||||||
+
|
|
||||||
+#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 <kukuk@suse.de>
|
|
||||||
+
|
|
||||||
+ 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
|
|
||||||
+++ src/install.c
|
+++ src/install.c
|
||||||
@@ -572,7 +572,8 @@
|
@@ -571,7 +571,8 @@ strip (char const *name)
|
||||||
while (pid != wait (&status)) /* Wait for kid to finish. */
|
while (pid != wait (&status)) /* Wait for kid to finish. */
|
||||||
/* Do nothing. */ ;
|
/* Do nothing. */ ;
|
||||||
if (status)
|
if (status)
|
||||||
@ -399,339 +99,11 @@
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
--- src/su.c
|
Index: src/system.h
|
||||||
+++ src/su.c
|
===================================================================
|
||||||
@@ -38,6 +38,12 @@
|
--- src/system.h.orig
|
||||||
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 <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
|
|
||||||
|
|
||||||
/* 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 <syslog.h>
|
|
||||||
+# 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 <paths.h>
|
|
||||||
#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
|
|
||||||
+++ src/system.h
|
+++ src/system.h
|
||||||
@@ -173,7 +173,7 @@
|
@@ -168,7 +168,7 @@ enum
|
||||||
# define DEV_BSIZE BBSIZE
|
# define DEV_BSIZE BBSIZE
|
||||||
#endif
|
#endif
|
||||||
#ifndef DEV_BSIZE
|
#ifndef DEV_BSIZE
|
||||||
@ -740,9 +112,11 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Extract or fake data from a `struct stat'.
|
/* Extract or fake data from a `struct stat'.
|
||||||
--- tests/help-version
|
Index: tests/help-version
|
||||||
|
===================================================================
|
||||||
|
--- tests/help-version.orig
|
||||||
+++ tests/help-version
|
+++ tests/help-version
|
||||||
@@ -190,7 +190,7 @@
|
@@ -197,7 +197,7 @@ lbracket_args=": ]"
|
||||||
|
|
||||||
for i in $all_programs; do
|
for i in $all_programs; do
|
||||||
# Skip these.
|
# Skip these.
|
||||||
@ -751,9 +125,11 @@
|
|||||||
|
|
||||||
rm -rf $tmp_in $tmp_in2 $tmp_dir $tmp_out
|
rm -rf $tmp_in $tmp_in2 $tmp_dir $tmp_out
|
||||||
echo > $tmp_in
|
echo > $tmp_in
|
||||||
--- tests/other-fs-tmpdir
|
Index: tests/other-fs-tmpdir
|
||||||
|
===================================================================
|
||||||
|
--- tests/other-fs-tmpdir.orig
|
||||||
+++ tests/other-fs-tmpdir
|
+++ tests/other-fs-tmpdir
|
||||||
@@ -44,6 +44,8 @@
|
@@ -44,6 +44,8 @@ for d in $CANDIDATE_TMP_DIRS; do
|
||||||
fi
|
fi
|
||||||
|
|
||||||
done
|
done
|
||||||
|
@ -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
|
Sun Feb 25 10:58:58 CET 2007 - schwab@suse.de
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ Obsoletes: libselinux <= 1.23.11-3 libselinux-32bit >= 9 libselinux-64bit =
|
|||||||
Autoreqprov: on
|
Autoreqprov: on
|
||||||
PreReq: %{install_info_prereq}
|
PreReq: %{install_info_prereq}
|
||||||
Version: 6.8
|
Version: 6.8
|
||||||
Release: 1
|
Release: 3
|
||||||
Summary: GNU Core Utilities
|
Summary: GNU Core Utilities
|
||||||
Source: coreutils-%{version}.tar.bz2
|
Source: coreutils-%{version}.tar.bz2
|
||||||
Source1: su.pamd
|
Source1: su.pamd
|
||||||
@ -32,13 +32,13 @@ Patch30: coreutils-changelog.diff
|
|||||||
Patch4: coreutils-5.3.0-i18n-0.1.patch
|
Patch4: coreutils-5.3.0-i18n-0.1.patch
|
||||||
Patch5: i18n-uninit.diff
|
Patch5: i18n-uninit.diff
|
||||||
Patch6: i18n-infloop.diff
|
Patch6: i18n-infloop.diff
|
||||||
Patch7: coreutils-5.0-pam-env.patch
|
|
||||||
Patch8: coreutils-sysinfo.diff
|
Patch8: coreutils-sysinfo.diff
|
||||||
Patch11: i18n-monthsort.diff
|
Patch11: i18n-monthsort.diff
|
||||||
Patch16: invalid-ids.diff
|
Patch16: invalid-ids.diff
|
||||||
Patch17: no-no.diff
|
Patch17: no-no.diff
|
||||||
Patch20: coreutils-5.3.0-pie.diff
|
Patch20: coreutils-6.8-su.diff
|
||||||
Patch21: coreutils-5.3.0-sbin4su.diff
|
Patch21: coreutils-6.8.0-pie.diff
|
||||||
|
Patch22: coreutils-5.3.0-sbin4su.diff
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
|
|
||||||
%description
|
%description
|
||||||
@ -98,18 +98,18 @@ Authors:
|
|||||||
%patch5
|
%patch5
|
||||||
%patch6
|
%patch6
|
||||||
%patch
|
%patch
|
||||||
%patch7 -p1
|
|
||||||
%patch8 -p1
|
%patch8 -p1
|
||||||
%patch11
|
%patch11
|
||||||
%patch16 -p1
|
%patch16 -p1
|
||||||
%patch17
|
%patch17
|
||||||
%patch20
|
%patch20
|
||||||
%patch21
|
%patch21
|
||||||
|
%patch22
|
||||||
rm -f po/no.*
|
rm -f po/no.*
|
||||||
|
|
||||||
%build
|
%build
|
||||||
AUTOPOINT=true autoreconf -fi
|
AUTOPOINT=true autoreconf -fi
|
||||||
./configure CFLAGS="-DUSE_PAM $RPM_OPT_FLAGS -Wall" \
|
./configure CFLAGS="$RPM_OPT_FLAGS -Wall" \
|
||||||
DEFAULT_POSIX2_VERSION=199209 \
|
DEFAULT_POSIX2_VERSION=199209 \
|
||||||
--prefix=%{_prefix} --mandir=%{_mandir} \
|
--prefix=%{_prefix} --mandir=%{_mandir} \
|
||||||
--infodir=%{_infodir} --without-included-regex
|
--infodir=%{_infodir} --without-included-regex
|
||||||
@ -139,6 +139,7 @@ done > bin.files
|
|||||||
ln -sf ../../bin/basename ../../bin/sort ../../bin/touch $RPM_BUILD_ROOT%{_bindir}
|
ln -sf ../../bin/basename ../../bin/sort ../../bin/touch $RPM_BUILD_ROOT%{_bindir}
|
||||||
install -d -m 755 $RPM_BUILD_ROOT/etc/pam.d
|
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
|
||||||
|
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 -d -m 755 $RPM_BUILD_ROOT/etc/default
|
||||||
install -m 644 $RPM_SOURCE_DIR/su.default $RPM_BUILD_ROOT/etc/default/su
|
install -m 644 $RPM_SOURCE_DIR/su.default $RPM_BUILD_ROOT/etc/default/su
|
||||||
ln -sf /bin/su $RPM_BUILD_ROOT%{_bindir}/sux
|
ln -sf /bin/su $RPM_BUILD_ROOT%{_bindir}/sux
|
||||||
@ -162,6 +163,7 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%defattr(-,root,root)
|
%defattr(-,root,root)
|
||||||
%doc README NEWS
|
%doc README NEWS
|
||||||
%config /etc/pam.d/su
|
%config /etc/pam.d/su
|
||||||
|
%config /etc/pam.d/su-l
|
||||||
%config(noreplace) /etc/default/su
|
%config(noreplace) /etc/default/su
|
||||||
%{_bindir}/*
|
%{_bindir}/*
|
||||||
%doc %{_infodir}/coreutils.info*.gz
|
%doc %{_infodir}/coreutils.info*.gz
|
||||||
@ -169,6 +171,13 @@ rm -rf $RPM_BUILD_ROOT
|
|||||||
%dir %{_prefix}/share/locale/*/LC_TIME
|
%dir %{_prefix}/share/locale/*/LC_TIME
|
||||||
|
|
||||||
%changelog
|
%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
|
* Sun Feb 25 2007 - schwab@suse.de
|
||||||
- Update to coreutils 6.8.
|
- Update to coreutils 6.8.
|
||||||
** Bug fixes
|
** Bug fixes
|
||||||
|
Loading…
x
Reference in New Issue
Block a user