diff options
author | assar <assar@FreeBSD.org> | 2001-02-13 16:46:19 +0000 |
---|---|---|
committer | assar <assar@FreeBSD.org> | 2001-02-13 16:46:19 +0000 |
commit | ebfe6dc471c206300fd82c7c0fd145f683aa52f6 (patch) | |
tree | e66aa570ad1d12c43b32a7313b0f8e28971bf8a9 /crypto/heimdal/lib/hdb | |
parent | e5f617598c2db0dd51906a38ecea9208123a8b70 (diff) | |
download | FreeBSD-src-ebfe6dc471c206300fd82c7c0fd145f683aa52f6.zip FreeBSD-src-ebfe6dc471c206300fd82c7c0fd145f683aa52f6.tar.gz |
import of heimdal 0.3e
Diffstat (limited to 'crypto/heimdal/lib/hdb')
-rw-r--r-- | crypto/heimdal/lib/hdb/Makefile.am | 32 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/Makefile.in | 312 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/common.c | 21 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/convert_db.c | 28 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/db.c | 24 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/db3.c | 310 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb-ldap.c | 1344 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb-private.h | 12 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb-protos.h | 53 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb.asn1 | 6 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb.c | 219 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb.h | 13 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb_err.et | 3 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/hdb_locl.h | 6 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/keytab.c | 122 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/mkey.c | 475 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/ndbm.c | 25 | ||||
-rw-r--r-- | crypto/heimdal/lib/hdb/print.c | 50 |
18 files changed, 2575 insertions, 480 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/hdb_locl.h b/crypto/heimdal/lib/hdb/hdb_locl.h index 5d0a6d0..1c825fa 100644 --- a/crypto/heimdal/lib/hdb/hdb_locl.h +++ b/crypto/heimdal/lib/hdb/hdb_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: hdb_locl.h,v 1.13 2000/02/06 05:17:05 assar Exp $ */ +/* $Id: hdb_locl.h,v 1.14 2000/11/14 06:57:17 assar Exp $ */ #ifndef __HDB_LOCL_H__ #define __HDB_LOCL_H__ @@ -67,8 +67,10 @@ #include <db.h> #endif -#ifdef HAVE_NDBM_H +#if defined(HAVE_NDBM_H) #include <ndbm.h> +#elif defined(HAVE_GDBM_NDBM_H) +#include <gdbm/ndbm.h> #endif int hdb_principal2key(krb5_context, krb5_principal, krb5_data*); 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; |