Incude definition for MNT_DETACH which is missing in older GNU libc headers.
[sysvinit.git] / contrib / notify-pam-dead.patch
1 Index: 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
15 Index: 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 }
70 Index: 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 +
182 Index: 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