--- /dev/null
+Index: src/init.sample
+===================================================================
+--- src/init.sample (revision 0)
++++ src/init.sample (revision 0)
+@@ -0,0 +1,9 @@
++#%PAM-1.0
++#
++# The PAM configuration file for /sbin/init
++# Used for updating the lastlog logging file
++#
++auth sufficient pam_rootok.so
++account include common-account
++session include common-session
++session requisite pam_lastlog.so silent
+Index: src/init.c
+===================================================================
+--- src/init.c (revision 56)
++++ src/init.c (working copy)
+@@ -76,6 +76,10 @@
+ #include "reboot.h"
+ #include "set.h"
+
++#ifdef USE_PAM
++extern void notify_pam_dead_session(const char *id);
++#endif
++
+ #ifndef SIGPWR
+ # define SIGPWR SIGUSR2
+ #endif
+@@ -1129,6 +1133,9 @@
+ }
+ dup(f);
+ dup(f);
++#ifdef USE_PAM
++ notify_pam_dead_session(ch->id);
++#endif
+ }
+
+ /*
+@@ -1548,6 +1555,9 @@
+ INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
+ ch->pid, ch->id);
+ ch->flags &= ~RUNNING;
++#ifdef USE_PAM
++ notify_pam_dead_session(ch->id);
++#endif
+ if (ch->process[0] != '+')
+ write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
+ }
+@@ -2009,6 +2019,9 @@
+ if (ch->flags & ZOMBIE) {
+ INITDBG(L_VB, "Child died, PID= %d", ch->pid);
+ ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
++#ifdef USE_PAM
++ notify_pam_dead_session(ch->id);
++#endif
+ if (ch->process[0] != '+')
+ write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
+ }
+@@ -2453,6 +2466,9 @@
+ if (ch->flags & ZOMBIE) {
+ INITDBG(L_VB, "Child died, PID= %d", ch->pid);
+ ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
++#ifdef USE_PAM
++ notify_pam_dead_session(ch->id);
++#endif
+ if (ch->process[0] != '+')
+ write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
+ }
+Index: src/utmp.c
+===================================================================
+--- src/utmp.c (revision 51)
++++ src/utmp.c (working copy)
+@@ -34,10 +34,18 @@
+ #include <string.h>
+ #include <utmp.h>
+
++#if defined(USE_PAM) && defined(INIT_MAIN)
++# include <security/pam_appl.h>
++# include <security/pam_misc.h>
++#endif
++
+ #include "init.h"
+ #include "initreq.h"
+ #include "paths.h"
+
++#ifndef _PATH_DEV
++# define _PATH_DEV "/dev/"
++#endif
+
+ #if defined(__GLIBC__)
+ # if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0) && defined(__powerpc__)
+@@ -127,9 +135,9 @@
+ strncpy(utmp.ut_name, user, sizeof(utmp.ut_name));
+ strncpy(utmp.ut_id , id , sizeof(utmp.ut_id ));
+ strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
+-
+- /* Put the OS version in place of the hostname */
+- if (uname(&uname_buf) == 0)
++
++ /* Put the OS version in place of the hostname */
++ if (uname(&uname_buf) == 0)
+ strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host));
+
+ #if HAVE_UPDWTMP
+@@ -262,3 +270,75 @@
+ write_wtmp(user, id, pid, type, line && line[0] ? line : oldline);
+ }
+
++#if defined(USE_PAM) && defined(INIT_MAIN)
++static pam_handle_t *pamh = NULL;
++# ifdef __GNUC__
++static int
++null_conv(int num_msg, const struct pam_message **msgm,
++ struct pam_response **response __attribute__((unused)),
++ void *appdata_ptr __attribute__((unused)))
++# else
++static int
++null_conv(int num_msg, const struct pam_message **msgm,
++ struct pam_response **response, void *appdata_ptr)
++# endif
++{
++ int i;
++ for (i = 0; i < num_msg; i++) {
++ const struct pam_message *msg = msgm[i];
++ if (msg == (const struct pam_message*)0)
++ continue;
++ if (msg->msg == (char*)0)
++ continue;
++ switch (msg->msg_style) {
++ case PAM_ERROR_MSG:
++ case PAM_TEXT_INFO:
++ initlog(L_VB, "pam_message %s", msg->msg);
++ default:
++ break;
++ }
++ }
++ return 0;
++}
++static const struct pam_conv conv = { null_conv, NULL };
++# define PAM_FAIL_CHECK(func, args...) \
++ { \
++ if ((pam_ret = (func)(args)) != PAM_SUCCESS) { \
++ initlog(L_VB, "%s", pam_strerror(pamh, pam_ret)); \
++ goto pam_error; \
++ } \
++ }
++
++void notify_pam_dead_session(const char *id)
++{
++ struct utmp *oldut, ut;
++
++ setutent();
++
++ memset(&ut, 0, sizeof(ut));
++ ut.ut_type = DEAD_PROCESS;
++ strncpy(ut.ut_id, id, sizeof(ut.ut_id));
++
++ if ((oldut = getutid(&ut)) && (oldut->ut_type == USER_PROCESS)) {
++ int pam_ret;
++ char tty[UT_LINESIZE+ strlen(_PATH_DEV) + 1];
++
++ if (strncmp(oldut->ut_line, _PATH_DEV, strlen(_PATH_DEV)))
++ snprintf(tty, sizeof(tty), _PATH_DEV "%.*s",
++ UT_LINESIZE, oldut->ut_line);
++ else
++ snprintf(tty, sizeof(tty), "%.*s",
++ UT_LINESIZE, oldut->ut_line);
++
++ PAM_FAIL_CHECK(pam_start, "init", oldut->ut_user, &conv, &pamh);
++ PAM_FAIL_CHECK(pam_set_item, pamh, PAM_TTY, tty);
++ PAM_FAIL_CHECK(pam_set_item, pamh, PAM_RHOST, oldut->ut_host);
++ PAM_FAIL_CHECK(pam_close_session, pamh, PAM_SILENT);
++ pam_error:
++ pam_end(pamh, pam_ret);
++ }
++
++ endutent();
++}
++#endif /* USE_PAM && INIT_MAIN */
++
+Index: src/Makefile
+===================================================================
+--- src/Makefile (revision 58)
++++ src/Makefile (working copy)
+@@ -8,7 +8,7 @@
+ # Version: @(#)Makefile 2.85-13 23-Mar-2004 miquels@cistron.nl
+ #
+
+-CPPFLAGS =
++CPPFLAGS = -DUSE_PAM
+ CFLAGS ?= -ansi -O2 -fomit-frame-pointer
+ override CFLAGS += -W -Wall -D_GNU_SOURCE
+ STATIC =
+@@ -79,6 +79,13 @@
+ endif
+
+ # Additional libs for GNU libc.
++ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),)
++ INITLIBS += -lpam
++ PAMDOTD = /etc/pam.d
++ PAMINIT = $(PAMDOTD)/init
++endif
++
++# Additional libs for GNU libc.
+ ifneq ($(wildcard /usr/lib*/libcrypt.a),)
+ SULOGINLIBS += -lcrypt
+ endif
+@@ -153,6 +160,11 @@
+ $(STRIP) $$i ; \
+ $(INSTALL_EXEC) $$i $(ROOT)/usr/bin/ ; \
+ done
++ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),)
++ $(INSTALL_DIR) $(ROOT)$(PAMDOTD)
++ test -s $(ROOT)$(PAMINIT) || \
++ $(INSTALL_DATA) init.sample $(ROOT)$(PAMINIT)
++endif
+ # $(INSTALL_DIR) $(ROOT)/etc/
+ # $(INSTALL_EXEC) initscript.sample $(ROOT)/etc/
+ ln -sf halt $(ROOT)/sbin/reboot