name = krb5
version = %{version_maj}.%{version_min}
-version_maj= 1.10
-version_min= 3
+version_maj= 1.14
+version_min= 4
release = 1
groups = System/Libraries
practice of sending passwords over the network in unencrypted form.
end
-# Upstream only provides a "signed" tarball which contains the actual
-# tar archive.
-#source_dl = http://we1b.mit.edu/kerberos/dist/krb5/%{version_maj}/
-#sources = %{thisapp}-signed.tar
-
-patches
- krb5-1.10.2-pam.patch
- krb5-1.10.2-manpaths.patch
- krb5-1.10.2-selinux-label.patch
- krb5-1.3.1-dns.patch
- krb5-1.3.4-send-pr-tempfile.patch
- krb5-1.7-ktany.patch
- krb5-1.8-api.patch
- krb5-1.9-debuginfo.patch0
- krb5-1.9-dirsrv-accountlock.patch
- krb5-1.10-buildconf.patch
- krb5-1.10-doublelog.patch
- krb5-1.10-gcc47.patch0
- krb5-1.10-kpasswd_tcp.patch
- krb5-1.10-kprop-mktemp.patch
- krb5-1.10-ksu-access.patch
- krb5-1.10-ksu-path.patch
- krb5-1.10.2-keytab-etype.patch
- krb5-kvno-230379.patch
- krb5-tex-pdf.sh
- krb5-trunk-7046.patch
- krb5-trunk-7047.patch
- krb5-trunk-7048.patch
- krb5-trunk-pkinit-anchorsign.patch
-end
+source_dl = http://web.mit.edu/kerberos/dist/krb5/%{version_maj}/
build
requires
texinfo
end
- prepare_cmds
- pushd src
- for file in appl/sample/sserver/sserver.M \
- config-files/kdc.conf.M \
- config-files/krb5.conf.M \
- gen-manpages/kerberos.M \
- kadmin/cli/kadmin.M \
- slave/kpropd.M \
- slave/kprop.M; do
- mv -v ${file} ${file}.in
- done
-
- rm -vf lib/krb5/krb/deltat.c
-
- # Regenerate configure scripts.
- autoheader
- autoconf
- popd
- end
-
configure_options += \
--enable-shared \
--disable-rpath \
make %{PARALLELISMFLAGS}
end
- test
- make -C src fake-install
- tmpdir=$(mktemp -d)
-
- # Disable the following tests, because the don't work in the chroot env.
- #make -C src/lib check TMPDIR=${tmpdir}
- #make -C src/kdc check TMPDIR=${tmpdir}
- end
-
install
# Install krb5.
make -C src install DESTDIR=%{BUILDROOT}
+++ /dev/null
-Build binaries in this package as RELRO PIEs, libraries as partial RELRO,
-and install shared libraries with the execute bit set on them. Prune out
-the -L/usr/lib* and PIE flags where they might leak out and affect
-apps which just want to link with the libraries. FIXME: needs to check and
-not just assume that the compiler supports using these flags.
-
---- krb5/src/config/shlib.conf
-+++ krb5/src/config/shlib.conf
-@@ -419,7 +419,7 @@ mips-*-netbsd*)
- SHLIBEXT=.so
- # Linux ld doesn't default to stuffing the SONAME field...
- # Use objdump -x to examine the fields of the library
-- LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined'
-+ LDCOMBINE='$(CC) -shared -fPIC -Wl,-h,$(LIBPREFIX)$(LIBBASE)$(SHLIBSEXT),--no-undefined -Wl,-z,relro'
- #
- LDCOMBINE_TAIL='-Wl,--version-script binutils.versions && $(PERL) -w $(top_srcdir)/util/export-check.pl $(SHLIB_EXPORT_FILE) $@'
- SHLIB_EXPORT_FILE_DEP=binutils.versions
-@@ -430,7 +430,8 @@
- SHLIB_EXPFLAGS='$(SHLIB_RPATH_FLAGS) $(SHLIB_DIRS) $(SHLIB_EXPLIBS)'
- PROFFLAGS=-pg
- PROG_RPATH_FLAGS='$(RPATH_FLAG)$(PROG_RPATH)'
-- CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) $(LDFLAGS)'
-+ CC_LINK_SHARED='$(CC) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CFLAGS) -pie -Wl,-z,relro -Wl,-z,now $(LDFLAGS)'
-+ INSTALL_SHLIB='${INSTALL} -m755'
- CC_LINK_STATIC='$(CC) $(PROG_LIBPATH) $(CFLAGS) $(LDFLAGS)'
- CXX_LINK_SHARED='$(CXX) $(PROG_LIBPATH) $(PROG_RPATH_FLAGS) $(CXXFLAGS) $(LDFLAGS)'
- CXX_LINK_STATIC='$(CXX) $(PROG_LIBPATH) $(CXXFLAGS) $(LDFLAGS)'
---- krb5/src/krb5-config.in
-+++ krb5/src/krb5-config.in
-@@ -189,6 +189,13 @@ if test -n "$do_libs"; then
- -e 's#\$(PTHREAD_CFLAGS)#'"$PTHREAD_CFLAGS"'#' \
- -e 's#\$(CFLAGS)##'`
-
-+ if test `dirname $libdir` = /usr ; then
-+ lib_flags=`echo $lib_flags | sed -e "s#-L$libdir##" -e "s#$RPATH_FLAG$libdir##"`
-+ fi
-+ lib_flags=`echo $lib_flags | sed -e "s#-fPIE##g" -e "s#-pie##g"`
-+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,relro##g"`
-+ lib_flags=`echo $lib_flags | sed -e "s#-Wl,-z,now##g"`
-+
- if test $library = 'kdb'; then
- lib_flags="$lib_flags -lkdb5 $KDB5_DB_LIB"
- library=krb5
---- krb5/src/config/pre.in
-+++ krb5/src/config/pre.in
-@@ -188,7 +188,7 @@
- INSTALL_SCRIPT=@INSTALL_PROGRAM@
- INSTALL_DATA=@INSTALL_DATA@
- INSTALL_SHLIB=@INSTALL_SHLIB@
--INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755 -o root
-+INSTALL_SETUID=$(INSTALL) $(INSTALL_STRIP) -m 4755
- ## This is needed because autoconf will sometimes define @exec_prefix@ to be
- ## ${prefix}.
- prefix=@prefix@
+++ /dev/null
-Don't double-log (actually, don't process /etc/krb5.conf twice) just
-because we built with --sysconfdir=/etc. RT#3277
-
---- krb5/src/include/Makefile.in
-+++ krb5/src/include/Makefile.in
-@@ -67,6 +67,8 @@ PROCESS_REPLACE = -e "s+@KRB5RCTMPDIR+$(
- -e "s+@GSSMODULEDIR+$(GSS_MODULE_DIR)+" \
- -e 's+@LOCALSTATEDIR+$(LOCALSTATEDIR)+' \
- -e 's+@SYSCONFDIR+$(SYSCONFDIR)+' \
-+ -e 's+:/etc/krb5.conf:/etc/krb5.conf"+:/etc/krb5.conf"+' \
-+ -e 's+"/etc/krb5.conf:/etc/krb5.conf"+"/etc/krb5.conf"+' \
- -e 's+@DYNOBJEXT+$(DYNOBJEXT)+'
-
- OSCONFSRC = $(srcdir)/osconf.hin
+++ /dev/null
-This file also triggers the maybe-uninitialized warning/error. RT#7080
-
---- src/lib/krb5/krb/x-deltat.y
-+++ src/lib/krb5/krb/x-deltat.y
-@@ -44,6 +44,7 @@
- #ifdef __GNUC__
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wuninitialized"
-+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
- #endif
-
- #include <ctype.h>
+++ /dev/null
-Fall back to TCP on kdc-unresolvable/unreachable errors. We still have
-to wait for UDP to fail, so this might not be ideal. RT #5868.
-
---- krb5/src/lib/krb5/os/changepw.c
-+++ krb5/src/lib/krb5/os/changepw.c
-@@ -270,10 +270,22 @@ change_set_password(krb5_context context
- &callback_info, &chpw_rep, ss2sa(&remote_addr),
- &addrlen, NULL, NULL, NULL);
- if (code) {
-- /*
-- * Here we may want to switch to TCP on some errors.
-- * right?
-- */
-+ /* if we're not using a stream socket, and it's an error which
-+ * might reasonably be specific to a datagram "connection", try
-+ * again with a stream socket */
-+ if (!use_tcp) {
-+ switch (code) {
-+ case KRB5_KDC_UNREACH:
-+ case KRB5_REALM_CANT_RESOLVE:
-+ case KRB5KRB_ERR_RESPONSE_TOO_BIG:
-+ /* should we do this for more result codes than these? */
-+ k5_free_serverlist (&sl);
-+ use_tcp = 1;
-+ continue;
-+ default:
-+ break;
-+ }
-+ }
- break;
- }
-
+++ /dev/null
-Use an in-memory ccache to silence a compiler warning, for RT#6414.
-
---- krb5/src/slave/kprop.c
-+++ krb5/src/slave/kprop.c
-@@ -202,9 +202,8 @@ void PRS(argc, argv)
- void get_tickets(context)
- krb5_context context;
- {
-- char buf[BUFSIZ], *def_realm;
-+ char buf[] = "MEMORY:_kproptkt", *def_realm;
- krb5_error_code retval;
-- static char tkstring[] = "/tmp/kproptktXXXXXX";
- krb5_keytab keytab = NULL;
-
- /*
-@@ -229,11 +228,8 @@ void get_tickets(context)
- #endif
-
- /*
-- * Initialize cache file which we're going to be using
-+ * Initialize an in-memory cache for temporary use
- */
-- (void) mktemp(tkstring);
-- snprintf(buf, sizeof(buf), "FILE:%s", tkstring);
--
- retval = krb5_cc_resolve(context, buf, &ccache);
- if (retval) {
- com_err(progname, retval, _("while opening credential cache %s"), buf);
+++ /dev/null
-The idea is to not complain about problems in the default ticket file if we
-couldn't read it, because the client would be able to tell if it's there or
-not, and we're implicitly letting the client tell us where it is. Still needs
-work, I think.
-
---- krb5/src/clients/ksu/ccache.c
-+++ krb5/src/clients/ksu/ccache.c
-@@ -78,7 +78,7 @@ krb5_error_code krb5_ccache_copy (contex
- cc_def_name = krb5_cc_get_name(context, cc_def);
- cc_other_name = krb5_cc_get_name(context, *cc_other);
-
-- if ( ! stat(cc_def_name, &st_temp)){
-+ if ( ! access(cc_def_name, R_OK) && ! stat(cc_def_name, &st_temp)){
- if((retval = krb5_get_nonexp_tkts(context,cc_def,&cc_def_creds_arr))){
- return retval;
- }
---- krb5/src/clients/ksu/heuristic.c
-+++ krb5/src/clients/ksu/heuristic.c
-@@ -409,7 +409,7 @@ krb5_error_code find_either_ticket (cont
-
- cc_source_name = krb5_cc_get_name(context, cc);
-
-- if ( ! stat(cc_source_name, &st_temp)){
-+ if ( ! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)){
-
- retval = find_ticket(context, cc, client, end_server, &temp_found);
- if (retval)
-@@ -569,7 +569,7 @@ krb5_error_code get_best_princ_for_targe
- cc_source_name = krb5_cc_get_name(context, cc_source);
-
-
-- if (! stat(cc_source_name, &st_temp)) {
-+ if (! access(cc_source_name, F_OK | R_OK) && ! stat(cc_source_name, &st_temp)) {
- retval = krb5_cc_get_principal(context, cc_source, &cc_def_princ);
- if (retval)
- return retval;
---- krb5/src/clients/ksu/main.c
-+++ krb5/src/clients/ksu/main.c
-@@ -270,7 +270,7 @@ main (argc, argv)
- if ( strchr(cc_source_tag, ':')){
- cc_source_tag_tmp = strchr(cc_source_tag, ':') + 1;
-
-- if( stat( cc_source_tag_tmp, &st_temp)){
-+ if( access( cc_source_tag_tmp, F_OK | R_OK) || stat( cc_source_tag_tmp, &st_temp)){
- com_err(prog_name, errno,
- _("while looking for credentials file %s"),
- cc_source_tag_tmp);
+++ /dev/null
-Set the default PATH to the one set by login.
-
---- krb5/src/clients/ksu/Makefile.in
-+++ krb5/src/clients/ksu/Makefile.in
-@@ -1,6 +1,6 @@
- mydir=clients$(S)ksu
- BUILDTOP=$(REL)..$(S)..
--DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/bin /local/bin"'
-+DEFINES = -DGET_TGT_VIA_PASSWD -DPRINC_LOOK_AHEAD -DCMD_PATH='"/usr/local/sbin /usr/local/bin /sbin /bin /usr/sbin /usr/bin"'
- DEFS=
-
- PROG_LIBPATH=-L$(TOPLIBD)
+++ /dev/null
-(Had to drop the changes to src/tests/t_keytab.py, which didn't exist in 1.10.)
-
-commit d1da158f47ea604bed4d5db5e98a976a9e54ccd0
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Thu Apr 19 17:55:10 2012 +0000
-
- Unify krb5_get_init_creds_keytab code paths
-
- Use krb5_init_creds_set_keytab in krb5_get_init_creds_keytab, so that
- processing added to the former will be used by the latter. This is
- slightly awkward because of the way we do the use_master fallback, in
- that we have to duplicate some of krb5int_get_init_creds.
-
- Based on a patch from Stef Walter.
-
- git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25817 dc483132-0cff-0310-8789-dd5450dbe970
-
-diff --git a/src/lib/krb5/krb/deps b/src/lib/krb5/krb/deps
-index fe2d54c..8c4db77 100644
---- a/src/lib/krb5/krb/deps
-+++ b/src/lib/krb5/krb/deps
-@@ -473,7 +473,8 @@ gic_keytab.so gic_keytab.po $(OUTPRE)gic_keytab.$(OBJEXT): \
- $(top_srcdir)/include/k5-trace.h $(top_srcdir)/include/krb5.h \
- $(top_srcdir)/include/krb5/authdata_plugin.h $(top_srcdir)/include/krb5/plugin.h \
- $(top_srcdir)/include/krb5/preauth_plugin.h $(top_srcdir)/include/port-sockets.h \
-- $(top_srcdir)/include/socket-utils.h gic_keytab.c init_creds_ctx.h
-+ $(top_srcdir)/include/socket-utils.h gic_keytab.c init_creds_ctx.h \
-+ int-proto.h
- gic_opt.so gic_opt.po $(OUTPRE)gic_opt.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
- $(BUILDTOP)/include/krb5/krb5.h $(BUILDTOP)/include/osconf.h \
- $(BUILDTOP)/include/profile.h $(COM_ERR_DEPS) $(top_srcdir)/include/k5-buf.h \
-diff --git a/src/lib/krb5/krb/get_in_tkt.c b/src/lib/krb5/krb/get_in_tkt.c
-index aaabc4e..681b648 100644
---- a/src/lib/krb5/krb/get_in_tkt.c
-+++ b/src/lib/krb5/krb/get_in_tkt.c
-@@ -542,10 +542,9 @@ krb5_init_creds_free(krb5_context context,
- free(ctx);
- }
-
--static krb5_error_code
--init_creds_get(krb5_context context,
-- krb5_init_creds_context ctx,
-- int *use_master)
-+krb5_error_code
-+k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx,
-+ int *use_master)
- {
- krb5_error_code code;
- krb5_data request;
-@@ -599,7 +598,7 @@ krb5_init_creds_get(krb5_context context,
- {
- int use_master = 0;
-
-- return init_creds_get(context, ctx, &use_master);
-+ return k5_init_creds_get(context, ctx, &use_master);
- }
-
- krb5_error_code KRB5_CALLCONV
-@@ -1664,7 +1663,7 @@ krb5int_get_init_creds(krb5_context context,
- goto cleanup;
- }
-
-- code = init_creds_get(context, ctx, use_master);
-+ code = k5_init_creds_get(context, ctx, use_master);
- if (code != 0)
- goto cleanup;
-
-diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
-index 88de6a8..e59177f 100644
---- a/src/lib/krb5/krb/gic_keytab.c
-+++ b/src/lib/krb5/krb/gic_keytab.c
-@@ -26,6 +26,7 @@
- #ifndef LEAN_CLIENT
-
- #include "k5-int.h"
-+#include "int-proto.h"
- #include "init_creds_ctx.h"
-
- static krb5_error_code
-@@ -87,6 +88,44 @@ krb5_init_creds_set_keytab(krb5_context context,
- return 0;
- }
-
-+static krb5_error_code
-+get_init_creds_keytab(krb5_context context, krb5_creds *creds,
-+ krb5_principal client, krb5_keytab keytab,
-+ krb5_deltat start_time, char *in_tkt_service,
-+ krb5_get_init_creds_opt *options, int *use_master)
-+{
-+ krb5_error_code ret;
-+ krb5_init_creds_context ctx = NULL;
-+
-+ ret = krb5_init_creds_init(context, client, NULL, NULL, start_time,
-+ options, &ctx);
-+ if (ret != 0)
-+ goto cleanup;
-+
-+ if (in_tkt_service) {
-+ ret = krb5_init_creds_set_service(context, ctx, in_tkt_service);
-+ if (ret != 0)
-+ goto cleanup;
-+ }
-+
-+ ret = krb5_init_creds_set_keytab(context, ctx, keytab);
-+ if (ret != 0)
-+ goto cleanup;
-+
-+ ret = k5_init_creds_get(context, ctx, use_master);
-+ if (ret != 0)
-+ goto cleanup;
-+
-+ ret = krb5_init_creds_get_creds(context, ctx, creds);
-+ if (ret != 0)
-+ goto cleanup;
-+
-+cleanup:
-+ krb5_init_creds_free(context, ctx);
-+
-+ return ret;
-+}
-+
- krb5_error_code KRB5_CALLCONV
- krb5_get_init_creds_keytab(krb5_context context,
- krb5_creds *creds,
-@@ -111,10 +150,8 @@ krb5_get_init_creds_keytab(krb5_context context,
-
- /* first try: get the requested tkt from any kdc */
-
-- ret = krb5int_get_init_creds(context, creds, client, NULL, NULL,
-- start_time, in_tkt_service, options,
-- get_as_key_keytab, (void *) keytab,
-- &use_master,NULL);
-+ ret = get_init_creds_keytab(context, creds, client, keytab, start_time,
-+ in_tkt_service, options, &use_master);
-
- /* check for success */
-
-@@ -132,10 +169,9 @@ krb5_get_init_creds_keytab(krb5_context context,
- if (!use_master) {
- use_master = 1;
-
-- ret2 = krb5int_get_init_creds(context, creds, client, NULL, NULL,
-- start_time, in_tkt_service, options,
-- get_as_key_keytab, (void *) keytab,
-- &use_master, NULL);
-+ ret2 = get_init_creds_keytab(context, creds, client, keytab,
-+ start_time, in_tkt_service, options,
-+ &use_master);
-
- if (ret2 == 0) {
- ret = 0;
-diff --git a/src/lib/krb5/krb/int-proto.h b/src/lib/krb5/krb/int-proto.h
-index 6b16095..899579f 100644
---- a/src/lib/krb5/krb/int-proto.h
-+++ b/src/lib/krb5/krb/int-proto.h
-@@ -196,4 +196,8 @@ krb5int_mk_setpw_req(krb5_context context, krb5_auth_context auth_context,
- void
- k5_ccselect_free_context(krb5_context context);
-
-+krb5_error_code
-+k5_init_creds_get(krb5_context context, krb5_init_creds_context ctx,
-+ int *use_master);
-+
- #endif /* KRB5_INT_FUNC_PROTO__ */
-
-commit 8230c4b7b7323cdef2a6c877deb710a15380f40f
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Thu Apr 19 17:55:14 2012 +0000
-
- Use etypes from keytab in krb5_gic_keytab
-
- When getting initial credentials with a keytab, filter the list of
- request enctypes based on the keys in the keytab.
-
- Based on a patch from Stef Walter.
-
- ticket: 2131
-
- git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25818 dc483132-0cff-0310-8789-dd5450dbe970
-
-diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
-index 3749cf9..36eb23b 100644
---- a/src/include/k5-trace.h
-+++ b/src/include/k5-trace.h
-@@ -187,6 +187,10 @@
- #define TRACE_INIT_CREDS_GAK(c, salt, s2kparams) \
- TRACE(c, (c, "Getting AS key, salt \"{data}\", params \"{data}\"", \
- salt, s2kparams))
-+#define TRACE_INIT_CREDS_KEYTAB_LOOKUP(c, etypes) \
-+ TRACE(c, (c, "Looked up etypes in keytab: {etypes}", etypes))
-+#define TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(c, code) \
-+ TRACE(c, (c, "Couldn't lookup etypes in keytab: {kerr}", code))
- #define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code) \
- TRACE(c, (c, "Decrypt with preauth AS key failed: {kerr}", code))
- #define TRACE_INIT_CREDS_RESTART_FAST(c) \
-diff --git a/src/lib/krb5/krb/gic_keytab.c b/src/lib/krb5/krb/gic_keytab.c
-index e59177f..3554b25 100644
---- a/src/lib/krb5/krb/gic_keytab.c
-+++ b/src/lib/krb5/krb/gic_keytab.c
-@@ -77,14 +77,132 @@ get_as_key_keytab(krb5_context context,
- return(ret);
- }
-
-+/* Return the list of etypes available for client in keytab. */
-+static krb5_error_code
-+lookup_etypes_for_keytab(krb5_context context, krb5_keytab keytab,
-+ krb5_principal client, krb5_enctype **etypes_out)
-+{
-+ krb5_kt_cursor cursor;
-+ krb5_keytab_entry entry;
-+ krb5_enctype *p, *etypes = NULL;
-+ krb5_kvno max_kvno = 0;
-+ krb5_error_code ret;
-+ size_t count = 0;
-+
-+ *etypes_out = NULL;
-+
-+ if (keytab->ops->start_seq_get == NULL)
-+ return EINVAL;
-+ ret = krb5_kt_start_seq_get(context, keytab, &cursor);
-+ if (ret != 0)
-+ return ret;
-+
-+ for (;;) {
-+ ret = krb5_kt_next_entry(context, keytab, &entry, &cursor);
-+ if (ret == KRB5_KT_END)
-+ break;
-+ if (ret)
-+ goto cleanup;
-+
-+ if (!krb5_c_valid_enctype(entry.key.enctype))
-+ continue;
-+ if (!krb5_principal_compare(context, entry.principal, client))
-+ continue;
-+ /* Make sure our list is for the highest kvno found for client. */
-+ if (entry.vno > max_kvno) {
-+ free(etypes);
-+ etypes = NULL;
-+ count = 0;
-+ max_kvno = entry.vno;
-+ } else if (entry.vno != max_kvno)
-+ continue;
-+
-+ /* Leave room for the terminator and possibly a second entry. */
-+ p = realloc(etypes, (count + 3) * sizeof(*etypes));
-+ if (p == NULL) {
-+ ret = ENOMEM;
-+ goto cleanup;
-+ }
-+ etypes = p;
-+ etypes[count++] = entry.key.enctype;
-+ /* All DES key types work with des-cbc-crc, which is more likely to be
-+ * accepted by the KDC (since MIT KDCs refuse des-cbc-md5). */
-+ if (entry.key.enctype == ENCTYPE_DES_CBC_MD5 ||
-+ entry.key.enctype == ENCTYPE_DES_CBC_MD4)
-+ etypes[count++] = ENCTYPE_DES_CBC_CRC;
-+ etypes[count] = 0;
-+ }
-+
-+ ret = 0;
-+ *etypes_out = etypes;
-+ etypes = NULL;
-+cleanup:
-+ krb5_kt_end_seq_get(context, keytab, &cursor);
-+ free(etypes);
-+ return ret;
-+}
-+
-+/* Return true if search_for is in etype_list. */
-+static krb5_boolean
-+check_etypes_have(krb5_enctype *etype_list, krb5_enctype search_for)
-+{
-+ int i;
-+
-+ if (!etype_list)
-+ return FALSE;
-+
-+ for (i = 0; etype_list[i] != 0; i++) {
-+ if (etype_list[i] == search_for)
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
- krb5_error_code KRB5_CALLCONV
- krb5_init_creds_set_keytab(krb5_context context,
- krb5_init_creds_context ctx,
- krb5_keytab keytab)
- {
-+ krb5_enctype *etype_list;
-+ krb5_error_code ret;
-+ int i, j;
-+ char *name;
-+
- ctx->gak_fct = get_as_key_keytab;
- ctx->gak_data = keytab;
-
-+ ret = lookup_etypes_for_keytab(context, keytab, ctx->request->client,
-+ &etype_list);
-+ if (ret) {
-+ TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(context, ret);
-+ return 0;
-+ }
-+
-+ TRACE_INIT_CREDS_KEYTAB_LOOKUP(context, etype_list);
-+
-+ /* Filter the ktypes list based on what's in the keytab */
-+ for (i = 0, j = 0; i < ctx->request->nktypes; i++) {
-+ if (check_etypes_have(etype_list, ctx->request->ktype[i])) {
-+ ctx->request->ktype[j] = ctx->request->ktype[i];
-+ j++;
-+ }
-+ }
-+ ctx->request->nktypes = j;
-+ free(etype_list);
-+
-+ /* Error out now if there's no overlap. */
-+ if (ctx->request->nktypes == 0) {
-+ ret = krb5_unparse_name(context, ctx->request->client, &name);
-+ if (ret == 0) {
-+ krb5_set_error_message(context, KRB5_KT_NOTFOUND,
-+ _("Keytab contains no suitable keys for "
-+ "%s"), name);
-+ }
-+ krb5_free_unparsed_name(context, name);
-+ return KRB5_KT_NOTFOUND;
-+ }
-+
- return 0;
- }
-
+++ /dev/null
-Change the absolute paths included in the man pages so that the correct
-values can be dropped in by config.status. After applying this patch,
-these files should be renamed to their ".in" counterparts, and then the
-configure scripts should be rebuilt. Originally RT#6525
-
---- krb5/src/aclocal.m4
-+++ krb5/src/aclocal.m4
-@@ -1770,3 +1770,24 @@ AC_SUBST(PAM_LIBS)
- AC_SUBST(PAM_MAN)
- AC_SUBST(NON_PAM_MAN)
- ])dnl
-+AC_DEFUN(V5_AC_OUTPUT_MANPAGE,[
-+mansysconfdir=$sysconfdir
-+mansysconfdir=`eval echo $mansysconfdir | sed -e "s,NONE,$prefix,g"`
-+mansysconfdir=`eval echo $mansysconfdir | sed -e "s,NONE,$ac_default_prefix,g"`
-+mansbindir=$sbindir
-+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$exec_prefix,g"`
-+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$prefix,g"`
-+mansbindir=`eval echo $mansbindir | sed -e "s,NONE,$ac_default_prefix,g"`
-+manlocalstatedir=$localstatedir
-+manlocalstatedir=`eval echo $manlocalstatedir | sed -e "s,NONE,$prefix,g"`
-+manlocalstatedir=`eval echo $manlocalstatedir | sed -e "s,NONE,$ac_default_prefix,g"`
-+manlibexecdir=$libexecdir
-+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$exec_prefix,g"`
-+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$prefix,g"`
-+manlibexecdir=`eval echo $manlibexecdir | sed -e "s,NONE,$ac_default_prefix,g"`
-+AC_SUBST(mansysconfdir)
-+AC_SUBST(mansbindir)
-+AC_SUBST(manlocalstatedir)
-+AC_SUBST(manlibexecdir)
-+AC_CONFIG_FILES($1)
-+])
---- krb5/src/configure.in
-+++ krb5/src/configure.in
-@@ -1054,6 +1054,17 @@ fi
- AC_SUBST(localedir)
-
- AC_CONFIG_FILES(krb5-config, [chmod +x krb5-config])
-+
-+V5_AC_OUTPUT_MANPAGE([
-+ appl/sample/sserver/sserver.M
-+ config-files/kdc.conf.M
-+ config-files/krb5.conf.M
-+ gen-manpages/kerberos.M
-+ kadmin/cli/kadmin.M
-+ slave/kpropd.M
-+ slave/kprop.M
-+])
-+
- V5_AC_OUTPUT_MAKEFILE(.
-
- util util/support util/profile util/profile/testmod util/send-pr
---- krb5/src/appl/sample/sserver/sserver.M
-+++ krb5/src/appl/sample/sserver/sserver.M
-@@ -59,7 +59,7 @@ option allows for a different keytab tha
- using a line in
- /etc/inetd.conf that looks like this:
- .PP
--sample stream tcp nowait root /usr/local/sbin/sserver sserver
-+sample stream tcp nowait root @mansbindir@/sserver sserver
- .PP
- Since \fBsample\fP is normally not a port defined in /etc/services, you will
- usually have to add a line to /etc/services which looks like this:
---- krb5/src/config-files/kdc.conf.M
-+++ krb5/src/config-files/kdc.conf.M
-@@ -82,14 +82,14 @@ This
- .B string
- specifies the location of the access control list (acl) file that
- kadmin uses to determine which principals are allowed which permissions
--on the database. The default value is /usr/local/var/krb5kdc/kadm5.acl.
-+on the database. The default value is @manlocalstatedir@/krb5kdc/kadm5.acl.
-
- .IP admin_keytab
- This
- .B string
- Specifies the location of the keytab file that kadmin uses to
- authenticate to the database. The default value is
--/usr/local/var/krb5kdc/kadm5.keytab.
-+@manlocalstatedir@/krb5kdc/kadm5.keytab.
-
- .IP database_name
- This
-@@ -254,7 +254,7 @@ tickets should be checked against the tr
- realm names and the [capaths] section of its krb5.conf file
-
- .SH FILES
--/usr/local/var/krb5kdc/kdc.conf
-+@manlocalstatedir@/krb5kdc/kdc.conf
-
- .SH SEE ALSO
- krb5.conf(5), krb5kdc(8)
---- krb5/src/config-files/krb5.conf.M
-+++ krb5/src/config-files/krb5.conf.M
-@@ -808,6 +808,6 @@ is whitespace-separated. The LDAP server
- This module implements the encrypted timestamp mechanism.
-
- .SH FILES
--/etc/krb5.conf
-+@mansysconfdir@/krb5.conf
- .SH SEE ALSO
- syslog(3)
---- krb5/src/gen-manpages/kerberos.M
-+++ krb5/src/gen-manpages/kerberos.M
-@@ -126,7 +126,7 @@
- Specifies the location of the KDC configuration file, which contains
- additional configuration directives for the Key Distribution Center
- daemon and associated programs. The default is
--/usr/local/var/krb5kdc/kdc.conf.
-+@manlocalstatedir@/krb5kdc/kdc.conf.
- .TP
- .B KRB5RCACHETYPE
- Specifies the default type of replay cache to use for servers. Valid
---- krb5/src/kadmin/cli/kadmin.M
-+++ krb5/src/kadmin/cli/kadmin.M
-@@ -869,9 +869,9 @@ option is specified, less verbose status
- .RS
- .TP
- EXAMPLE:
--kadmin: ktremove -k /usr/local/var/krb5kdc/kadmind.keytab kadmin/admin
-+kadmin: ktremove -k @manlocalstatedir@/krb5kdc/kadmind.keytab kadmin/admin
- Entry for principal kadmin/admin with kvno 3 removed
-- from keytab WRFILE:/usr/local/var/krb5kdc/kadmind.keytab.
-+ from keytab WRFILE:@manlocalstatedir@/krb5kdc/kadmind.keytab.
- kadmin:
- .RE
- .fi
---- krb5/src/slave/kpropd.M
-+++ krb5/src/slave/kpropd.M
-@@ -74,7 +74,7 @@ Normally, kpropd is invoked out of
- This is done by adding a line to the inetd.conf file which looks like
- this:
-
--kprop stream tcp nowait root /usr/local/sbin/kpropd kpropd
-+kprop stream tcp nowait root @mansbindir@/kpropd kpropd
-
- However, kpropd can also run as a standalone daemon, if the
- .B \-S
-@@ -111,13 +111,13 @@ is used.
- \fB\-f\fP \fIfile\fP
- specifies the filename where the dumped principal database file is to be
- stored; by default the dumped database file is KPROPD_DEFAULT_FILE
--(normally /usr/local/var/krb5kdc/from_master).
-+(normally @manlocalstatedir@/krb5kdc/from_master).
- .TP
- .B \-p
- allows the user to specify the pathname to the
- .IR kdb5_util (8)
- program; by default the pathname used is KPROPD_DEFAULT_KDB5_UTIL
--(normally /usr/local/sbin/kdb5_util).
-+(normally @mansbindir@/kdb5_util).
- .TP
- .B \-S
- turn on standalone mode. Normally, kpropd is invoked out of
-@@ -148,14 +148,14 @@ mode.
- allows the user to specify the path to the
- kpropd.acl
- file; by default the path used is KPROPD_ACL_FILE
--(normally /usr/local/var/krb5kdc/kpropd.acl).
-+(normally @manlocalstatedir@/krb5kdc/kpropd.acl).
- .SH FILES
- .TP "\w'kpropd.acl\ \ 'u"
- kpropd.acl
- Access file for
- .BR kpropd ;
- the default location is KPROPD_ACL_FILE (normally
--/usr/local/var/krb5kdc/kpropd.acl).
-+@manlocalstatedir@/krb5kdc/kpropd.acl).
- Each entry is a line containing the principal of a host from which the
- local machine will allow Kerberos database propagation via kprop.
- .SH SEE ALSO
---- krb5/src/slave/kprop.M
-+++ krb5/src/slave/kprop.M
-@@ -39,7 +39,7 @@ Kerberos server to a slave Kerberos serv
- This is done by transmitting the dumped database file to the slave
- server over an encrypted, secure channel. The dump file must be created
- by kdb5_util, and is normally KPROP_DEFAULT_FILE
--(/usr/local/var/krb5kdc/slave_datatrans).
-+(@manlocalstatedir@/krb5kdc/slave_datatrans).
- .SH OPTIONS
- .TP
- \fB\-r\fP \fIrealm\fP
-@@ -51,7 +51,7 @@ is used.
- \fB\-f\fP \fIfile\fP
- specifies the filename where the dumped principal database file is to be
- found; by default the dumped database file is KPROP_DEFAULT_FILE
--(normally /usr/local/var/krb5kdc/slave_datatrans).
-+(normally @manlocalstatedir@/krb5kdc/slave_datatrans).
- .TP
- \fB\-P\fP \fIport\fP
- specifies the port to use to contact the
+++ /dev/null
-Modify ksu so that it performs account and session management on behalf of
-the target user account, mimicking the action of regular su. The default
-service name is "ksu", because on Fedora at least the configuration used
-is determined by whether or not a login shell is being opened, and so
-this may need to vary, too. At run-time, ksu's behavior can be reset to
-the earlier, non-PAM behavior by setting "use_pam" to false in the [ksu]
-section of /etc/krb5.conf.
-
-When enabled, ksu gains a dependency on libpam.
-
-Originally RT#5939, though it's changed since then to perform the account
-and session management before dropping privileges.
-
-diff -up krb5-1.8/src/aclocal.m4.pam krb5-1.8/src/aclocal.m4
---- krb5-1.8/src/aclocal.m4.pam 2009-11-22 12:00:45.000000000 -0500
-+++ krb5-1.8/src/aclocal.m4 2010-03-05 10:48:08.000000000 -0500
-@@ -1703,3 +1703,70 @@ AC_DEFUN(KRB5_AC_KEYRING_CCACHE,[
- ]))
- ])dnl
- dnl
-+dnl
-+dnl Use PAM instead of local crypt() compare for checking local passwords,
-+dnl and perform PAM account, session management, and password-changing where
-+dnl appropriate.
-+dnl
-+AC_DEFUN(KRB5_WITH_PAM,[
-+AC_ARG_WITH(pam,[AC_HELP_STRING(--with-pam,[compile with PAM support])],
-+ withpam="$withval",withpam=auto)
-+AC_ARG_WITH(pam-ksu-service,[AC_HELP_STRING(--with-ksu-service,[PAM service name for ksu ["ksu"]])],
-+ withksupamservice="$withval",withksupamservice=ksu)
-+old_LIBS="$LIBS"
-+if test "$withpam" != no ; then
-+ AC_MSG_RESULT([checking for PAM...])
-+ PAM_LIBS=
-+
-+ AC_CHECK_HEADERS(security/pam_appl.h)
-+ if test "x$ac_cv_header_security_pam_appl_h" != xyes ; then
-+ if test "$withpam" = auto ; then
-+ AC_MSG_RESULT([Unable to locate security/pam_appl.h.])
-+ withpam=no
-+ else
-+ AC_MSG_ERROR([Unable to locate security/pam_appl.h.])
-+ fi
-+ fi
-+
-+ LIBS=
-+ unset ac_cv_func_pam_start
-+ AC_CHECK_FUNCS(putenv pam_start)
-+ if test "x$ac_cv_func_pam_start" = xno ; then
-+ unset ac_cv_func_pam_start
-+ AC_CHECK_LIB(dl,dlopen)
-+ AC_CHECK_FUNCS(pam_start)
-+ if test "x$ac_cv_func_pam_start" = xno ; then
-+ AC_CHECK_LIB(pam,pam_start)
-+ unset ac_cv_func_pam_start
-+ unset ac_cv_func_pam_getenvlist
-+ AC_CHECK_FUNCS(pam_start pam_getenvlist)
-+ if test "x$ac_cv_func_pam_start" = xyes ; then
-+ PAM_LIBS="$LIBS"
-+ else
-+ if test "$withpam" = auto ; then
-+ AC_MSG_RESULT([Unable to locate libpam.])
-+ withpam=no
-+ else
-+ AC_MSG_ERROR([Unable to locate libpam.])
-+ fi
-+ fi
-+ fi
-+ fi
-+ if test "$withpam" != no ; then
-+ AC_MSG_NOTICE([building with PAM support])
-+ AC_DEFINE(USE_PAM,1,[Define if Kerberos-aware tools should support PAM])
-+ AC_DEFINE_UNQUOTED(KSU_PAM_SERVICE,"$withksupamservice",
-+ [Define to the name of the PAM service name to be used by ksu.])
-+ PAM_LIBS="$LIBS"
-+ NON_PAM_MAN=".\\\" "
-+ PAM_MAN=
-+ else
-+ PAM_MAN=".\\\" "
-+ NON_PAM_MAN=
-+ fi
-+fi
-+LIBS="$old_LIBS"
-+AC_SUBST(PAM_LIBS)
-+AC_SUBST(PAM_MAN)
-+AC_SUBST(NON_PAM_MAN)
-+])dnl
-diff -up krb5-1.8/src/clients/ksu/main.c.pam krb5-1.8/src/clients/ksu/main.c
---- krb5-1.8/src/clients/ksu/main.c.pam 2009-11-02 22:27:56.000000000 -0500
-+++ krb5-1.8/src/clients/ksu/main.c 2010-03-05 10:48:08.000000000 -0500
-@@ -26,6 +26,7 @@
- * KSU was writen by: Ari Medvinsky, ari@isi.edu
- */
-
-+#include "autoconf.h"
- #include "ksu.h"
- #include "adm_proto.h"
- #include <sys/types.h>
-@@ -33,6 +34,10 @@
- #include <signal.h>
- #include <grp.h>
-
-+#ifdef USE_PAM
-+#include "pam.h"
-+#endif
-+
- /* globals */
- char * prog_name;
- int auth_debug =0;
-@@ -40,6 +45,7 @@ char k5login_path[MAXPATHLEN];
- char k5users_path[MAXPATHLEN];
- char * gb_err = NULL;
- int quiet = 0;
-+int force_fork = 0;
- /***********/
-
- #define _DEF_CSH "/bin/csh"
-@@ -586,6 +592,25 @@ main (argc, argv)
- prog_name,target_user,client_name,
- source_user,ontty());
-
-+#ifdef USE_PAM
-+ if (appl_pam_enabled(ksu_context, "ksu")) {
-+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
-+ NULL, source_user,
-+ ttyname(STDERR_FILENO)) != 0) {
-+ fprintf(stderr, "Access denied for %s.\n", target_user);
-+ sweep_up(ksu_context, cc_target);
-+ exit(1);
-+ }
-+ if (appl_pam_requires_chauthtok()) {
-+ fprintf(stderr, "Password change required for %s.\n",
-+ target_user);
-+ sweep_up(ksu_context, cc_target);
-+ exit(1);
-+ }
-+ force_fork++;
-+ }
-+#endif
-+
- /* Run authorization as target.*/
- if (krb5_seteuid(target_uid)) {
- com_err(prog_name, errno, _("while switching to target for "
-@@ -651,6 +676,26 @@
- sweep_up(ksu_context, cc_target);
- exit(1);
- }
-+#ifdef USE_PAM
-+ } else {
-+ /* we always do PAM account management, even for root */
-+ if (appl_pam_enabled(ksu_context, "ksu")) {
-+ if (appl_pam_acct_mgmt(KSU_PAM_SERVICE, 1, target_user, NULL,
-+ NULL, source_user,
-+ ttyname(STDERR_FILENO)) != 0) {
-+ fprintf(stderr, "Access denied for %s.\n", target_user);
-+ sweep_up(ksu_context, cc_target);
-+ exit(1);
-+ }
-+ if (appl_pam_requires_chauthtok()) {
-+ fprintf(stderr, "Password change required for %s.\n",
-+ target_user);
-+ sweep_up(ksu_context, cc_target);
-+ exit(1);
-+ }
-+ force_fork++;
-+ }
-+#endif
- }
-
- if( some_rest_copy){
-@@ -720,6 +745,32 @@
- exit(1);
- }
-
-+#ifdef USE_PAM
-+ if (appl_pam_enabled(ksu_context, "ksu")) {
-+ if (appl_pam_session_open() != 0) {
-+ fprintf(stderr, "Error opening session for %s.\n", target_user);
-+ sweep_up(ksu_context, cc_target);
-+ exit(1);
-+ }
-+#ifdef DEBUG
-+ if (auth_debug){
-+ printf(" Opened PAM session.\n");
-+ }
-+#endif
-+ if (appl_pam_cred_init()) {
-+ fprintf(stderr, "Error initializing credentials for %s.\n",
-+ target_user);
-+ sweep_up(ksu_context, cc_target);
-+ exit(1);
-+ }
-+#ifdef DEBUG
-+ if (auth_debug){
-+ printf(" Initialized PAM credentials.\n");
-+ }
-+#endif
-+ }
-+#endif
-+
- /* set permissions */
- if (setgid(target_pwd->pw_gid) < 0) {
- perror("ksu: setgid");
-@@ -792,7 +817,7 @@ main (argc, argv)
- fprintf(stderr, "program to be execed %s\n",params[0]);
- }
-
-- if( keep_target_cache ) {
-+ if( keep_target_cache && !force_fork ) {
- execv(params[0], params);
- com_err(prog_name, errno, _("while trying to execv %s"), params[0]);
- sweep_up(ksu_context, cc_target);
-@@ -823,16 +875,35 @@ main (argc, argv)
- if (ret_pid == -1) {
- com_err(prog_name, errno, _("while calling waitpid"));
- }
-- sweep_up(ksu_context, cc_target);
-+ if( !keep_target_cache ) {
-+ sweep_up(ksu_context, cc_target);
-+ }
- exit (statusp);
- case -1:
- com_err(prog_name, errno, _("while trying to fork."));
- sweep_up(ksu_context, cc_target);
- exit (1);
- case 0:
-+#ifdef USE_PAM
-+ if (appl_pam_enabled(ksu_context, "ksu")) {
-+ if (appl_pam_setenv() != 0) {
-+ fprintf(stderr, "Error setting up environment for %s.\n",
-+ target_user);
-+ exit (1);
-+ }
-+#ifdef DEBUG
-+ if (auth_debug){
-+ printf(" Set up PAM environment.\n");
-+ }
-+#endif
-+ }
-+#endif
- execv(params[0], params);
- com_err(prog_name, errno, _("while trying to execv %s"),
- params[0]);
-+ if( keep_target_cache ) {
-+ sweep_up(ksu_context, cc_target);
-+ }
- exit (1);
- }
- }
-diff -up krb5-1.8/src/clients/ksu/Makefile.in.pam krb5-1.8/src/clients/ksu/Makefile.in
---- krb5-1.8/src/clients/ksu/Makefile.in.pam 2009-11-22 13:13:29.000000000 -0500
-+++ krb5-1.8/src/clients/ksu/Makefile.in 2010-03-05 11:55:14.000000000 -0500
-@@ -7,12 +7,14 @@
- PROG_RPATH=$(KRB5_LIBDIR)
-
- KSU_LIBS=@KSU_LIBS@
-+PAM_LIBS=@PAM_LIBS@
-
- SRCS = \
- $(srcdir)/krb_auth_su.c \
- $(srcdir)/ccache.c \
- $(srcdir)/authorization.c \
- $(srcdir)/main.c \
-+ $(srcdir)/pam.c \
- $(srcdir)/heuristic.c \
- $(srcdir)/xmalloc.c \
- $(srcdir)/setenv.c
-@@ -21,13 +23,17 @@ OBJS = \
- ccache.o \
- authorization.o \
- main.o \
-+ pam.o \
- heuristic.o \
- xmalloc.o @SETENVOBJ@
-
- all:: ksu
-
- ksu: $(OBJS) $(KRB5_BASE_DEPLIBS)
-- $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS)
-+ $(CC_LINK) -o $@ $(OBJS) $(KRB5_BASE_LIBS) $(KSU_LIBS) $(PAM_LIBS)
-+
-+pam.o: pam.c
-+ $(CC) $(ALL_CFLAGS) -c $<
-
- clean::
- $(RM) ksu
-diff -up krb5-1.8/src/clients/ksu/pam.c.pam krb5-1.8/src/clients/ksu/pam.c
---- krb5-1.8/src/clients/ksu/pam.c.pam 2010-03-05 10:48:08.000000000 -0500
-+++ krb5-1.8/src/clients/ksu/pam.c 2010-03-05 10:48:08.000000000 -0500
-@@ -0,0 +1,389 @@
-+/*
-+ * src/clients/ksu/pam.c
-+ *
-+ * Copyright 2007,2009,2010 Red Hat, Inc.
-+ *
-+ * All Rights Reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ * Redistributions of source code must retain the above copyright notice, this
-+ * list of conditions and the following disclaimer.
-+ *
-+ * Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ *
-+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
-+ * used to endorse or promote products derived from this software without
-+ * specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * Convenience wrappers for using PAM.
-+ */
-+
-+#include "autoconf.h"
-+#ifdef USE_PAM
-+#include <sys/types.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include "k5-int.h"
-+#include "pam.h"
-+
-+#ifndef MAXPWSIZE
-+#define MAXPWSIZE 128
-+#endif
-+
-+static int appl_pam_started;
-+static pid_t appl_pam_starter = -1;
-+static int appl_pam_session_opened;
-+static int appl_pam_creds_initialized;
-+static int appl_pam_pwchange_required;
-+static pam_handle_t *appl_pamh;
-+static struct pam_conv appl_pam_conv;
-+static char *appl_pam_user;
-+struct appl_pam_non_interactive_args {
-+ const char *user;
-+ const char *password;
-+};
-+
-+int
-+appl_pam_enabled(krb5_context context, const char *section)
-+{
-+ int enabled = 1;
-+ if ((context != NULL) && (context->profile != NULL)) {
-+ if (profile_get_boolean(context->profile,
-+ section,
-+ USE_PAM_CONFIGURATION_KEYWORD,
-+ NULL,
-+ enabled, &enabled) != 0) {
-+ enabled = 1;
-+ }
-+ }
-+ return enabled;
-+}
-+
-+void
-+appl_pam_cleanup(void)
-+{
-+ if (getpid() != appl_pam_starter) {
-+ return;
-+ }
-+#ifdef DEBUG
-+ printf("Called to clean up PAM.\n");
-+#endif
-+ if (appl_pam_creds_initialized) {
-+#ifdef DEBUG
-+ printf("Deleting PAM credentials.\n");
-+#endif
-+ pam_setcred(appl_pamh, PAM_DELETE_CRED);
-+ appl_pam_creds_initialized = 0;
-+ }
-+ if (appl_pam_session_opened) {
-+#ifdef DEBUG
-+ printf("Closing PAM session.\n");
-+#endif
-+ pam_close_session(appl_pamh, 0);
-+ appl_pam_session_opened = 0;
-+ }
-+ appl_pam_pwchange_required = 0;
-+ if (appl_pam_started) {
-+#ifdef DEBUG
-+ printf("Shutting down PAM.\n");
-+#endif
-+ pam_end(appl_pamh, 0);
-+ appl_pam_started = 0;
-+ appl_pam_starter = -1;
-+ free(appl_pam_user);
-+ appl_pam_user = NULL;
-+ }
-+}
-+static int
-+appl_pam_interactive_converse(int num_msg, const struct pam_message **msg,
-+ struct pam_response **presp, void *appdata_ptr)
-+{
-+ const struct pam_message *message;
-+ struct pam_response *resp;
-+ int i, code;
-+ char *pwstring, pwbuf[MAXPWSIZE];
-+ unsigned int pwsize;
-+ resp = malloc(sizeof(struct pam_response) * num_msg);
-+ if (resp == NULL) {
-+ return PAM_BUF_ERR;
-+ }
-+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
-+ code = PAM_SUCCESS;
-+ for (i = 0; i < num_msg; i++) {
-+ message = &(msg[0][i]); /* XXX */
-+ message = msg[i]; /* XXX */
-+ pwstring = NULL;
-+ switch (message->msg_style) {
-+ case PAM_TEXT_INFO:
-+ case PAM_ERROR_MSG:
-+ printf("[%s]\n", message->msg ? message->msg : "");
-+ fflush(stdout);
-+ resp[i].resp = NULL;
-+ resp[i].resp_retcode = PAM_SUCCESS;
-+ break;
-+ case PAM_PROMPT_ECHO_ON:
-+ case PAM_PROMPT_ECHO_OFF:
-+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
-+ if (fgets(pwbuf, sizeof(pwbuf),
-+ stdin) != NULL) {
-+ pwbuf[strcspn(pwbuf, "\r\n")] = '\0';
-+ pwstring = pwbuf;
-+ }
-+ } else {
-+ pwstring = getpass(message->msg ?
-+ message->msg :
-+ "");
-+ }
-+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
-+ pwsize = strlen(pwstring);
-+ resp[i].resp = malloc(pwsize + 1);
-+ if (resp[i].resp == NULL) {
-+ resp[i].resp_retcode = PAM_BUF_ERR;
-+ } else {
-+ memcpy(resp[i].resp, pwstring, pwsize);
-+ resp[i].resp[pwsize] = '\0';
-+ resp[i].resp_retcode = PAM_SUCCESS;
-+ }
-+ } else {
-+ resp[i].resp_retcode = PAM_CONV_ERR;
-+ code = PAM_CONV_ERR;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ *presp = resp;
-+ return code;
-+}
-+static int
-+appl_pam_non_interactive_converse(int num_msg,
-+ const struct pam_message **msg,
-+ struct pam_response **presp,
-+ void *appdata_ptr)
-+{
-+ const struct pam_message *message;
-+ struct pam_response *resp;
-+ int i, code;
-+ unsigned int pwsize;
-+ struct appl_pam_non_interactive_args *args;
-+ const char *pwstring;
-+ resp = malloc(sizeof(struct pam_response) * num_msg);
-+ if (resp == NULL) {
-+ return PAM_BUF_ERR;
-+ }
-+ args = appdata_ptr;
-+ memset(resp, 0, sizeof(struct pam_response) * num_msg);
-+ code = PAM_SUCCESS;
-+ for (i = 0; i < num_msg; i++) {
-+ message = &((*msg)[i]);
-+ message = msg[i];
-+ pwstring = NULL;
-+ switch (message->msg_style) {
-+ case PAM_TEXT_INFO:
-+ case PAM_ERROR_MSG:
-+ break;
-+ case PAM_PROMPT_ECHO_ON:
-+ case PAM_PROMPT_ECHO_OFF:
-+ if (message->msg_style == PAM_PROMPT_ECHO_ON) {
-+ /* assume "user" */
-+ pwstring = args->user;
-+ } else {
-+ /* assume "password" */
-+ pwstring = args->password;
-+ }
-+ if ((pwstring != NULL) && (pwstring[0] != '\0')) {
-+ pwsize = strlen(pwstring);
-+ resp[i].resp = malloc(pwsize + 1);
-+ if (resp[i].resp == NULL) {
-+ resp[i].resp_retcode = PAM_BUF_ERR;
-+ } else {
-+ memcpy(resp[i].resp, pwstring, pwsize);
-+ resp[i].resp[pwsize] = '\0';
-+ resp[i].resp_retcode = PAM_SUCCESS;
-+ }
-+ } else {
-+ resp[i].resp_retcode = PAM_CONV_ERR;
-+ code = PAM_CONV_ERR;
-+ }
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ *presp = resp;
-+ return code;
-+}
-+static int
-+appl_pam_start(const char *service, int interactive,
-+ const char *login_username,
-+ const char *non_interactive_password,
-+ const char *hostname,
-+ const char *ruser,
-+ const char *tty)
-+{
-+ static int exit_handler_registered;
-+ static struct appl_pam_non_interactive_args args;
-+ int ret = 0;
-+ if (appl_pam_started &&
-+ (strcmp(login_username, appl_pam_user) != 0)) {
-+ appl_pam_cleanup();
-+ appl_pam_user = NULL;
-+ }
-+ if (!appl_pam_started) {
-+#ifdef DEBUG
-+ printf("Starting PAM up (service=\"%s\",user=\"%s\").\n",
-+ service, login_username);
-+#endif
-+ memset(&appl_pam_conv, 0, sizeof(appl_pam_conv));
-+ appl_pam_conv.conv = interactive ?
-+ &appl_pam_interactive_converse :
-+ &appl_pam_non_interactive_converse;
-+ memset(&args, 0, sizeof(args));
-+ args.user = strdup(login_username);
-+ args.password = non_interactive_password ?
-+ strdup(non_interactive_password) :
-+ NULL;
-+ appl_pam_conv.appdata_ptr = &args;
-+ ret = pam_start(service, login_username,
-+ &appl_pam_conv, &appl_pamh);
-+ if (ret == 0) {
-+ if (hostname != NULL) {
-+#ifdef DEBUG
-+ printf("Setting PAM_RHOST to \"%s\".\n", hostname);
-+#endif
-+ pam_set_item(appl_pamh, PAM_RHOST, hostname);
-+ }
-+ if (ruser != NULL) {
-+#ifdef DEBUG
-+ printf("Setting PAM_RUSER to \"%s\".\n", ruser);
-+#endif
-+ pam_set_item(appl_pamh, PAM_RUSER, ruser);
-+ }
-+ if (tty != NULL) {
-+#ifdef DEBUG
-+ printf("Setting PAM_TTY to \"%s\".\n", tty);
-+#endif
-+ pam_set_item(appl_pamh, PAM_TTY, tty);
-+ }
-+ if (!exit_handler_registered &&
-+ (atexit(appl_pam_cleanup) != 0)) {
-+ pam_end(appl_pamh, 0);
-+ appl_pamh = NULL;
-+ ret = -1;
-+ } else {
-+ appl_pam_started = 1;
-+ appl_pam_starter = getpid();
-+ appl_pam_user = strdup(login_username);
-+ exit_handler_registered = 1;
-+ }
-+ }
-+ }
-+ return ret;
-+}
-+int
-+appl_pam_acct_mgmt(const char *service, int interactive,
-+ const char *login_username,
-+ const char *non_interactive_password,
-+ const char *hostname,
-+ const char *ruser,
-+ const char *tty)
-+{
-+ int ret;
-+ appl_pam_pwchange_required = 0;
-+ ret = appl_pam_start(service, interactive, login_username,
-+ non_interactive_password, hostname, ruser, tty);
-+ if (ret == 0) {
-+#ifdef DEBUG
-+ printf("Calling pam_acct_mgmt().\n");
-+#endif
-+ ret = pam_acct_mgmt(appl_pamh, 0);
-+ switch (ret) {
-+ case PAM_IGNORE:
-+ ret = 0;
-+ break;
-+ case PAM_NEW_AUTHTOK_REQD:
-+ appl_pam_pwchange_required = 1;
-+ ret = 0;
-+ break;
-+ default:
-+ break;
-+ }
-+ }
-+ return ret;
-+}
-+int
-+appl_pam_requires_chauthtok(void)
-+{
-+ return appl_pam_pwchange_required;
-+}
-+int
-+appl_pam_session_open(void)
-+{
-+ int ret = 0;
-+ if (appl_pam_started) {
-+#ifdef DEBUG
-+ printf("Opening PAM session.\n");
-+#endif
-+ ret = pam_open_session(appl_pamh, 0);
-+ if (ret == 0) {
-+ appl_pam_session_opened = 1;
-+ }
-+ }
-+ return ret;
-+}
-+int
-+appl_pam_setenv(void)
-+{
-+ int ret = 0;
-+#ifdef HAVE_PAM_GETENVLIST
-+#ifdef HAVE_PUTENV
-+ int i;
-+ char **list;
-+ if (appl_pam_started) {
-+ list = pam_getenvlist(appl_pamh);
-+ for (i = 0; ((list != NULL) && (list[i] != NULL)); i++) {
-+#ifdef DEBUG
-+ printf("Setting \"%s\" in environment.\n", list[i]);
-+#endif
-+ putenv(list[i]);
-+ }
-+ }
-+#endif
-+#endif
-+ return ret;
-+}
-+int
-+appl_pam_cred_init(void)
-+{
-+ int ret = 0;
-+ if (appl_pam_started) {
-+#ifdef DEBUG
-+ printf("Initializing PAM credentials.\n");
-+#endif
-+ ret = pam_setcred(appl_pamh, PAM_ESTABLISH_CRED);
-+ if (ret == 0) {
-+ appl_pam_creds_initialized = 1;
-+ }
-+ }
-+ return ret;
-+}
-+#endif
-diff -up krb5-1.8/src/clients/ksu/pam.h.pam krb5-1.8/src/clients/ksu/pam.h
---- krb5-1.8/src/clients/ksu/pam.h.pam 2010-03-05 10:48:08.000000000 -0500
-+++ krb5-1.8/src/clients/ksu/pam.h 2010-03-05 10:48:08.000000000 -0500
-@@ -0,0 +1,57 @@
-+/*
-+ * src/clients/ksu/pam.h
-+ *
-+ * Copyright 2007,2009,2010 Red Hat, Inc.
-+ *
-+ * All Rights Reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ * Redistributions of source code must retain the above copyright notice, this
-+ * list of conditions and the following disclaimer.
-+ *
-+ * Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ *
-+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
-+ * used to endorse or promote products derived from this software without
-+ * specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * Convenience wrappers for using PAM.
-+ */
-+
-+#include <krb5.h>
-+#ifdef HAVE_SECURITY_PAM_APPL_H
-+#include <security/pam_appl.h>
-+#endif
-+
-+#define USE_PAM_CONFIGURATION_KEYWORD "use_pam"
-+
-+#ifdef USE_PAM
-+int appl_pam_enabled(krb5_context context, const char *section);
-+int appl_pam_acct_mgmt(const char *service, int interactive,
-+ const char *local_username,
-+ const char *non_interactive_password,
-+ const char *hostname,
-+ const char *ruser,
-+ const char *tty);
-+int appl_pam_requires_chauthtok(void);
-+int appl_pam_session_open(void);
-+int appl_pam_setenv(void);
-+int appl_pam_cred_init(void);
-+void appl_pam_cleanup(void);
-+#endif
-diff -up krb5-1.8/src/configure.in.pam krb5-1.8/src/configure.in
---- krb5-1.8/src/configure.in.pam 2009-12-31 18:13:56.000000000 -0500
-+++ krb5-1.8/src/configure.in 2010-03-05 10:48:08.000000000 -0500
-@@ -1051,6 +1051,8 @@ if test "$ac_cv_lib_socket" = "yes" -a "
- AC_SUBST([VERTO_LIBS])
- AC_SUBST([VERTO_VERSION])
-
-+KRB5_WITH_PAM
-+
- # Make localedir work in autoconf 2.5x.
- if test "${localedir+set}" != set; then
- localedir='$(datadir)/locale'
+++ /dev/null
-SELinux bases access to files on the domain of the requesting process,
-the operation being performed, and the context applied to the file.
-
-In many cases, applications needn't be SELinux aware to work properly,
-because SELinux can apply a default label to a file based on the label
-of the directory in which it's created.
-
-In the case of files such as /etc/krb5.keytab, however, this isn't
-sufficient, as /etc/krb5.keytab will almost always need to be given a
-label which differs from that of /etc/issue or /etc/resolv.conf. The
-the kdb stash file needs a different label than the database for which
-it's holding a master key, even though both typically live in the same
-directory.
-
-To give the file the correct label, we can either force a "restorecon"
-call to fix a file's label after it's created, or create the file with
-the right label, as we attempt to do here. We lean on THREEPARAMOPEN
-and define a similar macro named WRITABLEFOPEN with which we replace
-several uses of fopen().
-
-The file creation context that we're manipulating here is a process-wide
-attribute. While for the most part, applications which need to label
-files when they're created have tended to be single-threaded, there's
-not much we can do to avoid interfering with an application that
-manipulates the creation context directly. Right now we're mediating
-access using a library-local mutex, but that can only work for consumers
-that are part of this package -- an unsuspecting application will still
-stomp all over us.
-
-The selabel APIs for looking up the context should be thread-safe (per
-Red Hat #273081), so switching to using them instead of matchpathcon(),
-which we used earlier, is some improvement.
-
---- krb5/src/aclocal.m4
-+++ krb5/src/aclocal.m4
-@@ -103,6 +103,7 @@ AC_SUBST_FILE(libnodeps_frag)
- dnl
- KRB5_AC_PRAGMA_WEAK_REF
- WITH_LDAP
-+KRB5_WITH_SELINUX
- KRB5_LIB_PARAMS
- KRB5_AC_INITFINI
- KRB5_AC_ENABLE_THREADS
-@@ -1791,3 +1792,51 @@ AC_SUBST(manlocalstatedir)
- AC_SUBST(manlibexecdir)
- AC_CONFIG_FILES($1)
- ])
-+dnl
-+dnl Use libselinux to set file contexts on newly-created files.
-+dnl
-+AC_DEFUN(KRB5_WITH_SELINUX,[
-+AC_ARG_WITH(selinux,[AC_HELP_STRING(--with-selinux,[compile with SELinux labeling support])],
-+ withselinux="$withval",withselinux=auto)
-+old_LIBS="$LIBS"
-+if test "$withselinux" != no ; then
-+ AC_MSG_RESULT([checking for libselinux...])
-+ SELINUX_LIBS=
-+ AC_CHECK_HEADERS(selinux/selinux.h selinux/label.h)
-+ if test "x$ac_cv_header_selinux_selinux_h" != xyes ; then
-+ if test "$withselinux" = auto ; then
-+ AC_MSG_RESULT([Unable to locate selinux/selinux.h.])
-+ withselinux=no
-+ else
-+ AC_MSG_ERROR([Unable to locate selinux/selinux.h.])
-+ fi
-+ fi
-+
-+ LIBS=
-+ unset ac_cv_func_setfscreatecon
-+ AC_CHECK_FUNCS(setfscreatecon selabel_open)
-+ if test "x$ac_cv_func_setfscreatecon" = xno ; then
-+ AC_CHECK_LIB(selinux,setfscreatecon)
-+ unset ac_cv_func_setfscreatecon
-+ AC_CHECK_FUNCS(setfscreatecon selabel_open)
-+ if test "x$ac_cv_func_setfscreatecon" = xyes ; then
-+ SELINUX_LIBS="$LIBS"
-+ else
-+ if test "$withselinux" = auto ; then
-+ AC_MSG_RESULT([Unable to locate libselinux.])
-+ withselinux=no
-+ else
-+ AC_MSG_ERROR([Unable to locate libselinux.])
-+ fi
-+ fi
-+ fi
-+ if test "$withselinux" != no ; then
-+ AC_MSG_NOTICE([building with SELinux labeling support])
-+ AC_DEFINE(USE_SELINUX,1,[Define if Kerberos-aware tools should set SELinux file contexts when creating files.])
-+ SELINUX_LIBS="$LIBS"
-+ EXTRA_SUPPORT_SYMS="$EXTRA_SUPPORT_SYMS krb5int_labeled_open krb5int_labeled_fopen krb5int_push_fscreatecon_for krb5int_pop_fscreatecon"
-+ fi
-+fi
-+LIBS="$old_LIBS"
-+AC_SUBST(SELINUX_LIBS)
-+])dnl
---- krb5/src/config/pre.in
-+++ krb5/src/config/pre.in
-@@ -180,6 +180,7 @@ LD_UNRESOLVED_PREFIX = @LD_UNRESOLVED_PREFIX@
- LD_SHLIBDIR_PREFIX = @LD_SHLIBDIR_PREFIX@
- LDARGS = @LDARGS@
- LIBS = @LIBS@
-+SELINUX_LIBS=@SELINUX_LIBS@
-
- INSTALL=@INSTALL@
- INSTALL_STRIP=
-@@ -379,7 +380,7 @@ SUPPORT_LIB = -l$(SUPPORT_LIBNAME)
- # HESIOD_LIBS is -lhesiod...
- HESIOD_LIBS = @HESIOD_LIBS@
-
--KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(DL_LIB)
-+KRB5_BASE_LIBS = $(KRB5_LIB) $(K5CRYPTO_LIB) $(COM_ERR_LIB) $(SUPPORT_LIB) $(GEN_LIB) $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
- KDB5_LIBS = $(KDB5_LIB) $(GSSRPC_LIBS)
- GSS_LIBS = $(GSS_KRB5_LIB)
- # needs fixing if ever used on Mac OS X!
---- krb5/src/configure.in
-+++ krb5/src/configure.in
-@@ -1053,6 +1053,8 @@ fi
-
- KRB5_WITH_PAM
-
-+KRB5_WITH_SELINUX
-+
- # Make localedir work in autoconf 2.5x.
- if test "${localedir+set}" != set; then
- localedir='$(datadir)/locale'
---- krb5/src/include/k5-int.h
-+++ krb5/src/include/k5-int.h
-@@ -133,6 +133,7 @@ typedef unsigned char u_char;
- typedef UINT64_TYPE krb5_ui_8;
- typedef INT64_TYPE krb5_int64;
-
-+#include "k5-label.h"
-
- #define DEFAULT_PWD_STRING1 "Enter password"
- #define DEFAULT_PWD_STRING2 "Re-enter password for verification"
---- krb5/src/include/k5-label.h
-+++ krb5/src/include/k5-label.h
-@@ -0,0 +1,32 @@
-+#ifndef _KRB5_LABEL_H
-+#define _KRB5_LABEL_H
-+
-+#ifdef THREEPARAMOPEN
-+#undef THREEPARAMOPEN
-+#endif
-+#ifdef WRITABLEFOPEN
-+#undef WRITABLEFOPEN
-+#endif
-+
-+/* Wrapper functions which help us create files and directories with the right
-+ * context labels. */
-+#ifdef USE_SELINUX
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <fcntl.h>
-+#include <stdio.h>
-+#include <unistd.h>
-+FILE *krb5int_labeled_fopen(const char *path, const char *mode);
-+int krb5int_labeled_creat(const char *path, mode_t mode);
-+int krb5int_labeled_open(const char *path, int flags, ...);
-+int krb5int_labeled_mkdir(const char *path, mode_t mode);
-+int krb5int_labeled_mknod(const char *path, mode_t mode, dev_t device);
-+#define THREEPARAMOPEN(x,y,z) krb5int_labeled_open(x,y,z)
-+#define WRITABLEFOPEN(x,y) krb5int_labeled_fopen(x,y)
-+void *krb5int_push_fscreatecon_for(const char *pathname);
-+void krb5int_pop_fscreatecon(void *previous);
-+#else
-+#define WRITABLEFOPEN(x,y) fopen(x,y)
-+#define THREEPARAMOPEN(x,y,z) open(x,y,z)
-+#endif
-+#endif
---- krb5/src/include/krb5/krb5.hin
-+++ krb5/src/include/krb5/krb5.hin
-@@ -87,6 +87,12 @@
- #define THREEPARAMOPEN(x,y,z) open(x,y,z)
- #endif
-
-+#if KRB5_PRIVATE
-+#ifndef WRITABLEFOPEN
-+#define WRITABLEFOPEN(x,y) fopen(x,y)
-+#endif
-+#endif
-+
- #define KRB5_OLD_CRYPTO
-
- #include <stdlib.h>
---- krb5/src/kadmin/dbutil/dump.c
-+++ krb5/src/kadmin/dbutil/dump.c
-@@ -346,7 +346,7 @@
- exit_status++;
- return;
- }
-- if ((fd = open(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
-+ if ((fd = THREEPARAMOPEN(file_ok, O_WRONLY|O_CREAT|O_TRUNC, 0600)) < 0) {
- com_err(progname, errno, _("while creating 'ok' file, '%s'"),
- file_ok);
- exit_status++;
-@@ -1274,7 +1274,7 @@ dump_db(argc, argv)
- * want to get into.
- */
- unlink(ofile);
-- if (!(f = fopen(ofile, "w"))) {
-+ if (!(f = WRITABLEFOPEN(ofile, "w"))) {
- fprintf(stderr, ofopen_error,
- progname, ofile, error_message(errno));
- exit_status++;
---- krb5/src/krb5-config.in
-+++ krb5/src/krb5-config.in
-@@ -38,6 +38,7 @@ RPATH_FLAG='@RPATH_FLAG@'
- PROG_RPATH_FLAGS='@PROG_RPATH_FLAGS@'
- PTHREAD_CFLAGS='@PTHREAD_CFLAGS@'
- DL_LIB='@DL_LIB@'
-+SELINUX_LIBS='@SELINUX_LIBS@'
-
- LIBS='@LIBS@'
- GEN_LIB=@GEN_LIB@
-@@ -218,7 +219,7 @@
- fi
-
- # If we ever support a flag to generate output suitable for static
-- # linking, we would output "-lkrb5support $GEN_LIB $LIBS $DL_LIB"
-+ # linking, we would output "-lkrb5support $GEN_LIB $LIBS $SELINUX_LIBS $DL_LIB"
- # here.
-
- echo $lib_flags
---- krb5/src/lib/kadm5/logger.c
-+++ krb5/src/lib/kadm5/logger.c
-@@ -425,7 +425,7 @@ krb5_klog_init(krb5_context kcontext, ch
- * Check for append/overwrite, then open the file.
- */
- if (cp[4] == ':' || cp[4] == '=') {
-- f = fopen(&cp[5], (cp[4] == ':') ? "a" : "w");
-+ f = WRITABLEFOPEN(&cp[5], (cp[4] == ':') ? "a" : "w");
- if (f) {
- set_cloexec_file(f);
- log_control.log_entries[i].lfu_filep = f;
-@@ -961,7 +961,7 @@ krb5_klog_reopen(krb5_context kcontext)
- * In case the old logfile did not get moved out of the
- * way, open for append to prevent squashing the old logs.
- */
-- f = fopen(log_control.log_entries[lindex].lfu_fname, "a+");
-+ f = WRITABLEFOPEN(log_control.log_entries[lindex].lfu_fname, "a+");
- if (f) {
- set_cloexec_file(f);
- log_control.log_entries[lindex].lfu_filep = f;
---- krb5/src/lib/krb5/keytab/kt_file.c
-+++ krb5/src/lib/krb5/keytab/kt_file.c
-@@ -1050,7 +1050,7 @@ krb5_ktfileint_open(krb5_context context
-
- KTCHECKLOCK(id);
- errno = 0;
-- KTFILEP(id) = fopen(KTFILENAME(id),
-+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id),
- (mode == KRB5_LOCKMODE_EXCLUSIVE) ?
- fopen_mode_rbplus : fopen_mode_rb);
- if (!KTFILEP(id)) {
-@@ -1058,7 +1058,7 @@ krb5_ktfileint_open(krb5_context context
- /* try making it first time around */
- krb5_create_secure_file(context, KTFILENAME(id));
- errno = 0;
-- KTFILEP(id) = fopen(KTFILENAME(id), fopen_mode_rbplus);
-+ KTFILEP(id) = WRITABLEFOPEN(KTFILENAME(id), fopen_mode_rbplus);
- if (!KTFILEP(id))
- goto report_errno;
- writevno = 1;
---- krb5/src/plugins/kdb/db2/adb_openclose.c
-+++ krb5/src/plugins/kdb/db2/adb_openclose.c
-@@ -201,7 +201,7 @@ osa_adb_init_db(osa_adb_db_t *dbp, char
- * POSIX systems
- */
- lockp->lockinfo.filename = strdup(lockfilename);
-- if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) {
-+ if ((lockp->lockinfo.lockfile = WRITABLEFOPEN(lockfilename, "r+")) == NULL) {
- /*
- * maybe someone took away write permission so we could only
- * get shared locks?
---- krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
-+++ krb5/src/plugins/kdb/db2/libdb2/btree/bt_open.c
-@@ -60,6 +60,7 @@ static char sccsid[] = "@(#)bt_open.c 8.
-
- #include "k5-platform.h" /* mkstemp? */
-
-+#include "k5-int.h"
- #include "db-int.h"
- #include "btree.h"
-
-@@ -203,7 +204,7 @@ __bt_open(fname, flags, mode, openinfo,
- goto einval;
- }
-
-- if ((t->bt_fd = open(fname, flags | O_BINARY, mode)) < 0)
-+ if ((t->bt_fd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
- goto err;
-
- } else {
---- krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
-+++ krb5/src/plugins/kdb/db2/libdb2/hash/hash.c
-@@ -51,6 +51,7 @@ static char sccsid[] = "@(#)hash.c 8.12
- #include <assert.h>
- #endif
-
-+#include "k5-int.h"
- #include "db-int.h"
- #include "hash.h"
- #include "page.h"
-@@ -140,7 +141,7 @@ __kdb2_hash_open(file, flags, mode, info
- new_table = 1;
- }
- if (file) {
-- if ((hashp->fp = open(file, flags|O_BINARY, mode)) == -1)
-+ if ((hashp->fp = THREEPARAMOPEN(file, flags|O_BINARY, mode)) == -1)
- RETURN_ERROR(errno, error0);
- (void)fcntl(hashp->fp, F_SETFD, 1);
- }
---- krb5/src/plugins/kdb/db2/libdb2/test/Makefile.in
-+++ krb5/src/plugins/kdb/db2/libdb2/test/Makefile.in
-@@ -12,7 +12,8 @@ PROG_RPATH=$(KRB5_LIBDIR)
-
- KRB5_RUN_ENV= @KRB5_RUN_ENV@
-
--DB_LIB = -ldb
-+DB_LIB = -ldb $(SUPPORT_DEPLIB)
-+
- DB_DEPLIB = ../libdb$(DEPLIBEXT)
-
- all::
---- krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
-+++ krb5/src/plugins/kdb/ldap/ldap_util/kdb5_ldap_services.c
-@@ -1091,7 +1091,7 @@
-
- /* Create a temporary file which contains all the entries except the
- entry for the given service dn */
-- pfile = fopen(file_name, "r+");
-+ pfile = WRITABLEFOPEN(file_name, "r+");
- if (pfile == NULL) {
- com_err(me, errno, "while deleting entry from file %s", file_name);
- goto cleanup;
-@@ -1108,7 +1108,7 @@
- snprintf (tmp_file, strlen(file_name) + 4 + 1, "%s%s", file_name, ".tmp");
-
-
-- tmpfd = creat(tmp_file, S_IRUSR|S_IWUSR);
-+ tmpfd = THREEPARAMOPEN(tmp_file, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
- umask(omask);
- if (tmpfd == -1) {
- com_err(me, errno, "while deleting entry from file\n");
-@@ -1728,7 +1728,7 @@
-
- printf("File does not exist. Creating the file %s...\n", file_name);
- omask = umask(077);
-- fd = creat(file_name, S_IRUSR|S_IWUSR);
-+ fd = THREEPARAMOPEN(file_name, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR);
- umask(omask);
- if (fd == -1) {
- com_err(me, errno, "Error creating file %s", file_name);
-@@ -1756,7 +1756,7 @@
-
- /* TODO: file lock for the service password file */
- /* set password in the file */
-- pfile = fopen(file_name, "r+");
-+ pfile = WRITABLEFOPEN(file_name, "r+");
- if (pfile == NULL) {
- com_err(me, errno, "Failed to open file %s", file_name);
- goto cleanup;
-@@ -1797,7 +1797,7 @@
- }
-
- omask = umask(077);
-- newfile = fopen(tmp_file, "w+");
-+ newfile = WRITABLEFOPEN(tmp_file, "w+");
- umask(omask);
- if (newfile == NULL) {
- com_err(me, errno, "Error creating file %s", tmp_file);
-@@ -2019,7 +2019,7 @@
-
- /* set password in the file */
- old_mode = umask(0177);
-- pfile = fopen(file_name, "a+");
-+ pfile = WRITABLEFOPEN(file_name, "a+");
- if (pfile == NULL) {
- com_err(me, errno, _("Failed to open file %s: %s"), file_name,
- strerror (errno));
-@@ -2069,7 +2069,7 @@
- }
-
- omask = umask(077);
-- newfile = fopen(tmp_file, "w");
-+ newfile = WRITABLEFOPEN(tmp_file, "w");
- umask (omask);
- if (newfile == NULL) {
- com_err(me, errno, _("Error creating file %s"), tmp_file);
---- krb5/src/slave/kpropd.c
-+++ krb5/src/slave/kpropd.c
-@@ -328,7 +328,7 @@ retry:
- if (!debug && iproprole != IPROP_SLAVE)
- daemon(1, 0);
- #ifdef PID_FILE
-- if ((pidfile = fopen(PID_FILE, "w")) != NULL) {
-+ if ((pidfile = WRITABLEFOPEN(PID_FILE, "w")) != NULL) {
- fprintf(pidfile, "%d\n", getpid());
- fclose(pidfile);
- } else
-@@ -437,6 +437,9 @@ void doit(fd)
- krb5_enctype etype;
- int database_fd;
- char host[INET6_ADDRSTRLEN+1];
-+#ifdef USE_SELINUX
-+ void *selabel;
-+#endif
-
- if (kpropd_context->kdblog_context &&
- kpropd_context->kdblog_context->iproprole == IPROP_SLAVE) {
-@@ -515,9 +518,15 @@ void doit(fd)
- free(name);
- exit(1);
- }
-+#ifdef USE_SELINUX
-+ selabel = krb5int_push_fscreatecon_for(file);
-+#endif
- omask = umask(077);
- lock_fd = open(temp_file_name, O_RDWR|O_CREAT, 0600);
- (void) umask(omask);
-+#ifdef USE_SELINUX
-+ krb5int_pop_fscreatecon(selabel);
-+#endif
- retval = krb5_lock_file(kpropd_context, lock_fd,
- KRB5_LOCKMODE_EXCLUSIVE|KRB5_LOCKMODE_DONTBLOCK);
- if (retval) {
---- krb5/src/util/profile/prof_file.c
-+++ krb5/src/util/profile/prof_file.c
-@@ -30,6 +30,7 @@
- #endif
-
- #include "k5-platform.h"
-+#include "k5-label.h"
-
- struct global_shared_profile_data {
- /* This is the head of the global list of shared trees */
-@@ -418,7 +419,7 @@ static errcode_t write_data_to_file(prf_
-
- errno = 0;
-
-- f = fopen(new_file, "w");
-+ f = WRITABLEFOPEN(new_file, "w");
- if (!f) {
- retval = errno;
- if (retval == 0)
---- krb5/src/util/support/Makefile.in
-+++ krb5/src/util/support/Makefile.in
-@@ -54,6 +54,7 @@ IPC_SYMS= \
-
- STLIBOBJS= \
- threads.o \
-+ selinux.o \
- init-addrinfo.o \
- plugins.o \
- errors.o \
-@@ -108,7 +109,7 @@ SRCS=\
-
- SHLIB_EXPDEPS =
- # Add -lm if dumping thread stats, for sqrt.
--SHLIB_EXPLIBS= $(LIBS) $(DL_LIB)
-+SHLIB_EXPLIBS= $(LIBS) $(SELINUX_LIBS) $(DL_LIB)
- SHLIB_DIRS=
- SHLIB_RDIRS=$(KRB5_LIBDIR)
-
---- krb5/src/util/support/selinux.c
-+++ krb5/src/util/support/selinux.c
-@@ -0,0 +1,373 @@
-+/*
-+ * Copyright 2007,2008,2009,2011,2012 Red Hat, Inc. All Rights Reserved.
-+ *
-+ * Redistribution and use in source and binary forms, with or without
-+ * modification, are permitted provided that the following conditions are met:
-+ *
-+ * Redistributions of source code must retain the above copyright notice, this
-+ * list of conditions and the following disclaimer.
-+ *
-+ * Redistributions in binary form must reproduce the above copyright notice,
-+ * this list of conditions and the following disclaimer in the documentation
-+ * and/or other materials provided with the distribution.
-+ *
-+ * Neither the name of Red Hat, Inc. nor the names of its contributors may be
-+ * used to endorse or promote products derived from this software without
-+ * specific prior written permission.
-+ *
-+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-+ * POSSIBILITY OF SUCH DAMAGE.
-+ *
-+ * File-opening wrappers for creating correctly-labeled files. So far, we can
-+ * assume that this is Linux-specific, so we make many simplifying assumptions.
-+ */
-+
-+#include "../../include/autoconf.h"
-+
-+#ifdef USE_SELINUX
-+
-+#include <k5-label.h>
-+#include <k5-thread.h>
-+#include <sys/types.h>
-+#include <sys/stat.h>
-+#include <errno.h>
-+#include <fcntl.h>
-+#include <limits.h>
-+#include <pthread.h>
-+#include <stdarg.h>
-+#include <stdio.h>
-+#include <stdlib.h>
-+#include <string.h>
-+#include <unistd.h>
-+#include <selinux/selinux.h>
-+#include <selinux/context.h>
-+#ifdef HAVE_SELINUX_LABEL_H
-+#include <selinux/label.h>
-+#endif
-+
-+/* #define DEBUG 1 */
-+
-+/* Mutex used to serialize use of the process-global file creation context. */
-+k5_mutex_t labeled_mutex = K5_MUTEX_PARTIAL_INITIALIZER;
-+
-+/* Make sure we finish initializing that mutex before attempting to use it. */
-+k5_once_t labeled_once = K5_ONCE_INIT;
-+static void
-+label_mutex_init(void)
-+{
-+ k5_mutex_finish_init(&labeled_mutex);
-+}
-+
-+static security_context_t
-+push_fscreatecon(const char *pathname, mode_t mode)
-+{
-+ security_context_t previous, configuredsc, currentsc, derivedsc;
-+ context_t current, derived;
-+ const char *fullpath, *currentuser;
-+#ifdef HAVE_SELINUX_LABEL_H
-+ struct selabel_handle *ctx;
-+#endif
-+
-+ previous = NULL;
-+ if (is_selinux_enabled()) {
-+ if (getfscreatecon(&previous) == 0) {
-+ char *genpath;
-+ genpath = NULL;
-+ if (pathname[0] != '/') {
-+ char *wd;
-+ size_t len;
-+ len = 0;
-+ wd = getcwd(NULL, len);
-+ if (wd == NULL) {
-+ if (previous != NULL) {
-+ freecon(previous);
-+ }
-+ return NULL;
-+ }
-+ len = strlen(wd) + 1 + strlen(pathname) + 1;
-+ genpath = malloc(len);
-+ if (genpath == NULL) {
-+ free(wd);
-+ if (previous != NULL) {
-+ freecon(previous);
-+ }
-+ return NULL;
-+ }
-+ sprintf(genpath, "%s/%s", wd, pathname);
-+ free(wd);
-+ fullpath = genpath;
-+ } else {
-+ fullpath = pathname;
-+ }
-+#ifdef DEBUG
-+ if (isatty(fileno(stderr))) {
-+ fprintf(stderr, "Looking up context for "
-+ "\"%s\"(%05o).\n", fullpath, mode);
-+ }
-+#endif
-+ configuredsc = NULL;
-+#ifdef HAVE_SELINUX_LABEL_H
-+ ctx = selabel_open(SELABEL_CTX_FILE, NULL, 0);
-+ if (ctx != NULL) {
-+ if (selabel_lookup(ctx, &configuredsc,
-+ fullpath, mode) != 0) {
-+ selabel_close(ctx);
-+ free(genpath);
-+ if (previous != NULL) {
-+ freecon(previous);
-+ }
-+ return NULL;
-+ }
-+ selabel_close(ctx);
-+ }
-+#else
-+ if (matchpathcon(fullpath, mode, &configuredsc) != 0) {
-+ free(genpath);
-+ if (previous != NULL) {
-+ freecon(previous);
-+ }
-+ return NULL;
-+ }
-+#endif
-+ free(genpath);
-+ if (configuredsc == NULL) {
-+ if (previous != NULL) {
-+ freecon(previous);
-+ }
-+ return NULL;
-+ }
-+ currentsc = NULL;
-+ getcon(¤tsc);
-+ if (currentsc != NULL) {
-+ derived = context_new(configuredsc);
-+ if (derived != NULL) {
-+ current = context_new(currentsc);
-+ if (current != NULL) {
-+ currentuser = context_user_get(current);
-+ if (currentuser != NULL) {
-+ if (context_user_set(derived,
-+ currentuser) == 0) {
-+ derivedsc = context_str(derived);
-+ if (derivedsc != NULL) {
-+ freecon(configuredsc);
-+ configuredsc = strdup(derivedsc);
-+ }
-+ }
-+ }
-+ context_free(current);
-+ }
-+ context_free(derived);
-+ }
-+ freecon(currentsc);
-+ }
-+#ifdef DEBUG
-+ if (isatty(fileno(stderr))) {
-+ fprintf(stderr, "Setting file creation context "
-+ "to \"%s\".\n", configuredsc);
-+ }
-+#endif
-+ if (setfscreatecon(configuredsc) != 0) {
-+ freecon(configuredsc);
-+ if (previous != NULL) {
-+ freecon(previous);
-+ }
-+ return NULL;
-+ }
-+ freecon(configuredsc);
-+#ifdef DEBUG
-+ } else {
-+ if (isatty(fileno(stderr))) {
-+ fprintf(stderr, "Unable to determine "
-+ "current context.\n");
-+ }
-+#endif
-+ }
-+ }
-+ return previous;
-+}
-+
-+static void
-+pop_fscreatecon(security_context_t previous)
-+{
-+ if (is_selinux_enabled()) {
-+#ifdef DEBUG
-+ if (isatty(fileno(stderr))) {
-+ if (previous != NULL) {
-+ fprintf(stderr, "Resetting file creation "
-+ "context to \"%s\".\n", previous);
-+ } else {
-+ fprintf(stderr, "Resetting file creation "
-+ "context to default.\n");
-+ }
-+ }
-+#endif
-+ setfscreatecon(previous);
-+ if (previous != NULL) {
-+ freecon(previous);
-+ }
-+ }
-+}
-+
-+void *
-+krb5int_push_fscreatecon_for(const char *pathname)
-+{
-+ struct stat st;
-+ void *retval;
-+ k5_once(&labeled_once, label_mutex_init);
-+ if (k5_mutex_lock(&labeled_mutex) == 0) {
-+ if (stat(pathname, &st) != 0) {
-+ st.st_mode = S_IRUSR | S_IWUSR;
-+ }
-+ retval = push_fscreatecon(pathname, st.st_mode);
-+ return retval ? retval : (void *) -1;
-+ } else {
-+ return NULL;
-+ }
-+}
-+
-+void
-+krb5int_pop_fscreatecon(void *con)
-+{
-+ if (con != NULL) {
-+ pop_fscreatecon((con == (void *) -1) ? NULL : con);
-+ k5_mutex_unlock(&labeled_mutex);
-+ }
-+}
-+
-+FILE *
-+krb5int_labeled_fopen(const char *path, const char *mode)
-+{
-+ FILE *fp;
-+ int errno_save;
-+ security_context_t ctx;
-+
-+ if ((strcmp(mode, "r") == 0) ||
-+ (strcmp(mode, "rb") == 0)) {
-+ return fopen(path, mode);
-+ }
-+
-+ k5_once(&labeled_once, label_mutex_init);
-+ if (k5_mutex_lock(&labeled_mutex) == 0) {
-+ ctx = push_fscreatecon(path, 0);
-+ fp = fopen(path, mode);
-+ errno_save = errno;
-+ pop_fscreatecon(ctx);
-+ k5_mutex_unlock(&labeled_mutex);
-+ errno = errno_save;
-+ } else {
-+ fp = fopen(path, mode);
-+ }
-+
-+ return fp;
-+}
-+
-+int
-+krb5int_labeled_creat(const char *path, mode_t mode)
-+{
-+ int fd;
-+ int errno_save;
-+ security_context_t ctx;
-+
-+ k5_once(&labeled_once, label_mutex_init);
-+ if (k5_mutex_lock(&labeled_mutex) == 0) {
-+ ctx = push_fscreatecon(path, 0);
-+ fd = creat(path, mode);
-+ errno_save = errno;
-+ pop_fscreatecon(ctx);
-+ k5_mutex_unlock(&labeled_mutex);
-+ errno = errno_save;
-+ } else {
-+ fd = creat(path, mode);
-+ }
-+ return fd;
-+}
-+
-+int
-+krb5int_labeled_mknod(const char *path, mode_t mode, dev_t dev)
-+{
-+ int ret;
-+ int errno_save;
-+ security_context_t ctx;
-+
-+ k5_once(&labeled_once, label_mutex_init);
-+ if (k5_mutex_lock(&labeled_mutex) == 0) {
-+ ctx = push_fscreatecon(path, mode);
-+ ret = mknod(path, mode, dev);
-+ errno_save = errno;
-+ pop_fscreatecon(ctx);
-+ k5_mutex_unlock(&labeled_mutex);
-+ errno = errno_save;
-+ } else {
-+ ret = mknod(path, mode, dev);
-+ }
-+ return ret;
-+}
-+
-+int
-+krb5int_labeled_mkdir(const char *path, mode_t mode)
-+{
-+ int ret;
-+ int errno_save;
-+ security_context_t ctx;
-+
-+ k5_once(&labeled_once, label_mutex_init);
-+ if (k5_mutex_lock(&labeled_mutex) == 0) {
-+ ctx = push_fscreatecon(path, S_IFDIR);
-+ ret = mkdir(path, mode);
-+ errno_save = errno;
-+ pop_fscreatecon(ctx);
-+ k5_mutex_unlock(&labeled_mutex);
-+ errno = errno_save;
-+ } else {
-+ ret = mkdir(path, mode);
-+ }
-+ return ret;
-+}
-+
-+int
-+krb5int_labeled_open(const char *path, int flags, ...)
-+{
-+ int fd;
-+ int errno_save;
-+ security_context_t ctx;
-+ mode_t mode;
-+ va_list ap;
-+
-+ if ((flags & O_CREAT) == 0) {
-+ return open(path, flags);
-+ }
-+
-+ k5_once(&labeled_once, label_mutex_init);
-+ if (k5_mutex_lock(&labeled_mutex) == 0) {
-+ ctx = push_fscreatecon(path, 0);
-+
-+ va_start(ap, flags);
-+ mode = va_arg(ap, mode_t);
-+ fd = open(path, flags, mode);
-+ va_end(ap);
-+
-+ errno_save = errno;
-+ pop_fscreatecon(ctx);
-+ k5_mutex_unlock(&labeled_mutex);
-+ errno = errno_save;
-+ } else {
-+ va_start(ap, flags);
-+ mode = va_arg(ap, mode_t);
-+ fd = open(path, flags, mode);
-+ errno_save = errno;
-+ va_end(ap);
-+ errno = errno_save;
-+ }
-+ return fd;
-+}
-+
-+#endif
---- krb5/src/lib/krb5/rcache/rc_dfl.c
-+++ krb5/src/lib/krb5/rcache/rc_dfl.c
-@@ -813,6 +813,9 @@ krb5_rc_dfl_expunge_locked(krb5_context
- krb5_error_code retval = 0;
- krb5_rcache tmp;
- krb5_deltat lifespan = t->lifespan; /* save original lifespan */
-+#ifdef USE_SELINUX
-+ void *selabel;
-+#endif
-
- if (! t->recovering) {
- name = t->name;
-@@ -834,7 +837,17 @@ krb5_rc_dfl_expunge_locked(krb5_context
- retval = krb5_rc_resolve(context, tmp, 0);
- if (retval)
- goto cleanup;
-+#ifdef USE_SELINUX
-+ if (t->d.fn != NULL)
-+ selabel = krb5int_push_fscreatecon_for(t->d.fn);
-+ else
-+ selabel = NULL;
-+#endif
- retval = krb5_rc_initialize(context, tmp, lifespan);
-+#ifdef USE_SELINUX
-+ if (selabel != NULL)
-+ krb5int_pop_fscreatecon(selabel);
-+#endif
- if (retval)
- goto cleanup;
- for (q = t->a; q; q = q->na) {
---- krb5/src/plugins/kdb/db2/kdb_db2.c
-+++ krb5/src/plugins/kdb/db2/kdb_db2.c
-@@ -683,8 +683,8 @@
- if (retval)
- return retval;
-
-- dbc->db_lf_file = open(dbc->db_lf_name, O_CREAT | O_RDWR | O_TRUNC,
-- 0600);
-+ dbc->db_lf_file = THREEPARAMOPEN(dbc->db_lf_name,
-+ O_CREAT | O_RDWR | O_TRUNC, 0600);
- if (dbc->db_lf_file < 0) {
- retval = errno;
- goto cleanup;
---- krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
-+++ krb5/src/plugins/kdb/db2/libdb2/recno/rec_open.c
-@@ -51,6 +51,7 @@
- #include <stdio.h>
- #include <unistd.h>
-
-+#include "k5-int.h"
- #include "db-int.h"
- #include "recno.h"
-
-@@ -68,7 +69,8 @@
- int rfd = -1, sverrno;
-
- /* Open the user's file -- if this fails, we're done. */
-- if (fname != NULL && (rfd = open(fname, flags | O_BINARY, mode)) < 0)
-+ if (fname != NULL &&
-+ (rfd = THREEPARAMOPEN(fname, flags | O_BINARY, mode)) < 0)
- return (NULL);
-
- if (fname != NULL && fcntl(rfd, F_SETFD, 1) == -1) {
---- krb5/src/kdc/main.c
-+++ krb5/src/kdc/main.c
-@@ -905,7 +905,7 @@ write_pid_file(const char *path)
- FILE *file;
- unsigned long pid;
-
-- file = fopen(path, "w");
-+ file = WRITABLEFOPEN(path, "w");
- if (file == NULL)
- return errno;
- pid = (unsigned long) getpid();
---- krb5/src/lib/kdb/kdb_log.c
-+++ krb5/src/lib/kdb/kdb_log.c
-@@ -566,7 +566,7 @@ ulog_map(krb5_context context, const cha
- return (errno);
- }
-
-- if ((ulogfd = open(logname, O_RDWR+O_CREAT, 0600)) == -1) {
-+ if ((ulogfd = THREEPARAMOPEN(logname, O_RDWR | O_CREAT, 0600)) == -1) {
- return (errno);
- }
-
---- krb5/src/util/gss-kernel-lib/Makefile.in
-+++ krb5/src/util/gss-kernel-lib/Makefile.in
-@@ -60,6 +60,7 @@ HEADERS= \
- gssapi_err_generic.h \
- k5-int.h \
- k5-int-pkinit.h \
-+ k5-label.h \
- k5-thread.h \
- k5-platform.h \
- k5-buf.h \
-@@ -166,10 +167,12 @@ gssapi_generic.h: $(GSS_GENERIC)/gssapi_
- $(CP) $(GSS_GENERIC)/gssapi_generic.h $@
- gssapi_err_generic.h: $(GSS_GENERIC_BUILD)/gssapi_err_generic.h
- $(CP) $(GSS_GENERIC_BUILD)/gssapi_err_generic.h $@
--k5-int.h: $(INCLUDE)/k5-int.h
-+k5-int.h: $(INCLUDE)/k5-int.h k5-label.h
- $(CP) $(INCLUDE)/k5-int.h $@
- k5-int-pkinit.h: $(INCLUDE)/k5-int-pkinit.h
- $(CP) $(INCLUDE)/k5-int-pkinit.h $@
-+k5-label.h: $(INCLUDE)/k5-label.h
-+ $(CP) $(INCLUDE)/k5-label.h $@
- k5-thread.h: $(INCLUDE)/k5-thread.h
- $(CP) $(INCLUDE)/k5-thread.h $@
- k5-platform.h: $(INCLUDE)/k5-platform.h
+++ /dev/null
-We want to be able to use --with-netlib and --enable-dns at the same time.
-RT#2022
---- krb5-1.3.1/src/aclocal.m4 2003-11-24 11:17:30.000000000 -0500
-+++ krb5-1.3.1/src/aclocal.m4 2003-11-24 11:18:45.000000000 -0500
-@@ -647,6 +647,7 @@
- LIBS="$LIBS $withval"
- AC_MSG_RESULT("netlib will use \'$withval\'")
- fi
-+ KRB5_AC_ENABLE_DNS
- ],dnl
- [AC_LIBRARY_NET]
- )])dnl
+++ /dev/null
-Use mktemp to create our temporary files instead of basing them on our PID.
-Only portable if you assume the presence of a mktemp helper.
-diff -ur krb5-1.3.4/src/util/send-pr/send-pr.sh krb5-1.3.4/src/util/send-pr/send-pr.sh
---- krb5-1.3.4/src/util/send-pr/send-pr.sh 1997-03-20 01:13:56.000000000 +0100
-+++ krb5-1.3.4/src/util/send-pr/send-pr.sh 2004-09-20 11:28:56.000000000 +0200
-@@ -96,9 +96,9 @@
- fi
- fi
-
--TEMP=$TMPDIR/p$$
--BAD=$TMPDIR/pbad$$
--REF=$TMPDIR/pf$$
-+TEMP=`mktemp "$TMPDIR"/p.XXXXXX` || exit 1
-+BAD=`mktemp "$TMPDIR"/pbad.XXXXXX` || exit 1
-+REF=`mktemp "$TMPDIR"/pf.XXXXXX` || exit 1
-
- # find a user name
- if [ "$LOGNAME" = "" ]; then
-@@ -122,9 +122,10 @@
- else
- # Must use temp file due to incompatibilities in quoting behavior
- # and to protect shell metacharacters in the expansion of $LOGNAME
-- $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP
-- ORIGINATOR="`cat $TEMP`"
-- rm -f $TEMP
-+ TEMP2=`mktemp "$TMPDIR"/plogname.XXXXXX` || exit 1
-+ $PASSWD | grep "^$LOGNAME:" | awk -F: '{print $5}' | sed -e 's/,.*//' > $TEMP2
-+ ORIGINATOR="`cat $TEMP2`"
-+ rm -f $TEMP2
- fi
-
- if [ -n "$ORGANIZATION" ]; then
-@@ -280,7 +281,7 @@
- # Catch some signals. ($xs kludge needed by Sun /bin/sh)
- xs=0
- trap 'rm -f $REF $TEMP; exit $xs' 0
--trap 'echo "$COMMAND: Aborting ..."; rm -f $REF $TEMP; xs=1; exit' 1 2 3 13 15
-+trap 'echo "$COMMAND: Aborting ..."; rm -f "$REF" "$BAD" "$TEMP"; xs=1; exit' 1 2 3 13 15
-
- # If they told us to use a specific file, then do so.
- if [ -n "$IN_FILE" ]; then
+++ /dev/null
-Provide an option to make the KDC also listen on loopback interfaces for
-datagram requests. Adds an internal symbol to libkrb5 which the KDC
-needs if listening on loopback is enabled.
-
-The default might be better changed from FALSE to TRUE so that the
-default matches what we do with stream sockets.
-
-FIXME: doesn't add documentation anywhere.
-
-diff -up src/include/foreachaddr.h src/include/foreachaddr.h
---- src/include/foreachaddr.h 2004-05-05 18:44:46.000000000 -0400
-+++ src/include/foreachaddr.h 2008-04-04 15:39:28.000000000 -0400
-@@ -62,3 +62,18 @@ krb5int_foreach_localaddr (/*@null@*/ vo
- ;
-
- #define foreach_localaddr krb5int_foreach_localaddr
-+
-+extern int
-+krb5int_foreach_localaddr_ext (/*@null@*/ void *data,
-+ int (*pass1fn) (/*@null@*/ void *,
-+ struct sockaddr *) /*@*/,
-+ /*@null@*/ krb5_boolean (*skipfn) (/*@null@*/ struct sockaddr *, int) /*@*/,
-+ /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
-+ /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
-+ struct sockaddr *) /*@*/)
-+#if defined(DEBUG) || defined(TEST)
-+ /*@modifies fileSystem@*/
-+#endif
-+ ;
-+
-+#define foreach_localaddr_ext krb5int_foreach_localaddr_ext
-diff -up src/kdc/kdc_util.h src/kdc/kdc_util.h
---- src/kdc/kdc_util.h 2008-04-04 16:28:18.000000000 -0400
-+++ src/kdc/kdc_util.h 2008-04-04 16:51:27.000000000 -0400
-@@ -126,6 +126,7 @@ krb5_error_code kdc_initialize_rcache (k
- krb5_error_code setup_server_realm (krb5_principal);
-
- /* network.c */
-+void process_listen_loopback (krb5_boolean);
- krb5_error_code listen_and_process (const char *);
- krb5_error_code setup_network (const char *);
- krb5_error_code closedown_network (const char *);
-diff -up src/kdc/main.c src/kdc/main.c
---- src/kdc/main.c 2008-04-04 16:22:43.000000000 -0400
-+++ src/kdc/main.c 2008-04-04 16:55:22.000000000 -0400
-@@ -422,6 +422,7 @@ initialize_realms(krb5_context kcontext,
- krb5_enctype menctype = ENCTYPE_UNKNOWN;
- kdc_realm_t *rdatap;
- krb5_boolean manual = FALSE;
-+ krb5_boolean listen_loopback = FALSE;
- char *default_udp_ports = 0;
- char *default_tcp_ports = 0;
- krb5_pointer aprof;
-@@ -448,6 +449,9 @@ initialize_realms(krb5_context kcontext,
- if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode))
- v4mode = 0;
- #endif
-+ hierarchy[1] = "kdc_listen_loopback";
-+ if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &listen_loopback))
-+ listen_loopback = FALSE;
- /* aprof_init can return 0 with aprof == NULL */
- if (aprof)
- krb5_aprof_finish(aprof);
-@@ -587,6 +591,8 @@ initialize_realms(krb5_context kcontext,
- free(v4mode);
- #endif
-
-+ process_listen_loopback(listen_loopback);
-+
- /*
- * Check to see if we processed any realms.
- */
-diff -up src/kdc/network.c src/kdc/network.c
---- src/kdc/network.c 2008-04-04 15:39:28.000000000 -0400
-+++ src/kdc/network.c 2008-04-04 16:51:44.000000000 -0400
-@@ -221,6 +221,7 @@ static SET(u_short) udp_port_data, tcp_p
- #include "cm.h"
-
- static struct select_state sstate;
-+static krb5_boolean listen_loopback;
-
- static krb5_error_code add_udp_port(int port)
- {
-@@ -604,6 +605,12 @@ scan_for_newlines:
- }
- #endif
-
-+void
-+process_listen_loopback(krb5_boolean listen_loop)
-+{
-+ listen_loopback = listen_loop;
-+}
-+
- /* XXX */
- extern int krb5int_debug_sendto_kdc;
- extern void (*krb5int_sendtokdc_debug_handler)(const void*, size_t);
-@@ -662,7 +669,9 @@ setup_network(const char *prog)
- so we might need only one UDP socket; fall back to binding
- sockets on each address only if IPV6_PKTINFO isn't
- supported. */
-- if (foreach_localaddr (&setup_data, setup_udp_port, 0, 0)) {
-+ if (listen_loopback ?
-+ foreach_localaddr_ext (&setup_data, setup_udp_port, 0, 0, 0) :
-+ foreach_localaddr (&setup_data, setup_udp_port, 0, 0)) {
- return setup_data.retval;
- }
- setup_tcp_listener_ports(&setup_data);
-diff -up src/lib/krb5/os/localaddr.c src/lib/krb5/os/localaddr.c
---- src/lib/krb5/os/localaddr.c 2005-04-13 12:55:43.000000000 -0400
-+++ src/lib/krb5/os/localaddr.c 2008-04-04 15:39:28.000000000 -0400
-@@ -242,6 +242,17 @@ addr_eq (const struct sockaddr *s1, cons
- }
- #endif
-
-+static krb5_boolean
-+skip_loopback (struct sockaddr *addr, int flags)
-+{
-+#ifdef IFF_LOOPBACK
-+ if (flags & IFF_LOOPBACK) {
-+ return TRUE;
-+ }
-+#endif
-+ return FALSE;
-+}
-+
- #ifndef HAVE_IFADDRS_H
- /*@-usereleased@*/ /* lclint doesn't understand realloc */
- static /*@null@*/ void *
-@@ -413,14 +424,27 @@ get_linux_ipv6_addrs ()
- indication, it should do it via some field pointed to by the DATA
- argument. */
-
--#ifdef HAVE_IFADDRS_H
--
- int
- foreach_localaddr (/*@null@*/ void *data,
- int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
- /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
- /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
- struct sockaddr *) /*@*/)
-+{
-+ return foreach_localaddr_ext(data, pass1fn,
-+ &skip_loopback, betweenfn,
-+ pass2fn);
-+}
-+
-+#ifdef HAVE_IFADDRS_H
-+
-+int
-+foreach_localaddr_ext (/*@null@*/ void *data,
-+ int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
-+ /*@null@*/ krb5_boolean (*skipfn) (/*@null@*/ struct sockaddr *, int) /*@*/,
-+ /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
-+ /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
-+ struct sockaddr *) /*@*/)
- #if defined(DEBUG) || defined(TEST)
- /*@modifies fileSystem@*/
- #endif
-@@ -436,7 +460,7 @@ foreach_localaddr (/*@null@*/ void *data
- #endif
- if ((ifp->ifa_flags & IFF_UP) == 0)
- continue;
-- if (ifp->ifa_flags & IFF_LOOPBACK) {
-+ if (skipfn && (*skipfn)(ifp->ifa_addr, ifp->ifa_flags)) {
- /* Pretend it's not up, so the second pass will skip
- it. */
- ifp->ifa_flags &= ~IFF_UP;
-@@ -459,7 +483,7 @@ foreach_localaddr (/*@null@*/ void *data
- for (ifp2 = ifp_head; ifp2 && ifp2 != ifp; ifp2 = ifp2->ifa_next) {
- if ((ifp2->ifa_flags & IFF_UP) == 0)
- continue;
-- if (ifp2->ifa_flags & IFF_LOOPBACK)
-+ if (skipfn && (*skipfn)(ifp2->ifa_addr, ifp2->ifa_flags))
- continue;
- if (addr_eq (ifp->ifa_addr, ifp2->ifa_addr)) {
- match = 1;
-@@ -488,11 +512,12 @@ foreach_localaddr (/*@null@*/ void *data
- #elif defined (SIOCGLIFNUM) && defined(HAVE_STRUCT_LIFCONF) /* Solaris 8 and later; Sol 7? */
-
- int
--foreach_localaddr (/*@null@*/ void *data,
-- int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
-- /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
-- /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
-- struct sockaddr *) /*@*/)
-+foreach_localaddr_ext (/*@null@*/ void *data,
-+ int (*pass1fn) (/*@null@*/ void *, struct sockaddr *) /*@*/,
-+ /*@null@*/ int (*skipfn) (/*@null@*/ struct sockaddr *, int) /*@*/,
-+ /*@null@*/ int (*betweenfn) (/*@null@*/ void *) /*@*/,
-+ /*@null@*/ int (*pass2fn) (/*@null@*/ void *,
-+ struct sockaddr *) /*@*/)
- #if defined(DEBUG) || defined(TEST)
- /*@modifies fileSystem@*/
- #endif
-@@ -583,13 +608,12 @@ foreach_localaddr (/*@null@*/ void *data
- }
- /*@=moduncon@*/
-
--#ifdef IFF_LOOPBACK
-- /* None of the current callers want loopback addresses. */
-- if (lifreq.lifr_flags & IFF_LOOPBACK) {
-- Tprintf ((" loopback\n"));
-+ if (skipfn && (*skipfn)(lifreq.lifr_addr, lifreq.lifr_flags))
-+ if (skipfn && (skipfn == &skip_loopback))
-+ Tprintf ((" loopback\n"));
- goto skip;
- }
--#endif
-+
- /* Ignore interfaces that are down. */
- if ((lifreq.lifr_flags & IFF_UP) == 0) {
- Tprintf ((" down\n"));
-@@ -755,13 +779,12 @@ foreach_localaddr (/*@null@*/ void *data
- }
- /*@=moduncon@*/
-
--#ifdef IFF_LOOPBACK
- /* None of the current callers want loopback addresses. */
-- if (lifreq.iflr_flags & IFF_LOOPBACK) {
-- Tprintf ((" loopback\n"));
-+ if (skipfn && (*skipfn)(ifp2->ifa_addr, lifreq.lifr_flags))
-+ if (skipfn && (skipfn == &skip_loopback))
-+ Tprintf ((" loopback\n"));
- goto skip;
- }
--#endif
- /* Ignore interfaces that are down. */
- if ((lifreq.iflr_flags & IFF_UP) == 0) {
- Tprintf ((" down\n"));
-@@ -971,13 +994,12 @@ foreach_localaddr (/*@null@*/ void *data
- }
- /*@=moduncon@*/
-
--#ifdef IFF_LOOPBACK
-- /* None of the current callers want loopback addresses. */
-- if (ifreq.ifr_flags & IFF_LOOPBACK) {
-- Tprintf ((" loopback\n"));
-+ if (skipfn && (*skipfn)(NULL, ifreq.ifr_flags))
-+ if (skipfn && (skipfn == &skip_loopback))
-+ Tprintf ((" loopback\n"));
- goto skip;
- }
--#endif
-+
- /* Ignore interfaces that are down. */
- if ((ifreq.ifr_flags & IFF_UP) == 0) {
- Tprintf ((" down\n"));
+++ /dev/null
-Adds an "ANY" keytab type which is a list of other keytab locations to search
-when searching for a specific entry. When iterated through, it only presents
-the contents of the first keytab.
-
-diff -up /dev/null krb5-1.7/src/lib/krb5/keytab/kt_any.c
---- /dev/null 2009-06-04 10:34:55.169007373 -0400
-+++ krb5-1.7/src/lib/krb5/keytab/kt_any.c 2009-06-04 13:54:36.000000000 -0400
-@@ -0,0 +1,292 @@
-+/*
-+ * lib/krb5/keytab/kt_any.c
-+ *
-+ * Copyright 1998, 1999 by the Massachusetts Institute of Technology.
-+ * All Rights Reserved.
-+ *
-+ * Export of this software from the United States of America may
-+ * require a specific license from the United States Government.
-+ * It is the responsibility of any person or organization contemplating
-+ * export to obtain such a license before exporting.
-+ *
-+ * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
-+ * distribute this software and its documentation for any purpose and
-+ * without fee is hereby granted, provided that the above copyright
-+ * notice appear in all copies and that both that copyright notice and
-+ * this permission notice appear in supporting documentation, and that
-+ * the name of M.I.T. not be used in advertising or publicity pertaining
-+ * to distribution of the software without specific, written prior
-+ * permission. M.I.T. makes no representations about the suitability of
-+ * this software for any purpose. It is provided "as is" without express
-+ * or implied warranty.
-+ *
-+ *
-+ * krb5_kta_ops
-+ */
-+
-+#include "k5-int.h"
-+
-+typedef struct _krb5_ktany_data {
-+ char *name;
-+ krb5_keytab *choices;
-+ int nchoices;
-+} krb5_ktany_data;
-+
-+typedef struct _krb5_ktany_cursor_data {
-+ int which;
-+ krb5_kt_cursor cursor;
-+} krb5_ktany_cursor_data;
-+
-+static krb5_error_code krb5_ktany_resolve
-+ (krb5_context,
-+ const char *,
-+ krb5_keytab *);
-+static krb5_error_code krb5_ktany_get_name
-+ (krb5_context context,
-+ krb5_keytab id,
-+ char *name,
-+ unsigned int len);
-+static krb5_error_code krb5_ktany_close
-+ (krb5_context context,
-+ krb5_keytab id);
-+static krb5_error_code krb5_ktany_get_entry
-+ (krb5_context context,
-+ krb5_keytab id,
-+ krb5_const_principal principal,
-+ krb5_kvno kvno,
-+ krb5_enctype enctype,
-+ krb5_keytab_entry *entry);
-+static krb5_error_code krb5_ktany_start_seq_get
-+ (krb5_context context,
-+ krb5_keytab id,
-+ krb5_kt_cursor *cursorp);
-+static krb5_error_code krb5_ktany_next_entry
-+ (krb5_context context,
-+ krb5_keytab id,
-+ krb5_keytab_entry *entry,
-+ krb5_kt_cursor *cursor);
-+static krb5_error_code krb5_ktany_end_seq_get
-+ (krb5_context context,
-+ krb5_keytab id,
-+ krb5_kt_cursor *cursor);
-+static void cleanup
-+ (krb5_context context,
-+ krb5_ktany_data *data,
-+ int nchoices);
-+
-+struct _krb5_kt_ops krb5_kta_ops = {
-+ 0,
-+ "ANY", /* Prefix -- this string should not appear anywhere else! */
-+ krb5_ktany_resolve,
-+ krb5_ktany_get_name,
-+ krb5_ktany_close,
-+ krb5_ktany_get_entry,
-+ krb5_ktany_start_seq_get,
-+ krb5_ktany_next_entry,
-+ krb5_ktany_end_seq_get,
-+ NULL,
-+ NULL,
-+ NULL,
-+};
-+
-+static krb5_error_code
-+krb5_ktany_resolve(context, name, id)
-+ krb5_context context;
-+ const char *name;
-+ krb5_keytab *id;
-+{
-+ const char *p, *q;
-+ char *copy;
-+ krb5_error_code kerror;
-+ krb5_ktany_data *data;
-+ int i;
-+
-+ /* Allocate space for our data and remember a copy of the name. */
-+ if ((data = (krb5_ktany_data *)malloc(sizeof(krb5_ktany_data))) == NULL)
-+ return(ENOMEM);
-+ if ((data->name = (char *)malloc(strlen(name) + 1)) == NULL) {
-+ krb5_xfree(data);
-+ return(ENOMEM);
-+ }
-+ strcpy(data->name, name);
-+
-+ /* Count the number of choices and allocate memory for them. */
-+ data->nchoices = 1;
-+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1)
-+ data->nchoices++;
-+ if ((data->choices = (krb5_keytab *)
-+ malloc(data->nchoices * sizeof(krb5_keytab))) == NULL) {
-+ krb5_xfree(data->name);
-+ krb5_xfree(data);
-+ return(ENOMEM);
-+ }
-+
-+ /* Resolve each of the choices. */
-+ i = 0;
-+ for (p = name; (q = strchr(p, ',')) != NULL; p = q + 1) {
-+ /* Make a copy of the choice name so we can terminate it. */
-+ if ((copy = (char *)malloc(q - p + 1)) == NULL) {
-+ cleanup(context, data, i);
-+ return(ENOMEM);
-+ }
-+ memcpy(copy, p, q - p);
-+ copy[q - p] = 0;
-+
-+ /* Try resolving the choice name. */
-+ kerror = krb5_kt_resolve(context, copy, &data->choices[i]);
-+ krb5_xfree(copy);
-+ if (kerror) {
-+ cleanup(context, data, i);
-+ return(kerror);
-+ }
-+ i++;
-+ }
-+ if ((kerror = krb5_kt_resolve(context, p, &data->choices[i]))) {
-+ cleanup(context, data, i);
-+ return(kerror);
-+ }
-+
-+ /* Allocate and fill in an ID for the caller. */
-+ if ((*id = (krb5_keytab)malloc(sizeof(**id))) == NULL) {
-+ cleanup(context, data, i);
-+ return(ENOMEM);
-+ }
-+ (*id)->ops = &krb5_kta_ops;
-+ (*id)->data = (krb5_pointer)data;
-+ (*id)->magic = KV5M_KEYTAB;
-+
-+ return(0);
-+}
-+
-+static krb5_error_code
-+krb5_ktany_get_name(context, id, name, len)
-+ krb5_context context;
-+ krb5_keytab id;
-+ char *name;
-+ unsigned int len;
-+{
-+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
-+
-+ if (len < strlen(data->name) + 1)
-+ return(KRB5_KT_NAME_TOOLONG);
-+ strcpy(name, data->name);
-+ return(0);
-+}
-+
-+static krb5_error_code
-+krb5_ktany_close(context, id)
-+ krb5_context context;
-+ krb5_keytab id;
-+{
-+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
-+
-+ cleanup(context, data, data->nchoices);
-+ id->ops = 0;
-+ krb5_xfree(id);
-+ return(0);
-+}
-+
-+static krb5_error_code
-+krb5_ktany_get_entry(context, id, principal, kvno, enctype, entry)
-+ krb5_context context;
-+ krb5_keytab id;
-+ krb5_const_principal principal;
-+ krb5_kvno kvno;
-+ krb5_enctype enctype;
-+ krb5_keytab_entry *entry;
-+{
-+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
-+ krb5_error_code kerror = KRB5_KT_NOTFOUND;
-+ int i;
-+
-+ for (i = 0; i < data->nchoices; i++) {
-+ if ((kerror = krb5_kt_get_entry(context, data->choices[i], principal,
-+ kvno, enctype, entry)) != ENOENT)
-+ return kerror;
-+ }
-+ return kerror;
-+}
-+
-+static krb5_error_code
-+krb5_ktany_start_seq_get(context, id, cursorp)
-+ krb5_context context;
-+ krb5_keytab id;
-+ krb5_kt_cursor *cursorp;
-+{
-+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
-+ krb5_ktany_cursor_data *cdata;
-+ krb5_error_code kerror = ENOENT;
-+ int i;
-+
-+ if ((cdata = (krb5_ktany_cursor_data *)
-+ malloc(sizeof(krb5_ktany_cursor_data))) == NULL)
-+ return(ENOMEM);
-+
-+ /* Find a choice which can handle the serialization request. */
-+ for (i = 0; i < data->nchoices; i++) {
-+ if ((kerror = krb5_kt_start_seq_get(context, data->choices[i],
-+ &cdata->cursor)) == 0)
-+ break;
-+ else if (kerror != ENOENT) {
-+ krb5_xfree(cdata);
-+ return(kerror);
-+ }
-+ }
-+
-+ if (i == data->nchoices) {
-+ /* Everyone returned ENOENT, so no go. */
-+ krb5_xfree(cdata);
-+ return(kerror);
-+ }
-+
-+ cdata->which = i;
-+ *cursorp = (krb5_kt_cursor)cdata;
-+ return(0);
-+}
-+
-+static krb5_error_code
-+krb5_ktany_next_entry(context, id, entry, cursor)
-+ krb5_context context;
-+ krb5_keytab id;
-+ krb5_keytab_entry *entry;
-+ krb5_kt_cursor *cursor;
-+{
-+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
-+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
-+ krb5_keytab choice_id;
-+
-+ choice_id = data->choices[cdata->which];
-+ return(krb5_kt_next_entry(context, choice_id, entry, &cdata->cursor));
-+}
-+
-+static krb5_error_code
-+krb5_ktany_end_seq_get(context, id, cursor)
-+ krb5_context context;
-+ krb5_keytab id;
-+ krb5_kt_cursor *cursor;
-+{
-+ krb5_ktany_data *data = (krb5_ktany_data *)id->data;
-+ krb5_ktany_cursor_data *cdata = (krb5_ktany_cursor_data *)*cursor;
-+ krb5_keytab choice_id;
-+ krb5_error_code kerror;
-+
-+ choice_id = data->choices[cdata->which];
-+ kerror = krb5_kt_end_seq_get(context, choice_id, &cdata->cursor);
-+ krb5_xfree(cdata);
-+ return(kerror);
-+}
-+
-+static void
-+cleanup(context, data, nchoices)
-+ krb5_context context;
-+ krb5_ktany_data *data;
-+ int nchoices;
-+{
-+ int i;
-+
-+ krb5_xfree(data->name);
-+ for (i = 0; i < nchoices; i++)
-+ krb5_kt_close(context, data->choices[i]);
-+ krb5_xfree(data->choices);
-+ krb5_xfree(data);
-+}
-diff -up krb5-1.7/src/lib/krb5/keytab/ktbase.c krb5-1.7/src/lib/krb5/keytab/ktbase.c
---- krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-02-18 13:18:56.000000000 -0500
-+++ krb5-1.7/src/lib/krb5/keytab/ktbase.c 2009-06-04 13:54:36.000000000 -0400
-@@ -59,14 +59,19 @@ extern const krb5_kt_ops krb5_ktf_ops;
- extern const krb5_kt_ops krb5_ktf_writable_ops;
- extern const krb5_kt_ops krb5_kts_ops;
- extern const krb5_kt_ops krb5_mkt_ops;
-+extern const krb5_kt_ops krb5_kta_ops;
-
- struct krb5_kt_typelist {
- const krb5_kt_ops *ops;
- const struct krb5_kt_typelist *next;
- };
-+static struct krb5_kt_typelist krb5_kt_typelist_any = {
-+ &krb5_kta_ops,
-+ NULL
-+};
- const static struct krb5_kt_typelist krb5_kt_typelist_srvtab = {
- &krb5_kts_ops,
-- NULL
-+ &krb5_kt_typelist_any
- };
- const static struct krb5_kt_typelist krb5_kt_typelist_memory = {
- &krb5_mkt_ops,
-diff -up krb5-1.7/src/lib/krb5/keytab/Makefile.in krb5-1.7/src/lib/krb5/keytab/Makefile.in
---- krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-01-05 15:27:53.000000000 -0500
-+++ krb5-1.7/src/lib/krb5/keytab/Makefile.in 2009-06-04 13:54:36.000000000 -0400
-@@ -19,6 +19,7 @@ STLIBOBJS= \
- ktfr_entry.o \
- ktremove.o \
- ktfns.o \
-+ kt_any.o \
- kt_file.o \
- kt_memory.o \
- kt_srvtab.o \
-@@ -31,6 +32,7 @@ OBJS= \
- $(OUTPRE)ktfr_entry.$(OBJEXT) \
- $(OUTPRE)ktremove.$(OBJEXT) \
- $(OUTPRE)ktfns.$(OBJEXT) \
-+ $(OUTPRE)kt_any.$(OBJEXT) \
- $(OUTPRE)kt_file.$(OBJEXT) \
- $(OUTPRE)kt_memory.$(OBJEXT) \
- $(OUTPRE)kt_srvtab.$(OBJEXT) \
-@@ -43,6 +45,7 @@ SRCS= \
- $(srcdir)/ktfr_entry.c \
- $(srcdir)/ktremove.c \
- $(srcdir)/ktfns.c \
-+ $(srcdir)/kt_any.c \
- $(srcdir)/kt_file.c \
- $(srcdir)/kt_memory.c \
- $(srcdir)/kt_srvtab.c \
+++ /dev/null
-Reference docs don't define what happens if you call krb5_realm_compare() with
-malformed krb5_principal structures. Define a behavior which keeps it from
-crashing if applications don't check ahead of time.
-
-diff -up krb5-1.8/src/lib/krb5/krb/princ_comp.c.api krb5-1.8/src/lib/krb5/krb/princ_comp.c
---- krb5-1.8/src/lib/krb5/krb/princ_comp.c.api 2009-10-30 20:48:38.000000000 -0400
-+++ krb5-1.8/src/lib/krb5/krb/princ_comp.c 2010-03-05 11:00:55.000000000 -0500
-@@ -41,6 +41,12 @@ realm_compare_flags(krb5_context context
- const krb5_data *realm1 = krb5_princ_realm(context, princ1);
- const krb5_data *realm2 = krb5_princ_realm(context, princ2);
-
-+ if ((princ1 == NULL) || (princ2 == NULL))
-+ return FALSE;
-+
-+ if ((realm1 == NULL) || (realm2 == NULL))
-+ return FALSE;
-+
- if (realm1->length != realm2->length)
- return FALSE;
-
-@@ -92,6 +98,9 @@ krb5_principal_compare_flags(krb5_contex
- krb5_principal upn2 = NULL;
- krb5_boolean ret = FALSE;
-
-+ if ((princ1 == NULL) || (princ2 == NULL))
-+ return FALSE;
-+
- if (flags & KRB5_PRINCIPAL_COMPARE_ENTERPRISE) {
- /* Treat UPNs as if they were real principals */
- if (krb5_princ_type(context, princ1) == KRB5_NT_ENTERPRISE_PRINCIPAL) {
+++ /dev/null
-We want to keep these y.tab.c files around because the debuginfo points to
-them. It would be more elegant at the end to use symbolic links, but that
-could mess up people working in the tree on other things.
-
---- src/kadmin/cli/Makefile.in
-+++ src/kadmin/cli/Makefile.in
-@@ -43,3 +43,8 @@ clean-unix::
- # CC_LINK is not meant for compilation and this use may break in the future.
- datetest: getdate.c
- $(CC_LINK) $(ALL_CFLAGS) -DTEST -o datetest getdate.c
-+
-+%.c: %.y
-+ $(RM) y.tab.c $@
-+ $(YACC.y) $<
-+ $(CP) y.tab.c $@
---- src/plugins/kdb/ldap/ldap_util/Makefile.in
-+++ src/plugins/kdb/ldap/ldap_util/Makefile.in
-@@ -22,7 +22,7 @@ $(PROG): $(OBJS) $(KADMSRV_DEPLIBS) $(KR
- getdate.c: $(GETDATE)
- $(RM) getdate.c y.tab.c
- $(YACC) $(GETDATE)
-- $(MV) y.tab.c getdate.c
-+ $(CP) y.tab.c getdate.c
-
- install::
- $(INSTALL_PROGRAM) $(PROG) ${DESTDIR}$(ADMIN_BINDIR)/$(PROG)
+++ /dev/null
-Treat 'nsAccountLock: true' the same as 'loginDisabled: true'. Updated from
-original version filed as RT#5891.
-
-diff -up krb5-1.8/src/aclocal.m4.dirsrv-accountlock krb5-1.8/src/aclocal.m4
---- krb5-1.8/src/aclocal.m4.dirsrv-accountlock 2010-03-05 11:03:09.000000000 -0500
-+++ krb5-1.8/src/aclocal.m4 2010-03-05 11:03:10.000000000 -0500
-@@ -1678,6 +1678,12 @@ AC_ARG_WITH([edirectory],
- yes | no) ;;
- *) AC_MSG_ERROR(Invalid option value --with-edirectory="$withval") ;;
- esac], with_edirectory=no)dnl
-+AC_ARG_WITH([dirsrv],
-+[ --with-dirsrv compile 389/Red Hat/Fedora/Netscape Directory Server database backend module],
-+[case "$withval" in
-+ yes | no) ;;
-+ *) AC_MSG_ERROR(Invalid option value --with-dirsrv="$withval") ;;
-+esac], with_dirsrv=no)dnl
-
- if test $with_ldap = yes; then
- if test $with_edirectory = yes; then
-@@ -1689,6 +1695,10 @@ elif test $with_edirectory = yes; then
- AC_MSG_NOTICE(enabling eDirectory database backend module support)
- OPENLDAP_PLUGIN=yes
- AC_DEFINE(HAVE_EDIRECTORY,1,[Define if LDAP KDB interface should assume eDirectory.])
-+elif test $with_dirsrv = yes; then
-+ AC_MSG_NOTICE(enabling 389/Red Hat/Fedora/Netscape Directory Server database backend module support)
-+ OPENLDAP_PLUGIN=yes
-+ AC_DEFINE(HAVE_DIRSRV,1,[Define if LDAP KDB interface should assume RHDS/FDS/NDS.])
- else
- : # neither enabled
- dnl AC_MSG_NOTICE(disabling ldap backend module support)
-diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500
-+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c 2010-03-05 11:03:10.000000000 -0500
-@@ -2101,6 +2101,22 @@ populate_krb5_db_entry(krb5_context cont
- }
- }
- #endif
-+#ifdef HAVE_DIRSRV
-+ {
-+ krb5_timestamp expiretime=0;
-+ char *is_login_disabled=NULL;
-+
-+ /* LOGIN DISABLED */
-+ if ((st=krb5_ldap_get_string(ld, ent, "nsaccountlock", &is_login_disabled,
-+ &attr_present)) != 0)
-+ goto cleanup;
-+ if (attr_present == TRUE) {
-+ if (strcasecmp(is_login_disabled, "TRUE")== 0)
-+ entry->attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
-+ free (is_login_disabled);
-+ }
-+ }
-+#endif
-
- if ((st=krb5_read_tkt_policy (context, ldap_context, entry, tktpolname)) !=0)
- goto cleanup;
-diff -up krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
---- krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c.dirsrv-accountlock 2009-11-24 18:52:25.000000000 -0500
-+++ krb5-1.8/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c 2010-03-05 11:03:10.000000000 -0500
-@@ -59,6 +59,9 @@ char *principal_attributes[] = { "kr
- "loginexpirationtime",
- "logindisabled",
- #endif
-+#ifdef HAVE_DIRSRV
-+ "nsaccountlock",
-+#endif
- "krbLastPwdChange",
- "krbLastAdminUnlock",
- "krbExtraData",
+++ /dev/null
-From patch attached to http://krbdev.mit.edu/rt/Ticket/Display.html?id=3349,
-at http://krbdev.mit.edu/rt/Ticket/Attachment/23851/13214/kvno.diff, adjusted
-as needed to apply to 1.10. FIXME: I'd like to better handle cases where we
-have a new key with the right version stored later in the keytab file.
-Currently, we're setting up to overlook that possibility.
-
-Note that this only affects the path taken when krb5_rd_rep() is passed a
-server principal name, as without a server principal name it already tries
-all of the keys it finds in the keytab, regardless of version numbers.
-
-Index: krb5/src/kadmin/ktutil/ktutil.c
-===================================================================
---- krb5/src/kadmin/ktutil/ktutil.c (revision 3367)
-+++ krb5/src/kadmin/ktutil/ktutil.c (working copy)
-@@ -155,7 +155,7 @@
- char *princ = NULL;
- char *enctype = NULL;
- krb5_kvno kvno = 0;
-- int use_pass = 0, use_key = 0, i;
-+ int use_pass = 0, use_key = 0, use_kvno = 0, i;
-
- for (i = 1; i < argc; i++) {
- if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-p", 2)) {
-@@ -164,6 +164,7 @@
- }
- if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-k", 2)) {
- kvno = (krb5_kvno) atoi(argv[++i]);
-+ use_kvno++;
- continue;
- }
- if ((strlen(argv[i]) == 2) && !strncmp(argv[i], "-e", 2)) {
-@@ -180,7 +181,7 @@
- }
- }
-
-- if (argc != 8 || !(princ && kvno && enctype) || (use_pass+use_key != 1)) {
-+ if (argc != 8 || !(princ && use_kvno && enctype) || (use_pass+use_key != 1)) {
- fprintf(stderr, _("usage: %s (-key | -password) -p principal "
- "-k kvno -e enctype\n"), argv[0]);
- return;
-Index: krb5/src/lib/krb5/keytab/kt_file.c
-===================================================================
---- krb5/src/lib/krb5/keytab/kt_file.c (revision 3367)
-+++ krb5/src/lib/krb5/keytab/kt_file.c (working copy)
-@@ -349,7 +349,7 @@
- higher than that. Short-term workaround: only compare
- the low 8 bits. */
-
-- if (new_entry.vno == (kvno & 0xff)) {
-+ if (new_entry.vno == (kvno & 0xff) || new_entry.vno == IGNORE_VNO) {
- krb5_kt_free_entry(context, &cur_entry);
- cur_entry = new_entry;
- break;
+++ /dev/null
-#!/bin/sh
-
-# Based on Enrico's snippet for using pdflatex for building PDFs, except we're
-# switching to pregenerating the docs for the SRPM so that we don't get
-# different contents when we build on multiple build machines and architectures
-# (timestamps and IDs change, and even some of the compressed content looks
-# different). The filename and checksum are used to verify that the PDF always
-# matches the doc which was used to generate it, and we flag an error if that
-# isn't the case.
-
-create() {
- pushd "$1" > /dev/null
- touch "$2".ind
- pdflatex "$2"
- test ! -e "$2".idx || makeindex ${3:+-s "$3".ist} "$2".idx
- pdflatex "$2"
- pdflatex "$2"
- sum=`sha1sum "$2".tex | sed 's,[[:blank:]].*,,g'`
- sed -ri \
- -e 's|^/ID \[<.{32}> <.{32}>\]|/ID [<'"$1/$2"'> <'"$sum"'>]|g' \
- "$2".pdf
- popd > /dev/null
-}
-
-check() {
- pushd "$1" > /dev/null
- sum=`sha1sum "$2".tex | sed 's, .*,,g'`
- id=`sed -rn -e '/^\/ID \[<[^>]*> <[^>]*>\]/p' "$2".pdf`
- filename=`echo "$id" | sed -r 's|^.*\[<([^>]*)> <([^>]*)>\].*|\1|g'`
- checksum=`echo "$id" | sed -r 's|^.*\[<([^>]*)> <([^>]*)>\].*|\2|g'`
- echo $filename
- echo $checksum $sum
- popd > /dev/null
- test "$filename" = "$1/$2" && test "$checksum" = "$sum"
-}
-
-mode=$1
-case $mode in
- create)
- while read subdir doc style ; do
- if ! create $subdir $doc $style ; then
- exit 1
- fi
- done
- ;;
- check)
- while read subdir doc style ; do
- if ! check $subdir $doc $style ; then
- exit 1
- fi
- done
- ;;
-esac
-
-exit 0
+++ /dev/null
-commit 9dc75551cb8cc4c03f7e0fe5e8a705ed678079f4
-Author: ghudson <ghudson@dc483132-0cff-0310-8789-dd5450dbe970>
-Date: Wed Dec 7 19:38:13 2011 +0000
-
- ticket: 7046
- subject: Allow S4U2Proxy delegated credentials to be saved
-
- The initial implementation of client-side S4U2Proxy support did not
- allow delegated proxy credentials to be stored (gss_store_cred would
- error out, and gss_krb5_copy_ccache would generate a non-working
- cache). To make this work, we save the impersonator name in a cache
- config variable and in a cred structure field (replacing the
- proxy_cred flag), and make the default principal of the proxy cache
- the subject principal as the caller would expect for a regular
- delegated cred.
-
- git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25529 dc483132-0cff-0310-8789-dd5450dbe970
-
-diff --git a/src/include/k5-int.h b/src/include/k5-int.h
-index 514e2ea..b25c159 100644
---- a/src/include/k5-int.h
-+++ b/src/include/k5-int.h
-@@ -273,7 +273,10 @@ typedef INT64_TYPE krb5_int64;
- #define KRB5_CONF_V4_INSTANCE_CONVERT "v4_instance_convert"
- #define KRB5_CONF_V4_REALM "v4_realm"
- #define KRB5_CONF_ASTERISK "*"
-+
-+/* Cache configuration variables */
- #define KRB5_CONF_FAST_AVAIL "fast_avail"
-+#define KRB5_CONF_PROXY_IMPERSONATOR "proxy_impersonator"
-
- /* Error codes used in KRB_ERROR protocol messages.
- Return values of library routines are based on a different error table
-diff --git a/src/lib/gssapi/krb5/acquire_cred.c b/src/lib/gssapi/krb5/acquire_cred.c
-index c815b35..c08e059 100644
---- a/src/lib/gssapi/krb5/acquire_cred.c
-+++ b/src/lib/gssapi/krb5/acquire_cred.c
-@@ -417,6 +417,34 @@ prep_ccache(krb5_context context, krb5_gss_cred_id_rec *cred,
- return 0;
- }
-
-+/* If an impersonator config entry exists in ccache, set *impersonator_out to
-+ * the parsed principal. Otherwise set *impersonator_out to NULL. */
-+static krb5_error_code
-+get_impersonator(krb5_context context, krb5_ccache ccache,
-+ krb5_principal *impersonator_out)
-+{
-+ krb5_error_code code;
-+ krb5_data data = empty_data(), data0 = empty_data();
-+
-+ *impersonator_out = NULL;
-+
-+ code = krb5_cc_get_config(context, ccache, NULL,
-+ KRB5_CONF_PROXY_IMPERSONATOR, &data);
-+ if (code)
-+ return (code == KRB5_CC_NOTFOUND) ? 0 : code;
-+
-+ code = krb5int_copy_data_contents_add0(context, &data, &data0);
-+ if (code)
-+ goto cleanup;
-+
-+ code = krb5_parse_name(context, data0.data, impersonator_out);
-+
-+cleanup:
-+ krb5_free_data_contents(context, &data);
-+ krb5_free_data_contents(context, &data0);
-+ return code;
-+}
-+
- /* Check ccache and scan it for its expiry time. On success, cred takes
- * ownership of ccache. */
- static krb5_error_code
-@@ -493,6 +521,10 @@ scan_ccache(krb5_context context, krb5_gss_cred_id_rec *cred,
- goto cleanup;
- }
-
-+ code = get_impersonator(context, ccache, &cred->impersonator);
-+ if (code)
-+ goto cleanup;
-+
- (void)krb5_cc_set_flags(context, ccache, KRB5_TC_OPENCLOSE);
- cred->ccache = ccache;
-
-@@ -622,6 +654,7 @@ acquire_cred(OM_uint32 *minor_status,
-
- cred->usage = args->cred_usage;
- cred->name = NULL;
-+ cred->impersonator = NULL;
- cred->iakerb_mech = args->iakerb;
- cred->default_identity = (name == NULL);
- #ifndef LEAN_CLIENT
-diff --git a/src/lib/gssapi/krb5/gssapiP_krb5.h b/src/lib/gssapi/krb5/gssapiP_krb5.h
-index 016a2e6..6b7d530 100644
---- a/src/lib/gssapi/krb5/gssapiP_krb5.h
-+++ b/src/lib/gssapi/krb5/gssapiP_krb5.h
-@@ -172,7 +172,7 @@ typedef struct _krb5_gss_cred_id_rec {
- /* name/type of credential */
- gss_cred_usage_t usage;
- krb5_gss_name_t name;
-- unsigned int proxy_cred : 1;
-+ krb5_principal impersonator;
- unsigned int default_identity : 1;
- unsigned int iakerb_mech : 1;
- unsigned int destroy_ccache : 1;
-diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
-index 1b8120c..d7b9ffa 100644
---- a/src/lib/gssapi/krb5/init_sec_context.c
-+++ b/src/lib/gssapi/krb5/init_sec_context.c
-@@ -129,7 +129,6 @@ static krb5_error_code get_credentials(context, cred, server, now,
- krb5_error_code code;
- krb5_creds in_creds, evidence_creds, *result_creds = NULL;
- krb5_flags flags = 0;
-- krb5_principal cc_princ = NULL;
-
- *out_creds = NULL;
-
-@@ -140,16 +139,13 @@ static krb5_error_code get_credentials(context, cred, server, now,
-
- assert(cred->name != NULL);
-
-- if ((code = krb5_cc_get_principal(context, cred->ccache, &cc_princ)))
-- goto cleanup;
--
- /*
- * Do constrained delegation if we have proxy credentials and
- * we're not trying to get a ticket to ourselves (in which case
- * we can just use the S4U2Self or evidence ticket directly).
- */
-- if (cred->proxy_cred &&
-- !krb5_principal_compare(context, cc_princ, server->princ)) {
-+ if (cred->impersonator &&
-+ !krb5_principal_compare(context, cred->impersonator, server->princ)) {
- krb5_creds mcreds;
-
- flags |= KRB5_GC_CANONICALIZE |
-@@ -159,20 +155,18 @@ static krb5_error_code get_credentials(context, cred, server, now,
- memset(&mcreds, 0, sizeof(mcreds));
-
- mcreds.magic = KV5M_CREDS;
-- mcreds.times.endtime = cred->tgt_expire;
-- mcreds.server = cc_princ;
-+ mcreds.server = cred->impersonator;
- mcreds.client = cred->name->princ;
-
- code = krb5_cc_retrieve_cred(context, cred->ccache,
-- KRB5_TC_MATCH_TIMES | KRB5_TC_MATCH_AUTHDATA,
-- &mcreds,
-+ KRB5_TC_MATCH_AUTHDATA, &mcreds,
- &evidence_creds);
- if (code)
- goto cleanup;
-
- assert(evidence_creds.ticket_flags & TKT_FLG_FORWARDABLE);
-
-- in_creds.client = cc_princ;
-+ in_creds.client = cred->impersonator;
- in_creds.second_ticket = evidence_creds.ticket;
- } else {
- in_creds.client = cred->name->princ;
-@@ -255,7 +249,6 @@ static krb5_error_code get_credentials(context, cred, server, now,
-
- cleanup:
- krb5_free_authdata(context, in_creds.authdata);
-- krb5_free_principal(context, cc_princ);
- krb5_free_cred_contents(context, &evidence_creds);
- krb5_free_creds(context, result_creds);
-
-diff --git a/src/lib/gssapi/krb5/rel_cred.c b/src/lib/gssapi/krb5/rel_cred.c
-index 5b2ea2f..4fd3694 100644
---- a/src/lib/gssapi/krb5/rel_cred.c
-+++ b/src/lib/gssapi/krb5/rel_cred.c
-@@ -71,6 +71,8 @@ krb5_gss_release_cred(minor_status, cred_handle)
- if (cred->name)
- kg_release_name(context, &cred->name);
-
-+ krb5_free_principal(context, cred->impersonator);
-+
- if (cred->req_enctypes)
- free(cred->req_enctypes);
-
-diff --git a/src/lib/gssapi/krb5/s4u_gss_glue.c b/src/lib/gssapi/krb5/s4u_gss_glue.c
-index 4ac2ce3..4b37c5a 100644
---- a/src/lib/gssapi/krb5/s4u_gss_glue.c
-+++ b/src/lib/gssapi/krb5/s4u_gss_glue.c
-@@ -169,6 +169,39 @@ krb5_gss_acquire_cred_impersonate_name(OM_uint32 *minor_status,
-
- }
-
-+/*
-+ * Set up cred to be an S4U2Proxy credential by copying in the impersonator's
-+ * creds, setting a cache config variable with the impersonator principal name,
-+ * and saving the impersonator principal name in the cred structure.
-+ */
-+static krb5_error_code
-+make_proxy_cred(krb5_context context, krb5_gss_cred_id_t cred,
-+ krb5_gss_cred_id_t impersonator_cred)
-+{
-+ krb5_error_code code;
-+ krb5_data data;
-+ char *str;
-+
-+ code = krb5_cc_copy_creds(context, impersonator_cred->ccache,
-+ cred->ccache);
-+ if (code)
-+ return code;
-+
-+ code = krb5_unparse_name(context, impersonator_cred->name->princ, &str);
-+ if (code)
-+ return code;
-+
-+ data = string2data(str);
-+ code = krb5_cc_set_config(context, cred->ccache, NULL,
-+ KRB5_CONF_PROXY_IMPERSONATOR, &data);
-+ krb5_free_unparsed_name(context, str);
-+ if (code)
-+ return code;
-+
-+ return krb5_copy_principal(context, impersonator_cred->name->princ,
-+ &cred->impersonator);
-+}
-+
- OM_uint32
- kg_compose_deleg_cred(OM_uint32 *minor_status,
- krb5_gss_cred_id_t impersonator_cred,
-@@ -187,7 +220,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
-
- if (!kg_is_initiator_cred(impersonator_cred) ||
- impersonator_cred->name == NULL ||
-- impersonator_cred->proxy_cred) {
-+ impersonator_cred->impersonator != NULL) {
- code = G_BAD_USAGE;
- goto cleanup;
- }
-@@ -208,14 +241,7 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
- if (code != 0)
- goto cleanup;
-
-- /*
-- * Only return a "proxy" credential for use with constrained
-- * delegation if the subject credentials are forwardable.
-- * Submitting non-forwardable credentials to the KDC for use
-- * with constrained delegation will only return an error.
-- */
- cred->usage = GSS_C_INITIATE;
-- cred->proxy_cred = !!(subject_creds->ticket_flags & TKT_FLG_FORWARDABLE);
-
- cred->tgt_expire = subject_creds->times.endtime;
-
-@@ -229,16 +255,18 @@ kg_compose_deleg_cred(OM_uint32 *minor_status,
- goto cleanup;
- cred->destroy_ccache = 1;
-
-- code = krb5_cc_initialize(context, cred->ccache,
-- cred->proxy_cred ? impersonator_cred->name->princ :
-- subject_creds->client);
-+ code = krb5_cc_initialize(context, cred->ccache, subject_creds->client);
- if (code != 0)
- goto cleanup;
-
-- if (cred->proxy_cred) {
-- /* Impersonator's TGT will be necessary for S4U2Proxy */
-- code = krb5_cc_copy_creds(context, impersonator_cred->ccache,
-- cred->ccache);
-+ /*
-+ * Only return a "proxy" credential for use with constrained
-+ * delegation if the subject credentials are forwardable.
-+ * Submitting non-forwardable credentials to the KDC for use
-+ * with constrained delegation will only return an error.
-+ */
-+ if (subject_creds->ticket_flags & TKT_FLG_FORWARDABLE) {
-+ code = make_proxy_cred(context, cred, impersonator_cred);
- if (code != 0)
- goto cleanup;
- }
-diff --git a/src/lib/gssapi/krb5/store_cred.c b/src/lib/gssapi/krb5/store_cred.c
-index bff3cde..d587589 100644
---- a/src/lib/gssapi/krb5/store_cred.c
-+++ b/src/lib/gssapi/krb5/store_cred.c
-@@ -91,7 +91,7 @@ copy_initiator_creds(OM_uint32 *minor_status,
-
- kcred = (krb5_gss_cred_id_t)input_cred_handle;
-
-- if (kcred->ccache == NULL || kcred->proxy_cred) {
-+ if (kcred->ccache == NULL) {
- *minor_status = KG_CCACHE_NOMATCH;
- major_status = GSS_S_DEFECTIVE_CREDENTIAL;
- goto cleanup;
-diff --git a/src/lib/gssapi/krb5/val_cred.c b/src/lib/gssapi/krb5/val_cred.c
-index e87f249..46a9ae1 100644
---- a/src/lib/gssapi/krb5/val_cred.c
-+++ b/src/lib/gssapi/krb5/val_cred.c
-@@ -50,8 +50,7 @@ krb5_gss_validate_cred_1(OM_uint32 *minor_status, gss_cred_id_t cred_handle,
- *minor_status = code;
- return(GSS_S_DEFECTIVE_CREDENTIAL);
- }
-- if (!cred->proxy_cred &&
-- !krb5_principal_compare(context, princ, cred->name->princ)) {
-+ if (!krb5_principal_compare(context, princ, cred->name->princ)) {
- k5_mutex_unlock(&cred->lock);
- *minor_status = KG_CCACHE_NOMATCH;
- return(GSS_S_DEFECTIVE_CREDENTIAL);
+++ /dev/null
-commit 59a8a0861d5aacd4e985ad4dc4d46a11c2ebc136
-Author: ghudson <ghudson@dc483132-0cff-0310-8789-dd5450dbe970>
-Date: Wed Dec 7 19:38:22 2011 +0000
-
- ticket: 7047
- subject: Allow S4U2Proxy service tickets to be cached
-
- Previous to this change, the GSS code avoids caching S4U2Proxy results
- for fear of the memory cache growing without bound, but that seems
- unlikely to be a serious problem. Allow these to be cached.
-
- git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25530 dc483132-0cff-0310-8789-dd5450dbe970
-
-diff --git a/src/lib/gssapi/krb5/init_sec_context.c b/src/lib/gssapi/krb5/init_sec_context.c
-index d7b9ffa..07baefa 100644
---- a/src/lib/gssapi/krb5/init_sec_context.c
-+++ b/src/lib/gssapi/krb5/init_sec_context.c
-@@ -148,9 +148,7 @@ static krb5_error_code get_credentials(context, cred, server, now,
- !krb5_principal_compare(context, cred->impersonator, server->princ)) {
- krb5_creds mcreds;
-
-- flags |= KRB5_GC_CANONICALIZE |
-- KRB5_GC_NO_STORE |
-- KRB5_GC_CONSTRAINED_DELEGATION;
-+ flags |= KRB5_GC_CANONICALIZE | KRB5_GC_CONSTRAINED_DELEGATION;
-
- memset(&mcreds, 0, sizeof(mcreds));
-
+++ /dev/null
-commit 1c2f5144de0f15f7d9c8659a71adc10c2755b57e
-Author: ghudson <ghudson@dc483132-0cff-0310-8789-dd5450dbe970>
-Date: Wed Dec 7 19:38:32 2011 +0000
-
- ticket: 7048
- subject: Allow null server key to krb5_pac_verify
-
- When the KDC verifies a PAC, it doesn't really need to check the
- server signature, since it can't trust that anyway. Allow the caller
- to pass only a TGT key.
-
- git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25532 dc483132-0cff-0310-8789-dd5450dbe970
-
-diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
-index f3d0225..83c2dc7 100644
---- a/src/include/krb5/krb5.hin
-+++ b/src/include/krb5/krb5.hin
-@@ -7506,13 +7506,13 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
- * @param [in] pac PAC handle
- * @param [in] authtime Expected timestamp
- * @param [in] principal Expected principal name (or NULL)
-- * @param [in] server Key to validate server checksum
-+ * @param [in] server Key to validate server checksum (or NULL)
- * @param [in] privsvr Key to validate KDC checksum (or NULL)
- *
- * This function validates @a pac against the supplied @a server, @a privsvr,
- * @a principal and @a authtime. If @a principal is NULL, the principal and
-- * authtime are not verified. If @a privsvr is NULL, the KDC checksum is not
-- * verified.
-+ * authtime are not verified. If @a server or @a privsvr is NULL, the
-+ * corresponding checksum is not verified.
- *
- * If successful, @a pac is marked as verified.
- *
-diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
-index f173b04..23aa930 100644
---- a/src/lib/krb5/krb/pac.c
-+++ b/src/lib/krb5/krb/pac.c
-@@ -637,9 +637,11 @@ krb5_pac_verify(krb5_context context,
- if (server == NULL)
- return EINVAL;
-
-- ret = k5_pac_verify_server_checksum(context, pac, server);
-- if (ret != 0)
-- return ret;
-+ if (server != NULL) {
-+ ret = k5_pac_verify_server_checksum(context, pac, server);
-+ if (ret != 0)
-+ return ret;
-+ }
-
- if (privsvr != NULL) {
- ret = k5_pac_verify_kdc_checksum(context, pac, privsvr);
-
-commit e31486a84380647e49ba6199a3e10ac739fa1a45
-Author: ghudson <ghudson@dc483132-0cff-0310-8789-dd5450dbe970>
-Date: Thu Dec 8 04:21:23 2011 +0000
-
- ticket: 7048
-
- Actually allow null server key in krb5_pac_verify
-
- git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@25534 dc483132-0cff-0310-8789-dd5450dbe970
-
-diff --git a/src/lib/krb5/krb/pac.c b/src/lib/krb5/krb/pac.c
-index 23aa930..3262d21 100644
---- a/src/lib/krb5/krb/pac.c
-+++ b/src/lib/krb5/krb/pac.c
-@@ -634,9 +634,6 @@ krb5_pac_verify(krb5_context context,
- {
- krb5_error_code ret;
-
-- if (server == NULL)
-- return EINVAL;
--
- if (server != NULL) {
- ret = k5_pac_verify_server_checksum(context, pac, server);
- if (ret != 0)
+++ /dev/null
-commit db83abc7dcfe369bd4467c78eebb7028ba0c0e0d
-Author: Greg Hudson <ghudson@mit.edu>
-Date: Thu Jun 21 17:20:29 2012 -0400
-
- Handle PKINIT DH replies with no certs
-
- If a PKINIT Diffie-Hellman reply contains no certificates in the
- SignedData object, that may be because the signer certificate was a
- trust anchor as transmitted to the KDC. Heimdal's KDC, for instance,
- filters client trust anchors out of the returned set of certificates.
- Match against idctx->trustedCAs and idctx->intermediateCAs to handle
- this case. This fix only works with OpenSSL 1.0 or later; when built
- against OpenSSL 0.9.x, the client will still require a cert in the
- reply.
-
- Code changes suggested by nalin@redhat.com.
-
- ticket: 7183
-
-diff --git a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
-index 0136d4f..7120ecf 100644
---- a/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
-+++ b/src/plugins/preauth/pkinit/pkinit_crypto_openssl.c
-@@ -1398,8 +1398,15 @@ cms_signeddata_verify(krb5_context context,
- X509_STORE_set_verify_cb_func(store, openssl_callback_ignore_crls);
- X509_STORE_set_flags(store, vflags);
-
-- /* get the signer's information from the CMS message */
-+ /*
-+ * Get the signer's information from the CMS message. Match signer ID
-+ * against anchors and intermediate CAs in case no certs are present in the
-+ * SignedData. If we start sending kdcPkId values in requests, we'll need
-+ * to match against the source of that information too.
-+ */
- CMS_set1_signers_certs(cms, NULL, 0);
-+ CMS_set1_signers_certs(cms, idctx->trustedCAs, CMS_NOINTERN);
-+ CMS_set1_signers_certs(cms, idctx->intermediateCAs, CMS_NOINTERN);
- if (((si_sk = CMS_get0_SignerInfos(cms)) == NULL) ||
- ((si = sk_CMS_SignerInfo_value(si_sk, 0)) == NULL)) {
- /* Not actually signed; anonymous case */