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