[Pkg-shadow-commits] r3357 - in upstream/trunk: . src

Nicolas FRANÇOIS nekral-guest at alioth.debian.org
Mon Jun 13 18:27:34 UTC 2011


Author: nekral-guest
Date: 2011-06-13 18:27:34 +0000 (Mon, 13 Jun 2011)
New Revision: 3357

Modified:
   upstream/trunk/ChangeLog
   upstream/trunk/NEWS
   upstream/trunk/src/su.c
Log:
	* src/su.c (prepare_pam_close_session): Extract the creation of a
	child and listening for signal in the parent from run_shell().
	prepare_pam_close_session() is now executed before the creation of
	the pam session and before the UID is changed. This allows to
	close the session as root.

Modified: upstream/trunk/ChangeLog
===================================================================
--- upstream/trunk/ChangeLog	2011-06-13 18:27:28 UTC (rev 3356)
+++ upstream/trunk/ChangeLog	2011-06-13 18:27:34 UTC (rev 3357)
@@ -1,3 +1,11 @@
+2011-06-13  Nicolas François  <nicolas.francois at centraliens.net>
+
+	* src/su.c (prepare_pam_close_session): Extract the creation of a
+	child and listening for signal in the parent from run_shell().
+	prepare_pam_close_session() is now executed before the creation of
+	the pam session and before the UID is changed. This allows to
+	close the session as root.
+
 2011-06-12  Nicolas François  <nicolas.francois at centraliens.net>
 
 	* src/su.c (save_caller_context): Extract from main() the code

Modified: upstream/trunk/NEWS
===================================================================
--- upstream/trunk/NEWS	2011-06-13 18:27:28 UTC (rev 3356)
+++ upstream/trunk/NEWS	2011-06-13 18:27:34 UTC (rev 3357)
@@ -46,6 +46,8 @@
   * Do not forward the controlling terminal to commands executed with -c.
     This prevents tty hijacking which could lead to execution with the
     caller's privileges.
+  * Close PAM sessions as root. This will be more friendly to PAM modules
+    like pam_mount or pam_systemd.
 - newgrp, sg, groupmems
   * Fix parsing of gshadow entries.
 - useradd

Modified: upstream/trunk/src/su.c
===================================================================
--- upstream/trunk/src/su.c	2011-06-13 18:27:28 UTC (rev 3356)
+++ upstream/trunk/src/su.c	2011-06-13 18:27:34 UTC (rev 3357)
@@ -257,49 +257,31 @@
 	caught = sig;
 }
 
-/* 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.
+/*
+ * Create a session and fork.
+ * Only the child returns. The parent will wait for the child to terminate
+ * and exit.
  */
