]> git.pld-linux.org Git - packages/coreutils.git/blame - coreutils-pam.patch
- release 2
[packages/coreutils.git] / coreutils-pam.patch
CommitLineData
f774849c 1diff -Nur sh-utils-2.0.12.orig/configure.ac sh-utils-2.0.12/configure.ac
2--- sh-utils-2.0.12.orig/configure.ac Sun Apr 28 11:29:18 2002
3+++ sh-utils-2.0.12/configure.ac Mon May 27 23:10:36 2002
4@@ -8,6 +8,13 @@
5
6 AM_INIT_AUTOMAKE([1.6b gnits dist-bzip2])
7
8+dnl Give the chance to enable PAM
9+AC_ARG_ENABLE(pam, dnl
10+[ --enable-pam Enable use of the PAM libraries],
11+AC_DEFINE(USE_PAM,,[Use PAM?])
12+LIB_PAM="-ldl -lpam -lpam_misc"
13+)
14+
15 AC_GNU_SOURCE
16 jm_PERL
17 AC_PROG_CC
40ce7301 18@@ -238,6 +245,13 @@
f774849c 19
20 AM_GNU_GETTEXT([external])
21
22+# just in case we want PAM
23+AC_SUBST(LIB_PAM)
40ce7301
JB
24+# with PAM su doesn't need libcrypt
25+if test -n "$LIB_PAM" ; then
26+ LIB_CRYPT=
27+fi
f774849c 28+
29 AC_CONFIG_FILES(
30 Makefile
31 doc/Makefile
32diff -Nur sh-utils-2.0.12.orig/doc/coreutils.texi sh-utils-2.0.12/doc/coreutils.texi
33--- sh-utils-2.0.12.orig/doc/coreutils.texi Sun Apr 28 23:55:31 2002
34+++ sh-utils-2.0.12/doc/coreutils.texi Mon May 27 23:11:49 2002
35@@ -10898,32 +10898,6 @@
36
37 @end table
38
39-@cindex wheel group, not supported
40-@cindex group wheel, not supported
41-@cindex fascism
42-@heading Why GNU @command{su} does not support the @samp{wheel} group
43-
44-(This section is by Richard Stallman.)
45-
46-@cindex Twenex
47-@cindex MIT AI lab
48-Sometimes a few of the users try to hold total power over all the
49-rest. For example, in 1984, a few users at the MIT AI lab decided to
50-seize power by changing the operator password on the Twenex system and
51-keeping it secret from everyone else. (I was able to thwart this coup
52-and give power back to the users by patching the kernel, but I
53-wouldn't know how to do that in Unix.)
54-
55-However, occasionally the rulers do tell someone. Under the usual
56-@command{su} mechanism, once someone learns the root password who
57-sympathizes with the ordinary users, he or she can tell the rest. The
58-``wheel group'' feature would make this impossible, and thus cement the
59-power of the rulers.
60-
61-I'm on the side of the masses, not that of the rulers. If you are
62-used to supporting the bosses and sysadmins in whatever they do, you
63-might find this idea strange at first.
64-
65
66 @node Process control
67 @chapter Process control
68diff -Nur sh-utils-2.0.12.orig/src/Makefile.am sh-utils-2.0.12/src/Makefile.am
69--- sh-utils-2.0.12.orig/src/Makefile.am Mon May 27 23:06:24 2002
70+++ sh-utils-2.0.12/src/Makefile.am Mon May 27 23:09:22 2002
71@@ -47,7 +47,7 @@
72
73 uptime_LDADD = $(LDADD) @GETLOADAVG_LIBS@
74
75-su_LDADD = $(LDADD) @LIB_CRYPT@
76+su_LDADD = $(LDADD) @LIB_CRYPT@ @LIB_PAM@
77
78 $(PROGRAMS): ../lib/libfetish.a
79
80diff -Nur sh-utils-2.0.12.orig/src/su.c sh-utils-2.0.12/src/su.c
81--- sh-utils-2.0.12.orig/src/su.c Mon May 27 23:06:24 2002
82+++ sh-utils-2.0.12/src/su.c Mon May 27 23:08:28 2002
83@@ -38,6 +38,16 @@
84 restricts who can su to UID 0 accounts. RMS considers that to
85 be fascist.
86
87+#ifdef USE_PAM
88+
89+ Actually, with PAM, su has nothing to do with whether or not a
90+ wheel group is enforced by su. RMS tries to restrict your access
91+ to a su which implements the wheel group, but PAM considers that
92+ to be fascist, and gives the user/sysadmin the opportunity to
93+ enforce a wheel group by proper editing of /etc/pam.conf
94+
95+#endif
96+
97 Options:
98 -, -l, --login Make the subshell a login shell.
99 Unset all environment variables except
100@@ -81,6 +91,14 @@
101 prototype (returning `int') in <unistd.h>. */
102 #define getusershell _getusershell_sys_proto_
103
104+#ifdef USE_PAM
105+# include <security/pam_appl.h>
106+# include <security/pam_misc.h>
107+# include <signal.h>
108+# include <sys/wait.h>
109+# include <sys/fsuid.h>
110+#endif /* USE_PAM */
111+
112 #include "system.h"
113 #include "closeout.h"
114 #include "dirname.h"
115@@ -151,7 +169,9 @@
116 /* The user to become if none is specified. */
117 #define DEFAULT_USER "root"
118
119+#ifndef USE_PAM
120 char *crypt ();
121+#endif
122 char *getpass ();
123 char *getusershell ();
124 void endusershell ();
125@@ -159,7 +179,7 @@
126
127 extern char **environ;
128
129-static void run_shell (const char *, const char *, char **)
130+static void run_shell (const char *, const char *, char **, const struct passwd *)
131 ATTRIBUTE_NORETURN;
132
133 /* The name this program was run with. */
134@@ -272,7 +292,22 @@
135 }
136 #endif
137
138+#ifdef USE_PAM
139+static pam_handle_t *pamh = NULL;
140+static int retval;
141+static struct pam_conv conv = {
142+ misc_conv,
143+ NULL
144+};
145+
146+#define PAM_BAIL_P if (retval) { \
147+ pam_end(pamh, PAM_SUCCESS); \
148+ return 0; \
149+}
150+#endif
151+
152 /* Ask the user for a password.
153+ If PAM is in use, let PAM ask for the password if necessary.
154 Return 1 if the user gives the correct password for entry PW,
155 0 if not. Return 1 without asking for a password if run by UID 0
156 or if PW has an empty password. */
157@@ -280,6 +315,29 @@
158 static int
159 correct_password (const struct passwd *pw)
160 {
161+#ifdef USE_PAM
162+ /* root always succeeds; this isn't an authentication question (no
163+ * extra privs are being granted) so it shouldn't authenticate with PAM.
164+ * However, we want to create the pam_handle so that proper credentials
165+ * are created later with pam_setcred(). */
166+ retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh);
167+ PAM_BAIL_P;
168+
169+ retval = pam_authenticate(pamh, 0);
170+ PAM_BAIL_P;
171+
172+ retval = pam_acct_mgmt(pamh, 0);
173+ if (retval == PAM_NEW_AUTHTOK_REQD) {
174+ /* password has expired. Offer option to change it. */
175+ if (getuid()) {
176+ retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK);
177+ PAM_BAIL_P;
178+ } else retval = PAM_SUCCESS;
179+ }
180+ PAM_BAIL_P;
181+ /* must be authenticated if this point was reached */
182+ return 1;
183+#else /* !USE_PAM */
184 char *unencrypted, *encrypted, *correct;
185 #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP
186 /* Shadow passwd stuff for SVR3 and maybe other systems. */
187@@ -304,6 +362,7 @@
188 encrypted = crypt (unencrypted, correct);
189 memset (unencrypted, 0, strlen (unencrypted));
190 return strcmp (encrypted, correct) == 0;
191+#endif /* !USE_PAM */
192 }
193
194 /* Update `environ' for the new shell based on PW, with SHELL being
195@@ -313,16 +372,20 @@
196 modify_environment (const struct passwd *pw, const char *shell)
197 {
198 char *term;
199+ char *display;
200
201 if (simulate_login)
202 {
203- /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
204+ /* Leave TERM, DISPLAY unchanged. Set HOME, SHELL, USER, LOGNAME, PATH.
205 Unset all other environment variables. */
206 term = getenv ("TERM");
207+ display = getenv ("DISPLAY");
208 environ = (char **) xmalloc (2 * sizeof (char *));
209 environ[0] = 0;
210 if (term)
211 xputenv (concat ("TERM", "=", term));
212+ if (display)
213+ xputenv (concat ("DISPLAY", "=", display));
214 xputenv (concat ("HOME", "=", pw->pw_dir));
215 xputenv (concat ("SHELL", "=", shell));
216 xputenv (concat ("USER", "=", pw->pw_name));
217@@ -359,23 +422,73 @@
218 error (EXIT_FAILURE, errno, _("cannot set groups"));
219 endgrent ();
220 #endif
221+#ifdef USE_PAM
222+ retval = pam_setcred(pamh, PAM_ESTABLISH_CRED);
223+ if (retval != PAM_SUCCESS)
224+ error (1, 0, pam_strerror(pamh, retval));
225+#endif /* USE_PAM */
226 if (setgid (pw->pw_gid))
227 error (EXIT_FAILURE, errno, _("cannot set group id"));
228 if (setuid (pw->pw_uid))
229 error (EXIT_FAILURE, errno, _("cannot set user id"));
230 }
231
232+#ifdef USE_PAM
233+static int caught=0;
234+/* Signal handler for parent process later */
235+static void su_catch_sig(int sig)
236+{
237+ ++caught;
238+}
239+
240+int
241+pam_copyenv (pam_handle_t *pamh)
242+{
243+ char **env;
244+
245+ env = pam_getenvlist(pamh);
246+ if(env) {
247+ while(*env) {
248+ xputenv(*env);
249+ env++;
250+ }
251+ }
252+ return(0);
253+}
254+#endif
255+
256 /* Run SHELL, or DEFAULT_SHELL if SHELL is empty.
257 If COMMAND is nonzero, pass it to the shell with the -c option.
258 If ADDITIONAL_ARGS is nonzero, pass it to the shell as more
259 arguments. */
260
261 static void
262-run_shell (const char *shell, const char *command, char **additional_args)
263+run_shell (const char *shell, const char *command, char **additional_args, const struct passwd *pw)
264 {
265 const char **args;
266 int argno = 1;
267+#ifdef USE_PAM
268+ int child;
269+ sigset_t ourset;
270+ int status;
271+
272+ retval = pam_open_session(pamh,0);
273+ if (retval != PAM_SUCCESS) {
40ce7301 274+ fprintf (stderr, _("could not open session\n"));
f774849c 275+ exit (1);
276+ }
277+
278+/* do this at the last possible moment, because environment variables may
279+ be passed even in the session phase
280+*/
281+ if(pam_copyenv(pamh) != PAM_SUCCESS)
40ce7301 282+ fprintf (stderr, _("error copying PAM environment\n"));
f774849c 283
284+ child = fork();
285+ if (child == 0) { /* child shell */
286+ change_identity (pw);
287+ pam_end(pamh, 0);
288+#endif
289 if (additional_args)
290 args = (const char **) xmalloc (sizeof (char *)
291 * (10 + elements (additional_args)));
292@@ -408,6 +521,61 @@
293 error (0, errno, "%s", shell);
294 exit (exit_status);
295 }
296+#ifdef USE_PAM
297+ } else if (child == -1) {
b4227111 298+ fprintf(stderr, _("cannot fork user shell: %s"), strerror(errno));
f774849c 299+ exit(1);
300+ }
301+ /* parent only */
302+ sigfillset(&ourset);
303+ if (sigprocmask(SIG_BLOCK, &ourset, NULL)) {
40ce7301 304+ fprintf(stderr, _("%s: signal malfunction\n"), PROGRAM_NAME);
f774849c 305+ caught = 1;
306+ }
307+ if (!caught) {
308+ struct sigaction action;
309+ action.sa_handler = su_catch_sig;
310+ sigemptyset(&action.sa_mask);
311+ action.sa_flags = 0;
312+ sigemptyset(&ourset);
313+ if (sigaddset(&ourset, SIGTERM)
314+ || sigaddset(&ourset, SIGALRM)
315+ || sigaction(SIGTERM, &action, NULL)
316+ || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) {
40ce7301 317+ fprintf(stderr, _("%s: signal masking malfunction\n"), PROGRAM_NAME);
f774849c 318+ caught = 1;
319+ }
320+ }
321+ if (!caught) {
322+ do {
323+ int pid;
324+
325+ pid = waitpid(-1, &status, WUNTRACED);
326+
327+ if (WIFSTOPPED(status)) {
328+ kill(getpid(), SIGSTOP);
329+ /* once we get here, we must have resumed */
330+ kill(pid, SIGCONT);
331+ }
332+ } while (WIFSTOPPED(status));
333+ }
334+
335+ if (caught) {
40ce7301 336+ fprintf(stderr, _("\nSession terminated, killing shell..."));
f774849c 337+ kill (child, SIGTERM);
338+ }
339+ retval = pam_close_session(pamh, 0);
340+ PAM_BAIL_P;
341+ retval = pam_end(pamh, PAM_SUCCESS);
342+ PAM_BAIL_P;
343+ if (caught) {
344+ sleep(2);
345+ kill(child, SIGKILL);
40ce7301 346+ fprintf(stderr, _(" killed.\n"));
f774849c 347+ exit(-1);
348+ }
349+ exit (WEXITSTATUS(status));
350+#endif /* USE_PAM */
351 }
352
353 /* Return 1 if SHELL is a restricted shell (one not returned by
354@@ -580,9 +748,14 @@
355 }
356 modify_environment (pw, shell);
357
358+
359+#ifdef USE_PAM
360+ setfsuid(pw->pw_uid);
361+#else
362 change_identity (pw);
363+#endif
364 if (simulate_login && chdir (pw->pw_dir))
365 error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir);
366
367- run_shell (shell, command, additional_args);
368+ run_shell (shell, command, additional_args, pw);
369 }
b4227111
JB
370--- coreutils-4.5.3.orig/po/pl.po Fri Nov 1 01:55:42 2002
371+++ coreutils-4.5.3/po/pl.po Fri Nov 1 02:11:20 2002
372@@ -6491,6 +6491,41 @@
373 msgid "cannot set user id"
374