]> git.ipfire.org Git - ipfire-3.x.git/blame - krb5/patches/krb5-1.10.2-pam.patch
mesa: Build dri drivers only for x86
[ipfire-3.x.git] / krb5 / patches / krb5-1.10.2-pam.patch
CommitLineData
6cf77d05
SS
1Modify ksu so that it performs account and session management on behalf of
2the target user account, mimicking the action of regular su. The default
3service name is "ksu", because on Fedora at least the configuration used
4is determined by whether or not a login shell is being opened, and so
5this may need to vary, too. At run-time, ksu's behavior can be reset to
6the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
7section of /etc/krb5.conf.
8
9When enabled, ksu gains a dependency on libpam.
10
11Originally RT#5939, though it's changed since then to perform the account
12and session management before dropping privileges.
13
14diff -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
88diff -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 }
250diff -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
287diff -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
680diff -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
741diff -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'