[PATCH] login: close pam session on logout

Ian Wienand ianw at vmware.com
Wed Sep 7 18:05:01 UTC 2011


Currently, (if PAM is enabled) then login never closes the PAM session
it opens.  This probably leaks something in PAM, but also loses audit
information about users logging out.

-i

Acked-by: Ian Wienand <ianw at vmware.com>
Signed-off-by: Mukund Gunti <mgunti at vmware.com>
---
 loginutils/login.c |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 46 insertions(+), 0 deletions(-)

diff --git a/loginutils/login.c b/loginutils/login.c
index 2f7b9b2..ccb8da0 100644
--- a/loginutils/login.c
+++ b/loginutils/login.c
@@ -142,6 +142,29 @@ static void run_login_script(struct passwd *pw, char *full_tty)
 void run_login_script(struct passwd *pw, char *full_tty);
 #endif
 
+#if ENABLE_PAM
+static void login_pam_end(pam_handle_t *pamh)
+{
+	int pamret, pam_end_ret;
+        pamret = pam_setcred(pamh, PAM_DELETE_CRED);
+        if (pamret != PAM_SUCCESS) {
+                syslog(LOG_WARNING, "pam_setcred failed: %s (%d)",
+                       pam_strerror(pamh, pamret), pamret);
+	}
+        pamret = pam_close_session(pamh, 0);
+	if (pamret != PAM_SUCCESS) {
+                syslog(LOG_WARNING, "pam_close_session failed: %s (%d)",
+				     pam_strerror(pamh, pamret), pamret);
+	}
+        pam_end_ret = pam_end(pamh, pamret);
+	if (pam_end_ret != PAM_SUCCESS) {
+                syslog(LOG_WARNING, "pam_end failed: %s (%d)",
+				     pam_strerror(pamh, pam_end_ret),
+                                     pam_end_ret);
+	}
+}
+#endif /* ENABLE_PAM */
+
 static void get_username_or_die(char *buf, int size_buf)
 {
 	int c, cntdown;
@@ -223,6 +246,8 @@ int login_main(int argc UNUSED_PARAM, char **argv)
 	struct passwd pwdstruct;
 	char pwdbuf[256];
 	char **pamenv;
+        int wait_ret, child_ret;
+        pid_t child_pid;
 #endif
 
 	username[0] = '\0';
@@ -393,6 +418,27 @@ int login_main(int argc UNUSED_PARAM, char **argv)
 	if (pw->pw_uid != 0)
 		die_if_nologin();
 
+#if ENABLE_PAM
+        child_pid = fork();
+        if (child_pid < 0) {
+                syslog(LOG_WARNING, "failed to fork: %s (%d)",
+                       strerror(errno), errno);
+                login_pam_end(pamh);
+                return EXIT_FAILURE;
+        }
+
+        if (child_pid > 0) {
+                wait_ret = waitpid(child_pid, &child_ret, 0);
+                if (wait_ret == -1) {
+                        syslog(LOG_WARNING, "waitpid failed: %s (%d)",
+                                             strerror(errno), errno);
+                }
+                login_pam_end(pamh);
+	        update_utmp(child_pid, DEAD_PROCESS, NULL, NULL, NULL);
+	        return child_ret;
+        }
+#endif /* ENABLE_PAM */
+
 	IF_SELINUX(initselinux(username, full_tty, &user_sid));
 
 	/* Try these, but don't complain if they fail.
-- 
1.7.4.1



More information about the busybox mailing list