-static void run_shell (const char *shellstr, char *args[], bool doshell,
-                       char *const envp[])
+static void prepare_pam_close_session (void)
 {
-	pid_t child;
 	sigset_t ourset;
 	int status;
 	int ret;
 
-	child = fork ();
-	if (child == 0) {	/* child shell */
-		/*
-		 * PAM_DATA_SILENT is not supported by some modules, and
-		 * there is no strong need to clean up the process space's
-		 * memory since we will either call exec or exit.
-		pam_end (pamh, PAM_SUCCESS | PAM_DATA_SILENT);
-		 */
-
-		if (doshell) {
-			(void) shell (shellstr, (char *) args[0], envp);
-		} else {
-			/* There is no need for a controlling terminal.
-			 * This avoids the callee to inject commands on
-			 * the caller's tty. */
-			(void) setsid ();
-
-			execve_shell (shellstr, (char **) args, envp);
-		}
-
-		exit (errno == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
-	} else if ((pid_t)-1 == child) {
+	pid_child = fork ();
+	if (pid_child == 0) {	/* child shell */
+		return; /* Only the child will return from pam_create_session */
+	} else if ((pid_t)-1 == pid_child) {
 		(void) fprintf (stderr,
 		                _("%s: Cannot fork user shell\n"),
 		                Prog);
 		SYSLOG ((LOG_WARN, "Cannot execute %s", shellstr));
 		closelog ();
 		exit (1);
+		/* Only the child returns. See above. */
 	}
+
 	/* parent only */
-	pid_child = child;
 	sigfillset (&ourset);
 	if (sigprocmask (SIG_BLOCK, &ourset, NULL) != 0) {
 		(void) fprintf (stderr,
@@ -320,8 +302,8 @@
 		    || (sigaction (SIGTERM, &action, NULL) != 0)
 		    || (   !doshell /* handle SIGINT (Ctrl-C), SIGQUIT
 		                     * (Ctrl-\), and SIGTSTP (Ctrl-Z)
-		                     * since the child does not control
-		                     * the tty anymore.
+		                     * since the child will not control
+		                     * the tty.
 		                     */
 		        && (   (sigaddset (&ourset, SIGINT)  != 0)
 		            || (sigaddset (&ourset, SIGQUIT) != 0)
@@ -359,7 +341,7 @@
 				 * We will SIGSTOP ourself on the next
 				 * waitpid round.
 				 */
-				kill (child, SIGSTOP);
+				kill (pid_child, SIGSTOP);
 				stop = false;
 			} else if (   ((pid_t)-1 != pid)
 			           && (0 != WIFSTOPPED (status))) {
@@ -377,13 +359,13 @@
 		(void) fputs ("\n", stderr);
 		(void) fputs (_("Session terminated, terminating shell..."),
 		              stderr);
-		(void) kill (child, caught);
+		(void) kill (pid_child, caught);
 	}
 
 	ret = pam_close_session (pamh, 0);
 	if (PAM_SUCCESS != ret) {
 		SYSLOG ((LOG_ERR, "pam_close_session: %s",
-			 pam_strerror (pamh, ret)));
+		         pam_strerror (pamh, ret)));
 		fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
 		(void) pam_end (pamh, ret);
 		exit (1);
@@ -401,9 +383,34 @@
 
 	exit ((0 != WIFEXITED (status)) ? WEXITSTATUS (status)
 	                                : WTERMSIG (status) + 128);
+	/* Only the child returns. See above. */
 }
-#endif
 
+static void run_shell (const char *shellstr, char *args[], bool doshell,
+                       char *const envp[])
+{
+		/*
+		 * PAM_DATA_SILENT is not supported by some modules, and
+		 * there is no strong need to clean up the process space's
+		 * memory since we will either call exec or exit.
+		pam_end (pamh, PAM_SUCCESS | PAM_DATA_SILENT);
+		 */
+
+		if (doshell) {
+			(void) shell (shellstr, (char *) args[0], envp);
+		} else {
+			/* There is no need for a controlling terminal.
+			 * This avoids the callee to inject commands on
+			 * the caller's tty. */
+			(void) setsid ();
+
+			execve_shell (shellstr, (char **) args, envp);
+		}
+
+		exit (errno == ENOENT ? E_CMD_NOTFOUND : E_CMD_NOEXEC);
+}
+#endif				/* USE_PAM */
+
 /*
  * usage - print command line syntax and exit
   */
@@ -929,9 +936,9 @@
 	ret = pam_start ("su", name, &conv, &pamh);
 	if (PAM_SUCCESS != ret) {
 		SYSLOG ((LOG_ERR, "pam_start: error %d", ret);
-			fprintf (stderr,
-			         _("%s: pam_start: error %d\n"),
-			         Prog, ret));
+		fprintf (stderr,
+		         _("%s: pam_start: error %d\n"),
+		         Prog, ret));
 		exit (1);
 	}
 
@@ -941,7 +948,7 @@
 	}
 	if (PAM_SUCCESS != ret) {
 		SYSLOG ((LOG_ERR, "pam_set_item: %s",
-			 pam_strerror (pamh, ret)));
+		         pam_strerror (pamh, ret)));
 		fprintf (stderr, _("%s: %s\n"), Prog, pam_strerror (pamh, ret));
 		pam_end (pamh, ret);
 		exit (1);
@@ -1020,6 +1027,8 @@
 		exit (1);
 	}
 
+	prepare_pam_close_session ();
+
 	/* become the new user */
 	if (change_uid (pw) != 0) {
 		pam_close_session (pamh, 0);




More information about the Pkg-shadow-commits mailing list