summaryrefslogtreecommitdiffstats
path: root/crypto/heimdal/lib/hdb
diff options
context:
space:
mode:
authorassar <assar@FreeBSD.org>2001-02-13 16:46:19 +0000
committerassar <assar@FreeBSD.org>2001-02-13 16:46:19 +0000
commit3a971fe69aad52dfd248901ae796e64a96ae3e37 (patch)
treeac7b5c62510ffa9f0316643bcb19a3fed3d5bef7 /crypto/heimdal/lib/hdb
parent2934fc23653f64b32f4db32233d7eda11ca274f0 (diff)
parentebfe6dc471c206300fd82c7c0fd145f683aa52f6 (diff)
downloadFreeBSD-src-3a971fe69aad52dfd248901ae796e64a96ae3e37.zip
FreeBSD-src-3a971fe69aad52dfd248901ae796e64a96ae3e37.tar.gz
This commit was generated by cvs2svn to compensate for changes in r72445,
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.am32
-rw-r--r--crypto/heimdal/lib/hdb/Makefile.in312
-rw-r--r--crypto/heimdal/lib/hdb/common.c21
-rw-r--r--crypto/heimdal/lib/hdb/convert_db.c28
-rw-r--r--crypto/heimdal/lib/hdb/db.c24
-rw-r--r--crypto/heimdal/lib/hdb/db3.c310
-rw-r--r--crypto/heimdal/lib/hdb/hdb-ldap.c1344
-rw-r--r--crypto/heimdal/lib/hdb/hdb-private.h12
-rw-r--r--crypto/heimdal/lib/hdb/hdb-protos.h53
-rw-r--r--crypto/heimdal/lib/hdb/hdb.asn16
-rw-r--r--crypto/heimdal/lib/hdb/hdb.c219
-rw-r--r--crypto/heimdal/lib/hdb/hdb.h13
-rw-r--r--crypto/heimdal/lib/hdb/hdb_err.et3
-rw-r--r--crypto/heimdal/lib/hdb/keytab.c122
-rw-r--r--crypto/heimdal/lib/hdb/mkey.c475
-rw-r--r--crypto/heimdal/lib/hdb/ndbm.c25
-rw-r--r--crypto/heimdal/lib/hdb/print.c50
17 files changed, 2571 insertions, 478 deletions
diff --git a/crypto/heimdal/lib/hdb/Makefile.am b/crypto/heimdal/lib/hdb/Makefile.am
index 6c4341e..f3aba3b 100644
--- a/crypto/heimdal/lib/hdb/Makefile.am
+++ b/crypto/heimdal/lib/hdb/Makefile.am
@@ -1,4 +1,4 @@
-# $Id: Makefile.am,v 1.33 2000/01/06 21:45:41 assar Exp $
+# $Id: Makefile.am,v 1.43 2001/01/30 01:49:16 assar Exp $
include $(top_srcdir)/Makefile.am.common
@@ -13,27 +13,33 @@ CLEANFILES = $(BUILT_SOURCES) $(foo) hdb_asn1.h asn1_files
noinst_PROGRAMS = convert_db
LDADD = libhdb.la \
+ $(LIB_openldap) \
../krb5/libkrb5.la \
../asn1/libasn1.la \
- ../des/libdes.la \
+ $(LIB_des) \
$(LIB_roken) \
$(DBLIB)
lib_LTLIBRARIES = libhdb.la
-libhdb_la_LDFLAGS = -version-info 4:1:1
-
-libhdb_la_SOURCES = \
- keytab.c \
- hdb.c \
- common.c \
- db.c \
- ndbm.c \
- print.c \
- $(BUILT_SOURCES)
+libhdb_la_LDFLAGS = -version-info 7:0:0
+
+libhdb_la_SOURCES = \
+ common.c \
+ db.c \
+ db3.c \
+ hdb-ldap.c \
+ hdb.c \
+ keytab.c \
+ mkey.c \
+ ndbm.c \
+ print.c \
+ $(BUILT_SOURCES)
+
+INCLUDES += $(INCLUDE_openldap)
include_HEADERS = hdb.h hdb_err.h hdb_asn1.h hdb-protos.h hdb-private.h
-libhdb_la_LIBADD =
+libhdb_la_LIBADD = $(LIB_openldap)
$(libhdb_la_OBJECTS): $(srcdir)/hdb-protos.h $(srcdir)/hdb-private.h
diff --git a/crypto/heimdal/lib/hdb/Makefile.in b/crypto/heimdal/lib/hdb/Makefile.in
index ef92550..ad12e78 100644
--- a/crypto/heimdal/lib/hdb/Makefile.in
+++ b/crypto/heimdal/lib/hdb/Makefile.in
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4 from Makefile.am
+# Makefile.in generated automatically by automake 1.4a from Makefile.am
-# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-9, 2000 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.
@@ -10,15 +10,6 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
-# $Id: Makefile.am,v 1.33 2000/01/06 21:45:41 assar Exp $
-
-
-# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
-
-
-# $Id: Makefile.am.common,v 1.13 1999/11/01 03:19:58 assar Exp $
-
-
SHELL = @SHELL@
srcdir = @srcdir@
@@ -40,8 +31,6 @@ mandir = @mandir@
includedir = @includedir@
oldincludedir = /usr/include
-DESTDIR =
-
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
@@ -54,9 +43,10 @@ AUTOMAKE = @AUTOMAKE@
AUTOHEADER = @AUTOHEADER@
INSTALL = @INSTALL@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_FLAG =
transform = @program_transform_name@
NORMAL_INSTALL = :
@@ -65,26 +55,39 @@ POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
+
+@SET_MAKE@
host_alias = @host_alias@
host_triplet = @host@
-AFS_EXTRA_LD = @AFS_EXTRA_LD@
AIX_EXTRA_KAFS = @AIX_EXTRA_KAFS@
+AMDEP = @AMDEP@
+AMTAR = @AMTAR@
+AS = @AS@
AWK = @AWK@
CANONICAL_HOST = @CANONICAL_HOST@
CATMAN = @CATMAN@
CATMANEXT = @CATMANEXT@
CC = @CC@
+CPP = @CPP@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
DBLIB = @DBLIB@
+DEPDIR = @DEPDIR@
+DIR_des = @DIR_des@
+DIR_roken = @DIR_roken@
+DLLTOOL = @DLLTOOL@
EXEEXT = @EXEEXT@
EXTRA_LIB45 = @EXTRA_LIB45@
GROFF = @GROFF@
+INCLUDES_roken = @INCLUDES_roken@
INCLUDE_ = @INCLUDE_@
-LD = @LD@
LEX = @LEX@
LIBOBJS = @LIBOBJS@
LIBTOOL = @LIBTOOL@
LIB_ = @LIB_@
LIB_AUTH_SUBDIRS = @LIB_AUTH_SUBDIRS@
+LIB_des = @LIB_des@
+LIB_des_appl = @LIB_des_appl@
LIB_kdb = @LIB_kdb@
LIB_otp = @LIB_otp@
LIB_roken = @LIB_roken@
@@ -92,31 +95,43 @@ LIB_security = @LIB_security@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
-MAKE_X_PROGS_BIN_PROGS = @MAKE_X_PROGS_BIN_PROGS@
-MAKE_X_PROGS_BIN_SCRPTS = @MAKE_X_PROGS_BIN_SCRPTS@
-MAKE_X_PROGS_LIBEXEC_PROGS = @MAKE_X_PROGS_LIBEXEC_PROGS@
NEED_WRITEAUTH_FALSE = @NEED_WRITEAUTH_FALSE@
NEED_WRITEAUTH_TRUE = @NEED_WRITEAUTH_TRUE@
-NM = @NM@
NROFF = @NROFF@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
PACKAGE = @PACKAGE@
RANLIB = @RANLIB@
+STRIP = @STRIP@
VERSION = @VERSION@
VOID_RETSIGTYPE = @VOID_RETSIGTYPE@
WFLAGS = @WFLAGS@
WFLAGS_NOIMPLICITINT = @WFLAGS_NOIMPLICITINT@
WFLAGS_NOUNUSED = @WFLAGS_NOUNUSED@
YACC = @YACC@
+dpagaix_CFLAGS = @dpagaix_CFLAGS@
+dpagaix_LDADD = @dpagaix_LDADD@
+install_sh = @install_sh@
+
+# $Id: Makefile.am,v 1.43 2001/01/30 01:49:16 assar Exp $
+
+
+# $Id: Makefile.am.common,v 1.3 1999/04/01 14:58:43 joda Exp $
+
+
+# $Id: Makefile.am.common,v 1.23 2000/12/05 09:11:09 joda Exp $
+
AUTOMAKE_OPTIONS = foreign no-dependencies
SUFFIXES = .et .h .1 .3 .5 .8 .cat1 .cat3 .cat5 .cat8 .x
-INCLUDES = -I$(top_builddir)/include -I../asn1 -I$(srcdir)/../asn1
+INCLUDES = -I$(top_builddir)/include $(INCLUDES_roken) -I../asn1 -I$(srcdir)/../asn1 $(INCLUDE_openldap)
AM_CFLAGS = $(WFLAGS)
+CP = cp
+
COMPILE_ET = $(top_builddir)/lib/com_err/compile_et
buildinclude = $(top_builddir)/include
@@ -136,6 +151,7 @@ LIB_getsockopt = @LIB_getsockopt@
LIB_logout = @LIB_logout@
LIB_logwtmp = @LIB_logwtmp@
LIB_odm_initialize = @LIB_odm_initialize@
+LIB_pidfile = @LIB_pidfile@
LIB_readline = @LIB_readline@
LIB_res_search = @LIB_res_search@
LIB_setpcred = @LIB_setpcred@
@@ -144,6 +160,8 @@ LIB_socket = @LIB_socket@
LIB_syslog = @LIB_syslog@
LIB_tgetent = @LIB_tgetent@
+LIBS = @LIBS@
+
HESIODLIB = @HESIODLIB@
HESIODINCLUDE = @HESIODINCLUDE@
INCLUDE_hesiod = @INCLUDE_hesiod@
@@ -152,28 +170,25 @@ LIB_hesiod = @LIB_hesiod@
INCLUDE_krb4 = @INCLUDE_krb4@
LIB_krb4 = @LIB_krb4@
+INCLUDE_openldap = @INCLUDE_openldap@
+LIB_openldap = @LIB_openldap@
+
INCLUDE_readline = @INCLUDE_readline@
LEXLIB = @LEXLIB@
-cat1dir = $(mandir)/cat1
-cat3dir = $(mandir)/cat3
-cat5dir = $(mandir)/cat5
-cat8dir = $(mandir)/cat8
-
-MANRX = \(.*\)\.\([0-9]\)
-CATSUFFIX = @CATSUFFIX@
-
NROFF_MAN = groff -mandoc -Tascii
-@KRB4_TRUE@LIB_kafs = $(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
+@KRB4_TRUE@LIB_kafs = @KRB4_TRUE@$(top_builddir)/lib/kafs/libkafs.la $(AIX_EXTRA_KAFS)
-@KRB5_TRUE@LIB_krb5 = $(top_builddir)/lib/krb5/libkrb5.la $(top_builddir)/lib/asn1/libasn1.la
-@KRB5_TRUE@LIB_gssapi = $(top_builddir)/lib/gssapi/libgssapi.la
+@KRB5_TRUE@LIB_krb5 = @KRB5_TRUE@$(top_builddir)/lib/krb5/libkrb5.la \
+@KRB5_TRUE@ $(top_builddir)/lib/asn1/libasn1.la
+@KRB5_TRUE@LIB_gssapi = @KRB5_TRUE@$(top_builddir)/lib/gssapi/libgssapi.la
CHECK_LOCAL = $(PROGRAMS)
-BUILT_SOURCES = asn1_Key.c asn1_Event.c asn1_HDBFlags.c asn1_hdb_entry.c asn1_Salt.c hdb_err.c hdb_err.h
+BUILT_SOURCES = asn1_Key.c asn1_Event.c asn1_HDBFlags.c asn1_hdb_entry.c \
+ asn1_Salt.c hdb_err.c hdb_err.h
foo = asn1_Key.x asn1_Event.x asn1_HDBFlags.x asn1_hdb_entry.x asn1_Salt.x
@@ -181,18 +196,35 @@ foo = asn1_Key.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 ../krb5/libkrb5.la ../asn1/libasn1.la ../des/libdes.la $(LIB_roken) $(DBLIB)
+LDADD = libhdb.la \
+ $(LIB_openldap) \
+ ../krb5/libkrb5.la \
+ ../asn1/libasn1.la \
+ $(LIB_des) \
+ $(LIB_roken) \
+ $(DBLIB)
lib_LTLIBRARIES = libhdb.la
-libhdb_la_LDFLAGS = -version-info 4:1:1
+libhdb_la_LDFLAGS = -version-info 7:0:0
-libhdb_la_SOURCES = keytab.c hdb.c common.c db.c ndbm.c print.c $(BUILT_SOURCES)
+libhdb_la_SOURCES = \
+ common.c \
+ db.c \
+ db3.c \
+ hdb-ldap.c \
+ hdb.c \
+ keytab.c \
+ mkey.c \
+ ndbm.c \
+ print.c \
+ $(BUILT_SOURCES)
include_HEADERS = hdb.h hdb_err.h hdb_asn1.h hdb-protos.h hdb-private.h
-libhdb_la_LIBADD =
+libhdb_la_LIBADD = $(LIB_openldap)
+subdir = lib/hdb
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
CONFIG_HEADER = ../../include/config.h
CONFIG_CLEAN_FILES =
@@ -202,15 +234,15 @@ LTLIBRARIES = $(lib_LTLIBRARIES)
DEFS = @DEFS@ -I. -I$(srcdir) -I../../include
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
-LIBS = @LIBS@
X_CFLAGS = @X_CFLAGS@
X_LIBS = @X_LIBS@
X_EXTRA_LIBS = @X_EXTRA_LIBS@
X_PRE_LIBS = @X_PRE_LIBS@
libhdb_la_DEPENDENCIES =
-libhdb_la_OBJECTS = keytab.lo hdb.lo common.lo db.lo ndbm.lo print.lo \
-asn1_Key.lo asn1_Event.lo asn1_HDBFlags.lo asn1_hdb_entry.lo \
-asn1_Salt.lo hdb_err.lo
+am_libhdb_la_OBJECTS = common.lo db.lo db3.lo hdb-ldap.lo hdb.lo \
+keytab.lo mkey.lo ndbm.lo print.lo asn1_Key.lo asn1_Event.lo \
+asn1_HDBFlags.lo asn1_hdb_entry.lo asn1_Salt.lo hdb_err.lo
+libhdb_la_OBJECTS = $(am_libhdb_la_OBJECTS)
noinst_PROGRAMS = convert_db$(EXEEXT)
PROGRAMS = $(noinst_PROGRAMS)
@@ -218,28 +250,29 @@ convert_db_SOURCES = convert_db.c
convert_db_OBJECTS = convert_db.$(OBJEXT)
convert_db_LDADD = $(LDADD)
convert_db_DEPENDENCIES = libhdb.la ../krb5/libkrb5.la \
-../asn1/libasn1.la ../des/libdes.la
+../asn1/libasn1.la
convert_db_LDFLAGS =
-CFLAGS = @CFLAGS@
COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CFLAGS = @CFLAGS@
CCLD = $(CC)
-LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
+DIST_SOURCES = $(libhdb_la_SOURCES) convert_db.c
HEADERS = $(include_HEADERS)
-DIST_COMMON = Makefile.am Makefile.in
+depcomp =
+DIST_COMMON = $(include_HEADERS) Makefile.am Makefile.in
-DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-TAR = tar
GZIP_ENV = --best
SOURCES = $(libhdb_la_SOURCES) convert_db.c
-OBJECTS = $(libhdb_la_OBJECTS) convert_db.$(OBJEXT)
+OBJECTS = $(am_libhdb_la_OBJECTS) convert_db.$(OBJEXT)
all: all-redirect
.SUFFIXES:
-.SUFFIXES: .1 .3 .5 .8 .S .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .s .x
+.SUFFIXES: .1 .3 .5 .8 .c .cat1 .cat3 .cat5 .cat8 .et .h .lo .o .obj .x
$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4) $(top_srcdir)/Makefile.am.common $(top_srcdir)/cf/Makefile.am.common
cd $(top_srcdir) && $(AUTOMAKE) --foreign lib/hdb/Makefile
@@ -262,31 +295,18 @@ install-libLTLIBRARIES: $(lib_LTLIBRARIES)
$(mkinstalldirs) $(DESTDIR)$(libdir)
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
if test -f $$p; then \
- echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
- $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ echo " $(LIBTOOL) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$p $(DESTDIR)$(libdir)/$$p; \
else :; fi; \
done
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
- list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ echo " $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p"; \
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
done
-.c.o:
- $(COMPILE) -c $<
-
-# FIXME: We should only use cygpath when building on Windows,
-# and only if it is available.
-.c.obj:
- $(COMPILE) -c `cygpath -w $<`
-
-.s.o:
- $(COMPILE) -c $<
-
-.S.o:
- $(COMPILE) -c $<
-
mostlyclean-compile:
-rm -f *.o core *.core
-rm -f *.$(OBJEXT)
@@ -298,15 +318,6 @@ distclean-compile:
maintainer-clean-compile:
-.c.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
-.s.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
-.S.lo:
- $(LIBTOOL) --mode=compile $(COMPILE) -c $<
-
mostlyclean-libtool:
-rm -f *.lo
@@ -332,41 +343,54 @@ maintainer-clean-noinstPROGRAMS:
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)
+.c.o:
+ $(COMPILE) -c $<
+.c.obj:
+ $(COMPILE) -c `cygpath -w $<`
+.c.lo:
+ $(LTCOMPILE) -c -o $@ $<
install-includeHEADERS: $(include_HEADERS)
@$(NORMAL_INSTALL)
$(mkinstalldirs) $(DESTDIR)$(includedir)
@list='$(include_HEADERS)'; for p in $$list; do \
if test -f "$$p"; then d= ; else d="$(srcdir)/"; fi; \
- echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p"; \
- $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$p; \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$f"; \
+ $(INSTALL_DATA) $$d$$p $(DESTDIR)$(includedir)/$$f; \
done
uninstall-includeHEADERS:
@$(NORMAL_UNINSTALL)
- list='$(include_HEADERS)'; for p in $$list; do \
- rm -f $(DESTDIR)$(includedir)/$$p; \
+ @list='$(include_HEADERS)'; for p in $$list; do \
+ f="`echo $$p | sed -e 's|^.*/||'`"; \
+ echo " rm -f $(DESTDIR)$(includedir)/$$f"; \
+ rm -f $(DESTDIR)$(includedir)/$$f; \
done
tags: TAGS
-ID: $(HEADERS) $(SOURCES) $(LISP)
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
- here=`pwd` && cd $(srcdir) \
- && mkid -f$$here/ID $$unique $(LISP)
+ mkid -fID $$unique $(LISP)
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
- list='$(SOURCES) $(HEADERS)'; \
- unique=`for i in $$list; do echo $$i; done | \
- awk ' { files[$$0] = 1; } \
+ list='$(SOURCES) $(HEADERS) $(TAGS_FILES)'; \
+ unique=`for i in $$list; do \
+ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
+ done | \
+ $(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
- || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+ || etags $(ETAGS_ARGS) $$tags $$unique $(LISP)
mostlyclean-tags:
@@ -379,17 +403,16 @@ maintainer-clean-tags:
distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
-subdir = lib/hdb
-
distdir: $(DISTFILES)
@for file in $(DISTFILES); do \
d=$(srcdir); \
if test -d $$d/$$file; then \
- cp -pr $$/$$file $(distdir)/$$file; \
+ cp -pR $$d/$$file $(distdir) \
+ || exit 1; \
else \
test -f $(distdir)/$$file \
- || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
- || cp -p $$d/$$file $(distdir)/$$file || :; \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
fi; \
done
$(MAKE) $(AM_MAKEFLAGS) top_distdir="$(top_distdir)" distdir="$(distdir)" dist-hook
@@ -418,7 +441,7 @@ uninstall: uninstall-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS) all-local
all-redirect: all-am
install-strip:
- $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_STRIP_FLAG=-s install
installdirs:
$(mkinstalldirs) $(DESTDIR)$(libdir) $(DESTDIR)$(includedir)
@@ -433,6 +456,7 @@ distclean-generic:
-rm -f config.cache config.log stamp-h stamp-h[0-9]*
maintainer-clean-generic:
+ -rm -f Makefile.in
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
mostlyclean-libtool mostlyclean-noinstPROGRAMS \
@@ -474,8 +498,8 @@ install-includeHEADERS tags mostlyclean-tags distclean-tags clean-tags \
maintainer-clean-tags distdir info-am info dvi-am dvi check-local check \
check-am installcheck-am installcheck install-exec-am install-exec \
install-data-local install-data-am install-data install-am install \
-uninstall-am uninstall all-local all-redirect all-am all installdirs \
-mostlyclean-generic distclean-generic clean-generic \
+uninstall-am uninstall all-local all-redirect all-am all install-strip \
+installdirs mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
@@ -484,7 +508,10 @@ install-suid-programs:
for file in $$foo; do \
x=$(DESTDIR)$(bindir)/$$file; \
if chown 0:0 $$x && chmod u+s $$x; then :; else \
- chmod 0 $$x; fi; done
+ echo "*"; \
+ echo "* Failed to install $$x setuid root"; \
+ echo "*"; \
+ fi; done
install-exec-hook: install-suid-programs
@@ -496,8 +523,8 @@ install-build-headers:: $(include_HEADERS) $(build_HEADERZ)
else file="$$f"; fi; \
if cmp -s $$file $(buildinclude)/$$f 2> /dev/null ; then \
: ; else \
- echo " cp $$file $(buildinclude)/$$f"; \
- cp $$file $(buildinclude)/$$f; \
+ echo " $(CP) $$file $(buildinclude)/$$f"; \
+ $(CP) $$file $(buildinclude)/$$f; \
fi ; \
done
@@ -566,87 +593,8 @@ dist-cat8-mans:
dist-hook: dist-cat1-mans dist-cat3-mans dist-cat5-mans dist-cat8-mans
-install-cat1-mans:
- @ext=1;\
- foo='$(man1_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.1) foo="$$foo $$i";; \
- esac; done; \
- if test "$$foo"; then \
- $(mkinstalldirs) $(DESTDIR)$(cat1dir); \
- for x in $$foo; do \
- f=`echo $$x | sed 's/\.[^.]*$$/.cat1/'`; \
- if test -f "$(srcdir)/$$f"; then \
- b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
- echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX)";\
- $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat1dir)/$$b.$(CATSUFFIX);\
- fi; \
- done ;\
- fi
-
-install-cat3-mans:
- @ext=3;\
- foo='$(man3_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.3) foo="$$foo $$i";; \
- esac; done; \
- if test "$$foo"; then \
- $(mkinstalldirs) $(DESTDIR)$(cat3dir); \
- for x in $$foo; do \
- f=`echo $$x | sed 's/\.[^.]*$$/.cat3/'`; \
- if test -f "$(srcdir)/$$f"; then \
- b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
- echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX)";\
- $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat3dir)/$$b.$(CATSUFFIX);\
- fi; \
- done ;\
- fi
-
-install-cat5-mans:
- @ext=5;\
- foo='$(man5_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.5) foo="$$foo $$i";; \
- esac; done; \
- if test "$$foo"; then \
- $(mkinstalldirs) $(DESTDIR)$(cat5dir); \
- for x in $$foo; do \
- f=`echo $$x | sed 's/\.[^.]*$$/.cat5/'`; \
- if test -f "$(srcdir)/$$f"; then \
- b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
- echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX)";\
- $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat5dir)/$$b.$(CATSUFFIX);\
- fi; \
- done ;\
- fi
-
-install-cat8-mans:
- @ext=8;\
- foo='$(man8_MANS)'; \
- bar='$(man_MANS)'; \
- for i in $$bar; do \
- case $$i in \
- *.8) foo="$$foo $$i";; \
- esac; done; \
- if test "$$foo"; then \
- $(mkinstalldirs) $(DESTDIR)$(cat8dir); \
- for x in $$foo; do \
- f=`echo $$x | sed 's/\.[^.]*$$/.cat8/'`; \
- if test -f "$(srcdir)/$$f"; then \
- b=`echo $$x | sed 's!$(MANRX)!\1!'`; \
- echo "$(INSTALL_DATA) $(srcdir)/$$f $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX)";\
- $(INSTALL_DATA) $(srcdir)/$$g $(DESTDIR)$(cat8dir)/$$b.$(CATSUFFIX);\
- fi; \
- done ;\
- fi
-
-install-cat-mans: install-cat1-mans install-cat3-mans install-cat5-mans install-cat8-mans
+install-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)
install-data-local: install-cat-mans
diff --git a/crypto/heimdal/lib/hdb/common.c b/crypto/heimdal/lib/hdb/common.c
index 6e95667..befde78 100644
--- a/crypto/heimdal/lib/hdb/common.c
+++ b/crypto/heimdal/lib/hdb/common.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997-1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997-2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "hdb_locl.h"
-RCSID("$Id: common.c,v 1.6 1999/12/02 17:05:04 joda Exp $");
+RCSID("$Id: common.c,v 1.8 2001/01/30 01:22:17 assar Exp $");
int
hdb_principal2key(krb5_context context, krb5_principal p, krb5_data *key)
@@ -102,7 +102,7 @@ krb5_error_code
_hdb_fetch(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
{
krb5_data key, value;
- int code;
+ int code = 0;
hdb_principal2key(context, entry->principal, &key);
code = db->_get(context, db, key, &value);
@@ -110,10 +110,13 @@ _hdb_fetch(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
if(code)
return code;
hdb_value2entry(context, &value, entry);
- if (db->master_key_set && (flags & HDB_F_DECRYPT))
- hdb_unseal_keys (db, entry);
+ if (db->master_key_set && (flags & HDB_F_DECRYPT)) {
+ code = hdb_unseal_keys (context, db, entry);
+ if (code)
+ hdb_free_entry(context, entry);
+ }
krb5_data_free(&value);
- return 0;
+ return code;
}
krb5_error_code
@@ -123,7 +126,11 @@ _hdb_store(krb5_context context, HDB *db, unsigned flags, hdb_entry *entry)
int code;
hdb_principal2key(context, entry->principal, &key);
- hdb_seal_keys(db, entry);
+ code = hdb_seal_keys(context, db, entry);
+ if (code) {
+ krb5_data_free(&key);
+ return code;
+ }
hdb_entry2value(context, entry, &value);
code = db->_put(context, db, flags & HDB_F_REPLACE, key, value);
krb5_data_free(&value);
diff --git a/crypto/heimdal/lib/hdb/convert_db.c b/crypto/heimdal/lib/hdb/convert_db.c
index b257809..1a7ebb4 100644
--- a/crypto/heimdal/lib/hdb/convert_db.c
+++ b/crypto/heimdal/lib/hdb/convert_db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -38,9 +38,10 @@
*/
#include "hdb_locl.h"
-#include "getarg.h"
+#include <getarg.h>
+#include <err.h>
-RCSID("$Id: convert_db.c,v 1.8 1999/05/09 22:47:47 assar Exp $");
+RCSID("$Id: convert_db.c,v 1.11 2001/01/25 12:45:01 assar Exp $");
static krb5_error_code
update_keytypes(krb5_context context, HDB *db, hdb_entry *entry, void *data)
@@ -132,7 +133,6 @@ main(int argc, char **argv)
krb5_error_code ret;
krb5_context context;
HDB *db, *new;
- EncryptionKey key;
int optind = 0;
int master_key_set = 0;
@@ -151,29 +151,23 @@ main(int argc, char **argv)
ret = krb5_init_context(&context);
if(ret != 0)
- krb5_err(NULL, 1, ret, "krb5_init_context");
+ errx(1, "krb5_init_context failed: %d", ret);
ret = hdb_create(context, &db, old_database);
if(ret != 0)
krb5_err(context, 1, ret, "hdb_create");
- ret = hdb_read_master_key(context, mkeyfile, &key);
- if(ret == 0) {
- if(key.keytype == KEYTYPE_DES)
- key.keytype = ETYPE_DES_CBC_MD5;
-
- ret = hdb_set_master_key(context, db, key);
- if (ret)
- krb5_err(context, 1, ret, "hdb_set_master_key");
- master_key_set = 1;
- }
+ ret = hdb_set_master_keyfile(context, db, mkeyfile);
+ if (ret)
+ krb5_err(context, 1, ret, "hdb_set_master_keyfile");
+ master_key_set = 1;
ret = hdb_create(context, &new, new_database);
if(ret != 0)
krb5_err(context, 1, ret, "hdb_create");
if (master_key_set) {
- ret = hdb_set_master_key(context, new, key);
+ ret = hdb_set_master_keyfile(context, new, mkeyfile);
if (ret)
- krb5_err(context, 1, ret, "hdb_set_master_key");
+ krb5_err(context, 1, ret, "hdb_set_master_keyfile");
}
ret = db->open(context, db, O_RDONLY, 0);
if(ret == HDB_ERR_BADVERSION) {
diff --git a/crypto/heimdal/lib/hdb/db.c b/crypto/heimdal/lib/hdb/db.c
index 4699437..6f9c688 100644
--- a/crypto/heimdal/lib/hdb/db.c
+++ b/crypto/heimdal/lib/hdb/db.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,9 +33,9 @@
#include "hdb_locl.h"
-RCSID("$Id: db.c,v 1.25 1999/12/02 17:05:04 joda Exp $");
+RCSID("$Id: db.c,v 1.28 2001/01/30 01:24:00 assar Exp $");
-#ifdef HAVE_DB_H
+#if defined(HAVE_DB_H) && DB_VERSION_MAJOR < 3
static krb5_error_code
DB_close(krb5_context context, HDB *db)
@@ -102,13 +102,21 @@ DB_seq(krb5_context context, HDB *db,
data.length = value.size;
if (hdb_value2entry(context, &data, entry))
return DB_seq(context, db, flags, entry, R_NEXT);
- if (db->master_key_set && (flags & HDB_F_DECRYPT))
- hdb_unseal_keys (db, entry);
- if (entry->principal == NULL) {
+ if (db->master_key_set && (flags & HDB_F_DECRYPT)) {
+ code = hdb_unseal_keys (context, db, entry);
+ if (code)
+ hdb_free_entry (context, entry);
+ }
+ if (code == 0 && entry->principal == NULL) {
entry->principal = malloc(sizeof(*entry->principal));
- hdb_key2principal(context, &key_data, entry->principal);
+ if (entry->principal == NULL) {
+ code = ENOMEM;
+ hdb_free_entry (context, entry);
+ } else {
+ hdb_key2principal(context, &key_data, entry->principal);
+ }
}
- return 0;
+ return code;
}
diff --git a/crypto/heimdal/lib/hdb/db3.c b/crypto/heimdal/lib/hdb/db3.c
new file mode 100644
index 0000000..a682071
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/db3.c
@@ -0,0 +1,310 @@
+/*
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 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: db3.c,v 1.6 2001/01/30 01:24:00 assar Exp $");
+
+#if defined(HAVE_DB_H) && DB_VERSION_MAJOR == 3
+static krb5_error_code
+DB_close(krb5_context context, HDB *db)
+{
+ DB *d = (DB*)db->db;
+ DBC *dbcp = (DBC*)db->dbc;
+
+ dbcp->c_close(dbcp);
+ db->dbc = 0;
+ d->close(d, 0);
+ return 0;
+}
+
+static krb5_error_code
+DB_destroy(krb5_context context, HDB *db)
+{
+ krb5_error_code ret;
+
+ ret = hdb_clear_master_key (context, db);
+ free(db->name);
+ free(db);
+ return ret;
+}
+
+static krb5_error_code
+DB_lock(krb5_context context, HDB *db, int operation)
+{
+ DB *d = (DB*)db->db;
+ int fd;
+ if ((*d->fd)(d, &fd))
+ 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;
+ int fd;
+ if ((*d->fd)(d, &fd))
+ 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)
+{
+ DB *d = (DB*)db->db;
+ DBT key, value;
+ DBC *dbcp = db->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))
+ return HDB_ERR_DB_INUSE;
+ code = dbcp->c_get(dbcp, &key, &value, flag);
+ db->unlock(context, db); /* XXX check value */
+ if (code == DB_NOTFOUND)
+ return HDB_ERR_NOENTRY;
+ if (code)
+ return code;
+
+ key_data.data = key.data;
+ key_data.length = key.size;
+ data.data = value.data;
+ data.length = value.size;
+ if (hdb_value2entry(context, &data, 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 (code)
+ hdb_free_entry (context, entry);
+ }
+ if (entry->principal == NULL) {
+ entry->principal = malloc(sizeof(*entry->principal));
+ if (entry->principal == NULL) {
+ code = ENOMEM;
+ hdb_free_entry (context, entry);
+ } else {
+ hdb_key2principal(context, &key_data, entry->principal);
+ }
+ }
+ return 0;
+}
+
+
+static krb5_error_code
+DB_firstkey(krb5_context context, HDB *db, unsigned flags, hdb_entry *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)
+{
+ return DB_seq(context, db, flags, entry, DB_NEXT);
+}
+
+static krb5_error_code
+DB_rename(krb5_context context, HDB *db, const char *new_name)
+{
+ int ret;
+ char *old, *new;
+
+ asprintf(&old, "%s.db", db->name);
+ asprintf(&new, "%s.db", new_name);
+ ret = rename(old, new);
+ free(old);
+ free(new);
+ if(ret)
+ return errno;
+
+ free(db->name);
+ db->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;
+ DBT k, v;
+ int code;
+
+ memset(&k, 0, sizeof(DBT));
+ memset(&v, 0, sizeof(DBT));
+ k.data = key.data;
+ k.size = key.length;
+ k.flags = 0;
+ if ((code = db->lock(context, db, HDB_RLOCK)))
+ return code;
+ code = d->get(d, NULL, &k, &v, 0);
+ db->unlock(context, db);
+ if(code == DB_NOTFOUND)
+ return HDB_ERR_NOENTRY;
+ if(code)
+ return code;
+
+ krb5_data_copy(reply, v.data, v.size);
+ return 0;
+}
+
+static krb5_error_code
+DB__put(krb5_context context, HDB *db, int replace,
+ krb5_data key, krb5_data value)
+{
+ DB *d = (DB*)db->db;
+ DBT k, v;
+ int code;
+
+ memset(&k, 0, sizeof(DBT));
+ memset(&v, 0, sizeof(DBT));
+ k.data = key.data;
+ k.size = key.length;
+ k.flags = 0;
+ v.data = value.data;
+ v.size = value.length;
+ v.flags = 0;
+ if ((code = db->lock(context, db, HDB_WLOCK)))
+ return code;
+ code = d->put(d, NULL, &k, &v, replace ? 0 : DB_NOOVERWRITE);
+ db->unlock(context, db);
+ if(code == DB_KEYEXIST)
+ return HDB_ERR_EXISTS;
+ if(code)
+ return errno;
+ return 0;
+}
+
+static krb5_error_code
+DB__del(krb5_context context, HDB *db, krb5_data key)
+{
+ DB *d = (DB*)db->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);
+ if(code)
+ return code;
+ code = d->del(d, NULL, &k, 0);
+ db->unlock(context, db);
+ if(code == DB_NOTFOUND)
+ return HDB_ERR_NOENTRY;
+ if(code)
+ return code;
+ return 0;
+}
+
+static krb5_error_code
+DB_open(krb5_context context, HDB *db, int flags, mode_t mode)
+{
+ char *fn;
+ krb5_error_code ret;
+ DB *d;
+ int myflags = 0;
+
+ if (flags & O_CREAT)
+ myflags |= DB_CREATE;
+
+ if (flags & O_EXCL)
+ myflags |= DB_EXCL;
+
+ if (flags & O_RDONLY)
+ myflags |= DB_RDONLY;
+
+ if (flags & O_TRUNC)
+ myflags |= DB_TRUNCATE;
+
+ asprintf(&fn, "%s.db", db->name);
+ if (fn == NULL)
+ return ENOMEM;
+ db_create(&d, NULL, 0);
+ db->db = d;
+ if ((ret = d->open(db->db, fn, NULL, DB_BTREE, myflags, mode))) {
+ if(ret == ENOENT)
+ /* try to open without .db extension */
+ if (d->open(db->db, db->name, NULL, DB_BTREE, myflags, mode)) {
+ free(fn);
+ return ret;
+ }
+ }
+ free(fn);
+
+ ret = d->cursor(d, NULL, (DBC **)&db->dbc, 0);
+ if (ret)
+ return ret;
+
+ if((flags & O_ACCMODE) == O_RDONLY)
+ ret = hdb_check_db_format(context, db);
+ else
+ ret = hdb_init_db(context, db);
+ if(ret == HDB_ERR_NOENTRY)
+ return 0;
+ return ret;
+}
+
+krb5_error_code
+hdb_db_create(krb5_context context, HDB **db,
+ const char *filename)
+{
+ *db = malloc(sizeof(**db));
+ if (*db == NULL)
+ return ENOMEM;
+
+ (*db)->db = NULL;
+ (*db)->name = strdup(filename);
+ (*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;
+ return 0;
+}
+#endif
diff --git a/crypto/heimdal/lib/hdb/hdb-ldap.c b/crypto/heimdal/lib/hdb/hdb-ldap.c
new file mode 100644
index 0000000..6d264b4
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/hdb-ldap.c
@@ -0,0 +1,1344 @@
+/*
+ * Copyright (c) 1999 - 2001, PADL Software Pty Ltd.
+ * 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 PADL Software 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 PADL SOFTWARE 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 PADL SOFTWARE 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: hdb-ldap.c,v 1.7 2001/01/30 16:59:08 assar Exp $");
+
+#ifdef OPENLDAP
+
+#include <ldap.h>
+#include <lber.h>
+#include <ctype.h>
+#include <sys/un.h>
+
+static krb5_error_code LDAP__connect(krb5_context context, HDB * db);
+
+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",
+ NULL
+};
+
+static char *krb5principal_attrs[] =
+ { "krb5PrincipalName", "cn", "krb5PrincipalRealm",
+ "modifiersName", "modifyTimestamp", "creatorsName", "createTimestamp",
+ NULL
+};
+
+/* based on samba: source/passdb/ldap.c */
+static krb5_error_code
+LDAP_addmod_len(LDAPMod *** modlist, int modop, const char *attribute,
+ unsigned char *value, size_t len)
+{
+ LDAPMod **mods = *modlist;
+ int i, j;
+
+ if (mods == NULL) {
+ mods = (LDAPMod **) calloc(1, sizeof(LDAPMod *));
+ if (mods == NULL) {
+ return ENOMEM;
+ }
+ mods[0] = NULL;
+ }
+
+ for (i = 0; mods[i] != NULL; ++i) {
+ if ((mods[i]->mod_op & (~LDAP_MOD_BVALUES)) == modop
+ && (!strcasecmp(mods[i]->mod_type, attribute))) {
+ break;
+ }
+ }
+
+ if (mods[i] == NULL) {
+ mods = (LDAPMod **) realloc(mods, (i + 2) * sizeof(LDAPMod *));
+ if (mods == NULL) {
+ return ENOMEM;
+ }
+ mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
+ if (mods[i] == NULL) {
+ return ENOMEM;
+ }
+ mods[i]->mod_op = modop | LDAP_MOD_BVALUES;
+ mods[i]->mod_bvalues = NULL;
+ mods[i]->mod_type = strdup(attribute);
+ if (mods[i]->mod_type == NULL) {
+ return ENOMEM;
+ }
+ mods[i + 1] = NULL;
+ }
+
+ if (value != NULL) {
+ j = 0;
+ if (mods[i]->mod_bvalues != NULL) {
+ for (; mods[i]->mod_bvalues[j] != NULL; j++);
+ }
+ mods[i]->mod_bvalues =
+ (struct berval **) realloc(mods[i]->mod_bvalues,
+ (j + 2) * sizeof(struct berval *));
+ if (mods[i]->mod_bvalues == NULL) {
+ return ENOMEM;
+ }
+ /* Caller allocates memory on our behalf, unlike LDAP_addmod. */
+ mods[i]->mod_bvalues[j] =
+ (struct berval *) malloc(sizeof(struct berval));
+ if (mods[i]->mod_bvalues[j] == NULL) {
+ return ENOMEM;
+ }
+ mods[i]->mod_bvalues[j]->bv_val = value;
+ mods[i]->mod_bvalues[j]->bv_len = len;
+ mods[i]->mod_bvalues[j + 1] = NULL;
+ }
+ *modlist = mods;
+ return 0;
+}
+
+static krb5_error_code
+LDAP_addmod(LDAPMod *** modlist, int modop, const char *attribute,
+ const char *value)
+{
+ LDAPMod **mods = *modlist;
+ int i, j;
+
+ if (mods == NULL) {
+ mods = (LDAPMod **) calloc(1, sizeof(LDAPMod *));
+ if (mods == NULL) {
+ return ENOMEM;
+ }
+ mods[0] = NULL;
+ }
+
+ for (i = 0; mods[i] != NULL; ++i) {
+ if (mods[i]->mod_op == modop
+ && (!strcasecmp(mods[i]->mod_type, attribute))) {
+ break;
+ }
+ }
+
+ if (mods[i] == NULL) {
+ mods = (LDAPMod **) realloc(mods, (i + 2) * sizeof(LDAPMod *));
+ if (mods == NULL) {
+ return ENOMEM;
+ }
+ mods[i] = (LDAPMod *) malloc(sizeof(LDAPMod));
+ if (mods[i] == NULL) {
+ return ENOMEM;
+ }
+ mods[i]->mod_op = modop;
+ mods[i]->mod_values = NULL;
+ mods[i]->mod_type = strdup(attribute);
+ if (mods[i]->mod_type == NULL) {
+ return ENOMEM;
+ }
+ mods[i + 1] = NULL;
+ }
+
+ if (value != NULL) {
+ j = 0;
+ if (mods[i]->mod_values != NULL) {
+ for (; mods[i]->mod_values[j] != NULL; j++);
+ }
+ mods[i]->mod_values = (char **) realloc(mods[i]->mod_values,
+ (j + 2) * sizeof(char *));
+ if (mods[i]->mod_values == NULL) {
+ return ENOMEM;
+ }
+ mods[i]->mod_values[j] = strdup(value);
+ if (mods[i]->mod_values[j] == NULL) {
+ return ENOMEM;
+ }
+ mods[i]->mod_values[j + 1] = NULL;
+ }
+ *modlist = mods;
+ return 0;
+}
+
+static krb5_error_code
+LDAP_addmod_generalized_time(LDAPMod *** mods, int modop,
+ const char *attribute, KerberosTime * time)
+{
+ char buf[22];
+ struct tm *tm;
+
+ /* XXX not threadsafe */
+ tm = gmtime(time);
+ strftime(buf, sizeof(buf), "%Y%m%d%H%M%SZ", tm);
+
+ return LDAP_addmod(mods, modop, attribute, buf);
+}
+
+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);
+ if (vals == NULL) {
+ return HDB_ERR_NOENTRY;
+ }
+ *ptr = strdup(vals[0]);
+ if (*ptr == NULL) {
+ ret = ENOMEM;
+ } else {
+ ret = 0;
+ }
+
+ ldap_value_free(vals);
+
+ return ret;
+}
+
+static krb5_error_code
+LDAP_get_integer_value(HDB * db, LDAPMessage * entry,
+ const char *attribute, int *ptr)
+{
+ char **vals;
+
+ vals = ldap_get_values((LDAP *) db->db, entry, (char *) attribute);
+ if (vals == NULL) {
+ return HDB_ERR_NOENTRY;
+ }
+ *ptr = atoi(vals[0]);
+ ldap_value_free(vals);
+ return 0;
+}
+
+static krb5_error_code
+LDAP_get_generalized_time_value(HDB * db, LDAPMessage * entry,
+ const char *attribute, KerberosTime * kt)
+{
+ char *tmp, *gentime;
+ struct tm tm;
+ int ret;
+
+ *kt = 0;
+
+ ret = LDAP_get_string_value(db, entry, attribute, &gentime);
+ if (ret != 0) {
+ return ret;
+ }
+
+ tmp = strptime(gentime, "%Y%m%d%H%M%SZ", &tm);
+ if (tmp == NULL) {
+ free(gentime);
+ return HDB_ERR_NOENTRY;
+ }
+
+ free(gentime);
+
+ *kt = timegm(&tm);
+
+ return 0;
+}
+
+static krb5_error_code
+LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry * 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;
+ unsigned long oflags, nflags;
+
+ if (msg != NULL) {
+ ret = LDAP_message2entry(context, db, msg, &orig);
+ if (ret != 0) {
+ goto out;
+ }
+ is_new_entry = FALSE;
+ } else {
+ /* 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) {
+ goto out;
+ }
+ ret =
+ LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass",
+ "krb5Principal");
+ if (ret != 0) {
+ goto out;
+ }
+ ret = LDAP_addmod(&mods, LDAP_MOD_ADD, "objectClass",
+ "krb5KDCEntry");
+ if (ret != 0) {
+ 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;
+ }
+ ret =
+ LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5PrincipalName", tmp);
+ if (ret != 0) {
+ free(tmp);
+ goto out;
+ }
+ free(tmp);
+ }
+
+ if (ent->kvno != orig.kvno) {
+ rc = asprintf(&tmp, "%d", ent->kvno);
+ if (rc < 0) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret =
+ LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5KeyVersionNumber",
+ tmp);
+ free(tmp);
+ if (ret != 0) {
+ 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) {
+ 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->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->max_life) {
+ if (orig.max_life == NULL
+ || (*(ent->max_life) != *(orig.max_life))) {
+ rc = asprintf(&tmp, "%d", *(ent->max_life));
+ if (rc < 0) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5MaxLife", tmp);
+ free(tmp);
+ if (ret != 0) {
+ 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) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret =
+ LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5MaxRenew", tmp);
+ free(tmp);
+ if (ret != 0) {
+ goto out;
+ }
+ }
+ }
+
+ memset(&oflags, 0, sizeof(oflags));
+ memcpy(&oflags, &orig.flags, sizeof(HDBFlags));
+ memset(&nflags, 0, sizeof(nflags));
+ memcpy(&nflags, &ent->flags, sizeof(HDBFlags));
+
+ if (memcmp(&oflags, &nflags, sizeof(HDBFlags))) {
+ rc = asprintf(&tmp, "%lu", nflags);
+ if (rc < 0) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = LDAP_addmod(&mods, LDAP_MOD_REPLACE, "krb5KDCFlags", tmp);
+ free(tmp);
+ if (ret != 0) {
+ 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;
+ }
+ }
+
+ for (i = 0; i < ent->keys.len; i++) {
+ unsigned char *buf;
+ size_t len;
+ Key new;
+
+ ret = copy_Key(&ent->keys.val[i], &new);
+ if (ret != 0) {
+ goto out;
+ }
+
+ len = length_Key(&new);
+ buf = malloc(len);
+ if (buf == NULL) {
+ ret = ENOMEM;
+ free_Key(&new);
+ goto out;
+ }
+
+ ret = encode_Key(buf + len - 1, len, &new, &len);
+ if (ret != 0) {
+ free(buf);
+ free_Key(&new);
+ goto out;
+ }
+ free_Key(&new);
+
+ /* 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) {
+ goto out;
+ }
+ }
+
+ if (ent->etypes) {
+ /* clobber and replace encryption types. */
+ if (is_new_entry == FALSE) {
+ ret =
+ LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5EncryptionType",
+ NULL);
+ }
+ for (i = 0; i < ent->etypes->len; i++) {
+ rc = asprintf(&tmp, "%d", ent->etypes->val[i]);
+ if (rc < 0) {
+ ret = ENOMEM;
+ goto out;
+ }
+ free(tmp);
+ ret =
+ LDAP_addmod(&mods, LDAP_MOD_ADD, "krb5EncryptionType",
+ tmp);
+ if (ret != 0) {
+ goto out;
+ }
+ }
+ }
+
+ /* for clarity */
+ ret = 0;
+
+ out:
+
+ if (ret == 0) {
+ *pmods = mods;
+ } else if (mods != NULL) {
+ ldap_mods_free(mods, 1);
+ *pmods = NULL;
+ }
+
+ if (msg != NULL) {
+ hdb_free_entry(context, &orig);
+ }
+
+ return ret;
+}
+
+static krb5_error_code
+LDAP_dn2principal(krb5_context context, HDB * db, const char *dn,
+ krb5_principal * principal)
+{
+ krb5_error_code ret;
+ int rc;
+ char **values;
+ LDAPMessage *res = NULL, *e;
+
+ rc = 1;
+ (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, &rc);
+ rc = ldap_search_s((LDAP *) db->db, db->name, LDAP_SCOPE_BASE,
+ "(objectclass=krb5Principal)", krb5principal_attrs,
+ 0, &res);
+
+ if (rc != LDAP_SUCCESS) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ e = ldap_first_entry((LDAP *) db->db, res);
+ if (e == NULL) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ values = ldap_get_values((LDAP *) db->db, e, "krb5PrincipalName");
+ if (values == NULL) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ ret = krb5_parse_name(context, values[0], principal);
+ ldap_value_free(values);
+
+ out:
+ if (res != NULL) {
+ ldap_msgfree(res);
+ }
+ return ret;
+}
+
+static krb5_error_code
+LDAP__lookup_princ(krb5_context context, HDB * db, const char *princname,
+ LDAPMessage ** msg)
+{
+ krb5_error_code ret;
+ int rc;
+ char *filter = NULL;
+
+ (void) LDAP__connect(context, db);
+
+ rc =
+ asprintf(&filter,
+ "(&(objectclass=krb5KDCEntry)(krb5PrincipalName=%s))",
+ princname);
+ if (rc < 0) {
+ ret = ENOMEM;
+ goto out;
+ }
+
+ rc = 1;
+ (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, (void *) &rc);
+
+ rc = ldap_search_s((LDAP *) db->db, db->name, LDAP_SCOPE_ONELEVEL, filter,
+ krb5kdcentry_attrs, 0, msg);
+ if (rc != LDAP_SUCCESS) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ ret = 0;
+
+ out:
+ if (filter != NULL) {
+ free(filter);
+ }
+ return ret;
+}
+
+static krb5_error_code
+LDAP_principal2message(krb5_context context, HDB * db,
+ krb5_principal princ, LDAPMessage ** msg)
+{
+ char *princname = NULL;
+ krb5_error_code ret;
+
+ ret = krb5_unparse_name(context, princ, &princname);
+ if (ret != 0) {
+ return ret;
+ }
+
+ ret = LDAP__lookup_princ(context, db, princname, msg);
+ free(princname);
+
+ return ret;
+}
+
+/*
+ * Construct an hdb_entry from a directory entry.
+ */
+static krb5_error_code
+LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg,
+ hdb_entry * ent)
+{
+ char *unparsed_name = NULL, *dn = NULL;
+ int ret;
+ unsigned long tmp;
+ struct berval **keys;
+ char **values;
+
+ memset(ent, 0, sizeof(*ent));
+ memset(&ent->flags, 0, sizeof(HDBFlags));
+
+ 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_integer_value(db, msg, "krb5KeyVersionNumber",
+ &ent->kvno);
+ if (ret != 0) {
+ ent->kvno = 0;
+ }
+
+ keys = ldap_get_values_len((LDAP *) db->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));
+ for (i = 0; i < ent->keys.len; i++) {
+ decode_Key((unsigned char *) keys[i]->bv_val,
+ (size_t) keys[i]->bv_len, &ent->keys.val[i], &l);
+ }
+ ber_bvecfree(keys);
+ } else {
+#if 1
+ /*
+ * This violates the ASN1 but it allows a principal to
+ * be related to a general directory entry without creating
+ * the keys. Hopefully it's OK.
+ */
+ ent->keys.len = 0;
+ ent->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);
+ }
+
+ ent->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)
+ != 0) {
+ ent->created_by.principal = NULL;
+ }
+ free(dn);
+ }
+
+ ent->modified_by = (Event *) malloc(sizeof(Event));
+ if (ent->modified_by == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret =
+ LDAP_get_generalized_time_value(db, msg, "modifyTimestamp",
+ &ent->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;
+ }
+ free(dn);
+ } else {
+ free(ent->modified_by);
+ ent->modified_by = NULL;
+ }
+
+ if ((ent->valid_start = (KerberosTime *) malloc(sizeof(KerberosTime)))
+ == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret =
+ LDAP_get_generalized_time_value(db, msg, "krb5ValidStart",
+ ent->valid_start);
+ if (ret != 0) {
+ /* OPTIONAL */
+ free(ent->valid_start);
+ ent->valid_start = NULL;
+ }
+
+ if ((ent->valid_end = (KerberosTime *) malloc(sizeof(KerberosTime))) ==
+ NULL) {ret = ENOMEM;
+ goto out;
+ }
+ ret =
+ LDAP_get_generalized_time_value(db, msg, "krb5ValidEnd",
+ ent->valid_end);
+ if (ret != 0) {
+ /* OPTIONAL */
+ free(ent->valid_end);
+ ent->valid_end = NULL;
+ }
+
+ if ((ent->pw_end = (KerberosTime *) malloc(sizeof(KerberosTime))) ==
+ NULL) {ret = ENOMEM;
+ goto out;
+ }
+ ret =
+ LDAP_get_generalized_time_value(db, msg, "krb5PasswordEnd",
+ ent->pw_end);
+ if (ret != 0) {
+ /* OPTIONAL */
+ free(ent->pw_end);
+ ent->pw_end = NULL;
+ }
+
+ ent->max_life = (int *) malloc(sizeof(int));
+ if (ent->max_life == NULL) {
+ 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;
+ }
+
+ ent->max_renew = (int *) malloc(sizeof(int));
+ if (ent->max_renew == NULL) {
+ ret = ENOMEM;
+ goto out;
+ }
+ ret = LDAP_get_integer_value(db, msg, "krb5MaxRenew", ent->max_renew);
+ if (ret != 0) {
+ free(ent->max_renew);
+ ent->max_renew = NULL;
+ }
+
+ values = ldap_get_values((LDAP *) db->db, msg, "krb5KDCFlags");
+ if (values != NULL) {
+ tmp = strtoul(values[0], (char **) NULL, 10);
+ if (tmp == ULONG_MAX && errno == ERANGE) {
+ ret = ERANGE;
+ goto out;
+ }
+ } else {
+ tmp = 0;
+ }
+ memcpy(&ent->flags, &tmp, sizeof(HDBFlags));
+
+ values = ldap_get_values((LDAP *) db->db, msg, "krb5EncryptionType");
+ if (values != NULL) {
+ int i;
+
+ ent->etypes = malloc(sizeof(*(ent->etypes)));
+ if (ent->etypes == NULL) {
+ 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]);
+ }
+ ldap_value_free(values);
+ }
+
+ ret = 0;
+
+ out:
+ if (unparsed_name != NULL) {
+ free(unparsed_name);
+ }
+
+ if (ret != 0) {
+ /* I don't think this frees ent itself. */
+ hdb_free_entry(context, ent);
+ }
+
+ return ret;
+}
+
+static krb5_error_code LDAP_close(krb5_context context, HDB * db)
+{
+ LDAP *ld = (LDAP *) db->db;
+
+ ldap_unbind(ld);
+ db->db = NULL;
+ return 0;
+}
+
+static krb5_error_code
+LDAP_lock(krb5_context context, HDB * db, int operation)
+{
+ return 0;
+}
+
+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)
+{
+ int msgid, rc, parserc;
+ krb5_error_code ret;
+ LDAPMessage *e;
+
+ msgid = db->openp; /* BOGUS OVERLOADING */
+ if (msgid < 0) {
+ return HDB_ERR_NOENTRY;
+ }
+
+ do {
+ rc = ldap_result((LDAP *) db->db, msgid, LDAP_MSG_ONE, NULL, &e);
+ switch (rc) {
+ case LDAP_RES_SEARCH_ENTRY:
+ /* We have an entry. Parse it. */
+ ret = LDAP_message2entry(context, db, e, entry);
+ ldap_msgfree(e);
+ break;
+ 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,
+ NULL, NULL, 1);
+ if (parserc != LDAP_SUCCESS
+ && parserc != LDAP_MORE_RESULTS_TO_RETURN) {
+ ldap_abandon((LDAP *) db->db, msgid);
+ }
+ ret = HDB_ERR_NOENTRY;
+ db->openp = -1;
+ break;
+ case 0:
+ case -1:
+ default:
+ /* Some unspecified error (timeout?). Abandon. */
+ ldap_msgfree(e);
+ ldap_abandon((LDAP *) db->db, msgid);
+ ret = HDB_ERR_NOENTRY;
+ db->openp = -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 (ret)
+ hdb_free_entry(context,entry);
+ }
+ }
+
+ return ret;
+}
+
+static krb5_error_code
+LDAP_firstkey(krb5_context context, HDB * db, unsigned flags,
+ hdb_entry * entry)
+{
+ int msgid;
+
+ (void) LDAP__connect(context, db);
+
+ msgid = LDAP_NO_LIMIT;
+ (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, &msgid);
+
+ msgid = ldap_search((LDAP *) db->db, db->name,
+ LDAP_SCOPE_ONELEVEL, "(objectclass=krb5KDCEntry)",
+ krb5kdcentry_attrs, 0);
+ if (msgid < 0) {
+ return HDB_ERR_NOENTRY;
+ }
+
+ db->openp = msgid;
+
+ return LDAP_seq(context, db, flags, entry);
+}
+
+static krb5_error_code
+LDAP_nextkey(krb5_context context, HDB * db, unsigned flags,
+ hdb_entry * 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_boolean LDAP__is_user_namingcontext(const char *ctx,
+ char *const *subschema)
+{
+ char *const *p;
+
+ if (!strcasecmp(ctx, "CN=MONITOR")
+ || !strcasecmp(ctx, "CN=CONFIG")) {
+ return FALSE;
+ }
+
+ if (subschema != NULL) {
+ for (p = subschema; *p != NULL; p++) {
+ if (!strcasecmp(ctx, *p)) {
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+static krb5_error_code LDAP__connect(krb5_context context, HDB * db)
+{
+ int rc;
+ krb5_error_code ret;
+ char *attrs[] = { "namingContexts", "subschemaSubentry", NULL };
+ LDAPMessage *res = NULL, *e;
+
+ if (db->db != NULL) {
+ /* connection has been opened. ping server. */
+ struct sockaddr_un addr;
+ socklen_t len;
+ int sd;
+
+ if (ldap_get_option((LDAP *) db->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 */
+ return 0;
+ }
+
+ rc = ldap_initialize((LDAP **) & db->db, "ldapi:///");
+ if (rc != LDAP_SUCCESS) {
+ return HDB_ERR_NOENTRY;
+ }
+
+ rc = LDAP_VERSION3;
+ (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_PROTOCOL_VERSION, &rc);
+
+ /* XXX set db->name to the search base */
+ rc = ldap_search_s((LDAP *) db->db, "", LDAP_SCOPE_BASE,
+ "(objectclass=*)", attrs, 0, &res);
+ if (rc != LDAP_SUCCESS) {
+ ret = HDB_ERR_BADVERSION;
+ goto out;
+ }
+
+ e = ldap_first_entry((LDAP *) db->db, res);
+ if (e == NULL) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ if (db->name == NULL) {
+ char **contexts = NULL, **schema_contexts, **p;
+
+ contexts = ldap_get_values((LDAP *) db->db, e, "namingContexts");
+ if (contexts == NULL) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ schema_contexts =
+ ldap_get_values((LDAP *) db->db, e, "subschemaSubentry");
+
+ if (db->name != NULL) {
+ free(db->name);
+ db->name = NULL;
+ }
+
+ for (p = contexts; *p != NULL; p++) {
+ if (LDAP__is_user_namingcontext(*p, schema_contexts)) {
+ break;
+ }
+ }
+
+ db->name = strdup(*p);
+ if (db->name == NULL) {
+ ldap_value_free(contexts);
+ ret = ENOMEM;
+ goto out;
+ }
+
+ ldap_value_free(contexts);
+ if (schema_contexts != NULL) {
+ ldap_value_free(schema_contexts);
+ }
+ }
+
+ ret = 0;
+
+ out:
+
+ if (res != NULL) {
+ ldap_msgfree(res);
+ }
+
+ if (ret != 0) {
+ if (db->db != NULL) {
+ ldap_unbind((LDAP *) db->db);
+ db->db = NULL;
+ }
+ }
+
+ return ret;
+}
+
+static krb5_error_code
+LDAP_open(krb5_context context, HDB * db, int flags, mode_t mode)
+{
+ krb5_error_code ret;
+
+ /* Not the right place for this. */
+#ifdef HAVE_SIGACTION
+ {
+ struct sigaction sa;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ sigemptyset(&sa.sa_mask);
+
+ sigaction(SIGPIPE, &sa, NULL);
+ }
+#else
+ signal(SIGPIPE, SIG_IGN);
+#endif
+
+ if (db->name != NULL) {
+ free(db->name);
+ db->name = NULL;
+ }
+
+ ret = LDAP__connect(context, db);
+ if (ret != 0) {
+ return ret;
+ }
+
+ return ret;
+}
+
+static krb5_error_code
+LDAP_fetch(krb5_context context, HDB * db, unsigned flags,
+ hdb_entry * entry)
+{
+ LDAPMessage *msg, *e;
+ krb5_error_code ret;
+
+ ret = LDAP_principal2message(context, db, entry->principal, &msg);
+ if (ret != 0) {
+ return ret;
+ }
+
+ e = ldap_first_entry((LDAP *) db->db, msg);
+ if (e == NULL) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ 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 (ret)
+ hdb_free_entry(context,entry);
+ }
+ }
+
+ out:
+ ldap_msgfree(msg);
+
+ return ret;
+}
+
+static krb5_error_code
+LDAP_store(krb5_context context, HDB * db, unsigned flags,
+ hdb_entry * entry)
+{
+ LDAPMod **mods = NULL;
+ krb5_error_code ret;
+ 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__lookup_princ(context, db, name, &msg);
+ if (ret == 0) {
+ e = ldap_first_entry((LDAP *) db->db, msg);
+ }
+
+ ret = hdb_seal_keys(context, db, entry);
+ if (ret)
+ goto out;
+
+ /* turn new entry into LDAPMod array */
+ ret = LDAP_entry2mods(context, db, entry, e, &mods);
+ if (ret != 0) {
+ 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;
+ }
+
+ ret = asprintf(&dn, "cn=%s,%s", name, db->name);
+ if (ret < 0) {
+ ret = ENOMEM;
+ goto out;
+ }
+ } else if (flags & HDB_F_REPLACE) {
+ /* Entry exists, and we're allowed to replace it. */
+ dn = ldap_get_dn((LDAP *) db->db, e);
+ } else {
+ /* Entry exists, but we're not allowed to replace it. Bail. */
+ ret = HDB_ERR_EXISTS;
+ goto out;
+ }
+
+ /* write entry into directory */
+ if (e == NULL) {
+ /* didn't exist before */
+ ret = ldap_add_s((LDAP *) db->db, dn, mods);
+ } else {
+ /* already existed, send deltas only */
+ ret = ldap_modify_s((LDAP *) db->db, dn, mods);
+ }
+
+ if (ret == LDAP_SUCCESS) {
+ ret = 0;
+ } else {
+ ret = HDB_ERR_CANT_LOCK_DB;
+ }
+
+ out:
+ /* free stuff */
+ if (dn != NULL) {
+ free(dn);
+ }
+
+ if (msg != NULL) {
+ ldap_msgfree(msg);
+ }
+
+ if (mods != NULL) {
+ ldap_mods_free(mods, 1);
+ }
+
+ if (name != NULL) {
+ free(name);
+ }
+
+ return ret;
+}
+
+static krb5_error_code
+LDAP_remove(krb5_context context, HDB * db, hdb_entry * entry)
+{
+ krb5_error_code ret;
+ LDAPMessage *msg, *e;
+ char *dn = NULL;
+
+ ret = LDAP_principal2message(context, db, entry->principal, &msg);
+ if (ret != 0) {
+ goto out;
+ }
+
+ e = ldap_first_entry((LDAP *) db->db, msg);
+ if (e == NULL) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ dn = ldap_get_dn((LDAP *) db->db, e);
+ if (dn == NULL) {
+ ret = HDB_ERR_NOENTRY;
+ goto out;
+ }
+
+ ret = LDAP_NO_LIMIT;
+ (void) ldap_set_option((LDAP *) db->db, LDAP_OPT_SIZELIMIT, &ret);
+
+ ret = ldap_delete_s((LDAP *) db->db, dn);
+ if (ret == LDAP_SUCCESS) {
+ ret = 0;
+ } else {
+ ret = HDB_ERR_CANT_LOCK_DB;
+ }
+
+ out:
+ if (dn != NULL) {
+ free(dn);
+ }
+
+ 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)
+{
+ krb5_error_code ret;
+
+ ret = hdb_clear_master_key(context, db);
+ free(db->name);
+ free(db);
+
+ return ret;
+}
+
+krb5_error_code
+hdb_ldap_create(krb5_context context, HDB ** db, const char *filename)
+{
+ *db = malloc(sizeof(**db));
+ if (*db == NULL)
+ return ENOMEM;
+
+ (*db)->db = NULL;
+/* (*db)->name = strdup(filename); */
+ (*db)->name = NULL;
+ (*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;
+
+ return 0;
+}
+
+#endif /* OPENLDAP */
diff --git a/crypto/heimdal/lib/hdb/hdb-private.h b/crypto/heimdal/lib/hdb/hdb-private.h
index ce868bd..7563d36 100644
--- a/crypto/heimdal/lib/hdb/hdb-private.h
+++ b/crypto/heimdal/lib/hdb/hdb-private.h
@@ -26,12 +26,6 @@ _hdb_remove __P((
HDB *db,
hdb_entry *entry));
-void
-_hdb_seal_keys_int __P((
- hdb_entry *ent,
- int key_version,
- krb5_data schedule));
-
krb5_error_code
_hdb_store __P((
krb5_context context,
@@ -39,10 +33,4 @@ _hdb_store __P((
unsigned flags,
hdb_entry *entry));
-void
-_hdb_unseal_keys_int __P((
- hdb_entry *ent,
- int key_version,
- krb5_data schedule));
-
#endif /* __hdb_private_h__ */
diff --git a/crypto/heimdal/lib/hdb/hdb-protos.h b/crypto/heimdal/lib/hdb/hdb-protos.h
index e0f15b1..dbb00a5 100644
--- a/crypto/heimdal/lib/hdb/hdb-protos.h
+++ b/crypto/heimdal/lib/hdb/hdb-protos.h
@@ -14,6 +14,12 @@
#endif
krb5_error_code
+hdb_add_master_key __P((
+ krb5_context context,
+ krb5_keyblock *key,
+ hdb_master_key *inout));
+
+krb5_error_code
hdb_check_db_format __P((
krb5_context context,
HDB *db));
@@ -70,6 +76,11 @@ hdb_free_entry __P((
void
hdb_free_key __P((Key *key));
+void
+hdb_free_master_key __P((
+ krb5_context context,
+ hdb_master_key mkey));
+
krb5_error_code
hdb_init_db __P((
krb5_context context,
@@ -82,6 +93,12 @@ hdb_key2principal __P((
krb5_principal p));
krb5_error_code
+hdb_ldap_create __P((
+ krb5_context context,
+ HDB ** db,
+ const char *filename));
+
+krb5_error_code
hdb_lock __P((
int fd,
int operation));
@@ -95,7 +112,7 @@ hdb_ndbm_create __P((
krb5_error_code
hdb_next_enctype2key __P((
krb5_context context,
- hdb_entry *e,
+ const hdb_entry *e,
krb5_enctype enctype,
Key **key));
@@ -115,25 +132,34 @@ hdb_print_entry __P((
krb5_error_code
hdb_process_master_key __P((
krb5_context context,
- EncryptionKey key,
- krb5_data *schedule));
+ int kvno,
+ krb5_keyblock *key,
+ krb5_enctype etype,
+ hdb_master_key *mkey));
krb5_error_code
hdb_read_master_key __P((
krb5_context context,
const char *filename,
- EncryptionKey *key));
+ hdb_master_key *mkey));
-void
+krb5_error_code
hdb_seal_keys __P((
+ krb5_context context,
HDB *db,
hdb_entry *ent));
krb5_error_code
+hdb_seal_keys_mkey __P((
+ krb5_context context,
+ hdb_entry *ent,
+ hdb_master_key mkey));
+
+krb5_error_code
hdb_set_master_key __P((
krb5_context context,
HDB *db,
- EncryptionKey key));
+ krb5_keyblock *key));
krb5_error_code
hdb_set_master_keyfile __P((
@@ -144,15 +170,28 @@ hdb_set_master_keyfile __P((
krb5_error_code
hdb_unlock __P((int fd));
-void
+krb5_error_code
hdb_unseal_keys __P((
+ krb5_context context,
HDB *db,
hdb_entry *ent));
+krb5_error_code
+hdb_unseal_keys_mkey __P((
+ krb5_context context,
+ hdb_entry *ent,
+ hdb_master_key mkey));
+
int
hdb_value2entry __P((
krb5_context context,
krb5_data *value,
hdb_entry *ent));
+krb5_error_code
+hdb_write_master_key __P((
+ krb5_context context,
+ const char *filename,
+ hdb_master_key mkey));
+
#endif /* __hdb_protos_h__ */
diff --git a/crypto/heimdal/lib/hdb/hdb.asn1 b/crypto/heimdal/lib/hdb/hdb.asn1
index 99537d6..2a20cd1 100644
--- a/crypto/heimdal/lib/hdb/hdb.asn1
+++ b/crypto/heimdal/lib/hdb/hdb.asn1
@@ -1,10 +1,8 @@
--- $Id: hdb.asn1,v 1.7 1999/05/03 16:48:52 joda Exp $
+-- $Id: hdb.asn1,v 1.8 2000/06/19 15:22:22 joda Exp $
HDB DEFINITIONS ::=
BEGIN
-EncryptionKey EXTERNAL
-KerberosTime EXTERNAL
-Principal EXTERNAL
+IMPORTS EncryptionKey, KerberosTime, Principal FROM krb5;
HDB_DB_FORMAT INTEGER ::= 2 -- format of database,
-- update when making changes
diff --git a/crypto/heimdal/lib/hdb/hdb.c b/crypto/heimdal/lib/hdb/hdb.c
index edf6677..1565f03 100644
--- a/crypto/heimdal/lib/hdb/hdb.c
+++ b/crypto/heimdal/lib/hdb/hdb.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,17 +33,42 @@
#include "hdb_locl.h"
-RCSID("$Id: hdb.c,v 1.35 1999/12/02 17:05:05 joda Exp $");
+RCSID("$Id: hdb.c,v 1.42 2000/11/15 23:12:15 assar Exp $");
+
+struct hdb_method {
+ const char *prefix;
+ krb5_error_code (*create)(krb5_context, HDB **, const char *filename);
+};
+
+static struct hdb_method methods[] = {
+#ifdef HAVE_DB_H
+ {"db:", hdb_db_create},
+#endif
+#if defined(HAVE_NDBM_H) || defined(HAVE_GDBM_NDBM_H)
+ {"ndbm:", hdb_ndbm_create},
+#endif
+#ifdef OPENLDAP
+ {"ldap:", hdb_ldap_create},
+#endif
+#ifdef HAVE_DB_H
+ {"", hdb_db_create},
+#elif defined(HAVE_NDBM_H)
+ {"", hdb_ndbm_create},
+#elif defined(OPENLDAP)
+ {"", hdb_ldap_create},
+#endif
+ {NULL, NULL}
+};
krb5_error_code
hdb_next_enctype2key(krb5_context context,
- hdb_entry *e,
+ const hdb_entry *e,
krb5_enctype enctype,
Key **key)
{
Key *k;
- for (k = *key ? *key : e->keys.val;
+ for (k = *key ? (*key) + 1 : e->keys.val;
k < e->keys.val + e->keys.len;
k++)
if(k->key.keytype == enctype){
@@ -63,108 +88,6 @@ hdb_enctype2key(krb5_context context,
return hdb_next_enctype2key(context, e, enctype, key);
}
-/* this is a bit ugly, but will get better when the crypto framework
- gets fixed */
-
-krb5_error_code
-hdb_process_master_key(krb5_context context, EncryptionKey key,
- krb5_data *schedule)
-{
- krb5_error_code ret;
-
- if(key.keytype != ETYPE_DES_CBC_MD5)
- return KRB5_PROG_KEYTYPE_NOSUPP;
-
- ret = krb5_data_alloc (schedule, sizeof(des_key_schedule));
- if (ret)
- return ret;
-
- des_set_key((des_cblock*)key.keyvalue.data, schedule->data);
- return 0;
-}
-
-krb5_error_code
-hdb_read_master_key(krb5_context context, const char *filename,
- EncryptionKey *key)
-{
- FILE *f;
- unsigned char buf[256];
- size_t len;
- krb5_error_code ret;
- if(filename == NULL)
- filename = HDB_DB_DIR "/m-key";
- f = fopen(filename, "r");
- if(f == NULL)
- return errno;
- len = fread(buf, 1, sizeof(buf), f);
- if(ferror(f))
- ret = errno;
- else
- ret = decode_EncryptionKey(buf, len, key, &len);
- fclose(f);
- memset(buf, 0, sizeof(buf));
- return ret;
-}
-
-void
-_hdb_unseal_keys_int(hdb_entry *ent, int key_version, krb5_data schedule)
-{
- int i;
- for(i = 0; i < ent->keys.len; i++){
- des_cblock iv;
- int num = 0;
- if(ent->keys.val[i].mkvno == NULL)
- continue;
- if(*ent->keys.val[i].mkvno != key_version)
- ;
- memset(&iv, 0, sizeof(iv));
-
- des_cfb64_encrypt(ent->keys.val[i].key.keyvalue.data,
- ent->keys.val[i].key.keyvalue.data,
- ent->keys.val[i].key.keyvalue.length,
- schedule.data, &iv, &num, 0);
- free(ent->keys.val[i].mkvno);
- ent->keys.val[i].mkvno = NULL;
- }
-}
-
-void
-hdb_unseal_keys(HDB *db, hdb_entry *ent)
-{
- if (db->master_key_set == 0)
- return;
- _hdb_unseal_keys_int(ent, db->master_key_version, db->master_key);
-}
-
-void
-_hdb_seal_keys_int(hdb_entry *ent, int key_version, krb5_data schedule)
-{
- int i;
- for(i = 0; i < ent->keys.len; i++){
- des_cblock iv;
- int num = 0;
-
- if(ent->keys.val[i].mkvno != NULL)
- continue;
- memset(&iv, 0, sizeof(iv));
- des_cfb64_encrypt(ent->keys.val[i].key.keyvalue.data,
- ent->keys.val[i].key.keyvalue.data,
- ent->keys.val[i].key.keyvalue.length,
- schedule.data, &iv, &num, 1);
- ent->keys.val[i].mkvno = malloc(sizeof(*ent->keys.val[i].mkvno));
- *ent->keys.val[i].mkvno = key_version;
- }
-}
-
-void
-hdb_seal_keys(HDB *db, hdb_entry *ent)
-{
- if (db->master_key_set == 0)
- return;
-
- _hdb_seal_keys_int(ent, db->master_key_version, db->master_key);
-}
-
void
hdb_free_key(Key *key)
{
@@ -179,7 +102,8 @@ hdb_free_key(Key *key)
krb5_error_code
hdb_lock(int fd, int operation)
{
- int i, code;
+ int i, code = 0;
+
for(i = 0; i < 3; i++){
code = flock(fd, (operation == HDB_RLOCK ? LOCK_SH : LOCK_EX) | LOCK_NB);
if(code == 0 || errno != EWOULDBLOCK)
@@ -281,69 +205,36 @@ hdb_init_db(krb5_context context, HDB *db)
return ret;
}
-krb5_error_code
-hdb_create(krb5_context context, HDB **db, const char *filename)
-{
- krb5_error_code ret = 0;
- if(filename == NULL)
- filename = HDB_DEFAULT_DB;
- initialize_hdb_error_table_r(&context->et_list);
-#ifdef HAVE_DB_H
- ret = hdb_db_create(context, db, filename);
-#elif HAVE_NDBM_H
- ret = hdb_ndbm_create(context, db, filename);
-#else
- krb5_errx(context, 1, "No database support! (hdb_create)");
-#endif
- return ret;
-}
+/*
+ * find the relevant method for `filename', returning a pointer to the
+ * rest in `rest'.
+ * return NULL if there's no such method.
+ */
-krb5_error_code
-hdb_set_master_key (krb5_context context,
- HDB *db,
- EncryptionKey key)
+static const struct hdb_method *
+find_method (const char *filename, const char **rest)
{
- krb5_error_code ret;
+ const struct hdb_method *h;
- ret = hdb_process_master_key(context, key, &db->master_key);
- if (ret)
- return ret;
-#if 0 /* XXX - why? */
- des_set_random_generator_seed(key.keyvalue.data);
-#endif
- db->master_key_set = 1;
- db->master_key_version = 0; /* XXX */
- return 0;
+ for (h = methods; h->prefix != NULL; ++h)
+ if (strncmp (filename, h->prefix, strlen(h->prefix)) == 0) {
+ *rest = filename + strlen(h->prefix);
+ return h;
+ }
+ return NULL;
}
krb5_error_code
-hdb_set_master_keyfile (krb5_context context,
- HDB *db,
- const char *keyfile)
+hdb_create(krb5_context context, HDB **db, const char *filename)
{
- EncryptionKey key;
- krb5_error_code ret;
-
- ret = hdb_read_master_key(context, keyfile, &key);
- if (ret) {
- if (ret != ENOENT)
- return ret;
- return 0;
- }
- ret = hdb_set_master_key(context, db, key);
- memset(key.keyvalue.data, 0, key.keyvalue.length);
- free_EncryptionKey(&key);
- return ret;
-}
+ const struct hdb_method *h;
+ const char *residual;
-krb5_error_code
-hdb_clear_master_key (krb5_context context,
- HDB *db)
-{
- if (db->master_key_set) {
- memset(db->master_key.data, 0, db->master_key.length);
- krb5_data_free(&db->master_key);
- db->master_key_set = 0;
- }
- return 0;
+ if(filename == NULL)
+ filename = HDB_DEFAULT_DB;
+ initialize_hdb_error_table_r(&context->et_list);
+ h = find_method (filename, &residual);
+ if (h == NULL)
+ krb5_errx(context, 1, "No database support! (hdb_create)");
+ return (*h->create)(context, db, residual);
}
diff --git a/crypto/heimdal/lib/hdb/hdb.h b/crypto/heimdal/lib/hdb/hdb.h
index f4cb001..21d739b 100644
--- a/crypto/heimdal/lib/hdb/hdb.h
+++ b/crypto/heimdal/lib/hdb/hdb.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*/
-/* $Id: hdb.h,v 1.26 1999/12/02 17:05:05 joda Exp $ */
+/* $Id: hdb.h,v 1.31 2000/07/08 16:03:37 joda Exp $ */
#ifndef __HDB_H__
#define __HDB_H__
@@ -46,12 +46,17 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
#define HDB_F_DECRYPT 1 /* decrypt keys */
#define HDB_F_REPLACE 2 /* replace entry */
+/* key usage for master key */
+#define HDB_KU_MKEY 0x484442
+
+typedef struct hdb_master_key_data *hdb_master_key;
+
typedef struct HDB{
void *db;
+ void *dbc;
char *name;
int master_key_set;
- krb5_data master_key;
- int master_key_version;
+ hdb_master_key master_key;
int openp;
krb5_error_code (*open)(krb5_context, struct HDB*, int, mode_t);
diff --git a/crypto/heimdal/lib/hdb/hdb_err.et b/crypto/heimdal/lib/hdb/hdb_err.et
index a08a2d4..9929a56 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.4 1998/02/16 16:29:15 joda Exp $"
+id "$Id: hdb_err.et,v 1.5 2001/01/28 23:05:52 assar Exp $"
error_table hdb
@@ -22,5 +22,6 @@ error_code BADLOCKMODE, "Invalid kdb lock mode"
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"
end
diff --git a/crypto/heimdal/lib/hdb/keytab.c b/crypto/heimdal/lib/hdb/keytab.c
index d9be75d..5de3cc5 100644
--- a/crypto/heimdal/lib/hdb/keytab.c
+++ b/crypto/heimdal/lib/hdb/keytab.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999 - 2000 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -35,20 +35,24 @@
/* keytab backend for HDB databases */
-RCSID("$Id: keytab.c,v 1.2 1999/08/26 13:24:05 joda Exp $");
+RCSID("$Id: keytab.c,v 1.3 2000/08/27 04:31:42 assar Exp $");
struct hdb_data {
char *dbname;
char *mkey;
- HDB *db;
};
+/*
+ * the format for HDB keytabs is:
+ * HDB:[database:mkey]
+ */
+
static krb5_error_code
hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
{
- krb5_error_code ret;
struct hdb_data *d;
const char *db, *mkey;
+
d = malloc(sizeof(*d));
if(d == NULL)
return ENOMEM;
@@ -74,7 +78,7 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
free(d);
return ENOMEM;
}
- strncpy(d->dbname, db, mkey - db);
+ memmove(d->dbname, db, mkey - db);
d->dbname[mkey - db] = '\0';
}
d->mkey = strdup(mkey + 1);
@@ -84,21 +88,6 @@ hdb_resolve(krb5_context context, const char *name, krb5_keytab id)
return ENOMEM;
}
}
- ret = hdb_create(context, &d->db, d->dbname);
- if(ret) {
- free(d->dbname);
- free(d->mkey);
- free(d);
- return ret;
- }
- ret = hdb_set_master_keyfile (context, d->db, d->mkey);
- if(ret) {
- (*d->db->destroy)(context, d->db);
- free(d->dbname);
- free(d->mkey);
- free(d);
- return ret;
- }
id->data = d;
return 0;
}
@@ -107,7 +96,9 @@ static krb5_error_code
hdb_close(krb5_context context, krb5_keytab id)
{
struct hdb_data *d = id->data;
- (*d->db->destroy)(context, d->db);
+
+ free(d->dbname);
+ free(d->mkey);
free(d);
return 0;
}
@@ -119,6 +110,7 @@ hdb_get_name(krb5_context context,
size_t namesize)
{
struct hdb_data *d = id->data;
+
snprintf(name, namesize, "%s%s%s",
d->dbname ? d->dbname : "",
(d->dbname || d->mkey) ? ":" : "",
@@ -126,6 +118,68 @@ hdb_get_name(krb5_context context,
return 0;
}
+static void
+set_config (krb5_context context,
+ krb5_config_binding *binding,
+ const char **dbname,
+ const char **mkey)
+{
+ *dbname = krb5_config_get_string(context, binding, "dbname", NULL);
+ *mkey = krb5_config_get_string(context, binding, "mkey_file", NULL);
+}
+
+/*
+ * try to figure out the database (`dbname') and master-key (`mkey')
+ * that should be used for `principal'.
+ */
+
+static void
+find_db (krb5_context context,
+ const char **dbname,
+ const char **mkey,
+ krb5_const_principal principal)
+{
+ 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);
+
+ *dbname = *mkey = NULL;
+
+ while ((db = (krb5_config_binding *)
+ krb5_config_get_next(context,
+ NULL,
+ &top_bind,
+ krb5_config_list,
+ "kdc",
+ "database",
+ NULL)) != NULL) {
+ const char *p;
+
+ p = krb5_config_get_string (context, db, "realm", NULL);
+ if (p == NULL) {
+ if(default_binding) {
+ krb5_warnx(context, "WARNING: more than one realm-less "
+ "database specification");
+ krb5_warnx(context, "WARNING: using the first encountered");
+ } else
+ default_binding = db;
+ } else if (strcmp (*prealm, p) == 0) {
+ set_config (context, db, dbname, mkey);
+ break;
+ }
+ }
+ if (*dbname == NULL && default_binding != NULL)
+ set_config (context, default_binding, dbname, mkey);
+ if (*dbname == NULL)
+ *dbname = HDB_DEFAULT_DB;
+}
+
+/*
+ * find the keytab entry in `id' for `principal, kvno, enctype' and return
+ * it in `entry'. return 0 or an error code
+ */
+
static krb5_error_code
hdb_get_entry(krb5_context context,
krb5_keytab id,
@@ -138,13 +192,32 @@ hdb_get_entry(krb5_context context,
krb5_error_code ret;
struct hdb_data *d = id->data;
int i;
+ HDB *db;
+ const char *dbname = d->dbname;
+ const char *mkey = d->mkey;
+
+ if (dbname == NULL)
+ find_db (context, &dbname, &mkey, principal);
- ret = (*d->db->open)(context, d->db, O_RDONLY, 0);
+ ret = hdb_create (context, &db, dbname);
if (ret)
return ret;
+ ret = hdb_set_master_keyfile (context, db, mkey);
+ if (ret) {
+ (*db->destroy)(context, db);
+ return ret;
+ }
+
+ ret = (*db->open)(context, db, O_RDONLY, 0);
+ if (ret) {
+ (*db->destroy)(context, db);
+ return ret;
+ }
ent.principal = (krb5_principal)principal;
- ret = (*d->db->fetch)(context, d->db, HDB_F_DECRYPT, &ent);
- (*d->db->close)(context, d->db);
+ ret = (*db->fetch)(context, db, HDB_F_DECRYPT, &ent);
+ (*db->close)(context, db);
+ (*db->destroy)(context, db);
+
if(ret == HDB_ERR_NOENTRY)
return KRB5_KT_NOTFOUND;
else if(ret)
@@ -184,4 +257,3 @@ krb5_kt_ops hdb_kt_ops = {
NULL, /* add */
NULL /* remove */
};
-
diff --git a/crypto/heimdal/lib/hdb/mkey.c b/crypto/heimdal/lib/hdb/mkey.c
new file mode 100644
index 0000000..2c85333
--- /dev/null
+++ b/crypto/heimdal/lib/hdb/mkey.c
@@ -0,0 +1,475 @@
+/*
+ * Copyright (c) 2000 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 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"
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+RCSID("$Id: mkey.c,v 1.8 2001/01/30 01:20:57 assar Exp $");
+
+struct hdb_master_key_data {
+ krb5_keytab_entry keytab;
+ krb5_crypto crypto;
+ struct hdb_master_key_data *next;
+};
+
+void
+hdb_free_master_key(krb5_context context, hdb_master_key mkey)
+{
+ struct hdb_master_key_data *ptr;
+ while(mkey) {
+ krb5_kt_free_entry(context, &mkey->keytab);
+ krb5_crypto_destroy(context, mkey->crypto);
+ ptr = mkey;
+ mkey = mkey->next;
+ free(ptr);
+ }
+}
+
+krb5_error_code
+hdb_process_master_key(krb5_context context,
+ int kvno, krb5_keyblock *key, krb5_enctype etype,
+ hdb_master_key *mkey)
+{
+ krb5_error_code ret;
+ *mkey = calloc(1, sizeof(**mkey));
+ if(*mkey == NULL)
+ return ENOMEM;
+ (*mkey)->keytab.vno = kvno;
+ ret = krb5_parse_name(context, "K/M", &(*mkey)->keytab.principal);
+ ret = krb5_copy_keyblock_contents(context, key, &(*mkey)->keytab.keyblock);
+ if(ret) {
+ free(*mkey);
+ *mkey = NULL;
+ return ret;
+ }
+ if(etype != 0)
+ (*mkey)->keytab.keyblock.keytype = etype;
+ (*mkey)->keytab.timestamp = time(NULL);
+ ret = krb5_crypto_init(context, key, etype, &(*mkey)->crypto);
+ if(ret) {
+ krb5_free_keyblock_contents(context, &(*mkey)->keytab.keyblock);
+ free(*mkey);
+ *mkey = NULL;
+ }
+ return ret;
+}
+
+krb5_error_code
+hdb_add_master_key(krb5_context context, krb5_keyblock *key,
+ hdb_master_key *inout)
+{
+ int vno = 0;
+ hdb_master_key p;
+ krb5_error_code ret;
+
+ for(p = *inout; p; p = p->next)
+ vno = max(vno, p->keytab.vno);
+ vno++;
+ ret = hdb_process_master_key(context, vno, key, 0, &p);
+ if(ret)
+ return ret;
+ p->next = *inout;
+ *inout = p;
+ return 0;
+}
+
+static krb5_error_code
+read_master_keytab(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ krb5_error_code ret;
+ krb5_keytab id;
+ krb5_kt_cursor cursor;
+ krb5_keytab_entry entry;
+ hdb_master_key p;
+
+ ret = krb5_kt_resolve(context, filename, &id);
+ if(ret)
+ return ret;
+
+ ret = krb5_kt_start_seq_get(context, id, &cursor);
+ if(ret)
+ goto out;
+ *mkey = NULL;
+ while(krb5_kt_next_entry(context, id, &entry, &cursor) == 0) {
+ p = calloc(1, sizeof(*p));
+ p->keytab = entry;
+ ret = krb5_crypto_init(context, &p->keytab.keyblock, 0, &p->crypto);
+ p->next = *mkey;
+ *mkey = p;
+ }
+ krb5_kt_end_seq_get(context, id, &cursor);
+ out:
+ krb5_kt_close(context, id);
+ return ret;
+}
+
+/* read a MIT master keyfile */
+static krb5_error_code
+read_master_mit(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ int fd;
+ krb5_error_code ret;
+ krb5_storage *sp;
+ u_int16_t enctype;
+ krb5_keyblock key;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if(fd < 0)
+ return errno;
+ sp = krb5_storage_from_fd(fd);
+ if(sp == NULL) {
+ close(fd);
+ return errno;
+ }
+ krb5_storage_set_flags(sp, KRB5_STORAGE_HOST_BYTEORDER);
+#if 0
+ /* could possibly use ret_keyblock here, but do it with more
+ checks for now */
+ ret = krb5_ret_keyblock(sp, &key);
+#else
+ ret = krb5_ret_int16(sp, &enctype);
+ if((htons(enctype) & 0xff00) == 0x3000) {
+ ret = HEIM_ERR_BAD_MKEY;
+ goto out;
+ }
+ key.keytype = enctype;
+ ret = krb5_ret_data(sp, &key.keyvalue);
+ if(ret)
+ goto out;
+#endif
+ ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+ krb5_free_keyblock_contents(context, &key);
+ out:
+ krb5_storage_free(sp);
+ close(fd);
+ return ret;
+}
+
+/* read an old master key file */
+static krb5_error_code
+read_master_encryptionkey(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ int fd;
+ krb5_keyblock key;
+ krb5_error_code ret;
+ unsigned char buf[256];
+ ssize_t len;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if(fd < 0)
+ return errno;
+
+ len = read(fd, buf, sizeof(buf));
+ close(fd);
+ if(len < 0)
+ return errno;
+
+ ret = decode_EncryptionKey(buf, len, &key, &len);
+ memset(buf, 0, sizeof(buf));
+ if(ret)
+ return ret;
+
+ /* Originally, the keytype was just that, and later it got changed
+ to des-cbc-md5, but we always used des in cfb64 mode. This
+ should cover all cases, but will break if someone has hacked
+ this code to really use des-cbc-md5 -- but then that's not my
+ problem. */
+ if(key.keytype == KEYTYPE_DES || key.keytype == ETYPE_DES_CBC_MD5)
+ key.keytype = ETYPE_DES_CFB64_NONE;
+
+ ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+ krb5_free_keyblock_contents(context, &key);
+ return ret;
+}
+
+/* read a krb4 /.k style file */
+static krb5_error_code
+read_master_krb4(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ int fd;
+ krb5_keyblock key;
+ krb5_error_code ret;
+ unsigned char buf[256];
+ ssize_t len;
+
+ fd = open(filename, O_RDONLY | O_BINARY);
+ if(fd < 0)
+ return errno;
+
+ len = read(fd, buf, sizeof(buf));
+ close(fd);
+ if(len < 0)
+ return errno;
+
+ memset(&key, 0, sizeof(key));
+ key.keytype = ETYPE_DES_PCBC_NONE;
+ ret = krb5_data_copy(&key.keyvalue, buf, len);
+ memset(buf, 0, sizeof(buf));
+ if(ret)
+ return ret;
+
+ ret = hdb_process_master_key(context, 0, &key, 0, mkey);
+ krb5_free_keyblock_contents(context, &key);
+ return ret;
+}
+
+krb5_error_code
+hdb_read_master_key(krb5_context context, const char *filename,
+ hdb_master_key *mkey)
+{
+ FILE *f;
+ unsigned char buf[16];
+ krb5_error_code ret;
+
+ off_t len;
+
+ *mkey = NULL;
+
+ if(filename == NULL)
+ filename = HDB_DB_DIR "/m-key";
+
+ f = fopen(filename, "r");
+ if(f == NULL)
+ return errno;
+
+ if(fread(buf, 1, 2, f) != 2) {
+ fclose(f);
+ return HEIM_ERR_EOF;
+ }
+
+ fseek(f, 0, SEEK_END);
+ len = ftell(f);
+
+ if(fclose(f) != 0)
+ return errno;
+
+ if(len < 0)
+ return errno;
+
+ if(len == 8) {
+ ret = read_master_krb4(context, filename, mkey);
+ } else if(buf[0] == 0x30 && len <= 127 && buf[1] == len - 2) {
+ ret = read_master_encryptionkey(context, filename, mkey);
+ } else if(buf[0] == 5 && buf[1] >= 1 && buf[1] <= 2) {
+ ret = read_master_keytab(context, filename, mkey);
+ } else {
+ ret = read_master_mit(context, filename, mkey);
+ }
+ return ret;
+}
+
+krb5_error_code
+hdb_write_master_key(krb5_context context, const char *filename,
+ hdb_master_key mkey)
+{
+ krb5_error_code ret;
+ hdb_master_key p;
+ krb5_keytab kt;
+
+ if(filename == NULL)
+ filename = HDB_DB_DIR "/m-key";
+
+ ret = krb5_kt_resolve(context, filename, &kt);
+ if(ret)
+ return ret;
+
+ for(p = mkey; p; p = p->next) {
+ ret = krb5_kt_add_entry(context, kt, &p->keytab);
+ }
+
+ krb5_kt_close(context, kt);
+
+ return ret;
+}
+
+static hdb_master_key
+find_master_key(Key *key, 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(ret == NULL || mkey->keytab.vno > ret->keytab.vno)
+ ret = mkey;
+ } else if(mkey->keytab.vno == *key->mkvno)
+ return mkey;
+ mkey = mkey->next;
+ }
+ return ret;
+}
+
+krb5_error_code
+hdb_unseal_keys_mkey(krb5_context context, hdb_entry *ent, hdb_master_key mkey)
+{
+ int i;
+ krb5_error_code ret;
+ krb5_data res;
+ Key *k;
+
+ for(i = 0; i < ent->keys.len; i++){
+ hdb_master_key key;
+
+ k = &ent->keys.val[i];
+ if(k->mkvno == NULL)
+ continue;
+
+ key = find_master_key(&ent->keys.val[i], mkey);
+
+ if (key == NULL)
+ return HDB_ERR_NO_MKEY;
+
+ ret = krb5_decrypt(context, key->crypto, 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;
+ free(k->mkvno);
+ k->mkvno = NULL;
+ }
+ return 0;
+}
+
+krb5_error_code
+hdb_unseal_keys(krb5_context context, HDB *db, hdb_entry *ent)
+{
+ if (db->master_key_set == 0)
+ return 0;
+ return hdb_unseal_keys_mkey(context, ent, db->master_key);
+}
+
+krb5_error_code
+hdb_seal_keys_mkey(krb5_context context, hdb_entry *ent, 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;
+
+ if(k->mkvno != NULL)
+ continue;
+
+ key = find_master_key(k, 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;
+
+ memset(k->key.keyvalue.data, 0, k->key.keyvalue.length);
+ free(k->key.keyvalue.data);
+ k->key.keyvalue = res;
+
+ k->mkvno = malloc(sizeof(*k->mkvno));
+ if (k->mkvno == NULL)
+ return ENOMEM;
+ *k->mkvno = key->keytab.vno;
+ }
+ return 0;
+}
+
+krb5_error_code
+hdb_seal_keys(krb5_context context, HDB *db, hdb_entry *ent)
+{
+ if (db->master_key_set == 0)
+ return 0;
+
+ return hdb_seal_keys_mkey(context, ent, db->master_key);
+}
+
+krb5_error_code
+hdb_set_master_key (krb5_context context,
+ HDB *db,
+ krb5_keyblock *key)
+{
+ krb5_error_code ret;
+ hdb_master_key mkey;
+
+ ret = hdb_process_master_key(context, 0, key, 0, &mkey);
+ if (ret)
+ return ret;
+ db->master_key = mkey;
+#if 0 /* XXX - why? */
+ des_set_random_generator_seed(key.keyvalue.data);
+#endif
+ db->master_key_set = 1;
+ return 0;
+}
+
+krb5_error_code
+hdb_set_master_keyfile (krb5_context context,
+ HDB *db,
+ const char *keyfile)
+{
+ hdb_master_key key;
+ krb5_error_code ret;
+
+ ret = hdb_read_master_key(context, keyfile, &key);
+ if (ret) {
+ if (ret != ENOENT)
+ return ret;
+ return 0;
+ }
+ db->master_key = key;
+ db->master_key_set = 1;
+ return ret;
+}
+
+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;
+ }
+ return 0;
+}
diff --git a/crypto/heimdal/lib/hdb/ndbm.c b/crypto/heimdal/lib/hdb/ndbm.c
index 79ca978..b4335f9 100644
--- a/crypto/heimdal/lib/hdb/ndbm.c
+++ b/crypto/heimdal/lib/hdb/ndbm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1997, 1998, 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,9 +33,9 @@
#include "hdb_locl.h"
-RCSID("$Id: ndbm.c,v 1.26 1999/12/02 17:05:05 joda Exp $");
+RCSID("$Id: ndbm.c,v 1.30 2001/01/30 01:24:00 assar Exp $");
-#ifdef HAVE_NDBM_H
+#if defined(HAVE_NDBM_H) || defined(HAVE_GDBM_NDBM_H)
struct ndbm_db {
DBM *db;
@@ -75,7 +75,7 @@ NDBM_seq(krb5_context context, HDB *db,
struct ndbm_db *d = (struct ndbm_db *)db->db;
datum key, value;
krb5_data key_data, data;
- krb5_error_code ret;
+ krb5_error_code ret = 0;
if(first)
key = dbm_firstkey(d->db);
@@ -93,13 +93,21 @@ NDBM_seq(krb5_context context, HDB *db,
data.length = value.dsize;
if(hdb_value2entry(context, &data, entry))
return NDBM_seq(context, db, flags, entry, 0);
- if (db->master_key_set && (flags & HDB_F_DECRYPT))
- hdb_unseal_keys (db, entry);
+ if (db->master_key_set && (flags & HDB_F_DECRYPT)) {
+ ret = hdb_unseal_keys (context, db, entry);
+ if (ret)
+ hdb_free_entry (context, entry);
+ }
if (entry->principal == NULL) {
entry->principal = malloc (sizeof(*entry->principal));
- hdb_key2principal (context, &key_data, entry->principal);
+ if (entry->principal == NULL) {
+ ret = ENOMEM;
+ hdb_free_entry (context, entry);
+ } else {
+ hdb_key2principal (context, &key_data, entry->principal);
+ }
}
- return 0;
+ return ret;
}
@@ -312,5 +320,4 @@ hdb_ndbm_create(krb5_context context, HDB **db,
return 0;
}
-
#endif
diff --git a/crypto/heimdal/lib/hdb/print.c b/crypto/heimdal/lib/hdb/print.c
index 5db3166..903e78b 100644
--- a/crypto/heimdal/lib/hdb/print.c
+++ b/crypto/heimdal/lib/hdb/print.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999 Kungliga Tekniska Högskolan
+ * Copyright (c) 1999-2001 Kungliga Tekniska Högskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -33,7 +33,7 @@
#include "hdb_locl.h"
#include <ctype.h>
-RCSID("$Id: print.c,v 1.4 1999/12/26 13:50:22 assar Exp $");
+RCSID("$Id: print.c,v 1.5 2001/01/26 15:08:36 joda Exp $");
/*
This is the present contents of a dump line. This might change at
@@ -75,9 +75,14 @@ append_hex(char *str, krb5_data *data)
p[data->length + 1] = '\"';
memcpy(p + 1, data->data, data->length);
}else{
- p = calloc(1, data->length * 2 + 1);
- for(i = 0; i < data->length; i++)
- sprintf(p + 2 * i, "%02x", ((u_char*)data->data)[i]);
+ const char *xchars = "0123456789abcdef";
+ char *q = p = malloc(data->length * 2 + 1);
+ for(i = 0; i < data->length; i++) {
+ unsigned char c = ((u_char*)data->data)[i];
+ *q++ = xchars[(c & 0xf0) >> 4];
+ *q++ = xchars[(c & 0xf)];
+ }
+ *q = '\0';
}
strcat(str, p);
free(p);
@@ -123,6 +128,7 @@ hdb_entry2string(krb5_context context, hdb_entry *ent, char **str)
{
char *p;
char buf[1024] = "";
+ char tmp[32];
int i;
krb5_error_code ret;
@@ -134,29 +140,26 @@ hdb_entry2string(krb5_context context, hdb_entry *ent, char **str)
strlcat(buf, " ", sizeof(buf));
free(p);
/* --- kvno */
- asprintf(&p, "%d", ent->kvno);
- strlcat(buf, p, sizeof(buf));
- free(p);
+ snprintf(tmp, sizeof(tmp), "%d", ent->kvno);
+ strlcat(buf, tmp, sizeof(buf));
/* --- keys */
for(i = 0; i < ent->keys.len; i++){
/* --- mkvno, keytype */
if(ent->keys.val[i].mkvno)
- asprintf(&p, ":%d:%d:",
+ snprintf(tmp, sizeof(tmp), ":%d:%d:",
*ent->keys.val[i].mkvno,
ent->keys.val[i].key.keytype);
else
- asprintf(&p, "::%d:",
+ snprintf(tmp, sizeof(tmp), "::%d:",
ent->keys.val[i].key.keytype);
- strlcat(buf, p, sizeof(buf));
- free(p);
+ strlcat(buf, tmp, sizeof(buf));
/* --- keydata */
append_hex(buf, &ent->keys.val[i].key.keyvalue);
strlcat(buf, ":", sizeof(buf));
/* --- salt */
if(ent->keys.val[i].salt){
- asprintf(&p, "%u/", ent->keys.val[i].salt->type);
- strlcat(buf, p, sizeof(buf));
- free(p);
+ snprintf(tmp, sizeof(tmp), "%u/", ent->keys.val[i].salt->type);
+ strlcat(buf, tmp, sizeof(buf));
append_hex(buf, &ent->keys.val[i].salt->salt);
}else
strlcat(buf, "-", sizeof(buf));
@@ -196,28 +199,25 @@ hdb_entry2string(krb5_context context, hdb_entry *ent, char **str)
/* --- max life */
if(ent->max_life){
- asprintf(&p, "%d", *ent->max_life);
- strlcat(buf, p, sizeof(buf));
- free(p);
+ snprintf(tmp, sizeof(tmp), "%d", *ent->max_life);
+ strlcat(buf, tmp, sizeof(buf));
}else
strlcat(buf, "-", sizeof(buf));
strlcat(buf, " ", sizeof(buf));
/* --- max renewable life */
if(ent->max_renew){
- asprintf(&p, "%d", *ent->max_renew);
- strlcat(buf, p, sizeof(buf));
- free(p);
+ snprintf(tmp, sizeof(tmp), "%d", *ent->max_renew);
+ strlcat(buf, tmp, sizeof(buf));
}else
strlcat(buf, "-", sizeof(buf));
strlcat(buf, " ", sizeof(buf));
/* --- flags */
- asprintf(&p, "%d", HDBFlags2int(ent->flags));
- strlcat(buf, p, sizeof(buf));
- free(p);
-
+ snprintf(tmp, sizeof(tmp), "%d", HDBFlags2int(ent->flags));
+ strlcat(buf, tmp, sizeof(buf));
+
*str = strdup(buf);
return 0;
OpenPOWER on IntegriCloud