diff options
author | dfr <dfr@FreeBSD.org> | 2008-05-07 13:39:42 +0000 |
---|---|---|
committer | dfr <dfr@FreeBSD.org> | 2008-05-07 13:39:42 +0000 |
commit | 52bf09d8197dd1ec84e1ab72684f2058f0eae9e1 (patch) | |
tree | 07a0d6761d1b42410a27e4c7d583b766d6671f80 /crypto/heimdal/lib/hdb | |
parent | 6c68306921f6e85bce52c905cf2606c25acdb436 (diff) | |
parent | 51b6601db456e699ea5d4843cbc7239ee92d9c13 (diff) | |
download | FreeBSD-src-52bf09d8197dd1ec84e1ab72684f2058f0eae9e1.zip FreeBSD-src-52bf09d8197dd1ec84e1ab72684f2058f0eae9e1.tar.gz |
This commit was generated by cvs2svn to compensate for changes in r178825,
which included commits to RCS files with non-trunk default branches.
Diffstat (limited to 'crypto/heimdal/lib/hdb')
-rw-r--r-- | crypto/heimdal/lib/hdb/Makefile.am | 105 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/Makefile.in | 582 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/common.c | 192 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/db.c | 188 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/db3.c | 167 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/dbinfo.c | 266 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/ext.c | 418 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb-ldap.c | 1677 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb-private.h | 33 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb-protos.h | 220 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb.asn1 | 107 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb.c | 220 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb.h | 117 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb.schema | 139 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb_err.et | 3 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/keys.c | 398 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/keytab.c | 64 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/mkey.c | 220 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/ndbm.c | 149 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/print.c | 46 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/test_dbinfo.c | 91 |
21 files changed, 4163 insertions, 1239 deletions
diff --git a/crypto/heimdal/lib/hdb/Makefile.am b/crypto/heimdal/lib/hdb/Makefile.am index 952944b..f66cd06 100644 --- a/crypto/heimdal/lib/hdb/Makefile.am +++ b/crypto/heimdal/lib/hdb/Makefile.am @@ -1,62 +1,115 @@ -# $Id: Makefile.am,v 1.53.4.2 2003/10/14 16:13:14 joda Exp $ +# $Id: Makefile.am 22490 2008-01-21 11:49:33Z lha $ include $(top_srcdir)/Makefile.am.common -INCLUDES += -I../asn1 -I$(srcdir)/../asn1 $(INCLUDE_des) +AM_CPPFLAGS += -I../asn1 -I$(srcdir)/../asn1 $(INCLUDE_hcrypto) + +BUILT_SOURCES = \ + $(gen_files_hdb:.x=.c) \ + hdb_err.c \ + hdb_err.h + +gen_files_hdb = \ + asn1_Salt.x \ + asn1_Key.x \ + asn1_Event.x \ + asn1_HDBFlags.x \ + asn1_GENERATION.x \ + asn1_HDB_Ext_PKINIT_acl.x \ + asn1_HDB_Ext_PKINIT_hash.x \ + asn1_HDB_Ext_Constrained_delegation_acl.x \ + asn1_HDB_Ext_Lan_Manager_OWF.x \ + asn1_HDB_Ext_Password.x \ + asn1_HDB_Ext_Aliases.x \ + asn1_HDB_extension.x \ + asn1_HDB_extensions.x \ + asn1_hdb_entry.x \ + asn1_hdb_entry_alias.x + +CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) hdb_asn1.h hdb_asn1_files -BUILT_SOURCES = asn1_Key.c asn1_Event.c asn1_HDBFlags.c asn1_hdb_entry.c \ - asn1_Salt.c hdb_err.c hdb_err.h asn1_GENERATION.c - -foo = asn1_Key.x asn1_GENERATION.x asn1_Event.x asn1_HDBFlags.x asn1_hdb_entry.x asn1_Salt.x - -CLEANFILES = $(BUILT_SOURCES) $(foo) hdb_asn1.h asn1_files - -noinst_PROGRAMS = convert_db LDADD = libhdb.la \ $(LIB_openldap) \ ../krb5/libkrb5.la \ ../asn1/libasn1.la \ - $(LIB_des) \ - $(LIB_roken) + $(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 + +else + +ldap = hdb-ldap.c + +endif + -lib_LTLIBRARIES = libhdb.la -libhdb_la_LDFLAGS = -version-info 7:7:0 +lib_LTLIBRARIES = libhdb.la $(ldap_so) +libhdb_la_LDFLAGS = -version-info 11:0:2 -libhdb_la_SOURCES = \ +noinst_PROGRAMS = test_dbinfo + +dist_libhdb_la_SOURCES = \ common.c \ db.c \ db3.c \ - hdb-ldap.c \ + ext.c \ + $(ldap) \ hdb.c \ + hdb_locl.h \ + hdb-private.h \ + keys.c \ keytab.c \ + dbinfo.c \ mkey.c \ ndbm.c \ - print.c \ - $(BUILT_SOURCES) + print.c + +nodist_libhdb_la_SOURCES = $(BUILT_SOURCES) -INCLUDES += $(INCLUDE_openldap) +AM_CPPFLAGS += $(INCLUDE_openldap) -include_HEADERS = hdb.h hdb_err.h hdb_asn1.h hdb-protos.h hdb-private.h +include_HEADERS = hdb.h hdb-protos.h +nodist_include_HEADERS = hdb_err.h hdb_asn1.h -libhdb_la_LIBADD = ../krb5/libkrb5.la ../asn1/libasn1.la ../roken/libroken.la $(LIB_openldap) $(DBLIB) $(LIB_NDBM) +libhdb_la_CPPFLAGS = -DHDB_DB_DIR=\"$(DIR_hdbdir)\" + +libhdb_la_LIBADD = \ + $(LIB_com_err) \ + ../krb5/libkrb5.la \ + ../asn1/libasn1.la \ + $(LIBADD_roken) \ + $(LIB_openldap) \ + $(LIB_dlopen) \ + $(DBLIB) \ + $(LIB_NDBM) $(libhdb_la_OBJECTS): $(srcdir)/hdb-protos.h $(srcdir)/hdb-private.h $(srcdir)/hdb-protos.h: - cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -o hdb-protos.h $(libhdb_la_SOURCES) || rm -f 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 $(srcdir)/hdb-private.h: - cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -p hdb-private.h $(libhdb_la_SOURCES) || rm -f 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 -$(foo) hdb_asn1.h: asn1_files +$(gen_files_hdb) hdb_asn1.h: hdb_asn1_files -asn1_files: ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 +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 -$(convert_db_OBJECTS): hdb_asn1.h hdb_err.h +test_dbinfo_SOURCES = test_dbinfo.c + +test_dbinfo_LIBS = libhdb.la # to help stupid solaris make hdb_err.h: hdb_err.et + +EXTRA_DIST = hdb.asn1 hdb_err.et hdb.schema diff --git a/crypto/heimdal/lib/hdb/Makefile.in b/crypto/heimdal/lib/hdb/Makefile.in index 28ca7d5..cb0f916 100644 --- a/crypto/heimdal/lib/hdb/Makefile.in +++ b/crypto/heimdal/lib/hdb/Makefile.in @@ -1,8 +1,8 @@ -# Makefile.in generated by automake 1.8.3 from Makefile.am. +# Makefile.in generated by automake 1.10 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, -# 2003, 2004 Free Software Foundation, Inc. +# 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. @@ -14,25 +14,19 @@ @SET_MAKE@ -# $Id: Makefile.am,v 1.53.4.2 2003/10/14 16:13:14 joda Exp $ +# $Id: Makefile.am 22490 2008-01-21 11:49:33Z lha $ -# $Id: Makefile.am.common,v 1.5 2002/05/19 18:35:37 joda Exp $ +# $Id: Makefile.am.common 10998 2002-05-19 18:35:37Z joda $ -# $Id: Makefile.am.common,v 1.37.2.2 2003/10/13 13:15:39 joda Exp $ +# $Id: Makefile.am.common 22488 2008-01-21 11:47:22Z lha $ -SOURCES = $(libhdb_la_SOURCES) convert_db.c - -srcdir = @srcdir@ -top_srcdir = @top_srcdir@ VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ pkgincludedir = $(includedir)/@PACKAGE@ -top_builddir = ../.. am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd -INSTALL = @INSTALL@ install_sh_DATA = $(install_sh) -c -m 644 install_sh_PROGRAM = $(install_sh) -c install_sh_SCRIPT = $(install_sh) -c @@ -44,24 +38,23 @@ POST_INSTALL = : NORMAL_UNINSTALL = : PRE_UNINSTALL = : POST_UNINSTALL = : +build_triplet = @build@ 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 = convert_db$(EXEEXT) +noinst_PROGRAMS = test_dbinfo$(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/auth-modules.m4 $(top_srcdir)/cf/autobuild.m4 \ $(top_srcdir)/cf/broken-getaddrinfo.m4 \ - $(top_srcdir)/cf/broken-getnameinfo.m4 \ $(top_srcdir)/cf/broken-glob.m4 \ $(top_srcdir)/cf/broken-realloc.m4 \ $(top_srcdir)/cf/broken-snprintf.m4 $(top_srcdir)/cf/broken.m4 \ $(top_srcdir)/cf/broken2.m4 $(top_srcdir)/cf/c-attribute.m4 \ $(top_srcdir)/cf/capabilities.m4 \ $(top_srcdir)/cf/check-compile-et.m4 \ - $(top_srcdir)/cf/check-declaration.m4 \ $(top_srcdir)/cf/check-getpwnam_r-posix.m4 \ $(top_srcdir)/cf/check-man.m4 \ $(top_srcdir)/cf/check-netinet-ip-and-tcp.m4 \ @@ -74,6 +67,7 @@ am__aclocal_m4_deps = $(top_srcdir)/cf/aix.m4 \ $(top_srcdir)/cf/find-func-no-libs2.m4 \ $(top_srcdir)/cf/find-func.m4 \ $(top_srcdir)/cf/find-if-not-broken.m4 \ + $(top_srcdir)/cf/framework-security.m4 \ $(top_srcdir)/cf/have-struct-field.m4 \ $(top_srcdir)/cf/have-type.m4 $(top_srcdir)/cf/irix.m4 \ $(top_srcdir)/cf/krb-bigendian.m4 \ @@ -82,63 +76,104 @@ 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/mips-abi.m4 $(top_srcdir)/cf/misc.m4 \ - $(top_srcdir)/cf/need-proto.m4 $(top_srcdir)/cf/osfc2.m4 \ - $(top_srcdir)/cf/otp.m4 $(top_srcdir)/cf/proto-compat.m4 \ - $(top_srcdir)/cf/retsigtype.m4 $(top_srcdir)/cf/roken-frag.m4 \ - $(top_srcdir)/cf/sunos.m4 $(top_srcdir)/cf/telnet.m4 \ - $(top_srcdir)/cf/test-package.m4 $(top_srcdir)/cf/wflags.m4 \ - $(top_srcdir)/cf/with-all.m4 $(top_srcdir)/configure.in + $(top_srcdir)/cf/largefile.m4 $(top_srcdir)/cf/mips-abi.m4 \ + $(top_srcdir)/cf/misc.m4 $(top_srcdir)/cf/need-proto.m4 \ + $(top_srcdir)/cf/osfc2.m4 $(top_srcdir)/cf/otp.m4 \ + $(top_srcdir)/cf/proto-compat.m4 $(top_srcdir)/cf/pthreads.m4 \ + $(top_srcdir)/cf/resolv.m4 $(top_srcdir)/cf/retsigtype.m4 \ + $(top_srcdir)/cf/roken-frag.m4 \ + $(top_srcdir)/cf/socket-wrapper.m4 $(top_srcdir)/cf/sunos.m4 \ + $(top_srcdir)/cf/telnet.m4 $(top_srcdir)/cf/test-package.m4 \ + $(top_srcdir)/cf/version-script.m4 $(top_srcdir)/cf/wflags.m4 \ + $(top_srcdir)/cf/win32.m4 $(top_srcdir)/cf/with-all.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) -mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +mkinstalldirs = $(install_sh) -d CONFIG_HEADER = $(top_builddir)/include/config.h CONFIG_CLEAN_FILES = -am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" +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__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" \ + "$(DESTDIR)$(includedir)" libLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(lib_LTLIBRARIES) +hdb_ldap_la_LIBADD = +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) +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 = ../krb5/libkrb5.la ../asn1/libasn1.la \ - ../roken/libroken.la $(am__DEPENDENCIES_1) \ - $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) -am__objects_1 = asn1_Key.lo asn1_Event.lo asn1_HDBFlags.lo \ - asn1_hdb_entry.lo asn1_Salt.lo hdb_err.lo asn1_GENERATION.lo -am_libhdb_la_OBJECTS = common.lo db.lo db3.lo hdb-ldap.lo hdb.lo \ - keytab.lo mkey.lo ndbm.lo print.lo $(am__objects_1) -libhdb_la_OBJECTS = $(am_libhdb_la_OBJECTS) +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) +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 +nodist_libhdb_la_OBJECTS = $(am__objects_3) +libhdb_la_OBJECTS = $(dist_libhdb_la_OBJECTS) \ + $(nodist_libhdb_la_OBJECTS) +libhdb_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libhdb_la_LDFLAGS) $(LDFLAGS) -o $@ PROGRAMS = $(noinst_PROGRAMS) -convert_db_SOURCES = convert_db.c -convert_db_OBJECTS = convert_db.$(OBJEXT) -convert_db_LDADD = $(LDADD) -convert_db_DEPENDENCIES = libhdb.la $(am__DEPENDENCIES_1) \ +am_test_dbinfo_OBJECTS = test_dbinfo.$(OBJEXT) +test_dbinfo_OBJECTS = $(am_test_dbinfo_OBJECTS) +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$(srcdir) -I$(top_builddir)/include +DEFAULT_INCLUDES = -I. -I$(top_builddir)/include@am__isrc@ depcomp = am__depfiles_maybe = COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) CCLD = $(CC) -LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -SOURCES = $(libhdb_la_SOURCES) convert_db.c -DIST_SOURCES = $(libhdb_la_SOURCES) convert_db.c +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) +DIST_SOURCES = $(am__hdb_ldap_la_SOURCES_DIST) \ + $(am__dist_libhdb_la_SOURCES_DIST) $(test_dbinfo_SOURCES) includeHEADERS_INSTALL = $(INSTALL_HEADER) -HEADERS = $(include_HEADERS) +nodist_includeHEADERS_INSTALL = $(INSTALL_HEADER) +HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) ETAGS = etags CTAGS = ctags DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) ACLOCAL = @ACLOCAL@ -AIX4_FALSE = @AIX4_FALSE@ -AIX4_TRUE = @AIX4_TRUE@ -AIX_DYNAMIC_AFS_FALSE = @AIX_DYNAMIC_AFS_FALSE@ -AIX_DYNAMIC_AFS_TRUE = @AIX_DYNAMIC_AFS_TRUE@ AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@ -AIX_FALSE = @AIX_FALSE@ -AIX_TRUE = @AIX_TRUE@ AMTAR = @AMTAR@ AR = @AR@ AUTOCONF = @AUTOCONF@ @@ -148,8 +183,6 @@ AWK = @AWK@ CANONICAL_HOST = @CANONICAL_HOST@ CATMAN = @CATMAN@ CATMANEXT = @CATMANEXT@ -CATMAN_FALSE = @CATMAN_FALSE@ -CATMAN_TRUE = @CATMAN_TRUE@ CC = @CC@ CFLAGS = @CFLAGS@ COMPILE_ET = @COMPILE_ET@ @@ -160,11 +193,10 @@ CXXCPP = @CXXCPP@ CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DBLIB = @DBLIB@ -DCE_FALSE = @DCE_FALSE@ -DCE_TRUE = @DCE_TRUE@ DEFS = @DEFS@ DIR_com_err = @DIR_com_err@ -DIR_des = @DIR_des@ +DIR_hcrypto = @DIR_hcrypto@ +DIR_hdbdir = @DIR_hdbdir@ DIR_roken = @DIR_roken@ ECHO = @ECHO@ ECHO_C = @ECHO_C@ @@ -172,42 +204,27 @@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -EXTRA_LIB45 = @EXTRA_LIB45@ F77 = @F77@ FFLAGS = @FFLAGS@ +GREP = @GREP@ GROFF = @GROFF@ -HAVE_DB1_FALSE = @HAVE_DB1_FALSE@ -HAVE_DB1_TRUE = @HAVE_DB1_TRUE@ -HAVE_DB3_FALSE = @HAVE_DB3_FALSE@ -HAVE_DB3_TRUE = @HAVE_DB3_TRUE@ -HAVE_DLOPEN_FALSE = @HAVE_DLOPEN_FALSE@ -HAVE_DLOPEN_TRUE = @HAVE_DLOPEN_TRUE@ -HAVE_NDBM_FALSE = @HAVE_NDBM_FALSE@ -HAVE_NDBM_TRUE = @HAVE_NDBM_TRUE@ -HAVE_OPENSSL_FALSE = @HAVE_OPENSSL_FALSE@ -HAVE_OPENSSL_TRUE = @HAVE_OPENSSL_TRUE@ -HAVE_X_FALSE = @HAVE_X_FALSE@ -HAVE_X_TRUE = @HAVE_X_TRUE@ INCLUDES_roken = @INCLUDES_roken@ -INCLUDE_des = @INCLUDE_des@ +INCLUDE_hcrypto = @INCLUDE_hcrypto@ INCLUDE_hesiod = @INCLUDE_hesiod@ INCLUDE_krb4 = @INCLUDE_krb4@ INCLUDE_openldap = @INCLUDE_openldap@ INCLUDE_readline = @INCLUDE_readline@ +INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ -IRIX_FALSE = @IRIX_FALSE@ -IRIX_TRUE = @IRIX_TRUE@ -KRB4_FALSE = @KRB4_FALSE@ -KRB4_TRUE = @KRB4_TRUE@ -KRB5_FALSE = @KRB5_FALSE@ -KRB5_TRUE = @KRB5_TRUE@ LDFLAGS = @LDFLAGS@ +LDFLAGS_VERSION_SCRIPT = @LDFLAGS_VERSION_SCRIPT@ LEX = @LEX@ LEXLIB = @LEXLIB@ LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@ +LIBADD_roken = @LIBADD_roken@ LIBOBJS = @LIBOBJS@ LIBS = @LIBS@ LIBTOOL = @LIBTOOL@ @@ -225,12 +242,9 @@ LIB_crypt = @LIB_crypt@ LIB_db_create = @LIB_db_create@ LIB_dbm_firstkey = @LIB_dbm_firstkey@ LIB_dbopen = @LIB_dbopen@ -LIB_des = @LIB_des@ -LIB_des_a = @LIB_des_a@ -LIB_des_appl = @LIB_des_appl@ -LIB_des_so = @LIB_des_so@ LIB_dlopen = @LIB_dlopen@ LIB_dn_expand = @LIB_dn_expand@ +LIB_door_create = @LIB_door_create@ LIB_el_init = @LIB_el_init@ LIB_freeaddrinfo = @LIB_freeaddrinfo@ LIB_gai_strerror = @LIB_gai_strerror@ @@ -240,15 +254,14 @@ LIB_gethostbyname2 = @LIB_gethostbyname2@ LIB_getnameinfo = @LIB_getnameinfo@ LIB_getpwnam_r = @LIB_getpwnam_r@ LIB_getsockopt = @LIB_getsockopt@ +LIB_hcrypto = @LIB_hcrypto@ +LIB_hcrypto_a = @LIB_hcrypto_a@ +LIB_hcrypto_appl = @LIB_hcrypto_appl@ +LIB_hcrypto_so = @LIB_hcrypto_so@ LIB_hesiod = @LIB_hesiod@ LIB_hstrerror = @LIB_hstrerror@ LIB_kdb = @LIB_kdb@ LIB_krb4 = @LIB_krb4@ -LIB_krb_disable_debug = @LIB_krb_disable_debug@ -LIB_krb_enable_debug = @LIB_krb_enable_debug@ -LIB_krb_get_kdc_time_diff = @LIB_krb_get_kdc_time_diff@ -LIB_krb_get_our_ip_for_realm = @LIB_krb_get_our_ip_for_realm@ -LIB_krb_kdctimeofday = @LIB_krb_kdctimeofday@ LIB_loadquery = @LIB_loadquery@ LIB_logout = @LIB_logout@ LIB_logwtmp = @LIB_logwtmp@ @@ -257,6 +270,7 @@ LIB_openpty = @LIB_openpty@ LIB_otp = @LIB_otp@ LIB_pidfile = @LIB_pidfile@ LIB_readline = @LIB_readline@ +LIB_res_ndestroy = @LIB_res_ndestroy@ LIB_res_nsearch = @LIB_res_nsearch@ LIB_res_search = @LIB_res_search@ LIB_roken = @LIB_roken@ @@ -268,15 +282,10 @@ LIB_tgetent = @LIB_tgetent@ LN_S = @LN_S@ LTLIBOBJS = @LTLIBOBJS@ MAINT = @MAINT@ -MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@ -MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@ MAKEINFO = @MAKEINFO@ -NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@ -NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@ +MKDIR_P = @MKDIR_P@ NROFF = @NROFF@ OBJEXT = @OBJEXT@ -OTP_FALSE = @OTP_FALSE@ -OTP_TRUE = @OTP_TRUE@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ @@ -284,74 +293,80 @@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ +PTHREADS_CFLAGS = @PTHREADS_CFLAGS@ +PTHREADS_LIBS = @PTHREADS_LIBS@ RANLIB = @RANLIB@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STRIP = @STRIP@ VERSION = @VERSION@ +VERSIONING = @VERSIONING@ VOID_RETSIGTYPE = @VOID_RETSIGTYPE@ WFLAGS = @WFLAGS@ WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@ WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@ +XMKMF = @XMKMF@ X_CFLAGS = @X_CFLAGS@ X_EXTRA_LIBS = @X_EXTRA_LIBS@ X_LIBS = @X_LIBS@ X_PRE_LIBS = @X_PRE_LIBS@ YACC = @YACC@ -ac_ct_AR = @ac_ct_AR@ +YFLAGS = @YFLAGS@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ ac_ct_CXX = @ac_ct_CXX@ ac_ct_F77 = @ac_ct_F77@ -ac_ct_RANLIB = @ac_ct_RANLIB@ -ac_ct_STRIP = @ac_ct_STRIP@ am__leading_dot = @am__leading_dot@ +am__tar = @am__tar@ +am__untar = @am__untar@ bindir = @bindir@ build = @build@ build_alias = @build_alias@ build_cpu = @build_cpu@ build_os = @build_os@ build_vendor = @build_vendor@ +builddir = @builddir@ datadir = @datadir@ -do_roken_rename_FALSE = @do_roken_rename_FALSE@ -do_roken_rename_TRUE = @do_roken_rename_TRUE@ +datarootdir = @datarootdir@ +docdir = @docdir@ dpagaix_cflags = @dpagaix_cflags@ dpagaix_ldadd = @dpagaix_ldadd@ dpagaix_ldflags = @dpagaix_ldflags@ -el_compat_FALSE = @el_compat_FALSE@ -el_compat_TRUE = @el_compat_TRUE@ +dvidir = @dvidir@ exec_prefix = @exec_prefix@ -have_err_h_FALSE = @have_err_h_FALSE@ -have_err_h_TRUE = @have_err_h_TRUE@ -have_fnmatch_h_FALSE = @have_fnmatch_h_FALSE@ -have_fnmatch_h_TRUE = @have_fnmatch_h_TRUE@ -have_glob_h_FALSE = @have_glob_h_FALSE@ -have_glob_h_TRUE = @have_glob_h_TRUE@ -have_ifaddrs_h_FALSE = @have_ifaddrs_h_FALSE@ -have_ifaddrs_h_TRUE = @have_ifaddrs_h_TRUE@ -have_vis_h_FALSE = @have_vis_h_FALSE@ -have_vis_h_TRUE = @have_vis_h_TRUE@ host = @host@ host_alias = @host_alias@ host_cpu = @host_cpu@ host_os = @host_os@ host_vendor = @host_vendor@ +htmldir = @htmldir@ includedir = @includedir@ infodir = @infodir@ install_sh = @install_sh@ libdir = @libdir@ libexecdir = @libexecdir@ +localedir = @localedir@ localstatedir = @localstatedir@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ prefix = @prefix@ program_transform_name = @program_transform_name@ +psdir = @psdir@ sbindir = @sbindir@ sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ -SUFFIXES = .et .h .x .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 -INCLUDES = -I$(top_builddir)/include $(INCLUDES_roken) -I../asn1 -I$(srcdir)/../asn1 $(INCLUDE_des) $(INCLUDE_openldap) +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) @do_roken_rename_TRUE@ROKEN_RENAME = -DROKEN_RENAME AM_CFLAGS = $(WFLAGS) CP = cp @@ -368,40 +383,83 @@ LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS) @KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la @KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la +@KRB5_TRUE@LIB_tsasl = $(top_builddir)/lib/tsasl/libtsasl.la @DCE_TRUE@LIB_kdfs = $(top_builddir)/lib/kdfs/libkdfs.la -BUILT_SOURCES = asn1_Key.c asn1_Event.c asn1_HDBFlags.c asn1_hdb_entry.c \ - asn1_Salt.c hdb_err.c hdb_err.h asn1_GENERATION.c - -foo = asn1_Key.x asn1_GENERATION.x asn1_Event.x asn1_HDBFlags.x asn1_hdb_entry.x asn1_Salt.x -CLEANFILES = $(BUILT_SOURCES) $(foo) hdb_asn1.h asn1_files +BUILT_SOURCES = \ + $(gen_files_hdb:.x=.c) \ + hdb_err.c \ + hdb_err.h + +gen_files_hdb = \ + asn1_Salt.x \ + asn1_Key.x \ + asn1_Event.x \ + asn1_HDBFlags.x \ + asn1_GENERATION.x \ + asn1_HDB_Ext_PKINIT_acl.x \ + asn1_HDB_Ext_PKINIT_hash.x \ + asn1_HDB_Ext_Constrained_delegation_acl.x \ + asn1_HDB_Ext_Lan_Manager_OWF.x \ + asn1_HDB_Ext_Password.x \ + asn1_HDB_Ext_Aliases.x \ + asn1_HDB_extension.x \ + asn1_HDB_extensions.x \ + asn1_hdb_entry.x \ + asn1_hdb_entry_alias.x + +CLEANFILES = $(BUILT_SOURCES) $(gen_files_hdb) hdb_asn1.h hdb_asn1_files LDADD = libhdb.la \ $(LIB_openldap) \ ../krb5/libkrb5.la \ ../asn1/libasn1.la \ - $(LIB_des) \ - $(LIB_roken) - -lib_LTLIBRARIES = libhdb.la -libhdb_la_LDFLAGS = -version-info 7:7:0 -libhdb_la_SOURCES = \ + $(LIB_hcrypto) \ + $(LIB_roken) \ + $(LIB_ldopen) + +@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_FALSE@ldap = hdb-ldap.c +lib_LTLIBRARIES = libhdb.la $(ldap_so) +libhdb_la_LDFLAGS = -version-info 11:0:2 +dist_libhdb_la_SOURCES = \ common.c \ db.c \ db3.c \ - hdb-ldap.c \ + ext.c \ + $(ldap) \ hdb.c \ + hdb_locl.h \ + hdb-private.h \ + keys.c \ keytab.c \ + dbinfo.c \ mkey.c \ ndbm.c \ - print.c \ - $(BUILT_SOURCES) + print.c + +nodist_libhdb_la_SOURCES = $(BUILT_SOURCES) +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 \ + $(LIBADD_roken) \ + $(LIB_openldap) \ + $(LIB_dlopen) \ + $(DBLIB) \ + $(LIB_NDBM) -include_HEADERS = hdb.h hdb_err.h hdb_asn1.h hdb-protos.h hdb-private.h -libhdb_la_LIBADD = ../krb5/libkrb5.la ../asn1/libasn1.la ../roken/libroken.la $(LIB_openldap) $(DBLIB) $(LIB_NDBM) +test_dbinfo_SOURCES = test_dbinfo.c +test_dbinfo_LIBS = libhdb.la +EXTRA_DIST = hdb.asn1 hdb_err.et hdb.schema all: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) all-am .SUFFIXES: -.SUFFIXES: .et .h .x .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj +.SUFFIXES: .et .h .x .z .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .c .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -433,10 +491,10 @@ $(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh install-libLTLIBRARIES: $(lib_LTLIBRARIES) @$(NORMAL_INSTALL) - test -z "$(libdir)" || $(mkdir_p) "$(DESTDIR)$(libdir)" + test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)" @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ if test -f $$p; then \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ + 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"; \ else :; fi; \ @@ -445,7 +503,7 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES) uninstall-libLTLIBRARIES: @$(NORMAL_UNINSTALL) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ - p="`echo $$p | sed -e 's|^.*/||'`"; \ + p=$(am__strip_dir) \ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$p'"; \ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$p"; \ done @@ -454,12 +512,14 @@ clean-libLTLIBRARIES: -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES) @list='$(lib_LTLIBRARIES)'; for p in $$list; do \ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \ - test "$$dir" = "$$p" && dir=.; \ + test "$$dir" != "$$p" || dir=.; \ echo "rm -f \"$${dir}/so_locations\""; \ rm -f "$${dir}/so_locations"; \ done +hdb_ldap.la: $(hdb_ldap_la_OBJECTS) $(hdb_ldap_la_DEPENDENCIES) + $(hdb_ldap_la_LINK) $(am_hdb_ldap_la_rpath) $(hdb_ldap_la_OBJECTS) $(hdb_ldap_la_LIBADD) $(LIBS) libhdb.la: $(libhdb_la_OBJECTS) $(libhdb_la_DEPENDENCIES) - $(LINK) -rpath $(libdir) $(libhdb_la_LDFLAGS) $(libhdb_la_OBJECTS) $(libhdb_la_LIBADD) $(LIBS) + $(libhdb_la_LINK) -rpath $(libdir) $(libhdb_la_OBJECTS) $(libhdb_la_LIBADD) $(LIBS) clean-noinstPROGRAMS: @list='$(noinst_PROGRAMS)'; for p in $$list; do \ @@ -467,9 +527,9 @@ clean-noinstPROGRAMS: echo " rm -f $$p $$f"; \ rm -f $$p $$f ; \ done -convert_db$(EXEEXT): $(convert_db_OBJECTS) $(convert_db_DEPENDENCIES) - @rm -f convert_db$(EXEEXT) - $(LINK) $(convert_db_LDFLAGS) $(convert_db_OBJECTS) $(convert_db_LDADD) $(LIBS) +test_dbinfo$(EXEEXT): $(test_dbinfo_OBJECTS) $(test_dbinfo_DEPENDENCIES) + @rm -f test_dbinfo$(EXEEXT) + $(LINK) $(test_dbinfo_OBJECTS) $(test_dbinfo_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -486,21 +546,101 @@ distclean-compile: .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 + mostlyclean-libtool: -rm -f *.lo clean-libtool: -rm -rf .libs _libs - -distclean-libtool: - -rm -f libtool -uninstall-info-am: install-includeHEADERS: $(include_HEADERS) @$(NORMAL_INSTALL) - test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)" + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" @list='$(include_HEADERS)'; for p in $$list; do \ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ + f=$(am__strip_dir) \ echo " $(includeHEADERS_INSTALL) '$$d$$p' '$(DESTDIR)$(includedir)/$$f'"; \ $(includeHEADERS_INSTALL) "$$d$$p" "$(DESTDIR)$(includedir)/$$f"; \ done @@ -508,7 +648,24 @@ install-includeHEADERS: $(include_HEADERS) uninstall-includeHEADERS: @$(NORMAL_UNINSTALL) @list='$(include_HEADERS)'; for p in $$list; do \ - f="`echo $$p | sed -e 's|^.*/||'`"; \ + f=$(am__strip_dir) \ + echo " rm -f '$(DESTDIR)$(includedir)/$$f'"; \ + rm -f "$(DESTDIR)$(includedir)/$$f"; \ + done +install-nodist_includeHEADERS: $(nodist_include_HEADERS) + @$(NORMAL_INSTALL) + test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)" + @list='$(nodist_include_HEADERS)'; 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"; \ + 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 @@ -533,9 +690,11 @@ TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ done | \ $(AWK) ' { files[$$0] = 1; } \ END { for (i in files) print i; }'`; \ - test -z "$(ETAGS_ARGS)$$tags$$unique" \ - || $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ - $$tags $$unique + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi ctags: CTAGS CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ $(TAGS_FILES) $(LISP) @@ -560,23 +719,21 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags distdir: $(DISTFILES) - $(mkdir_p) $(distdir)/../.. $(distdir)/../../cf - @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \ - topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \ - list='$(DISTFILES)'; for file in $$list; do \ - case $$file in \ - $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \ - $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \ - esac; \ + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ - dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \ - if test "$$dir" != "$$file" && test "$$dir" != "."; then \ - dir="/$$dir"; \ - $(mkdir_p) "$(distdir)$$dir"; \ - else \ - dir=''; \ - fi; \ if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ fi; \ @@ -596,8 +753,8 @@ check: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) check-am all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local installdirs: - for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \ - test -z "$$dir" || $(mkdir_p) "$$dir"; \ + for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)" "$(DESTDIR)$(includedir)"; do \ + test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: $(BUILT_SOURCES) $(MAKE) $(AM_MAKEFLAGS) install-am @@ -620,7 +777,7 @@ clean-generic: -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean-generic: - -rm -f $(CONFIG_CLEAN_FILES) + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) maintainer-clean-generic: @echo "This command is intended for maintainers to use" @@ -634,7 +791,7 @@ clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \ distclean: distclean-am -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ - distclean-libtool distclean-tags + distclean-tags dvi: dvi-am @@ -646,18 +803,26 @@ info: info-am info-am: -install-data-am: install-includeHEADERS +install-data-am: install-includeHEADERS install-nodist_includeHEADERS @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-data-hook +install-dvi: install-dvi-am + install-exec-am: install-libLTLIBRARIES @$(NORMAL_INSTALL) $(MAKE) $(AM_MAKEFLAGS) install-exec-hook +install-html: install-html-am + install-info: install-info-am install-man: +install-pdf: install-pdf-am + +install-ps: install-ps-am + installcheck-am: maintainer-clean: maintainer-clean-am @@ -677,22 +842,32 @@ ps: ps-am ps-am: -uninstall-am: uninstall-includeHEADERS uninstall-info-am \ - uninstall-libLTLIBRARIES +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 .PHONY: CTAGS GTAGS all all-am all-local check check-am check-local \ clean clean-generic clean-libLTLIBRARIES clean-libtool \ - clean-noinstPROGRAMS ctags distclean distclean-compile \ - distclean-generic distclean-libtool distclean-tags distdir dvi \ - dvi-am html html-am info info-am install install-am \ - install-data install-data-am install-exec install-exec-am \ + clean-noinstPROGRAMS ctags dist-hook distclean \ + distclean-compile distclean-generic distclean-libtool \ + distclean-tags distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am \ + install-data-hook install-dvi install-dvi-am install-exec \ + install-exec-am install-exec-hook install-html install-html-am \ install-includeHEADERS install-info install-info-am \ - install-libLTLIBRARIES install-man install-strip installcheck \ + install-libLTLIBRARIES install-man \ + install-nodist_includeHEADERS install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ installcheck-am installdirs maintainer-clean \ maintainer-clean-generic mostlyclean mostlyclean-compile \ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags uninstall uninstall-am uninstall-includeHEADERS \ - uninstall-info-am uninstall-libLTLIBRARIES + tags uninstall uninstall-am uninstall-hook \ + uninstall-includeHEADERS uninstall-libLTLIBRARIES \ + uninstall-nodist_includeHEADERS install-suid-programs: @@ -707,8 +882,8 @@ install-suid-programs: install-exec-hook: install-suid-programs -install-build-headers:: $(include_HEADERS) $(build_HEADERZ) - @foo='$(include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \ +install-build-headers:: $(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ) $(nobase_include_HEADERS) + @foo='$(include_HEADERS) $(dist_include_HEADERS) $(nodist_include_HEADERS) $(build_HEADERZ)'; \ for f in $$foo; do \ f=`basename $$f`; \ if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ @@ -718,19 +893,31 @@ install-build-headers:: $(include_HEADERS) $(build_HEADERZ) echo " $(CP) $$file $(buildinclude)/$$f"; \ $(CP) $$file $(buildinclude)/$$f; \ fi ; \ + done ; \ + foo='$(nobase_include_HEADERS)'; \ + for f in $$foo; do \ + if test -f "$(srcdir)/$$f"; then file="$(srcdir)/$$f"; \ + else file="$$f"; fi; \ + $(mkdir_p) $(buildinclude)/`dirname $$f` ; \ + if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \ + : ; else \ + echo " $(CP) $$file $(buildinclude)/$$f"; \ + $(CP) $$file $(buildinclude)/$$f; \ + fi ; \ done all-local: install-build-headers check-local:: - @if test '$(CHECK_LOCAL)'; then \ + @if test '$(CHECK_LOCAL)' = "no-check-local"; then \ + foo=''; elif test '$(CHECK_LOCAL)'; then \ foo='$(CHECK_LOCAL)'; else \ foo='$(PROGRAMS)'; fi; \ if test "$$foo"; then \ failed=0; all=0; \ for i in $$foo; do \ all=`expr $$all + 1`; \ - if ./$$i --version > /dev/null 2>&1; then \ + if (./$$i --version && ./$$i --help) > /dev/null 2>&1; then \ echo "PASS: $$i"; \ else \ echo "FAIL: $$i"; \ @@ -746,7 +933,7 @@ check-local:: echo "$$dashes"; \ echo "$$banner"; \ echo "$$dashes"; \ - test "$$failed" -eq 0; \ + test "$$failed" -eq 0 || exit 1; \ fi .x.c: @@ -816,32 +1003,55 @@ dist-cat8-mans: dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans install-cat-mans: - $(SHELL) $(top_srcdir)/cf/install-catman.sh "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + $(SHELL) $(top_srcdir)/cf/install-catman.sh install "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) + +uninstall-cat-mans: + $(SHELL) $(top_srcdir)/cf/install-catman.sh uninstall "$(INSTALL_DATA)" "$(mkinstalldirs)" "$(srcdir)" "$(DESTDIR)$(mandir)" '$(CATMANEXT)' $(man_MANS) $(man1_MANS) $(man3_MANS) $(man5_MANS) $(man8_MANS) install-data-hook: install-cat-mans +uninstall-hook: uninstall-cat-mans .et.h: $(COMPILE_ET) $< .et.c: $(COMPILE_ET) $< +# +# Useful target for debugging +# + +check-valgrind: + tobjdir=`cd $(top_builddir) && pwd` ; \ + tsrcdir=`cd $(top_srcdir) && pwd` ; \ + env TESTS_ENVIRONMENT="$${tobjdir}/libtool --mode execute valgrind --leak-check=full --trace-children=yes --quiet -q --num-callers=30 --suppressions=$${tsrcdir}/cf/valgrind-suppressions" make check + +# +# Target to please samba build farm, builds distfiles in-tree. +# Will break when automake changes... +# + +distdir-in-tree: $(DISTFILES) $(INFO_DEPS) + list='$(DIST_SUBDIRS)'; for subdir in $$list; do \ + if test "$$subdir" != .; then \ + (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) distdir-in-tree) ; \ + fi ; \ + done + $(libhdb_la_OBJECTS): $(srcdir)/hdb-protos.h $(srcdir)/hdb-private.h $(srcdir)/hdb-protos.h: - cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -o hdb-protos.h $(libhdb_la_SOURCES) || rm -f 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 $(srcdir)/hdb-private.h: - cd $(srcdir); perl ../../cf/make-proto.pl -q -P comment -p hdb-private.h $(libhdb_la_SOURCES) || rm -f 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 -$(foo) hdb_asn1.h: asn1_files +$(gen_files_hdb) hdb_asn1.h: hdb_asn1_files -asn1_files: ../asn1/asn1_compile$(EXEEXT) $(srcdir)/hdb.asn1 +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 -$(convert_db_OBJECTS): hdb_asn1.h hdb_err.h - # to help stupid solaris make hdb_err.h: hdb_err.et diff --git a/crypto/heimdal/lib/hdb/common.c b/crypto/heimdal/lib/hdb/common.c index 6f0e730..680b666 100644 --- a/crypto/heimdal/lib/hdb/common.c +++ b/crypto/heimdal/lib/hdb/common.c @@ -33,10 +33,10 @@ #include "hdb_locl.h" -RCSID("$Id: common.c,v 1.12 2003/01/14 06:54:32 lha Exp $"); +RCSID("$Id: common.c 20236 2007-02-16 23:52:29Z lha $"); int -hdb_principal2key(krb5_context context, krb5_principal p, krb5_data *key) +hdb_principal2key(krb5_context context, krb5_const_principal p, krb5_data *key) { Principal new; size_t len; @@ -48,6 +48,8 @@ hdb_principal2key(krb5_context context, krb5_principal p, krb5_data *key) new.name.name_type = 0; ASN1_MALLOC_ENCODE(Principal, key->data, key->length, &new, &len, ret); + if (ret == 0 && key->length != len) + krb5_abortx(context, "internal asn.1 encoder error"); free_Principal(&new); return ret; } @@ -59,12 +61,14 @@ hdb_key2principal(krb5_context context, krb5_data *key, krb5_principal p) } int -hdb_entry2value(krb5_context context, hdb_entry *ent, krb5_data *value) +hdb_entry2value(krb5_context context, const hdb_entry *ent, krb5_data *value) { size_t len; 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"); return ret; } @@ -74,69 +78,205 @@ hdb_value2entry(krb5_context context, krb5_data *value, hdb_entry *ent) return decode_hdb_entry(value->data, value->length, ent, NULL); } +int +hdb_entry_alias2value(krb5_context context, + const hdb_entry_alias *alias, + krb5_data *value) +{ + size_t len; + int ret; + + 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"); + return ret; +} + +int +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, unsigned flags, hdb_entry *entry) +_hdb_fetch(krb5_context context, HDB *db, krb5_const_principal principal, + unsigned flags, hdb_entry_ex *entry) { krb5_data key, value; int code; - hdb_principal2key(context, entry->principal, &key); - code = db->_get(context, db, key, &value); + hdb_principal2key(context, principal, &key); + code = db->hdb__get(context, db, key, &value); krb5_data_free(&key); if(code) return code; - code = hdb_value2entry(context, &value, entry); + code = hdb_value2entry(context, &value, &entry->entry); + if (code == ASN1_BAD_ID && (flags & HDB_F_CANON) == 0) { + krb5_data_free(&value); + return HDB_ERR_NOENTRY; + } else if (code == ASN1_BAD_ID) { + hdb_entry_alias alias; + + code = hdb_value2entry_alias(context, &value, &alias); + if (code) { + krb5_data_free(&value); + return code; + } + hdb_principal2key(context, alias.principal, &key); + krb5_data_free(&value); + free_hdb_entry_alias(&alias); + + code = db->hdb__get(context, db, key, &value); + krb5_data_free(&key); + if (code) + return code; + code = hdb_value2entry(context, &value, &entry->entry); + if (code) { + krb5_data_free(&value); + return code; + } + } krb5_data_free(&value); - if (code) - return code; - if (db->master_key_set && (flags & HDB_F_DECRYPT)) { - code = hdb_unseal_keys (context, db, entry); + 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 +hdb_remove_aliases(krb5_context context, HDB *db, krb5_data *key) +{ + const HDB_Ext_Aliases *aliases; + krb5_error_code code; + hdb_entry oldentry; + krb5_data value; + int 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) + return code; + + code = hdb_entry_get_aliases(&oldentry, &aliases); + if (code || aliases == NULL) { + free_hdb_entry(&oldentry); + return code; + } + for (i = 0; i < aliases->aliases.len; i++) { + krb5_data akey; + + hdb_principal2key(context, &aliases->aliases.val[i], &akey); + code = db->hdb__del(context, db, akey); + krb5_data_free(&akey); + if (code) { + free_hdb_entry(&oldentry); + return code; + } + } + free_hdb_entry(&oldentry); + return 0; +} + +static krb5_error_code +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; + + 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) { + krb5_data_free(&key); + return code; + } + code = db->hdb__put(context, db, flags, key, value); + krb5_data_free(&key); + krb5_data_free(&value); + if (code) + return code; + } + return 0; +} + krb5_error_code -_hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) +_hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { krb5_data key, value; int code; - if(entry->generation == NULL) { + if(entry->entry.generation == NULL) { struct timeval t; - entry->generation = malloc(sizeof(*entry->generation)); - if(entry->generation == NULL) { + entry->entry.generation = malloc(sizeof(*entry->entry.generation)); + if(entry->entry.generation == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } gettimeofday(&t, NULL); - entry->generation->time = t.tv_sec; - entry->generation->usec = t.tv_usec; - entry->generation->gen = 0; + entry->entry.generation->time = t.tv_sec; + entry->entry.generation->usec = t.tv_usec; + entry->entry.generation->gen = 0; } else - entry->generation->gen++; - hdb_principal2key(context, entry->principal, &key); - code = hdb_seal_keys(context, db, entry); + 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); + return code; + } + + /* remove aliases */ + code = hdb_remove_aliases(context, db, &key); if (code) { krb5_data_free(&key); return code; } - hdb_entry2value(context, entry, &value); - code = db->_put(context, db, flags & HDB_F_REPLACE, key, value); + hdb_entry2value(context, &entry->entry, &value); + code = db->hdb__put(context, db, flags & HDB_F_REPLACE, key, value); krb5_data_free(&value); krb5_data_free(&key); + if (code) + return code; + + code = hdb_add_aliases(context, db, flags, entry); + return code; } krb5_error_code -_hdb_remove(krb5_context context, HDB *db, hdb_entry *entry) +_hdb_remove(krb5_context context, HDB *db, krb5_const_principal principal) { krb5_data key; int code; - hdb_principal2key(context, entry->principal, &key); - code = db->_del(context, db, key); + hdb_principal2key(context, principal, &key); + + code = hdb_remove_aliases(context, db, &key); + if (code) { + krb5_data_free(&key); + return code; + } + code = db->hdb__del(context, db, key); krb5_data_free(&key); return code; } diff --git a/crypto/heimdal/lib/hdb/db.c b/crypto/heimdal/lib/hdb/db.c index 4dfbc66..870f043 100644 --- a/crypto/heimdal/lib/hdb/db.c +++ b/crypto/heimdal/lib/hdb/db.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: db.c,v 1.30 2001/08/09 08:41:48 assar Exp $"); +RCSID("$Id: db.c 20215 2007-02-09 21:59:53Z lha $"); #if HAVE_DB1 @@ -46,8 +46,8 @@ RCSID("$Id: db.c,v 1.30 2001/08/09 08:41:48 assar Exp $"); static krb5_error_code DB_close(krb5_context context, HDB *db) { - DB *d = (DB*)db->db; - d->close(d); + DB *d = (DB*)db->hdb_db; + (*d->close)(d); return 0; } @@ -57,7 +57,7 @@ DB_destroy(krb5_context context, HDB *db) krb5_error_code ret; ret = hdb_clear_master_key (context, db); - free(db->name); + free(db->hdb_name); free(db); return ret; } @@ -65,62 +65,77 @@ DB_destroy(krb5_context context, HDB *db) static krb5_error_code DB_lock(krb5_context context, HDB *db, int operation) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); - if(fd < 0) + if(fd < 0) { + krb5_set_error_string(context, + "Can't lock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; + } return hdb_lock(fd, operation); } static krb5_error_code DB_unlock(krb5_context context, HDB *db) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; int fd = (*d->fd)(d); - if(fd < 0) + if(fd < 0) { + krb5_set_error_string(context, + "Can't unlock database: %s", db->hdb_name); return HDB_ERR_CANT_LOCK_DB; + } return hdb_unlock(fd); } static krb5_error_code DB_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry *entry, int flag) + unsigned flags, hdb_entry_ex *entry, int flag) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; DBT key, value; krb5_data key_data, data; int code; - code = db->lock(context, db, HDB_RLOCK); - if(code == -1) + code = db->hdb_lock(context, db, HDB_RLOCK); + if(code == -1) { + krb5_set_error_string(context, "Database %s in use", db->hdb_name); return HDB_ERR_DB_INUSE; - code = d->seq(d, &key, &value, flag); - db->unlock(context, db); /* XXX check value */ - if(code == -1) - return errno; - if(code == 1) + } + 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)); + return code; + } + if(code == 1) { + krb5_clear_error_string(context); return HDB_ERR_NOENTRY; + } key_data.data = key.data; key_data.length = key.size; data.data = value.data; data.length = value.size; - if (hdb_value2entry(context, &data, entry)) + memset(entry, 0, sizeof(*entry)); + if (hdb_value2entry(context, &data, &entry->entry)) return DB_seq(context, db, flags, entry, R_NEXT); - if (db->master_key_set && (flags & HDB_F_DECRYPT)) { - code = hdb_unseal_keys (context, db, entry); + 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); } - if (code == 0 && entry->principal == NULL) { - entry->principal = malloc(sizeof(*entry->principal)); - if (entry->principal == NULL) { + 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; hdb_free_entry (context, entry); } else { - hdb_key2principal(context, &key_data, entry->principal); + hdb_key2principal(context, &key_data, entry->entry.principal); } } return code; @@ -128,14 +143,14 @@ DB_seq(krb5_context context, HDB *db, static krb5_error_code -DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) +DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { return DB_seq(context, db, flags, entry, R_FIRST); } static krb5_error_code -DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) +DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { return DB_seq(context, db, flags, entry, R_NEXT); } @@ -146,7 +161,7 @@ DB_rename(krb5_context context, HDB *db, const char *new_name) int ret; char *old, *new; - asprintf(&old, "%s.db", db->name); + asprintf(&old, "%s.db", db->hdb_name); asprintf(&new, "%s.db", new_name); ret = rename(old, new); free(old); @@ -154,29 +169,35 @@ DB_rename(krb5_context context, HDB *db, const char *new_name) if(ret) return errno; - free(db->name); - db->name = strdup(new_name); + free(db->hdb_name); + db->hdb_name = strdup(new_name); return 0; } static krb5_error_code DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; DBT k, v; int code; k.data = key.data; k.size = key.length; - code = db->lock(context, db, HDB_RLOCK); + code = db->hdb_lock(context, db, HDB_RLOCK); if(code) return code; - code = d->get(d, &k, &v, 0); - db->unlock(context, db); - if(code < 0) - return errno; - if(code == 1) + code = (*d->get)(d, &k, &v, 0); + 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)); + return code; + } + if(code == 1) { + krb5_clear_error_string(context); return HDB_ERR_NOENTRY; + } krb5_data_copy(reply, v.data, v.size); return 0; @@ -186,7 +207,7 @@ static krb5_error_code DB__put(krb5_context context, HDB *db, int replace, krb5_data key, krb5_data value) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; DBT k, v; int code; @@ -194,33 +215,43 @@ DB__put(krb5_context context, HDB *db, int replace, k.size = key.length; v.data = value.data; v.size = value.length; - code = db->lock(context, db, HDB_WLOCK); + code = db->hdb_lock(context, db, HDB_WLOCK); if(code) return code; - code = d->put(d, &k, &v, replace ? 0 : R_NOOVERWRITE); - db->unlock(context, db); - if(code < 0) - return errno; - if(code == 1) + code = (*d->put)(d, &k, &v, replace ? 0 : R_NOOVERWRITE); + 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)); + return code; + } + if(code == 1) { + krb5_clear_error_string(context); return HDB_ERR_EXISTS; + } return 0; } static krb5_error_code DB__del(krb5_context context, HDB *db, krb5_data key) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; DBT k; krb5_error_code code; k.data = key.data; k.size = key.length; - code = db->lock(context, db, HDB_WLOCK); + code = db->hdb_lock(context, db, HDB_WLOCK); if(code) return code; - code = d->del(d, &k, 0); - db->unlock(context, db); - if(code == 1) - return HDB_ERR_NOENTRY; + code = (*d->del)(d, &k, 0); + 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)); + return code; + } if(code < 0) return errno; return 0; @@ -232,20 +263,20 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) char *fn; krb5_error_code ret; - asprintf(&fn, "%s.db", db->name); + asprintf(&fn, "%s.db", db->hdb_name); if (fn == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - db->db = dbopen(fn, flags, mode, DB_BTREE, NULL); + db->hdb_db = dbopen(fn, flags, mode, DB_BTREE, NULL); free(fn); /* try to open without .db extension */ - if(db->db == NULL && errno == ENOENT) - db->db = dbopen(db->name, flags, mode, DB_BTREE, NULL); - if(db->db == NULL) { + 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_string(context, "dbopen (%s): %s", - db->name, strerror(ret)); + db->hdb_name, strerror(ret)); return ret; } if((flags & O_ACCMODE) == O_RDONLY) @@ -256,6 +287,13 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) krb5_clear_error_string(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", + db->hdb_name); + } return ret; } @@ -263,36 +301,36 @@ krb5_error_code hdb_db_create(krb5_context context, HDB **db, const char *filename) { - *db = malloc(sizeof(**db)); + *db = calloc(1, sizeof(**db)); if (*db == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - (*db)->db = NULL; - (*db)->name = strdup(filename); - if ((*db)->name == NULL) { + (*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; return ENOMEM; } - (*db)->master_key_set = 0; - (*db)->openp = 0; - (*db)->open = DB_open; - (*db)->close = DB_close; - (*db)->fetch = _hdb_fetch; - (*db)->store = _hdb_store; - (*db)->remove = _hdb_remove; - (*db)->firstkey = DB_firstkey; - (*db)->nextkey= DB_nextkey; - (*db)->lock = DB_lock; - (*db)->unlock = DB_unlock; - (*db)->rename = DB_rename; - (*db)->_get = DB__get; - (*db)->_put = DB__put; - (*db)->_del = DB__del; - (*db)->destroy = DB_destroy; + (*db)->hdb_master_key_set = 0; + (*db)->hdb_openp = 0; + (*db)->hdb_open = DB_open; + (*db)->hdb_close = DB_close; + (*db)->hdb_fetch = _hdb_fetch; + (*db)->hdb_store = _hdb_store; + (*db)->hdb_remove = _hdb_remove; + (*db)->hdb_firstkey = DB_firstkey; + (*db)->hdb_nextkey= DB_nextkey; + (*db)->hdb_lock = DB_lock; + (*db)->hdb_unlock = DB_unlock; + (*db)->hdb_rename = DB_rename; + (*db)->hdb__get = DB__get; + (*db)->hdb__put = DB__put; + (*db)->hdb__del = DB__del; + (*db)->hdb_destroy = DB_destroy; return 0; } diff --git a/crypto/heimdal/lib/hdb/db3.c b/crypto/heimdal/lib/hdb/db3.c index 8ae3535..45ccbef 100644 --- a/crypto/heimdal/lib/hdb/db3.c +++ b/crypto/heimdal/lib/hdb/db3.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: db3.c,v 1.8.6.1 2003/08/29 16:59:39 lha Exp $"); +RCSID("$Id: db3.c 21610 2007-07-17 07:10:45Z lha $"); #if HAVE_DB3 @@ -48,12 +48,12 @@ RCSID("$Id: db3.c,v 1.8.6.1 2003/08/29 16:59:39 lha Exp $"); static krb5_error_code DB_close(krb5_context context, HDB *db) { - DB *d = (DB*)db->db; - DBC *dbcp = (DBC*)db->dbc; + DB *d = (DB*)db->hdb_db; + DBC *dbcp = (DBC*)db->hdb_dbc; - dbcp->c_close(dbcp); - db->dbc = 0; - d->close(d, 0); + (*dbcp->c_close)(dbcp); + db->hdb_dbc = 0; + (*d->close)(d, 0); return 0; } @@ -63,7 +63,7 @@ DB_destroy(krb5_context context, HDB *db) krb5_error_code ret; ret = hdb_clear_master_key (context, db); - free(db->name); + free(db->hdb_name); free(db); return ret; } @@ -71,7 +71,7 @@ DB_destroy(krb5_context context, HDB *db) static krb5_error_code DB_lock(krb5_context context, HDB *db, int operation) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; int fd; if ((*d->fd)(d, &fd)) return HDB_ERR_CANT_LOCK_DB; @@ -81,7 +81,7 @@ DB_lock(krb5_context context, HDB *db, int operation) static krb5_error_code DB_unlock(krb5_context context, HDB *db) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; int fd; if ((*d->fd)(d, &fd)) return HDB_ERR_CANT_LOCK_DB; @@ -91,19 +91,19 @@ DB_unlock(krb5_context context, HDB *db) static krb5_error_code DB_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry *entry, int flag) + unsigned flags, hdb_entry_ex *entry, int flag) { DBT key, value; - DBC *dbcp = db->dbc; + DBC *dbcp = db->hdb_dbc; krb5_data key_data, data; int code; memset(&key, 0, sizeof(DBT)); memset(&value, 0, sizeof(DBT)); - if (db->lock(context, db, HDB_RLOCK)) + if ((*db->hdb_lock)(context, db, HDB_RLOCK)) return HDB_ERR_DB_INUSE; - code = dbcp->c_get(dbcp, &key, &value, flag); - db->unlock(context, db); /* XXX check value */ + code = (*dbcp->c_get)(dbcp, &key, &value, flag); + (*db->hdb_unlock)(context, db); /* XXX check value */ if (code == DB_NOTFOUND) return HDB_ERR_NOENTRY; if (code) @@ -113,21 +113,22 @@ DB_seq(krb5_context context, HDB *db, key_data.length = key.size; data.data = value.data; data.length = value.size; - if (hdb_value2entry(context, &data, entry)) + memset(entry, 0, sizeof(*entry)); + if (hdb_value2entry(context, &data, &entry->entry)) return DB_seq(context, db, flags, entry, DB_NEXT); - if (db->master_key_set && (flags & HDB_F_DECRYPT)) { - code = hdb_unseal_keys (context, db, entry); + 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); } - if (entry->principal == NULL) { - entry->principal = malloc(sizeof(*entry->principal)); - if (entry->principal == NULL) { + if (entry->entry.principal == NULL) { + 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"); return ENOMEM; } else { - hdb_key2principal(context, &key_data, entry->principal); + hdb_key2principal(context, &key_data, entry->entry.principal); } } return 0; @@ -135,14 +136,14 @@ DB_seq(krb5_context context, HDB *db, static krb5_error_code -DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) +DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { return DB_seq(context, db, flags, entry, DB_FIRST); } static krb5_error_code -DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) +DB_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry_ex *entry) { return DB_seq(context, db, flags, entry, DB_NEXT); } @@ -153,7 +154,7 @@ DB_rename(krb5_context context, HDB *db, const char *new_name) int ret; char *old, *new; - asprintf(&old, "%s.db", db->name); + asprintf(&old, "%s.db", db->hdb_name); asprintf(&new, "%s.db", new_name); ret = rename(old, new); free(old); @@ -161,15 +162,15 @@ DB_rename(krb5_context context, HDB *db, const char *new_name) if(ret) return errno; - free(db->name); - db->name = strdup(new_name); + free(db->hdb_name); + db->hdb_name = strdup(new_name); return 0; } static krb5_error_code DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; DBT k, v; int code; @@ -178,10 +179,10 @@ DB__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) k.data = key.data; k.size = key.length; k.flags = 0; - if ((code = db->lock(context, db, HDB_RLOCK))) + if ((code = (*db->hdb_lock)(context, db, HDB_RLOCK))) return code; - code = d->get(d, NULL, &k, &v, 0); - db->unlock(context, db); + code = (*d->get)(d, NULL, &k, &v, 0); + (*db->hdb_unlock)(context, db); if(code == DB_NOTFOUND) return HDB_ERR_NOENTRY; if(code) @@ -195,7 +196,7 @@ static krb5_error_code DB__put(krb5_context context, HDB *db, int replace, krb5_data key, krb5_data value) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; DBT k, v; int code; @@ -207,10 +208,10 @@ DB__put(krb5_context context, HDB *db, int replace, v.data = value.data; v.size = value.length; v.flags = 0; - if ((code = db->lock(context, db, HDB_WLOCK))) + if ((code = (*db->hdb_lock)(context, db, HDB_WLOCK))) return code; - code = d->put(d, NULL, &k, &v, replace ? 0 : DB_NOOVERWRITE); - db->unlock(context, db); + code = (*d->put)(d, NULL, &k, &v, replace ? 0 : DB_NOOVERWRITE); + (*db->hdb_unlock)(context, db); if(code == DB_KEYEXIST) return HDB_ERR_EXISTS; if(code) @@ -221,18 +222,18 @@ DB__put(krb5_context context, HDB *db, int replace, static krb5_error_code DB__del(krb5_context context, HDB *db, krb5_data key) { - DB *d = (DB*)db->db; + DB *d = (DB*)db->hdb_db; DBT k; krb5_error_code code; memset(&k, 0, sizeof(DBT)); k.data = key.data; k.size = key.length; k.flags = 0; - code = db->lock(context, db, HDB_WLOCK); + code = (*db->hdb_lock)(context, db, HDB_WLOCK); if(code) return code; - code = d->del(d, NULL, &k, 0); - db->unlock(context, db); + code = (*d->del)(d, NULL, &k, 0); + (*db->hdb_unlock)(context, db); if(code == DB_NOTFOUND) return HDB_ERR_NOENTRY; if(code) @@ -243,6 +244,7 @@ DB__del(krb5_context context, HDB *db, krb5_data key) static krb5_error_code DB_open(krb5_context context, HDB *db, int flags, mode_t mode) { + DBC *dbc = NULL; char *fn; krb5_error_code ret; DB *d; @@ -254,44 +256,51 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) if (flags & O_EXCL) myflags |= DB_EXCL; - if (flags & O_RDONLY) + if((flags & O_ACCMODE) == O_RDONLY) myflags |= DB_RDONLY; if (flags & O_TRUNC) myflags |= DB_TRUNCATE; - asprintf(&fn, "%s.db", db->name); + asprintf(&fn, "%s.db", db->hdb_name); if (fn == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } db_create(&d, NULL, 0); - db->db = d; -#if (DB_VERSION_MAJOR > 3) && (DB_VERSION_MINOR > 0) - if ((ret = d->open(db->db, NULL, fn, NULL, DB_BTREE, myflags, mode))) { + db->hdb_db = d; + +#if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 1) + ret = (*d->open)(db->hdb_db, NULL, fn, NULL, DB_BTREE, myflags, mode); #else - if ((ret = d->open(db->db, fn, NULL, DB_BTREE, myflags, mode))) { + ret = (*d->open)(db->hdb_db, fn, NULL, DB_BTREE, myflags, mode); #endif - if(ret == ENOENT) + + if (ret == ENOENT) { /* try to open without .db extension */ -#if (DB_VERSION_MAJOR > 3) && (DB_VERSION_MINOR > 0) - if (d->open(db->db, NULL, db->name, NULL, DB_BTREE, myflags, mode)) { +#if (DB_VERSION_MAJOR >= 4) && (DB_VERSION_MINOR >= 1) + ret = (*d->open)(db->hdb_db, NULL, db->hdb_name, NULL, DB_BTREE, + myflags, mode); #else - if (d->open(db->db, db->name, NULL, DB_BTREE, myflags, mode)) { + ret = (*d->open)(db->hdb_db, db->hdb_name, NULL, DB_BTREE, + myflags, mode); #endif - free(fn); - krb5_set_error_string(context, "opening %s: %s", - db->name, strerror(ret)); - return ret; - } + } + + if (ret) { + free(fn); + krb5_set_error_string(context, "opening %s: %s", + db->hdb_name, strerror(ret)); + return ret; } free(fn); - ret = d->cursor(d, NULL, (DBC **)&db->dbc, 0); + ret = (*d->cursor)(d, NULL, &dbc, 0); if (ret) { krb5_set_error_string(context, "d->cursor: %s", strerror(ret)); return ret; } + db->hdb_dbc = dbc; if((flags & O_ACCMODE) == O_RDONLY) ret = hdb_check_db_format(context, db); @@ -299,6 +308,14 @@ DB_open(krb5_context context, HDB *db, int flags, mode_t mode) ret = hdb_init_db(context, db); if(ret == HDB_ERR_NOENTRY) 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); + } + return ret; } @@ -306,36 +323,36 @@ krb5_error_code hdb_db_create(krb5_context context, HDB **db, const char *filename) { - *db = malloc(sizeof(**db)); + *db = calloc(1, sizeof(**db)); if (*db == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - (*db)->db = NULL; - (*db)->name = strdup(filename); - if ((*db)->name == NULL) { + (*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; return ENOMEM; } - (*db)->master_key_set = 0; - (*db)->openp = 0; - (*db)->open = DB_open; - (*db)->close = DB_close; - (*db)->fetch = _hdb_fetch; - (*db)->store = _hdb_store; - (*db)->remove = _hdb_remove; - (*db)->firstkey = DB_firstkey; - (*db)->nextkey= DB_nextkey; - (*db)->lock = DB_lock; - (*db)->unlock = DB_unlock; - (*db)->rename = DB_rename; - (*db)->_get = DB__get; - (*db)->_put = DB__put; - (*db)->_del = DB__del; - (*db)->destroy = DB_destroy; + (*db)->hdb_master_key_set = 0; + (*db)->hdb_openp = 0; + (*db)->hdb_open = DB_open; + (*db)->hdb_close = DB_close; + (*db)->hdb_fetch = _hdb_fetch; + (*db)->hdb_store = _hdb_store; + (*db)->hdb_remove = _hdb_remove; + (*db)->hdb_firstkey = DB_firstkey; + (*db)->hdb_nextkey= DB_nextkey; + (*db)->hdb_lock = DB_lock; + (*db)->hdb_unlock = DB_unlock; + (*db)->hdb_rename = DB_rename; + (*db)->hdb__get = DB__get; + (*db)->hdb__put = DB__put; + (*db)->hdb__del = DB__del; + (*db)->hdb_destroy = DB_destroy; return 0; } #endif /* HAVE_DB3 */ diff --git a/crypto/heimdal/lib/hdb/dbinfo.c b/crypto/heimdal/lib/hdb/dbinfo.c new file mode 100644 index 0000000..d43e31b --- /dev/null +++ b/crypto/heimdal/lib/hdb/dbinfo.c @@ -0,0 +1,266 @@ +/* + * 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: + * + * 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" + +RCSID("$Id: dbinfo.c 22306 2007-12-14 12:22:38Z lha $"); + +struct hdb_dbinfo { + char *label; + char *realm; + char *dbname; + char *mkey_file; + char *acl_file; + char *log_file; + const krb5_config_binding *binding; + struct hdb_dbinfo *next; +}; + +static int +get_dbinfo(krb5_context context, + const krb5_config_binding *db_binding, + const char *label, + struct hdb_dbinfo **db) +{ + struct hdb_dbinfo *di; + const char *p; + + *db = NULL; + + p = krb5_config_get_string(context, db_binding, "dbname", NULL); + if(p == NULL) + return 0; + + di = calloc(1, sizeof(*di)); + if (di == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + di->label = strdup(label); + di->dbname = strdup(p); + + p = krb5_config_get_string(context, db_binding, "realm", NULL); + if(p) + di->realm = strdup(p); + p = krb5_config_get_string(context, db_binding, "mkey_file", NULL); + if(p) + di->mkey_file = strdup(p); + p = krb5_config_get_string(context, db_binding, "acl_file", NULL); + if(p) + di->acl_file = strdup(p); + p = krb5_config_get_string(context, db_binding, "log_file", NULL); + if(p) + di->log_file = strdup(p); + + di->binding = db_binding; + + *db = di; + return 0; +} + + +int +hdb_get_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) +{ + const krb5_config_binding *db_binding; + struct hdb_dbinfo *di, **dt, *databases; + const char *default_dbname = HDB_DEFAULT_DB; + const char *default_mkey = HDB_DB_DIR "/m-key"; + const char *default_acl = HDB_DB_DIR "/kadmind.acl"; + const char *p; + int ret; + + *dbp = NULL; + dt = NULL; + databases = NULL; + + db_binding = krb5_config_get(context, NULL, krb5_config_list, + "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, + db_binding->name, &di); + if (ret) + krb5_err(context, 1, ret, "failed getting realm"); + + if (di == NULL) + continue; + + if (dt) + *dt = di; + else + databases = di; + dt = &di->next; + + } + } + + if(databases == NULL) { + /* if there are none specified, create one and use defaults */ + di = calloc(1, sizeof(*di)); + databases = di; + di->label = strdup("default"); + } + + for(di = databases; di; di = di->next) { + if(di->dbname == NULL) { + di->dbname = strdup(default_dbname); + if (di->mkey_file == NULL) + di->mkey_file = strdup(default_mkey); + } + if(di->mkey_file == NULL) { + p = strrchr(di->dbname, '.'); + if(p == NULL || strchr(p, '/') != NULL) + /* final pathname component does not contain a . */ + asprintf(&di->mkey_file, "%s.mkey", di->dbname); + else + /* the filename is something.else, replace .else with + .mkey */ + asprintf(&di->mkey_file, "%.*s.mkey", + (int)(p - di->dbname), di->dbname); + } + if(di->acl_file == NULL) + di->acl_file = strdup(default_acl); + } + *dbp = databases; + return 0; +} + + +struct hdb_dbinfo * +hdb_dbinfo_get_next(struct hdb_dbinfo *dbp, struct hdb_dbinfo *dbprevp) +{ + if (dbprevp == NULL) + return dbp; + else + return dbprevp->next; +} + +const char * +hdb_dbinfo_get_label(krb5_context context, struct hdb_dbinfo *dbp) +{ + return dbp->label; +} + +const char * +hdb_dbinfo_get_realm(krb5_context context, struct hdb_dbinfo *dbp) +{ + return dbp->realm; +} + +const char * +hdb_dbinfo_get_dbname(krb5_context context, struct hdb_dbinfo *dbp) +{ + return dbp->dbname; +} + +const char * +hdb_dbinfo_get_mkey_file(krb5_context context, struct hdb_dbinfo *dbp) +{ + return dbp->mkey_file; +} + +const char * +hdb_dbinfo_get_acl_file(krb5_context context, struct hdb_dbinfo *dbp) +{ + return dbp->acl_file; +} + +const char * +hdb_dbinfo_get_log_file(krb5_context context, struct hdb_dbinfo *dbp) +{ + return dbp->log_file; +} + +const krb5_config_binding * +hdb_dbinfo_get_binding(krb5_context context, struct hdb_dbinfo *dbp) +{ + return dbp->binding; +} + +void +hdb_free_dbinfo(krb5_context context, struct hdb_dbinfo **dbp) +{ + struct hdb_dbinfo *di, *ndi; + + for(di = *dbp; di != NULL; di = ndi) { + ndi = di->next; + free (di->realm); + free (di->dbname); + if (di->mkey_file) + free (di->mkey_file); + free(di); + } + *dbp = NULL; +} + +/** + * Return the directory where the hdb database resides. + * + * @param context Kerberos 5 context. + * + * @return string pointing to directory. + */ + +const char * +hdb_db_dir(krb5_context context) +{ + return HDB_DB_DIR; +} + +/** + * Return the default hdb database resides. + * + * @param context Kerberos 5 context. + * + * @return string pointing to directory. + */ + +const char * +hdb_default_db(krb5_context context) +{ + return HDB_DEFAULT_DB; +} diff --git a/crypto/heimdal/lib/hdb/ext.c b/crypto/heimdal/lib/hdb/ext.c new file mode 100644 index 0000000..5f60999 --- /dev/null +++ b/crypto/heimdal/lib/hdb/ext.c @@ -0,0 +1,418 @@ +/* + * 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: + * + * 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 <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; + + 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 != + choice_HDB_extension_data_asn1_ellipsis) + continue; + if (ent->extensions->val[i].mandatory) { + krb5_set_error_string(context, "Principal have unknown " + "mandatory extension"); + return HDB_ERR_MANDATORY_OPTION; + } + } + return 0; +} + +HDB_extension * +hdb_find_extension(const hdb_entry *entry, int type) +{ + int i; + + if (entry->extensions == NULL) + return NULL; + + for (i = 0; i < entry->extensions->len; i++) + if (entry->extensions->val[i].data.element == type) + return &entry->extensions->val[i]; + return NULL; +} + +/* + * Replace the extension `ext' in `entry'. Make a copy of the + * extension, so the caller must still free `ext' on both success and + * failure. Returns 0 or error code. + */ + +krb5_error_code +hdb_replace_extension(krb5_context context, + hdb_entry *entry, + const HDB_extension *ext) +{ + HDB_extension *ext2; + HDB_extension *es; + int ret; + + ext2 = NULL; + + if (entry->extensions == NULL) { + entry->extensions = calloc(1, sizeof(*entry->extensions)); + if (entry->extensions == NULL) { + krb5_set_error_string(context, "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 + * rescue. The first tag in each branch in the CHOICE is + * unique, so just find the element in the list that have the + * same tag was we are putting into the list. + */ + Der_class replace_class, list_class; + Der_type replace_type, list_type; + unsigned int replace_tag, list_tag; + size_t size; + int 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"); + return ret; + } + + for (i = 0; i < entry->extensions->len; i++) { + HDB_extension *ext3 = &entry->extensions->val[i]; + + if (ext3->data.element != choice_HDB_extension_data_asn1_ellipsis) + continue; + + ret = der_get_tag(ext3->data.u.asn1_ellipsis.data, + ext3->data.u.asn1_ellipsis.length, + &list_class, &list_type, &list_tag, + &size); + if (ret) { + krb5_set_error_string(context, "hdb: failed to decode " + "present hdb extention"); + return ret; + } + + if (MAKE_TAG(replace_class,replace_type,replace_type) == + MAKE_TAG(list_class,list_type,list_type)) { + ext2 = ext3; + break; + } + } + } + + if (ext2) { + free_HDB_extension(ext2); + ret = copy_HDB_extension(ext, ext2); + if (ret) + krb5_set_error_string(context, "hdb: failed to copy replacement " + "hdb extention"); + return ret; + } + + 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"); + return ENOMEM; + } + entry->extensions->val = es; + + ret = copy_HDB_extension(ext, + &entry->extensions->val[entry->extensions->len]); + if (ret == 0) + entry->extensions->len++; + else + krb5_set_error_string(context, "hdb: failed to copy new extension"); + + return ret; +} + +krb5_error_code +hdb_clear_extension(krb5_context context, + hdb_entry *entry, + int type) +{ + int i; + + if (entry->extensions == NULL) + return 0; + + for (i = 0; i < entry->extensions->len; i++) { + if (entry->extensions->val[i].data.element == type) { + free_HDB_extension(&entry->extensions->val[i]); + memmove(&entry->extensions->val[i], + &entry->extensions->val[i + 1], + sizeof(entry->extensions->val[i]) * (entry->extensions->len - i - 1)); + entry->extensions->len--; + } + } + if (entry->extensions->len == 0) { + free(entry->extensions->val); + free(entry->extensions); + entry->extensions = NULL; + } + + return 0; +} + + +krb5_error_code +hdb_entry_get_pkinit_acl(const hdb_entry *entry, const HDB_Ext_PKINIT_acl **a) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_acl); + if (ext) + *a = &ext->data.u.pkinit_acl; + else + *a = NULL; + + return 0; +} + +krb5_error_code +hdb_entry_get_pkinit_hash(const hdb_entry *entry, const HDB_Ext_PKINIT_hash **a) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, choice_HDB_extension_data_pkinit_cert_hash); + if (ext) + *a = &ext->data.u.pkinit_cert_hash; + 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; + + ext = hdb_find_extension(entry, choice_HDB_extension_data_last_pw_change); + if (ext) + *t = ext->data.u.last_pw_change; + else + *t = 0; + + return 0; +} + +krb5_error_code +hdb_entry_set_pw_change_time(krb5_context context, + hdb_entry *entry, + time_t t) +{ + HDB_extension ext; + + ext.mandatory = FALSE; + ext.data.element = choice_HDB_extension_data_last_pw_change; + if (t == 0) + t = time(NULL); + ext.data.u.last_pw_change = t; + + return hdb_replace_extension(context, entry, &ext); +} + +int +hdb_entry_get_password(krb5_context context, HDB *db, + const hdb_entry *entry, char **p) +{ + HDB_extension *ext; + char *str; + int ret; + + ext = hdb_find_extension(entry, choice_HDB_extension_data_password); + if (ext) { + heim_utf8_string str; + 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, + db->hdb_master_key); + + if (key == NULL) { + krb5_set_error_string(context, "master key %d missing", + *ext->data.u.password.mkvno); + return HDB_ERR_NO_MKEY; + } + + ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY, + ext->data.u.password.password.data, + ext->data.u.password.password.length, + &pw); + } else { + ret = der_copy_octet_string(&ext->data.u.password.password, &pw); + } + if (ret) { + krb5_clear_error_string(context); + return ret; + } + + str = pw.data; + if (str[pw.length - 1] != '\0') { + krb5_set_error_string(context, "password malformated"); + return EINVAL; + } + + *p = strdup(str); + + der_free_octet_string(&pw); + if (*p == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + return 0; + } + + ret = krb5_unparse_name(context, entry->principal, &str); + if (ret == 0) { + krb5_set_error_string(context, "no password attributefor %s", str); + free(str); + } else + krb5_clear_error_string(context); + + return ENOENT; +} + +int +hdb_entry_set_password(krb5_context context, HDB *db, + hdb_entry *entry, const char *p) +{ + HDB_extension ext; + hdb_master_key key; + int ret; + + ext.mandatory = FALSE; + ext.data.element = choice_HDB_extension_data_password; + + if (db->hdb_master_key_set) { + + 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"); + return HDB_ERR_NO_MKEY; + } + + ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY, + p, strlen(p) + 1, + &ext.data.u.password.password); + if (ret) + return ret; + + 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"); + return ENOMEM; + } + *ext.data.u.password.mkvno = _hdb_mkey_version(key); + + } else { + ext.data.u.password.mkvno = NULL; + + ret = krb5_data_copy(&ext.data.u.password.password, + p, strlen(p) + 1); + if (ret) { + krb5_set_error_string(context, "malloc: out of memory"); + free_HDB_extension(&ext); + return ret; + } + } + + ret = hdb_replace_extension(context, entry, &ext); + + free_HDB_extension(&ext); + + return ret; +} + +int +hdb_entry_clear_password(krb5_context context, hdb_entry *entry) +{ + return hdb_clear_extension(context, entry, + choice_HDB_extension_data_password); +} + +krb5_error_code +hdb_entry_get_ConstrainedDelegACL(const hdb_entry *entry, + const HDB_Ext_Constrained_delegation_acl **a) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, + choice_HDB_extension_data_allowed_to_delegate_to); + if (ext) + *a = &ext->data.u.allowed_to_delegate_to; + else + *a = NULL; + + return 0; +} + +krb5_error_code +hdb_entry_get_aliases(const hdb_entry *entry, const HDB_Ext_Aliases **a) +{ + const HDB_extension *ext; + + ext = hdb_find_extension(entry, choice_HDB_extension_data_aliases); + if (ext) + *a = &ext->data.u.aliases; + else + *a = NULL; + + return 0; +} diff --git a/crypto/heimdal/lib/hdb/hdb-ldap.c b/crypto/heimdal/lib/hdb/hdb-ldap.c index aed29b3..c9f3d37 100644 --- a/crypto/heimdal/lib/hdb/hdb-ldap.c +++ b/crypto/heimdal/lib/hdb/hdb-ldap.c @@ -1,5 +1,7 @@ /* - * Copyright (c) 1999-2001, PADL Software Pty Ltd. + * Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd. + * Copyright (c) 2004, Andrew Bartlett. + * Copyright (c) 2003 - 2007, Kungliga Tekniska Högskolan. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,47 +34,124 @@ #include "hdb_locl.h" -RCSID("$Id: hdb-ldap.c,v 1.10.4.1 2003/09/18 20:49:09 lha Exp $"); +RCSID("$Id: hdb-ldap.c 22071 2007-11-14 20:04:50Z lha $"); #ifdef OPENLDAP #include <lber.h> #include <ldap.h> -#include <ctype.h> #include <sys/un.h> +#include <hex.h> -static krb5_error_code LDAP__connect(krb5_context context, HDB * db); +static krb5_error_code LDAP__connect(krb5_context context, HDB *); +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 * ent); - -static char *krb5kdcentry_attrs[] = - { "krb5PrincipalName", "cn", "krb5PrincipalRealm", - "krb5KeyVersionNumber", "krb5Key", - "krb5ValidStart", "krb5ValidEnd", "krb5PasswordEnd", - "krb5MaxLife", "krb5MaxRenew", "krb5KDCFlags", "krb5EncryptionType", - "modifiersName", "modifyTimestamp", "creatorsName", "createTimestamp", + hdb_entry_ex * ent); + +static const char *default_structural_object = "account"; +static char *structural_object; +static krb5_boolean samba_forwardable; + +struct hdbldapdb { + LDAP *h_lp; + int h_msgid; + char *h_base; + char *h_url; + char *h_createbase; +}; + +#define HDB2LDAP(db) (((struct hdbldapdb *)(db)->hdb_db)->h_lp) +#define HDB2MSGID(db) (((struct hdbldapdb *)(db)->hdb_db)->h_msgid) +#define HDBSETMSGID(db,msgid) \ + do { ((struct hdbldapdb *)(db)->hdb_db)->h_msgid = msgid; } while(0) +#define HDB2BASE(dn) (((struct hdbldapdb *)(db)->hdb_db)->h_base) +#define HDB2URL(dn) (((struct hdbldapdb *)(db)->hdb_db)->h_url) +#define HDB2CREATE(db) (((struct hdbldapdb *)(db)->hdb_db)->h_createbase) + +/* + * + */ + +static char * krb5kdcentry_attrs[] = { + "cn", + "createTimestamp", + "creatorsName", + "krb5EncryptionType", + "krb5KDCFlags", + "krb5Key", + "krb5KeyVersionNumber", + "krb5MaxLife", + "krb5MaxRenew", + "krb5PasswordEnd", + "krb5PrincipalName", + "krb5PrincipalRealm", + "krb5ValidEnd", + "krb5ValidStart", + "modifiersName", + "modifyTimestamp", + "objectClass", + "sambaAcctFlags", + "sambaKickoffTime", + "sambaNTPassword", + "sambaPwdLastSet", + "sambaPwdMustChange", + "uid", NULL }; -static char *krb5principal_attrs[] = - { "krb5PrincipalName", "cn", "krb5PrincipalRealm", - "modifiersName", "modifyTimestamp", "creatorsName", "createTimestamp", +static char *krb5principal_attrs[] = { + "cn", + "createTimestamp", + "creatorsName", + "krb5PrincipalName", + "krb5PrincipalRealm", + "modifiersName", + "modifyTimestamp", + "objectClass", + "uid", NULL }; +static int +LDAP_no_size_limit(krb5_context context, LDAP *lp) +{ + int ret, limit = LDAP_NO_LIMIT; + + 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)); + return HDB_ERR_BADVERSION; + } + return 0; +} + +static int +check_ldap(krb5_context context, HDB *db, int ret) +{ + switch (ret) { + case LDAP_SUCCESS: + return 0; + case LDAP_SERVER_DOWN: + LDAP_close(context, db); + return 1; + default: + return 1; + } +} + static krb5_error_code LDAP__setmod(LDAPMod *** modlist, int modop, const char *attribute, - int *pIndex) + int *pIndex) { int cMods; if (*modlist == NULL) { *modlist = (LDAPMod **)ber_memcalloc(1, sizeof(LDAPMod *)); - if (*modlist == NULL) { + if (*modlist == NULL) return ENOMEM; - } } for (cMods = 0; (*modlist)[cMods] != NULL; cMods++) { @@ -89,13 +168,12 @@ LDAP__setmod(LDAPMod *** modlist, int modop, const char *attribute, *modlist = (LDAPMod **)ber_memrealloc(*modlist, (cMods + 2) * sizeof(LDAPMod *)); - if (*modlist == NULL) { + if (*modlist == NULL) return ENOMEM; - } + (*modlist)[cMods] = (LDAPMod *)ber_memalloc(sizeof(LDAPMod)); - if ((*modlist)[cMods] == NULL) { + if ((*modlist)[cMods] == NULL) return ENOMEM; - } mod = (*modlist)[cMods]; mod->mod_op = modop; @@ -122,39 +200,36 @@ static krb5_error_code LDAP_addmod_len(LDAPMod *** modlist, int modop, const char *attribute, unsigned char *value, size_t len) { - int cMods, cValues = 0; krb5_error_code ret; + int cMods, i = 0; ret = LDAP__setmod(modlist, modop | LDAP_MOD_BVALUES, attribute, &cMods); - if (ret != 0) { + if (ret) return ret; - } if (value != NULL) { - struct berval *bValue; - struct berval ***pbValues = &((*modlist)[cMods]->mod_bvalues); + struct berval **bv; - if (*pbValues != NULL) { - for (cValues = 0; (*pbValues)[cValues] != NULL; cValues++) + bv = (*modlist)[cMods]->mod_bvalues; + if (bv != NULL) { + for (i = 0; bv[i] != NULL; i++) ; - *pbValues = (struct berval **)ber_memrealloc(*pbValues, (cValues + 2) - * sizeof(struct berval *)); - } else { - *pbValues = (struct berval **)ber_memalloc(2 * sizeof(struct berval *)); - } - if (*pbValues == NULL) { + bv = ber_memrealloc(bv, (i + 2) * sizeof(*bv)); + } else + bv = ber_memalloc(2 * sizeof(*bv)); + if (bv == NULL) return ENOMEM; - } - (*pbValues)[cValues] = (struct berval *)ber_memalloc(sizeof(struct berval));; - if ((*pbValues)[cValues] == NULL) { + + (*modlist)[cMods]->mod_bvalues = bv; + + bv[i] = ber_memalloc(sizeof(*bv));; + if (bv[i] == NULL) return ENOMEM; - } - bValue = (*pbValues)[cValues]; - bValue->bv_val = value; - bValue->bv_len = len; + bv[i]->bv_val = (void *)value; + bv[i]->bv_len = len; - (*pbValues)[cValues + 1] = NULL; + bv[i + 1] = NULL; } return 0; @@ -164,32 +239,33 @@ static krb5_error_code LDAP_addmod(LDAPMod *** modlist, int modop, const char *attribute, const char *value) { - int cMods, cValues = 0; + int cMods, i = 0; krb5_error_code ret; ret = LDAP__setmod(modlist, modop, attribute, &cMods); - if (ret != 0) { + if (ret) return ret; - } if (value != NULL) { - char ***pValues = &((*modlist)[cMods]->mod_values); + char **bv; - if (*pValues != NULL) { - for (cValues = 0; (*pValues)[cValues] != NULL; cValues++) + bv = (*modlist)[cMods]->mod_values; + if (bv != NULL) { + for (i = 0; bv[i] != NULL; i++) ; - *pValues = (char **)ber_memrealloc(*pValues, (cValues + 2) * sizeof(char *)); - } else { - *pValues = (char **)ber_memalloc(2 * sizeof(char *)); - } - if (*pValues == NULL) { + bv = ber_memrealloc(bv, (i + 2) * sizeof(*bv)); + } else + bv = ber_memalloc(2 * sizeof(*bv)); + if (bv == NULL) return ENOMEM; - } - (*pValues)[cValues] = ber_strdup(value); - if ((*pValues)[cValues] == NULL) { + + (*modlist)[cMods]->mod_values = bv; + + bv[i] = ber_strdup(value); + if (bv[i] == NULL) return ENOMEM; - } - (*pValues)[cValues + 1] = NULL; + + bv[i + 1] = NULL; } return 0; @@ -210,22 +286,41 @@ LDAP_addmod_generalized_time(LDAPMod *** mods, int modop, } static krb5_error_code +LDAP_addmod_integer(krb5_context context, + LDAPMod *** mods, int modop, + const char *attribute, unsigned long l) +{ + krb5_error_code ret; + char *buf; + + ret = asprintf(&buf, "%ld", l); + if (ret < 0) { + krb5_set_error_string(context, "asprintf: out of memory:"); + return ret; + } + ret = LDAP_addmod(mods, modop, attribute, buf); + free (buf); + return ret; +} + +static krb5_error_code LDAP_get_string_value(HDB * db, LDAPMessage * entry, const char *attribute, char **ptr) { char **vals; int ret; - vals = ldap_get_values((LDAP *) db->db, entry, (char *) attribute); + vals = ldap_get_values(HDB2LDAP(db), entry, (char *) attribute); if (vals == NULL) { + *ptr = NULL; return HDB_ERR_NOENTRY; } + *ptr = strdup(vals[0]); - if (*ptr == NULL) { + if (*ptr == NULL) ret = ENOMEM; - } else { + else ret = 0; - } ldap_value_free(vals); @@ -238,10 +333,10 @@ LDAP_get_integer_value(HDB * db, LDAPMessage * entry, { char **vals; - vals = ldap_get_values((LDAP *) db->db, entry, (char *) attribute); - if (vals == NULL) { + vals = ldap_get_values(HDB2LDAP(db), entry, (char *) attribute); + if (vals == NULL) return HDB_ERR_NOENTRY; - } + *ptr = atoi(vals[0]); ldap_value_free(vals); return 0; @@ -258,9 +353,8 @@ LDAP_get_generalized_time_value(HDB * db, LDAPMessage * entry, *kt = 0; ret = LDAP_get_string_value(db, entry, attribute, &gentime); - if (ret != 0) { + if (ret) return ret; - } tmp = strptime(gentime, "%Y%m%d%H%M%SZ", &tm); if (tmp == NULL) { @@ -276,218 +370,337 @@ LDAP_get_generalized_time_value(HDB * db, LDAPMessage * entry, } static krb5_error_code -LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, +LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, LDAPMessage * msg, LDAPMod *** pmods) { krb5_error_code ret; krb5_boolean is_new_entry; - int rc, i; char *tmp = NULL; LDAPMod **mods = NULL; - hdb_entry orig; + hdb_entry_ex orig; unsigned long oflags, nflags; + int i; + + krb5_boolean is_samba_account = FALSE; + krb5_boolean is_account = FALSE; + krb5_boolean is_heimdal_entry = FALSE; + krb5_boolean is_heimdal_principal = FALSE; + + char **values; + + *pmods = NULL; if (msg != NULL) { + ret = LDAP_message2entry(context, db, msg, &orig); - if (ret != 0) { + if (ret) goto out; - } + is_new_entry = FALSE; - } else { + + values = ldap_get_values(HDB2LDAP(db), msg, "objectClass"); + if (values) { + int num_objectclasses = ldap_count_values(values); + for (i=0; i < num_objectclasses; i++) { + if (strcasecmp(values[i], "sambaSamAccount") == 0) { + is_samba_account = TRUE; + } else if (strcasecmp(values[i], structural_object) == 0) { + is_account = TRUE; + } else if (strcasecmp(values[i], "krb5Principal") == 0) { + is_heimdal_principal = TRUE; + } else if (strcasecmp(values[i], "krb5KDCEntry") == 0) { + is_heimdal_entry = TRUE; + } + } + ldap_value_free(values); + } + + /* + * 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 && + is_heimdal_entry == FALSE) { + if (is_account == TRUE) { + is_new_entry = TRUE; + } else { + ret = HDB_ERR_NOENTRY; + goto out; + } + } + } else + is_new_entry = TRUE; + + if (is_new_entry) { + /* to make it perfectly obvious we're depending on * orig being intiialized to zero */ memset(&orig, 0, sizeof(orig)); - is_new_entry = TRUE; - } - if (is_new_entry) { ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "top"); - if (ret != 0) { - goto out; - } - /* person is the structural object class */ - ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "person"); - if (ret != 0) { + if (ret) goto out; + + /* account is the structural object class */ + if (is_account == FALSE) { + ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", + structural_object); + is_account = TRUE; + if (ret) + goto out; } - ret = - LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", - "krb5Principal"); - if (ret != 0) { + + ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "krb5Principal"); + is_heimdal_principal = TRUE; + if (ret) goto out; - } - ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", - "krb5KDCEntry"); - if (ret != 0) { + + ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass", "krb5KDCEntry"); + is_heimdal_entry = TRUE; + if (ret) goto out; - } } - if (is_new_entry || - krb5_principal_compare(context, ent->principal, orig.principal) == - FALSE) { - ret = krb5_unparse_name(context, ent->principal, &tmp); - if (ret != 0) { - goto out; + if (is_new_entry || + krb5_principal_compare(context, ent->entry.principal, orig.entry.principal) + == FALSE) + { + if (is_heimdal_principal || is_heimdal_entry) { + + ret = krb5_unparse_name(context, ent->entry.principal, &tmp); + if (ret) + goto out; + + ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, + "krb5PrincipalName", tmp); + if (ret) { + free(tmp); + goto out; + } + free(tmp); } - ret = - LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5PrincipalName", tmp); - if (ret != 0) { + + if (is_account || is_samba_account) { + ret = krb5_unparse_name_short(context, ent->entry.principal, &tmp); + if (ret) + goto out; + ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "uid", tmp); + if (ret) { + free(tmp); + goto out; + } free(tmp); - goto out; } - free(tmp); } - if (ent->kvno != orig.kvno) { - rc = asprintf(&tmp, "%d", ent->kvno); - if (rc < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); - ret = ENOMEM; - goto out; - } - ret = - LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5KeyVersionNumber", - tmp); - free(tmp); - if (ret != 0) { + if (is_heimdal_entry && (ent->entry.kvno != orig.entry.kvno || is_new_entry)) { + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, + "krb5KeyVersionNumber", + ent->entry.kvno); + if (ret) goto out; - } } - if (ent->valid_start) { - if (orig.valid_end == NULL - || (*(ent->valid_start) != *(orig.valid_start))) { - ret = - LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, - "krb5ValidStart", - ent->valid_start); - if (ret != 0) { + if (is_heimdal_entry && ent->entry.valid_start) { + if (orig.entry.valid_end == NULL + || (*(ent->entry.valid_start) != *(orig.entry.valid_start))) { + ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, + "krb5ValidStart", + ent->entry.valid_start); + if (ret) goto out; - } } } - if (ent->valid_end) { - if (orig.valid_end == NULL - || (*(ent->valid_end) != *(orig.valid_end))) { - ret = - LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, - "krb5ValidEnd", - ent->valid_end); - if (ret != 0) { - goto out; + if (ent->entry.valid_end) { + if (orig.entry.valid_end == NULL || (*(ent->entry.valid_end) != *(orig.entry.valid_end))) { + if (is_heimdal_entry) { + ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, + "krb5ValidEnd", + ent->entry.valid_end); + if (ret) + goto out; + } + if (is_samba_account) { + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, + "sambaKickoffTime", + *(ent->entry.valid_end)); + if (ret) + goto out; } - } + } } - if (ent->pw_end) { - if (orig.pw_end == NULL || (*(ent->pw_end) != *(orig.pw_end))) { - ret = - LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, - "krb5PasswordEnd", - ent->pw_end); - if (ret != 0) { - goto out; + if (ent->entry.pw_end) { + if (orig.entry.pw_end == NULL || (*(ent->entry.pw_end) != *(orig.entry.pw_end))) { + if (is_heimdal_entry) { + ret = LDAP_addmod_generalized_time(&mods, LDAP_MOD_REPLACE, + "krb5PasswordEnd", + ent->entry.pw_end); + if (ret) + goto out; } - } - } - if (ent->max_life) { - if (orig.max_life == NULL - || (*(ent->max_life) != *(orig.max_life))) { - rc = asprintf(&tmp, "%d", *(ent->max_life)); - if (rc < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); - ret = ENOMEM; - goto out; - } - ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5MaxLife", tmp); - free(tmp); - if (ret != 0) { - goto out; + if (is_samba_account) { + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, + "sambaPwdMustChange", + *(ent->entry.pw_end)); + if (ret) + goto out; } } } - if (ent->max_renew) { - if (orig.max_renew == NULL - || (*(ent->max_renew) != *(orig.max_renew))) { - rc = asprintf(&tmp, "%d", *(ent->max_renew)); - if (rc < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); - ret = ENOMEM; - goto out; - } - ret = - LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5MaxRenew", tmp); - free(tmp); - if (ret != 0) { + +#if 0 /* we we have last_pw_change */ + 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", + *(ent->entry.last_pw_change)); + if (ret) goto out; - } } } +#endif - oflags = HDBFlags2int(orig.flags); - nflags = HDBFlags2int(ent->flags); + if (is_heimdal_entry && ent->entry.max_life) { + if (orig.entry.max_life == NULL + || (*(ent->entry.max_life) != *(orig.entry.max_life))) { - if (oflags != nflags) { - rc = asprintf(&tmp, "%lu", nflags); - if (rc < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); - ret = ENOMEM; - goto out; - } - ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5KDCFlags", tmp); - free(tmp); - if (ret != 0) { - goto out; + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, + "krb5MaxLife", + *(ent->entry.max_life)); + if (ret) + goto out; } } - if (is_new_entry == FALSE && orig.keys.len > 0) { - /* for the moment, clobber and replace keys. */ - ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5Key", NULL); - if (ret != 0) { - goto out; + if (is_heimdal_entry && ent->entry.max_renew) { + if (orig.entry.max_renew == NULL + || (*(ent->entry.max_renew) != *(orig.entry.max_renew))) { + + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, + "krb5MaxRenew", + *(ent->entry.max_renew)); + if (ret) + goto out; } } - for (i = 0; i < ent->keys.len; i++) { - unsigned char *buf; - size_t len; + oflags = HDBFlags2int(orig.entry.flags); + nflags = HDBFlags2int(ent->entry.flags); - ASN1_MALLOC_ENCODE(Key, buf, len, &ent->keys.val[i], &len, ret); - if (ret != 0) - goto out; + if (is_heimdal_entry && oflags != nflags) { - /* addmod_len _owns_ the key, doesn't need to copy it */ - ret = LDAP_addmod_len(&mods, LDAP_MOD_ADD, "krb5Key", buf, len); - if (ret != 0) { + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_REPLACE, + "krb5KDCFlags", + nflags); + if (ret) goto out; - } } - if (ent->etypes) { - /* clobber and replace encryption types. */ - if (is_new_entry == FALSE) { - ret = - LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5EncryptionType", - NULL); + /* 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); + + ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5Key", NULL); + if (ret) + goto out; } - for (i = 0; i < ent->etypes->len; i++) { - rc = asprintf(&tmp, "%d", ent->etypes->val[i]); - if (rc < 0) { - krb5_set_error_string(context, "asprintf: out of memory"); + } + + for (i = 0; i < ent->entry.keys.len; i++) { + + if (is_samba_account + && ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { + char *ntHexPassword; + char *nt; + + /* 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; goto out; } - free(tmp); - ret = - LDAP_addmod(&mods, LDAP_MOD_ADD, "krb5EncryptionType", - tmp); - if (ret != 0) { + ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "sambaNTPassword", + ntHexPassword); + free(ntHexPassword); + 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); + 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; + + ASN1_MALLOC_ENCODE(Key, buf, buf_size, &ent->entry.keys.val[i], &len, ret); + if (ret) + goto out; + if(buf_size != len) + krb5_abortx(context, "internal error in ASN.1 encoder"); + + /* addmod_len _owns_ the key, doesn't need to copy it */ + ret = LDAP_addmod_len(&mods, LDAP_MOD_ADD, "krb5Key", buf, len); + if (ret) + goto out; + } + } + + 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); + ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5EncryptionType", + NULL); + if (ret) + goto out; + add_krb5EncryptionType = 1; + } + } else if (is_heimdal_entry) + add_krb5EncryptionType = 1; + + if (add_krb5EncryptionType) { + for (i = 0; i < ent->entry.etypes->len; i++) { + if (is_samba_account && + ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) + { + ; + } else if (is_heimdal_entry) { + ret = LDAP_addmod_integer(context, &mods, LDAP_MOD_ADD, + "krb5EncryptionType", + ent->entry.etypes->val[i]); + if (ret) + goto out; + } } } } @@ -495,18 +708,17 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * ent, /* for clarity */ ret = 0; - out: + out: - if (ret == 0) { + if (ret == 0) *pmods = mods; - } else if (mods != NULL) { + else if (mods != NULL) { ldap_mods_free(mods, 1); *pmods = NULL; } - if (msg != NULL) { + if (msg) hdb_free_entry(context, &orig); - } return ret; } @@ -516,33 +728,32 @@ LDAP_dn2principal(krb5_context context, HDB * db, const char *dn, krb5_principal * principal) { krb5_error_code ret; - int rc, limit = 1; + int rc; + const char *filter = "(objectClass=krb5Principal)"; char **values; LDAPMessage *res = NULL, *e; - rc = ldap_set_option((LDAP *) db->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; + ret = LDAP_no_size_limit(context, HDB2LDAP(db)); + if (ret) goto out; - } - rc = ldap_search_s((LDAP *) db->db, dn, LDAP_SCOPE_BASE, - "(objectclass=krb5Principal)", krb5principal_attrs, + rc = ldap_search_s(HDB2LDAP(db), dn, LDAP_SCOPE_SUBTREE, + filter, krb5principal_attrs, 0, &res); - if (rc != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_search_s: %s", ldap_err2string(rc)); + 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; goto out; } - e = ldap_first_entry((LDAP *) db->db, res); + e = ldap_first_entry(HDB2LDAP(db), res); if (e == NULL) { ret = HDB_ERR_NOENTRY; goto out; } - values = ldap_get_values((LDAP *) db->db, e, "krb5PrincipalName"); + values = ldap_get_values(HDB2LDAP(db), e, "krb5PrincipalName"); if (values == NULL) { ret = HDB_ERR_NOENTRY; goto out; @@ -552,70 +763,123 @@ LDAP_dn2principal(krb5_context context, HDB * db, const char *dn, ldap_value_free(values); out: - if (res != NULL) { + if (res) ldap_msgfree(res); - } + return ret; } static krb5_error_code -LDAP__lookup_princ(krb5_context context, HDB * db, const char *princname, - LDAPMessage ** msg) +LDAP__lookup_princ(krb5_context context, + HDB *db, + const char *princname, + const char *userid, + LDAPMessage **msg) { krb5_error_code ret; - int rc, limit = 1; + int rc; char *filter = NULL; - (void) LDAP__connect(context, db); + ret = LDAP__connect(context, db); + if (ret) + return ret; - rc = - asprintf(&filter, - "(&(objectclass=krb5KDCEntry)(krb5PrincipalName=%s))", - princname); + rc = asprintf(&filter, + "(&(objectClass=krb5Principal)(krb5PrincipalName=%s))", + princname); if (rc < 0) { krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; goto out; } - rc = ldap_set_option((LDAP *) db->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; + ret = LDAP_no_size_limit(context, HDB2LDAP(db)); + if (ret) goto out; - } - rc = ldap_search_s((LDAP *) db->db, db->name, LDAP_SCOPE_ONELEVEL, filter, + rc = ldap_search_s(HDB2LDAP(db), HDB2BASE(db), LDAP_SCOPE_SUBTREE, filter, krb5kdcentry_attrs, 0, msg); - if (rc != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_search_s: %s", ldap_err2string(rc)); + 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; goto out; } + if (userid && ldap_count_entries(HDB2LDAP(db), *msg) == 0) { + free(filter); + filter = NULL; + ldap_msgfree(*msg); + *msg = NULL; + + rc = asprintf(&filter, + "(&(|(objectClass=sambaSamAccount)(objectClass=%s))(uid=%s))", + structural_object, userid); + if (rc < 0) { + krb5_set_error_string(context, "asprintf: out of memory"); + ret = ENOMEM; + 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); + 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; + goto out; + } + } + ret = 0; out: - if (filter != NULL) { + if (filter) free(filter); - } + return ret; } static krb5_error_code LDAP_principal2message(krb5_context context, HDB * db, - krb5_principal princ, LDAPMessage ** msg) + krb5_const_principal princ, LDAPMessage ** msg) { - char *princname = NULL; + char *name, *name_short = NULL; krb5_error_code ret; + krb5_realm *r, *r0; - ret = krb5_unparse_name(context, princ, &princname); - if (ret != 0) { + *msg = NULL; + + ret = krb5_unparse_name(context, princ, &name); + if (ret) + return ret; + + ret = krb5_get_default_realms(context, &r0); + if(ret) { + free(name); return ret; } + for (r = r0; *r != NULL; r++) { + if(strcmp(krb5_principal_get_realm(context, princ), *r) == 0) { + ret = krb5_unparse_name_short(context, princ, &name_short); + if (ret) { + krb5_free_host_realm(context, r0); + free(name); + return ret; + } + break; + } + } + krb5_free_host_realm(context, r0); - ret = LDAP__lookup_princ(context, db, princname, msg); - free(princname); + ret = LDAP__lookup_princ(context, db, name, name_short, msg); + free(name); + free(name_short); return ret; } @@ -625,51 +889,62 @@ LDAP_principal2message(krb5_context context, HDB * db, */ static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, - hdb_entry * ent) + hdb_entry_ex * ent) { - char *unparsed_name = NULL, *dn = NULL; - int ret; + 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; memset(ent, 0, sizeof(*ent)); - ent->flags = int2HDBFlags(0); + ent->entry.flags = int2HDBFlags(0); - ret = - LDAP_get_string_value(db, msg, "krb5PrincipalName", - &unparsed_name); - if (ret != 0) { - return ret; - } - - ret = krb5_parse_name(context, unparsed_name, &ent->principal); - if (ret != 0) { - goto out; + ret = LDAP_get_string_value(db, msg, "krb5PrincipalName", &unparsed_name); + if (ret == 0) { + ret = krb5_parse_name(context, unparsed_name, &ent->entry.principal); + if (ret) + goto out; + } else { + ret = LDAP_get_string_value(db, msg, "uid", + &unparsed_name); + if (ret == 0) { + ret = krb5_parse_name(context, unparsed_name, &ent->entry.principal); + if (ret) + goto out; + } else { + krb5_set_error_string(context, "hdb-ldap: ldap entry missing" + "principal name"); + return HDB_ERR_NOENTRY; + } } - ret = - LDAP_get_integer_value(db, msg, "krb5KeyVersionNumber", - &ent->kvno); - if (ret != 0) { - ent->kvno = 0; + { + int integer; + ret = LDAP_get_integer_value(db, msg, "krb5KeyVersionNumber", + &integer); + if (ret) + ent->entry.kvno = 0; + else + ent->entry.kvno = integer; } - keys = ldap_get_values_len((LDAP *) db->db, msg, "krb5Key"); + keys = ldap_get_values_len(HDB2LDAP(db), msg, "krb5Key"); if (keys != NULL) { int i; size_t l; - ent->keys.len = ldap_count_values_len(keys); - ent->keys.val = (Key *) calloc(ent->keys.len, sizeof(Key)); - if (ent->keys.val == NULL) { + 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; goto out; } - for (i = 0; i < ent->keys.len; i++) { + for (i = 0; i < ent->entry.keys.len; i++) { decode_Key((unsigned char *) keys[i]->bv_val, - (size_t) keys[i]->bv_len, &ent->keys.val[i], &l); + (size_t) keys[i]->bv_len, &ent->entry.keys.val[i], &l); } ber_bvecfree(keys); } else { @@ -679,124 +954,248 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, * be related to a general directory entry without creating * the keys. Hopefully it's OK. */ - ent->keys.len = 0; - ent->keys.val = NULL; + ent->entry.keys.len = 0; + ent->entry.keys.val = NULL; #else ret = HDB_ERR_NOENTRY; goto out; #endif } - ret = - LDAP_get_generalized_time_value(db, msg, "createTimestamp", - &ent->created_by.time); - if (ret != 0) { - ent->created_by.time = time(NULL); + values = ldap_get_values(HDB2LDAP(db), msg, "krb5EncryptionType"); + if (values != 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; + goto out; + } + ent->entry.etypes->len = ldap_count_values(values); + 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; + goto out; + } + for (i = 0; i < ent->entry.etypes->len; i++) { + ent->entry.etypes->val[i] = atoi(values[i]); + } + ldap_value_free(values); } - ent->created_by.principal = NULL; + for (i = 0; i < ent->entry.keys.len; i++) { + if (ent->entry.keys.val[i].key.keytype == ETYPE_ARCFOUR_HMAC_MD5) { + have_arcfour = 1; + break; + } + } + + /* manually construct the NT (type 23) key */ + ret = LDAP_get_string_value(db, msg, "sambaNTPassword", &ntPasswordIN); + if (ret == 0 && have_arcfour == 0) { + unsigned *etypes; + Key *keys; + int i; + + keys = realloc(ent->entry.keys.val, + (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; + goto out; + } + ent->entry.keys.val = keys; + memset(&ent->entry.keys.val[ent->entry.keys.len], 0, sizeof(Key)); + 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"); + free(ntPasswordIN); + ret = ENOMEM; + goto out; + } + ret = hex_decode(ntPasswordIN, + ent->entry.keys.val[ent->entry.keys.len].key.keyvalue.data, 16); + ent->entry.keys.len++; + + 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; + goto out; + } + ent->entry.etypes->val = NULL; + ent->entry.etypes->len = 0; + } + + for (i = 0; i < ent->entry.etypes->len; i++) + if (ent->entry.etypes->val[i] == ETYPE_ARCFOUR_HMAC_MD5) + 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) * + sizeof(ent->entry.etypes->val[0])); + if (etypes == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + goto out; + } + ent->entry.etypes->val = etypes; + ent->entry.etypes->val[ent->entry.etypes->len] = + ETYPE_ARCFOUR_HMAC_MD5; + ent->entry.etypes->len++; + } + } + + ret = LDAP_get_generalized_time_value(db, msg, "createTimestamp", + &ent->entry.created_by.time); + if (ret) + ent->entry.created_by.time = time(NULL); + + 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->created_by.principal) + if (LDAP_dn2principal(context, db, dn, &ent->entry.created_by.principal) != 0) { - ent->created_by.principal = NULL; + ent->entry.created_by.principal = NULL; } free(dn); } - ent->modified_by = (Event *) malloc(sizeof(Event)); - if (ent->modified_by == NULL) { + 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->modified_by->time); + 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->modified_by->principal) != 0) { - ent->modified_by->principal = NULL; - } + if (LDAP_dn2principal(context, db, dn, &ent->entry.modified_by->principal)) + ent->entry.modified_by->principal = NULL; free(dn); } else { - free(ent->modified_by); - ent->modified_by = NULL; + free(ent->entry.modified_by); + ent->entry.modified_by = NULL; } - if ((ent->valid_start = (KerberosTime *) malloc(sizeof(KerberosTime))) - == 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; goto out; } - ret = - LDAP_get_generalized_time_value(db, msg, "krb5ValidStart", - ent->valid_start); - if (ret != 0) { + ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidStart", + ent->entry.valid_start); + if (ret) { /* OPTIONAL */ - free(ent->valid_start); - ent->valid_start = NULL; + free(ent->entry.valid_start); + ent->entry.valid_start = NULL; } - - if ((ent->valid_end = (KerberosTime *) malloc(sizeof(KerberosTime))) == - 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; goto out; } - ret = - LDAP_get_generalized_time_value(db, msg, "krb5ValidEnd", - ent->valid_end); - if (ret != 0) { + ret = LDAP_get_generalized_time_value(db, msg, "krb5ValidEnd", + ent->entry.valid_end); + if (ret) { /* OPTIONAL */ - free(ent->valid_end); - ent->valid_end = NULL; + free(ent->entry.valid_end); + ent->entry.valid_end = NULL; } - if ((ent->pw_end = (KerberosTime *) malloc(sizeof(KerberosTime))) == - NULL) { + ret = LDAP_get_integer_value(db, msg, "sambaKickoffTime", &tmp_time); + if (ret == 0) { + 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; + goto out; + } + } + *ent->entry.valid_end = tmp_time; + } + + 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; goto out; } - ret = - LDAP_get_generalized_time_value(db, msg, "krb5PasswordEnd", - ent->pw_end); - if (ret != 0) { + ret = LDAP_get_generalized_time_value(db, msg, "krb5PasswordEnd", + ent->entry.pw_end); + if (ret) { /* OPTIONAL */ - free(ent->pw_end); - ent->pw_end = NULL; + free(ent->entry.pw_end); + ent->entry.pw_end = NULL; } - ent->max_life = (int *) malloc(sizeof(int)); - if (ent->max_life == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; - } - ret = LDAP_get_integer_value(db, msg, "krb5MaxLife", ent->max_life); - if (ret != 0) { - free(ent->max_life); - ent->max_life = NULL; + 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; + goto out; + } + } + *ent->entry.pw_end = tmp_time; } - ent->max_renew = (int *) malloc(sizeof(int)); - if (ent->max_renew == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; + /* OPTIONAL */ + ret = LDAP_get_integer_value(db, msg, "sambaPwdLastSet", &tmp_time); + if (ret == 0) + hdb_entry_set_pw_change_time(context, &ent->entry, tmp_time); + + { + int max_life; + + 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; + goto out; + } + ret = LDAP_get_integer_value(db, msg, "krb5MaxLife", &max_life); + if (ret) { + free(ent->entry.max_life); + ent->entry.max_life = NULL; + } else + *ent->entry.max_life = max_life; } - ret = LDAP_get_integer_value(db, msg, "krb5MaxRenew", ent->max_renew); - if (ret != 0) { - free(ent->max_renew); - ent->max_renew = NULL; + + { + int max_renew; + + 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; + goto out; + } + ret = LDAP_get_integer_value(db, msg, "krb5MaxRenew", &max_renew); + if (ret) { + free(ent->entry.max_renew); + ent->entry.max_renew = NULL; + } else + *ent->entry.max_renew = max_renew; } - values = ldap_get_values((LDAP *) db->db, msg, "krb5KDCFlags"); + 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"); @@ -806,46 +1205,109 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, } else { tmp = 0; } - ent->flags = int2HDBFlags(tmp); - values = ldap_get_values((LDAP *) db->db, msg, "krb5EncryptionType"); - if (values != NULL) { - int i; + ent->entry.flags = int2HDBFlags(tmp); - ent->etypes = malloc(sizeof(*(ent->etypes))); - if (ent->etypes == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; - } - ent->etypes->len = ldap_count_values(values); - ent->etypes->val = calloc(ent->etypes->len, sizeof(int)); - for (i = 0; i < ent->etypes->len; i++) { - ent->etypes->val[i] = atoi(values[i]); + /* Try and find Samba flags to put into the mix */ + 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 + + */ + + 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] != ']') + goto out2; + + /* Allow forwarding */ + if (samba_forwardable) + ent->entry.flags.forwardable = TRUE; + + for (i=0; i < flags_len; i++) { + switch (samba_acct_flags[i]) { + case ' ': + case '[': + case ']': + break; + case 'N': + /* how to handle no password in kerberos? */ + break; + case 'D': + ent->entry.flags.invalid = TRUE; + break; + case 'H': + break; + case 'T': + /* temp duplicate */ + ent->entry.flags.invalid = TRUE; + break; + case 'U': + ent->entry.flags.client = TRUE; + break; + case 'M': + break; + case 'W': + case 'S': + ent->entry.flags.server = TRUE; + ent->entry.flags.client = TRUE; + break; + case 'L': + ent->entry.flags.invalid = TRUE; + break; + case 'X': + if (ent->entry.pw_end) { + free(ent->entry.pw_end); + ent->entry.pw_end = NULL; + } + break; + case 'I': + ent->entry.flags.server = TRUE; + ent->entry.flags.client = TRUE; + break; + } } - ldap_value_free(values); + out2: + free(samba_acct_flags); } ret = 0; - out: - if (unparsed_name != NULL) { +out: + if (unparsed_name) free(unparsed_name); - } - if (ret != 0) { - /* I don't think this frees ent itself. */ + if (ret) hdb_free_entry(context, ent); - } return ret; } -static krb5_error_code LDAP_close(krb5_context context, HDB * db) +static krb5_error_code +LDAP_close(krb5_context context, HDB * db) { - ldap_unbind_ext((LDAP *) db->db, NULL, NULL); - db->db = NULL; - + if (HDB2LDAP(db)) { + ldap_unbind_ext(HDB2LDAP(db), NULL, NULL); + ((struct hdbldapdb *)db->hdb_db)->h_lp = NULL; + } + return 0; } @@ -855,26 +1317,30 @@ LDAP_lock(krb5_context context, HDB * db, int operation) return 0; } -static krb5_error_code LDAP_unlock(krb5_context context, HDB * db) +static krb5_error_code +LDAP_unlock(krb5_context context, HDB * db) { return 0; } static krb5_error_code -LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) +LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) { int msgid, rc, parserc; krb5_error_code ret; LDAPMessage *e; - msgid = db->openp; /* BOGUS OVERLOADING */ - if (msgid < 0) { + msgid = HDB2MSGID(db); + if (msgid < 0) return HDB_ERR_NOENTRY; - } do { - rc = ldap_result((LDAP *) db->db, msgid, LDAP_MSG_ONE, NULL, &e); + rc = ldap_result(HDB2LDAP(db), msgid, LDAP_MSG_ONE, NULL, &e); switch (rc) { + case LDAP_RES_SEARCH_REFERENCE: + ldap_msgfree(e); + ret = 0; + break; case LDAP_RES_SEARCH_ENTRY: /* We have an entry. Parse it. */ ret = LDAP_message2entry(context, db, e, entry); @@ -883,33 +1349,38 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) case LDAP_RES_SEARCH_RESULT: /* We're probably at the end of the results. If not, abandon. */ parserc = - ldap_parse_result((LDAP *) db->db, e, NULL, NULL, NULL, + ldap_parse_result(HDB2LDAP(db), e, NULL, NULL, NULL, NULL, NULL, 1); if (parserc != LDAP_SUCCESS && parserc != LDAP_MORE_RESULTS_TO_RETURN) { - krb5_set_error_string(context, "ldap_parse_result: %s", ldap_err2string(parserc)); - ldap_abandon((LDAP *) db->db, msgid); + krb5_set_error_string(context, "ldap_parse_result: %s", + ldap_err2string(parserc)); + ldap_abandon(HDB2LDAP(db), msgid); } ret = HDB_ERR_NOENTRY; - db->openp = -1; + HDBSETMSGID(db, -1); + break; + case LDAP_SERVER_DOWN: + ldap_msgfree(e); + LDAP_close(context, db); + HDBSETMSGID(db, -1); + ret = ENETDOWN; break; - case 0: - case -1: default: /* Some unspecified error (timeout?). Abandon. */ ldap_msgfree(e); - ldap_abandon((LDAP *) db->db, msgid); + ldap_abandon(HDB2LDAP(db), msgid); ret = HDB_ERR_NOENTRY; - db->openp = -1; + HDBSETMSGID(db, -1); break; } } while (rc == LDAP_RES_SEARCH_REFERENCE); if (ret == 0) { - if (db->master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys(context, db, entry); + 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); + hdb_free_entry(context, entry); } } @@ -917,45 +1388,41 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry * entry) } static krb5_error_code -LDAP_firstkey(krb5_context context, HDB * db, unsigned flags, - hdb_entry * entry) +LDAP_firstkey(krb5_context context, HDB *db, unsigned flags, + hdb_entry_ex *entry) { - int msgid, limit = LDAP_NO_LIMIT, rc; + krb5_error_code ret; + int msgid; - (void) LDAP__connect(context, db); + ret = LDAP__connect(context, db); + if (ret) + return ret; - rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (const void *)&limit); - if (rc != LDAP_SUCCESS) { - krb5_set_error_string(context, "ldap_set_option: %s", ldap_err2string(rc)); - return HDB_ERR_BADVERSION; - } + ret = LDAP_no_size_limit(context, HDB2LDAP(db)); + if (ret) + return ret; - msgid = ldap_search((LDAP *) db->db, db->name, - LDAP_SCOPE_ONELEVEL, "(objectclass=krb5KDCEntry)", + msgid = ldap_search(HDB2LDAP(db), HDB2BASE(db), + LDAP_SCOPE_SUBTREE, + "(|(objectClass=krb5Principal)(objectClass=sambaSamAccount))", krb5kdcentry_attrs, 0); - if (msgid < 0) { + if (msgid < 0) return HDB_ERR_NOENTRY; - } - db->openp = msgid; + HDBSETMSGID(db, msgid); return LDAP_seq(context, db, flags, entry); } static krb5_error_code LDAP_nextkey(krb5_context context, HDB * db, unsigned flags, - hdb_entry * entry) + hdb_entry_ex * entry) { return LDAP_seq(context, db, flags, entry); } static krb5_error_code -LDAP_rename(krb5_context context, HDB * db, const char *new_name) -{ - return HDB_ERR_DB_INUSE; -} - -static krb5_error_code LDAP__connect(krb5_context context, HDB * db) +LDAP__connect(krb5_context context, HDB * db) { int rc, version = LDAP_VERSION3; /* @@ -966,43 +1433,44 @@ static krb5_error_code LDAP__connect(krb5_context context, HDB * db) */ struct berval bv = { 0, "" }; - if (db->db != NULL) { + if (HDB2LDAP(db)) { /* connection has been opened. ping server. */ struct sockaddr_un addr; - socklen_t len; + socklen_t len = sizeof(addr); int sd; - if (ldap_get_option((LDAP *) db->db, LDAP_OPT_DESC, &sd) == 0 && + if (ldap_get_option(HDB2LDAP(db), LDAP_OPT_DESC, &sd) == 0 && getpeername(sd, (struct sockaddr *) &addr, &len) < 0) { /* the other end has died. reopen. */ LDAP_close(context, db); } } - if (db->db != NULL) { - /* server is UP */ + if (HDB2LDAP(db) != NULL) /* server is UP */ return 0; - } - rc = ldap_initialize((LDAP **) & db->db, "ldapi:///"); + 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_string(context, "ldap_initialize: %s", + ldap_err2string(rc)); return HDB_ERR_NOENTRY; } - rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_PROTOCOL_VERSION, (const void *)&version); + 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)); - ldap_unbind_ext((LDAP *) db->db, NULL, NULL); - db->db = NULL; + krb5_set_error_string(context, "ldap_set_option: %s", + ldap_err2string(rc)); + LDAP_close(context, db); return HDB_ERR_BADVERSION; } - rc = ldap_sasl_bind_s((LDAP *) db->db, NULL, "EXTERNAL", &bv, NULL, NULL, NULL); + 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)); - ldap_unbind_ext((LDAP *) db->db, NULL, NULL); - db->db = NULL; + krb5_set_error_string(context, "ldap_sasl_bind_s: %s", + ldap_err2string(rc)); + LDAP_close(context, db); return HDB_ERR_BADVERSION; } @@ -1029,18 +1497,17 @@ LDAP_open(krb5_context context, HDB * db, int flags, mode_t mode) } static krb5_error_code -LDAP_fetch(krb5_context context, HDB * db, unsigned flags, - hdb_entry * entry) +LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, + unsigned flags, hdb_entry_ex * entry) { LDAPMessage *msg, *e; krb5_error_code ret; - ret = LDAP_principal2message(context, db, entry->principal, &msg); - if (ret != 0) { + ret = LDAP_principal2message(context, db, principal, &msg); + if (ret) return ret; - } - e = ldap_first_entry((LDAP *) db->db, msg); + e = ldap_first_entry(HDB2LDAP(db), msg); if (e == NULL) { ret = HDB_ERR_NOENTRY; goto out; @@ -1048,10 +1515,10 @@ LDAP_fetch(krb5_context context, HDB * db, unsigned flags, ret = LDAP_message2entry(context, db, e, entry); if (ret == 0) { - if (db->master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys(context, db, entry); + 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); + hdb_free_entry(context, entry); } } @@ -1063,7 +1530,7 @@ LDAP_fetch(krb5_context context, HDB * db, unsigned flags, static krb5_error_code LDAP_store(krb5_context context, HDB * db, unsigned flags, - hdb_entry * entry) + hdb_entry_ex * entry) { LDAPMod **mods = NULL; krb5_error_code ret; @@ -1072,60 +1539,27 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, LDAPMessage *msg = NULL, *e = NULL; char *dn = NULL, *name = NULL; - ret = krb5_unparse_name(context, entry->principal, &name); - if (ret != 0) { - goto out; - } + ret = LDAP_principal2message(context, db, entry->entry.principal, &msg); + if (ret == 0) + e = ldap_first_entry(HDB2LDAP(db), msg); - ret = LDAP__lookup_princ(context, db, name, &msg); - if (ret == 0) { - e = ldap_first_entry((LDAP *) db->db, msg); + ret = krb5_unparse_name(context, entry->entry.principal, &name); + if (ret) { + free(name); + return ret; } - ret = hdb_seal_keys(context, db, entry); - if (ret != 0) { + ret = hdb_seal_keys(context, db, &entry->entry); + if (ret) goto out; - } /* turn new entry into LDAPMod array */ ret = LDAP_entry2mods(context, db, entry, e, &mods); - if (ret != 0) { + if (ret) goto out; - } if (e == NULL) { - /* Doesn't exist yet. */ - char *p; - - e = NULL; - - /* normalize the naming attribute */ - for (p = name; *p != '\0'; p++) { - *p = (char) tolower((int) *p); - } - - /* - * We could do getpwnam() on the local component of - * the principal to find cn/sn but that's probably - * bad thing to do from inside a KDC. Better leave - * it to management tools. - */ - ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "cn", name); - if (ret < 0) { - goto out; - } - - ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "sn", name); - if (ret < 0) { - goto out; - } - - if (db->name != NULL) { - ret = asprintf(&dn, "cn=%s,%s", name, db->name); - } else { - /* A bit bogus, but we don't have a search base */ - ret = asprintf(&dn, "cn=%s", name); - } + ret = asprintf(&dn, "krb5PrincipalName=%s,%s", name, HDB2CREATE(db)); if (ret < 0) { krb5_set_error_string(context, "asprintf: out of memory"); ret = ENOMEM; @@ -1133,7 +1567,7 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, } } else if (flags & HDB_F_REPLACE) { /* Entry exists, and we're allowed to replace it. */ - dn = ldap_get_dn((LDAP *) db->db, e); + dn = ldap_get_dn(HDB2LDAP(db), e); } else { /* Entry exists, but we're not allowed to replace it. Bail. */ ret = HDB_ERR_EXISTS; @@ -1143,182 +1577,253 @@ LDAP_store(krb5_context context, HDB * db, unsigned flags, /* write entry into directory */ if (e == NULL) { /* didn't exist before */ - rc = ldap_add_s((LDAP *) db->db, dn, mods); + rc = ldap_add_s(HDB2LDAP(db), dn, mods); errfn = "ldap_add_s"; } else { /* already existed, send deltas only */ - rc = ldap_modify_s((LDAP *) db->db, dn, mods); + rc = ldap_modify_s(HDB2LDAP(db), dn, mods); errfn = "ldap_modify_s"; } - if (rc == LDAP_SUCCESS) { - ret = 0; - } else { - krb5_set_error_string(context, "%s: %s (dn=%s) %s", - errfn, name, dn, ldap_err2string(rc)); + 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; - } + } else + ret = 0; out: /* free stuff */ - if (dn != NULL) { + if (dn) free(dn); - } - - if (msg != NULL) { + if (msg) ldap_msgfree(msg); - } - - if (mods != NULL) { + if (mods) ldap_mods_free(mods, 1); - } - - if (name != NULL) { + if (name) free(name); - } return ret; } static krb5_error_code -LDAP_remove(krb5_context context, HDB * db, hdb_entry * entry) +LDAP_remove(krb5_context context, HDB *db, krb5_const_principal principal) { krb5_error_code ret; LDAPMessage *msg, *e; char *dn = NULL; int rc, limit = LDAP_NO_LIMIT; - ret = LDAP_principal2message(context, db, entry->principal, &msg); - if (ret != 0) { + ret = LDAP_principal2message(context, db, principal, &msg); + if (ret) goto out; - } - e = ldap_first_entry((LDAP *) db->db, msg); + e = ldap_first_entry(HDB2LDAP(db), msg); if (e == NULL) { ret = HDB_ERR_NOENTRY; goto out; } - dn = ldap_get_dn((LDAP *) db->db, e); + dn = ldap_get_dn(HDB2LDAP(db), e); if (dn == NULL) { ret = HDB_ERR_NOENTRY; goto out; } - rc = ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (const void *)&limit); + 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)); + krb5_set_error_string(context, "ldap_set_option: %s", + ldap_err2string(rc)); ret = HDB_ERR_BADVERSION; goto out; } - rc = ldap_delete_s((LDAP *) db->db, dn); - if (rc == LDAP_SUCCESS) { - ret = 0; - } else { - krb5_set_error_string(context, "ldap_delete_s: %s", ldap_err2string(rc)); + rc = ldap_delete_s(HDB2LDAP(db), dn); + if (check_ldap(context, db, rc)) { + krb5_set_error_string(context, "ldap_delete_s: %s", + ldap_err2string(rc)); ret = HDB_ERR_CANT_LOCK_DB; - } + } else + ret = 0; out: - if (dn != NULL) { + if (dn != NULL) free(dn); - } - - if (msg != NULL) { + if (msg != NULL) ldap_msgfree(msg); - } return ret; } static krb5_error_code -LDAP__get(krb5_context context, HDB * db, krb5_data key, krb5_data * reply) -{ - fprintf(stderr, "LDAP__get not implemented\n"); - abort(); - return 0; -} - -static krb5_error_code -LDAP__put(krb5_context context, HDB * db, int replace, - krb5_data key, krb5_data value) -{ - fprintf(stderr, "LDAP__put not implemented\n"); - abort(); - return 0; -} - -static krb5_error_code -LDAP__del(krb5_context context, HDB * db, krb5_data key) -{ - fprintf(stderr, "LDAP__del not implemented\n"); - abort(); - return 0; -} - -static krb5_error_code LDAP_destroy(krb5_context context, HDB * db) +LDAP_destroy(krb5_context context, HDB * db) { krb5_error_code ret; + LDAP_close(context, db); + ret = hdb_clear_master_key(context, db); - if (db->name != NULL) { - free(db->name); - } + if (HDB2BASE(db)) + free(HDB2BASE(db)); + if (HDB2CREATE(db)) + free(HDB2CREATE(db)); + if (HDB2URL(db)) + free(HDB2URL(db)); + if (db->hdb_name) + free(db->hdb_name); + free(db->hdb_db); free(db); return ret; } krb5_error_code -hdb_ldap_create(krb5_context context, HDB ** db, const char *arg) +hdb_ldap_common(krb5_context context, + HDB ** db, + const char *search_base, + const char *url) { - *db = malloc(sizeof(**db)); + struct hdbldapdb *h; + const char *create_base = NULL; + + if (search_base == NULL && search_base[0] == '\0') { + krb5_set_error_string(context, "ldap search base not configured"); + return ENOMEM; /* XXX */ + } + + if (structural_object == NULL) { + const char *p; + + 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"); + return ENOMEM; + } + } + + 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"); return ENOMEM; } + memset(*db, 0, sizeof(**db)); - (*db)->db = NULL; + h = calloc(1, sizeof(*h)); + if (h == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + free(*db); + *db = NULL; + return ENOMEM; + } + (*db)->hdb_db = h; - if (arg == NULL || arg[0] == '\0') { - /* - * if no argument specified in the configuration file - * then use NULL, which tells OpenLDAP to look in - * the ldap.conf file. This doesn't work for - * writing entries because we don't know where to - * put new principals. - */ - (*db)->name = NULL; - } else { - (*db)->name = strdup(arg); - if ((*db)->name == NULL) { - krb5_set_error_string(context, "strdup: out of memory"); - free(*db); - *db = NULL; - return ENOMEM; - } + /* 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; + return ENOMEM; + } + + h->h_url = strdup(url); + 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; + return ENOMEM; } - (*db)->master_key_set = 0; - (*db)->openp = 0; - (*db)->open = LDAP_open; - (*db)->close = LDAP_close; - (*db)->fetch = LDAP_fetch; - (*db)->store = LDAP_store; - (*db)->remove = LDAP_remove; - (*db)->firstkey = LDAP_firstkey; - (*db)->nextkey = LDAP_nextkey; - (*db)->lock = LDAP_lock; - (*db)->unlock = LDAP_unlock; - (*db)->rename = LDAP_rename; - /* can we ditch these? */ - (*db)->_get = LDAP__get; - (*db)->_put = LDAP__put; - (*db)->_del = LDAP__del; - (*db)->destroy = LDAP_destroy; + create_base = krb5_config_get_string(context, NULL, "kdc", + "hdb-ldap-create-base", NULL); + if (create_base == NULL) + create_base = h->h_base; + + 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; + return ENOMEM; + } + + (*db)->hdb_master_key_set = 0; + (*db)->hdb_openp = 0; + (*db)->hdb_open = LDAP_open; + (*db)->hdb_close = LDAP_close; + (*db)->hdb_fetch = LDAP_fetch; + (*db)->hdb_store = LDAP_store; + (*db)->hdb_remove = LDAP_remove; + (*db)->hdb_firstkey = LDAP_firstkey; + (*db)->hdb_nextkey = LDAP_nextkey; + (*db)->hdb_lock = LDAP_lock; + (*db)->hdb_unlock = LDAP_unlock; + (*db)->hdb_rename = NULL; + (*db)->hdb__get = NULL; + (*db)->hdb__put = NULL; + (*db)->hdb__del = NULL; + (*db)->hdb_destroy = LDAP_destroy; return 0; } +krb5_error_code +hdb_ldap_create(krb5_context context, HDB ** db, const char *arg) +{ + return hdb_ldap_common(context, db, arg, "ldapi:///"); +} + +krb5_error_code +hdb_ldapi_create(krb5_context context, HDB ** db, const char *arg) +{ + krb5_error_code ret; + char *search_base, *p; + + asprintf(&p, "ldapi:%s", arg); + if (p == NULL) { + krb5_set_error_string(context, "out of memory"); + *db = NULL; + return ENOMEM; + } + search_base = strchr(p + strlen("ldapi://"), ':'); + if (search_base == NULL) { + krb5_set_error_string(context, "search base missing"); + *db = NULL; + return HDB_ERR_BADVERSION; + } + *search_base = '\0'; + search_base++; + + ret = hdb_ldap_common(context, db, search_base, p); + free(p); + return ret; +} + +#ifdef OPENLDAP_MODULE + +struct hdb_so_method hdb_ldap_interface = { + HDB_INTERFACE_VERSION, + "ldap", + hdb_ldap_create +}; + +struct hdb_so_method hdb_ldapi_interface = { + HDB_INTERFACE_VERSION, + "ldapi", + hdb_ldapi_create +}; + +#endif + #endif /* OPENLDAP */ diff --git a/crypto/heimdal/lib/hdb/hdb-private.h b/crypto/heimdal/lib/hdb/hdb-private.h index a47de70..5147d8b 100644 --- a/crypto/heimdal/lib/hdb/hdb-private.h +++ b/crypto/heimdal/lib/hdb/hdb-private.h @@ -8,20 +8,47 @@ krb5_error_code _hdb_fetch ( krb5_context /*context*/, HDB */*db*/, + krb5_const_principal /*principal*/, unsigned /*flags*/, - hdb_entry */*entry*/); + hdb_entry_ex */*entry*/); + +hdb_master_key +_hdb_find_master_key ( + uint32_t */*mkvno*/, + hdb_master_key /*mkey*/); + +int +_hdb_mkey_decrypt ( + krb5_context /*context*/, + hdb_master_key /*key*/, + krb5_key_usage /*usage*/, + void */*ptr*/, + size_t /*size*/, + krb5_data */*res*/); + +int +_hdb_mkey_encrypt ( + krb5_context /*context*/, + hdb_master_key /*key*/, + krb5_key_usage /*usage*/, + const void */*ptr*/, + size_t /*size*/, + krb5_data */*res*/); + +int +_hdb_mkey_version (hdb_master_key /*mkey*/); krb5_error_code _hdb_remove ( krb5_context /*context*/, HDB */*db*/, - hdb_entry */*entry*/); + krb5_const_principal /*principal*/); krb5_error_code _hdb_store ( krb5_context /*context*/, HDB */*db*/, unsigned /*flags*/, - hdb_entry */*entry*/); + hdb_entry_ex */*entry*/); #endif /* __hdb_private_h__ */ diff --git a/crypto/heimdal/lib/hdb/hdb-protos.h b/crypto/heimdal/lib/hdb/hdb-protos.h index ce85fcb..4c3d3eb 100644 --- a/crypto/heimdal/lib/hdb/hdb-protos.h +++ b/crypto/heimdal/lib/hdb/hdb-protos.h @@ -4,6 +4,10 @@ #include <stdarg.h> +#ifdef __cplusplus +extern "C" { +#endif + krb5_error_code hdb_add_master_key ( krb5_context /*context*/, @@ -16,6 +20,12 @@ hdb_check_db_format ( HDB */*db*/); krb5_error_code +hdb_clear_extension ( + krb5_context /*context*/, + hdb_entry */*entry*/, + int /*type*/); + +krb5_error_code hdb_clear_master_key ( krb5_context /*context*/, HDB */*db*/); @@ -32,6 +42,52 @@ hdb_db_create ( HDB **/*db*/, const char */*filename*/); +const char * +hdb_db_dir (krb5_context /*context*/); + +const char * +hdb_dbinfo_get_acl_file ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const krb5_config_binding * +hdb_dbinfo_get_binding ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_dbinfo_get_dbname ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_dbinfo_get_label ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_dbinfo_get_log_file ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_dbinfo_get_mkey_file ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +struct hdb_dbinfo * +hdb_dbinfo_get_next ( + struct hdb_dbinfo */*dbp*/, + struct hdb_dbinfo */*dbprevp*/); + +const char * +hdb_dbinfo_get_realm ( + krb5_context /*context*/, + struct hdb_dbinfo */*dbp*/); + +const char * +hdb_default_db (krb5_context /*context*/); + krb5_error_code hdb_enctype2key ( krb5_context /*context*/, @@ -48,9 +104,75 @@ hdb_entry2string ( int hdb_entry2value ( krb5_context /*context*/, - hdb_entry */*ent*/, + const hdb_entry */*ent*/, krb5_data */*value*/); +int +hdb_entry_alias2value ( + krb5_context /*context*/, + const hdb_entry_alias */*alias*/, + krb5_data */*value*/); + +krb5_error_code +hdb_entry_check_mandatory ( + krb5_context /*context*/, + const hdb_entry */*ent*/); + +int +hdb_entry_clear_password ( + krb5_context /*context*/, + hdb_entry */*entry*/); + +krb5_error_code +hdb_entry_get_ConstrainedDelegACL ( + const hdb_entry */*entry*/, + const HDB_Ext_Constrained_delegation_acl **/*a*/); + +krb5_error_code +hdb_entry_get_aliases ( + const hdb_entry */*entry*/, + const HDB_Ext_Aliases **/*a*/); + +int +hdb_entry_get_password ( + krb5_context /*context*/, + HDB */*db*/, + const hdb_entry */*entry*/, + char **/*p*/); + +krb5_error_code +hdb_entry_get_pkinit_acl ( + const hdb_entry */*entry*/, + const HDB_Ext_PKINIT_acl **/*a*/); + +krb5_error_code +hdb_entry_get_pkinit_hash ( + const hdb_entry */*entry*/, + const HDB_Ext_PKINIT_hash **/*a*/); + +krb5_error_code +hdb_entry_get_pw_change_time ( + const hdb_entry */*entry*/, + time_t */*t*/); + +int +hdb_entry_set_password ( + krb5_context /*context*/, + HDB */*db*/, + hdb_entry */*entry*/, + const char */*p*/); + +krb5_error_code +hdb_entry_set_pw_change_time ( + krb5_context /*context*/, + hdb_entry */*entry*/, + time_t /*t*/); + +HDB_extension * +hdb_find_extension ( + const hdb_entry */*entry*/, + int /*type*/); + krb5_error_code hdb_foreach ( krb5_context /*context*/, @@ -60,19 +182,51 @@ hdb_foreach ( void */*data*/); void +hdb_free_dbinfo ( + krb5_context /*context*/, + struct hdb_dbinfo **/*dbp*/); + +void hdb_free_entry ( krb5_context /*context*/, - hdb_entry */*ent*/); + hdb_entry_ex */*ent*/); void hdb_free_key (Key */*key*/); void +hdb_free_keys ( + krb5_context /*context*/, + int /*len*/, + Key */*keys*/); + +void hdb_free_master_key ( krb5_context /*context*/, hdb_master_key /*mkey*/); krb5_error_code +hdb_generate_key_set ( + krb5_context /*context*/, + krb5_principal /*principal*/, + Key **/*ret_key_set*/, + size_t */*nkeyset*/, + int /*no_salt*/); + +krb5_error_code +hdb_generate_key_set_password ( + krb5_context /*context*/, + krb5_principal /*principal*/, + const char */*password*/, + Key **/*keys*/, + size_t */*num_keys*/); + +int +hdb_get_dbinfo ( + krb5_context /*context*/, + struct hdb_dbinfo **/*dbp*/); + +krb5_error_code hdb_init_db ( krb5_context /*context*/, HDB */*db*/); @@ -84,12 +238,30 @@ hdb_key2principal ( krb5_principal /*p*/); krb5_error_code +hdb_ldap_common ( + krb5_context /*context*/, + HDB ** /*db*/, + const char */*search_base*/, + const char */*url*/); + +krb5_error_code hdb_ldap_create ( krb5_context /*context*/, HDB ** /*db*/, const char */*arg*/); krb5_error_code +hdb_ldapi_create ( + krb5_context /*context*/, + HDB ** /*db*/, + const char */*arg*/); + +krb5_error_code +hdb_list_builtin ( + krb5_context /*context*/, + char **/*list*/); + +krb5_error_code hdb_lock ( int /*fd*/, int /*operation*/); @@ -110,14 +282,14 @@ hdb_next_enctype2key ( int hdb_principal2key ( krb5_context /*context*/, - krb5_principal /*p*/, + krb5_const_principal /*p*/, krb5_data */*key*/); krb5_error_code hdb_print_entry ( krb5_context /*context*/, HDB */*db*/, - hdb_entry */*entry*/, + hdb_entry_ex */*entry*/, void */*data*/); krb5_error_code @@ -135,6 +307,24 @@ hdb_read_master_key ( hdb_master_key */*mkey*/); krb5_error_code +hdb_replace_extension ( + krb5_context /*context*/, + hdb_entry */*entry*/, + const HDB_extension */*ext*/); + +krb5_error_code +hdb_seal_key ( + krb5_context /*context*/, + HDB */*db*/, + Key */*k*/); + +krb5_error_code +hdb_seal_key_mkey ( + krb5_context /*context*/, + Key */*k*/, + hdb_master_key /*mkey*/); + +krb5_error_code hdb_seal_keys ( krb5_context /*context*/, HDB */*db*/, @@ -162,6 +352,18 @@ krb5_error_code hdb_unlock (int /*fd*/); krb5_error_code +hdb_unseal_key ( + krb5_context /*context*/, + HDB */*db*/, + Key */*k*/); + +krb5_error_code +hdb_unseal_key_mkey ( + krb5_context /*context*/, + Key */*k*/, + hdb_master_key /*mkey*/); + +krb5_error_code hdb_unseal_keys ( krb5_context /*context*/, HDB */*db*/, @@ -179,10 +381,20 @@ hdb_value2entry ( krb5_data */*value*/, hdb_entry */*ent*/); +int +hdb_value2entry_alias ( + krb5_context /*context*/, + krb5_data */*value*/, + hdb_entry_alias */*ent*/); + krb5_error_code hdb_write_master_key ( krb5_context /*context*/, const char */*filename*/, hdb_master_key /*mkey*/); +#ifdef __cplusplus +} +#endif + #endif /* __hdb_protos_h__ */ diff --git a/crypto/heimdal/lib/hdb/hdb.asn1 b/crypto/heimdal/lib/hdb/hdb.asn1 index 084d5a1..acd8f61 100644 --- a/crypto/heimdal/lib/hdb/hdb.asn1 +++ b/crypto/heimdal/lib/hdb/hdb.asn1 @@ -1,4 +1,4 @@ --- $Id: hdb.asn1,v 1.9 2001/06/21 14:54:53 joda Exp $ +-- $Id: hdb.asn1 20236 2007-02-16 23:52:29Z lha $ HDB DEFINITIONS ::= BEGIN @@ -12,12 +12,12 @@ hdb-pw-salt INTEGER ::= 3 hdb-afs3-salt INTEGER ::= 10 Salt ::= SEQUENCE { - type[0] INTEGER, + type[0] INTEGER (0..4294967295), salt[1] OCTET STRING } Key ::= SEQUENCE { - mkvno[0] INTEGER OPTIONAL, -- master key version number + mkvno[0] INTEGER (0..4294967295) OPTIONAL, -- master key version number key[1] EncryptionKey, salt[2] Salt OPTIONAL } @@ -28,43 +28,100 @@ Event ::= SEQUENCE { } HDBFlags ::= BIT STRING { - initial(0), -- require as-req - forwardable(1), -- may issue forwardable - proxiable(2), -- may issue proxiable - renewable(3), -- may issue renewable - postdate(4), -- may issue postdatable - server(5), -- may be server - client(6), -- may be client - invalid(7), -- entry is invalid - require-preauth(8), -- must use preauth - change-pw(9), -- change password service - require-hwauth(10), -- must use hwauth - ok-as-delegate(11), -- as in TicketFlags - user-to-user(12), -- may use user-to-user auth - immutable(13) -- may not be deleted + initial(0), -- require as-req + forwardable(1), -- may issue forwardable + proxiable(2), -- may issue proxiable + renewable(3), -- may issue renewable + postdate(4), -- may issue postdatable + server(5), -- may be server + client(6), -- may be client + invalid(7), -- entry is invalid + require-preauth(8), -- must use preauth + change-pw(9), -- change password service + require-hwauth(10), -- must use hwauth + ok-as-delegate(11), -- as in TicketFlags + user-to-user(12), -- may use user-to-user auth + 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 } GENERATION ::= SEQUENCE { - time[0] KerberosTime, -- timestamp - usec[1] INTEGER, -- microseconds - gen[2] INTEGER -- generation number + time[0] KerberosTime, -- timestamp + usec[1] INTEGER (0..4294967295), -- microseconds + gen[2] INTEGER (0..4294967295) -- generation number } +HDB-Ext-PKINIT-acl ::= SEQUENCE OF SEQUENCE { + subject[0] UTF8String, + issuer[1] UTF8String OPTIONAL, + anchor[2] UTF8String OPTIONAL +} + +HDB-Ext-PKINIT-hash ::= SEQUENCE OF SEQUENCE { + digest-type[0] OBJECT IDENTIFIER, + digest[1] OCTET STRING +} + +HDB-Ext-Constrained-delegation-acl ::= SEQUENCE OF Principal + +-- hdb-ext-referrals ::= PA-SERVER-REFERRAL-DATA + +HDB-Ext-Lan-Manager-OWF ::= OCTET STRING + +HDB-Ext-Password ::= SEQUENCE { + mkvno[0] INTEGER (0..4294967295) OPTIONAL, -- master key version number + password OCTET STRING +} + +HDB-Ext-Aliases ::= SEQUENCE { + case-insensitive[0] BOOLEAN, -- case insensitive name allowed + aliases[1] SEQUENCE OF Principal -- all names, inc primary +} + + +HDB-extension ::= SEQUENCE { + mandatory[0] BOOLEAN, -- kdc MUST understand this extension, + -- if not the whole entry must + -- be rejected + data[1] CHOICE { + pkinit-acl[0] HDB-Ext-PKINIT-acl, + pkinit-cert-hash[1] HDB-Ext-PKINIT-hash, + allowed-to-delegate-to[2] HDB-Ext-Constrained-delegation-acl, +-- referral-info[3] HDB-Ext-Referrals, + lm-owf[4] HDB-Ext-Lan-Manager-OWF, + password[5] HDB-Ext-Password, + aliases[6] HDB-Ext-Aliases, + last-pw-change[7] KerberosTime, + ... + }, + ... +} + +HDB-extensions ::= SEQUENCE OF HDB-extension + + hdb_entry ::= SEQUENCE { principal[0] Principal OPTIONAL, -- this is optional only -- for compatibility with libkrb5 - kvno[1] INTEGER, + kvno[1] INTEGER (0..4294967295), keys[2] SEQUENCE OF Key, created-by[3] Event, modified-by[4] Event OPTIONAL, valid-start[5] KerberosTime OPTIONAL, valid-end[6] KerberosTime OPTIONAL, pw-end[7] KerberosTime OPTIONAL, - max-life[8] INTEGER OPTIONAL, - max-renew[9] INTEGER OPTIONAL, + max-life[8] INTEGER (0..4294967295) OPTIONAL, + max-renew[9] INTEGER (0..4294967295) OPTIONAL, flags[10] HDBFlags, - etypes[11] SEQUENCE OF INTEGER OPTIONAL, - generation[12] GENERATION OPTIONAL + etypes[11] SEQUENCE OF INTEGER (0..4294967295) OPTIONAL, + generation[12] GENERATION OPTIONAL, + extensions[13] HDB-extensions OPTIONAL +} + +hdb_entry_alias ::= [APPLICATION 0] SEQUENCE { + principal[0] Principal OPTIONAL } END diff --git a/crypto/heimdal/lib/hdb/hdb.c b/crypto/heimdal/lib/hdb/hdb.c index 95fde19..a515709 100644 --- a/crypto/heimdal/lib/hdb/hdb.c +++ b/crypto/heimdal/lib/hdb/hdb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,11 @@ #include "hdb_locl.h" -RCSID("$Id: hdb.c,v 1.44 2001/08/09 08:41:48 assar Exp $"); +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; @@ -47,19 +51,23 @@ static struct hdb_method methods[] = { #if HAVE_NDBM {"ndbm:", hdb_ndbm_create}, #endif -#ifdef OPENLDAP +#if defined(OPENLDAP) && !defined(OPENLDAP_MODULE) {"ldap:", hdb_ldap_create}, + {"ldapi:", hdb_ldapi_create}, #endif -#if HAVE_DB1 || HAVE_DB3 - {"", hdb_db_create}, -#elif defined(HAVE_NDBM) - {"", hdb_ndbm_create}, -#elif defined(OPENLDAP) - {"", hdb_ldap_create}, +#ifdef HAVE_LDB /* Used for integrated samba build */ + {"ldb:", hdb_ldb_create}, #endif {NULL, NULL} }; +#if HAVE_DB1 || HAVE_DB3 +static struct hdb_method dbmetod = {"", hdb_db_create }; +#elif defined(HAVE_NDBM) +static struct hdb_method dbmetod = {"", hdb_ndbm_create }; +#endif + + krb5_error_code hdb_next_enctype2key(krb5_context context, const hdb_entry *e, @@ -70,11 +78,15 @@ hdb_next_enctype2key(krb5_context context, for (k = *key ? (*key) + 1 : e->keys.val; k < e->keys.val + e->keys.len; - k++) + k++) + { if(k->key.keytype == enctype){ *key = k; return 0; } + } + krb5_set_error_string(context, "No next enctype %d for hdb-entry", + (int)enctype); return KRB5_PROG_ETYPE_NOSUPP; /* XXX */ } @@ -128,16 +140,19 @@ hdb_unlock(int fd) } void -hdb_free_entry(krb5_context context, hdb_entry *ent) +hdb_free_entry(krb5_context context, hdb_entry_ex *ent) { int i; - for(i = 0; i < ent->keys.len; ++i) { - Key *k = &ent->keys.val[i]; + if (ent->free_entry) + (*ent->free_entry)(context, ent); + + for(i = 0; i < ent->entry.keys.len; ++i) { + Key *k = &ent->entry.keys.val[i]; memset (k->key.keyvalue.data, 0, k->key.keyvalue.length); } - free_hdb_entry(ent); + free_hdb_entry(&ent->entry); } krb5_error_code @@ -148,13 +163,15 @@ hdb_foreach(krb5_context context, void *data) { krb5_error_code ret; - hdb_entry entry; - ret = db->firstkey(context, db, flags, &entry); + hdb_entry_ex entry; + ret = db->hdb_firstkey(context, db, flags, &entry); + if (ret == 0) + krb5_clear_error_string(context); while(ret == 0){ ret = (*func)(context, db, &entry, data); hdb_free_entry(context, &entry); if(ret == 0) - ret = db->nextkey(context, db, flags, &entry); + ret = db->hdb_nextkey(context, db, flags, &entry); } if(ret == HDB_ERR_NOENTRY) ret = 0; @@ -166,15 +183,22 @@ hdb_check_db_format(krb5_context context, HDB *db) { krb5_data tag; krb5_data version; - krb5_error_code ret; + krb5_error_code ret, ret2; unsigned ver; int foo; + ret = db->hdb_lock(context, db, HDB_RLOCK); + if (ret) + return ret; + tag.data = HDB_DB_FORMAT_ENTRY; tag.length = strlen(tag.data); - ret = (*db->_get)(context, db, tag, &version); + ret = (*db->hdb__get)(context, db, tag, &version); + ret2 = db->hdb_unlock(context, db); if(ret) return ret; + if (ret2) + return ret2; foo = sscanf(version.data, "%u", &ver); krb5_data_free (&version); if (foo != 1) @@ -187,7 +211,7 @@ hdb_check_db_format(krb5_context context, HDB *db) krb5_error_code hdb_init_db(krb5_context context, HDB *db) { - krb5_error_code ret; + krb5_error_code ret, ret2; krb5_data tag; krb5_data version; char ver[32]; @@ -196,15 +220,118 @@ hdb_init_db(krb5_context context, HDB *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.length = strlen(tag.data); snprintf(ver, sizeof(ver), "%u", HDB_DB_FORMAT); version.data = ver; version.length = strlen(version.data) + 1; /* zero terminated */ - ret = (*db->_put)(context, db, 0, tag, version); - return ret; + ret = (*db->hdb__put)(context, db, 0, tag, version); + ret2 = db->hdb_unlock(context, db); + if (ret) { + if (ret2) + krb5_clear_error_string(context); + return ret; + } + return ret2; } +#ifdef HAVE_DLOPEN + + /* + * Load a dynamic backend from /usr/heimdal/lib/hdb_NAME.so, + * looking for the hdb_NAME_create symbol. + */ + +static const struct hdb_method * +find_dynamic_method (krb5_context context, + const char *filename, + const char **rest) +{ + static struct hdb_method method; + struct hdb_so_method *mso; + char *prefix, *path, *symbol; + const char *p; + void *dl; + size_t len; + + p = strchr(filename, ':'); + + /* if no prefix, don't know what module to load, just ignore it */ + if (p == NULL) + return NULL; + + len = p - filename; + *rest = filename + len + 1; + + prefix = strndup(filename, len); + if (prefix == NULL) + krb5_errx(context, 1, "out of memory"); + + if (asprintf(&path, LIBDIR "/hdb_%s.so", prefix) == -1) + krb5_errx(context, 1, "out of memory"); + +#ifndef RTLD_NOW +#define RTLD_NOW 0 +#endif +#ifndef RTLD_GLOBAL +#define RTLD_GLOBAL 0 +#endif + + dl = dlopen(path, RTLD_NOW | RTLD_GLOBAL); + if (dl == NULL) { + krb5_warnx(context, "error trying to load dynamic module %s: %s\n", + path, dlerror()); + free(prefix); + free(path); + return NULL; + } + + if (asprintf(&symbol, "hdb_%s_interface", prefix) == -1) + krb5_errx(context, 1, "out of memory"); + + mso = dlsym(dl, symbol); + if (mso == NULL) { + krb5_warnx(context, "error finding symbol %s in %s: %s\n", + symbol, path, dlerror()); + dlclose(dl); + free(symbol); + free(prefix); + free(path); + return NULL; + } + free(path); + free(symbol); + + if (mso->version != HDB_INTERFACE_VERSION) { + krb5_warnx(context, + "error wrong version in shared module %s " + "version: %d should have been %d\n", + prefix, mso->version, HDB_INTERFACE_VERSION); + dlclose(dl); + free(prefix); + return NULL; + } + + if (mso->create == NULL) { + krb5_errx(context, 1, + "no entry point function in shared mod %s ", + prefix); + dlclose(dl); + free(prefix); + return NULL; + } + + method.create = mso->create; + method.prefix = prefix; + + return &method; +} +#endif /* HAVE_DLOPEN */ + /* * find the relevant method for `filename', returning a pointer to the * rest in `rest'. @@ -216,15 +343,56 @@ find_method (const char *filename, const char **rest) { const struct hdb_method *h; - for (h = methods; h->prefix != NULL; ++h) + for (h = methods; h->prefix != NULL; ++h) { if (strncmp (filename, h->prefix, strlen(h->prefix)) == 0) { *rest = filename + strlen(h->prefix); return h; } + } +#if defined(HAVE_DB1) || defined(HAVE_DB3) || defined(HAVE_NDBM) + if (strncmp(filename, "/", 1) == 0 + || strncmp(filename, "./", 2) == 0 + || strncmp(filename, "../", 3) == 0) + { + *rest = filename; + return &dbmetod; + } +#endif + return NULL; } krb5_error_code +hdb_list_builtin(krb5_context context, char **list) +{ + const struct hdb_method *h; + size_t len = 0; + char *buf = NULL; + + for (h = methods; h->prefix != NULL; ++h) { + if (h->prefix[0] == '\0') + continue; + len += strlen(h->prefix) + 2; + } + + len += 1; + buf = malloc(len); + if (buf == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + buf[0] = '\0'; + + for (h = methods; h->prefix != NULL; ++h) { + if (h != methods) + strlcat(buf, ", ", len); + strlcat(buf, h->prefix, len); + } + *list = buf; + return 0; +} + +krb5_error_code hdb_create(krb5_context context, HDB **db, const char *filename) { const struct hdb_method *h; @@ -234,7 +402,11 @@ hdb_create(krb5_context context, HDB **db, const char *filename) filename = HDB_DEFAULT_DB; krb5_add_et_list(context, initialize_hdb_error_table_r); h = find_method (filename, &residual); +#ifdef HAVE_DLOPEN + if (h == NULL) + h = find_dynamic_method (context, filename, &residual); +#endif if (h == NULL) - krb5_errx(context, 1, "No database support! (hdb_create)"); + krb5_errx(context, 1, "No database support for %s", filename); return (*h->create)(context, db, residual); } diff --git a/crypto/heimdal/lib/hdb/hdb.h b/crypto/heimdal/lib/hdb/hdb.h index 21d739b..742b924 100644 --- a/crypto/heimdal/lib/hdb/hdb.h +++ b/crypto/heimdal/lib/hdb/hdb.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,59 +31,112 @@ * SUCH DAMAGE. */ -/* $Id: hdb.h,v 1.31 2000/07/08 16:03:37 joda Exp $ */ +/* $Id: hdb.h 22198 2007-12-07 13:09:25Z lha $ */ #ifndef __HDB_H__ #define __HDB_H__ #include <hdb_err.h> +#include <heim_asn1.h> #include <hdb_asn1.h> +struct hdb_dbinfo; + enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; /* flags for various functions */ -#define HDB_F_DECRYPT 1 /* decrypt keys */ -#define HDB_F_REPLACE 2 /* replace entry */ +#define HDB_F_DECRYPT 1 /* decrypt keys */ +#define HDB_F_REPLACE 2 /* replace entry */ +#define HDB_F_GET_CLIENT 4 /* fetch client */ +#define HDB_F_GET_SERVER 8 /* fetch server */ +#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 */ /* key usage for master key */ #define HDB_KU_MKEY 0x484442 typedef struct hdb_master_key_data *hdb_master_key; +typedef struct hdb_entry_ex { + void *ctx; + hdb_entry entry; + void (*free_entry)(krb5_context, struct hdb_entry_ex *); +} hdb_entry_ex; + + typedef struct HDB{ - void *db; - void *dbc; - char *name; - int master_key_set; - hdb_master_key master_key; - int openp; - - krb5_error_code (*open)(krb5_context, struct HDB*, int, mode_t); - krb5_error_code (*close)(krb5_context, struct HDB*); - krb5_error_code (*fetch)(krb5_context, struct HDB*, unsigned, hdb_entry*); - krb5_error_code (*store)(krb5_context, struct HDB*, unsigned, hdb_entry*); - krb5_error_code (*remove)(krb5_context, struct HDB*, hdb_entry*); - krb5_error_code (*firstkey)(krb5_context, struct HDB*, - unsigned, hdb_entry*); - krb5_error_code (*nextkey)(krb5_context, struct HDB*, - unsigned, hdb_entry*); - krb5_error_code (*lock)(krb5_context, struct HDB*, int operation); - krb5_error_code (*unlock)(krb5_context, struct HDB*); - krb5_error_code (*rename)(krb5_context, struct HDB*, const char*); - krb5_error_code (*_get)(krb5_context, struct HDB*, krb5_data, krb5_data*); - krb5_error_code (*_put)(krb5_context, struct HDB*, int, - krb5_data, krb5_data); - krb5_error_code (*_del)(krb5_context, struct HDB*, krb5_data); - krb5_error_code (*destroy)(krb5_context, struct HDB*); + void *hdb_db; + void *hdb_dbc; + 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*, + 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*); }HDB; -#define HDB_DB_DIR "/var/heimdal" -#define HDB_DEFAULT_DB HDB_DB_DIR "/heimdal" -#define HDB_DB_FORMAT_ENTRY "hdb/db-format" +#define HDB_INTERFACE_VERSION 4 + +struct hdb_so_method { + int version; + const char *prefix; + krb5_error_code (*create)(krb5_context, HDB **, const char *filename); +}; typedef krb5_error_code (*hdb_foreach_func_t)(krb5_context, HDB*, - hdb_entry*, void*); + hdb_entry_ex*, void*); extern krb5_kt_ops hdb_kt_ops; #include <hdb-protos.h> diff --git a/crypto/heimdal/lib/hdb/hdb.schema b/crypto/heimdal/lib/hdb/hdb.schema new file mode 100644 index 0000000..6e5c0f7 --- /dev/null +++ b/crypto/heimdal/lib/hdb/hdb.schema @@ -0,0 +1,139 @@ +# Definitions for a Kerberos V KDC schema +# +# $Id: hdb.schema 14958 2005-04-25 17:33:40Z lha $ +# +# This version is compatible with OpenLDAP 1.8 +# +# OID Base is iso(1) org(3) dod(6) internet(1) private(4) enterprise(1) padl(5322) kdcSchema(10) +# +# Syntaxes are under 1.3.6.1.4.1.5322.10.0 +# Attributes types are under 1.3.6.1.4.1.5322.10.1 +# Object classes are under 1.3.6.1.4.1.5322.10.2 + +# Syntax definitions + +#krb5KDCFlagsSyntax SYNTAX ::= { +# WITH SYNTAX INTEGER +#-- initial(0), -- require as-req +#-- forwardable(1), -- may issue forwardable +#-- proxiable(2), -- may issue proxiable +#-- renewable(3), -- may issue renewable +#-- postdate(4), -- may issue postdatable +#-- server(5), -- may be server +#-- client(6), -- may be client +#-- invalid(7), -- entry is invalid +#-- require-preauth(8), -- must use preauth +#-- change-pw(9), -- change password service +#-- require-hwauth(10), -- must use hwauth +#-- ok-as-delegate(11), -- as in TicketFlags +#-- user-to-user(12), -- may use user-to-user auth +#-- immutable(13) -- may not be deleted +# ID { 1.3.6.1.4.1.5322.10.0.1 } +#} + +#krb5PrincipalNameSyntax SYNTAX ::= { +# WITH SYNTAX OCTET STRING +#-- String representations of distinguished names as per RFC1510 +# ID { 1.3.6.1.4.1.5322.10.0.2 } +#} + +# Attribute type definitions + +attributetype ( 1.3.6.1.4.1.5322.10.1.1 + NAME 'krb5PrincipalName' + DESC 'The unparsed Kerberos principal name' + EQUALITY caseExactIA5Match + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.2 + NAME 'krb5KeyVersionNumber' + EQUALITY integerMatch + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.3 + NAME 'krb5MaxLife' + EQUALITY integerMatch + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.4 + NAME 'krb5MaxRenew' + EQUALITY integerMatch + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.5 + NAME 'krb5KDCFlags' + EQUALITY integerMatch + SINGLE-VALUE + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.6 + NAME 'krb5EncryptionType' + EQUALITY integerMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.7 + NAME 'krb5ValidStart' + EQUALITY generalizedTimeMatch + ORDERING generalizedTimeOrderingMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 + SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.8 + NAME 'krb5ValidEnd' + EQUALITY generalizedTimeMatch + ORDERING generalizedTimeOrderingMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 + SINGLE-VALUE ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.9 + NAME 'krb5PasswordEnd' + EQUALITY generalizedTimeMatch + ORDERING generalizedTimeOrderingMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 + SINGLE-VALUE ) + +# this is temporary; keys will eventually +# be child entries or compound attributes. +attributetype ( 1.3.6.1.4.1.5322.10.1.10 + NAME 'krb5Key' + DESC 'Encoded ASN1 Key as an octet string' + SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.11 + NAME 'krb5PrincipalRealm' + DESC 'Distinguished name of krb5Realm entry' + SUP distinguishedName ) + +attributetype ( 1.3.6.1.4.1.5322.10.1.12 + NAME 'krb5RealmName' + EQUALITY octetStringMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} ) + +# Object class definitions + +objectclass ( 1.3.6.1.4.1.5322.10.2.1 + NAME 'krb5Principal' + SUP top + AUXILIARY + MUST ( krb5PrincipalName ) + MAY ( cn $ krb5PrincipalRealm ) ) + +objectclass ( 1.3.6.1.4.1.5322.10.2.2 + NAME 'krb5KDCEntry' + SUP krb5Principal + AUXILIARY + MUST ( krb5KeyVersionNumber ) + MAY ( krb5ValidStart $ krb5ValidEnd $ krb5PasswordEnd $ + krb5MaxLife $ krb5MaxRenew $ krb5KDCFlags $ + krb5EncryptionType $ krb5Key ) ) + +objectclass ( 1.3.6.1.4.1.5322.10.2.3 + NAME 'krb5Realm' + SUP top + AUXILIARY + MUST ( krb5RealmName ) ) + diff --git a/crypto/heimdal/lib/hdb/hdb_err.et b/crypto/heimdal/lib/hdb/hdb_err.et index 9929a56..5c5b80b 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,v 1.5 2001/01/28 23:05:52 assar Exp $" +id "$Id: hdb_err.et 15878 2005-08-11 13:17:22Z lha $" error_table hdb @@ -23,5 +23,6 @@ error_code CANT_LOCK_DB, "Insufficient access to lock database" 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" end diff --git a/crypto/heimdal/lib/hdb/keys.c b/crypto/heimdal/lib/hdb/keys.c new file mode 100644 index 0000000..60a5867 --- /dev/null +++ b/crypto/heimdal/lib/hdb/keys.c @@ -0,0 +1,398 @@ +/* + * 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: + * + * 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" + +RCSID("$Id: keys.c 22071 2007-11-14 20:04:50Z lha $"); + +/* + * free all the memory used by (len, keys) + */ + +void +hdb_free_keys (krb5_context context, int len, Key *keys) +{ + int i; + + for (i = 0; i < len; i++) { + free(keys[i].mkvno); + keys[i].mkvno = NULL; + if (keys[i].salt != NULL) { + free_Salt(keys[i].salt); + free(keys[i].salt); + keys[i].salt = NULL; + } + krb5_free_keyblock_contents(context, &keys[i].key); + } + 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 + * means all etypes, and if string is omitted is means the default + * string (for that principal). Additional special values: + * v5 == pw-salt, and + * v4 == des:pw-salt: + * afs or afs3 == des:afs3-salt + */ + +/* the 3 DES types must be first */ +static const krb5_enctype all_etypes[] = { + ETYPE_DES_CBC_MD5, + ETYPE_DES_CBC_MD4, + ETYPE_DES_CBC_CRC, + 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, + krb5_salt *salt, krb5_principal principal) +{ + const char *p; + char buf[3][256]; + int num_buf = 0; + int i, num_enctypes = 0; + krb5_enctype e; + const krb5_enctype *enctypes = NULL; + krb5_error_code ret; + + p = key; + + *ret_enctypes = NULL; + *ret_num_enctypes = 0; + + /* split p in a list of :-separated strings */ + for(num_buf = 0; num_buf < 3; num_buf++) + if(strsep_copy(&p, ":", buf[num_buf], sizeof(buf[num_buf])) == -1) + break; + + salt->saltvalue.data = NULL; + salt->saltvalue.length = 0; + + for(i = 0; i < num_buf; i++) { + if(enctypes == NULL && num_buf > 1) { + /* this might be a etype specifier */ + /* 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; + } else if(strcmp(buf[i], "des3") == 0) { + e = ETYPE_DES3_CBC_SHA1; + enctypes = &e; + num_enctypes = 1; + } else { + ret = krb5_string_to_enctype(context, buf[i], &e); + if (ret == 0) { + enctypes = &e; + num_enctypes = 1; + } else + return ret; + } + continue; + } + if(salt->salttype == 0) { + /* interpret string as a salt specifier, if no etype + is set, this sets default values */ + /* XXX should perhaps use string_to_salttype, but that + interface sucks */ + if(strcmp(buf[i], "pw-salt") == 0) { + if(enctypes == NULL) { + enctypes = all_etypes; + num_enctypes = sizeof(all_etypes)/sizeof(all_etypes[0]); + } + salt->salttype = KRB5_PW_SALT; + } else if(strcmp(buf[i], "afs3-salt") == 0) { + if(enctypes == NULL) { + enctypes = all_etypes; + num_enctypes = 3; + } + salt->salttype = KRB5_AFS3_SALT; + } + continue; + } + + { + /* if there is a final string, use it as the string to + salt with, this is mostly useful with null salt for + 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"); + 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); + 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); + if(salt->saltvalue.data == NULL) { + krb5_set_error_string(context, "out of memory while " + "parsing salt specifiers"); + return ENOMEM; + } + strlwr(salt->saltvalue.data); + 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"); + return ENOMEM; + } + memcpy(*ret_enctypes, enctypes, sizeof(enctypes[0]) * num_enctypes); + *ret_num_enctypes = num_enctypes; + + return 0; +} + +static krb5_error_code +add_enctype_to_key_set(Key **key_set, size_t *nkeyset, + krb5_enctype enctype, krb5_salt *salt) +{ + krb5_error_code ret; + Key key, *tmp; + + memset(&key, 0, sizeof(key)); + + 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)); + 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, + salt->saltvalue.length); + if (ret) { + free_Key(&key); + return ret; + } + } else + key.salt = NULL; + + (*key_set)[*nkeyset] = key; + + *nkeyset += 1; + + return 0; +} + + +/* + * Generate the `key_set' from the [kadmin]default_keys statement. If + * `no_salt' is set, salt is not important (and will not be set) since + * it's random keys that is going to be created. + */ + +krb5_error_code +hdb_generate_key_set(krb5_context context, krb5_principal principal, + Key **ret_key_set, size_t *nkeyset, int no_salt) +{ + char **ktypes, **kp; + krb5_error_code ret; + Key *k, *key_set; + int i, j; + char *default_keytypes[] = { + "des:pw-salt", + "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(); + + *ret_key_set = key_set = NULL; + *nkeyset = 0; + + ret = 0; + + for(kp = ktypes; kp && *kp; kp++) { + const char *p; + krb5_salt salt; + krb5_enctype *enctypes; + size_t num_enctypes; + + p = *kp; + /* check alias */ + if(strcmp(p, "v5") == 0) + p = "pw-salt"; + else if(strcmp(p, "v4") == 0) + p = "des:pw-salt:"; + else if(strcmp(p, "afs") == 0 || strcmp(p, "afs3") == 0) + 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, + &enctypes, &num_enctypes, &salt, principal); + if (ret) { + krb5_warn(context, ret, "bad value for default_keys `%s'", *kp); + ret = 0; + continue; + } + + for (i = 0; i < num_enctypes; i++) { + /* find duplicates */ + for (j = 0; j < *nkeyset; j++) { + + k = &key_set[j]; + + if (k->key.keytype == enctypes[i]) { + if (no_salt) + break; + if (k->salt == NULL && salt.salttype == KRB5_PW_SALT) + break; + if (k->salt->type == salt.salttype && + k->salt->salt.length == salt.saltvalue.length && + 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], + no_salt ? NULL : &salt); + if (ret) { + free(enctypes); + krb5_free_salt(context, salt); + goto out; + } + } + } + free(enctypes); + krb5_free_salt(context, salt); + } + + *ret_key_set = key_set; + + out: + if (ktypes != default_keytypes) + krb5_config_free_strings(ktypes); + + if (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, + "failed to parse any of the [kadmin]default_keys values"); + ret = EINVAL; /* XXX */ + } + + return ret; +} + + +krb5_error_code +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; + + ret = hdb_generate_key_set(context, principal, + keys, num_keys, 0); + if (ret) + return ret; + + for (i = 0; i < (*num_keys); i++) { + krb5_salt salt; + + salt.salttype = (*keys)[i].salt->type; + salt.saltvalue.length = (*keys)[i].salt->salt.length; + salt.saltvalue.data = (*keys)[i].salt->salt.data; + + ret = krb5_string_to_key_salt (context, + (*keys)[i].key.keytype, + password, + salt, + &(*keys)[i].key); + + if(ret) + break; + } + + if(ret) { + hdb_free_keys (context, *num_keys, *keys); + return ret; + } + return ret; +} diff --git a/crypto/heimdal/lib/hdb/keytab.c b/crypto/heimdal/lib/hdb/keytab.c index 6ede2b9..e319bb5 100644 --- a/crypto/heimdal/lib/hdb/keytab.c +++ b/crypto/heimdal/lib/hdb/keytab.c @@ -35,7 +35,7 @@ /* keytab backend for HDB databases */ -RCSID("$Id: keytab.c,v 1.5 2002/08/26 13:28:11 assar Exp $"); +RCSID("$Id: keytab.c 18380 2006-10-09 12:36:40Z lha $"); struct hdb_data { char *dbname; @@ -44,7 +44,7 @@ struct hdb_data { /* * the format for HDB keytabs is: - * HDB:[database:mkey] + * HDB:[database:file:mkey] */ static krb5_error_code @@ -76,7 +76,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id) if((mkey - db) == 0) { d->dbname = NULL; } else { - d->dbname = malloc(mkey - db); + d->dbname = malloc(mkey - db + 1); if(d->dbname == NULL) { free(d); krb5_set_error_string(context, "malloc: out of memory"); @@ -125,7 +125,7 @@ hdb_get_name(krb5_context context, static void set_config (krb5_context context, - krb5_config_binding *binding, + const krb5_config_binding *binding, const char **dbname, const char **mkey) { @@ -145,13 +145,13 @@ find_db (krb5_context context, krb5_const_principal principal) { const krb5_config_binding *top_bind = NULL; - krb5_config_binding *default_binding = NULL; - krb5_config_binding *db; - krb5_realm *prealm = krb5_princ_realm(context, (krb5_principal)principal); + const krb5_config_binding *default_binding = NULL; + const krb5_config_binding *db; + krb5_realm *prealm = krb5_princ_realm(context, rk_UNCONST(principal)); *dbname = *mkey = NULL; - while ((db = (krb5_config_binding *) + while ((db = krb5_config_get_next(context, NULL, &top_bind, @@ -193,7 +193,7 @@ hdb_get_entry(krb5_context context, krb5_enctype enctype, krb5_keytab_entry *entry) { - hdb_entry ent; + hdb_entry_ex ent; krb5_error_code ret; struct hdb_data *d = id->data; int i; @@ -201,6 +201,8 @@ hdb_get_entry(krb5_context context, const char *dbname = d->dbname; const char *mkey = d->mkey; + memset(&ent, 0, sizeof(ent)); + if (dbname == NULL) find_db (context, &dbname, &mkey, principal); @@ -209,44 +211,50 @@ hdb_get_entry(krb5_context context, return ret; ret = hdb_set_master_keyfile (context, db, mkey); if (ret) { - (*db->destroy)(context, db); + (*db->hdb_destroy)(context, db); return ret; } - ret = (*db->open)(context, db, O_RDONLY, 0); + ret = (*db->hdb_open)(context, db, O_RDONLY, 0); if (ret) { - (*db->destroy)(context, db); + (*db->hdb_destroy)(context, db); return ret; } - ent.principal = (krb5_principal)principal; - ret = (*db->fetch)(context, db, HDB_F_DECRYPT, &ent); - (*db->close)(context, db); - (*db->destroy)(context, db); + ret = (*db->hdb_fetch)(context, db, principal, + HDB_F_DECRYPT| + HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, + &ent); - if(ret == HDB_ERR_NOENTRY) - return KRB5_KT_NOTFOUND; - else if(ret) - return ret; - if(kvno && ent.kvno != kvno) { + if(ret == HDB_ERR_NOENTRY) { + ret = KRB5_KT_NOTFOUND; + goto out; + }else if(ret) + goto out; + + if(kvno && ent.entry.kvno != kvno) { hdb_free_entry(context, &ent); - return KRB5_KT_NOTFOUND; + ret = KRB5_KT_NOTFOUND; + goto out; } if(enctype == 0) - if(ent.keys.len > 0) - enctype = ent.keys.val[0].key.keytype; + if(ent.entry.keys.len > 0) + enctype = ent.entry.keys.val[0].key.keytype; ret = KRB5_KT_NOTFOUND; - for(i = 0; i < ent.keys.len; i++) { - if(ent.keys.val[i].key.keytype == enctype) { + for(i = 0; i < ent.entry.keys.len; i++) { + if(ent.entry.keys.val[i].key.keytype == enctype) { krb5_copy_principal(context, principal, &entry->principal); - entry->vno = ent.kvno; + entry->vno = ent.entry.kvno; krb5_copy_keyblock_contents(context, - &ent.keys.val[i].key, + &ent.entry.keys.val[i].key, &entry->keyblock); ret = 0; break; } } hdb_free_entry(context, &ent); +out: + (*db->hdb_close)(context, db); + (*db->hdb_destroy)(context, db); return ret; } diff --git a/crypto/heimdal/lib/hdb/mkey.c b/crypto/heimdal/lib/hdb/mkey.c index 92bcd86..05cf71c 100644 --- a/crypto/heimdal/lib/hdb/mkey.c +++ b/crypto/heimdal/lib/hdb/mkey.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000 - 2002 Kungliga Tekniska Högskolan + * Copyright (c) 2000 - 2004 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -36,7 +36,7 @@ #define O_BINARY 0 #endif -RCSID("$Id: mkey.c,v 1.15 2003/03/28 02:01:33 lha Exp $"); +RCSID("$Id: mkey.c 21745 2007-07-31 16:11:25Z lha $"); struct hdb_master_key_data { krb5_keytab_entry keytab; @@ -129,6 +129,11 @@ read_master_keytab(krb5_context context, const char *filename, *mkey = NULL; while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) { p = calloc(1, sizeof(*p)); + if(p == NULL) { + krb5_kt_end_seq_get(context, id, &cursor); + ret = ENOMEM; + goto out; + } p->keytab = entry; ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto); p->next = *mkey; @@ -148,7 +153,7 @@ read_master_mit(krb5_context context, const char *filename, int fd; krb5_error_code ret; krb5_storage *sp; - u_int16_t enctype; + int16_t enctype; krb5_keyblock key; fd = open(filename, O_RDONLY | O_BINARY); @@ -354,68 +359,111 @@ hdb_write_master_key(krb5_context context, const char *filename, return ret; } -static hdb_master_key -find_master_key(Key *key, hdb_master_key mkey) +hdb_master_key +_hdb_find_master_key(uint32_t *mkvno, hdb_master_key mkey) { hdb_master_key ret = NULL; while(mkey) { if(ret == NULL && mkey->keytab.vno == 0) ret = mkey; - if(key->mkvno == NULL) { + if(mkvno == NULL) { if(ret == NULL || mkey->keytab.vno > ret->keytab.vno) ret = mkey; - } else if(mkey->keytab.vno == *key->mkvno) + } else if(mkey->keytab.vno == *mkvno) return mkey; mkey = mkey->next; } return ret; } +int +_hdb_mkey_version(hdb_master_key mkey) +{ + return mkey->keytab.vno; +} + +int +_hdb_mkey_decrypt(krb5_context context, hdb_master_key key, + krb5_key_usage usage, + void *ptr, size_t size, krb5_data *res) +{ + return krb5_decrypt(context, key->crypto, usage, + ptr, size, res); +} + +int +_hdb_mkey_encrypt(krb5_context context, hdb_master_key key, + krb5_key_usage usage, + const void *ptr, size_t size, krb5_data *res) +{ + return krb5_encrypt(context, key->crypto, usage, + ptr, size, res); +} + krb5_error_code -hdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) +hdb_unseal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) { - int i; + krb5_error_code ret; krb5_data res; size_t keysize; - Key *k; - for(i = 0; i < ent->keys.len; i++){ - hdb_master_key key; + hdb_master_key key; + + if(k->mkvno == NULL) + return 0; + + key = _hdb_find_master_key(k->mkvno, mkey); + + if (key == NULL) + return HDB_ERR_NO_MKEY; + + ret = _hdb_mkey_decrypt(context, key, HDB_KU_MKEY, + k->key.keyvalue.data, + k->key.keyvalue.length, + &res); + if(ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { + /* try to decrypt with MIT key usage */ + ret = _hdb_mkey_decrypt(context, key, 0, + k->key.keyvalue.data, + k->key.keyvalue.length, + &res); + } + if (ret) + return ret; - k = &ent->keys.val[i]; - if(k->mkvno == NULL) - continue; + /* fixup keylength if the key got padded when encrypting it */ + ret = krb5_enctype_keysize(context, k->key.keytype, &keysize); + if (ret) { + krb5_data_free(&res); + return ret; + } + if (keysize > res.length) { + krb5_data_free(&res); + return KRB5_BAD_KEYSIZE; + } - key = find_master_key(&ent->keys.val[i], mkey); + memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); + free(k->key.keyvalue.data); + k->key.keyvalue = res; + k->key.keyvalue.length = keysize; + free(k->mkvno); + k->mkvno = NULL; - if (key == NULL) - return HDB_ERR_NO_MKEY; + return 0; +} - ret = krb5_decrypt(context, key->crypto, HDB_KU_MKEY, - k->key.keyvalue.data, - k->key.keyvalue.length, - &res); - if (ret) - return ret; +krb5_error_code +hdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) +{ + int i; - /* fixup keylength if the key got padded when encrypting it */ - ret = krb5_enctype_keysize(context, k->key.keytype, &keysize); - if (ret) { - krb5_data_free(&res); - return ret; - } - if (keysize > res.length) { - krb5_data_free(&res); - return KRB5_BAD_KEYSIZE; - } + for(i = 0; i < ent->keys.len; i++){ + krb5_error_code ret; - memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); - free(k->key.keyvalue.data); - k->key.keyvalue = res; - k->key.keyvalue.length = keysize; - free(k->mkvno); - k->mkvno = NULL; + ret = hdb_unseal_key_mkey(context, &ent->keys.val[i], mkey); + if (ret) + return ret; } return 0; } @@ -423,44 +471,65 @@ hdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) krb5_error_code hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent) { - if (db->master_key_set == 0) + if (db->hdb_master_key_set == 0) return 0; - return hdb_unseal_keys_mkey(context, ent, db->master_key); + return hdb_unseal_keys_mkey(context, ent, db->hdb_master_key); } krb5_error_code -hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) +hdb_unseal_key(krb5_context context, HDB *db, Key *k) +{ + if (db->hdb_master_key_set == 0) + return 0; + return hdb_unseal_key_mkey(context, k, db->hdb_master_key); +} + +krb5_error_code +hdb_seal_key_mkey(krb5_context context, Key *k, hdb_master_key mkey) { - int i; krb5_error_code ret; krb5_data res; - for(i = 0; i < ent->keys.len; i++){ - Key *k = &ent->keys.val[i]; - hdb_master_key key; + hdb_master_key key; - if(k->mkvno != NULL) - continue; + if(k->mkvno != NULL) + return 0; - key = find_master_key(k, mkey); + key = _hdb_find_master_key(k->mkvno, mkey); - if (key == NULL) - return HDB_ERR_NO_MKEY; + if (key == NULL) + return HDB_ERR_NO_MKEY; - ret = krb5_encrypt(context, key->crypto, HDB_KU_MKEY, - k->key.keyvalue.data, - k->key.keyvalue.length, - &res); - if (ret) - return ret; + ret = _hdb_mkey_encrypt(context, key, HDB_KU_MKEY, + k->key.keyvalue.data, + k->key.keyvalue.length, + &res); + if (ret) + return ret; - memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); - free(k->key.keyvalue.data); - k->key.keyvalue = res; + memset(k->key.keyvalue.data, 0, k->key.keyvalue.length); + free(k->key.keyvalue.data); + k->key.keyvalue = res; + if (k->mkvno == NULL) { k->mkvno = malloc(sizeof(*k->mkvno)); if (k->mkvno == NULL) return ENOMEM; - *k->mkvno = key->keytab.vno; + } + *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; + for(i = 0; i < ent->keys.len; i++){ + krb5_error_code ret; + + ret = hdb_seal_key_mkey(context, &ent->keys.val[i], mkey); + if (ret) + return ret; } return 0; } @@ -468,10 +537,19 @@ hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey) krb5_error_code hdb_seal_keys(krb5_context context, HDB *db, hdb_entry *ent) { - if (db->master_key_set == 0) + if (db->hdb_master_key_set == 0) + return 0; + + return hdb_seal_keys_mkey(context, ent, db->hdb_master_key); +} + +krb5_error_code +hdb_seal_key(krb5_context context, HDB *db, Key *k) +{ + if (db->hdb_master_key_set == 0) return 0; - return hdb_seal_keys_mkey(context, ent, db->master_key); + return hdb_seal_key_mkey(context, k, db->hdb_master_key); } krb5_error_code @@ -485,11 +563,11 @@ hdb_set_master_key (krb5_context context, ret = hdb_process_master_key(context, 0, key, 0, &mkey); if (ret) return ret; - db->master_key = mkey; + db->hdb_master_key = mkey; #if 0 /* XXX - why? */ des_set_random_generator_seed(key.keyvalue.data); #endif - db->master_key_set = 1; + db->hdb_master_key_set = 1; return 0; } @@ -508,8 +586,8 @@ hdb_set_master_keyfile (krb5_context context, krb5_clear_error_string(context); return 0; } - db->master_key = key; - db->master_key_set = 1; + db->hdb_master_key = key; + db->hdb_master_key_set = 1; return ret; } @@ -517,9 +595,9 @@ krb5_error_code hdb_clear_master_key (krb5_context context, HDB *db) { - if (db->master_key_set) { - hdb_free_master_key(context, db->master_key); - db->master_key_set = 0; + if (db->hdb_master_key_set) { + hdb_free_master_key(context, db->hdb_master_key); + db->hdb_master_key_set = 0; } return 0; } diff --git a/crypto/heimdal/lib/hdb/ndbm.c b/crypto/heimdal/lib/hdb/ndbm.c index c162145..6575b8a 100644 --- a/crypto/heimdal/lib/hdb/ndbm.c +++ b/crypto/heimdal/lib/hdb/ndbm.c @@ -33,7 +33,7 @@ #include "hdb_locl.h" -RCSID("$Id: ndbm.c,v 1.33 2001/09/03 05:03:01 assar Exp $"); +RCSID("$Id: ndbm.c 16395 2005-12-13 11:54:10Z lha $"); #if HAVE_NDBM @@ -56,7 +56,7 @@ NDBM_destroy(krb5_context context, HDB *db) krb5_error_code ret; ret = hdb_clear_master_key (context, db); - free(db->name); + free(db->hdb_name); free(db); return 0; } @@ -64,23 +64,23 @@ NDBM_destroy(krb5_context context, HDB *db) static krb5_error_code NDBM_lock(krb5_context context, HDB *db, int operation) { - struct ndbm_db *d = db->db; + struct ndbm_db *d = db->hdb_db; return hdb_lock(d->lock_fd, operation); } static krb5_error_code NDBM_unlock(krb5_context context, HDB *db) { - struct ndbm_db *d = db->db; + struct ndbm_db *d = db->hdb_db; return hdb_unlock(d->lock_fd); } static krb5_error_code NDBM_seq(krb5_context context, HDB *db, - unsigned flags, hdb_entry *entry, int first) + unsigned flags, hdb_entry_ex *entry, int first) { - struct ndbm_db *d = (struct ndbm_db *)db->db; + struct ndbm_db *d = (struct ndbm_db *)db->hdb_db; datum key, value; krb5_data key_data, data; krb5_error_code ret = 0; @@ -93,27 +93,28 @@ NDBM_seq(krb5_context context, HDB *db, return HDB_ERR_NOENTRY; key_data.data = key.dptr; key_data.length = key.dsize; - ret = db->lock(context, db, HDB_RLOCK); + ret = db->hdb_lock(context, db, HDB_RLOCK); if(ret) return ret; value = dbm_fetch(d->db, key); - db->unlock(context, db); + db->hdb_unlock(context, db); data.data = value.dptr; data.length = value.dsize; - if(hdb_value2entry(context, &data, entry)) + memset(entry, 0, sizeof(*entry)); + if(hdb_value2entry(context, &data, &entry->entry)) return NDBM_seq(context, db, flags, entry, 0); - if (db->master_key_set && (flags & HDB_F_DECRYPT)) { - ret = hdb_unseal_keys (context, db, entry); + 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); } - if (entry->principal == NULL) { - entry->principal = malloc (sizeof(*entry->principal)); - if (entry->principal == NULL) { + 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"); } else { - hdb_key2principal (context, &key_data, entry->principal); + hdb_key2principal (context, &key_data, entry->entry.principal); } } return ret; @@ -121,14 +122,14 @@ NDBM_seq(krb5_context context, HDB *db, static krb5_error_code -NDBM_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) +NDBM_firstkey(krb5_context context, HDB *db,unsigned flags,hdb_entry_ex *entry) { return NDBM_seq(context, db, flags, entry, 1); } static krb5_error_code -NDBM_nextkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry) +NDBM_nextkey(krb5_context context, HDB *db, unsigned flags,hdb_entry_ex *entry) { return NDBM_seq(context, db, flags, entry, 0); } @@ -137,7 +138,7 @@ static krb5_error_code NDBM_rename(krb5_context context, HDB *db, const char *new_name) { /* XXX this function will break */ - struct ndbm_db *d = db->db; + struct ndbm_db *d = db->hdb_db; int ret; char *old_dir, *old_pag, *new_dir, *new_pag; @@ -145,19 +146,19 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) int lock_fd; /* lock old and new databases */ - ret = db->lock(context, db, HDB_WLOCK); + ret = db->hdb_lock(context, db, HDB_WLOCK); if(ret) return ret; asprintf(&new_lock, "%s.lock", new_name); if(new_lock == NULL) { - db->unlock(context, db); + 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->unlock(context, db); + db->hdb_unlock(context, db); krb5_set_error_string(context, "open(%s): %s", new_lock, strerror(ret)); free(new_lock); @@ -166,13 +167,13 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) free(new_lock); ret = hdb_lock(lock_fd, HDB_WLOCK); if(ret) { - db->unlock(context, db); + db->hdb_unlock(context, db); close(lock_fd); return ret; } - asprintf(&old_dir, "%s.dir", db->name); - asprintf(&old_pag, "%s.pag", db->name); + asprintf(&old_dir, "%s.dir", db->hdb_name); + asprintf(&old_pag, "%s.pag", db->hdb_name); asprintf(&new_dir, "%s.dir", new_name); asprintf(&new_pag, "%s.pag", new_name); @@ -182,7 +183,7 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) free(new_dir); free(new_pag); hdb_unlock(lock_fd); - db->unlock(context, db); + db->hdb_unlock(context, db); if(ret) { ret = errno; @@ -194,25 +195,25 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) close(d->lock_fd); d->lock_fd = lock_fd; - free(db->name); - db->name = strdup(new_name); + free(db->hdb_name); + db->hdb_name = strdup(new_name); return 0; } static krb5_error_code NDBM__get(krb5_context context, HDB *db, krb5_data key, krb5_data *reply) { - struct ndbm_db *d = (struct ndbm_db *)db->db; + struct ndbm_db *d = (struct ndbm_db *)db->hdb_db; datum k, v; int code; k.dptr = key.data; k.dsize = key.length; - code = db->lock(context, db, HDB_RLOCK); + code = db->hdb_lock(context, db, HDB_RLOCK); if(code) return code; v = dbm_fetch(d->db, k); - db->unlock(context, db); + db->hdb_unlock(context, db); if(v.dptr == NULL) return HDB_ERR_NOENTRY; @@ -224,7 +225,7 @@ static krb5_error_code NDBM__put(krb5_context context, HDB *db, int replace, krb5_data key, krb5_data value) { - struct ndbm_db *d = (struct ndbm_db *)db->db; + struct ndbm_db *d = (struct ndbm_db *)db->hdb_db; datum k, v; int code; @@ -233,11 +234,11 @@ NDBM__put(krb5_context context, HDB *db, int replace, v.dptr = value.data; v.dsize = value.length; - code = db->lock(context, db, HDB_WLOCK); + code = db->hdb_lock(context, db, HDB_WLOCK); if(code) return code; code = dbm_store(d->db, k, v, replace ? DBM_REPLACE : DBM_INSERT); - db->unlock(context, db); + db->hdb_unlock(context, db); if(code == 1) return HDB_ERR_EXISTS; if (code < 0) @@ -248,22 +249,33 @@ NDBM__put(krb5_context context, HDB *db, int replace, static krb5_error_code NDBM__del(krb5_context context, HDB *db, krb5_data key) { - struct ndbm_db *d = (struct ndbm_db *)db->db; + struct ndbm_db *d = (struct ndbm_db *)db->hdb_db; datum k; int code; krb5_error_code ret; k.dptr = key.data; k.dsize = key.length; - ret = db->lock(context, db, HDB_WLOCK); + ret = db->hdb_lock(context, db, HDB_WLOCK); if(ret) return ret; code = dbm_delete(d->db, k); - db->unlock(context, db); + db->hdb_unlock(context, db); if(code < 0) return errno; return 0; } + +static krb5_error_code +NDBM_close(krb5_context context, HDB *db) +{ + struct ndbm_db *d = db->hdb_db; + dbm_close(d->db); + close(d->lock_fd); + free(d); + return 0; +} + static krb5_error_code NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) { @@ -275,18 +287,18 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - asprintf(&lock_file, "%s.lock", (char*)db->name); + asprintf(&lock_file, "%s.lock", (char*)db->hdb_name); if(lock_file == NULL) { free(d); krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - d->db = dbm_open((char*)db->name, flags, mode); + 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->name, + krb5_set_error_string(context, "dbm_open(%s): %s", db->hdb_name, strerror(ret)); return ret; } @@ -301,60 +313,57 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) return ret; } free(lock_file); - db->db = d; + db->hdb_db = d; 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) 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); + } return ret; } -static krb5_error_code -NDBM_close(krb5_context context, HDB *db) -{ - struct ndbm_db *d = db->db; - dbm_close(d->db); - close(d->lock_fd); - free(d); - return 0; -} - krb5_error_code hdb_ndbm_create(krb5_context context, HDB **db, const char *filename) { - *db = malloc(sizeof(**db)); + *db = calloc(1, sizeof(**db)); if (*db == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - (*db)->db = NULL; - (*db)->name = strdup(filename); - if ((*db)->name == NULL) { + (*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; return ENOMEM; } - (*db)->master_key_set = 0; - (*db)->openp = 0; - (*db)->open = NDBM_open; - (*db)->close = NDBM_close; - (*db)->fetch = _hdb_fetch; - (*db)->store = _hdb_store; - (*db)->remove = _hdb_remove; - (*db)->firstkey = NDBM_firstkey; - (*db)->nextkey= NDBM_nextkey; - (*db)->lock = NDBM_lock; - (*db)->unlock = NDBM_unlock; - (*db)->rename = NDBM_rename; - (*db)->_get = NDBM__get; - (*db)->_put = NDBM__put; - (*db)->_del = NDBM__del; - (*db)->destroy = NDBM_destroy; + (*db)->hdb_master_key_set = 0; + (*db)->hdb_openp = 0; + (*db)->hdb_open = NDBM_open; + (*db)->hdb_close = NDBM_close; + (*db)->hdb_fetch = _hdb_fetch; + (*db)->hdb_store = _hdb_store; + (*db)->hdb_remove = _hdb_remove; + (*db)->hdb_firstkey = NDBM_firstkey; + (*db)->hdb_nextkey= NDBM_nextkey; + (*db)->hdb_lock = NDBM_lock; + (*db)->hdb_unlock = NDBM_unlock; + (*db)->hdb_rename = NDBM_rename; + (*db)->hdb__get = NDBM__get; + (*db)->hdb__put = NDBM__put; + (*db)->hdb__del = NDBM__del; + (*db)->hdb_destroy = NDBM_destroy; return 0; } diff --git a/crypto/heimdal/lib/hdb/print.c b/crypto/heimdal/lib/hdb/print.c index 5ad172f..60b7e8d 100644 --- a/crypto/heimdal/lib/hdb/print.c +++ b/crypto/heimdal/lib/hdb/print.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999-2002 Kungliga Tekniska Högskolan + * Copyright (c) 1999-2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,9 +31,10 @@ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "hdb_locl.h" +#include <hex.h> #include <ctype.h> -RCSID("$Id: print.c,v 1.8 2002/05/24 15:18:02 joda Exp $"); +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 @@ -91,8 +92,9 @@ append_hex(krb5_context context, krb5_storage *sp, krb5_data *data) if(printable) return append_string(context, sp, "\"%.*s\"", data->length, data->data); - for(i = 0; i < data->length; i++) - append_string(context, sp, "%02x", ((unsigned char*)data->data)[i]); + hex_encode(data->data, data->length, &p); + append_string(context, sp, "%s", p); + free(p); return 0; } @@ -198,11 +200,41 @@ entry2string_int (krb5_context context, krb5_storage *sp, hdb_entry *ent) /* --- generation number */ if(ent->generation) { - append_string(context, sp, "%s:%d:%d", time2str(ent->generation->time), + append_string(context, sp, "%s:%d:%d ", time2str(ent->generation->time), ent->generation->usec, ent->generation->gen); } else + append_string(context, sp, "- "); + + /* --- extensions */ + if(ent->extensions && ent->extensions->len > 0) { + for(i = 0; i < ent->extensions->len; i++) { + void *d; + size_t size, sz; + + ASN1_MALLOC_ENCODE(HDB_extension, d, size, + &ent->extensions->val[i], &sz, ret); + if (ret) { + krb5_clear_error_string(context); + return ret; + } + if(size != sz) + krb5_abortx(context, "internal asn.1 encoder error"); + + if (hex_encode(d, size, &p) < 0) { + free(d); + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + free(d); + append_string(context, sp, "%s%s", p, + ent->extensions->len - 1 != i ? ":" : ""); + free(p); + } + } else append_string(context, sp, "-"); + return 0; } @@ -236,7 +268,7 @@ hdb_entry2string (krb5_context context, hdb_entry *ent, char **str) /* print a hdb_entry to (FILE*)data; suitable for hdb_foreach */ krb5_error_code -hdb_print_entry(krb5_context context, HDB *db, hdb_entry *entry, void *data) +hdb_print_entry(krb5_context context, HDB *db, hdb_entry_ex *entry, void *data) { krb5_error_code ret; krb5_storage *sp; @@ -250,7 +282,7 @@ hdb_print_entry(krb5_context context, HDB *db, hdb_entry *entry, void *data) return ENOMEM; } - ret = entry2string_int(context, sp, entry); + ret = entry2string_int(context, sp, &entry->entry); if(ret) { krb5_storage_free(sp); return ret; diff --git a/crypto/heimdal/lib/hdb/test_dbinfo.c b/crypto/heimdal/lib/hdb/test_dbinfo.c new file mode 100644 index 0000000..d92a538 --- /dev/null +++ b/crypto/heimdal/lib/hdb/test_dbinfo.c @@ -0,0 +1,91 @@ +/* + * 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: + * + * 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 <getarg.h> + +RCSID("$Id: test_dbinfo.c 20575 2007-04-27 20:20:32Z lha $"); + +static int help_flag; +static int version_flag; + +struct getargs args[] = { + { "help", 'h', arg_flag, &help_flag }, + { "version", 0, arg_flag, &version_flag } +}; + +static int num_args = sizeof(args) / sizeof(args[0]); + +int +main(int argc, char **argv) +{ + struct hdb_dbinfo *info, *d; + krb5_context context; + int ret, o = 0; + + setprogname(argv[0]); + + if(getarg(args, num_args, argc, argv, &o)) + krb5_std_usage(1, args, num_args); + + if(help_flag) + krb5_std_usage(0, args, num_args); + + if(version_flag){ + print_version(NULL); + exit(0); + } + + ret = krb5_init_context(&context); + if (ret) + errx (1, "krb5_init_context failed: %d", ret); + + ret = hdb_get_dbinfo(context, &info); + if (ret) + krb5_err(context, 1, ret, "hdb_get_dbinfo"); + + 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)); + } + + hdb_free_dbinfo(context, &info); + + krb5_free_context(context); + + return 0; +} |