[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