diff options
Diffstat (limited to 'crypto/heimdal/lib/hdb')
26 files changed, 4138 insertions, 1353 deletions
diff --git a/crypto/heimdal/lib/hdb/Makefile.am b/crypto/heimdal/lib/hdb/Makefile.am index f66cd06..b629f56 100644 --- a/crypto/heimdal/lib/hdb/Makefile.am +++ b/crypto/heimdal/lib/hdb/Makefile.am @@ -1,8 +1,15 @@ -# $Id: Makefile.am 22490 2008-01-21 11:49:33Z lha $ +# $Id$ include $(top_srcdir)/Makefile.am.common AM_CPPFLAGS += -I../asn1 -I$(srcdir)/../asn1 $(INCLUDE_hcrypto) +AM_CPPFLAGS += $(INCLUDE_openldap) -DHDB_DB_DIR=\"$(DIR_hdbdir)\" +AM_CPPFLAGS += -I$(srcdir)/../krb5 +AM_CPPFLAGS += $(INCLUDE_sqlite3) +AM_CPPFLAGS += $(INCLUDE_libintl) +if HAVE_DBHEADER +AM_CPPFLAGS += -I$(DBHEADER) +endif BUILT_SOURCES = \ $(gen_files_hdb:.x=.c) \ @@ -16,6 +23,7 @@ gen_files_hdb = \ asn1_HDBFlags.x \ asn1_GENERATION.x \ asn1_HDB_Ext_PKINIT_acl.x \ + asn1_HDB_Ext_PKINIT_cert.x \ asn1_HDB_Ext_PKINIT_hash.x \ asn1_HDB_Ext_Constrained_delegation_acl.x \ asn1_HDB_Ext_Lan_Manager_OWF.x \ @@ -24,27 +32,33 @@ gen_files_hdb = \ asn1_HDB_extension.x \ asn1_HDB_extensions.x \ asn1_hdb_entry.x \ - asn1_hdb_entry_alias.x + asn1_hdb_entry_alias.x \ + asn1_hdb_keyset.x -CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) hdb_asn1.h hdb_asn1_files +CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) \ + hdb_asn1{,-priv}.h* hdb_asn1_files hdb_asn1-template.c* LDADD = libhdb.la \ $(LIB_openldap) \ + $(LIB_libintl) \ ../krb5/libkrb5.la \ ../asn1/libasn1.la \ $(LIB_hcrypto) \ $(LIB_roken) \ $(LIB_ldopen) + if OPENLDAP_MODULE ldap_so = hdb_ldap.la hdb_ldap_la_SOURCES = hdb-ldap.c -hdb_ldap_la_LDFLAGS = -module +hdb_ldap_la_LDFLAGS = -module -avoid-version +hdb_ldap_la_LIBADD = $(LIB_openldap) libhdb.la else ldap = hdb-ldap.c +ldap_lib = $(LIB_openldap) endif @@ -52,7 +66,11 @@ endif lib_LTLIBRARIES = libhdb.la $(ldap_so) libhdb_la_LDFLAGS = -version-info 11:0:2 -noinst_PROGRAMS = test_dbinfo +if versionscript +libhdb_la_LDFLAGS += $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map +endif + +noinst_PROGRAMS = test_dbinfo test_hdbkeys test_mkey dist_libhdb_la_SOURCES = \ common.c \ @@ -61,6 +79,9 @@ dist_libhdb_la_SOURCES = \ ext.c \ $(ldap) \ hdb.c \ + hdb-sqlite.c \ + hdb-keytab.c \ + hdb-mitdb.c \ hdb_locl.h \ hdb-private.h \ keys.c \ @@ -72,24 +93,24 @@ dist_libhdb_la_SOURCES = \ nodist_libhdb_la_SOURCES = $(BUILT_SOURCES) -AM_CPPFLAGS += $(INCLUDE_openldap) +libhdb_la_DEPENDENCIES = version-script.map include_HEADERS = hdb.h hdb-protos.h nodist_include_HEADERS = hdb_err.h hdb_asn1.h -libhdb_la_CPPFLAGS = -DHDB_DB_DIR=\"$(DIR_hdbdir)\" - libhdb_la_LIBADD = \ $(LIB_com_err) \ ../krb5/libkrb5.la \ ../asn1/libasn1.la \ + $(LIB_sqlite3) \ $(LIBADD_roken) \ - $(LIB_openldap) \ + $(ldap_lib) \ $(LIB_dlopen) \ $(DBLIB) \ $(LIB_NDBM) $(libhdb_la_OBJECTS): $(srcdir)/hdb-protos.h $(srcdir)/hdb-private.h +$(libhdb_la_OBJECTS): hdb_asn1.h hdb_asn1-priv.h hdb_err.h $(srcdir)/hdb-protos.h: cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -o hdb-protos.h $(dist_libhdb_la_SOURCES) || rm -f hdb-protos.h @@ -97,19 +118,27 @@ $(srcdir)/hdb-protos.h: $(srcdir)/hdb-private.h: cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -p hdb-private.h $(dist_libhdb_la_SOURCES) || rm -f hdb-private.h -$(gen_files_hdb) hdb_asn1.h: hdb_asn1_files - -hdb_asn1_files: ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 - ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 hdb_asn1 +$(gen_files_hdb) hdb_asn1.hx hdb_asn1-priv.hx: hdb_asn1_files -$(libhdb_la_OBJECTS): hdb_asn1.h hdb_err.h - -test_dbinfo_SOURCES = test_dbinfo.c +hdb_asn1_files: $(ASN1_COMPILE_DEP) $(srcdir)/hdb.asn1 + $(ASN1_COMPILE) $(srcdir)/hdb.asn1 hdb_asn1 test_dbinfo_LIBS = libhdb.la +test_hdbkeys_LIBS = ../krb5/libkrb5.la libhdb.la +test_mkey_LIBS = $(test_hdbkeys_LIBS) + # to help stupid solaris make hdb_err.h: hdb_err.et -EXTRA_DIST = hdb.asn1 hdb_err.et hdb.schema +EXTRA_DIST = \ + NTMakefile \ + libhdb-version.rc \ + libhdb-exports.def \ + hdb.asn1 \ + hdb_err.et \ + hdb.schema \ + version-script.map \ + data-mkey.mit.des3.le \ + data-mkey.mit.des3.be diff --git a/crypto/heimdal/lib/hdb/Makefile.in b/crypto/heimdal/lib/hdb/Makefile.in index cb0f916..9fcd770 100644 --- a/crypto/heimdal/lib/hdb/Makefile.in +++ b/crypto/heimdal/lib/hdb/Makefile.in @@ -1,8 +1,9 @@ -# Makefile.in generated by automake 1.10 from Makefile.am. +# Makefile.in generated by automake 1.11.1 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006, 2007, 2008, 2009 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. @@ -14,18 +15,19 @@ @SET_MAKE@ -# $Id: Makefile.am 22490 2008-01-21 11:49:33Z lha $ +# $Id$ -# $Id: Makefile.am.common 10998 2002-05-19 18:35:37Z joda $ +# $Id$ -# $Id: Makefile.am.common 22488 2008-01-21 11:47:22Z lha $ +# $Id$ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ -pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c @@ -43,11 +45,14 @@ host_triplet = @host@ DIST_COMMON = $(include_HEADERS) $(srcdir)/Makefile.am \ $(srcdir)/Makefile.in $(top_srcdir)/Makefile.am.common \ $(top_srcdir)/cf/Makefile.am.common -noinst_PROGRAMS = test_dbinfo$(EXEEXT) +@HAVE_DBHEADER_TRUE@am__append_1 = -I$(DBHEADER) +@versionscript_TRUE@am__append_2 = $(LDFLAGS_VERSION_SCRIPT)$(srcdir)/version-script.map +noinst_PROGRAMS = test_dbinfo$(EXEEXT) test_hdbkeys$(EXEEXT) \ + test_mkey$(EXEEXT) subdir = lib/hdb ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ - $(top_srcdir)/cf/auth-modules.m4 $(top_srcdir)/cf/autobuild.m4 \ + $(top_srcdir)/cf/auth-modules.m4 \ $(top_srcdir)/cf/broken-getaddrinfo.m4 \ $(top_srcdir)/cf/broken-glob.m4 \ $(top_srcdir)/cf/broken-realloc.m4 \ @@ -62,7 +67,7 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ $(top_srcdir)/cf/check-var.m4 $(top_srcdir)/cf/check-x.m4 \ $(top_srcdir)/cf/check-xau.m4 $(top_srcdir)/cf/crypto.m4 \ $(top_srcdir)/cf/db.m4 $(top_srcdir)/cf/destdirs.m4 \ - $(top_srcdir)/cf/dlopen.m4 \ + $(top_srcdir)/cf/dispatch.m4 $(top_srcdir)/cf/dlopen.m4 \ $(top_srcdir)/cf/find-func-no-libs.m4 \ $(top_srcdir)/cf/find-func-no-libs2.m4 \ $(top_srcdir)/cf/find-func.m4 \ @@ -76,9 +81,12 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ $(top_srcdir)/cf/krb-readline.m4 \ $(top_srcdir)/cf/krb-struct-spwd.m4 \ $(top_srcdir)/cf/krb-struct-winsize.m4 \ - $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/mips-abi.m4 \ - $(top_srcdir)/cf/misc.m4 $(top_srcdir)/cf/need-proto.m4 \ - $(top_srcdir)/cf/osfc2.m4 $(top_srcdir)/cf/otp.m4 \ + $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/libtool.m4 \ + $(top_srcdir)/cf/ltoptions.m4 $(top_srcdir)/cf/ltsugar.m4 \ + $(top_srcdir)/cf/ltversion.m4 $(top_srcdir)/cf/lt~obsolete.m4 \ + $(top_srcdir)/cf/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \ + $(top_srcdir)/cf/need-proto.m4 $(top_srcdir)/cf/osfc2.m4 \ + $(top_srcdir)/cf/otp.m4 $(top_srcdir)/cf/pkg.m4 \ $(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \ $(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \ $(top_srcdir)/cf/roken-frag.m4 \ @@ -86,23 +94,40 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ $(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \ $(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \ $(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \ - $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; am__vpath_adj = case $$p in \ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \ *) f=$$p;; \ esac; -am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; +am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`; +am__install_max = 40 +am__nobase_strip_setup = \ + srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'` +am__nobase_strip = \ + for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||" +am__nobase_list = $(am__nobase_strip_setup); \ + for p in $$list; do echo "$$p $$p"; done | \ + sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \ + $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \ + if (++n[$$2] == $(am__install_max)) \ + { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \ + END { for (dir in files) print dir, files[dir] }' +am__base_list = \ + sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \ + sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g' am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \ "$(DESTDIR)$(includedir)" -libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) -hdb_ldap_la_LIBADD = +am__DEPENDENCIES_1 = +@OPENLDAP_MODULE_TRUE@hdb_ldap_la_DEPENDENCIES = \ +@OPENLDAP_MODULE_TRUE@ $(am__DEPENDENCIES_1) libhdb.la am__hdb_ldap_la_SOURCES_DIST = hdb-ldap.c @OPENLDAP_MODULE_TRUE@am_hdb_ldap_la_OBJECTS = hdb-ldap.lo hdb_ldap_la_OBJECTS = $(am_hdb_ldap_la_OBJECTS) @@ -110,33 +135,24 @@ hdb_ldap_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(hdb_ldap_la_LDFLAGS) $(LDFLAGS) -o $@ @OPENLDAP_MODULE_TRUE@am_hdb_ldap_la_rpath = -rpath $(libdir) -am__DEPENDENCIES_1 = -libhdb_la_DEPENDENCIES = $(am__DEPENDENCIES_1) ../krb5/libkrb5.la \ - ../asn1/libasn1.la $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) +@OPENLDAP_MODULE_FALSE@am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) am__dist_libhdb_la_SOURCES_DIST = common.c db.c db3.c ext.c hdb-ldap.c \ - hdb.c hdb_locl.h hdb-private.h keys.c keytab.c dbinfo.c mkey.c \ - ndbm.c print.c -@OPENLDAP_MODULE_FALSE@am__objects_1 = libhdb_la-hdb-ldap.lo -dist_libhdb_la_OBJECTS = libhdb_la-common.lo libhdb_la-db.lo \ - libhdb_la-db3.lo libhdb_la-ext.lo $(am__objects_1) \ - libhdb_la-hdb.lo libhdb_la-keys.lo libhdb_la-keytab.lo \ - libhdb_la-dbinfo.lo libhdb_la-mkey.lo libhdb_la-ndbm.lo \ - libhdb_la-print.lo -am__objects_2 = libhdb_la-asn1_Salt.lo libhdb_la-asn1_Key.lo \ - libhdb_la-asn1_Event.lo libhdb_la-asn1_HDBFlags.lo \ - libhdb_la-asn1_GENERATION.lo \ - libhdb_la-asn1_HDB_Ext_PKINIT_acl.lo \ - libhdb_la-asn1_HDB_Ext_PKINIT_hash.lo \ - libhdb_la-asn1_HDB_Ext_Constrained_delegation_acl.lo \ - libhdb_la-asn1_HDB_Ext_Lan_Manager_OWF.lo \ - libhdb_la-asn1_HDB_Ext_Password.lo \ - libhdb_la-asn1_HDB_Ext_Aliases.lo \ - libhdb_la-asn1_HDB_extension.lo \ - libhdb_la-asn1_HDB_extensions.lo libhdb_la-asn1_hdb_entry.lo \ - libhdb_la-asn1_hdb_entry_alias.lo -am__objects_3 = $(am__objects_2) libhdb_la-hdb_err.lo + hdb.c hdb-sqlite.c hdb-keytab.c hdb-mitdb.c hdb_locl.h \ + hdb-private.h keys.c keytab.c dbinfo.c mkey.c ndbm.c print.c +@OPENLDAP_MODULE_FALSE@am__objects_1 = hdb-ldap.lo +dist_libhdb_la_OBJECTS = common.lo db.lo db3.lo ext.lo \ + $(am__objects_1) hdb.lo hdb-sqlite.lo hdb-keytab.lo \ + hdb-mitdb.lo keys.lo keytab.lo dbinfo.lo mkey.lo ndbm.lo \ + print.lo +am__objects_2 = asn1_Salt.lo asn1_Key.lo asn1_Event.lo \ + asn1_HDBFlags.lo asn1_GENERATION.lo asn1_HDB_Ext_PKINIT_acl.lo \ + asn1_HDB_Ext_PKINIT_cert.lo asn1_HDB_Ext_PKINIT_hash.lo \ + asn1_HDB_Ext_Constrained_delegation_acl.lo \ + asn1_HDB_Ext_Lan_Manager_OWF.lo asn1_HDB_Ext_Password.lo \ + asn1_HDB_Ext_Aliases.lo asn1_HDB_extension.lo \ + asn1_HDB_extensions.lo asn1_hdb_entry.lo \ + asn1_hdb_entry_alias.lo asn1_hdb_keyset.lo +am__objects_3 = $(am__objects_2) hdb_err.lo nodist_libhdb_la_OBJECTS = $(am__objects_3) libhdb_la_OBJECTS = $(dist_libhdb_la_OBJECTS) \ $(nodist_libhdb_la_OBJECTS) @@ -144,15 +160,27 @@ libhdb_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libhdb_la_LDFLAGS) $(LDFLAGS) -o $@ PROGRAMS = $(noinst_PROGRAMS) -am_test_dbinfo_OBJECTS = test_dbinfo.$(OBJEXT) -test_dbinfo_OBJECTS = $(am_test_dbinfo_OBJECTS) +test_dbinfo_SOURCES = test_dbinfo.c +test_dbinfo_OBJECTS = test_dbinfo.$(OBJEXT) test_dbinfo_LDADD = $(LDADD) test_dbinfo_DEPENDENCIES = libhdb.la $(am__DEPENDENCIES_1) \ - ../krb5/libkrb5.la ../asn1/libasn1.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) -DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@ -depcomp = -am__depfiles_maybe = + $(am__DEPENDENCIES_1) ../krb5/libkrb5.la ../asn1/libasn1.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +test_hdbkeys_SOURCES = test_hdbkeys.c +test_hdbkeys_OBJECTS = test_hdbkeys.$(OBJEXT) +test_hdbkeys_LDADD = $(LDADD) +test_hdbkeys_DEPENDENCIES = libhdb.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) ../krb5/libkrb5.la ../asn1/libasn1.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +test_mkey_SOURCES = test_mkey.c +test_mkey_OBJECTS = test_mkey.$(OBJEXT) +test_mkey_LDADD = $(LDADD) +test_mkey_DEPENDENCIES = libhdb.la $(am__DEPENDENCIES_1) \ + $(am__DEPENDENCIES_1) ../krb5/libkrb5.la ../asn1/libasn1.la \ + $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ @@ -163,11 +191,11 @@ LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ SOURCES = $(hdb_ldap_la_SOURCES) $(dist_libhdb_la_SOURCES) \ - $(nodist_libhdb_la_SOURCES) $(test_dbinfo_SOURCES) + $(nodist_libhdb_la_SOURCES) test_dbinfo.c test_hdbkeys.c \ + test_mkey.c DIST_SOURCES = $(am__hdb_ldap_la_SOURCES_DIST) \ - $(am__dist_libhdb_la_SOURCES_DIST) $(test_dbinfo_SOURCES) -includeHEADERS_INSTALL = $(INSTALL_HEADER) -nodist_includeHEADERS_INSTALL = $(INSTALL_HEADER) + $(am__dist_libhdb_la_SOURCES_DIST) test_dbinfo.c \ + test_hdbkeys.c test_mkey.c HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) ETAGS = etags CTAGS = ctags @@ -176,49 +204,58 @@ ACLOCAL = @ACLOCAL@ AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@ AMTAR = @AMTAR@ AR = @AR@ +ASN1_COMPILE = @ASN1_COMPILE@ +ASN1_COMPILE_DEP = @ASN1_COMPILE_DEP@ AUTOCONF = @AUTOCONF@ AUTOHEADER = @AUTOHEADER@ AUTOMAKE = @AUTOMAKE@ AWK = @AWK@ CANONICAL_HOST = @CANONICAL_HOST@ +CAPNG_CFLAGS = @CAPNG_CFLAGS@ +CAPNG_LIBS = @CAPNG_LIBS@ CATMAN = @CATMAN@ CATMANEXT = @CATMANEXT@ CC = @CC@ +CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ COMPILE_ET = @COMPILE_ET@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ +DBHEADER = @DBHEADER@ DBLIB = @DBLIB@ DEFS = @DEFS@ +DEPDIR = @DEPDIR@ DIR_com_err = @DIR_com_err@ DIR_hcrypto = @DIR_hcrypto@ DIR_hdbdir = @DIR_hdbdir@ DIR_roken = @DIR_roken@ -ECHO = @ECHO@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ +FGREP = @FGREP@ GREP = @GREP@ GROFF = @GROFF@ INCLUDES_roken = @INCLUDES_roken@ INCLUDE_hcrypto = @INCLUDE_hcrypto@ INCLUDE_hesiod = @INCLUDE_hesiod@ INCLUDE_krb4 = @INCLUDE_krb4@ +INCLUDE_libedit = @INCLUDE_libedit@ +INCLUDE_libintl = @INCLUDE_libintl@ INCLUDE_openldap = @INCLUDE_openldap@ INCLUDE_readline = @INCLUDE_readline@ +INCLUDE_sqlite3 = @INCLUDE_sqlite3@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ LDFLAGS = @LDFLAGS@ LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@ LEX = @LEX@ @@ -242,10 +279,11 @@ LIB_crypt = @LIB_crypt@ LIB_db_create = @LIB_db_create@ LIB_dbm_firstkey = @LIB_dbm_firstkey@ LIB_dbopen = @LIB_dbopen@ +LIB_dispatch_async_f = @LIB_dispatch_async_f@ LIB_dlopen = @LIB_dlopen@ LIB_dn_expand = @LIB_dn_expand@ +LIB_dns_search = @LIB_dns_search@ LIB_door_create = @LIB_door_create@ -LIB_el_init = @LIB_el_init@ LIB_freeaddrinfo = @LIB_freeaddrinfo@ LIB_gai_strerror = @LIB_gai_strerror@ LIB_getaddrinfo = @LIB_getaddrinfo@ @@ -262,6 +300,8 @@ LIB_hesiod = @LIB_hesiod@ LIB_hstrerror = @LIB_hstrerror@ LIB_kdb = @LIB_kdb@ LIB_krb4 = @LIB_krb4@ +LIB_libedit = @LIB_libedit@ +LIB_libintl = @LIB_libintl@ LIB_loadquery = @LIB_loadquery@ LIB_logout = @LIB_logout@ LIB_logwtmp = @LIB_logwtmp@ @@ -277,31 +317,45 @@ LIB_roken = @LIB_roken@ LIB_security = @LIB_security@ LIB_setsockopt = @LIB_setsockopt@ LIB_socket = @LIB_socket@ +LIB_sqlite3 = @LIB_sqlite3@ LIB_syslog = @LIB_syslog@ LIB_tgetent = @LIB_tgetent@ +LIPO = @LIPO@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +NO_AFS = @NO_AFS@ NROFF = @NROFF@ +OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ -PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ -PTHREADS_LIBS = @PTHREADS_LIBS@ +PKG_CONFIG = @PKG_CONFIG@ +PTHREAD_CFLAGS = @PTHREAD_CFLAGS@ +PTHREAD_LDADD = @PTHREAD_LDADD@ +PTHREAD_LIBADD = @PTHREAD_LIBADD@ RANLIB = @RANLIB@ +SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ +SLC = @SLC@ +SLC_DEP = @SLC_DEP@ STRIP = @STRIP@ VERSION = @VERSION@ VERSIONING = @VERSIONING@ -VOID_RETSIGTYPE = @VOID_RETSIGTYPE@ WFLAGS = @WFLAGS@ WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@ WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@ @@ -316,10 +370,12 @@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ am__tar = @am__tar@ am__untar = @am__untar@ bindir = @bindir@ @@ -360,30 +416,37 @@ psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ +subdirs = @subdirs@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ -SUFFIXES = .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 -AM_CPPFLAGS = -I$(top_builddir)/include $(INCLUDES_roken) -I../asn1 \ - -I$(srcdir)/../asn1 $(INCLUDE_hcrypto) $(INCLUDE_openldap) +SUFFIXES = .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 +DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)/include -I$(top_srcdir)/include +AM_CPPFLAGS = $(INCLUDES_roken) -I../asn1 -I$(srcdir)/../asn1 \ + $(INCLUDE_hcrypto) $(INCLUDE_openldap) \ + -DHDB_DB_DIR=\"$(DIR_hdbdir)\" -I$(srcdir)/../krb5 \ + $(INCLUDE_sqlite3) $(INCLUDE_libintl) $(am__append_1) @do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME AM_CFLAGS = $(WFLAGS) CP = cp buildinclude = $(top_builddir)/include +LIB_el_init = @LIB_el_init@ LIB_getattr = @LIB_getattr@ LIB_getpwent_r = @LIB_getpwent_r@ LIB_odm_initialize = @LIB_odm_initialize@ LIB_setpcred = @LIB_setpcred@ HESIODLIB = @HESIODLIB@ HESIODINCLUDE = @HESIODINCLUDE@ +libexec_heimdaldir = $(libexecdir)/heimdal NROFF_MAN = groff -mandoc -Tascii LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS) @KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la \ @KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la @KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la -@KRB5_TRUE@LIB_tsasl = $(top_builddir)/lib/tsasl/libtsasl.la +LIB_heimbase = $(top_builddir)/base/libheimbase.la @DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la BUILT_SOURCES = \ $(gen_files_hdb:.x=.c) \ @@ -397,6 +460,7 @@ gen_files_hdb = \ asn1_HDBFlags.x \ asn1_GENERATION.x \ asn1_HDB_Ext_PKINIT_acl.x \ + asn1_HDB_Ext_PKINIT_cert.x \ asn1_HDB_Ext_PKINIT_hash.x \ asn1_HDB_Ext_Constrained_delegation_acl.x \ asn1_HDB_Ext_Lan_Manager_OWF.x \ @@ -405,11 +469,15 @@ gen_files_hdb = \ asn1_HDB_extension.x \ asn1_HDB_extensions.x \ asn1_hdb_entry.x \ - asn1_hdb_entry_alias.x + asn1_hdb_entry_alias.x \ + asn1_hdb_keyset.x + +CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) \ + hdb_asn1{,-priv}.h* hdb_asn1_files hdb_asn1-template.c* -CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) hdb_asn1.h hdb_asn1_files LDADD = libhdb.la \ $(LIB_openldap) \ + $(LIB_libintl) \ ../krb5/libkrb5.la \ ../asn1/libasn1.la \ $(LIB_hcrypto) \ @@ -418,10 +486,12 @@ LDADD = libhdb.la \ @OPENLDAP_MODULE_TRUE@ldap_so = hdb_ldap.la @OPENLDAP_MODULE_TRUE@hdb_ldap_la_SOURCES = hdb-ldap.c -@OPENLDAP_MODULE_TRUE@hdb_ldap_la_LDFLAGS = -module +@OPENLDAP_MODULE_TRUE@hdb_ldap_la_LDFLAGS = -module -avoid-version +@OPENLDAP_MODULE_TRUE@hdb_ldap_la_LIBADD = $(LIB_openldap) libhdb.la @OPENLDAP_MODULE_FALSE@ldap = hdb-ldap.c +@OPENLDAP_MODULE_FALSE@ldap_lib = $(LIB_openldap) lib_LTLIBRARIES = libhdb.la $(ldap_so) -libhdb_la_LDFLAGS = -version-info 11:0:2 +libhdb_la_LDFLAGS = -version-info 11:0:2 $(am__append_2) dist_libhdb_la_SOURCES = \ common.c \ db.c \ @@ -429,6 +499,9 @@ dist_libhdb_la_SOURCES = \ ext.c \ $(ldap) \ hdb.c \ + hdb-sqlite.c \ + hdb-keytab.c \ + hdb-mitdb.c \ hdb_locl.h \ hdb-private.h \ keys.c \ @@ -439,39 +512,51 @@ dist_libhdb_la_SOURCES = \ print.c nodist_libhdb_la_SOURCES = $(BUILT_SOURCES) +libhdb_la_DEPENDENCIES = version-script.map include_HEADERS = hdb.h hdb-protos.h nodist_include_HEADERS = hdb_err.h hdb_asn1.h -libhdb_la_CPPFLAGS = -DHDB_DB_DIR=\"$(DIR_hdbdir)\" libhdb_la_LIBADD = \ $(LIB_com_err) \ ../krb5/libkrb5.la \ ../asn1/libasn1.la \ + $(LIB_sqlite3) \ $(LIBADD_roken) \ - $(LIB_openldap) \ + $(ldap_lib) \ $(LIB_dlopen) \ $(DBLIB) \ $(LIB_NDBM) -test_dbinfo_SOURCES = test_dbinfo.c test_dbinfo_LIBS = libhdb.la -EXTRA_DIST = hdb.asn1 hdb_err.et hdb.schema +test_hdbkeys_LIBS = ../krb5/libkrb5.la libhdb.la +test_mkey_LIBS = $(test_hdbkeys_LIBS) +EXTRA_DIST = \ + NTMakefile \ + libhdb-version.rc \ + libhdb-exports.def \ + hdb.asn1 \ + hdb_err.et \ + hdb.schema \ + version-script.map \ + data-mkey.mit.des3.le \ + data-mkey.mit.des3.be + all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: -.SUFFIXES: .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj +.SUFFIXES: .et .h .x .z .hx .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ - echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign --ignore-deps lib/hdb/Makefile'; \ - cd $(top_srcdir) && \ - $(AUTOMAKE) --foreign --ignore-deps lib/hdb/Makefile + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/hdb/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign lib/hdb/Makefile .PRECIOUS: Makefile Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status @case '$?' in \ @@ -489,23 +574,28 @@ $(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + list2=; for p in $$list; do \ if test -f $$p; then \ - f=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(libdir)/$$f'"; \ - $(LIBTOOL) --mode=install $(libLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(libdir)/$$f"; \ + list2="$$list2 $$p"; \ else :; fi; \ - done + done; \ + test -z "$$list2" || { \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \ + } uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) - @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - p=$(am__strip_dir) \ - echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ - $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ + @list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \ + for p in $$list; do \ + $(am__strip_dir) \ + echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \ + $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \ done clean-libLTLIBRARIES: @@ -522,14 +612,22 @@ libhdb.la: $(libhdb_la_OBJECTS) $(libhdb_la_DEPENDENCIES) $(libhdb_la_LINK) -rpath $(libdir) $(libhdb_la_OBJECTS) $(libhdb_la_LIBADD) $(LIBS) clean-noinstPROGRAMS: - @list='$(noinst_PROGRAMS)'; for p in $$list; do \ - f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ - echo " rm -f $$p $$f"; \ - rm -f $$p $$f ; \ - done + @list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \ + echo " rm -f" $$list; \ + rm -f $$list || exit $$?; \ + test -n "$(EXEEXT)" || exit 0; \ + list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f" $$list; \ + rm -f $$list test_dbinfo$(EXEEXT): $(test_dbinfo_OBJECTS) $(test_dbinfo_DEPENDENCIES) @rm -f test_dbinfo$(EXEEXT) $(LINK) $(test_dbinfo_OBJECTS) $(test_dbinfo_LDADD) $(LIBS) +test_hdbkeys$(EXEEXT): $(test_hdbkeys_OBJECTS) $(test_hdbkeys_DEPENDENCIES) + @rm -f test_hdbkeys$(EXEEXT) + $(LINK) $(test_hdbkeys_OBJECTS) $(test_hdbkeys_LDADD) $(LIBS) +test_mkey$(EXEEXT): $(test_mkey_OBJECTS) $(test_mkey_DEPENDENCIES) + @rm -f test_mkey$(EXEEXT) + $(LINK) $(test_mkey_OBJECTS) $(test_mkey_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -537,98 +635,63 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_Event.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_GENERATION.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDBFlags.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_Ext_Aliases.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_Ext_Constrained_delegation_acl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_Ext_Lan_Manager_OWF.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_Ext_PKINIT_acl.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_Ext_PKINIT_cert.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_Ext_PKINIT_hash.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_Ext_Password.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_extension.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_HDB_extensions.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_Key.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_Salt.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_hdb_entry.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_hdb_entry_alias.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asn1_hdb_keyset.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/db3.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dbinfo.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ext.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb-keytab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb-ldap.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb-mitdb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb-sqlite.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hdb_err.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keys.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keytab.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkey.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ndbm.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/print.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_dbinfo.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_hdbkeys.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/test_mkey.Po@am__quote@ + .c.o: - $(COMPILE) -c $< +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< .c.obj: - $(COMPILE) -c `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` .c.lo: - $(LTCOMPILE) -c -o $@ $< - -libhdb_la-common.lo: common.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-common.lo `test -f 'common.c' || echo '$(srcdir)/'`common.c - -libhdb_la-db.lo: db.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-db.lo `test -f 'db.c' || echo '$(srcdir)/'`db.c - -libhdb_la-db3.lo: db3.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-db3.lo `test -f 'db3.c' || echo '$(srcdir)/'`db3.c - -libhdb_la-ext.lo: ext.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-ext.lo `test -f 'ext.c' || echo '$(srcdir)/'`ext.c - -libhdb_la-hdb-ldap.lo: hdb-ldap.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-hdb-ldap.lo `test -f 'hdb-ldap.c' || echo '$(srcdir)/'`hdb-ldap.c - -libhdb_la-hdb.lo: hdb.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-hdb.lo `test -f 'hdb.c' || echo '$(srcdir)/'`hdb.c - -libhdb_la-keys.lo: keys.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-keys.lo `test -f 'keys.c' || echo '$(srcdir)/'`keys.c - -libhdb_la-keytab.lo: keytab.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-keytab.lo `test -f 'keytab.c' || echo '$(srcdir)/'`keytab.c - -libhdb_la-dbinfo.lo: dbinfo.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-dbinfo.lo `test -f 'dbinfo.c' || echo '$(srcdir)/'`dbinfo.c - -libhdb_la-mkey.lo: mkey.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-mkey.lo `test -f 'mkey.c' || echo '$(srcdir)/'`mkey.c - -libhdb_la-ndbm.lo: ndbm.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-ndbm.lo `test -f 'ndbm.c' || echo '$(srcdir)/'`ndbm.c - -libhdb_la-print.lo: print.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-print.lo `test -f 'print.c' || echo '$(srcdir)/'`print.c - -libhdb_la-asn1_Salt.lo: asn1_Salt.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_Salt.lo `test -f 'asn1_Salt.c' || echo '$(srcdir)/'`asn1_Salt.c - -libhdb_la-asn1_Key.lo: asn1_Key.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_Key.lo `test -f 'asn1_Key.c' || echo '$(srcdir)/'`asn1_Key.c - -libhdb_la-asn1_Event.lo: asn1_Event.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_Event.lo `test -f 'asn1_Event.c' || echo '$(srcdir)/'`asn1_Event.c - -libhdb_la-asn1_HDBFlags.lo: asn1_HDBFlags.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDBFlags.lo `test -f 'asn1_HDBFlags.c' || echo '$(srcdir)/'`asn1_HDBFlags.c - -libhdb_la-asn1_GENERATION.lo: asn1_GENERATION.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_GENERATION.lo `test -f 'asn1_GENERATION.c' || echo '$(srcdir)/'`asn1_GENERATION.c - -libhdb_la-asn1_HDB_Ext_PKINIT_acl.lo: asn1_HDB_Ext_PKINIT_acl.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_Ext_PKINIT_acl.lo `test -f 'asn1_HDB_Ext_PKINIT_acl.c' || echo '$(srcdir)/'`asn1_HDB_Ext_PKINIT_acl.c - -libhdb_la-asn1_HDB_Ext_PKINIT_hash.lo: asn1_HDB_Ext_PKINIT_hash.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_Ext_PKINIT_hash.lo `test -f 'asn1_HDB_Ext_PKINIT_hash.c' || echo '$(srcdir)/'`asn1_HDB_Ext_PKINIT_hash.c - -libhdb_la-asn1_HDB_Ext_Constrained_delegation_acl.lo: asn1_HDB_Ext_Constrained_delegation_acl.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_Ext_Constrained_delegation_acl.lo `test -f 'asn1_HDB_Ext_Constrained_delegation_acl.c' || echo '$(srcdir)/'`asn1_HDB_Ext_Constrained_delegation_acl.c - -libhdb_la-asn1_HDB_Ext_Lan_Manager_OWF.lo: asn1_HDB_Ext_Lan_Manager_OWF.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_Ext_Lan_Manager_OWF.lo `test -f 'asn1_HDB_Ext_Lan_Manager_OWF.c' || echo '$(srcdir)/'`asn1_HDB_Ext_Lan_Manager_OWF.c - -libhdb_la-asn1_HDB_Ext_Password.lo: asn1_HDB_Ext_Password.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_Ext_Password.lo `test -f 'asn1_HDB_Ext_Password.c' || echo '$(srcdir)/'`asn1_HDB_Ext_Password.c - -libhdb_la-asn1_HDB_Ext_Aliases.lo: asn1_HDB_Ext_Aliases.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_Ext_Aliases.lo `test -f 'asn1_HDB_Ext_Aliases.c' || echo '$(srcdir)/'`asn1_HDB_Ext_Aliases.c - -libhdb_la-asn1_HDB_extension.lo: asn1_HDB_extension.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_extension.lo `test -f 'asn1_HDB_extension.c' || echo '$(srcdir)/'`asn1_HDB_extension.c - -libhdb_la-asn1_HDB_extensions.lo: asn1_HDB_extensions.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_HDB_extensions.lo `test -f 'asn1_HDB_extensions.c' || echo '$(srcdir)/'`asn1_HDB_extensions.c - -libhdb_la-asn1_hdb_entry.lo: asn1_hdb_entry.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_hdb_entry.lo `test -f 'asn1_hdb_entry.c' || echo '$(srcdir)/'`asn1_hdb_entry.c - -libhdb_la-asn1_hdb_entry_alias.lo: asn1_hdb_entry_alias.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-asn1_hdb_entry_alias.lo `test -f 'asn1_hdb_entry_alias.c' || echo '$(srcdir)/'`asn1_hdb_entry_alias.c - -libhdb_la-hdb_err.lo: hdb_err.c - $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libhdb_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libhdb_la-hdb_err.lo `test -f 'hdb_err.c' || echo '$(srcdir)/'`hdb_err.c +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< mostlyclean-libtool: -rm -f *.lo @@ -638,82 +701,92 @@ clean-libtool: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" - @list='$(include_HEADERS)'; for p in $$list; do \ + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ - $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) - @list='$(include_HEADERS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ - rm -f "$(DESTDIR)$(includedir)/$$f"; \ - done + @list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(includedir)" && rm -f $$files install-nodist_includeHEADERS: $(nodist_include_HEADERS) @$(NORMAL_INSTALL) test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" - @list='$(nodist_include_HEADERS)'; for p in $$list; do \ + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f=$(am__strip_dir) \ - echo " $(nodist_includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ - $(nodist_includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ + echo "$$d$$p"; \ + done | $(am__base_list) | \ + while read files; do \ + echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \ + $(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \ done uninstall-nodist_includeHEADERS: @$(NORMAL_UNINSTALL) - @list='$(nodist_include_HEADERS)'; for p in $$list; do \ - f=$(am__strip_dir) \ - echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ - rm -f "$(DESTDIR)$(includedir)/$$f"; \ - done + @list='$(nodist_include_HEADERS)'; test -n "$(includedir)" || list=; \ + files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \ + test -n "$$files" || exit 0; \ + echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \ + cd "$(DESTDIR)$(includedir)" && rm -f $$files ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) - tags=; \ + set x; \ here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ test -n "$$unique" || unique=$$empty_fix; \ - $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) - tags=; \ - here=`pwd`; \ list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) ' { files[$$0] = 1; } \ - END { for (i in files) print i; }'`; \ - test -z "$(CTAGS_ARGS)$$tags$$unique" \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$unique" \ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ - $$tags $$unique + $$unique GTAGS: here=`$(am__cd) $(top_builddir) && pwd` \ - && cd $(top_srcdir) \ - && gtags -i $(GTAGS_ARGS) $$here + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags @@ -734,13 +807,17 @@ distdir: $(DISTFILES) if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ if test -d $$d/$$file; then \ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ - cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ fi; \ - cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ else \ - test -f $(distdir)/$$file \ - || cp -p $$d/$$file $(distdir)/$$file \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ || exit 1; \ fi; \ done @@ -778,6 +855,7 @@ clean-generic: distclean-generic: -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -789,6 +867,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ clean-noinstPROGRAMS mostlyclean-am distclean: distclean-am + -rm -rf ./$(DEPDIR) -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -799,6 +878,8 @@ dvi-am: html: html-am +html-am: + info: info-am info-am: @@ -806,26 +887,35 @@ info-am: install-data-am: install-includeHEADERS install-nodist_includeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook - install-dvi: install-dvi-am +install-dvi-am: + install-exec-am: install-libLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook - install-html: install-html-am +install-html-am: + install-info: install-info-am +install-info-am: + install-man: install-pdf: install-pdf-am +install-pdf-am: + install-ps: install-ps-am +install-ps-am: + installcheck-am: maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -846,9 +936,8 @@ uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \ uninstall-nodist_includeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) uninstall-hook - -.MAKE: install-am install-data-am install-exec-am install-strip \ - uninstall-am +.MAKE: all check check-am install install-am install-data-am \ + install-exec-am install-strip uninstall-am .PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \ clean clean-generic clean-libLTLIBRARIES clean-libtool \ @@ -938,6 +1027,9 @@ check-local:: .x.c: @cmp -s $< $@ 2> /dev/null || cp $< $@ + +.hx.h: + @cmp -s $< $@ 2> /dev/null || cp $< $@ #NROFF_MAN = nroff -man .1.cat1: $(NROFF_MAN) $< > $@ @@ -1023,7 +1115,7 @@ uninstall-hook: uninstall-cat-mans check-valgrind: tobjdir=`cd $(top_builddir) && pwd` ; \ tsrcdir=`cd $(top_srcdir) && pwd` ; \ - env TESTS_ENVIRONMENT="$${tobjdir}/libtool --mode execute valgrind --leak-check=full --trace-children=yes --quiet -q --num-callers=30 --suppressions=$${tsrcdir}/cf/valgrind-suppressions" make check + env TESTS_ENVIRONMENT="$${tsrcdir}/cf/maybe-valgrind.sh -s $${tsrcdir} -o $${tobjdir}" make check # # Target to please samba build farm, builds distfiles in-tree. @@ -1038,6 +1130,7 @@ distdir-in-tree: $(DISTFILES) $(INFO_DEPS) done $(libhdb_la_OBJECTS): $(srcdir)/hdb-protos.h $(srcdir)/hdb-private.h +$(libhdb_la_OBJECTS): hdb_asn1.h hdb_asn1-priv.h hdb_err.h $(srcdir)/hdb-protos.h: cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -o hdb-protos.h $(dist_libhdb_la_SOURCES) || rm -f hdb-protos.h @@ -1045,16 +1138,15 @@ $(srcdir)/hdb-protos.h: $(srcdir)/hdb-private.h: cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -p hdb-private.h $(dist_libhdb_la_SOURCES) || rm -f hdb-private.h -$(gen_files_hdb) hdb_asn1.h: hdb_asn1_files +$(gen_files_hdb) hdb_asn1.hx hdb_asn1-priv.hx: hdb_asn1_files -hdb_asn1_files: ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 - ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 hdb_asn1 - -$(libhdb_la_OBJECTS): hdb_asn1.h hdb_err.h +hdb_asn1_files: $(ASN1_COMPILE_DEP) $(srcdir)/hdb.asn1 + $(ASN1_COMPILE) $(srcdir)/hdb.asn1 hdb_asn1 # to help stupid solaris make hdb_err.h: hdb_err.et + # 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/lib/hdb/common.c b/crypto/heimdal/lib/hdb/common.c index 680b666..2715adf 100644 --- a/crypto/heimdal/lib/hdb/common.c +++ b/crypto/heimdal/lib/hdb/common.c @@ -1,49 +1,47 @@ /* - * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" -RCSID("$Id: common.c 20236 2007-02-16 23:52:29Z lha $"); - int hdb_principal2key(krb5_context context, krb5_const_principal p, krb5_data *key) { Principal new; - size_t len; + size_t len = 0; int ret; ret = copy_Principal(p, &new); - if(ret) + if(ret) return ret; new.name.name_type = 0; @@ -63,9 +61,9 @@ hdb_key2principal(krb5_context context, krb5_data *key, krb5_principal p) int hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value) { - size_t len; + size_t len = 0; int ret; - + ASN1_MALLOC_ENCODE(hdb_entry, value->data, value->length, ent, &len, ret); if (ret == 0 && value->length != len) krb5_abortx(context, "internal asn.1 encoder error"); @@ -79,14 +77,14 @@ hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent) } int -hdb_entry_alias2value(krb5_context context, +hdb_entry_alias2value(krb5_context context, const hdb_entry_alias *alias, krb5_data *value) { - size_t len; + size_t len = 0; int ret; - - ASN1_MALLOC_ENCODE(hdb_entry_alias, value->data, value->length, + + ASN1_MALLOC_ENCODE(hdb_entry_alias, value->data, value->length, alias, &len, ret); if (ret == 0 && value->length != len) krb5_abortx(context, "internal asn.1 encoder error"); @@ -94,20 +92,39 @@ hdb_entry_alias2value(krb5_context context, } int -hdb_value2entry_alias(krb5_context context, krb5_data *value, +hdb_value2entry_alias(krb5_context context, krb5_data *value, hdb_entry_alias *ent) { return decode_hdb_entry_alias(value->data, value->length, ent, NULL); } krb5_error_code -_hdb_fetch(krb5_context context, HDB *db, krb5_const_principal principal, - unsigned flags, hdb_entry_ex *entry) +_hdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, + unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry) { + krb5_principal enterprise_principal = NULL; krb5_data key, value; + krb5_error_code ret; int code; + if (principal->name.name_type == KRB5_NT_ENTERPRISE_PRINCIPAL) { + if (principal->name.name_string.len != 1) { + ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, "malformed principal: " + "enterprise name with %d name components", + principal->name.name_string.len); + return ret; + } + ret = krb5_parse_name(context, principal->name.name_string.val[0], + &enterprise_principal); + if (ret) + return ret; + principal = enterprise_principal; + } + hdb_principal2key(context, principal, &key); + if (enterprise_principal) + krb5_free_principal(context, enterprise_principal); code = db->hdb__get(context, db, key, &value); krb5_data_free(&key); if(code) @@ -154,14 +171,14 @@ hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key) krb5_error_code code; hdb_entry oldentry; krb5_data value; - int i; + size_t i; code = db->hdb__get(context, db, *key, &value); if (code == HDB_ERR_NOENTRY) return 0; else if (code) return code; - + code = hdb_value2entry(context, &value, &oldentry); krb5_data_free(&value); if (code) @@ -188,22 +205,22 @@ hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key) } static krb5_error_code -hdb_add_aliases(krb5_context context, HDB *db, +hdb_add_aliases(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { const HDB_Ext_Aliases *aliases; krb5_error_code code; krb5_data key, value; - int i; - + size_t i; + code = hdb_entry_get_aliases(&entry->entry, &aliases); if (code || aliases == NULL) return code; - + for (i = 0; i < aliases->aliases.len; i++) { hdb_entry_alias entryalias; entryalias.principal = entry->entry.principal; - + hdb_principal2key(context, &aliases->aliases.val[i], &key); code = hdb_entry_alias2value(context, &entryalias, &value); if (code) { @@ -219,17 +236,64 @@ hdb_add_aliases(krb5_context context, HDB *db, return 0; } +static krb5_error_code +hdb_check_aliases(krb5_context context, HDB *db, hdb_entry_ex *entry) +{ + const HDB_Ext_Aliases *aliases; + int code; + size_t i; + + /* check if new aliases already is used */ + + code = hdb_entry_get_aliases(&entry->entry, &aliases); + if (code) + return code; + + for (i = 0; aliases && i < aliases->aliases.len; i++) { + hdb_entry_alias alias; + krb5_data akey, value; + + hdb_principal2key(context, &aliases->aliases.val[i], &akey); + code = db->hdb__get(context, db, akey, &value); + krb5_data_free(&akey); + if (code == HDB_ERR_NOENTRY) + continue; + else if (code) + return code; + + code = hdb_value2entry_alias(context, &value, &alias); + krb5_data_free(&value); + + if (code == ASN1_BAD_ID) + return HDB_ERR_EXISTS; + else if (code) + return code; + + code = krb5_principal_compare(context, alias.principal, + entry->entry.principal); + free_hdb_entry_alias(&alias); + if (code == 0) + return HDB_ERR_EXISTS; + } + return 0; +} + krb5_error_code _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { krb5_data key, value; int code; + /* check if new aliases already is used */ + code = hdb_check_aliases(context, db, entry); + if (code) + return code; + if(entry->entry.generation == NULL) { struct timeval t; entry->entry.generation = malloc(sizeof(*entry->entry.generation)); if(entry->entry.generation == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } gettimeofday(&t, NULL); @@ -238,12 +302,12 @@ _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) entry->entry.generation->gen = 0; } else entry->entry.generation->gen++; - hdb_principal2key(context, entry->entry.principal, &key); + code = hdb_seal_keys(context, db, &entry->entry); - if (code) { - krb5_data_free(&key); + if (code) return code; - } + + hdb_principal2key(context, entry->entry.principal, &key); /* remove aliases */ code = hdb_remove_aliases(context, db, &key); diff --git a/crypto/heimdal/lib/hdb/db.c b/crypto/heimdal/lib/hdb/db.c index 870f043..69940ed 100644 --- a/crypto/heimdal/lib/hdb/db.c +++ b/crypto/heimdal/lib/hdb/db.c @@ -1,40 +1,38 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2001 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: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" -RCSID("$Id: db.c 20215 2007-02-09 21:59:53Z lha $"); - #if HAVE_DB1 #if defined(HAVE_DB_185_H) @@ -68,8 +66,8 @@ DB_lock(krb5_context context, HDB *db, int operation) DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); if(fd < 0) { - krb5_set_error_string(context, - "Can't lock database: %s", db->hdb_name); + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "Can't lock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; } return hdb_lock(fd, operation); @@ -81,8 +79,8 @@ DB_unlock(krb5_context context, HDB *db) DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); if(fd < 0) { - krb5_set_error_string(context, - "Can't unlock database: %s", db->hdb_name); + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "Can't unlock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; } return hdb_unlock(fd); @@ -100,19 +98,19 @@ DB_seq(krb5_context context, HDB *db, code = db->hdb_lock(context, db, HDB_RLOCK); if(code == -1) { - krb5_set_error_string(context, "Database %s in use", db->hdb_name); + krb5_set_error_message(context, HDB_ERR_DB_INUSE, "Database %s in use", db->hdb_name); return HDB_ERR_DB_INUSE; } code = (*d->seq)(d, &key, &value, flag); db->hdb_unlock(context, db); /* XXX check value */ if(code == -1) { code = errno; - krb5_set_error_string(context, "Database %s seq error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s seq error: %s", + db->hdb_name, strerror(code)); return code; } if(code == 1) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); return HDB_ERR_NOENTRY; } @@ -131,8 +129,8 @@ DB_seq(krb5_context context, HDB *db, if (code == 0 && entry->entry.principal == NULL) { entry->entry.principal = malloc(sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); code = ENOMEM; + krb5_set_error_message(context, code, "malloc: out of memory"); hdb_free_entry (context, entry); } else { hdb_key2principal(context, &key_data, entry->entry.principal); @@ -168,7 +166,7 @@ DB_rename(krb5_context context, HDB *db, const char *new_name) free(new); if(ret) return errno; - + free(db->hdb_name); db->hdb_name = strdup(new_name); return 0; @@ -190,21 +188,21 @@ DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) db->hdb_unlock(context, db); if(code < 0) { code = errno; - krb5_set_error_string(context, "Database %s get error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s get error: %s", + db->hdb_name, strerror(code)); return code; } if(code == 1) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); return HDB_ERR_NOENTRY; } - + krb5_data_copy(reply, v.data, v.size); return 0; } static krb5_error_code -DB__put(krb5_context context, HDB *db, int replace, +DB__put(krb5_context context, HDB *db, int replace, krb5_data key, krb5_data value) { DB *d = (DB*)db->hdb_db; @@ -222,12 +220,12 @@ DB__put(krb5_context context, HDB *db, int replace, db->hdb_unlock(context, db); if(code < 0) { code = errno; - krb5_set_error_string(context, "Database %s put error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s put error: %s", + db->hdb_name, strerror(code)); return code; } if(code == 1) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); return HDB_ERR_EXISTS; } return 0; @@ -248,8 +246,8 @@ DB__del(krb5_context context, HDB *db, krb5_data key) db->hdb_unlock(context, db); if(code == 1) { code = errno; - krb5_set_error_string(context, "Database %s put error: %s", - db->hdb_name, strerror(code)); + krb5_set_error_message(context, code, "Database %s put error: %s", + db->hdb_name, strerror(code)); return code; } if(code < 0) @@ -265,7 +263,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) asprintf(&fn, "%s.db", db->hdb_name); if (fn == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } db->hdb_db = dbopen(fn, flags, mode, DB_BTREE, NULL); @@ -275,7 +273,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) db->hdb_db = dbopen(db->hdb_name, flags, mode, DB_BTREE, NULL); if(db->hdb_db == NULL) { ret = errno; - krb5_set_error_string(context, "dbopen (%s): %s", + krb5_set_error_message(context, ret, "dbopen (%s): %s", db->hdb_name, strerror(ret)); return ret; } @@ -284,42 +282,43 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) else ret = hdb_init_db(context, db); if(ret == HDB_ERR_NOENTRY) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); return 0; } if (ret) { DB_close(context, db); - krb5_set_error_string(context, "hdb_open: failed %s database %s", - (flags & O_ACCMODE) == O_RDONLY ? - "checking format of" : "initialize", + krb5_set_error_message(context, ret, "hdb_open: failed %s database %s", + (flags & O_ACCMODE) == O_RDONLY ? + "checking format of" : "initialize", db->hdb_name); } return ret; } krb5_error_code -hdb_db_create(krb5_context context, HDB **db, +hdb_db_create(krb5_context context, HDB **db, const char *filename) { *db = calloc(1, sizeof(**db)); if (*db == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_db = NULL; (*db)->hdb_name = strdup(filename); if ((*db)->hdb_name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); free(*db); *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_master_key_set = 0; (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL; (*db)->hdb_open = DB_open; (*db)->hdb_close = DB_close; - (*db)->hdb_fetch = _hdb_fetch; + (*db)->hdb_fetch_kvno = _hdb_fetch_kvno; (*db)->hdb_store = _hdb_store; (*db)->hdb_remove = _hdb_remove; (*db)->hdb_firstkey = DB_firstkey; diff --git a/crypto/heimdal/lib/hdb/db3.c b/crypto/heimdal/lib/hdb/db3.c index 45ccbef..58f892f 100644 --- a/crypto/heimdal/lib/hdb/db3.c +++ b/crypto/heimdal/lib/hdb/db3.c @@ -1,45 +1,47 @@ /* - * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" -RCSID("$Id: db3.c 21610 2007-07-17 07:10:45Z lha $"); - #if HAVE_DB3 -#ifdef HAVE_DB4_DB_H +#ifdef HAVE_DBHEADER +#include <db.h> +#elif HAVE_DB5_DB_H +#include <db5/db.h> +#elif HAVE_DB4_DB_H #include <db4/db.h> -#elif defined(HAVE_DB3_DB_H) +#elif HAVE_DB3_DB_H #include <db3/db.h> #else #include <db.h> @@ -125,7 +127,7 @@ DB_seq(krb5_context context, HDB *db, entry->entry.principal = malloc(sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { hdb_free_entry (context, entry); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } else { hdb_key2principal(context, &key_data, entry->entry.principal); @@ -161,7 +163,7 @@ DB_rename(krb5_context context, HDB *db, const char *new_name) free(new); if(ret) return errno; - + free(db->hdb_name); db->hdb_name = strdup(new_name); return 0; @@ -193,7 +195,7 @@ DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) } static krb5_error_code -DB__put(krb5_context context, HDB *db, int replace, +DB__put(krb5_context context, HDB *db, int replace, krb5_data key, krb5_data value) { DB *d = (DB*)db->hdb_db; @@ -264,10 +266,14 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) asprintf(&fn, "%s.db", db->hdb_name); if (fn == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + if (db_create(&d, NULL, 0) != 0) { + free(fn); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - db_create(&d, NULL, 0); db->hdb_db = d; #if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 1) @@ -282,14 +288,14 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) ret = (*d->open)(db->hdb_db, NULL, db->hdb_name, NULL, DB_BTREE, myflags, mode); #else - ret = (*d->open)(db->hdb_db, db->hdb_name, NULL, DB_BTREE, + ret = (*d->open)(db->hdb_db, db->hdb_name, NULL, DB_BTREE, myflags, mode); #endif } if (ret) { free(fn); - krb5_set_error_string(context, "opening %s: %s", + krb5_set_error_message(context, ret, "opening %s: %s", db->hdb_name, strerror(ret)); return ret; } @@ -297,7 +303,7 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) ret = (*d->cursor)(d, NULL, &dbc, 0); if (ret) { - krb5_set_error_string(context, "d->cursor: %s", strerror(ret)); + krb5_set_error_message(context, ret, "d->cursor: %s", strerror(ret)); return ret; } db->hdb_dbc = dbc; @@ -310,38 +316,39 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) return 0; if (ret) { DB_close(context, db); - krb5_set_error_string(context, "hdb_open: failed %s database %s", - (flags & O_ACCMODE) == O_RDONLY ? - "checking format of" : "initialize", - db->hdb_name); + krb5_set_error_message(context, ret, "hdb_open: failed %s database %s", + (flags & O_ACCMODE) == O_RDONLY ? + "checking format of" : "initialize", + db->hdb_name); } return ret; } krb5_error_code -hdb_db_create(krb5_context context, HDB **db, +hdb_db_create(krb5_context context, HDB **db, const char *filename) { *db = calloc(1, sizeof(**db)); if (*db == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_db = NULL; (*db)->hdb_name = strdup(filename); if ((*db)->hdb_name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); free(*db); *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_master_key_set = 0; (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL; (*db)->hdb_open = DB_open; (*db)->hdb_close = DB_close; - (*db)->hdb_fetch = _hdb_fetch; + (*db)->hdb_fetch_kvno = _hdb_fetch_kvno; (*db)->hdb_store = _hdb_store; (*db)->hdb_remove = _hdb_remove; (*db)->hdb_firstkey = DB_firstkey; diff --git a/crypto/heimdal/lib/hdb/dbinfo.c b/crypto/heimdal/lib/hdb/dbinfo.c index d43e31b..52e3941 100644 --- a/crypto/heimdal/lib/hdb/dbinfo.c +++ b/crypto/heimdal/lib/hdb/dbinfo.c @@ -1,40 +1,38 @@ /* - * Copyright (c) 2005 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" -RCSID("$Id: dbinfo.c 22306 2007-12-14 12:22:38Z lha $"); - struct hdb_dbinfo { char *label; char *realm; @@ -63,7 +61,7 @@ get_dbinfo(krb5_context context, di = calloc(1, sizeof(*di)); if (di == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } di->label = strdup(label); @@ -104,24 +102,24 @@ hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) dt = NULL; databases = NULL; - db_binding = krb5_config_get(context, NULL, krb5_config_list, - "kdc", - "database", - NULL); + db_binding = krb5_config_get_list(context, NULL, + "kdc", + "database", + NULL); if (db_binding) { ret = get_dbinfo(context, db_binding, "default", &di); if (ret == 0 && di) { databases = di; dt = &di->next; - } + } for ( ; db_binding != NULL; db_binding = db_binding->next) { if (db_binding->type != krb5_config_list) continue; - ret = get_dbinfo(context, db_binding->u.list, + ret = get_dbinfo(context, db_binding->u.list, db_binding->name, &di); if (ret) krb5_err(context, 1, ret, "failed getting realm"); @@ -159,7 +157,7 @@ hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) else /* the filename is something.else, replace .else with .mkey */ - asprintf(&di->mkey_file, "%.*s.mkey", + asprintf(&di->mkey_file, "%.*s.mkey", (int)(p - di->dbname), di->dbname); } if(di->acl_file == NULL) @@ -228,10 +226,12 @@ hdb_free_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) for(di = *dbp; di != NULL; di = ndi) { ndi = di->next; + free (di->label); free (di->realm); free (di->dbname); - if (di->mkey_file) - free (di->mkey_file); + free (di->mkey_file); + free (di->acl_file); + free (di->log_file); free(di); } *dbp = NULL; diff --git a/crypto/heimdal/lib/hdb/ext.c b/crypto/heimdal/lib/hdb/ext.c index 5f60999..d2a4373 100644 --- a/crypto/heimdal/lib/hdb/ext.c +++ b/crypto/heimdal/lib/hdb/ext.c @@ -1,60 +1,59 @@ /* - * Copyright (c) 2004 - 2005 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 2004 - 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" #include <der.h> -RCSID("$Id: ext.c 21113 2007-06-18 12:59:32Z lha $"); - krb5_error_code hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent) { - int i; + size_t i; if (ent->extensions == NULL) return 0; - /* + /* * check for unknown extensions and if they where tagged mandatory */ for (i = 0; i < ent->extensions->len; i++) { - if (ent->extensions->val[i].data.element != + if (ent->extensions->val[i].data.element != choice_HDB_extension_data_asn1_ellipsis) continue; if (ent->extensions->val[i].mandatory) { - krb5_set_error_string(context, "Principal have unknown " - "mandatory extension"); + krb5_set_error_message(context, HDB_ERR_MANDATORY_OPTION, + "Principal have unknown " + "mandatory extension"); return HDB_ERR_MANDATORY_OPTION; } } @@ -64,13 +63,13 @@ hdb_entry_check_mandatory(krb5_context context, const hdb_entry *ent) HDB_extension * hdb_find_extension(const hdb_entry *entry, int type) { - int i; + size_t i; if (entry->extensions == NULL) return NULL; for (i = 0; i < entry->extensions->len; i++) - if (entry->extensions->val[i].data.element == type) + if (entry->extensions->val[i].data.element == (unsigned)type) return &entry->extensions->val[i]; return NULL; } @@ -82,8 +81,8 @@ hdb_find_extension(const hdb_entry *entry, int type) */ krb5_error_code -hdb_replace_extension(krb5_context context, - hdb_entry *entry, +hdb_replace_extension(krb5_context context, + hdb_entry *entry, const HDB_extension *ext) { HDB_extension *ext2; @@ -95,13 +94,13 @@ hdb_replace_extension(krb5_context context, if (entry->extensions == NULL) { entry->extensions = calloc(1, sizeof(*entry->extensions)); if (entry->extensions == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } else if (ext->data.element != choice_HDB_extension_data_asn1_ellipsis) { ext2 = hdb_find_extension(entry, ext->data.element); } else { - /* + /* * This is an unknown extention, and we are asked to replace a * possible entry in `entry' that is of the same type. This * might seem impossible, but ASN.1 CHOICE comes to our @@ -113,15 +112,15 @@ hdb_replace_extension(krb5_context context, Der_type replace_type, list_type; unsigned int replace_tag, list_tag; size_t size; - int i; + size_t i; ret = der_get_tag(ext->data.u.asn1_ellipsis.data, ext->data.u.asn1_ellipsis.length, &replace_class, &replace_type, &replace_tag, &size); if (ret) { - krb5_set_error_string(context, "hdb: failed to decode " - "replacement hdb extention"); + krb5_set_error_message(context, ret, "hdb: failed to decode " + "replacement hdb extention"); return ret; } @@ -136,8 +135,8 @@ hdb_replace_extension(krb5_context context, &list_class, &list_type, &list_tag, &size); if (ret) { - krb5_set_error_string(context, "hdb: failed to decode " - "present hdb extention"); + krb5_set_error_message(context, ret, "hdb: failed to decode " + "present hdb extention"); return ret; } @@ -153,15 +152,15 @@ hdb_replace_extension(krb5_context context, free_HDB_extension(ext2); ret = copy_HDB_extension(ext, ext2); if (ret) - krb5_set_error_string(context, "hdb: failed to copy replacement " - "hdb extention"); + krb5_set_error_message(context, ret, "hdb: failed to copy replacement " + "hdb extention"); return ret; } - es = realloc(entry->extensions->val, + es = realloc(entry->extensions->val, (entry->extensions->len+1)*sizeof(entry->extensions->val[0])); if (es == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } entry->extensions->val = es; @@ -171,23 +170,23 @@ hdb_replace_extension(krb5_context context, if (ret == 0) entry->extensions->len++; else - krb5_set_error_string(context, "hdb: failed to copy new extension"); + krb5_set_error_message(context, ret, "hdb: failed to copy new extension"); return ret; } krb5_error_code -hdb_clear_extension(krb5_context context, - hdb_entry *entry, +hdb_clear_extension(krb5_context context, + hdb_entry *entry, int type) { - int i; + size_t i; if (entry->extensions == NULL) return 0; for (i = 0; i < entry->extensions->len; i++) { - if (entry->extensions->val[i].data.element == type) { + if (entry->extensions->val[i].data.element == (unsigned)type) { free_HDB_extension(&entry->extensions->val[i]); memmove(&entry->extensions->val[i], &entry->extensions->val[i + 1], @@ -234,6 +233,20 @@ hdb_entry_get_pkinit_hash(const hdb_entry *entry, const HDB_Ext_PKINIT_hash **a) } krb5_error_code +hdb_entry_get_pkinit_cert(const hdb_entry *entry, const HDB_Ext_PKINIT_cert **a) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_cert); + if (ext) + *a = &ext->data.u.pkinit_cert; + else + *a = NULL; + + return 0; +} + +krb5_error_code hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t) { const HDB_extension *ext; @@ -248,7 +261,7 @@ hdb_entry_get_pw_change_time(const hdb_entry *entry, time_t *t) } krb5_error_code -hdb_entry_set_pw_change_time(krb5_context context, +hdb_entry_set_pw_change_time(krb5_context context, hdb_entry *entry, time_t t) { @@ -264,7 +277,7 @@ hdb_entry_set_pw_change_time(krb5_context context, } int -hdb_entry_get_password(krb5_context context, HDB *db, +hdb_entry_get_password(krb5_context context, HDB *db, const hdb_entry *entry, char **p) { HDB_extension *ext; @@ -273,18 +286,19 @@ hdb_entry_get_password(krb5_context context, HDB *db, ext = hdb_find_extension(entry, choice_HDB_extension_data_password); if (ext) { - heim_utf8_string str; + heim_utf8_string xstr; heim_octet_string pw; if (db->hdb_master_key_set && ext->data.u.password.mkvno) { hdb_master_key key; - key = _hdb_find_master_key(ext->data.u.password.mkvno, + key = _hdb_find_master_key(ext->data.u.password.mkvno, db->hdb_master_key); if (key == NULL) { - krb5_set_error_string(context, "master key %d missing", - *ext->data.u.password.mkvno); + krb5_set_error_message(context, HDB_ERR_NO_MKEY, + "master key %d missing", + *ext->data.u.password.mkvno); return HDB_ERR_NO_MKEY; } @@ -296,21 +310,21 @@ hdb_entry_get_password(krb5_context context, HDB *db, ret = der_copy_octet_string(&ext->data.u.password.password, &pw); } if (ret) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); return ret; } - str = pw.data; - if (str[pw.length - 1] != '\0') { - krb5_set_error_string(context, "password malformated"); + xstr = pw.data; + if (xstr[pw.length - 1] != '\0') { + krb5_set_error_message(context, EINVAL, "malformed password"); return EINVAL; } - *p = strdup(str); + *p = strdup(xstr); der_free_octet_string(&pw); if (*p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -318,16 +332,17 @@ hdb_entry_get_password(krb5_context context, HDB *db, ret = krb5_unparse_name(context, entry->principal, &str); if (ret == 0) { - krb5_set_error_string(context, "no password attributefor %s", str); + krb5_set_error_message(context, ENOENT, + "no password attribute for %s", str); free(str); - } else - krb5_clear_error_string(context); + } else + krb5_clear_error_message(context); return ENOENT; } int -hdb_entry_set_password(krb5_context context, HDB *db, +hdb_entry_set_password(krb5_context context, HDB *db, hdb_entry *entry, const char *p) { HDB_extension ext; @@ -341,22 +356,23 @@ hdb_entry_set_password(krb5_context context, HDB *db, key = _hdb_find_master_key(NULL, db->hdb_master_key); if (key == NULL) { - krb5_set_error_string(context, "hdb_entry_set_password: " - "failed to find masterkey"); + krb5_set_error_message(context, HDB_ERR_NO_MKEY, + "hdb_entry_set_password: " + "failed to find masterkey"); return HDB_ERR_NO_MKEY; } ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY, - p, strlen(p) + 1, + p, strlen(p) + 1, &ext.data.u.password.password); if (ret) return ret; - ext.data.u.password.mkvno = + ext.data.u.password.mkvno = malloc(sizeof(*ext.data.u.password.mkvno)); if (ext.data.u.password.mkvno == NULL) { free_HDB_extension(&ext); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *ext.data.u.password.mkvno = _hdb_mkey_version(key); @@ -364,10 +380,10 @@ hdb_entry_set_password(krb5_context context, HDB *db, } else { ext.data.u.password.mkvno = NULL; - ret = krb5_data_copy(&ext.data.u.password.password, + ret = krb5_data_copy(&ext.data.u.password.password, p, strlen(p) + 1); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); free_HDB_extension(&ext); return ret; } @@ -383,17 +399,17 @@ hdb_entry_set_password(krb5_context context, HDB *db, int hdb_entry_clear_password(krb5_context context, hdb_entry *entry) { - return hdb_clear_extension(context, entry, + return hdb_clear_extension(context, entry, choice_HDB_extension_data_password); } krb5_error_code -hdb_entry_get_ConstrainedDelegACL(const hdb_entry *entry, +hdb_entry_get_ConstrainedDelegACL(const hdb_entry *entry, const HDB_Ext_Constrained_delegation_acl **a) { const HDB_extension *ext; - ext = hdb_find_extension(entry, + ext = hdb_find_extension(entry, choice_HDB_extension_data_allowed_to_delegate_to); if (ext) *a = &ext->data.u.allowed_to_delegate_to; diff --git a/crypto/heimdal/lib/hdb/hdb-keytab.c b/crypto/heimdal/lib/hdb/hdb-keytab.c new file mode 100644 index 0000000..ab2afb5 --- /dev/null +++ b/crypto/heimdal/lib/hdb/hdb-keytab.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2009 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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 "hdb_locl.h" +#include <assert.h> + +typedef struct { + char *path; + krb5_keytab keytab; +} *hdb_keytab; + +/* + * + */ + +static krb5_error_code +hkt_close(krb5_context context, HDB *db) +{ + hdb_keytab k = (hdb_keytab)db->hdb_db; + krb5_error_code ret; + + assert(k->keytab); + + ret = krb5_kt_close(context, k->keytab); + k->keytab = NULL; + + return ret; +} + +static krb5_error_code +hkt_destroy(krb5_context context, HDB *db) +{ + hdb_keytab k = (hdb_keytab)db->hdb_db; + krb5_error_code ret; + + ret = hdb_clear_master_key (context, db); + + free(k->path); + free(k); + + free(db->hdb_name); + free(db); + return ret; +} + +static krb5_error_code +hkt_lock(krb5_context context, HDB *db, int operation) +{ + return 0; +} + +static krb5_error_code +hkt_unlock(krb5_context context, HDB *db) +{ + return 0; +} + +static krb5_error_code +hkt_firstkey(krb5_context context, HDB *db, + unsigned flags, hdb_entry_ex *entry) +{ + return HDB_ERR_DB_INUSE; +} + +static krb5_error_code +hkt_nextkey(krb5_context context, HDB * db, unsigned flags, + hdb_entry_ex * entry) +{ + return HDB_ERR_DB_INUSE; +} + +static krb5_error_code +hkt_open(krb5_context context, HDB * db, int flags, mode_t mode) +{ + hdb_keytab k = (hdb_keytab)db->hdb_db; + krb5_error_code ret; + + assert(k->keytab == NULL); + + ret = krb5_kt_resolve(context, k->path, &k->keytab); + if (ret) + return ret; + + return 0; +} + +static krb5_error_code +hkt_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, + unsigned flags, krb5_kvno kvno, hdb_entry_ex * entry) +{ + hdb_keytab k = (hdb_keytab)db->hdb_db; + krb5_error_code ret; + krb5_keytab_entry ktentry; + + if (!(flags & HDB_F_KVNO_SPECIFIED)) { + /* Preserve previous behaviour if no kvno specified */ + kvno = 0; + } + + memset(&ktentry, 0, sizeof(ktentry)); + + entry->entry.flags.server = 1; + entry->entry.flags.forwardable = 1; + entry->entry.flags.renewable = 1; + + /* Not recorded in the OD backend, make something up */ + ret = krb5_parse_name(context, "hdb/keytab@WELL-KNOWN:KEYTAB-BACKEND", + &entry->entry.created_by.principal); + if (ret) + goto out; + + /* + * XXX really needs to try all enctypes and just not pick the + * first one, even if that happens to be des3-cbc-sha1 (ie best + * enctype) in the Apple case. A while loop over all known + * enctypes should work. + */ + + ret = krb5_kt_get_entry(context, k->keytab, principal, kvno, 0, &ktentry); + if (ret) { + ret = HDB_ERR_NOENTRY; + goto out; + } + + ret = krb5_copy_principal(context, principal, &entry->entry.principal); + if (ret) + goto out; + + ret = _hdb_keytab2hdb_entry(context, &ktentry, entry); + + out: + if (ret) { + free_hdb_entry(&entry->entry); + memset(&entry->entry, 0, sizeof(entry->entry)); + } + krb5_kt_free_entry(context, &ktentry); + + return ret; +} + +static krb5_error_code +hkt_store(krb5_context context, HDB * db, unsigned flags, + hdb_entry_ex * entry) +{ + return HDB_ERR_DB_INUSE; +} + + +krb5_error_code +hdb_keytab_create(krb5_context context, HDB ** db, const char *arg) +{ + hdb_keytab k; + + *db = calloc(1, sizeof(**db)); + if (*db == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + memset(*db, 0, sizeof(**db)); + + k = calloc(1, sizeof(*k)); + if (k == NULL) { + free(*db); + *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + k->path = strdup(arg); + if (k->path == NULL) { + free(k); + free(*db); + *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + + (*db)->hdb_db = k; + + (*db)->hdb_master_key_set = 0; + (*db)->hdb_openp = 0; + (*db)->hdb_open = hkt_open; + (*db)->hdb_close = hkt_close; + (*db)->hdb_fetch_kvno = hkt_fetch_kvno; + (*db)->hdb_store = hkt_store; + (*db)->hdb_remove = NULL; + (*db)->hdb_firstkey = hkt_firstkey; + (*db)->hdb_nextkey = hkt_nextkey; + (*db)->hdb_lock = hkt_lock; + (*db)->hdb_unlock = hkt_unlock; + (*db)->hdb_rename = NULL; + (*db)->hdb__get = NULL; + (*db)->hdb__put = NULL; + (*db)->hdb__del = NULL; + (*db)->hdb_destroy = hkt_destroy; + + return 0; +} diff --git a/crypto/heimdal/lib/hdb/hdb-ldap.c b/crypto/heimdal/lib/hdb/hdb-ldap.c index c9f3d37..1b4024a 100644 --- a/crypto/heimdal/lib/hdb/hdb-ldap.c +++ b/crypto/heimdal/lib/hdb/hdb-ldap.c @@ -1,7 +1,7 @@ /* * Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd. * Copyright (c) 2004, Andrew Bartlett. - * Copyright (c) 2003 - 2007, Kungliga Tekniska Högskolan. + * Copyright (c) 2003 - 2008, Kungliga Tekniska Högskolan. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,8 +34,6 @@ #include "hdb_locl.h" -RCSID("$Id: hdb-ldap.c 22071 2007-11-14 20:04:50Z lha $"); - #ifdef OPENLDAP #include <lber.h> @@ -48,7 +46,7 @@ static krb5_error_code LDAP_close(krb5_context context, HDB *); static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, - hdb_entry_ex * ent); + int flags, hdb_entry_ex * ent); static const char *default_structural_object = "account"; static char *structural_object; @@ -74,7 +72,7 @@ struct hdbldapdb { * */ -static char * krb5kdcentry_attrs[] = { +static char * krb5kdcentry_attrs[] = { "cn", "createTimestamp", "creatorsName", @@ -121,8 +119,9 @@ LDAP_no_size_limit(krb5_context context, LDAP *lp) ret = ldap_set_option(lp, LDAP_OPT_SIZELIMIT, (const void *)&limit); if (ret != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_set_option: %s", - ldap_err2string(ret)); + krb5_set_error_message(context, HDB_ERR_BADVERSION, + "ldap_set_option: %s", + ldap_err2string(ret)); return HDB_ERR_BADVERSION; } return 0; @@ -222,7 +221,7 @@ LDAP_addmod_len(LDAPMod *** modlist, int modop, const char *attribute, (*modlist)[cMods]->mod_bvalues = bv; - bv[i] = ber_memalloc(sizeof(*bv));; + bv[i] = ber_memalloc(sizeof(**bv));; if (bv[i] == NULL) return ENOMEM; @@ -295,8 +294,9 @@ LDAP_addmod_integer(krb5_context context, ret = asprintf(&buf, "%ld", l); if (ret < 0) { - krb5_set_error_string(context, "asprintf: out of memory:"); - return ret; + krb5_set_error_message(context, ENOMEM, + "asprintf: out of memory:"); + return ENOMEM; } ret = LDAP_addmod(mods, modop, attribute, buf); free (buf); @@ -307,38 +307,40 @@ static krb5_error_code LDAP_get_string_value(HDB * db, LDAPMessage * entry, const char *attribute, char **ptr) { - char **vals; - int ret; + struct berval **vals; - vals = ldap_get_values(HDB2LDAP(db), entry, (char *) attribute); - if (vals == NULL) { + vals = ldap_get_values_len(HDB2LDAP(db), entry, attribute); + if (vals == NULL || vals[0] == NULL) { *ptr = NULL; return HDB_ERR_NOENTRY; } - *ptr = strdup(vals[0]); - if (*ptr == NULL) - ret = ENOMEM; - else - ret = 0; + *ptr = malloc(vals[0]->bv_len + 1); + if (*ptr == NULL) { + ldap_value_free_len(vals); + return ENOMEM; + } - ldap_value_free(vals); + memcpy(*ptr, vals[0]->bv_val, vals[0]->bv_len); + (*ptr)[vals[0]->bv_len] = 0; - return ret; + ldap_value_free_len(vals); + + return 0; } static krb5_error_code LDAP_get_integer_value(HDB * db, LDAPMessage * entry, const char *attribute, int *ptr) { - char **vals; - - vals = ldap_get_values(HDB2LDAP(db), entry, (char *) attribute); - if (vals == NULL) - return HDB_ERR_NOENTRY; + krb5_error_code ret; + char *val; - *ptr = atoi(vals[0]); - ldap_value_free(vals); + ret = LDAP_get_string_value(db, entry, attribute, &val); + if (ret) + return ret; + *ptr = atoi(val); + free(val); return 0; } @@ -369,6 +371,14 @@ LDAP_get_generalized_time_value(HDB * db, LDAPMessage * entry, return 0; } +static int +bervalstrcmp(struct berval *v, const char *str) +{ + size_t len = strlen(str); + return (v->bv_len == len) && strncasecmp(str, (char *)v->bv_val, len) == 0; +} + + static krb5_error_code LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, LDAPMessage * msg, LDAPMod *** pmods) @@ -386,40 +396,39 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, krb5_boolean is_heimdal_entry = FALSE; krb5_boolean is_heimdal_principal = FALSE; - char **values; + struct berval **vals; *pmods = NULL; if (msg != NULL) { - ret = LDAP_message2entry(context, db, msg, &orig); + ret = LDAP_message2entry(context, db, msg, 0, &orig); if (ret) goto out; is_new_entry = FALSE; - - values = ldap_get_values(HDB2LDAP(db), msg, "objectClass"); - if (values) { - int num_objectclasses = ldap_count_values(values); + + vals = ldap_get_values_len(HDB2LDAP(db), msg, "objectClass"); + if (vals) { + int num_objectclasses = ldap_count_values_len(vals); for (i=0; i < num_objectclasses; i++) { - if (strcasecmp(values[i], "sambaSamAccount") == 0) { + if (bervalstrcmp(vals[i], "sambaSamAccount")) is_samba_account = TRUE; - } else if (strcasecmp(values[i], structural_object) == 0) { + else if (bervalstrcmp(vals[i], structural_object)) is_account = TRUE; - } else if (strcasecmp(values[i], "krb5Principal") == 0) { + else if (bervalstrcmp(vals[i], "krb5Principal")) is_heimdal_principal = TRUE; - } else if (strcasecmp(values[i], "krb5KDCEntry") == 0) { + else if (bervalstrcmp(vals[i], "krb5KDCEntry")) is_heimdal_entry = TRUE; - } } - ldap_value_free(values); + ldap_value_free_len(vals); } /* * If this is just a "account" entry and no other objectclass * is hanging on this entry, it's really a new entry. */ - if (is_samba_account == FALSE && is_heimdal_principal == FALSE && + if (is_samba_account == FALSE && is_heimdal_principal == FALSE && is_heimdal_entry == FALSE) { if (is_account == TRUE) { is_new_entry = TRUE; @@ -440,10 +449,10 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "top"); if (ret) goto out; - + /* account is the structural object class */ if (is_account == FALSE) { - ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", + ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", structural_object); is_account = TRUE; if (ret) @@ -461,7 +470,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, goto out; } - if (is_new_entry || + if (is_new_entry || krb5_principal_compare(context, ent->entry.principal, orig.entry.principal) == FALSE) { @@ -495,7 +504,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (is_heimdal_entry && (ent->entry.kvno != orig.entry.kvno || is_new_entry)) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, - "krb5KeyVersionNumber", + "krb5KeyVersionNumber", ent->entry.kvno); if (ret) goto out; @@ -514,7 +523,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (ent->entry.valid_end) { if (orig.entry.valid_end == NULL || (*(ent->entry.valid_end) != *(orig.entry.valid_end))) { - if (is_heimdal_entry) { + if (is_heimdal_entry) { ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, "krb5ValidEnd", ent->entry.valid_end); @@ -523,7 +532,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, } if (is_samba_account) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, - "sambaKickoffTime", + "sambaKickoffTime", *(ent->entry.valid_end)); if (ret) goto out; @@ -543,7 +552,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (is_samba_account) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, - "sambaPwdMustChange", + "sambaPwdMustChange", *(ent->entry.pw_end)); if (ret) goto out; @@ -556,7 +565,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (is_samba_account && ent->entry.last_pw_change) { if (orig.entry.last_pw_change == NULL || (*(ent->entry.last_pw_change) != *(orig.entry.last_pw_change))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, - "sambaPwdLastSet", + "sambaPwdLastSet", *(ent->entry.last_pw_change)); if (ret) goto out; @@ -569,7 +578,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, || (*(ent->entry.max_life) != *(orig.entry.max_life))) { ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, - "krb5MaxLife", + "krb5MaxLife", *(ent->entry.max_life)); if (ret) goto out; @@ -602,9 +611,9 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, /* Remove keys if they exists, and then replace keys. */ if (!is_new_entry && orig.entry.keys.len > 0) { - values = ldap_get_values(HDB2LDAP(db), msg, "krb5Key"); - if (values) { - ldap_value_free(values); + vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5Key"); + if (vals) { + ldap_value_free_len(vals); ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5Key", NULL); if (ret) @@ -618,38 +627,43 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, && ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { char *ntHexPassword; char *nt; - + time_t now = time(NULL); + /* the key might have been 'sealed', but samba passwords are clear in the directory */ ret = hdb_unseal_key(context, db, &ent->entry.keys.val[i]); if (ret) goto out; - + nt = ent->entry.keys.val[i].key.keyvalue.data; /* store in ntPassword, not krb5key */ ret = hex_encode(nt, 16, &ntHexPassword); if (ret < 0) { - krb5_set_error_string(context, "hdb-ldap: failed to " - "hex encode key"); ret = ENOMEM; + krb5_set_error_message(context, ret, "hdb-ldap: failed to " + "hex encode key"); goto out; } - ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "sambaNTPassword", + ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "sambaNTPassword", ntHexPassword); free(ntHexPassword); if (ret) goto out; - + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, + "sambaPwdLastSet", now); + if (ret) + goto out; + /* have to kill the LM passwod if it exists */ - values = ldap_get_values(HDB2LDAP(db), msg, "sambaLMPassword"); - if (values) { - ldap_value_free(values); + vals = ldap_get_values_len(HDB2LDAP(db), msg, "sambaLMPassword"); + if (vals) { + ldap_value_free_len(vals); ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "sambaLMPassword", NULL); if (ret) goto out; } - + } else if (is_heimdal_entry) { unsigned char *buf; size_t len, buf_size; @@ -670,15 +684,15 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (ent->entry.etypes) { int add_krb5EncryptionType = 0; - /* + /* * Only add/modify krb5EncryptionType if it's a new heimdal * entry or krb5EncryptionType already exists on the entry. */ if (!is_new_entry) { - values = ldap_get_values(HDB2LDAP(db), msg, "krb5EncryptionType"); - if (values) { - ldap_value_free(values); + vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5EncryptionType"); + if (vals) { + ldap_value_free_len(vals); ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5EncryptionType", NULL); if (ret) @@ -690,7 +704,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (add_krb5EncryptionType) { for (i = 0; i < ent->entry.etypes->len; i++) { - if (is_samba_account && + if (is_samba_account && ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { ; @@ -730,20 +744,22 @@ LDAP_dn2principal(krb5_context context, HDB * db, const char *dn, krb5_error_code ret; int rc; const char *filter = "(objectClass=krb5Principal)"; - char **values; LDAPMessage *res = NULL, *e; + char *p; ret = LDAP_no_size_limit(context, HDB2LDAP(db)); if (ret) goto out; - rc = ldap_search_s(HDB2LDAP(db), dn, LDAP_SCOPE_SUBTREE, - filter, krb5principal_attrs, - 0, &res); + rc = ldap_search_ext_s(HDB2LDAP(db), dn, LDAP_SCOPE_SUBTREE, + filter, krb5principal_attrs, 0, + NULL, NULL, NULL, + 0, &res); if (check_ldap(context, db, rc)) { - krb5_set_error_string(context, "ldap_search_s: filter: %s error: %s", - filter, ldap_err2string(rc)); ret = HDB_ERR_NOENTRY; + krb5_set_error_message(context, ret, "ldap_search_ext_s: " + "filter: %s error: %s", + filter, ldap_err2string(rc)); goto out; } @@ -753,14 +769,14 @@ LDAP_dn2principal(krb5_context context, HDB * db, const char *dn, goto out; } - values = ldap_get_values(HDB2LDAP(db), e, "krb5PrincipalName"); - if (values == NULL) { + ret = LDAP_get_string_value(db, e, "krb5PrincipalName", &p); + if (ret) { ret = HDB_ERR_NOENTRY; goto out; } - ret = krb5_parse_name(context, values[0], principal); - ldap_value_free(values); + ret = krb5_parse_name(context, p, principal); + free(p); out: if (res) @@ -769,6 +785,49 @@ LDAP_dn2principal(krb5_context context, HDB * db, const char *dn, return ret; } +static int +need_quote(unsigned char c) +{ + return (c & 0x80) || + (c < 32) || + (c == '(') || + (c == ')') || + (c == '*') || + (c == '\\') || + (c == 0x7f); +} + +const static char hexchar[] = "0123456789ABCDEF"; + +static krb5_error_code +escape_value(krb5_context context, const unsigned char *unquoted, char **quoted) +{ + size_t i, len; + + for (i = 0, len = 0; unquoted[i] != '\0'; i++, len++) { + if (need_quote((unsigned char)unquoted[i])) + len += 2; + } + + *quoted = malloc(len + 1); + if (*quoted == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + for (i = 0; unquoted[0] ; unquoted++) { + if (need_quote((unsigned char *)unquoted[0])) { + (*quoted)[i++] = '\\'; + (*quoted)[i++] = hexchar[(unquoted[0] >> 4) & 0xf]; + (*quoted)[i++] = hexchar[(unquoted[0] ) & 0xf]; + } else + (*quoted)[i++] = (char)unquoted[0]; + } + (*quoted)[i] = '\0'; + return 0; +} + + static krb5_error_code LDAP__lookup_princ(krb5_context context, HDB *db, @@ -778,18 +837,29 @@ LDAP__lookup_princ(krb5_context context, { krb5_error_code ret; int rc; - char *filter = NULL; + char *quote, *filter = NULL; ret = LDAP__connect(context, db); if (ret) return ret; + /* + * Quote searches that contain filter language, this quote + * searches for *@REALM, which takes very long time. + */ + + ret = escape_value(context, princname, "e); + if (ret) + goto out; + rc = asprintf(&filter, "(&(objectClass=krb5Principal)(krb5PrincipalName=%s))", - princname); + quote); + free(quote); + if (rc < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -797,12 +867,16 @@ LDAP__lookup_princ(krb5_context context, if (ret) goto out; - rc = ldap_search_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, filter, - krb5kdcentry_attrs, 0, msg); + rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db), + LDAP_SCOPE_SUBTREE, filter, + krb5kdcentry_attrs, 0, + NULL, NULL, NULL, + 0, msg); if (check_ldap(context, db, rc)) { - krb5_set_error_string(context, "ldap_search_s: filter: %s - error: %s", - filter, ldap_err2string(rc)); ret = HDB_ERR_NOENTRY; + krb5_set_error_message(context, ret, "ldap_search_ext_s: " + "filter: %s - error: %s", + filter, ldap_err2string(rc)); goto out; } @@ -811,27 +885,34 @@ LDAP__lookup_princ(krb5_context context, filter = NULL; ldap_msgfree(*msg); *msg = NULL; - + + ret = escape_value(context, userid, "e); + if (ret) + goto out; + rc = asprintf(&filter, "(&(|(objectClass=sambaSamAccount)(objectClass=%s))(uid=%s))", - structural_object, userid); + structural_object, quote); + free(quote); if (rc < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "asprintf: out of memory"); goto out; } - + ret = LDAP_no_size_limit(context, HDB2LDAP(db)); if (ret) goto out; - rc = ldap_search_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, - filter, krb5kdcentry_attrs, 0, msg); + rc = ldap_search_ext_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, + filter, krb5kdcentry_attrs, 0, + NULL, NULL, NULL, + 0, msg); if (check_ldap(context, db, rc)) { - krb5_set_error_string(context, - "ldap_search_s: filter: %s error: %s", - filter, ldap_err2string(rc)); ret = HDB_ERR_NOENTRY; + krb5_set_error_message(context, ret, + "ldap_search_ext_s: filter: %s error: %s", + filter, ldap_err2string(rc)); goto out; } } @@ -889,14 +970,13 @@ LDAP_principal2message(krb5_context context, HDB * db, */ static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, - hdb_entry_ex * ent) + int flags, hdb_entry_ex * ent) { char *unparsed_name = NULL, *dn = NULL, *ntPasswordIN = NULL; char *samba_acct_flags = NULL; - unsigned long tmp; struct berval **keys; - char **values; - int tmp_time, i, ret, have_arcfour = 0; + struct berval **vals; + int tmp, tmp_time, i, ret, have_arcfour = 0; memset(ent, 0, sizeof(*ent)); ent->entry.flags = int2HDBFlags(0); @@ -914,7 +994,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, if (ret) goto out; } else { - krb5_set_error_string(context, "hdb-ldap: ldap entry missing" + krb5_set_error_message(context, HDB_ERR_NOENTRY, + "hdb-ldap: ldap entry missing" "principal name"); return HDB_ERR_NOENTRY; } @@ -938,8 +1019,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.keys.len = ldap_count_values_len(keys); ent->entry.keys.val = (Key *) calloc(ent->entry.keys.len, sizeof(Key)); if (ent->entry.keys.val == NULL) { - krb5_set_error_string(context, "calloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "calloc: out of memory"); goto out; } for (i = 0; i < ent->entry.keys.len; i++) { @@ -962,27 +1043,39 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, #endif } - values = ldap_get_values(HDB2LDAP(db), msg, "krb5EncryptionType"); - if (values != NULL) { + vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5EncryptionType"); + if (vals != NULL) { int i; ent->entry.etypes = malloc(sizeof(*(ent->entry.etypes))); if (ent->entry.etypes == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret,"malloc: out of memory"); goto out; } - ent->entry.etypes->len = ldap_count_values(values); + ent->entry.etypes->len = ldap_count_values_len(vals); ent->entry.etypes->val = calloc(ent->entry.etypes->len, sizeof(int)); if (ent->entry.etypes->val == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); + ent->entry.etypes->len = 0; goto out; } for (i = 0; i < ent->entry.etypes->len; i++) { - ent->entry.etypes->val[i] = atoi(values[i]); + char *buf; + + buf = malloc(vals[i]->bv_len + 1); + if (buf == NULL) { + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); + goto out; + } + memcpy(buf, vals[i]->bv_val, vals[i]->bv_len); + buf[vals[i]->bv_len] = '\0'; + ent->entry.etypes->val[i] = atoi(buf); + free(buf); } - ldap_value_free(values); + ldap_value_free_len(vals); } for (i = 0; i < ent->entry.keys.len; i++) { @@ -1003,8 +1096,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, (ent->entry.keys.len + 1) * sizeof(ent->entry.keys.val[0])); if (keys == NULL) { free(ntPasswordIN); - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ent->entry.keys.val = keys; @@ -1012,7 +1105,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.keys.val[ent->entry.keys.len].key.keytype = ETYPE_ARCFOUR_HMAC_MD5; ret = krb5_data_alloc (&ent->entry.keys.val[ent->entry.keys.len].key.keyvalue, 16); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); free(ntPasswordIN); ret = ENOMEM; goto out; @@ -1024,8 +1117,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, if (ent->entry.etypes == NULL) { ent->entry.etypes = malloc(sizeof(*(ent->entry.etypes))); if (ent->entry.etypes == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ent->entry.etypes->val = NULL; @@ -1037,16 +1130,16 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, break; /* If there is no ARCFOUR enctype, add one */ if (i == ent->entry.etypes->len) { - etypes = realloc(ent->entry.etypes->val, - (ent->entry.etypes->len + 1) * + etypes = realloc(ent->entry.etypes->val, + (ent->entry.etypes->len + 1) * sizeof(ent->entry.etypes->val[0])); if (etypes == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; - goto out; + krb5_set_error_message(context, ret, "malloc: out of memory"); + goto out; } ent->entry.etypes->val = etypes; - ent->entry.etypes->val[ent->entry.etypes->len] = + ent->entry.etypes->val[ent->entry.etypes->len] = ETYPE_ARCFOUR_HMAC_MD5; ent->entry.etypes->len++; } @@ -1059,37 +1152,38 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.created_by.principal = NULL; - ret = LDAP_get_string_value(db, msg, "creatorsName", &dn); - if (ret == 0) { - if (LDAP_dn2principal(context, db, dn, &ent->entry.created_by.principal) - != 0) { - ent->entry.created_by.principal = NULL; + if (flags & HDB_F_ADMIN_DATA) { + ret = LDAP_get_string_value(db, msg, "creatorsName", &dn); + if (ret == 0) { + LDAP_dn2principal(context, db, dn, &ent->entry.created_by.principal); + free(dn); } - free(dn); - } - ent->entry.modified_by = (Event *) malloc(sizeof(Event)); - if (ent->entry.modified_by == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; - } - ret = LDAP_get_generalized_time_value(db, msg, "modifyTimestamp", - &ent->entry.modified_by->time); - if (ret == 0) { - ret = LDAP_get_string_value(db, msg, "modifiersName", &dn); - if (LDAP_dn2principal(context, db, dn, &ent->entry.modified_by->principal)) - ent->entry.modified_by->principal = NULL; - free(dn); - } else { - free(ent->entry.modified_by); - ent->entry.modified_by = NULL; + ent->entry.modified_by = calloc(1, sizeof(*ent->entry.modified_by)); + if (ent->entry.modified_by == NULL) { + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); + goto out; + } + + ret = LDAP_get_generalized_time_value(db, msg, "modifyTimestamp", + &ent->entry.modified_by->time); + if (ret == 0) { + ret = LDAP_get_string_value(db, msg, "modifiersName", &dn); + if (ret == 0) { + LDAP_dn2principal(context, db, dn, &ent->entry.modified_by->principal); + free(dn); + } else { + free(ent->entry.modified_by); + ent->entry.modified_by = NULL; + } + } } ent->entry.valid_start = malloc(sizeof(*ent->entry.valid_start)); if (ent->entry.valid_start == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidStart", @@ -1099,11 +1193,11 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, free(ent->entry.valid_start); ent->entry.valid_start = NULL; } - + ent->entry.valid_end = malloc(sizeof(*ent->entry.valid_end)); if (ent->entry.valid_end == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidEnd", @@ -1119,8 +1213,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, if (ent->entry.valid_end == NULL) { ent->entry.valid_end = malloc(sizeof(*ent->entry.valid_end)); if (ent->entry.valid_end == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } } @@ -1129,8 +1223,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.pw_end = malloc(sizeof(*ent->entry.pw_end)); if (ent->entry.pw_end == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_generalized_time_value(db, msg, "krb5PasswordEnd", @@ -1141,13 +1235,34 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.pw_end = NULL; } + ret = LDAP_get_integer_value(db, msg, "sambaPwdLastSet", &tmp_time); + if (ret == 0) { + time_t delta; + + if (ent->entry.pw_end == NULL) { + ent->entry.pw_end = malloc(sizeof(*ent->entry.pw_end)); + if (ent->entry.pw_end == NULL) { + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); + goto out; + } + } + + delta = krb5_config_get_time_default(context, NULL, + 365 * 24 * 60 * 60, + "kadmin", + "password_lifetime", + NULL); + *ent->entry.pw_end = tmp_time + delta; + } + ret = LDAP_get_integer_value(db, msg, "sambaPwdMustChange", &tmp_time); if (ret == 0) { if (ent->entry.pw_end == NULL) { ent->entry.pw_end = malloc(sizeof(*ent->entry.pw_end)); if (ent->entry.pw_end == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } } @@ -1164,8 +1279,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.max_life = malloc(sizeof(*ent->entry.max_life)); if (ent->entry.max_life == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_integer_value(db, msg, "krb5MaxLife", &max_life); @@ -1181,8 +1296,8 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.max_renew = malloc(sizeof(*ent->entry.max_renew)); if (ent->entry.max_renew == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = LDAP_get_integer_value(db, msg, "krb5MaxRenew", &max_renew); @@ -1193,18 +1308,9 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, *ent->entry.max_renew = max_renew; } - values = ldap_get_values(HDB2LDAP(db), msg, "krb5KDCFlags"); - if (values != NULL) { - errno = 0; - tmp = strtoul(values[0], (char **) NULL, 10); - if (tmp == ULONG_MAX && errno == ERANGE) { - krb5_set_error_string(context, "strtoul: could not convert flag"); - ret = ERANGE; - goto out; - } - } else { + ret = LDAP_get_integer_value(db, msg, "krb5KDCFlags", &tmp); + if (ret) tmp = 0; - } ent->entry.flags = int2HDBFlags(tmp); @@ -1212,29 +1318,29 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ret = LDAP_get_string_value(db, msg, "sambaAcctFlags", &samba_acct_flags); if (ret == 0) { /* parse the [UXW...] string: - - 'N' No password - 'D' Disabled - 'H' Homedir required - 'T' Temp account. - 'U' User account (normal) - 'M' MNS logon user account - what is this ? - 'W' Workstation account - 'S' Server account - 'L' Locked account - 'X' No Xpiry on password - 'I' Interdomain trust account - - */ - + + 'N' No password + 'D' Disabled + 'H' Homedir required + 'T' Temp account. + 'U' User account (normal) + 'M' MNS logon user account - what is this ? + 'W' Workstation account + 'S' Server account + 'L' Locked account + 'X' No Xpiry on password + 'I' Interdomain trust account + + */ + int i; int flags_len = strlen(samba_acct_flags); if (flags_len < 2) goto out2; - if (samba_acct_flags[0] != '[' - || samba_acct_flags[flags_len - 1] != ']') + if (samba_acct_flags[0] != '[' + || samba_acct_flags[flags_len - 1] != ']') goto out2; /* Allow forwarding */ @@ -1307,7 +1413,7 @@ LDAP_close(krb5_context context, HDB * db) ldap_unbind_ext(HDB2LDAP(db), NULL, NULL); ((struct hdbldapdb *)db->hdb_db)->h_lp = NULL; } - + return 0; } @@ -1343,7 +1449,7 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) break; case LDAP_RES_SEARCH_ENTRY: /* We have an entry. Parse it. */ - ret = LDAP_message2entry(context, db, e, entry); + ret = LDAP_message2entry(context, db, e, flags, entry); ldap_msgfree(e); break; case LDAP_RES_SEARCH_RESULT: @@ -1351,13 +1457,13 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) parserc = ldap_parse_result(HDB2LDAP(db), e, NULL, NULL, NULL, NULL, NULL, 1); + ret = HDB_ERR_NOENTRY; if (parserc != LDAP_SUCCESS && parserc != LDAP_MORE_RESULTS_TO_RETURN) { - krb5_set_error_string(context, "ldap_parse_result: %s", - ldap_err2string(parserc)); - ldap_abandon(HDB2LDAP(db), msgid); + krb5_set_error_message(context, ret, "ldap_parse_result: %s", + ldap_err2string(parserc)); + ldap_abandon_ext(HDB2LDAP(db), msgid, NULL, NULL); } - ret = HDB_ERR_NOENTRY; HDBSETMSGID(db, -1); break; case LDAP_SERVER_DOWN: @@ -1369,7 +1475,7 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) default: /* Some unspecified error (timeout?). Abandon. */ ldap_msgfree(e); - ldap_abandon(HDB2LDAP(db), msgid); + ldap_abandon_ext(HDB2LDAP(db), msgid, NULL, NULL); ret = HDB_ERR_NOENTRY; HDBSETMSGID(db, -1); break; @@ -1402,10 +1508,11 @@ LDAP_firstkey(krb5_context context, HDB *db, unsigned flags, if (ret) return ret; - msgid = ldap_search(HDB2LDAP(db), HDB2BASE(db), + ret = ldap_search_ext(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, "(|(objectClass=krb5Principal)(objectClass=sambaSamAccount))", - krb5kdcentry_attrs, 0); + krb5kdcentry_attrs, 0, + NULL, NULL, NULL, 0, &msgid); if (msgid < 0) return HDB_ERR_NOENTRY; @@ -1451,16 +1558,16 @@ LDAP__connect(krb5_context context, HDB * db) rc = ldap_initialize(&((struct hdbldapdb *)db->hdb_db)->h_lp, HDB2URL(db)); if (rc != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_initialize: %s", - ldap_err2string(rc)); + krb5_set_error_message(context, HDB_ERR_NOENTRY, "ldap_initialize: %s", + ldap_err2string(rc)); return HDB_ERR_NOENTRY; } rc = ldap_set_option(HDB2LDAP(db), LDAP_OPT_PROTOCOL_VERSION, (const void *)&version); if (rc != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_set_option: %s", - ldap_err2string(rc)); + krb5_set_error_message(context, HDB_ERR_BADVERSION, + "ldap_set_option: %s", ldap_err2string(rc)); LDAP_close(context, db); return HDB_ERR_BADVERSION; } @@ -1468,8 +1575,8 @@ LDAP__connect(krb5_context context, HDB * db) rc = ldap_sasl_bind_s(HDB2LDAP(db), NULL, "EXTERNAL", &bv, NULL, NULL, NULL); if (rc != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_sasl_bind_s: %s", - ldap_err2string(rc)); + krb5_set_error_message(context, HDB_ERR_BADVERSION, + "ldap_sasl_bind_s: %s", ldap_err2string(rc)); LDAP_close(context, db); return HDB_ERR_BADVERSION; } @@ -1497,8 +1604,8 @@ LDAP_open(krb5_context context, HDB * db, int flags, mode_t mode) } static krb5_error_code -LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, - unsigned flags, hdb_entry_ex * entry) +LDAP_fetch_kvno(krb5_context context, HDB * db, krb5_const_principal principal, + unsigned flags, krb5_kvno kvno, hdb_entry_ex * entry) { LDAPMessage *msg, *e; krb5_error_code ret; @@ -1513,7 +1620,7 @@ LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, goto out; } - ret = LDAP_message2entry(context, db, e, entry); + ret = LDAP_message2entry(context, db, e, flags, entry); if (ret == 0) { if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { ret = hdb_unseal_keys(context, db, &entry->entry); @@ -1529,6 +1636,14 @@ LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, } static krb5_error_code +LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, + unsigned flags, hdb_entry_ex * entry) +{ + return LDAP_fetch_kvno(context, db, principal, + flags & (~HDB_F_KVNO_SPECIFIED), 0, entry); +} + +static krb5_error_code LDAP_store(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) { @@ -1561,8 +1676,8 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, if (e == NULL) { ret = asprintf(&dn, "krb5PrincipalName=%s,%s", name, HDB2CREATE(db)); if (ret < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "asprintf: out of memory"); goto out; } } else if (flags & HDB_F_REPLACE) { @@ -1577,21 +1692,21 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, /* write entry into directory */ if (e == NULL) { /* didn't exist before */ - rc = ldap_add_s(HDB2LDAP(db), dn, mods); - errfn = "ldap_add_s"; + rc = ldap_add_ext_s(HDB2LDAP(db), dn, mods, NULL, NULL ); + errfn = "ldap_add_ext_s"; } else { /* already existed, send deltas only */ - rc = ldap_modify_s(HDB2LDAP(db), dn, mods); - errfn = "ldap_modify_s"; + rc = ldap_modify_ext_s(HDB2LDAP(db), dn, mods, NULL, NULL ); + errfn = "ldap_modify_ext_s"; } if (check_ldap(context, db, rc)) { char *ld_error = NULL; ldap_get_option(HDB2LDAP(db), LDAP_OPT_ERROR_STRING, &ld_error); - krb5_set_error_string(context, "%s: %s (DN=%s) %s: %s", - errfn, name, dn, ldap_err2string(rc), ld_error); ret = HDB_ERR_CANT_LOCK_DB; + krb5_set_error_message(context, ret, "%s: %s (DN=%s) %s: %s", + errfn, name, dn, ldap_err2string(rc), ld_error); } else ret = 0; @@ -1635,17 +1750,17 @@ LDAP_remove(krb5_context context, HDB *db, krb5_const_principal principal) rc = ldap_set_option(HDB2LDAP(db), LDAP_OPT_SIZELIMIT, (const void *)&limit); if (rc != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_set_option: %s", - ldap_err2string(rc)); ret = HDB_ERR_BADVERSION; + krb5_set_error_message(context, ret, "ldap_set_option: %s", + ldap_err2string(rc)); goto out; } - rc = ldap_delete_s(HDB2LDAP(db), dn); + rc = ldap_delete_ext_s(HDB2LDAP(db), dn, NULL, NULL ); if (check_ldap(context, db, rc)) { - krb5_set_error_string(context, "ldap_delete_s: %s", - ldap_err2string(rc)); ret = HDB_ERR_CANT_LOCK_DB; + krb5_set_error_message(context, ret, "ldap_delete_ext_s: %s", + ldap_err2string(rc)); } else ret = 0; @@ -1680,7 +1795,7 @@ LDAP_destroy(krb5_context context, HDB * db) return ret; } -krb5_error_code +static krb5_error_code hdb_ldap_common(krb5_context context, HDB ** db, const char *search_base, @@ -1690,40 +1805,40 @@ hdb_ldap_common(krb5_context context, const char *create_base = NULL; if (search_base == NULL && search_base[0] == '\0') { - krb5_set_error_string(context, "ldap search base not configured"); + krb5_set_error_message(context, ENOMEM, "ldap search base not configured"); return ENOMEM; /* XXX */ } if (structural_object == NULL) { const char *p; - p = krb5_config_get_string(context, NULL, "kdc", + p = krb5_config_get_string(context, NULL, "kdc", "hdb-ldap-structural-object", NULL); if (p == NULL) p = default_structural_object; structural_object = strdup(p); if (structural_object == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } - samba_forwardable = + samba_forwardable = krb5_config_get_bool_default(context, NULL, TRUE, "kdc", "hdb-samba-forwardable", NULL); *db = calloc(1, sizeof(**db)); if (*db == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memset(*db, 0, sizeof(**db)); h = calloc(1, sizeof(*h)); if (h == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); free(*db); *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_db = h; @@ -1731,8 +1846,8 @@ hdb_ldap_common(krb5_context context, /* XXX */ if (asprintf(&(*db)->hdb_name, "ldap:%s", search_base) == -1) { LDAP_destroy(context, *db); - krb5_set_error_string(context, "strdup: out of memory"); *db = NULL; + krb5_set_error_message(context, ENOMEM, "strdup: out of memory"); return ENOMEM; } @@ -1740,12 +1855,12 @@ hdb_ldap_common(krb5_context context, h->h_base = strdup(search_base); if (h->h_url == NULL || h->h_base == NULL) { LDAP_destroy(context, *db); - krb5_set_error_string(context, "strdup: out of memory"); *db = NULL; + krb5_set_error_message(context, ENOMEM, "strdup: out of memory"); return ENOMEM; } - create_base = krb5_config_get_string(context, NULL, "kdc", + create_base = krb5_config_get_string(context, NULL, "kdc", "hdb-ldap-create-base", NULL); if (create_base == NULL) create_base = h->h_base; @@ -1753,16 +1868,17 @@ hdb_ldap_common(krb5_context context, h->h_createbase = strdup(create_base); if (h->h_createbase == NULL) { LDAP_destroy(context, *db); - krb5_set_error_string(context, "strdup: out of memory"); *db = NULL; + krb5_set_error_message(context, ENOMEM, "strdup: out of memory"); return ENOMEM; } (*db)->hdb_master_key_set = 0; (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = 0; (*db)->hdb_open = LDAP_open; (*db)->hdb_close = LDAP_close; - (*db)->hdb_fetch = LDAP_fetch; + (*db)->hdb_fetch_kvno = LDAP_fetch_kvno; (*db)->hdb_store = LDAP_store; (*db)->hdb_remove = LDAP_remove; (*db)->hdb_firstkey = LDAP_firstkey; @@ -1792,14 +1908,15 @@ hdb_ldapi_create(krb5_context context, HDB ** db, const char *arg) asprintf(&p, "ldapi:%s", arg); if (p == NULL) { - krb5_set_error_string(context, "out of memory"); *db = NULL; + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } search_base = strchr(p + strlen("ldapi://"), ':'); if (search_base == NULL) { - krb5_set_error_string(context, "search base missing"); *db = NULL; + krb5_set_error_message(context, HDB_ERR_BADVERSION, + "search base missing"); return HDB_ERR_BADVERSION; } *search_base = '\0'; diff --git a/crypto/heimdal/lib/hdb/hdb-mitdb.c b/crypto/heimdal/lib/hdb/hdb-mitdb.c new file mode 100644 index 0000000..cd619b3 --- /dev/null +++ b/crypto/heimdal/lib/hdb/hdb-mitdb.c @@ -0,0 +1,818 @@ +/* + * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 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. + */ + +#define KRB5_KDB_DISALLOW_POSTDATED 0x00000001 +#define KRB5_KDB_DISALLOW_FORWARDABLE 0x00000002 +#define KRB5_KDB_DISALLOW_TGT_BASED 0x00000004 +#define KRB5_KDB_DISALLOW_RENEWABLE 0x00000008 +#define KRB5_KDB_DISALLOW_PROXIABLE 0x00000010 +#define KRB5_KDB_DISALLOW_DUP_SKEY 0x00000020 +#define KRB5_KDB_DISALLOW_ALL_TIX 0x00000040 +#define KRB5_KDB_REQUIRES_PRE_AUTH 0x00000080 +#define KRB5_KDB_REQUIRES_HW_AUTH 0x00000100 +#define KRB5_KDB_REQUIRES_PWCHANGE 0x00000200 +#define KRB5_KDB_DISALLOW_SVR 0x00001000 +#define KRB5_KDB_PWCHANGE_SERVICE 0x00002000 +#define KRB5_KDB_SUPPORT_DESMD5 0x00004000 +#define KRB5_KDB_NEW_PRINC 0x00008000 + +/* + +key: krb5_unparse_name + NUL + + 16: baselength + 32: attributes + 32: max time + 32: max renewable time + 32: client expire + 32: passwd expire + 32: last successful passwd + 32: last failed attempt + 32: num of failed attempts + 16: num tl data + 16: num data data + 16: principal length + length: principal + for num tl data times + 16: tl data type + 16: tl data length + length: length + for num key data times + 16: version (num keyblocks) + 16: kvno + for version times: + 16: type + 16: length + length: keydata + + +key_data_contents[0] + + int16: length + read-of-data: key-encrypted, key-usage 0, master-key + +salt: + version2 = salt in key_data->key_data_contents[1] + else default salt. + +*/ + +#include "hdb_locl.h" + +#define KDB_V1_BASE_LENGTH 38 + +#if HAVE_DB1 + +#if defined(HAVE_DB_185_H) +#include <db_185.h> +#elif defined(HAVE_DB_H) +#include <db.h> +#endif + +#define CHECK(x) do { if ((x)) goto out; } while(0) + +static krb5_error_code +mdb_principal2key(krb5_context context, + krb5_const_principal principal, + krb5_data *key) +{ + krb5_error_code ret; + char *str; + + ret = krb5_unparse_name(context, principal, &str); + if (ret) + return ret; + key->data = str; + key->length = strlen(str) + 1; + return 0; +} + +#define KRB5_KDB_SALTTYPE_NORMAL 0 +#define KRB5_KDB_SALTTYPE_V4 1 +#define KRB5_KDB_SALTTYPE_NOREALM 2 +#define KRB5_KDB_SALTTYPE_ONLYREALM 3 +#define KRB5_KDB_SALTTYPE_SPECIAL 4 +#define KRB5_KDB_SALTTYPE_AFS3 5 +#define KRB5_KDB_SALTTYPE_CERTHASH 6 + +static krb5_error_code +fix_salt(krb5_context context, hdb_entry *ent, int key_num) +{ + krb5_error_code ret; + Salt *salt = ent->keys.val[key_num].salt; + /* fix salt type */ + switch((int)salt->type) { + case KRB5_KDB_SALTTYPE_NORMAL: + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_V4: + krb5_data_free(&salt->salt); + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_NOREALM: + { + size_t len; + size_t i; + char *p; + + len = 0; + for (i = 0; i < ent->principal->name.name_string.len; ++i) + len += strlen(ent->principal->name.name_string.val[i]); + ret = krb5_data_alloc (&salt->salt, len); + if (ret) + return ret; + p = salt->salt.data; + for (i = 0; i < ent->principal->name.name_string.len; ++i) { + memcpy (p, + ent->principal->name.name_string.val[i], + strlen(ent->principal->name.name_string.val[i])); + p += strlen(ent->principal->name.name_string.val[i]); + } + + salt->type = KRB5_PADATA_PW_SALT; + break; + } + case KRB5_KDB_SALTTYPE_ONLYREALM: + krb5_data_free(&salt->salt); + ret = krb5_data_copy(&salt->salt, + ent->principal->realm, + strlen(ent->principal->realm)); + if(ret) + return ret; + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_SPECIAL: + salt->type = KRB5_PADATA_PW_SALT; + break; + case KRB5_KDB_SALTTYPE_AFS3: + krb5_data_free(&salt->salt); + ret = krb5_data_copy(&salt->salt, + ent->principal->realm, + strlen(ent->principal->realm)); + if(ret) + return ret; + salt->type = KRB5_PADATA_AFS3_SALT; + break; + case KRB5_KDB_SALTTYPE_CERTHASH: + krb5_data_free(&salt->salt); + free(ent->keys.val[key_num].salt); + ent->keys.val[key_num].salt = NULL; + break; + default: + abort(); + } + return 0; +} + + +static krb5_error_code +mdb_value2entry(krb5_context context, krb5_data *data, krb5_kvno kvno, hdb_entry *entry) +{ + krb5_error_code ret; + krb5_storage *sp; + uint32_t u32; + uint16_t u16, num_keys, num_tl; + size_t i, j; + char *p; + + sp = krb5_storage_from_data(data); + if (sp == NULL) { + krb5_set_error_message(context, ENOMEM, "out of memory"); + return ENOMEM; + } + + krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE); + + /* + * 16: baselength + * + * The story here is that these 16 bits have to be a constant: + * KDB_V1_BASE_LENGTH. Once upon a time a different value here + * would have been used to indicate the presence of "extra data" + * between the "base" contents and the {principal name, TL data, + * keys} that follow it. Nothing supports such "extra data" + * nowadays, so neither do we here. + * + * XXX But... surely we ought to log about this extra data, or skip + * it, or something, in case anyone has MIT KDBs with ancient + * entries in them... Logging would allow the admin to know which + * entries to dump with MIT krb5's kdb5_util. + */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + if (u16 != KDB_V1_BASE_LENGTH) { ret = EINVAL; goto out; } + /* 32: attributes */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + entry->flags.postdate = !(u32 & KRB5_KDB_DISALLOW_POSTDATED); + entry->flags.forwardable = !(u32 & KRB5_KDB_DISALLOW_FORWARDABLE); + entry->flags.initial = !!(u32 & KRB5_KDB_DISALLOW_TGT_BASED); + entry->flags.renewable = !(u32 & KRB5_KDB_DISALLOW_RENEWABLE); + entry->flags.proxiable = !(u32 & KRB5_KDB_DISALLOW_PROXIABLE); + /* DUP_SKEY */ + entry->flags.invalid = !!(u32 & KRB5_KDB_DISALLOW_ALL_TIX); + entry->flags.require_preauth =!!(u32 & KRB5_KDB_REQUIRES_PRE_AUTH); + entry->flags.require_hwauth =!!(u32 & KRB5_KDB_REQUIRES_HW_AUTH); + entry->flags.server = !(u32 & KRB5_KDB_DISALLOW_SVR); + entry->flags.change_pw = !!(u32 & KRB5_KDB_PWCHANGE_SERVICE); + entry->flags.client = 1; /* XXX */ + + /* 32: max time */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + if (u32) { + entry->max_life = malloc(sizeof(*entry->max_life)); + *entry->max_life = u32; + } + /* 32: max renewable time */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + if (u32) { + entry->max_renew = malloc(sizeof(*entry->max_renew)); + *entry->max_renew = u32; + } + /* 32: client expire */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + if (u32) { + entry->valid_end = malloc(sizeof(*entry->valid_end)); + *entry->valid_end = u32; + } + /* 32: passwd expire */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + if (u32) { + entry->pw_end = malloc(sizeof(*entry->pw_end)); + *entry->pw_end = u32; + } + /* 32: last successful passwd */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + /* 32: last failed attempt */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + /* 32: num of failed attempts */ + CHECK(ret = krb5_ret_uint32(sp, &u32)); + /* 16: num tl data */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + num_tl = u16; + /* 16: num key data */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + num_keys = u16; + /* 16: principal length */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + /* length: principal */ + { + /* + * Note that the principal name includes the NUL in the entry, + * but we don't want to take chances, so we add an extra NUL. + */ + p = malloc(u16 + 1); + if (p == NULL) { + ret = ENOMEM; + goto out; + } + krb5_storage_read(sp, p, u16); + p[u16] = '\0'; + CHECK(ret = krb5_parse_name(context, p, &entry->principal)); + free(p); + } + /* for num tl data times + 16: tl data type + 16: tl data length + length: length */ + for (i = 0; i < num_tl; i++) { + /* 16: TL data type */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + /* 16: TL data length */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + krb5_storage_seek(sp, u16, SEEK_CUR); + } + /* + * for num key data times + * 16: "version" + * 16: kvno + * for version times: + * 16: type + * 16: length + * length: keydata + * + * "version" here is really 1 or 2, the first meaning there's only + * keys for this kvno, the second meaning there's keys and salt[s?]. + * That's right... hold that gag reflex, you can do it. + */ + for (i = 0; i < num_keys; i++) { + int keep = 0; + uint16_t version; + void *ptr; + + CHECK(ret = krb5_ret_uint16(sp, &u16)); + version = u16; + CHECK(ret = krb5_ret_uint16(sp, &u16)); + + /* + * First time through, and until we find one matching key, + * entry->kvno == 0. + */ + if ((entry->kvno < u16) && (kvno == 0 || kvno == u16)) { + keep = 1; + entry->kvno = u16; + /* + * Found a higher kvno than earlier, so free the old highest + * kvno keys. + * + * XXX Of course, we actually want to extract the old kvnos + * as well, for some of the kadm5 APIs. We shouldn't free + * these keys, but keep them elsewhere. + */ + for (j = 0; j < entry->keys.len; j++) + free_Key(&entry->keys.val[j]); + free(entry->keys.val); + entry->keys.len = 0; + entry->keys.val = NULL; + } else if (entry->kvno == u16) + /* Accumulate keys */ + keep = 1; + + if (keep) { + Key *k; + + ptr = realloc(entry->keys.val, sizeof(entry->keys.val[0]) * (entry->keys.len + 1)); + if (ptr == NULL) { + ret = ENOMEM; + goto out; + } + entry->keys.val = ptr; + + /* k points to current Key */ + k = &entry->keys.val[entry->keys.len]; + + memset(k, 0, sizeof(*k)); + entry->keys.len += 1; + + k->mkvno = malloc(sizeof(*k->mkvno)); + if (k->mkvno == NULL) { + ret = ENOMEM; + goto out; + } + *k->mkvno = 1; + + for (j = 0; j < version; j++) { + uint16_t type; + CHECK(ret = krb5_ret_uint16(sp, &type)); + CHECK(ret = krb5_ret_uint16(sp, &u16)); + if (j == 0) { + /* This "version" means we have a key */ + k->key.keytype = type; + if (u16 < 2) { + ret = EINVAL; + goto out; + } + /* + * MIT stores keys encrypted keys as {16-bit length + * of plaintext key, {encrypted key}}. The reason + * for this is that the Kerberos cryptosystem is not + * length-preserving. Heimdal's approach is to + * truncate the plaintext to the expected length of + * the key given its enctype, so we ignore this + * 16-bit length-of-plaintext-key field. + */ + krb5_storage_seek(sp, 2, SEEK_CUR); /* skip real length */ + k->key.keyvalue.length = u16 - 2; /* adjust cipher len */ + k->key.keyvalue.data = malloc(k->key.keyvalue.length); + krb5_storage_read(sp, k->key.keyvalue.data, + k->key.keyvalue.length); + } else if (j == 1) { + /* This "version" means we have a salt */ + k->salt = calloc(1, sizeof(*k->salt)); + if (k->salt == NULL) { + ret = ENOMEM; + goto out; + } + k->salt->type = type; + if (u16 != 0) { + k->salt->salt.data = malloc(u16); + if (k->salt->salt.data == NULL) { + ret = ENOMEM; + goto out; + } + k->salt->salt.length = u16; + krb5_storage_read(sp, k->salt->salt.data, k->salt->salt.length); + } + fix_salt(context, entry, entry->keys.len - 1); + } else { + /* + * Whatever this "version" might be, we skip it + * + * XXX A krb5.conf parameter requesting that we log + * about strangeness like this, or return an error + * from here, might be nice. + */ + krb5_storage_seek(sp, u16, SEEK_CUR); + } + } + } else { + /* + * XXX For now we skip older kvnos, but we should extract + * them... + */ + for (j = 0; j < version; j++) { + /* enctype */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + /* encrypted key (or plaintext salt) */ + CHECK(ret = krb5_ret_uint16(sp, &u16)); + krb5_storage_seek(sp, u16, SEEK_CUR); + } + } + } + + if (entry->kvno == 0 && kvno != 0) { + ret = HDB_ERR_NOT_FOUND_HERE; + goto out; + } + + return 0; + out: + if (ret == HEIM_ERR_EOF) + /* Better error code than "end of file" */ + ret = HEIM_ERR_BAD_HDBENT_ENCODING; + return ret; +} + +#if 0 +static krb5_error_code +mdb_entry2value(krb5_context context, hdb_entry *entry, krb5_data *data) +{ + return EINVAL; +} +#endif + + +static krb5_error_code +mdb_close(krb5_context context, HDB *db) +{ + DB *d = (DB*)db->hdb_db; + (*d->close)(d); + return 0; +} + +static krb5_error_code +mdb_destroy(krb5_context context, HDB *db) +{ + krb5_error_code ret; + + ret = hdb_clear_master_key (context, db); + free(db->hdb_name); + free(db); + return ret; +} + +static krb5_error_code +mdb_lock(krb5_context context, HDB *db, int operation) +{ + DB *d = (DB*)db->hdb_db; + int fd = (*d->fd)(d); + if(fd < 0) { + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "Can't lock database: %s", db->hdb_name); + return HDB_ERR_CANT_LOCK_DB; + } + return hdb_lock(fd, operation); +} + +static krb5_error_code +mdb_unlock(krb5_context context, HDB *db) +{ + DB *d = (DB*)db->hdb_db; + int fd = (*d->fd)(d); + if(fd < 0) { + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "Can't unlock database: %s", db->hdb_name); + return HDB_ERR_CANT_LOCK_DB; + } + return hdb_unlock(fd); +} + + +static krb5_error_code +mdb_seq(krb5_context context, HDB *db, + unsigned flags, hdb_entry_ex *entry, int flag) +{ + DB *d = (DB*)db->hdb_db; + DBT key, value; + krb5_data key_data, data; + int code; + + code = db->hdb_lock(context, db, HDB_RLOCK); + if(code == -1) { + krb5_set_error_message(context, HDB_ERR_DB_INUSE, "Database %s in use", db->hdb_name); + return HDB_ERR_DB_INUSE; + } + code = (*d->seq)(d, &key, &value, flag); + db->hdb_unlock(context, db); /* XXX check value */ + if(code == -1) { + code = errno; + krb5_set_error_message(context, code, "Database %s seq error: %s", + db->hdb_name, strerror(code)); + return code; + } + if(code == 1) { + krb5_clear_error_message(context); + return HDB_ERR_NOENTRY; + } + + key_data.data = key.data; + key_data.length = key.size; + data.data = value.data; + data.length = value.size; + memset(entry, 0, sizeof(*entry)); + + if (mdb_value2entry(context, &data, 0, &entry->entry)) + return mdb_seq(context, db, flags, entry, R_NEXT); + + if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { + code = hdb_unseal_keys (context, db, &entry->entry); + if (code) + hdb_free_entry (context, entry); + } + + return code; +} + + +static krb5_error_code +mdb_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +{ + return mdb_seq(context, db, flags, entry, R_FIRST); +} + + +static krb5_error_code +mdb_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +{ + return mdb_seq(context, db, flags, entry, R_NEXT); +} + +static krb5_error_code +mdb_rename(krb5_context context, HDB *db, const char *new_name) +{ + int ret; + char *old, *new; + + asprintf(&old, "%s.db", db->hdb_name); + asprintf(&new, "%s.db", new_name); + ret = rename(old, new); + free(old); + free(new); + if(ret) + return errno; + + free(db->hdb_name); + db->hdb_name = strdup(new_name); + return 0; +} + +static krb5_error_code +mdb__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) +{ + DB *d = (DB*)db->hdb_db; + DBT k, v; + int code; + + k.data = key.data; + k.size = key.length; + code = db->hdb_lock(context, db, HDB_RLOCK); + if(code) + return code; + code = (*d->get)(d, &k, &v, 0); + db->hdb_unlock(context, db); + if(code < 0) { + code = errno; + krb5_set_error_message(context, code, "Database %s get error: %s", + db->hdb_name, strerror(code)); + return code; + } + if(code == 1) { + krb5_clear_error_message(context); + return HDB_ERR_NOENTRY; + } + + krb5_data_copy(reply, v.data, v.size); + return 0; +} + +static krb5_error_code +mdb__put(krb5_context context, HDB *db, int replace, + krb5_data key, krb5_data value) +{ + DB *d = (DB*)db->hdb_db; + DBT k, v; + int code; + + k.data = key.data; + k.size = key.length; + v.data = value.data; + v.size = value.length; + code = db->hdb_lock(context, db, HDB_WLOCK); + if(code) + return code; + code = (*d->put)(d, &k, &v, replace ? 0 : R_NOOVERWRITE); + db->hdb_unlock(context, db); + if(code < 0) { + code = errno; + krb5_set_error_message(context, code, "Database %s put error: %s", + db->hdb_name, strerror(code)); + return code; + } + if(code == 1) { + krb5_clear_error_message(context); + return HDB_ERR_EXISTS; + } + return 0; +} + +static krb5_error_code +mdb__del(krb5_context context, HDB *db, krb5_data key) +{ + DB *d = (DB*)db->hdb_db; + DBT k; + krb5_error_code code; + k.data = key.data; + k.size = key.length; + code = db->hdb_lock(context, db, HDB_WLOCK); + if(code) + return code; + code = (*d->del)(d, &k, 0); + db->hdb_unlock(context, db); + if(code == 1) { + code = errno; + krb5_set_error_message(context, code, "Database %s put error: %s", + db->hdb_name, strerror(code)); + return code; + } + if(code < 0) + return errno; + return 0; +} + +static krb5_error_code +mdb_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, + unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry) +{ + krb5_data key, value; + krb5_error_code code; + + code = mdb_principal2key(context, principal, &key); + if (code) + return code; + code = db->hdb__get(context, db, key, &value); + krb5_data_free(&key); + if(code) + return code; + code = mdb_value2entry(context, &value, kvno, &entry->entry); + krb5_data_free(&value); + if (code) + return code; + + if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { + code = hdb_unseal_keys (context, db, &entry->entry); + if (code) + hdb_free_entry(context, entry); + } + + return 0; +} + +static krb5_error_code +mdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) +{ + krb5_set_error_message(context, EINVAL, "can't set principal in mdb"); + return EINVAL; +} + +static krb5_error_code +mdb_remove(krb5_context context, HDB *db, krb5_const_principal principal) +{ + krb5_error_code code; + krb5_data key; + + mdb_principal2key(context, principal, &key); + code = db->hdb__del(context, db, key); + krb5_data_free(&key); + return code; +} + +static krb5_error_code +mdb_open(krb5_context context, HDB *db, int flags, mode_t mode) +{ + char *fn; + krb5_error_code ret; + + asprintf(&fn, "%s.db", db->hdb_name); + if (fn == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + db->hdb_db = dbopen(fn, flags, mode, DB_BTREE, NULL); + free(fn); + + if (db->hdb_db == NULL) { + switch (errno) { +#ifdef EFTYPE + case EFTYPE: +#endif + case EINVAL: + db->hdb_db = dbopen(fn, flags, mode, DB_BTREE, NULL); + } + } + + /* try to open without .db extension */ + if(db->hdb_db == NULL && errno == ENOENT) + db->hdb_db = dbopen(db->hdb_name, flags, mode, DB_BTREE, NULL); + if(db->hdb_db == NULL) { + ret = errno; + krb5_set_error_message(context, ret, "dbopen (%s): %s", + db->hdb_name, strerror(ret)); + return ret; + } + if((flags & O_ACCMODE) == O_RDONLY) + ret = hdb_check_db_format(context, db); + else + ret = hdb_init_db(context, db); + if(ret == HDB_ERR_NOENTRY) { + krb5_clear_error_message(context); + return 0; + } + if (ret) { + mdb_close(context, db); + krb5_set_error_message(context, ret, "hdb_open: failed %s database %s", + (flags & O_ACCMODE) == O_RDONLY ? + "checking format of" : "initialize", + db->hdb_name); + } + return ret; +} + +krb5_error_code +hdb_mdb_create(krb5_context context, HDB **db, + const char *filename) +{ + *db = calloc(1, sizeof(**db)); + if (*db == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + (*db)->hdb_db = NULL; + (*db)->hdb_name = strdup(filename); + if ((*db)->hdb_name == NULL) { + free(*db); + *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + (*db)->hdb_master_key_set = 0; + (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = 0; + (*db)->hdb_open = mdb_open; + (*db)->hdb_close = mdb_close; + (*db)->hdb_fetch_kvno = mdb_fetch_kvno; + (*db)->hdb_store = mdb_store; + (*db)->hdb_remove = mdb_remove; + (*db)->hdb_firstkey = mdb_firstkey; + (*db)->hdb_nextkey= mdb_nextkey; + (*db)->hdb_lock = mdb_lock; + (*db)->hdb_unlock = mdb_unlock; + (*db)->hdb_rename = mdb_rename; + (*db)->hdb__get = mdb__get; + (*db)->hdb__put = mdb__put; + (*db)->hdb__del = mdb__del; + (*db)->hdb_destroy = mdb_destroy; + return 0; +} + +#endif /* HAVE_DB1 */ diff --git a/crypto/heimdal/lib/hdb/hdb-private.h b/crypto/heimdal/lib/hdb/hdb-private.h index 5147d8b..8a74869 100644 --- a/crypto/heimdal/lib/hdb/hdb-private.h +++ b/crypto/heimdal/lib/hdb/hdb-private.h @@ -5,11 +5,12 @@ #include <stdarg.h> krb5_error_code -_hdb_fetch ( +_hdb_fetch_kvno ( krb5_context /*context*/, HDB */*db*/, krb5_const_principal /*principal*/, unsigned /*flags*/, + krb5_kvno /*kvno*/, hdb_entry_ex */*entry*/); hdb_master_key @@ -17,6 +18,12 @@ _hdb_find_master_key ( uint32_t */*mkvno*/, hdb_master_key /*mkey*/); +krb5_error_code +_hdb_keytab2hdb_entry ( + krb5_context /*context*/, + const krb5_keytab_entry */*ktentry*/, + hdb_entry_ex */*entry*/); + int _hdb_mkey_decrypt ( krb5_context /*context*/, diff --git a/crypto/heimdal/lib/hdb/hdb-protos.h b/crypto/heimdal/lib/hdb/hdb-protos.h index 4c3d3eb..44a1bdd 100644 --- a/crypto/heimdal/lib/hdb/hdb-protos.h +++ b/crypto/heimdal/lib/hdb/hdb-protos.h @@ -146,6 +146,11 @@ hdb_entry_get_pkinit_acl ( const HDB_Ext_PKINIT_acl **/*a*/); krb5_error_code +hdb_entry_get_pkinit_cert ( + const hdb_entry */*entry*/, + const HDB_Ext_PKINIT_cert **/*a*/); + +krb5_error_code hdb_entry_get_pkinit_hash ( const hdb_entry */*entry*/, const HDB_Ext_PKINIT_hash **/*a*/); @@ -238,11 +243,10 @@ hdb_key2principal ( krb5_principal /*p*/); krb5_error_code -hdb_ldap_common ( +hdb_keytab_create ( krb5_context /*context*/, HDB ** /*db*/, - const char */*search_base*/, - const char */*url*/); + const char */*arg*/); krb5_error_code hdb_ldap_create ( @@ -267,6 +271,12 @@ hdb_lock ( int /*operation*/); krb5_error_code +hdb_mdb_create ( + krb5_context /*context*/, + HDB **/*db*/, + const char */*filename*/); + +krb5_error_code hdb_ndbm_create ( krb5_context /*context*/, HDB **/*db*/, @@ -349,6 +359,12 @@ hdb_set_master_keyfile ( const char */*keyfile*/); krb5_error_code +hdb_sqlite_create ( + krb5_context /*context*/, + HDB **/*db*/, + const char */*argument*/); + +krb5_error_code hdb_unlock (int /*fd*/); krb5_error_code diff --git a/crypto/heimdal/lib/hdb/hdb-sqlite.c b/crypto/heimdal/lib/hdb/hdb-sqlite.c new file mode 100644 index 0000000..e0635888 --- /dev/null +++ b/crypto/heimdal/lib/hdb/hdb-sqlite.c @@ -0,0 +1,879 @@ +/* + * Copyright (c) 2009 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 "hdb_locl.h" +#include "sqlite3.h" + +#define MAX_RETRIES 10 + +typedef struct hdb_sqlite_db { + double version; + sqlite3 *db; + char *db_file; + + sqlite3_stmt *get_version; + sqlite3_stmt *fetch; + sqlite3_stmt *get_ids; + sqlite3_stmt *add_entry; + sqlite3_stmt *add_principal; + sqlite3_stmt *add_alias; + sqlite3_stmt *delete_aliases; + sqlite3_stmt *update_entry; + sqlite3_stmt *remove; + sqlite3_stmt *get_all_entries; + +} hdb_sqlite_db; + +/* This should be used to mark updates which make the code incompatible + * with databases created with previous versions. Don't update it if + * compatibility is not broken. */ +#define HDBSQLITE_VERSION 0.1 + +#define _HDBSQLITE_STRINGIFY(x) #x +#define HDBSQLITE_STRINGIFY(x) _HDBSQLITE_STRINGIFY(x) + +#define HDBSQLITE_CREATE_TABLES \ + " BEGIN TRANSACTION;" \ + " CREATE TABLE Version (number REAL);" \ + " INSERT INTO Version (number)" \ + " VALUES (" HDBSQLITE_STRINGIFY(HDBSQLITE_VERSION) ");" \ + " CREATE TABLE Principal" \ + " (id INTEGER PRIMARY KEY," \ + " principal TEXT UNIQUE NOT NULL," \ + " canonical INTEGER," \ + " entry INTEGER);" \ + " CREATE TABLE Entry" \ + " (id INTEGER PRIMARY KEY," \ + " data BLOB);" \ + " COMMIT" +#define HDBSQLITE_CREATE_TRIGGERS \ + " CREATE TRIGGER remove_principals AFTER DELETE ON Entry" \ + " BEGIN" \ + " DELETE FROM Principal" \ + " WHERE entry = OLD.id;" \ + " END" +#define HDBSQLITE_GET_VERSION \ + " SELECT number FROM Version" +#define HDBSQLITE_FETCH \ + " SELECT Entry.data FROM Principal, Entry" \ + " WHERE Principal.principal = ? AND" \ + " Entry.id = Principal.entry" +#define HDBSQLITE_GET_IDS \ + " SELECT id, entry FROM Principal" \ + " WHERE principal = ?" +#define HDBSQLITE_ADD_ENTRY \ + " INSERT INTO Entry (data) VALUES (?)" +#define HDBSQLITE_ADD_PRINCIPAL \ + " INSERT INTO Principal (principal, entry, canonical)" \ + " VALUES (?, last_insert_rowid(), 1)" +#define HDBSQLITE_ADD_ALIAS \ + " INSERT INTO Principal (principal, entry, canonical)" \ + " VALUES(?, ?, 0)" +#define HDBSQLITE_DELETE_ALIASES \ + " DELETE FROM Principal" \ + " WHERE entry = ? AND canonical = 0" +#define HDBSQLITE_UPDATE_ENTRY \ + " UPDATE Entry SET data = ?" \ + " WHERE id = ?" +#define HDBSQLITE_REMOVE \ + " DELETE FROM ENTRY WHERE id = " \ + " (SELECT entry FROM Principal" \ + " WHERE principal = ?)" +#define HDBSQLITE_GET_ALL_ENTRIES \ + " SELECT data FROM Entry" + +/** + * Wrapper around sqlite3_prepare_v2. + * + * @param context The current krb5 context + * @param statement Where to store the pointer to the statement + * after preparing it + * @param str SQL code for the statement + * + * @return 0 if OK, an error code if not + */ +static krb5_error_code +hdb_sqlite_prepare_stmt(krb5_context context, + sqlite3 *db, + sqlite3_stmt **statement, + const char *str) +{ + int ret, tries = 0; + + ret = sqlite3_prepare_v2(db, str, -1, statement, NULL); + while((tries++ < MAX_RETRIES) && + ((ret == SQLITE_BUSY) || + (ret == SQLITE_IOERR_BLOCKED) || + (ret == SQLITE_LOCKED))) { + krb5_warnx(context, "hdb-sqlite: prepare busy"); + sleep(1); + ret = sqlite3_prepare_v2(db, str, -1, statement, NULL); + } + + if (ret != SQLITE_OK) { + krb5_set_error_message(context, EINVAL, + "Failed to prepare stmt %s: %s", + str, sqlite3_errmsg(db)); + return EINVAL; + } + + return 0; +} + +/** + * A wrapper around sqlite3_exec. + * + * @param context The current krb5 context + * @param database An open sqlite3 database handle + * @param statement SQL code to execute + * @param error_code What to return if the statement fails + * + * @return 0 if OK, else error_code + */ +static krb5_error_code +hdb_sqlite_exec_stmt(krb5_context context, + sqlite3 *database, + const char *statement, + krb5_error_code error_code) +{ + int ret; + + ret = sqlite3_exec(database, statement, NULL, NULL, NULL); + + while(((ret == SQLITE_BUSY) || + (ret == SQLITE_IOERR_BLOCKED) || + (ret == SQLITE_LOCKED))) { + krb5_warnx(context, "hdb-sqlite: exec busy: %d", (int)getpid()); + sleep(1); + ret = sqlite3_exec(database, statement, NULL, NULL, NULL); + } + + if (ret != SQLITE_OK && error_code) { + krb5_set_error_message(context, error_code, + "Execute %s: %s", statement, + sqlite3_errmsg(database)); + return error_code; + } + + return 0; +} + +/** + * Opens an sqlite3 database handle to a file, may create the + * database file depending on flags. + * + * @param context The current krb5 context + * @param db Heimdal database handle + * @param flags Controls whether or not the file may be created, + * may be 0 or SQLITE_OPEN_CREATE + */ +static krb5_error_code +hdb_sqlite_open_database(krb5_context context, HDB *db, int flags) +{ + int ret; + hdb_sqlite_db *hsdb = (hdb_sqlite_db*) db->hdb_db; + + ret = sqlite3_open_v2(hsdb->db_file, &hsdb->db, + SQLITE_OPEN_READWRITE | flags, NULL); + + if (ret) { + if (hsdb->db) { + ret = ENOENT; + krb5_set_error_message(context, ret, + "Error opening sqlite database %s: %s", + hsdb->db_file, sqlite3_errmsg(hsdb->db)); + sqlite3_close(hsdb->db); + hsdb->db = NULL; + } else + ret = krb5_enomem(context); + return ret; + } + + return 0; +} + +static int +hdb_sqlite_step(krb5_context context, sqlite3 *db, sqlite3_stmt *stmt) +{ + int ret; + + ret = sqlite3_step(stmt); + while(((ret == SQLITE_BUSY) || + (ret == SQLITE_IOERR_BLOCKED) || + (ret == SQLITE_LOCKED))) { + krb5_warnx(context, "hdb-sqlite: step busy: %d", (int)getpid()); + sleep(1); + ret = sqlite3_step(stmt); + } + return ret; +} + +/** + * Closes the database and frees memory allocated for statements. + * + * @param context The current krb5 context + * @param db Heimdal database handle + */ +static krb5_error_code +hdb_sqlite_close_database(krb5_context context, HDB *db) +{ + hdb_sqlite_db *hsdb = (hdb_sqlite_db *) db->hdb_db; + + sqlite3_finalize(hsdb->get_version); + sqlite3_finalize(hsdb->fetch); + sqlite3_finalize(hsdb->get_ids); + sqlite3_finalize(hsdb->add_entry); + sqlite3_finalize(hsdb->add_principal); + sqlite3_finalize(hsdb->add_alias); + sqlite3_finalize(hsdb->delete_aliases); + sqlite3_finalize(hsdb->update_entry); + sqlite3_finalize(hsdb->remove); + sqlite3_finalize(hsdb->get_all_entries); + + sqlite3_close(hsdb->db); + + return 0; +} + +/** + * Opens an sqlite database file and prepares it for use. + * If the file does not exist it will be created. + * + * @param context The current krb5_context + * @param db The heimdal database handle + * @param filename Where to store the database file + * + * @return 0 if everything worked, an error code if not + */ +static krb5_error_code +hdb_sqlite_make_database(krb5_context context, HDB *db, const char *filename) +{ + int ret; + int created_file = 0; + hdb_sqlite_db *hsdb = (hdb_sqlite_db *) db->hdb_db; + + hsdb->db_file = strdup(filename); + if(hsdb->db_file == NULL) + return ENOMEM; + + ret = hdb_sqlite_open_database(context, db, 0); + if (ret) { + ret = hdb_sqlite_open_database(context, db, SQLITE_OPEN_CREATE); + if (ret) goto out; + + created_file = 1; + + ret = hdb_sqlite_exec_stmt(context, hsdb->db, + HDBSQLITE_CREATE_TABLES, + EINVAL); + if (ret) goto out; + + ret = hdb_sqlite_exec_stmt(context, hsdb->db, + HDBSQLITE_CREATE_TRIGGERS, + EINVAL); + if (ret) goto out; + } + + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->get_version, + HDBSQLITE_GET_VERSION); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->fetch, + HDBSQLITE_FETCH); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->get_ids, + HDBSQLITE_GET_IDS); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->add_entry, + HDBSQLITE_ADD_ENTRY); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->add_principal, + HDBSQLITE_ADD_PRINCIPAL); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->add_alias, + HDBSQLITE_ADD_ALIAS); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->delete_aliases, + HDBSQLITE_DELETE_ALIASES); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->update_entry, + HDBSQLITE_UPDATE_ENTRY); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->remove, + HDBSQLITE_REMOVE); + if (ret) goto out; + ret = hdb_sqlite_prepare_stmt(context, hsdb->db, + &hsdb->get_all_entries, + HDBSQLITE_GET_ALL_ENTRIES); + if (ret) goto out; + + ret = hdb_sqlite_step(context, hsdb->db, hsdb->get_version); + if(ret == SQLITE_ROW) { + hsdb->version = sqlite3_column_double(hsdb->get_version, 0); + } + sqlite3_reset(hsdb->get_version); + ret = 0; + + if(hsdb->version != HDBSQLITE_VERSION) { + ret = EINVAL; + krb5_set_error_message(context, ret, "HDBSQLITE_VERSION mismatch"); + } + + if(ret) goto out; + + return 0; + + out: + if (hsdb->db) + sqlite3_close(hsdb->db); + if (created_file) + unlink(hsdb->db_file); + + return ret; +} + +/** + * Retrieves an entry by searching for the given + * principal in the Principal database table, both + * for canonical principals and aliases. + * + * @param context The current krb5_context + * @param db Heimdal database handle + * @param principal The principal whose entry to search for + * @param flags Currently only for HDB_F_DECRYPT + * @param kvno kvno to fetch is HDB_F_KVNO_SPECIFIED use used + * + * @return 0 if everything worked, an error code if not + */ +static krb5_error_code +hdb_sqlite_fetch_kvno(krb5_context context, HDB *db, krb5_const_principal principal, + unsigned flags, krb5_kvno kvno, hdb_entry_ex *entry) +{ + int sqlite_error; + krb5_error_code ret; + char *principal_string; + hdb_sqlite_db *hsdb = (hdb_sqlite_db*)(db->hdb_db); + sqlite3_stmt *fetch = hsdb->fetch; + krb5_data value; + + ret = krb5_unparse_name(context, principal, &principal_string); + if (ret) { + free(principal_string); + return ret; + } + + sqlite3_bind_text(fetch, 1, principal_string, -1, SQLITE_STATIC); + + sqlite_error = hdb_sqlite_step(context, hsdb->db, fetch); + if (sqlite_error != SQLITE_ROW) { + if(sqlite_error == SQLITE_DONE) { + ret = HDB_ERR_NOENTRY; + goto out; + } else { + ret = EINVAL; + krb5_set_error_message(context, ret, + "sqlite fetch failed: %d", + sqlite_error); + goto out; + } + } + + value.length = sqlite3_column_bytes(fetch, 0); + value.data = (void *) sqlite3_column_blob(fetch, 0); + + ret = hdb_value2entry(context, &value, &entry->entry); + if(ret) + goto out; + + if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { + ret = hdb_unseal_keys(context, db, &entry->entry); + if(ret) { + hdb_free_entry(context, entry); + goto out; + } + } + + ret = 0; + +out: + + sqlite3_clear_bindings(fetch); + sqlite3_reset(fetch); + + free(principal_string); + + return ret; +} + +/** + * Convenience function to step a prepared statement with no + * value once. + * + * @param context The current krb5_context + * @param statement A prepared sqlite3 statement + * + * @return 0 if everything worked, an error code if not + */ +static krb5_error_code +hdb_sqlite_step_once(krb5_context context, HDB *db, sqlite3_stmt *statement) +{ + int ret; + hdb_sqlite_db *hsdb = (hdb_sqlite_db *) db->hdb_db; + + ret = hdb_sqlite_step(context, hsdb->db, statement); + sqlite3_clear_bindings(statement); + sqlite3_reset(statement); + + return ret; +} + + +/** + * Stores an hdb_entry in the database. If flags contains HDB_F_REPLACE + * a previous entry may be replaced. + * + * @param context The current krb5_context + * @param db Heimdal database handle + * @param flags May currently only contain HDB_F_REPLACE + * @param entry The data to store + * + * @return 0 if everything worked, an error code if not + */ +static krb5_error_code +hdb_sqlite_store(krb5_context context, HDB *db, unsigned flags, + hdb_entry_ex *entry) +{ + int ret; + int i; + sqlite_int64 entry_id; + char *principal_string = NULL; + char *alias_string; + const HDB_Ext_Aliases *aliases; + + hdb_sqlite_db *hsdb = (hdb_sqlite_db *)(db->hdb_db); + krb5_data value; + sqlite3_stmt *get_ids = hsdb->get_ids; + + ret = hdb_sqlite_exec_stmt(context, hsdb->db, + "BEGIN IMMEDIATE TRANSACTION", EINVAL); + if(ret != SQLITE_OK) { + ret = EINVAL; + krb5_set_error_message(context, ret, + "SQLite BEGIN TRANSACTION failed: %s", + sqlite3_errmsg(hsdb->db)); + goto rollback; + } + + ret = krb5_unparse_name(context, + entry->entry.principal, &principal_string); + if (ret) { + goto rollback; + } + + ret = hdb_seal_keys(context, db, &entry->entry); + if(ret) { + goto rollback; + } + + ret = hdb_entry2value(context, &entry->entry, &value); + if(ret) { + goto rollback; + } + + sqlite3_bind_text(get_ids, 1, principal_string, -1, SQLITE_STATIC); + ret = hdb_sqlite_step(context, hsdb->db, get_ids); + + if(ret == SQLITE_DONE) { /* No such principal */ + + sqlite3_bind_blob(hsdb->add_entry, 1, + value.data, value.length, SQLITE_STATIC); + ret = hdb_sqlite_step(context, hsdb->db, hsdb->add_entry); + sqlite3_clear_bindings(hsdb->add_entry); + sqlite3_reset(hsdb->add_entry); + if(ret != SQLITE_DONE) + goto rollback; + + sqlite3_bind_text(hsdb->add_principal, 1, + principal_string, -1, SQLITE_STATIC); + ret = hdb_sqlite_step(context, hsdb->db, hsdb->add_principal); + sqlite3_clear_bindings(hsdb->add_principal); + sqlite3_reset(hsdb->add_principal); + if(ret != SQLITE_DONE) + goto rollback; + + entry_id = sqlite3_column_int64(get_ids, 1); + + } else if(ret == SQLITE_ROW) { /* Found a principal */ + + if(! (flags & HDB_F_REPLACE)) /* Not allowed to replace it */ + goto rollback; + + entry_id = sqlite3_column_int64(get_ids, 1); + + sqlite3_bind_int64(hsdb->delete_aliases, 1, entry_id); + ret = hdb_sqlite_step_once(context, db, hsdb->delete_aliases); + if(ret != SQLITE_DONE) + goto rollback; + + sqlite3_bind_blob(hsdb->update_entry, 1, + value.data, value.length, SQLITE_STATIC); + sqlite3_bind_int64(hsdb->update_entry, 2, entry_id); + ret = hdb_sqlite_step_once(context, db, hsdb->update_entry); + if(ret != SQLITE_DONE) + goto rollback; + + } else { + /* Error! */ + goto rollback; + } + + ret = hdb_entry_get_aliases(&entry->entry, &aliases); + if(ret || aliases == NULL) + goto commit; + + for(i = 0; i < aliases->aliases.len; i++) { + + ret = krb5_unparse_name(context, &aliases->aliases.val[i], + &alias_string); + if (ret) { + free(alias_string); + goto rollback; + } + + sqlite3_bind_text(hsdb->add_alias, 1, alias_string, + -1, SQLITE_STATIC); + sqlite3_bind_int64(hsdb->add_alias, 2, entry_id); + ret = hdb_sqlite_step_once(context, db, hsdb->add_alias); + + free(alias_string); + + if(ret != SQLITE_DONE) + goto rollback; + } + + ret = 0; + +commit: + + free(principal_string); + + krb5_data_free(&value); + + sqlite3_clear_bindings(get_ids); + sqlite3_reset(get_ids); + + ret = hdb_sqlite_exec_stmt(context, hsdb->db, "COMMIT", EINVAL); + if(ret != SQLITE_OK) + krb5_warnx(context, "hdb-sqlite: COMMIT problem: %d: %s", + ret, sqlite3_errmsg(hsdb->db)); + + return ret; + +rollback: + + krb5_warnx(context, "hdb-sqlite: store rollback problem: %d: %s", + ret, sqlite3_errmsg(hsdb->db)); + + free(principal_string); + + ret = hdb_sqlite_exec_stmt(context, hsdb->db, + "ROLLBACK", EINVAL); + return ret; +} + +/** + * This may be called often by other code, since the BDB backends + * can not have several open connections. SQLite can handle + * many processes with open handles to the database file + * and closing/opening the handle is an expensive operation. + * Hence, this function does nothing. + * + * @param context The current krb5 context + * @param db Heimdal database handle + * + * @return Always returns 0 + */ +static krb5_error_code +hdb_sqlite_close(krb5_context context, HDB *db) +{ + return 0; +} + +/** + * The opposite of hdb_sqlite_close. Since SQLite accepts + * many open handles to the database file the handle does not + * need to be closed, or reopened. + * + * @param context The current krb5 context + * @param db Heimdal database handle + * @param flags + * @param mode_t + * + * @return Always returns 0 + */ +static krb5_error_code +hdb_sqlite_open(krb5_context context, HDB *db, int flags, mode_t mode) +{ + return 0; +} + +/** + * Closes the databse and frees all resources. + * + * @param context The current krb5 context + * @param db Heimdal database handle + * + * @return 0 on success, an error code if not + */ +static krb5_error_code +hdb_sqlite_destroy(krb5_context context, HDB *db) +{ + int ret; + hdb_sqlite_db *hsdb; + + ret = hdb_clear_master_key(context, db); + + hdb_sqlite_close_database(context, db); + + hsdb = (hdb_sqlite_db*)(db->hdb_db); + + free(hsdb->db_file); + free(db->hdb_db); + free(db); + + return ret; +} + +/* + * Not sure if this is needed. + */ +static krb5_error_code +hdb_sqlite_lock(krb5_context context, HDB *db, int operation) +{ + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "lock not implemented"); + return HDB_ERR_CANT_LOCK_DB; +} + +/* + * Not sure if this is needed. + */ +static krb5_error_code +hdb_sqlite_unlock(krb5_context context, HDB *db) +{ + krb5_set_error_message(context, HDB_ERR_CANT_LOCK_DB, + "unlock not implemented"); + return HDB_ERR_CANT_LOCK_DB; +} + +/* + * Should get the next entry, to allow iteration over all entries. + */ +static krb5_error_code +hdb_sqlite_nextkey(krb5_context context, HDB *db, unsigned flags, + hdb_entry_ex *entry) +{ + krb5_error_code ret = 0; + int sqlite_error; + krb5_data value; + + hdb_sqlite_db *hsdb = (hdb_sqlite_db *) db->hdb_db; + + sqlite_error = hdb_sqlite_step(context, hsdb->db, hsdb->get_all_entries); + if(sqlite_error == SQLITE_ROW) { + /* Found an entry */ + value.length = sqlite3_column_bytes(hsdb->get_all_entries, 0); + value.data = (void *) sqlite3_column_blob(hsdb->get_all_entries, 0); + memset(entry, 0, sizeof(*entry)); + ret = hdb_value2entry(context, &value, &entry->entry); + } + else if(sqlite_error == SQLITE_DONE) { + /* No more entries */ + ret = HDB_ERR_NOENTRY; + sqlite3_reset(hsdb->get_all_entries); + } + else { + /* XXX SQLite error. Should be handled in some way. */ + ret = EINVAL; + } + + return ret; +} + +/* + * Should get the first entry in the database. + * What is flags used for? + */ +static krb5_error_code +hdb_sqlite_firstkey(krb5_context context, HDB *db, unsigned flags, + hdb_entry_ex *entry) +{ + hdb_sqlite_db *hsdb = (hdb_sqlite_db *) db->hdb_db; + krb5_error_code ret; + + sqlite3_reset(hsdb->get_all_entries); + + ret = hdb_sqlite_nextkey(context, db, flags, entry); + if(ret) + return ret; + + return 0; +} + +/* + * Renames the database file. + */ +static krb5_error_code +hdb_sqlite_rename(krb5_context context, HDB *db, const char *new_name) +{ + hdb_sqlite_db *hsdb = (hdb_sqlite_db *) db->hdb_db; + int ret; + + krb5_warnx(context, "hdb_sqlite_rename"); + + if (strncasecmp(new_name, "sqlite:", 7) == 0) + new_name += 7; + + hdb_sqlite_close_database(context, db); + + ret = rename(hsdb->db_file, new_name); + free(hsdb->db_file); + + hdb_sqlite_make_database(context, db, new_name); + + return ret; +} + +/* + * Removes a principal, including aliases and associated entry. + */ +static krb5_error_code +hdb_sqlite_remove(krb5_context context, HDB *db, + krb5_const_principal principal) +{ + krb5_error_code ret; + char *principal_string; + hdb_sqlite_db *hsdb = (hdb_sqlite_db*)(db->hdb_db); + sqlite3_stmt *remove = hsdb->remove; + + ret = krb5_unparse_name(context, principal, &principal_string); + if (ret) { + free(principal_string); + return ret; + } + + sqlite3_bind_text(remove, 1, principal_string, -1, SQLITE_STATIC); + + ret = hdb_sqlite_step(context, hsdb->db, remove); + if (ret != SQLITE_DONE) { + ret = EINVAL; + krb5_set_error_message(context, ret, + "sqlite remove failed: %d", + ret); + } else + ret = 0; + + sqlite3_clear_bindings(remove); + sqlite3_reset(remove); + + return ret; +} + +/** + * Create SQLITE object, and creates the on disk database if its doesn't exists. + * + * @param context A Kerberos 5 context. + * @param db a returned database handle. + * @param argument filename + * + * @return 0 on success, an error code if not + */ + +krb5_error_code +hdb_sqlite_create(krb5_context context, HDB **db, const char *argument) +{ + krb5_error_code ret; + hdb_sqlite_db *hsdb; + + *db = calloc(1, sizeof (**db)); + if (*db == NULL) + return krb5_enomem(context); + + hsdb = (hdb_sqlite_db*) calloc(1, sizeof (*hsdb)); + if (hsdb == NULL) { + free(*db); + *db = NULL; + return krb5_enomem(context); + } + + (*db)->hdb_db = hsdb; + + /* XXX make_database should make sure everything else is freed on error */ + ret = hdb_sqlite_make_database(context, *db, argument); + if (ret) { + free((*db)->hdb_db); + free(*db); + + return ret; + } + + (*db)->hdb_master_key_set = 0; + (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = 0; + + (*db)->hdb_open = hdb_sqlite_open; + (*db)->hdb_close = hdb_sqlite_close; + + (*db)->hdb_lock = hdb_sqlite_lock; + (*db)->hdb_unlock = hdb_sqlite_unlock; + (*db)->hdb_firstkey = hdb_sqlite_firstkey; + (*db)->hdb_nextkey = hdb_sqlite_nextkey; + (*db)->hdb_fetch_kvno = hdb_sqlite_fetch_kvno; + (*db)->hdb_store = hdb_sqlite_store; + (*db)->hdb_remove = hdb_sqlite_remove; + (*db)->hdb_destroy = hdb_sqlite_destroy; + (*db)->hdb_rename = hdb_sqlite_rename; + (*db)->hdb__get = NULL; + (*db)->hdb__put = NULL; + (*db)->hdb__del = NULL; + + return 0; +} diff --git a/crypto/heimdal/lib/hdb/hdb.asn1 b/crypto/heimdal/lib/hdb/hdb.asn1 index acd8f61..a72851c 100644 --- a/crypto/heimdal/lib/hdb/hdb.asn1 +++ b/crypto/heimdal/lib/hdb/hdb.asn1 @@ -1,4 +1,4 @@ --- $Id: hdb.asn1 20236 2007-02-16 23:52:29Z lha $ +-- $Id$ HDB DEFINITIONS ::= BEGIN @@ -13,7 +13,8 @@ hdb-afs3-salt INTEGER ::= 10 Salt ::= SEQUENCE { type[0] INTEGER (0..4294967295), - salt[1] OCTET STRING + salt[1] OCTET STRING, + opaque[2] OCTET STRING OPTIONAL } Key ::= SEQUENCE { @@ -44,7 +45,9 @@ HDBFlags ::= BIT STRING { immutable(13), -- may not be deleted trusted-for-delegation(14), -- Trusted to print forwardabled tickets allow-kerberos4(15), -- Allow Kerberos 4 requests - allow-digest(16) -- Allow digest requests + allow-digest(16), -- Allow digest requests + locked-out(17) -- Account is locked out, + -- authentication will be denied } GENERATION ::= SEQUENCE { @@ -64,6 +67,10 @@ HDB-Ext-PKINIT-hash ::= SEQUENCE OF SEQUENCE { digest[1] OCTET STRING } +HDB-Ext-PKINIT-cert ::= SEQUENCE OF SEQUENCE { + cert[0] OCTET STRING +} + HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal -- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA @@ -94,6 +101,7 @@ HDB-extension ::= SEQUENCE { password[5] HDB-Ext-Password, aliases[6] HDB-Ext-Aliases, last-pw-change[7] KerberosTime, + pkinit-cert[8] HDB-Ext-PKINIT-cert, ... }, ... @@ -101,6 +109,10 @@ HDB-extension ::= SEQUENCE { HDB-extensions ::= SEQUENCE OF HDB-extension +hdb_keyset ::= SEQUENCE { + kvno[1] INTEGER (0..4294967295), + keys[0] SEQUENCE OF Key +} hdb_entry ::= SEQUENCE { principal[0] Principal OPTIONAL, -- this is optional only diff --git a/crypto/heimdal/lib/hdb/hdb.c b/crypto/heimdal/lib/hdb/hdb.c index a515709..ca05cc4 100644 --- a/crypto/heimdal/lib/hdb/hdb.c +++ b/crypto/heimdal/lib/hdb/hdb.c @@ -1,70 +1,95 @@ /* - * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2008 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: + * Portions Copyright (c) 2009 Apple Inc. All rights reserved. * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 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. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 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. + * 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. * - * 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. + * 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 "krb5_locl.h" #include "hdb_locl.h" -RCSID("$Id: hdb.c 20214 2007-02-09 21:51:10Z lha $"); - #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif -struct hdb_method { - const char *prefix; - krb5_error_code (*create)(krb5_context, HDB **, const char *filename); -}; +/*! @mainpage Heimdal database backend library + * + * @section intro Introduction + * + * Heimdal libhdb library provides the backend support for Heimdal kdc + * and kadmind. Its here where plugins for diffrent database engines + * can be pluged in and extend support for here Heimdal get the + * principal and policy data from. + * + * Example of Heimdal backend are: + * - Berkeley DB 1.85 + * - Berkeley DB 3.0 + * - Berkeley DB 4.0 + * - New Berkeley DB + * - LDAP + * + * + * The project web page: http://www.h5l.org/ + * + */ + +const int hdb_interface_version = HDB_INTERFACE_VERSION; static struct hdb_method methods[] = { #if HAVE_DB1 || HAVE_DB3 - {"db:", hdb_db_create}, + { HDB_INTERFACE_VERSION, "db:", hdb_db_create}, +#endif +#if HAVE_DB1 + { HDB_INTERFACE_VERSION, "mit-db:", hdb_mdb_create}, #endif #if HAVE_NDBM - {"ndbm:", hdb_ndbm_create}, + { HDB_INTERFACE_VERSION, "ndbm:", hdb_ndbm_create}, #endif + { HDB_INTERFACE_VERSION, "keytab:", hdb_keytab_create}, #if defined(OPENLDAP) && !defined(OPENLDAP_MODULE) - {"ldap:", hdb_ldap_create}, - {"ldapi:", hdb_ldapi_create}, + { HDB_INTERFACE_VERSION, "ldap:", hdb_ldap_create}, + { HDB_INTERFACE_VERSION, "ldapi:", hdb_ldapi_create}, #endif -#ifdef HAVE_LDB /* Used for integrated samba build */ - {"ldb:", hdb_ldb_create}, +#ifdef HAVE_SQLITE3 + { HDB_INTERFACE_VERSION, "sqlite:", hdb_sqlite_create}, #endif - {NULL, NULL} + {0, NULL, NULL} }; #if HAVE_DB1 || HAVE_DB3 -static struct hdb_method dbmetod = {"", hdb_db_create }; +static struct hdb_method dbmetod = + { HDB_INTERFACE_VERSION, "", hdb_db_create }; #elif defined(HAVE_NDBM) -static struct hdb_method dbmetod = {"", hdb_ndbm_create }; +static struct hdb_method dbmetod = + { HDB_INTERFACE_VERSION, "", hdb_ndbm_create }; #endif @@ -75,25 +100,26 @@ hdb_next_enctype2key(krb5_context context, Key **key) { Key *k; - + for (k = *key ? (*key) + 1 : e->keys.val; - k < e->keys.val + e->keys.len; - k++) + k < e->keys.val + e->keys.len; + k++) { if(k->key.keytype == enctype){ *key = k; return 0; } } - krb5_set_error_string(context, "No next enctype %d for hdb-entry", + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "No next enctype %d for hdb-entry", (int)enctype); return KRB5_PROG_ETYPE_NOSUPP; /* XXX */ } krb5_error_code -hdb_enctype2key(krb5_context context, - hdb_entry *e, - krb5_enctype enctype, +hdb_enctype2key(krb5_context context, + hdb_entry *e, + krb5_enctype enctype, Key **key) { *key = NULL; @@ -103,7 +129,7 @@ hdb_enctype2key(krb5_context context, void hdb_free_key(Key *key) { - memset(key->key.keyvalue.data, + memset(key->key.keyvalue.data, 0, key->key.keyvalue.length); free_Key(key); @@ -142,7 +168,7 @@ hdb_unlock(int fd) void hdb_free_entry(krb5_context context, hdb_entry_ex *ent) { - int i; + size_t i; if (ent->free_entry) (*ent->free_entry)(context, ent); @@ -166,7 +192,7 @@ hdb_foreach(krb5_context context, hdb_entry_ex entry; ret = db->hdb_firstkey(context, db, flags, &entry); if (ret == 0) - krb5_clear_error_string(context); + krb5_clear_error_message(context); while(ret == 0){ ret = (*func)(context, db, &entry, data); hdb_free_entry(context, &entry); @@ -191,7 +217,7 @@ hdb_check_db_format(krb5_context context, HDB *db) if (ret) return ret; - tag.data = HDB_DB_FORMAT_ENTRY; + tag.data = (void *)(intptr_t)HDB_DB_FORMAT_ENTRY; tag.length = strlen(tag.data); ret = (*db->hdb__get)(context, db, tag, &version); ret2 = db->hdb_unlock(context, db); @@ -215,16 +241,16 @@ hdb_init_db(krb5_context context, HDB *db) krb5_data tag; krb5_data version; char ver[32]; - + ret = hdb_check_db_format(context, db); if(ret != HDB_ERR_NOENTRY) return ret; - + ret = db->hdb_lock(context, db, HDB_WLOCK); if (ret) return ret; - tag.data = HDB_DB_FORMAT_ENTRY; + tag.data = (void *)(intptr_t)HDB_DB_FORMAT_ENTRY; tag.length = strlen(tag.data); snprintf(ver, sizeof(ver), "%u", HDB_DB_FORMAT); version.data = ver; @@ -233,7 +259,7 @@ hdb_init_db(krb5_context context, HDB *db) ret2 = db->hdb_unlock(context, db); if (ret) { if (ret2) - krb5_clear_error_string(context); + krb5_clear_error_message(context); return ret; } return ret2; @@ -248,7 +274,7 @@ hdb_init_db(krb5_context context, HDB *db) static const struct hdb_method * find_dynamic_method (krb5_context context, - const char *filename, + const char *filename, const char **rest) { static struct hdb_method method; @@ -257,7 +283,7 @@ find_dynamic_method (krb5_context context, const char *p; void *dl; size_t len; - + p = strchr(filename, ':'); /* if no prefix, don't know what module to load, just ignore it */ @@ -266,11 +292,12 @@ find_dynamic_method (krb5_context context, len = p - filename; *rest = filename + len + 1; - - prefix = strndup(filename, len); + + prefix = malloc(len + 1); if (prefix == NULL) krb5_errx(context, 1, "out of memory"); - + strlcpy(prefix, filename, len + 1); + if (asprintf(&path, LIBDIR "/hdb_%s.so", prefix) == -1) krb5_errx(context, 1, "out of memory"); @@ -289,13 +316,13 @@ find_dynamic_method (krb5_context context, free(path); return NULL; } - + if (asprintf(&symbol, "hdb_%s_interface", prefix) == -1) krb5_errx(context, 1, "out of memory"); - - mso = dlsym(dl, symbol); + + mso = (struct hdb_so_method *) dlsym(dl, symbol); if (mso == NULL) { - krb5_warnx(context, "error finding symbol %s in %s: %s\n", + krb5_warnx(context, "error finding symbol %s in %s: %s\n", symbol, path, dlerror()); dlclose(dl); free(symbol); @@ -307,9 +334,9 @@ find_dynamic_method (krb5_context context, free(symbol); if (mso->version != HDB_INTERFACE_VERSION) { - krb5_warnx(context, + krb5_warnx(context, "error wrong version in shared module %s " - "version: %d should have been %d\n", + "version: %d should have been %d\n", prefix, mso->version, HDB_INTERFACE_VERSION); dlclose(dl); free(prefix); @@ -378,7 +405,7 @@ hdb_list_builtin(krb5_context context, char **list) len += 1; buf = malloc(len); if (buf == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } buf[0] = '\0'; @@ -393,15 +420,65 @@ hdb_list_builtin(krb5_context context, char **list) } krb5_error_code +_hdb_keytab2hdb_entry(krb5_context context, + const krb5_keytab_entry *ktentry, + hdb_entry_ex *entry) +{ + entry->entry.kvno = ktentry->vno; + entry->entry.created_by.time = ktentry->timestamp; + + entry->entry.keys.val = calloc(1, sizeof(entry->entry.keys.val[0])); + if (entry->entry.keys.val == NULL) + return ENOMEM; + entry->entry.keys.len = 1; + + entry->entry.keys.val[0].mkvno = NULL; + entry->entry.keys.val[0].salt = NULL; + + return krb5_copy_keyblock_contents(context, + &ktentry->keyblock, + &entry->entry.keys.val[0].key); +} + +/** + * Create a handle for a Kerberos database + * + * Create a handle for a Kerberos database backend specified by a + * filename. Doesn't create a file if its doesn't exists, you have to + * use O_CREAT to tell the backend to create the file. + */ + +krb5_error_code hdb_create(krb5_context context, HDB **db, const char *filename) { const struct hdb_method *h; const char *residual; + krb5_error_code ret; + struct krb5_plugin *list = NULL, *e; if(filename == NULL) filename = HDB_DEFAULT_DB; krb5_add_et_list(context, initialize_hdb_error_table_r); h = find_method (filename, &residual); + + if (h == NULL) { + ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "hdb", &list); + if(ret == 0 && list != NULL) { + for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) { + h = _krb5_plugin_get_symbol(e); + if (strncmp (filename, h->prefix, strlen(h->prefix)) == 0 + && h->interface_version == HDB_INTERFACE_VERSION) { + residual = filename + strlen(h->prefix); + break; + } + } + if (e == NULL) { + h = NULL; + _krb5_plugin_free(list); + } + } + } + #ifdef HAVE_DLOPEN if (h == NULL) h = find_dynamic_method (context, filename, &residual); diff --git a/crypto/heimdal/lib/hdb/hdb.h b/crypto/heimdal/lib/hdb/hdb.h index 742b924..a1692ce 100644 --- a/crypto/heimdal/lib/hdb/hdb.h +++ b/crypto/heimdal/lib/hdb/hdb.h @@ -1,41 +1,43 @@ /* - * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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: hdb.h 22198 2007-12-07 13:09:25Z lha $ */ +/* $Id$ */ #ifndef __HDB_H__ #define __HDB_H__ +#include <krb5.h> + #include <hdb_err.h> #include <heim_asn1.h> @@ -53,12 +55,36 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_F_GET_KRBTGT 16 /* fetch krbtgt */ #define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */ #define HDB_F_CANON 32 /* want canonicalition */ +#define HDB_F_ADMIN_DATA 64 /* want data that kdc don't use */ +#define HDB_F_KVNO_SPECIFIED 128 /* we want a particular KVNO */ +#define HDB_F_CURRENT_KVNO 256 /* we want the current KVNO */ +/* 512, 1024, 2048 are reserved for kvno operations that is not part of the 1.5 branch */ +#define HDB_F_ALL_KVNOS 2048 /* we want all the keys, live or not */ +#define HDB_F_FOR_AS_REQ 4096 /* fetch is for a AS REQ */ +#define HDB_F_FOR_TGS_REQ 8192 /* fetch is for a TGS REQ */ + +/* hdb_capability_flags */ +#define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1 +#define HDB_CAP_F_HANDLE_PASSWORDS 2 +#define HDB_CAP_F_PASSWORD_UPDATE_KEYS 4 + +/* auth status values */ +#define HDB_AUTH_SUCCESS 0 +#define HDB_AUTH_WRONG_PASSWORD 1 +#define HDB_AUTH_INVALID_SIGNATURE 2 /* key usage for master key */ #define HDB_KU_MKEY 0x484442 typedef struct hdb_master_key_data *hdb_master_key; +/** + * hdb_entry_ex is a wrapper structure around the hdb_entry structure + * that allows backends to keep a pointer to the backing store, ie in + * ->hdb_fetch_kvno(), so that we the kadmin/kpasswd backend gets around to + * ->hdb_store(), the backend doesn't need to lookup the entry again. + */ + typedef struct hdb_entry_ex { void *ctx; hdb_entry entry; @@ -66,68 +92,173 @@ typedef struct hdb_entry_ex { } hdb_entry_ex; +/** + * HDB backend function pointer structure + * + * The HDB structure is what the KDC and kadmind framework uses to + * query the backend database when talking about principals. + */ + typedef struct HDB{ void *hdb_db; - void *hdb_dbc; + void *hdb_dbc; /** don't use, only for DB3 */ char *hdb_name; int hdb_master_key_set; hdb_master_key hdb_master_key; int hdb_openp; - - krb5_error_code (*hdb_open)(krb5_context, - struct HDB*, - int, - mode_t); - krb5_error_code (*hdb_close)(krb5_context, - struct HDB*); - void (*hdb_free)(krb5_context, - struct HDB*, - hdb_entry_ex*); - krb5_error_code (*hdb_fetch)(krb5_context, - struct HDB*, - krb5_const_principal, - unsigned, - hdb_entry_ex*); - krb5_error_code (*hdb_store)(krb5_context, - struct HDB*, - unsigned, - hdb_entry_ex*); - krb5_error_code (*hdb_remove)(krb5_context, - struct HDB*, + int hdb_capability_flags; + /** + * Open (or create) the a Kerberos database. + * + * Open (or create) the a Kerberos database that was resolved with + * hdb_create(). The third and fourth flag to the function are the + * same as open(), thus passing O_CREAT will create the data base + * if it doesn't exists. + * + * Then done the caller should call hdb_close(), and to release + * all resources hdb_destroy(). + */ + krb5_error_code (*hdb_open)(krb5_context, struct HDB*, int, mode_t); + /** + * Close the database for transaction + * + * Closes the database for further transactions, wont release any + * permanant resources. the database can be ->hdb_open-ed again. + */ + krb5_error_code (*hdb_close)(krb5_context, struct HDB*); + /** + * Free an entry after use. + */ + void (*hdb_free)(krb5_context, struct HDB*, hdb_entry_ex*); + /** + * Fetch an entry from the backend + * + * Fetch an entry from the backend, flags are what type of entry + * should be fetch: client, server, krbtgt. + * knvo (if specified and flags HDB_F_KVNO_SPECIFIED set) is the kvno to get + */ + krb5_error_code (*hdb_fetch_kvno)(krb5_context, struct HDB*, + krb5_const_principal, unsigned, krb5_kvno, + hdb_entry_ex*); + /** + * Store an entry to database + */ + krb5_error_code (*hdb_store)(krb5_context, struct HDB*, + unsigned, hdb_entry_ex*); + /** + * Remove an entry from the database. + */ + krb5_error_code (*hdb_remove)(krb5_context, struct HDB*, krb5_const_principal); - krb5_error_code (*hdb_firstkey)(krb5_context, - struct HDB*, - unsigned, - hdb_entry_ex*); - krb5_error_code (*hdb_nextkey)(krb5_context, - struct HDB*, - unsigned, - hdb_entry_ex*); - krb5_error_code (*hdb_lock)(krb5_context, - struct HDB*, - int operation); - krb5_error_code (*hdb_unlock)(krb5_context, - struct HDB*); - krb5_error_code (*hdb_rename)(krb5_context, - struct HDB*, - const char*); - krb5_error_code (*hdb__get)(krb5_context, - struct HDB*, - krb5_data, - krb5_data*); - krb5_error_code (*hdb__put)(krb5_context, - struct HDB*, - int, - krb5_data, - krb5_data); - krb5_error_code (*hdb__del)(krb5_context, - struct HDB*, - krb5_data); - krb5_error_code (*hdb_destroy)(krb5_context, - struct HDB*); + /** + * As part of iteration, fetch one entry + */ + krb5_error_code (*hdb_firstkey)(krb5_context, struct HDB*, + unsigned, hdb_entry_ex*); + /** + * As part of iteration, fetch next entry + */ + krb5_error_code (*hdb_nextkey)(krb5_context, struct HDB*, + unsigned, hdb_entry_ex*); + /** + * Lock database + * + * A lock can only be held by one consumers. Transaction can still + * happen on the database while the lock is held, so the entry is + * only useful for syncroning creation of the database and renaming of the database. + */ + krb5_error_code (*hdb_lock)(krb5_context, struct HDB*, int); + /** + * Unlock database + */ + krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*); + /** + * Rename the data base. + * + * Assume that the database is not hdb_open'ed and not locked. + */ + krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*); + /** + * Get an hdb_entry from a classical DB backend + * + * If the database is a classical DB (ie BDB, NDBM, GDBM, etc) + * backend, this function will take a principal key (krb5_data) + * and return all data related to principal in the return + * krb5_data. The returned encoded entry is of type hdb_entry or + * hdb_entry_alias. + */ + krb5_error_code (*hdb__get)(krb5_context, struct HDB*, + krb5_data, krb5_data*); + /** + * Store an hdb_entry from a classical DB backend + * + * Same discussion as in @ref HDB::hdb__get + */ + krb5_error_code (*hdb__put)(krb5_context, struct HDB*, int, + krb5_data, krb5_data); + /** + * Delete and hdb_entry from a classical DB backend + * + * Same discussion as in @ref HDB::hdb__get + */ + krb5_error_code (*hdb__del)(krb5_context, struct HDB*, krb5_data); + /** + * Destroy the handle to the database. + * + * Destroy the handle to the database, deallocate all memory and + * related resources. Does not remove any permanent data. Its the + * logical reverse of hdb_create() function that is the entry + * point for the module. + */ + krb5_error_code (*hdb_destroy)(krb5_context, struct HDB*); + /** + * Get the list of realms this backend handles. + * This call is optional to support. The returned realms are used + * for announcing the realms over bonjour. Free returned array + * with krb5_free_host_realm(). + */ + krb5_error_code (*hdb_get_realms)(krb5_context, struct HDB *, krb5_realm **); + /** + * Change password. + * + * Will update keys for the entry when given password. The new + * keys must be written into the entry and will then later be + * ->hdb_store() into the database. The backend will still perform + * all other operations, increasing the kvno, and update + * modification timestamp. + * + * The backend needs to call _kadm5_set_keys() and perform password + * quality checks. + */ + krb5_error_code (*hdb_password)(krb5_context, struct HDB*, hdb_entry_ex*, const char *, int); + + /** + * Auth feedback + * + * This is a feedback call that allows backends that provides + * lockout functionality to register failure and/or successes. + * + * In case the entry is locked out, the backend should set the + * hdb_entry.flags.locked-out flag. + */ + krb5_error_code (*hdb_auth_status)(krb5_context, struct HDB *, hdb_entry_ex *, int); + /** + * Check if delegation is allowed. + */ + krb5_error_code (*hdb_check_constrained_delegation)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal); + + /** + * Check if this name is an alias for the supplied client for PKINIT userPrinicpalName logins + */ + krb5_error_code (*hdb_check_pkinit_ms_upn_match)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal); + + /** + * Check if s4u2self is allowed from this client to this server + */ + krb5_error_code (*hdb_check_s4u2self)(krb5_context, struct HDB *, hdb_entry_ex *, krb5_const_principal); }HDB; -#define HDB_INTERFACE_VERSION 4 +#define HDB_INTERFACE_VERSION 7 struct hdb_so_method { int version; @@ -139,6 +270,14 @@ typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*, hdb_entry_ex*, void*); extern krb5_kt_ops hdb_kt_ops; +struct hdb_method { + int interface_version; + const char *prefix; + krb5_error_code (*create)(krb5_context, HDB **, const char *filename); +}; + +extern const int hdb_interface_version; + #include <hdb-protos.h> #endif /* __HDB_H__ */ diff --git a/crypto/heimdal/lib/hdb/hdb.schema b/crypto/heimdal/lib/hdb/hdb.schema index 6e5c0f7..5730390 100644 --- a/crypto/heimdal/lib/hdb/hdb.schema +++ b/crypto/heimdal/lib/hdb/hdb.schema @@ -1,6 +1,6 @@ # Definitions for a Kerberos V KDC schema # -# $Id: hdb.schema 14958 2005-04-25 17:33:40Z lha $ +# $Id$ # # This version is compatible with OpenLDAP 1.8 # diff --git a/crypto/heimdal/lib/hdb/hdb_err.et b/crypto/heimdal/lib/hdb/hdb_err.et index 5c5b80b..2cad4da 100644 --- a/crypto/heimdal/lib/hdb/hdb_err.et +++ b/crypto/heimdal/lib/hdb/hdb_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: hdb_err.et 15878 2005-08-11 13:17:22Z lha $" +id "$Id$" error_table hdb @@ -24,5 +24,7 @@ error_code EXISTS, "Entry already exists in database" error_code BADVERSION, "Wrong database version" error_code NO_MKEY, "No correct master key" error_code MANDATORY_OPTION, "Entry contains unknown mandatory extension" +error_code NO_WRITE_SUPPORT, "HDB backend doesn't contain write support" +error_code NOT_FOUND_HERE, "The secret for this entry is not replicated to this database" end diff --git a/crypto/heimdal/lib/hdb/hdb_locl.h b/crypto/heimdal/lib/hdb/hdb_locl.h index 0a67e54..e896b58 100644 --- a/crypto/heimdal/lib/hdb/hdb_locl.h +++ b/crypto/heimdal/lib/hdb/hdb_locl.h @@ -1,38 +1,37 @@ /* - * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997-2001 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: + * 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. + * 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. + * 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. + * 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. + * 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: hdb_locl.h 22209 2007-12-07 19:03:41Z lha $ */ -/* $FreeBSD$ */ +/* $Id$ */ #ifndef __HDB_LOCL_H__ #define __HDB_LOCL_H__ diff --git a/crypto/heimdal/lib/hdb/keys.c b/crypto/heimdal/lib/hdb/keys.c index 60a5867..3d0b9d7 100644 --- a/crypto/heimdal/lib/hdb/keys.c +++ b/crypto/heimdal/lib/hdb/keys.c @@ -1,40 +1,39 @@ + /* - * Copyright (c) 1997 - 2001, 2003 - 2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2001, 2003 - 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" -RCSID("$Id: keys.c 22071 2007-11-14 20:04:50Z lha $"); - /* * free all the memory used by (len, keys) */ @@ -57,7 +56,7 @@ hdb_free_keys (krb5_context context, int len, Key *keys) free (keys); } -/* +/* * for each entry in `default_keys' try to parse it as a sequence * of etype:salttype:salt, syntax of this if something like: * [(des|des3|etype):](pw-salt|afs3)[:string], if etype is omitted it @@ -68,19 +67,21 @@ hdb_free_keys (krb5_context context, int len, Key *keys) * afs or afs3 == des:afs3-salt */ -/* the 3 DES types must be first */ -static const krb5_enctype all_etypes[] = { +static const krb5_enctype des_etypes[] = { ETYPE_DES_CBC_MD5, ETYPE_DES_CBC_MD4, - ETYPE_DES_CBC_CRC, + ETYPE_DES_CBC_CRC +}; + +static const krb5_enctype all_etypes[] = { ETYPE_AES256_CTS_HMAC_SHA1_96, ETYPE_ARCFOUR_HMAC_MD5, ETYPE_DES3_CBC_SHA1 }; static krb5_error_code -parse_key_set(krb5_context context, const char *key, - krb5_enctype **ret_enctypes, size_t *ret_num_enctypes, +parse_key_set(krb5_context context, const char *key, + krb5_enctype **ret_enctypes, size_t *ret_num_enctypes, krb5_salt *salt, krb5_principal principal) { const char *p; @@ -90,7 +91,7 @@ parse_key_set(krb5_context context, const char *key, krb5_enctype e; const krb5_enctype *enctypes = NULL; krb5_error_code ret; - + p = key; *ret_enctypes = NULL; @@ -110,8 +111,8 @@ parse_key_set(krb5_context context, const char *key, /* XXX there should be a string_to_etypes handling special cases like `des' and `all' */ if(strcmp(buf[i], "des") == 0) { - enctypes = all_etypes; - num_enctypes = 3; + enctypes = des_etypes; + num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]); } else if(strcmp(buf[i], "des3") == 0) { e = ETYPE_DES3_CBC_SHA1; enctypes = &e; @@ -139,8 +140,8 @@ parse_key_set(krb5_context context, const char *key, salt->salttype = KRB5_PW_SALT; } else if(strcmp(buf[i], "afs3-salt") == 0) { if(enctypes == NULL) { - enctypes = all_etypes; - num_enctypes = 3; + enctypes = des_etypes; + num_enctypes = sizeof(des_etypes)/sizeof(des_etypes[0]); } salt->salttype = KRB5_AFS3_SALT; } @@ -153,39 +154,40 @@ parse_key_set(krb5_context context, const char *key, v4 compat, and a cell name for afs compat */ salt->saltvalue.data = strdup(buf[i]); if (salt->saltvalue.data == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } salt->saltvalue.length = strlen(buf[i]); } } - + if(enctypes == NULL || salt->salttype == 0) { - krb5_set_error_string(context, "bad value for default_keys `%s'", key); + krb5_set_error_message(context, EINVAL, "bad value for default_keys `%s'", key); return EINVAL; } - + /* if no salt was specified make up default salt */ if(salt->saltvalue.data == NULL) { if(salt->salttype == KRB5_PW_SALT) ret = krb5_get_pw_salt(context, principal, salt); else if(salt->salttype == KRB5_AFS3_SALT) { - krb5_realm *realm = krb5_princ_realm(context, principal); - salt->saltvalue.data = strdup(*realm); + krb5_const_realm realm = krb5_principal_get_realm(context, principal); + salt->saltvalue.data = strdup(realm); if(salt->saltvalue.data == NULL) { - krb5_set_error_string(context, "out of memory while " - "parsing salt specifiers"); + krb5_set_error_message(context, ENOMEM, + "out of memory while " + "parsing salt specifiers"); return ENOMEM; } strlwr(salt->saltvalue.data); - salt->saltvalue.length = strlen(*realm); + salt->saltvalue.length = strlen(realm); } } *ret_enctypes = malloc(sizeof(enctypes[0]) * num_enctypes); if (*ret_enctypes == NULL) { krb5_free_salt(context, *salt); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(*ret_enctypes, enctypes, sizeof(enctypes[0]) * num_enctypes); @@ -195,7 +197,7 @@ parse_key_set(krb5_context context, const char *key, } static krb5_error_code -add_enctype_to_key_set(Key **key_set, size_t *nkeyset, +add_enctype_to_key_set(Key **key_set, size_t *nkeyset, krb5_enctype enctype, krb5_salt *salt) { krb5_error_code ret; @@ -206,25 +208,25 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset, tmp = realloc(*key_set, (*nkeyset + 1) * sizeof((*key_set)[0])); if (tmp == NULL) return ENOMEM; - + *key_set = tmp; key.key.keytype = enctype; key.key.keyvalue.length = 0; key.key.keyvalue.data = NULL; - + if (salt) { - key.salt = malloc(sizeof(*key.salt)); + key.salt = calloc(1, sizeof(*key.salt)); if (key.salt == NULL) { free_Key(&key); return ENOMEM; } - + key.salt->type = salt->salttype; krb5_data_zero (&key.salt->salt); - - ret = krb5_data_copy(&key.salt->salt, - salt->saltvalue.data, + + ret = krb5_data_copy(&key.salt->salt, + salt->saltvalue.data, salt->saltvalue.length); if (ret) { free_Key(&key); @@ -232,9 +234,9 @@ add_enctype_to_key_set(Key **key_set, size_t *nkeyset, } } else key.salt = NULL; - + (*key_set)[*nkeyset] = key; - + *nkeyset += 1; return 0; @@ -254,28 +256,24 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal, char **ktypes, **kp; krb5_error_code ret; Key *k, *key_set; - int i, j; - char *default_keytypes[] = { - "des:pw-salt", + size_t i, j; + static const char *default_keytypes[] = { "aes256-cts-hmac-sha1-96:pw-salt", "des3-cbc-sha1:pw-salt", "arcfour-hmac-md5:pw-salt", NULL }; - + ktypes = krb5_config_get_strings(context, NULL, "kadmin", "default_keys", NULL); if (ktypes == NULL) - ktypes = default_keytypes; - - if (ktypes == NULL) - abort(); + ktypes = (char **)(intptr_t)default_keytypes; *ret_key_set = key_set = NULL; *nkeyset = 0; ret = 0; - + for(kp = ktypes; kp && *kp; kp++) { const char *p; krb5_salt salt; @@ -292,7 +290,7 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal, p = "des:afs3-salt"; else if (strcmp(p, "arcfour-hmac-md5") == 0) p = "arcfour-hmac-md5:pw-salt"; - + memset(&salt, 0, sizeof(salt)); ret = parse_key_set(context, p, @@ -316,14 +314,14 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal, break; if (k->salt->type == salt.salttype && k->salt->salt.length == salt.saltvalue.length && - memcmp(k->salt->salt.data, salt.saltvalue.data, + memcmp(k->salt->salt.data, salt.saltvalue.data, salt.saltvalue.length) == 0) break; } } /* not a duplicate, lets add it */ if (j == *nkeyset) { - ret = add_enctype_to_key_set(&key_set, nkeyset, enctypes[i], + ret = add_enctype_to_key_set(&key_set, nkeyset, enctypes[i], no_salt ? NULL : &salt); if (ret) { free(enctypes); @@ -335,22 +333,22 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal, free(enctypes); krb5_free_salt(context, salt); } - + *ret_key_set = key_set; out: - if (ktypes != default_keytypes) + if (ktypes != (char **)(intptr_t)default_keytypes) krb5_config_free_strings(ktypes); if (ret) { - krb5_warn(context, ret, + krb5_warn(context, ret, "failed to parse the [kadmin]default_keys values"); for (i = 0; i < *nkeyset; i++) free_Key(&key_set[i]); free(key_set); } else if (*nkeyset == 0) { - krb5_warnx(context, + krb5_warnx(context, "failed to parse any of the [kadmin]default_keys values"); ret = EINVAL; /* XXX */ } @@ -360,13 +358,13 @@ hdb_generate_key_set(krb5_context context, krb5_principal principal, krb5_error_code -hdb_generate_key_set_password(krb5_context context, - krb5_principal principal, - const char *password, - Key **keys, size_t *num_keys) +hdb_generate_key_set_password(krb5_context context, + krb5_principal principal, + const char *password, + Key **keys, size_t *num_keys) { krb5_error_code ret; - int i; + size_t i; ret = hdb_generate_key_set(context, principal, keys, num_keys, 0); diff --git a/crypto/heimdal/lib/hdb/keytab.c b/crypto/heimdal/lib/hdb/keytab.c index e319bb5..c72b797 100644 --- a/crypto/heimdal/lib/hdb/keytab.c +++ b/crypto/heimdal/lib/hdb/keytab.c @@ -1,53 +1,58 @@ /* - * Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1999 - 2002 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" /* keytab backend for HDB databases */ -RCSID("$Id: keytab.c 18380 2006-10-09 12:36:40Z lha $"); - struct hdb_data { char *dbname; char *mkey; }; +struct hdb_cursor { + HDB *db; + hdb_entry_ex hdb_entry; + int first, next; + int key_idx; +}; + /* * the format for HDB keytabs is: - * HDB:[database:file:mkey] + * HDB:[HDBFORMAT:database-specific-data[:mkey=mkey-file]] */ -static krb5_error_code +static krb5_error_code KRB5_CALLCONV hdb_resolve(krb5_context context, const char *name, krb5_keytab id) { struct hdb_data *d; @@ -55,41 +60,38 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id) d = malloc(sizeof(*d)); if(d == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } db = name; - mkey = strchr(name, ':'); - if(mkey == NULL || mkey[1] == '\0') { + mkey = strstr(name, ":mkey="); + if(mkey == NULL || mkey[5] == '\0') { if(*name == '\0') d->dbname = NULL; else { d->dbname = strdup(name); if(d->dbname == NULL) { free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } d->mkey = NULL; } else { - if((mkey - db) == 0) { - d->dbname = NULL; - } else { - d->dbname = malloc(mkey - db + 1); - if(d->dbname == NULL) { - free(d); - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; - } - memmove(d->dbname, db, mkey - db); - d->dbname[mkey - db] = '\0'; + d->dbname = malloc(mkey - db + 1); + if(d->dbname == NULL) { + free(d); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; } - d->mkey = strdup(mkey + 1); + memmove(d->dbname, db, mkey - db); + d->dbname[mkey - db] = '\0'; + + d->mkey = strdup(mkey + 5); if(d->mkey == NULL) { free(d->dbname); free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } @@ -97,7 +99,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV hdb_close(krb5_context context, krb5_keytab id) { struct hdb_data *d = id->data; @@ -108,76 +110,58 @@ hdb_close(krb5_context context, krb5_keytab id) return 0; } -static krb5_error_code -hdb_get_name(krb5_context context, - krb5_keytab id, - char *name, +static krb5_error_code KRB5_CALLCONV +hdb_get_name(krb5_context context, + krb5_keytab id, + char *name, size_t namesize) { struct hdb_data *d = id->data; - snprintf(name, namesize, "%s%s%s", + snprintf(name, namesize, "%s%s%s", d->dbname ? d->dbname : "", (d->dbname || d->mkey) ? ":" : "", d->mkey ? d->mkey : ""); return 0; } -static void -set_config (krb5_context context, - const krb5_config_binding *binding, - const char **dbname, - const char **mkey) -{ - *dbname = krb5_config_get_string(context, binding, "dbname", NULL); - *mkey = krb5_config_get_string(context, binding, "mkey_file", NULL); -} - /* * try to figure out the database (`dbname') and master-key (`mkey') * that should be used for `principal'. */ -static void +static krb5_error_code find_db (krb5_context context, - const char **dbname, - const char **mkey, + char **dbname, + char **mkey, krb5_const_principal principal) { - const krb5_config_binding *top_bind = NULL; - const krb5_config_binding *default_binding = NULL; - const krb5_config_binding *db; - krb5_realm *prealm = krb5_princ_realm(context, rk_UNCONST(principal)); + krb5_const_realm realm = krb5_principal_get_realm(context, principal); + krb5_error_code ret; + struct hdb_dbinfo *head, *dbinfo = NULL; *dbname = *mkey = NULL; - while ((db = - krb5_config_get_next(context, - NULL, - &top_bind, - krb5_config_list, - "kdc", - "database", - NULL)) != NULL) { - const char *p; - - p = krb5_config_get_string (context, db, "realm", NULL); - if (p == NULL) { - if(default_binding) { - krb5_warnx(context, "WARNING: more than one realm-less " - "database specification"); - krb5_warnx(context, "WARNING: using the first encountered"); - } else - default_binding = db; - } else if (strcmp (*prealm, p) == 0) { - set_config (context, db, dbname, mkey); + ret = hdb_get_dbinfo(context, &head); + if (ret) + return ret; + + while ((dbinfo = hdb_dbinfo_get_next(head, dbinfo)) != NULL) { + const char *p = hdb_dbinfo_get_realm(context, dbinfo); + if (p && strcmp (realm, p) == 0) { + p = hdb_dbinfo_get_dbname(context, dbinfo); + if (p) + *dbname = strdup(p); + p = hdb_dbinfo_get_mkey_file(context, dbinfo); + if (p) + *mkey = strdup(p); break; } } - if (*dbname == NULL && default_binding != NULL) - set_config (context, default_binding, dbname, mkey); + hdb_free_dbinfo(context, &head); if (*dbname == NULL) - *dbname = HDB_DEFAULT_DB; + *dbname = strdup(HDB_DEFAULT_DB); + return 0; } /* @@ -185,7 +169,7 @@ find_db (krb5_context context, * it in `entry'. return 0 or an error code */ -static krb5_error_code +static krb5_error_code KRB5_CALLCONV hdb_get_entry(krb5_context context, krb5_keytab id, krb5_const_principal principal, @@ -196,34 +180,41 @@ hdb_get_entry(krb5_context context, hdb_entry_ex ent; krb5_error_code ret; struct hdb_data *d = id->data; - int i; - HDB *db; const char *dbname = d->dbname; const char *mkey = d->mkey; + char *fdbname = NULL, *fmkey = NULL; + HDB *db; + size_t i; memset(&ent, 0, sizeof(ent)); - if (dbname == NULL) - find_db (context, &dbname, &mkey, principal); + if (dbname == NULL) { + ret = find_db(context, &fdbname, &fmkey, principal); + if (ret) + return ret; + dbname = fdbname; + mkey = fmkey; + } ret = hdb_create (context, &db, dbname); if (ret) - return ret; + goto out2; ret = hdb_set_master_keyfile (context, db, mkey); if (ret) { (*db->hdb_destroy)(context, db); - return ret; + goto out2; } - + ret = (*db->hdb_open)(context, db, O_RDONLY, 0); if (ret) { (*db->hdb_destroy)(context, db); - return ret; + goto out2; } - ret = (*db->hdb_fetch)(context, db, principal, - HDB_F_DECRYPT| - HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, - &ent); + + ret = (*db->hdb_fetch_kvno)(context, db, principal, + HDB_F_DECRYPT|HDB_F_KVNO_SPECIFIED| + HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, + kvno, &ent); if(ret == HDB_ERR_NOENTRY) { ret = KRB5_KT_NOTFOUND; @@ -231,7 +222,7 @@ hdb_get_entry(krb5_context context, }else if(ret) goto out; - if(kvno && ent.entry.kvno != kvno) { + if(kvno && (krb5_kvno)ent.entry.kvno != kvno) { hdb_free_entry(context, &ent); ret = KRB5_KT_NOTFOUND; goto out; @@ -244,29 +235,190 @@ hdb_get_entry(krb5_context context, if(ent.entry.keys.val[i].key.keytype == enctype) { krb5_copy_principal(context, principal, &entry->principal); entry->vno = ent.entry.kvno; - krb5_copy_keyblock_contents(context, - &ent.entry.keys.val[i].key, + krb5_copy_keyblock_contents(context, + &ent.entry.keys.val[i].key, &entry->keyblock); ret = 0; break; } } hdb_free_entry(context, &ent); -out: + out: (*db->hdb_close)(context, db); (*db->hdb_destroy)(context, db); + out2: + free(fdbname); + free(fmkey); + return ret; +} + +/* + * find the keytab entry in `id' for `principal, kvno, enctype' and return + * it in `entry'. return 0 or an error code + */ + +static krb5_error_code KRB5_CALLCONV +hdb_start_seq_get(krb5_context context, + krb5_keytab id, + krb5_kt_cursor *cursor) +{ + krb5_error_code ret; + struct hdb_cursor *c; + struct hdb_data *d = id->data; + const char *dbname = d->dbname; + const char *mkey = d->mkey; + HDB *db; + + if (dbname == NULL) { + /* + * We don't support enumerating without being told what + * backend to enumerate on + */ + ret = KRB5_KT_NOTFOUND; + return ret; + } + + ret = hdb_create (context, &db, dbname); + if (ret) + return ret; + ret = hdb_set_master_keyfile (context, db, mkey); + if (ret) { + (*db->hdb_destroy)(context, db); + return ret; + } + + ret = (*db->hdb_open)(context, db, O_RDONLY, 0); + if (ret) { + (*db->hdb_destroy)(context, db); + return ret; + } + + cursor->data = c = malloc (sizeof(*c)); + if(c == NULL){ + (*db->hdb_close)(context, db); + (*db->hdb_destroy)(context, db); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + c->db = db; + c->first = TRUE; + c->next = TRUE; + c->key_idx = 0; + + cursor->data = c; return ret; } +static int KRB5_CALLCONV +hdb_next_entry(krb5_context context, + krb5_keytab id, + krb5_keytab_entry *entry, + krb5_kt_cursor *cursor) +{ + struct hdb_cursor *c = cursor->data; + krb5_error_code ret; + + memset(entry, 0, sizeof(*entry)); + + if (c->first) { + c->first = FALSE; + ret = (c->db->hdb_firstkey)(context, c->db, + HDB_F_DECRYPT| + HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, + &c->hdb_entry); + if (ret == HDB_ERR_NOENTRY) + return KRB5_KT_END; + else if (ret) + return ret; + + if (c->hdb_entry.entry.keys.len == 0) + hdb_free_entry(context, &c->hdb_entry); + else + c->next = FALSE; + } + + while (c->next) { + ret = (c->db->hdb_nextkey)(context, c->db, + HDB_F_DECRYPT| + HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, + &c->hdb_entry); + if (ret == HDB_ERR_NOENTRY) + return KRB5_KT_END; + else if (ret) + return ret; + + /* If no keys on this entry, try again */ + if (c->hdb_entry.entry.keys.len == 0) + hdb_free_entry(context, &c->hdb_entry); + else + c->next = FALSE; + } + + /* + * Return next enc type (keytabs are one slot per key, while + * hdb is one record per principal. + */ + + ret = krb5_copy_principal(context, + c->hdb_entry.entry.principal, + &entry->principal); + if (ret) + return ret; + + entry->vno = c->hdb_entry.entry.kvno; + ret = krb5_copy_keyblock_contents(context, + &c->hdb_entry.entry.keys.val[c->key_idx].key, + &entry->keyblock); + if (ret) { + krb5_free_principal(context, entry->principal); + memset(entry, 0, sizeof(*entry)); + return ret; + } + c->key_idx++; + + /* + * Once we get to the end of the list, signal that we want the + * next entry + */ + + if ((size_t)c->key_idx == c->hdb_entry.entry.keys.len) { + hdb_free_entry(context, &c->hdb_entry); + c->next = TRUE; + c->key_idx = 0; + } + + return 0; +} + + +static int KRB5_CALLCONV +hdb_end_seq_get(krb5_context context, + krb5_keytab id, + krb5_kt_cursor *cursor) +{ + struct hdb_cursor *c = cursor->data; + + if (!c->next) + hdb_free_entry(context, &c->hdb_entry); + + (c->db->hdb_close)(context, c->db); + (c->db->hdb_destroy)(context, c->db); + + free(c); + return 0; +} + krb5_kt_ops hdb_kt_ops = { "HDB", hdb_resolve, hdb_get_name, hdb_close, + NULL, /* destroy */ hdb_get_entry, - NULL, /* start_seq_get */ - NULL, /* next_entry */ - NULL, /* end_seq_get */ + hdb_start_seq_get, + hdb_next_entry, + hdb_end_seq_get, NULL, /* add */ NULL /* remove */ }; diff --git a/crypto/heimdal/lib/hdb/mkey.c b/crypto/heimdal/lib/hdb/mkey.c index 05cf71c..9eb98fc 100644 --- a/crypto/heimdal/lib/hdb/mkey.c +++ b/crypto/heimdal/lib/hdb/mkey.c @@ -1,34 +1,34 @@ /* - * Copyright (c) 2000 - 2004 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 2000 - 2004 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" @@ -36,8 +36,6 @@ #define O_BINARY 0 #endif -RCSID("$Id: mkey.c 21745 2007-07-31 16:11:25Z lha $"); - struct hdb_master_key_data { krb5_keytab_entry keytab; krb5_crypto crypto; @@ -67,7 +65,7 @@ hdb_process_master_key(krb5_context context, *mkey = calloc(1, sizeof(**mkey)); if(*mkey == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*mkey)->keytab.vno = kvno; @@ -110,7 +108,7 @@ hdb_add_master_key(krb5_context context, krb5_keyblock *key, } static krb5_error_code -read_master_keytab(krb5_context context, const char *filename, +read_master_keytab(krb5_context context, const char *filename, hdb_master_key *mkey) { krb5_error_code ret; @@ -118,7 +116,7 @@ read_master_keytab(krb5_context context, const char *filename, krb5_kt_cursor cursor; krb5_keytab_entry entry; hdb_master_key p; - + ret = krb5_kt_resolve(context, filename, &id); if(ret) return ret; @@ -147,20 +145,20 @@ read_master_keytab(krb5_context context, const char *filename, /* read a MIT master keyfile */ static krb5_error_code -read_master_mit(krb5_context context, const char *filename, - hdb_master_key *mkey) +read_master_mit(krb5_context context, const char *filename, + int byteorder, hdb_master_key *mkey) { int fd; krb5_error_code ret; krb5_storage *sp; int16_t enctype; krb5_keyblock key; - + fd = open(filename, O_RDONLY | O_BINARY); if(fd < 0) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", filename, - strerror(save_errno)); + krb5_set_error_message(context, save_errno, "failed to open %s: %s", + filename, strerror(save_errno)); return save_errno; } sp = krb5_storage_from_fd(fd); @@ -168,25 +166,22 @@ read_master_mit(krb5_context context, const char *filename, close(fd); return errno; } - krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER); -#if 0 + krb5_storage_set_flags(sp, byteorder); /* could possibly use ret_keyblock here, but do it with more checks for now */ - ret = krb5_ret_keyblock(sp, &key); -#else - ret = krb5_ret_int16(sp, &enctype); - if((htons(enctype) & 0xff00) == 0x3000) { - krb5_set_error_string(context, "unknown keytype in %s: %#x, expected %#x", - filename, htons(enctype), 0x3000); - ret = HEIM_ERR_BAD_MKEY; - goto out; + { + ret = krb5_ret_int16(sp, &enctype); + if (ret) + goto out; + ret = krb5_enctype_valid(context, enctype); + if (ret) + goto out; + key.keytype = enctype; + ret = krb5_ret_data(sp, &key.keyvalue); + if(ret) + goto out; } - key.keytype = enctype; - ret = krb5_ret_data(sp, &key.keyvalue); - if(ret) - goto out; -#endif - ret = hdb_process_master_key(context, 0, &key, 0, mkey); + ret = hdb_process_master_key(context, 1, &key, 0, mkey); krb5_free_keyblock_contents(context, &key); out: krb5_storage_free(sp); @@ -196,7 +191,7 @@ read_master_mit(krb5_context context, const char *filename, /* read an old master key file */ static krb5_error_code -read_master_encryptionkey(krb5_context context, const char *filename, +read_master_encryptionkey(krb5_context context, const char *filename, hdb_master_key *mkey) { int fd; @@ -205,20 +200,20 @@ read_master_encryptionkey(krb5_context context, const char *filename, unsigned char buf[256]; ssize_t len; size_t ret_len; - + fd = open(filename, O_RDONLY | O_BINARY); if(fd < 0) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", + krb5_set_error_message(context, save_errno, "failed to open %s: %s", filename, strerror(save_errno)); return save_errno; } - + len = read(fd, buf, sizeof(buf)); close(fd); if(len < 0) { int save_errno = errno; - krb5_set_error_string(context, "error reading %s: %s", + krb5_set_error_message(context, save_errno, "error reading %s: %s", filename, strerror(save_errno)); return save_errno; } @@ -233,9 +228,9 @@ read_master_encryptionkey(krb5_context context, const char *filename, should cover all cases, but will break if someone has hacked this code to really use des-cbc-md5 -- but then that's not my problem. */ - if(key.keytype == KEYTYPE_DES || key.keytype == ETYPE_DES_CBC_MD5) + if(key.keytype == ETYPE_DES_CBC_CRC || key.keytype == ETYPE_DES_CBC_MD5) key.keytype = ETYPE_DES_CFB64_NONE; - + ret = hdb_process_master_key(context, 0, &key, 0, mkey); krb5_free_keyblock_contents(context, &key); return ret; @@ -243,7 +238,7 @@ read_master_encryptionkey(krb5_context context, const char *filename, /* read a krb4 /.k style file */ static krb5_error_code -read_master_krb4(krb5_context context, const char *filename, +read_master_krb4(krb5_context context, const char *filename, hdb_master_key *mkey) { int fd; @@ -251,25 +246,26 @@ read_master_krb4(krb5_context context, const char *filename, krb5_error_code ret; unsigned char buf[256]; ssize_t len; - + fd = open(filename, O_RDONLY | O_BINARY); if(fd < 0) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", - filename, strerror(save_errno)); + krb5_set_error_message(context, save_errno, "failed to open %s: %s", + filename, strerror(save_errno)); return save_errno; } - + len = read(fd, buf, sizeof(buf)); close(fd); if(len < 0) { int save_errno = errno; - krb5_set_error_string(context, "error reading %s: %s", - filename, strerror(save_errno)); + krb5_set_error_message(context, save_errno, "error reading %s: %s", + filename, strerror(save_errno)); return save_errno; } if(len != 8) { - krb5_set_error_string(context, "bad contents of %s", filename); + krb5_set_error_message(context, HEIM_ERR_EOF, + "bad contents of %s", filename); return HEIM_ERR_EOF; /* XXX file might be too large */ } @@ -277,7 +273,7 @@ read_master_krb4(krb5_context context, const char *filename, key.keytype = ETYPE_DES_PCBC_NONE; ret = krb5_data_copy(&key.keyvalue, buf, len); memset(buf, 0, sizeof(buf)); - if(ret) + if(ret) return ret; ret = hdb_process_master_key(context, 0, &key, 0, mkey); @@ -286,7 +282,7 @@ read_master_krb4(krb5_context context, const char *filename, } krb5_error_code -hdb_read_master_key(krb5_context context, const char *filename, +hdb_read_master_key(krb5_context context, const char *filename, hdb_master_key *mkey) { FILE *f; @@ -303,26 +299,26 @@ hdb_read_master_key(krb5_context context, const char *filename, f = fopen(filename, "r"); if(f == NULL) { int save_errno = errno; - krb5_set_error_string(context, "failed to open %s: %s", - filename, strerror(save_errno)); + krb5_set_error_message(context, save_errno, "failed to open %s: %s", + filename, strerror(save_errno)); return save_errno; } - + if(fread(buf, 1, 2, f) != 2) { - krb5_set_error_string(context, "end of file reading %s", filename); fclose(f); + krb5_set_error_message(context, HEIM_ERR_EOF, "end of file reading %s", filename); return HEIM_ERR_EOF; } - + fseek(f, 0, SEEK_END); len = ftell(f); if(fclose(f) != 0) return errno; - + if(len < 0) return errno; - + if(len == 8) { ret = read_master_krb4(context, filename, mkey); } else if(buf[0] == 0x30 && len <= 127 && buf[1] == len - 2) { @@ -330,13 +326,20 @@ hdb_read_master_key(krb5_context context, const char *filename, } else if(buf[0] == 5 && buf[1] >= 1 && buf[1] <= 2) { ret = read_master_keytab(context, filename, mkey); } else { - ret = read_master_mit(context, filename, mkey); + /* + * Check both LittleEndian and BigEndian since they key file + * might be moved from a machine with diffrent byte order, or + * its running on MacOS X that always uses BE master keys. + */ + ret = read_master_mit(context, filename, KRB5_STORAGE_BYTEORDER_LE, mkey); + if (ret) + ret = read_master_mit(context, filename, KRB5_STORAGE_BYTEORDER_BE, mkey); } return ret; } krb5_error_code -hdb_write_master_key(krb5_context context, const char *filename, +hdb_write_master_key(krb5_context context, const char *filename, hdb_master_key mkey) { krb5_error_code ret; @@ -369,7 +372,7 @@ _hdb_find_master_key(uint32_t *mkvno, hdb_master_key mkey) if(mkvno == NULL) { if(ret == NULL || mkey->keytab.vno > ret->keytab.vno) ret = mkey; - } else if(mkey->keytab.vno == *mkvno) + } else if((uint32_t)mkey->keytab.vno == *mkvno) return mkey; mkey = mkey->next; } @@ -401,9 +404,9 @@ _hdb_mkey_encrypt(krb5_context context, hdb_master_key key, } krb5_error_code -hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) +hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) { - + krb5_error_code ret; krb5_data res; size_t keysize; @@ -412,7 +415,7 @@ hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) if(k->mkvno == NULL) return 0; - + key = _hdb_find_master_key(k->mkvno, mkey); if (key == NULL) @@ -428,7 +431,7 @@ hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) k->key.keyvalue.data, k->key.keyvalue.length, &res); - } + } if (ret) return ret; @@ -456,13 +459,13 @@ hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) krb5_error_code hdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) { - int i; + size_t i; for(i = 0; i < ent->keys.len; i++){ krb5_error_code ret; ret = hdb_unseal_key_mkey(context, &ent->keys.val[i], mkey); - if (ret) + if (ret) return ret; } return 0; @@ -516,14 +519,14 @@ hdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) return ENOMEM; } *k->mkvno = key->keytab.vno; - + return 0; } krb5_error_code hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) { - int i; + size_t i; for(i = 0; i < ent->keys.len; i++){ krb5_error_code ret; @@ -539,7 +542,7 @@ hdb_seal_keys(krb5_context context, HDB *db, hdb_entry *ent) { if (db->hdb_master_key_set == 0) return 0; - + return hdb_seal_keys_mkey(context, ent, db->hdb_master_key); } @@ -548,7 +551,7 @@ hdb_seal_key(krb5_context context, HDB *db, Key *k) { if (db->hdb_master_key_set == 0) return 0; - + return hdb_seal_key_mkey(context, k, db->hdb_master_key); } @@ -583,7 +586,7 @@ hdb_set_master_keyfile (krb5_context context, if (ret) { if (ret != ENOENT) return ret; - krb5_clear_error_string(context); + krb5_clear_error_message(context); return 0; } db->hdb_master_key = key; diff --git a/crypto/heimdal/lib/hdb/ndbm.c b/crypto/heimdal/lib/hdb/ndbm.c index 6575b8a..5b2c07e 100644 --- a/crypto/heimdal/lib/hdb/ndbm.c +++ b/crypto/heimdal/lib/hdb/ndbm.c @@ -1,47 +1,47 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2001 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: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" -RCSID("$Id: ndbm.c 16395 2005-12-13 11:54:10Z lha $"); - #if HAVE_NDBM #if defined(HAVE_GDBM_NDBM_H) #include <gdbm/ndbm.h> +#define WRITE_SUPPORT 1 #elif defined(HAVE_NDBM_H) #include <ndbm.h> #elif defined(HAVE_DBM_H) +#define WRITE_SUPPORT 1 #include <dbm.h> #endif @@ -53,9 +53,7 @@ struct ndbm_db { static krb5_error_code NDBM_destroy(krb5_context context, HDB *db) { - krb5_error_code ret; - - ret = hdb_clear_master_key (context, db); + hdb_clear_master_key (context, db); free(db->hdb_name); free(db); return 0; @@ -76,7 +74,7 @@ NDBM_unlock(krb5_context context, HDB *db) } static krb5_error_code -NDBM_seq(krb5_context context, HDB *db, +NDBM_seq(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry, int first) { @@ -110,9 +108,9 @@ NDBM_seq(krb5_context context, HDB *db, if (ret == 0 && entry->entry.principal == NULL) { entry->entry.principal = malloc (sizeof(*entry->entry.principal)); if (entry->entry.principal == NULL) { - ret = ENOMEM; hdb_free_entry (context, entry); - krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); } else { hdb_key2principal (context, &key_data, entry->entry.principal); } @@ -135,40 +133,59 @@ NDBM_nextkey(krb5_context context, HDB *db, unsigned flags,hdb_entry_ex *entry) } static krb5_error_code -NDBM_rename(krb5_context context, HDB *db, const char *new_name) +open_lock_file(krb5_context context, const char *db_name, int *fd) { - /* XXX this function will break */ - struct ndbm_db *d = db->hdb_db; + char *lock_file; + + /* lock old and new databases */ + asprintf(&lock_file, "%s.lock", db_name); + if(lock_file == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + *fd = open(lock_file, O_RDWR | O_CREAT, 0600); + free(lock_file); + if(*fd < 0) { + int ret = errno; + krb5_set_error_message(context, ret, "open(%s): %s", lock_file, + strerror(ret)); + return ret; + } + return 0; +} + +static krb5_error_code +NDBM_rename(krb5_context context, HDB *db, const char *new_name) +{ int ret; char *old_dir, *old_pag, *new_dir, *new_pag; - char *new_lock; - int lock_fd; + int old_lock_fd, new_lock_fd; /* lock old and new databases */ - ret = db->hdb_lock(context, db, HDB_WLOCK); - if(ret) + ret = open_lock_file(context, db->hdb_name, &old_lock_fd); + if (ret) + return ret; + + ret = hdb_lock(old_lock_fd, HDB_WLOCK); + if(ret) { + close(old_lock_fd); return ret; - asprintf(&new_lock, "%s.lock", new_name); - if(new_lock == NULL) { - db->hdb_unlock(context, db); - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; } - lock_fd = open(new_lock, O_RDWR | O_CREAT, 0600); - if(lock_fd < 0) { - ret = errno; - db->hdb_unlock(context, db); - krb5_set_error_string(context, "open(%s): %s", new_lock, - strerror(ret)); - free(new_lock); + + ret = open_lock_file(context, new_name, &new_lock_fd); + if (ret) { + hdb_unlock(old_lock_fd); + close(old_lock_fd); return ret; } - free(new_lock); - ret = hdb_lock(lock_fd, HDB_WLOCK); + + ret = hdb_lock(new_lock_fd, HDB_WLOCK); if(ret) { - db->hdb_unlock(context, db); - close(lock_fd); + hdb_unlock(old_lock_fd); + close(old_lock_fd); + close(new_lock_fd); return ret; } @@ -178,23 +195,26 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) asprintf(&new_pag, "%s.pag", new_name); ret = rename(old_dir, new_dir) || rename(old_pag, new_pag); + if (ret) { + ret = errno; + if (ret == 0) + ret = EPERM; + krb5_set_error_message(context, ret, "rename: %s", strerror(ret)); + } + free(old_dir); free(old_pag); free(new_dir); free(new_pag); - hdb_unlock(lock_fd); - db->hdb_unlock(context, db); - if(ret) { - ret = errno; - close(lock_fd); - krb5_set_error_string(context, "rename: %s", strerror(ret)); + hdb_unlock(new_lock_fd); + hdb_unlock(old_lock_fd); + close(new_lock_fd); + close(old_lock_fd); + + if(ret) return ret; - } - close(d->lock_fd); - d->lock_fd = lock_fd; - free(db->hdb_name); db->hdb_name = strdup(new_name); return 0; @@ -222,9 +242,10 @@ NDBM__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) } static krb5_error_code -NDBM__put(krb5_context context, HDB *db, int replace, +NDBM__put(krb5_context context, HDB *db, int replace, krb5_data key, krb5_data value) { +#ifdef WRITE_SUPPORT struct ndbm_db *d = (struct ndbm_db *)db->hdb_db; datum k, v; int code; @@ -244,6 +265,9 @@ NDBM__put(krb5_context context, HDB *db, int replace, if (code < 0) return code; return 0; +#else + return HDB_ERR_NO_WRITE_SUPPORT; +#endif } static krb5_error_code @@ -281,38 +305,31 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) { krb5_error_code ret; struct ndbm_db *d = malloc(sizeof(*d)); - char *lock_file; if(d == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; - } - asprintf(&lock_file, "%s.lock", (char*)db->hdb_name); - if(lock_file == NULL) { - free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } + d->db = dbm_open((char*)db->hdb_name, flags, mode); if(d->db == NULL){ ret = errno; free(d); - free(lock_file); - krb5_set_error_string(context, "dbm_open(%s): %s", db->hdb_name, - strerror(ret)); + krb5_set_error_message(context, ret, "dbm_open(%s): %s", db->hdb_name, + strerror(ret)); return ret; } - d->lock_fd = open(lock_file, O_RDWR | O_CREAT, 0600); - if(d->lock_fd < 0){ + + ret = open_lock_file(context, db->hdb_name, &d->lock_fd); + if (ret) { ret = errno; dbm_close(d->db); free(d); - krb5_set_error_string(context, "open(%s): %s", lock_file, - strerror(ret)); - free(lock_file); + krb5_set_error_message(context, ret, "open(lock file): %s", + strerror(ret)); return ret; } - free(lock_file); + db->hdb_db = d; if((flags & O_ACCMODE) == O_RDONLY) ret = hdb_check_db_format(context, db); @@ -322,37 +339,38 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) return 0; if (ret) { NDBM_close(context, db); - krb5_set_error_string(context, "hdb_open: failed %s database %s", - (flags & O_ACCMODE) == O_RDONLY ? - "checking format of" : "initialize", - db->hdb_name); + krb5_set_error_message(context, ret, "hdb_open: failed %s database %s", + (flags & O_ACCMODE) == O_RDONLY ? + "checking format of" : "initialize", + db->hdb_name); } return ret; } krb5_error_code -hdb_ndbm_create(krb5_context context, HDB **db, +hdb_ndbm_create(krb5_context context, HDB **db, const char *filename) { *db = calloc(1, sizeof(**db)); if (*db == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_db = NULL; (*db)->hdb_name = strdup(filename); if ((*db)->hdb_name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); free(*db); *db = NULL; + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*db)->hdb_master_key_set = 0; (*db)->hdb_openp = 0; + (*db)->hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL; (*db)->hdb_open = NDBM_open; (*db)->hdb_close = NDBM_close; - (*db)->hdb_fetch = _hdb_fetch; + (*db)->hdb_fetch_kvno = _hdb_fetch_kvno; (*db)->hdb_store = _hdb_store; (*db)->hdb_remove = _hdb_remove; (*db)->hdb_firstkey = NDBM_firstkey; diff --git a/crypto/heimdal/lib/hdb/print.c b/crypto/heimdal/lib/hdb/print.c index 60b7e8d..697d32d 100644 --- a/crypto/heimdal/lib/hdb/print.c +++ b/crypto/heimdal/lib/hdb/print.c @@ -1,18 +1,18 @@ /* - * Copyright (c) 1999-2005 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1999-2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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 @@ -34,9 +34,7 @@ #include <hex.h> #include <ctype.h> -RCSID("$Id: print.c 16378 2005-12-12 12:40:12Z lha $"); - -/* +/* This is the present contents of a dump line. This might change at any time. Fields are separated by white space. @@ -69,7 +67,7 @@ append_string(krb5_context context, krb5_storage *sp, const char *fmt, ...) vasprintf(&s, fmt, ap); va_end(ap); if(s == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_storage_write(sp, s, strlen(s)); @@ -80,7 +78,8 @@ append_string(krb5_context context, krb5_storage *sp, const char *fmt, ...) static krb5_error_code append_hex(krb5_context context, krb5_storage *sp, krb5_data *data) { - int i, printable = 1; + int printable = 1; + size_t i; char *p; p = data->data; @@ -128,7 +127,7 @@ static krb5_error_code entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) { char *p; - int i; + size_t i; krb5_error_code ret; /* --- principal */ @@ -143,11 +142,11 @@ entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) for(i = 0; i < ent->keys.len; i++){ /* --- mkvno, keytype */ if(ent->keys.val[i].mkvno) - append_string(context, sp, ":%d:%d:", - *ent->keys.val[i].mkvno, + append_string(context, sp, ":%d:%d:", + *ent->keys.val[i].mkvno, ent->keys.val[i].key.keytype); else - append_string(context, sp, "::%d:", + append_string(context, sp, "::%d:", ent->keys.val[i].key.keytype); /* --- keydata */ append_hex(context, sp, &ent->keys.val[i].key.keyvalue); @@ -176,7 +175,7 @@ entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) append_string(context, sp, "%s ", time2str(*ent->valid_end)); else append_string(context, sp, "- "); - + /* --- password ends */ if(ent->pw_end) append_string(context, sp, "%s ", time2str(*ent->pw_end)); @@ -194,7 +193,7 @@ entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) append_string(context, sp, "%d ", *ent->max_renew); else append_string(context, sp, "- "); - + /* --- flags */ append_string(context, sp, "%d ", HDBFlags2int(ent->flags)); @@ -210,12 +209,12 @@ entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) if(ent->extensions && ent->extensions->len > 0) { for(i = 0; i < ent->extensions->len; i++) { void *d; - size_t size, sz; + size_t size, sz = 0; ASN1_MALLOC_ENCODE(HDB_extension, d, size, &ent->extensions->val[i], &sz, ret); if (ret) { - krb5_clear_error_string(context); + krb5_clear_error_message(context); return ret; } if(size != sz) @@ -223,19 +222,19 @@ entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) if (hex_encode(d, size, &p) < 0) { free(d); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } free(d); - append_string(context, sp, "%s%s", p, + append_string(context, sp, "%s%s", p, ent->extensions->len - 1 != i ? ":" : ""); free(p); } } else append_string(context, sp, "-"); - + return 0; } @@ -248,10 +247,10 @@ hdb_entry2string (krb5_context context, hdb_entry *ent, char **str) sp = krb5_storage_emem(); if(sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - + ret = entry2string_int(context, sp, ent); if(ret) { krb5_storage_free(sp); @@ -278,10 +277,10 @@ hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, void *data) fflush(f); sp = krb5_storage_from_fd(fileno(f)); if(sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - + ret = entry2string_int(context, sp, &entry->entry); if(ret) { krb5_storage_free(sp); diff --git a/crypto/heimdal/lib/hdb/test_dbinfo.c b/crypto/heimdal/lib/hdb/test_dbinfo.c index d92a538..efe50af 100644 --- a/crypto/heimdal/lib/hdb/test_dbinfo.c +++ b/crypto/heimdal/lib/hdb/test_dbinfo.c @@ -1,41 +1,39 @@ /* - * Copyright (c) 2005 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 2005 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * 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. + * 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. + * 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. + * 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. + * 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 "hdb_locl.h" #include <getarg.h> -RCSID("$Id: test_dbinfo.c 20575 2007-04-27 20:20:32Z lha $"); - static int help_flag; static int version_flag; @@ -60,7 +58,7 @@ main(int argc, char **argv) if(help_flag) krb5_std_usage(0, args, num_args); - + if(version_flag){ print_version(NULL); exit(0); @@ -76,11 +74,17 @@ main(int argc, char **argv) d = NULL; while ((d = hdb_dbinfo_get_next(info, d)) != NULL) { - printf("label: %s\n", hdb_dbinfo_get_label(context, d)); - printf("\trealm: %s\n", hdb_dbinfo_get_realm(context, d)); - printf("\tdbname: %s\n", hdb_dbinfo_get_dbname(context, d)); - printf("\tmkey_file: %s\n", hdb_dbinfo_get_mkey_file(context, d)); - printf("\tacl_file: %s\n", hdb_dbinfo_get_acl_file(context, d)); + const char *s; + s = hdb_dbinfo_get_label(context, d); + printf("label: %s\n", s ? s : "no label"); + s = hdb_dbinfo_get_realm(context, d); + printf("\trealm: %s\n", s ? s : "no realm"); + s = hdb_dbinfo_get_dbname(context, d); + printf("\tdbname: %s\n", s ? s : "no dbname"); + s = hdb_dbinfo_get_mkey_file(context, d); + printf("\tmkey_file: %s\n", s ? s : "no mkey file"); + s = hdb_dbinfo_get_acl_file(context, d); + printf("\tacl_file: %s\n", s ? s : "no acl file"); } hdb_free_dbinfo(context, &info); diff --git a/crypto/heimdal/lib/hdb/version-script.map b/crypto/heimdal/lib/hdb/version-script.map new file mode 100644 index 0000000..50a36ce --- /dev/null +++ b/crypto/heimdal/lib/hdb/version-script.map @@ -0,0 +1,107 @@ +# $Id$ + +HEIMDAL_HDB_1.0 { + global: + encode_hdb_keyset; + hdb_add_master_key; + hdb_check_db_format; + hdb_clear_extension; + hdb_clear_master_key; + hdb_create; + hdb_db_dir; + hdb_dbinfo_get_acl_file; + hdb_dbinfo_get_binding; + hdb_dbinfo_get_dbname; + hdb_dbinfo_get_label; + hdb_dbinfo_get_log_file; + hdb_dbinfo_get_mkey_file; + hdb_dbinfo_get_next; + hdb_dbinfo_get_realm; + hdb_default_db; + hdb_enctype2key; + hdb_entry2string; + hdb_entry2value; + hdb_entry_alias2value; + hdb_entry_check_mandatory; + hdb_entry_clear_password; + hdb_entry_get_ConstrainedDelegACL; + hdb_entry_get_aliases; + hdb_entry_get_password; + hdb_entry_get_pkinit_acl; + hdb_entry_get_pkinit_cert; + hdb_entry_get_pkinit_hash; + hdb_entry_get_pw_change_time; + hdb_entry_set_password; + hdb_entry_set_pw_change_time; + hdb_find_extension; + hdb_foreach; + hdb_free_dbinfo; + hdb_free_entry; + hdb_free_key; + hdb_free_keys; + hdb_free_master_key; + hdb_generate_key_set; + hdb_generate_key_set_password; + hdb_get_dbinfo; + hdb_init_db; + hdb_key2principal; + hdb_list_builtin; + hdb_lock; + hdb_next_enctype2key; + hdb_principal2key; + hdb_print_entry; + hdb_process_master_key; + hdb_read_master_key; + hdb_replace_extension; + hdb_seal_key; + hdb_seal_key_mkey; + hdb_seal_keys; + hdb_seal_keys_mkey; + hdb_set_master_key; + hdb_set_master_keyfile; + hdb_unlock; + hdb_unseal_key; + hdb_unseal_key_mkey; + hdb_unseal_keys; + hdb_unseal_keys_mkey; + hdb_value2entry; + hdb_value2entry_alias; + hdb_write_master_key; + length_hdb_keyset; + hdb_interface_version; + initialize_hdb_error_table_r; + + hdb_kt_ops; + + # some random bits needed for libkadm + HDBFlags2int; + asn1_HDBFlags_units; + copy_Event; + copy_HDB_extensions; + copy_Key; + copy_Salt; + decode_HDB_Ext_Aliases; + decode_HDB_Ext_PKINIT_acl; + decode_HDB_extension; + decode_Key; + encode_HDB_Ext_Aliases; + encode_HDB_Ext_PKINIT_acl; + encode_HDB_extension; + encode_Key; + free_Event; + free_HDB_Ext_Aliases; + free_HDB_Ext_PKINIT_acl; + free_HDB_extension; + free_HDB_extensions; + free_Key; + free_Salt; + free_hdb_entry; + int2HDBFlags; + length_HDB_Ext_Aliases; + length_HDB_Ext_PKINIT_acl; + length_HDB_extension; + length_Key; + + local: + *; +}; |