aboutsummaryrefslogtreecommitdiff
path: root/kuser
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2023-06-26 22:56:52 +0000
committerCy Schubert <cy@FreeBSD.org>2023-06-26 22:56:52 +0000
commitb6a943f7197af1a5eb6bb028b9b808ec5016e30c (patch)
treecfbb91e940dd89d0e1d46095f43c228d7d079fa0 /kuser
parent6f4e10db3298f6d65e1e646fe52aaafc3682b788 (diff)
Heimdal 7.8.0 does not support OpenSSL 3.0. 7.9.0 will but it hasn't been released yet. We are importing f62e2f278 for its OpenSSL 3.0 support.
Diffstat (limited to 'kuser')
-rw-r--r--kuser/Makefile.am15
-rw-r--r--kuser/Makefile.in1451
-rw-r--r--kuser/NTMakefile11
-rw-r--r--kuser/generate-requests.c2
-rw-r--r--kuser/heimtools-commands.in55
-rw-r--r--kuser/kdestroy.c2
-rw-r--r--kuser/kdestroy.cat136
-rw-r--r--kuser/kdigest.cat8132
-rw-r--r--kuser/kgetcred.114
-rw-r--r--kuser/kgetcred.cat1106
-rw-r--r--kuser/kimpersonate.c31
-rw-r--r--kuser/kimpersonate.cat893
-rw-r--r--kuser/kinit.1230
-rw-r--r--kuser/kinit.c680
-rw-r--r--kuser/kinit.cat1136
-rw-r--r--kuser/klist.c596
-rw-r--r--kuser/klist.cat189
-rw-r--r--kuser/kswitch.cat131
-rw-r--r--kuser/kuser_locl.h5
-rw-r--r--kuser/kx509.1133
-rw-r--r--kuser/kx509.c303
21 files changed, 1806 insertions, 2345 deletions
diff --git a/kuser/Makefile.am b/kuser/Makefile.am
index 0e82c8ea6f77..96ad36fd29e0 100644
--- a/kuser/Makefile.am
+++ b/kuser/Makefile.am
@@ -7,6 +7,7 @@ afs_lib = $(LIB_kafs)
endif
AM_CPPFLAGS += -I$(srcdir)/../lib/krb5 \
+ -I$(srcdir)/../lib/gssapi \
$(INCLUDE_libintl) \
-DHEIMDAL_LOCALEDIR='"$(localedir)"'
@@ -17,7 +18,8 @@ man_MANS = \
kswitch.1 \
kdigest.8 \
kgetcred.1 \
- kimpersonate.8
+ kimpersonate.8 \
+ kx509.1
bin_PROGRAMS = kinit kdestroy kgetcred heimtools
libexec_PROGRAMS = kdigest kimpersonate
@@ -27,6 +29,8 @@ noinst_PROGRAMS = kverify kdecode_ticket generate-requests
kinit_LDADD = \
$(afs_lib) \
$(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/gssapi/libgssapi.la \
+ $(top_builddir)/lib/gss_preauth/libgss_preauth.la \
$(top_builddir)/lib/ntlm/libheimntlm.la \
$(LIB_hcrypto) \
$(top_builddir)/lib/asn1/libasn1.la \
@@ -37,12 +41,16 @@ kdestroy_LDADD = $(kinit_LDADD)
kimpersonate_LDADD = $(kinit_LDADD)
+LIB_hx509 = ../lib/hx509/libhx509.la
+
heimtools_LDADD = \
$(top_builddir)/lib/sl/libsl.la \
$(kinit_LDADD) \
- $(LIB_readline)
+ $(LIB_readline) \
+ $(LIB_heimbase) \
+ $(LIB_hx509)
-dist_heimtools_SOURCES = heimtools.c klist.c kswitch.c copy_cred_cache.c
+dist_heimtools_SOURCES = heimtools.c klist.c kx509.c kswitch.c copy_cred_cache.c
nodist_heimtools_SOURCES = heimtools-commands.c
$(heimtools_OBJECTS): heimtools-commands.h
@@ -91,5 +99,6 @@ EXTRA_DIST = NTMakefile $(man_MANS) \
# make sure install-exec-hook doesn't have any commands in Makefile.am.common
install-exec-hook:
(cd $(DESTDIR)$(bindir) && rm -f klist && $(LN_S) heimtools klist)
+ (cd $(DESTDIR)$(bindir) && rm -f kx509 && $(LN_S) heimtools kx509)
(cd $(DESTDIR)$(bindir) && rm -f kswitch && $(LN_S) heimtools kswitch)
diff --git a/kuser/Makefile.in b/kuser/Makefile.in
deleted file mode 100644
index e06464d5802f..000000000000
--- a/kuser/Makefile.in
+++ /dev/null
@@ -1,1451 +0,0 @@
-# Makefile.in generated by automake 1.16.5 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994-2021 Free Software Foundation, Inc.
-
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-# $Id$
-
-# $Id$
-
-# $Id$
-
-VPATH = @srcdir@
-am__is_gnu_make = { \
- if test -z '$(MAKELEVEL)'; then \
- false; \
- elif test -n '$(MAKE_HOST)'; then \
- true; \
- elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \
- true; \
- else \
- false; \
- fi; \
-}
-am__make_running_with_option = \
- case $${target_option-} in \
- ?) ;; \
- *) echo "am__make_running_with_option: internal error: invalid" \
- "target option '$${target_option-}' specified" >&2; \
- exit 1;; \
- esac; \
- has_opt=no; \
- sane_makeflags=$$MAKEFLAGS; \
- if $(am__is_gnu_make); then \
- sane_makeflags=$$MFLAGS; \
- else \
- case $$MAKEFLAGS in \
- *\\[\ \ ]*) \
- bs=\\; \
- sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
- | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
- esac; \
- fi; \
- skip_next=no; \
- strip_trailopt () \
- { \
- flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
- }; \
- for flg in $$sane_makeflags; do \
- test $$skip_next = yes && { skip_next=no; continue; }; \
- case $$flg in \
- *=*|--*) continue;; \
- -*I) strip_trailopt 'I'; skip_next=yes;; \
- -*I?*) strip_trailopt 'I';; \
- -*O) strip_trailopt 'O'; skip_next=yes;; \
- -*O?*) strip_trailopt 'O';; \
- -*l) strip_trailopt 'l'; skip_next=yes;; \
- -*l?*) strip_trailopt 'l';; \
- -[dEDm]) skip_next=yes;; \
- -[JT]) skip_next=yes;; \
- esac; \
- case $$flg in \
- *$$target_option*) has_opt=yes; break;; \
- esac; \
- done; \
- test $$has_opt = yes
-am__make_dryrun = (target_option=n; $(am__make_running_with_option))
-am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-bin_PROGRAMS = kinit$(EXEEXT) kdestroy$(EXEEXT) kgetcred$(EXEEXT) \
- heimtools$(EXEEXT)
-libexec_PROGRAMS = kdigest$(EXEEXT) kimpersonate$(EXEEXT)
-noinst_PROGRAMS = kverify$(EXEEXT) kdecode_ticket$(EXEEXT) \
- generate-requests$(EXEEXT)
-subdir = kuser
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \
- $(top_srcdir)/cf/auth-modules.m4 \
- $(top_srcdir)/cf/broken-glob.m4 \
- $(top_srcdir)/cf/broken-realloc.m4 \
- $(top_srcdir)/cf/broken-snprintf.m4 $(top_srcdir)/cf/broken.m4 \
- $(top_srcdir)/cf/broken2.m4 $(top_srcdir)/cf/c-attribute.m4 \
- $(top_srcdir)/cf/capabilities.m4 \
- $(top_srcdir)/cf/check-compile-et.m4 \
- $(top_srcdir)/cf/check-getpwnam_r-posix.m4 \
- $(top_srcdir)/cf/check-man.m4 \
- $(top_srcdir)/cf/check-netinet-ip-and-tcp.m4 \
- $(top_srcdir)/cf/check-type-extra.m4 \
- $(top_srcdir)/cf/check-var.m4 $(top_srcdir)/cf/crypto.m4 \
- $(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/destdirs.m4 \
- $(top_srcdir)/cf/dispatch.m4 $(top_srcdir)/cf/dlopen.m4 \
- $(top_srcdir)/cf/find-func-no-libs.m4 \
- $(top_srcdir)/cf/find-func-no-libs2.m4 \
- $(top_srcdir)/cf/find-func.m4 \
- $(top_srcdir)/cf/find-if-not-broken.m4 \
- $(top_srcdir)/cf/framework-security.m4 \
- $(top_srcdir)/cf/have-struct-field.m4 \
- $(top_srcdir)/cf/have-type.m4 $(top_srcdir)/cf/irix.m4 \
- $(top_srcdir)/cf/krb-bigendian.m4 \
- $(top_srcdir)/cf/krb-func-getlogin.m4 \
- $(top_srcdir)/cf/krb-ipv6.m4 $(top_srcdir)/cf/krb-prog-ln-s.m4 \
- $(top_srcdir)/cf/krb-prog-perl.m4 \
- $(top_srcdir)/cf/krb-readline.m4 \
- $(top_srcdir)/cf/krb-struct-spwd.m4 \
- $(top_srcdir)/cf/krb-struct-winsize.m4 \
- $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/libtool.m4 \
- $(top_srcdir)/cf/ltoptions.m4 $(top_srcdir)/cf/ltsugar.m4 \
- $(top_srcdir)/cf/ltversion.m4 $(top_srcdir)/cf/lt~obsolete.m4 \
- $(top_srcdir)/cf/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \
- $(top_srcdir)/cf/need-proto.m4 $(top_srcdir)/cf/osfc2.m4 \
- $(top_srcdir)/cf/otp.m4 $(top_srcdir)/cf/pkg.m4 \
- $(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \
- $(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \
- $(top_srcdir)/cf/roken-frag.m4 \
- $(top_srcdir)/cf/socket-wrapper.m4 $(top_srcdir)/cf/sunos.m4 \
- $(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \
- $(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \
- $(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \
- $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON)
-mkinstalldirs = $(install_sh) -d
-CONFIG_HEADER = $(top_builddir)/include/config.h
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \
- "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"
-PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(noinst_PROGRAMS)
-generate_requests_SOURCES = generate-requests.c
-generate_requests_OBJECTS = generate-requests.$(OBJEXT)
-generate_requests_LDADD = $(LDADD)
-am__DEPENDENCIES_1 =
-generate_requests_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
- $(am__DEPENDENCIES_1)
-AM_V_lt = $(am__v_lt_@AM_V@)
-am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
-am__v_lt_0 = --silent
-am__v_lt_1 =
-dist_heimtools_OBJECTS = heimtools.$(OBJEXT) klist.$(OBJEXT) \
- kswitch.$(OBJEXT) copy_cred_cache.$(OBJEXT)
-nodist_heimtools_OBJECTS = heimtools-commands.$(OBJEXT)
-heimtools_OBJECTS = $(dist_heimtools_OBJECTS) \
- $(nodist_heimtools_OBJECTS)
-@NO_AFS_FALSE@am__DEPENDENCIES_2 = \
-@NO_AFS_FALSE@ $(top_builddir)/lib/kafs/libkafs.la \
-@NO_AFS_FALSE@ $(am__DEPENDENCIES_1)
-@NO_AFS_FALSE@am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2)
-am__DEPENDENCIES_4 = $(am__DEPENDENCIES_3) \
- $(top_builddir)/lib/krb5/libkrb5.la \
- $(top_builddir)/lib/ntlm/libheimntlm.la $(am__DEPENDENCIES_1) \
- $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
-heimtools_DEPENDENCIES = $(top_builddir)/lib/sl/libsl.la \
- $(am__DEPENDENCIES_4) $(am__DEPENDENCIES_1)
-kdecode_ticket_SOURCES = kdecode_ticket.c
-kdecode_ticket_OBJECTS = kdecode_ticket.$(OBJEXT)
-kdecode_ticket_LDADD = $(LDADD)
-kdecode_ticket_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
- $(am__DEPENDENCIES_1)
-kdestroy_SOURCES = kdestroy.c
-kdestroy_OBJECTS = kdestroy.$(OBJEXT)
-kdestroy_DEPENDENCIES = $(am__DEPENDENCIES_4)
-dist_kdigest_OBJECTS = kdigest.$(OBJEXT)
-nodist_kdigest_OBJECTS = kdigest-commands.$(OBJEXT)
-kdigest_OBJECTS = $(dist_kdigest_OBJECTS) $(nodist_kdigest_OBJECTS)
-kdigest_DEPENDENCIES = $(top_builddir)/lib/ntlm/libheimntlm.la \
- $(top_builddir)/lib/krb5/libkrb5.la $(am__DEPENDENCIES_1) \
- $(top_builddir)/lib/asn1/libasn1.la \
- $(top_builddir)/lib/sl/libsl.la $(am__DEPENDENCIES_1)
-kgetcred_SOURCES = kgetcred.c
-kgetcred_OBJECTS = kgetcred.$(OBJEXT)
-kgetcred_LDADD = $(LDADD)
-kgetcred_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
- $(am__DEPENDENCIES_1)
-kimpersonate_SOURCES = kimpersonate.c
-kimpersonate_OBJECTS = kimpersonate.$(OBJEXT)
-kimpersonate_DEPENDENCIES = $(am__DEPENDENCIES_4)
-kinit_SOURCES = kinit.c
-kinit_OBJECTS = kinit.$(OBJEXT)
-kinit_DEPENDENCIES = $(am__DEPENDENCIES_3) \
- $(top_builddir)/lib/krb5/libkrb5.la \
- $(top_builddir)/lib/ntlm/libheimntlm.la $(am__DEPENDENCIES_1) \
- $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1) \
- $(am__DEPENDENCIES_1)
-kverify_SOURCES = kverify.c
-kverify_OBJECTS = kverify.$(OBJEXT)
-kverify_LDADD = $(LDADD)
-kverify_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
- $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
- $(am__DEPENDENCIES_1)
-AM_V_P = $(am__v_P_@AM_V@)
-am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
-am__v_P_0 = false
-am__v_P_1 = :
-AM_V_GEN = $(am__v_GEN_@AM_V@)
-am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
-am__v_GEN_0 = @echo " GEN " $@;
-am__v_GEN_1 =
-AM_V_at = $(am__v_at_@AM_V@)
-am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
-am__v_at_0 = @
-am__v_at_1 =
-depcomp = $(SHELL) $(top_srcdir)/depcomp
-am__maybe_remake_depfiles = depfiles
-am__depfiles_remade = ./$(DEPDIR)/copy_cred_cache.Po \
- ./$(DEPDIR)/generate-requests.Po \
- ./$(DEPDIR)/heimtools-commands.Po ./$(DEPDIR)/heimtools.Po \
- ./$(DEPDIR)/kdecode_ticket.Po ./$(DEPDIR)/kdestroy.Po \
- ./$(DEPDIR)/kdigest-commands.Po ./$(DEPDIR)/kdigest.Po \
- ./$(DEPDIR)/kgetcred.Po ./$(DEPDIR)/kimpersonate.Po \
- ./$(DEPDIR)/kinit.Po ./$(DEPDIR)/klist.Po \
- ./$(DEPDIR)/kswitch.Po ./$(DEPDIR)/kverify.Po
-am__mv = mv -f
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CFLAGS) $(CFLAGS)
-AM_V_CC = $(am__v_CC_@AM_V@)
-am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
-am__v_CC_0 = @echo " CC " $@;
-am__v_CC_1 =
-CCLD = $(CC)
-LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
- $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-AM_V_CCLD = $(am__v_CCLD_@AM_V@)
-am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
-am__v_CCLD_0 = @echo " CCLD " $@;
-am__v_CCLD_1 =
-SOURCES = generate-requests.c $(dist_heimtools_SOURCES) \
- $(nodist_heimtools_SOURCES) kdecode_ticket.c kdestroy.c \
- $(dist_kdigest_SOURCES) $(nodist_kdigest_SOURCES) kgetcred.c \
- kimpersonate.c kinit.c kverify.c
-DIST_SOURCES = generate-requests.c $(dist_heimtools_SOURCES) \
- kdecode_ticket.c kdestroy.c $(dist_kdigest_SOURCES) kgetcred.c \
- kimpersonate.c kinit.c kverify.c
-am__can_run_installinfo = \
- case $$AM_UPDATE_INFO_DIR in \
- n|no|NO) false;; \
- *) (install-info --version) >/dev/null 2>&1;; \
- esac
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__uninstall_files_from_dir = { \
- test -z "$$files" \
- || { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
- || { echo " ( cd '$$dir' && rm -f" $$files ")"; \
- $(am__cd) "$$dir" && rm -f $$files; }; \
- }
-man1dir = $(mandir)/man1
-man8dir = $(mandir)/man8
-MANS = $(man_MANS)
-am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
-# Read a list of newline-separated strings from the standard input,
-# and print each of them once, without duplicates. Input order is
-# *not* preserved.
-am__uniquify_input = $(AWK) '\
- BEGIN { nonempty = 0; } \
- { items[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in items) print i; }; } \
-'
-# Make sure the list of sources is unique. This is necessary because,
-# e.g., the same source file might be shared among _SOURCES variables
-# for different programs/libraries.
-am__define_uniq_tagged_files = \
- list='$(am__tagged_files)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | $(am__uniquify_input)`
-am__DIST_COMMON = $(srcdir)/Makefile.in \
- $(top_srcdir)/Makefile.am.common \
- $(top_srcdir)/cf/Makefile.am.common $(top_srcdir)/depcomp
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
-AMTAR = @AMTAR@
-AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
-AR = @AR@
-AS = @AS@
-ASN1_COMPILE = @ASN1_COMPILE@
-ASN1_COMPILE_DEP = @ASN1_COMPILE_DEP@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CANONICAL_HOST = @CANONICAL_HOST@
-CAPNG_CFLAGS = @CAPNG_CFLAGS@
-CAPNG_LIBS = @CAPNG_LIBS@
-CATMAN = @CATMAN@
-CATMANEXT = @CATMANEXT@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CLANG_FORMAT = @CLANG_FORMAT@
-COMPILE_ET = @COMPILE_ET@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CSCOPE = @CSCOPE@
-CTAGS = @CTAGS@
-CYGPATH_W = @CYGPATH_W@
-DB1LIB = @DB1LIB@
-DB3LIB = @DB3LIB@
-DBHEADER = @DBHEADER@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DIR_com_err = @DIR_com_err@
-DIR_hdbdir = @DIR_hdbdir@
-DIR_roken = @DIR_roken@
-DLLTOOL = @DLLTOOL@
-DSYMUTIL = @DSYMUTIL@
-DUMPBIN = @DUMPBIN@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-ENABLE_AFS_STRING_TO_KEY = @ENABLE_AFS_STRING_TO_KEY@
-ETAGS = @ETAGS@
-EXEEXT = @EXEEXT@
-FGREP = @FGREP@
-FILECMD = @FILECMD@
-GCD_MIG = @GCD_MIG@
-GREP = @GREP@
-GROFF = @GROFF@
-INCLUDES_roken = @INCLUDES_roken@
-INCLUDE_libedit = @INCLUDE_libedit@
-INCLUDE_libintl = @INCLUDE_libintl@
-INCLUDE_openldap = @INCLUDE_openldap@
-INCLUDE_openssl_crypto = @INCLUDE_openssl_crypto@
-INCLUDE_readline = @INCLUDE_readline@
-INCLUDE_sqlite3 = @INCLUDE_sqlite3@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LD = @LD@
-LDFLAGS = @LDFLAGS@
-LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@
-LEX = @LEX@
-LEXLIB = @LEXLIB@
-LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
-LIBADD_roken = @LIBADD_roken@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
-LIB_bswap16 = @LIB_bswap16@
-LIB_bswap32 = @LIB_bswap32@
-LIB_bswap64 = @LIB_bswap64@
-LIB_com_err = @LIB_com_err@
-LIB_com_err_a = @LIB_com_err_a@
-LIB_com_err_so = @LIB_com_err_so@
-LIB_crypt = @LIB_crypt@
-LIB_db_create = @LIB_db_create@
-LIB_dbm_firstkey = @LIB_dbm_firstkey@
-LIB_dbopen = @LIB_dbopen@
-LIB_dispatch_async_f = @LIB_dispatch_async_f@
-LIB_dladdr = @LIB_dladdr@
-LIB_dlopen = @LIB_dlopen@
-LIB_dn_expand = @LIB_dn_expand@
-LIB_dns_search = @LIB_dns_search@
-LIB_door_create = @LIB_door_create@
-LIB_freeaddrinfo = @LIB_freeaddrinfo@
-LIB_gai_strerror = @LIB_gai_strerror@
-LIB_getaddrinfo = @LIB_getaddrinfo@
-LIB_gethostbyname = @LIB_gethostbyname@
-LIB_gethostbyname2 = @LIB_gethostbyname2@
-LIB_getnameinfo = @LIB_getnameinfo@
-LIB_getpwnam_r = @LIB_getpwnam_r@
-LIB_getsockopt = @LIB_getsockopt@
-LIB_hcrypto = @LIB_hcrypto@
-LIB_hcrypto_a = @LIB_hcrypto_a@
-LIB_hcrypto_appl = @LIB_hcrypto_appl@
-LIB_hcrypto_so = @LIB_hcrypto_so@
-LIB_hstrerror = @LIB_hstrerror@
-LIB_kdb = @LIB_kdb@
-LIB_libedit = @LIB_libedit@
-LIB_libintl = @LIB_libintl@
-LIB_loadquery = @LIB_loadquery@
-LIB_logout = @LIB_logout@
-LIB_logwtmp = @LIB_logwtmp@
-LIB_openldap = @LIB_openldap@
-LIB_openpty = @LIB_openpty@
-LIB_openssl_crypto = @LIB_openssl_crypto@
-LIB_otp = @LIB_otp@
-LIB_pidfile = @LIB_pidfile@
-LIB_readline = @LIB_readline@
-LIB_res_ndestroy = @LIB_res_ndestroy@
-LIB_res_nsearch = @LIB_res_nsearch@
-LIB_res_search = @LIB_res_search@
-LIB_roken = @LIB_roken@
-LIB_security = @LIB_security@
-LIB_setsockopt = @LIB_setsockopt@
-LIB_socket = @LIB_socket@
-LIB_sqlite3 = @LIB_sqlite3@
-LIB_syslog = @LIB_syslog@
-LIB_tgetent = @LIB_tgetent@
-LIPO = @LIPO@
-LMDBLIB = @LMDBLIB@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MANIFEST_TOOL = @MANIFEST_TOOL@
-MKDIR_P = @MKDIR_P@
-NDBMLIB = @NDBMLIB@
-NM = @NM@
-NMEDIT = @NMEDIT@
-NO_AFS = @NO_AFS@
-NROFF = @NROFF@
-OBJDUMP = @OBJDUMP@
-OBJEXT = @OBJEXT@
-OTOOL = @OTOOL@
-OTOOL64 = @OTOOL64@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL = @PERL@
-PKG_CONFIG = @PKG_CONFIG@
-PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
-PTHREAD_LDADD = @PTHREAD_LDADD@
-PTHREAD_LIBADD = @PTHREAD_LIBADD@
-PYTHON = @PYTHON@
-PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
-PYTHON_PLATFORM = @PYTHON_PLATFORM@
-PYTHON_PREFIX = @PYTHON_PREFIX@
-PYTHON_VERSION = @PYTHON_VERSION@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-SLC = @SLC@
-SLC_DEP = @SLC_DEP@
-STRIP = @STRIP@
-VERSION = @VERSION@
-VERSIONING = @VERSIONING@
-WFLAGS = @WFLAGS@
-WFLAGS_LITE = @WFLAGS_LITE@
-YACC = @YACC@
-YFLAGS = @YFLAGS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-db_type = @db_type@
-db_type_preference = @db_type_preference@
-docdir = @docdir@
-dpagaix_cflags = @dpagaix_cflags@
-dpagaix_ldadd = @dpagaix_ldadd@
-dpagaix_ldflags = @dpagaix_ldflags@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-pkgpyexecdir = @pkgpyexecdir@
-pkgpythondir = @pkgpythondir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-pyexecdir = @pyexecdir@
-pythondir = @pythondir@
-runstatedir = @runstatedir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-subdirs = @subdirs@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-SUFFIXES = .et .h .pc.in .pc .x .z .hx .1 .3 .5 .7 .8 .cat1 .cat3 \
- .cat5 .cat7 .cat8
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include
-AM_CPPFLAGS = $(INCLUDES_roken) -I$(srcdir)/../lib/krb5 \
- $(INCLUDE_libintl) -DHEIMDAL_LOCALEDIR='"$(localedir)"'
-@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME
-AM_CFLAGS = $(WFLAGS)
-CP = cp
-buildinclude = $(top_builddir)/include
-LIB_XauReadAuth = @LIB_XauReadAuth@
-LIB_el_init = @LIB_el_init@
-LIB_getattr = @LIB_getattr@
-LIB_getpwent_r = @LIB_getpwent_r@
-LIB_odm_initialize = @LIB_odm_initialize@
-LIB_setpcred = @LIB_setpcred@
-INCLUDE_krb4 = @INCLUDE_krb4@
-LIB_krb4 = @LIB_krb4@
-libexec_heimdaldir = $(libexecdir)/heimdal
-NROFF_MAN = groff -mandoc -Tascii
-@NO_AFS_FALSE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
-@NO_AFS_TRUE@LIB_kafs =
-@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \
-@KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la
-
-@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
-LIB_heimbase = $(top_builddir)/lib/base/libheimbase.la
-@DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la
-
-#silent-rules
-heim_verbose = $(heim_verbose_$(V))
-heim_verbose_ = $(heim_verbose_$(AM_DEFAULT_VERBOSITY))
-heim_verbose_0 = @echo " GEN "$@;
-@NO_AFS_FALSE@afs_lib = $(LIB_kafs)
-man_MANS = \
- kinit.1 \
- klist.1 \
- kdestroy.1 \
- kswitch.1 \
- kdigest.8 \
- kgetcred.1 \
- kimpersonate.8
-
-kinit_LDADD = \
- $(afs_lib) \
- $(top_builddir)/lib/krb5/libkrb5.la \
- $(top_builddir)/lib/ntlm/libheimntlm.la \
- $(LIB_hcrypto) \
- $(top_builddir)/lib/asn1/libasn1.la \
- $(LIB_libintl) \
- $(LIB_roken)
-
-kdestroy_LDADD = $(kinit_LDADD)
-kimpersonate_LDADD = $(kinit_LDADD)
-heimtools_LDADD = \
- $(top_builddir)/lib/sl/libsl.la \
- $(kinit_LDADD) \
- $(LIB_readline)
-
-dist_heimtools_SOURCES = heimtools.c klist.c kswitch.c copy_cred_cache.c
-nodist_heimtools_SOURCES = heimtools-commands.c
-dist_kdigest_SOURCES = kdigest.c
-nodist_kdigest_SOURCES = kdigest-commands.c
-kdigest_LDADD = \
- $(top_builddir)/lib/ntlm/libheimntlm.la \
- $(top_builddir)/lib/krb5/libkrb5.la \
- $(LIB_hcrypto) \
- $(top_builddir)/lib/asn1/libasn1.la \
- $(top_builddir)/lib/sl/libsl.la \
- $(LIB_roken)
-
-CLEANFILES = \
- kdigest-commands.h kdigest-commands.c \
- heimtools-commands.h heimtools-commands.c
-
-LDADD = \
- $(top_builddir)/lib/krb5/libkrb5.la \
- $(LIB_hcrypto) \
- $(top_builddir)/lib/asn1/libasn1.la \
- $(LIB_roken)
-
-EXTRA_DIST = NTMakefile $(man_MANS) \
- heimtools-version.rc \
- kcpytkt.c \
- kdeltkt.c \
- kvno.c \
- kdestroy-version.rc \
- kdigest-version.rc \
- kgetcred-version.rc \
- kimpersonate-version.rc \
- kinit-version.rc \
- kuser_locl.h heimtools-commands.in kdigest-commands.in copy_cred_cache.1
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .et .h .pc.in .pc .x .z .hx .1 .3 .5 .7 .8 .cat1 .cat3 .cat5 .cat7 .cat8 .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign kuser/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign kuser/Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \
- esac;
-$(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__empty):
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-binPROGRAMS: $(bin_PROGRAMS)
- @$(NORMAL_INSTALL)
- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \
- fi; \
- for p in $$list; do echo "$$p $$p"; done | \
- sed 's/$(EXEEXT)$$//' | \
- while read p p1; do if test -f $$p \
- || test -f $$p1 \
- ; then echo "$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n;h' \
- -e 's|.*|.|' \
- -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
- sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) files[d] = files[d] " " $$1; \
- else { print "f", $$3 "/" $$4, $$1; } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-binPROGRAMS:
- @$(NORMAL_UNINSTALL)
- @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
- -e 's/$$/$(EXEEXT)/' \
- `; \
- test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(bindir)" && rm -f $$files
-
-clean-binPROGRAMS:
- @list='$(bin_PROGRAMS)'; test -n "$$list" || exit 0; \
- echo " rm -f" $$list; \
- rm -f $$list || exit $$?; \
- test -n "$(EXEEXT)" || exit 0; \
- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f" $$list; \
- rm -f $$list
-install-libexecPROGRAMS: $(libexec_PROGRAMS)
- @$(NORMAL_INSTALL)
- @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
- if test -n "$$list"; then \
- echo " $(MKDIR_P) '$(DESTDIR)$(libexecdir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(libexecdir)" || exit 1; \
- fi; \
- for p in $$list; do echo "$$p $$p"; done | \
- sed 's/$(EXEEXT)$$//' | \
- while read p p1; do if test -f $$p \
- || test -f $$p1 \
- ; then echo "$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n;h' \
- -e 's|.*|.|' \
- -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \
- sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) files[d] = files[d] " " $$1; \
- else { print "f", $$3 "/" $$4, $$1; } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(libexecdir)$$dir'"; \
- $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(libexecdir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-libexecPROGRAMS:
- @$(NORMAL_UNINSTALL)
- @list='$(libexec_PROGRAMS)'; test -n "$(libexecdir)" || list=; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \
- -e 's/$$/$(EXEEXT)/' \
- `; \
- test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(libexecdir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(libexecdir)" && rm -f $$files
-
-clean-libexecPROGRAMS:
- @list='$(libexec_PROGRAMS)'; test -n "$$list" || exit 0; \
- echo " rm -f" $$list; \
- rm -f $$list || exit $$?; \
- test -n "$(EXEEXT)" || exit 0; \
- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f" $$list; \
- rm -f $$list
-
-clean-noinstPROGRAMS:
- @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
- echo " rm -f" $$list; \
- rm -f $$list || exit $$?; \
- test -n "$(EXEEXT)" || exit 0; \
- list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
- echo " rm -f" $$list; \
- rm -f $$list
-
-generate-requests$(EXEEXT): $(generate_requests_OBJECTS) $(generate_requests_DEPENDENCIES) $(EXTRA_generate_requests_DEPENDENCIES)
- @rm -f generate-requests$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(generate_requests_OBJECTS) $(generate_requests_LDADD) $(LIBS)
-
-heimtools$(EXEEXT): $(heimtools_OBJECTS) $(heimtools_DEPENDENCIES) $(EXTRA_heimtools_DEPENDENCIES)
- @rm -f heimtools$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(heimtools_OBJECTS) $(heimtools_LDADD) $(LIBS)
-
-kdecode_ticket$(EXEEXT): $(kdecode_ticket_OBJECTS) $(kdecode_ticket_DEPENDENCIES) $(EXTRA_kdecode_ticket_DEPENDENCIES)
- @rm -f kdecode_ticket$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(kdecode_ticket_OBJECTS) $(kdecode_ticket_LDADD) $(LIBS)
-
-kdestroy$(EXEEXT): $(kdestroy_OBJECTS) $(kdestroy_DEPENDENCIES) $(EXTRA_kdestroy_DEPENDENCIES)
- @rm -f kdestroy$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(kdestroy_OBJECTS) $(kdestroy_LDADD) $(LIBS)
-
-kdigest$(EXEEXT): $(kdigest_OBJECTS) $(kdigest_DEPENDENCIES) $(EXTRA_kdigest_DEPENDENCIES)
- @rm -f kdigest$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(kdigest_OBJECTS) $(kdigest_LDADD) $(LIBS)
-
-kgetcred$(EXEEXT): $(kgetcred_OBJECTS) $(kgetcred_DEPENDENCIES) $(EXTRA_kgetcred_DEPENDENCIES)
- @rm -f kgetcred$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(kgetcred_OBJECTS) $(kgetcred_LDADD) $(LIBS)
-
-kimpersonate$(EXEEXT): $(kimpersonate_OBJECTS) $(kimpersonate_DEPENDENCIES) $(EXTRA_kimpersonate_DEPENDENCIES)
- @rm -f kimpersonate$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(kimpersonate_OBJECTS) $(kimpersonate_LDADD) $(LIBS)
-
-kinit$(EXEEXT): $(kinit_OBJECTS) $(kinit_DEPENDENCIES) $(EXTRA_kinit_DEPENDENCIES)
- @rm -f kinit$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(kinit_OBJECTS) $(kinit_LDADD) $(LIBS)
-
-kverify$(EXEEXT): $(kverify_OBJECTS) $(kverify_DEPENDENCIES) $(EXTRA_kverify_DEPENDENCIES)
- @rm -f kverify$(EXEEXT)
- $(AM_V_CCLD)$(LINK) $(kverify_OBJECTS) $(kverify_LDADD) $(LIBS)
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/copy_cred_cache.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/generate-requests.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heimtools-commands.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/heimtools.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdecode_ticket.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdestroy.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdigest-commands.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kdigest.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kgetcred.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kimpersonate.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kinit.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/klist.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kswitch.Po@am__quote@ # am--include-marker
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/kverify.Po@am__quote@ # am--include-marker
-
-$(am__depfiles_remade):
- @$(MKDIR_P) $(@D)
- @echo '# dummy' >$@-t && $(am__mv) $@-t $@
-
-am--depfiles: $(am__depfiles_remade)
-
-.c.o:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $<
-
-.c.obj:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
-
-.c.lo:
-@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
-@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-install-man1: $(man_MANS)
- @$(NORMAL_INSTALL)
- @list1=''; \
- list2='$(man_MANS)'; \
- test -n "$(man1dir)" \
- && test -n "`echo $$list1$$list2`" \
- || exit 0; \
- echo " $(MKDIR_P) '$(DESTDIR)$(man1dir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(man1dir)" || exit 1; \
- { for i in $$list1; do echo "$$i"; done; \
- if test -n "$$list2"; then \
- for i in $$list2; do echo "$$i"; done \
- | sed -n '/\.1[a-z]*$$/p'; \
- fi; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
- done; }
-
-uninstall-man1:
- @$(NORMAL_UNINSTALL)
- @list=''; test -n "$(man1dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.1[a-z]*$$/p'; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- dir='$(DESTDIR)$(man1dir)'; $(am__uninstall_files_from_dir)
-install-man8: $(man_MANS)
- @$(NORMAL_INSTALL)
- @list1=''; \
- list2='$(man_MANS)'; \
- test -n "$(man8dir)" \
- && test -n "`echo $$list1$$list2`" \
- || exit 0; \
- echo " $(MKDIR_P) '$(DESTDIR)$(man8dir)'"; \
- $(MKDIR_P) "$(DESTDIR)$(man8dir)" || exit 1; \
- { for i in $$list1; do echo "$$i"; done; \
- if test -n "$$list2"; then \
- for i in $$list2; do echo "$$i"; done \
- | sed -n '/\.8[a-z]*$$/p'; \
- fi; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man8dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man8dir)" || exit $$?; }; \
- done; }
-
-uninstall-man8:
- @$(NORMAL_UNINSTALL)
- @list=''; test -n "$(man8dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.8[a-z]*$$/p'; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^8][0-9a-z]*$$,8,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- dir='$(DESTDIR)$(man8dir)'; $(am__uninstall_files_from_dir)
-
-ID: $(am__tagged_files)
- $(am__define_uniq_tagged_files); mkid -fID $$unique
-tags: tags-am
-TAGS: tags
-
-tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- set x; \
- here=`pwd`; \
- $(am__define_uniq_tagged_files); \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: ctags-am
-
-CTAGS: ctags
-ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
- $(am__define_uniq_tagged_files); \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-cscopelist: cscopelist-am
-
-cscopelist-am: $(am__tagged_files)
- list='$(am__tagged_files)'; \
- case "$(srcdir)" in \
- [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
- *) sdir=$(subdir)/$(srcdir) ;; \
- esac; \
- for i in $$list; do \
- if test -f "$$i"; then \
- echo "$(subdir)/$$i"; \
- else \
- echo "$$sdir/$$i"; \
- fi; \
- done >> $(top_builddir)/cscope.files
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-distdir: $(BUILT_SOURCES)
- $(MAKE) $(AM_MAKEFLAGS) distdir-am
-
-distdir-am: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$(top_distdir)" distdir="$(distdir)" \
- dist-hook
-check-am: all-am
- $(MAKE) $(AM_MAKEFLAGS) check-local
-check: check-am
-all-am: Makefile $(PROGRAMS) $(MANS) all-local
-installdirs:
- for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" "$(DESTDIR)$(man1dir)" "$(DESTDIR)$(man8dir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- if test -z '$(STRIP)'; then \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- install; \
- else \
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
- fi
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-binPROGRAMS clean-generic clean-libexecPROGRAMS \
- clean-libtool clean-noinstPROGRAMS mostlyclean-am
-
-distclean: distclean-am
- -rm -f ./$(DEPDIR)/copy_cred_cache.Po
- -rm -f ./$(DEPDIR)/generate-requests.Po
- -rm -f ./$(DEPDIR)/heimtools-commands.Po
- -rm -f ./$(DEPDIR)/heimtools.Po
- -rm -f ./$(DEPDIR)/kdecode_ticket.Po
- -rm -f ./$(DEPDIR)/kdestroy.Po
- -rm -f ./$(DEPDIR)/kdigest-commands.Po
- -rm -f ./$(DEPDIR)/kdigest.Po
- -rm -f ./$(DEPDIR)/kgetcred.Po
- -rm -f ./$(DEPDIR)/kimpersonate.Po
- -rm -f ./$(DEPDIR)/kinit.Po
- -rm -f ./$(DEPDIR)/klist.Po
- -rm -f ./$(DEPDIR)/kswitch.Po
- -rm -f ./$(DEPDIR)/kverify.Po
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-man
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-data-hook
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am: install-binPROGRAMS install-exec-local \
- install-libexecPROGRAMS
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man: install-man1 install-man8
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f ./$(DEPDIR)/copy_cred_cache.Po
- -rm -f ./$(DEPDIR)/generate-requests.Po
- -rm -f ./$(DEPDIR)/heimtools-commands.Po
- -rm -f ./$(DEPDIR)/heimtools.Po
- -rm -f ./$(DEPDIR)/kdecode_ticket.Po
- -rm -f ./$(DEPDIR)/kdestroy.Po
- -rm -f ./$(DEPDIR)/kdigest-commands.Po
- -rm -f ./$(DEPDIR)/kdigest.Po
- -rm -f ./$(DEPDIR)/kgetcred.Po
- -rm -f ./$(DEPDIR)/kimpersonate.Po
- -rm -f ./$(DEPDIR)/kinit.Po
- -rm -f ./$(DEPDIR)/klist.Po
- -rm -f ./$(DEPDIR)/kswitch.Po
- -rm -f ./$(DEPDIR)/kverify.Po
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-binPROGRAMS uninstall-libexecPROGRAMS \
- uninstall-man
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) uninstall-hook
-uninstall-man: uninstall-man1 uninstall-man8
-
-.MAKE: check-am install-am install-data-am install-exec-am \
- install-strip uninstall-am
-
-.PHONY: CTAGS GTAGS TAGS all all-am all-local am--depfiles check \
- check-am check-local clean clean-binPROGRAMS clean-generic \
- clean-libexecPROGRAMS clean-libtool clean-noinstPROGRAMS \
- cscopelist-am ctags ctags-am dist-hook distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-binPROGRAMS install-data \
- install-data-am install-data-hook install-dvi install-dvi-am \
- install-exec install-exec-am install-exec-hook \
- install-exec-local install-html install-html-am install-info \
- install-info-am install-libexecPROGRAMS install-man \
- install-man1 install-man8 install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-compile \
- mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
- tags tags-am uninstall uninstall-am uninstall-binPROGRAMS \
- uninstall-hook uninstall-libexecPROGRAMS uninstall-man \
- uninstall-man1 uninstall-man8
-
-.PRECIOUS: Makefile
-
-
-install-suid-programs:
- @foo='$(bin_SUIDS)'; \
- for file in $$foo; do \
- x=$(DESTDIR)$(bindir)/$$file; \
- if chown 0:0 $$x && chmod u+s $$x; then :; else \
- echo "*"; \
- echo "* Failed to install $$x setuid root"; \
- echo "*"; \
- fi; \
- done
-
-install-exec-local: install-suid-programs
-
-codesign-all:
- @if [ X"$$CODE_SIGN_IDENTITY" != X ] ; then \
- foo='$(bin_PROGRAMS) $(sbin_PROGRAMS) $(libexec_PROGRAMS)' ; \
- for file in $$foo ; do \
- echo "CODESIGN $$file" ; \
- codesign -f -s "$$CODE_SIGN_IDENTITY" $$file || exit 1 ; \
- done ; \
- fi
-
-all-local: codesign-all
-
-install-build-headers:: $(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(nobase_include_HEADERS) $(noinst_HEADERS)
- @foo='$(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(noinst_HEADERS)'; \
- for f in $$foo; do \
- f=`basename $$f`; \
- if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
- else file="$$f"; fi; \
- if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
- : ; else \
- echo " $(CP) $$file $(buildinclude)/$$f"; \
- $(CP) $$file $(buildinclude)/$$f || true; \
- fi ; \
- done ; \
- foo='$(nobase_include_HEADERS)'; \
- for f in $$foo; do \
- if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \
- else file="$$f"; fi; \
- $(mkdir_p) $(buildinclude)/`dirname $$f` ; \
- if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
- : ; else \
- echo " $(CP) $$file $(buildinclude)/$$f"; \
- $(CP) $$file $(buildinclude)/$$f; \
- fi ; \
- done
-
-all-local: install-build-headers
-
-check-local::
- @if test '$(CHECK_LOCAL)' = "no-check-local"; then \
- foo=''; elif test '$(CHECK_LOCAL)'; then \
- foo='$(CHECK_LOCAL)'; else \
- foo='$(PROGRAMS)'; fi; \
- if test "$$foo"; then \
- failed=0; all=0; \
- for i in $$foo; do \
- all=`expr $$all + 1`; \
- if (./$$i --version && ./$$i --help) > /dev/null 2>&1; then \
- echo "PASS: $$i"; \
- else \
- echo "FAIL: $$i"; \
- failed=`expr $$failed + 1`; \
- fi; \
- done; \
- if test "$$failed" -eq 0; then \
- banner="All $$all tests passed"; \
- else \
- banner="$$failed of $$all tests failed"; \
- fi; \
- dashes=`echo "$$banner" | sed s/./=/g`; \
- echo "$$dashes"; \
- echo "$$banner"; \
- echo "$$dashes"; \
- test "$$failed" -eq 0 || exit 1; \
- fi
-
-# It's useful for debugging to format generated sources. The default for all
-# clang-format styles is to sort includes, but in many cases in-tree we really
-# don't want to do that.
-.x.c:
- @if [ -z "$(CLANG_FORMAT)" ]; then \
- cmp -s $< $@ 2> /dev/null || cp $< $@; \
- else \
- cp $< $@.tmp.c; \
- $(CLANG_FORMAT) -style='{BasedOnStyle: Chromium, SortIncludes: false}' -i $@.tmp.c; \
- cmp -s $@.tmp.c $@ 2> /dev/null || mv $@.tmp.c $@; \
- fi
-
-.hx.h:
- @cmp -s $< $@ 2> /dev/null || cp $< $@;
-#NROFF_MAN = nroff -man
-.1.cat1:
- $(NROFF_MAN) $< > $@
-.3.cat3:
- $(NROFF_MAN) $< > $@
-.5.cat5:
- $(NROFF_MAN) $< > $@
-.7.cat7:
- $(NROFF_MAN) $< > $@
-.8.cat8:
- $(NROFF_MAN) $< > $@
-
-dist-cat1-mans:
- @foo='$(man1_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.1) foo="$$foo $$i";; \
- esac; done ;\
- for i in $$foo; do \
- x=`echo $$i | sed 's/\.[^.]*$$/.cat1/'`; \
- echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
- $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
- done
-
-dist-cat3-mans:
- @foo='$(man3_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.3) foo="$$foo $$i";; \
- esac; done ;\
- for i in $$foo; do \
- x=`echo $$i | sed 's/\.[^.]*$$/.cat3/'`; \
- echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
- $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
- done
-
-dist-cat5-mans:
- @foo='$(man5_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.5) foo="$$foo $$i";; \
- esac; done ;\
- for i in $$foo; do \
- x=`echo $$i | sed 's/\.[^.]*$$/.cat5/'`; \
- echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
- $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
- done
-
-dist-cat7-mans:
- @foo='$(man7_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.7) foo="$$foo $$i";; \
- esac; done ;\
- for i in $$foo; do \
- x=`echo $$i | sed 's/\.[^.]*$$/.cat7/'`; \
- echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
- $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
- done
-
-dist-cat8-mans:
- @foo='$(man8_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.8) foo="$$foo $$i";; \
- esac; done ;\
- for i in $$foo; do \
- x=`echo $$i | sed 's/\.[^.]*$$/.cat8/'`; \
- echo "$(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x"; \
- $(NROFF_MAN) $(srcdir)/$$i > $(distdir)/$$x; \
- done
-
-dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat7-mans dist-cat8-mans
-
-install-cat-mans:
- $(SHELL) $(top_srcdir)/cf/install-catman.sh install "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man7_MANS) $(man8_MANS)
-
-uninstall-cat-mans:
- $(SHELL) $(top_srcdir)/cf/install-catman.sh uninstall "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man7_MANS) $(man8_MANS)
-
-install-data-hook: install-cat-mans
-uninstall-hook: uninstall-cat-mans
-
-.et.h:
- $(COMPILE_ET) $<
-.et.c:
- $(COMPILE_ET) $<
-
-#
-# Useful target for debugging
-#
-
-check-valgrind:
- tobjdir=`cd $(top_builddir) && pwd` ; \
- tsrcdir=`cd $(top_srcdir) && pwd` ; \
- env TESTS_ENVIRONMENT="$${tsrcdir}/cf/maybe-valgrind.sh -s $${tsrcdir} -o $${tobjdir}" make check
-
-#
-# Target to please samba build farm, builds distfiles in-tree.
-# Will break when automake changes...
-#
-
-distdir-in-tree: $(DISTFILES) $(INFO_DEPS)
- list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" != .; then \
- (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) distdir-in-tree) ; \
- fi ; \
- done
-
-$(heimtools_OBJECTS): heimtools-commands.h
-
-$(kdigest_OBJECTS): kdigest-commands.h
-
-kdigest-commands.c kdigest-commands.h: kdigest-commands.in
- $(SLC) $(srcdir)/kdigest-commands.in
-
-heimtools-commands.c heimtools-commands.h: heimtools-commands.in
- $(SLC) $(srcdir)/heimtools-commands.in
-
-# make sure install-exec-hook doesn't have any commands in Makefile.am.common
-install-exec-hook:
- (cd $(DESTDIR)$(bindir) && rm -f klist && $(LN_S) heimtools klist)
- (cd $(DESTDIR)$(bindir) && rm -f kswitch && $(LN_S) heimtools kswitch)
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/kuser/NTMakefile b/kuser/NTMakefile
index f9106c391611..4b97b7084e7b 100644
--- a/kuser/NTMakefile
+++ b/kuser/NTMakefile
@@ -31,7 +31,7 @@
RELDIR=kuser
-intcflags=-I$(OBJ)
+intcflags=-I$(OBJ) -I$(SRC)\lib\gssapi -I$(OBJDIR)\lib\gssapi -I$(OBJDIR)\lib\gss_preauth
!include ../windows/NTMakefile.w32
@@ -55,8 +55,12 @@ NOINSTPROGRAMS=\
BINLIBS=\
+ $(LIBHEIMBASE) \
+ $(LIBGSS_PREAUTH) \
+ $(LIBGSSAPI) \
$(LIBHEIMDAL) \
$(LIBHEIMNTLM) \
+ $(LIBHX509) \
!if !defined(NO_AFS)
$(LIBKAFS) \
!endif
@@ -70,7 +74,7 @@ clean::
$(BINDIR)\kinit.exe: $(OBJ)\kinit.obj $(BINLIBS) $(OBJ)\kinit-version.res
- $(EXECONLINK)
+ $(EXECONLINK) Secur32.lib Shell32.lib
$(EXEPREP)
HEIMTOOLS_OBJS = \
@@ -78,6 +82,7 @@ HEIMTOOLS_OBJS = \
$(OBJ)\heimtools.obj \
$(OBJ)\kswitch.obj \
$(OBJ)\klist.obj \
+ $(OBJ)\kx509.obj \
$(OBJ)\copy_cred_cache.obj
HEIMTOOLSLIBS=\
@@ -85,7 +90,7 @@ HEIMTOOLSLIBS=\
$(LIBSL)
$(BINDIR)\heimtools.exe: $(HEIMTOOLS_OBJS) $(HEIMTOOLSLIBS) $(OBJ)\heimtools-version.res
- $(EXECONLINK)
+ $(EXECONLINK) Secur32.lib Shell32.lib
$(EXEPREP)
diff --git a/kuser/generate-requests.c b/kuser/generate-requests.c
index 1196c16dc679..2dd71bf7ab8a 100644
--- a/kuser/generate-requests.c
+++ b/kuser/generate-requests.c
@@ -49,7 +49,7 @@ read_words (const char *filename, char ***ret_w)
buf[strcspn(buf, "\r\n")] = '\0';
if (n >= alloc) {
alloc += 16;
- w = erealloc (w, alloc * sizeof(char **));
+ w = erealloc (w, alloc * sizeof(*w));
}
w[n++] = estrdup (buf);
}
diff --git a/kuser/heimtools-commands.in b/kuser/heimtools-commands.in
index b22a8c58d882..ea8b073f6edf 100644
--- a/kuser/heimtools-commands.in
+++ b/kuser/heimtools-commands.in
@@ -238,6 +238,61 @@ command = {
min_args = "1"
max_args = "2"
help = "Copies credential caches"
+ argument = "[source] destination"
+}
+command = {
+ name = "kx509"
+ help = "Acquire or extract certificates"
+ option = {
+ long = "cache"
+ short = "c"
+ type = "string"
+ help = "Kerberos credential cache"
+ }
+ option = {
+ long = "save"
+ short = "s"
+ type = "flag"
+ help = "save the certificate and private key in the Kerberos credential cache"
+ }
+ option = {
+ long = "out"
+ short = "o"
+ type = "string"
+ help = "hx509 store for kx509 certificate and private key"
+ }
+ option = {
+ long = "extract"
+ short = "x"
+ type = "flag"
+ help = "extract certificate and private key from credential cache"
+ }
+ option = {
+ long = "test"
+ short = "t"
+ type = "integer"
+ help = "check for certificate with at least given time left"
+ }
+ option = {
+ name = "private-key"
+ short = "K"
+ type = "string"
+ help = "hx509 store containing private key"
+ }
+ option = {
+ name = "csr"
+ short = "C"
+ type = "string"
+ help = "file containing DER-encoded PKCS#10 certificate request"
+ }
+ option = {
+ name = "realm"
+ short = "r"
+ type = "string"
+ help = "realm from which to acquire certificate"
+ }
+ min_args = "0"
+ max_args = "0"
}
command = {
name = "help"
diff --git a/kuser/kdestroy.c b/kuser/kdestroy.c
index feabe55fdcdb..1823bf56ca48 100644
--- a/kuser/kdestroy.c
+++ b/kuser/kdestroy.c
@@ -90,9 +90,7 @@ main (int argc, char **argv)
}
argc -= optidx;
-#ifndef __clang_analyzer__
argv += optidx;
-#endif
if (argc != 0)
usage (1);
diff --git a/kuser/kdestroy.cat1 b/kuser/kdestroy.cat1
deleted file mode 100644
index 324ab85ff05c..000000000000
--- a/kuser/kdestroy.cat1
+++ /dev/null
@@ -1,36 +0,0 @@
-KDESTROY(1) BSD General Commands Manual KDESTROY(1)
-
-NAME
- kdestroy -- remove one credential or destroy the current ticket file
-
-SYNOPSIS
- kdestroy [-c cachefile] [--credential=principal] [--cache=cachefile]
- [-A | --all] [--no-unlog] [--no-delete-v4] [--version] [--help]
-
-DESCRIPTION
- kdestroy removes one credential or the current set of tickets.
-
- Supported options:
-
- -credential=principal
- remove principal from the credential cache if it exists.
-
- -c cachefile
-
- -cache=cachefile
- The cache file to remove.
-
- -A
-
- --all remove all credential caches.
-
- --no-unlog
- Do not remove AFS tokens.
-
- --no-delete-v4
- Do not remove v4 tickets.
-
-SEE ALSO
- kinit(1), klist(1)
-
-HEIMDAL April 27, 2006 HEIMDAL
diff --git a/kuser/kdigest.cat8 b/kuser/kdigest.cat8
deleted file mode 100644
index a407888796e0..000000000000
--- a/kuser/kdigest.cat8
+++ /dev/null
@@ -1,132 +0,0 @@
-KDIGEST(8) BSD System Manager's Manual KDIGEST(8)
-
-NAME
- kdigest -- userland tool to access digest interface in the KDC
-
-SYNOPSIS
- kdigest [--ccache=string] [--version] [--help] command [arguments]
-
-DESCRIPTION
- Supported options:
-
- --ccache=string
- credential cache
-
- --version
- print version
-
- --help
-
- Available commands are:
-
- digest-probe [--realm=string] [-h | --help]
-
- --realm=string
- Kerberos realm to communicate with
-
- digest-server-init [--type=string] [--kerberos-realm=realm]
- [--digest=digest-type] [--cb-type=type] [--cb-value=value]
- [--hostname=hostname] [--realm=string]
-
- --type=string
- digest type
-
- --kerberos-realm=realm
-
- --digest=digest-type
- digest type to use in the algorithm
-
- --cb-type=type
- type of channel bindings
-
- --cb-value=value
- value of channel bindings
-
- --hostname=hostname
- hostname of the server
-
- --realm=string
- Kerberos realm to communicate with
-
- digest-server-request [--type=string] [--kerberos-realm=realm]
- [--username=name] [--server-nonce=nonce]
- [--server-identifier=nonce] [--client-nonce=nonce]
- [--client-response=response] [--opaque=string]
- [--authentication-name=name] [--realm=realm] [--method=method]
- [--uri=uri] [--nounce-count=count] [--qop=qop] [--ccache=ccache]
-
- --type=string
- digest type
-
- --kerberos-realm=realm
-
- --username=name
- digest type
-
- --server-nonce=nonce
-
- --server-identifier=nonce
-
- --client-nonce=nonce
-
- --client-response=response
-
- --opaque=string
-
- --authentication-name=name
-
- --realm=realm
-
- --method=method
-
- --uri=uri
-
- --nounce-count=count
-
- --qop=qop
-
- --ccache=ccache
- Where the the credential cache is created when the KDC
- returns tickets
-
- digest-client-request [--type=string] [--username=name]
- [--password=password] [--server-nonce=nonce]
- [--server-identifier=nonce] [--client-nonce=nonce]
- [--opaque=string] [--realm=realm] [--method=method] [--uri=uri]
- [--nounce-count=count] [--qop=qop]
-
- --type=string
- digest type
-
- --username=name
- digest type
-
- --password=password
-
- --server-nonce=nonce
-
- --server-identifier=nonce
-
- --client-nonce=nonce
-
- --opaque=string
-
- --realm=realm
-
- --method=method
-
- --uri=uri
-
- --nounce-count=count
-
- --qop=qop
-
- ntlm-server-init [--version=integer] [--kerberos-realm=string]
-
- --version=integer
- ntlm version
-
- --kerberos-realm=string
- Kerberos realm to communicate with
-
-HEIMDAL September 25, 2008 HEIMDAL
diff --git a/kuser/kgetcred.1 b/kuser/kgetcred.1
index c8473ab99a5e..f6c8461daec8 100644
--- a/kuser/kgetcred.1
+++ b/kuser/kgetcred.1
@@ -167,6 +167,20 @@ same behavior as using the
.Fl Fl canonicalize
.Fl Fl hostbased
options here.
+.Sh ENVIRONMENT
+.Bl -tag -width Ds
+.It Ev KRB5CCNAME
+Specifies the default credentials cache.
+.It Ev KRB5_CONFIG
+The file name of
+.Pa krb5.conf ,
+the default being
+.Pa /etc/krb5.conf .
+.It Ev KRB5_NO_TICKET_STORE
+If this variable is present in the environment, any service tickets obtained
+are not added to the credential cache. This affects all heimdal applications
+and library clients, not just kgetcred.
+.El
.Sh SEE ALSO
.Xr kinit 1 ,
.Xr klist 1 ,
diff --git a/kuser/kgetcred.cat1 b/kuser/kgetcred.cat1
deleted file mode 100644
index 25c8fc566372..000000000000
--- a/kuser/kgetcred.cat1
+++ /dev/null
@@ -1,106 +0,0 @@
-KGETCRED(1) BSD General Commands Manual KGETCRED(1)
-
-NAME
- kgetcred -- get a ticket for a particular service
-
-SYNOPSIS
- kgetcred [--canonicalize] [--canonical] [-c -cache | --cache=cache] [-e
- enctype | --enctype=enctype] [--debug] [-H | --hostbased]
- [--name-type=name-type] [--no-transit-check] [--no-store]
- [--cached-only] [-n | --anonymous] [--version] [--help]
- principal
- kgetcred [options] --hostbased principal
- kgetcred [options] --hostbased service hostname [extra-components]
-
-DESCRIPTION
- kgetcred obtains a ticket for the given service principal. Usually tick-
- ets for services are obtained automatically when needed but sometimes for
- some odd reason you want to obtain a particular ticket or of a special
- type.
-
- If --hostbased is given then the given service principal name will be
- canonicalized (see below).
-
- The third form constructs a host-based principal from the given service
- name and hostname. The service name "host" is used if the given service
- name in the third usage is the empty string.
-
- For host-based names, the local host's hostname is used if the given
- hostname is the empty string or if the principal has a single component.
-
- Any additional components will be included, even for host-based service
- principal names, but there are no defaults nor local canonicalization
- rules for additional components.
-
- Local name canonicalization rules are applied unless the --canonical op-
- tion is given. Currently local name canonicalization rules are supported
- only for host-based principal names' hostname component.
-
- The principal's realm name may be canonicalized by following Kerberos re-
- ferrals from the client principal's home realm if the --canonicalize op-
- tion is given or if the local name canonicalization rules are configured
- to use referrals.
-
- Supported options:
-
- --canonicalize
- requests that the KDC canonicalize the principal. Currently this
- only canonicalizes the realm by chasing referrals from the user's
- start realm, but in the future this may also enable the KDC to
- canonicalize the complete principal name.
-
- --canonical
- turns off local canonicalization of the principal name.
-
- --name-type=name-type
- the name-type to use when parsing the principal name.
-
- --hostbased
- is short for --name-type=srv_hst.
-
- -c cache, --cache=cache
- the credential cache to use.
-
- --delegation-credential-cache=cache
- the credential cache to use for delegation.
-
- -e enctype, --enctype=enctype
- encryption type to use.
-
- --no-transit-check
- requests that the KDC doesn't do transit checking.
-
- --no-store
- do not store tickets in the ccache.
-
- --cached-only
- do not talk the TGS, search only the ccache.
-
- --anonymous
- obtain an anonymous service ticket.
-
- --forwardable
-
- --debug
- enables debug output to stderr.
-
- --version
-
- --help
-
- If the --canonical option is used, then no further canonicalization
- should be done locally by the client (for example, DNS), but if
- --canonicalize is used, then the client will ask that the KDC canonical-
- ize the name.
-
- If the --canonicalize option is used with --hostbased a host-based name-
- type, and --canonical is not used, then the hostname will be canonical-
- ized according to the name canonicalization rules in krb5.conf.
-
- GSS-API initiator applications with host-based services will get the same
- behavior as using the --canonicalize --hostbased options here.
-
-SEE ALSO
- kinit(1), klist(1), krb5.conf(5), krb5_openlog(3)
-
-HEIMDAL March 12, 2004 HEIMDAL
diff --git a/kuser/kimpersonate.c b/kuser/kimpersonate.c
index b1cefea0fd49..35b4295fb36d 100644
--- a/kuser/kimpersonate.c
+++ b/kuser/kimpersonate.c
@@ -82,14 +82,12 @@ encode_ticket(krb5_context context,
et.flags = cred->flags.b;
et.key = cred->session;
et.crealm = cred->client->realm;
- ret = copy_PrincipalName(&cred->client->name, &et.cname);
- if (ret)
- krb5_err(context, 1, ret, "copy_PrincipalName");
+ et.cname = cred->client->name;
{
krb5_data empty_string;
krb5_data_zero(&empty_string);
- et.transited.tr_type = DOMAIN_X500_COMPRESS;
+ et.transited.tr_type = domain_X500_Compress;
et.transited.contents = empty_string;
}
et.authtime = cred->times.authtime;
@@ -129,16 +127,11 @@ encode_ticket(krb5_context context,
ticket.tkt_vno = 5;
ticket.realm = cred->server->realm;
- ret = copy_PrincipalName(&cred->server->name, &ticket.sname);
- if (ret)
- krb5_err(context, 1, ret, "copy_PrincipalName");
-
- ASN1_MALLOC_ENCODE(Ticket, buf, len, &ticket, &size, ret);
+ ticket.sname = cred->server->name;
+ ASN1_MALLOC_ENCODE(Ticket, cred->ticket.data, cred->ticket.length, &ticket, &size, ret);
+ free_EncryptedData(&ticket.enc_part);
if(ret)
krb5_err(context, 1, ret, "encode_Ticket");
-
- krb5_data_copy(&cred->ticket, buf, len);
- free(buf);
}
/*
@@ -173,12 +166,13 @@ create_krb5_tickets(krb5_context context, krb5_keytab kt)
ret = krb5_copy_principal(context, client_principal, &cred.client);
+ if (ret == 0)
+ ret = krb5_copy_principal(context, server_principal, &cred.server);
if (ret)
krb5_err(context, 1, ret, "krb5_copy_principal");
- ret = krb5_copy_principal(context, server_principal, &cred.server);
+ ret = krb5_generate_random_keyblock(context, session_etype, &cred.session);
if (ret)
- krb5_err(context, 1, ret, "krb5_copy_principal");
- krb5_generate_random_keyblock(context, session_etype, &cred.session);
+ krb5_err(context, 1, ret, "krb5_generate_random_keyblock");
cred.times.authtime = time(NULL);
cred.times.starttime = time(NULL);
@@ -214,7 +208,7 @@ create_krb5_tickets(krb5_context context, krb5_keytab kt)
}
if (add_to_ccache) {
- krb5_principal def_princ;
+ krb5_principal def_princ = NULL;
/*
* Force fcache to read the ccache header, otherwise the store
@@ -283,13 +277,13 @@ setup_env(krb5_context context, krb5_keytab *kt)
krb5_errx(context, 1, "missing client principal");
ret = krb5_parse_name(context, client_principal_str, &client_principal);
if (ret)
- krb5_err(context, 1, ret, "resolvning client name");
+ krb5_err(context, 1, ret, "resolving client name");
if (server_principal_str == NULL)
krb5_errx(context, 1, "missing server principal");
ret = krb5_parse_name(context, server_principal_str, &server_principal);
if (ret)
- krb5_err(context, 1, ret, "resolvning server name");
+ krb5_err(context, 1, ret, "resolving server name");
/* If no session-enc-type specified on command line and this is an afs */
/* service ticket, change default of session_enc_type to DES. */
@@ -395,6 +389,7 @@ main(int argc, char **argv)
create_krb5_tickets(context, kt);
krb5_kt_close(context, kt);
+ krb5_free_context(context);
return 0;
}
diff --git a/kuser/kimpersonate.cat8 b/kuser/kimpersonate.cat8
deleted file mode 100644
index a28d97e168f1..000000000000
--- a/kuser/kimpersonate.cat8
+++ /dev/null
@@ -1,93 +0,0 @@
-KIMPERSONATE(8) BSD System Manager's Manual KIMPERSONATE(8)
-
-NAME
- kimpersonate -- impersonate a user when there exist a keyfile or KeyFile
-
-SYNOPSIS
- kimpersonate [-s string | --ccache=string] [-s string | --server=string]
- [-c string | --client=string] [-k string | --keytab=string]
- [-5 | --krb5] [-A | --add] [-R | --referral]
- [-e integer | --expire-time=integer]
- [-a string | --client-address=string]
- [-t string | --enc-type=string] [--session-enc-type=string]
- [-f string | --ticket-flags=string] [--verbose] [--version]
- [--help]
-
-DESCRIPTION
- The kimpersonate program creates a "fake" ticket using the service-key of
- the service and stores it in the given (or default) ccache. This is use-
- ful for testing. The service key can be read from a Kerberos 5 keytab or
- AFS KeyFile. Supported options:
-
- --ccache=string
- ccache into which to store the ticket
-
- -s string, --server=string
- name of server principal
-
- -c string, --client=string
- name of client principal
-
- -k string, --keytab=string
- name of keytab file
-
- -5, --krb5
- create a Kerberos 5 ticket
-
- -A, --add
- don't re-initialize the ccache, instead add the ticket to an ex-
- isting ccache.
-
- -R, --referral
- simulate a referrals-based KDC client by storing two entries, one
- with the empty realm for the service principal name.
-
- -e integer, --expire-time=integer
- lifetime of ticket in seconds
-
- -a string, --client-address=string
- address of client
-
- -t string, --enc-type=string
- encryption type (defaults to "aes256-cts-hmac-sha1-96")
-
- --session-enc-type=string
- session encryption type (defaults to enc-type or "des-cbc-crc"
- for afs service tickets)
-
- -f string, --ticket-flags=string
- ticket flags for krb5 ticket
-
- --verbose
- Verbose output
-
- --version
- Print version
-
- --help
-
-FILES
- Uses /etc/krb5.keytab, and /usr/afs/etc/KeyFile when available and the -k
- option is used with an appropriate prefix.
-
-EXAMPLES
- kimpersonate can be used in samba root preexec option or for debugging.
- kimpersonate -s host/hummel.e.kth.se@E.KTH.SE -c lha@E.KTH.SE -5 will
- create a Kerberos 5 ticket for lha@E.KTH.SE for the host hummel.e.kth.se
- if there exists a keytab entry for it in /etc/krb5.keytab.
-
- In combination with the ktutil command, this is useful for testing. For
- example,
-
- ktutil -k tkt add -p host/foo.test@TEST -V2 -e aes256-cts-hmac-sha1-96 -r
-
- kimpersonate --cache=tcc -s host/foo.test@TEST -c jdoe@TEST -k tkt --re-
- ferral
-
-SEE ALSO
- kinit(1), klist(1)
-
-AUTHORS
- Love Hornquist Astrand <lha@kth.se>
-
-BSD September 18, 2006 BSD
diff --git a/kuser/kinit.1 b/kuser/kinit.1
index bb3c90af1b5e..f374a7c06289 100644
--- a/kuser/kinit.1
+++ b/kuser/kinit.1
@@ -39,6 +39,8 @@
.Nd acquire initial tickets
.Sh SYNOPSIS
.Nm kinit
+.Op Fl Fl no-change-default
+.Op Fl Fl default-for-principal
.Op Fl Fl afslog
.Oo Fl c Ar cachename \*(Ba Xo
.Fl Fl cache= Ns Ar cachename
@@ -97,9 +99,48 @@ can later be used to obtain tickets for other services.
.Pp
Supported options:
.Bl -tag -width Ds
-.It Fl c Ar cachename Fl Fl cache= Ns Ar cachename
+.It Fl c Ar cachename | Fl Fl cache= Ns Ar cachename
The credentials cache to put the acquired ticket in, if other than
default.
+.It Fl Fl no-change-default
+By default the principal's credentials will be stored in the default
+credential cache. This option will cause them to instead be stored
+only in a cache whose name is derived from the principal's name. Note
+that
+.Xr klist 1
+with the
+.Fl l
+option will list all the credential caches the user has, along with
+the name of the principal whose credentials are stored therein. This
+option is ignored if the
+.Fl c Ar cachename | Fl Fl cache= Ns Ar cachename
+option is given.
+See also
+.Xr kswitch 1 .
+.It Fl Fl default-for-principal
+If this option is given and
+.Fl c Ar cachename | Fl Fl cache= Ns Ar cachename
+is not given, then the cache that will be used will be one that
+is appropriate for the client principal. For example, if the
+default cache type is
+.Ar FILE
+then the default cache may be either
+.Ar FILE:/tmp/krb5cc_%{uid}+%{principal_name}
+or
+.Ar FILE:/tmp/krb5cc_%{uid}
+if the principal is the default principal for the user, meaning
+that it is of the form
+.Ar ${USER}@${user_realm}
+or
+.Ar ${USER}@${default_realm} .
+This option implies
+.Fl Fl no-change-default
+unless
+.Fl Fl change-default
+is given. Caches for the user can be listed with the
+.Fl l
+option to
+.Xr klist 1 .
.It Fl f Fl Fl forwardable
Obtain a ticket than can be forwarded to another host.
.It Fl F Fl Fl no-forwardable
@@ -115,10 +156,18 @@ like
.It Fl p , Fl Fl proxiable
Request tickets with the proxiable flag set.
.It Fl R , Fl Fl renew
-Try to renew ticket.
+Try to renew a ticket.
The ticket must have the
.Sq renewable
-flag set, and must not be expired.
+flag set, and must not be expired. If the
+.Oo Fl S Ar principal Oc
+option is specified, the ticket for the indicated service is renewed.
+If no service is explicitly specified, an attempt is made to renew the
+TGT for the client realm. If no TGT for the client realm is found in the
+credential cache, an attempt is made to renew the TGT for the defaualt
+realm (if that is found in the credential cache), or else the first
+TGT found. This makes it easier for users to renew forwarded tickets
+that are not issued by the origin realm.
.It Fl Fl renewable
The same as
.Fl Fl renewable-life ,
@@ -191,6 +240,15 @@ An example of an enterprise name is
and this option is usually used with canonicalize so that the
principal returned from the KDC will typically be the real principal
name.
+.It Fl Fl gss-mech
+Enable GSS-API pre-authentication using the specified mechanism OID. Unless
+.Ar gss-name
+is also set, then the specified principal name will be used as the GSS-API
+initiator name. If the principal is specified as @REALM or left unspecified,
+then the default GSS-API credential will be used.
+.It Fl Fl gss-name
+Attempt GSS-API pre-authentication using an initiator name distinct from the
+Kerberos client principal,
.It Fl Fl afslog
Gets AFS tickets, converts them to version 4 format, and stores them
in the kernel.
@@ -215,6 +273,170 @@ is given,
will set up new credentials caches, and AFS PAG, and then run the given
command.
When it finishes the credentials will be removed.
+.Sh CREDENTIALS CACHE TYPES
+Heimdal supports a number of credentials cache types:
+.Bl -tag -width Ds
+.It FILE
+Uses a file per-cache with a binary format common to other Kerberos
+implementations.
+.It DIR
+Uses a directory with multiple files, one per-cache in a collection.
+.It SCC
+Uses a SQLite3 database with multiple caches in the database.
+.It KEYRING
+Uses a Linux keyring.
+.It KCM
+Uses a inter-process communications (IPC) to talk to a daemon typically named
+.Nm kcm .
+.It API
+Uses KCM or else a shared object that implements the "CCAPI".
+.It MEMORY
+Uses in-process memory (which disappears on process exit, so this if of little
+use in this program,
+.Nm
+).
+.El
+.Sh CREDENTIALS CACHE COLLECTIONS
+Every credentials cache's name consists of its cache type (e.g.,
+FILE), a possibly-optional collection name, and a possibly
+optional "subsidiary" name naming a single cache in the
+collection.
+.Pp
+The convention in Heimdal is that a cache's subsidiary cache name
+is the name of the client principal whose credentials are
+expected to be stored and found in that cache, with the following
+characters replaced with a hyphen: slash, backslash, colon, and
+plus.
+.Pp
+The caches in a credentials cache collection can be listed by the
+.Xr klist 1
+command.
+The
+.Sq FILE
+credentials cache type supports listing of caches in the
+collection only when the
+.Ql enable_file_cache_iteration
+is set to
+.Ql yes
+in the
+.Ql [libdefaults]
+section of
+.Xr krb5.conf 5 .
+.Sh CREDENTIALS CACHE NAMES
+The general syntax for credentials cache names is
+.Dl TYPE:[collection-name][:subsidiary]
+except that for the FILE type it is
+.Dl FILE:collection-name[+subsidiary]
+and for the KEYRING type it is:
+.Dl KEYRING:[anchor:][collection[:subsidiary]]
+where the collection name is free-form and the anchor is one of
+.Sq process ,
+.Sq thread ,
+or
+.Sq legacy .
+.Pp
+The collection name is always absent for the
+.Ql MEMORY
+credentials cache type.
+.Pp
+When the collection name is absent then the default collection
+for the given credentials cache type is used, which are:
+.Bl -tag -compact
+.It Ql /tmp/krb5cc_{UID}
+for FILE caches, where {UID} is a numeric user ID
+.It Ql /tmp/krb5cc_{UID}_dir
+for DIR caches, where {UID} is a numeric user ID
+.It Ql /tmp/krb5scc_{UID}
+for SCC caches, where {UID} is a numeric user ID, and where the
+named file is a SQLite3 database file
+.It Ql {UID}
+for KCM caches, where {UID} is the user's numeric user ID
+.It <implementation-specific>
+for API (CCAPI) credentials caches
+.El
+.Pp
+The collection name is only optional for:
+.Ql DIR ,
+.Ql SCC ,
+.Ql KCM ,
+.Ql KEYRING
+and
+.Ql API
+credentials cache types.
+.Sh EXAMPLE CREDENTIALS CACHE NAMES
+.Bl -tag -width Ds
+.It Ql FILE:/tmp/cc
+this is a FILE cache in a file named
+.Ql /tmp/cc
+(the default would be
+.Ql /tmp/krb5cc_{UID} )
+.It Ql FILE:/tmp/cc+jane@TEST.H5L.SE
+.It Ql DIR:/tmp/ccdir
+this is a FILE cache named by
+.Ql /tmp/krb5cc_{UID}_dir/primary
+which will be of the form
+.Ql /tmp/ccdir/tkt.XXXXXX
+.It Ql DIR:/tmp/ccdir:jane@TEST.H5L.SE
+this is a FILE ccache named
+.Ql /tmp/ccdir/tkt.jane@TEST.H5L.SE
+.It Ql DIR::jane@TEST.H5L.SE
+this is a FILE ccache named
+.Ql /tmp/krb5cc_{UID}_dir/tkt.jane@TEST.H5L.SE
+where {UID} is the user's numeric identifier
+.It Ql SCC:
+this is the current primary cache in the SQLite3 database named
+.Ql /tmp/krb5scc_{UID}
+.It Ql SCC:/tmp/ccdb
+this is the current primary cache in the SQLite3 database named
+.Ql /tmp/ccdb
+.It Ql SCC:/tmp/ccdb:jane@TEST.H5L.SE
+this is the cache
+.Dq named jane@TEST.H5L.SE
+in the SQLite3 database
+named
+.Ql /tmp/ccdb
+.It Ql SCC::jane@TEST.H5L.SE
+this is the cache named
+.Dq jane@TEST.H5L.SE
+in the SQLite3 database named
+.Ql /tmp/krb5scc_{UID}
+.It Ql KEYRING:
+this is the primary cache in the default KEYRING collection for
+the running user
+.It Ql KEYRING:foo
+this is the primary cache in the KEYRING collection named
+.Dq foo
+.It Ql KEYRING:foo:jane@TEST.H5L.SE
+this is the cache named
+.Dq jane@TEST.H5L.SE
+in the KEYRING collection named
+.Dq foo
+.It Ql KCM:
+this is the primary cache in the default KCM collection for the
+running user
+.It Ql KCM:12345
+this is the primary cache in the default KCM collection for the
+user whose numeric identifier is 12345
+.It Ql KCM:jane@TEST.H5L.SE
+this is the cache named
+.Dq jane@TEST.H5L.SE
+in the default KCM collection for the running user
+.It Ql KCM:12345:jane@TEST.H5L.SE
+this is the cache named
+.Dq jane@TEST.H5L.SE
+in the default KCM collection for the given user
+.It Ql API:
+this is the primary cache in the default API collection for the
+running user
+.It Ql API:foo
+this is the primary cache in the API collection named
+.Dq foo
+.It Ql API:foo:jane@TEST.H5L.SE
+this is the cache named
+.Dq jane@TEST.H5L.SE
+in the KEYRING collection named
+.Dq foo
+.El
.Sh ENVIRONMENT
.Bl -tag -width Ds
.It Ev KRB5CCNAME
@@ -231,6 +453,8 @@ the default being
.Sh SEE ALSO
.Xr kdestroy 1 ,
.Xr klist 1 ,
+.Xr kswitch 1 ,
+.Xr kcm 8 ,
.Xr krb5_appdefault 3 ,
.Xr krb5.conf 5
.\".Sh STANDARDS
diff --git a/kuser/kinit.c b/kuser/kinit.c
index 61f962bbe7ed..a5e00c943392 100644
--- a/kuser/kinit.c
+++ b/kuser/kinit.c
@@ -34,8 +34,10 @@
*/
#include "kuser_locl.h"
+#undef HC_DEPRECATED_CRYPTO
+#include <krb5_locl.h>
-#ifdef __APPLE__
+#ifdef HAVE_FRAMEWORK_SECURITY
#include <Security/Security.h>
#endif
@@ -61,9 +63,11 @@ int anonymous_flag = 0;
char *lifetime = NULL;
char *renew_life = NULL;
char *server_str = NULL;
+static krb5_principal tgs_service;
char *cred_cache = NULL;
char *start_str = NULL;
-static int switch_cache_flags = 1;
+static int default_for = 0;
+static int switch_cache_flags = -1;
struct getarg_strings etype_str;
int use_keytab = 0;
char *keytab_str = NULL;
@@ -76,6 +80,10 @@ int pk_enterprise_flag = 0;
struct hx509_certs_data *ent_user_id = NULL;
char *pk_x509_anchors = NULL;
int pk_use_enckey = 0;
+int pk_anon_fast_armor = -1;
+char *gss_preauth_mech = NULL;
+char *gss_preauth_name = NULL;
+char *kdc_hostname = NULL;
static int canonicalize_flag = 0;
static int enterprise_flag = 0;
static int ok_as_delegate_flag = 0;
@@ -181,7 +189,20 @@ static struct getargs args[] = {
{ "pk-use-enckey", 0, arg_flag, &pk_use_enckey,
NP_("Use RSA encrypted reply (instead of DH)", ""), NULL },
+
+ { "pk-anon-fast-armor", 0, arg_flag, &pk_anon_fast_armor,
+ NP_("use unauthenticated anonymous PKINIT as FAST armor", ""), NULL },
#endif
+
+ { "gss-mech", 0, arg_string, &gss_preauth_mech,
+ NP_("use GSS mechanism for pre-authentication", ""), NULL },
+
+ { "gss-name", 0, arg_string, &gss_preauth_name,
+ NP_("use distinct GSS identity for pre-authentication", ""), NULL },
+
+ { "kdc-hostname", 0, arg_string, &kdc_hostname,
+ NP_("KDC host name", ""), "hostname" },
+
#ifndef NO_NTLM
{ "ntlm-domain", 0, arg_string, &ntlm_domain,
NP_("NTLM domain", ""), "domain" },
@@ -190,6 +211,9 @@ static struct getargs args[] = {
{ "change-default", 0, arg_negative_flag, &switch_cache_flags,
NP_("switch the default cache to the new credentials cache", ""), NULL },
+ { "default-for-principal", 0, arg_flag, &default_for,
+ NP_("Use a default cache appropriate for the client principal", ""), NULL },
+
{ "ok-as-delegate", 0, arg_flag, &ok_as_delegate_flag,
NP_("honor ok-as-delegate on tickets", ""), NULL },
@@ -218,18 +242,124 @@ usage(int ret)
}
static krb5_error_code
+tgs_principal(krb5_context context,
+ krb5_ccache cache,
+ krb5_principal client,
+ krb5_const_realm tgs_realm,
+ krb5_principal *out_princ)
+{
+ krb5_error_code ret;
+ krb5_principal tgs_princ;
+ krb5_creds creds;
+ krb5_creds *tick;
+ krb5_flags options;
+
+ ret = krb5_make_principal(context, &tgs_princ, tgs_realm,
+ KRB5_TGS_NAME, tgs_realm, NULL);
+ if (ret)
+ return ret;
+
+ /*
+ * Don't fail-over to a different realm just because a TGT expired
+ */
+ options = KRB5_GC_CACHED | KRB5_GC_EXPIRED_OK;
+
+ memset(&creds, 0, sizeof(creds));
+ creds.client = client;
+ creds.server = tgs_princ;
+ ret = krb5_get_credentials(context, options, cache, &creds, &tick);
+ if (ret == 0) {
+ krb5_free_creds(context, tick);
+ *out_princ = tgs_princ;
+ } else {
+ krb5_free_principal(context, tgs_princ);
+ }
+
+ return ret;
+}
+
+
+/*
+ * Try TGS specified with '-S',
+ * then TGS of client realm,
+ * then if fallback is FALSE: fail,
+ * otherwise try TGS of default realm,
+ * and finally first TGT in ccache.
+ */
+static krb5_error_code
get_server(krb5_context context,
+ krb5_ccache cache,
krb5_principal client,
const char *server,
+ krb5_boolean fallback,
krb5_principal *princ)
{
+ krb5_error_code ret = 0;
krb5_const_realm realm;
- if (server)
- return krb5_parse_name(context, server, princ);
+ krb5_realm def_realm;
+ krb5_cc_cursor cursor;
+ krb5_creds creds;
+ const char *pcomp;
+
+ if (tgs_service)
+ goto done;
+ if (server) {
+ ret = krb5_parse_name(context, server, &tgs_service);
+ goto done;
+ }
+
+ /* Try the client realm first */
realm = krb5_principal_get_realm(context, client);
- return krb5_make_principal(context, princ, realm,
- KRB5_TGS_NAME, realm, NULL);
+ ret = tgs_principal(context, cache, client, realm, &tgs_service);
+ if (ret == 0 || ret != KRB5_CC_NOTFOUND)
+ goto done;
+
+ if (!fallback)
+ return ret;
+
+ /* Next try the default realm */
+ ret = krb5_get_default_realm(context, &def_realm);
+ if (ret)
+ return ret;
+ ret = tgs_principal(context, cache, client, def_realm, &tgs_service);
+ free(def_realm);
+ if (ret == 0 || ret != KRB5_CC_NOTFOUND)
+ goto done;
+
+ /* Finally try the first TGT with instance == realm in the cache */
+ ret = krb5_cc_start_seq_get(context, cache, &cursor);
+ if (ret)
+ return ret;
+
+ for (/**/; ret == 0; krb5_free_cred_contents (context, &creds)) {
+
+ ret = krb5_cc_next_cred(context, cache, &cursor, &creds);
+ if (ret)
+ break;
+ if (creds.server->name.name_string.len != 2)
+ continue;
+ pcomp = krb5_principal_get_comp_string(context, creds.server, 0);
+ if (strcmp(pcomp, KRB5_TGS_NAME) != 0)
+ continue;
+ realm = krb5_principal_get_realm(context, creds.server);
+ pcomp = krb5_principal_get_comp_string(context, creds.server, 1);
+ if (strcmp(realm, pcomp) != 0)
+ continue;
+ ret = krb5_copy_principal(context, creds.server, &tgs_service);
+ break;
+ }
+ if (ret == KRB5_CC_END) {
+ ret = KRB5_CC_NOTFOUND;
+ krb5_set_error_message(context, ret,
+ N_("Credential cache contains no TGTs", ""));
+ }
+ krb5_cc_end_seq_get(context, cache, &cursor);
+
+done:
+ if (!ret)
+ ret = krb5_copy_principal(context, tgs_service, princ);
+ return ret;
}
static krb5_error_code
@@ -311,29 +441,57 @@ static krb5_error_code
renew_validate(krb5_context context,
int renew,
int validate,
- krb5_ccache cache,
+ krb5_ccache *cachep,
+ krb5_const_principal principal,
+ krb5_boolean cache_is_default_for,
const char *server,
krb5_deltat life)
{
krb5_error_code ret;
krb5_ccache tempccache = NULL;
+ krb5_ccache cache = *cachep;
krb5_creds in, *out = NULL;
krb5_kdc_flags flags;
memset(&in, 0, sizeof(in));
ret = krb5_cc_get_principal(context, cache, &in.client);
+ if (ret && cache_is_default_for && principal) {
+ krb5_error_code ret2;
+ krb5_ccache def_ccache = NULL;
+
+ ret2 = krb5_cc_default(context, &def_ccache);
+ if (ret2 == 0)
+ ret2 = krb5_cc_get_principal(context, def_ccache, &in.client);
+ if (ret2 == 0 &&
+ krb5_principal_compare(context, principal, in.client)) {
+ krb5_cc_close(context, *cachep);
+ cache = *cachep = def_ccache;
+ def_ccache = NULL;
+ ret = 0;
+ }
+ krb5_cc_close(context, def_ccache);
+ }
if (ret) {
krb5_warn(context, ret, "krb5_cc_get_principal");
return ret;
}
+ if (principal && !krb5_principal_compare(context, principal, in.client)) {
+ char *ccname = NULL;
+
+ (void) krb5_cc_get_full_name(context, cache, &ccname);
+ krb5_errx(context, 1, "Credentials in cache %s do not match requested "
+ "principal", ccname ? ccname : "requested");
+ free(ccname);
+ }
+
if (server == NULL &&
krb5_principal_is_anonymous(context, in.client,
KRB5_ANON_MATCH_UNAUTHENTICATED))
ret = get_anon_pkinit_tgs_name(context, cache, &in.server);
else
- ret = get_server(context, in.client, server, &in.server);
+ ret = get_server(context, cache, in.client, server, TRUE, &in.server);
if (ret) {
krb5_warn(context, ret, "get_server");
goto out;
@@ -344,7 +502,7 @@ renew_validate(krb5_context context,
* no need to check the error here, it's only to be
* friendly to the user
*/
- krb5_get_credentials(context, KRB5_GC_CACHED, cache, &in, &out);
+ (void) krb5_get_credentials(context, KRB5_GC_CACHED, cache, &in, &out);
}
flags.i = 0;
@@ -427,6 +585,106 @@ out:
return ret;
}
+static krb5_error_code
+make_wellknown_name(krb5_context context,
+ krb5_const_realm realm,
+ const char *instance,
+ krb5_principal *principal)
+{
+ krb5_error_code ret;
+
+ ret = krb5_make_principal(context, principal, realm,
+ KRB5_WELLKNOWN_NAME, instance, NULL);
+ if (ret == 0)
+ krb5_principal_set_type(context, *principal, KRB5_NT_WELLKNOWN);
+
+ return ret;
+}
+
+static krb5_error_code
+acquire_gss_cred(krb5_context context,
+ krb5_const_principal client,
+ krb5_deltat life,
+ const char *passwd,
+ gss_cred_id_t *cred,
+ gss_OID *mech)
+{
+ krb5_error_code ret;
+ OM_uint32 major, minor;
+ gss_name_t name = GSS_C_NO_NAME;
+ gss_key_value_element_desc cred_element;
+ gss_key_value_set_desc cred_store;
+ gss_OID_set_desc mechs;
+
+ *cred = GSS_C_NO_CREDENTIAL;
+ *mech = GSS_C_NO_OID;
+
+ if (gss_preauth_mech) {
+ *mech = gss_name_to_oid(gss_preauth_mech);
+ if (*mech == GSS_C_NO_OID)
+ return EINVAL;
+ }
+
+ if (gss_preauth_name) {
+ gss_buffer_desc buf;
+
+ buf.value = gss_preauth_name;
+ buf.length = strlen(gss_preauth_name);
+
+ major = gss_import_name(&minor, &buf, GSS_C_NT_USER_NAME, &name);
+ ret = _krb5_gss_map_error(major, minor);
+ } else if (!krb5_principal_is_federated(context, client)) {
+ ret = _krb5_gss_pa_unparse_name(context, client, &name);
+ } else {
+ /*
+ * WELLKNOWN/FEDERATED is used a placeholder where the user
+ * did not specify either a Kerberos credential or a GSS-API
+ * initiator name. It avoids the expense of acquiring a default
+ * credential purely to interrogate the credential name.
+ */
+ name = GSS_C_NO_NAME;
+ ret = 0;
+ }
+ if (ret)
+ goto out;
+
+ cred_store.count = 1;
+ cred_store.elements = &cred_element;
+
+ if (passwd && passwd[0]) {
+ cred_element.key = "password";
+ cred_element.value = passwd;
+ } else if (keytab_str) {
+ cred_element.key = "client_keytab",
+ cred_element.value = keytab_str;
+ } else {
+ cred_store.count = 0;
+ }
+
+ if (*mech) {
+ mechs.count = 1;
+ mechs.elements = (gss_OID)*mech;
+ }
+
+ major = gss_acquire_cred_from(&minor,
+ name,
+ life ? life : GSS_C_INDEFINITE,
+ *mech ? &mechs : GSS_C_NO_OID_SET,
+ GSS_C_INITIATE,
+ &cred_store,
+ cred,
+ NULL,
+ NULL);
+ if (major != GSS_S_COMPLETE) {
+ ret = _krb5_gss_map_error(major, minor);
+ goto out;
+ }
+
+out:
+ gss_release_name(&minor, &name);
+ return ret;
+}
+
#ifndef NO_NTLM
static krb5_error_code
@@ -481,6 +739,10 @@ get_new_tickets(krb5_context context,
krb5_init_creds_context ctx = NULL;
krb5_get_init_creds_opt *opt = NULL;
krb5_prompter_fct prompter = krb5_prompter_posix;
+ gss_cred_id_t gss_cred = GSS_C_NO_CREDENTIAL;
+ gss_OID gss_mech = GSS_C_NO_OID;
+ krb5_principal federated_name = NULL;
+
#ifndef NO_NTLM
struct ntlm_buf ntlmkey;
memset(&ntlmkey, 0, sizeof(ntlmkey));
@@ -498,7 +760,7 @@ get_new_tickets(krb5_context context,
else
f = fopen(password_file, "r");
if (f == NULL) {
- krb5_warnx(context, "Failed to open the password file %s",
+ krb5_warnx(context, N_("Failed to open the password file %s", ""),
password_file);
return errno;
}
@@ -506,7 +768,8 @@ get_new_tickets(krb5_context context,
if (fgets(passwd, sizeof(passwd), f) == NULL) {
krb5_warnx(context, N_("Failed to read password from file %s", ""),
password_file);
- fclose(f);
+ if (f != stdin)
+ fclose(f);
return EINVAL; /* XXX Need a better error */
}
if (f != stdin)
@@ -514,31 +777,83 @@ get_new_tickets(krb5_context context,
passwd[strcspn(passwd, "\n")] = '\0';
}
-#ifdef __APPLE__
+#ifdef HAVE_FRAMEWORK_SECURITY
if (passwd[0] == '\0') {
+ enum querykey {
+ qk_class, qk_matchlimit, qk_service, qk_account, qk_secreturndata,
+ };
+ const void *querykeys[] = {
+ [qk_class] = kSecClass,
+ [qk_matchlimit] = kSecMatchLimit,
+ [qk_service] = kSecAttrService,
+ [qk_account] = kSecAttrAccount,
+ [qk_secreturndata] = kSecReturnData,
+ };
+ const void *queryargs[] = {
+ [qk_class] = kSecClassGenericPassword,
+ [qk_matchlimit] = kSecMatchLimitOne,
+ [qk_service] = NULL, /* filled in later */
+ [qk_account] = NULL, /* filled in later */
+ [qk_secreturndata] = kCFBooleanTrue,
+ };
+ CFStringRef service_ref = NULL;
+ CFStringRef account_ref = NULL;
+ CFDictionaryRef query_ref = NULL;
const char *realm;
OSStatus osret;
- UInt32 length;
- void *buffer;
- char *name;
+ char *name = NULL;
+ CFTypeRef item_ref = NULL;
+ CFDataRef item;
+ CFIndex length;
realm = krb5_principal_get_realm(context, principal);
ret = krb5_unparse_name_flags(context, principal,
KRB5_PRINCIPAL_UNPARSE_NO_REALM, &name);
if (ret)
- goto nopassword;
-
- osret = SecKeychainFindGenericPassword(NULL, strlen(realm), realm,
- strlen(name), name,
- &length, &buffer, NULL);
+ goto fail;
+
+ service_ref = CFStringCreateWithCString(kCFAllocatorDefault, realm,
+ kCFStringEncodingUTF8);
+ if (service_ref == NULL)
+ goto fail;
+
+ account_ref = CFStringCreateWithCString(kCFAllocatorDefault, name,
+ kCFStringEncodingUTF8);
+ if (account_ref == NULL)
+ goto fail;
+
+ queryargs[qk_service] = service_ref;
+ queryargs[qk_account] = account_ref;
+ query_ref = CFDictionaryCreate(kCFAllocatorDefault,
+ querykeys, queryargs,
+ /*numValues*/sizeof(querykeys)/sizeof(querykeys[0]),
+ /*keyCallbacks*/NULL, /*valueCallbacks*/NULL);
+ if (query_ref == NULL)
+ goto fail;
+
+ osret = SecItemCopyMatching(query_ref, &item_ref);
+ if (osret != noErr)
+ goto fail;
+
+ item = item_ref;
+ length = CFDataGetLength(item);
+ if (length >= sizeof(passwd) - 1)
+ goto fail;
+
+ CFDataGetBytes(item, CFRangeMake(0, length), (UInt8 *)passwd);
+ passwd[length] = '\0';
+
+ fail:
+ if (item_ref)
+ CFRelease(item_ref);
+ if (query_ref)
+ CFRelease(query_ref);
+ if (account_ref)
+ CFRelease(account_ref);
+ if (service_ref)
+ CFRelease(service_ref);
free(name);
- if (osret == noErr && length < sizeof(passwd) - 1) {
- memcpy(passwd, buffer, length);
- passwd[length] = '\0';
- }
- nopassword:
- do { } while(0);
}
#endif
@@ -567,6 +882,8 @@ get_new_tickets(krb5_context context,
if (pk_enterprise_flag || enterprise_flag || canonicalize_flag || windows_flag)
krb5_get_init_creds_opt_set_win2k(context, opt, TRUE);
if (pk_user_id || ent_user_id || anonymous_pkinit) {
+ if (pk_anon_fast_armor == -1)
+ pk_anon_fast_armor = 0;
ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
principal,
pk_user_id,
@@ -630,6 +947,29 @@ get_new_tickets(krb5_context context,
etype_str.num_strings);
}
+ if (gss_preauth_mech || gss_preauth_name) {
+ ret = acquire_gss_cred(context, principal, ticket_life,
+ passwd, &gss_cred, &gss_mech);
+ if (ret)
+ goto out;
+
+ /*
+ * The principal specified on the command line is used as the GSS-API
+ * initiator name, unless the --gss-name option was present, in which
+ * case the initiator name is specified independently.
+ */
+ if (gss_preauth_name == NULL) {
+ krb5_const_realm realm = krb5_principal_get_realm(context, principal);
+
+ ret = make_wellknown_name(context, realm,
+ KRB5_FEDERATED_NAME, &federated_name);
+ if (ret)
+ goto out;
+
+ principal = federated_name;
+ }
+ }
+
ret = krb5_init_creds_init(context, principal, prompter, NULL, start_time, opt, &ctx);
if (ret) {
krb5_warn(context, ret, "krb5_init_creds_init");
@@ -644,23 +984,63 @@ get_new_tickets(krb5_context context,
}
}
+ if (kdc_hostname) {
+ ret = krb5_init_creds_set_kdc_hostname(context, ctx, kdc_hostname);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_init_creds_set_kdc_hostname");
+ goto out;
+ }
+ }
+
+ if (anonymous_flag && pk_anon_fast_armor == -1)
+ pk_anon_fast_armor = 0;
+ if (!gss_preauth_mech && anonymous_flag && pk_anon_fast_armor) {
+ krb5_warnx(context, N_("Ignoring --pk-anon-fast-armor because "
+ "--anonymous given", ""));
+ pk_anon_fast_armor = 0;
+ }
+
if (fast_armor_cache_string) {
- krb5_ccache fastid;
-
+ krb5_ccache fastid = NULL;
+
+ if (pk_anon_fast_armor > 0)
+ krb5_errx(context, 1,
+ N_("cannot specify FAST armor cache with FAST "
+ "anonymous PKINIT option", ""));
+ pk_anon_fast_armor = 0;
+
ret = krb5_cc_resolve(context, fast_armor_cache_string, &fastid);
if (ret) {
krb5_warn(context, ret, "krb5_cc_resolve(FAST cache)");
goto out;
}
-
+
ret = krb5_init_creds_set_fast_ccache(context, ctx, fastid);
if (ret) {
krb5_warn(context, ret, "krb5_init_creds_set_fast_ccache");
goto out;
}
+ } else if (pk_anon_fast_armor == -1) {
+ ret = _krb5_init_creds_set_fast_anon_pkinit_optimistic(context, ctx);
+ if (ret) {
+ krb5_warn(context, ret, "_krb5_init_creds_set_fast_anon_pkinit_optimistic");
+ goto out;
+ }
+ } else if (pk_anon_fast_armor) {
+ ret = krb5_init_creds_set_fast_anon_pkinit(context, ctx);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_init_creds_set_fast_anon_pkinit");
+ goto out;
+ }
}
- if (use_keytab || keytab_str) {
+ if (gss_mech != GSS_C_NO_OID) {
+ ret = krb5_gss_set_init_creds(context, ctx, gss_cred, gss_mech);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_gss_set_init_creds");
+ goto out;
+ }
+ } else if (use_keytab || keytab_str) {
ret = krb5_init_creds_set_keytab(context, ctx, kt);
if (ret) {
krb5_warn(context, ret, "krb5_init_creds_set_keytab");
@@ -780,6 +1160,18 @@ get_new_tickets(krb5_context context,
goto out;
}
+ ret = krb5_init_creds_store_config(context, ctx, tempccache);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_init_creds_store_config");
+ goto out;
+ }
+
+ ret = krb5_init_creds_warn_user(context, ctx);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_init_creds_warn_user");
+ goto out;
+ }
+
krb5_init_creds_free(context, ctx);
ctx = NULL;
@@ -823,12 +1215,16 @@ get_new_tickets(krb5_context context,
}
out:
+ {
+ OM_uint32 minor;
+ gss_release_cred(&minor, &gss_cred);
+ }
+ krb5_free_principal(context, federated_name);
krb5_get_init_creds_opt_free(context, opt);
if (ctx)
krb5_init_creds_free(context, ctx);
if (tempccache)
krb5_cc_destroy(context, tempccache);
-
if (enctype)
free(enctype);
@@ -854,7 +1250,10 @@ ticket_lifetime(krb5_context context, krb5_ccache cache, krb5_principal client,
krb5_warn(context, ret, "krb5_cc_get_principal");
return 0;
}
- ret = get_server(context, in_cred.client, server, &in_cred.server);
+
+ /* Determine TGS principal without fallback */
+ ret = get_server(context, cache, in_cred.client, server, FALSE,
+ &in_cred.server);
if (ret) {
krb5_free_principal(context, in_cred.client);
krb5_warn(context, ret, "get_server");
@@ -916,16 +1315,18 @@ update_siginfo_msg(time_t exp, const char *srv)
#ifdef HAVE_SIGACTION
static void
-handle_siginfo(int sig)
+handler(int sig)
{
- struct iovec iov[2];
+ if (sig == SIGINFO) {
+ struct iovec iov[2];
- iov[0].iov_base = rk_UNCONST(siginfo_msg);
- iov[0].iov_len = strlen(siginfo_msg);
- iov[1].iov_base = "\n";
- iov[1].iov_len = 1;
+ iov[0].iov_base = rk_UNCONST(siginfo_msg);
+ iov[0].iov_len = strlen(siginfo_msg);
+ iov[1].iov_base = "\n";
+ iov[1].iov_len = 1;
- writev(STDERR_FILENO, iov, sizeof(iov)/sizeof(iov[0]));
+ writev(STDERR_FILENO, iov, sizeof(iov)/sizeof(iov[0]));
+ } /* else ignore interrupts; our progeny will not ignore them */
}
#endif
@@ -935,6 +1336,7 @@ struct renew_ctx {
krb5_principal principal;
krb5_deltat ticket_life;
krb5_deltat timeout;
+ int anonymous_pkinit;
};
static time_t
@@ -967,19 +1369,21 @@ renew_func(void *ptr)
if (use_keytab || keytab_str)
expire += ctx->timeout;
if (renew_expire > expire) {
- ret = renew_validate(ctx->context, 1, validate_flag, ctx->ccache,
- server_str, ctx->ticket_life);
+ ret = renew_validate(ctx->context, 1, validate_flag, &ctx->ccache,
+ NULL, FALSE, server_str, ctx->ticket_life);
} else {
ret = get_new_tickets(ctx->context, ctx->principal, ctx->ccache,
- ctx->ticket_life, 0, 0);
+ ctx->ticket_life, 0, ctx->anonymous_pkinit);
}
- expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
- server_str, &renew_expire);
+ if (ret == 0) {
+ expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
+ server_str, &renew_expire);
#ifndef NO_AFS
- if (ret == 0 && server_str == NULL && do_afslog && k_hasafs())
- krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
+ if (server_str == NULL && do_afslog && k_hasafs())
+ krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
#endif
+ }
update_siginfo_msg(expire, server_str);
@@ -1083,29 +1487,35 @@ get_user_realm(krb5_context context)
}
static void
-get_princ(krb5_context context, krb5_principal *principal, const char *name)
+get_princ(krb5_context context,
+ krb5_principal *principal,
+ const char *ccname,
+ const char *name)
{
- krb5_error_code ret;
+ krb5_error_code ret = 0;
krb5_principal tmp;
int parseflags = 0;
char *user_realm;
if (name == NULL) {
- krb5_ccache ccache;
+ krb5_ccache ccache = NULL;
/* If credential cache provides a client principal, use that. */
- if (krb5_cc_default(context, &ccache) == 0) {
+ if (ccname)
+ ret = krb5_cc_resolve(context, ccname, &ccache);
+ else
+ ret = krb5_cc_default(context, &ccache);
+ if (ret == 0)
ret = krb5_cc_get_principal(context, ccache, principal);
- krb5_cc_close(context, ccache);
- if (ret == 0)
- return;
- }
+ krb5_cc_close(context, ccache);
+ if (ret == 0)
+ return;
}
user_realm = get_user_realm(context);
if (name) {
- if (canonicalize_flag || enterprise_flag)
+ if (enterprise_flag)
parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;
parse_name_realm(context, name, parseflags, user_realm, &tmp);
@@ -1282,9 +1692,13 @@ main(int argc, char **argv)
ret = krb5_init_context(&context);
if (ret == KRB5_CONFIG_BADFORMAT)
- errx(1, "krb5_init_context failed to parse configuration file");
+ krb5_err(context, 1, ret, "Failed to parse configuration file");
+ else if (ret == EISDIR)
+ /* We use EISDIR to mean "not a regular file" */
+ krb5_errx(context, 1,
+ "Failed to read configuration file: not a regular file");
else if (ret)
- errx(1, "krb5_init_context failed: %d", ret);
+ krb5_err(context, 1, ret, "Failed to read configuration file");
if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
usage(1);
@@ -1324,17 +1738,29 @@ main(int argc, char **argv)
krb5_err(context, 1, ret, "krb5_pk_enterprise_certs");
pk_user_id = NULL;
+ if (pk_anon_fast_armor > 0)
+ krb5_warnx(context, N_("Ignoring --pk-anon-fast-armor "
+ "because --pk-user given", ""));
+ pk_anon_fast_armor = 0;
+ } else if (argc && argv[0][0] == '@' &&
+ (gss_preauth_mech || anonymous_flag)) {
+ const char *instance;
+
+ if (gss_preauth_mech) {
+ instance = KRB5_FEDERATED_NAME;
+ } else if (anonymous_flag) {
+ instance = KRB5_ANON_NAME;
+ anonymous_pkinit = TRUE;
+ }
- } else if (anonymous_flag && argc && argv[0][0] == '@') {
- /* If principal argument as @REALM, try anonymous PKINIT */
-
- ret = krb5_make_principal(context, &principal, &argv[0][1],
- KRB5_WELLKNOWN_NAME, KRB5_ANON_NAME,
- NULL);
+ ret = make_wellknown_name(context, &argv[0][1], instance, &principal);
if (ret)
- krb5_err(context, 1, ret, "krb5_make_principal");
- krb5_principal_set_type(context, principal, KRB5_NT_WELLKNOWN);
- anonymous_pkinit = TRUE;
+ krb5_err(context, 1, ret, "make_wellknown_name");
+ if (!gss_preauth_mech && pk_anon_fast_armor > 1) {
+ krb5_warnx(context, N_("Ignoring --pk-anon-fast-armor "
+ "because --anonymous given", ""));
+ pk_anon_fast_armor = 0;
+ }
} else if (anonymous_flag && historical_anon_pkinit) {
char *realm = argc == 0 ? get_default_realm(context) :
argv[0][0] == '@' ? &argv[0][1] : argv[0];
@@ -1347,8 +1773,17 @@ main(int argc, char **argv)
anonymous_pkinit = TRUE;
} else if (use_keytab || keytab_str) {
get_princ_kt(context, &principal, argv[0]);
+ } else if (gss_preauth_mech && argc == 0 && gss_preauth_name == NULL) {
+ /*
+ * Use the federated name as a placeholder if we have neither a Kerberos
+ * nor a GSS-API client name, and we are performing GSS-API preauth.
+ */
+ ret = make_wellknown_name(context, get_default_realm(context),
+ KRB5_FEDERATED_NAME, &principal);
+ if (ret)
+ krb5_err(context, 1, ret, "make_wellknown_name");
} else {
- get_princ(context, &principal, argv[0]);
+ get_princ(context, &principal, cred_cache, argv[0]);
}
if (fcache_version)
@@ -1364,43 +1799,73 @@ main(int argc, char **argv)
krb5_principal_get_realm(context, principal),
"afslog", TRUE, &do_afslog);
- if (cred_cache)
+ /*
+ * Cases:
+ *
+ * - use the given ccache
+ * - use a new unique ccache for running a command with (in this case we
+ * get to set KRB5CCNAME, so a new unique ccache makes sense)
+ * - use the default ccache for the given principal as requested and do
+ * not later switch the collection's default/primary to it
+ * - use the default cache, possibly a new unique one that later gets
+ * switched to it
+ *
+ * The important thing is that, except for the case where we're running a
+ * command, we _can't set KRB5CCNAME_, and we can't expect the user to read
+ * our output and figure out to set it (we could have an output-for-shell-
+ * eval mode, like ssh-agent and such, but we don't). Therefore, in all
+ * cases where we can't set KRB5CCNAME we must do something that makes
+ * sense to the user, and that is to either initialize a given ccache, use
+ * the default, or use a subsidiary ccache named after the principal whose
+ * creds we're initializing.
+ */
+ if (cred_cache) {
+ /* Use the given ccache */
ret = krb5_cc_resolve(context, cred_cache, &ccache);
- else {
- if (argc > 1) {
- char s[1024];
- ret = krb5_cc_new_unique(context, NULL, NULL, &ccache);
- if (ret)
- krb5_err(context, 1, ret, "creating cred cache");
- snprintf(s, sizeof(s), "%s:%s",
- krb5_cc_get_type(context, ccache),
- krb5_cc_get_name(context, ccache));
- setenv("KRB5CCNAME", s, 1);
- unique_ccache = TRUE;
- } else {
- ret = krb5_cc_cache_match(context, principal, &ccache);
- if (ret) {
- const char *type;
- ret = krb5_cc_default(context, &ccache);
- if (ret)
- krb5_err(context, 1, ret,
- N_("resolving credentials cache", ""));
-
- /*
- * Check if the type support switching, and we do,
- * then do that instead over overwriting the current
- * default credential
- */
- type = krb5_cc_get_type(context, ccache);
- if (krb5_cc_support_switch(context, type)) {
- krb5_cc_close(context, ccache);
- ret = get_switched_ccache(context, type, principal,
- &ccache);
- if (ret == 0)
- unique_ccache = TRUE;
- }
- }
- }
+ } else if (argc > 1) {
+ char s[1024];
+
+ /*
+ * A command was given, so use a new unique ccache (and destroy it
+ * later).
+ */
+ ret = krb5_cc_new_unique(context, NULL, NULL, &ccache);
+ if (ret)
+ krb5_err(context, 1, ret, "creating cred cache");
+ snprintf(s, sizeof(s), "%s:%s",
+ krb5_cc_get_type(context, ccache),
+ krb5_cc_get_name(context, ccache));
+ setenv("KRB5CCNAME", s, 1);
+ unique_ccache = TRUE;
+ switch_cache_flags = 0;
+ } else if (default_for) {
+ ret = krb5_cc_default_for(context, principal, &ccache);
+ if (switch_cache_flags == -1)
+ switch_cache_flags = 0;
+ } else {
+ ret = krb5_cc_cache_match(context, principal, &ccache);
+ if (ret) {
+ const char *type;
+ ret = krb5_cc_default(context, &ccache);
+ if (ret)
+ krb5_err(context, 1, ret,
+ N_("resolving credentials cache", ""));
+
+ /*
+ * Check if the type support switching, and we do,
+ * then do that instead over overwriting the current
+ * default credential
+ */
+ type = krb5_cc_get_type(context, ccache);
+ if (krb5_cc_support_switch(context, type) &&
+ strcmp(type, "FILE")) {
+ krb5_cc_close(context, ccache);
+ ret = get_switched_ccache(context, type, principal,
+ &ccache);
+ if (ret == 0)
+ unique_ccache = TRUE;
+ }
+ }
}
if (ret)
krb5_err(context, 1, ret, N_("resolving credentials cache", ""));
@@ -1439,7 +1904,9 @@ main(int argc, char **argv)
if (renew_flag || validate_flag) {
ret = renew_validate(context, renew_flag, validate_flag,
- ccache, server_str, ticket_life);
+ &ccache, principal,
+ default_for ? TRUE : FALSE, server_str,
+ ticket_life);
#ifndef NO_AFS
if (ret == 0 && server_str == NULL && do_afslog && k_hasafs())
@@ -1476,13 +1943,16 @@ main(int argc, char **argv)
ctx.principal = principal;
ctx.ticket_life = ticket_life;
ctx.timeout = timeout;
+ ctx.anonymous_pkinit = anonymous_pkinit;
#ifdef HAVE_SIGACTION
memset(&sa, 0, sizeof(sa));
sigemptyset(&sa.sa_mask);
- sa.sa_handler = handle_siginfo;
+ sa.sa_handler = handler;
sigaction(SIGINFO, &sa, NULL);
+ sigaction(SIGINT, &sa, NULL);
+ sigaction(SIGQUIT, &sa, NULL);
#endif
ret = simple_execvp_timed(argv[1], argv+1,
diff --git a/kuser/kinit.cat1 b/kuser/kinit.cat1
deleted file mode 100644
index f1781591d0de..000000000000
--- a/kuser/kinit.cat1
+++ /dev/null
@@ -1,136 +0,0 @@
-KINIT(1) BSD General Commands Manual KINIT(1)
-
-NAME
- kinit -- acquire initial tickets
-
-SYNOPSIS
- kinit [--afslog] [-c cachename | --cache=cachename] [-f | --forwardable]
- [-F | --no-forwardable] [-t keytabname | --keytab=keytabname] [-l
- time | --lifetime=time] [-p | --proxiable] [-R | --renew]
- [--renewable] [-r time | --renewable-life=time] [-S principal |
- --server=principal] [-s time | --start-time=time]
- [-k | --use-keytab] [-v | --validate] [-e enctypes |
- --enctypes=enctypes] [-a addresses | --extra-addresses=addresses]
- [--password-file=filename] [--fcache-version=version-number]
- [-A | --no-addresses] [-n | --anonymous] [--enterprise] [--version]
- [--help] [principal [command]]
-
-DESCRIPTION
- kinit is used to authenticate to the Kerberos server as principal, or if
- none is given, a system generated default (typically your login name at
- the default realm), and acquire a ticket granting ticket that can later
- be used to obtain tickets for other services.
-
- Supported options:
-
- -c cachename --cache=cachename
- The credentials cache to put the acquired ticket in, if other
- than default.
-
- -f --forwardable
- Obtain a ticket than can be forwarded to another host.
-
- -F --no-forwardable
- Do not obtain a forwardable ticket.
-
- -t keytabname, --keytab=keytabname
- Don't ask for a password, but instead get the key from the speci-
- fied keytab.
-
- -l time, --lifetime=time
- Specifies the lifetime of the ticket. The argument can either be
- in seconds, or a more human readable string like `1h'.
-
- -p, --proxiable
- Request tickets with the proxiable flag set.
-
- -R, --renew
- Try to renew ticket. The ticket must have the `renewable' flag
- set, and must not be expired.
-
- --renewable
- The same as --renewable-life, with an infinite time.
-
- -r time, --renewable-life=time
- The max renewable ticket life.
-
- -S principal, --server=principal
- Get a ticket for a service other than krbtgt/LOCAL.REALM.
-
- -s time, --start-time=time
- Obtain a ticket that starts to be valid time (which can really be
- a generic time specification, like `1h') seconds into the future.
-
- -k, --use-keytab
- The same as --keytab, but with the default keytab name (normally
- FILE:/etc/krb5.keytab).
-
- -v, --validate
- Try to validate an invalid ticket.
-
- -e, --enctypes=enctypes
- Request tickets with this particular enctype.
-
- --password-file=filename
- read the password from the first line of filename. If the
- filename is STDIN, the password will be read from the standard
- input.
-
- --fcache-version=version-number
- Create a credentials cache of version version-number.
-
- -a, --extra-addresses=enctypes
- Adds a set of addresses that will, in addition to the systems lo-
- cal addresses, be put in the ticket. This can be useful if all
- addresses a client can use can't be automatically figured out.
- One such example is if the client is behind a firewall. Also
- settable via libdefaults/extra_addresses in krb5.conf(5).
-
- -A, --no-addresses
- Request a ticket with no addresses.
-
- -n, --anonymous
- Request an anonymous ticket. With the default (false) setting of
- the historical_anon_pkinit configuration parameter, if the prin-
- cipal is specified as @REALM, then anonymous PKINIT will be used
- to acquire an unauthenticated anonymous ticket and both the
- client name and (with fully RFC-comformant KDCs) realm in the re-
- turned ticket will be anonymized. Otherwise, authentication pro-
- ceeds as normal and the anonymous ticket will have only the
- client name anonymized. With historical_anon_pkinit set to true,
- the principal is interpreted as a realm even without an at-sign
- prefix, and it is not possible to obtain authenticated anonymized
- tickets.
-
- --enterprise
- Parse principal as a enterprise (KRB5-NT-ENTERPRISE) name. Enter-
- prise names are email like principals that are stored in the name
- part of the principal, and since there are two @ characters the
- parser needs to know that the first is not a realm. An example
- of an enterprise name is "lha@e.kth.se@KTH.SE", and this option
- is usually used with canonicalize so that the principal returned
- from the KDC will typically be the real principal name.
-
- --afslog
- Gets AFS tickets, converts them to version 4 format, and stores
- them in the kernel. Only useful if you have AFS.
-
- The forwardable, proxiable, ticket_life, and renewable_life options can
- be set to a default value from the appdefaults section in krb5.conf, see
- krb5_appdefault(3).
-
- If a command is given, kinit will set up new credentials caches, and AFS
- PAG, and then run the given command. When it finishes the credentials
- will be removed.
-
-ENVIRONMENT
- KRB5CCNAME
- Specifies the default credentials cache.
-
- KRB5_CONFIG
- The file name of krb5.conf, the default being /etc/krb5.conf.
-
-SEE ALSO
- kdestroy(1), klist(1), krb5_appdefault(3), krb5.conf(5)
-
-HEIMDAL April 25, 2006 HEIMDAL
diff --git a/kuser/klist.c b/kuser/klist.c
index 02db225d3425..f0a438218b78 100644
--- a/kuser/klist.c
+++ b/kuser/klist.c
@@ -36,8 +36,9 @@
#include "kuser_locl.h"
#include "parse_units.h"
#include "heimtools-commands.h"
+#undef HC_DEPRECATED_CRYPTO
-static char*
+static const char *
printable_time_internal(time_t t, int x)
{
static char s[128];
@@ -51,13 +52,13 @@ printable_time_internal(time_t t, int x)
return s;
}
-static char*
+static const char *
printable_time(time_t t)
{
return printable_time_internal(t, 20);
}
-static char*
+static const char *
printable_time_long(time_t t)
{
return printable_time_internal(t, 20);
@@ -135,18 +136,173 @@ print_cred(krb5_context context, krb5_creds *cred, rtbl_t ct, int do_flags)
}
static void
-print_cred_verbose(krb5_context context, krb5_creds *cred, int do_json)
+cred2json(krb5_context context, krb5_creds *cred, heim_array_t tix)
{
- size_t j;
+ heim_dict_t t = heim_dict_create(10); /* ticket top-level */
+ heim_dict_t e = heim_dict_create(10); /* ticket times */
+ heim_dict_t f = heim_dict_create(20); /* flags */
+ heim_object_t o;
+ char buf[16], *sp = buf;
char *str;
krb5_error_code ret;
krb5_timestamp sec;
- if (do_json) { /* XXX support more json formating later */
- printf("{ \"verbose-supported\" : false }");
- return;
+ heim_array_append_value(tix, t);
+ krb5_timeofday(context, &sec);
+
+ /*
+ * JSON object names (keys) that start with capitals are for compatibility
+ * with the JSON we used to output. The others are new.
+ */
+ heim_dict_set_value(t, HSTR("times"), e);
+ heim_dict_set_value(t, HSTR("flags"), f);
+
+ heim_dict_set_value(e, HSTR("authtime"),
+ o = heim_number_create(cred->times.authtime));
+ heim_release(o);
+ heim_dict_set_value(t, HSTR("Issued"),
+ o = heim_string_create(printable_time(cred->times.authtime)));
+ heim_release(o);
+ heim_dict_set_value(e, HSTR("starttime"), heim_null_create());
+ if (cred->times.starttime) {
+ heim_dict_set_value(e, HSTR("starttime"),
+ o = heim_number_create(cred->times.starttime));
+ heim_release(o);
+ heim_dict_set_value(t, HSTR("Starttime"),
+ o = heim_string_create(printable_time(cred->times.starttime)));
+ heim_release(o);
+ }
+
+ if (cred->times.renew_till) {
+ heim_dict_set_value(e, HSTR("renew_till"),
+ o = heim_number_create(cred->times.starttime));
+ heim_release(o);
+ heim_dict_set_value(t, HSTR("Renew till"),
+ o = heim_string_create(printable_time(cred->times.starttime)));
+ heim_release(o);
+ }
+
+ heim_dict_set_value(e, HSTR("endtime"),
+ o = heim_number_create(cred->times.endtime));
+ heim_release(o);
+
+ if (cred->times.endtime > sec) {
+ heim_dict_set_value(t, HSTR("Expires"),
+ o = heim_string_create(printable_time(cred->times.endtime)));
+ heim_release(o);
+ heim_dict_set_value(t, HSTR("expired"), heim_bool_create(0));
+ } else {
+ heim_dict_set_value(t, HSTR("Expires"), HSTR(">>>Expired<<<"));
+ heim_dict_set_value(t, HSTR("expired"), heim_bool_create(1));
}
+ ret = krb5_unparse_name(context, cred->server, &str);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_unparse_name");
+ heim_dict_set_value(t, HSTR("Principal"), o = heim_string_create(str));
+ heim_release(o);
+
+ if (cred->flags.b.forwardable) {
+ heim_dict_set_value(f, HSTR("forwardable"), heim_bool_create(1));
+ *sp++ = 'F';
+ } else {
+ heim_dict_set_value(f, HSTR("forwardable"), heim_bool_create(0));
+ }
+ if (cred->flags.b.forwarded) {
+ heim_dict_set_value(f, HSTR("forwarded"), heim_bool_create(1));
+ *sp++ = 'f';
+ } else {
+ heim_dict_set_value(f, HSTR("forwarded"), heim_bool_create(0));
+ }
+ if (cred->flags.b.proxiable) {
+ heim_dict_set_value(f, HSTR("proxiable"), heim_bool_create(1));
+ *sp++ = 'P';
+ } else {
+ heim_dict_set_value(f, HSTR("proxiable"), heim_bool_create(0));
+ }
+ if (cred->flags.b.proxy) {
+ heim_dict_set_value(f, HSTR("proxy"), heim_bool_create(1));
+ *sp++ = 'p';
+ } else {
+ heim_dict_set_value(f, HSTR("proxy"), heim_bool_create(0));
+ }
+ if (cred->flags.b.may_postdate) {
+ heim_dict_set_value(f, HSTR("may_postdate"), heim_bool_create(1));
+ *sp++ = 'D';
+ } else {
+ heim_dict_set_value(f, HSTR("may_postdate"), heim_bool_create(0));
+ }
+ if (cred->flags.b.postdated) {
+ heim_dict_set_value(f, HSTR("postdated"), heim_bool_create(1));
+ *sp++ = 'd';
+ } else {
+ heim_dict_set_value(f, HSTR("postdated"), heim_bool_create(0));
+ }
+ if (cred->flags.b.renewable) {
+ heim_dict_set_value(f, HSTR("renewable"), heim_bool_create(1));
+ *sp++ = 'R';
+ } else {
+ heim_dict_set_value(f, HSTR("renewable"), heim_bool_create(0));
+ }
+ if (cred->flags.b.initial) {
+ heim_dict_set_value(f, HSTR("initial"), heim_bool_create(1));
+ *sp++ = 'I';
+ } else {
+ heim_dict_set_value(f, HSTR("initial"), heim_bool_create(0));
+ }
+ if (cred->flags.b.invalid) {
+ heim_dict_set_value(f, HSTR("invalid"), heim_bool_create(1));
+ *sp++ = 'i';
+ } else {
+ heim_dict_set_value(f, HSTR("invalid"), heim_bool_create(0));
+ }
+ if (cred->flags.b.pre_authent) {
+ heim_dict_set_value(f, HSTR("pre_authent"), heim_bool_create(1));
+ *sp++ = 'A';
+ } else {
+ heim_dict_set_value(f, HSTR("pre_authent"), heim_bool_create(0));
+ }
+ if (cred->flags.b.hw_authent) {
+ heim_dict_set_value(f, HSTR("hw_authent"), heim_bool_create(1));
+ *sp++ = 'H';
+ } else {
+ heim_dict_set_value(f, HSTR("hw_authent"), heim_bool_create(0));
+ }
+ if (cred->flags.b.transited_policy_checked) {
+ heim_dict_set_value(f, HSTR("transited_policy_checked"), heim_bool_create(1));
+ *sp++ = 'T';
+ } else {
+ heim_dict_set_value(f, HSTR("transited_policy_checked"), heim_bool_create(0));
+ }
+ if (cred->flags.b.ok_as_delegate) {
+ heim_dict_set_value(f, HSTR("ok_as_delegate"), heim_bool_create(1));
+ *sp++ = 'O';
+ } else {
+ heim_dict_set_value(f, HSTR("ok_as_delegate"), heim_bool_create(0));
+ }
+ if (cred->flags.b.anonymous) {
+ heim_dict_set_value(f, HSTR("anonymous"), heim_bool_create(1));
+ *sp++ = 'a';
+ } else {
+ heim_dict_set_value(f, HSTR("anonymous"), heim_bool_create(0));
+ }
+ *sp = '\0';
+ heim_dict_set_value(t, HSTR("Flags"), o = heim_string_create(sp));
+ heim_release(e);
+ heim_release(f);
+ heim_release(t);
+ heim_release(o);
+ free(str);
+}
+
+static void
+print_cred_verbose(krb5_context context, krb5_creds *cred)
+{
+ size_t j;
+ char *str;
+ krb5_error_code ret;
+ krb5_timestamp sec;
+
krb5_timeofday (context, &sec);
ret = krb5_unparse_name(context, cred->server, &str);
@@ -161,7 +317,28 @@ print_cred_verbose(krb5_context context, krb5_creds *cred, int do_json)
printf(N_("Client: %s\n", ""), str);
free (str);
- if (!krb5_is_config_principal(context, cred->client)) {
+ if (krb5_is_config_principal(context, cred->server)) {
+ if (krb5_principal_get_num_comp(context, cred->server) > 1) {
+ const char *s;
+
+ /* If the payload is text and not secret/sensitive, print it */
+ s = krb5_principal_get_comp_string(context, cred->server, 1);
+ if (strcmp(s, "start_realm") == 0 ||
+ strcmp(s, "anon_pkinit_realm") == 0 ||
+ strcmp(s, "default-ntlm-domain") == 0 ||
+ strcmp(s, "FriendlyName") == 0 ||
+ strcmp(s, "fast_avail") == 0 ||
+ strcmp(s, "kx509store") == 0 ||
+ strcmp(s, "kx509_service_realm") == 0 ||
+ strcmp(s, "kx509_service_status") == 0)
+ printf(N_("Configuration item payload: %.*s\n", ""),
+ (int)cred->ticket.length,
+ (const char *)cred->ticket.data);
+ else
+ printf(N_("Configuration item payload length: %lu\n", ""),
+ (unsigned long)cred->ticket.length);
+ } /* else... this is a meaningless entry; nothing would create it */
+ } else {
Ticket t;
size_t len;
char *s;
@@ -190,64 +367,131 @@ print_cred_verbose(krb5_context context, krb5_creds *cred, int do_json)
free_Ticket(&t);
printf(N_("Ticket length: %lu\n", ""),
(unsigned long)cred->ticket.length);
- }
- printf(N_("Auth time: %s\n", ""),
- printable_time_long(cred->times.authtime));
- if(cred->times.authtime != cred->times.starttime)
- printf(N_("Start time: %s\n", ""),
- printable_time_long(cred->times.starttime));
- printf(N_("End time: %s", ""),
- printable_time_long(cred->times.endtime));
- if(sec > cred->times.endtime)
- printf(N_(" (expired)", ""));
- printf("\n");
- if(cred->flags.b.renewable)
- printf(N_("Renew till: %s\n", ""),
- printable_time_long(cred->times.renew_till));
- {
- char flags[1024];
- unparse_flags(TicketFlags2int(cred->flags.b),
- asn1_TicketFlags_units(),
- flags, sizeof(flags));
- printf(N_("Ticket flags: %s\n", ""), flags);
- }
- printf(N_("Addresses: ", ""));
- if (cred->addresses.len != 0) {
- for(j = 0; j < cred->addresses.len; j++){
- char buf[128];
- size_t len;
- if(j) printf(", ");
- ret = krb5_print_address(&cred->addresses.val[j],
- buf, sizeof(buf), &len);
-
- if(ret == 0)
- printf("%s", buf);
- }
- } else {
- printf(N_("addressless", ""));
+ printf(N_("Auth time: %s\n", ""),
+ printable_time_long(cred->times.authtime));
+ if(cred->times.authtime != cred->times.starttime)
+ printf(N_("Start time: %s\n", ""),
+ printable_time_long(cred->times.starttime));
+ printf(N_("End time: %s", ""),
+ printable_time_long(cred->times.endtime));
+ if(sec > cred->times.endtime)
+ printf(N_(" (expired)", ""));
+ printf("\n");
+ if(cred->flags.b.renewable)
+ printf(N_("Renew till: %s\n", ""),
+ printable_time_long(cred->times.renew_till));
+ {
+ char flags[1024];
+ int result = unparse_flags(TicketFlags2int(cred->flags.b),
+ asn1_TicketFlags_units(),
+ flags, sizeof(flags));
+ if (result > 0) {
+ printf(N_("Ticket flags: %s\n", ""), flags);
+ }
+ }
+ printf(N_("Addresses: ", ""));
+ if (cred->addresses.len != 0) {
+ for(j = 0; j < cred->addresses.len; j++){
+ char buf[128];
+ if(j) printf(", ");
+ ret = krb5_print_address(&cred->addresses.val[j],
+ buf, sizeof(buf), &len);
+
+ if(ret == 0)
+ printf("%s", buf);
+ }
+ } else {
+ printf(N_("addressless", ""));
+ }
}
printf("\n\n");
}
+static void
+cache2json(krb5_context context,
+ krb5_ccache ccache,
+ krb5_principal principal,
+ heim_dict_t dict)
+{
+ heim_array_t tix = heim_array_create();
+ heim_object_t o;
+ char *str, *fullname;
+ char *name = NULL;
+ krb5_error_code ret;
+ krb5_cc_cursor cursor;
+ krb5_creds creds;
+ krb5_deltat sec;
+
+ ret = krb5_unparse_name(context, principal, &str);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_unparse_name");
+
+ ret = krb5_cc_get_full_name(context, ccache, &fullname);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_get_full_name");
+
+ heim_dict_set_value(dict, HSTR("cache"),
+ o = heim_string_create(fullname));
+ heim_release(o);
+ heim_dict_set_value(dict, HSTR("principal"),
+ o = heim_string_create(str));
+ heim_release(o);
+ heim_dict_set_value(dict, HSTR("cache_version"),
+ o = heim_number_create(krb5_cc_get_version(context,
+ ccache)));
+ heim_release(o);
+ free(str);
+
+ ret = krb5_cc_get_friendly_name(context, ccache, &name);
+ if (ret == 0) {
+ heim_dict_set_value(dict, HSTR("friendly_name"),
+ o = heim_string_create(name));
+ heim_release(o);
+ }
+ free(name);
+
+ ret = krb5_cc_get_kdc_offset(context, ccache, &sec);
+ if (ret == 0) {
+ heim_dict_set_value(dict, HSTR("kdc_offset"),
+ o = heim_number_create(sec));
+ heim_release(o);
+ }
+
+ heim_dict_set_value(dict, HSTR("tickets"), tix);
+ ret = krb5_cc_start_seq_get(context, ccache, &cursor);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_start_seq_get");
+
+ while ((ret = krb5_cc_next_cred(context, ccache, &cursor, &creds)) == 0) {
+ cred2json(context, &creds, tix);
+ krb5_free_cred_contents(context, &creds);
+ }
+ if (ret != KRB5_CC_END)
+ krb5_err(context, 1, ret, "krb5_cc_get_next");
+ ret = krb5_cc_end_seq_get(context, ccache, &cursor);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_end_seq_get");
+ heim_release(tix);
+ free(fullname);
+}
+
/*
* Print all tickets in `ccache' on stdout, verbosely if do_verbose.
*/
static void
-print_tickets (krb5_context context,
- krb5_ccache ccache,
- krb5_principal principal,
- int do_verbose,
- int do_flags,
- int do_hidden,
- int do_json)
+print_tickets(krb5_context context,
+ krb5_ccache ccache,
+ krb5_principal principal,
+ int do_verbose,
+ int do_flags,
+ int do_hidden)
{
char *str, *name, *fullname;
krb5_error_code ret;
krb5_cc_cursor cursor;
krb5_creds creds;
krb5_deltat sec;
-
rtbl_t ct = NULL;
ret = krb5_unparse_name (context, principal, &str);
@@ -258,27 +502,26 @@ print_tickets (krb5_context context,
if (ret)
krb5_err (context, 1, ret, "krb5_cc_get_full_name");
- if (!do_json) {
- printf ("%17s: %s\n", N_("Credentials cache", ""), fullname);
- printf ("%17s: %s\n", N_("Principal", ""), str);
-
- ret = krb5_cc_get_friendly_name(context, ccache, &name);
- if (ret == 0) {
- if (strcmp(name, str) != 0)
- printf ("%17s: %s\n", N_("Friendly name", ""), name);
- free(name);
- }
+ printf ("%17s: %s\n", N_("Credentials cache", ""), fullname);
+ printf ("%17s: %s\n", N_("Principal", ""), str);
- if(do_verbose) {
- printf ("%17s: %d\n", N_("Cache version", ""),
- krb5_cc_get_version(context, ccache));
- } else {
- krb5_cc_set_flags(context, ccache, KRB5_TC_NOTICKET);
- }
+ ret = krb5_cc_get_friendly_name(context, ccache, &name);
+ if (ret == 0) {
+ if (strcmp(name, str) != 0) {
+ printf ("%17s: %s\n", N_("Friendly name", ""), name);
+ }
+ free(name);
+ }
+
+ if(do_verbose) {
+ printf ("%17s: %d\n", N_("Cache version", ""),
+ krb5_cc_get_version(context, ccache));
+ }
- ret = krb5_cc_get_kdc_offset(context, ccache, &sec);
+ ret = krb5_cc_get_kdc_offset(context, ccache, &sec);
+ if (ret == 0) {
+ if (do_verbose && sec != 0) {
- if (ret == 0 && do_verbose && sec != 0) {
char buf[BUFSIZ];
int val;
int sig;
@@ -294,18 +537,16 @@ print_tickets (krb5_context context,
printf ("%17s: %s%s\n", N_("KDC time offset", ""),
sig == -1 ? "-" : "", buf);
- }
- printf("\n");
- } else {
- printf ("{ \"cache\" : \"%s\", \"principal\" : \"%s\", ", fullname, str);
+ }
}
+ printf("\n");
free(str);
ret = krb5_cc_start_seq_get (context, ccache, &cursor);
if (ret)
krb5_err(context, 1, ret, "krb5_cc_start_seq_get");
- if(!do_verbose) {
+ if (!do_verbose) {
ct = rtbl_create();
rtbl_add_column(ct, COL_ISSUED, 0);
rtbl_add_column(ct, COL_EXPIRES, 0);
@@ -313,40 +554,28 @@ print_tickets (krb5_context context,
rtbl_add_column(ct, COL_FLAGS, 0);
rtbl_add_column(ct, COL_PRINCIPAL, 0);
rtbl_set_separator(ct, " ");
- if (do_json) {
- rtbl_set_flags(ct, RTBL_JSON);
- printf("\"tickets\" : ");
- }
}
- if (do_verbose && do_json)
- printf("\"tickets\" : [");
- while ((ret = krb5_cc_next_cred (context,
- ccache,
- &cursor,
- &creds)) == 0) {
+ while ((ret = krb5_cc_next_cred(context, ccache, &cursor, &creds)) == 0) {
if (!do_hidden && krb5_is_config_principal(context, creds.server)) {
;
- }else if(do_verbose){
- print_cred_verbose(context, &creds, do_json);
- }else{
+ } else if (do_verbose) {
+ print_cred_verbose(context, &creds);
+ } else {
print_cred(context, &creds, ct, do_flags);
}
- krb5_free_cred_contents (context, &creds);
+ krb5_free_cred_contents(context, &creds);
}
- if(ret != KRB5_CC_END)
+ if (ret != KRB5_CC_END)
krb5_err(context, 1, ret, "krb5_cc_get_next");
ret = krb5_cc_end_seq_get (context, ccache, &cursor);
if (ret)
- krb5_err (context, 1, ret, "krb5_cc_end_seq_get");
+ krb5_err(context, 1, ret, "krb5_cc_end_seq_get");
+
if(!do_verbose) {
rtbl_format(ct, stdout);
rtbl_destroy(ct);
}
- if (do_json) {
- if (do_verbose)
- printf("]");
- printf("}");
- }
+ free(fullname);
}
/*
@@ -450,10 +679,10 @@ display_tokens(int do_verbose)
*/
static int
-display_v5_ccache (krb5_context context, krb5_ccache ccache,
- int do_test, int do_verbose,
- int do_flags, int do_hidden,
- int do_json)
+display_v5_ccache(krb5_context context, krb5_ccache ccache,
+ int do_test, int do_verbose,
+ int do_flags, int do_hidden,
+ heim_dict_t dict)
{
krb5_error_code ret;
krb5_principal principal;
@@ -462,10 +691,8 @@ display_v5_ccache (krb5_context context, krb5_ccache ccache,
ret = krb5_cc_get_principal (context, ccache, &principal);
if (ret) {
- if (do_json) {
- printf("{}");
+ if (dict)
return 0;
- }
if(ret == ENOENT) {
if (!do_test)
krb5_warnx(context, N_("No ticket file: %s", ""),
@@ -474,11 +701,18 @@ display_v5_ccache (krb5_context context, krb5_ccache ccache,
} else
krb5_err (context, 1, ret, "krb5_cc_get_principal");
}
- if (do_test)
- exit_status = check_expiration(context, ccache, NULL);
- else
- print_tickets (context, ccache, principal, do_verbose,
- do_flags, do_hidden, do_json);
+ exit_status = check_expiration(context, ccache, NULL);
+ if (!do_test) {
+ if (dict) {
+ heim_dict_set_value(dict, HSTR("expired"),
+ heim_bool_create(!!exit_status));
+ cache2json(context, ccache, principal, dict);
+ } else {
+ print_tickets(context, ccache, principal, do_verbose,
+ do_flags, do_hidden);
+ }
+ exit_status = 0;
+ }
ret = krb5_cc_close (context, ccache);
if (ret)
@@ -489,6 +723,87 @@ display_v5_ccache (krb5_context context, krb5_ccache ccache,
return exit_status;
}
+static int
+caches2json(krb5_context context)
+{
+ krb5_cccol_cursor cursor;
+ const char *cdef_name = krb5_cc_default_name(context);
+ char *def_name;
+ heim_object_t o;
+ heim_array_t a = heim_array_create();
+ krb5_error_code ret;
+ krb5_ccache id;
+
+ if ((def_name = krb5_cccol_get_default_ccname(context)) == NULL)
+ cdef_name = krb5_cc_default_name(context);
+ if (!def_name && cdef_name && (def_name = strdup(cdef_name)) == NULL)
+ krb5_err(context, 1, ENOMEM, "Out of memory");
+
+ ret = krb5_cccol_cursor_new(context, &cursor);
+ if (ret == KRB5_CC_NOSUPP) {
+ free(def_name);
+ return 0;
+ }
+ else if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_cache_get_first");
+
+ while (krb5_cccol_cursor_next(context, cursor, &id) == 0 && id != NULL) {
+ heim_dict_t dict = heim_dict_create(10);
+ int expired = 0;
+ char *name;
+ time_t t;
+
+ expired = check_expiration(context, id, &t);
+ ret = krb5_cc_get_friendly_name(context, id, &name);
+ if (ret == 0) {
+ char *fname;
+
+ heim_dict_set_value(dict, HSTR("Name"),
+ o = heim_string_create(name));
+ heim_release(o);
+ free(name);
+
+ if (expired)
+ o = heim_string_create(N_(">>> Expired <<<", ""));
+ else
+ o = heim_string_create(printable_time(t));
+ heim_dict_set_value(dict, HSTR("Expires"), o);
+ heim_release(o);
+
+ ret = krb5_cc_get_full_name(context, id, &fname);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_get_full_name");
+
+ heim_dict_set_value(dict, HSTR("Cache Name"),
+ o = heim_string_create(fname));
+ heim_release(o);
+
+ if (def_name && strcmp(fname, def_name) == 0)
+ heim_dict_set_value(dict, HSTR("is_default_cache"),
+ heim_bool_create(1));
+ else
+ heim_dict_set_value(dict, HSTR("is_default_cache"),
+ heim_bool_create(0));
+ heim_array_append_value(a, dict);
+ heim_release(dict);
+
+ krb5_xfree(fname);
+ }
+ krb5_cc_close(context, id);
+ }
+
+ krb5_cccol_cursor_free(context, &cursor);
+ free(def_name);
+
+ o = heim_json_copy_serialize(a, HEIM_JSON_F_STRICT | HEIM_JSON_F_INDENT2,
+ NULL);
+ printf("%s", heim_string_get_utf8(o));
+ heim_release(a);
+ heim_release(o);
+
+ return 0;
+}
+
/*
*
*/
@@ -497,16 +812,16 @@ static int
list_caches(krb5_context context, struct klist_options *opt)
{
krb5_cccol_cursor cursor;
- const char *cdef_name;
+ const char *cdef_name = krb5_cc_default_name(context);
char *def_name;
krb5_error_code ret;
krb5_ccache id;
rtbl_t ct;
- cdef_name = krb5_cc_default_name(context);
- if (cdef_name == NULL)
- krb5_errx(context, 1, "krb5_cc_default_name");
- def_name = strdup(cdef_name);
+ if ((def_name = krb5_cccol_get_default_ccname(context)) == NULL)
+ cdef_name = krb5_cc_default_name(context);
+ if (!def_name && cdef_name && (def_name = strdup(cdef_name)) == NULL)
+ krb5_err(context, 1, ENOMEM, "Out of memory");
ret = krb5_cccol_cursor_new(context, &cursor);
if (ret == KRB5_CC_NOSUPP) {
@@ -525,10 +840,8 @@ list_caches(krb5_context context, struct klist_options *opt)
rtbl_set_prefix(ct, " ");
rtbl_set_column_prefix(ct, COL_DEFCACHE, "");
rtbl_set_column_prefix(ct, COL_NAME, " ");
- if (opt->json_flag)
- rtbl_set_flags(ct, RTBL_JSON);
- while (krb5_cccol_cursor_next(context, cursor, &id) == 0) {
+ while (krb5_cccol_cursor_next(context, cursor, &id) == 0 && id != NULL) {
int expired = 0;
char *name;
time_t t;
@@ -554,9 +867,7 @@ list_caches(krb5_context context, struct klist_options *opt)
krb5_err (context, 1, ret, "krb5_cc_get_full_name");
rtbl_add_column_entry(ct, COL_CACHENAME, fname);
- if (opt->json_flag)
- ;
- else if (strcmp(fname, def_name) == 0)
+ if (def_name && strcmp(fname, def_name) == 0)
rtbl_add_column_entry(ct, COL_DEFCACHE, "*");
else
rtbl_add_column_entry(ct, COL_DEFCACHE, "");
@@ -572,9 +883,6 @@ list_caches(krb5_context context, struct klist_options *opt)
rtbl_format(ct, stdout);
rtbl_destroy(ct);
- if (opt->json_flag)
- printf("\n");
-
return 0;
}
@@ -586,6 +894,7 @@ int
klist(struct klist_options *opt, int argc, char **argv)
{
krb5_error_code ret;
+ heim_object_t o = NULL;
int exit_status = 0;
int do_verbose =
@@ -602,7 +911,10 @@ klist(struct klist_options *opt, int argc, char **argv)
}
if (opt->list_all_flag) {
- exit_status = list_caches(heimtools_context, opt);
+ if (opt->json_flag)
+ exit_status = caches2json(heimtools_context);
+ else
+ exit_status = list_caches(heimtools_context, opt);
return exit_status;
}
@@ -610,31 +922,28 @@ klist(struct klist_options *opt, int argc, char **argv)
krb5_ccache id;
if (opt->all_content_flag) {
+ heim_array_t a = opt->json_flag ? heim_array_create() : NULL;
krb5_cc_cache_cursor cursor;
- int first = 1;
ret = krb5_cc_cache_get_first(heimtools_context, NULL, &cursor);
if (ret)
krb5_err(heimtools_context, 1, ret, "krb5_cc_cache_get_first");
- if (opt->json_flag)
- printf("[");
while (krb5_cc_cache_next(heimtools_context, cursor, &id) == 0) {
- if (opt->json_flag && !first)
- printf(",");
+ heim_dict_t dict = opt->json_flag ? heim_dict_create(10) : NULL;
exit_status |= display_v5_ccache(heimtools_context, id, do_test,
do_verbose, opt->flags_flag,
- opt->hidden_flag, opt->json_flag);
- if (!opt->json_flag)
- printf("\n\n");
-
- first = 0;
+ opt->hidden_flag,
+ dict);
+ if (a)
+ heim_array_append_value(a, dict);
+ heim_release(dict);
}
krb5_cc_cache_end_seq_get(heimtools_context, cursor);
- if (opt->json_flag)
- printf("]");
+ o = a;
} else {
+ heim_dict_t dict = opt->json_flag ? heim_dict_create(10) : NULL;
if(opt->cache_string) {
ret = krb5_cc_resolve(heimtools_context, opt->cache_string, &id);
if (ret)
@@ -646,10 +955,25 @@ klist(struct klist_options *opt, int argc, char **argv)
}
exit_status = display_v5_ccache(heimtools_context, id, do_test,
do_verbose, opt->flags_flag,
- opt->hidden_flag, opt->json_flag);
+ opt->hidden_flag, dict);
+ o = dict;
}
}
+ if (o) {
+ heim_string_t s = heim_json_copy_serialize(o,
+ HEIM_JSON_F_STRICT |
+ HEIM_JSON_F_INDENT2,
+ NULL);
+
+ if (s == NULL)
+ errx(1, "Could not format JSON text");
+
+ printf("%s", heim_string_get_utf8(s));
+ heim_release(o);
+ heim_release(s);
+ }
+
if (!do_test) {
#ifndef NO_AFS
if (opt->tokens_flag && k_hasafs()) {
diff --git a/kuser/klist.cat1 b/kuser/klist.cat1
deleted file mode 100644
index 3c8f2667868a..000000000000
--- a/kuser/klist.cat1
+++ /dev/null
@@ -1,89 +0,0 @@
-KLIST(1) BSD General Commands Manual KLIST(1)
-
-NAME
- klist -- list Kerberos credentials
-
-SYNOPSIS
- klist [-c cache | --cache=cache] [-s | -t | --test] [-T | --tokens]
- [-5 | --v5] [-v | --verbose] [-l | --list-caches] [-f] [--version]
- [--help]
-
-DESCRIPTION
- klist reads and displays the current tickets in the credential cache
- (also known as the ticket file).
-
- Options supported:
-
- -c cache, --cache=cache
- credential cache to list
-
- -s, -t, --test
- Test for there being an active and valid TGT for the local realm
- of the user in the credential cache.
-
- -T, --tokens
- display AFS tokens
-
- -5, --v5
- display v5 cred cache (this is the default)
-
- -f Include ticket flags in short form, each character stands for a
- specific flag, as follows:
- F forwardable
- f forwarded
- P proxiable
- p proxied
- D postdate-able
- d postdated
- R renewable
- I initial
- i invalid
- A pre-authenticated
- H hardware authenticated
-
- This information is also output with the --verbose option, but in
- a more verbose way.
-
- -v, --verbose
- Verbose output. Include all possible information:
-
- Server
- the principal the ticket is for
-
- Ticket etype
- the encryption type used in the ticket, followed by
- the key version of the ticket, if it is available
-
- Session key
- the encryption type of the session key, if it's dif-
- ferent from the encryption type of the ticket
-
- Auth time
- the time the authentication exchange took place
-
- Start time
- the time that this ticket is valid from (only printed
- if it's different from the auth time)
-
- End time
- when the ticket expires, if it has already expired
- this is also noted
-
- Renew till
- the maximum possible end time of any ticket derived
- from this one
-
- Ticket flags
- the flags set on the ticket
-
- Addresses
- the set of addresses from which this ticket is valid
-
- -l, --list-caches
- List the credential caches for the current users, not all cache
- types supports listing multiple caches.
-
-SEE ALSO
- kdestroy(1), kinit(1)
-
-HEIMDAL October 6, 2005 HEIMDAL
diff --git a/kuser/kswitch.cat1 b/kuser/kswitch.cat1
deleted file mode 100644
index 4c7e706d1661..000000000000
--- a/kuser/kswitch.cat1
+++ /dev/null
@@ -1,31 +0,0 @@
-KSWITCH(1) BSD General Commands Manual KSWITCH(1)
-
-NAME
- kswitch -- switch between default credential caches
-
-SYNOPSIS
- kswitch [-t type | --type=type] [-c cache | --cache=cache] [-p principal
- | --principal=principal] [-i | --interactive] [--version]
- [--help]
-
-DESCRIPTION
- Supported options:
-
- -t type, --type=type
- type of credential cache
-
- -c cache, --cache=cache
- name of credential cache to switch to
-
- -p principal, --principal=principal
- name of principal to switch to
-
- -i, --interactive
- interactive switching between credentials.
-
- --version
- print version
-
- --help
-
-HEIMDAL August 25, 2009 HEIMDAL
diff --git a/kuser/kuser_locl.h b/kuser/kuser_locl.h
index a0fcc9db698c..8218a6f096fd 100644
--- a/kuser/kuser_locl.h
+++ b/kuser/kuser_locl.h
@@ -72,6 +72,11 @@
#include <parse_time.h>
#include <err.h>
#include <krb5.h>
+#include <heimbase.h>
+
+#include <gssapi_mech.h>
+#include <gss-preauth-protos.h>
+#include <gss-preauth-private.h>
#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
#include <sys/ioctl.h>
diff --git a/kuser/kx509.1 b/kuser/kx509.1
new file mode 100644
index 000000000000..1fb3ce2af5d6
--- /dev/null
+++ b/kuser/kx509.1
@@ -0,0 +1,133 @@
+.\" Copyright (c) 2019 Kungliga Tekniska Högskolan
+.\" (Royal Institute of Technology, Stockholm, Sweden).
+.\" All rights reserved.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\"
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\"
+.\" 2. 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.
+.\"
+.\" 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+.\"
+.\" $Id$
+.\"
+.Dd October 6, 2005
+.Dt KLIST 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kx509
+.Nd acquire or extract certificates using Kerberos credentials
+.Sh SYNOPSIS
+.Nm
+.Bk -words
+.Oo Fl c Ar cache \*(Ba Xo
+.Fl Fl cache= Ns Ar cache
+.Xc
+.Oc
+.Oo Fl s \*(Ba Xo
+.Fl Fl save
+.Xc
+.Oc
+.Oo Fl o Ar store \*(Ba Xo
+.Fl Fl out= Ns Ar store
+.Xc
+.Oc
+.Oo Fl x \*(Ba Xo
+.Fl Fl extract
+.Xc
+.Oc
+.Oo Fl t Ar time-left \*(Ba Xo
+.Fl Fl test= Ns Ar time-left
+.Xc
+.Oc
+.Oo Fl C Ar PKCS10:filename \*(Ba Xo
+.Fl Fl csr= Ns Ar PKCS10:filename
+.Xc
+.Oc
+.Oo Fl C Ar PKCS10:filename \*(Ba Xo
+.Fl Fl csr= Ns Ar PKCS10:filename
+.Xc
+.Oc
+.Oo Fl K Ar hx509-store \*(Ba Xo
+.Fl Fl private-key= Ns Ar hx509-store
+.Xc
+.Oc
+.Oo Fl r Ar realm \*(Ba Xo
+.Fl Fl realm= Ns Ar realm
+.Xc
+.Oc
+.Op Fl Fl help
+.Ek
+.Sh DESCRIPTION
+.Nm
+acquires PKIX credentials from a credential cache using the kx509
+protocol, or extracts PKIX credentials stored in a credential
+cache.
+.Pp
+Options supported:
+.Bl -tag -width Ds
+.It Fl c Ar cache , Fl Fl cache= Ns Ar cache
+credential cache to use (if not given, then the default will be
+used).
+.It Fl t Ar time-left , Fl Fl test= Ns Ar time-left
+Test for there being an active and valid certificate in the
+credential cache, with at least
+.Ar time-left
+seconds left of valid life. If given with the
+.Fl o
+then the certificates in the hx509 store are tested along with
+those in the credentials cache (if any).
+.It Fl x , Fl Fl extract
+Extract, rather than acquire credentials.
+.It Fl s , Fl Fl save
+save the acquired certificate and the private key used in the
+given credential cache.
+.It Fl o , Fl Fl out= Ns Ar hx509-store
+An hx509 store specification, such as
+.Va DER-FILE:/path/to/der/file ,
+.Va PEM-FILE:/path/to/PEM/file ,
+.Va FILE:/path/to/PEM/file ,
+or
+.Va PKCS12:/path/to/PKCS#12/file
+into which to store any PKIX certificate and private key
+(unencrypted) that may have been acquired with the kx509 protocol
+and stored in the
+.Ns Ar ccache.
+.It Fl r Ar realm, Fl Fl realm= Ns Ar realm
+specify the name of the realm whose kx509 service to use.
+.It Fl K Ar store, Fl Fl private-key= Ns Ar store
+use the private key from the given hx509 store for requesting a
+certificate.
+.It Fl C Ar csr, Fl Fl csr= Ns Ar certificate-request
+specify a CSR to use, which must be a string of the form
+PKCS10:filename and which must contain the DER encoding of a
+PKCS#10 certification request.
+.El
+.Pp
+The
+.Nm hxtool(1)
+command can be used to create private keys and CSRs.
+.Sh SEE ALSO
+.Xr kdestroy 1 ,
+.Xr kinit 1 ,
+.Xr hxtool 1
diff --git a/kuser/kx509.c b/kuser/kx509.c
new file mode 100644
index 000000000000..1cd76fcf955b
--- /dev/null
+++ b/kuser/kx509.c
@@ -0,0 +1,303 @@
+/*
+ * Copyright (c) 2019 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. 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.
+ *
+ * 3. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
+ */
+
+#include "kuser_locl.h"
+#include "heimtools-commands.h"
+#include <kx509_asn1.h>
+#undef HC_DEPRECATED_CRYPTO
+#include "../lib/hx509/hx_locl.h"
+#include "../lib/krb5/krb5_locl.h"
+#include "hx509-private.h"
+
+struct validate_store {
+ size_t ncerts;
+ int grace;
+};
+
+static int KRB5_CALLCONV
+validate1(hx509_context hx509ctx, void *d, hx509_cert cert)
+{
+ struct validate_store *v = d;
+
+ if (hx509_cert_get_notAfter(cert) < time(NULL) + v->grace)
+ return HX509_CERT_USED_AFTER_TIME;
+ v->ncerts++;
+ return 0;
+}
+
+static void
+validate(krb5_context context,
+ int grace,
+ const char *hx509_store,
+ krb5_data *der_cert,
+ krb5_data *pkcs8_priv_key)
+{
+ hx509_context hx509ctx = NULL;
+ hx509_cert cert;
+ krb5_error_code ret;
+
+ ret = hx509_context_init(&hx509ctx);
+ if (ret)
+ krb5_err(context, 1, ret, "hx509 context init");
+
+ if (der_cert->data && pkcs8_priv_key->data) {
+ hx509_private_key key = NULL;
+
+ cert = hx509_cert_init_data(hx509ctx, der_cert->data,
+ der_cert->length, NULL);
+ if (cert == NULL)
+ krb5_err(context, 1, errno, "certificate could not be loaded");
+ ret = hx509_parse_private_key(hx509ctx, NULL, pkcs8_priv_key->data,
+ pkcs8_priv_key->length,
+ HX509_KEY_FORMAT_PKCS8, &key);
+ if (ret)
+ krb5_err(context, 1, ret, "certificate could not be loaded");
+ if (hx509_cert_get_notAfter(cert) < time(NULL) + grace)
+ krb5_errx(context, 1, "certificate is expired");
+ hx509_private_key_free(&key);
+ hx509_cert_free(cert);
+ }
+ if (hx509_store) {
+ struct validate_store v;
+ hx509_certs certs;
+
+ v.ncerts = 0;
+ v.grace = grace;
+
+ ret = hx509_certs_init(hx509ctx, hx509_store, 0, NULL, &certs);
+ if (ret)
+ krb5_err(context, 1, ret, "could not read hx509 store %s",
+ hx509_store);
+ ret = hx509_certs_iter_f(hx509ctx, certs, validate1, &v);
+ if (ret)
+ krb5_err(context, 1, ret, "at least one certificate in %s expired",
+ hx509_store);
+ if (!v.ncerts)
+ krb5_errx(context, 1, "no certificates in %s", hx509_store);
+
+ hx509_certs_free(&certs);
+ }
+
+ hx509_context_free(&hx509ctx);
+}
+
+static krb5_error_code KRB5_CALLCONV
+add1_2chain(hx509_context hx509ctx, void *d, hx509_cert cert)
+{
+ heim_octet_string os;
+ krb5_error_code ret;
+ Certificates *cs = d;
+ Certificate c;
+
+ ret = hx509_cert_binary(hx509ctx, cert, &os);
+ if (ret == 0)
+ ret = decode_Certificate(os.data, os.length, &c, NULL);
+ der_free_octet_string(&os);
+ if (ret == 0) {
+ add_Certificates(cs, &c);
+ free_Certificate(&c);
+ }
+ return ret;
+}
+
+static krb5_error_code
+add_chain(hx509_context hx509ctx, hx509_certs certs, krb5_data *chain)
+{
+ krb5_error_code ret;
+ Certificates cs;
+ size_t len;
+
+ ret = decode_Certificates(chain->data, chain->length, &cs, &len);
+ if (ret == 0) {
+ ret = hx509_certs_iter_f(hx509ctx, certs, add1_2chain, &cs);
+ free_Certificates(&cs);
+ }
+ return ret;
+}
+
+static void
+store(krb5_context context,
+ const char *hx509_store,
+ krb5_data *der_cert,
+ krb5_data *pkcs8_priv_key,
+ krb5_data *chain)
+{
+ hx509_context hx509ctx = NULL;
+ hx509_private_key key = NULL;
+ hx509_certs certs;
+ hx509_cert cert;
+ char *store_exp = NULL;
+ krb5_error_code ret;
+
+ if (hx509_store == NULL) {
+ hx509_store = krb5_config_get_string(context, NULL, "libdefaults",
+ "kx509_store", NULL);
+ if (hx509_store) {
+ ret = _krb5_expand_path_tokens(context, hx509_store, 1,
+ &store_exp);
+ if (ret)
+ krb5_err(context, 1, ret, "expanding tokens in default "
+ "hx509 store");
+ hx509_store = store_exp;
+ }
+ }
+ if (hx509_store == NULL)
+ krb5_errx(context, 1, "no hx509 store given and no default hx509 "
+ "store configured");
+
+ ret = hx509_context_init(&hx509ctx);
+ if (ret)
+ krb5_err(context, 1, ret, "hx509 context init");
+
+ cert = hx509_cert_init_data(hx509ctx, der_cert->data,
+ der_cert->length, NULL);
+ if (cert == NULL)
+ krb5_err(context, 1, errno, "certificate could not be loaded");
+ ret = hx509_parse_private_key(hx509ctx, NULL, pkcs8_priv_key->data,
+ pkcs8_priv_key->length,
+ HX509_KEY_FORMAT_PKCS8, &key);
+ if (ret)
+ krb5_err(context, 1, ret, "certificate could not be loaded");
+ (void) _hx509_cert_assign_key(cert, key);
+
+ ret = hx509_certs_init(hx509ctx, hx509_store, HX509_CERTS_CREATE, NULL,
+ &certs);
+ if (ret == 0)
+ ret = hx509_certs_add(hx509ctx, certs, cert);
+ if (ret == 0)
+ add_chain(hx509ctx, certs, chain);
+ if (ret == 0)
+ ret = hx509_certs_store(hx509ctx, certs, 0, NULL);
+ if (ret)
+ krb5_err(context, 1, ret, "certificate could not be stored");
+
+ hx509_private_key_free(&key);
+ hx509_certs_free(&certs);
+ hx509_cert_free(cert);
+ hx509_context_free(&hx509ctx);
+ free(store_exp);
+}
+
+static void
+set_csr(krb5_context context, krb5_kx509_req_ctx req, const char *csr_file)
+{
+ krb5_error_code ret;
+ krb5_data d;
+
+ if (strncmp(csr_file, "PKCS10:", sizeof("PKCS10:") - 1) != 0)
+ krb5_errx(context, 1, "CSR filename must start with \"PKCS10:\"");
+ ret = rk_undumpdata(csr_file + sizeof("PKCS10:") - 1, &d.data, &d.length);
+ if (ret)
+ krb5_err(context, 1, ret, "could not read CSR");
+ ret = krb5_kx509_ctx_set_csr_der(context, req, &d);
+ if (ret)
+ krb5_err(context, 1, ret, "hx509 context init");
+}
+
+int
+kx509(struct kx509_options *opt, int argc, char **argv)
+{
+ krb5_kx509_req_ctx req = NULL;
+ krb5_context context = heimtools_context;
+ krb5_error_code ret = 0;
+ krb5_ccache ccout = NULL;
+ krb5_ccache cc = NULL;
+
+ if (opt->cache_string)
+ ret = krb5_cc_resolve(context, opt->cache_string, &cc);
+ else if (opt->save_flag || opt->extract_flag)
+ ret = krb5_cc_default(context, &cc);
+ if (ret)
+ krb5_err(context, 1, ret, "no input credential cache");
+ if (opt->save_flag)
+ ccout = cc;
+
+ if (opt->test_integer &&
+ (opt->extract_flag || opt->csr_string || opt->private_key_string))
+ krb5_errx(context, 1, "--test is exclusive of --extract, --csr, and "
+ "--private-key");
+
+ if (opt->extract_flag && (opt->csr_string || opt->private_key_string))
+ krb5_errx(context, 1, "--extract is exclusive of --csr and "
+ "--private-key");
+
+ if (opt->test_integer || opt->extract_flag) {
+ krb5_data der_cert, pkcs8_key, chain;
+
+ der_cert.data = pkcs8_key.data = chain.data = NULL;
+ der_cert.length = pkcs8_key.length = chain.length = 0;
+ ret = krb5_cc_get_config(context, cc, NULL, "kx509cert", &der_cert);
+ if (ret == 0)
+ ret = krb5_cc_get_config(context, cc, NULL, "kx509key",
+ &pkcs8_key);
+ if (ret == 0)
+ ret = krb5_cc_get_config(context, cc, NULL, "kx509cert-chain",
+ &chain);
+ if (ret)
+ krb5_err(context, 1, ret, "no certificate in credential cache");
+ if (opt->test_integer)
+ validate(context, opt->test_integer, opt->out_string, &der_cert,
+ &pkcs8_key);
+ else
+ store(context, opt->out_string, &der_cert, &pkcs8_key, &chain);
+ krb5_data_free(&pkcs8_key);
+ krb5_data_free(&der_cert);
+ krb5_data_free(&chain);
+ } else {
+ /*
+ * XXX We should delete any cc configs that indicate that kx509 is
+ * disabled.
+ */
+ ret = krb5_kx509_ctx_init(context, &req);
+ if (ret == 0 && opt->realm_string)
+ ret = krb5_kx509_ctx_set_realm(context, req, opt->realm_string);
+ if (ret == 0 && opt->csr_string)
+ set_csr(context, req, opt->csr_string);
+ if (ret == 0 && opt->private_key_string)
+ ret = krb5_kx509_ctx_set_key(context, req,
+ opt->private_key_string);
+ if (ret)
+ krb5_err(context, 1, ret,
+ "could not set up kx509 request options");
+
+ ret = krb5_kx509_ext(context, req, cc, opt->out_string, ccout);
+ if (ret)
+ krb5_err(context, 1, ret,
+ "could not acquire certificate with kx509");
+ krb5_kx509_ctx_free(context, &req);
+ }
+
+ krb5_cc_close(context, cc);
+
+ return 0;
+}