[Pkg-shadow-devel] patch for su (needed by the switch to getopt in 4.0.14)

Nicolas François nicolas.francois at centraliens.net
Sun Dec 11 22:32:00 UTC 2005


Hello Tomasz,

Here are some additional fixes (patch to your CVS):
 * I replaced "shell" by "shellstr" ("shell" is also the name of a function)
 * I removed some stuff I forgot to remove in my last patches
 * another fixes due to getopt: argc is not decremented and argv is not
   incremented


Here are also other fixesi (not in the patch):
 * src/vipw: a "break" is missing in case 'q'

 * src/useradd.c: in the comment before the grp_add function:
                  s/grp_update/grp_add/
 * src/login.c: I'm not using WITH_AUDIT. I think #include "libaudit.h"
                should be inside a "#ifdef WITH_AUDIT"
                Also, maybe #include "libaudit.h" should be
                #include <libaudit.h>
                (or libaudit.h is missing)

Kind Regards,
-- 
Nekral
-------------- next part --------------
Index: src/su.c
===================================================================
RCS file: /cvsroot/shadow/src/su.c,v
retrieving revision 1.54
diff -u -r1.54 su.c
--- src/su.c	10 Dec 2005 20:48:17 -0000	1.54
+++ src/su.c	11 Dec 2005 22:19:53 -0000
@@ -115,13 +115,13 @@
 #endif				/* !USE_PAM */
 
 /* borrowed from GNU sh-utils' "su.c" */
-static int restricted_shell (const char *shell)
+static int restricted_shell (const char *shellstr)
 {
 	char *line;
 
 	setusershell ();
 	while ((line = getusershell ()) != NULL) {
-		if (*line != '#' && strcmp (line, shell) == 0) {
+		if (*line != '#' && strcmp (line, shellstr) == 0) {
 			endusershell ();
 			return 0;
 		}
@@ -253,7 +253,6 @@
   */
 static void usage (void)
 {
-// tabs seems dangerous here
 	fprintf (stderr, _("Usage: su [options] [login]\n"
 			   "\n"
 			   "Options:\n"
@@ -290,7 +289,7 @@
 	uid_t my_uid;
 	struct passwd *pw = 0;
 	char **envp = environ;
-	char *shell = 0;
+	char *shellstr = 0;
 
 #ifdef USE_PAM
 	int ret;
@@ -354,7 +353,7 @@
 				change_environment = 0;
 				break;
 			case 's':
-				shell = optarg;
+				shellstr = optarg;
 				break;
 			default:
 				usage ();
@@ -395,23 +394,19 @@
 		tty = "???";
 	}
 
-// Note this block was just moved earlier, because we need to check if
-// pwent.pw_shell is a restricted shell (and thus we need pwent earlier).
 	/*
 	 * 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 (optind < argc && argv[optind][0] != '-') {
+		STRFCPY (name, argv[optind++]);	/* use this login id */
 	}
 	if (!name[0])		/* use default user ID */
 		(void) strcpy (name, "root");
 
-	doshell = argc == 0;	/* any arguments remaining? */
+	doshell = argc == optind;	/* any arguments remaining? */
 
 	/*
 	 * Get the user's real name. The current UID is used to determine
@@ -566,24 +561,24 @@
 	 * use the current SHELL.
 	 * (unless another shell is required by the command line)
 	 */
-	if (shell == NULL && change_environment == 0)
-		shell = getenv ("SHELL");
+	if (shellstr == NULL && change_environment == 0)
+		shellstr = getenv ("SHELL");
 	/* For users with non null UID, if this user has a restricted
 	 * shell, the shell must be the one specified in /etc/passwd
 	 */
-	if (shell != NULL && getuid () && restricted_shell (pwent.pw_shell))
-		shell = NULL;
+	if (shellstr != NULL && getuid () && restricted_shell (pwent.pw_shell))
+		shellstr = NULL;
 	/* If the shell is not set at this time, use the shell specified
 	 * in /etc/passwd.
 	 */
-	if (shell == NULL)
-		shell = (char *) strdup (pwent.pw_shell);
+	if (shellstr == NULL)
+		shellstr = (char *) strdup (pwent.pw_shell);
 
 	/*
 	 * Set the default shell.
 	 */
-	if (shell == NULL || shell[0] == '\0')
-		shell = "/bin/sh";
+	if (shellstr == NULL || shellstr[0] == '\0')
+		shellstr = "/bin/sh";
 
 	signal (SIGINT, SIG_IGN);
 	signal (SIGQUIT, SIG_IGN);
@@ -781,7 +776,7 @@
 		else {
 			addenv ("HOME", pwent.pw_dir);
 			addenv ("USER", pwent.pw_name);
-			addenv ("SHELL", shell);
+			addenv ("SHELL", shellstr);
 		}
 	}
 
@@ -803,35 +798,37 @@
 
 		cp = getdef_str ("SU_NAME");
 		if (!cp)
-			cp = Basename (shell);
+			cp = Basename (shellstr);
 
 		arg0 = xmalloc (strlen (cp) + 2);
 		arg0[0] = '-';
 		strcpy (arg0 + 1, cp);
 		cp = arg0;
 	} else
-		cp = Basename (shell);
+		cp = Basename (shellstr);
 
 	if (!doshell) {
+		/* Position argv to the remaining arguments */
+		argv += optind;
 		/*
 		 * Use new user's shell from /etc/passwd and create an argv
 		 * with the rest of the command line included.
 		 */
-		argv[-1] = shell;
+		argv[-1] = shellstr;
 #ifndef USE_PAM
-		(void) execv (shell, &argv[-1]);
+		(void) execv (shellstr, &argv[-1]);
 #else
-		run_shell (shell, &argv[-1], 0);
+		run_shell (shellstr, &argv[-1], 0);
 #endif
 		(void) fprintf (stderr, _("No shell\n"));
-		SYSLOG ((LOG_WARN, "Cannot execute %s", shell));
+		SYSLOG ((LOG_WARN, "Cannot execute %s", shellstr));
 		closelog ();
 		exit (1);
 	}
 #ifndef USE_PAM
-	shell (shell, cp);
+	shell (shellstr, cp);
 #else
-	run_shell (shell, &cp, 1);
+	run_shell (shellstr, &cp, 1);
 #endif
 	/* NOT REACHED */
 	exit (1);


More information about the Pkg-shadow-devel mailing list