]> git.ipfire.org Git - ipfire-3.x.git/blob - krb5/patches/krb5-1.10.2-pam.patch
4d7c0540d77b19853d48995885e8df4830073116
[ipfire-3.x.git] / krb5 / patches / krb5-1.10.2-pam.patch
1 Modify ksu so that it performs account and session management on behalf of
2 the target user account, mimicking the action of regular su. The default
3 service name is "ksu", because on Fedora at least the configuration used
4 is determined by whether or not a login shell is being opened, and so
5 this may need to vary, too. At run-time, ksu's behavior can be reset to
6 the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
7 section of /etc/krb5.conf.
8
9 When enabled, ksu gains a dependency on libpam.
10
11 Originally RT#5939, though it's changed since then to perform the account
12 and session management before dropping privileges.
13
14 diff -up krb5-1.8/src/aclocal.m4.pam krb5-1.8/src/aclocal.m4
15 --- krb5-1.8/src/aclocal.m4.pam 2009-11-22 12:00:45.000000000 -0500
16 +++ krb5-1.8/src/aclocal.m4 2010-03-05 10:48:08.000000000 -0500
17 @@ -1703,3 +1703,70 @@ AC_DEFUN(KRB5_AC_KEYRING_CCACHE,[
18 ]))
19 ])dnl
20 dnl
21 +dnl
22 +dnl Use PAM instead of local crypt() compare for checking local passwords,
23 +dnl and perform PAM account, session management, and password-changing where
24 +dnl appropriate.
25 +dnl
26 +AC_DEFUN(KRB5_WITH_PAM,[
27 +AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
28 + withpam="$withval",withpam=auto)
29 +AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])],
30 + withksupamservice="$withval",withksupamservice=ksu)
31 +old_LIBS="$LIBS"
32 +if test "$withpam" != no ; then
33 + AC_MSG_RESULT([checking for PAM...])
34 + PAM_LIBS=
35 +
36 + AC_CHECK_HEADERS(security/pam_appl.h)
37 + if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
38 + if test "$withpam" = auto ; then
39 + AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
40 + withpam=no
41 + else
42 + AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
43 + fi
44 + fi
45 +
46 + LIBS=
47 + unset ac_cv_func_pam_start
48 + AC_CHECK_FUNCS(putenv pam_start)
49 + if test "x$ac_cv_func_pam_start" = xno ; then
50 + unset ac_cv_func_pam_start
51 + AC_CHECK_LIB(dl,dlopen)
52 + AC_CHECK_FUNCS(pam_start)
53 + if test "x$ac_cv_func_pam_start" = xno ; then
54 + AC_CHECK_LIB(pam,pam_start)
55 + unset ac_cv_func_pam_start
56 + unset ac_cv_func_pam_getenvlist
57 + AC_CHECK_FUNCS(pam_start pam_getenvlist)
58 + if test "x$ac_cv_func_pam_start" = xyes ; then
59 + PAM_LIBS="$LIBS"
60 + else
61 + if test "$withpam" = auto ; then
62 + AC_MSG_RESULT([Unable to locate libpam.])
63 + withpam=no
64 + else
65 + AC_MSG_ERROR([Unable to locate libpam.])
66 + fi
67 + fi
68 + fi
69 + fi
70 + if test "$withpam" != no ; then
71 + AC_MSG_NOTICE([building with PAM support])
72 + AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
73 + AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice",
74 + [Define to the name of the PAM service name to be used by ksu.])
75 + PAM_LIBS="$LIBS"
76 + NON_PAM_MAN=".\\\" "
77 + PAM_MAN=
78 + else
79 + PAM_MAN=".\\\" "
80 + NON_PAM_MAN=
81 + fi
82 +fi
83 +LIBS="$old_LIBS"
84 +AC_SUBST(PAM_LIBS)
85 +AC_SUBST(PAM_MAN)
86 +AC_SUBST(NON_PAM_MAN)
87 +])dnl
88 diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/src/clients/ksu/main.c
89 --- krb5-1.8/src/clients/ksu/main.c.pam 2009-11-02 22:27:56.000000000 -0500
90 +++ krb5-1.8/src/clients/ksu/main.c 2010-03-05 10:48:08.000000000 -0500
91 @@ -26,6 +26,7 @@
92 * KSU was writen by: Ari Medvinsky, ari@isi.edu
93 */
94
95 +#include "autoconf.h"
96 #include "ksu.h"
97 #include "adm_proto.h"
98 #include <sys/types.h>
99 @@ -33,6 +34,10 @@
100 #include <signal.h>
101 #include <grp.h>
102
103 +#ifdef USE_PAM
104 +#include "pam.h"
105 +#endif
106 +
107 /* globals */
108 char * prog_name;
109 int auth_debug =0;
110 @@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN];
111 char k5users_path[MAXPATHLEN];
112 char * gb_err = NULL;
113 int quiet = 0;
114 +int force_fork = 0;
115 /***********/
116
117 #define _DEF_CSH "/bin/csh"
118 @@ -586,6 +592,25 @@ main (argc, argv)
119 prog_name,target_user,client_name,
120 source_user,ontty());
121
122 +#ifdef USE_PAM
123 + if (appl_pam_enabled(ksu_context, "ksu")) {
124 + if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
125 + NULL, source_user,
126 + ttyname(STDERR_FILENO)) != 0) {
127 + fprintf(stderr, "Access denied for %s.\n", target_user);
128 + sweep_up(ksu_context, cc_target);
129 + exit(1);
130 + }
131 + if (appl_pam_requires_chauthtok()) {
132 + fprintf(stderr, "Password change required for %s.\n",
133 + target_user);
134 + sweep_up(ksu_context, cc_target);
135 + exit(1);
136 + }
137 + force_fork++;
138 + }
139 +#endif
140 +
141 /* Run authorization as target.*/
142 if (krb5_seteuid(target_uid)) {
143 com_err(prog_name, errno, _("while switching to target for "
144 @@ -651,6 +676,26 @@
145 sweep_up(ksu_context, cc_target);
146 exit(1);
147 }
148 +#ifdef USE_PAM
149 + } else {
150 + /* we always do PAM account management, even for root */
151 + if (appl_pam_enabled(ksu_context, "ksu")) {
152 + if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
153 + NULL, source_user,
154 + ttyname(STDERR_FILENO)) != 0) {
155 + fprintf(stderr, "Access denied for %s.\n", target_user);
156 + sweep_up(ksu_context, cc_target);
157 + exit(1);
158 + }
159 + if (appl_pam_requires_chauthtok()) {
160 + fprintf(stderr, "Password change required for %s.\n",
161 + target_user);
162 + sweep_up(ksu_context, cc_target);
163 + exit(1);
164 + }
165 + force_fork++;
166 + }
167 +#endif
168 }
169
170 if( some_rest_copy){
171 @@ -720,6 +745,32 @@
172 exit(1);
173 }
174
175 +#ifdef USE_PAM
176 + if (appl_pam_enabled(ksu_context, "ksu")) {
177 + if (appl_pam_session_open() != 0) {
178 + fprintf(stderr, "Error opening session for %s.\n", target_user);
179 + sweep_up(ksu_context, cc_target);
180 + exit(1);
181 + }
182 +#ifdef DEBUG
183 + if (auth_debug){
184 + printf(" Opened PAM session.\n");
185 + }
186 +#endif
187 + if (appl_pam_cred_init()) {
188 + fprintf(stderr, "Error initializing credentials for %s.\n",
189 + target_user);
190 + sweep_up(ksu_context, cc_target);
191 + exit(1);
192 + }
193 +#ifdef DEBUG
194 + if (auth_debug){
195 + printf(" Initialized PAM credentials.\n");
196 + }
197 +#endif
198 + }
199 +#endif
200 +
201 /* set permissions */
202 if (setgid(target_pwd->pw_gid) < 0) {
203 perror("ksu: setgid");
204 @@ -792,7 +817,7 @@ main (argc, argv)
205 fprintf(stderr, "program to be execed %s\n",params[0]);
206 }
207
208 - if( keep_target_cache ) {
209 + if( keep_target_cache && !force_fork ) {
210 execv(params[0], params);
211 com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
212 sweep_up(ksu_context, cc_target);
213 @@ -823,16 +875,35 @@ main (argc, argv)
214 if (ret_pid == -1) {
215 com_err(prog_name, errno, _("while calling waitpid"));
216 }
217 - sweep_up(ksu_context, cc_target);
218 + if( !keep_target_cache ) {
219 + sweep_up(ksu_context, cc_target);
220 + }
221 exit (statusp);
222 case -1:
223 com_err(prog_name, errno, _("while trying to fork."));
224 sweep_up(ksu_context, cc_target);
225 exit (1);
226 case 0:
227 +#ifdef USE_PAM
228 + if (appl_pam_enabled(ksu_context, "ksu")) {
229 + if (appl_pam_setenv() != 0) {
230 + fprintf(stderr, "Error setting up environment for %s.\n",
231 + target_user);
232 + exit (1);
233 + }
234 +#ifdef DEBUG
235 + if (auth_debug){
236 + printf(" Set up PAM environment.\n");
237 + }
238 +#endif
239 + }
240 +#endif
241 execv(params[0], params);
242 com_err(prog_name, errno, _("while trying to execv %s"),
243 params[0]);
244 + if( keep_target_cache ) {
245 + sweep_up(ksu_context, cc_target);
246 + }
247 exit (1);
248 }
249 }
250 diff -up krb5-1.8/src/clients/ksu/Makefile.in.pam krb5-1.8/src/clients/ksu/Makefile.in
251 --- krb5-1.8/src/clients/ksu/Makefile.in.pam 2009-11-22 13:13:29.000000000 -0500
252 +++ krb5-1.8/src/clients/ksu/Makefile.in 2010-03-05 11:55:14.000000000 -0500
253 @@ -7,12 +7,14 @@
254 PROG_RPATH=$(KRB5_LIBDIR)
255
256 KSU_LIBS=@KSU_LIBS@
257 +PAM_LIBS=@PAM_LIBS@
258
259 SRCS = \
260 $(srcdir)/krb_auth_su.c \
261 $(srcdir)/ccache.c \
262 $(srcdir)/authorization.c \
263 $(srcdir)/main.c \
264 + $(srcdir)/pam.c \
265 $(srcdir)/heuristic.c \
266 $(srcdir)/xmalloc.c \
267 $(srcdir)/setenv.c
268 @@ -21,13 +23,17 @@ OBJS = \
269 ccache.o \
270 authorization.o \
271 main.o \
272 + pam.o \
273 heuristic.o \
274 xmalloc.o @SETENVOBJ@
275
276 all:: ksu
277
278 ksu: $(OBJS) $(KRB5_BASE_DEPLIBS)
279 - $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS)
280 + $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS)
281 +
282 +pam.o: pam.c
283 + $(CC) $(ALL_CFLAGS) -c $<
284
285 clean::
286 $(RM) ksu
287 diff -up krb5-1.8/src/clients/ksu/pam.c.pam krb5-1.8/src/clients/ksu/pam.c
288 --- krb5-1.8/src/clients/ksu/pam.c.pam 2010-03-05 10:48:08.000000000 -0500
289 +++ krb5-1.8/src/clients/ksu/pam.c 2010-03-05 10:48:08.000000000 -0500
290 @@ -0,0 +1,389 @@
291 +/*
292 + * src/clients/ksu/pam.c
293 + *
294 + * Copyright 2007,2009,2010 Red Hat, Inc.
295 + *
296 + * All Rights Reserved.
297 + *
298 + * Redistribution and use in source and binary forms, with or without
299 + * modification, are permitted provided that the following conditions are met:
300 + *
301 + * Redistributions of source code must retain the above copyright notice, this
302 + * list of conditions and the following disclaimer.
303 + *
304 + * Redistributions in binary form must reproduce the above copyright notice,
305 + * this list of conditions and the following disclaimer in the documentation
306 + * and/or other materials provided with the distribution.
307 + *
308 + * Neither the name of Red Hat, Inc. nor the names of its contributors may be
309 + * used to endorse or promote products derived from this software without
310 + * specific prior written permission.
311 + *
312 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
313 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
314 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
315 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
316 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
317 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
318 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
319 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
320 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
321 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
322 + * POSSIBILITY OF SUCH DAMAGE.
323 + *
324 + * Convenience wrappers for using PAM.
325 + */
326 +
327 +#include "autoconf.h"
328 +#ifdef USE_PAM
329 +#include <sys/types.h>
330 +#include <stdio.h>
331 +#include <stdlib.h>
332 +#include <string.h>
333 +#include <unistd.h>
334 +#include "k5-int.h"
335 +#include "pam.h"
336 +
337 +#ifndef MAXPWSIZE
338 +#define MAXPWSIZE 128
339 +#endif
340 +
341 +static int appl_pam_started;
342 +static pid_t appl_pam_starter = -1;
343 +static int appl_pam_session_opened;
344 +static int appl_pam_creds_initialized;
345 +static int appl_pam_pwchange_required;
346 +static pam_handle_t *appl_pamh;
347 +static struct pam_conv appl_pam_conv;
348 +static char *appl_pam_user;
349 +struct appl_pam_non_interactive_args {
350 + const char *user;
351 + const char *password;
352 +};
353 +
354 +int
355 +appl_pam_enabled(krb5_context context, const char *section)
356 +{
357 + int enabled = 1;
358 + if ((context != NULL) && (context->profile != NULL)) {
359 + if (profile_get_boolean(context->profile,
360 + section,
361 + USE_PAM_CONFIGURATION_KEYWORD,
362 + NULL,
363 + enabled, &enabled) != 0) {
364 + enabled = 1;
365 + }
366 + }
367 + return enabled;
368 +}
369 +
370 +void
371 +appl_pam_cleanup(void)
372 +{
373 + if (getpid() != appl_pam_starter) {
374 + return;
375 + }
376 +#ifdef DEBUG
377 + printf("Called to clean up PAM.\n");
378 +#endif
379 + if (appl_pam_creds_initialized) {
380 +#ifdef DEBUG
381 + printf("Deleting PAM credentials.\n");
382 +#endif
383 + pam_setcred(appl_pamh, PAM_DELETE_CRED);
384 + appl_pam_creds_initialized = 0;
385 + }
386 + if (appl_pam_session_opened) {
387 +#ifdef DEBUG
388 + printf("Closing PAM session.\n");
389 +#endif
390 + pam_close_session(appl_pamh, 0);
391 + appl_pam_session_opened = 0;
392 + }
393 + appl_pam_pwchange_required = 0;
394 + if (appl_pam_started) {
395 +#ifdef DEBUG
396 + printf("Shutting down PAM.\n");
397 +#endif
398 + pam_end(appl_pamh, 0);
399 + appl_pam_started = 0;
400 + appl_pam_starter = -1;
401 + free(appl_pam_user);
402 + appl_pam_user = NULL;
403 + }
404 +}
405 +static int
406 +appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
407 + struct pam_response **presp, void *appdata_ptr)
408 +{
409 + const struct pam_message *message;
410 + struct pam_response *resp;
411 + int i, code;
412 + char *pwstring, pwbuf[MAXPWSIZE];
413 + unsigned int pwsize;
414 + resp = malloc(sizeof(struct pam_response) * num_msg);
415 + if (resp == NULL) {
416 + return PAM_BUF_ERR;
417 + }
418 + memset(resp, 0, sizeof(struct pam_response) * num_msg);
419 + code = PAM_SUCCESS;
420 + for (i = 0; i < num_msg; i++) {
421 + message = &(msg[0][i]); /* XXX */
422 + message = msg[i]; /* XXX */
423 + pwstring = NULL;
424 + switch (message->msg_style) {
425 + case PAM_TEXT_INFO:
426 + case PAM_ERROR_MSG:
427 + printf("[%s]\n", message->msg ? message->msg : "");
428 + fflush(stdout);
429 + resp[i].resp = NULL;
430 + resp[i].resp_retcode = PAM_SUCCESS;
431 + break;
432 + case PAM_PROMPT_ECHO_ON:
433 + case PAM_PROMPT_ECHO_OFF:
434 + if (message->msg_style == PAM_PROMPT_ECHO_ON) {
435 + if (fgets(pwbuf, sizeof(pwbuf),
436 + stdin) != NULL) {
437 + pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
438 + pwstring = pwbuf;
439 + }
440 + } else {
441 + pwstring = getpass(message->msg ?
442 + message->msg :
443 + "");
444 + }
445 + if ((pwstring != NULL) && (pwstring[0] != '\0')) {
446 + pwsize = strlen(pwstring);
447 + resp[i].resp = malloc(pwsize + 1);
448 + if (resp[i].resp == NULL) {
449 + resp[i].resp_retcode = PAM_BUF_ERR;
450 + } else {
451 + memcpy(resp[i].resp, pwstring, pwsize);
452 + resp[i].resp[pwsize] = '\0';
453 + resp[i].resp_retcode = PAM_SUCCESS;
454 + }
455 + } else {
456 + resp[i].resp_retcode = PAM_CONV_ERR;
457 + code = PAM_CONV_ERR;
458 + }
459 + break;
460 + default:
461 + break;
462 + }
463 + }
464 + *presp = resp;
465 + return code;
466 +}
467 +static int
468 +appl_pam_non_interactive_converse(int num_msg,
469 + const struct pam_message **msg,
470 + struct pam_response **presp,
471 + void *appdata_ptr)
472 +{
473 + const struct pam_message *message;
474 + struct pam_response *resp;
475 + int i, code;
476 + unsigned int pwsize;
477 + struct appl_pam_non_interactive_args *args;
478 + const char *pwstring;
479 + resp = malloc(sizeof(struct pam_response) * num_msg);
480 + if (resp == NULL) {
481 + return PAM_BUF_ERR;
482 + }
483 + args = appdata_ptr;
484 + memset(resp, 0, sizeof(struct pam_response) * num_msg);
485 + code = PAM_SUCCESS;
486 + for (i = 0; i < num_msg; i++) {
487 + message = &((*msg)[i]);
488 + message = msg[i];
489 + pwstring = NULL;
490 + switch (message->msg_style) {
491 + case PAM_TEXT_INFO:
492 + case PAM_ERROR_MSG:
493 + break;
494 + case PAM_PROMPT_ECHO_ON:
495 + case PAM_PROMPT_ECHO_OFF:
496 + if (message->msg_style == PAM_PROMPT_ECHO_ON) {
497 + /* assume "user" */
498 + pwstring = args->user;
499 + } else {
500 + /* assume "password" */
501 + pwstring = args->password;
502 + }
503 + if ((pwstring != NULL) && (pwstring[0] != '\0')) {
504 + pwsize = strlen(pwstring);
505 + resp[i].resp = malloc(pwsize + 1);
506 + if (resp[i].resp == NULL) {
507 + resp[i].resp_retcode = PAM_BUF_ERR;
508 + } else {
509 + memcpy(resp[i].resp, pwstring, pwsize);
510 + resp[i].resp[pwsize] = '\0';
511 + resp[i].resp_retcode = PAM_SUCCESS;
512 + }
513 + } else {
514 + resp[i].resp_retcode = PAM_CONV_ERR;
515 + code = PAM_CONV_ERR;
516 + }
517 + break;
518 + default:
519 + break;
520 + }
521 + }
522 + *presp = resp;
523 + return code;
524 +}
525 +static int
526 +appl_pam_start(const char *service, int interactive,
527 + const char *login_username,
528 + const char *non_interactive_password,
529 + const char *hostname,
530 + const char *ruser,
531 + const char *tty)
532 +{
533 + static int exit_handler_registered;
534 + static struct appl_pam_non_interactive_args args;
535 + int ret = 0;
536 + if (appl_pam_started &&
537 + (strcmp(login_username, appl_pam_user) != 0)) {
538 + appl_pam_cleanup();
539 + appl_pam_user = NULL;
540 + }
541 + if (!appl_pam_started) {
542 +#ifdef DEBUG
543 + printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
544 + service, login_username);
545 +#endif
546 + memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
547 + appl_pam_conv.conv = interactive ?
548 + &appl_pam_interactive_converse :
549 + &appl_pam_non_interactive_converse;
550 + memset(&args, 0, sizeof(args));
551 + args.user = strdup(login_username);
552 + args.password = non_interactive_password ?
553 + strdup(non_interactive_password) :
554 + NULL;
555 + appl_pam_conv.appdata_ptr = &args;
556 + ret = pam_start(service, login_username,
557 + &appl_pam_conv, &appl_pamh);
558 + if (ret == 0) {
559 + if (hostname != NULL) {
560 +#ifdef DEBUG
561 + printf("Setting PAM_RHOST to \"%s\".\n", hostname);
562 +#endif
563 + pam_set_item(appl_pamh, PAM_RHOST, hostname);
564 + }
565 + if (ruser != NULL) {
566 +#ifdef DEBUG
567 + printf("Setting PAM_RUSER to \"%s\".\n", ruser);
568 +#endif
569 + pam_set_item(appl_pamh, PAM_RUSER, ruser);
570 + }
571 + if (tty != NULL) {
572 +#ifdef DEBUG
573 + printf("Setting PAM_TTY to \"%s\".\n", tty);
574 +#endif
575 + pam_set_item(appl_pamh, PAM_TTY, tty);
576 + }
577 + if (!exit_handler_registered &&
578 + (atexit(appl_pam_cleanup) != 0)) {
579 + pam_end(appl_pamh, 0);
580 + appl_pamh = NULL;
581 + ret = -1;
582 + } else {
583 + appl_pam_started = 1;
584 + appl_pam_starter = getpid();
585 + appl_pam_user = strdup(login_username);
586 + exit_handler_registered = 1;
587 + }
588 + }
589 + }
590 + return ret;
591 +}
592 +int
593 +appl_pam_acct_mgmt(const char *service, int interactive,
594 + const char *login_username,
595 + const char *non_interactive_password,
596 + const char *hostname,
597 + const char *ruser,
598 + const char *tty)
599 +{
600 + int ret;
601 + appl_pam_pwchange_required = 0;
602 + ret = appl_pam_start(service, interactive, login_username,
603 + non_interactive_password, hostname, ruser, tty);
604 + if (ret == 0) {
605 +#ifdef DEBUG
606 + printf("Calling pam_acct_mgmt().\n");
607 +#endif
608 + ret = pam_acct_mgmt(appl_pamh, 0);
609 + switch (ret) {
610 + case PAM_IGNORE:
611 + ret = 0;
612 + break;
613 + case PAM_NEW_AUTHTOK_REQD:
614 + appl_pam_pwchange_required = 1;
615 + ret = 0;
616 + break;
617 + default:
618 + break;
619 + }
620 + }
621 + return ret;
622 +}
623 +int
624 +appl_pam_requires_chauthtok(void)
625 +{
626 + return appl_pam_pwchange_required;
627 +}
628 +int
629 +appl_pam_session_open(void)
630 +{
631 + int ret = 0;
632 + if (appl_pam_started) {
633 +#ifdef DEBUG
634 + printf("Opening PAM session.\n");
635 +#endif
636 + ret = pam_open_session(appl_pamh, 0);
637 + if (ret == 0) {
638 + appl_pam_session_opened = 1;
639 + }
640 + }
641 + return ret;
642 +}
643 +int
644 +appl_pam_setenv(void)
645 +{
646 + int ret = 0;
647 +#ifdef HAVE_PAM_GETENVLIST
648 +#ifdef HAVE_PUTENV
649 + int i;
650 + char **list;
651 + if (appl_pam_started) {
652 + list = pam_getenvlist(appl_pamh);
653 + for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
654 +#ifdef DEBUG
655 + printf("Setting \"%s\" in environment.\n", list[i]);
656 +#endif
657 + putenv(list[i]);
658 + }
659 + }
660 +#endif
661 +#endif
662 + return ret;
663 +}
664 +int
665 +appl_pam_cred_init(void)
666 +{
667 + int ret = 0;
668 + if (appl_pam_started) {
669 +#ifdef DEBUG
670 + printf("Initializing PAM credentials.\n");
671 +#endif
672 + ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
673 + if (ret == 0) {
674 + appl_pam_creds_initialized = 1;
675 + }
676 + }
677 + return ret;
678 +}
679 +#endif
680 diff -up krb5-1.8/src/clients/ksu/pam.h.pam krb5-1.8/src/clients/ksu/pam.h
681 --- krb5-1.8/src/clients/ksu/pam.h.pam 2010-03-05 10:48:08.000000000 -0500
682 +++ krb5-1.8/src/clients/ksu/pam.h 2010-03-05 10:48:08.000000000 -0500
683 @@ -0,0 +1,57 @@
684 +/*
685 + * src/clients/ksu/pam.h
686 + *
687 + * Copyright 2007,2009,2010 Red Hat, Inc.
688 + *
689 + * All Rights Reserved.
690 + *
691 + * Redistribution and use in source and binary forms, with or without
692 + * modification, are permitted provided that the following conditions are met:
693 + *
694 + * Redistributions of source code must retain the above copyright notice, this
695 + * list of conditions and the following disclaimer.
696 + *
697 + * Redistributions in binary form must reproduce the above copyright notice,
698 + * this list of conditions and the following disclaimer in the documentation
699 + * and/or other materials provided with the distribution.
700 + *
701 + * Neither the name of Red Hat, Inc. nor the names of its contributors may be
702 + * used to endorse or promote products derived from this software without
703 + * specific prior written permission.
704 + *
705 + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
706 + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
707 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
708 + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
709 + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
710 + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
711 + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
712 + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
713 + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
714 + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
715 + * POSSIBILITY OF SUCH DAMAGE.
716 + *
717 + * Convenience wrappers for using PAM.
718 + */
719 +
720 +#include <krb5.h>
721 +#ifdef HAVE_SECURITY_PAM_APPL_H
722 +#include <security/pam_appl.h>
723 +#endif
724 +
725 +#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
726 +
727 +#ifdef USE_PAM
728 +int appl_pam_enabled(krb5_context context, const char *section);
729 +int appl_pam_acct_mgmt(const char *service, int interactive,
730 + const char *local_username,
731 + const char *non_interactive_password,
732 + const char *hostname,
733 + const char *ruser,
734 + const char *tty);
735 +int appl_pam_requires_chauthtok(void);
736 +int appl_pam_session_open(void);
737 +int appl_pam_setenv(void);
738 +int appl_pam_cred_init(void);
739 +void appl_pam_cleanup(void);
740 +#endif
741 diff -up krb5-1.8/src/configure.in.pam krb5-1.8/src/configure.in
742 --- krb5-1.8/src/configure.in.pam 2009-12-31 18:13:56.000000000 -0500
743 +++ krb5-1.8/src/configure.in 2010-03-05 10:48:08.000000000 -0500
744 @@ -1051,6 +1051,8 @@ if test "$ac_cv_lib_socket" = "yes" -a "
745 AC_SUBST([VERTO_LIBS])
746 AC_SUBST([VERTO_VERSION])
747
748 +KRB5_WITH_PAM
749 +
750 # Make localedir work in autoconf 2.5x.
751 if test "${localedir+set}" != set; then
752 localedir='$(datadir)/locale'