]>
Commit | Line | Data |
---|---|---|
f774849c | 1 | diff -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 | |
32 | diff -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 | |
68 | diff -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 | ||
80 | diff -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 |