aboutsummaryrefslogtreecommitdiff
path: root/kuser
diff options
context:
space:
mode:
authorStanislav Sedov <stas@FreeBSD.org>2011-09-29 05:23:57 +0000
committerStanislav Sedov <stas@FreeBSD.org>2011-09-29 05:23:57 +0000
commit31f1e9c17ffae440059e8cc532fa26b92d534f7b (patch)
treecf5b65423910d126fddaaf04b885d0de3507d692 /kuser
parentc19800e8cd5640693f36f2040db4ab5e8d738146 (diff)
Notes
Diffstat (limited to 'kuser')
-rw-r--r--kuser/Makefile.am64
-rw-r--r--kuser/Makefile.in1002
-rw-r--r--kuser/copy_cred_cache.197
-rw-r--r--kuser/copy_cred_cache.c215
-rw-r--r--kuser/generate-requests.c161
-rw-r--r--kuser/kauth_options.c40
-rw-r--r--kuser/kdecode_ticket.c162
-rw-r--r--kuser/kdestroy.171
-rw-r--r--kuser/kdestroy.c150
-rw-r--r--kuser/kdigest-commands.in280
-rw-r--r--kuser/kdigest.c551
-rw-r--r--kuser/kgetcred.191
-rw-r--r--kuser/kgetcred.c228
-rw-r--r--kuser/kimpersonate.1152
-rw-r--r--kuser/kimpersonate.c330
-rw-r--r--kuser/kinit.1291
-rw-r--r--kuser/kinit.c852
-rw-r--r--kuser/kinit_options.c40
-rw-r--r--kuser/klist.1154
-rw-r--r--kuser/klist.c639
-rw-r--r--kuser/kuser_locl.h87
-rw-r--r--kuser/kverify.c128
22 files changed, 5785 insertions, 0 deletions
diff --git a/kuser/Makefile.am b/kuser/Makefile.am
new file mode 100644
index 0000000000000..619d8f8562dd5
--- /dev/null
+++ b/kuser/Makefile.am
@@ -0,0 +1,64 @@
+# $Id: Makefile.am 22285 2007-12-13 20:40:57Z lha $
+
+include $(top_srcdir)/Makefile.am.common
+
+AM_CPPFLAGS += $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
+
+man_MANS = \
+ kinit.1 \
+ klist.1 \
+ kdestroy.1 \
+ kgetcred.1 \
+ kimpersonate.1
+
+SLC = $(top_builddir)/lib/sl/slc
+
+bin_PROGRAMS = kinit klist kdestroy kgetcred
+libexec_PROGRAMS = kdigest kimpersonate
+
+noinst_PROGRAMS = kverify kdecode_ticket generate-requests copy_cred_cache
+
+kinit_LDADD = \
+ $(LIB_kafs) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(LIB_hcrypto) \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
+
+kdestroy_LDADD = $(kinit_LDADD)
+
+klist_LDADD = $(kinit_LDADD)
+
+kimpersonate_LDADD = $(kinit_LDADD)
+
+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)
+
+$(kdigest_OBJECTS): kdigest-commands.h
+
+CLEANFILES = kdigest-commands.h kdigest-commands.c
+
+kdigest-commands.c kdigest-commands.h: kdigest-commands.in
+ $(SLC) $(srcdir)/kdigest-commands.in
+
+LDADD = \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_hcrypto) \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
+
+# make sure install-exec-hook doesn't have any commands in Makefile.am.common
+install-exec-hook:
+ (cd $(DESTDIR)$(bindir) && rm -f kauth && $(LN_S) kinit kauth)
+
+EXTRA_DIST = $(man_MANS) kuser_locl.h kdigest-commands.in copy_cred_cache.1
+
diff --git a/kuser/Makefile.in b/kuser/Makefile.in
new file mode 100644
index 0000000000000..8616bf3869ef4
--- /dev/null
+++ b/kuser/Makefile.in
@@ -0,0 +1,1002 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 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: Makefile.am 22285 2007-12-13 20:40:57Z lha $
+
+# $Id: Makefile.am.common 10998 2002-05-19 18:35:37Z joda $
+
+# $Id: Makefile.am.common 22488 2008-01-21 11:47:22Z lha $
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@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@
+DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
+ $(top_srcdir)/Makefile.am.common \
+ $(top_srcdir)/cf/Makefile.am.common
+bin_PROGRAMS = kinit$(EXEEXT) klist$(EXEEXT) kdestroy$(EXEEXT) \
+ kgetcred$(EXEEXT)
+libexec_PROGRAMS = kdigest$(EXEEXT) kimpersonate$(EXEEXT)
+noinst_PROGRAMS = kverify$(EXEEXT) kdecode_ticket$(EXEEXT) \
+ generate-requests$(EXEEXT) copy_cred_cache$(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/autobuild.m4 \
+ $(top_srcdir)/cf/broken-getaddrinfo.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/check-x.m4 \
+ $(top_srcdir)/cf/check-xau.m4 $(top_srcdir)/cf/crypto.m4 \
+ $(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/destdirs.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-readline.m4 \
+ $(top_srcdir)/cf/krb-struct-spwd.m4 \
+ $(top_srcdir)/cf/krb-struct-winsize.m4 \
+ $(top_srcdir)/cf/largefile.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/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.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(install_sh) -d
+CONFIG_HEADER = $(top_builddir)/include/config.h
+CONFIG_CLEAN_FILES =
+am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(libexecdir)" \
+ "$(DESTDIR)$(man1dir)"
+binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+libexecPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
+PROGRAMS = $(bin_PROGRAMS) $(libexec_PROGRAMS) $(noinst_PROGRAMS)
+copy_cred_cache_SOURCES = copy_cred_cache.c
+copy_cred_cache_OBJECTS = copy_cred_cache.$(OBJEXT)
+copy_cred_cache_LDADD = $(LDADD)
+am__DEPENDENCIES_1 =
+copy_cred_cache_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+ $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
+ $(am__DEPENDENCIES_1)
+generate_requests_SOURCES = generate-requests.c
+generate_requests_OBJECTS = generate-requests.$(OBJEXT)
+generate_requests_LDADD = $(LDADD)
+generate_requests_DEPENDENCIES = $(top_builddir)/lib/krb5/libkrb5.la \
+ $(am__DEPENDENCIES_1) $(top_builddir)/lib/asn1/libasn1.la \
+ $(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)
+am__DEPENDENCIES_2 = $(top_builddir)/lib/kafs/libkafs.la \
+ $(am__DEPENDENCIES_1)
+am__DEPENDENCIES_3 = $(am__DEPENDENCIES_2) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/ntlm/libheimntlm.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1)
+kdestroy_DEPENDENCIES = $(am__DEPENDENCIES_3)
+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_3)
+kinit_SOURCES = kinit.c
+kinit_OBJECTS = kinit.$(OBJEXT)
+kinit_DEPENDENCIES = $(am__DEPENDENCIES_2) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/ntlm/libheimntlm.la $(am__DEPENDENCIES_1) \
+ $(top_builddir)/lib/asn1/libasn1.la $(am__DEPENDENCIES_1)
+klist_SOURCES = klist.c
+klist_OBJECTS = klist.$(OBJEXT)
+klist_DEPENDENCIES = $(am__DEPENDENCIES_3)
+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)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@
+depcomp =
+am__depfiles_maybe =
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = copy_cred_cache.c generate-requests.c kdecode_ticket.c \
+ kdestroy.c $(dist_kdigest_SOURCES) $(nodist_kdigest_SOURCES) \
+ kgetcred.c kimpersonate.c kinit.c klist.c kverify.c
+DIST_SOURCES = copy_cred_cache.c generate-requests.c kdecode_ticket.c \
+ kdestroy.c $(dist_kdigest_SOURCES) kgetcred.c kimpersonate.c \
+ kinit.c klist.c kverify.c
+man1dir = $(mandir)/man1
+MANS = $(man_MANS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+CFLAGS = @CFLAGS@
+COMPILE_ET = @COMPILE_ET@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DBLIB = @DBLIB@
+DEFS = @DEFS@
+DIR_com_err = @DIR_com_err@
+DIR_hcrypto = @DIR_hcrypto@
+DIR_hdbdir = @DIR_hdbdir@
+DIR_roken = @DIR_roken@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+GREP = @GREP@
+GROFF = @GROFF@
+INCLUDES_roken = @INCLUDES_roken@
+INCLUDE_hcrypto = @INCLUDE_hcrypto@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+INCLUDE_krb4 = @INCLUDE_krb4@
+INCLUDE_openldap = @INCLUDE_openldap@
+INCLUDE_readline = @INCLUDE_readline@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+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_NDBM = @LIB_NDBM@
+LIB_XauFileName = @LIB_XauFileName@
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_XauWriteAuth = @LIB_XauWriteAuth@
+LIB_bswap16 = @LIB_bswap16@
+LIB_bswap32 = @LIB_bswap32@
+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_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_door_create = @LIB_door_create@
+LIB_el_init = @LIB_el_init@
+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_hesiod = @LIB_hesiod@
+LIB_hstrerror = @LIB_hstrerror@
+LIB_kdb = @LIB_kdb@
+LIB_krb4 = @LIB_krb4@
+LIB_loadquery = @LIB_loadquery@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_openldap = @LIB_openldap@
+LIB_openpty = @LIB_openpty@
+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_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
+PACKAGE_NAME = @PACKAGE_NAME@
+PACKAGE_STRING = @PACKAGE_STRING@
+PACKAGE_TARNAME = @PACKAGE_TARNAME@
+PACKAGE_VERSION = @PACKAGE_VERSION@
+PATH_SEPARATOR = @PATH_SEPARATOR@
+PTHREADS_CFLAGS = @PTHREADS_CFLAGS@
+PTHREADS_LIBS = @PTHREADS_LIBS@
+RANLIB = @RANLIB@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+VERSION = @VERSION@
+VERSIONING = @VERSIONING@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+XMKMF = @XMKMF@
+X_CFLAGS = @X_CFLAGS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_LIBS = @X_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+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_CC = @ac_ct_CC@
+ac_ct_CXX = @ac_ct_CXX@
+ac_ct_F77 = @ac_ct_F77@
+am__leading_dot = @am__leading_dot@
+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@
+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@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+SUFFIXES = .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8
+AM_CPPFLAGS = -I$(top_builddir)/include $(INCLUDES_roken) \
+ $(INCLUDE_hcrypto) -I$(srcdir)/../lib/krb5
+@do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME
+AM_CFLAGS = $(WFLAGS)
+CP = cp
+buildinclude = $(top_builddir)/include
+LIB_getattr = @LIB_getattr@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_setpcred = @LIB_setpcred@
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+NROFF_MAN = groff -mandoc -Tascii
+LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_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
+@KRB5_TRUE@LIB_tsasl = $(top_builddir)/lib/tsasl/libtsasl.la
+@DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la
+man_MANS = \
+ kinit.1 \
+ klist.1 \
+ kdestroy.1 \
+ kgetcred.1 \
+ kimpersonate.1
+
+SLC = $(top_builddir)/lib/sl/slc
+kinit_LDADD = \
+ $(LIB_kafs) \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/ntlm/libheimntlm.la \
+ $(LIB_hcrypto) \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
+
+kdestroy_LDADD = $(kinit_LDADD)
+klist_LDADD = $(kinit_LDADD)
+kimpersonate_LDADD = $(kinit_LDADD)
+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
+LDADD = \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(LIB_hcrypto) \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken)
+
+EXTRA_DIST = $(man_MANS) kuser_locl.h kdigest-commands.in copy_cred_cache.1
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .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 \
+ && exit 0; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps kuser/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --foreign --ignore-deps kuser/Makefile
+.PRECIOUS: 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__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(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
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
+ rm -f "$(DESTDIR)$(bindir)/$$f"; \
+ done
+
+clean-binPROGRAMS:
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ test -z "$(libexecdir)" || $(MKDIR_P) "$(DESTDIR)$(libexecdir)"
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ if test -f $$p \
+ || test -f $$p1 \
+ ; then \
+ f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(libexecdir)/$$f'"; \
+ $(INSTALL_PROGRAM_ENV) $(LIBTOOL) --mode=install $(libexecPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(libexecdir)/$$f" || exit 1; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
+ echo " rm -f '$(DESTDIR)$(libexecdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(libexecdir)/$$f"; \
+ done
+
+clean-libexecPROGRAMS:
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+
+clean-noinstPROGRAMS:
+ @list='$(noinst_PROGRAMS)'; for p in $$list; do \
+ f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
+ echo " rm -f $$p $$f"; \
+ rm -f $$p $$f ; \
+ done
+copy_cred_cache$(EXEEXT): $(copy_cred_cache_OBJECTS) $(copy_cred_cache_DEPENDENCIES)
+ @rm -f copy_cred_cache$(EXEEXT)
+ $(LINK) $(copy_cred_cache_OBJECTS) $(copy_cred_cache_LDADD) $(LIBS)
+generate-requests$(EXEEXT): $(generate_requests_OBJECTS) $(generate_requests_DEPENDENCIES)
+ @rm -f generate-requests$(EXEEXT)
+ $(LINK) $(generate_requests_OBJECTS) $(generate_requests_LDADD) $(LIBS)
+kdecode_ticket$(EXEEXT): $(kdecode_ticket_OBJECTS) $(kdecode_ticket_DEPENDENCIES)
+ @rm -f kdecode_ticket$(EXEEXT)
+ $(LINK) $(kdecode_ticket_OBJECTS) $(kdecode_ticket_LDADD) $(LIBS)
+kdestroy$(EXEEXT): $(kdestroy_OBJECTS) $(kdestroy_DEPENDENCIES)
+ @rm -f kdestroy$(EXEEXT)
+ $(LINK) $(kdestroy_OBJECTS) $(kdestroy_LDADD) $(LIBS)
+kdigest$(EXEEXT): $(kdigest_OBJECTS) $(kdigest_DEPENDENCIES)
+ @rm -f kdigest$(EXEEXT)
+ $(LINK) $(kdigest_OBJECTS) $(kdigest_LDADD) $(LIBS)
+kgetcred$(EXEEXT): $(kgetcred_OBJECTS) $(kgetcred_DEPENDENCIES)
+ @rm -f kgetcred$(EXEEXT)
+ $(LINK) $(kgetcred_OBJECTS) $(kgetcred_LDADD) $(LIBS)
+kimpersonate$(EXEEXT): $(kimpersonate_OBJECTS) $(kimpersonate_DEPENDENCIES)
+ @rm -f kimpersonate$(EXEEXT)
+ $(LINK) $(kimpersonate_OBJECTS) $(kimpersonate_LDADD) $(LIBS)
+kinit$(EXEEXT): $(kinit_OBJECTS) $(kinit_DEPENDENCIES)
+ @rm -f kinit$(EXEEXT)
+ $(LINK) $(kinit_OBJECTS) $(kinit_LDADD) $(LIBS)
+klist$(EXEEXT): $(klist_OBJECTS) $(klist_DEPENDENCIES)
+ @rm -f klist$(EXEEXT)
+ $(LINK) $(klist_OBJECTS) $(klist_LDADD) $(LIBS)
+kverify$(EXEEXT): $(kverify_OBJECTS) $(kverify_DEPENDENCIES)
+ @rm -f kverify$(EXEEXT)
+ $(LINK) $(kverify_OBJECTS) $(kverify_LDADD) $(LIBS)
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+.c.o:
+ $(COMPILE) -c $<
+
+.c.obj:
+ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man1: $(man1_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+uninstall-man1:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man1_MANS) $(dist_man1_MANS) $(nodist_man1_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.1*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 1*) ;; \
+ *) ext='1' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man1dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man1dir)/$$inst"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+distclean-tags:
+ -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
+
+distdir: $(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 $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$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)"; 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:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_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 Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: 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-exec-am: install-binPROGRAMS install-libexecPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man: install-man1
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -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
+
+.MAKE: install-am install-data-am install-exec-am install-strip \
+ uninstall-am
+
+.PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \
+ clean clean-binPROGRAMS clean-generic clean-libexecPROGRAMS \
+ clean-libtool clean-noinstPROGRAMS ctags 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-html \
+ install-html-am install-info install-info-am \
+ install-libexecPROGRAMS install-man install-man1 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 uninstall uninstall-am uninstall-binPROGRAMS \
+ uninstall-hook uninstall-libexecPROGRAMS uninstall-man \
+ uninstall-man1
+
+
+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-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(nobase_include_HEADERS)
+ @foo='$(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \
+ 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; \
+ 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
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+#NROFF_MAN = nroff -man
+.1.cat1:
+ $(NROFF_MAN) $< > $@
+.3.cat3:
+ $(NROFF_MAN) $< > $@
+.5.cat5:
+ $(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-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-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) $(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) $(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="$${tobjdir}/libtool --mode execute valgrind --leak-check=full --trace-children=yes --quiet -q --num-callers=30 --suppressions=$${tsrcdir}/cf/valgrind-suppressions" 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
+
+$(kdigest_OBJECTS): kdigest-commands.h
+
+kdigest-commands.c kdigest-commands.h: kdigest-commands.in
+ $(SLC) $(srcdir)/kdigest-commands.in
+
+# make sure install-exec-hook doesn't have any commands in Makefile.am.common
+install-exec-hook:
+ (cd $(DESTDIR)$(bindir) && rm -f kauth && $(LN_S) kinit kauth)
+# 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/copy_cred_cache.1 b/kuser/copy_cred_cache.1
new file mode 100644
index 0000000000000..b589735b78882
--- /dev/null
+++ b/kuser/copy_cred_cache.1
@@ -0,0 +1,97 @@
+.\" Copyright (c) 2004 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: copy_cred_cache.1 13783 2004-04-25 16:03:45Z joda $
+.\"
+.Dd April 24, 2004
+.Dt COPY_CRED_CACHE 1
+.Os HEIMDAL
+.Sh NAME
+.Nm copy_cred_cache
+.Nd
+copy credentials from one cache to another
+.Sh SYNOPSIS
+.Nm
+.Op Fl -krbtgt-only
+.Op Fl -service= Ns Ar principal
+.Op Fl -enctype= Ns Ar enctype
+.Op Fl -flags= Ns Ar ticketflags
+.Op Fl -valid-for= Ns Ar time
+.Op Fl -fcache-version= Ns Ar integer
+.Op Aq Ar from-cache
+.Aq Ar to-cache
+.Sh DESCRIPTION
+.Nm
+copies credentials from
+.Aq Ar from-cache
+(or the default cache) to
+.Aq Ar to-cache .
+.Pp
+Supported options:
+.Bl -tag -width Ds
+.It Fl -krbtgt-only
+Copies only krbtgt credentials for the client's realm. This is
+equivalent to
+.Fl -service= Ns Li krbtgt/ Ns Ao Ar CLIENTREALM Ac Ns Li @ Ns Ao Ar CLIENTREALM Ac .
+.It Fl -service= Ns Ar principal
+Copies only credentials matching this service principal.
+.It Fl -enctype= Ns Ar enctype
+Copies only credentials a matching enctype.
+.It Fl -flags= Ns Ar ticketflags
+Copies only credentials with these ticket flags set.
+.It Fl -valid-for= Ns Ar time
+Copies only credentials that are valid for at least this long. This
+does not take renewable creds into account.
+.It Fl -fcache-version= Ns Ar integer
+The created cache, If a standard
+.Li FILE
+cache is created, it will have this file format version.
+.El
+.\".Sh ENVIRONMENT
+.\".Sh FILES
+.Sh EXAMPLES
+To copy only credentials that are valid for at least one day and with
+the
+.Li initial
+flag set, try something like:
+.Bd -literal -offset indent
+$ copy_cred_cache --valid-for=1d --flags=initial FILE:/some/cache
+.Ed
+.Sh DIAGNOSTICS
+The
+.Nm
+utility exits 0 on success, and \*[Gt]0 if an error occurs, or of no
+credentials where actually copied.
+.\".Sh SEE ALSO
+.\".Sh STANDARDS
+.\".Sh HISTORY
+.\".Sh AUTHORS
+.\".Sh BUGS
diff --git a/kuser/copy_cred_cache.c b/kuser/copy_cred_cache.c
new file mode 100644
index 0000000000000..8faf82d41ff41
--- /dev/null
+++ b/kuser/copy_cred_cache.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2004 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.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+RCSID("$Id: copy_cred_cache.c 15542 2005-07-01 07:20:54Z lha $");
+#endif
+
+#include <stdlib.h>
+#include <krb5.h>
+#include <roken.h>
+#include <getarg.h>
+#include <parse_units.h>
+#include <parse_time.h>
+
+static int krbtgt_only_flag;
+static char *service_string;
+static char *enctype_string;
+static char *flags_string;
+static char *valid_string;
+static int fcache_version;
+static int help_flag;
+static int version_flag;
+
+static struct getargs args[] = {
+ { "krbtgt-only", 0, arg_flag, &krbtgt_only_flag,
+ "only copy local krbtgt" },
+ { "service", 0, arg_string, &service_string,
+ "limit to this service", "principal" },
+ { "enctype", 0, arg_string, &enctype_string,
+ "limit to this enctype", "enctype" },
+ { "flags", 0, arg_string, &flags_string,
+ "limit to these flags", "ticketflags" },
+ { "valid-for", 0, arg_string, &valid_string,
+ "limit to creds valid for at least this long", "time" },
+ { "fcache-version", 0, arg_integer, &fcache_version,
+ "file cache version to create" },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 'h', arg_flag, &help_flag }
+};
+
+static void
+usage(int ret)
+{
+ arg_printusage(args,
+ sizeof(args) / sizeof(*args),
+ NULL,
+ "[from-cache] to-cache");
+ exit(ret);
+}
+
+static int32_t
+bitswap32(int32_t b)
+{
+ int32_t r = 0;
+ int i;
+ for (i = 0; i < 32; i++) {
+ r = r << 1 | (b & 1);
+ b = b >> 1;
+ }
+ return r;
+}
+
+static void
+parse_ticket_flags(krb5_context context,
+ const char *string, krb5_ticket_flags *ret_flags)
+{
+ TicketFlags ff;
+ int flags = parse_flags(string, asn1_TicketFlags_units(), 0);
+ if (flags == -1) /* XXX */
+ krb5_errx(context, 1, "bad flags specified: \"%s\"", string);
+
+ memset(&ff, 0, sizeof(ff));
+ ff.proxy = 1;
+ if (parse_flags("proxy", asn1_TicketFlags_units(), 0) == TicketFlags2int(ff))
+ ret_flags->i = flags;
+ else
+ ret_flags->i = bitswap32(flags);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ int optidx = 0;
+ const char *from_name, *to_name;
+ krb5_ccache from_ccache, to_ccache;
+ krb5_flags whichfields = 0;
+ krb5_creds mcreds;
+ unsigned int matched;
+
+ setprogname(argv[0]);
+
+ memset(&mcreds, 0, sizeof(mcreds));
+
+ if (getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage(0);
+
+ if (version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc < 1 || argc > 2)
+ usage(1);
+
+ if (krb5_init_context(&context))
+ errx(1, "krb5_init_context failed");
+
+ if (service_string) {
+ ret = krb5_parse_name(context, service_string, &mcreds.server);
+ if (ret)
+ krb5_err(context, 1, ret, "%s", service_string);
+ }
+ if (enctype_string) {
+ krb5_enctype enctype;
+ ret = krb5_string_to_enctype(context, enctype_string, &enctype);
+ if (ret)
+ krb5_err(context, 1, ret, "%s", enctype_string);
+ whichfields |= KRB5_TC_MATCH_KEYTYPE;
+ mcreds.session.keytype = enctype;
+ }
+ if (flags_string) {
+ parse_ticket_flags(context, flags_string, &mcreds.flags);
+ whichfields |= KRB5_TC_MATCH_FLAGS;
+ }
+ if (valid_string) {
+ time_t t = parse_time(valid_string, "s");
+ if(t < 0)
+ errx(1, "unknown time \"%s\"", valid_string);
+ mcreds.times.endtime = time(NULL) + t;
+ whichfields |= KRB5_TC_MATCH_TIMES;
+ }
+ if (fcache_version)
+ krb5_set_fcache_version(context, fcache_version);
+
+ if (argc == 1) {
+ from_name = krb5_cc_default_name(context);
+ to_name = argv[0];
+ } else {
+ from_name = argv[0];
+ to_name = argv[1];
+ }
+
+ ret = krb5_cc_resolve(context, from_name, &from_ccache);
+ if (ret)
+ krb5_err(context, 1, ret, "%s", from_name);
+
+ if (krbtgt_only_flag) {
+ krb5_principal client;
+ ret = krb5_cc_get_principal(context, from_ccache, &client);
+ if (ret)
+ krb5_err(context, 1, ret, "getting default principal");
+ ret = krb5_make_principal(context, &mcreds.server,
+ krb5_principal_get_realm(context, client),
+ KRB5_TGS_NAME,
+ krb5_principal_get_realm(context, client),
+ NULL);
+ if (ret)
+ krb5_err(context, 1, ret, "constructing krbtgt principal");
+ krb5_free_principal(context, client);
+ }
+ ret = krb5_cc_resolve(context, to_name, &to_ccache);
+ if (ret)
+ krb5_err(context, 1, ret, "%s", to_name);
+
+ ret = krb5_cc_copy_cache_match(context, from_ccache, to_ccache,
+ whichfields, &mcreds, &matched);
+ if (ret)
+ krb5_err(context, 1, ret, "copying cred cache");
+
+ krb5_cc_close(context, from_ccache);
+ if(matched == 0)
+ krb5_cc_destroy(context, to_ccache);
+ else
+ krb5_cc_close(context, to_ccache);
+ krb5_free_context(context);
+ return matched == 0;
+}
diff --git a/kuser/generate-requests.c b/kuser/generate-requests.c
new file mode 100644
index 0000000000000..95d8dc968bbfb
--- /dev/null
+++ b/kuser/generate-requests.c
@@ -0,0 +1,161 @@
+/*
+ * Copyright (c) 2000 - 2004 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"
+
+RCSID("$Id: generate-requests.c 19233 2006-12-06 08:04:05Z lha $");
+
+static krb5_error_code
+null_key_proc (krb5_context context,
+ krb5_enctype type,
+ krb5_salt salt,
+ krb5_const_pointer keyseed,
+ krb5_keyblock **key)
+{
+ return ENOTTY;
+}
+
+static unsigned
+read_words (const char *filename, char ***ret_w)
+{
+ unsigned n, alloc;
+ FILE *f;
+ char buf[256];
+ char **w = NULL;
+
+ f = fopen (filename, "r");
+ if (f == NULL)
+ err (1, "cannot open %s", filename);
+ alloc = n = 0;
+ while (fgets (buf, sizeof(buf), f) != NULL) {
+ buf[strcspn(buf, "\r\n")] = '\0';
+ if (n >= alloc) {
+ alloc += 16;
+ w = erealloc (w, alloc * sizeof(char **));
+ }
+ w[n++] = estrdup (buf);
+ }
+ *ret_w = w;
+ if (n == 0)
+ errx(1, "%s is an empty file, no words to try", filename);
+ return n;
+}
+
+static void
+generate_requests (const char *filename, unsigned nreq)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_creds cred;
+ int i;
+ char **words;
+ unsigned nwords;
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx (1, "krb5_init_context failed: %d", ret);
+
+ nwords = read_words (filename, &words);
+
+ for (i = 0; i < nreq; ++i) {
+ char *name = words[rand() % nwords];
+ krb5_realm *client_realm;
+
+ memset(&cred, 0, sizeof(cred));
+
+ ret = krb5_parse_name (context, name, &cred.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", name);
+ client_realm = krb5_princ_realm (context, cred.client);
+
+ ret = krb5_make_principal(context, &cred.server, *client_realm,
+ KRB5_TGS_NAME, *client_realm, NULL);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_make_principal");
+
+ ret = krb5_get_in_cred (context, 0, NULL, NULL, NULL, NULL,
+ null_key_proc, NULL, NULL, NULL,
+ &cred, NULL);
+ krb5_free_cred_contents (context, &cred);
+ }
+}
+
+static int version_flag = 0;
+static int help_flag = 0;
+
+static struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "file number");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ int optidx = 0;
+ int nreq;
+ char *end;
+
+ setprogname(argv[0]);
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc != 2)
+ usage (1);
+ srand (0);
+ nreq = strtol (argv[1], &end, 0);
+ if (argv[1] == end || *end != '\0')
+ usage (1);
+ generate_requests (argv[0], nreq);
+ return 0;
+}
diff --git a/kuser/kauth_options.c b/kuser/kauth_options.c
new file mode 100644
index 0000000000000..c432d32ac14a9
--- /dev/null
+++ b/kuser/kauth_options.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1998 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"
+RCSID("$Id: kauth_options.c,v 1.2 1999/12/02 17:05:00 joda Exp $");
+
+#ifdef KRB4
+int do_afslog = 1;
+int get_v4_tgt = 1;
+#endif
diff --git a/kuser/kdecode_ticket.c b/kuser/kdecode_ticket.c
new file mode 100644
index 0000000000000..968478d347791
--- /dev/null
+++ b/kuser/kdecode_ticket.c
@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 1997 - 2004 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"
+
+RCSID("$Id: kdecode_ticket.c 15541 2005-07-01 07:14:58Z lha $");
+
+static char *etype_str;
+static int version_flag;
+static int help_flag;
+
+static void
+print_and_decode_tkt (krb5_context context,
+ krb5_data *ticket,
+ krb5_principal server,
+ krb5_enctype enctype)
+{
+ krb5_error_code ret;
+ krb5_crypto crypto;
+ krb5_data dec_data;
+ size_t len;
+ EncTicketPart decr_part;
+ krb5_keyblock key;
+ Ticket tkt;
+
+ ret = decode_Ticket (ticket->data, ticket->length, &tkt, &len);
+ if (ret)
+ krb5_err (context, 1, ret, "decode_Ticket");
+
+ ret = krb5_string_to_key (context, enctype, "foo", server, &key);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_string_to_key");
+
+ ret = krb5_crypto_init(context, &key, 0, &crypto);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_crypto_init");
+
+ ret = krb5_decrypt_EncryptedData (context, crypto, KRB5_KU_TICKET,
+ &tkt.enc_part, &dec_data);
+ krb5_crypto_destroy (context, crypto);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_decrypt_EncryptedData");
+ ret = krb5_decode_EncTicketPart (context, dec_data.data, dec_data.length,
+ &decr_part, &len);
+ krb5_data_free (&dec_data);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_decode_EncTicketPart");
+}
+
+struct getargs args[] = {
+ { "enctype", 'e', arg_string, &etype_str,
+ "encryption type to use", "enctype"},
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "service");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache cache;
+ krb5_creds in, *out;
+ int optidx = 0;
+
+ setprogname (argv[0]);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx(1, "krb5_init_context failed: %d", ret);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc != 1)
+ usage (1);
+
+ ret = krb5_cc_default(context, &cache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_default");
+
+ memset(&in, 0, sizeof(in));
+
+ if (etype_str) {
+ krb5_enctype enctype;
+
+ ret = krb5_string_to_enctype(context, etype_str, &enctype);
+ if (ret)
+ krb5_errx (context, 1, "unrecognized enctype: %s", etype_str);
+ in.session.keytype = enctype;
+ }
+
+ ret = krb5_cc_get_principal(context, cache, &in.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_get_principal");
+
+ ret = krb5_parse_name(context, argv[0], &in.server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]);
+
+ in.times.endtime = 0;
+ ret = krb5_get_credentials(context, 0, cache, &in, &out);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_credentials");
+
+ print_and_decode_tkt (context, &out->ticket, out->server,
+ out->session.keytype);
+
+ krb5_free_cred_contents(context, out);
+ return 0;
+}
diff --git a/kuser/kdestroy.1 b/kuser/kdestroy.1
new file mode 100644
index 0000000000000..5e187019ba454
--- /dev/null
+++ b/kuser/kdestroy.1
@@ -0,0 +1,71 @@
+.\" Copyright (c) 1997, 1999, 2001, 2004, 2006 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: kdestroy.1 22071 2007-11-14 20:04:50Z lha $
+.\"
+.Dd April 27, 2006
+.Dt KDESTROY 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kdestroy
+.Nd remove one credental or destroy the current ticket file
+.Sh SYNOPSIS
+.Nm
+.Bk -words
+.Op Fl c Ar cachefile
+.Op Fl -credential= Ns Ar principal
+.Op Fl -cache= Ns Ar cachefile
+.Op Fl -no-unlog
+.Op Fl -no-delete-v4
+.Op Fl -version
+.Op Fl -help
+.Ek
+.Sh DESCRIPTION
+.Nm
+remove one or the current set of tickets.
+.Pp
+Supported options:
+.Bl -tag -width Ds
+.It Fl credential= Ns Ar principal
+remove
+.Fa principal
+from the credential cache if it exists.
+.It Fl c Ar cachefile
+.It Fl cache= Ns Ar cachefile
+The cache file to remove.
+.It Fl -no-unlog
+Do not remove AFS tokens.
+.It Fl -no-delete-v4
+Do not remove v4 tickets.
+.El
+.Sh SEE ALSO
+.Xr kinit 1 ,
+.Xr klist 1
diff --git a/kuser/kdestroy.c b/kuser/kdestroy.c
new file mode 100644
index 0000000000000..5358fcd67d92f
--- /dev/null
+++ b/kuser/kdestroy.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright (c) 1997 - 2000, 2003 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"
+RCSID("$Id: kdestroy.c 20458 2007-04-19 20:41:27Z lha $");
+
+static const char *cache;
+static const char *credential;
+static int help_flag;
+static int version_flag;
+static int unlog_flag = 1;
+static int dest_tkt_flag = 1;
+
+struct getargs args[] = {
+ { "credential", 0, arg_string, &credential,
+ "remove one credential", "principal" },
+ { "cache", 'c', arg_string, &cache, "cache to destroy", "cache" },
+ { "unlog", 0, arg_negative_flag, &unlog_flag,
+ "do not destroy tokens", NULL },
+ { "delete-v4", 0, arg_negative_flag, &dest_tkt_flag,
+ "do not destroy v4 tickets", NULL },
+ { "version", 0, arg_flag, &version_flag, NULL, NULL },
+ { "help", 'h', arg_flag, &help_flag, NULL, NULL}
+};
+
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage (int status)
+{
+ arg_printusage (args, num_args, NULL, "");
+ exit (status);
+}
+
+int
+main (int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache ccache;
+ int optidx = 0;
+ int exit_val = 0;
+
+ setprogname (argv[0]);
+
+ if(getarg(args, num_args, argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc != 0)
+ usage (1);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx (1, "krb5_init_context failed: %d", ret);
+
+ if(cache == NULL) {
+ cache = krb5_cc_default_name(context);
+ if (cache == NULL) {
+ warnx ("krb5_cc_default_name: %s", krb5_get_err_text(context, ret));
+ exit(1);
+ }
+ }
+
+ ret = krb5_cc_resolve(context,
+ cache,
+ &ccache);
+
+ if (ret == 0) {
+ if (credential) {
+ krb5_creds mcred;
+
+ krb5_cc_clear_mcred(&mcred);
+
+ ret = krb5_parse_name(context, credential, &mcred.server);
+ if (ret)
+ krb5_err(context, 1, ret,
+ "Can't parse principal %s", credential);
+
+ ret = krb5_cc_remove_cred(context, ccache, 0, &mcred);
+ if (ret)
+ krb5_err(context, 1, ret,
+ "Failed to remove principal %s", credential);
+
+ krb5_cc_close(context, ccache);
+ krb5_free_principal(context, mcred.server);
+ krb5_free_context(context);
+ return 0;
+ }
+
+ ret = krb5_cc_destroy (context, ccache);
+ if (ret) {
+ warnx ("krb5_cc_destroy: %s", krb5_get_err_text(context, ret));
+ exit_val = 1;
+ }
+ } else {
+ warnx ("krb5_cc_resolve(%s): %s", cache,
+ krb5_get_err_text(context, ret));
+ exit_val = 1;
+ }
+
+ krb5_free_context (context);
+
+ if (unlog_flag && k_hasafs ()) {
+ if (k_unlog ())
+ exit_val = 1;
+ }
+
+ return exit_val;
+}
diff --git a/kuser/kdigest-commands.in b/kuser/kdigest-commands.in
new file mode 100644
index 0000000000000..c980b188eddde
--- /dev/null
+++ b/kuser/kdigest-commands.in
@@ -0,0 +1,280 @@
+/*
+ * Copyright (c) 2006 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: kdigest-commands.in 22157 2007-12-04 20:03:29Z lha $ */
+
+command = {
+ name = "digest-probe"
+ option = {
+ long = "realm"
+ type = "string"
+ help = "Kerberos realm to communicate with"
+ }
+ help = "probe what mech is allowed/supported for this server"
+}
+command = {
+ name = "digest-server-init"
+ option = {
+ long = "type"
+ type = "string"
+ help = "digest type"
+ default = "sasl"
+ }
+ option = {
+ long = "kerberos-realm"
+ type = "string"
+ argument = "realm"
+ help = ""
+ }
+ option = {
+ long = "digest"
+ type = "string"
+ argument = "digest-type"
+ help = "digest type to use in the algorithm"
+ }
+ option = {
+ long = "cb-type"
+ type = "string"
+ argument = "type"
+ help = "type of channel bindings"
+ }
+ option = {
+ long = "cb-value"
+ type = "string"
+ argument = "value"
+ help = "value of channel bindings"
+ }
+ option = {
+ long = "hostname"
+ type = "string"
+ argument = "hostname"
+ help = "hostname of the server"
+ }
+ option = {
+ long = "realm"
+ type = "string"
+ help = "Kerberos realm to communicate with"
+ }
+ help = "Sets up a digest context and return initial parameters"
+}
+command = {
+ name = "digest-server-request"
+ option = {
+ long = "type"
+ type = "string"
+ help = "digest type"
+ default = "sasl"
+ }
+ option = {
+ long = "kerberos-realm"
+ type = "string"
+ argument = "realm"
+ help = ""
+ }
+ option = {
+ long = "username"
+ type = "string"
+ argument = "name"
+ help = "digest type"
+ }
+ option = {
+ long = "server-nonce"
+ type = "string"
+ argument = "nonce"
+ help = ""
+ }
+ option = {
+ long = "server-identifier"
+ type = "string"
+ argument = "nonce"
+ help = ""
+ }
+ option = {
+ long = "client-nonce"
+ type = "string"
+ argument = "nonce"
+ help = ""
+ }
+ option = {
+ long = "client-response"
+ type = "string"
+ argument = "response"
+ help = ""
+ }
+ option = {
+ long = "opaque"
+ type = "string"
+ argument = "string"
+ help = ""
+ }
+ option = {
+ long = "authentication-name"
+ type = "string"
+ argument = "name"
+ help = ""
+ }
+ option = {
+ long = "realm"
+ type = "string"
+ argument = "realm"
+ help = ""
+ }
+ option = {
+ long = "method"
+ type = "string"
+ argument = "method"
+ help = ""
+ }
+ option = {
+ long = "uri"
+ type = "string"
+ argument = "uri"
+ help = ""
+ }
+ option = {
+ long = "nounce-count"
+ type = "string"
+ argument = "count"
+ help = ""
+ }
+ option = {
+ long = "qop"
+ type = "string"
+ argument = "qop"
+ help = ""
+ }
+ option = {
+ long = "ccache"
+ type = "string"
+ argument = "ccache"
+ help = "Where the the credential cache is created when the KDC returns tickets"
+ }
+ help = "Completes digest negotiation and return final parameters"
+}
+command = {
+ name = "digest-client-request"
+ option = {
+ long = "type"
+ type = "string"
+ help = "digest type"
+ default = "sasl"
+ }
+ option = {
+ long = "username"
+ type = "string"
+ argument = "name"
+ help = "digest type"
+ }
+ option = {
+ long = "password"
+ type = "string"
+ argument = "password"
+ }
+ option = {
+ long = "server-nonce"
+ type = "string"
+ argument = "nonce"
+ help = ""
+ }
+ option = {
+ long = "server-identifier"
+ type = "string"
+ argument = "nonce"
+ help = ""
+ }
+ option = {
+ long = "client-nonce"
+ type = "string"
+ argument = "nonce"
+ help = ""
+ }
+ option = {
+ long = "opaque"
+ type = "string"
+ argument = "string"
+ help = ""
+ }
+ option = {
+ long = "realm"
+ type = "string"
+ argument = "realm"
+ help = ""
+ }
+ option = {
+ long = "method"
+ type = "string"
+ argument = "method"
+ help = ""
+ }
+ option = {
+ long = "uri"
+ type = "string"
+ argument = "uri"
+ help = ""
+ }
+ option = {
+ long = "nounce-count"
+ type = "string"
+ argument = "count"
+ help = ""
+ }
+ option = {
+ long = "qop"
+ type = "string"
+ argument = "qop"
+ help = ""
+ }
+ help = "Client part of a digest exchange"
+}
+command = {
+ name = "ntlm-server-init"
+ option = {
+ long = "version"
+ type = "integer"
+ help = "ntlm version"
+ default = "1"
+ }
+ option = {
+ long = "kerberos-realm"
+ type = "string"
+ help = "Kerberos realm to communicate with"
+ }
+ help = "Sets up a digest context and return initial parameters"
+}
+command = {
+ name = "help"
+ name = "?"
+ argument = "[command]"
+ min_args = "0"
+ max_args = "1"
+ help = "Help! I need somebody."
+}
diff --git a/kuser/kdigest.c b/kuser/kdigest.c
new file mode 100644
index 0000000000000..418aedb714419
--- /dev/null
+++ b/kuser/kdigest.c
@@ -0,0 +1,551 @@
+/*
+ * Copyright (c) 2006 - 2007 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"
+RCSID("$Id: kdigest.c 22158 2007-12-04 20:04:01Z lha $");
+#include <kdigest-commands.h>
+#include <hex.h>
+#include <base64.h>
+#include <heimntlm.h>
+#include "crypto-headers.h"
+
+static int version_flag = 0;
+static int help_flag = 0;
+static char *ccache_string;
+static krb5_ccache id;
+
+static struct getargs args[] = {
+ {"ccache", 0, arg_string, &ccache_string, "credential cache", NULL },
+ {"version", 0, arg_flag, &version_flag, "print version", NULL },
+ {"help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args, sizeof(args)/sizeof(*args),
+ NULL, "");
+ exit (ret);
+}
+
+static krb5_context context;
+
+int
+digest_probe(struct digest_probe_options *opt,
+ int argc, char ** argv)
+{
+ krb5_error_code ret;
+ krb5_realm realm;
+ unsigned flags;
+
+ realm = opt->realm_string;
+
+ if (realm == NULL)
+ errx(1, "realm missing");
+
+ ret = krb5_digest_probe(context, realm, id, &flags);
+ if (ret)
+ krb5_err(context, 1, ret, "digest_probe");
+
+ printf("flags: %u\n", flags);
+
+ return 0;
+}
+
+int
+digest_server_init(struct digest_server_init_options *opt,
+ int argc, char ** argv)
+{
+ krb5_error_code ret;
+ krb5_digest digest;
+
+ ret = krb5_digest_alloc(context, &digest);
+ if (ret)
+ krb5_err(context, 1, ret, "digest_alloc");
+
+ ret = krb5_digest_set_type(context, digest, opt->type_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_type");
+
+ if (opt->cb_type_string && opt->cb_value_string) {
+ ret = krb5_digest_set_server_cb(context, digest,
+ opt->cb_type_string,
+ opt->cb_value_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_server_cb");
+ }
+ ret = krb5_digest_init_request(context,
+ digest,
+ opt->kerberos_realm_string,
+ id);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_init_request");
+
+ printf("type=%s\n", opt->type_string);
+ printf("server-nonce=%s\n",
+ krb5_digest_get_server_nonce(context, digest));
+ {
+ const char *s = krb5_digest_get_identifier(context, digest);
+ if (s)
+ printf("identifier=%s\n", s);
+ }
+ printf("opaque=%s\n", krb5_digest_get_opaque(context, digest));
+
+ return 0;
+}
+
+int
+digest_server_request(struct digest_server_request_options *opt,
+ int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_digest digest;
+ const char *status, *rsp;
+ krb5_data session_key;
+
+ if (opt->server_nonce_string == NULL)
+ errx(1, "server nonce missing");
+ if (opt->type_string == NULL)
+ errx(1, "type missing");
+ if (opt->opaque_string == NULL)
+ errx(1, "opaque missing");
+ if (opt->client_response_string == NULL)
+ errx(1, "client response missing");
+
+ ret = krb5_digest_alloc(context, &digest);
+ if (ret)
+ krb5_err(context, 1, ret, "digest_alloc");
+
+ if (strcasecmp(opt->type_string, "CHAP") == 0) {
+ if (opt->server_identifier_string == NULL)
+ errx(1, "server identifier missing");
+
+ ret = krb5_digest_set_identifier(context, digest,
+ opt->server_identifier_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_type");
+ }
+
+ ret = krb5_digest_set_type(context, digest, opt->type_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_type");
+
+ ret = krb5_digest_set_username(context, digest, opt->username_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_username");
+
+ ret = krb5_digest_set_server_nonce(context, digest,
+ opt->server_nonce_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_server_nonce");
+
+ if(opt->client_nonce_string) {
+ ret = krb5_digest_set_client_nonce(context, digest,
+ opt->client_nonce_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_client_nonce");
+ }
+
+
+ ret = krb5_digest_set_opaque(context, digest, opt->opaque_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_opaque");
+
+ ret = krb5_digest_set_responseData(context, digest,
+ opt->client_response_string);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_set_responseData");
+
+ ret = krb5_digest_request(context, digest,
+ opt->kerberos_realm_string, id);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_request");
+
+ status = krb5_digest_rep_get_status(context, digest) ? "ok" : "failed";
+ rsp = krb5_digest_get_rsp(context, digest);
+
+ printf("status=%s\n", status);
+ if (rsp)
+ printf("rsp=%s\n", rsp);
+ printf("tickets=no\n");
+
+ ret = krb5_digest_get_session_key(context, digest, &session_key);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_digest_get_session_key");
+
+ if (session_key.length) {
+ char *key;
+ hex_encode(session_key.data, session_key.length, &key);
+ if (key == NULL)
+ krb5_errx(context, 1, "hex_encode");
+ krb5_data_free(&session_key);
+ printf("session-key=%s\n", key);
+ free(key);
+ }
+
+ return 0;
+}
+
+static void
+client_chap(const void *server_nonce, size_t snoncelen,
+ unsigned char server_identifier,
+ const char *password)
+{
+ MD5_CTX ctx;
+ unsigned char md[MD5_DIGEST_LENGTH];
+ char *h;
+
+ MD5_Init(&ctx);
+ MD5_Update(&ctx, &server_identifier, 1);
+ MD5_Update(&ctx, password, strlen(password));
+ MD5_Update(&ctx, server_nonce, snoncelen);
+ MD5_Final(md, &ctx);
+
+ hex_encode(md, 16, &h);
+
+ printf("responseData=%s\n", h);
+ free(h);
+}
+
+static const unsigned char ms_chap_v2_magic1[39] = {
+ 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76,
+ 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65,
+ 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67,
+ 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74
+};
+static const unsigned char ms_chap_v2_magic2[41] = {
+ 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B,
+ 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F,
+ 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E,
+ 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F,
+ 0x6E
+};
+static const unsigned char ms_rfc3079_magic1[27] = {
+ 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74,
+ 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d,
+ 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79
+};
+
+static void
+client_mschapv2(const void *server_nonce, size_t snoncelen,
+ const void *client_nonce, size_t cnoncelen,
+ const char *username,
+ const char *password)
+{
+ SHA_CTX ctx;
+ MD4_CTX hctx;
+ unsigned char md[SHA_DIGEST_LENGTH], challange[SHA_DIGEST_LENGTH];
+ unsigned char hmd[MD4_DIGEST_LENGTH];
+ struct ntlm_buf answer;
+ int i, len, ret;
+ char *h;
+
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, client_nonce, cnoncelen);
+ SHA1_Update(&ctx, server_nonce, snoncelen);
+ SHA1_Update(&ctx, username, strlen(username));
+ SHA1_Final(md, &ctx);
+
+ MD4_Init(&hctx);
+ len = strlen(password);
+ for (i = 0; i < len; i++) {
+ MD4_Update(&hctx, &password[i], 1);
+ MD4_Update(&hctx, &password[len], 1);
+ }
+ MD4_Final(hmd, &hctx);
+
+ /* ChallengeResponse */
+ ret = heim_ntlm_calculate_ntlm1(hmd, sizeof(hmd), md, &answer);
+ if (ret)
+ errx(1, "heim_ntlm_calculate_ntlm1");
+
+ hex_encode(answer.data, answer.length, &h);
+ printf("responseData=%s\n", h);
+ free(h);
+
+ /* PasswordHash */
+ MD4_Init(&hctx);
+ MD4_Update(&hctx, hmd, sizeof(hmd));
+ MD4_Final(hmd, &hctx);
+
+ /* GenerateAuthenticatorResponse */
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, hmd, sizeof(hmd));
+ SHA1_Update(&ctx, answer.data, answer.length);
+ SHA1_Update(&ctx, ms_chap_v2_magic1, sizeof(ms_chap_v2_magic1));
+ SHA1_Final(md, &ctx);
+
+ /* ChallengeHash */
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, client_nonce, cnoncelen);
+ SHA1_Update(&ctx, server_nonce, snoncelen);
+ SHA1_Update(&ctx, username, strlen(username));
+ SHA1_Final(challange, &ctx);
+
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, md, sizeof(md));
+ SHA1_Update(&ctx, challange, 8);
+ SHA1_Update(&ctx, ms_chap_v2_magic2, sizeof(ms_chap_v2_magic2));
+ SHA1_Final(md, &ctx);
+
+ hex_encode(md, sizeof(md), &h);
+ printf("AuthenticatorResponse=%s\n", h);
+ free(h);
+
+ /* get_master, rfc 3079 3.4 */
+ SHA1_Init(&ctx);
+ SHA1_Update(&ctx, hmd, sizeof(hmd));
+ SHA1_Update(&ctx, answer.data, answer.length);
+ SHA1_Update(&ctx, ms_rfc3079_magic1, sizeof(ms_rfc3079_magic1));
+ SHA1_Final(md, &ctx);
+
+ free(answer.data);
+
+ hex_encode(md, 16, &h);
+ printf("session-key=%s\n", h);
+ free(h);
+}
+
+
+int
+digest_client_request(struct digest_client_request_options *opt,
+ int argc, char **argv)
+{
+ char *server_nonce, *client_nonce = NULL, server_identifier;
+ ssize_t snoncelen, cnoncelen = 0;
+
+ if (opt->server_nonce_string == NULL)
+ errx(1, "server nonce missing");
+ if (opt->password_string == NULL)
+ errx(1, "password missing");
+
+ if (opt->opaque_string == NULL)
+ errx(1, "opaque missing");
+
+ snoncelen = strlen(opt->server_nonce_string);
+ server_nonce = malloc(snoncelen);
+ if (server_nonce == NULL)
+ errx(1, "server_nonce");
+
+ snoncelen = hex_decode(opt->server_nonce_string, server_nonce, snoncelen);
+ if (snoncelen <= 0)
+ errx(1, "server nonce wrong");
+
+ if (opt->client_nonce_string) {
+ cnoncelen = strlen(opt->client_nonce_string);
+ client_nonce = malloc(cnoncelen);
+ if (client_nonce == NULL)
+ errx(1, "client_nonce");
+
+ cnoncelen = hex_decode(opt->client_nonce_string,
+ client_nonce, cnoncelen);
+ if (cnoncelen <= 0)
+ errx(1, "client nonce wrong");
+ }
+
+ if (opt->server_identifier_string) {
+ int ret;
+
+ ret = hex_decode(opt->server_identifier_string, &server_identifier, 1);
+ if (ret != 1)
+ errx(1, "server identifier wrong length");
+ }
+
+ if (strcasecmp(opt->type_string, "CHAP") == 0) {
+ if (opt->server_identifier_string == NULL)
+ errx(1, "server identifier missing");
+
+ client_chap(server_nonce, snoncelen, server_identifier,
+ opt->password_string);
+
+ } else if (strcasecmp(opt->type_string, "MS-CHAP-V2") == 0) {
+ if (opt->client_nonce_string == NULL)
+ errx(1, "client nonce missing");
+ if (opt->username_string == NULL)
+ errx(1, "client nonce missing");
+
+ client_mschapv2(server_nonce, snoncelen,
+ client_nonce, cnoncelen,
+ opt->username_string,
+ opt->password_string);
+ }
+
+
+ return 0;
+}
+
+#include <heimntlm.h>
+
+int
+ntlm_server_init(struct ntlm_server_init_options *opt,
+ int argc, char ** argv)
+{
+ krb5_error_code ret;
+ krb5_ntlm ntlm;
+ struct ntlm_type2 type2;
+ krb5_data challange, opaque;
+ struct ntlm_buf data;
+ char *s;
+
+ memset(&type2, 0, sizeof(type2));
+
+ ret = krb5_ntlm_alloc(context, &ntlm);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_ntlm_alloc");
+
+ ret = krb5_ntlm_init_request(context,
+ ntlm,
+ opt->kerberos_realm_string,
+ id,
+ NTLM_NEG_UNICODE|NTLM_NEG_NTLM,
+ "NUTCRACKER",
+ "L");
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_ntlm_init_request");
+
+ /*
+ *
+ */
+
+ ret = krb5_ntlm_init_get_challange(context, ntlm, &challange);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_ntlm_init_get_challange");
+
+ if (challange.length != sizeof(type2.challange))
+ krb5_errx(context, 1, "ntlm challange have wrong length");
+ memcpy(type2.challange, challange.data, sizeof(type2.challange));
+ krb5_data_free(&challange);
+
+ ret = krb5_ntlm_init_get_flags(context, ntlm, &type2.flags);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_ntlm_init_get_flags");
+
+ krb5_ntlm_init_get_targetname(context, ntlm, &type2.targetname);
+ type2.targetinfo.data = "\x00\x00";
+ type2.targetinfo.length = 2;
+
+ ret = heim_ntlm_encode_type2(&type2, &data);
+ if (ret)
+ krb5_errx(context, 1, "heim_ntlm_encode_type2");
+
+ free(type2.targetname);
+
+ /*
+ *
+ */
+
+ base64_encode(data.data, data.length, &s);
+ free(data.data);
+ printf("type2=%s\n", s);
+ free(s);
+
+ /*
+ *
+ */
+
+ ret = krb5_ntlm_init_get_opaque(context, ntlm, &opaque);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_ntlm_init_get_opaque");
+
+ base64_encode(opaque.data, opaque.length, &s);
+ krb5_data_free(&opaque);
+ printf("opaque=%s\n", s);
+ free(s);
+
+ /*
+ *
+ */
+
+ krb5_ntlm_free(context, ntlm);
+
+ return 0;
+}
+
+
+/*
+ *
+ */
+
+int
+help(void *opt, int argc, char **argv)
+{
+ sl_slc_help(commands, argc, argv);
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ int optidx = 0;
+
+ setprogname(argv[0]);
+
+ ret = krb5_init_context (&context);
+ if (ret == KRB5_CONFIG_BADFORMAT)
+ errx (1, "krb5_init_context failed to parse configuration file");
+ else if (ret)
+ errx(1, "krb5_init_context failed: %d", ret);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc == 0) {
+ help(NULL, argc, argv);
+ return 1;
+ }
+
+ if (ccache_string) {
+ ret = krb5_cc_resolve(context, ccache_string, &id);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_resolve");
+ }
+
+ ret = sl_command (commands, argc, argv);
+ if (ret == -1) {
+ help(NULL, argc, argv);
+ return 1;
+ }
+ return ret;
+}
diff --git a/kuser/kgetcred.1 b/kuser/kgetcred.1
new file mode 100644
index 0000000000000..1949ff7e0bbb1
--- /dev/null
+++ b/kuser/kgetcred.1
@@ -0,0 +1,91 @@
+.\" Copyright (c) 1999, 2001 - 2002 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: kgetcred.1 14090 2004-08-05 18:49:47Z lha $
+.\"
+.Dd March 12, 2004
+.Dt KGETCRED 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kgetcred
+.Nd "get a ticket for a particular service"
+.Sh SYNOPSIS
+.Nm
+.Op Fl -canonicalize
+.Oo Fl c cache \*(Ba Xo
+.Fl -cache= Ns Ar cache
+.Xc
+.Oc
+.Oo Fl e Ar enctype \*(Ba Xo
+.Fl -enctype= Ns Ar enctype
+.Xc
+.Oc
+.Op Fl -no-transit-check
+.Op Fl -version
+.Op Fl -help
+.Ar service
+.Sh DESCRIPTION
+.Nm
+obtains a ticket for a service.
+Usually tickets 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.
+.Pp
+Supported options:
+.Bl -tag -width Ds
+.It Xo
+.Fl -canonicalize
+.Xc
+requests that the KDC canonicalize the principal.
+.It Xo
+.Fl c Ar cache ,
+.Fl -cache= Ns Ar cache
+.Xc
+the credential cache to use.
+.It Xo
+.Fl e Ar enctype ,
+.Fl -enctype= Ns Ar enctype
+.Xc
+encryption type to use.
+.It Xo
+.Fl -no-transit-check
+.Xc
+requests that the KDC doesn't do trasnit checking.
+.It Xo
+.Fl -version
+.Xc
+.It Xo
+.Fl -help
+.Xc
+.El
+.Sh SEE ALSO
+.Xr kinit 1 ,
+.Xr klist 1
diff --git a/kuser/kgetcred.c b/kuser/kgetcred.c
new file mode 100644
index 0000000000000..a842e002da54c
--- /dev/null
+++ b/kuser/kgetcred.c
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 1997 - 2007 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"
+
+RCSID("$Id: kgetcred.c 22276 2007-12-12 02:42:31Z lha $");
+
+static char *cache_str;
+static char *out_cache_str;
+static char *delegation_cred_str;
+static char *etype_str;
+static int transit_flag = 1;
+static int forwardable_flag;
+static char *impersonate_str;
+static char *nametype_str;
+static int version_flag;
+static int help_flag;
+
+struct getargs args[] = {
+ { "cache", 'c', arg_string, &cache_str,
+ "credential cache to use", "cache"},
+ { "out-cache", 0, arg_string, &out_cache_str,
+ "credential cache to store credential in", "cache"},
+ { "delegation-credential-cache",0,arg_string, &delegation_cred_str,
+ "where to find the ticket use for delegation", "cache"},
+ { "forwardable", 0, arg_flag, &forwardable_flag,
+ "forwardable ticket requested"},
+ { "transit-check", 0, arg_negative_flag, &transit_flag },
+ { "enctype", 'e', arg_string, &etype_str,
+ "encryption type to use", "enctype"},
+ { "impersonate", 0, arg_string, &impersonate_str,
+ "client to impersonate", "principal"},
+ { "name-type", 0, arg_string, &nametype_str },
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "service");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache cache;
+ krb5_creds *out;
+ int optidx = 0;
+ krb5_get_creds_opt opt;
+ krb5_principal server;
+ krb5_principal impersonate = NULL;
+
+ setprogname (argv[0]);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx(1, "krb5_init_context failed: %d", ret);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc != 1)
+ usage (1);
+
+ if(cache_str) {
+ ret = krb5_cc_resolve(context, cache_str, &cache);
+ if (ret)
+ krb5_err (context, 1, ret, "%s", cache_str);
+ } else {
+ ret = krb5_cc_default (context, &cache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_resolve");
+ }
+
+ ret = krb5_get_creds_opt_alloc(context, &opt);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_creds_opt_alloc");
+
+ if (etype_str) {
+ krb5_enctype enctype;
+
+ ret = krb5_string_to_enctype(context, etype_str, &enctype);
+ if (ret)
+ krb5_errx (context, 1, "unrecognized enctype: %s", etype_str);
+ krb5_get_creds_opt_set_enctype(context, opt, enctype);
+ }
+
+ if (impersonate_str) {
+ ret = krb5_parse_name(context, impersonate_str, &impersonate);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", impersonate_str);
+ krb5_get_creds_opt_set_impersonate(context, opt, impersonate);
+ krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE);
+ }
+
+ if (out_cache_str)
+ krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_STORE);
+
+ if (forwardable_flag)
+ krb5_get_creds_opt_add_options(context, opt, KRB5_GC_FORWARDABLE);
+ if (!transit_flag)
+ krb5_get_creds_opt_add_options(context, opt, KRB5_GC_NO_TRANSIT_CHECK);
+
+ if (delegation_cred_str) {
+ krb5_ccache id;
+ krb5_creds c, mc;
+ Ticket ticket;
+
+ krb5_cc_clear_mcred(&mc);
+ ret = krb5_cc_get_principal(context, cache, &mc.server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_get_principal");
+
+ ret = krb5_cc_resolve(context, delegation_cred_str, &id);
+ if(ret)
+ krb5_err (context, 1, ret, "krb5_cc_resolve");
+
+ ret = krb5_cc_retrieve_cred(context, id, 0, &mc, &c);
+ if(ret)
+ krb5_err (context, 1, ret, "krb5_cc_retrieve_cred");
+
+ ret = decode_Ticket(c.ticket.data, c.ticket.length, &ticket, NULL);
+ if (ret) {
+ krb5_clear_error_string(context);
+ krb5_err (context, 1, ret, "decode_Ticket");
+ }
+ krb5_free_cred_contents(context, &c);
+
+ ret = krb5_get_creds_opt_set_ticket(context, opt, &ticket);
+ if(ret)
+ krb5_err (context, 1, ret, "krb5_get_creds_opt_set_ticket");
+ free_Ticket(&ticket);
+
+ krb5_cc_close (context, id);
+ krb5_free_principal(context, mc.server);
+
+ krb5_get_creds_opt_add_options(context, opt,
+ KRB5_GC_CONSTRAINED_DELEGATION);
+ }
+
+ ret = krb5_parse_name(context, argv[0], &server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", argv[0]);
+
+ if (nametype_str) {
+ ret = krb5_parse_nametype(context, nametype_str,
+ &server->name.name_type);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_parse_nametype");
+ }
+
+ ret = krb5_get_creds(context, opt, cache, server, &out);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_creds");
+
+ if (out_cache_str) {
+ krb5_ccache id;
+
+ ret = krb5_cc_resolve(context, out_cache_str, &id);
+ if(ret)
+ krb5_err (context, 1, ret, "krb5_cc_resolve");
+
+ ret = krb5_cc_initialize(context, id, out->client);
+ if(ret)
+ krb5_err (context, 1, ret, "krb5_cc_initialize");
+
+ ret = krb5_cc_store_cred(context, id, out);
+ if(ret)
+ krb5_err (context, 1, ret, "krb5_cc_store_cred");
+ krb5_cc_close (context, id);
+ }
+
+ krb5_free_creds(context, out);
+ krb5_free_principal(context, server);
+ krb5_get_creds_opt_free(context, opt);
+ krb5_cc_close (context, cache);
+ krb5_free_context (context);
+
+ return 0;
+}
diff --git a/kuser/kimpersonate.1 b/kuser/kimpersonate.1
new file mode 100644
index 0000000000000..b9cd8d61488f6
--- /dev/null
+++ b/kuser/kimpersonate.1
@@ -0,0 +1,152 @@
+.\" Copyright (c) 2002 - 2007 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: kimpersonate.1 20259 2007-02-17 23:49:54Z lha $
+.\"
+.Dd September 18, 2006
+.Dt KERBEROS 1
+.Os Heimdal
+.Sh NAME
+.Nm kimpersonate
+.Nd
+impersonate a user when there exist a srvtab, keyfile or KeyFile
+.Sh SYNOPSIS
+.Nm
+.Oo Fl s Ar string \*(Ba Xo
+.Fl -server= Ns Ar string Oc
+.Xc
+.Oo Fl c Ar string \*(Ba Xo
+.Fl -client= Ns Ar string Oc
+.Xc
+.Oo Fl k Ar string \*(Ba Xo
+.Fl -keytab= Ns Ar string Oc
+.Xc
+.Op Fl 5 | Fl -krb5
+.Oo Fl e Ar integer \*(Ba Xo
+.Fl -expire-time= Ns Ar integer Oc
+.Xc
+.Oo Fl a Ar string \*(Ba Xo
+.Fl -client-address= Ns Ar string Oc
+.Xc
+.Oo Fl t Ar string \*(Ba Xo
+.Fl -enc-type= Ns Ar string Oc
+.Xc
+.Oo Fl f Ar string \*(Ba Xo
+.Fl -ticket-flags= Ns Ar string Oc
+.Xc
+.Op Fl -verbose
+.Op Fl -version
+.Op Fl -help
+.Sh DESCRIPTION
+The
+.Nm
+program creates a "fake" ticket using the service-key of the service.
+The service key can be read from a Kerberos 5 keytab, AFS KeyFile or
+(if compiled with support for Kerberos 4) a Kerberos 4 srvtab.
+Supported options:
+.Bl -tag -width Ds
+.It Xo
+.Fl s Ar string Ns ,
+.Fl -server= Ns Ar string
+.Xc
+name of server principal
+.It Xo
+.Fl c Ar string Ns ,
+.Fl -client= Ns Ar string
+.Xc
+name of client principal
+.It Xo
+.Fl k Ar string Ns ,
+.Fl -keytab= Ns Ar string
+.Xc
+name of keytab file
+.It Xo
+.Fl 5 Ns ,
+.Fl -krb5
+.Xc
+create a Kerberos 5 ticket
+.It Xo
+.Fl e Ar integer Ns ,
+.Fl -expire-time= Ns Ar integer
+.Xc
+lifetime of ticket in seconds
+.It Xo
+.Fl a Ar string Ns ,
+.Fl -client-address= Ns Ar string
+.Xc
+address of client
+.It Xo
+.Fl t Ar string Ns ,
+.Fl -enc-type= Ns Ar string
+.Xc
+encryption type
+.It Xo
+.Fl f Ar string Ns ,
+.Fl -ticket-flags= Ns Ar string
+.Xc
+ticket flags for krb5 ticket
+.It Xo
+.Fl -verbose
+.Xc
+Verbose output
+.It Xo
+.Fl -version
+.Xc
+Print version
+.It Xo
+.Fl -help
+.Xc
+.El
+.Sh FILES
+Uses
+.Pa /etc/krb5.keytab,
+.Pa /etc/srvtab
+and
+.Pa /usr/afs/etc/KeyFile
+when avalible and the the
+.Fl k
+is used with appropriate prefix.
+.Sh EXAMPLES
+.Nm
+can be used in
+.Nm samba
+root preexec option
+or for debugging.
+.Nm
+-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
+.Pa /etc/krb5.keytab .
+.Sh SEE ALSO
+.Xr kinit 1 ,
+.Xr klist 1
+.Sh AUTHORS
+Love Hornquist Astrand <lha@kth.se>
diff --git a/kuser/kimpersonate.c b/kuser/kimpersonate.c
new file mode 100644
index 0000000000000..9ef99aff9f114
--- /dev/null
+++ b/kuser/kimpersonate.c
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2000 - 2007 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"
+RCSID("$Id: kimpersonate.c 22117 2007-12-03 21:24:16Z lha $");
+#include <parse_units.h>
+
+static char *client_principal_str = NULL;
+static krb5_principal client_principal;
+static char *server_principal_str = NULL;
+static krb5_principal server_principal;
+
+static char *ccache_str = NULL;
+
+static char *ticket_flags_str = NULL;
+static TicketFlags ticket_flags;
+static char *keytab_file = NULL;
+static char *enc_type = "des-cbc-md5";
+static int expiration_time = 3600;
+static struct getarg_strings client_addresses;
+static int version_flag = 0;
+static int help_flag = 0;
+static int use_krb5 = 1;
+
+/*
+ *
+ */
+
+static void
+encode_ticket (krb5_context context,
+ EncryptionKey *skey,
+ krb5_enctype etype,
+ int skvno,
+ krb5_creds *cred)
+{
+ size_t len, size;
+ char *buf;
+ krb5_error_code ret;
+ krb5_crypto crypto;
+ EncryptedData enc_part;
+ EncTicketPart et;
+ Ticket ticket;
+
+ memset (&enc_part, 0, sizeof(enc_part));
+ memset (&ticket, 0, sizeof(ticket));
+
+ /*
+ * Set up `enc_part'
+ */
+
+ et.flags = cred->flags.b;
+ et.key = cred->session;
+ et.crealm = *krb5_princ_realm (context, cred->client);
+ copy_PrincipalName(&cred->client->name, &et.cname);
+ {
+ krb5_data empty_string;
+
+ krb5_data_zero(&empty_string);
+ et.transited.tr_type = DOMAIN_X500_COMPRESS;
+ et.transited.contents = empty_string;
+ }
+ et.authtime = cred->times.authtime;
+ et.starttime = NULL;
+ et.endtime = cred->times.endtime;
+ et.renew_till = NULL;
+ et.caddr = &cred->addresses;
+ et.authorization_data = NULL; /* XXX allow random authorization_data */
+
+ /*
+ * Encrypt `enc_part' of ticket with service key
+ */
+
+ ASN1_MALLOC_ENCODE(EncTicketPart, buf, len, &et, &size, ret);
+ if (ret)
+ krb5_err(context, 1, ret, "EncTicketPart");
+
+ krb5_crypto_init(context, skey, etype, &crypto);
+ krb5_encrypt_EncryptedData (context,
+ crypto,
+ KRB5_KU_TICKET,
+ buf,
+ len,
+ skvno,
+ &ticket.enc_part);
+ free(buf);
+ krb5_crypto_destroy(context, crypto);
+
+ /*
+ * Encode ticket
+ */
+
+ ticket.tkt_vno = 5;
+ ticket.realm = *krb5_princ_realm (context, cred->server);
+ copy_PrincipalName(&cred->server->name, &ticket.sname);
+
+ ASN1_MALLOC_ENCODE(Ticket, buf, len, &ticket, &size, ret);
+ if(ret)
+ krb5_err (context, 1, ret, "encode_Ticket");
+
+ krb5_data_copy(&cred->ticket, buf, len);
+}
+
+/*
+ *
+ */
+
+static int
+create_krb5_tickets (krb5_context context, krb5_keytab kt)
+{
+ krb5_error_code ret;
+ krb5_keytab_entry entry;
+ krb5_creds cred;
+ krb5_enctype etype;
+ krb5_ccache ccache;
+
+ memset (&cred, 0, sizeof(cred));
+
+ ret = krb5_string_to_enctype (context, enc_type, &etype);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_string_to_enctype");
+ ret = krb5_kt_get_entry (context, kt, server_principal,
+ 0, etype, &entry);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_kt_get_entry");
+
+ /*
+ * setup cred
+ */
+
+
+ ret = krb5_copy_principal (context, client_principal, &cred.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_copy_principal");
+ ret = krb5_copy_principal (context, server_principal, &cred.server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_copy_principal");
+ krb5_generate_random_keyblock(context, etype, &cred.session);
+
+ cred.times.authtime = time(NULL);
+ cred.times.starttime = time(NULL);
+ cred.times.endtime = time(NULL) + expiration_time;
+ cred.times.renew_till = 0;
+ krb5_data_zero(&cred.second_ticket);
+
+ ret = krb5_get_all_client_addrs (context, &cred.addresses);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_all_client_addrs");
+ cred.flags.b = ticket_flags;
+
+
+ /*
+ * Encode encrypted part of ticket
+ */
+
+ encode_ticket (context, &entry.keyblock, etype, entry.vno, &cred);
+
+ /*
+ * Write to cc
+ */
+
+ if (ccache_str) {
+ ret = krb5_cc_resolve(context, ccache_str, &ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_resolve");
+ } else {
+ ret = krb5_cc_default (context, &ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_default");
+ }
+
+ ret = krb5_cc_initialize (context, ccache, cred.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_initialize");
+
+ ret = krb5_cc_store_cred (context, ccache, &cred);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_store_cred");
+
+ krb5_free_cred_contents (context, &cred);
+ krb5_cc_close (context, ccache);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static void
+setup_env (krb5_context context, krb5_keytab *kt)
+{
+ krb5_error_code ret;
+
+ if (keytab_file)
+ ret = krb5_kt_resolve (context, keytab_file, kt);
+ else
+ ret = krb5_kt_default (context, kt);
+ if (ret)
+ krb5_err (context, 1, ret, "resolving keytab");
+
+ if (client_principal_str == NULL)
+ 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");
+
+ 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 client name");
+
+ if (ticket_flags_str) {
+ int ticket_flags_int;
+
+ ticket_flags_int = parse_flags(ticket_flags_str,
+ asn1_TicketFlags_units(), 0);
+ if (ticket_flags_int <= 0) {
+ krb5_warnx (context, "bad ticket flags: `%s'", ticket_flags_str);
+ print_flags_table (asn1_TicketFlags_units(), stderr);
+ exit (1);
+ }
+ if (ticket_flags_int)
+ ticket_flags = int2TicketFlags (ticket_flags_int);
+ }
+}
+
+/*
+ *
+ */
+
+struct getargs args[] = {
+ { "ccache", 0, arg_string, &ccache_str,
+ "name of kerberos 5 credential cache", "cache-name"},
+ { "server", 's', arg_string, &server_principal_str,
+ "name of server principal" },
+ { "client", 'c', arg_string, &client_principal_str,
+ "name of client principal" },
+ { "keytab", 'k', arg_string, &keytab_file,
+ "name of keytab file" },
+ { "krb5", '5', arg_flag, &use_krb5,
+ "create a kerberos 5 ticket"},
+ { "expire-time", 'e', arg_integer, &expiration_time,
+ "lifetime of ticket in seconds" },
+ { "client-addresses", 'a', arg_strings, &client_addresses,
+ "addresses of client" },
+ { "enc-type", 't', arg_string, &enc_type,
+ "encryption type" },
+ { "ticket-flags", 'f', arg_string, &ticket_flags_str,
+ "ticket flags for krb5 ticket" },
+ { "version", 0, arg_flag, &version_flag, "Print version",
+ NULL },
+ { "help", 0, arg_flag, &help_flag, NULL,
+ NULL }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args) / sizeof(args[0]),
+ NULL,
+ "");
+ exit (ret);
+}
+
+int
+main (int argc, char **argv)
+{
+ int optind = 0;
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_keytab kt;
+
+ setprogname (argv[0]);
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx(1, "krb5_init_context failed: %u", ret);
+
+ if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv,
+ &optind))
+ usage (1);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version(NULL);
+ return 0;
+ }
+
+ setup_env (context, &kt);
+
+ if (use_krb5)
+ create_krb5_tickets (context, kt);
+
+ krb5_kt_close (context, kt);
+ return 0;
+}
diff --git a/kuser/kinit.1 b/kuser/kinit.1
new file mode 100644
index 0000000000000..01fac262a685b
--- /dev/null
+++ b/kuser/kinit.1
@@ -0,0 +1,291 @@
+.\" Copyright (c) 1998 - 2003, 2006 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: kinit.1 17822 2006-07-10 14:46:58Z lha $
+.\"
+.Dd April 25, 2006
+.Dt KINIT 1
+.Os HEIMDAL
+.Sh NAME
+.Nm kinit
+.Nm kauth
+.Nd acquire initial tickets
+.Sh SYNOPSIS
+.Nm kinit
+.Op Fl 4 | Fl -524init
+.Op Fl 9 | Fl -524convert
+.Op Fl -afslog
+.Oo Fl c Ar cachename \*(Ba Xo
+.Fl -cache= Ns Ar cachename
+.Xc
+.Oc
+.Op Fl f | Fl -forwardable
+.Oo Fl t Ar keytabname \*(Ba Xo
+.Fl -keytab= Ns Ar keytabname
+.Xc
+.Oc
+.Oo Fl l Ar time \*(Ba Xo
+.Fl -lifetime= Ns Ar time
+.Xc
+.Oc
+.Op Fl p | Fl -proxiable
+.Op Fl R | Fl -renew
+.Op Fl -renewable
+.Oo Fl r Ar time \*(Ba Xo
+.Fl -renewable-life= Ns Ar time
+.Xc
+.Oc
+.Oo Fl S Ar principal \*(Ba Xo
+.Fl -server= Ns Ar principal
+.Xc
+.Oc
+.Oo Fl s Ar time \*(Ba Xo
+.Fl -start-time= Ns Ar time
+.Xc
+.Oc
+.Op Fl k | Fl -use-keytab
+.Op Fl v | Fl -validate
+.Oo Fl e Ar enctypes \*(Ba Xo
+.Fl -enctypes= Ns Ar enctypes
+.Xc
+.Oc
+.Oo Fl a Ar addresses \*(Ba Xo
+.Fl -extra-addresses= Ns Ar addresses
+.Xc
+.Oc
+.Op Fl -password-file= Ns Ar filename
+.Op Fl -fcache-version= Ns Ar version-number
+.Op Fl A | Fl -no-addresses
+.Op Fl -anonymous
+.Op Fl -version
+.Op Fl -help
+.Op Ar principal Op Ar command
+.Sh DESCRIPTION
+.Nm
+is used to authenticate to the Kerberos server as
+.Ar 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.
+.Pp
+If you have compiled
+.Nm kinit
+with Kerberos 4 support and you have a
+Kerberos 4 server,
+.Nm
+will detect this and get you Kerberos 4 tickets.
+.Pp
+Supported options:
+.Bl -tag -width Ds
+.It Xo
+.Fl c Ar cachename
+.Fl -cache= Ns Ar cachename
+.Xc
+The credentials cache to put the acquired ticket in, if other than
+default.
+.It Xo
+.Fl f ,
+.Fl -forwardable
+.Xc
+Get ticket that can be forwarded to another host.
+.It Xo
+.Fl t Ar keytabname ,
+.Fl -keytab= Ns Ar keytabname
+.Xc
+Don't ask for a password, but instead get the key from the specified
+keytab.
+.It Xo
+.Fl l Ar time ,
+.Fl -lifetime= Ns Ar time
+.Xc
+Specifies the lifetime of the ticket.
+The argument can either be in seconds, or a more human readable string
+like
+.Sq 1h .
+.It Xo
+.Fl p ,
+.Fl -proxiable
+.Xc
+Request tickets with the proxiable flag set.
+.It Xo
+.Fl R ,
+.Fl -renew
+.Xc
+Try to renew ticket.
+The ticket must have the
+.Sq renewable
+flag set, and must not be expired.
+.It Fl -renewable
+The same as
+.Fl -renewable-life ,
+with an infinite time.
+.It Xo
+.Fl r Ar time ,
+.Fl -renewable-life= Ns Ar time
+.Xc
+The max renewable ticket life.
+.It Xo
+.Fl S Ar principal ,
+.Fl -server= Ns Ar principal
+.Xc
+Get a ticket for a service other than krbtgt/LOCAL.REALM.
+.It Xo
+.Fl s Ar time ,
+.Fl -start-time= Ns Ar time
+.Xc
+Obtain a ticket that starts to be valid
+.Ar time
+(which can really be a generic time specification, like
+.Sq 1h )
+seconds into the future.
+.It Xo
+.Fl k ,
+.Fl -use-keytab
+.Xc
+The same as
+.Fl -keytab ,
+but with the default keytab name (normally
+.Ar FILE:/etc/krb5.keytab ) .
+.It Xo
+.Fl v ,
+.Fl -validate
+.Xc
+Try to validate an invalid ticket.
+.It Xo
+.Fl e ,
+.Fl -enctypes= Ns Ar enctypes
+.Xc
+Request tickets with this particular enctype.
+.It Xo
+.Fl -password-file= Ns Ar filename
+.Xc
+read the password from the first line of
+.Ar filename .
+If the
+.Ar filename
+is
+.Ar STDIN ,
+the password will be read from the standard input.
+.It Xo
+.Fl -fcache-version= Ns Ar version-number
+.Xc
+Create a credentials cache of version
+.Ar version-number .
+.It Xo
+.Fl a ,
+.Fl -extra-addresses= Ns Ar enctypes
+.Xc
+Adds a set of addresses that will, in addition to the systems local
+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
+.Li libdefaults/extra_addresses
+in
+.Xr krb5.conf 5 .
+.It Xo
+.Fl A ,
+.Fl -no-addresses
+.Xc
+Request a ticket with no addresses.
+.It Xo
+.Fl -anonymous
+.Xc
+Request an anonymous ticket (which means that the ticket will be
+issued to an anonymous principal, typically
+.Dq anonymous@REALM ) .
+.El
+.Pp
+The following options are only available if
+.Nm
+has been compiled with support for Kerberos 4.
+.Bl -tag -width Ds
+.It Xo
+.Fl 4 ,
+.Fl -524init
+.Xc
+Try to convert the obtained Kerberos 5 krbtgt to a version 4
+compatible ticket.
+It will store this ticket in the default Kerberos 4 ticket file.
+.It Xo
+.Fl 9 ,
+.Fl -524convert
+.Xc
+only convert ticket to version 4
+.It Fl -afslog
+Gets AFS tickets, converts them to version 4 format, and stores them
+in the kernel.
+Only useful if you have AFS.
+.El
+.Pp
+The
+.Ar forwardable ,
+.Ar proxiable ,
+.Ar ticket_life ,
+and
+.Ar renewable_life
+options can be set to a default value from the
+.Dv appdefaults
+section in krb5.conf, see
+.Xr krb5_appdefault 3 .
+.Pp
+If a
+.Ar command
+is given,
+.Nm kinit
+will set up new credentials caches, and AFS PAG, and then run the given
+command.
+When it finishes the credentials will be removed.
+.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 KRBTKFILE
+Specifies the Kerberos 4 ticket file to store version 4 tickets in.
+.El
+.\".Sh FILES
+.\".Sh EXAMPLES
+.\".Sh DIAGNOSTICS
+.Sh SEE ALSO
+.Xr kdestroy 1 ,
+.Xr klist 1 ,
+.Xr krb5_appdefault 3 ,
+.Xr krb5.conf 5
+.\".Sh STANDARDS
+.\".Sh HISTORY
+.\".Sh AUTHORS
+.\".Sh BUGS
diff --git a/kuser/kinit.c b/kuser/kinit.c
new file mode 100644
index 0000000000000..2676309859089
--- /dev/null
+++ b/kuser/kinit.c
@@ -0,0 +1,852 @@
+/*
+ * Copyright (c) 1997-2007 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"
+RCSID("$Id: kinit.c 22116 2007-12-03 21:22:58Z lha $");
+
+#include "krb5-v4compat.h"
+
+#include "heimntlm.h"
+
+int forwardable_flag = -1;
+int proxiable_flag = -1;
+int renewable_flag = -1;
+int renew_flag = 0;
+int pac_flag = -1;
+int validate_flag = 0;
+int version_flag = 0;
+int help_flag = 0;
+int addrs_flag = -1;
+struct getarg_strings extra_addresses;
+int anonymous_flag = 0;
+char *lifetime = NULL;
+char *renew_life = NULL;
+char *server_str = NULL;
+char *cred_cache = NULL;
+char *start_str = NULL;
+struct getarg_strings etype_str;
+int use_keytab = 0;
+char *keytab_str = NULL;
+int do_afslog = -1;
+int get_v4_tgt = -1;
+int convert_524 = 0;
+int fcache_version;
+char *password_file = NULL;
+char *pk_user_id = NULL;
+char *pk_x509_anchors = NULL;
+int pk_use_enckey = 0;
+static int canonicalize_flag = 0;
+static char *ntlm_domain;
+
+static char *krb4_cc_name;
+
+static struct getargs args[] = {
+ /*
+ * used by MIT
+ * a: ~A
+ * V: verbose
+ * F: ~f
+ * P: ~p
+ * C: v4 cache name?
+ * 5:
+ */
+ { "524init", '4', arg_flag, &get_v4_tgt,
+ "obtain version 4 TGT" },
+
+ { "524convert", '9', arg_flag, &convert_524,
+ "only convert ticket to version 4" },
+
+ { "afslog", 0 , arg_flag, &do_afslog,
+ "obtain afs tokens" },
+
+ { "cache", 'c', arg_string, &cred_cache,
+ "credentials cache", "cachename" },
+
+ { "forwardable", 'f', arg_flag, &forwardable_flag,
+ "get forwardable tickets"},
+
+ { "keytab", 't', arg_string, &keytab_str,
+ "keytab to use", "keytabname" },
+
+ { "lifetime", 'l', arg_string, &lifetime,
+ "lifetime of tickets", "time"},
+
+ { "proxiable", 'p', arg_flag, &proxiable_flag,
+ "get proxiable tickets" },
+
+ { "renew", 'R', arg_flag, &renew_flag,
+ "renew TGT" },
+
+ { "renewable", 0, arg_flag, &renewable_flag,
+ "get renewable tickets" },
+
+ { "renewable-life", 'r', arg_string, &renew_life,
+ "renewable lifetime of tickets", "time" },
+
+ { "server", 'S', arg_string, &server_str,
+ "server to get ticket for", "principal" },
+
+ { "start-time", 's', arg_string, &start_str,
+ "when ticket gets valid", "time" },
+
+ { "use-keytab", 'k', arg_flag, &use_keytab,
+ "get key from keytab" },
+
+ { "validate", 'v', arg_flag, &validate_flag,
+ "validate TGT" },
+
+ { "enctypes", 'e', arg_strings, &etype_str,
+ "encryption types to use", "enctypes" },
+
+ { "fcache-version", 0, arg_integer, &fcache_version,
+ "file cache version to create" },
+
+ { "addresses", 'A', arg_negative_flag, &addrs_flag,
+ "request a ticket with no addresses" },
+
+ { "extra-addresses",'a', arg_strings, &extra_addresses,
+ "include these extra addresses", "addresses" },
+
+ { "anonymous", 0, arg_flag, &anonymous_flag,
+ "request an anonymous ticket" },
+
+ { "request-pac", 0, arg_flag, &pac_flag,
+ "request a Windows PAC" },
+
+ { "password-file", 0, arg_string, &password_file,
+ "read the password from a file" },
+
+ { "canonicalize",0, arg_flag, &canonicalize_flag,
+ "canonicalize client principal" },
+#ifdef PKINIT
+ { "pk-user", 'C', arg_string, &pk_user_id,
+ "principal's public/private/certificate identifier", "id" },
+
+ { "x509-anchors", 'D', arg_string, &pk_x509_anchors,
+ "directory with CA certificates", "directory" },
+
+ { "pk-use-enckey", 0, arg_flag, &pk_use_enckey,
+ "Use RSA encrypted reply (instead of DH)" },
+#endif
+ { "ntlm-domain", 0, arg_string, &ntlm_domain,
+ "NTLM domain", "domain" },
+
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "[principal [command]]");
+ exit (ret);
+}
+
+static krb5_error_code
+get_server(krb5_context context,
+ krb5_principal client,
+ const char *server,
+ krb5_principal *princ)
+{
+ krb5_realm *client_realm;
+ if(server)
+ return krb5_parse_name(context, server, princ);
+
+ client_realm = krb5_princ_realm (context, client);
+ return krb5_make_principal(context, princ, *client_realm,
+ KRB5_TGS_NAME, *client_realm, NULL);
+}
+
+static krb5_error_code
+do_524init(krb5_context context, krb5_ccache ccache,
+ krb5_creds *creds, const char *server)
+{
+ krb5_error_code ret;
+
+ struct credentials c;
+ krb5_creds in_creds, *real_creds;
+
+ if(creds != NULL)
+ real_creds = creds;
+ else {
+ krb5_principal client;
+ krb5_cc_get_principal(context, ccache, &client);
+ memset(&in_creds, 0, sizeof(in_creds));
+ ret = get_server(context, client, server, &in_creds.server);
+ if(ret) {
+ krb5_free_principal(context, client);
+ return ret;
+ }
+ in_creds.client = client;
+ ret = krb5_get_credentials(context, 0, ccache, &in_creds, &real_creds);
+ krb5_free_principal(context, client);
+ krb5_free_principal(context, in_creds.server);
+ if(ret)
+ return ret;
+ }
+ ret = krb524_convert_creds_kdc_ccache(context, ccache, real_creds, &c);
+ if(ret)
+ krb5_warn(context, ret, "converting creds");
+ else {
+ krb5_error_code tret = _krb5_krb_tf_setup(context, &c, NULL, 0);
+ if(tret)
+ krb5_warn(context, tret, "saving v4 creds");
+ }
+
+ if(creds == NULL)
+ krb5_free_creds(context, real_creds);
+ memset(&c, 0, sizeof(c));
+
+ return ret;
+}
+
+static int
+renew_validate(krb5_context context,
+ int renew,
+ int validate,
+ krb5_ccache cache,
+ const char *server,
+ krb5_deltat life)
+{
+ krb5_error_code ret;
+ 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) {
+ krb5_warn(context, ret, "krb5_cc_get_principal");
+ return ret;
+ }
+ ret = get_server(context, in.client, server, &in.server);
+ if(ret) {
+ krb5_warn(context, ret, "get_server");
+ goto out;
+ }
+
+ if (renew) {
+ /*
+ * 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);
+ }
+
+ flags.i = 0;
+ flags.b.renewable = flags.b.renew = renew;
+ flags.b.validate = validate;
+
+ if (forwardable_flag != -1)
+ flags.b.forwardable = forwardable_flag;
+ else if (out)
+ flags.b.forwardable = out->flags.b.forwardable;
+
+ if (proxiable_flag != -1)
+ flags.b.proxiable = proxiable_flag;
+ else if (out)
+ flags.b.proxiable = out->flags.b.proxiable;
+
+ if (anonymous_flag != -1)
+ flags.b.request_anonymous = anonymous_flag;
+ if(life)
+ in.times.endtime = time(NULL) + life;
+
+ if (out) {
+ krb5_free_creds (context, out);
+ out = NULL;
+ }
+
+
+ ret = krb5_get_kdc_cred(context,
+ cache,
+ flags,
+ NULL,
+ NULL,
+ &in,
+ &out);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_get_kdc_cred");
+ goto out;
+ }
+ ret = krb5_cc_initialize(context, cache, in.client);
+ if(ret) {
+ krb5_free_creds (context, out);
+ krb5_warn(context, ret, "krb5_cc_initialize");
+ goto out;
+ }
+ ret = krb5_cc_store_cred(context, cache, out);
+
+ if(ret == 0 && server == NULL) {
+ /* only do this if it's a general renew-my-tgt request */
+ if(get_v4_tgt)
+ do_524init(context, cache, out, NULL);
+ if(do_afslog && k_hasafs())
+ krb5_afslog(context, cache, NULL, NULL);
+ }
+
+ krb5_free_creds (context, out);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_cc_store_cred");
+ goto out;
+ }
+out:
+ krb5_free_cred_contents(context, &in);
+ return ret;
+}
+
+static krb5_error_code
+store_ntlmkey(krb5_context context, krb5_ccache id,
+ const char *domain, krb5_const_principal client,
+ struct ntlm_buf *buf)
+{
+ krb5_error_code ret;
+ krb5_creds cred;
+
+ memset(&cred, 0, sizeof(cred));
+
+ ret = krb5_make_principal(context, &cred.server,
+ krb5_principal_get_realm(context, client),
+ "@ntlm-key", domain, NULL);
+ if (ret)
+ goto out;
+ ret = krb5_copy_principal(context, client, &cred.client);
+ if (ret)
+ goto out;
+
+ cred.times.authtime = time(NULL);
+ cred.times.endtime = time(NULL) + 3600 * 24 * 30; /* XXX */
+ cred.session.keytype = ENCTYPE_ARCFOUR_HMAC_MD5;
+ ret = krb5_data_copy(&cred.session.keyvalue, buf->data, buf->length);
+ if (ret)
+ goto out;
+
+ ret = krb5_cc_store_cred(context, id, &cred);
+
+out:
+ krb5_free_cred_contents (context, &cred);
+ return 0;
+}
+
+static krb5_error_code
+get_new_tickets(krb5_context context,
+ krb5_principal principal,
+ krb5_ccache ccache,
+ krb5_deltat ticket_life,
+ int interactive)
+{
+ krb5_error_code ret;
+ krb5_get_init_creds_opt *opt;
+ krb5_creds cred;
+ char passwd[256];
+ krb5_deltat start_time = 0;
+ krb5_deltat renew = 0;
+ char *renewstr = NULL;
+ krb5_enctype *enctype = NULL;
+ struct ntlm_buf ntlmkey;
+ krb5_ccache tempccache;
+
+ memset(&ntlmkey, 0, sizeof(ntlmkey));
+ passwd[0] = '\0';
+
+ if (password_file) {
+ FILE *f;
+
+ if (strcasecmp("STDIN", password_file) == 0)
+ f = stdin;
+ else
+ f = fopen(password_file, "r");
+ if (f == NULL)
+ krb5_errx(context, 1, "Failed to open the password file %s",
+ password_file);
+
+ if (fgets(passwd, sizeof(passwd), f) == NULL)
+ krb5_errx(context, 1,
+ "Failed to read password from file %s", password_file);
+ if (f != stdin)
+ fclose(f);
+ passwd[strcspn(passwd, "\n")] = '\0';
+ }
+
+
+ memset(&cred, 0, sizeof(cred));
+
+ ret = krb5_get_init_creds_opt_alloc (context, &opt);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
+
+ krb5_get_init_creds_opt_set_default_flags(context, "kinit",
+ krb5_principal_get_realm(context, principal), opt);
+
+ if(forwardable_flag != -1)
+ krb5_get_init_creds_opt_set_forwardable (opt, forwardable_flag);
+ if(proxiable_flag != -1)
+ krb5_get_init_creds_opt_set_proxiable (opt, proxiable_flag);
+ if(anonymous_flag != -1)
+ krb5_get_init_creds_opt_set_anonymous (opt, anonymous_flag);
+ if (pac_flag != -1)
+ krb5_get_init_creds_opt_set_pac_request(context, opt,
+ pac_flag ? TRUE : FALSE);
+ if (canonicalize_flag)
+ krb5_get_init_creds_opt_set_canonicalize(context, opt, TRUE);
+ if (pk_user_id) {
+ ret = krb5_get_init_creds_opt_set_pkinit(context, opt,
+ principal,
+ pk_user_id,
+ pk_x509_anchors,
+ NULL,
+ NULL,
+ pk_use_enckey ? 2 : 0,
+ krb5_prompter_posix,
+ NULL,
+ passwd);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_get_init_creds_opt_set_pkinit");
+ }
+
+ if (addrs_flag != -1)
+ krb5_get_init_creds_opt_set_addressless(context, opt,
+ addrs_flag ? FALSE : TRUE);
+
+ if (renew_life == NULL && renewable_flag)
+ renewstr = "1 month";
+ if (renew_life)
+ renewstr = renew_life;
+ if (renewstr) {
+ renew = parse_time (renewstr, "s");
+ if (renew < 0)
+ errx (1, "unparsable time: %s", renewstr);
+
+ krb5_get_init_creds_opt_set_renew_life (opt, renew);
+ }
+
+ if(ticket_life != 0)
+ krb5_get_init_creds_opt_set_tkt_life (opt, ticket_life);
+
+ if(start_str) {
+ int tmp = parse_time (start_str, "s");
+ if (tmp < 0)
+ errx (1, "unparsable time: %s", start_str);
+
+ start_time = tmp;
+ }
+
+ if(etype_str.num_strings) {
+ int i;
+
+ enctype = malloc(etype_str.num_strings * sizeof(*enctype));
+ if(enctype == NULL)
+ errx(1, "out of memory");
+ for(i = 0; i < etype_str.num_strings; i++) {
+ ret = krb5_string_to_enctype(context,
+ etype_str.strings[i],
+ &enctype[i]);
+ if(ret)
+ errx(1, "unrecognized enctype: %s", etype_str.strings[i]);
+ }
+ krb5_get_init_creds_opt_set_etype_list(opt, enctype,
+ etype_str.num_strings);
+ }
+
+ if(use_keytab || keytab_str) {
+ krb5_keytab kt;
+ if(keytab_str)
+ ret = krb5_kt_resolve(context, keytab_str, &kt);
+ else
+ ret = krb5_kt_default(context, &kt);
+ if (ret)
+ krb5_err (context, 1, ret, "resolving keytab");
+ ret = krb5_get_init_creds_keytab (context,
+ &cred,
+ principal,
+ kt,
+ start_time,
+ server_str,
+ opt);
+ krb5_kt_close(context, kt);
+ } else if (pk_user_id) {
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ passwd,
+ krb5_prompter_posix,
+ NULL,
+ start_time,
+ server_str,
+ opt);
+ } else if (!interactive) {
+ krb5_warnx(context, "Not interactive, failed to get initial ticket");
+ krb5_get_init_creds_opt_free(context, opt);
+ return 0;
+ } else {
+
+ if (passwd[0] == '\0') {
+ char *p, *prompt;
+
+ krb5_unparse_name (context, principal, &p);
+ asprintf (&prompt, "%s's Password: ", p);
+ free (p);
+
+ if (UI_UTIL_read_pw_string(passwd, sizeof(passwd)-1, prompt, 0)){
+ memset(passwd, 0, sizeof(passwd));
+ exit(1);
+ }
+ free (prompt);
+ }
+
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ passwd,
+ krb5_prompter_posix,
+ NULL,
+ start_time,
+ server_str,
+ opt);
+ }
+ krb5_get_init_creds_opt_free(context, opt);
+ if (ntlm_domain && passwd[0])
+ heim_ntlm_nt_key(passwd, &ntlmkey);
+ memset(passwd, 0, sizeof(passwd));
+
+ switch(ret){
+ case 0:
+ break;
+ case KRB5_LIBOS_PWDINTR: /* don't print anything if it was just C-c:ed */
+ exit(1);
+ case KRB5KRB_AP_ERR_BAD_INTEGRITY:
+ case KRB5KRB_AP_ERR_MODIFIED:
+ case KRB5KDC_ERR_PREAUTH_FAILED:
+ krb5_errx(context, 1, "Password incorrect");
+ break;
+ case KRB5KRB_AP_ERR_V4_REPLY:
+ krb5_errx(context, 1, "Looks like a Kerberos 4 reply");
+ break;
+ default:
+ krb5_err(context, 1, ret, "krb5_get_init_creds");
+ }
+
+ if(ticket_life != 0) {
+ if(abs(cred.times.endtime - cred.times.starttime - ticket_life) > 30) {
+ char life[64];
+ unparse_time_approx(cred.times.endtime - cred.times.starttime,
+ life, sizeof(life));
+ krb5_warnx(context, "NOTICE: ticket lifetime is %s", life);
+ }
+ }
+ if(renew_life) {
+ if(abs(cred.times.renew_till - cred.times.starttime - renew) > 30) {
+ char life[64];
+ unparse_time_approx(cred.times.renew_till - cred.times.starttime,
+ life, sizeof(life));
+ krb5_warnx(context, "NOTICE: ticket renewable lifetime is %s",
+ life);
+ }
+ }
+
+ ret = krb5_cc_new_unique(context, krb5_cc_get_type(context, ccache),
+ NULL, &tempccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_new_unique");
+
+ ret = krb5_cc_initialize (context, tempccache, cred.client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_initialize");
+
+ ret = krb5_cc_store_cred (context, tempccache, &cred);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_store_cred");
+
+ krb5_free_cred_contents (context, &cred);
+
+ ret = krb5_cc_move(context, tempccache, ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_move");
+
+ if (ntlm_domain && ntlmkey.data)
+ store_ntlmkey(context, ccache, ntlm_domain, principal, &ntlmkey);
+
+ if (enctype)
+ free(enctype);
+
+ return 0;
+}
+
+static time_t
+ticket_lifetime(krb5_context context, krb5_ccache cache,
+ krb5_principal client, const char *server)
+{
+ krb5_creds in_cred, *cred;
+ krb5_error_code ret;
+ time_t timeout;
+
+ memset(&in_cred, 0, sizeof(in_cred));
+
+ ret = krb5_cc_get_principal(context, cache, &in_cred.client);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_cc_get_principal");
+ return 0;
+ }
+ ret = get_server(context, in_cred.client, server, &in_cred.server);
+ if(ret) {
+ krb5_free_principal(context, in_cred.client);
+ krb5_warn(context, ret, "get_server");
+ return 0;
+ }
+
+ ret = krb5_get_credentials(context, KRB5_GC_CACHED,
+ cache, &in_cred, &cred);
+ krb5_free_principal(context, in_cred.client);
+ krb5_free_principal(context, in_cred.server);
+ if(ret) {
+ krb5_warn(context, ret, "krb5_get_credentials");
+ return 0;
+ }
+ timeout = cred->times.endtime - cred->times.starttime;
+ if (timeout < 0)
+ timeout = 0;
+ krb5_free_creds(context, cred);
+ return timeout;
+}
+
+struct renew_ctx {
+ krb5_context context;
+ krb5_ccache ccache;
+ krb5_principal principal;
+ krb5_deltat ticket_life;
+};
+
+static time_t
+renew_func(void *ptr)
+{
+ struct renew_ctx *ctx = ptr;
+ krb5_error_code ret;
+ time_t expire;
+ int new_tickets = 0;
+
+ if (renewable_flag) {
+ ret = renew_validate(ctx->context, renewable_flag, validate_flag,
+ ctx->ccache, server_str, ctx->ticket_life);
+ if (ret)
+ new_tickets = 1;
+ } else
+ new_tickets = 1;
+
+ if (new_tickets)
+ get_new_tickets(ctx->context, ctx->principal,
+ ctx->ccache, ctx->ticket_life, 0);
+
+ if(get_v4_tgt || convert_524)
+ do_524init(ctx->context, ctx->ccache, NULL, server_str);
+ if(do_afslog && k_hasafs())
+ krb5_afslog(ctx->context, ctx->ccache, NULL, NULL);
+
+ expire = ticket_lifetime(ctx->context, ctx->ccache, ctx->principal,
+ server_str) / 2;
+ return expire + 1;
+}
+
+int
+main (int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache ccache;
+ krb5_principal principal;
+ int optidx = 0;
+ krb5_deltat ticket_life = 0;
+ int parseflags = 0;
+
+ setprogname (argv[0]);
+
+ ret = krb5_init_context (&context);
+ if (ret == KRB5_CONFIG_BADFORMAT)
+ errx (1, "krb5_init_context failed to parse configuration file");
+ else if (ret)
+ errx(1, "krb5_init_context failed: %d", ret);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (canonicalize_flag)
+ parseflags |= KRB5_PRINCIPAL_PARSE_ENTERPRISE;
+
+ if (argv[0]) {
+ ret = krb5_parse_name_flags (context, argv[0], parseflags, &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name");
+ } else {
+ ret = krb5_get_default_principal (context, &principal);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_get_default_principal");
+ }
+
+ if(fcache_version)
+ krb5_set_fcache_version(context, fcache_version);
+
+ if(renewable_flag == -1)
+ /* this seems somewhat pointless, but whatever */
+ krb5_appdefault_boolean(context, "kinit",
+ krb5_principal_get_realm(context, principal),
+ "renewable", FALSE, &renewable_flag);
+ if(get_v4_tgt == -1)
+ krb5_appdefault_boolean(context, "kinit",
+ krb5_principal_get_realm(context, principal),
+ "krb4_get_tickets", FALSE, &get_v4_tgt);
+ if(do_afslog == -1)
+ krb5_appdefault_boolean(context, "kinit",
+ krb5_principal_get_realm(context, principal),
+ "afslog", TRUE, &do_afslog);
+
+ if(cred_cache)
+ ret = krb5_cc_resolve(context, cred_cache, &ccache);
+ else {
+ if(argc > 1) {
+ char s[1024];
+ ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &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);
+ if (get_v4_tgt) {
+ int fd;
+ if (asprintf(&krb4_cc_name, "%s_XXXXXX", TKT_ROOT) < 0)
+ krb5_errx(context, 1, "out of memory");
+ if((fd = mkstemp(krb4_cc_name)) >= 0) {
+ close(fd);
+ setenv("KRBTKFILE", krb4_cc_name, 1);
+ } else {
+ free(krb4_cc_name);
+ krb4_cc_name = NULL;
+ }
+ }
+ } else {
+ ret = krb5_cc_cache_match(context, principal, NULL, &ccache);
+ if (ret)
+ ret = krb5_cc_default (context, &ccache);
+ }
+ }
+ if (ret)
+ krb5_err (context, 1, ret, "resolving credentials cache");
+
+ if(argc > 1 && k_hasafs ())
+ k_setpag();
+
+ if (lifetime) {
+ int tmp = parse_time (lifetime, "s");
+ if (tmp < 0)
+ errx (1, "unparsable time: %s", lifetime);
+
+ ticket_life = tmp;
+ }
+
+ if(addrs_flag == 0 && extra_addresses.num_strings > 0)
+ krb5_errx(context, 1, "specifying both extra addresses and "
+ "no addresses makes no sense");
+ {
+ int i;
+ krb5_addresses addresses;
+ memset(&addresses, 0, sizeof(addresses));
+ for(i = 0; i < extra_addresses.num_strings; i++) {
+ ret = krb5_parse_address(context, extra_addresses.strings[i],
+ &addresses);
+ if (ret == 0) {
+ krb5_add_extra_addresses(context, &addresses);
+ krb5_free_addresses(context, &addresses);
+ }
+ }
+ free_getarg_strings(&extra_addresses);
+ }
+
+ if(renew_flag || validate_flag) {
+ ret = renew_validate(context, renew_flag, validate_flag,
+ ccache, server_str, ticket_life);
+ exit(ret != 0);
+ }
+
+ if(!convert_524)
+ get_new_tickets(context, principal, ccache, ticket_life, 1);
+
+ if(get_v4_tgt || convert_524)
+ do_524init(context, ccache, NULL, server_str);
+ if(do_afslog && k_hasafs())
+ krb5_afslog(context, ccache, NULL, NULL);
+ if(argc > 1) {
+ struct renew_ctx ctx;
+ time_t timeout;
+
+ timeout = ticket_lifetime(context, ccache, principal, server_str) / 2;
+
+ ctx.context = context;
+ ctx.ccache = ccache;
+ ctx.principal = principal;
+ ctx.ticket_life = ticket_life;
+
+ ret = simple_execvp_timed(argv[1], argv+1,
+ renew_func, &ctx, timeout);
+#define EX_NOEXEC 126
+#define EX_NOTFOUND 127
+ if(ret == EX_NOEXEC)
+ krb5_warnx(context, "permission denied: %s", argv[1]);
+ else if(ret == EX_NOTFOUND)
+ krb5_warnx(context, "command not found: %s", argv[1]);
+
+ krb5_cc_destroy(context, ccache);
+ _krb5_krb_dest_tkt(context, krb4_cc_name);
+ if(k_hasafs())
+ k_unlog();
+ } else {
+ krb5_cc_close (context, ccache);
+ ret = 0;
+ }
+ krb5_free_principal(context, principal);
+ krb5_free_context (context);
+ return ret;
+}
diff --git a/kuser/kinit_options.c b/kuser/kinit_options.c
new file mode 100644
index 0000000000000..5a7dcd98753d4
--- /dev/null
+++ b/kuser/kinit_options.c
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 1998 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"
+RCSID("$Id: kinit_options.c,v 1.2 1999/12/02 17:05:01 joda Exp $");
+
+#ifdef KRB4
+int do_afslog = 0;
+int get_v4_tgt = 0;
+#endif
diff --git a/kuser/klist.1 b/kuser/klist.1
new file mode 100644
index 0000000000000..65ed7d36aa174
--- /dev/null
+++ b/kuser/klist.1
@@ -0,0 +1,154 @@
+.\" Copyright (c) 2000 - 2005 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: klist.1 20458 2007-04-19 20:41:27Z lha $
+.\"
+.Dd October 6, 2005
+.Dt KLIST 1
+.Os HEIMDAL
+.Sh NAME
+.Nm klist
+.Nd list Kerberos credentials
+.Sh SYNOPSIS
+.Nm
+.Bk -words
+.Oo Fl c Ar cache \*(Ba Xo
+.Fl -cache= Ns Ar cache
+.Xc
+.Oc
+.Op Fl s | Fl t | Fl -test
+.Op Fl T | Fl -tokens
+.Op Fl 5 | Fl -v5
+.Op Fl v | Fl -verbose
+.Op Fl l | Fl -list-caches
+.Op Fl f
+.Op Fl -version
+.Op Fl -help
+.Ek
+.Sh DESCRIPTION
+.Nm
+reads and displays the current tickets in the credential cache (also
+known as the ticket file).
+.Pp
+Options supported:
+.Bl -tag -width Ds
+.It Xo
+.Fl c Ar cache ,
+.Fl -cache= Ns Ar cache
+.Xc
+credential cache to list
+.It Xo
+.Fl s ,
+.Fl t ,
+.Fl -test
+.Xc
+Test for there being an active and valid TGT for the local realm of
+the user in the credential cache.
+.It Xo
+.Fl T ,
+.Fl -tokens
+.Xc
+display AFS tokens
+.It Xo
+.Fl 5 ,
+.Fl -v5
+.Xc
+display v5 cred cache (this is the default)
+.It Fl f
+Include ticket flags in short form, each character stands for a
+specific flag, as follows:
+.Bl -tag -width XXX -compact -offset indent
+.It F
+forwardable
+.It f
+forwarded
+.It P
+proxiable
+.It p
+proxied
+.It D
+postdate-able
+.It d
+postdated
+.It R
+renewable
+.It I
+initial
+.It i
+invalid
+.It A
+pre-authenticated
+.It H
+hardware authenticated
+.El
+.Pp
+This information is also output with the
+.Fl -verbose
+option, but in a more verbose way.
+.It Xo
+.Fl v ,
+.Fl -verbose
+.Xc
+Verbose output. Include all possible information:
+.Bl -tag -width XXXX -offset indent
+.It Server
+the principal the ticket is for
+.It Ticket etype
+the encryption type used in the ticket, followed by the key version of
+the ticket, if it is available
+.It Session key
+the encryption type of the session key, if it's different from the
+encryption type of the ticket
+.It Auth time
+the time the authentication exchange took place
+.It Start time
+the time that this ticket is valid from (only printed if it's
+different from the auth time)
+.It End time
+when the ticket expires, if it has already expired this is also noted
+.It Renew till
+the maximum possible end time of any ticket derived from this one
+.It Ticket flags
+the flags set on the ticket
+.It Addresses
+the set of addresses from which this ticket is valid
+.El
+.It Xo
+.Fl l ,
+.Fl -list-caches
+.Xc
+List the credential caches for the current users, not all cache types
+supports listing multiple caches.
+.Pp
+.El
+.Sh SEE ALSO
+.Xr kdestroy 1 ,
+.Xr kinit 1
diff --git a/kuser/klist.c b/kuser/klist.c
new file mode 100644
index 0000000000000..3148ddc275e24
--- /dev/null
+++ b/kuser/klist.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 1997-2004 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 "rtbl.h"
+
+RCSID("$Id: klist.c 20516 2007-04-22 10:40:41Z lha $");
+
+static char*
+printable_time(time_t t)
+{
+ static char s[128];
+ strlcpy(s, ctime(&t)+ 4, sizeof(s));
+ s[15] = 0;
+ return s;
+}
+
+static char*
+printable_time_long(time_t t)
+{
+ static char s[128];
+ strlcpy(s, ctime(&t)+ 4, sizeof(s));
+ s[20] = 0;
+ return s;
+}
+
+#define COL_ISSUED " Issued"
+#define COL_EXPIRES " Expires"
+#define COL_FLAGS "Flags"
+#define COL_PRINCIPAL " Principal"
+#define COL_PRINCIPAL_KVNO " Principal (kvno)"
+#define COL_CACHENAME " Cache name"
+
+static void
+print_cred(krb5_context context, krb5_creds *cred, rtbl_t ct, int do_flags)
+{
+ char *str;
+ krb5_error_code ret;
+ krb5_timestamp sec;
+
+ krb5_timeofday (context, &sec);
+
+
+ if(cred->times.starttime)
+ rtbl_add_column_entry(ct, COL_ISSUED,
+ printable_time(cred->times.starttime));
+ else
+ rtbl_add_column_entry(ct, COL_ISSUED,
+ printable_time(cred->times.authtime));
+
+ if(cred->times.endtime > sec)
+ rtbl_add_column_entry(ct, COL_EXPIRES,
+ printable_time(cred->times.endtime));
+ else
+ rtbl_add_column_entry(ct, COL_EXPIRES, ">>>Expired<<<");
+ ret = krb5_unparse_name (context, cred->server, &str);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_unparse_name");
+ rtbl_add_column_entry(ct, COL_PRINCIPAL, str);
+ if(do_flags) {
+ char s[16], *sp = s;
+ if(cred->flags.b.forwardable)
+ *sp++ = 'F';
+ if(cred->flags.b.forwarded)
+ *sp++ = 'f';
+ if(cred->flags.b.proxiable)
+ *sp++ = 'P';
+ if(cred->flags.b.proxy)
+ *sp++ = 'p';
+ if(cred->flags.b.may_postdate)
+ *sp++ = 'D';
+ if(cred->flags.b.postdated)
+ *sp++ = 'd';
+ if(cred->flags.b.renewable)
+ *sp++ = 'R';
+ if(cred->flags.b.initial)
+ *sp++ = 'I';
+ if(cred->flags.b.invalid)
+ *sp++ = 'i';
+ if(cred->flags.b.pre_authent)
+ *sp++ = 'A';
+ if(cred->flags.b.hw_authent)
+ *sp++ = 'H';
+ *sp++ = '\0';
+ rtbl_add_column_entry(ct, COL_FLAGS, s);
+ }
+ free(str);
+}
+
+static void
+print_cred_verbose(krb5_context context, krb5_creds *cred)
+{
+ int j;
+ char *str;
+ krb5_error_code ret;
+ int first_flag;
+ krb5_timestamp sec;
+
+ krb5_timeofday (context, &sec);
+
+ ret = krb5_unparse_name(context, cred->server, &str);
+ if(ret)
+ exit(1);
+ printf("Server: %s\n", str);
+ free (str);
+
+ ret = krb5_unparse_name(context, cred->client, &str);
+ if(ret)
+ exit(1);
+ printf("Client: %s\n", str);
+ free (str);
+
+ {
+ Ticket t;
+ size_t len;
+ char *s;
+
+ decode_Ticket(cred->ticket.data, cred->ticket.length, &t, &len);
+ ret = krb5_enctype_to_string(context, t.enc_part.etype, &s);
+ printf("Ticket etype: ");
+ if (ret == 0) {
+ printf("%s", s);
+ free(s);
+ } else {
+ printf("unknown(%d)", t.enc_part.etype);
+ }
+ if(t.enc_part.kvno)
+ printf(", kvno %d", *t.enc_part.kvno);
+ printf("\n");
+ if(cred->session.keytype != t.enc_part.etype) {
+ ret = krb5_enctype_to_string(context, cred->session.keytype, &str);
+ if(ret)
+ krb5_warn(context, ret, "session keytype");
+ else {
+ printf("Session key: %s\n", str);
+ free(str);
+ }
+ }
+ free_Ticket(&t);
+ printf("Ticket length: %lu\n", (unsigned long)cred->ticket.length);
+ }
+ printf("Auth time: %s\n", printable_time_long(cred->times.authtime));
+ if(cred->times.authtime != cred->times.starttime)
+ printf("Start time: %s\n", printable_time_long(cred->times.starttime));
+ printf("End time: %s", printable_time_long(cred->times.endtime));
+ if(sec > cred->times.endtime)
+ printf(" (expired)");
+ printf("\n");
+ if(cred->flags.b.renewable)
+ printf("Renew till: %s\n",
+ printable_time_long(cred->times.renew_till));
+ printf("Ticket flags: ");
+#define PRINT_FLAG2(f, s) if(cred->flags.b.f) { if(!first_flag) printf(", "); printf("%s", #s); first_flag = 0; }
+#define PRINT_FLAG(f) PRINT_FLAG2(f, f)
+ first_flag = 1;
+ PRINT_FLAG(forwardable);
+ PRINT_FLAG(forwarded);
+ PRINT_FLAG(proxiable);
+ PRINT_FLAG(proxy);
+ PRINT_FLAG2(may_postdate, may-postdate);
+ PRINT_FLAG(postdated);
+ PRINT_FLAG(invalid);
+ PRINT_FLAG(renewable);
+ PRINT_FLAG(initial);
+ PRINT_FLAG2(pre_authent, pre-authenticated);
+ PRINT_FLAG2(hw_authent, hw-authenticated);
+ PRINT_FLAG2(transited_policy_checked, transited-policy-checked);
+ PRINT_FLAG2(ok_as_delegate, ok-as-delegate);
+ PRINT_FLAG(anonymous);
+ printf("\n");
+ printf("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("addressless");
+ }
+ printf("\n\n");
+}
+
+/*
+ * Print all tickets in `ccache' on stdout, verbosily iff do_verbose.
+ */
+
+static void
+print_tickets (krb5_context context,
+ krb5_ccache ccache,
+ krb5_principal principal,
+ int do_verbose,
+ int do_flags,
+ int do_hidden)
+{
+ krb5_error_code ret;
+ char *str;
+ krb5_cc_cursor cursor;
+ krb5_creds creds;
+ int32_t sec, usec;
+
+ rtbl_t ct = NULL;
+
+ ret = krb5_unparse_name (context, principal, &str);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_unparse_name");
+
+ printf ("%17s: %s:%s\n",
+ "Credentials cache",
+ krb5_cc_get_type(context, ccache),
+ krb5_cc_get_name(context, ccache));
+ printf ("%17s: %s\n", "Principal", str);
+ free (str);
+
+ if(do_verbose)
+ printf ("%17s: %d\n", "Cache version",
+ krb5_cc_get_version(context, ccache));
+
+ krb5_get_kdc_sec_offset(context, &sec, &usec);
+
+ if (do_verbose && sec != 0) {
+ char buf[BUFSIZ];
+ int val;
+ int sig;
+
+ val = sec;
+ sig = 1;
+ if (val < 0) {
+ sig = -1;
+ val = -val;
+ }
+
+ unparse_time (val, buf, sizeof(buf));
+
+ printf ("%17s: %s%s\n", "KDC time offset",
+ sig == -1 ? "-" : "", buf);
+ }
+
+ printf("\n");
+
+ ret = krb5_cc_start_seq_get (context, ccache, &cursor);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_cc_start_seq_get");
+
+ if(!do_verbose) {
+ ct = rtbl_create();
+ rtbl_add_column(ct, COL_ISSUED, 0);
+ rtbl_add_column(ct, COL_EXPIRES, 0);
+ if(do_flags)
+ rtbl_add_column(ct, COL_FLAGS, 0);
+ rtbl_add_column(ct, COL_PRINCIPAL, 0);
+ rtbl_set_separator(ct, " ");
+ }
+ while ((ret = krb5_cc_next_cred (context,
+ ccache,
+ &cursor,
+ &creds)) == 0) {
+ const char *str;
+ str = krb5_principal_get_comp_string(context, creds.server, 0);
+ if (!do_hidden && str && str[0] == '@') {
+ ;
+ }else if(do_verbose){
+ print_cred_verbose(context, &creds);
+ }else{
+ print_cred(context, &creds, ct, do_flags);
+ }
+ 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");
+ if(!do_verbose) {
+ rtbl_format(ct, stdout);
+ rtbl_destroy(ct);
+ }
+}
+
+/*
+ * Check if there's a tgt for the realm of `principal' and ccache and
+ * if so return 0, else 1
+ */
+
+static int
+check_for_tgt (krb5_context context,
+ krb5_ccache ccache,
+ krb5_principal principal,
+ time_t *expiration)
+{
+ krb5_error_code ret;
+ krb5_creds pattern;
+ krb5_creds creds;
+ krb5_realm *client_realm;
+ int expired;
+
+ krb5_cc_clear_mcred(&pattern);
+
+ client_realm = krb5_princ_realm (context, principal);
+
+ ret = krb5_make_principal (context, &pattern.server,
+ *client_realm, KRB5_TGS_NAME, *client_realm,
+ NULL);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_make_principal");
+ pattern.client = principal;
+
+ ret = krb5_cc_retrieve_cred (context, ccache, 0, &pattern, &creds);
+ krb5_free_principal (context, pattern.server);
+ if (ret) {
+ if (ret == KRB5_CC_END)
+ return 1;
+ krb5_err (context, 1, ret, "krb5_cc_retrieve_cred");
+ }
+
+ expired = time(NULL) > creds.times.endtime;
+
+ if (expiration)
+ *expiration = creds.times.endtime;
+
+ krb5_free_cred_contents (context, &creds);
+
+ return expired;
+}
+
+/*
+ * Print a list of all AFS tokens
+ */
+
+static void
+display_tokens(int do_verbose)
+{
+ uint32_t i;
+ unsigned char t[4096];
+ struct ViceIoctl parms;
+
+ parms.in = (void *)&i;
+ parms.in_size = sizeof(i);
+ parms.out = (void *)t;
+ parms.out_size = sizeof(t);
+
+ for (i = 0;; i++) {
+ int32_t size_secret_tok, size_public_tok;
+ unsigned char *cell;
+ struct ClearToken ct;
+ unsigned char *r = t;
+ struct timeval tv;
+ char buf1[20], buf2[20];
+
+ if(k_pioctl(NULL, VIOCGETTOK, &parms, 0) < 0) {
+ if(errno == EDOM)
+ break;
+ continue;
+ }
+ if(parms.out_size > sizeof(t))
+ continue;
+ if(parms.out_size < sizeof(size_secret_tok))
+ continue;
+ t[min(parms.out_size,sizeof(t)-1)] = 0;
+ memcpy(&size_secret_tok, r, sizeof(size_secret_tok));
+ /* dont bother about the secret token */
+ r += size_secret_tok + sizeof(size_secret_tok);
+ if (parms.out_size < (r - t) + sizeof(size_public_tok))
+ continue;
+ memcpy(&size_public_tok, r, sizeof(size_public_tok));
+ r += sizeof(size_public_tok);
+ if (parms.out_size < (r - t) + size_public_tok + sizeof(int32_t))
+ continue;
+ memcpy(&ct, r, size_public_tok);
+ r += size_public_tok;
+ /* there is a int32_t with length of cellname, but we dont read it */
+ r += sizeof(int32_t);
+ cell = r;
+
+ gettimeofday (&tv, NULL);
+ strlcpy (buf1, printable_time(ct.BeginTimestamp),
+ sizeof(buf1));
+ if (do_verbose || tv.tv_sec < ct.EndTimestamp)
+ strlcpy (buf2, printable_time(ct.EndTimestamp),
+ sizeof(buf2));
+ else
+ strlcpy (buf2, ">>> Expired <<<", sizeof(buf2));
+
+ printf("%s %s ", buf1, buf2);
+
+ if ((ct.EndTimestamp - ct.BeginTimestamp) & 1)
+ printf("User's (AFS ID %d) tokens for %s", ct.ViceId, cell);
+ else
+ printf("Tokens for %s", cell);
+ if (do_verbose)
+ printf(" (%d)", ct.AuthHandle);
+ putchar('\n');
+ }
+}
+
+/*
+ * display the ccache in `cred_cache'
+ */
+
+static int
+display_v5_ccache (const char *cred_cache, int do_test, int do_verbose,
+ int do_flags, int do_hidden)
+{
+ krb5_error_code ret;
+ krb5_context context;
+ krb5_ccache ccache;
+ krb5_principal principal;
+ int exit_status = 0;
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx (1, "krb5_init_context failed: %d", ret);
+
+ if(cred_cache) {
+ ret = krb5_cc_resolve(context, cred_cache, &ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "%s", cred_cache);
+ } else {
+ ret = krb5_cc_default (context, &ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_resolve");
+ }
+
+ ret = krb5_cc_get_principal (context, ccache, &principal);
+ if (ret) {
+ if(ret == ENOENT) {
+ if (!do_test)
+ krb5_warnx(context, "No ticket file: %s",
+ krb5_cc_get_name(context, ccache));
+ return 1;
+ } else
+ krb5_err (context, 1, ret, "krb5_cc_get_principal");
+ }
+ if (do_test)
+ exit_status = check_for_tgt (context, ccache, principal, NULL);
+ else
+ print_tickets (context, ccache, principal, do_verbose,
+ do_flags, do_hidden);
+
+ ret = krb5_cc_close (context, ccache);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_close");
+
+ krb5_free_principal (context, principal);
+ krb5_free_context (context);
+ return exit_status;
+}
+
+/*
+ *
+ */
+
+static int
+list_caches(void)
+{
+ krb5_cc_cache_cursor cursor;
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_ccache id;
+ rtbl_t ct;
+
+ ret = krb5_init_context (&context);
+ if (ret)
+ errx (1, "krb5_init_context failed: %d", ret);
+
+ ret = krb5_cc_cache_get_first (context, NULL, &cursor);
+ if (ret == KRB5_CC_NOSUPP)
+ return 0;
+ else if (ret)
+ krb5_err (context, 1, ret, "krb5_cc_cache_get_first");
+
+ ct = rtbl_create();
+ rtbl_add_column(ct, COL_PRINCIPAL, 0);
+ rtbl_add_column(ct, COL_CACHENAME, 0);
+ rtbl_add_column(ct, COL_EXPIRES, 0);
+ rtbl_set_prefix(ct, " ");
+ rtbl_set_column_prefix(ct, COL_PRINCIPAL, "");
+
+ while ((ret = krb5_cc_cache_next (context, cursor, &id)) == 0) {
+ krb5_principal principal;
+ char *name;
+
+ ret = krb5_cc_get_principal(context, id, &principal);
+ if (ret == 0) {
+ time_t t;
+ int expired = check_for_tgt (context, id, principal, &t);
+
+ ret = krb5_unparse_name(context, principal, &name);
+ if (ret == 0) {
+ rtbl_add_column_entry(ct, COL_PRINCIPAL, name);
+ rtbl_add_column_entry(ct, COL_CACHENAME,
+ krb5_cc_get_name(context, id));
+ rtbl_add_column_entry(ct, COL_EXPIRES,
+ expired ? ">>> Expired <<<" :
+ printable_time(t));
+ free(name);
+ krb5_free_principal(context, principal);
+ }
+ }
+ krb5_cc_close(context, id);
+ }
+
+ krb5_cc_cache_end_seq_get(context, cursor);
+
+ rtbl_format(ct, stdout);
+ rtbl_destroy(ct);
+
+ return 0;
+}
+
+/*
+ *
+ */
+
+static int version_flag = 0;
+static int help_flag = 0;
+static int do_verbose = 0;
+static int do_list_caches = 0;
+static int do_test = 0;
+static int do_tokens = 0;
+static int do_v5 = 1;
+static char *cred_cache;
+static int do_flags = 0;
+static int do_hidden = 0;
+
+static struct getargs args[] = {
+ { NULL, 'f', arg_flag, &do_flags },
+ { "cache", 'c', arg_string, &cred_cache,
+ "credentials cache to list", "cache" },
+ { "test", 't', arg_flag, &do_test,
+ "test for having tickets", NULL },
+ { NULL, 's', arg_flag, &do_test },
+ { "tokens", 'T', arg_flag, &do_tokens,
+ "display AFS tokens", NULL },
+ { "v5", '5', arg_flag, &do_v5,
+ "display v5 cred cache", NULL},
+ { "list-caches", 'l', arg_flag, &do_list_caches,
+ "verbose output", NULL },
+ { "verbose", 'v', arg_flag, &do_verbose,
+ "verbose output", NULL },
+ { "hidden", 0, arg_flag, &do_hidden,
+ "display hidden credentials", NULL },
+ { NULL, 'a', arg_flag, &do_verbose },
+ { NULL, 'n', arg_flag, &do_verbose },
+ { "version", 0, arg_flag, &version_flag,
+ "print version", NULL },
+ { "help", 0, arg_flag, &help_flag,
+ NULL, NULL}
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "");
+ exit (ret);
+}
+
+int
+main (int argc, char **argv)
+{
+ int optidx = 0;
+ int exit_status = 0;
+
+ setprogname (argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag){
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ if (argc != 0)
+ usage (1);
+
+ if (do_list_caches) {
+ exit_status = list_caches();
+ return exit_status;
+ }
+
+ if (do_v5)
+ exit_status = display_v5_ccache (cred_cache, do_test,
+ do_verbose, do_flags, do_hidden);
+
+ if (!do_test) {
+ if (do_tokens && k_hasafs ()) {
+ if (do_v5)
+ printf ("\n");
+ display_tokens (do_verbose);
+ }
+ }
+
+ return exit_status;
+}
diff --git a/kuser/kuser_locl.h b/kuser/kuser_locl.h
new file mode 100644
index 0000000000000..36ea01a9a59f3
--- /dev/null
+++ b/kuser/kuser_locl.h
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 1997 - 1999 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: kuser_locl.h 20458 2007-04-19 20:41:27Z lha $ */
+
+#ifndef __KUSER_LOCL_H__
+#define __KUSER_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+#ifdef HAVE_NETINET_IN6_H
+#include <netinet/in6.h>
+#endif
+#ifdef HAVE_NETINET6_IN6_H
+#include <netinet6/in6.h>
+#endif
+
+#ifdef HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#endif
+#include <roken.h>
+#include <getarg.h>
+#include <parse_time.h>
+#include <err.h>
+#include <krb5.h>
+
+#if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
+#include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_IOCCOM_H
+#include <sys/ioccom.h>
+#endif
+#include <kafs.h>
+#include "crypto-headers.h" /* for des_read_pw_string */
+
+#endif /* __KUSER_LOCL_H__ */
diff --git a/kuser/kverify.c b/kuser/kverify.c
new file mode 100644
index 0000000000000..888658d95294b
--- /dev/null
+++ b/kuser/kverify.c
@@ -0,0 +1,128 @@
+/*
+ * Copyright (c) 1997 - 2005, 2007 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"
+
+RCSID("$Id: kverify.c 19920 2007-01-15 23:21:32Z lha $");
+
+static int help_flag = 0;
+static int version_flag = 0;
+
+static struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag },
+ { "help", 0, arg_flag, &help_flag }
+};
+
+static void
+usage (int ret)
+{
+ arg_printusage (args,
+ sizeof(args)/sizeof(*args),
+ NULL,
+ "[principal]");
+ exit (ret);
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_context context;
+ krb5_error_code ret;
+ krb5_creds cred;
+ krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
+ krb5_get_init_creds_opt *get_options;
+ krb5_verify_init_creds_opt verify_options;
+ krb5_principal principal = NULL;
+ int optidx = 0;
+
+ setprogname (argv[0]);
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
+ usage(1);
+
+ if (help_flag)
+ usage (0);
+
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optidx;
+ argv += optidx;
+
+ ret = krb5_init_context(&context);
+ if (ret)
+ errx (1, "krb5_init_context failed: %d", ret);
+
+ ret = krb5_get_init_creds_opt_alloc (context, &get_options);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");
+
+ krb5_get_init_creds_opt_set_preauth_list (get_options,
+ pre_auth_types,
+ 1);
+
+ krb5_verify_init_creds_opt_init (&verify_options);
+
+ if (argc) {
+ ret = krb5_parse_name(context, argv[0], &principal);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_parse_name: %s", argv[0]);
+ }
+
+ ret = krb5_get_init_creds_password (context,
+ &cred,
+ principal,
+ NULL,
+ krb5_prompter_posix,
+ NULL,
+ 0,
+ NULL,
+ get_options);
+ if (ret)
+ errx (1, "krb5_get_init_creds: %s", krb5_get_err_text(context, ret));
+
+ ret = krb5_verify_init_creds (context,
+ &cred,
+ NULL,
+ NULL,
+ NULL,
+ &verify_options);
+ if (ret)
+ errx (1, "krb5_verify_init_creds: %s",
+ krb5_get_err_text(context, ret));
+ krb5_free_cred_contents (context, &cred);
+ krb5_free_context (context);
+ return 0;
+}