Incude definition for MNT_DETACH which is missing in older GNU libc headers.
[sysvinit.git] / contrib / notify-pam-dead.patch
CommitLineData
872353ef
DWF
1Index: src/init.sample
2===================================================================
3--- src/init.sample (revision 0)
4+++ src/init.sample (revision 0)
5@@ -0,0 +1,9 @@
6+#%PAM-1.0
7+#
8+# The PAM configuration file for /sbin/init
9+# Used for updating the lastlog logging file
10+#
11+auth sufficient pam_rootok.so
12+account include common-account
13+session include common-session
14+session requisite pam_lastlog.so silent
15Index: src/init.c
16===================================================================
17--- src/init.c (revision 56)
18+++ src/init.c (working copy)
19@@ -76,6 +76,10 @@
20 #include "reboot.h"
21 #include "set.h"
22
23+#ifdef USE_PAM
24+extern void notify_pam_dead_session(const char *id);
25+#endif
26+
27 #ifndef SIGPWR
28 # define SIGPWR SIGUSR2
29 #endif
30@@ -1129,6 +1133,9 @@
31 }
32 dup(f);
33 dup(f);
34+#ifdef USE_PAM
35+ notify_pam_dead_session(ch->id);
36+#endif
37 }
38
39 /*
40@@ -1548,6 +1555,9 @@
41 INITDBG(L_VB, "Updating utmp for pid %d [id %s]",
42 ch->pid, ch->id);
43 ch->flags &= ~RUNNING;
44+#ifdef USE_PAM
45+ notify_pam_dead_session(ch->id);
46+#endif
47 if (ch->process[0] != '+')
48 write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
49 }
50@@ -2009,6 +2019,9 @@
51 if (ch->flags & ZOMBIE) {
52 INITDBG(L_VB, "Child died, PID= %d", ch->pid);
53 ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
54+#ifdef USE_PAM
55+ notify_pam_dead_session(ch->id);
56+#endif
57 if (ch->process[0] != '+')
58 write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
59 }
60@@ -2453,6 +2466,9 @@
61 if (ch->flags & ZOMBIE) {
62 INITDBG(L_VB, "Child died, PID= %d", ch->pid);
63 ch->flags &= ~(RUNNING|ZOMBIE|WAITING);
64+#ifdef USE_PAM
65+ notify_pam_dead_session(ch->id);
66+#endif
67 if (ch->process[0] != '+')
68 write_utmp_wtmp("", ch->id, ch->pid, DEAD_PROCESS, NULL);
69 }
70Index: src/utmp.c
71===================================================================
72--- src/utmp.c (revision 51)
73+++ src/utmp.c (working copy)
74@@ -34,10 +34,18 @@
75 #include <string.h>
76 #include <utmp.h>
77
78+#if defined(USE_PAM) && defined(INIT_MAIN)
79+# include <security/pam_appl.h>
80+# include <security/pam_misc.h>
81+#endif
82+
83 #include "init.h"
84 #include "initreq.h"
85 #include "paths.h"
86
87+#ifndef _PATH_DEV
88+# define _PATH_DEV "/dev/"
89+#endif
90
91 #if defined(__GLIBC__)
92 # if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 0) && defined(__powerpc__)
93@@ -127,9 +135,9 @@
94 strncpy(utmp.ut_name, user, sizeof(utmp.ut_name));
95 strncpy(utmp.ut_id , id , sizeof(utmp.ut_id ));
96 strncpy(utmp.ut_line, line, sizeof(utmp.ut_line));
97-
98- /* Put the OS version in place of the hostname */
99- if (uname(&uname_buf) == 0)
100+
101+ /* Put the OS version in place of the hostname */
102+ if (uname(&uname_buf) == 0)
103 strncpy(utmp.ut_host, uname_buf.release, sizeof(utmp.ut_host));
104
105 #if HAVE_UPDWTMP
106@@ -262,3 +270,75 @@
107 write_wtmp(user, id, pid, type, line && line[0] ? line : oldline);
108 }
109
110+#if defined(USE_PAM) && defined(INIT_MAIN)
111+static pam_handle_t *pamh = NULL;
112+# ifdef __GNUC__
113+static int
114+null_conv(int num_msg, const struct pam_message **msgm,
115+ struct pam_response **response __attribute__((unused)),
116+ void *appdata_ptr __attribute__((unused)))
117+# else
118+static int
119+null_conv(int num_msg, const struct pam_message **msgm,
120+ struct pam_response **response, void *appdata_ptr)
121+# endif
122+{
123+ int i;
124+ for (i = 0; i < num_msg; i++) {
125+ const struct pam_message *msg = msgm[i];
126+ if (msg == (const struct pam_message*)0)
127+ continue;
128+ if (msg->msg == (char*)0)
129+ continue;
130+ switch (msg->msg_style) {
131+ case PAM_ERROR_MSG:
132+ case PAM_TEXT_INFO:
133+ initlog(L_VB, "pam_message %s", msg->msg);
134+ default:
135+ break;
136+ }
137+ }
138+ return 0;
139+}
140+static const struct pam_conv conv = { null_conv, NULL };
141+# define PAM_FAIL_CHECK(func, args...) \
142+ { \
143+ if ((pam_ret = (func)(args)) != PAM_SUCCESS) { \
144+ initlog(L_VB, "%s", pam_strerror(pamh, pam_ret)); \
145+ goto pam_error; \
146+ } \
147+ }
148+
149+void notify_pam_dead_session(const char *id)
150+{
151+ struct utmp *oldut, ut;
152+
153+ setutent();
154+
155+ memset(&ut, 0, sizeof(ut));
156+ ut.ut_type = DEAD_PROCESS;
157+ strncpy(ut.ut_id, id, sizeof(ut.ut_id));
158+
159+ if ((oldut = getutid(&ut)) && (oldut->ut_type == USER_PROCESS)) {
160+ int pam_ret;
161+ char tty[UT_LINESIZE+ strlen(_PATH_DEV) + 1];
162+
163+ if (strncmp(oldut->ut_line, _PATH_DEV, strlen(_PATH_DEV)))
164+ snprintf(tty, sizeof(tty), _PATH_DEV "%.*s",
165+ UT_LINESIZE, oldut->ut_line);
166+ else
167+ snprintf(tty, sizeof(tty), "%.*s",
168+ UT_LINESIZE, oldut->ut_line);
169+
170+ PAM_FAIL_CHECK(pam_start, "init", oldut->ut_user, &conv, &pamh);
171+ PAM_FAIL_CHECK(pam_set_item, pamh, PAM_TTY, tty);
172+ PAM_FAIL_CHECK(pam_set_item, pamh, PAM_RHOST, oldut->ut_host);
173+ PAM_FAIL_CHECK(pam_close_session, pamh, PAM_SILENT);
174+ pam_error:
175+ pam_end(pamh, pam_ret);
176+ }
177+
178+ endutent();
179+}
180+#endif /* USE_PAM && INIT_MAIN */
181+
182Index: src/Makefile
183===================================================================
184--- src/Makefile (revision 58)
185+++ src/Makefile (working copy)
186@@ -8,7 +8,7 @@
187 # Version: @(#)Makefile 2.85-13 23-Mar-2004 miquels@cistron.nl
188 #
189
190-CPPFLAGS =
191+CPPFLAGS = -DUSE_PAM
192 CFLAGS ?= -ansi -O2 -fomit-frame-pointer
193 override CFLAGS += -W -Wall -D_GNU_SOURCE
194 STATIC =
195@@ -79,6 +79,13 @@
196 endif
197
198 # Additional libs for GNU libc.
199+ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),)
200+ INITLIBS += -lpam
201+ PAMDOTD = /etc/pam.d
202+ PAMINIT = $(PAMDOTD)/init
203+endif
204+
205+# Additional libs for GNU libc.
206 ifneq ($(wildcard /usr/lib*/libcrypt.a),)
207 SULOGINLIBS += -lcrypt
208 endif
209@@ -153,6 +160,11 @@
210 $(STRIP) $$i ; \
211 $(INSTALL_EXEC) $$i $(ROOT)/usr/bin/ ; \
212 done
213+ifneq ($(findstring -DUSE_PAM,$(CPPFLAGS)),)
214+ $(INSTALL_DIR) $(ROOT)$(PAMDOTD)
215+ test -s $(ROOT)$(PAMINIT) || \
216+ $(INSTALL_DATA) init.sample $(ROOT)$(PAMINIT)
217+endif
218 # $(INSTALL_DIR) $(ROOT)/etc/
219 # $(INSTALL_EXEC) initscript.sample $(ROOT)/etc/
220 ln -sf halt $(ROOT)/sbin/reboot