]>
Commit | Line | Data |
---|---|---|
ca7ee99d JR |
1 | --- coreutils-6.7/src/Makefile.am.pam 2006-11-24 21:28:10.000000000 +0000 |
2 | +++ coreutils-6.7/src/Makefile.am 2007-01-09 17:00:01.000000000 +0000 | |
3 | @@ -103,7 +103,7 @@ | |
4 | # If necessary, add -lm to resolve use of pow in lib/strtod.c. | |
5 | uptime_LDADD = $(LDADD) $(POW_LIB) $(GETLOADAVG_LIBS) | |
f774849c | 6 | |
ca7ee99d JR |
7 | -su_LDADD = $(LDADD) $(LIB_CRYPT) |
8 | +su_LDADD = $(LDADD) $(LIB_CRYPT) $(LIB_PAM) | |
9 | ||
10 | dir_LDADD += $(LIB_ACL) | |
11 | ls_LDADD += $(LIB_ACL) | |
3c350007 JB |
12 | --- coreutils-6.10/src/su.c.orig 2007-11-25 14:23:31.000000000 +0100 |
13 | +++ coreutils-6.10/src/su.c 2008-03-02 02:07:13.568059486 +0100 | |
14 | @@ -37,6 +37,16 @@ | |
ca7ee99d JR |
15 | restricts who can su to UID 0 accounts. RMS considers that to |
16 | be fascist. | |
17 | ||
18 | +#ifdef USE_PAM | |
f774849c | 19 | + |
ca7ee99d JR |
20 | + Actually, with PAM, su has nothing to do with whether or not a |
21 | + wheel group is enforced by su. RMS tries to restrict your access | |
22 | + to a su which implements the wheel group, but PAM considers that | |
23 | + to be fascist, and gives the user/sysadmin the opportunity to | |
24 | + enforce a wheel group by proper editing of /etc/pam.conf | |
25 | + | |
26 | +#endif | |
27 | + | |
28 | Compile-time options: | |
29 | -DSYSLOG_SUCCESS Log successful su's (by default, to root) with syslog. | |
30 | -DSYSLOG_FAILURE Log failed su's (by default, to root) with syslog. | |
3c350007 | 31 | @@ -58,6 +68,15 @@ |
ca7ee99d JR |
32 | prototype (returning `int') in <unistd.h>. */ |
33 | #define getusershell _getusershell_sys_proto_ | |
f774849c | 34 | |
ca7ee99d JR |
35 | +#ifdef USE_PAM |
36 | +# include <signal.h> | |
37 | +# include <sys/wait.h> | |
38 | +# include <sys/fsuid.h> | |
39 | +# include <unistd.h> | |
40 | +# include <security/pam_appl.h> | |
41 | +# include <security/pam_misc.h> | |
42 | +#endif /* USE_PAM */ | |
f774849c | 43 | + |
ca7ee99d JR |
44 | #include "system.h" |
45 | #include "getpass.h" | |
f774849c | 46 | |
3c350007 | 47 | @@ -118,15 +137,22 @@ |
ca7ee99d JR |
48 | /* The user to become if none is specified. */ |
49 | #define DEFAULT_USER "root" | |
f774849c | 50 | |
ca7ee99d JR |
51 | +#ifndef USE_PAM |
52 | char *crypt (); | |
53 | +#endif | |
54 | char *getusershell (); | |
55 | void endusershell (); | |
56 | void setusershell (); | |
f774849c | 57 | |
58 | extern char **environ; | |
59 | ||
c2be74f0 | 60 | -static void run_shell (char const *, char const *, char **, size_t) |
ca7ee99d JR |
61 | +static void run_shell (char const *, char const *, char **, size_t, |
62 | + const struct passwd *) | |
63 | +#ifdef USE_PAM | |
64 | + ; | |
65 | +#else | |
f774849c | 66 | ATTRIBUTE_NORETURN; |
ca7ee99d | 67 | +#endif |
f774849c | 68 | |
69 | /* The name this program was run with. */ | |
ca7ee99d | 70 | char *program_name; |
3c350007 | 71 | @@ -215,7 +241,26 @@ |
f774849c | 72 | } |
73 | #endif | |
74 | ||
75 | +#ifdef USE_PAM | |
76 | +static pam_handle_t *pamh = NULL; | |
77 | +static int retval; | |
78 | +static struct pam_conv conv = { | |
79 | + misc_conv, | |
80 | + NULL | |
81 | +}; | |
82 | + | |
83 | +#define PAM_BAIL_P if (retval) { \ | |
84 | + pam_end(pamh, PAM_SUCCESS); \ | |
85 | + return 0; \ | |
86 | +} | |
ca7ee99d JR |
87 | +#define PAM_BAIL_P_VOID if (retval) { \ |
88 | + pam_end(pamh, PAM_SUCCESS); \ | |
89 | +return; \ | |
90 | +} | |
f774849c | 91 | +#endif |
92 | + | |
93 | /* Ask the user for a password. | |
94 | + If PAM is in use, let PAM ask for the password if necessary. | |
c2be74f0 JB |
95 | Return true if the user gives the correct password for entry PW, |
96 | false if not. Return true without asking for a password if run by UID 0 | |
f774849c | 97 | or if PW has an empty password. */ |
3c350007 | 98 | @@ -223,6 +268,44 @@ |
c2be74f0 | 99 | static bool |
f774849c | 100 | correct_password (const struct passwd *pw) |
101 | { | |
102 | +#ifdef USE_PAM | |
ca7ee99d JR |
103 | + struct passwd *caller; |
104 | + char *tty_name, *ttyn; | |
f774849c | 105 | + retval = pam_start(PROGRAM_NAME, pw->pw_name, &conv, &pamh); |
106 | + PAM_BAIL_P; | |
107 | + | |
ca7ee99d JR |
108 | + if (getuid() != 0 && !isatty(0)) { |
109 | + fprintf(stderr, _("standard in must be a tty\n")); | |
110 | + exit(1); | |
111 | + } | |
112 | + | |
113 | + caller = getpwuid(getuid()); | |
114 | + if(caller != NULL && caller->pw_name != NULL) { | |
115 | + retval = pam_set_item(pamh, PAM_RUSER, caller->pw_name); | |
116 | + PAM_BAIL_P; | |
117 | + } | |
118 | + | |
119 | + ttyn = ttyname(0); | |
120 | + if (ttyn) { | |
121 | + if (strncmp(ttyn, "/dev/", 5) == 0) | |
122 | + tty_name = ttyn+5; | |
123 | + else | |
124 | + tty_name = ttyn; | |
125 | + retval = pam_set_item(pamh, PAM_TTY, tty_name); | |
126 | + PAM_BAIL_P; | |
127 | + } | |
f774849c | 128 | + retval = pam_authenticate(pamh, 0); |
129 | + PAM_BAIL_P; | |
f774849c | 130 | + retval = pam_acct_mgmt(pamh, 0); |
ca7ee99d | 131 | + if (retval == PAM_NEW_AUTHTOK_REQD && getuid()) { |
f774849c | 132 | + /* password has expired. Offer option to change it. */ |
ca7ee99d JR |
133 | + retval = pam_chauthtok(pamh, PAM_CHANGE_EXPIRED_AUTHTOK); |
134 | + PAM_BAIL_P; | |
f774849c | 135 | + } |
136 | + PAM_BAIL_P; | |
137 | + /* must be authenticated if this point was reached */ | |
138 | + return 1; | |
139 | +#else /* !USE_PAM */ | |
140 | char *unencrypted, *encrypted, *correct; | |
141 | #if HAVE_GETSPNAM && HAVE_STRUCT_SPWD_SP_PWDP | |
142 | /* Shadow passwd stuff for SVR3 and maybe other systems. */ | |
3c350007 | 143 | @@ -247,6 +330,7 @@ |
f774849c | 144 | encrypted = crypt (unencrypted, correct); |
145 | memset (unencrypted, 0, strlen (unencrypted)); | |
c2be74f0 | 146 | return STREQ (encrypted, correct); |
f774849c | 147 | +#endif /* !USE_PAM */ |
148 | } | |
149 | ||
150 | /* Update `environ' for the new shell based on PW, with SHELL being | |
3c350007 | 151 | @@ -260,12 +344,18 @@ |
ca7ee99d | 152 | /* Leave TERM unchanged. Set HOME, SHELL, USER, LOGNAME, PATH. |
f774849c | 153 | Unset all other environment variables. */ |
c2be74f0 JB |
154 | char const *term = getenv ("TERM"); |
155 | + char const *display = getenv ("DISPLAY"); | |
ca7ee99d | 156 | + char const *xauthority = getenv ("XAUTHORITY"); |
c2be74f0 JB |
157 | if (term) |
158 | term = xstrdup (term); | |
ca7ee99d | 159 | environ = xmalloc ((6 + !!term) * sizeof (char *)); |
c2be74f0 | 160 | environ[0] = NULL; |
f774849c | 161 | if (term) |
c2be74f0 | 162 | xsetenv ("TERM", term); |
f774849c | 163 | + if (display) |
c2be74f0 | 164 | + xsetenv ("DISPLAY", display); |
ca7ee99d JR |
165 | + if (xauthority) |
166 | + xsetenv ("XAUTHORITY", xauthority); | |
c2be74f0 JB |
167 | xsetenv ("HOME", pw->pw_dir); |
168 | xsetenv ("SHELL", shell); | |
169 | xsetenv ("USER", pw->pw_name); | |
3c350007 | 170 | @@ -298,8 +388,13 @@ |
ca7ee99d JR |
171 | { |
172 | #ifdef HAVE_INITGROUPS | |
173 | errno = 0; | |
174 | - if (initgroups (pw->pw_name, pw->pw_gid) == -1) | |
175 | + if (initgroups (pw->pw_name, pw->pw_gid) == -1) { | |
176 | +#ifdef USE_PAM | |
177 | + pam_close_session(pamh, 0); | |
178 | + pam_end(pamh, PAM_ABORT); | |
179 | +#endif | |
3c350007 | 180 | error (EXIT_FAILURE, errno, _("cannot set groups")); |
ca7ee99d | 181 | + } |
f774849c | 182 | endgrent (); |
183 | #endif | |
f774849c | 184 | if (setgid (pw->pw_gid)) |
3c350007 JB |
185 | @@ -308,6 +403,31 @@ |
186 | error (EXIT_FAILURE, errno, _("cannot set user id")); | |
f774849c | 187 | } |
188 | ||
189 | +#ifdef USE_PAM | |
190 | +static int caught=0; | |
191 | +/* Signal handler for parent process later */ | |
192 | +static void su_catch_sig(int sig) | |
193 | +{ | |
194 | + ++caught; | |
195 | +} | |
196 | + | |
197 | +int | |
198 | +pam_copyenv (pam_handle_t *pamh) | |
199 | +{ | |
200 | + char **env; | |
ca7ee99d | 201 | + |
f774849c | 202 | + env = pam_getenvlist(pamh); |
203 | + if(env) { | |
204 | + while(*env) { | |
ca7ee99d JR |
205 | + if (putenv (*env)) |
206 | + xalloc_die (); | |
f774849c | 207 | + env++; |
208 | + } | |
209 | + } | |
210 | + return(0); | |
211 | +} | |
212 | +#endif | |
213 | + | |
214 | /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. | |
215 | If COMMAND is nonzero, pass it to the shell with the -c option. | |
c2be74f0 | 216 | Pass ADDITIONAL_ARGS to the shell as more arguments; there |
3c350007 | 217 | @@ -315,17 +435,49 @@ |
f774849c | 218 | |
219 | static void | |
c2be74f0 JB |
220 | run_shell (char const *shell, char const *command, char **additional_args, |
221 | - size_t n_additional_args) | |
222 | + size_t n_additional_args, const struct passwd *pw) | |
f774849c | 223 | { |
c2be74f0 JB |
224 | size_t n_args = 1 + fast_startup + 2 * !!command + n_additional_args + 1; |
225 | char const **args = xnmalloc (n_args, sizeof *args); | |
226 | size_t argno = 1; | |
f774849c | 227 | +#ifdef USE_PAM |
228 | + int child; | |
229 | + sigset_t ourset; | |
230 | + int status; | |
231 | + | |
232 | + retval = pam_open_session(pamh,0); | |
233 | + if (retval != PAM_SUCCESS) { | |
40ce7301 | 234 | + fprintf (stderr, _("could not open session\n")); |
f774849c | 235 | + exit (1); |
236 | + } | |
237 | + | |
238 | +/* do this at the last possible moment, because environment variables may | |
239 | + be passed even in the session phase | |
240 | +*/ | |
241 | + if(pam_copyenv(pamh) != PAM_SUCCESS) | |
40ce7301 | 242 | + fprintf (stderr, _("error copying PAM environment\n")); |
700628e7 | 243 | + |
ca7ee99d JR |
244 | + /* Credentials should be set in the parent */ |
245 | + if (pam_setcred(pamh, PAM_ESTABLISH_CRED) != PAM_SUCCESS) { | |
246 | + pam_close_session(pamh, 0); | |
247 | + fprintf(stderr, _("could not set PAM credentials\n")); | |
248 | + exit(1); | |
249 | + } | |
250 | + | |
f774849c | 251 | + child = fork(); |
252 | + if (child == 0) { /* child shell */ | |
253 | + change_identity (pw); | |
254 | + pam_end(pamh, 0); | |
255 | +#endif | |
ca7ee99d | 256 | |
c2be74f0 JB |
257 | if (simulate_login) |
258 | { | |
259 | char *arg0; | |
ca7ee99d JR |
260 | char *shell_basename; |
261 | ||
262 | + if(chdir(pw->pw_dir)) | |
263 | + error(0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); | |
264 | + | |
265 | shell_basename = last_component (shell); | |
266 | arg0 = xmalloc (strlen (shell_basename) + 2); | |
267 | arg0[0] = '-'; | |
3c350007 | 268 | @@ -350,6 +502,66 @@ |
700628e7 JB |
269 | error (0, errno, "%s", shell); |
270 | exit (exit_status); | |
f774849c | 271 | } |
272 | +#ifdef USE_PAM | |
273 | + } else if (child == -1) { | |
ca7ee99d JR |
274 | + fprintf(stderr, _("can not fork user shell: %s"), strerror(errno)); |
275 | + pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); | |
276 | + pam_close_session(pamh, 0); | |
277 | + pam_end(pamh, PAM_ABORT); | |
f774849c | 278 | + exit(1); |
279 | + } | |
280 | + /* parent only */ | |
281 | + sigfillset(&ourset); | |
282 | + if (sigprocmask(SIG_BLOCK, &ourset, NULL)) { | |
40ce7301 | 283 | + fprintf(stderr, _("%s: signal malfunction\n"), PROGRAM_NAME); |
f774849c | 284 | + caught = 1; |
285 | + } | |
286 | + if (!caught) { | |
287 | + struct sigaction action; | |
288 | + action.sa_handler = su_catch_sig; | |
289 | + sigemptyset(&action.sa_mask); | |
290 | + action.sa_flags = 0; | |
291 | + sigemptyset(&ourset); | |
292 | + if (sigaddset(&ourset, SIGTERM) | |
293 | + || sigaddset(&ourset, SIGALRM) | |
294 | + || sigaction(SIGTERM, &action, NULL) | |
295 | + || sigprocmask(SIG_UNBLOCK, &ourset, NULL)) { | |
40ce7301 | 296 | + fprintf(stderr, _("%s: signal masking malfunction\n"), PROGRAM_NAME); |
f774849c | 297 | + caught = 1; |
298 | + } | |
299 | + } | |
300 | + if (!caught) { | |
301 | + do { | |
302 | + int pid; | |
303 | + | |
304 | + pid = waitpid(-1, &status, WUNTRACED); | |
305 | + | |
306 | + if (WIFSTOPPED(status)) { | |
307 | + kill(getpid(), SIGSTOP); | |
308 | + /* once we get here, we must have resumed */ | |
309 | + kill(pid, SIGCONT); | |
310 | + } | |
311 | + } while (WIFSTOPPED(status)); | |
312 | + } | |
313 | + | |
314 | + if (caught) { | |
40ce7301 | 315 | + fprintf(stderr, _("\nSession terminated, killing shell...")); |
f774849c | 316 | + kill (child, SIGTERM); |
317 | + } | |
ca7ee99d JR |
318 | + /* Not checking retval on this because we need to call close session */ |
319 | + pam_setcred(pamh, PAM_DELETE_CRED | PAM_SILENT); | |
f774849c | 320 | + retval = pam_close_session(pamh, 0); |
ca7ee99d | 321 | + PAM_BAIL_P_VOID; |
f774849c | 322 | + retval = pam_end(pamh, PAM_SUCCESS); |
ca7ee99d | 323 | + PAM_BAIL_P_VOID; |
f774849c | 324 | + if (caught) { |
325 | + sleep(2); | |
326 | + kill(child, SIGKILL); | |
ca7ee99d | 327 | + fprintf(stderr, _(" ...killed.\n")); |
f774849c | 328 | + exit(-1); |
329 | + } | |
330 | + exit (WEXITSTATUS(status)); | |
331 | +#endif /* USE_PAM */ | |
332 | } | |
333 | ||
c2be74f0 | 334 | /* Return true if SHELL is a restricted shell (one not returned by |
3c350007 | 335 | @@ -517,9 +729,9 @@ |
c2be74f0 | 336 | shell = xstrdup (shell ? shell : pw->pw_shell); |
f774849c | 337 | modify_environment (pw, shell); |
338 | ||
ca7ee99d | 339 | +#ifndef USE_PAM |
f774849c | 340 | change_identity (pw); |
ca7ee99d JR |
341 | - if (simulate_login && chdir (pw->pw_dir) != 0) |
342 | - error (0, errno, _("warning: cannot change directory to %s"), pw->pw_dir); | |
f774849c | 343 | +#endif |
f774849c | 344 | |
c2be74f0 JB |
345 | - run_shell (shell, command, argv + optind, MAX (0, argc - optind)); |
346 | + run_shell (shell, command, argv + optind, MAX (0, argc - optind), pw); | |
f774849c | 347 | } |
ca7ee99d JR |
348 | --- coreutils-6.7/doc/coreutils.texi.pam 2006-10-27 15:30:48.000000000 +0100 |
349 | +++ coreutils-6.7/doc/coreutils.texi 2007-01-09 17:00:01.000000000 +0000 | |
350 | @@ -13395,8 +13395,11 @@ | |
351 | @findex syslog | |
352 | @command{su} can optionally be compiled to use @code{syslog} to report | |
353 | failed, and optionally successful, @command{su} attempts. (If the system | |
354 | -supports @code{syslog}.) However, GNU @command{su} does not check if the | |
355 | -user is a member of the @code{wheel} group; see below. | |
356 | +supports @code{syslog}.) | |
357 | + | |
358 | +This version of @command{su} has support for using PAM for | |
359 | +authentication. You can edit @file{/etc/pam.d/su} to customize its | |
360 | +behaviour. | |
361 | ||
362 | The program accepts the following options. Also see @ref{Common options}. | |
363 | ||
364 | @@ -11892,32 +11892,6 @@ | |
365 | the exit status of the subshell otherwise | |
366 | @end display | |
367 | ||
368 | -@cindex wheel group, not supported | |
369 | -@cindex group wheel, not supported | |
370 | -@cindex fascism | |
371 | -@subsection Why GNU @command{su} does not support the @samp{wheel} group | |
372 | - | |
373 | -(This section is by Richard Stallman.) | |
374 | - | |
375 | -@cindex Twenex | |
376 | -@cindex MIT AI lab | |
377 | -Sometimes a few of the users try to hold total power over all the | |
378 | -rest. For example, in 1984, a few users at the MIT AI lab decided to | |
379 | -seize power by changing the operator password on the Twenex system and | |
380 | -keeping it secret from everyone else. (I was able to thwart this coup | |
381 | -and give power back to the users by patching the kernel, but I | |
382 | -wouldn't know how to do that in Unix.) | |
383 | - | |
384 | -However, occasionally the rulers do tell someone. Under the usual | |
385 | -@command{su} mechanism, once someone learns the root password who | |
386 | -sympathizes with the ordinary users, he or she can tell the rest. The | |
387 | -``wheel group'' feature would make this impossible, and thus cement the | |
388 | -power of the rulers. | |
389 | - | |
390 | -I'm on the side of the masses, not that of the rulers. If you are | |
391 | -used to supporting the bosses and sysadmins in whatever they do, you | |
392 | -might find this idea strange at first. | |
393 | - | |
394 | ||
395 | @node Delaying | |
396 | @chapter Delaying | |
3c350007 JB |
397 | --- coreutils-6.10/configure.ac.orig 2008-01-13 09:14:23.000000000 +0100 |
398 | +++ coreutils-6.10/configure.ac 2008-03-02 02:08:10.027276914 +0100 | |
399 | @@ -44,6 +44,13 @@ | |
ca7ee99d JR |
400 | gl_INIT |
401 | coreutils_MACROS | |
402 | ||
403 | +dnl Give the chance to enable PAM | |
404 | +AC_ARG_ENABLE(pam, dnl | |
405 | +[ --enable-pam Enable use of the PAM libraries], | |
c1e30285 | 406 | +AC_DEFINE(USE_PAM, 1, [Define if you want to use PAM]) |
ca7ee99d JR |
407 | +LIB_PAM="-ldl -lpam -lpam_misc" |
408 | +) | |
409 | + | |
3c350007 JB |
410 | AC_FUNC_FORK |
411 | ||
412 | optional_bin_progs= | |
413 | @@ -332,6 +339,13 @@ | |
ca7ee99d JR |
414 | AM_GNU_GETTEXT([external], [need-formatstring-macros]) |
415 | AM_GNU_GETTEXT_VERSION([0.15]) | |
416 | ||
417 | +# just in case we want PAM | |
418 | +AC_SUBST(LIB_PAM) | |
419 | +# with PAM su doesn't need libcrypt | |
420 | +if test -n "$LIB_PAM" ; then | |
421 | + LIB_CRYPT= | |
422 | +fi | |
423 | + | |
424 | AC_CONFIG_FILES( | |
425 | Makefile | |
426 | doc/Makefile | |
3c350007 JB |
427 | --- coreutils-6.10/po/pl.po.orig 2008-01-16 21:22:08.000000000 +0100 |
428 | +++ coreutils-6.10/po/pl.po 2008-03-02 02:09:23.671473657 +0100 | |
429 | @@ -8875,6 +8875,49 @@ | |
ca7ee99d | 430 | msgid "Usage: %s [OPTION]... [-] [USER [ARG]...]\n" |
e87f5ed5 | 431 |