summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/kadmin
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/heimdal/kadmin')
-rw-r--r--crypto/heimdal/kadmin/ChangeLog212
-rw-r--r--crypto/heimdal/kadmin/Makefile.am55
-rw-r--r--crypto/heimdal/kadmin/Makefile.in702
-rw-r--r--crypto/heimdal/kadmin/ank.c266
-rw-r--r--crypto/heimdal/kadmin/cpw.c177
-rw-r--r--crypto/heimdal/kadmin/del.c53
-rw-r--r--crypto/heimdal/kadmin/del_enctype.c132
-rw-r--r--crypto/heimdal/kadmin/dump.c80
-rw-r--r--crypto/heimdal/kadmin/ext.c116
-rw-r--r--crypto/heimdal/kadmin/get.c250
-rw-r--r--crypto/heimdal/kadmin/init.c210
-rw-r--r--crypto/heimdal/kadmin/kadmin.c281
-rw-r--r--crypto/heimdal/kadmin/kadmin_locl.h161
-rw-r--r--crypto/heimdal/kadmin/kadmind.c151
-rw-r--r--crypto/heimdal/kadmin/load.c335
-rw-r--r--crypto/heimdal/kadmin/mod.c143
-rw-r--r--crypto/heimdal/kadmin/random_password.c156
-rw-r--r--crypto/heimdal/kadmin/rename.c66
-rw-r--r--crypto/heimdal/kadmin/server.c506
-rw-r--r--crypto/heimdal/kadmin/util.c520
-rw-r--r--crypto/heimdal/kadmin/version4.c985
21 files changed, 5557 insertions, 0 deletions
diff --git a/crypto/heimdal/kadmin/ChangeLog b/crypto/heimdal/kadmin/ChangeLog
new file mode 100644
index 0000000..542667e
--- /dev/null
+++ b/crypto/heimdal/kadmin/ChangeLog
@@ -0,0 +1,212 @@
+2000-01-02 Assar Westerlund <assar@sics.se>
+
+ * server.c: check initial flag in ticket and allow users to change
+ their own password if it's set
+ * ext.c (do_ext_keytab): set timestamp
+
+1999-12-14 Assar Westerlund <assar@sics.se>
+
+ * del_enctype.c (usage): don't use arg_printusage
+
+1999-11-25 Assar Westerlund <assar@sics.se>
+
+ * del_enctype.c (del_enctype): try not to leak memory
+
+ * version4.c (kadm_ser_mod): use kadm5_s_modify_principal (no
+ _with_key)
+
+ * kadmin.c: add `del_enctype'
+
+ * del_enctype.c (del_enctype): new function for deleting enctypes
+ from a principal
+
+ * Makefile.am (kadmin_SOURCES): add del_enctype.c
+
+1999-11-09 Johan Danielsson <joda@pdc.kth.se>
+
+ * server.c: cope with old clients
+
+ * kadmin_locl.h: remove version string
+
+1999-10-17 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (kadmin_LDADD): add LIB_dlopen
+
+1999-10-01 Assar Westerlund <assar@sics.se>
+
+ * ank.c (add_one_principal): `password' can cactually be NULL in
+ the overwrite code, check for it.
+
+1999-09-20 Assar Westerlund <assar@sics.se>
+
+ * mod.c (mod_entry): print the correct principal name in error
+ messages. From Love <lha@e.kth.se>
+
+1999-09-10 Assar Westerlund <assar@sics.se>
+
+ * init.c (init): also create `changepw/kerberos'
+
+ * version4.c: only create you loose packets when we fail decoding
+ and not when an operation is not performed for some reason
+ (decode_packet): read the service key from the hdb
+ (dispatch, decode_packet): return proper error messages
+
+ * version4.c (kadm_ser_cpw): add password quality functions
+
+1999-08-27 Johan Danielsson <joda@pdc.kth.se>
+
+ * server.c (handle_v5): give more informative message if
+ KRB5_KT_NOTFOUND
+
+1999-08-26 Johan Danielsson <joda@pdc.kth.se>
+
+ * kadmind.c: use HDB keytabs
+
+1999-08-25 Assar Westerlund <assar@sics.se>
+
+ * cpw.c (set_password): use correct variable. From Love
+ <lha@e.kth.se>
+
+ * server.c (v5_loop): use correct error code
+
+ * ank.c (add_one_principal): initialize `default_ent'
+
+1999-08-21 Assar Westerlund <assar@sics.se>
+
+ * random_password.c: new file, stolen from krb4
+
+ * kadmin_locl.h: add prototype for random_password
+
+ * cpw.c: add support for --random-password
+
+ * ank.c: add support for --random-password
+
+ * Makefile.am (kadmin_SOURCES): add random_password.c
+
+1999-08-19 Assar Westerlund <assar@sics.se>
+
+ * util.c (edit_timet): break when we manage to parse the time not
+ the inverse.
+
+ * mod.c: add parsing of lots of options. From Love
+ <lha@stacken.kth.se>
+
+ * ank.c: add setting of expiration and password expiration
+
+ * kadmin_locl.h: update util.c prototypes
+
+ * util.c: move-around. clean-up, rename, make consistent (and
+ some other weird stuff). based on patches from Love
+ <lha@stacken.kth.se>
+
+ * version4.c (kadm_ser_cpw): initialize password
+ (handle_v4): remove unused variable `ret'
+
+1999-08-16 Assar Westerlund <assar@sics.se>
+
+ * version4.c (handle_v4): more error checking and more correct
+ error messages
+
+ * server.c (v5_loop, kadmind_loop): more error checking and more
+ correct error messages
+
+1999-07-24 Assar Westerlund <assar@sics.se>
+
+ * util.c (str2timeval, edit_time): functions for parsing and
+ editing times. Based on patches from Love <lha@stacken.kth.se>.
+ (edit_entry): call new functions
+
+ * mod.c (mod_entry): allow modifying expiration times
+
+ * kadmin_locl.h (str2timeval): add prototype
+
+ * ank.c (add_one_principal): allow setting expiration times
+
+1999-07-03 Assar Westerlund <assar@sics.se>
+
+ * server.c (v5_loop): handle data allocation with krb5_data_alloc
+ and check return value
+
+1999-06-23 Assar Westerlund <assar@sics.se>
+
+ * version4.c (kadm_ser_cpw): read the key in the strange order
+ it's sent
+
+ * util.c (edit_entry): look at default
+ (edit_time): always set mask even if value == 0
+
+ * kadmin_locl.h (edit_entry): update
+
+ * ank.c: make ank use the values of the default principal for
+ prompting
+
+ * version4.c (values_to_ent): convert key data correctly
+
+1999-05-23 Assar Westerlund <assar@sics.se>
+
+ * init.c (create_random_entry): more correct setting of mask
+
+1999-05-21 Assar Westerlund <assar@sics.se>
+
+ * server.c (handle_v5): read sendauth version correctly.
+
+1999-05-14 Assar Westerlund <assar@sics.se>
+
+ * version4.c (error_code): try to handle really old krb4
+ distributions
+
+1999-05-11 Assar Westerlund <assar@sics.se>
+
+ * init.c (init): initialize realm_max_life and realm_max_rlife
+
+1999-05-07 Assar Westerlund <assar@sics.se>
+
+ * ank.c (add_new_key): initialize more variables
+
+1999-05-04 Assar Westerlund <assar@sics.se>
+
+ * version4.c (kadm_ser_cpw): always allow a user to change her
+ password
+ (kadm_ser_*): make logging work
+ clean-up and restructure
+
+ * kadmin_locl.h (set_entry): add prototype
+
+ * kadmin.c (usage): update usage string
+
+ * init.c (init): new arguments realm-max-ticket-life and
+ realm-max-renewable-life
+
+ * util.c (edit_time, edit_attributes): don't do anything if it's
+ already set
+ (set_entry): new function
+
+ * ank.c (add_new_key): new options for setting max-ticket-life,
+ max-renewable-life, and attributes
+
+ * server.c (v5_loop): remove unused variable
+
+ * kadmin_locl.h: add prototypes
+
+ * version4.c: re-insert krb_err.h and other miss
+
+ * server.c (kadmind_loop): break-up and restructure
+
+ * version4.c: add ACL checks more error code checks restructure
+
+1999-05-03 Johan Danielsson <joda@pdc.kth.se>
+
+ * load.c: check for (un-)encrypted keys
+
+ * dump.c: use hdb_print_entry
+
+ * version4.c: version 4 support
+
+ * Makefile.am: link with krb4
+
+ * kadmin_locl.h: include <sys/un.h>
+
+ * server.c: move from lib/kadm5, and add basic support for krb4
+ kadmin protocol
+
+ * kadmind.c: move recvauth to kadmind_loop()
diff --git a/crypto/heimdal/kadmin/Makefile.am b/crypto/heimdal/kadmin/Makefile.am
new file mode 100644
index 0000000..2bafb55
--- /dev/null
+++ b/crypto/heimdal/kadmin/Makefile.am
@@ -0,0 +1,55 @@
+# $Id: Makefile.am,v 1.25 2000/01/06 08:04:13 assar Exp $
+
+include $(top_srcdir)/Makefile.am.common
+
+INCLUDES += $(INCLUDE_readline) $(INCLUDE_krb4)
+
+sbin_PROGRAMS = kadmin
+
+libexec_PROGRAMS = kadmind
+
+kadmin_SOURCES = \
+ ank.c \
+ cpw.c \
+ del.c \
+ del_enctype.c \
+ dump.c \
+ ext.c \
+ get.c \
+ init.c \
+ kadmin.c \
+ load.c \
+ mod.c \
+ rename.c \
+ util.c \
+ random_password.c \
+ kadmin_locl.h
+
+if KRB4
+KRB4LIB = $(LIB_krb4)
+version4_c = version4.c
+endif
+
+kadmind_SOURCES = kadmind.c server.c kadmin_locl.h $(version4_c)
+
+EXTRA_kadmind_SOURCES = version4.c
+
+COMMON_LDADD = \
+ $(top_builddir)/lib/hdb/libhdb.la \
+ $(top_builddir)/lib/krb5/libkrb5.la \
+ $(top_builddir)/lib/des/libdes.la \
+ $(top_builddir)/lib/asn1/libasn1.la \
+ $(LIB_roken) \
+ $(DBLIB)
+
+kadmind_LDADD = $(KRB4LIB) $(top_builddir)/lib/kadm5/libkadm5srv.la \
+ $(COMMON_LDADD) \
+ $(LIB_dlopen)
+
+kadmin_LDADD = \
+ $(top_builddir)/lib/kadm5/libkadm5clnt.la \
+ $(top_builddir)/lib/kadm5/libkadm5srv.la \
+ $(top_builddir)/lib/sl/libsl.la \
+ $(LIB_readline) \
+ $(COMMON_LDADD) \
+ $(LIB_dlopen)
diff --git a/crypto/heimdal/kadmin/Makefile.in b/crypto/heimdal/kadmin/Makefile.in
new file mode 100644
index 0000000..b7fa775
--- /dev/null
+++ b/crypto/heimdal/kadmin/Makefile.in
@@ -0,0 +1,702 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 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.
+
+# $Id: Makefile.am,v 1.25 2000/01/06 08:04:13 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AFS_EXTRA_LD = @AFS_EXTRA_LD@
+AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AWK = @AWK@
+CANONICAL_HOST = @CANONICAL_HOST@
+CATMAN = @CATMAN@
+CATMANEXT = @CATMANEXT@
+CC = @CC@
+DBLIB = @DBLIB@
+EXEEXT = @EXEEXT@
+EXTRA_LIB45 = @EXTRA_LIB45@
+GROFF = @GROFF@
+INCLUDE_ = @INCLUDE_@
+LD = @LD@
+LEX = @LEX@
+LIBOBJS = @LIBOBJS@
+LIBTOOL = @LIBTOOL@
+LIB_ = @LIB_@
+LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_kdb = @LIB_kdb@
+LIB_otp = @LIB_otp@
+LIB_roken = @LIB_roken@
+LIB_security = @LIB_security@
+LN_S = @LN_S@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
+MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
+MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
+NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
+NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
+NM = @NM@
+NROFF = @NROFF@
+OBJEXT = @OBJEXT@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
+WFLAGS = @WFLAGS@
+WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
+WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
+YACC = @YACC@
+
+AUTOMAKE_OPTIONS = foreign no-dependencies
+
+SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
+
+INCLUDES = -I$(top_builddir)/include $(INCLUDE_readline) $(INCLUDE_krb4)
+
+AM_CFLAGS = $(WFLAGS)
+
+COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
+
+buildinclude = $(top_builddir)/include
+
+LIB_XauReadAuth = @LIB_XauReadAuth@
+LIB_crypt = @LIB_crypt@
+LIB_dbm_firstkey = @LIB_dbm_firstkey@
+LIB_dbopen = @LIB_dbopen@
+LIB_dlopen = @LIB_dlopen@
+LIB_dn_expand = @LIB_dn_expand@
+LIB_el_init = @LIB_el_init@
+LIB_getattr = @LIB_getattr@
+LIB_gethostbyname = @LIB_gethostbyname@
+LIB_getpwent_r = @LIB_getpwent_r@
+LIB_getpwnam_r = @LIB_getpwnam_r@
+LIB_getsockopt = @LIB_getsockopt@
+LIB_logout = @LIB_logout@
+LIB_logwtmp = @LIB_logwtmp@
+LIB_odm_initialize = @LIB_odm_initialize@
+LIB_readline = @LIB_readline@
+LIB_res_search = @LIB_res_search@
+LIB_setpcred = @LIB_setpcred@
+LIB_setsockopt = @LIB_setsockopt@
+LIB_socket = @LIB_socket@
+LIB_syslog = @LIB_syslog@
+LIB_tgetent = @LIB_tgetent@
+
+HESIODLIB = @HESIODLIB@
+HESIODINCLUDE = @HESIODINCLUDE@
+INCLUDE_hesiod = @INCLUDE_hesiod@
+LIB_hesiod = @LIB_hesiod@
+
+INCLUDE_krb4 = @INCLUDE_krb4@
+LIB_krb4 = @LIB_krb4@
+
+INCLUDE_readline = @INCLUDE_readline@
+
+LEXLIB = @LEXLIB@
+
+cat1dir = $(mandir)/cat1
+cat3dir = $(mandir)/cat3
+cat5dir = $(mandir)/cat5
+cat8dir = $(mandir)/cat8
+
+MANRX = \(.*\)\.\([0-9]\)
+CATSUFFIX = @CATSUFFIX@
+
+NROFF_MAN = groff -mandoc -Tascii
+
+@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+
+@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+
+CHECK_LOCAL = $(PROGRAMS)
+
+sbin_PROGRAMS = kadmin
+
+libexec_PROGRAMS = kadmind
+
+kadmin_SOURCES = ank.c cpw.c del.c del_enctype.c dump.c ext.c get.c init.c kadmin.c load.c mod.c rename.c util.c random_password.c kadmin_locl.h
+
+
+@KRB4_TRUE@KRB4LIB = $(LIB_krb4)
+@KRB4_TRUE@version4_c = version4.c
+
+kadmind_SOURCES = kadmind.c server.c kadmin_locl.h $(version4_c)
+
+EXTRA_kadmind_SOURCES = version4.c
+
+COMMON_LDADD = $(top_builddir)/lib/hdb/libhdb.la $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la $(top_builddir)/lib/asn1/libasn1.la $(LIB_roken) $(DBLIB)
+
+
+kadmind_LDADD = $(KRB4LIB) $(top_builddir)/lib/kadm5/libkadm5srv.la $(COMMON_LDADD) $(LIB_dlopen)
+
+
+kadmin_LDADD = $(top_builddir)/lib/kadm5/libkadm5clnt.la $(top_builddir)/lib/kadm5/libkadm5srv.la $(top_builddir)/lib/sl/libsl.la $(LIB_readline) $(COMMON_LDADD) $(LIB_dlopen)
+
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = ../include/config.h
+CONFIG_CLEAN_FILES =
+libexec_PROGRAMS = kadmind$(EXEEXT)
+sbin_PROGRAMS = kadmin$(EXEEXT)
+PROGRAMS = $(libexec_PROGRAMS) $(sbin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir) -I../include
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+X_CFLAGS = @X_CFLAGS@
+X_LIBS = @X_LIBS@
+X_EXTRA_LIBS = @X_EXTRA_LIBS@
+X_PRE_LIBS = @X_PRE_LIBS@
+@KRB4_TRUE@kadmind_OBJECTS = kadmind.$(OBJEXT) server.$(OBJEXT) \
+@KRB4_TRUE@version4.$(OBJEXT)
+@KRB4_FALSE@kadmind_OBJECTS = kadmind.$(OBJEXT) server.$(OBJEXT)
+@KRB4_TRUE@kadmind_DEPENDENCIES = \
+@KRB4_TRUE@$(top_builddir)/lib/kadm5/libkadm5srv.la \
+@KRB4_TRUE@$(top_builddir)/lib/hdb/libhdb.la \
+@KRB4_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_TRUE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_TRUE@$(top_builddir)/lib/asn1/libasn1.la
+@KRB4_FALSE@kadmind_DEPENDENCIES = \
+@KRB4_FALSE@$(top_builddir)/lib/kadm5/libkadm5srv.la \
+@KRB4_FALSE@$(top_builddir)/lib/hdb/libhdb.la \
+@KRB4_FALSE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB4_FALSE@$(top_builddir)/lib/des/libdes.la \
+@KRB4_FALSE@$(top_builddir)/lib/asn1/libasn1.la
+kadmind_LDFLAGS =
+kadmin_OBJECTS = ank.$(OBJEXT) cpw.$(OBJEXT) del.$(OBJEXT) \
+del_enctype.$(OBJEXT) dump.$(OBJEXT) ext.$(OBJEXT) get.$(OBJEXT) \
+init.$(OBJEXT) kadmin.$(OBJEXT) load.$(OBJEXT) mod.$(OBJEXT) \
+rename.$(OBJEXT) util.$(OBJEXT) random_password.$(OBJEXT)
+kadmin_DEPENDENCIES = $(top_builddir)/lib/kadm5/libkadm5clnt.la \
+$(top_builddir)/lib/kadm5/libkadm5srv.la \
+$(top_builddir)/lib/sl/libsl.la $(top_builddir)/lib/hdb/libhdb.la \
+$(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/des/libdes.la \
+$(top_builddir)/lib/asn1/libasn1.la
+kadmin_LDFLAGS =
+CFLAGS = @CFLAGS@
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = ChangeLog Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = tar
+GZIP_ENV = --best
+SOURCES = $(kadmind_SOURCES) $(EXTRA_kadmind_SOURCES) $(kadmin_SOURCES)
+OBJECTS = $(kadmind_OBJECTS) $(kadmin_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
+ cd $(top_srcdir) && $(AUTOMAKE) --foreign kadmin/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libexecPROGRAMS:
+
+clean-libexecPROGRAMS:
+ -test -z "$(libexec_PROGRAMS)" || rm -f $(libexec_PROGRAMS)
+
+distclean-libexecPROGRAMS:
+
+maintainer-clean-libexecPROGRAMS:
+
+install-libexecPROGRAMS: $(libexec_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir)
+ @list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-libexecPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(libexec_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(libexecdir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+mostlyclean-sbinPROGRAMS:
+
+clean-sbinPROGRAMS:
+ -test -z "$(sbin_PROGRAMS)" || rm -f $(sbin_PROGRAMS)
+
+distclean-sbinPROGRAMS:
+
+maintainer-clean-sbinPROGRAMS:
+
+install-sbinPROGRAMS: $(sbin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(sbindir)
+ @list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-sbinPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(sbin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(sbindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.c.o:
+ $(COMPILE) -c $<
+
+# FIXME: We should only use cygpath when building on Windows,
+# and only if it is available.
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+ -rm -f *.$(OBJEXT)
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.c.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+kadmind$(EXEEXT): $(kadmind_OBJECTS) $(kadmind_DEPENDENCIES)
+ @rm -f kadmind$(EXEEXT)
+ $(LINK) $(kadmind_LDFLAGS) $(kadmind_OBJECTS) $(kadmind_LDADD) $(LIBS)
+
+kadmin$(EXEEXT): $(kadmin_OBJECTS) $(kadmin_DEPENDENCIES)
+ @rm -f kadmin$(EXEEXT)
+ $(LINK) $(kadmin_LDFLAGS) $(kadmin_OBJECTS) $(kadmin_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = kadmin
+
+distdir: $(DISTFILES)
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ $(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-local
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libexecPROGRAMS install-sbinPROGRAMS
+ @$(NORMAL_INSTALL)
+ $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
+install-exec: install-exec-am
+
+install-data-am: install-data-local
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libexecPROGRAMS uninstall-sbinPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS) all-local
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libexecdir) $(DESTDIR)$(sbindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libexecPROGRAMS mostlyclean-sbinPROGRAMS \
+ mostlyclean-compile mostlyclean-libtool \
+ mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libexecPROGRAMS clean-sbinPROGRAMS clean-compile \
+ clean-libtool clean-tags clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libexecPROGRAMS distclean-sbinPROGRAMS \
+ distclean-compile distclean-libtool distclean-tags \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libexecPROGRAMS \
+ maintainer-clean-sbinPROGRAMS maintainer-clean-compile \
+ maintainer-clean-libtool maintainer-clean-tags \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libexecPROGRAMS distclean-libexecPROGRAMS \
+clean-libexecPROGRAMS maintainer-clean-libexecPROGRAMS \
+uninstall-libexecPROGRAMS install-libexecPROGRAMS \
+mostlyclean-sbinPROGRAMS distclean-sbinPROGRAMS clean-sbinPROGRAMS \
+maintainer-clean-sbinPROGRAMS uninstall-sbinPROGRAMS \
+install-sbinPROGRAMS mostlyclean-compile distclean-compile \
+clean-compile maintainer-clean-compile mostlyclean-libtool \
+distclean-libtool clean-libtool maintainer-clean-libtool tags \
+mostlyclean-tags distclean-tags clean-tags maintainer-clean-tags \
+distdir info-am info dvi-am dvi check-local check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-local install-data-am install-data install-am install \
+uninstall-am uninstall all-local all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+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 \
+ chmod 0 $$x; fi; done
+
+install-exec-hook: install-suid-programs
+
+install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
+ @foo='$(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
+
+all-local: install-build-headers
+#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-cat1-mans:
+ @ext=1;\
+ foo='$(man1_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.1) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat3-mans:
+ @ext=3;\
+ foo='$(man3_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.3) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat5-mans:
+ @ext=5;\
+ foo='$(man5_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.5) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat8-mans:
+ @ext=8;\
+ foo='$(man8_MANS)'; \
+ bar='$(man_MANS)'; \
+ for i in $$bar; do \
+ case $$i in \
+ *.8) foo="$$foo $$i";; \
+ esac; done; \
+ if test "$$foo"; then \
+ $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
+ for x in $$foo; do \
+ f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
+ if test -f "$(srcdir)/$$f"; then \
+ b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
+ echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
+ $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
+ fi; \
+ done ;\
+ fi
+
+install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+
+install-data-local: install-cat-mans
+
+.et.h:
+ $(COMPILE_ET) $<
+.et.c:
+ $(COMPILE_ET) $<
+
+.x.c:
+ @cmp -s $< $@ 2> /dev/null || cp $< $@
+
+check-local::
+ @foo='$(CHECK_LOCAL)'; \
+ if test "$$foo"; then \
+ failed=0; all=0; \
+ for i in $$foo; do \
+ all=`expr $$all + 1`; \
+ if ./$$i --version > /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; \
+ fi
+
+# 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/crypto/heimdal/kadmin/ank.c b/crypto/heimdal/kadmin/ank.c
new file mode 100644
index 0000000..7068912
--- /dev/null
+++ b/crypto/heimdal/kadmin/ank.c
@@ -0,0 +1,266 @@
+/*
+ * 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: ank.c,v 1.19 1999/12/02 17:04:57 joda Exp $");
+
+/*
+ * fetch the default principal corresponding to `princ'
+ */
+
+static krb5_error_code
+get_default (kadm5_server_context *context,
+ krb5_principal princ,
+ kadm5_principal_ent_t default_ent)
+{
+ krb5_error_code ret;
+ krb5_principal def_principal;
+ krb5_realm *realm = krb5_princ_realm(context->context, princ);
+
+ ret = krb5_make_principal (context->context, &def_principal,
+ *realm, "default", NULL);
+ if (ret)
+ return ret;
+ ret = kadm5_get_principal (context, def_principal, default_ent,
+ KADM5_PRINCIPAL_NORMAL_MASK);
+ krb5_free_principal (context->context, def_principal);
+ return ret;
+}
+
+/*
+ * Add the principal `name' to the database.
+ * Prompt for all data not given by the input parameters.
+ */
+
+static krb5_error_code
+add_one_principal (const char *name,
+ int rand_key,
+ int rand_password,
+ char *password,
+ const char *max_ticket_life,
+ const char *max_renewable_life,
+ const char *attributes,
+ const char *expiration,
+ const char *pw_expiration)
+{
+ krb5_error_code ret;
+ kadm5_principal_ent_rec princ, defrec;
+ kadm5_principal_ent_rec *default_ent = NULL;
+ krb5_principal princ_ent = NULL;
+ int mask = 0;
+ int default_mask = 0;
+ char pwbuf[1024];
+
+ memset(&princ, 0, sizeof(princ));
+ ret = krb5_parse_name(context, name, &princ_ent);
+ if (ret) {
+ krb5_warn(context, ret, "krb5_parse_name");
+ return ret;
+ }
+ princ.principal = princ_ent;
+ mask |= KADM5_PRINCIPAL;
+
+ ret = set_entry(context, &princ, &mask,
+ max_ticket_life, max_renewable_life,
+ expiration, pw_expiration, attributes);
+ if (ret)
+ goto out;
+
+ default_ent = &defrec;
+ ret = get_default (kadm_handle, princ_ent, default_ent);
+ if (ret) {
+ default_ent = NULL;
+ default_mask = 0;
+ } else {
+ default_mask = KADM5_ATTRIBUTES | KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
+ KADM5_PRINC_EXPIRE_TIME | KADM5_PW_EXPIRATION;
+ }
+
+ edit_entry(&princ, &mask, default_ent, default_mask);
+ if(rand_key) {
+ princ.attributes |= KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+ strlcpy (pwbuf, "hemlig", sizeof(pwbuf));
+ password = pwbuf;
+ } else if (rand_password) {
+ random_password (pwbuf, sizeof(pwbuf));
+ password = pwbuf;
+ } else if(password == NULL) {
+ char *princ_name;
+ char *prompt;
+
+ krb5_unparse_name(context, princ_ent, &princ_name);
+ asprintf (&prompt, "%s's Password: ", princ_name);
+ free (princ_name);
+ ret = des_read_pw_string (pwbuf, sizeof(pwbuf), prompt, 1);
+ free (prompt);
+ if (ret)
+ goto out;
+ password = pwbuf;
+ }
+
+ ret = kadm5_create_principal(kadm_handle, &princ, mask, password);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_create_principal");
+ if(rand_key) {
+ krb5_keyblock *new_keys;
+ int n_keys, i;
+ ret = kadm5_randkey_principal(kadm_handle, princ_ent,
+ &new_keys, &n_keys);
+ if(ret){
+ krb5_warn(context, ret, "kadm5_randkey_principal");
+ n_keys = 0;
+ }
+ for(i = 0; i < n_keys; i++)
+ krb5_free_keyblock_contents(context, &new_keys[i]);
+ free(new_keys);
+ kadm5_get_principal(kadm_handle, princ_ent, &princ,
+ KADM5_PRINCIPAL | KADM5_KVNO | KADM5_ATTRIBUTES);
+ princ.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
+ princ.kvno = 1;
+ kadm5_modify_principal(kadm_handle, &princ,
+ KADM5_ATTRIBUTES | KADM5_KVNO);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ } else if (rand_password) {
+ char *princ_name;
+
+ krb5_unparse_name(context, princ_ent, &princ_name);
+ printf ("added %s with password `%s'\n", princ_name, password);
+ free (princ_name);
+ }
+out:
+ if (princ_ent)
+ krb5_free_principal (context, princ_ent);
+ if(default_ent)
+ kadm5_free_principal_ent (context, default_ent);
+ if (password != NULL)
+ memset (password, 0, strlen(password));
+ return ret;
+}
+
+/*
+ * the ank command
+ */
+
+static struct getargs args[] = {
+ { "random-key", 'r', arg_flag, NULL, "set random key" },
+ { "random-password", 0, arg_flag, NULL, "set random password" },
+ { "password", 'p', arg_string, NULL, "princial's password" },
+ { "max-ticket-life", 0, arg_string, NULL, "max ticket lifetime",
+ "lifetime"},
+ { "max-renewable-life", 0, arg_string, NULL,
+ "max renewable lifetime", "lifetime" },
+ { "attributes", 0, arg_string, NULL, "principal attributes",
+ "attributes"},
+ { "expiration-time",0, arg_string, NULL, "Expiration time",
+ "time"},
+ { "pw-expiration-time", 0, arg_string, NULL,
+ "Password expiration time", "time"}
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage (args, num_args, "ank", "principal");
+}
+
+/*
+ * Parse arguments and add all the principals.
+ */
+
+int
+add_new_key(int argc, char **argv)
+{
+ char *password = NULL;
+ int random_key = 0;
+ int random_password = 0;
+ int optind = 0;
+ krb5_error_code ret;
+ char *max_ticket_life = NULL;
+ char *max_renewable_life = NULL;
+ char *attributes = NULL;
+ char *expiration = NULL;
+ char *pw_expiration = NULL;
+ int i;
+ int num;
+
+ args[0].value = &random_key;
+ args[1].value = &random_password;
+ args[2].value = &password;
+ args[3].value = &max_ticket_life;
+ args[4].value = &max_renewable_life;
+ args[5].value = &attributes;
+ args[6].value = &expiration;
+ args[7].value = &pw_expiration;
+
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ usage ();
+ return 0;
+ }
+ if(optind == argc) {
+ usage ();
+ return 0;
+ }
+
+ num = 0;
+ if (random_key)
+ ++num;
+ if (random_password)
+ ++num;
+ if (password)
+ ++num;
+
+ if (num > 1) {
+ printf ("give only one of "
+ "--random-key, --random-password, --password\n");
+ return 0;
+ }
+
+ for (i = optind; i < argc; ++i) {
+ ret = add_one_principal (argv[i], random_key, random_password,
+ password,
+ max_ticket_life,
+ max_renewable_life,
+ attributes,
+ expiration,
+ pw_expiration);
+ if (ret) {
+ krb5_warn (context, ret, "adding %s", argv[i]);
+ break;
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/cpw.c b/crypto/heimdal/kadmin/cpw.c
new file mode 100644
index 0000000..2bd71a7
--- /dev/null
+++ b/crypto/heimdal/kadmin/cpw.c
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: cpw.c,v 1.9 1999/12/02 17:04:57 joda Exp $");
+
+struct cpw_entry_data {
+ int random_key;
+ int random_password;
+ char *password;
+};
+
+static struct getargs args[] = {
+ { "random-key", 'r', arg_flag, NULL, "set random key" },
+ { "random-password", 0, arg_flag, NULL, "set random password" },
+ { "password", 'p', arg_string, NULL, "princial's password" },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage(args, num_args, "cpw", "principal...");
+}
+
+static int
+set_random_key (krb5_principal principal)
+{
+ krb5_error_code ret;
+ int i;
+ krb5_keyblock *keys;
+ int num_keys;
+
+ ret = kadm5_randkey_principal(kadm_handle, principal, &keys, &num_keys);
+ if(ret)
+ return ret;
+ for(i = 0; i < num_keys; i++)
+ krb5_free_keyblock_contents(context, &keys[i]);
+ free(keys);
+ return 0;
+}
+
+static int
+set_random_password (krb5_principal principal)
+{
+ krb5_error_code ret;
+ char pw[128];
+
+ random_password (pw, sizeof(pw));
+ ret = kadm5_chpass_principal(kadm_handle, principal, pw);
+ if (ret == 0) {
+ char *princ_name;
+
+ krb5_unparse_name(context, principal, &princ_name);
+
+ printf ("%s's password set to `%s'\n", princ_name, pw);
+ free (princ_name);
+ }
+ memset (pw, 0, sizeof(pw));
+ return ret;
+}
+
+static int
+set_password (krb5_principal principal, char *password)
+{
+ krb5_error_code ret = 0;
+ char pwbuf[128];
+
+ if(password == NULL) {
+ char *princ_name;
+ char *prompt;
+
+ krb5_unparse_name(context, principal, &princ_name);
+ asprintf(&prompt, "%s's Password: ", princ_name);
+ free (princ_name);
+ ret = des_read_pw_string(pwbuf, sizeof(pwbuf), prompt, 1);
+ free (prompt);
+ if(ret){
+ return 0; /* XXX error code? */
+ }
+ password = pwbuf;
+ }
+ if(ret == 0)
+ ret = kadm5_chpass_principal(kadm_handle, principal, password);
+ memset(pwbuf, 0, sizeof(pwbuf));
+ return ret;
+}
+
+static int
+do_cpw_entry(krb5_principal principal, void *data)
+{
+ struct cpw_entry_data *e = data;
+
+ if (e->random_key)
+ return set_random_key (principal);
+ else if (e->random_password)
+ return set_random_password (principal);
+ else
+ return set_password (principal, e->password);
+}
+
+int
+cpw_entry(int argc, char **argv)
+{
+ krb5_error_code ret;
+ int i;
+ int optind = 0;
+ struct cpw_entry_data data;
+ int num;
+
+ data.random_key = 0;
+ data.random_password = 0;
+ data.password = NULL;
+
+ args[0].value = &data.random_key;
+ args[1].value = &data.random_password;
+ args[2].value = &data.password;
+ if(getarg(args, num_args, argc, argv, &optind)){
+ usage();
+ return 0;
+ }
+
+ num = 0;
+ if (data.random_key)
+ ++num;
+ if (data.random_password)
+ ++num;
+ if (data.password)
+ ++num;
+
+ if (num > 1) {
+ printf ("give only one of "
+ "--random-key, --random-password, --password\n");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ for(i = 0; i < argc; i++)
+ ret = foreach_principal(argv[i], do_cpw_entry, &data);
+
+ return 0;
+}
+
diff --git a/crypto/heimdal/kadmin/del.c b/crypto/heimdal/kadmin/del.c
new file mode 100644
index 0000000..39ee24e
--- /dev/null
+++ b/crypto/heimdal/kadmin/del.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 1997, 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 "kadmin_locl.h"
+
+RCSID("$Id: del.c,v 1.4 1999/12/02 17:04:58 joda Exp $");
+
+static int
+do_del_entry(krb5_principal principal, void *data)
+{
+ return kadm5_delete_principal(kadm_handle, principal);
+}
+
+int
+del_entry(int argc, char **argv)
+{
+ int i;
+ krb5_error_code ret;
+
+ for(i = 1; i < argc; i++)
+ ret = foreach_principal(argv[i], do_del_entry, NULL);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/del_enctype.c b/crypto/heimdal/kadmin/del_enctype.c
new file mode 100644
index 0000000..d772b65
--- /dev/null
+++ b/crypto/heimdal/kadmin/del_enctype.c
@@ -0,0 +1,132 @@
+/*
+ * Copyright (c) 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: del_enctype.c,v 1.4 1999/12/14 02:37:49 assar Exp $");
+
+static void
+usage(void)
+{
+ fprintf (stderr, "Usage: del_enctype principal enctypes...\n");
+}
+
+/*
+ * del_enctype principal enctypes...
+ */
+
+int
+del_enctype(int argc, char **argv)
+{
+ kadm5_principal_ent_rec princ;
+ krb5_principal princ_ent = NULL;
+ krb5_error_code ret;
+ const char *princ_name;
+ int i, j, k;
+ krb5_key_data *new_key_data;
+ int n_etypes;
+ krb5_enctype *etypes;
+
+ if (argc < 3) {
+ usage ();
+ return 0;
+ }
+
+ memset (&princ, 0, sizeof(princ));
+ princ_name = argv[1];
+ n_etypes = argc - 2;
+ etypes = malloc (n_etypes * sizeof(*etypes));
+ if (etypes == NULL) {
+ krb5_warnx (context, "out of memory");
+ return 0;
+ }
+ for (i = 0; i < n_etypes; ++i) {
+ ret = krb5_string_to_enctype (context, argv[i + 2], &etypes[i]);
+ if (ret) {
+ krb5_warnx (context, "bad enctype `%s'", argv[i + 2]);
+ goto out2;
+ }
+ }
+
+ ret = krb5_parse_name(context, princ_name, &princ_ent);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_parse_name %s", princ_name);
+ goto out2;
+ }
+
+ ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
+ KADM5_PRINCIPAL | KADM5_KEY_DATA);
+ if (ret) {
+ krb5_free_principal (context, princ_ent);
+ krb5_warnx (context, "no such principal: %s", princ_name);
+ goto out2;
+ }
+
+ new_key_data = malloc(princ.n_key_data * sizeof(*new_key_data));
+ if (new_key_data == NULL) {
+ krb5_warnx (context, "out of memory");
+ goto out;
+ }
+
+ for (i = 0, j = 0; i < princ.n_key_data; ++i) {
+ krb5_key_data *key = &princ.key_data[i];
+ int docopy = 1;
+
+ for (k = 0; k < n_etypes; ++k)
+ if (etypes[k] == key->key_data_type[0]) {
+ docopy = 0;
+ break;
+ }
+ if (docopy) {
+ new_key_data[j++] = *key;
+ } else {
+ int16_t ignore;
+
+ kadm5_free_key_data (kadm_handle, &ignore, key);
+ }
+ }
+
+ free (princ.key_data);
+ princ.n_key_data = j;
+ princ.key_data = new_key_data;
+
+ ret = kadm5_modify_principal (kadm_handle, &princ, KADM5_KEY_DATA);
+ if (ret)
+ krb5_warn(context, ret, "kadm5_modify_principal");
+out:
+ krb5_free_principal (context, princ_ent);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+out2:
+ free (etypes);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/dump.c b/crypto/heimdal/kadmin/dump.c
new file mode 100644
index 0000000..a57309c
--- /dev/null
+++ b/crypto/heimdal/kadmin/dump.c
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+#include <kadm5/private.h>
+
+RCSID("$Id: dump.c,v 1.26 1999/12/02 17:04:58 joda Exp $");
+
+int
+dump(int argc, char **argv)
+{
+ krb5_error_code ret;
+ FILE *f;
+ HDB *db = _kadm5_s_get_db(kadm_handle);
+ int decrypt = 0;
+ int optind = 0;
+
+ struct getargs args[] = {
+ { "decrypt", 'd', arg_flag, NULL, "decrypt keys" }
+ };
+ args[0].value = &decrypt;
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optind)) {
+ arg_printusage(args, sizeof(args) / sizeof(args[0]), "kadmin dump",
+ "[dump-file]");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+ if(argc < 1)
+ f = stdout;
+ else
+ f = fopen(argv[0], "w");
+
+ ret = db->open(context, db, O_RDONLY, 0600);
+ if(ret){
+ krb5_warn(context, ret, "hdb_open");
+ if(f != stdout)
+ fclose(f);
+ return 0;
+ }
+
+ hdb_foreach(context, db, decrypt ? HDB_F_DECRYPT : 0, hdb_print_entry, f);
+
+ if(f != stdout)
+ fclose(f);
+ db->close(context, db);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/ext.c b/crypto/heimdal/kadmin/ext.c
new file mode 100644
index 0000000..9d2be17
--- /dev/null
+++ b/crypto/heimdal/kadmin/ext.c
@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 1997 - 2000 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 "kadmin_locl.h"
+
+RCSID("$Id: ext.c,v 1.5 2000/01/02 03:58:02 assar Exp $");
+
+struct ext_keytab_data {
+ krb5_keytab keytab;
+};
+
+static struct getargs args[] = {
+ { "keytab", 'k', arg_string, NULL, "keytab to use" },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage(args, num_args, "ext", "principal...");
+}
+
+static int
+do_ext_keytab(krb5_principal principal, void *data)
+{
+ krb5_error_code ret;
+ int i;
+ kadm5_principal_ent_rec princ;
+ struct ext_keytab_data *e = data;
+
+ ret = kadm5_get_principal(kadm_handle, principal, &princ,
+ KADM5_PRINCIPAL|KADM5_KVNO|KADM5_KEY_DATA);
+ if(ret)
+ return ret;
+ for(i = 0; i < princ.n_key_data; i++){
+ krb5_keytab_entry key;
+ krb5_key_data *k = &princ.key_data[i];
+ key.principal = princ.principal;
+ key.vno = k->key_data_kvno;
+ key.keyblock.keytype = k->key_data_type[0];
+ key.keyblock.keyvalue.length = k->key_data_length[0];
+ key.keyblock.keyvalue.data = k->key_data_contents[0];
+ key.timestamp = time(NULL);
+ ret = krb5_kt_add_entry(context, e->keytab, &key);
+ if(ret)
+ krb5_warn(context, ret, "krb5_kt_add_entry");
+ }
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ return 0;
+}
+
+int
+ext_keytab(int argc, char **argv)
+{
+ krb5_error_code ret;
+ int i;
+ int optind = 0;
+ char *keytab = NULL;
+ struct ext_keytab_data data;
+
+ args[0].value = &keytab;
+ if(getarg(args, num_args, argc, argv, &optind)){
+ usage();
+ return 0;
+ }
+ if(keytab)
+ ret = krb5_kt_resolve(context, keytab, &data.keytab);
+ else
+ ret = krb5_kt_default(context, &data.keytab);
+ if(ret){
+ krb5_warn(context, ret, "krb5_kt_resolve");
+ return 0;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ for(i = 0; i < argc; i++)
+ foreach_principal(argv[i], do_ext_keytab, &data);
+
+ krb5_kt_close(context, data.keytab);
+
+ return 0;
+}
+
diff --git a/crypto/heimdal/kadmin/get.c b/crypto/heimdal/kadmin/get.c
new file mode 100644
index 0000000..1492ca9
--- /dev/null
+++ b/crypto/heimdal/kadmin/get.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+#include <parse_units.h>
+
+RCSID("$Id: get.c,v 1.8 1999/12/02 17:04:58 joda Exp $");
+
+struct get_entry_data {
+ void (*header)(void);
+ void (*format)(kadm5_principal_ent_t);
+};
+
+static void
+print_entry_terse(kadm5_principal_ent_t princ)
+{
+ char *p;
+ krb5_unparse_name(context, princ->principal, &p);
+ printf(" %s\n", p);
+ free(p);
+}
+
+static void
+print_header_short(void)
+{
+ printf("%-20s ", "Principal");
+
+ printf("%-10s ", "Expires");
+
+ printf("%-10s ", "PW-exp");
+
+ printf("%-10s ", "PW-change");
+
+ printf("%-9s ", "Max life");
+
+ printf("%-9s ", "Max renew");
+
+ printf("\n");
+}
+
+static void
+print_entry_short(kadm5_principal_ent_t princ)
+{
+ char buf[1024];
+
+ krb5_unparse_name_fixed_short(context, princ->principal, buf, sizeof(buf));
+ printf("%-20s ", buf);
+
+ time_t2str(princ->princ_expire_time, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ time_t2str(princ->pw_expiration, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ time_t2str(princ->last_pwd_change, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ deltat2str(princ->max_life, buf, sizeof(buf));
+ printf("%-9s ", buf);
+
+ deltat2str(princ->max_renewable_life, buf, sizeof(buf));
+ printf("%-9s ", buf);
+
+#if 0
+ time_t2str(princ->mod_date, buf, sizeof(buf), 0);
+ printf("%-10s ", buf);
+
+ krb5_unparse_name_fixed(context, princ->mod_name, buf, sizeof(buf));
+ printf("%-24s", buf);
+#endif
+
+ printf("\n");
+}
+
+static void
+print_entry_long(kadm5_principal_ent_t princ)
+{
+ char buf[1024];
+ int i;
+
+ krb5_unparse_name_fixed(context, princ->principal, buf, sizeof(buf));
+ printf("%24s: %s\n", "Principal", buf);
+ time_t2str(princ->princ_expire_time, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Principal expires", buf);
+
+ time_t2str(princ->pw_expiration, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Password expires", buf);
+
+ time_t2str(princ->last_pwd_change, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last password change", buf);
+
+ deltat2str(princ->max_life, buf, sizeof(buf));
+ printf("%24s: %s\n", "Max ticket life", buf);
+
+ deltat2str(princ->max_renewable_life, buf, sizeof(buf));
+ printf("%24s: %s\n", "Max renewable life", buf);
+ printf("%24s: %d\n", "Kvno", princ->kvno);
+ printf("%24s: %d\n", "Mkvno", princ->mkvno);
+ printf("%24s: %s\n", "Policy", princ->policy ? princ->policy : "none");
+ time_t2str(princ->last_success, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last successful login", buf);
+ time_t2str(princ->last_failed, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last failed login", buf);
+ printf("%24s: %d\n", "Failed login count", princ->fail_auth_count);
+ time_t2str(princ->mod_date, buf, sizeof(buf), 1);
+ printf("%24s: %s\n", "Last modified", buf);
+ krb5_unparse_name_fixed(context, princ->mod_name, buf, sizeof(buf));
+ printf("%24s: %s\n", "Modifier", buf);
+ attributes2str (princ->attributes, buf, sizeof(buf));
+ printf("%24s: %s\n", "Attributes", buf);
+
+ printf("%24s: ", "Keytypes(salts)");
+
+ for (i = 0; i < princ->n_key_data; ++i) {
+ krb5_key_data *k = &princ->key_data[i];
+ krb5_error_code ret;
+ char *e_string, *s_string;
+
+ ret = krb5_enctype_to_string (context,
+ k->key_data_type[0],
+ &e_string);
+ if (ret)
+ asprintf (&e_string, "unknown(%d)", k->key_data_type[0]);
+
+ ret = krb5_salttype_to_string (context,
+ k->key_data_type[0],
+ k->key_data_type[1],
+ &s_string);
+ if (ret)
+ asprintf (&s_string, "unknown(%d)", k->key_data_type[1]);
+
+ printf ("%s%s(%s)", (i != 0) ? ", " : "", e_string, s_string);
+ free (e_string);
+ free (s_string);
+ }
+ printf("\n\n");
+}
+
+static int
+do_get_entry(krb5_principal principal, void *data)
+{
+ kadm5_principal_ent_rec princ;
+ krb5_error_code ret;
+ struct get_entry_data *e = data;
+
+ memset(&princ, 0, sizeof(princ));
+ ret = kadm5_get_principal(kadm_handle, principal,
+ &princ,
+ KADM5_PRINCIPAL_NORMAL_MASK|KADM5_KEY_DATA);
+ if(ret)
+ return ret;
+ else {
+ if(e->header) {
+ (*e->header)();
+ e->header = NULL; /* XXX only once */
+ }
+ (e->format)(&princ);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ }
+ return 0;
+}
+
+int
+get_entry(int argc, char **argv)
+{
+ int i;
+ krb5_error_code ret;
+ struct get_entry_data data;
+ struct getargs args[] = {
+ { "long", 'l', arg_flag, NULL, "long format" },
+ { "terse", 't', arg_flag, NULL, "terse format" },
+ };
+ int num_args = sizeof(args) / sizeof(args[0]);
+ int optind = 0;
+ int long_flag = 0;
+ int terse_flag = 0;
+
+ args[0].value = &long_flag;
+ args[1].value = &terse_flag;
+ if(getarg(args, num_args, argc, argv, &optind))
+ goto usage;
+ if(optind == argc)
+ goto usage;
+
+ if(long_flag) {
+ data.format = print_entry_long;
+ data.header = NULL;
+ } else if(terse_flag) {
+ data.format = print_entry_terse;
+ data.header = NULL;
+ } else {
+ data.format = print_entry_short;
+ data.header = print_header_short;
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ for(i = 0; i < argc; i++)
+ ret = foreach_principal(argv[i], do_get_entry, &data);
+ return 0;
+usage:
+ arg_printusage (args, num_args, "get", "principal...");
+ return 0;
+}
+
+int
+list_princs(int argc, char **argv)
+{
+ int i;
+ krb5_error_code ret;
+ struct get_entry_data data;
+
+ data.format = print_entry_terse;
+ data.header = NULL;
+
+ for(i = 1; i < argc; i++)
+ ret = foreach_principal(argv[i], do_get_entry, &data);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/init.c b/crypto/heimdal/kadmin/init.c
new file mode 100644
index 0000000..b889131
--- /dev/null
+++ b/crypto/heimdal/kadmin/init.c
@@ -0,0 +1,210 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+#include <kadm5/private.h>
+
+RCSID("$Id: init.c,v 1.23 1999/12/02 17:04:58 joda Exp $");
+
+static kadm5_ret_t
+create_random_entry(krb5_principal princ,
+ unsigned max_life,
+ unsigned max_rlife,
+ u_int32_t attributes)
+{
+ kadm5_principal_ent_rec ent;
+ kadm5_ret_t ret;
+ int mask = 0;
+ krb5_keyblock *keys;
+ int n_keys, i;
+
+ memset(&ent, 0, sizeof(ent));
+ ent.principal = princ;
+ mask |= KADM5_PRINCIPAL;
+ if (max_life) {
+ ent.max_life = max_life;
+ mask |= KADM5_MAX_LIFE;
+ }
+ if (max_rlife) {
+ ent.max_renewable_life = max_rlife;
+ mask |= KADM5_MAX_RLIFE;
+ }
+ ent.attributes |= attributes | KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+
+ ret = kadm5_create_principal(kadm_handle, &ent, mask, "hemlig");
+ if(ret)
+ return ret;
+ ret = kadm5_randkey_principal(kadm_handle, princ, &keys, &n_keys);
+ if(ret)
+ return ret;
+ for(i = 0; i < n_keys; i++)
+ krb5_free_keyblock_contents(context, &keys[i]);
+ free(keys);
+ ret = kadm5_get_principal(kadm_handle, princ, &ent,
+ KADM5_PRINCIPAL | KADM5_ATTRIBUTES);
+ if(ret)
+ return ret;
+ ent.attributes &= (~KRB5_KDB_DISALLOW_ALL_TIX);
+ ent.kvno = 1;
+ ret = kadm5_modify_principal(kadm_handle, &ent,
+ KADM5_ATTRIBUTES|KADM5_KVNO);
+ kadm5_free_principal_ent (kadm_handle, &ent);
+ if(ret)
+ return ret;
+ return 0;
+}
+
+static struct getargs args[] = {
+ { "realm-max-ticket-life", 0, arg_string, NULL,
+ "realm max ticket lifetime" },
+ { "realm-max-renewable-life", 0, arg_string, NULL,
+ "realm max renewable lifetime" },
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(void)
+{
+ arg_printusage (args, num_args, "ank", "principal");
+}
+
+int
+init(int argc, char **argv)
+{
+ kadm5_ret_t ret;
+ int i;
+ char *realm_max_life = NULL;
+ char *realm_max_rlife = NULL;
+ HDB *db;
+ int optind = 0;
+ krb5_deltat max_life, max_rlife;
+
+ args[0].value = &realm_max_life;
+ args[1].value = &realm_max_rlife;
+
+ if(getarg(args, num_args, argc, argv, &optind)) {
+ usage();
+ return 0;
+ }
+
+ if (realm_max_life) {
+ if (str2deltat (realm_max_life, &max_life) != 0) {
+ krb5_warnx (context, "unable to parse `%s'", realm_max_life);
+ return 0;
+ }
+ }
+ if (realm_max_rlife) {
+ if (str2deltat (realm_max_rlife, &max_rlife) != 0) {
+ krb5_warnx (context, "unable to parse `%s'", realm_max_rlife);
+ return 0;
+ }
+ }
+
+ db = _kadm5_s_get_db(kadm_handle);
+
+ ret = db->open(context, db, O_RDWR | O_CREAT, 0600);
+ if(ret){
+ krb5_warn(context, ret, "hdb_open");
+ return 0;
+ }
+ db->close(context, db);
+ for(i = optind; i < argc; i++){
+ krb5_principal princ;
+ const char *realm = argv[i];
+
+ /* Create `krbtgt/REALM' */
+ krb5_make_principal(context, &princ, realm, "krbtgt", realm, NULL);
+ if (realm_max_life == NULL) {
+ max_life = 0;
+ edit_deltat ("Realm max ticket life", &max_life, NULL, 0);
+ }
+ if (realm_max_rlife == NULL) {
+ max_rlife = 0;
+ edit_deltat("Realm max renewable ticket life", &max_rlife,
+ NULL, 0);
+ }
+ create_random_entry(princ, max_life, max_rlife, 0);
+ krb5_free_principal(context, princ);
+
+ /* Create `kadmin/changepw' */
+ krb5_make_principal(context, &princ, realm,
+ "kadmin", "changepw", NULL);
+ create_random_entry(princ, 5*60, 5*60,
+ KRB5_KDB_DISALLOW_TGT_BASED|
+ KRB5_KDB_PWCHANGE_SERVICE|
+ KRB5_KDB_DISALLOW_POSTDATED|
+ KRB5_KDB_DISALLOW_FORWARDABLE|
+ KRB5_KDB_DISALLOW_RENEWABLE|
+ KRB5_KDB_DISALLOW_PROXIABLE|
+ KRB5_KDB_REQUIRES_PRE_AUTH);
+ krb5_free_principal(context, princ);
+
+ /* Create `kadmin/admin' */
+ krb5_make_principal(context, &princ, realm,
+ "kadmin", "admin", NULL);
+ create_random_entry(princ, 60*60, 60*60, KRB5_KDB_REQUIRES_PRE_AUTH);
+ krb5_free_principal(context, princ);
+
+ /* Create `changepw/kerberos' (for v4 compat) */
+ krb5_make_principal(context, &princ, realm,
+ "changepw", "kerberos", NULL);
+ create_random_entry(princ, 60*60, 60*60, 0);
+ krb5_free_principal(context, princ);
+
+ /* Create `default' */
+ {
+ kadm5_principal_ent_rec ent;
+ int mask = 0;
+
+ memset (&ent, 0, sizeof(ent));
+ mask |= KADM5_PRINCIPAL;
+ krb5_make_principal(context, &ent.principal, realm,
+ "default", NULL);
+ mask |= KADM5_MAX_LIFE;
+ ent.max_life = 24 * 60 * 60;
+ mask |= KADM5_MAX_RLIFE;
+ ent.max_renewable_life = 7 * ent.max_life;
+ ent.attributes = KRB5_KDB_DISALLOW_ALL_TIX;
+ mask |= KADM5_ATTRIBUTES;
+
+ ret = kadm5_create_principal(kadm_handle, &ent, mask, "");
+ if (ret)
+ krb5_err (context, 1, ret, "kadm5_create_principal");
+
+ krb5_free_principal(context, ent.principal);
+ }
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/kadmin.c b/crypto/heimdal/kadmin/kadmin.c
new file mode 100644
index 0000000..9172d6e
--- /dev/null
+++ b/crypto/heimdal/kadmin/kadmin.c
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+#include <sl.h>
+
+RCSID("$Id: kadmin.c,v 1.26 1999/12/02 17:04:58 joda Exp $");
+
+static char *config_file;
+static char *keyfile;
+static int local_flag;
+static int help_flag;
+static int version_flag;
+static char *realm;
+static char *admin_server;
+static int server_port = 0;
+static char *client_name;
+
+static struct getargs args[] = {
+ { "principal", 'p', arg_string, &client_name,
+ "principal to authenticate as" },
+ {
+ "config-file", 'c', arg_string, &config_file,
+ "location of config file", "file"
+ },
+ {
+ "key-file", 'k', arg_string, &keyfile,
+ "location of master key file", "file"
+ },
+ {
+ "realm", 'r', arg_string, &realm,
+ "realm to use", "realm"
+ },
+ {
+ "admin-server", 'a', arg_string, &admin_server,
+ "server to contact", "host"
+ },
+ {
+ "server-port", 's', arg_integer, &server_port,
+ "server to contact", "port number"
+ },
+ { "local", 'l', arg_flag, &local_flag, "local admin mode" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 'v', arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+static SL_cmd commands[] = {
+ /* commands that are only available with `-l' */
+ {
+ "dump", dump, "dump [file]",
+ "Dumps the database in a human readable format to the\n"
+ "specified file, or the standard out."
+ },
+ {
+ "load", load, "load file",
+ "Loads a previously dumped file."
+ },
+ {
+ "merge", merge, "merge file" ,
+ "Merges the contents of a dump file into the database."
+ },
+ {
+ "init", init, "init realm...",
+ "Initializes the default principals for a realm.\n"
+ "Creates the database if necessary."
+ },
+ /* common commands */
+ {
+ "add", add_new_key, "add principal" ,
+ "Adds a principal to the database."
+ },
+ { "add_new_key"},
+ { "ank"},
+ {
+ "passwd", cpw_entry, "passwd expression..." ,
+ "Changes the password of one or more principals\n"
+ "matching the expressions."
+ },
+ { "change_password"},
+ { "cpw"},
+ {
+ "delete", del_entry, "delete expression...",
+ "Deletes all principals matching the expressions."
+ },
+ { "del_entry" },
+ {
+ "del_enctype", del_enctype, "del_enctype principal enctype...",
+ "Delete all the mentioned enctypes for principal."
+ },
+ {
+ "ext_keytab", ext_keytab, "ext_keytab expression...",
+ "Extracts the keys of all principals matching the expressions,\n"
+ "and stores them in a keytab."
+ },
+ {
+ "get", get_entry, "get expression...",
+ "Shows information about principals matching the expressions."
+ },
+ { "get_entry" },
+ {
+ "rename", rename_entry, "rename source target",
+ "Renames `source' to `target'."
+ },
+ {
+ "modify", mod_entry, "modify principal",
+ "Modifies some attributes of the specified principal."
+ },
+ {
+ "privileges", get_privs, "privileges",
+ "Shows which kinds of operations you are allowed to perform."
+ },
+ {
+ "list", list_princs, "list expression...",
+ "Lists principals in a terse format. The same as `get -t'."
+ },
+ { "help", help, "help"},
+ { "?"},
+ { "exit", exit_kadmin, "exit"},
+ { NULL}
+};
+
+krb5_context context;
+void *kadm_handle;
+
+int
+help(int argc, char **argv)
+{
+ sl_help(commands, argc, argv);
+ return 0;
+}
+
+int
+exit_kadmin (int argc, char **argv)
+{
+ return 1;
+}
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "[command]");
+ exit (ret);
+}
+
+int
+get_privs(int argc, char **argv)
+{
+ u_int32_t privs;
+ char str[128];
+ kadm5_ret_t ret;
+
+ ret = kadm5_get_privs(kadm_handle, &privs);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_get_privs");
+ else{
+ ret =_kadm5_privs_to_string(privs, str, sizeof(str));
+ printf("%s\n", str);
+ }
+ return 0;
+}
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_config_section *cf = NULL;
+ kadm5_config_params conf;
+ int optind = 0;
+ int e;
+ SL_cmd *cmd;
+
+ set_progname(argv[0]);
+
+ krb5_init_context(&context);
+
+ while((e = getarg(args, num_args, argc, argv, &optind)))
+ warnx("error at argument `%s'", argv[optind]);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ if (config_file == NULL)
+ config_file = HDB_DB_DIR "/kdc.conf";
+
+ if(krb5_config_parse_file(config_file, &cf) == 0) {
+ const char *p = krb5_config_get_string (context, cf,
+ "kdc", "key-file", NULL);
+ if (p)
+ keyfile = strdup(p);
+ }
+
+ memset(&conf, 0, sizeof(conf));
+ if(realm) {
+ krb5_set_default_realm(context, realm); /* XXX should be fixed
+ some other way */
+ conf.realm = realm;
+ conf.mask |= KADM5_CONFIG_REALM;
+ }
+
+ if (admin_server) {
+ conf.admin_server = admin_server;
+ conf.mask |= KADM5_CONFIG_ADMIN_SERVER;
+ }
+
+ if (server_port) {
+ conf.kadmind_port = htons(server_port);
+ conf.mask |= KADM5_CONFIG_KADMIND_PORT;
+ }
+
+ if(local_flag){
+ ret = kadm5_s_init_with_password_ctx(context,
+ KADM5_ADMIN_SERVICE,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ cmd = commands;
+ } else {
+ ret = kadm5_c_init_with_password_ctx(context,
+ client_name,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &conf, 0, 0,
+ &kadm_handle);
+ cmd = commands + 4; /* XXX */
+ }
+
+ if(ret)
+ krb5_err(context, 1, ret, "kadm5_init_with_password");
+ if (argc != 0) {
+ ret = sl_command (cmd, argc, argv);
+ if(ret == -1)
+ krb5_warnx (context, "unrecognized command: %s", argv[0]);
+ } else
+ ret = sl_loop (cmd, "kadmin> ") != 0;
+
+ kadm5_destroy(kadm_handle);
+ krb5_config_file_free (context, cf);
+ krb5_free_context(context);
+ return ret;
+}
diff --git a/crypto/heimdal/kadmin/kadmin_locl.h b/crypto/heimdal/kadmin/kadmin_locl.h
new file mode 100644
index 0000000..240ca2c
--- /dev/null
+++ b/crypto/heimdal/kadmin/kadmin_locl.h
@@ -0,0 +1,161 @@
+/*
+ * 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: kadmin_locl.h,v 1.24 1999/12/02 17:04:58 joda Exp $
+ */
+
+#ifndef __ADMIN_LOCL_H__
+#define __ADMIN_LOCL_H__
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.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_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_SYS_UN_H
+#include <sys/un.h>
+#endif
+#include <err.h>
+#include <roken.h>
+#include <krb5.h>
+#include <hdb.h>
+#include <hdb_err.h>
+#include <kadm5/admin.h>
+#include <kadm5/private.h>
+#include <kadm5/kadm5_err.h>
+#include <parse_time.h>
+#include <getarg.h>
+
+
+extern krb5_context context;
+extern void * kadm_handle;
+
+#define DECL(X) int X(int, char **)
+
+DECL(add_new_key);
+DECL(cpw_entry);
+DECL(del_entry);
+DECL(del_enctype);
+DECL(exit_kadmin);
+DECL(ext_keytab);
+DECL(get_entry);
+DECL(get_privs);
+DECL(help);
+DECL(list_princs);
+DECL(mod_entry);
+DECL(rename_entry);
+DECL(init);
+DECL(dump);
+DECL(load);
+DECL(merge);
+
+#define ALLOC(X) ((X) = malloc(sizeof(*(X))))
+
+/* util.c */
+
+void attributes2str(krb5_flags attributes, char *str, size_t len);
+int str2attributes(const char *str, krb5_flags *flags);
+int parse_attributes (const char *resp, krb5_flags *attr, int *mask, int bit);
+int edit_attributes (const char *prompt, krb5_flags *attr, int *mask,
+ int bit);
+
+void time_t2str(time_t t, char *str, size_t len, int include_time);
+int str2time_t (const char *str, time_t *time);
+int parse_timet (const char *resp, krb5_timestamp *value, int *mask, int bit);
+int edit_timet (const char *prompt, krb5_timestamp *value, int *mask,
+ int bit);
+
+void deltat2str(unsigned t, char *str, size_t len);
+int str2deltat(const char *str, krb5_deltat *delta);
+int parse_deltat (const char *resp, krb5_deltat *value, int *mask, int bit);
+int edit_deltat (const char *prompt, krb5_deltat *value, int *mask, int bit);
+
+int edit_entry(kadm5_principal_ent_t ent, int *mask,
+ kadm5_principal_ent_t default_ent, int default_mask);
+int set_entry(krb5_context context,
+ kadm5_principal_ent_t ent,
+ int *mask,
+ const char *max_ticket_life,
+ const char *max_renewable_life,
+ const char *expiration,
+ const char *pw_expiration,
+ const char *attributes);
+int
+foreach_principal(const char *exp,
+ int (*func)(krb5_principal, void*),
+ void *data);
+
+void get_response(const char *prompt, const char *def, char *buf, size_t len);
+
+/* server.c */
+
+krb5_error_code
+kadmind_loop (krb5_context, krb5_auth_context, krb5_keytab, int);
+
+/* version4.c */
+
+void
+handle_v4(krb5_context context, int len, int fd);
+
+/* random_password.c */
+
+void
+random_password(char *pw, size_t len);
+
+#endif /* __ADMIN_LOCL_H__ */
diff --git a/crypto/heimdal/kadmin/kadmind.c b/crypto/heimdal/kadmin/kadmind.c
new file mode 100644
index 0000000..4b4fb0d
--- /dev/null
+++ b/crypto/heimdal/kadmin/kadmind.c
@@ -0,0 +1,151 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: kadmind.c,v 1.16 1999/12/02 17:04:58 joda Exp $");
+
+static char *config_file;
+static char *keyfile;
+static char *keytab_str = "HDB:";
+static int help_flag;
+static int version_flag;
+static int debug_flag;
+static int debug_port;
+char *realm;
+
+static struct getargs args[] = {
+ {
+ "config-file", 'c', arg_string, &config_file,
+ "location of config file", "file"
+ },
+ {
+ "key-file", 'k', arg_string, &keyfile,
+ "location of master key file", "file"
+ },
+ {
+ "keytab", 0, arg_string, &keytab_str,
+ "what keytab to use", "keytab"
+ },
+ { "realm", 'r', arg_string, &realm,
+ "realm to use", "realm"
+ },
+ { "debug", 'd', arg_flag, &debug_flag,
+ "enable debugging"
+ },
+ { "debug-port", 'p', arg_integer,&debug_port,
+ "port to use with debug", "port" },
+ { "help", 'h', arg_flag, &help_flag },
+ { "version", 'v', arg_flag, &version_flag }
+};
+
+static int num_args = sizeof(args) / sizeof(args[0]);
+
+krb5_context context;
+
+static void
+usage(int ret)
+{
+ arg_printusage (args, num_args, NULL, "");
+ exit (ret);
+}
+
+krb5_error_code
+kadmind_loop (krb5_context, krb5_auth_context, krb5_keytab, int);
+
+int
+main(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_config_section *cf;
+ int optind = 0;
+ int e;
+ krb5_log_facility *logf;
+ krb5_keytab keytab;
+
+ set_progname(argv[0]);
+
+ krb5_init_context(&context);
+
+ ret = krb5_openlog(context, "kadmind", &logf);
+ ret = krb5_set_warn_dest(context, logf);
+
+ while((e = getarg(args, num_args, argc, argv, &optind)))
+ warnx("error at argument `%s'", argv[optind]);
+
+ if (help_flag)
+ usage (0);
+
+ if (version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ argc -= optind;
+ argv += optind;
+
+ ret = krb5_kt_register(context, &hdb_kt_ops);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_kt_register");
+
+ if (config_file == NULL)
+ config_file = HDB_DB_DIR "/kdc.conf";
+
+ if(krb5_config_parse_file(config_file, &cf) == 0) {
+ const char *p = krb5_config_get_string (context, cf,
+ "kdc", "key-file", NULL);
+ if (p)
+ keyfile = strdup(p);
+ }
+
+ ret = krb5_kt_resolve(context, keytab_str, &keytab);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_kt_resolve");
+
+ {
+ int fd = 0;
+ krb5_auth_context ac = NULL;
+ if(debug_flag){
+ if(debug_port == 0)
+ debug_port = krb5_getportbyname (context, "kerberos-adm",
+ "tcp", 749);
+ else
+ debug_port = htons(debug_port);
+ mini_inetd(debug_port);
+ }
+ if(realm)
+ krb5_set_default_realm(context, realm); /* XXX */
+ kadmind_loop(context, ac, keytab, fd);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/load.c b/crypto/heimdal/kadmin/load.c
new file mode 100644
index 0000000..5f9f2b7
--- /dev/null
+++ b/crypto/heimdal/kadmin/load.c
@@ -0,0 +1,335 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+#include <kadm5/private.h>
+
+RCSID("$Id: load.c,v 1.34 1999/12/02 17:04:58 joda Exp $");
+
+struct entry{
+ char *principal;
+ char *key;
+ char *max_life;
+ char *max_renew;
+ char *created;
+ char *modified;
+ char *valid_start;
+ char *valid_end;
+ char *pw_end;
+ char *flags;
+ char *etypes;
+};
+
+static char *
+skip_next(char *p)
+{
+ while(*p && !isspace((unsigned char)*p))
+ p++;
+ *p++ = 0;
+ while(*p && isspace((unsigned char)*p)) p++;
+ return p;
+}
+
+static time_t*
+parse_time_string(time_t *t, char *s)
+{
+ int year, month, date, hour, minute, second;
+ struct tm tm;
+ if(strcmp(s, "-") == 0)
+ return NULL;
+ if(t == NULL)
+ t = malloc(sizeof(*t));
+ sscanf(s, "%04d%02d%02d%02d%02d%02d",
+ &year, &month, &date, &hour, &minute, &second);
+ tm.tm_year = year - 1900;
+ tm.tm_mon = month - 1;
+ tm.tm_mday = date;
+ tm.tm_hour = hour;
+ tm.tm_min = minute;
+ tm.tm_sec = second;
+ tm.tm_isdst = 0;
+ *t = timegm(&tm);
+ return t;
+}
+
+static unsigned*
+parse_integer(unsigned *u, char *s)
+{
+ if(strcmp(s, "-") == 0)
+ return NULL;
+ if(u == NULL)
+ u = malloc(sizeof(*u));
+ sscanf(s, "%u", u);
+ return u;
+}
+
+static void
+parse_keys(hdb_entry *ent, char *str)
+{
+ int tmp;
+ char *p;
+ int i;
+
+ p = strsep(&str, ":");
+ sscanf(p, "%d", &tmp);
+ ent->kvno = tmp;
+ p = strsep(&str, ":");
+ while(p){
+ Key *key;
+ key = realloc(ent->keys.val,
+ (ent->keys.len + 1) * sizeof(*ent->keys.val));
+ if(key == NULL)
+ abort();
+ ent->keys.val = key;
+ key = ent->keys.val + ent->keys.len;
+ ent->keys.len++;
+ memset(key, 0, sizeof(*key));
+ if(sscanf(p, "%d", &tmp) == 1) {
+ key->mkvno = malloc(sizeof(*key->mkvno));
+ *key->mkvno = tmp;
+ } else
+ key->mkvno = NULL;
+ p = strsep(&str, ":");
+ sscanf(p, "%d", &tmp);
+ key->key.keytype = tmp;
+ p = strsep(&str, ":");
+ krb5_data_alloc(&key->key.keyvalue, (strlen(p) - 1) / 2 + 1);
+ for(i = 0; i < strlen(p); i += 2){
+ sscanf(p + i, "%02x", &tmp);
+ ((u_char*)key->key.keyvalue.data)[i / 2] = tmp;
+ }
+ p = strsep(&str, ":");
+ if(strcmp(p, "-") != 0){
+ unsigned type;
+ size_t p_len;
+ if(sscanf(p, "%u/", &type) != 1){
+ abort ();
+ }
+ p = strchr(p, '/');
+ if(p == NULL)
+ abort ();
+ p++;
+ p_len = strlen(p);
+
+ key->salt = malloc(sizeof(*key->salt));
+ key->salt->type = type;
+
+ if (p_len) {
+ if(*p == '\"'){
+ krb5_data_copy(&key->salt->salt, p + 1, p_len - 2);
+ }else{
+ krb5_data_alloc(&key->salt->salt, (p_len - 1) / 2 + 1);
+ for(i = 0; i < p_len; i += 2){
+ sscanf(p + i, "%02x", &tmp);
+ ((u_char*)key->salt->salt.data)[i / 2] = tmp;
+ }
+ }
+ } else
+ krb5_data_zero (&key->salt->salt);
+ }
+ p = strsep(&str, ":");
+ }
+}
+
+static Event*
+parse_event(Event *ev, char *str)
+{
+ char *p;
+ if(strcmp(str, "-") == 0)
+ return NULL;
+ if(ev == NULL)
+ ev = malloc(sizeof(*ev));
+ memset(ev, 0, sizeof(*ev));
+ p = strsep(&str, ":");
+ parse_time_string(&ev->time, p);
+ p = strsep(&str, ":");
+ krb5_parse_name(context, p, &ev->principal);
+ return ev;
+}
+
+static HDBFlags
+parse_hdbflags2int(char *str)
+{
+ unsigned i;
+ parse_integer(&i, str);
+
+ return int2HDBFlags(i);
+}
+
+#if 0
+static void
+parse_etypes(char *str, unsigned **val, unsigned *len)
+{
+ unsigned v;
+
+ *val = NULL;
+ *len = 0;
+ while(sscanf(str, "%u", &v) == 1) {
+ *val = realloc(*val, (*len+1) * sizeof(**val));
+ (*val)[(*len)++] = v;
+ str = strchr(str, ':');
+ if(str == NULL)
+ break;
+ str++;
+ }
+}
+#endif
+
+static void
+doit(char *filename, int merge)
+{
+ krb5_error_code ret;
+ FILE *f;
+ char s[1024];
+ char *p;
+ int line;
+ int flags = O_RDWR;
+ struct entry e;
+ hdb_entry ent;
+ HDB *db = _kadm5_s_get_db(kadm_handle);
+
+ f = fopen(filename, "r");
+ if(f == NULL){
+ krb5_warn(context, errno, "fopen(%s)", filename);
+ return;
+ }
+ if(!merge)
+ flags |= O_CREAT | O_TRUNC;
+ ret = db->open(context, db, flags, 0600);
+ if(ret){
+ krb5_warn(context, ret, "hdb_open");
+ fclose(f);
+ return;
+ }
+ line = 0;
+ while(fgets(s, sizeof(s), f)){
+ line++;
+ e.principal = s;
+ for(p = s; *p; p++){
+ if(*p == '\\')
+ p++;
+ else if(isspace((unsigned char)*p)) {
+ *p = 0;
+ break;
+ }
+ }
+ p = skip_next(p);
+
+ e.key = p;
+ p = skip_next(p);
+
+ e.created = p;
+ p = skip_next(p);
+
+ e.modified = p;
+ p = skip_next(p);
+
+ e.valid_start = p;
+ p = skip_next(p);
+
+ e.valid_end = p;
+ p = skip_next(p);
+
+ e.pw_end = p;
+ p = skip_next(p);
+
+ e.max_life = p;
+ p = skip_next(p);
+
+ e.max_renew = p;
+ p = skip_next(p);
+
+ e.flags = p;
+ p = skip_next(p);
+
+ e.etypes = p;
+ p = skip_next(p);
+
+ memset(&ent, 0, sizeof(ent));
+ ret = krb5_parse_name(context, e.principal, &ent.principal);
+ if(ret){
+ fprintf(stderr, "%s:%d:%s (%s)\n",
+ filename,
+ line,
+ krb5_get_err_text(context, ret),
+ e.principal);
+ continue;
+ }
+
+ parse_keys(&ent, e.key);
+
+ parse_event(&ent.created_by, e.created);
+ ent.modified_by = parse_event(NULL, e.modified);
+ ent.valid_start = parse_time_string(NULL, e.valid_start);
+ ent.valid_end = parse_time_string(NULL, e.valid_end);
+ ent.pw_end = parse_time_string(NULL, e.pw_end);
+ ent.max_life = parse_integer(NULL, e.max_life);
+ ent.max_renew = parse_integer(NULL, e.max_renew);
+ ent.flags = parse_hdbflags2int(e.flags);
+#if 0
+ ALLOC(ent.etypes);
+ parse_etypes(e.etypes, &ent.etypes->val, &ent.etypes->len);
+ if(ent.etypes->len == 0) {
+ free(ent.etypes);
+ ent.etypes = NULL;
+ }
+#endif
+
+ db->store(context, db, HDB_F_REPLACE, &ent);
+ hdb_free_entry (context, &ent);
+ }
+ db->close(context, db);
+ fclose(f);
+}
+
+int
+load(int argc, char **argv)
+{
+ if(argc < 2){
+ krb5_warnx(context, "Usage: load filename");
+ return 0;
+ }
+ doit(argv[1], 0);
+ return 0;
+}
+
+int
+merge(int argc, char **argv)
+{
+ if(argc < 2){
+ krb5_warnx(context, "Usage: merge filename");
+ return 0;
+ }
+ doit(argv[1], 1);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/mod.c b/crypto/heimdal/kadmin/mod.c
new file mode 100644
index 0000000..48d00a6
--- /dev/null
+++ b/crypto/heimdal/kadmin/mod.c
@@ -0,0 +1,143 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: mod.c,v 1.7 1999/12/02 17:04:58 joda Exp $");
+
+static int parse_args (krb5_context context, kadm5_principal_ent_t ent,
+ int argc, char **argv, int *optind, char *name,
+ int *mask);
+
+static int
+parse_args(krb5_context context, kadm5_principal_ent_t ent,
+ int argc, char **argv, int *optind, char *name,
+ int *mask)
+{
+ char *attr_str = NULL;
+ char *max_life_str = NULL;
+ char *max_rlife_str = NULL;
+ char *expiration_str = NULL;
+ char *pw_expiration_str = NULL;
+ int ret, i;
+
+ struct getargs args[] = {
+ {"attributes", 'a', arg_string, NULL, "Attributies",
+ "attributes"},
+ {"max-ticket-life", 0, arg_string, NULL, "max ticket lifetime",
+ "lifetime"},
+ {"max-renewable-life", 0, arg_string, NULL,
+ "max renewable lifetime", "lifetime" },
+ {"expiration-time", 0, arg_string,
+ NULL, "Expiration time", "time"},
+ {"pw-expiration-time", 0, arg_string,
+ NULL, "Password expiration time", "time"},
+ };
+
+ i = 0;
+ args[i++].value = &attr_str;
+ args[i++].value = &max_life_str;
+ args[i++].value = &max_rlife_str;
+ args[i++].value = &expiration_str;
+ args[i++].value = &pw_expiration_str;
+
+ *optind = 0; /* XXX */
+
+ if(getarg(args, sizeof(args) / sizeof(args[0]),
+ argc, argv, optind)){
+ arg_printusage(args,
+ sizeof(args) / sizeof(args[0]),
+ name ? name : "",
+ "principal");
+ return -1;
+ }
+
+ ret = set_entry(context, ent, mask, max_life_str, max_rlife_str,
+ expiration_str, pw_expiration_str, attr_str);
+ if (ret)
+ return ret;
+ return 0;
+}
+
+int
+mod_entry(int argc, char **argv)
+{
+ kadm5_principal_ent_rec princ;
+ int mask = 0;
+ krb5_error_code ret;
+ krb5_principal princ_ent = NULL;
+ int optind;
+
+ memset (&princ, 0, sizeof(princ));
+
+ ret = parse_args (context, &princ, argc, argv,
+ &optind, "mod", &mask);
+ if (ret)
+ return 0;
+
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 1) {
+ printf ("Usage: mod [options] principal\n");
+ return 0;
+ }
+
+ krb5_parse_name(context, argv[0], &princ_ent);
+
+ if (mask == 0) {
+ memset(&princ, 0, sizeof(princ));
+ ret = kadm5_get_principal(kadm_handle, princ_ent, &princ,
+ KADM5_PRINCIPAL | KADM5_ATTRIBUTES |
+ KADM5_MAX_LIFE | KADM5_MAX_RLIFE |
+ KADM5_PRINC_EXPIRE_TIME |
+ KADM5_PW_EXPIRATION);
+ if (ret) {
+ printf ("no such principal: %s\n", argv[0]);
+ krb5_free_principal (context, princ_ent);
+ return 0;
+ }
+ edit_entry(&princ, &mask, NULL, 0);
+
+ } else {
+ princ.principal = princ_ent;
+ }
+
+ ret = kadm5_modify_principal(kadm_handle, &princ, mask);
+ if(ret)
+ krb5_warn(context, ret, "kadm5_modify_principal");
+ if(princ_ent)
+ krb5_free_principal(context, princ_ent);
+ kadm5_free_principal_ent(kadm_handle, &princ);
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/random_password.c b/crypto/heimdal/kadmin/random_password.c
new file mode 100644
index 0000000..aabe08c
--- /dev/null
+++ b/crypto/heimdal/kadmin/random_password.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+
+RCSID("$Id: random_password.c,v 1.3 1999/12/02 17:04:58 joda Exp $");
+
+/* This file defines some a function that generates a random password,
+ that can be used when creating a large amount of principals (such
+ as for a batch of students). Since this is a political matter, you
+ should think about how secure generated passwords has to be.
+
+ Both methods defined here will give you at least 55 bits of
+ entropy.
+ */
+
+/* If you want OTP-style passwords, define OTP_STYLE */
+
+#ifdef OTP_STYLE
+#include <otp.h>
+#else
+static void generate_password(char **pw, int num_classes, ...);
+#endif
+
+void
+random_password(char *pw, size_t len)
+{
+#ifdef OTP_STYLE
+ {
+ des_cblock newkey;
+
+ des_new_random_key(&newkey);
+ otp_print_stddict (newkey, pw, len);
+ strlwr(pw);
+ }
+#else
+ char *pass;
+ generate_password(&pass, 3,
+ "abcdefghijklmnopqrstuvwxyz", 7,
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 2,
+ "@$%&*()-+=:,/<>1234567890", 1);
+ strlcpy(pw, pass, len);
+ memset(pass, 0, strlen(pass));
+ free(pass);
+#endif
+}
+
+/* some helper functions */
+
+#ifndef OTP_STYLE
+/* return a random value in range 0-127 */
+static int
+RND(des_cblock *key, int *left)
+{
+ if(*left == 0){
+ des_new_random_key(key);
+ *left = 8;
+ }
+ (*left)--;
+ return ((unsigned char*)key)[*left];
+}
+
+/* This a helper function that generates a random password with a
+ number of characters from a set of character classes.
+
+ If there are n classes, and the size of each class is Pi, and the
+ number of characters from each class is Ni, the number of possible
+ passwords are (given that the character classes are disjoint):
+
+ n n
+ ----- / ---- \
+ | | Ni | \ |
+ | | Pi | \ Ni| !
+ | | ---- * | / |
+ | | Ni! | /___ |
+ i=1 \ i=1 /
+
+ Since it uses the RND function above, neither the size of each
+ class, nor the total length of the generated password should be
+ larger than 127 (without fixing RND).
+
+ */
+static void
+generate_password(char **pw, int num_classes, ...)
+{
+ struct {
+ const char *str;
+ int len;
+ int freq;
+ } *classes;
+ va_list ap;
+ int len, i;
+ des_cblock rbuf; /* random buffer */
+ int rleft = 0;
+
+ classes = malloc(num_classes * sizeof(*classes));
+ va_start(ap, num_classes);
+ len = 0;
+ for(i = 0; i < num_classes; i++){
+ classes[i].str = va_arg(ap, const char*);
+ classes[i].len = strlen(classes[i].str);
+ classes[i].freq = va_arg(ap, int);
+ len += classes[i].freq;
+ }
+ va_end(ap);
+ *pw = malloc(len + 1);
+ if(*pw == NULL)
+ return;
+ for(i = 0; i < len; i++) {
+ int j;
+ int x = RND(&rbuf, &rleft) % (len - i);
+ int t = 0;
+ for(j = 0; j < num_classes; j++) {
+ if(x < t + classes[j].freq) {
+ (*pw)[i] = classes[j].str[RND(&rbuf, &rleft) % classes[j].len];
+ classes[j].freq--;
+ break;
+ }
+ t += classes[j].freq;
+ }
+ }
+ (*pw)[len] = '\0';
+ memset(rbuf, 0, sizeof(rbuf));
+ free(classes);
+}
+#endif
diff --git a/crypto/heimdal/kadmin/rename.c b/crypto/heimdal/kadmin/rename.c
new file mode 100644
index 0000000..4d8a48e
--- /dev/null
+++ b/crypto/heimdal/kadmin/rename.c
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 1997 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 "kadmin_locl.h"
+
+RCSID("$Id: rename.c,v 1.2 1999/12/02 17:04:58 joda Exp $");
+
+int
+rename_entry(int argc, char **argv)
+{
+ krb5_error_code ret;
+ krb5_principal princ1, princ2;
+
+ if(argc != 3){
+ krb5_warnx(context, "rename source target");
+ return 0;
+ }
+ ret = krb5_parse_name(context, argv[1], &princ1);
+ if(ret){
+ krb5_warn(context, ret, "krb5_parse_name(%s)", argv[1]);
+ return 0;
+ }
+ ret = krb5_parse_name(context, argv[2], &princ2);
+ if(ret){
+ krb5_free_principal(context, princ2);
+ krb5_warn(context, ret, "krb5_parse_name(%s)", argv[2]);
+ return 0;
+ }
+ ret = kadm5_rename_principal(kadm_handle, princ1, princ2);
+ if(ret)
+ krb5_warn(context, ret, "rename");
+ krb5_free_principal(context, princ1);
+ krb5_free_principal(context, princ2);
+ return 0;
+}
+
diff --git a/crypto/heimdal/kadmin/server.c b/crypto/heimdal/kadmin/server.c
new file mode 100644
index 0000000..d491e46
--- /dev/null
+++ b/crypto/heimdal/kadmin/server.c
@@ -0,0 +1,506 @@
+/*
+ * Copyright (c) 1997 - 2000 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 "kadmin_locl.h"
+#include <krb5-private.h>
+
+RCSID("$Id: server.c,v 1.24 2000/01/02 03:58:45 assar Exp $");
+
+static kadm5_ret_t
+kadmind_dispatch(void *kadm_handle, krb5_boolean initial,
+ krb5_data *in, krb5_data *out)
+{
+ kadm5_ret_t ret;
+ int32_t cmd, mask, tmp;
+ kadm5_server_context *context = kadm_handle;
+ char client[128], name[128], name2[128];
+ char *op = "";
+ krb5_principal princ, princ2;
+ kadm5_principal_ent_rec ent;
+ char *password, *exp;
+ krb5_keyblock *new_keys;
+ int n_keys;
+ char **princs;
+ int n_princs;
+ krb5_storage *sp;
+
+ krb5_unparse_name_fixed(context->context, context->caller,
+ client, sizeof(client));
+
+ sp = krb5_storage_from_data(in);
+
+ krb5_ret_int32(sp, &cmd);
+ switch(cmd){
+ case kadm_get:{
+ op = "GET";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_int32(sp, &mask);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_GET);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_get_principal(kadm_handle, princ, &ent, mask);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ kadm5_store_principal_ent(sp, &ent);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ }
+ krb5_free_principal(context->context, princ);
+ break;
+ }
+ case kadm_delete:{
+ op = "DELETE";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_DELETE);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_delete_principal(kadm_handle, princ);
+ krb5_free_principal(context->context, princ);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_create:{
+ op = "CREATE";
+ ret = kadm5_ret_principal_ent(sp, &ent);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_int32(sp, &mask);
+ if(ret){
+ kadm5_free_principal_ent(context->context, &ent);
+ goto fail;
+ }
+ ret = krb5_ret_string(sp, &password);
+ if(ret){
+ kadm5_free_principal_ent(context->context, &ent);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, ent.principal,
+ name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_ADD);
+ if(ret){
+ kadm5_free_principal_ent(context->context, &ent);
+ memset(password, 0, strlen(password));
+ free(password);
+ goto fail;
+ }
+ ret = kadm5_create_principal(kadm_handle, &ent,
+ mask, password);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ memset(password, 0, strlen(password));
+ free(password);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_modify:{
+ op = "MODIFY";
+ ret = kadm5_ret_principal_ent(sp, &ent);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_int32(sp, &mask);
+ if(ret){
+ kadm5_free_principal_ent(context, &ent);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, ent.principal,
+ name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_MODIFY);
+ if(ret){
+ kadm5_free_principal_ent(context, &ent);
+ goto fail;
+ }
+ ret = kadm5_modify_principal(kadm_handle, &ent, mask);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_rename:{
+ op = "RENAME";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_principal(sp, &princ2);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_unparse_name_fixed(context->context, princ2, name2, sizeof(name2));
+ krb5_warnx(context->context, "%s: %s %s -> %s",
+ client, op, name, name2);
+ ret = _kadm5_acl_check_permission(context,
+ KADM5_PRIV_ADD|KADM5_PRIV_DELETE);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_rename_principal(kadm_handle, princ, princ2);
+ krb5_free_principal(context->context, princ);
+ krb5_free_principal(context->context, princ2);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_chpass:{
+ op = "CHPASS";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ ret = krb5_ret_string(sp, &password);
+ if(ret){
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+
+ /*
+ * The change is allowed if at least one of:
+ * a) it's for the principal him/herself and this was an initial ticket
+ * b) the user is on the CPW ACL.
+ */
+
+ if (initial
+ && krb5_principal_compare (context->context, context->caller,
+ princ))
+ ret = 0;
+ else
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW);
+
+ if(ret) {
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_chpass_principal(kadm_handle, princ, password);
+ krb5_free_principal(context->context, princ);
+ memset(password, 0, strlen(password));
+ free(password);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ break;
+ }
+ case kadm_randkey:{
+ op = "RANDKEY";
+ ret = krb5_ret_principal(sp, &princ);
+ if(ret)
+ goto fail;
+ krb5_unparse_name_fixed(context->context, princ, name, sizeof(name));
+ krb5_warnx(context->context, "%s: %s %s", client, op, name);
+ /*
+ * The change is allowed if at least one of:
+ * a) it's for the principal him/herself and this was an initial ticket
+ * b) the user is on the CPW ACL.
+ */
+
+ if (initial
+ && krb5_principal_compare (context->context, context->caller,
+ princ))
+ ret = 0;
+ else
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_CPW);
+
+ if(ret) {
+ krb5_free_principal(context->context, princ);
+ goto fail;
+ }
+ ret = kadm5_randkey_principal(kadm_handle, princ,
+ &new_keys, &n_keys);
+ krb5_free_principal(context->context, princ);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ int i;
+ krb5_store_int32(sp, n_keys);
+ for(i = 0; i < n_keys; i++){
+ krb5_store_keyblock(sp, new_keys[i]);
+ krb5_free_keyblock_contents(context->context, &new_keys[i]);
+ }
+ }
+ break;
+ }
+ case kadm_get_privs:{
+ ret = kadm5_get_privs(kadm_handle, &mask);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0)
+ krb5_store_int32(sp, mask);
+ break;
+ }
+ case kadm_get_princs:{
+ op = "LIST";
+ ret = krb5_ret_int32(sp, &tmp);
+ if(ret)
+ goto fail;
+ if(tmp){
+ ret = krb5_ret_string(sp, &exp);
+ if(ret)
+ goto fail;
+ }else
+ exp = NULL;
+ krb5_warnx(context->context, "%s: %s %s", client, op, exp ? exp : "*");
+ ret = _kadm5_acl_check_permission(context, KADM5_PRIV_LIST);
+ if(ret){
+ free(exp);
+ goto fail;
+ }
+ ret = kadm5_get_principals(kadm_handle, exp, &princs, &n_princs);
+ free(exp);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, ret);
+ if(ret == 0){
+ int i;
+ krb5_store_int32(sp, n_princs);
+ for(i = 0; i < n_princs; i++)
+ krb5_store_string(sp, princs[i]);
+ kadm5_free_name_list(kadm_handle, princs, &n_princs);
+ }
+ break;
+ }
+ default:
+ krb5_warnx(context->context, "%s: UNKNOWN OP %d", client, cmd);
+ krb5_storage_free(sp);
+ sp = krb5_storage_emem();
+ krb5_store_int32(sp, KADM5_FAILURE);
+ break;
+ }
+ krb5_storage_to_data(sp, out);
+ krb5_storage_free(sp);
+ return 0;
+fail:
+ krb5_warn(context->context, ret, "%s", op);
+ sp->seek(sp, 0, SEEK_SET);
+ krb5_store_int32(sp, ret);
+ krb5_storage_to_data(sp, out);
+ krb5_storage_free(sp);
+ return 0;
+}
+
+static void
+v5_loop (krb5_context context,
+ krb5_auth_context ac,
+ krb5_boolean initial,
+ void *kadm_handle,
+ int fd)
+{
+ krb5_error_code ret;
+ ssize_t n;
+ unsigned long len;
+ u_char tmp[4];
+ struct iovec iov[2];
+ krb5_data in, out, msg, reply;
+
+ for (;;) {
+ n = krb5_net_read(context, &fd, tmp, 4);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ if (n == 0)
+ exit (0);
+ _krb5_get_int (tmp, &len, 4);
+
+ ret = krb5_data_alloc(&in, len);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_data_alloc");
+
+ n = krb5_net_read(context, &fd, in.data, in.length);
+ if (n == 0)
+ exit (0);
+ if(n < 0)
+ krb5_errx(context, 1, "read error: %d", errno);
+ ret = krb5_rd_priv(context, ac, &in, &out, NULL);
+ if (ret)
+ krb5_err(context, 1, ret, "krb5_rd_priv");
+ krb5_data_free(&in);
+ kadmind_dispatch(kadm_handle, initial, &out, &msg);
+ krb5_data_free(&out);
+ ret = krb5_mk_priv(context, ac, &msg, &reply, NULL);
+ krb5_data_free(&msg);
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_mk_priv");
+
+ _krb5_put_int(tmp, reply.length, 4);
+
+ iov[0].iov_base = tmp;
+ iov[0].iov_len = 4;
+ iov[1].iov_base = reply.data;
+ iov[1].iov_len = reply.length;
+ n = writev(fd, iov, 2);
+ krb5_data_free(&reply);
+ if(n < 0)
+ krb5_err(context, 1, errno, "writev");
+ if(n < iov[0].iov_len + iov[1].iov_len)
+ krb5_errx(context, 1, "short write");
+ }
+}
+
+static krb5_boolean
+match_appl_version(void *data, const char *appl_version)
+{
+ unsigned minor;
+ if(sscanf(appl_version, "KADM0.%u", &minor) != 1)
+ return 0;
+ *(unsigned*)data = minor;
+ return 1;
+}
+
+static void
+handle_v5(krb5_context context,
+ krb5_auth_context ac,
+ krb5_keytab keytab,
+ int len,
+ int fd)
+{
+ krb5_error_code ret;
+ u_char version[sizeof(KRB5_SENDAUTH_VERSION)];
+ krb5_ticket *ticket;
+ krb5_principal server;
+ char *client;
+ void *kadm_handle;
+ ssize_t n;
+ krb5_boolean initial;
+
+ unsigned kadm_version;
+ kadm5_config_params realm_params;
+
+ if (len != sizeof(KRB5_SENDAUTH_VERSION))
+ krb5_errx(context, 1, "bad sendauth len %d", len);
+ n = krb5_net_read(context, &fd, version, len);
+ if (n < 0)
+ krb5_err (context, 1, errno, "reading sendauth version");
+ if (n == 0)
+ krb5_errx (context, 1, "EOF reading sendauth version");
+ if(memcmp(version, KRB5_SENDAUTH_VERSION, len) != 0)
+ krb5_errx(context, 1, "bad sendauth version %.8s", version);
+
+ ret = krb5_parse_name(context, KADM5_ADMIN_SERVICE, &server);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_parse_name %s", KADM5_ADMIN_SERVICE);
+ ret = krb5_recvauth_match_version(context, &ac, &fd,
+ match_appl_version, &kadm_version,
+ server, KRB5_RECVAUTH_IGNORE_VERSION,
+ keytab, &ticket);
+ if(ret == KRB5_KT_NOTFOUND) {
+ char *name;
+ krb5_unparse_name(context, server, &name);
+ krb5_errx(context, 1, "krb5_recvauth: %s (%s)",
+ krb5_get_err_text(context, ret),
+ name);
+ }
+ krb5_free_principal(context, server);
+
+ if(ret)
+ krb5_err(context, 1, ret, "krb5_recvauth");
+
+ memset(&realm_params, 0, sizeof(realm_params));
+
+ if(kadm_version == 1) {
+ krb5_data enc_data, params;
+ ret = krb5_read_message(context, &fd, &enc_data);
+ ret = krb5_rd_priv(context, ac, &enc_data, &params, NULL);
+ krb5_data_free(&enc_data);
+ _kadm5_unmarshal_params(context, &params, &realm_params);
+ }
+
+ initial = ticket->ticket.flags.initial;
+ ret = krb5_unparse_name(context, ticket->client, &client);
+ if (ret)
+ krb5_err (context, 1, ret, "krb5_unparse_name");
+ krb5_free_ticket (context, ticket);
+ ret = kadm5_init_with_password_ctx(context,
+ client,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ &realm_params,
+ 0, 0,
+ &kadm_handle);
+ if(ret)
+ krb5_err (context, 1, ret, "kadm5_init_with_password_ctx");
+ v5_loop (context, ac, initial, kadm_handle, fd);
+}
+
+krb5_error_code
+kadmind_loop(krb5_context context,
+ krb5_auth_context ac,
+ krb5_keytab keytab,
+ int fd)
+{
+ unsigned char tmp[4];
+ ssize_t n;
+ unsigned long len;
+
+ n = krb5_net_read(context, &fd, tmp, 4);
+ if(n == 0)
+ exit(0);
+ if(n < 0)
+ krb5_errx(context, 1, "read error: %d", errno);
+ _krb5_get_int(tmp, &len, 4);
+ if(len > 0xffff && (len & 0xffff) == ('K' << 8) + 'A') {
+ len >>= 16;
+#ifdef KRB4
+ handle_v4(context, len, fd);
+#else
+ krb5_errx(context, 1, "packet appears to be version 4");
+#endif
+ } else {
+ handle_v5(context, ac, keytab, len, fd);
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/kadmin/util.c b/crypto/heimdal/kadmin/util.c
new file mode 100644
index 0000000..f30c8c5
--- /dev/null
+++ b/crypto/heimdal/kadmin/util.c
@@ -0,0 +1,520 @@
+/*
+ * Copyright (c) 1997, 1998, 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.
+ */
+
+#include "kadmin_locl.h"
+#include <parse_units.h>
+
+RCSID("$Id: util.c,v 1.23 1999/12/02 17:04:58 joda Exp $");
+
+/*
+ * util.c - functions for parsing, unparsing, and editing different
+ * types of data used in kadmin.
+ */
+
+/*
+ * attributes
+ */
+
+struct units kdb_attrs[] = {
+ { "new-princ", KRB5_KDB_NEW_PRINC },
+ { "support-desmd5", KRB5_KDB_SUPPORT_DESMD5 },
+ { "pwchange-service", KRB5_KDB_PWCHANGE_SERVICE },
+ { "disallow-svr", KRB5_KDB_DISALLOW_SVR },
+ { "requires-pw-change", KRB5_KDB_REQUIRES_PWCHANGE },
+ { "requires-hw-auth", KRB5_KDB_REQUIRES_HW_AUTH },
+ { "requires-pre-auth", KRB5_KDB_REQUIRES_PRE_AUTH },
+ { "disallow-all-tix", KRB5_KDB_DISALLOW_ALL_TIX },
+ { "disallow-dup-skey", KRB5_KDB_DISALLOW_DUP_SKEY },
+ { "disallow-proxiable", KRB5_KDB_DISALLOW_PROXIABLE },
+ { "disallow-renewable", KRB5_KDB_DISALLOW_RENEWABLE },
+ { "disallow-tgt-based", KRB5_KDB_DISALLOW_TGT_BASED },
+ { "disallow-forwardable", KRB5_KDB_DISALLOW_FORWARDABLE },
+ { "disallow-postdated", KRB5_KDB_DISALLOW_POSTDATED },
+ { NULL }
+};
+
+/*
+ * convert the attributes in `attributes' into a printable string
+ * in `str, len'
+ */
+
+void
+attributes2str(krb5_flags attributes, char *str, size_t len)
+{
+ unparse_flags (attributes, kdb_attrs, str, len);
+}
+
+/*
+ * convert the string in `str' into attributes in `flags'
+ * return 0 if parsed ok, else -1.
+ */
+
+int
+str2attributes(const char *str, krb5_flags *flags)
+{
+ int res;
+
+ res = parse_flags (str, kdb_attrs, *flags);
+ if (res < 0)
+ return res;
+ else {
+ *flags = res;
+ return 0;
+ }
+}
+
+/*
+ * try to parse the string `resp' into attributes in `attr', also
+ * setting the `bit' in `mask' if attributes are given and valid.
+ */
+
+int
+parse_attributes (const char *resp, krb5_flags *attr, int *mask, int bit)
+{
+ krb5_flags tmp = *attr;
+
+ if (resp[0] == '\0')
+ return 0;
+ else if (str2attributes(resp, &tmp) == 0) {
+ *attr = tmp;
+ if (mask)
+ *mask |= bit;
+ return 0;
+ } else if(*resp == '?') {
+ print_flags_table (kdb_attrs, stderr);
+ } else {
+ fprintf (stderr, "Unable to parse '%s'\n", resp);
+ }
+ return -1;
+}
+
+/*
+ * allow the user to edit the attributes in `attr', prompting with `prompt'
+ */
+
+int
+edit_attributes (const char *prompt, krb5_flags *attr, int *mask, int bit)
+{
+ char buf[1024], resp[1024];
+
+ if (mask && (*mask & bit))
+ return 0;
+
+ attributes2str(*attr, buf, sizeof(buf));
+ for (;;) {
+ get_response("Attributes", buf, resp, sizeof(resp));
+ if (parse_attributes (resp, attr, mask, bit) == 0)
+ break;
+ }
+ return 0;
+}
+
+/*
+ * time_t
+ * the special value 0 means ``never''
+ */
+
+/*
+ * Convert the time `t' to a string representation in `str' (of max
+ * size `len'). If include_time also include time, otherwise just
+ * date.
+ */
+
+void
+time_t2str(time_t t, char *str, size_t len, int include_time)
+{
+ if(t) {
+ if(include_time)
+ strftime(str, len, "%Y-%m-%d %H:%M:%S UTC", gmtime(&t));
+ else
+ strftime(str, len, "%Y-%m-%d", gmtime(&t));
+ } else
+ snprintf(str, len, "never");
+}
+
+/*
+ * Convert the time representation in `str' to a time in `time'.
+ * Return 0 if succesful, else -1.
+ */
+
+int
+str2time_t (const char *str, time_t *time)
+{
+ const char *p;
+ struct tm tm;
+
+ memset (&tm, 0, sizeof (tm));
+
+ if(strcasecmp(str, "never") == 0) {
+ *time = 0;
+ return 0;
+ }
+
+ p = strptime (str, "%Y-%m-%d", &tm);
+
+ if (p == NULL)
+ return -1;
+
+ /* Do it on the end of the day */
+ tm.tm_hour = 23;
+ tm.tm_min = 59;
+ tm.tm_sec = 59;
+
+ strptime (p, "%H:%M:%S", &tm);
+
+ *time = tm2time (tm, 0);
+ return 0;
+}
+
+/*
+ * try to parse the time in `resp' storing it in `value'
+ */
+
+int
+parse_timet (const char *resp, krb5_timestamp *value, int *mask, int bit)
+{
+ time_t tmp;
+
+ if (str2time_t(resp, &tmp) == 0) {
+ *value = tmp;
+ if(mask)
+ *mask |= bit;
+ return 0;
+ } else if(*resp == '?') {
+ printf ("Print date on format YYYY-mm-dd [hh:mm:ss]\n");
+ } else {
+ fprintf (stderr, "Unable to parse time '%s'\n", resp);
+ }
+ return -1;
+}
+
+/*
+ * allow the user to edit the time in `value'
+ */
+
+int
+edit_timet (const char *prompt, krb5_timestamp *value, int *mask, int bit)
+{
+ char buf[1024], resp[1024];
+
+ if (mask && (*mask & bit))
+ return 0;
+
+ time_t2str (*value, buf, sizeof (buf), 0);
+
+ for (;;) {
+ get_response(prompt, buf, resp, sizeof(resp));
+ if (parse_timet (resp, value, mask, bit) == 0)
+ break;
+ }
+ return 0;
+}
+
+/*
+ * deltat
+ * the special value 0 means ``unlimited''
+ */
+
+/*
+ * convert the delta_t value in `t' into a printable form in `str, len'
+ */
+
+void
+deltat2str(unsigned t, char *str, size_t len)
+{
+ if(t)
+ unparse_time(t, str, len);
+ else
+ snprintf(str, len, "unlimited");
+}
+
+/*
+ * parse the delta value in `str', storing result in `*delta'
+ * return 0 if ok, else -1
+ */
+
+int
+str2deltat(const char *str, krb5_deltat *delta)
+{
+ int res;
+
+ if(strcasecmp(str, "unlimited") == 0) {
+ *delta = 0;
+ return 0;
+ }
+ res = parse_time(str, "day");
+ if (res < 0)
+ return res;
+ else {
+ *delta = res;
+ return 0;
+ }
+}
+
+/*
+ * try to parse the string in `resp' into a deltad in `value'
+ * `mask' will get the bit `bit' set if a value was given.
+ */
+
+int
+parse_deltat (const char *resp, krb5_deltat *value, int *mask, int bit)
+{
+ krb5_deltat tmp;
+
+ if (str2deltat(resp, &tmp) == 0) {
+ *value = tmp;
+ if (mask)
+ *mask |= bit;
+ return 0;
+ } else if(*resp == '?') {
+ print_time_table (stderr);
+ } else {
+ fprintf (stderr, "Unable to parse time '%s'\n", resp);
+ }
+ return -1;
+}
+
+/*
+ * allow the user to edit the deltat in `value'
+ */
+
+int
+edit_deltat (const char *prompt, krb5_deltat *value, int *mask, int bit)
+{
+ char buf[1024], resp[1024];
+
+ if (mask && (*mask & bit))
+ return 0;
+
+ deltat2str(*value, buf, sizeof(buf));
+ for (;;) {
+ get_response(prompt, buf, resp, sizeof(resp));
+ if (parse_deltat (resp, value, mask, bit) == 0)
+ break;
+ }
+ return 0;
+}
+
+/*
+ * allow the user to edit `ent'
+ */
+
+int
+edit_entry(kadm5_principal_ent_t ent, int *mask,
+ kadm5_principal_ent_t default_ent, int default_mask)
+{
+ if (default_ent && (default_mask & KADM5_MAX_LIFE))
+ ent->max_life = default_ent->max_life;
+ edit_deltat ("Max ticket life", &ent->max_life, mask,
+ KADM5_MAX_LIFE);
+
+ if (default_ent && (default_mask & KADM5_MAX_RLIFE))
+ ent->max_renewable_life = default_ent->max_renewable_life;
+ edit_deltat ("Max renewable life", &ent->max_renewable_life, mask,
+ KADM5_MAX_RLIFE);
+
+ if (default_ent && (default_mask & KADM5_PRINC_EXPIRE_TIME))
+ ent->princ_expire_time = default_ent->princ_expire_time;
+ edit_timet ("Principal expiration time", &ent->princ_expire_time, mask,
+ KADM5_PRINC_EXPIRE_TIME);
+
+ if (default_ent && (default_mask & KADM5_PW_EXPIRATION))
+ ent->pw_expiration = default_ent->pw_expiration;
+ edit_timet ("Password expiration time", &ent->pw_expiration, mask,
+ KADM5_PW_EXPIRATION);
+
+ if (default_ent && (default_mask & KADM5_ATTRIBUTES))
+ ent->attributes = default_ent->attributes & ~KRB5_KDB_DISALLOW_ALL_TIX;
+ edit_attributes ("Attributes", &ent->attributes, mask,
+ KADM5_ATTRIBUTES);
+ return 0;
+}
+
+/*
+ * Parse the arguments, set the fields in `ent' and the `mask' for the
+ * entries having been set.
+ * Return 1 on failure and 0 on success.
+ */
+
+int
+set_entry(krb5_context context,
+ kadm5_principal_ent_t ent,
+ int *mask,
+ const char *max_ticket_life,
+ const char *max_renewable_life,
+ const char *expiration,
+ const char *pw_expiration,
+ const char *attributes)
+{
+ if (max_ticket_life != NULL) {
+ if (parse_deltat (max_ticket_life, &ent->max_life,
+ mask, KADM5_MAX_LIFE)) {
+ krb5_warnx (context, "unable to parse `%s'", max_ticket_life);
+ return 1;
+ }
+ }
+ if (max_renewable_life != NULL) {
+ if (parse_deltat (max_renewable_life, &ent->max_renewable_life,
+ mask, KADM5_MAX_RLIFE)) {
+ krb5_warnx (context, "unable to parse `%s'", max_renewable_life);
+ return 1;
+ }
+ }
+
+ if (expiration) {
+ if (parse_timet (expiration, &ent->princ_expire_time,
+ mask, KADM5_PRINC_EXPIRE_TIME)) {
+ krb5_warnx (context, "unable to parse `%s'", expiration);
+ return 1;
+ }
+ }
+ if (pw_expiration) {
+ if (parse_timet (pw_expiration, &ent->pw_expiration,
+ mask, KADM5_PW_EXPIRATION)) {
+ krb5_warnx (context, "unable to parse `%s'", pw_expiration);
+ return 1;
+ }
+ }
+ if (attributes != NULL) {
+ if (parse_attributes (attributes, &ent->attributes,
+ mask, KADM5_ATTRIBUTES)) {
+ krb5_warnx (context, "unable to parse `%s'", attributes);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/*
+ * Does `string' contain any globing characters?
+ */
+
+static int
+is_expression(const char *string)
+{
+ const char *p;
+ int quote = 0;
+
+ for(p = string; *p; p++) {
+ if(quote) {
+ quote = 0;
+ continue;
+ }
+ if(*p == '\\')
+ quote++;
+ else if(strchr("[]*?", *p) != NULL)
+ return 1;
+ }
+ return 0;
+}
+
+/* loop over all principals matching exp */
+int
+foreach_principal(const char *exp,
+ int (*func)(krb5_principal, void*),
+ void *data)
+{
+ char **princs;
+ int num_princs;
+ int i;
+ krb5_error_code ret;
+ krb5_principal princ_ent;
+ int is_expr;
+
+ /* if this isn't an expression, there is no point in wading
+ through the whole database looking for matches */
+ is_expr = is_expression(exp);
+ if(is_expr)
+ ret = kadm5_get_principals(kadm_handle, exp, &princs, &num_princs);
+ if(!is_expr || ret == KADM5_AUTH_LIST) {
+ /* we might be able to perform the requested opreration even
+ if we're not allowed to list principals */
+ num_princs = 1;
+ princs = malloc(sizeof(*princs));
+ if(princs == NULL)
+ return ENOMEM;
+ princs[0] = strdup(exp);
+ if(princs[0] == NULL){
+ free(princs);
+ return ENOMEM;
+ }
+ } else if(ret) {
+ krb5_warn(context, ret, "kadm5_get_principals");
+ return ret;
+ }
+ for(i = 0; i < num_princs; i++) {
+ ret = krb5_parse_name(context, princs[i], &princ_ent);
+ if(ret){
+ krb5_warn(context, ret, "krb5_parse_name(%s)", princs[i]);
+ continue;
+ }
+ ret = (*func)(princ_ent, data);
+ if(ret) {
+ char *tmp;
+ krb5_error_code ret2;
+
+ ret2 = krb5_unparse_name(context, princ_ent, &tmp);
+ if(ret2) {
+ krb5_warn(context, ret2, "krb5_unparse_name");
+ krb5_warn(context, ret, "<unknown principal>");
+ } else {
+ krb5_warn(context, ret, "%s", tmp);
+ free(tmp);
+ }
+ }
+ krb5_free_principal(context, princ_ent);
+ }
+ kadm5_free_name_list(kadm_handle, princs, &num_princs);
+ return 0;
+}
+
+/*
+ * prompt with `prompt' and default value `def', and store the reply
+ * in `buf, len'
+ */
+
+void
+get_response(const char *prompt, const char *def, char *buf, size_t len)
+{
+ char *p;
+
+ printf("%s [%s]:", prompt, def);
+ if(fgets(buf, len, stdin) == NULL)
+ *buf = '\0';
+ p = strchr(buf, '\n');
+ if(p)
+ *p = '\0';
+ if(strcmp(buf, "") == 0)
+ strncpy(buf, def, len);
+ buf[len-1] = 0;
+}
diff --git a/crypto/heimdal/kadmin/version4.c b/crypto/heimdal/kadmin/version4.c
new file mode 100644
index 0000000..77ac029
--- /dev/null
+++ b/crypto/heimdal/kadmin/version4.c
@@ -0,0 +1,985 @@
+/*
+ * Copyright (c) 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 KTH 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 KTH AND ITS 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 KTH OR ITS 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 "kadmin_locl.h"
+#include <krb5-private.h>
+
+#define Principal krb4_Principal
+#define kadm_get krb4_kadm_get
+#undef ALLOC
+#include <krb.h>
+#include <kadm.h>
+#include <krb_err.h>
+#include <kadm_err.h>
+
+RCSID("$Id: version4.c,v 1.16 1999/11/25 22:32:47 assar Exp $");
+
+#define KADM_NO_OPCODE -1
+#define KADM_NO_ENCRYPT -2
+
+/*
+ * make an error packet if we fail encrypting
+ */
+
+static void
+make_you_loose_packet(int code, krb5_data *reply)
+{
+ krb5_data_alloc(reply, KADM_VERSIZE + 4);
+ memcpy(reply->data, KADM_ULOSE, KADM_VERSIZE);
+ _krb5_put_int((char*)reply->data + KADM_VERSIZE, code, 4);
+}
+
+static int
+ret_fields(krb5_storage *sp, char *fields)
+{
+ return sp->fetch(sp, fields, FLDSZ);
+}
+
+static int
+store_fields(krb5_storage *sp, char *fields)
+{
+ return sp->store(sp, fields, FLDSZ);
+}
+
+static void
+ret_vals(krb5_storage *sp, Kadm_vals *vals)
+{
+ int field;
+ char *tmp_string;
+
+ memset(vals, 0, sizeof(*vals));
+
+ ret_fields(sp, vals->fields);
+
+ for(field = 31; field >= 0; field--) {
+ if(IS_FIELD(field, vals->fields)) {
+ switch(field) {
+ case KADM_NAME:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->name, tmp_string, sizeof(vals->name));
+ free(tmp_string);
+ break;
+ case KADM_INST:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->instance, tmp_string,
+ sizeof(vals->instance));
+ free(tmp_string);
+ break;
+ case KADM_EXPDATE:
+ krb5_ret_int32(sp, &vals->exp_date);
+ break;
+ case KADM_ATTR:
+ krb5_ret_int16(sp, &vals->attributes);
+ break;
+ case KADM_MAXLIFE:
+ krb5_ret_int8(sp, &vals->max_life);
+ break;
+ case KADM_DESKEY:
+ krb5_ret_int32(sp, &vals->key_high);
+ krb5_ret_int32(sp, &vals->key_low);
+ break;
+#ifdef EXTENDED_KADM
+ case KADM_MODDATE:
+ krb5_ret_int32(sp, &vals->mod_date);
+ break;
+ case KADM_MODNAME:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->mod_name, tmp_string,
+ sizeof(vals->mod_name));
+ free(tmp_string);
+ break;
+ case KADM_MODINST:
+ krb5_ret_stringz(sp, &tmp_string);
+ strlcpy(vals->mod_instance, tmp_string,
+ sizeof(vals->mod_instance));
+ free(tmp_string);
+ break;
+ case KADM_KVNO:
+ krb5_ret_int8(sp, &vals->key_version);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static void
+store_vals(krb5_storage *sp, Kadm_vals *vals)
+{
+ int field;
+
+ store_fields(sp, vals->fields);
+
+ for(field = 31; field >= 0; field--) {
+ if(IS_FIELD(field, vals->fields)) {
+ switch(field) {
+ case KADM_NAME:
+ krb5_store_stringz(sp, vals->name);
+ break;
+ case KADM_INST:
+ krb5_store_stringz(sp, vals->instance);
+ break;
+ case KADM_EXPDATE:
+ krb5_store_int32(sp, vals->exp_date);
+ break;
+ case KADM_ATTR:
+ krb5_store_int16(sp, vals->attributes);
+ break;
+ case KADM_MAXLIFE:
+ krb5_store_int8(sp, vals->max_life);
+ break;
+ case KADM_DESKEY:
+ krb5_store_int32(sp, vals->key_high);
+ krb5_store_int32(sp, vals->key_low);
+ break;
+#ifdef EXTENDED_KADM
+ case KADM_MODDATE:
+ krb5_store_int32(sp, vals->mod_date);
+ break;
+ case KADM_MODNAME:
+ krb5_store_stringz(sp, vals->mod_name);
+ break;
+ case KADM_MODINST:
+ krb5_store_stringz(sp, vals->mod_instance);
+ break;
+ case KADM_KVNO:
+ krb5_store_int8(sp, vals->key_version);
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+ }
+}
+
+static int
+flags_4_to_5(char *flags)
+{
+ int i;
+ int32_t mask = 0;
+ for(i = 31; i >= 0; i--) {
+ if(IS_FIELD(i, flags))
+ switch(i) {
+ case KADM_NAME:
+ case KADM_INST:
+ mask |= KADM5_PRINCIPAL;
+ case KADM_EXPDATE:
+ mask |= KADM5_PW_EXPIRATION;
+ case KADM_MAXLIFE:
+ mask |= KADM5_MAX_LIFE;
+#ifdef EXTENDED_KADM
+ case KADM_KVNO:
+ mask |= KADM5_KEY_DATA;
+ case KADM_MODDATE:
+ mask |= KADM5_MOD_TIME;
+ case KADM_MODNAME:
+ case KADM_MODINST:
+ mask |= KADM5_MOD_NAME;
+#endif
+ }
+ }
+ return mask;
+}
+
+static void
+ent_to_values(krb5_context context,
+ kadm5_principal_ent_t ent,
+ int32_t mask,
+ Kadm_vals *vals)
+{
+ krb5_error_code ret;
+ char realm[REALM_SZ];
+
+ memset(vals, 0, sizeof(*vals));
+ if(mask & KADM5_PRINCIPAL) {
+ ret = krb5_524_conv_principal(context, ent->principal,
+ vals->name, vals->instance, realm);
+ SET_FIELD(KADM_NAME, vals->fields);
+ SET_FIELD(KADM_INST, vals->fields);
+ }
+ if(mask & KADM5_PW_EXPIRATION) {
+ time_t exp = 0;
+ if(ent->princ_expire_time != 0)
+ exp = ent->princ_expire_time;
+ if(ent->pw_expiration != 0 && (exp == 0 || exp > ent->pw_expiration))
+ exp = ent->pw_expiration;
+ if(exp) {
+ vals->exp_date = exp;
+ SET_FIELD(KADM_EXPDATE, vals->fields);
+ }
+ }
+ if(mask & KADM5_MAX_LIFE) {
+ if(ent->max_life == 0)
+ vals->max_life = 255;
+ else
+ vals->max_life = krb_time_to_life(0, ent->max_life);
+ SET_FIELD(KADM_MAXLIFE, vals->fields);
+ }
+ if(mask & KADM5_KEY_DATA) {
+ if(ent->n_key_data > 0) {
+#ifdef EXTENDED_KADM
+ vals->key_version = ent->key_data[0].key_data_kvno;
+ SET_FIELD(KADM_KVNO, vals->fields);
+#endif
+ }
+ /* XXX the key itself? */
+ }
+#ifdef EXTENDED_KADM
+ if(mask & KADM5_MOD_TIME) {
+ vals->mod_date = ent->mod_date;
+ SET_FIELD(KADM_MODDATE, vals->fields);
+ }
+ if(mask & KADM5_MOD_NAME) {
+ krb5_524_conv_principal(context, ent->mod_name,
+ vals->mod_name, vals->mod_instance, realm);
+ SET_FIELD(KADM_MODNAME, vals->fields);
+ SET_FIELD(KADM_MODINST, vals->fields);
+ }
+#endif
+}
+
+/*
+ * convert the kadm4 values in `vals' to `ent' (and `mask')
+ */
+
+static krb5_error_code
+values_to_ent(krb5_context context,
+ Kadm_vals *vals,
+ kadm5_principal_ent_t ent,
+ int32_t *mask)
+{
+ krb5_error_code ret;
+ *mask = 0;
+ memset(ent, 0, sizeof(*ent));
+
+ if(IS_FIELD(KADM_NAME, vals->fields)) {
+ char *inst = NULL;
+ if(IS_FIELD(KADM_INST, vals->fields))
+ inst = vals->instance;
+ ret = krb5_425_conv_principal(context,
+ vals->name,
+ inst,
+ NULL,
+ &ent->principal);
+ if(ret)
+ return ret;
+ *mask |= KADM5_PRINCIPAL;
+ }
+ if(IS_FIELD(KADM_EXPDATE, vals->fields)) {
+ ent->pw_expiration = vals->exp_date;
+ *mask |= KADM5_PW_EXPIRATION;
+ }
+ if(IS_FIELD(KADM_MAXLIFE, vals->fields)) {
+ ent->max_life = krb_life_to_time(0, vals->max_life);
+ *mask |= KADM5_MAX_LIFE;
+ }
+
+ if(IS_FIELD(KADM_DESKEY, vals->fields)) {
+ int i;
+ ent->key_data = calloc(3, sizeof(*ent->key_data));
+ if(ent->key_data == NULL)
+ return ENOMEM;
+ for(i = 0; i < 3; i++) {
+ u_int32_t key_low, key_high;
+
+ ent->key_data[i].key_data_ver = 2;
+#ifdef EXTENDED_KADM
+ if(IS_FIELD(KADM_KVNO, vals->fields))
+ ent->key_data[i].key_data_kvno = vals->key_version;
+#endif
+ ent->key_data[i].key_data_type[0] = ETYPE_DES_CBC_MD5;
+ ent->key_data[i].key_data_length[0] = 8;
+ if((ent->key_data[i].key_data_contents[0] = malloc(8)) == NULL)
+ return ENOMEM;
+
+ key_low = ntohl(vals->key_low);
+ key_high = ntohl(vals->key_high);
+ memcpy(ent->key_data[i].key_data_contents[0],
+ &key_low, 4);
+ memcpy((char*)ent->key_data[i].key_data_contents[0] + 4,
+ &key_high, 4);
+ ent->key_data[i].key_data_type[1] = KRB5_PW_SALT;
+ ent->key_data[i].key_data_length[1] = 0;
+ ent->key_data[i].key_data_contents[1] = NULL;
+ }
+ ent->key_data[1].key_data_type[0] = ETYPE_DES_CBC_MD4;
+ ent->key_data[2].key_data_type[0] = ETYPE_DES_CBC_CRC;
+ ent->n_key_data = 3;
+ *mask |= KADM5_KEY_DATA;
+ }
+
+#ifdef EXTENDED_KADM
+ if(IS_FIELD(KADM_MODDATE, vals->fields)) {
+ ent->mod_date = vals->mod_date;
+ *mask |= KADM5_MOD_TIME;
+ }
+ if(IS_FIELD(KADM_MODNAME, vals->fields)) {
+ char *inst = NULL;
+ if(IS_FIELD(KADM_MODINST, vals->fields))
+ inst = vals->mod_instance;
+ ret = krb5_425_conv_principal(context,
+ vals->mod_name,
+ inst,
+ NULL,
+ &ent->mod_name);
+ if(ret)
+ return ret;
+ *mask |= KADM5_MOD_NAME;
+ }
+#endif
+ return 0;
+}
+
+/*
+ * Try to translate a KADM5 error code into a v4 kadmin one.
+ */
+
+static int
+error_code(int ret)
+{
+ switch (ret) {
+ case 0:
+ return 0;
+ case KADM5_FAILURE :
+ case KADM5_AUTH_GET :
+ case KADM5_AUTH_ADD :
+ case KADM5_AUTH_MODIFY :
+ case KADM5_AUTH_DELETE :
+ case KADM5_AUTH_INSUFFICIENT :
+ return KADM_UNAUTH;
+ case KADM5_BAD_DB :
+ return KADM_UK_RERROR;
+ case KADM5_DUP :
+ return KADM_INUSE;
+ case KADM5_RPC_ERROR :
+ case KADM5_NO_SRV :
+ return KADM_NO_SERV;
+ case KADM5_NOT_INIT :
+ return KADM_NO_CONN;
+ case KADM5_UNK_PRINC :
+ return KADM_NOENTRY;
+ case KADM5_PASS_Q_TOOSHORT :
+#ifdef KADM_PASS_Q_TOOSHORT
+ return KADM_PASS_Q_TOOSHORT;
+#else
+ return KADM_INSECURE_PW;
+#endif
+ case KADM5_PASS_Q_CLASS :
+#ifdef KADM_PASS_Q_CLASS
+ return KADM_PASS_Q_CLASS;
+#else
+ return KADM_INSECURE_PW;
+#endif
+ case KADM5_PASS_Q_DICT :
+#ifdef KADM_PASS_Q_DICT
+ return KADM_PASS_Q_DICT;
+#else
+ return KADM_INSECURE_PW;
+#endif
+ case KADM5_PASS_REUSE :
+ case KADM5_PASS_TOOSOON :
+ case KADM5_BAD_PASSWORD :
+ return KADM_INSECURE_PW;
+ case KADM5_PROTECT_PRINCIPAL :
+ return KADM_IMMUTABLE;
+ case KADM5_POLICY_REF :
+ case KADM5_INIT :
+ case KADM5_BAD_HIST_KEY :
+ case KADM5_UNK_POLICY :
+ case KADM5_BAD_MASK :
+ case KADM5_BAD_CLASS :
+ case KADM5_BAD_LENGTH :
+ case KADM5_BAD_POLICY :
+ case KADM5_BAD_PRINCIPAL :
+ case KADM5_BAD_AUX_ATTR :
+ case KADM5_BAD_HISTORY :
+ case KADM5_BAD_MIN_PASS_LIFE :
+ case KADM5_BAD_SERVER_HANDLE :
+ case KADM5_BAD_STRUCT_VERSION :
+ case KADM5_OLD_STRUCT_VERSION :
+ case KADM5_NEW_STRUCT_VERSION :
+ case KADM5_BAD_API_VERSION :
+ case KADM5_OLD_LIB_API_VERSION :
+ case KADM5_OLD_SERVER_API_VERSION :
+ case KADM5_NEW_LIB_API_VERSION :
+ case KADM5_NEW_SERVER_API_VERSION :
+ case KADM5_SECURE_PRINC_MISSING :
+ case KADM5_NO_RENAME_SALT :
+ case KADM5_BAD_CLIENT_PARAMS :
+ case KADM5_BAD_SERVER_PARAMS :
+ case KADM5_AUTH_LIST :
+ case KADM5_AUTH_CHANGEPW :
+ case KADM5_BAD_TL_TYPE :
+ case KADM5_MISSING_CONF_PARAMS :
+ case KADM5_BAD_SERVER_NAME :
+ default :
+ return KADM_UNAUTH; /* XXX */
+ }
+}
+
+/*
+ * server functions
+ */
+
+static int
+kadm_ser_cpw(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ char key[8];
+ char *password = NULL;
+ krb5_error_code ret;
+
+ krb5_warnx(context, "v4-compat %s: cpw %s",
+ principal_string, principal_string);
+
+ ret = message->fetch(message, key + 4, 4);
+ ret = message->fetch(message, key, 4);
+ ret = krb5_ret_stringz(message, &password);
+
+ if(password) {
+ krb5_data pwd_data;
+ const char *tmp;
+
+ pwd_data.data = password;
+ pwd_data.length = strlen(password);
+
+ tmp = kadm5_check_password_quality (context, principal, &pwd_data);
+
+ if (tmp != NULL) {
+ krb5_store_stringz (reply, (char *)tmp);
+ ret = KADM5_PASS_Q_DICT;
+ goto fail;
+ }
+ ret = kadm5_chpass_principal(kadm_handle, principal, password);
+ } else {
+ krb5_key_data key_data[3];
+ int i;
+ for(i = 0; i < 3; i++) {
+ key_data[i].key_data_ver = 2;
+ key_data[i].key_data_kvno = 0;
+ /* key */
+ key_data[i].key_data_type[0] = ETYPE_DES_CBC_CRC;
+ key_data[i].key_data_length[0] = 8;
+ key_data[i].key_data_contents[0] = malloc(8);
+ memcpy(key_data[i].key_data_contents[0], &key, 8);
+ /* salt */
+ key_data[i].key_data_type[1] = KRB5_PW_SALT;
+ key_data[i].key_data_length[1] = 0;
+ key_data[i].key_data_contents[1] = NULL;
+ }
+ key_data[0].key_data_type[0] = ETYPE_DES_CBC_MD5;
+ key_data[1].key_data_type[0] = ETYPE_DES_CBC_MD4;
+ ret = kadm5_s_chpass_principal_with_key(kadm_handle,
+ principal, 3, key_data);
+ }
+
+ if(ret != 0) {
+ krb5_store_stringz(reply, (char*)krb5_get_err_text(context, ret));
+ goto fail;
+ }
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat cpw");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_add(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ int32_t mask;
+ kadm5_principal_ent_rec ent, out;
+ Kadm_vals values;
+ krb5_error_code ret;
+ char name[128];
+
+ ret_vals(message, &values);
+
+ ret = values_to_ent(context, &values, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: add %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_ADD);
+ if (ret)
+ goto fail;
+
+ ret = kadm5_s_create_principal_with_key(kadm_handle, &ent, mask);
+ if(ret) {
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ goto fail;
+ }
+
+ mask = KADM5_PRINCIPAL | KADM5_PW_EXPIRATION | KADM5_MAX_LIFE |
+ KADM5_KEY_DATA | KADM5_MOD_TIME | KADM5_MOD_NAME;
+
+ kadm5_get_principal(kadm_handle, ent.principal, &out, mask);
+ ent_to_values(context, &out, mask, &values);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ kadm5_free_principal_ent(kadm_handle, &out);
+ store_vals(reply, &values);
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat add");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_get(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ krb5_error_code ret;
+ Kadm_vals values;
+ kadm5_principal_ent_rec ent, out;
+ int32_t mask;
+ char flags[FLDSZ];
+ char name[128];
+
+ ret_vals(message, &values);
+ /* XXX BRAIN DAMAGE! these flags are not stored in the same order
+ as in the header */
+ krb5_ret_int8(message, &flags[3]);
+ krb5_ret_int8(message, &flags[2]);
+ krb5_ret_int8(message, &flags[1]);
+ krb5_ret_int8(message, &flags[0]);
+ ret = values_to_ent(context, &values, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: get %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_GET);
+ if (ret)
+ goto fail;
+
+ mask = flags_4_to_5(flags);
+
+ ret = kadm5_get_principal(kadm_handle, ent.principal, &out, mask);
+ kadm5_free_principal_ent(kadm_handle, &ent);
+
+ if (ret)
+ goto fail;
+
+ ent_to_values(context, &out, mask, &values);
+
+ kadm5_free_principal_ent(kadm_handle, &out);
+
+ store_vals(reply, &values);
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat get");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_mod(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ Kadm_vals values1, values2;
+ kadm5_principal_ent_rec ent, out;
+ int32_t mask;
+ krb5_error_code ret;
+ char name[128];
+
+ ret_vals(message, &values1);
+ /* why are the old values sent? is the mask the same in the old and
+ the new entry? */
+ ret_vals(message, &values2);
+
+ ret = values_to_ent(context, &values2, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: mod %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_MODIFY);
+ if (ret)
+ goto fail;
+
+ ret = kadm5_s_modify_principal(kadm_handle, &ent, mask);
+ if(ret) {
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ krb5_warn(context, ret, "kadm5_s_modify_principal");
+ goto fail;
+ }
+
+ ret = kadm5_get_principal(kadm_handle, ent.principal, &out, mask);
+ if(ret) {
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ krb5_warn(context, ret, "kadm5_s_modify_principal");
+ goto fail;
+ }
+
+ ent_to_values(context, &out, mask, &values1);
+
+ kadm5_free_principal_ent(kadm_handle, &ent);
+ kadm5_free_principal_ent(kadm_handle, &out);
+
+ store_vals(reply, &values1);
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat mod");
+ return error_code(ret);
+}
+
+static int
+kadm_ser_del(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_storage *message,
+ krb5_storage *reply)
+{
+ Kadm_vals values;
+ kadm5_principal_ent_rec ent;
+ int32_t mask;
+ krb5_error_code ret;
+ char name[128];
+
+ ret_vals(message, &values);
+
+ ret = values_to_ent(context, &values, &ent, &mask);
+ if(ret)
+ goto fail;
+
+ krb5_unparse_name_fixed(context, ent.principal, name, sizeof(name));
+ krb5_warnx(context, "v4-compat %s: del %s",
+ principal_string, name);
+
+ ret = _kadm5_acl_check_permission (kadm_handle, KADM5_PRIV_DELETE);
+ if (ret)
+ goto fail;
+
+ ret = kadm5_delete_principal(kadm_handle, ent.principal);
+
+ kadm5_free_principal_ent(kadm_handle, &ent);
+
+ if (ret)
+ goto fail;
+
+ return 0;
+fail:
+ krb5_warn(context, ret, "v4-compat add");
+ return error_code(ret);
+}
+
+static int
+dispatch(krb5_context context,
+ void *kadm_handle,
+ krb5_principal principal,
+ const char *principal_string,
+ krb5_data msg,
+ krb5_data *reply)
+{
+ int retval;
+ int8_t command;
+ krb5_storage *sp_in, *sp_out;
+
+ sp_in = krb5_storage_from_data(&msg);
+ krb5_ret_int8(sp_in, &command);
+
+ sp_out = krb5_storage_emem();
+ sp_out->store(sp_out, KADM_VERSTR, KADM_VERSIZE);
+ krb5_store_int32(sp_out, 0);
+
+ switch(command) {
+ case CHANGE_PW:
+ retval = kadm_ser_cpw(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case ADD_ENT:
+ retval = kadm_ser_add(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case GET_ENT:
+ retval = kadm_ser_get(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case MOD_ENT:
+ retval = kadm_ser_mod(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ case DEL_ENT:
+ retval = kadm_ser_del(context, kadm_handle, principal,
+ principal_string,
+ sp_in, sp_out);
+ break;
+ default:
+ krb5_warnx(context, "v4-compat %s: unknown opcode: %d",
+ principal_string, command);
+ retval = KADM_NO_OPCODE;
+ break;
+ }
+ krb5_storage_free(sp_in);
+ if(retval) {
+ sp_out->seek(sp_out, KADM_VERSIZE, SEEK_SET);
+ krb5_store_int32(sp_out, retval);
+ }
+ krb5_storage_to_data(sp_out, reply);
+ krb5_storage_free(sp_out);
+ return retval;
+}
+
+/*
+ * Decode a v4 kadmin packet in `message' and create a reply in `reply'
+ */
+
+static void
+decode_packet(krb5_context context,
+ struct sockaddr_in *admin_addr,
+ struct sockaddr_in *client_addr,
+ krb5_data message,
+ krb5_data *reply)
+{
+ int ret;
+ KTEXT_ST authent;
+ AUTH_DAT ad;
+ MSG_DAT msg_dat;
+ off_t off = 0;
+ unsigned long rlen;
+ char sname[] = "changepw", sinst[] = "kerberos";
+ unsigned long checksum;
+ des_key_schedule schedule;
+ char *msg = message.data;
+ void *kadm_handle;
+ krb5_principal client;
+ char *client_str;
+
+ if(message.length < KADM_VERSIZE
+ || strncmp(msg, KADM_VERSTR, KADM_VERSIZE) != 0) {
+ make_you_loose_packet (KADM_BAD_VER, reply);
+ return;
+ }
+
+ off = KADM_VERSIZE;
+ off += _krb5_get_int(msg + off, &rlen, 4);
+ memset(&authent, 0, sizeof(authent));
+ authent.length = message.length - rlen - KADM_VERSIZE - 4;
+ memcpy(authent.dat, (char*)msg + off, authent.length);
+ off += authent.length;
+
+ {
+ krb5_principal principal;
+ krb5_keyblock *key;
+
+ ret = krb5_make_principal(context, &principal, NULL,
+ "changepw", "kerberos", NULL);
+ if (ret) {
+ krb5_warn (context, ret, "krb5_make_principal");
+ make_you_loose_packet (KADM_NOMEM, reply);
+ return;
+ }
+ ret = krb5_kt_read_service_key(context,
+ "HDB:",
+ principal,
+ 0,
+/* ETYPE_DES_CBC_CRC,*/
+ ETYPE_DES_CBC_MD5,
+ &key);
+ krb5_free_principal(context, principal);
+ if(ret) {
+ if(ret == KRB5_KT_NOTFOUND)
+ make_you_loose_packet(KADM_NO_AUTH, reply);
+ else
+ /* XXX */
+ make_you_loose_packet(KADM_NO_AUTH, reply);
+ krb5_warn(context, ret, "krb5_kt_read_service_key");
+ return;
+ }
+
+ if(key->keyvalue.length != 8)
+ krb5_abortx(context, "key has wrong length (%lu)",
+ (unsigned long)key->keyvalue.length);
+ krb_set_key(key->keyvalue.data, 0);
+ krb5_free_keyblock(context, key);
+ }
+
+ ret = krb_rd_req(&authent, sname, sinst,
+ client_addr->sin_addr.s_addr, &ad, NULL);
+
+ if(ret) {
+ make_you_loose_packet(krb_err_base + ret, reply);
+ krb5_warnx(context, "krb_rd_req: %d", ret);
+ return;
+ }
+
+ krb5_425_conv_principal(context, ad.pname, ad.pinst, ad.prealm,
+ &client);
+ krb5_unparse_name(context, client, &client_str);
+
+ ret = kadm5_init_with_password_ctx(context,
+ client_str,
+ NULL,
+ KADM5_ADMIN_SERVICE,
+ NULL, 0, 0,
+ &kadm_handle);
+ if (ret) {
+ krb5_warn (context, ret, "kadm5_init_with_password_ctx");
+ make_you_loose_packet (KADM_NOMEM, reply);
+ goto out;
+ }
+
+ checksum = des_quad_cksum((des_cblock*)(msg + off), NULL, rlen,
+ 0, &ad.session);
+ if(checksum != ad.checksum) {
+ krb5_warnx(context, "decode_packet: bad checksum");
+ make_you_loose_packet (KADM_BAD_CHK, reply);
+ goto out;
+ }
+ des_set_key(&ad.session, schedule);
+ ret = krb_rd_priv(msg + off, rlen, schedule, &ad.session,
+ client_addr, admin_addr, &msg_dat);
+ if (ret) {
+ make_you_loose_packet (krb_err_base + ret, reply);
+ krb5_warnx(context, "krb_rd_priv: %d", ret);
+ goto out;
+ }
+
+ {
+ krb5_data d, r;
+ int retval;
+
+ d.data = msg_dat.app_data;
+ d.length = msg_dat.app_length;
+
+ retval = dispatch(context, kadm_handle,
+ client, client_str, d, &r);
+ krb5_data_alloc(reply, r.length + 26);
+ reply->length = krb_mk_priv(r.data, reply->data, r.length,
+ schedule, &ad.session,
+ admin_addr, client_addr);
+ if((ssize_t)reply->length < 0) {
+ make_you_loose_packet(KADM_NO_ENCRYPT, reply);
+ goto out;
+ }
+ }
+out:
+ krb5_free_principal(context, client);
+ free(client_str);
+}
+
+void
+handle_v4(krb5_context context,
+ int len,
+ int fd)
+{
+ int first = 1;
+ struct sockaddr_in admin_addr, client_addr;
+ int addr_len;
+ krb5_data message, reply;
+ ssize_t n;
+
+ addr_len = sizeof(client_addr);
+ if (getsockname(fd, (struct sockaddr*)&admin_addr, &addr_len) < 0)
+ krb5_errx (context, 1, "getsockname");
+ addr_len = sizeof(client_addr);
+ if (getpeername(fd, (struct sockaddr*)&client_addr, &addr_len) < 0)
+ krb5_errx (context, 1, "getpeername");
+
+ while(1) {
+ if(first) {
+ /* first time around, we have already read len, and two
+ bytes of the version string */
+ krb5_data_alloc(&message, len);
+ memcpy(message.data, "KA", 2);
+ n = krb5_net_read(context, &fd, (char*)message.data + 2,
+ len - 2);
+ if (n == 0)
+ exit (0);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ first = 0;
+ } else {
+ char buf[2];
+ unsigned long tmp;
+ ssize_t n;
+
+ n = krb5_net_read(context, &fd, buf, sizeof(2));
+ if (n == 0)
+ exit (0);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ _krb5_get_int(buf, &tmp, 2);
+ krb5_data_alloc(&message, tmp);
+ n = krb5_net_read(context, &fd, message.data, message.length);
+ if (n == 0)
+ krb5_errx (context, 1, "EOF in krb5_net_read");
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_read");
+ }
+ decode_packet(context, &admin_addr, &client_addr,
+ message, &reply);
+ krb5_data_free(&message);
+ {
+ char buf[2];
+
+ _krb5_put_int(buf, reply.length, sizeof(buf));
+ n = krb5_net_write(context, &fd, buf, sizeof(buf));
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_write");
+ n = krb5_net_write(context, &fd, reply.data, reply.length);
+ if (n < 0)
+ krb5_err (context, 1, errno, "krb5_net_write");
+ krb5_data_free(&reply);
+ }
+ }
+}
OpenPOWER on IntegriCloud