|
|
db6389 |
From 02a10f4b9a8decc8d10f3e045282a0ae7ed1c00d Mon Sep 17 00:00:00 2001
|
|
|
db6389 |
From: Robbie Harwood <rharwood@redhat.com>
|
|
|
db6389 |
Date: Tue, 23 Aug 2016 16:29:58 -0400
|
|
|
db6389 |
Subject: [PATCH] krb5-1.12.1-pam.patch
|
|
|
db6389 |
|
|
|
db6389 |
Modify ksu so that it performs account and session management on behalf of
|
|
|
db6389 |
the target user account, mimicking the action of regular su. The default
|
|
|
db6389 |
service name is "ksu", because on Fedora at least the configuration used
|
|
|
db6389 |
is determined by whether or not a login shell is being opened, and so
|
|
|
db6389 |
this may need to vary, too. At run-time, ksu's behavior can be reset to
|
|
|
db6389 |
the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
|
|
|
db6389 |
section of /etc/krb5.conf.
|
|
|
db6389 |
|
|
|
db6389 |
When enabled, ksu gains a dependency on libpam.
|
|
|
db6389 |
|
|
|
db6389 |
Originally RT#5939, though it's changed since then to perform the account
|
|
|
db6389 |
and session management before dropping privileges, and to apply on top of
|
|
|
db6389 |
changes we're proposing for how it handles cache collections.
|
|
|
db6389 |
---
|
|
|
db6389 |
src/aclocal.m4 | 67 +++++++
|
|
|
db6389 |
src/clients/ksu/Makefile.in | 8 +-
|
|
|
db6389 |
src/clients/ksu/main.c | 88 +++++++-
|
|
|
db6389 |
src/clients/ksu/pam.c | 389 ++++++++++++++++++++++++++++++++++++
|
|
|
db6389 |
src/clients/ksu/pam.h | 57 ++++++
|
|
|
db6389 |
src/configure.in | 2 +
|
|
|
db6389 |
6 files changed, 608 insertions(+), 3 deletions(-)
|
|
|
db6389 |
create mode 100644 src/clients/ksu/pam.c
|
|
|
db6389 |
create mode 100644 src/clients/ksu/pam.h
|
|
|
db6389 |
|
|
|
db6389 |
diff --git a/src/aclocal.m4 b/src/aclocal.m4
|
|
|
db6389 |
index 3752d9bd5..340546d80 100644
|
|
|
db6389 |
--- a/src/aclocal.m4
|
|
|
db6389 |
+++ b/src/aclocal.m4
|
|
|
db6389 |
@@ -1697,3 +1697,70 @@ AC_DEFUN(KRB5_AC_PERSISTENT_KEYRING,[
|
|
|
db6389 |
]))
|
|
|
db6389 |
])dnl
|
|
|
db6389 |
dnl
|
|
|
db6389 |
+dnl
|
|
|
db6389 |
+dnl Use PAM instead of local crypt() compare for checking local passwords,
|
|
|
db6389 |
+dnl and perform PAM account, session management, and password-changing where
|
|
|
db6389 |
+dnl appropriate.
|
|
|
db6389 |
+dnl
|
|
|
db6389 |
+AC_DEFUN(KRB5_WITH_PAM,[
|
|
|
db6389 |
+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
|
|
|
db6389 |
+ withpam="$withval",withpam=auto)
|
|
|
db6389 |
+AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])],
|
|
|
db6389 |
+ withksupamservice="$withval",withksupamservice=ksu)
|
|
|
db6389 |
+old_LIBS="$LIBS"
|
|
|
db6389 |
+if test "$withpam" != no ; then
|
|
|
db6389 |
+ AC_MSG_RESULT([checking for PAM...])
|
|
|
db6389 |
+ PAM_LIBS=
|
|
|
db6389 |
+
|
|
|
db6389 |
+ AC_CHECK_HEADERS(security/pam_appl.h)
|
|
|
db6389 |
+ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
|
|
|
db6389 |
+ if test "$withpam" = auto ; then
|
|
|
db6389 |
+ AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
|
|
|
db6389 |
+ withpam=no
|
|
|
db6389 |
+ else
|
|
|
db6389 |
+ AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
|
|
|
db6389 |
+ fi
|
|
|
db6389 |
+ fi
|
|
|
db6389 |
+
|
|
|
db6389 |
+ LIBS=
|
|
|
db6389 |
+ unset ac_cv_func_pam_start
|
|
|
db6389 |
+ AC_CHECK_FUNCS(putenv pam_start)
|
|
|
db6389 |
+ if test "x$ac_cv_func_pam_start" = xno ; then
|
|
|
db6389 |
+ unset ac_cv_func_pam_start
|
|
|
db6389 |
+ AC_CHECK_LIB(dl,dlopen)
|
|
|
db6389 |
+ AC_CHECK_FUNCS(pam_start)
|
|
|
db6389 |
+ if test "x$ac_cv_func_pam_start" = xno ; then
|
|
|
db6389 |
+ AC_CHECK_LIB(pam,pam_start)
|
|
|
db6389 |
+ unset ac_cv_func_pam_start
|
|
|
db6389 |
+ unset ac_cv_func_pam_getenvlist
|
|
|
db6389 |
+ AC_CHECK_FUNCS(pam_start pam_getenvlist)
|
|
|
db6389 |
+ if test "x$ac_cv_func_pam_start" = xyes ; then
|
|
|
db6389 |
+ PAM_LIBS="$LIBS"
|
|
|
db6389 |
+ else
|
|
|
db6389 |
+ if test "$withpam" = auto ; then
|
|
|
db6389 |
+ AC_MSG_RESULT([Unable to locate libpam.])
|
|
|
db6389 |
+ withpam=no
|
|
|
db6389 |
+ else
|
|
|
db6389 |
+ AC_MSG_ERROR([Unable to locate libpam.])
|
|
|
db6389 |
+ fi
|
|
|
db6389 |
+ fi
|
|
|
db6389 |
+ fi
|
|
|
db6389 |
+ fi
|
|
|
db6389 |
+ if test "$withpam" != no ; then
|
|
|
db6389 |
+ AC_MSG_NOTICE([building with PAM support])
|
|
|
db6389 |
+ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
|
|
|
db6389 |
+ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice",
|
|
|
db6389 |
+ [Define to the name of the PAM service name to be used by ksu.])
|
|
|
db6389 |
+ PAM_LIBS="$LIBS"
|
|
|
db6389 |
+ NON_PAM_MAN=".\\\" "
|
|
|
db6389 |
+ PAM_MAN=
|
|
|
db6389 |
+ else
|
|
|
db6389 |
+ PAM_MAN=".\\\" "
|
|
|
db6389 |
+ NON_PAM_MAN=
|
|
|
db6389 |
+ fi
|
|
|
db6389 |
+fi
|
|
|
db6389 |
+LIBS="$old_LIBS"
|
|
|
db6389 |
+AC_SUBST(PAM_LIBS)
|
|
|
db6389 |
+AC_SUBST(PAM_MAN)
|
|
|
db6389 |
+AC_SUBST(NON_PAM_MAN)
|
|
|
db6389 |
+])dnl
|
|
|
db6389 |
diff --git a/src/clients/ksu/Makefile.in b/src/clients/ksu/Makefile.in
|
|
|
db6389 |
index b2fcbf240..5755bb58a 100644
|
|
|
db6389 |
--- a/src/clients/ksu/Makefile.in
|
|
|
db6389 |
+++ b/src/clients/ksu/Makefile.in
|
|
|
db6389 |
@@ -3,12 +3,14 @@ BUILDTOP=$(REL)..$(S)..
|
|
|
db6389 |
DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
|
|
|
db6389 |
|
|
|
db6389 |
KSU_LIBS=@KSU_LIBS@
|
|
|
db6389 |
+PAM_LIBS=@PAM_LIBS@
|
|
|
db6389 |
|
|
|
db6389 |
SRCS = \
|
|
|
db6389 |
$(srcdir)/krb_auth_su.c \
|
|
|
db6389 |
$(srcdir)/ccache.c \
|
|
|
db6389 |
$(srcdir)/authorization.c \
|
|
|
db6389 |
$(srcdir)/main.c \
|
|
|
db6389 |
+ $(srcdir)/pam.c \
|
|
|
db6389 |
$(srcdir)/heuristic.c \
|
|
|
db6389 |
$(srcdir)/xmalloc.c \
|
|
|
db6389 |
$(srcdir)/setenv.c
|
|
|
db6389 |
@@ -17,13 +19,17 @@ OBJS = \
|
|
|
db6389 |
ccache.o \
|
|
|
db6389 |
authorization.o \
|
|
|
db6389 |
main.o \
|
|
|
db6389 |
+ pam.o \
|
|
|
db6389 |
heuristic.o \
|
|
|
db6389 |
xmalloc.o @SETENVOBJ@
|
|
|
db6389 |
|
|
|
db6389 |
all: ksu
|
|
|
db6389 |
|
|
|
db6389 |
ksu: $(OBJS) $(KRB5_BASE_DEPLIBS)
|
|
|
db6389 |
- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS)
|
|
|
db6389 |
+ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS)
|
|
|
db6389 |
+
|
|
|
db6389 |
+pam.o: pam.c
|
|
|
db6389 |
+ $(CC) $(ALL_CFLAGS) -c $<
|
|
|
db6389 |
|
|
|
db6389 |
clean:
|
|
|
db6389 |
$(RM) ksu
|
|
|
db6389 |
diff --git a/src/clients/ksu/main.c b/src/clients/ksu/main.c
|
|
|
db6389 |
index d9596d948..ec06788bc 100644
|
|
|
db6389 |
--- a/src/clients/ksu/main.c
|
|
|
db6389 |
+++ b/src/clients/ksu/main.c
|
|
|
db6389 |
@@ -26,6 +26,7 @@
|
|
|
db6389 |
* KSU was writen by: Ari Medvinsky, ari@isi.edu
|
|
|
db6389 |
*/
|
|
|
db6389 |
|
|
|
db6389 |
+#include "autoconf.h"
|
|
|
db6389 |
#include "ksu.h"
|
|
|
db6389 |
#include "adm_proto.h"
|
|
|
db6389 |
#include <sys/types.h>
|
|
|
db6389 |
@@ -33,6 +34,10 @@
|
|
|
db6389 |
#include <signal.h>
|
|
|
db6389 |
#include <grp.h>
|
|
|
db6389 |
|
|
|
db6389 |
+#ifdef USE_PAM
|
|
|
db6389 |
+#include "pam.h"
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+
|
|
|
db6389 |
/* globals */
|
|
|
db6389 |
char * prog_name;
|
|
|
db6389 |
int auth_debug =0;
|
|
|
db6389 |
@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN];
|
|
|
db6389 |
char k5users_path[MAXPATHLEN];
|
|
|
db6389 |
char * gb_err = NULL;
|
|
|
db6389 |
int quiet = 0;
|
|
|
db6389 |
+int force_fork = 0;
|
|
|
db6389 |
/***********/
|
|
|
db6389 |
|
|
|
db6389 |
#define KS_TEMPORARY_CACHE "MEMORY:_ksu"
|
|
|
db6389 |
@@ -528,6 +534,23 @@ main (argc, argv)
|
|
|
db6389 |
prog_name,target_user,client_name,
|
|
|
db6389 |
source_user,ontty());
|
|
|
db6389 |
|
|
|
db6389 |
+#ifdef USE_PAM
|
|
|
db6389 |
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
|
|
db6389 |
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
|
|
|
db6389 |
+ NULL, source_user,
|
|
|
db6389 |
+ ttyname(STDERR_FILENO)) != 0) {
|
|
|
db6389 |
+ fprintf(stderr, "Access denied for %s.\n", target_user);
|
|
|
db6389 |
+ exit(1);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if (appl_pam_requires_chauthtok()) {
|
|
|
db6389 |
+ fprintf(stderr, "Password change required for %s.\n",
|
|
|
db6389 |
+ target_user);
|
|
|
db6389 |
+ exit(1);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ force_fork++;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+
|
|
|
db6389 |
/* Run authorization as target.*/
|
|
|
db6389 |
if (krb5_seteuid(target_uid)) {
|
|
|
db6389 |
com_err(prog_name, errno, _("while switching to target for "
|
|
|
db6389 |
@@ -588,6 +611,24 @@ main (argc, argv)
|
|
|
db6389 |
|
|
|
db6389 |
exit(1);
|
|
|
db6389 |
}
|
|
|
db6389 |
+#ifdef USE_PAM
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ /* we always do PAM account management, even for root */
|
|
|
db6389 |
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
|
|
db6389 |
+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
|
|
|
db6389 |
+ NULL, source_user,
|
|
|
db6389 |
+ ttyname(STDERR_FILENO)) != 0) {
|
|
|
db6389 |
+ fprintf(stderr, "Access denied for %s.\n", target_user);
|
|
|
db6389 |
+ exit(1);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if (appl_pam_requires_chauthtok()) {
|
|
|
db6389 |
+ fprintf(stderr, "Password change required for %s.\n",
|
|
|
db6389 |
+ target_user);
|
|
|
db6389 |
+ exit(1);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ force_fork++;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
}
|
|
|
db6389 |
|
|
|
db6389 |
if( some_rest_copy){
|
|
|
db6389 |
@@ -645,6 +686,30 @@ main (argc, argv)
|
|
|
db6389 |
exit(1);
|
|
|
db6389 |
}
|
|
|
db6389 |
|
|
|
db6389 |
+#ifdef USE_PAM
|
|
|
db6389 |
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
|
|
db6389 |
+ if (appl_pam_session_open() != 0) {
|
|
|
db6389 |
+ fprintf(stderr, "Error opening session for %s.\n", target_user);
|
|
|
db6389 |
+ exit(1);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ if (auth_debug){
|
|
|
db6389 |
+ printf(" Opened PAM session.\n");
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ if (appl_pam_cred_init()) {
|
|
|
db6389 |
+ fprintf(stderr, "Error initializing credentials for %s.\n",
|
|
|
db6389 |
+ target_user);
|
|
|
db6389 |
+ exit(1);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ if (auth_debug){
|
|
|
db6389 |
+ printf(" Initialized PAM credentials.\n");
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+
|
|
|
db6389 |
/* set permissions */
|
|
|
db6389 |
if (setgid(target_pwd->pw_gid) < 0) {
|
|
|
db6389 |
perror("ksu: setgid");
|
|
|
db6389 |
@@ -742,7 +807,7 @@ main (argc, argv)
|
|
|
db6389 |
fprintf(stderr, "program to be execed %s\n",params[0]);
|
|
|
db6389 |
}
|
|
|
db6389 |
|
|
|
db6389 |
- if( keep_target_cache ) {
|
|
|
db6389 |
+ if( keep_target_cache && !force_fork ) {
|
|
|
db6389 |
execv(params[0], params);
|
|
|
db6389 |
com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
|
|
|
db6389 |
sweep_up(ksu_context, cc_target);
|
|
|
db6389 |
@@ -772,16 +837,35 @@ main (argc, argv)
|
|
|
db6389 |
if (ret_pid == -1) {
|
|
|
db6389 |
com_err(prog_name, errno, _("while calling waitpid"));
|
|
|
db6389 |
}
|
|
|
db6389 |
- sweep_up(ksu_context, cc_target);
|
|
|
db6389 |
+ if( !keep_target_cache ) {
|
|
|
db6389 |
+ sweep_up(ksu_context, cc_target);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
exit (statusp);
|
|
|
db6389 |
case -1:
|
|
|
db6389 |
com_err(prog_name, errno, _("while trying to fork."));
|
|
|
db6389 |
sweep_up(ksu_context, cc_target);
|
|
|
db6389 |
exit (1);
|
|
|
db6389 |
case 0:
|
|
|
db6389 |
+#ifdef USE_PAM
|
|
|
db6389 |
+ if (appl_pam_enabled(ksu_context, "ksu")) {
|
|
|
db6389 |
+ if (appl_pam_setenv() != 0) {
|
|
|
db6389 |
+ fprintf(stderr, "Error setting up environment for %s.\n",
|
|
|
db6389 |
+ target_user);
|
|
|
db6389 |
+ exit (1);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ if (auth_debug){
|
|
|
db6389 |
+ printf(" Set up PAM environment.\n");
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
execv(params[0], params);
|
|
|
db6389 |
com_err(prog_name, errno, _("while trying to execv %s"),
|
|
|
db6389 |
params[0]);
|
|
|
db6389 |
+ if( keep_target_cache ) {
|
|
|
db6389 |
+ sweep_up(ksu_context, cc_target);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
exit (1);
|
|
|
db6389 |
}
|
|
|
db6389 |
}
|
|
|
db6389 |
diff --git a/src/clients/ksu/pam.c b/src/clients/ksu/pam.c
|
|
|
db6389 |
new file mode 100644
|
|
|
db6389 |
index 000000000..cbfe48704
|
|
|
db6389 |
--- /dev/null
|
|
|
db6389 |
+++ b/src/clients/ksu/pam.c
|
|
|
db6389 |
@@ -0,0 +1,389 @@
|
|
|
db6389 |
+/*
|
|
|
db6389 |
+ * src/clients/ksu/pam.c
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Copyright 2007,2009,2010 Red Hat, Inc.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * All Rights Reserved.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Redistribution and use in source and binary forms, with or without
|
|
|
db6389 |
+ * modification, are permitted provided that the following conditions are met:
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Redistributions of source code must retain the above copyright notice, this
|
|
|
db6389 |
+ * list of conditions and the following disclaimer.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
db6389 |
+ * this list of conditions and the following disclaimer in the documentation
|
|
|
db6389 |
+ * and/or other materials provided with the distribution.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
|
|
|
db6389 |
+ * used to endorse or promote products derived from this software without
|
|
|
db6389 |
+ * specific prior written permission.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
db6389 |
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
db6389 |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
db6389 |
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
db6389 |
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
db6389 |
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
db6389 |
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
db6389 |
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
db6389 |
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
db6389 |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
db6389 |
+ * POSSIBILITY OF SUCH DAMAGE.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Convenience wrappers for using PAM.
|
|
|
db6389 |
+ */
|
|
|
db6389 |
+
|
|
|
db6389 |
+#include "autoconf.h"
|
|
|
db6389 |
+#ifdef USE_PAM
|
|
|
db6389 |
+#include <sys/types.h>
|
|
|
db6389 |
+#include <stdio.h>
|
|
|
db6389 |
+#include <stdlib.h>
|
|
|
db6389 |
+#include <string.h>
|
|
|
db6389 |
+#include <unistd.h>
|
|
|
db6389 |
+#include "k5-int.h"
|
|
|
db6389 |
+#include "pam.h"
|
|
|
db6389 |
+
|
|
|
db6389 |
+#ifndef MAXPWSIZE
|
|
|
db6389 |
+#define MAXPWSIZE 128
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+
|
|
|
db6389 |
+static int appl_pam_started;
|
|
|
db6389 |
+static pid_t appl_pam_starter = -1;
|
|
|
db6389 |
+static int appl_pam_session_opened;
|
|
|
db6389 |
+static int appl_pam_creds_initialized;
|
|
|
db6389 |
+static int appl_pam_pwchange_required;
|
|
|
db6389 |
+static pam_handle_t *appl_pamh;
|
|
|
db6389 |
+static struct pam_conv appl_pam_conv;
|
|
|
db6389 |
+static char *appl_pam_user;
|
|
|
db6389 |
+struct appl_pam_non_interactive_args {
|
|
|
db6389 |
+ const char *user;
|
|
|
db6389 |
+ const char *password;
|
|
|
db6389 |
+};
|
|
|
db6389 |
+
|
|
|
db6389 |
+int
|
|
|
db6389 |
+appl_pam_enabled(krb5_context context, const char *section)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ int enabled = 1;
|
|
|
db6389 |
+ if ((context != NULL) && (context->profile != NULL)) {
|
|
|
db6389 |
+ if (profile_get_boolean(context->profile,
|
|
|
db6389 |
+ section,
|
|
|
db6389 |
+ USE_PAM_CONFIGURATION_KEYWORD,
|
|
|
db6389 |
+ NULL,
|
|
|
db6389 |
+ enabled, &enabled) != 0) {
|
|
|
db6389 |
+ enabled = 1;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ return enabled;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+
|
|
|
db6389 |
+void
|
|
|
db6389 |
+appl_pam_cleanup(void)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ if (getpid() != appl_pam_starter) {
|
|
|
db6389 |
+ return;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Called to clean up PAM.\n");
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ if (appl_pam_creds_initialized) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Deleting PAM credentials.\n");
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ pam_setcred(appl_pamh, PAM_DELETE_CRED);
|
|
|
db6389 |
+ appl_pam_creds_initialized = 0;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if (appl_pam_session_opened) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Closing PAM session.\n");
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ pam_close_session(appl_pamh, 0);
|
|
|
db6389 |
+ appl_pam_session_opened = 0;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ appl_pam_pwchange_required = 0;
|
|
|
db6389 |
+ if (appl_pam_started) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Shutting down PAM.\n");
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ pam_end(appl_pamh, 0);
|
|
|
db6389 |
+ appl_pam_started = 0;
|
|
|
db6389 |
+ appl_pam_starter = -1;
|
|
|
db6389 |
+ free(appl_pam_user);
|
|
|
db6389 |
+ appl_pam_user = NULL;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+}
|
|
|
db6389 |
+static int
|
|
|
db6389 |
+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
|
|
|
db6389 |
+ struct pam_response **presp, void *appdata_ptr)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ const struct pam_message *message;
|
|
|
db6389 |
+ struct pam_response *resp;
|
|
|
db6389 |
+ int i, code;
|
|
|
db6389 |
+ char *pwstring, pwbuf[MAXPWSIZE];
|
|
|
db6389 |
+ unsigned int pwsize;
|
|
|
db6389 |
+ resp = malloc(sizeof(struct pam_response) * num_msg);
|
|
|
db6389 |
+ if (resp == NULL) {
|
|
|
db6389 |
+ return PAM_BUF_ERR;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
|
|
|
db6389 |
+ code = PAM_SUCCESS;
|
|
|
db6389 |
+ for (i = 0; i < num_msg; i++) {
|
|
|
db6389 |
+ message = &(msg[0][i]); /* XXX */
|
|
|
db6389 |
+ message = msg[i]; /* XXX */
|
|
|
db6389 |
+ pwstring = NULL;
|
|
|
db6389 |
+ switch (message->msg_style) {
|
|
|
db6389 |
+ case PAM_TEXT_INFO:
|
|
|
db6389 |
+ case PAM_ERROR_MSG:
|
|
|
db6389 |
+ printf("[%s]\n", message->msg ? message->msg : "");
|
|
|
db6389 |
+ fflush(stdout);
|
|
|
db6389 |
+ resp[i].resp = NULL;
|
|
|
db6389 |
+ resp[i].resp_retcode = PAM_SUCCESS;
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ case PAM_PROMPT_ECHO_ON:
|
|
|
db6389 |
+ case PAM_PROMPT_ECHO_OFF:
|
|
|
db6389 |
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
|
|
|
db6389 |
+ if (fgets(pwbuf, sizeof(pwbuf),
|
|
|
db6389 |
+ stdin) != NULL) {
|
|
|
db6389 |
+ pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
|
|
|
db6389 |
+ pwstring = pwbuf;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ pwstring = getpass(message->msg ?
|
|
|
db6389 |
+ message->msg :
|
|
|
db6389 |
+ "");
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
|
|
|
db6389 |
+ pwsize = strlen(pwstring);
|
|
|
db6389 |
+ resp[i].resp = malloc(pwsize + 1);
|
|
|
db6389 |
+ if (resp[i].resp == NULL) {
|
|
|
db6389 |
+ resp[i].resp_retcode = PAM_BUF_ERR;
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ memcpy(resp[i].resp, pwstring, pwsize);
|
|
|
db6389 |
+ resp[i].resp[pwsize] = '\0';
|
|
|
db6389 |
+ resp[i].resp_retcode = PAM_SUCCESS;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ resp[i].resp_retcode = PAM_CONV_ERR;
|
|
|
db6389 |
+ code = PAM_CONV_ERR;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ default:
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ *presp = resp;
|
|
|
db6389 |
+ return code;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+static int
|
|
|
db6389 |
+appl_pam_non_interactive_converse(int num_msg,
|
|
|
db6389 |
+ const struct pam_message **msg,
|
|
|
db6389 |
+ struct pam_response **presp,
|
|
|
db6389 |
+ void *appdata_ptr)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ const struct pam_message *message;
|
|
|
db6389 |
+ struct pam_response *resp;
|
|
|
db6389 |
+ int i, code;
|
|
|
db6389 |
+ unsigned int pwsize;
|
|
|
db6389 |
+ struct appl_pam_non_interactive_args *args;
|
|
|
db6389 |
+ const char *pwstring;
|
|
|
db6389 |
+ resp = malloc(sizeof(struct pam_response) * num_msg);
|
|
|
db6389 |
+ if (resp == NULL) {
|
|
|
db6389 |
+ return PAM_BUF_ERR;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ args = appdata_ptr;
|
|
|
db6389 |
+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
|
|
|
db6389 |
+ code = PAM_SUCCESS;
|
|
|
db6389 |
+ for (i = 0; i < num_msg; i++) {
|
|
|
db6389 |
+ message = &((*msg)[i]);
|
|
|
db6389 |
+ message = msg[i];
|
|
|
db6389 |
+ pwstring = NULL;
|
|
|
db6389 |
+ switch (message->msg_style) {
|
|
|
db6389 |
+ case PAM_TEXT_INFO:
|
|
|
db6389 |
+ case PAM_ERROR_MSG:
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ case PAM_PROMPT_ECHO_ON:
|
|
|
db6389 |
+ case PAM_PROMPT_ECHO_OFF:
|
|
|
db6389 |
+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
|
|
|
db6389 |
+ /* assume "user" */
|
|
|
db6389 |
+ pwstring = args->user;
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ /* assume "password" */
|
|
|
db6389 |
+ pwstring = args->password;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
|
|
|
db6389 |
+ pwsize = strlen(pwstring);
|
|
|
db6389 |
+ resp[i].resp = malloc(pwsize + 1);
|
|
|
db6389 |
+ if (resp[i].resp == NULL) {
|
|
|
db6389 |
+ resp[i].resp_retcode = PAM_BUF_ERR;
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ memcpy(resp[i].resp, pwstring, pwsize);
|
|
|
db6389 |
+ resp[i].resp[pwsize] = '\0';
|
|
|
db6389 |
+ resp[i].resp_retcode = PAM_SUCCESS;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ resp[i].resp_retcode = PAM_CONV_ERR;
|
|
|
db6389 |
+ code = PAM_CONV_ERR;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ default:
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ *presp = resp;
|
|
|
db6389 |
+ return code;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+static int
|
|
|
db6389 |
+appl_pam_start(const char *service, int interactive,
|
|
|
db6389 |
+ const char *login_username,
|
|
|
db6389 |
+ const char *non_interactive_password,
|
|
|
db6389 |
+ const char *hostname,
|
|
|
db6389 |
+ const char *ruser,
|
|
|
db6389 |
+ const char *tty)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ static int exit_handler_registered;
|
|
|
db6389 |
+ static struct appl_pam_non_interactive_args args;
|
|
|
db6389 |
+ int ret = 0;
|
|
|
db6389 |
+ if (appl_pam_started &&
|
|
|
db6389 |
+ (strcmp(login_username, appl_pam_user) != 0)) {
|
|
|
db6389 |
+ appl_pam_cleanup();
|
|
|
db6389 |
+ appl_pam_user = NULL;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if (!appl_pam_started) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
|
|
|
db6389 |
+ service, login_username);
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
|
|
|
db6389 |
+ appl_pam_conv.conv = interactive ?
|
|
|
db6389 |
+ &appl_pam_interactive_converse :
|
|
|
db6389 |
+ &appl_pam_non_interactive_converse;
|
|
|
db6389 |
+ memset(&args, 0, sizeof(args));
|
|
|
db6389 |
+ args.user = strdup(login_username);
|
|
|
db6389 |
+ args.password = non_interactive_password ?
|
|
|
db6389 |
+ strdup(non_interactive_password) :
|
|
|
db6389 |
+ NULL;
|
|
|
db6389 |
+ appl_pam_conv.appdata_ptr = &arg;;
|
|
|
db6389 |
+ ret = pam_start(service, login_username,
|
|
|
db6389 |
+ &appl_pam_conv, &appl_pamh);
|
|
|
db6389 |
+ if (ret == 0) {
|
|
|
db6389 |
+ if (hostname != NULL) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Setting PAM_RHOST to \"%s\".\n", hostname);
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ pam_set_item(appl_pamh, PAM_RHOST, hostname);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if (ruser != NULL) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Setting PAM_RUSER to \"%s\".\n", ruser);
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ pam_set_item(appl_pamh, PAM_RUSER, ruser);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if (tty != NULL) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Setting PAM_TTY to \"%s\".\n", tty);
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ pam_set_item(appl_pamh, PAM_TTY, tty);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ if (!exit_handler_registered &&
|
|
|
db6389 |
+ (atexit(appl_pam_cleanup) != 0)) {
|
|
|
db6389 |
+ pam_end(appl_pamh, 0);
|
|
|
db6389 |
+ appl_pamh = NULL;
|
|
|
db6389 |
+ ret = -1;
|
|
|
db6389 |
+ } else {
|
|
|
db6389 |
+ appl_pam_started = 1;
|
|
|
db6389 |
+ appl_pam_starter = getpid();
|
|
|
db6389 |
+ appl_pam_user = strdup(login_username);
|
|
|
db6389 |
+ exit_handler_registered = 1;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ return ret;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+int
|
|
|
db6389 |
+appl_pam_acct_mgmt(const char *service, int interactive,
|
|
|
db6389 |
+ const char *login_username,
|
|
|
db6389 |
+ const char *non_interactive_password,
|
|
|
db6389 |
+ const char *hostname,
|
|
|
db6389 |
+ const char *ruser,
|
|
|
db6389 |
+ const char *tty)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ int ret;
|
|
|
db6389 |
+ appl_pam_pwchange_required = 0;
|
|
|
db6389 |
+ ret = appl_pam_start(service, interactive, login_username,
|
|
|
db6389 |
+ non_interactive_password, hostname, ruser, tty);
|
|
|
db6389 |
+ if (ret == 0) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Calling pam_acct_mgmt().\n");
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ ret = pam_acct_mgmt(appl_pamh, 0);
|
|
|
db6389 |
+ switch (ret) {
|
|
|
db6389 |
+ case PAM_IGNORE:
|
|
|
db6389 |
+ ret = 0;
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ case PAM_NEW_AUTHTOK_REQD:
|
|
|
db6389 |
+ appl_pam_pwchange_required = 1;
|
|
|
db6389 |
+ ret = 0;
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ default:
|
|
|
db6389 |
+ break;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ return ret;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+int
|
|
|
db6389 |
+appl_pam_requires_chauthtok(void)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ return appl_pam_pwchange_required;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+int
|
|
|
db6389 |
+appl_pam_session_open(void)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ int ret = 0;
|
|
|
db6389 |
+ if (appl_pam_started) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Opening PAM session.\n");
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ ret = pam_open_session(appl_pamh, 0);
|
|
|
db6389 |
+ if (ret == 0) {
|
|
|
db6389 |
+ appl_pam_session_opened = 1;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ return ret;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+int
|
|
|
db6389 |
+appl_pam_setenv(void)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ int ret = 0;
|
|
|
db6389 |
+#ifdef HAVE_PAM_GETENVLIST
|
|
|
db6389 |
+#ifdef HAVE_PUTENV
|
|
|
db6389 |
+ int i;
|
|
|
db6389 |
+ char **list;
|
|
|
db6389 |
+ if (appl_pam_started) {
|
|
|
db6389 |
+ list = pam_getenvlist(appl_pamh);
|
|
|
db6389 |
+ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Setting \"%s\" in environment.\n", list[i]);
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ putenv(list[i]);
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ return ret;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+int
|
|
|
db6389 |
+appl_pam_cred_init(void)
|
|
|
db6389 |
+{
|
|
|
db6389 |
+ int ret = 0;
|
|
|
db6389 |
+ if (appl_pam_started) {
|
|
|
db6389 |
+#ifdef DEBUG
|
|
|
db6389 |
+ printf("Initializing PAM credentials.\n");
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
|
|
|
db6389 |
+ if (ret == 0) {
|
|
|
db6389 |
+ appl_pam_creds_initialized = 1;
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ }
|
|
|
db6389 |
+ return ret;
|
|
|
db6389 |
+}
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
diff --git a/src/clients/ksu/pam.h b/src/clients/ksu/pam.h
|
|
|
db6389 |
new file mode 100644
|
|
|
db6389 |
index 000000000..0ab76569c
|
|
|
db6389 |
--- /dev/null
|
|
|
db6389 |
+++ b/src/clients/ksu/pam.h
|
|
|
db6389 |
@@ -0,0 +1,57 @@
|
|
|
db6389 |
+/*
|
|
|
db6389 |
+ * src/clients/ksu/pam.h
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Copyright 2007,2009,2010 Red Hat, Inc.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * All Rights Reserved.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Redistribution and use in source and binary forms, with or without
|
|
|
db6389 |
+ * modification, are permitted provided that the following conditions are met:
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Redistributions of source code must retain the above copyright notice, this
|
|
|
db6389 |
+ * list of conditions and the following disclaimer.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Redistributions in binary form must reproduce the above copyright notice,
|
|
|
db6389 |
+ * this list of conditions and the following disclaimer in the documentation
|
|
|
db6389 |
+ * and/or other materials provided with the distribution.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
|
|
|
db6389 |
+ * used to endorse or promote products derived from this software without
|
|
|
db6389 |
+ * specific prior written permission.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
db6389 |
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
db6389 |
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
db6389 |
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
|
db6389 |
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
db6389 |
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
db6389 |
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
db6389 |
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
db6389 |
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
db6389 |
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
db6389 |
+ * POSSIBILITY OF SUCH DAMAGE.
|
|
|
db6389 |
+ *
|
|
|
db6389 |
+ * Convenience wrappers for using PAM.
|
|
|
db6389 |
+ */
|
|
|
db6389 |
+
|
|
|
db6389 |
+#include <krb5.h>
|
|
|
db6389 |
+#ifdef HAVE_SECURITY_PAM_APPL_H
|
|
|
db6389 |
+#include <security/pam_appl.h>
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
+
|
|
|
db6389 |
+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
|
|
|
db6389 |
+
|
|
|
db6389 |
+#ifdef USE_PAM
|
|
|
db6389 |
+int appl_pam_enabled(krb5_context context, const char *section);
|
|
|
db6389 |
+int appl_pam_acct_mgmt(const char *service, int interactive,
|
|
|
db6389 |
+ const char *local_username,
|
|
|
db6389 |
+ const char *non_interactive_password,
|
|
|
db6389 |
+ const char *hostname,
|
|
|
db6389 |
+ const char *ruser,
|
|
|
db6389 |
+ const char *tty);
|
|
|
db6389 |
+int appl_pam_requires_chauthtok(void);
|
|
|
db6389 |
+int appl_pam_session_open(void);
|
|
|
db6389 |
+int appl_pam_setenv(void);
|
|
|
db6389 |
+int appl_pam_cred_init(void);
|
|
|
db6389 |
+void appl_pam_cleanup(void);
|
|
|
db6389 |
+#endif
|
|
|
db6389 |
diff --git a/src/configure.in b/src/configure.in
|
|
|
db6389 |
index 61ef738dc..e9a12ac16 100644
|
|
|
db6389 |
--- a/src/configure.in
|
|
|
db6389 |
+++ b/src/configure.in
|
|
|
db6389 |
@@ -1352,6 +1352,8 @@ AC_SUBST([VERTO_VERSION])
|
|
|
db6389 |
|
|
|
db6389 |
AC_PATH_PROG(GROFF, groff)
|
|
|
db6389 |
|
|
|
db6389 |
+KRB5_WITH_PAM
|
|
|
db6389 |
+
|
|
|
db6389 |
# Make localedir work in autoconf 2.5x.
|
|
|
db6389 |
if test "${localedir+set}" != set; then
|
|
|
db6389 |
localedir='$(datadir)/locale'
|