aboutsummaryrefslogtreecommitdiff
path: root/kuser
diff options
context:
space:
mode:
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;
+}