[Pkg-shadow-commits] r401 - branches/experimental/debian/patches
Nicolas FRANCOIS
nekral-guest at costa.debian.org
Sun Jul 24 20:40:09 UTC 2005
Author: nekral-guest
Date: 2005-07-24 20:40:09 +0000 (Sun, 24 Jul 2005)
New Revision: 401
Added:
branches/experimental/debian/patches/437_su_add_GNU_options_1
branches/experimental/debian/patches/437_su_add_GNU_options_2
branches/experimental/debian/patches/437_su_add_GNU_options_3
branches/experimental/debian/patches/437_su_add_GNU_options_4
branches/experimental/debian/patches/437_su_add_GNU_options_5
branches/experimental/debian/patches/437_su_add_GNU_options_6
Removed:
branches/experimental/debian/patches/437_su_add_GNU_options
Log:
Update the 437_su_add_GNU_options patch.
It was easier for me to split it. The split is not always logical.
But if we are not happy with it, it is simple to make a big patch from
this one.
Deleted: branches/experimental/debian/patches/437_su_add_GNU_options
===================================================================
--- branches/experimental/debian/patches/437_su_add_GNU_options 2005-07-24 20:30:34 UTC (rev 400)
+++ branches/experimental/debian/patches/437_su_add_GNU_options 2005-07-24 20:40:09 UTC (rev 401)
@@ -1,376 +0,0 @@
-Goal: add -m, -p and -s command line options to match GNU options
-Fixes: #45394, #46424
-
-Status wrt upstream: Upstream does not support these options.
-
-Note: As the patch is quite big, and it probably cannot be splitted in
- smaller parts, I will try to describe the diffs:
-
- * switch to getopt to add the -m, -p and -s options
- * by default (if no -m or -p is provided), the environment is changed
- (change_environment=1)
- * the user can specify the shell, if he does not have a restricted shell
- * some functions were borrowed to GNU shell-utils' su
- (this is also the case of current upstream, even if those functions
- drastically evoled separately in Debian and upstream (run_shell))
- In debian, more work is performed in run_shell, because all options are
- parsed earlier with getopt.
- * There is an "usage"
- * if the user don't whant to change the environment (-m or -p options),
- SHELL is used for the new shell (except if this user has a restricted
- shell, in this case, she keep her restricted shell).
- Also, even when the environment is not changed, IFS is reset to the
- default \t\n value.
-
-Index: shadow-4.0.3/src/su.c
-===================================================================
---- shadow-4.0.3.orig/src/su.c 2005-05-30 23:13:57.716974000 +0200
-+++ shadow-4.0.3/src/su.c 2005-05-30 23:17:27.126974000 +0200
-@@ -49,6 +49,7 @@
- #include <grp.h>
- #include <signal.h>
- #include <pwd.h>
-+#include <getopt.h>
- #include "pwauth.h"
- #include "getdef.h"
-
-@@ -79,6 +80,18 @@
-
- /* local function prototypes */
-
-+/* If nonzero, change some environment vars to indicate the user su'd to. */
-+static int change_environment;
-+
-+static struct option const longopts[] =
-+{
-+ {"command", required_argument, 0, 'c'},
-+ {"preserve-environment", no_argument, 0, 'p'},
-+ {"shell", required_argument, 0, 's'},
-+ {"help", no_argument, 0, 'h'},
-+ {0, 0, 0, 0}
-+};
-+
- #ifndef USE_PAM
-
- static RETSIGTYPE die (int);
-@@ -118,6 +131,96 @@
- }
- #endif /* !USE_PAM */
-
-+/* borrowed from GNU sh-utils' "su.c" */
-+static int
-+restricted_shell (const char *shell)
-+{
-+ char *line;
-+
-+ setusershell ();
-+ while ((line = getusershell ()) != NULL) {
-+ if (*line != '#' && strcmp (line, shell) == 0) {
-+ endusershell ();
-+ return 0;
-+ }
-+ }
-+ endusershell ();
-+ return 1;
-+}
-+
-+/* borrowed from GNU sh-utils' "su.c" */
-+static int
-+elements (char **arr)
-+{
-+ int n = 0;
-+
-+ for (n = 0; *arr; ++arr)
-+ ++n;
-+ return n;
-+}
-+
-+/* borrowed from GNU sh-utils' "su.c" */
-+static void
-+run_shell (char *shell, const char *command, char **additional_args, int login)
-+{
-+ const char **args;
-+ int argno = 1;
-+ char cmd[BUFSIZ];
-+ int cmd_len_left = sizeof(cmd) - 1;
-+
-+ cmd[0] = '\0';
-+
-+ if (additional_args)
-+ args = (const char **) xmalloc (sizeof (char *)
-+ * (10 + elements (additional_args)));
-+ else
-+ args = (const char **) xmalloc (sizeof (char *) * 10);
-+
-+ if (login)
-+ {
-+ char *arg0;
-+ char *shell_basename;
-+
-+ shell_basename = getdef_str("SU_NAME");
-+ if (!shell_basename)
-+ shell_basename = Basename(shell);
-+
-+ arg0 = xmalloc (strlen (shell_basename) + 2);
-+ arg0[0] = '-';
-+ strcpy (arg0 + 1, shell_basename);
-+ args[0] = arg0;
-+ }
-+ else
-+ args[0] = Basename(shell);
-+ if (command || additional_args)
-+ args[argno++] = "-c";
-+ if (command) {
-+ if (strlen(command) > cmd_len_left) {
-+ fprintf(stderr, _("Command line args too long\n"));
-+ exit(1);
-+ }
-+ strcat(cmd, command);
-+ cmd_len_left -= strlen(command);
-+ }
-+ if (additional_args)
-+ for (; *additional_args; ++additional_args) {
-+ if ((strlen(*additional_args) + 1) > cmd_len_left) {
-+ fprintf(stderr, _("Command line args too long\n"));
-+ exit(1);
-+ }
-+ if (cmd[0]) {
-+ strcat(cmd, " ");
-+ cmd_len_left--;
-+ }
-+ strcat(cmd, *additional_args);
-+ cmd_len_left -= strlen(*additional_args);
-+ }
-+ if (cmd[0]) args[argno++] = cmd;
-+ args[argno] = NULL;
-+ execv (shell, (char **) args);
-+ fprintf (stderr, _("No shell\n"));
-+ SYSLOG((LOG_WARN, "Cannot execute %s\n", shell));
-+}
-
- static void su_failure (const char *tty)
- {
-@@ -153,13 +256,14 @@
- {
- char *cp;
- const char *tty = 0; /* Name of tty SU is run from */
-- int doshell = 0;
- int fakelogin = 0;
- int amroot = 0;
- uid_t my_uid;
- struct passwd *pw = 0;
- char **envp = environ;
--
-+ char *command = 0, *shell = 0, **additional_args = 0;
-+ int optc;
-+ char *tmp_name;
- #ifdef USE_PAM
- int ret;
- #else /* !USE_PAM */
-@@ -180,6 +284,8 @@
- bindtextdomain (PACKAGE, LOCALEDIR);
- textdomain (PACKAGE);
-
-+ change_environment = 1;
-+
- /*
- * Get the program name. The program name is used as a prefix to
- * most error messages.
-@@ -224,15 +330,55 @@
- * Process the command line arguments.
- */
-
-- argc--;
-- argv++; /* shift out command name */
--
-- if (argc > 0 && strcmp (argv[0], "-") == 0) {
-+ while ((optc = getopt_long (argc, argv, "c:mps:h", longopts, NULL)) != -1) {
-+ switch (optc) {
-+ case 0:
-+ break;
-+ case 'c':
-+ command = optarg;
-+ break;
-+ case 'm':
-+ case 'p':
-+ change_environment = 0;
-+ break;
-+ case 's':
-+ shell = optarg;
-+ break;
-+ default:
-+ fprintf(stderr, _("\
-+Usage: su [OPTS] [-] [username [ARGS]]\n\
-+ - make this a login shell\n\
-+ -c, --command=<command>\n\
-+ pass command to the invoked shell using its -c\n\
-+ option\n\
-+ -m, -p, --preserve-environment\n\
-+ do not reset environment variables, and keep the\n\
-+ same shell\n\
-+ -s, --shell=<shell>\n\
-+ use shell instead of the default in /etc/passwd\n"));
-+ exit(1);
-+ }
-+ }
-+
-+ if (optind < argc && !strcmp (argv[optind], "-")) {
- fakelogin = 1;
-- argc--;
-- argv++; /* shift ... */
-+ ++optind;
- }
-
-+ if (optind < argc)
-+ strncpy(name, argv[optind++], sizeof(name) - 1);
-+ else {
-+ struct passwd *root_pw = getpwuid(0);
-+ if (root_pw == NULL) {
-+ SYSLOG((LOG_CRIT, "There is no UID 0 user."));
-+ su_failure(tty);
-+ }
-+ strcpy(name, root_pw->pw_name);
-+ }
-+
-+ if (optind < argc)
-+ additional_args = argv + optind;
-+
- /*
- * If a new login is being set up, the old environment will be
- * ignored and a new one created later on.
-@@ -258,30 +404,6 @@
- }
-
- /*
-- * The next argument must be either a user ID, or some flag to a
-- * subshell. Pretty sticky since you can't have an argument which
-- * doesn't start with a "-" unless you specify the new user name.
-- * Any remaining arguments will be passed to the user's login shell.
-- */
--
-- if (argc > 0 && argv[0][0] != '-') {
-- STRFCPY (name, argv[0]); /* use this login id */
-- argc--;
-- argv++; /* shift ... */
-- }
-- if (!name[0]) /* use default user ID */
-- {
-- struct passwd *root_pw = getpwuid(0);
-- if (root_pw == NULL) {
-- SYSLOG((LOG_CRIT, "There is no UID 0 user."));
-- su_failure(tty)
-- }
-- strcpy(name, root_pw->pw_name);
-- }
--
-- doshell = argc == 0; /* any arguments remaining? */
--
-- /*
- * Get the user's real name. The current UID is used to determine
- * who has executed su. That user ID must exist.
- */
-@@ -406,8 +528,15 @@
- * Set the default shell.
- */
-
-- if (pwent.pw_shell[0] == '\0')
-- pwent.pw_shell = "/bin/sh"; /* XXX warning: const */
-+ if (pwent.pw_shell == NULL || pwent.pw_shell[0] == '\0')
-+ pwent.pw_shell = (char *) "/bin/sh";
-+
-+ if (shell == 0 && change_environment == 0)
-+ shell = getenv ("SHELL");
-+ if (shell != 0 && getuid () && restricted_shell (pwent.pw_shell))
-+ shell = 0;
-+ if (shell == 0)
-+ shell = (char *) strdup (pwent.pw_shell);
-
- #ifdef USE_PAM
- ret = pam_authenticate (pamh, 0);
-@@ -514,10 +643,14 @@
- }
- #endif
-
-- environ = newenvp; /* make new environment active */
--
-- if (getenv ("IFS")) /* don't export user IFS ... */
-- addenv ("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
-+ if (change_environment || restricted_shell(pwent.pw_shell)) {
-+ environ = newenvp; /* make new environment active */
-+ if (getenv ("IFS")) /* don't export user IFS ... */
-+ addenv("IFS= \t\n", NULL); /* ... instead, set a safe IFS */
-+ } else {
-+ if (getenv ("IFS"))
-+ putenv("IFS= \t\n");
-+ }
-
- if (pwent.pw_shell[0] == '*') { /* subsystem root required */
- pwent.pw_shell++; /* skip the '*' */
-@@ -580,13 +713,13 @@
- exit (1);
- #endif /* !USE_PAM */
-
-- if (fakelogin)
-- setup_env (&pwent);
-+ if (fakelogin && (change_environment || restricted_shell(pwent.pw_shell)))
-+ setup_env(&pwent);
- #if 1 /* Suggested by Joey Hess. XXX - is this right? */
-- else {
-- addenv ("HOME", pwent.pw_dir);
-- addenv ("USER", pwent.pw_name);
-- addenv ("SHELL", pwent.pw_shell);
-+ else if (change_environment || restricted_shell(pwent.pw_shell)) {
-+ addenv("HOME", pwent.pw_dir);
-+ addenv("USER", pwent.pw_name);
-+ addenv("SHELL", shell);
- }
- #endif
-
-@@ -599,46 +732,6 @@
- */
- closelog ();
-
-- /*
-- * See if the user has extra arguments on the command line. In that
-- * case they will be provided to the new user's shell as arguments.
-- */
--
-- if (fakelogin) {
-- char *arg0;
--
--#if 0 /* XXX - GNU su doesn't do this. --marekm */
-- if (!hushed (&pwent)) {
-- motd ();
-- mailcheck ();
-- }
--#endif
-- cp = getdef_str ("SU_NAME");
-- if (!cp)
-- cp = Basename (pwent.pw_shell);
--
-- arg0 = xmalloc (strlen (cp) + 2);
-- arg0[0] = '-';
-- strcpy (arg0 + 1, cp);
-- cp = arg0;
-- } else
-- cp = Basename (pwent.pw_shell);
--
-- if (!doshell) {
--
-- /*
-- * Use new user's shell from /etc/passwd and create an argv
-- * with the rest of the command line included.
-- */
--
-- argv[-1] = pwent.pw_shell;
-- (void) execv (pwent.pw_shell, &argv[-1]);
-- (void) fprintf (stderr, _("No shell\n"));
-- SYSLOG ((LOG_WARN, "Cannot execute %s", pwent.pw_shell));
-- closelog ();
-- exit (1);
-- }
--
-- shell (pwent.pw_shell, cp);
-+ run_shell (shell, command, additional_args, fakelogin);
- /*NOTREACHED*/ exit (1);
- }
Added: branches/experimental/debian/patches/437_su_add_GNU_options_1
===================================================================
--- branches/experimental/debian/patches/437_su_add_GNU_options_1 2005-07-24 20:30:34 UTC (rev 400)
+++ branches/experimental/debian/patches/437_su_add_GNU_options_1 2005-07-24 20:40:09 UTC (rev 401)
@@ -0,0 +1,182 @@
+Goal: First patch to switch to getopt.
+ Still incomplete.
+ Done:
+ * selection of the shell (-s).
+ Broken:
+ * additional_args is set, but not used.
+ * !doshell is broken (argv is not incremented)
+Index: shadow-4.0.10/src/su.c
+===================================================================
+--- shadow-4.0.10.orig/src/su.c 2005-07-19 23:12:26.000000000 +0200
++++ shadow-4.0.10/src/su.c 2005-07-19 23:43:57.000000000 +0200
+@@ -49,6 +49,7 @@
+ #include <grp.h>
+ #include <signal.h>
+ #include <pwd.h>
++#include <getopt.h>
+ #include "pwauth.h"
+ #include "getdef.h"
+
+@@ -79,6 +80,18 @@
+
+ /* local function prototypes */
+
++/* If nonzero, change some environment vars to indicate the user su'd to. */
++static int change_environment;
++
++static struct option const longopts[] =
++{
++ {"command", required_argument, 0, 'c'},
++ {"preserve-environment", no_argument, 0, 'p'},
++ {"shell", required_argument, 0, 's'},
++ {"help", no_argument, 0, 'h'},
++ {0, 0, 0, 0}
++};
++
+ #ifndef USE_PAM
+
+ static RETSIGTYPE die (int);
+@@ -263,6 +276,8 @@
+ uid_t my_uid;
+ struct passwd *pw = 0;
+ char **envp = environ;
++ char *command = 0, *shell = 0, **additional_args = 0;
++ int optc;
+
+ #ifdef USE_PAM
+ int ret;
+@@ -283,6 +298,8 @@
+ bindtextdomain (PACKAGE, LOCALEDIR);
+ textdomain (PACKAGE);
+
++ change_environment = 1;
++
+ /*
+ * Get the program name. The program name is used as a prefix to
+ * most error messages.
+@@ -326,15 +343,56 @@
+ * Process the command line arguments.
+ */
+
+- argc--;
+- argv++; /* shift out command name */
++ while ((optc = getopt_long (argc, argv, "c:mps:h", longopts, NULL)) != -1) {
++ switch (optc) {
++ case 0:
++ break;
++ case 'c':
++ command = optarg;
++ break;
++ case 'm':
++ case 'p':
++ change_environment = 0;
++ break;
++ case 's':
++ shell = optarg;
++ break;
++ default:
++ fprintf(stderr, _("\
++Usage: su [OPTS] [-] [username [ARGS]]\n\
++ - make this a login shell\n\
++ -c, --command=<command>\n\
++ pass command to the invoked shell using its -c\n\
++ option\n\
++ -m, -p, --preserve-environment\n\
++ do not reset environment variables, and keep the\n\
++ same shell\n\
++ -s, --shell=<shell>\n\
++ use shell instead of the default in /etc/passwd\n"));
++ exit(1);
++ }
++ }
+
+- if (argc > 0 && strcmp (argv[0], "-") == 0) {
++ if (optind < argc && !strcmp (argv[optind], "-")) {
+ fakelogin = 1;
+- argc--;
+- argv++; /* shift ... */
++ ++optind;
++ }
++
++ if (optind < argc)
++ strncpy(name, argv[optind++], sizeof(name) - 1);
++ else {
++ struct passwd *root_pw = getpwuid(0);
++ if (root_pw == NULL) {
++ SYSLOG((LOG_CRIT, "There is no UID 0 user."));
++ su_failure(tty);
++ }
++ strcpy(name, root_pw->pw_name);
+ }
+
++ if (optind < argc)
++ additional_args = argv + optind;
++
++
+ /*
+ * If a new login is being set up, the old environment will be
+ * ignored and a new one created later on.
+@@ -369,29 +427,7 @@
+ addenv (*envp++, NULL);
+ }
+
+- /*
+- * The next argument must be either a user ID, or some flag to a
+- * subshell. Pretty sticky since you can't have an argument which
+- * doesn't start with a "-" unless you specify the new user name.
+- * Any remaining arguments will be passed to the user's login shell.
+- */
+-
+- if (argc > 0 && argv[0][0] != '-') {
+- STRFCPY (name, argv[0]); /* use this login id */
+- argc--;
+- argv++; /* shift ... */
+- }
+- if (!name[0]) /* use default user ID */
+- {
+- struct passwd *root_pw = getpwuid(0);
+- if (root_pw == NULL) {
+- SYSLOG((LOG_CRIT, "There is no UID 0 user."));
+- su_failure(tty);
+- }
+- strcpy(name, root_pw->pw_name);
+- }
+-
+- doshell = argc == 0; /* any arguments remaining? */
++ doshell = optind == argc; /* any arguments remaining? */
+
+ /*
+ * Get the user's real name. The current UID is used to determine
+@@ -513,6 +549,23 @@
+ if (pwent.pw_shell[0] == '\0')
+ pwent.pw_shell = "/bin/sh"; /* XXX warning: const */
+
++ /* If the user do not want to change the environment,
++ * use the current SHELL.
++ * (unless another shell is required by the command line)
++ */
++ if (shell == 0 && change_environment == 0)
++ shell = getenv ("SHELL");
++ /* For users whith non null UID, if this user has a restricted
++ * shell, the shell must be the one specified in /etc/passwd
++ */
++ if (shell != 0 && getuid () && restricted_shell (pwent.pw_shell))
++ shell = 0;
++ /* If the shell is not set at this time, use the shell specified
++ * in /etc/passwd.
++ */
++ if (shell == 0)
++ shell = (char *) strdup (pwent.pw_shell);
++
+ #ifdef USE_PAM
+ ret = pam_authenticate (pamh, 0);
+ if (ret != PAM_SUCCESS) {
+@@ -692,7 +745,7 @@
+ else {
+ addenv ("HOME", pwent.pw_dir);
+ addenv ("USER", pwent.pw_name);
+- addenv ("SHELL", pwent.pw_shell);
++ addenv ("SHELL", shell);
+ }
+ #endif
+
Added: branches/experimental/debian/patches/437_su_add_GNU_options_2
===================================================================
--- branches/experimental/debian/patches/437_su_add_GNU_options_2 2005-07-24 20:30:34 UTC (rev 400)
+++ branches/experimental/debian/patches/437_su_add_GNU_options_2 2005-07-24 20:40:09 UTC (rev 401)
@@ -0,0 +1,196 @@
+Goal:
+ * need restricted_shell() for --preserve-environment
+ * run_shell has to be available when !USE_PAM
+ * for -c, we need to add arguments. It is safer to allocate a new
+ array than using argv. We need the elements() function to compute the
+ number of additional arguments.
+ * arg0 is computed in run_shell.
+ * There is no more need for doshell. We know that we only need to
+ execute a shell when there is no additional arguments.
+Index: shadow-4.0.10/src/su.c
+===================================================================
+--- shadow-4.0.10.orig/src/su.c 2005-07-22 19:32:04.000000000 +0200
++++ shadow-4.0.10/src/su.c 2005-07-22 19:35:30.000000000 +0200
+@@ -131,6 +131,24 @@
+ }
+ #endif /* !USE_PAM */
+
++/* borrowed from GNU sh-utils' "su.c" */
++static int
++restricted_shell (const char *shell)
++{
++ char *line;
++
++ setusershell ();
++ while ((line = getusershell ()) != NULL) {
++ if (*line != '#' && strcmp (line, shell) == 0) {
++ endusershell ();
++ return 0;
++ }
++ }
++ endusershell ();
++ return 1;
++}
++
++
+
+ static void su_failure (const char *tty)
+ {
+@@ -154,23 +172,70 @@
+ {
+ ++caught;
+ }
++#endif
++
++/* borrowed from GNU sh-utils' "su.c" */
++static int elements (char **arr)
++{
++ int n = 0;
++ if (arr)
++ for (n = 0; *arr; ++arr)
++ ++n;
++
++ return n;
++}
+
+ /* This I ripped out of su.c from sh-utils after the Mandrake pam patch
+ * have been applied. Some work was needed to get it integrated into
+ * su.c from shadow.
+ */
+-static void run_shell (const char *shellstr, char *args[], int doshell)
++static void run_shell (const char *shellstr, char **additional_args, int fakelogin)
+ {
++ const char **args;
+ int child;
+ sigset_t ourset;
+ int status;
+ int ret;
++ int argno = 0;
++
++ args = (const char **)xmalloc(sizeof (char *)
++ * (2 + elements (additional_args)));
+
++ if (fakelogin) {
++ char *arg0;
++ char *shell_basename;
++
++ shell_basename = getdef_str ("SU_NAME");
++ if (!shell_basename)
++ shell_basename = Basename (shellstr);
++
++ arg0 = xmalloc (strlen (shell_basename) + 2);
++ arg0[0] = '-';
++ strcpy (arg0 + 1, shell_basename);
++ args[0] = arg0;
++ } else
++ args[0] = Basename (shellstr);
++ argno = 1;
++
++ if (additional_args) {
++ for (; *additional_args; ++additional_args) {
++ args[argno++] = *additional_args;
++ }
++ }
++ args[argno] = NULL;
++
++#ifndef USE_PAM
++ if (argno > 1)
++ (void) execv (shellstr, args);
++ else
++ shell (shellstr, args[0]);
++ /* NOT REACHED */
++#else
+ child = fork ();
+ if (child == 0) { /* child shell */
+ pam_end (pamh, PAM_SUCCESS);
+
+- if (doshell)
++ if (argno == 1)
+ shell (shellstr, (char *) args[0]);
+ else
+ (void) execv (shellstr, (char **) args);
+@@ -248,8 +313,8 @@
+ }
+
+ exit (WEXITSTATUS (status));
++#endif /* USE_PAM */
+ }
+-#endif
+
+ /*
+ * su - switch user id
+@@ -270,7 +335,6 @@
+ char *cp;
+ char **envcp;
+ const char *tty = 0; /* Name of tty SU is run from */
+- int doshell = 0;
+ int fakelogin = 0;
+ int amroot = 0;
+ uid_t my_uid;
+@@ -392,7 +456,6 @@
+ if (optind < argc)
+ additional_args = argv + optind;
+
+-
+ /*
+ * If a new login is being set up, the old environment will be
+ * ignored and a new one created later on.
+@@ -427,8 +490,6 @@
+ addenv (*envp++, NULL);
+ }
+
+- doshell = optind == argc; /* any arguments remaining? */
+-
+ /*
+ * Get the user's real name. The current UID is used to determine
+ * who has executed su. That user ID must exist.
+@@ -758,48 +819,7 @@
+ */
+ closelog ();
+
+- /*
+- * See if the user has extra arguments on the command line. In that
+- * case they will be provided to the new user's shell as arguments.
+- */
+-
+- if (fakelogin) {
+- char *arg0;
+-
+- cp = getdef_str ("SU_NAME");
+- if (!cp)
+- cp = Basename (pwent.pw_shell);
+-
+- arg0 = xmalloc (strlen (cp) + 2);
+- arg0[0] = '-';
+- strcpy (arg0 + 1, cp);
+- cp = arg0;
+- } else
+- cp = Basename (pwent.pw_shell);
+-
+- if (!doshell) {
+-
+- /*
+- * Use new user's shell from /etc/passwd and create an argv
+- * with the rest of the command line included.
+- */
+-
+- argv[-1] = pwent.pw_shell;
+-#ifndef USE_PAM
+- (void) execv (pwent.pw_shell, &argv[-1]);
+-#else
+- run_shell (pwent.pw_shell, &argv[-1], 0);
+-#endif
+- (void) fprintf (stderr, _("No shell\n"));
+- SYSLOG ((LOG_WARN, "Cannot execute %s", pwent.pw_shell));
+- closelog ();
+- exit (1);
+- }
+-#ifndef USE_PAM
+- shell (pwent.pw_shell, cp);
+-#else
+- run_shell (pwent.pw_shell, &cp, 1);
+-#endif
++ run_shell (shell, additional_args, fakelogin);
+ /* NOT REACHED */
+ exit (1);
+ }
Added: branches/experimental/debian/patches/437_su_add_GNU_options_3
===================================================================
--- branches/experimental/debian/patches/437_su_add_GNU_options_3 2005-07-24 20:30:34 UTC (rev 400)
+++ branches/experimental/debian/patches/437_su_add_GNU_options_3 2005-07-24 20:40:09 UTC (rev 401)
@@ -0,0 +1,128 @@
+Goal:
+ * add -c ability to run_shell.
+ * only change environment if the user did not requested to preserve
+ the environment, or if the user has a restricted shell.
+Index: shadow-4.0.10/src/su.c
+===================================================================
+--- shadow-4.0.10.orig/src/su.c 2005-07-22 18:48:13.000000000 +0200
++++ shadow-4.0.10/src/su.c 2005-07-22 18:49:13.000000000 +0200
+@@ -188,7 +188,10 @@
+ * have been applied. Some work was needed to get it integrated into
+ * su.c from shadow.
+ */
+-static void run_shell (const char *shellstr, char **additional_args, int fakelogin)
++static void run_shell (const char *shellstr,
++ const char *command,
++ char **additional_args,
++ int fakelogin)
+ {
+ const char **args;
+ int child;
+@@ -197,8 +200,10 @@
+ int ret;
+ int argno = 0;
+
++ /* There is at most 4 arguments (arg0, '-c', <command>, NULL) + the
++ * number of arguments in the additional_args array. */
+ args = (const char **)xmalloc(sizeof (char *)
+- * (2 + elements (additional_args)));
++ * (4 + elements (additional_args)));
+
+ if (fakelogin) {
+ char *arg0;
+@@ -216,11 +221,17 @@
+ args[0] = Basename (shellstr);
+ argno = 1;
+
++ if (command) {
++ args[argno++] = "-c";
++ args[argno++] = command;
++ }
++
+ if (additional_args) {
+ for (; *additional_args; ++additional_args) {
+ args[argno++] = *additional_args;
+ }
+ }
++
+ args[argno] = NULL;
+
+ #ifndef USE_PAM
+@@ -720,7 +731,9 @@
+
+ /* setup the environment for pam later on, else we run into auth problems */
+ #ifndef USE_PAM
+- environ = newenvp; /* make new environment active */
++ if (change_environment || restricted_shell(pwent.pw_shell)) {
++ environ = newenvp; /* make new environment active */
++ }
+ #endif
+
+ if (getenv ("IFS")) /* don't export user IFS ... */
+@@ -771,18 +784,20 @@
+ exit (1);
+ }
+
+- /* we need to setup the environment *after* pam_open_session(),
+- * else the UID is changed before stuff like pam_xauth could
+- * run, and we cannot access /etc/shadow and co
+- */
+- environ = newenvp; /* make new environment active */
+-
+- /* update environment with all pam set variables */
+- envcp = pam_getenvlist (pamh);
+- if (envcp) {
+- while (*envcp) {
+- addenv (*envcp, NULL);
+- envcp++;
++ if (change_environment || restricted_shell(pwent.pw_shell)) {
++ /* we need to setup the environment *after* pam_open_session(),
++ * else the UID is changed before stuff like pam_xauth could
++ * run, and we cannot access /etc/shadow and co
++ */
++ environ = newenvp; /* make new environment active */
++
++ /* update environment with all pam set variables */
++ envcp = pam_getenvlist (pamh);
++ if (envcp) {
++ while (*envcp) {
++ addenv (*envcp, NULL);
++ envcp++;
++ }
+ }
+ }
+
+@@ -800,15 +815,17 @@
+ exit (1);
+ #endif /* !USE_PAM */
+
+- if (fakelogin)
+- setup_env (&pwent);
++ if (change_environment || restricted_shell (pwent.pw_shell)) {
++ if (fakelogin )
++ setup_env (&pwent);
+ #if 1 /* Suggested by Joey Hess. XXX - is this right? */
+- else {
+- addenv ("HOME", pwent.pw_dir);
+- addenv ("USER", pwent.pw_name);
+- addenv ("SHELL", shell);
+- }
++ else {
++ addenv ("HOME", pwent.pw_dir);
++ addenv ("USER", pwent.pw_name);
++ addenv ("SHELL", shell);
++ }
+ #endif
++ }
+
+ /*
+ * This is a workaround for Linux libc bug/feature (?) - the
+@@ -819,7 +836,7 @@
+ */
+ closelog ();
+
+- run_shell (shell, additional_args, fakelogin);
++ run_shell (shell, command, additional_args, fakelogin);
+ /* NOT REACHED */
+ exit (1);
+ }
Added: branches/experimental/debian/patches/437_su_add_GNU_options_4
===================================================================
--- branches/experimental/debian/patches/437_su_add_GNU_options_4 2005-07-24 20:30:34 UTC (rev 400)
+++ branches/experimental/debian/patches/437_su_add_GNU_options_4 2005-07-24 20:40:09 UTC (rev 401)
@@ -0,0 +1,139 @@
+Goal:
+ * remove compilation warnings (Basename)
+ * no more use shell() for executing a shell whithout argument.
+ This may have some implications on the environment: shell used to use
+ execle with newenvp as the new environment.
+ I think it is preferable to have the ssame behavior when there are
+ or isn't any argument.
+ if !change_environment (and the user shell is not restricted), we
+ need to add all the environmental variables to newenvp (with addenv)
+ and to copy newenvp to environ.
+ * if fakelogin, some env variables are set. This must not be done if
+ --preserve-environment wasspecified (for users whose shell is not
+ restricted)
+Index: shadow-4.0.10/src/su.c
+===================================================================
+--- shadow-4.0.10.orig/src/su.c 2005-07-22 19:39:09.000000000 +0200
++++ shadow-4.0.10/src/su.c 2005-07-22 19:51:55.000000000 +0200
+@@ -212,14 +212,14 @@
+
+ shell_basename = getdef_str ("SU_NAME");
+ if (!shell_basename)
+- shell_basename = Basename (shellstr);
++ shell_basename = Basename ((char *)shellstr);
+
+ arg0 = xmalloc (strlen (shell_basename) + 2);
+ arg0[0] = '-';
+ strcpy (arg0 + 1, shell_basename);
+ args[0] = arg0;
+ } else
+- args[0] = Basename (shellstr);
++ args[0] = Basename ((char *)shellstr);
+ argno = 1;
+
+ if (command) {
+@@ -236,20 +236,14 @@
+ args[argno] = NULL;
+
+ #ifndef USE_PAM
+- if (argno > 1)
+- (void) execv (shellstr, args);
+- else
+- shell (shellstr, args[0]);
++ (void) execv (shellstr, args);
+ /* NOT REACHED */
+ #else
+ child = fork ();
+ if (child == 0) { /* child shell */
+ pam_end (pamh, PAM_SUCCESS);
+
+- if (argno == 1)
+- shell (shellstr, (char *) args[0]);
+- else
+- (void) execv (shellstr, (char **) args);
++ (void) execv (shellstr, (char **) args);
+ {
+ int exit_status = (errno == ENOENT ? 127 : 126);
+
+@@ -468,40 +462,6 @@
+ additional_args = argv + optind;
+
+ /*
+- * If a new login is being set up, the old environment will be
+- * ignored and a new one created later on.
+- */
+-
+- if (fakelogin) {
+- if ((cp = getdef_str ("ENV_TZ")))
+- addenv (*cp == '/' ? tz (cp) : cp, NULL);
+- /*
+- * The clock frequency will be reset to the login value if required
+- */
+- if ((cp = getdef_str ("ENV_HZ")))
+- addenv (cp, NULL); /* set the default $HZ, if one */
+- /*
+- * The terminal type will be left alone if it is present in
+- * the environment already.
+- */
+- if ((cp = getenv ("TERM")))
+- addenv ("TERM", cp);
+-#ifndef USE_PAM
+- /*
+- * Also leave DISPLAY and XAUTHORITY if present, else
+- * pam_xauth will not work.
+- */
+- if ((cp = getenv ("DISPLAY")))
+- addenv ("DISPLAY", cp);
+- if ((cp = getenv ("XAUTHORITY")))
+- addenv ("XAUTHORITY", cp);
+-#endif /* !USE_PAM */
+- } else {
+- while (*envp)
+- addenv (*envp++, NULL);
+- }
+-
+- /*
+ * Get the user's real name. The current UID is used to determine
+ * who has executed su. That user ID must exist.
+ */
+@@ -568,6 +528,40 @@
+ #endif /* !USE_PAM */
+ pwent = *pw;
+
++ /*
++ * If a new login is being set up, the old environment will be
++ * ignored and a new one created later on.
++ */
++
++ if (fakelogin && (change_environment || restricted_shell(pwent.pw_shell))) {
++ if ((cp = getdef_str ("ENV_TZ")))
++ addenv (*cp == '/' ? tz (cp) : cp, NULL);
++ /*
++ * The clock frequency will be reset to the login value if required
++ */
++ if ((cp = getdef_str ("ENV_HZ")))
++ addenv (cp, NULL); /* set the default $HZ, if one */
++ /*
++ * The terminal type will be left alone if it is present in
++ * the environment already.
++ */
++ if ((cp = getenv ("TERM")))
++ addenv ("TERM", cp);
++#ifndef USE_PAM
++ /*
++ * Also leave DISPLAY and XAUTHORITY if present, else
++ * pam_xauth will not work.
++ */
++ if ((cp = getenv ("DISPLAY")))
++ addenv ("DISPLAY", cp);
++ if ((cp = getenv ("XAUTHORITY")))
++ addenv ("XAUTHORITY", cp);
++#endif /* !USE_PAM */
++ } else {
++ while (*envp)
++ addenv (*envp++, NULL);
++ }
++
+ #ifndef USE_PAM
+ /*
+ * BSD systems only allow "wheel" to SU to root. USG systems don't,
Added: branches/experimental/debian/patches/437_su_add_GNU_options_5
===================================================================
--- branches/experimental/debian/patches/437_su_add_GNU_options_5 2005-07-24 20:30:34 UTC (rev 400)
+++ branches/experimental/debian/patches/437_su_add_GNU_options_5 2005-07-24 20:40:09 UTC (rev 401)
@@ -0,0 +1,31 @@
+Goal: report failure to execute the shell to the user and to syslog.
+ Also, return a 126 or 127 exit status when !USE_PAM (was mising
+ from another patch.
+
+Index: shadow-4.0.10/src/su.c
+===================================================================
+--- shadow-4.0.10.orig/src/su.c 2005-07-22 10:34:01.000000000 +0200
++++ shadow-4.0.10/src/su.c 2005-07-22 10:36:52.000000000 +0200
+@@ -237,6 +237,13 @@
+
+ #ifndef USE_PAM
+ (void) execv (shellstr, args);
++ fprintf (stderr, _("No shell\n"));
++ SYSLOG((LOG_WARN, "Cannot execute %s\n", shellstr));
++ {
++ int exit_status = (errno == ENOENT ? 127 : 126);
++
++ exit (exit_status);
++ }
+ /* NOT REACHED */
+ #else
+ child = fork ();
+@@ -244,6 +251,8 @@
+ pam_end (pamh, PAM_SUCCESS);
+
+ (void) execv (shellstr, (char **) args);
++ fprintf (stderr, _("No shell\n"));
++ SYSLOG((LOG_WARN, "Cannot execute %s\n", shellstr));
+ {
+ int exit_status = (errno == ENOENT ? 127 : 126);
+
Added: branches/experimental/debian/patches/437_su_add_GNU_options_6
===================================================================
--- branches/experimental/debian/patches/437_su_add_GNU_options_6 2005-07-24 20:30:34 UTC (rev 400)
+++ branches/experimental/debian/patches/437_su_add_GNU_options_6 2005-07-24 20:40:09 UTC (rev 401)
@@ -0,0 +1,15 @@
+Goal: I'm not sure if the pw_shell can be NULL, but checking can't arm.
+
+Index: shadow-4.0.10/src/su.c
+===================================================================
+--- shadow-4.0.10.orig/src/su.c 2005-07-22 10:36:52.000000000 +0200
++++ shadow-4.0.10/src/su.c 2005-07-22 10:41:12.000000000 +0200
+@@ -622,7 +622,7 @@
+ * Set the default shell.
+ */
+
+- if (pwent.pw_shell[0] == '\0')
++ if (pwent.pw_shell == NULL || pwent.pw_shell[0] == '\0')
+ pwent.pw_shell = "/bin/sh"; /* XXX warning: const */
+
+ /* If the user do not want to change the environment,
More information about the Pkg-shadow-commits
mailing list