From: Stefan Schantl Date: Sun, 27 Jan 2013 13:37:21 +0000 (+0100) Subject: krb5: New package. X-Git-Url: http://git.ipfire.org/?p=ipfire-3.x.git;a=commitdiff_plain;h=6cf77d0523cec8229ba22fd925014010c017e0af krb5: New package. Fixes #10288. --- diff --git a/krb5/kadm5.acl b/krb5/kadm5.acl new file mode 100644 index 000000000..dc93eb0a0 --- /dev/null +++ b/krb5/kadm5.acl @@ -0,0 +1 @@ +*/admin@EXAMPLE.COM * diff --git a/krb5/kdc.conf b/krb5/kdc.conf new file mode 100644 index 000000000..a4f590150 --- /dev/null +++ b/krb5/kdc.conf @@ -0,0 +1,12 @@ +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + +[realms] + EXAMPLE.COM = { + #master_key_type = aes256-cts + acl_file = /var/kerberos/krb5kdc/kadm5.acl + dict_file = /usr/share/dict/words + admin_keytab = /var/kerberos/krb5kdc/kadm5.keytab + supported_enctypes = aes256-cts:normal aes128-cts:normal des3-hmac-sha1:normal arcfour-hmac:normal des-hmac-sha1:normal des-cbc-md5:normal des-cbc-crc:normal + } diff --git a/krb5/krb5.conf b/krb5/krb5.conf new file mode 100644 index 000000000..c45262109 --- /dev/null +++ b/krb5/krb5.conf @@ -0,0 +1,21 @@ +[logging] + default = FILE:/var/log/krb5libs.log + kdc = FILE:/var/log/krb5kdc.log + admin_server = FILE:/var/log/kadmind.log + +[libdefaults] + dns_lookup_realm = false + ticket_lifetime = 24h + renew_lifetime = 7d + forwardable = true +# default_realm = EXAMPLE.COM + +[realms] +# EXAMPLE.COM = { +# kdc = kerberos.example.com +# admin_server = kerberos.example.com +# } + +[domain_realm] +# .example.com = EXAMPLE.COM +# example.com = EXAMPLE.COM diff --git a/krb5/krb5.nm b/krb5/krb5.nm new file mode 100644 index 000000000..a80872d1c --- /dev/null +++ b/krb5/krb5.nm @@ -0,0 +1,245 @@ +############################################################################### +# IPFire.org - An Open Source Firewall Solution # +# Copyright (C) - IPFire Development Team # +############################################################################### + +name = krb5 +version = %{version_maj}.%{version_min} +version_maj= 1.10 +version_min= 2 +release = 1 + +groups = System/Libraries +url = http://web.mit.edu/kerberos/www/ +license = MIT +summary = The Kerberos network authentication system. + +description + Kerberos V5 is a trusted-third-party network authentication system, + which can improve your network's security by eliminating the insecure + 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 + +build + requires + autoconf + automake + bison + dejagnu + e2fsprogs-devel + flex + gettext + libselinux-devel + ncurses-devel + openldap-devel + openssl-devel + pam-devel + perl + systemd-units + tcl-devel + 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 \ + --localstatedir=/var/kerberos \ + --with-system-et \ + --with-system-ss \ + --with-netlib=-lresolv \ + --with-tcl \ + --enable-dns-for-realm \ + --with-dirsrv \ + --enable-pkinit \ + --with-crypto-impl=openssl \ + --with-pam \ + --with-selinux + + # Don't use strlcpy that comes with glibc. + configure_options += \ + ac_cv_func_strlcpy=no + + build + cd %{DIR_APP}/src + ./configure \ + %{configure_options} + + 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} + + # Sample KDC config files (bundled kdc.conf and kadm5.acl). + mkdir -pv %{BUILDROOT}%{localstatedir}/kerberos/krb5kdc + install -pm 600 %{DIR_SOURCE}/kdc.conf %{BUILDROOT}%{localstatedir}/kerberos/krb5kdc/ + install -pm 600 %{DIR_SOURCE}/kadm5.acl %{BUILDROOT}%{localstatedir}/kerberos/krb5kdc/ + + # Default configuration file for everything. + mkdir -pv %{BUILDROOT}/etc + install -pm 644 %{DIR_SOURCE}/krb5.conf %{BUILDROOT}/etc/krb5.conf + + # Plug-in directories. + install -pdm 755 %{BUILDROOT}%{libdir}/krb5/plugins/preauth + install -pdm 755 %{BUILDROOT}%{libdir}/krb5/plugins/kdb + install -pdm 755 %{BUILDROOT}%{libdir}/krb5/plugins/authdata + end +end + +packages + package %{name}-server + summary = The KDC and related programs for Kerberos 5. + description + Kerberos is a network authentication system. The krb5-server package + contains the programs that must be installed on a Kerberos 5 key + distribution center (KDC). If you are installing a Kerberos 5 KDC, + you need to install this package. + end + + requires + %{name}-libs = %{thisver} + end + + script postin + /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || : + end + + script preun + /usr/bin/systemctl --no-reload disable kadmin.service >/dev/null 2>&1 || : + /usr/bin/systemctl --no-reload disable kprop.service >/dev/null 2>&1 || : + /usr/bin/systemctl --no-reload disable krb5kdc.service >/dev/null 2>&1 || : + /usr/bin/systemctl stop kadmin.service >/dev/null 2>&1 || : + /usr/bin/systemctl stop kprop.service >/dev/null 2>&1 || : + /usr/bin/systemctl stop krb5kdc.service >/dev/null 2>&1 || : + end + + script postun + /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || : + end + + script postup + /usr/bin/systemctl daemon-reload >/dev/null 2>&1 || : + /usr/bin/systemctl try-restart kadmin.service >/dev/null 2>&1 || : + /usr/bin/systemctl try-restart kprop.service >/dev/null 2>&1 || : + /usr/bin/systemctl try-restart krb5kdc.service >/dev/null 2>&1 || : + end + end + + package %{name}-workstation + summary = Kerberos 5 programs for use on workstations. + description + Kerberos is a network authentication system. The krb5-workstation + package contains the basic Kerberos programs (kinit, klist, kdestroy, + kpasswd). If your network uses Kerberos, this package should be + installed on every workstation. + end + + requires + %{name}-libs = %{thisver} + end + + files + %{bindir}/kdestroy + %{bindir}/kinit + %{bindir}/klist + %{bindir}/kpassword + %{bindir}/kswitch + %{bindir}/kvno + %{bindir}/kadmin + %{bindir}/k5srvutil + %{bindir}/kutil + %{bindir}/ksu + %{bindir}/krb5-send-pr + + %{sysconfdir}/pam.d + + %{mandir}/man1/kdestroy.* + %{mandir}/man1/kinit.* + %{mandir}/man1/klist.* + %{mandir}/man1/kpassword.* + %{mandir}/man1/kswitch.* + %{mandir}/man1/kvno.* + %{mandir}/man1/kadmin.* + %{mandir}/man1/k5srvutil.* + %{mandir}/man1/kutil.* + %{mandir}/man1/ksu.* + end + end + + package %{name}-libs + template LIBS + end + + package %{name}-devel + template DEVEL + + requires + libselinux-devel + end + end + + package %{name}-debuginfo + template DEBUGINFO + end +end diff --git a/krb5/ksu.pam b/krb5/ksu.pam new file mode 100644 index 000000000..66f5b2cc6 --- /dev/null +++ b/krb5/ksu.pam @@ -0,0 +1,4 @@ +#%PAM-1.0 +auth include su +account include su +session include su diff --git a/krb5/logrotate/kadmind.logrotate b/krb5/logrotate/kadmind.logrotate new file mode 100644 index 000000000..52a66c418 --- /dev/null +++ b/krb5/logrotate/kadmind.logrotate @@ -0,0 +1,9 @@ +/var/log/kadmind.log { + missingok + notifempty + monthly + rotate 12 + postrotate + /bin/kill -HUP `cat /var/run/kadmind.pid 2>/dev/null` 2> /dev/null || true + endscript +} diff --git a/krb5/logrotate/krb5kdc.logrotate b/krb5/logrotate/krb5kdc.logrotate new file mode 100644 index 000000000..1100ed3a6 --- /dev/null +++ b/krb5/logrotate/krb5kdc.logrotate @@ -0,0 +1,9 @@ +/var/log/krb5kdc.log { + missingok + notifempty + monthly + rotate 12 + postrotate + /bin/kill -HUP `cat /var/run/krb5kdc.pid 2>/dev/null` 2> /dev/null || true + endscript +} diff --git a/krb5/patches/krb5-1.10-buildconf.patch b/krb5/patches/krb5-1.10-buildconf.patch new file mode 100644 index 000000000..25b05ace4 --- /dev/null +++ b/krb5/patches/krb5-1.10-buildconf.patch @@ -0,0 +1,54 @@ +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@ diff --git a/krb5/patches/krb5-1.10-doublelog.patch b/krb5/patches/krb5-1.10-doublelog.patch new file mode 100644 index 000000000..c20075ca9 --- /dev/null +++ b/krb5/patches/krb5-1.10-doublelog.patch @@ -0,0 +1,14 @@ +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 diff --git a/krb5/patches/krb5-1.10-gcc47.patch0 b/krb5/patches/krb5-1.10-gcc47.patch0 new file mode 100644 index 000000000..b973442ac --- /dev/null +++ b/krb5/patches/krb5-1.10-gcc47.patch0 @@ -0,0 +1,12 @@ +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 diff --git a/krb5/patches/krb5-1.10-kpasswd_tcp.patch b/krb5/patches/krb5-1.10-kpasswd_tcp.patch new file mode 100644 index 000000000..fd8da8e58 --- /dev/null +++ b/krb5/patches/krb5-1.10-kpasswd_tcp.patch @@ -0,0 +1,32 @@ +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; + } + diff --git a/krb5/patches/krb5-1.10-kprop-mktemp.patch b/krb5/patches/krb5-1.10-kprop-mktemp.patch new file mode 100644 index 000000000..62178df7f --- /dev/null +++ b/krb5/patches/krb5-1.10-kprop-mktemp.patch @@ -0,0 +1,28 @@ +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); diff --git a/krb5/patches/krb5-1.10-ksu-access.patch b/krb5/patches/krb5-1.10-ksu-access.patch new file mode 100644 index 000000000..ca155f726 --- /dev/null +++ b/krb5/patches/krb5-1.10-ksu-access.patch @@ -0,0 +1,47 @@ +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); diff --git a/krb5/patches/krb5-1.10-ksu-path.patch b/krb5/patches/krb5-1.10-ksu-path.patch new file mode 100644 index 000000000..48443efba --- /dev/null +++ b/krb5/patches/krb5-1.10-ksu-path.patch @@ -0,0 +1,12 @@ +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) diff --git a/krb5/patches/krb5-1.10.2-keytab-etype.patch b/krb5/patches/krb5-1.10.2-keytab-etype.patch new file mode 100644 index 000000000..4750a5cd6 --- /dev/null +++ b/krb5/patches/krb5-1.10.2-keytab-etype.patch @@ -0,0 +1,332 @@ +(Had to drop the changes to src/tests/t_keytab.py, which didn't exist in 1.10.) + +commit d1da158f47ea604bed4d5db5e98a976a9e54ccd0 +Author: Greg Hudson +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 +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; + } + diff --git a/krb5/patches/krb5-1.10.2-manpaths.patch b/krb5/patches/krb5-1.10.2-manpaths.patch new file mode 100644 index 000000000..2ef0a8386 --- /dev/null +++ b/krb5/patches/krb5-1.10.2-manpaths.patch @@ -0,0 +1,190 @@ +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 diff --git a/krb5/patches/krb5-1.10.2-pam.patch b/krb5/patches/krb5-1.10.2-pam.patch new file mode 100644 index 000000000..4d7c0540d --- /dev/null +++ b/krb5/patches/krb5-1.10.2-pam.patch @@ -0,0 +1,752 @@ +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 +@@ -33,6 +34,10 @@ + #include + #include + ++#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 ++#include ++#include ++#include ++#include ++#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 ++#ifdef HAVE_SECURITY_PAM_APPL_H ++#include ++#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' diff --git a/krb5/patches/krb5-1.10.2-selinux-label.patch b/krb5/patches/krb5-1.10.2-selinux-label.patch new file mode 100644 index 000000000..448aaec1a --- /dev/null +++ b/krb5/patches/krb5-1.10.2-selinux-label.patch @@ -0,0 +1,950 @@ +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 ++#include ++#include ++#include ++#include ++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 +--- 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 + #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 ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#ifdef HAVE_SELINUX_LABEL_H ++#include ++#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 + #include + ++#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 diff --git a/krb5/patches/krb5-1.3.1-dns.patch b/krb5/patches/krb5-1.3.1-dns.patch new file mode 100644 index 000000000..5d27689bb --- /dev/null +++ b/krb5/patches/krb5-1.3.1-dns.patch @@ -0,0 +1,12 @@ +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 diff --git a/krb5/patches/krb5-1.3.4-send-pr-tempfile.patch b/krb5/patches/krb5-1.3.4-send-pr-tempfile.patch new file mode 100644 index 000000000..a9ffa318d --- /dev/null +++ b/krb5/patches/krb5-1.3.4-send-pr-tempfile.patch @@ -0,0 +1,41 @@ +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 diff --git a/krb5/patches/krb5-1.6.3-kdc_listen_all.patch0 b/krb5/patches/krb5-1.6.3-kdc_listen_all.patch0 new file mode 100644 index 000000000..946199e8d --- /dev/null +++ b/krb5/patches/krb5-1.6.3-kdc_listen_all.patch0 @@ -0,0 +1,247 @@ +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")); diff --git a/krb5/patches/krb5-1.7-ktany.patch b/krb5/patches/krb5-1.7-ktany.patch new file mode 100644 index 000000000..902f3289f --- /dev/null +++ b/krb5/patches/krb5-1.7-ktany.patch @@ -0,0 +1,351 @@ +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 \ diff --git a/krb5/patches/krb5-1.8-api.patch b/krb5/patches/krb5-1.8-api.patch new file mode 100644 index 000000000..9cc9cd2d9 --- /dev/null +++ b/krb5/patches/krb5-1.8-api.patch @@ -0,0 +1,30 @@ +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) { diff --git a/krb5/patches/krb5-1.9-debuginfo.patch0 b/krb5/patches/krb5-1.9-debuginfo.patch0 new file mode 100644 index 000000000..ae81f7ce3 --- /dev/null +++ b/krb5/patches/krb5-1.9-debuginfo.patch0 @@ -0,0 +1,26 @@ +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) diff --git a/krb5/patches/krb5-1.9-dirsrv-accountlock.patch b/krb5/patches/krb5-1.9-dirsrv-accountlock.patch new file mode 100644 index 000000000..86578826c --- /dev/null +++ b/krb5/patches/krb5-1.9-dirsrv-accountlock.patch @@ -0,0 +1,69 @@ +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", diff --git a/krb5/patches/krb5-kvno-230379.patch b/krb5/patches/krb5-kvno-230379.patch new file mode 100644 index 000000000..ea9b69fac --- /dev/null +++ b/krb5/patches/krb5-kvno-230379.patch @@ -0,0 +1,53 @@ +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; diff --git a/krb5/patches/krb5-tex-pdf.sh b/krb5/patches/krb5-tex-pdf.sh new file mode 100644 index 000000000..ed72d2b0b --- /dev/null +++ b/krb5/patches/krb5-tex-pdf.sh @@ -0,0 +1,55 @@ +#!/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 diff --git a/krb5/patches/krb5-trunk-7046.patch b/krb5/patches/krb5-trunk-7046.patch new file mode 100644 index 000000000..7db7ef5f3 --- /dev/null +++ b/krb5/patches/krb5-trunk-7046.patch @@ -0,0 +1,301 @@ +commit 9dc75551cb8cc4c03f7e0fe5e8a705ed678079f4 +Author: ghudson +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); diff --git a/krb5/patches/krb5-trunk-7047.patch b/krb5/patches/krb5-trunk-7047.patch new file mode 100644 index 000000000..381449b61 --- /dev/null +++ b/krb5/patches/krb5-trunk-7047.patch @@ -0,0 +1,28 @@ +commit 59a8a0861d5aacd4e985ad4dc4d46a11c2ebc136 +Author: ghudson +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)); + diff --git a/krb5/patches/krb5-trunk-7048.patch b/krb5/patches/krb5-trunk-7048.patch new file mode 100644 index 000000000..0399565d9 --- /dev/null +++ b/krb5/patches/krb5-trunk-7048.patch @@ -0,0 +1,78 @@ +commit 1c2f5144de0f15f7d9c8659a71adc10c2755b57e +Author: ghudson +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 +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) diff --git a/krb5/patches/krb5-trunk-pkinit-anchorsign.patch b/krb5/patches/krb5-trunk-pkinit-anchorsign.patch new file mode 100644 index 000000000..508bb5b4e --- /dev/null +++ b/krb5/patches/krb5-trunk-pkinit-anchorsign.patch @@ -0,0 +1,40 @@ +commit db83abc7dcfe369bd4467c78eebb7028ba0c0e0d +Author: Greg Hudson +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 */ diff --git a/krb5/systemd/kadmin.service b/krb5/systemd/kadmin.service new file mode 100644 index 000000000..7775ea74c --- /dev/null +++ b/krb5/systemd/kadmin.service @@ -0,0 +1,14 @@ +[Unit] +Description=Kerberos 5 Password-changing and Administration +After=syslog.target network.target +ConditionPathExists=!/var/kerberos/krb5kdc/kpropd.acl + +[Service] +Type=forking +PIDFile=/var/run/kadmind.pid +EnvironmentFile=-/etc/sysconfig/kadmin +ExecStart=/usr/sbin/kadmind -P /var/run/kadmind.pid $KADMIND_ARGS +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target diff --git a/krb5/systemd/kprop.service b/krb5/systemd/kprop.service new file mode 100644 index 000000000..99ba12976 --- /dev/null +++ b/krb5/systemd/kprop.service @@ -0,0 +1,11 @@ +[Unit] +Description=Kerberos 5 Propagation +After=syslog.target network.target +ConditionPathExists=/var/kerberos/krb5kdc/kpropd.acl + +[Service] +Type=forking +ExecStart=/usr/sbin/kpropd -S + +[Install] +WantedBy=multi-user.target diff --git a/krb5/systemd/krb5kdc.service b/krb5/systemd/krb5kdc.service new file mode 100644 index 000000000..bc4920477 --- /dev/null +++ b/krb5/systemd/krb5kdc.service @@ -0,0 +1,13 @@ +[Unit] +Description=Kerberos 5 KDC +After=syslog.target network.target + +[Service] +Type=forking +PIDFile=/var/run/krb5kdc.pid +EnvironmentFile=-/etc/sysconfig/krb5kdc +ExecStart=/usr/sbin/krb5kdc -P /var/run/krb5kdc.pid $KRB5KDC_ARGS +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target