From f72c3ffaca4600d4e75282857ce4dda11106d5e7 Mon Sep 17 00:00:00 2001 From: Ken Raeburn Date: Tue, 21 Jun 2005 01:36:03 +0000 Subject: Novell Database Abstraction Layer merge. Will probably break things. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@17258 dc483132-0cff-0310-8789-dd5450dbe970 --- src/lib/ChangeLog | 7 + src/lib/Makefile.in | 2 +- src/lib/kadm5/ChangeLog | 13 + src/lib/kadm5/Makefile.in | 40 +- src/lib/kadm5/adb_err.et | 16 - src/lib/kadm5/admin.h | 13 +- src/lib/kadm5/admin_xdr.h | 3 + src/lib/kadm5/clnt/ChangeLog | 11 + src/lib/kadm5/clnt/Makefile.in | 47 +- src/lib/kadm5/clnt/client_init.c | 16 +- src/lib/kadm5/clnt/client_principal.c | 20 + src/lib/kadm5/clnt/clnt_policy.c | 24 + src/lib/kadm5/clnt/clnt_privs.c | 15 + src/lib/kadm5/clnt/err_handle.c | 185 +++ src/lib/kadm5/clnt/err_handle.h | 32 + src/lib/kadm5/kadm_err.et | 1 + src/lib/kadm5/kadm_rpc.h | 7 + src/lib/kadm5/kadm_rpc_xdr.c | 92 +- src/lib/kadm5/ovsec_glue.c | 9 +- src/lib/kadm5/server_internal.h | 26 +- src/lib/kadm5/srv/ChangeLog | 15 + src/lib/kadm5/srv/Makefile.in | 140 +-- src/lib/kadm5/srv/adb_free.c | 85 -- src/lib/kadm5/srv/adb_openclose.c | 410 ------- src/lib/kadm5/srv/adb_policy.c | 410 ------- src/lib/kadm5/srv/adb_xdr.c | 44 +- src/lib/kadm5/srv/server_init.c | 131 +- src/lib/kadm5/srv/server_kdb.c | 14 +- src/lib/kadm5/srv/server_misc.c | 19 +- src/lib/kadm5/srv/svr_iters.c | 9 +- src/lib/kadm5/srv/svr_policy.c | 80 +- src/lib/kadm5/srv/svr_principal.c | 300 +++-- src/lib/kadm5/unit-test/ChangeLog | 12 + src/lib/kadm5/unit-test/Makefile.in | 11 +- src/lib/kadm5/unit-test/destroy-test.c | 2 +- src/lib/kadm5/unit-test/handle-test.c | 2 +- src/lib/kadm5/unit-test/init-test.c | 2 +- src/lib/kadm5/unit-test/iter-test.c | 2 +- src/lib/kadm5/unit-test/lock-test.c | 38 +- src/lib/kadm5/unit-test/randkey-test.c | 2 +- src/lib/kadm5/unit-test/setkey-test.c | 2 +- src/lib/kdb/ChangeLog | 27 + src/lib/kdb/Makefile.in | 100 +- src/lib/kdb/adb_err.et | 16 + src/lib/kdb/configure.in | 4 +- src/lib/kdb/decrypt_key.c | 11 +- src/lib/kdb/encrypt_key.c | 13 +- src/lib/kdb/err_handle.c | 193 +++ src/lib/kdb/err_handle.h | 32 + src/lib/kdb/fetch_mkey.c | 182 --- src/lib/kdb/kdb5.c | 2051 ++++++++++++++++++++++++++++++++ src/lib/kdb/kdb5.h | 219 ++++ src/lib/kdb/kdb_compat.h | 81 -- src/lib/kdb/kdb_cpw.c | 126 +- src/lib/kdb/kdb_db2.c | 1434 ---------------------- src/lib/kdb/kdb_db2.h | 130 -- src/lib/kdb/kdb_db2/ChangeLog | 17 + src/lib/kdb/kdb_db2/Makefile.in | 150 +++ src/lib/kdb/kdb_db2/adb_openclose.c | 412 +++++++ src/lib/kdb/kdb_db2/adb_policy.c | 389 ++++++ src/lib/kdb/kdb_db2/configure.in | 22 + src/lib/kdb/kdb_db2/db2_exp.c | 64 + src/lib/kdb/kdb_db2/kdb_compat.h | 81 ++ src/lib/kdb/kdb_db2/kdb_db2.c | 2000 +++++++++++++++++++++++++++++++ src/lib/kdb/kdb_db2/kdb_db2.h | 216 ++++ src/lib/kdb/kdb_db2/kdb_xdr.c | 816 +++++++++++++ src/lib/kdb/kdb_db2/kdb_xdr.h | 32 + src/lib/kdb/kdb_db2/libkdb_db2.exports | 1 + src/lib/kdb/kdb_db2/pol_xdr.c | 88 ++ src/lib/kdb/kdb_db2/policy_db.h | 87 ++ src/lib/kdb/kdb_default.c | 329 +++++ src/lib/kdb/kdb_xdr.c | 814 ------------- src/lib/kdb/keytab.c | 13 +- src/lib/kdb/libkdb5.exports | 13 + src/lib/kdb/setup_mkey.c | 74 -- src/lib/kdb/store_mkey.c | 106 -- src/lib/kdb/t_kdb.c | 1091 ----------------- src/lib/kdb/t_krb5.conf | 29 - src/lib/kdb/verify_mky.c | 81 -- src/lib/krb5.saber.source | 18 - 80 files changed, 8405 insertions(+), 5466 deletions(-) delete mode 100644 src/lib/kadm5/adb_err.et create mode 100644 src/lib/kadm5/clnt/err_handle.c create mode 100644 src/lib/kadm5/clnt/err_handle.h delete mode 100644 src/lib/kadm5/srv/adb_free.c delete mode 100644 src/lib/kadm5/srv/adb_openclose.c delete mode 100644 src/lib/kadm5/srv/adb_policy.c create mode 100644 src/lib/kdb/adb_err.et create mode 100644 src/lib/kdb/err_handle.c create mode 100644 src/lib/kdb/err_handle.h delete mode 100644 src/lib/kdb/fetch_mkey.c create mode 100644 src/lib/kdb/kdb5.c create mode 100644 src/lib/kdb/kdb5.h delete mode 100644 src/lib/kdb/kdb_compat.h delete mode 100644 src/lib/kdb/kdb_db2.c delete mode 100644 src/lib/kdb/kdb_db2.h create mode 100644 src/lib/kdb/kdb_db2/ChangeLog create mode 100644 src/lib/kdb/kdb_db2/Makefile.in create mode 100644 src/lib/kdb/kdb_db2/adb_openclose.c create mode 100644 src/lib/kdb/kdb_db2/adb_policy.c create mode 100644 src/lib/kdb/kdb_db2/configure.in create mode 100644 src/lib/kdb/kdb_db2/db2_exp.c create mode 100644 src/lib/kdb/kdb_db2/kdb_compat.h create mode 100644 src/lib/kdb/kdb_db2/kdb_db2.c create mode 100644 src/lib/kdb/kdb_db2/kdb_db2.h create mode 100644 src/lib/kdb/kdb_db2/kdb_xdr.c create mode 100644 src/lib/kdb/kdb_db2/kdb_xdr.h create mode 100644 src/lib/kdb/kdb_db2/libkdb_db2.exports create mode 100644 src/lib/kdb/kdb_db2/pol_xdr.c create mode 100644 src/lib/kdb/kdb_db2/policy_db.h create mode 100644 src/lib/kdb/kdb_default.c delete mode 100644 src/lib/kdb/kdb_xdr.c delete mode 100644 src/lib/kdb/setup_mkey.c delete mode 100644 src/lib/kdb/store_mkey.c delete mode 100644 src/lib/kdb/t_kdb.c delete mode 100644 src/lib/kdb/t_krb5.conf delete mode 100644 src/lib/kdb/verify_mky.c delete mode 100644 src/lib/krb5.saber.source (limited to 'src/lib') diff --git a/src/lib/ChangeLog b/src/lib/ChangeLog index 4ef1d3109..dec6650ae 100644 --- a/src/lib/ChangeLog +++ b/src/lib/ChangeLog @@ -1,3 +1,10 @@ +2005-06-20 Ken Raeburn + + Novell merge. + * Makefile.in: + (LOCAL_SUBDIRS): Build kdb after rpc. + * krb5.saber.source: Deleted. + 2005-04-22 Jeffrey Altman * win_glue.c: Remove calls to WSAStartup/WSACleanup because diff --git a/src/lib/Makefile.in b/src/lib/Makefile.in index 67867c777..3e34ef0ef 100644 --- a/src/lib/Makefile.in +++ b/src/lib/Makefile.in @@ -1,7 +1,7 @@ thisconfigdir=./.. myfulldir=lib mydir=lib -LOCAL_SUBDIRS=crypto krb5 des425 @KRB4@ kdb gssapi rpc kadm5 apputils +LOCAL_SUBDIRS=crypto krb5 des425 @KRB4@ gssapi rpc kdb kadm5 apputils BUILDTOP=$(REL).. all-unix:: diff --git a/src/lib/kadm5/ChangeLog b/src/lib/kadm5/ChangeLog index 96b6dbc96..cb3f14b65 100644 --- a/src/lib/kadm5/ChangeLog +++ b/src/lib/kadm5/ChangeLog @@ -1,3 +1,16 @@ +2005-06-20 Ken Raeburn + + Novell merge. + * Makefile.in: + * adb_err.et: + * admin.h: + * admin_xdr.h: + * kadm_err.et: + * kadm_rpc.h: + * kadm_rpc_xdr.c: + * ovsec_glue.c: + * server_internal.h: + 2005-04-19 Ken Raeburn * configure.in: Don't invoke AC_CANONICAL_HOST explicitly, diff --git a/src/lib/kadm5/Makefile.in b/src/lib/kadm5/Makefile.in index 79847e982..fe8384c99 100644 --- a/src/lib/kadm5/Makefile.in +++ b/src/lib/kadm5/Makefile.in @@ -7,20 +7,16 @@ LOCAL_SUBDIRS = clnt srv unit-test ##DOSBUILDTOP = ..\.. kadm_err.$(OBJEXT): kadm_err.c -adb_err.$(OBJEXT): adb_err.c chpass_util_strings.$(OBJEXT): chpass_util_strings.c kadm_err.c kadm_err.h: $(srcdir)/kadm_err.et -adb_err.c adb_err.h: $(srcdir)/adb_err.et chpass_util_strings.c chpass_util_strings.h: $(srcdir)/chpass_util_strings.et clean:: $(RM) kadm_err.c kadm_err.h kadm_err.o - $(RM) adb_err.c adb_err.h adb_err.o $(RM) chpass_util_strings.c chpass_util_strings.h chpass_util_strings.o SRCS = kadm_err.c \ - adb_err.c \ chpass_util_strings.c \ $(srcdir)/ovsec_glue.c \ $(srcdir)/misc_free.c \ @@ -31,7 +27,6 @@ SRCS = kadm_err.c \ $(srcdir)/logger.c OBJS = kadm_err.$(OBJEXT) \ - adb_err.$(OBJEXT) \ chpass_util_strings.$(OBJEXT) \ ovsec_glue.$(OBJEXT) \ misc_free.$(OBJEXT) \ @@ -43,7 +38,6 @@ OBJS = kadm_err.$(OBJEXT) \ STLIBOBJS = \ kadm_err.o \ - adb_err.o \ chpass_util_strings.o \ ovsec_glue.o \ misc_free.o \ @@ -54,18 +48,16 @@ STLIBOBJS = \ logger.o HDRDIR=$(BUILDTOP)/include/kadm5 -HDRS = $(HDRDIR)/adb.h \ - $(HDRDIR)/admin.h \ +HDRS = $(HDRDIR)/admin.h \ $(HDRDIR)/admin_internal.h \ $(HDRDIR)/admin_xdr.h \ $(HDRDIR)/kadm_rpc.h \ $(HDRDIR)/server_internal.h \ - $(HDRDIR)/adb_err.h \ $(HDRDIR)/chpass_util_strings.h \ $(HDRDIR)/kadm_err.h -BUILD_HDRS = adb_err.h chpass_util_strings.h kadm_err.h -SRC_HDRS = adb.h admin.h admin_internal.h admin_xdr.h kadm_rpc.h \ +BUILD_HDRS = chpass_util_strings.h kadm_err.h +SRC_HDRS = admin.h admin_internal.h admin_xdr.h kadm_rpc.h \ server_internal.h $(HDRS): includes @@ -112,8 +104,6 @@ clean-windows:: # kadm_err.so kadm_err.po $(OUTPRE)kadm_err.$(OBJEXT): \ kadm_err.c $(COM_ERR_DEPS) -adb_err.so adb_err.po $(OUTPRE)adb_err.$(OBJEXT): adb_err.c \ - $(COM_ERR_DEPS) chpass_util_strings.so chpass_util_strings.po $(OUTPRE)chpass_util_strings.$(OBJEXT): \ chpass_util_strings.c $(COM_ERR_DEPS) ovsec_glue.so ovsec_glue.po $(OUTPRE)ovsec_glue.$(OBJEXT): \ @@ -130,7 +120,7 @@ ovsec_glue.so ovsec_glue.po $(OUTPRE)ovsec_glue.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h misc_free.so misc_free.po $(OUTPRE)misc_free.$(OBJEXT): \ misc_free.c $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ @@ -145,9 +135,8 @@ misc_free.so misc_free.po $(OUTPRE)misc_free.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - server_internal.h $(SRCTOP)/include/krb5/kdb.h admin_internal.h \ - adb.h $(DB_DEPS) + $(BUILDTOP)/include/kadm5/chpass_util_strings.h server_internal.h \ + $(SRCTOP)/include/krb5/kdb.h admin_internal.h kadm_rpc_xdr.so kadm_rpc_xdr.po $(OUTPRE)kadm_rpc_xdr.$(OBJEXT): \ kadm_rpc_xdr.c $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/gssrpc/rename.h $(BUILDTOP)/include/gssrpc/xdr.h \ @@ -162,9 +151,10 @@ kadm_rpc_xdr.so kadm_rpc_xdr.po $(OUTPRE)kadm_rpc_xdr.$(OBJEXT): \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/admin_xdr.h \ - $(BUILDTOP)/include/kadm5/kadm_rpc.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \ + $(BUILDTOP)/include/kadm5/admin_xdr.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \ + $(BUILDTOP)/include/kadm5/server_internal.h $(SRCTOP)/include/krb5/kdb.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h chpass_util.so chpass_util.po $(OUTPRE)chpass_util.$(OBJEXT): \ chpass_util.c $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ @@ -179,8 +169,7 @@ chpass_util.so chpass_util.po $(OUTPRE)chpass_util.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - admin_internal.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h admin_internal.h alt_prof.so alt_prof.po $(OUTPRE)alt_prof.$(OBJEXT): \ alt_prof.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ @@ -196,8 +185,7 @@ alt_prof.so alt_prof.po $(OUTPRE)alt_prof.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/svc_auth.h \ $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \ $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(SRCTOP)/include/krb5/adm_proto.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/adm_proto.h str_conv.so str_conv.po $(OUTPRE)str_conv.$(OBJEXT): \ str_conv.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ @@ -213,8 +201,8 @@ str_conv.so str_conv.po $(OUTPRE)str_conv.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/auth_gss.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \ $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/k5-int.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/adm_proto.h + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(SRCTOP)/include/krb5/adm_proto.h logger.so logger.po $(OUTPRE)logger.$(OBJEXT): logger.c \ $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ diff --git a/src/lib/kadm5/adb_err.et b/src/lib/kadm5/adb_err.et deleted file mode 100644 index 394802571..000000000 --- a/src/lib/kadm5/adb_err.et +++ /dev/null @@ -1,16 +0,0 @@ -error_table adb -error_code OSA_ADB_NOERR, "No Error" -error_code OSA_ADB_DUP, "Principal or policy already exists" -error_code OSA_ADB_NOENT, "Principal or policy does not exist" -error_code OSA_ADB_DBINIT, "Database not initialized" -error_code OSA_ADB_BAD_POLICY, "Invalid policy name" -error_code OSA_ADB_BAD_PRINC, "Invalid principal name" -error_code OSA_ADB_BAD_DB, "Database inconsistency detected" -error_code OSA_ADB_XDR_FAILURE, "XDR encoding error" -error_code OSA_ADB_FAILURE, "Failure!" -error_code OSA_ADB_BADLOCKMODE, "Bad lock mode" -error_code OSA_ADB_CANTLOCK_DB, "Cannot lock database" -error_code OSA_ADB_NOTLOCKED, "Database not locked" -error_code OSA_ADB_NOLOCKFILE, "KADM5 administration database lock file missing" -error_code OSA_ADB_NOEXCL_PERM, "Insufficient permission to lock file" -end diff --git a/src/lib/kadm5/admin.h b/src/lib/kadm5/admin.h index 4051601ec..a70e90b4e 100644 --- a/src/lib/kadm5/admin.h +++ b/src/lib/kadm5/admin.h @@ -43,7 +43,6 @@ #include #include #include -#include #include #define KADM5_ADMIN_SERVICE "kadmin/admin" @@ -204,11 +203,6 @@ typedef struct _kadm5_policy_ent_t { long policy_refcnt; } kadm5_policy_ent_rec, *kadm5_policy_ent_t; -typedef struct __krb5_key_salt_tuple { - krb5_enctype ks_enctype; - krb5_int32 ks_salttype; -} krb5_key_salt_tuple; - /* * Data structure returned by kadm5_get_config_params() */ @@ -304,6 +298,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, #endif krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle); kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, @@ -315,6 +310,7 @@ kadm5_ret_t kadm5_init_with_password(char *client_name, #endif krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle); kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, @@ -326,6 +322,7 @@ kadm5_ret_t kadm5_init_with_skey(char *client_name, #endif krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle); #if USE_KADM5_API_VERSION > 1 kadm5_ret_t kadm5_init_with_creds(char *client_name, @@ -334,6 +331,7 @@ kadm5_ret_t kadm5_init_with_creds(char *client_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle); #endif kadm5_ret_t kadm5_lock(void *server_handle); @@ -594,6 +592,7 @@ ovsec_kadm_ret_t ovsec_kadm_init(char *client_name, char *pass, char *service_name, char *realm, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle); ovsec_kadm_ret_t ovsec_kadm_init_with_password(char *client_name, char *pass, @@ -601,6 +600,7 @@ ovsec_kadm_ret_t ovsec_kadm_init_with_password(char *client_name, char *realm, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char ** db_args, void **server_handle); ovsec_kadm_ret_t ovsec_kadm_init_with_skey(char *client_name, char *keytab, @@ -608,6 +608,7 @@ ovsec_kadm_ret_t ovsec_kadm_init_with_skey(char *client_name, char *realm, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle); ovsec_kadm_ret_t ovsec_kadm_flush(void *server_handle); ovsec_kadm_ret_t ovsec_kadm_destroy(void *server_handle); diff --git a/src/lib/kadm5/admin_xdr.h b/src/lib/kadm5/admin_xdr.h index 305502541..05d1a7ea6 100644 --- a/src/lib/kadm5/admin_xdr.h +++ b/src/lib/kadm5/admin_xdr.h @@ -7,6 +7,7 @@ #include #include "kadm_rpc.h" +#include "server_internal.h" bool_t xdr_ui_4(XDR *xdrs, krb5_ui_4 *objp); bool_t xdr_nullstring(XDR *xdrs, char **objp); @@ -59,3 +60,5 @@ bool_t xdr_krb5_int32(XDR *xdrs, krb5_int32 *objp); bool_t xdr_krb5_enctype(XDR *xdrs, krb5_enctype *objp); bool_t xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp); bool_t xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp); +bool_t xdr_krb5_key_data(XDR *xdrs, krb5_key_data *objp); +bool_t xdr_osa_pw_hist_ent(XDR *xdrs, osa_pw_hist_ent *objp); diff --git a/src/lib/kadm5/clnt/ChangeLog b/src/lib/kadm5/clnt/ChangeLog index fc2dfca2e..a296c1e7d 100644 --- a/src/lib/kadm5/clnt/ChangeLog +++ b/src/lib/kadm5/clnt/ChangeLog @@ -1,3 +1,14 @@ +2005-06-20 Ken Raeburn + + Novell merge. + * Makefile.in: + * client_init.c: + * client_principal.c: + * clnt_policy.c: + * clnt_privs.c: + * err_handle.c: + * err_handle.h: + 2005-02-11 Tom Yu * client_init.c (kadm5_get_init_creds, kadm5_gic_iter) diff --git a/src/lib/kadm5/clnt/Makefile.in b/src/lib/kadm5/clnt/Makefile.in index f4ed9db74..449d75378 100644 --- a/src/lib/kadm5/clnt/Makefile.in +++ b/src/lib/kadm5/clnt/Makefile.in @@ -27,6 +27,7 @@ SRCS = $(srcdir)/clnt_policy.c \ $(srcdir)/client_principal.c \ $(srcdir)/client_init.c \ $(srcdir)/clnt_privs.c \ + $(srcdir)/err_handle.c \ $(srcdir)/clnt_chpass_util.c OBJS = \ @@ -35,6 +36,7 @@ OBJS = \ client_principal.$(OBJEXT) \ client_init.$(OBJEXT) \ clnt_privs.$(OBJEXT) \ + err_handle.$(OBJEXT) \ clnt_chpass_util.$(OBJEXT) STLIBOBJS = \ @@ -43,8 +45,11 @@ STLIBOBJS = \ client_principal.o \ client_init.o \ clnt_privs.o \ + err_handle.o \ clnt_chpass_util.o +err_handle.o : err_handle.h err_handle.c + all-unix:: includes all-unix:: all-liblinks all-windows:: $(OBJS) @@ -91,9 +96,9 @@ clnt_policy.so clnt_policy.po $(OUTPRE)clnt_policy.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \ + client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \ + err_handle.h client_rpc.so client_rpc.po $(OUTPRE)client_rpc.$(OBJEXT): \ client_rpc.c $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/gssrpc/rename.h $(BUILDTOP)/include/gssrpc/xdr.h \ @@ -108,8 +113,7 @@ client_rpc.so client_rpc.po $(OUTPRE)client_rpc.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h client_principal.so client_principal.po $(OUTPRE)client_principal.$(OBJEXT): \ client_principal.c $(BUILDTOP)/include/gssrpc/rpc.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ @@ -124,9 +128,9 @@ client_principal.so client_principal.po $(OUTPRE)client_principal.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \ - client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h err_handle.h client_init.so client_init.po $(OUTPRE)client_init.$(OBJEXT): \ client_init.c $(COM_ERR_DEPS) $(BUILDTOP)/include/krb5.h \ $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ @@ -141,10 +145,10 @@ client_init.so client_init.po $(OUTPRE)client_init.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \ $(BUILDTOP)/include/gssrpc/auth_gss.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \ - client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \ - $(BUILDTOP)/include/gssapi/gssapi_krb5.h $(BUILDTOP)/include/gssrpc/auth_gssapi.h + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/gssapi/gssapi_krb5.h \ + $(BUILDTOP)/include/gssrpc/auth_gssapi.h clnt_privs.so clnt_privs.po $(OUTPRE)clnt_privs.$(OBJEXT): \ clnt_privs.c $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \ $(BUILDTOP)/include/gssrpc/rename.h $(BUILDTOP)/include/gssrpc/xdr.h \ @@ -159,9 +163,17 @@ clnt_privs.so clnt_privs.po $(OUTPRE)clnt_privs.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(BUILDTOP)/include/kadm5/kadm_rpc.h client_internal.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/kadm_rpc.h \ + client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h \ + err_handle.h +err_handle.so err_handle.po $(OUTPRE)err_handle.$(OBJEXT): \ + err_handle.c err_handle.h $(SRCTOP)/include/k5-int.h \ + $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \ + $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ + $(SRCTOP)/include/krb5/kdb.h clnt_chpass_util.so clnt_chpass_util.po $(OUTPRE)clnt_chpass_util.$(OBJEXT): \ clnt_chpass_util.c $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \ @@ -176,6 +188,5 @@ clnt_chpass_util.so clnt_chpass_util.po $(OUTPRE)clnt_chpass_util.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h client_internal.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + client_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h diff --git a/src/lib/kadm5/clnt/client_init.c b/src/lib/kadm5/clnt/client_init.c index f1031548f..cf5638e46 100644 --- a/src/lib/kadm5/clnt/client_init.c +++ b/src/lib/kadm5/clnt/client_init.c @@ -65,6 +65,7 @@ static kadm5_ret_t _kadm5_init_any(char *client_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle); static kadm5_ret_t @@ -99,11 +100,12 @@ kadm5_ret_t kadm5_init_with_creds(char *client_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return _kadm5_init_any(client_name, INIT_CREDS, NULL, ccache, service_name, params, - struct_version, api_version, + struct_version, api_version, db_args, server_handle); } @@ -113,11 +115,12 @@ kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return _kadm5_init_any(client_name, INIT_PASS, pass, NULL, service_name, params, struct_version, - api_version, server_handle); + api_version, db_args, server_handle); } kadm5_ret_t kadm5_init(char *client_name, char *pass, @@ -125,11 +128,12 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return _kadm5_init_any(client_name, INIT_PASS, pass, NULL, service_name, params, struct_version, - api_version, server_handle); + api_version, db_args, server_handle); } kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, @@ -137,11 +141,12 @@ kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return _kadm5_init_any(client_name, INIT_SKEY, keytab, NULL, service_name, params, struct_version, - api_version, server_handle); + api_version, db_args, server_handle); } static kadm5_ret_t _kadm5_init_any(char *client_name, @@ -152,6 +157,7 @@ static kadm5_ret_t _kadm5_init_any(char *client_name, kadm5_config_params *params_in, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { struct sockaddr_in addr; @@ -168,7 +174,7 @@ static kadm5_ret_t _kadm5_init_any(char *client_name, generic_ret *r; initialize_ovk_error_table(); - initialize_adb_error_table(); +/* initialize_adb_error_table(); */ initialize_ovku_error_table(); if (! server_handle) { diff --git a/src/lib/kadm5/clnt/client_principal.c b/src/lib/kadm5/clnt/client_principal.c index 972a7b321..eb2248325 100644 --- a/src/lib/kadm5/clnt/client_principal.c +++ b/src/lib/kadm5/clnt/client_principal.c @@ -15,6 +15,7 @@ static char *rcsid = "$Header$"; #include #endif #include "client_internal.h" +#include "err_handle.h" #ifdef DEBUG #define eret() do { clnt_perror(handle->clnt, "null ret"); return KADM5_RPC_ERROR; } while (0) @@ -254,6 +255,11 @@ kadm5_get_principal(void *server_handle, memcpy(ent, &r->rec, sizeof(r->rec)); } + + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } @@ -282,6 +288,10 @@ kadm5_get_principals(void *server_handle, *princs = NULL; } + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } @@ -483,6 +493,11 @@ kadm5_randkey_principal_3(void *server_handle, } } + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } + return r->code; } @@ -531,6 +546,11 @@ kadm5_randkey_principal(void *server_handle, } } + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } + return r->code; } diff --git a/src/lib/kadm5/clnt/clnt_policy.c b/src/lib/kadm5/clnt/clnt_policy.c index 182b2d9e7..55bef4af7 100644 --- a/src/lib/kadm5/clnt/clnt_policy.c +++ b/src/lib/kadm5/clnt/clnt_policy.c @@ -14,6 +14,7 @@ static char *rcsid = "$Header$"; #include "client_internal.h" #include #include +#include "err_handle.h" kadm5_ret_t kadm5_create_policy(void *server_handle, @@ -34,6 +35,11 @@ kadm5_create_policy(void *server_handle, r = create_policy_1(&arg, handle->clnt); if(r == NULL) return KADM5_RPC_ERROR; + + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } @@ -55,6 +61,11 @@ kadm5_delete_policy(void *server_handle, char *name) r = delete_policy_1(&arg, handle->clnt); if(r == NULL) return KADM5_RPC_ERROR; + + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } @@ -78,6 +89,11 @@ kadm5_modify_policy(void *server_handle, r = modify_policy_1(&arg, handle->clnt); if(r == NULL) return KADM5_RPC_ERROR; + + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } @@ -116,6 +132,10 @@ kadm5_get_policy(void *server_handle, char *name, kadm5_policy_ent_t ent) memcpy(ent, &r->rec, sizeof(r->rec)); } + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } @@ -144,5 +164,9 @@ kadm5_get_policies(void *server_handle, *pols = NULL; } + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } diff --git a/src/lib/kadm5/clnt/clnt_privs.c b/src/lib/kadm5/clnt/clnt_privs.c index 0452f72e0..497feea5d 100644 --- a/src/lib/kadm5/clnt/clnt_privs.c +++ b/src/lib/kadm5/clnt/clnt_privs.c @@ -5,6 +5,15 @@ * $Source$ * * $Log$ + * Revision 1.3 2005/06/21 01:35:56 raeburn + * Novell Database Abstraction Layer merge. + * Will probably break things. + * + * Revision 1.2.26.1 2005/06/17 21:11:24 raeburn + * Initial checkin of Novell Database Abstraction Layer changes. + * Patches applied to 1.4.1 release code, updated to trunk, makefile dependencies + * deleted when they caused cvs merge conflicts. + * * Revision 1.2 1998/02/14 02:32:58 tlyu * * client_init.c: * * client_principal.c: @@ -65,6 +74,7 @@ static char *rcsid = "$Header$"; #include #include #include "client_internal.h" +#include "err_handle.h" kadm5_ret_t kadm5_get_privs(void *server_handle, long *privs) { @@ -76,5 +86,10 @@ kadm5_ret_t kadm5_get_privs(void *server_handle, long *privs) return KADM5_RPC_ERROR; else if (r->code == KADM5_OK) *privs = r->privs; + + if(r->code) + { + krb5_set_err( handle->context, krb5_err_have_str, r->code, r->err_str ); + } return r->code; } diff --git a/src/lib/kadm5/clnt/err_handle.c b/src/lib/kadm5/clnt/err_handle.c new file mode 100644 index 000000000..997544d5e --- /dev/null +++ b/src/lib/kadm5/clnt/err_handle.c @@ -0,0 +1,185 @@ +/********************************************************************** +* +* C %name: err_handle.c % +* Instance: idc_sec_1 +* Description: +* %created_by: spradeep % +* %date_created: Thu Apr 7 15:36:27 2005 % +* +**********************************************************************/ +#ifndef lint +static char *_csrc = "@(#) %filespec: err_handle.c~1 % (%full_filespec: err_handle.c~1:csrc:idc_sec#2 %)"; +#endif + +/* this file should be ideally be in util/et. But, for now thread safety requirement stops me from putting there. + if I do, then all the applications have to link to pthread */ + +#ifdef HAVE_PTHREAD_H +#include +#endif +#include "err_handle.h" +#include + +#ifdef NOVELL +krb5_errcode_2_string_func old_error_2_string = NULL; +#endif + +typedef struct { + char krb5_err_str[KRB5_MAX_ERR_STR + 1]; + long err_code; + krb5_err_subsystem subsystem; + krb5_context kcontext; +} krb5_err_struct_t; + +#ifdef HAVE_PTHREAD_H +static void tsd_key_destructor(void *data) +{ + free(data); +} + +static pthread_key_t krb5_err_key; + +static void init_err_handling( void ) +{ + assert(!pthread_key_create(&krb5_err_key, tsd_key_destructor)); +#ifdef NOVELL + old_error_2_string = error_message; + error_message = krb5_get_err_string; +#endif +} + +static pthread_once_t krb5_key_create = PTHREAD_ONCE_INIT; + +krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str ) +{ + int ret; + krb5_err_struct_t *err_struct; + pthread_once(&krb5_key_create, init_err_handling); + + err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key); + if( err_struct == NULL ) + { + err_struct = calloc(sizeof(krb5_err_struct_t), 1); + if( err_struct == NULL ) + return ENOMEM; + + if((ret = pthread_setspecific(krb5_err_key, err_struct))) + { + free( err_struct ); + return ret; + } + } + + err_struct->subsystem = subsystem; + err_struct->err_code = err_code; + err_struct->kcontext = kcontext; + if( err_struct->subsystem == krb5_err_have_str ) + { + strncpy( err_struct->krb5_err_str, str, sizeof(err_struct->krb5_err_str) ); + err_struct->krb5_err_str[KRB5_MAX_ERR_STR] = '\0'; + } + + return 0; +} + +const char * KRB5_CALLCONV krb5_get_err_string(long err_code) +{ + krb5_err_struct_t *err_struct; + pthread_once(&krb5_key_create, init_err_handling); + + err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key); + if( err_struct && (err_struct->subsystem == krb5_err_have_str) && (err_code == err_struct->err_code) ) + { + /* checking error code is for safety. + In case, the caller ignores a database error and calls other calls before doing com_err. + Though not perfect, caller should call krb5_clr_error before this*/ + err_struct->subsystem = krb5_err_unknown; + return err_struct->krb5_err_str; + } + + /* Error strings are not generated here. the remaining two cases are handled by the default error string convertor */ +#ifdef NOVELL + return old_error_2_string(err_code); +#else + return error_message(err_code); +#endif +} + +void krb5_clr_error() +{ + krb5_err_struct_t *err_struct; + pthread_once(&krb5_key_create, init_err_handling); + + err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key); + if( err_struct ) + err_struct->subsystem = krb5_err_unknown; +} + +#else +krb5_err_struct_t krb5_err = {{0}, 0, 0, 0}; +krb5_boolean krb5_init_once = TRUE; + +static void init_err_handling( void ) +{ + if( krb5_init_once ) + { +#ifdef NOVELL + old_error_2_string = error_message; + error_message = krb5_get_err_string; +#endif + krb5_init_once = FALSE; + } +} + +krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str ) +{ + krb5_err_struct_t *err_struct = &krb5_err; + + init_err_handling(); /* takes care for multiple inits */ + + err_struct->subsystem = subsystem; + err_struct->err_code = err_code; + err_struct->kcontext = kcontext; + if( err_struct->subsystem == krb5_err_have_str ) + { + strncpy( err_struct->krb5_err_str, str, sizeof(err_struct->krb5_err_str) ); + err_struct->krb5_err_str[KRB5_MAX_ERR_STR] = '\0'; + } + + return 0; +} + +const char * KRB5_CALLCONV krb5_get_err_string(long err_code) +{ + krb5_err_struct_t *err_struct = &krb5_err; + + init_err_handling(); /* takes care for multiple inits */ + + if( (err_struct->subsystem == krb5_err_have_str) && (err_code == err_struct->err_code) ) + { + /* checking error code is for safety. + In case, the caller ignores a database error and calls other calls before doing com_err. + Though not perfect, caller should call krb5_clr_error before this*/ + err_struct->subsystem = krb5_err_unknown; + return err_struct->krb5_err_str; + } + + /* it is not generated here. the remaining two cases are handled by the default error string convertor */ +#ifdef NOVELL + return old_error_2_string(err_code); +#else + return error_message(err_code); +#endif +} + +void krb5_clr_error() +{ + krb5_err_struct_t *err_struct = &krb5_err; + + init_err_handling(); /* takes care for multiple inits */ + + err_struct->subsystem = krb5_err_unknown; +} + + +#endif diff --git a/src/lib/kadm5/clnt/err_handle.h b/src/lib/kadm5/clnt/err_handle.h new file mode 100644 index 000000000..76b6ee43c --- /dev/null +++ b/src/lib/kadm5/clnt/err_handle.h @@ -0,0 +1,32 @@ +/********************************************************************** +* +* C Header: err_handle.h +* Instance: idc_sec_1 +* Description: +* %created_by: spradeep % +* %date_created: Thu Apr 7 15:36:49 2005 % +* +**********************************************************************/ +#ifndef _idc_sec_1_err_handle_h_H +#define _idc_sec_1_err_handle_h_H +#include + +/* Everything else goes here */ + +#define KRB5_MAX_ERR_STR 1024 +typedef enum krb5_err_subsystem { krb5_err_unknown = 0, /* no error or unknown system. Has to be probed */ + krb5_err_system, /* error in system call */ + krb5_err_krblib, /* error in kerberos library call, should lookup in the error table */ + krb5_err_have_str, /* error message is available in the string */ + krb5_err_db /* error is a database error, should be handled by calling DB */ +} krb5_err_subsystem; + +typedef krb5_error_code (*krb5_set_err_func_t)( krb5_context, krb5_err_subsystem, long, char*); + +krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str ); + +const char * KRB5_CALLCONV krb5_get_err_string(long err_code); + +void krb5_clr_error(void); + +#endif diff --git a/src/lib/kadm5/kadm_err.et b/src/lib/kadm5/kadm_err.et index c7b48b369..da18a74eb 100644 --- a/src/lib/kadm5/kadm_err.et +++ b/src/lib/kadm5/kadm_err.et @@ -59,4 +59,5 @@ error_code KADM5_SETKEY_DUP_ENCTYPES, "Multiple values for single or folded enct error_code KADM5_SETV4KEY_INVAL_ENCTYPE, "Invalid enctype for setv4key" error_code KADM5_SETKEY3_ETYPE_MISMATCH, "Mismatched enctypes for setkey3" error_code KADM5_MISSING_KRB5_CONF_PARAMS, "Missing parameters in krb5.conf required for kadmin client" +error_code KADM5_XDR_FAILURE, "XDR encoding error" end diff --git a/src/lib/kadm5/kadm_rpc.h b/src/lib/kadm5/kadm_rpc.h index d546c9472..df7764361 100644 --- a/src/lib/kadm5/kadm_rpc.h +++ b/src/lib/kadm5/kadm_rpc.h @@ -29,6 +29,7 @@ bool_t xdr_cprinc3_arg(); struct generic_ret { krb5_ui_4 api_version; kadm5_ret_t code; + char *err_str; }; typedef struct generic_ret generic_ret; bool_t xdr_generic_ret(); @@ -68,6 +69,7 @@ struct gprincs_ret { kadm5_ret_t code; char **princs; int count; + char *err_str; }; typedef struct gprincs_ret gprincs_ret; bool_t xdr_gprincs_ret(); @@ -143,6 +145,7 @@ struct chrand_ret { krb5_keyblock key; krb5_keyblock *keys; int n_keys; + char *err_str; }; typedef struct chrand_ret chrand_ret; bool_t xdr_chrand_ret(); @@ -159,6 +162,7 @@ struct gprinc_ret { krb5_ui_4 api_version; kadm5_ret_t code; kadm5_principal_ent_rec rec; + char *err_str; }; typedef struct gprinc_ret gprinc_ret; bool_t xdr_gprinc_ret(); @@ -206,6 +210,7 @@ struct gpol_ret { krb5_ui_4 api_version; kadm5_ret_t code; kadm5_policy_ent_rec rec; + char *err_str; }; typedef struct gpol_ret gpol_ret; bool_t xdr_gpol_ret(); @@ -222,6 +227,7 @@ struct gpols_ret { kadm5_ret_t code; char **pols; int count; + char *err_str; }; typedef struct gpols_ret gpols_ret; bool_t xdr_gpols_ret(); @@ -230,6 +236,7 @@ struct getprivs_ret { krb5_ui_4 api_version; kadm5_ret_t code; long privs; + char *err_str; }; typedef struct getprivs_ret getprivs_ret; bool_t xdr_getprivs_ret(); diff --git a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c index f5a34e925..f7090bdcf 100644 --- a/src/lib/kadm5/kadm_rpc_xdr.c +++ b/src/lib/kadm5/kadm_rpc_xdr.c @@ -544,6 +544,19 @@ xdr_generic_ret(XDR *xdrs, generic_ret *objp) if (!xdr_kadm5_ret_t(xdrs, &objp->code)) { return (FALSE); } + + if( xdrs->x_op == XDR_ENCODE ) + { + char *tmp_str = "Unknown error code"; + if(!xdr_string(xdrs, objp->err_str?&objp->err_str:&tmp_str, (unsigned int)-1 )) { + return (FALSE); + } + } else { + if(!xdr_string(xdrs, &objp->err_str, (unsigned int)-1 )) { + return (FALSE); + } + } + return(TRUE); } @@ -626,6 +639,19 @@ xdr_gprincs_ret(XDR *xdrs, gprincs_ret *objp) return (FALSE); } } + + if( xdrs->x_op == XDR_ENCODE ) + { + char *tmp_str = "Unknown error code"; + if(!xdr_string(xdrs, objp->err_str?&objp->err_str:&tmp_str, (unsigned int)-1 )) { + return (FALSE); + } + } else { + if(!xdr_string(xdrs, &objp->err_str, (unsigned int)-1 )) { + return (FALSE); + } + } + return (TRUE); } @@ -785,7 +811,19 @@ xdr_chrand_ret(XDR *xdrs, chrand_ret *objp) return FALSE; } } - + + if( xdrs->x_op == XDR_ENCODE ) + { + char *tmp_str = "Unknown error code"; + if(!xdr_string(xdrs, objp->err_str?&objp->err_str:&tmp_str, (unsigned int)-1 )) { + return (FALSE); + } + } else { + if(!xdr_string(xdrs, &objp->err_str, (unsigned int)-1 )) { + return (FALSE); + } + } + return (TRUE); } @@ -826,6 +864,19 @@ xdr_gprinc_ret(XDR *xdrs, gprinc_ret *objp) } } } + + if( xdrs->x_op == XDR_ENCODE ) + { + char *tmp_str = "Unknown error code"; + if(!xdr_string(xdrs, objp->err_str?&objp->err_str:&tmp_str, (unsigned int)-1 )) { + return (FALSE); + } + } else { + if(!xdr_string(xdrs, &objp->err_str, (unsigned int)-1 )) { + return (FALSE); + } + } + return (TRUE); } @@ -896,6 +947,19 @@ xdr_gpol_ret(XDR *xdrs, gpol_ret *objp) if (!xdr_kadm5_policy_ent_rec(xdrs, &objp->rec)) return (FALSE); } + + if( xdrs->x_op == XDR_ENCODE ) + { + char *tmp_str = "Unknown error code"; + if(!xdr_string(xdrs, objp->err_str?&objp->err_str:&tmp_str, (unsigned int)-1 )) { + return (FALSE); + } + } else { + if(!xdr_string(xdrs, &objp->err_str, (unsigned int)-1 )) { + return (FALSE); + } + } + return (TRUE); } @@ -930,6 +994,19 @@ xdr_gpols_ret(XDR *xdrs, gpols_ret *objp) return (FALSE); } } + + if( xdrs->x_op == XDR_ENCODE ) + { + char *tmp_str = "Unknown error code"; + if(!xdr_string(xdrs, objp->err_str?&objp->err_str:&tmp_str, (unsigned int)-1 )) { + return (FALSE); + } + } else { + if(!xdr_string(xdrs, &objp->err_str, (unsigned int)-1 )) { + return (FALSE); + } + } + return (TRUE); } @@ -941,6 +1018,19 @@ bool_t xdr_getprivs_ret(XDR *xdrs, getprivs_ret *objp) if (! xdr_kadm5_ret_t(xdrs, &objp->code) || ! xdr_long(xdrs, &objp->privs)) return FALSE; + + if( xdrs->x_op == XDR_ENCODE ) + { + char *tmp_str = "Unknown error code"; + if(!xdr_string(xdrs, objp->err_str?&objp->err_str:&tmp_str, (unsigned int)-1 )) { + return (FALSE); + } + } else { + if(!xdr_string(xdrs, &objp->err_str, (unsigned int)-1 )) { + return (FALSE); + } + } + return TRUE; } diff --git a/src/lib/kadm5/ovsec_glue.c b/src/lib/kadm5/ovsec_glue.c index ce818934f..750aa3f81 100644 --- a/src/lib/kadm5/ovsec_glue.c +++ b/src/lib/kadm5/ovsec_glue.c @@ -6,10 +6,11 @@ ovsec_kadm_ret_t ovsec_kadm_init_with_password(char *client_name, char *pass, char *realm, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return kadm5_init_with_password(client_name, pass, service_name, - realm, struct_version, api_version, + realm, struct_version, api_version, db_args, server_handle); } @@ -18,10 +19,11 @@ ovsec_kadm_ret_t ovsec_kadm_init_with_skey(char *client_name, char *keytab, char *realm, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return kadm5_init_with_skey(client_name, keytab, service_name, realm, - struct_version, api_version, + struct_version, api_version, db_args, server_handle); } @@ -30,10 +32,11 @@ ovsec_kadm_ret_t ovsec_kadm_init(char *client_name, char *from_stash, char *realm, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return kadm5_init(client_name, from_stash, service_name, - realm, struct_version, api_version, + realm, struct_version, api_version, db_args, server_handle); } diff --git a/src/lib/kadm5/server_internal.h b/src/lib/kadm5/server_internal.h index 7792d0a49..33d6593ac 100644 --- a/src/lib/kadm5/server_internal.h +++ b/src/lib/kadm5/server_internal.h @@ -21,7 +21,6 @@ #include #include #include "admin_internal.h" -#include "adb.h" typedef struct _kadm5_server_handle_t { krb5_ui_4 magic_number; @@ -31,9 +30,26 @@ typedef struct _kadm5_server_handle_t { krb5_principal current_caller; kadm5_config_params params; struct _kadm5_server_handle_t *lhandle; - osa_adb_policy_t policy_db; + char **db_args; } kadm5_server_handle_rec, *kadm5_server_handle_t; +#define OSA_ADB_PRINC_VERSION_1 0x12345C01 + +typedef struct _osa_pw_hist_t { + int n_key_data; + krb5_key_data *key_data; +} osa_pw_hist_ent, *osa_pw_hist_t; + typedef struct _osa_princ_ent_t { + int version; + char *policy; + long aux_attributes; + unsigned int old_key_len; + unsigned int old_key_next; + krb5_kvno admin_history_kvno; + osa_pw_hist_ent *old_keys; +} osa_princ_ent_rec, *osa_princ_ent_t; + + kadm5_ret_t adb_policy_init(kadm5_server_handle_t handle); kadm5_ret_t adb_policy_close(kadm5_server_handle_t handle); kadm5_ret_t passwd_check(kadm5_server_handle_t handle, @@ -55,6 +71,7 @@ krb5_error_code kdb_put_entry(kadm5_server_handle_t handle, krb5_error_code kdb_delete_entry(kadm5_server_handle_t handle, krb5_principal name); krb5_error_code kdb_iter_entry(kadm5_server_handle_t handle, + char *match_entry, void (*iter_fct)(void *, krb5_principal), void *data); @@ -115,4 +132,9 @@ extern krb5_principal current_caller; KADM5_NEW_SERVER_API_VERSION) \ SERVER_CHECK_HANDLE(handle) +bool_t xdr_osa_princ_ent_rec(XDR *xdrs, osa_princ_ent_t objp); + +void +osa_free_princ_ent(osa_princ_ent_t val); + #endif /* __KADM5_SERVER_INTERNAL_H__ */ diff --git a/src/lib/kadm5/srv/ChangeLog b/src/lib/kadm5/srv/ChangeLog index eeba8685c..c885bc65d 100644 --- a/src/lib/kadm5/srv/ChangeLog +++ b/src/lib/kadm5/srv/ChangeLog @@ -1,3 +1,18 @@ +2005-06-20 Ken Raeburn + + Novell merge. + * Makefile.in: + * adb_free.c: + * adb_openclose.c: + * adb_policy.c: + * adb_xdr.c: + * server_init.c: + * server_kdb.c: + * server_misc.c: + * svr_iters.c: + * svr_policy.c: + * svr_principal.c: + 2004-12-20 Tom Yu * svr_principal.c (add_to_history): Rewrite somewhat, using diff --git a/src/lib/kadm5/srv/Makefile.in b/src/lib/kadm5/srv/Makefile.in index 66de263ce..6a159ffcb 100644 --- a/src/lib/kadm5/srv/Makefile.in +++ b/src/lib/kadm5/srv/Makefile.in @@ -35,10 +35,7 @@ SRCS = $(srcdir)/svr_policy.c \ $(srcdir)/server_dict.c \ $(srcdir)/svr_iters.c \ $(srcdir)/svr_chpass_util.c \ - $(srcdir)/adb_xdr.c \ - $(srcdir)/adb_policy.c \ - $(srcdir)/adb_free.c \ - $(srcdir)/adb_openclose.c + $(srcdir)/adb_xdr.c OBJS = svr_policy.$(OBJEXT) \ svr_principal.$(OBJEXT) \ @@ -49,10 +46,7 @@ OBJS = svr_policy.$(OBJEXT) \ server_dict.$(OBJEXT) \ svr_iters.$(OBJEXT) \ svr_chpass_util.$(OBJEXT) \ - adb_xdr.$(OBJEXT) \ - adb_policy.$(OBJEXT) \ - adb_free.$(OBJEXT) \ - adb_openclose.$(OBJEXT) + adb_xdr.$(OBJEXT) STLIBOBJS = \ svr_policy.o \ @@ -64,10 +58,7 @@ STLIBOBJS = \ server_dict.o \ svr_iters.o \ svr_chpass_util.o \ - adb_xdr.o \ - adb_policy.o \ - adb_free.o \ - adb_openclose.o + adb_xdr.o all-unix:: includes all-unix:: all-liblinks @@ -115,10 +106,8 @@ svr_policy.so svr_policy.po $(OUTPRE)svr_policy.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(BUILDTOP)/include/kadm5/adb.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \ + $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin_internal.h svr_principal.so svr_principal.po $(OUTPRE)svr_principal.$(OBJEXT): \ svr_principal.c $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ @@ -133,10 +122,8 @@ svr_principal.so svr_principal.po $(OUTPRE)svr_principal.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(BUILDTOP)/include/kadm5/adb.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/kdb.h \ + $(BUILDTOP)/include/kadm5/server_internal.h $(BUILDTOP)/include/kadm5/admin_internal.h server_acl.so server_acl.po $(OUTPRE)server_acl.$(OBJEXT): \ server_acl.c $(SRCTOP)/include/syslog.h $(BUILDTOP)/include/gssapi/gssapi_generic.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(SRCTOP)/include/k5-int.h \ @@ -154,9 +141,8 @@ server_acl.so server_acl.po $(OUTPRE)server_acl.$(OBJEXT): \ $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/auth_gss.h \ $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \ $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/k5-int.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/admin_internal.h \ - $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS) $(SRCTOP)/include/krb5/adm_proto.h \ + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h $(SRCTOP)/include/krb5/adm_proto.h \ server_acl.h server_kdb.so server_kdb.po $(OUTPRE)server_kdb.$(OBJEXT): \ server_kdb.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ @@ -173,10 +159,8 @@ server_kdb.so server_kdb.po $(OUTPRE)server_kdb.$(OBJEXT): \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/svc_auth.h \ $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \ $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(BUILDTOP)/include/kadm5/server_internal.h $(SRCTOP)/include/krb5/kdb.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h \ - $(DB_DEPS) + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \ + $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin_internal.h server_misc.so server_misc.po $(OUTPRE)server_misc.$(OBJEXT): \ server_misc.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ @@ -184,18 +168,17 @@ server_misc.so server_misc.po $(OUTPRE)server_misc.$(OBJEXT): \ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/adb.h \ - $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ - $(SRCTOP)/include/k5-int.h $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h \ - $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/xdr.h \ + $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/server_internal.h \ + $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/kadm5/admin.h \ + $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \ + $(BUILDTOP)/include/gssrpc/rename.h $(BUILDTOP)/include/gssrpc/xdr.h \ $(BUILDTOP)/include/gssrpc/auth.h $(BUILDTOP)/include/gssrpc/clnt.h \ $(BUILDTOP)/include/gssrpc/rpc_msg.h $(BUILDTOP)/include/gssrpc/auth_unix.h \ $(BUILDTOP)/include/gssrpc/auth_gss.h $(BUILDTOP)/include/gssapi/gssapi.h \ $(BUILDTOP)/include/gssrpc/svc_auth.h $(BUILDTOP)/include/gssrpc/svc.h \ $(BUILDTOP)/include/krb5.h $(SRCTOP)/include/k5-int.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h server_init.so server_init.po $(OUTPRE)server_init.$(OBJEXT): \ server_init.c $(COM_ERR_DEPS) $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \ @@ -210,10 +193,9 @@ server_init.so server_init.po $(OUTPRE)server_init.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \ - $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin_internal.h \ - $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS) + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/server_internal.h $(SRCTOP)/include/krb5/kdb.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h server_dict.so server_dict.po $(OUTPRE)server_dict.$(OBJEXT): \ server_dict.c $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ @@ -228,11 +210,9 @@ server_dict.so server_dict.po $(OUTPRE)server_dict.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(SRCTOP)/include/krb5/adm_proto.h $(SRCTOP)/include/syslog.h \ - $(BUILDTOP)/include/kadm5/server_internal.h $(SRCTOP)/include/krb5/kdb.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h \ - $(DB_DEPS) + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(SRCTOP)/include/krb5/adm_proto.h \ + $(SRCTOP)/include/syslog.h $(BUILDTOP)/include/kadm5/server_internal.h \ + $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin_internal.h svr_iters.so svr_iters.po $(OUTPRE)svr_iters.$(OBJEXT): \ svr_iters.c $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ @@ -247,10 +227,8 @@ svr_iters.so svr_iters.po $(OUTPRE)svr_iters.$(OBJEXT): \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ - $(BUILDTOP)/include/kadm5/adb.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) $(BUILDTOP)/include/kadm5/server_internal.h \ - $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/adb.h + $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \ + $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin_internal.h svr_chpass_util.so svr_chpass_util.po $(OUTPRE)svr_chpass_util.$(OBJEXT): \ svr_chpass_util.c $(BUILDTOP)/include/kadm5/admin.h \ $(BUILDTOP)/include/gssrpc/rpc.h $(BUILDTOP)/include/gssrpc/types.h \ @@ -265,10 +243,9 @@ svr_chpass_util.so svr_chpass_util.po $(OUTPRE)svr_chpass_util.$(OBJEXT): \ $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/server_internal.h \ - $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/kadm5/admin_internal.h \ - $(BUILDTOP)/include/kadm5/adb.h $(DB_DEPS) + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/server_internal.h $(SRCTOP)/include/krb5/kdb.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h adb_xdr.so adb_xdr.po $(OUTPRE)adb_xdr.$(OBJEXT): adb_xdr.c \ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/gssrpc/rpc.h \ $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ @@ -276,65 +253,14 @@ adb_xdr.so adb_xdr.po $(OUTPRE)adb_xdr.$(OBJEXT): adb_xdr.c \ $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \ $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/auth_gss.h \ $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/svc_auth.h \ - $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/adb.h \ + $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/kadm5/server_internal.h \ $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(SRCTOP)/include/k5-int.h \ - $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/adb_err.h \ - $(BUILDTOP)/include/kadm5/chpass_util_strings.h $(BUILDTOP)/include/kadm5/admin_xdr.h \ - $(BUILDTOP)/include/kadm5/kadm_rpc.h -adb_policy.so adb_policy.po $(OUTPRE)adb_policy.$(OBJEXT): \ - adb_policy.c $(BUILDTOP)/include/kadm5/adb.h $(BUILDTOP)/include/gssrpc/types.h \ - $(BUILDTOP)/include/gssrpc/rename.h $(SRCTOP)/include/k5-int.h \ - $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \ - $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ - $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ - $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \ - $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \ - $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/auth_gss.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/svc_auth.h \ - $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \ - $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h -adb_free.so adb_free.po $(OUTPRE)adb_free.$(OBJEXT): \ - adb_free.c $(BUILDTOP)/include/kadm5/adb.h $(BUILDTOP)/include/gssrpc/types.h \ - $(BUILDTOP)/include/gssrpc/rename.h $(SRCTOP)/include/k5-int.h \ - $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \ - $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ - $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ - $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \ - $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \ - $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/auth_gss.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/svc_auth.h \ - $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \ - $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h -adb_openclose.so adb_openclose.po $(OUTPRE)adb_openclose.$(OBJEXT): \ - adb_openclose.c $(BUILDTOP)/include/kadm5/adb.h $(BUILDTOP)/include/gssrpc/types.h \ - $(BUILDTOP)/include/gssrpc/rename.h $(SRCTOP)/include/k5-int.h \ - $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \ - $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ - $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) $(BUILDTOP)/include/kadm5/admin.h $(BUILDTOP)/include/gssrpc/rpc.h \ - $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \ - $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \ - $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/auth_gss.h \ - $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/svc_auth.h \ - $(BUILDTOP)/include/gssrpc/svc.h $(BUILDTOP)/include/krb5.h \ - $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/kadm5/kadm_err.h \ - $(BUILDTOP)/include/kadm5/adb_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h + $(BUILDTOP)/include/kadm5/admin.h $(SRCTOP)/include/k5-int.h \ + $(BUILDTOP)/include/kadm5/kadm_err.h $(BUILDTOP)/include/kadm5/chpass_util_strings.h \ + $(BUILDTOP)/include/kadm5/admin_internal.h $(BUILDTOP)/include/kadm5/admin_xdr.h \ + $(BUILDTOP)/include/kadm5/kadm_rpc.h $(BUILDTOP)/include/kadm5/server_internal.h diff --git a/src/lib/kadm5/srv/adb_free.c b/src/lib/kadm5/srv/adb_free.c deleted file mode 100644 index cfc107d06..000000000 --- a/src/lib/kadm5/srv/adb_free.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved - * - * $Header$ - * - * $Log$ - * Revision 1.3 2000/06/01 02:02:03 tritan - * Check for existance of . - * (from Nathan Neulinger ) - * - * Revision 1.2 1996/10/18 19:45:49 bjaspan - * * svr_misc_free.c, server_dict.c, adb_policy.c, adb_free.c: - * include stdlib.h instead of malloc.h [krb5-admin/35] - * - * Revision 1.1 1996/07/24 22:23:09 tlyu - * * Makefile.in, configure.in: break out server lib into a - * subdirectory - * - * Revision 1.8 1996/07/22 20:35:16 marc - * this commit includes all the changes on the OV_9510_INTEGRATION and - * OV_MERGE branches. This includes, but is not limited to, the new openvision - * admin system, and major changes to gssapi to add functionality, and bring - * the implementation in line with rfc1964. before committing, the - * code was built and tested for netbsd and solaris. - * - * Revision 1.7.4.1 1996/07/18 03:08:07 marc - * merged in changes from OV_9510_BP to OV_9510_FINAL1 - * - * Revision 1.7.2.1 1996/06/20 02:16:25 marc - * File added to the repository on a branch - * - * Revision 1.7 1996/05/12 06:21:57 marc - * don't use for "internal header files" - * - * Revision 1.6 1993/12/13 21:15:56 shanzer - * fixed memory leak - * ., - * - * Revision 1.5 1993/12/06 22:20:37 marc - * fixup free functions to use xdr to free the underlying struct - * - * Revision 1.4 1993/11/15 00:29:46 shanzer - * check to make sure pointers are somewhat vaid before freeing. - * - * Revision 1.3 1993/11/09 04:02:24 shanzer - * added some includefiles - * changed bzero to memset - * - * Revision 1.2 1993/11/04 01:54:24 shanzer - * added rcs header .. - * - */ - -#if !defined(lint) && !defined(__CODECENTER__) -static char *rcsid = "$Header$"; -#endif - -#include "adb.h" -#ifdef HAVE_MEMORY_H -#include -#endif -#include - -void -osa_free_princ_ent(osa_princ_ent_t val) -{ - XDR xdrs; - - xdrmem_create(&xdrs, NULL, 0, XDR_FREE); - - xdr_osa_princ_ent_rec(&xdrs, val); - free(val); -} - -void -osa_free_policy_ent(osa_policy_ent_t val) -{ - XDR xdrs; - - xdrmem_create(&xdrs, NULL, 0, XDR_FREE); - - xdr_osa_policy_ent_rec(&xdrs, val); - free(val); -} - diff --git a/src/lib/kadm5/srv/adb_openclose.c b/src/lib/kadm5/srv/adb_openclose.c deleted file mode 100644 index 7bb671e9c..000000000 --- a/src/lib/kadm5/srv/adb_openclose.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved - * - * $Header$ - */ - -#if !defined(lint) && !defined(__CODECENTER__) -static char *rcsid = "$Header$"; -#endif - -#include -#include -#include -#include "adb.h" -#include - -#define MAX_LOCK_TRIES 5 - -struct _locklist { - osa_adb_lock_ent lockinfo; - struct _locklist *next; -}; - -osa_adb_ret_t osa_adb_create_db(char *filename, char *lockfilename, - int magic) -{ - int lf; - DB *db; - BTREEINFO btinfo; - - memset(&btinfo, 0, sizeof(btinfo)); - btinfo.flags = 0; - btinfo.cachesize = 0; - btinfo.psize = 4096; - btinfo.lorder = 0; - btinfo.minkeypage = 0; - btinfo.compare = NULL; - btinfo.prefix = NULL; - db = dbopen(filename, O_RDWR | O_CREAT | O_EXCL, 0600, DB_BTREE, &btinfo); - if (db == NULL) - return errno; - if (db->close(db) < 0) - return errno; - - /* only create the lock file if we successfully created the db */ - lf = THREEPARAMOPEN(lockfilename, O_RDWR | O_CREAT | O_EXCL, 0600); - if (lf == -1) - return errno; - (void) close(lf); - - return OSA_ADB_OK; -} - -osa_adb_ret_t osa_adb_destroy_db(char *filename, char *lockfilename, - int magic) -{ - /* the admin databases do not contain security-critical data */ - if (unlink(filename) < 0 || - unlink(lockfilename) < 0) - return errno; - return OSA_ADB_OK; -} - -osa_adb_ret_t osa_adb_rename_db(char *filefrom, char *lockfrom, - char *fileto, char *lockto, int magic) -{ - osa_adb_db_t fromdb, todb; - osa_adb_ret_t ret; - - /* make sure todb exists */ - if ((ret = osa_adb_create_db(fileto, lockto, magic)) && - ret != EEXIST) - return ret; - - if ((ret = osa_adb_init_db(&fromdb, filefrom, lockfrom, magic))) - return ret; - if ((ret = osa_adb_init_db(&todb, fileto, lockto, magic))) { - (void) osa_adb_fini_db(fromdb, magic); - return ret; - } - if ((ret = osa_adb_get_lock(fromdb, OSA_ADB_PERMANENT))) { - (void) osa_adb_fini_db(fromdb, magic); - (void) osa_adb_fini_db(todb, magic); - return ret; - } - if ((ret = osa_adb_get_lock(todb, OSA_ADB_PERMANENT))) { - (void) osa_adb_fini_db(fromdb, magic); - (void) osa_adb_fini_db(todb, magic); - return ret; - } - if ((rename(filefrom, fileto) < 0)) { - (void) osa_adb_fini_db(fromdb, magic); - (void) osa_adb_fini_db(todb, magic); - return errno; - } - /* - * Do not release the lock on fromdb because it is being renamed - * out of existence; no one can ever use it again. - */ - if ((ret = osa_adb_release_lock(todb))) { - (void) osa_adb_fini_db(fromdb, magic); - (void) osa_adb_fini_db(todb, magic); - return ret; - } - - (void) osa_adb_fini_db(fromdb, magic); - (void) osa_adb_fini_db(todb, magic); - return 0; -} - -osa_adb_ret_t osa_adb_init_db(osa_adb_db_t *dbp, char *filename, - char *lockfilename, int magic) -{ - osa_adb_db_t db; - static struct _locklist *locklist = NULL; - struct _locklist *lockp; - krb5_error_code code; - - if (dbp == NULL || filename == NULL) - return EINVAL; - - db = (osa_adb_princ_t) malloc(sizeof(osa_adb_db_ent)); - if (db == NULL) - return ENOMEM; - - memset(db, 0, sizeof(*db)); - db->info.hash = NULL; - db->info.bsize = 256; - db->info.ffactor = 8; - db->info.nelem = 25000; - db->info.lorder = 0; - - db->btinfo.flags = 0; - db->btinfo.cachesize = 0; - db->btinfo.psize = 4096; - db->btinfo.lorder = 0; - db->btinfo.minkeypage = 0; - db->btinfo.compare = NULL; - db->btinfo.prefix = NULL; - /* - * A process is allowed to open the same database multiple times - * and access it via different handles. If the handles use - * distinct lockinfo structures, things get confused: lock(A), - * lock(B), release(B) will result in the kernel unlocking the - * lock file but handle A will still think the file is locked. - * Therefore, all handles using the same lock file must share a - * single lockinfo structure. - * - * It is not sufficient to have a single lockinfo structure, - * however, because a single process may also wish to open - * multiple different databases simultaneously, with different - * lock files. This code used to use a single static lockinfo - * structure, which means that the second database opened used - * the first database's lock file. This was Bad. - * - * We now maintain a linked list of lockinfo structures, keyed by - * lockfilename. An entry is added when this function is called - * with a new lockfilename, and all subsequent calls with that - * lockfilename use the existing entry, updating the refcnt. - * When the database is closed with fini_db(), the refcnt is - * decremented, and when it is zero the lockinfo structure is - * freed and reset. The entry in the linked list, however, is - * never removed; it will just be reinitialized the next time - * init_db is called with the right lockfilename. - */ - - /* find or create the lockinfo structure for lockfilename */ - lockp = locklist; - while (lockp) { - if (strcmp(lockp->lockinfo.filename, lockfilename) == 0) - break; - else - lockp = lockp->next; - } - if (lockp == NULL) { - /* doesn't exist, create it, add to list */ - lockp = (struct _locklist *) malloc(sizeof(*lockp)); - if (lockp == NULL) { - free(db); - return ENOMEM; - } - memset(lockp, 0, sizeof(*lockp)); - lockp->next = locklist; - locklist = lockp; - } - - /* now initialize lockp->lockinfo if necessary */ - if (lockp->lockinfo.lockfile == NULL) { - if ((code = krb5_init_context(&lockp->lockinfo.context))) { - free(db); - return((osa_adb_ret_t) code); - } - - /* - * needs be open read/write so that write locking can work with - * POSIX systems - */ - lockp->lockinfo.filename = strdup(lockfilename); - if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { - /* - * maybe someone took away write permission so we could only - * get shared locks? - */ - if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r")) - == NULL) { - free(db); - return OSA_ADB_NOLOCKFILE; - } - } - lockp->lockinfo.lockmode = lockp->lockinfo.lockcnt = 0; - } - - /* lockp is set, lockinfo is initialized, update the reference count */ - db->lock = &lockp->lockinfo; - db->lock->refcnt++; - - db->opencnt = 0; - db->filename = strdup(filename); - db->magic = magic; - - *dbp = db; - - return OSA_ADB_OK; -} - -osa_adb_ret_t osa_adb_fini_db(osa_adb_db_t db, int magic) -{ - if (db->magic != magic) - return EINVAL; - if (db->lock->refcnt == 0) { - /* barry says this can't happen */ - return OSA_ADB_FAILURE; - } else { - db->lock->refcnt--; - } - - if (db->lock->refcnt == 0) { - /* - * Don't free db->lock->filename, it is used as a key to - * find the lockinfo entry in the linked list. If the - * lockfile doesn't exist, we must be closing the database - * after trashing it. This has to be allowed, so don't - * generate an error. - */ - if (db->lock->lockmode != OSA_ADB_PERMANENT) - (void) fclose(db->lock->lockfile); - db->lock->lockfile = NULL; - krb5_free_context(db->lock->context); - } - - db->magic = 0; - free(db->filename); - free(db); - return OSA_ADB_OK; -} - -osa_adb_ret_t osa_adb_get_lock(osa_adb_db_t db, int mode) -{ - int tries, gotlock, perm, krb5_mode, ret; - - if (db->lock->lockmode >= mode) { - /* No need to upgrade lock, just incr refcnt and return */ - db->lock->lockcnt++; - return(OSA_ADB_OK); - } - - perm = 0; - switch (mode) { - case OSA_ADB_PERMANENT: - perm = 1; - case OSA_ADB_EXCLUSIVE: - krb5_mode = KRB5_LOCKMODE_EXCLUSIVE; - break; - case OSA_ADB_SHARED: - krb5_mode = KRB5_LOCKMODE_SHARED; - break; - default: - return(EINVAL); - } - - for (gotlock = tries = 0; tries < MAX_LOCK_TRIES; tries++) { - if ((ret = krb5_lock_file(db->lock->context, - fileno(db->lock->lockfile), - krb5_mode|KRB5_LOCKMODE_DONTBLOCK)) == 0) { - gotlock++; - break; - } else if (ret == EBADF && mode == OSA_ADB_EXCLUSIVE) - /* tried to exclusive-lock something we don't have */ - /* write access to */ - return OSA_ADB_NOEXCL_PERM; - - sleep(1); - } - - /* test for all the likely "can't get lock" error codes */ - if (ret == EACCES || ret == EAGAIN || ret == EWOULDBLOCK) - return OSA_ADB_CANTLOCK_DB; - else if (ret != 0) - return ret; - - /* - * If the file no longer exists, someone acquired a permanent - * lock. If that process terminates its exclusive lock is lost, - * but if we already had the file open we can (probably) lock it - * even though it has been unlinked. So we need to insist that - * it exist. - */ - if (access(db->lock->filename, F_OK) < 0) { - (void) krb5_lock_file(db->lock->context, - fileno(db->lock->lockfile), - KRB5_LOCKMODE_UNLOCK); - return OSA_ADB_NOLOCKFILE; - } - - /* we have the shared/exclusive lock */ - - if (perm) { - if (unlink(db->lock->filename) < 0) { - /* somehow we can't delete the file, but we already */ - /* have the lock, so release it and return */ - - ret = errno; - (void) krb5_lock_file(db->lock->context, - fileno(db->lock->lockfile), - KRB5_LOCKMODE_UNLOCK); - - /* maybe we should return CANTLOCK_DB.. but that would */ - /* look just like the db was already locked */ - return ret; - } - - /* this releases our exclusive lock.. which is okay because */ - /* now no one else can get one either */ - (void) fclose(db->lock->lockfile); - } - - db->lock->lockmode = mode; - db->lock->lockcnt++; - return OSA_ADB_OK; -} - -osa_adb_ret_t osa_adb_release_lock(osa_adb_db_t db) -{ - int ret, fd; - - if (!db->lock->lockcnt) /* lock already unlocked */ - return OSA_ADB_NOTLOCKED; - - if (--db->lock->lockcnt == 0) { - if (db->lock->lockmode == OSA_ADB_PERMANENT) { - /* now we need to create the file since it does not exist */ - fd = THREEPARAMOPEN(db->lock->filename,O_RDWR | O_CREAT | O_EXCL, - 0600); - if ((db->lock->lockfile = fdopen(fd, "w+")) == NULL) - return OSA_ADB_NOLOCKFILE; - } else if ((ret = krb5_lock_file(db->lock->context, - fileno(db->lock->lockfile), - KRB5_LOCKMODE_UNLOCK))) - return ret; - - db->lock->lockmode = 0; - } - return OSA_ADB_OK; -} - -osa_adb_ret_t osa_adb_open_and_lock(osa_adb_princ_t db, int locktype) -{ - int ret; - - ret = osa_adb_get_lock(db, locktype); - if (ret != OSA_ADB_OK) - return ret; - if (db->opencnt) - goto open_ok; - - db->db = dbopen(db->filename, O_RDWR, 0600, DB_BTREE, &db->btinfo); - if (db->db != NULL) - goto open_ok; - switch (errno) { -#ifdef EFTYPE - case EFTYPE: -#endif - case EINVAL: - db->db = dbopen(db->filename, O_RDWR, 0600, DB_HASH, &db->info); - if (db->db != NULL) - goto open_ok; - default: - (void) osa_adb_release_lock(db); - if (errno == EINVAL) - return OSA_ADB_BAD_DB; - return errno; - } -open_ok: - db->opencnt++; - return OSA_ADB_OK; -} - -osa_adb_ret_t osa_adb_close_and_unlock(osa_adb_princ_t db) -{ - if (--db->opencnt) - return osa_adb_release_lock(db); - if(db->db != NULL && db->db->close(db->db) == -1) { - (void) osa_adb_release_lock(db); - return OSA_ADB_FAILURE; - } - - db->db = NULL; - - return(osa_adb_release_lock(db)); -} diff --git a/src/lib/kadm5/srv/adb_policy.c b/src/lib/kadm5/srv/adb_policy.c deleted file mode 100644 index f081551d7..000000000 --- a/src/lib/kadm5/srv/adb_policy.c +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved - * - * $Header$ - */ - -#if !defined(lint) && !defined(__CODECENTER__) -static char *rcsid = "$Header$"; -#endif - -#include -#include -#include "adb.h" -#include -#include -#include - - -#define OPENLOCK(db, mode) \ -{ \ - int olret; \ - if (db == NULL) \ - return EINVAL; \ - else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \ - return OSA_ADB_DBINIT; \ - else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \ - return olret; \ - } - -#define CLOSELOCK(db) \ -{ \ - int cl_ret; \ - if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \ - return cl_ret; \ -} - -osa_adb_ret_t osa_adb_create_policy_db(kadm5_config_params *params) -{ - return osa_adb_create_db(params->admin_dbname, - params->admin_lockfile, - OSA_ADB_POLICY_DB_MAGIC); -} - -osa_adb_ret_t osa_adb_rename_policy_db(kadm5_config_params *fromparams, - kadm5_config_params *toparams) -{ - return osa_adb_rename_db(fromparams->admin_dbname, - fromparams->admin_lockfile, - toparams->admin_dbname, - toparams->admin_lockfile, - OSA_ADB_POLICY_DB_MAGIC); -} - -osa_adb_ret_t osa_adb_destroy_policy_db(kadm5_config_params *params) -{ - return osa_adb_destroy_db(params->admin_dbname, - params->admin_lockfile, - OSA_ADB_POLICY_DB_MAGIC); -} - -osa_adb_ret_t osa_adb_open_policy(osa_adb_princ_t *dbp, - kadm5_config_params *rparams) -{ - return osa_adb_init_db(dbp, rparams->admin_dbname, - rparams->admin_lockfile, - OSA_ADB_POLICY_DB_MAGIC); -} - -osa_adb_ret_t osa_adb_close_policy(osa_adb_princ_t db) -{ - return osa_adb_fini_db(db, OSA_ADB_POLICY_DB_MAGIC); -} - -/* - * Function: osa_adb_create_policy - * - * Purpose: create a policy entry in the policy db. - * - * Arguments: - * entry (input) pointer to the entry to be added - * OSA_ADB_OK on success, else error code. - * - * Requires: - * entry have a valid name. - * - * Effects: - * creates the entry in the db - * - * Modifies: - * the policy db. - * - */ -osa_adb_ret_t -osa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry) -{ - DBT dbkey; - DBT dbdata; - XDR xdrs; - int ret; - - OPENLOCK(db, OSA_ADB_EXCLUSIVE); - - if(entry->name == NULL) { - ret = EINVAL; - goto error; - } - dbkey.data = entry->name; - dbkey.size = (strlen(entry->name) + 1); - - switch(db->db->get(db->db, &dbkey, &dbdata, 0)) { - case 0: - ret = OSA_ADB_DUP; - goto error; - case 1: - break; - default: - ret = errno; - goto error; - } - xdralloc_create(&xdrs, XDR_ENCODE); - if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { - xdr_destroy(&xdrs); - ret = OSA_ADB_XDR_FAILURE; - goto error; - } - dbdata.data = xdralloc_getdata(&xdrs); - dbdata.size = xdr_getpos(&xdrs); - switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) { - case 0: - if((db->db->sync(db->db, 0)) == -1) - ret = OSA_ADB_FAILURE; - ret = OSA_ADB_OK; - break; - case 1: - ret = OSA_ADB_DUP; - break; - default: - ret = OSA_ADB_FAILURE; - break; - } - xdr_destroy(&xdrs); - -error: - CLOSELOCK(db); - return ret; -} - -/* - * Function: osa_adb_destroy_policy - * - * Purpose: destroy a policy entry - * - * Arguments: - * db (input) database handle - * name (input) name of policy - * OSA_ADB_OK on success, or error code. - * - * Requires: - * db being valid. - * name being non-null. - * Effects: - * deletes policy from db. - * - * Modifies: - * policy db. - * - */ -osa_adb_ret_t -osa_adb_destroy_policy(osa_adb_policy_t db, kadm5_policy_t name) -{ - DBT dbkey; - int status, ret; - - OPENLOCK(db, OSA_ADB_EXCLUSIVE); - - if(name == NULL) { - ret = EINVAL; - goto error; - } - dbkey.data = name; - dbkey.size = (strlen(name) + 1); - - status = db->db->del(db->db, &dbkey, 0); - switch(status) { - case 1: - ret = OSA_ADB_NOENT; - goto error; - case 0: - if ((db->db->sync(db->db, 0)) == -1) { - ret = OSA_ADB_FAILURE; - goto error; - } - ret = OSA_ADB_OK; - break; - default: - ret = OSA_ADB_FAILURE; - goto error; - } - -error: - CLOSELOCK(db); - return ret; -} - -/* - * Function: osa_adb_get_policy - * - * Purpose: retrieve policy - * - * Arguments: - * db (input) db handle - * name (input) name of policy - * entry (output) policy entry - * 0 on success, error code on failure. - * - * Requires: - * Effects: - * Modifies: - */ -osa_adb_ret_t -osa_adb_get_policy(osa_adb_policy_t db, kadm5_policy_t name, - osa_policy_ent_t *entry) -{ - DBT dbkey; - DBT dbdata; - XDR xdrs; - int ret; - char *aligned_data; - - OPENLOCK(db, OSA_ADB_SHARED); - - if(name == NULL) { - ret = EINVAL; - goto error; - } - dbkey.data = name; - dbkey.size = (strlen(dbkey.data) + 1); - dbdata.data = NULL; - dbdata.size = 0; - switch((db->db->get(db->db, &dbkey, &dbdata, 0))) { - case 1: - ret = OSA_ADB_NOENT; - goto error; - case 0: - break; - default: - ret = OSA_ADB_FAILURE; - goto error; - } - if (!(*(entry) = (osa_policy_ent_t)malloc(sizeof(osa_policy_ent_rec)))) { - ret = ENOMEM; - goto error; - } - if (!(aligned_data = (char *) malloc(dbdata.size))) { - ret = ENOMEM; - goto error; - } - memcpy(aligned_data, dbdata.data, dbdata.size); - memset(*entry, 0, sizeof(osa_policy_ent_rec)); - xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE); - if (!xdr_osa_policy_ent_rec(&xdrs, *entry)) - ret = OSA_ADB_FAILURE; - else ret = OSA_ADB_OK; - xdr_destroy(&xdrs); - free(aligned_data); - -error: - CLOSELOCK(db); - return ret; -} - -/* - * Function: osa_adb_put_policy - * - * Purpose: update a policy in the dababase - * - * Arguments: - * db (input) db handle - * entry (input) policy entry - * 0 on success error code on failure. - * - * Requires: - * [requires] - * - * Effects: - * [effects] - * - * Modifies: - * [modifies] - * - */ -osa_adb_ret_t -osa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry) -{ - DBT dbkey; - DBT dbdata; - DBT tmpdb; - XDR xdrs; - int ret; - - OPENLOCK(db, OSA_ADB_EXCLUSIVE); - - if(entry->name == NULL) { - ret = EINVAL; - goto error; - } - dbkey.data = entry->name; - dbkey.size = (strlen(entry->name) + 1); - switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) { - case 0: - break; - case 1: - ret = OSA_ADB_NOENT; - goto error; - default: - ret = OSA_ADB_FAILURE; - goto error; - } - xdralloc_create(&xdrs, XDR_ENCODE); - if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { - xdr_destroy(&xdrs); - ret = OSA_ADB_XDR_FAILURE; - goto error; - } - dbdata.data = xdralloc_getdata(&xdrs); - dbdata.size = xdr_getpos(&xdrs); - switch(db->db->put(db->db, &dbkey, &dbdata, 0)) { - case 0: - if((db->db->sync(db->db, 0)) == -1) - ret = OSA_ADB_FAILURE; - ret = OSA_ADB_OK; - break; - default: - ret = OSA_ADB_FAILURE; - break; - } - xdr_destroy(&xdrs); - -error: - CLOSELOCK(db); - return ret; -} - -/* - * Function: osa_adb_iter_policy - * - * Purpose: iterate over the policy database. - * - * Arguments: - * db (input) db handle - * func (input) fucntion pointer to call - * data opaque data type - * 0 on success error code on failure - * - * Requires: - * Effects: - * Modifies: - */ -osa_adb_ret_t -osa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func, - void *data) -{ - DBT dbkey, - dbdata; - XDR xdrs; - int ret; - osa_policy_ent_t entry; - char *aligned_data; - - OPENLOCK(db, OSA_ADB_EXCLUSIVE); /* hmmm */ - - if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) { - ret = errno; - goto error; - } - - while (ret == 0) { - if (!(entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec)))) { - ret = ENOMEM; - goto error; - } - - if(!(aligned_data = (char *) malloc(dbdata.size))) { - ret = ENOMEM; - goto error; - } - memcpy(aligned_data, dbdata.data, dbdata.size); - - memset(entry, 0, sizeof(osa_policy_ent_rec)); - xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE); - if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { - xdr_destroy(&xdrs); - free(aligned_data); - ret = OSA_ADB_FAILURE; - goto error; - } - (*func)(data, entry); - xdr_destroy(&xdrs); - free(aligned_data); - osa_free_policy_ent(entry); - ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT); - } - if(ret == -1) - ret = errno; - else ret = OSA_ADB_OK; - -error: - CLOSELOCK(db); - return ret; -} diff --git a/src/lib/kadm5/srv/adb_xdr.c b/src/lib/kadm5/srv/adb_xdr.c index 757cf92e5..d5d17062a 100644 --- a/src/lib/kadm5/srv/adb_xdr.c +++ b/src/lib/kadm5/srv/adb_xdr.c @@ -11,7 +11,7 @@ static char *rcsid = "$Header$"; #include #include #include -#include "adb.h" +#include "server_internal.h" #include "admin_xdr.h" #ifdef HAVE_MEMORY_H #include @@ -97,38 +97,14 @@ xdr_osa_princ_ent_rec(XDR *xdrs, osa_princ_ent_t objp) return (TRUE); } -bool_t -xdr_osa_policy_ent_rec(XDR *xdrs, osa_policy_ent_t objp) +void +osa_free_princ_ent(osa_princ_ent_t val) { - switch (xdrs->x_op) { - case XDR_ENCODE: - objp->version = OSA_ADB_POLICY_VERSION_1; - /* fall through */ - case XDR_FREE: - if (!xdr_int(xdrs, &objp->version)) - return FALSE; - break; - case XDR_DECODE: - if (!xdr_int(xdrs, &objp->version)) - return FALSE; - if (objp->version != OSA_ADB_POLICY_VERSION_1) - return FALSE; - break; - } - - if(!xdr_nullstring(xdrs, &objp->name)) - return (FALSE); - if (!xdr_u_int32(xdrs, &objp->pw_min_life)) - return (FALSE); - if (!xdr_u_int32(xdrs, &objp->pw_max_life)) - return (FALSE); - if (!xdr_u_int32(xdrs, &objp->pw_min_length)) - return (FALSE); - if (!xdr_u_int32(xdrs, &objp->pw_min_classes)) - return (FALSE); - if (!xdr_u_int32(xdrs, &objp->pw_history_num)) - return (FALSE); - if (!xdr_u_int32(xdrs, &objp->policy_refcnt)) - return (FALSE); - return (TRUE); + XDR xdrs; + + xdrmem_create(&xdrs, NULL, 0, XDR_FREE); + + xdr_osa_princ_ent_rec(&xdrs, val); + free(val); } + diff --git a/src/lib/kadm5/srv/server_init.c b/src/lib/kadm5/srv/server_init.c index dc3526a72..a5369298a 100644 --- a/src/lib/kadm5/srv/server_init.c +++ b/src/lib/kadm5/srv/server_init.c @@ -33,15 +33,70 @@ static int check_handle(void *handle) return 0; } +static int dup_db_args( kadm5_server_handle_t handle, char **db_args ) +{ + int count = 0; + int ret = 0; + + for( count=0; db_args && db_args[count]; count++ ); + if( count == 0 ) + { + handle->db_args = NULL; + goto clean_n_exit; + } + + handle->db_args = calloc(sizeof(char*), count+1); + if( handle->db_args == NULL ) + { + ret=ENOMEM; + goto clean_n_exit; + } + + for(count=0; db_args[count]; count++) + { + handle->db_args[count] = strdup(db_args[count]); + if( handle->db_args[count] == NULL ) + { + ret = ENOMEM; + goto clean_n_exit; + } + } + + clean_n_exit: + if( ret && handle->db_args ) + { + for(count=0; handle->db_args[count]; count++ ) + free( handle->db_args[count] ); + + free(handle->db_args), handle->db_args = NULL; + } + + return ret; +} + +static void free_db_args(kadm5_server_handle_t handle) +{ + int count; + + if( handle->db_args ) + { + for(count=0; handle->db_args[count]; count++ ) + free( handle->db_args[count] ); + + free(handle->db_args), handle->db_args = NULL; + } +} + kadm5_ret_t kadm5_init_with_password(char *client_name, char *pass, char *service_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { return kadm5_init(client_name, pass, service_name, params, - struct_version, api_version, + struct_version, api_version, db_args, server_handle); } @@ -51,6 +106,7 @@ kadm5_ret_t kadm5_init_with_creds(char *client_name, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { /* @@ -64,7 +120,7 @@ kadm5_ret_t kadm5_init_with_creds(char *client_name, params->mkey_from_kbd) return KADM5_BAD_SERVER_PARAMS; return kadm5_init(client_name, NULL, service_name, params, - struct_version, api_version, + struct_version, api_version, db_args, server_handle); } @@ -74,6 +130,7 @@ kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, kadm5_config_params *params, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { /* @@ -87,7 +144,7 @@ kadm5_ret_t kadm5_init_with_skey(char *client_name, char *keytab, params->mkey_from_kbd) return KADM5_BAD_SERVER_PARAMS; return kadm5_init(client_name, NULL, service_name, params, - struct_version, api_version, + struct_version, api_version, db_args, server_handle); } @@ -96,6 +153,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, kadm5_config_params *params_in, krb5_ui_4 struct_version, krb5_ui_4 api_version, + char **db_args, void **server_handle) { int ret; @@ -112,14 +170,22 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, return ENOMEM; memset(handle, 0, sizeof(*handle)); + ret = dup_db_args( handle, db_args ); + if( ret ) + { + free(handle); + return ret; + } + ret = (int) krb5_init_context(&(handle->context)); if (ret) { + free_db_args(handle); free(handle); return(ret); } initialize_ovk_error_table(); - initialize_adb_error_table(); +/* initialize_adb_error_table(); */ initialize_ovku_error_table(); handle->magic_number = KADM5_SERVER_HANDLE_MAGIC; @@ -153,6 +219,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, #define ILLEGAL_PARAMS (KADM5_CONFIG_ADMIN_SERVER) if (params_in && (params_in->mask & ILLEGAL_PARAMS)) { krb5_free_context(handle->context); + free_db_args(handle); free(handle); return KADM5_BAD_SERVER_PARAMS; } @@ -162,6 +229,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, &handle->params); if (ret) { krb5_free_context(handle->context); + free_db_args(handle); free(handle); return(ret); } @@ -176,24 +244,24 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, if ((handle->params.mask & REQUIRED_PARAMS) != REQUIRED_PARAMS) { krb5_free_context(handle->context); + free_db_args(handle); free(handle); return KADM5_MISSING_CONF_PARAMS; } - /* - * Set the db_name based on configuration before calling - * krb5_db_init, so it will get used. - */ - - ret = krb5_db_set_name(handle->context, handle->params.dbname); - if (ret) { - free(handle); - return(ret); - } + ret = krb5_set_default_realm(handle->context, handle->params.realm); + if( ret ) + { + krb5_free_context(handle->context); + free_db_args(handle); + free(handle); + return ret; + } - ret = krb5_db_init(handle->context); + ret = krb5_db_open(handle->context, db_args, KRB5_KDB_OPEN_RW); if (ret) { krb5_free_context(handle->context); + free_db_args(handle); free(handle); return(ret); } @@ -202,6 +270,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, &handle->current_caller))) { krb5_db_fini(handle->context); krb5_free_context(handle->context); + free_db_args(handle); free(handle); return ret; } @@ -209,6 +278,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, if (! (handle->lhandle = malloc(sizeof(*handle)))) { krb5_db_fini(handle->context); krb5_free_context(handle->context); + free_db_args(handle); free(handle); return ENOMEM; } @@ -220,6 +290,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, /* can't check the handle until current_caller is set */ ret = check_handle((void *) handle); if (ret) { + free_db_args(handle); free(handle); return ret; } @@ -250,6 +321,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, if (ret) { krb5_db_fini(handle->context); krb5_free_context(handle->context); + free_db_args(handle); free(handle); return ret; } @@ -258,6 +330,7 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, if (ret) { krb5_db_fini(handle->context); krb5_free_context(handle->context); + free_db_args(handle); free(handle); return ret; } @@ -267,20 +340,11 @@ kadm5_ret_t kadm5_init(char *client_name, char *pass, krb5_db_fini(handle->context); krb5_free_principal(handle->context, handle->current_caller); krb5_free_context(handle->context); + free_db_args(handle); free(handle); return ret; } - ret = adb_policy_init(handle); - if (ret) { - krb5_db_fini(handle->context); - krb5_free_principal(handle->context, handle->current_caller); - krb5_free_context(handle->context); - free(handle); - return ret; - } - handle->lhandle->policy_db = handle->policy_db; - *server_handle = (void *) handle; return KADM5_OK; @@ -301,6 +365,7 @@ kadm5_ret_t kadm5_destroy(void *server_handle) krb5_free_context(handle->context); handle->magic_number = 0; free(handle->lhandle); + free_db_args(handle); free(handle); return KADM5_OK; @@ -312,10 +377,7 @@ kadm5_ret_t kadm5_lock(void *server_handle) kadm5_ret_t ret; CHECK_HANDLE(server_handle); - ret = osa_adb_open_and_lock(handle->policy_db, OSA_ADB_EXCLUSIVE); - if (ret) - return ret; - ret = krb5_db_lock(handle->context, KRB5_LOCKMODE_EXCLUSIVE); + ret = krb5_db_lock(handle->context, KRB5_DB_LOCKMODE_EXCLUSIVE); if (ret) return ret; @@ -328,9 +390,6 @@ kadm5_ret_t kadm5_unlock(void *server_handle) kadm5_ret_t ret; CHECK_HANDLE(server_handle); - ret = osa_adb_close_and_unlock(handle->policy_db); - if (ret) - return ret; ret = krb5_db_unlock(handle->context); if (ret) return ret; @@ -346,13 +405,7 @@ kadm5_ret_t kadm5_flush(void *server_handle) CHECK_HANDLE(server_handle); if ((ret = krb5_db_fini(handle->context)) || - /* - * Set the db_name based on configuration before calling - * krb5_db_init, so it will get used. - */ - (ret = krb5_db_set_name(handle->context, - handle->params.dbname)) || - (ret = krb5_db_init(handle->context)) || + (ret = krb5_db_open(handle->context, handle->db_args, KRB5_KDB_OPEN_RW)) || (ret = adb_policy_close(handle)) || (ret = adb_policy_init(handle))) { (void) kadm5_destroy(server_handle); diff --git a/src/lib/kadm5/srv/server_kdb.c b/src/lib/kadm5/srv/server_kdb.c index 97d38c7b6..6392ef10d 100644 --- a/src/lib/kadm5/srv/server_kdb.c +++ b/src/lib/kadm5/srv/server_kdb.c @@ -42,7 +42,7 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, } else { realm = r; } - + if ((ret = krb5_db_setup_mkey_name(handle->context, handle->params.mkey_name, realm, NULL, &master_princ))) @@ -60,9 +60,6 @@ krb5_error_code kdb_init_master(kadm5_server_handle_t handle, if (ret) goto done; - if ((ret = krb5_db_init(handle->context)) != KSUCCESS) - goto done; - if ((ret = krb5_db_verify_master_key(handle->context, master_princ, &master_keyblock))) { krb5_db_fini(handle->context); @@ -264,7 +261,7 @@ kdb_get_entry(kadm5_server_handle_t handle, if (! xdr_osa_princ_ent_rec(&xdrs, adb)) { xdr_destroy(&xdrs); krb5_db_free_principal(handle->context, kdb, 1); - return(OSA_ADB_XDR_FAILURE); + return(KADM5_XDR_FAILURE); } xdr_destroy(&xdrs); } @@ -346,7 +343,7 @@ kdb_put_entry(kadm5_server_handle_t handle, xdralloc_create(&xdrs, XDR_ENCODE); if(! xdr_osa_princ_ent_rec(&xdrs, adb)) { xdr_destroy(&xdrs); - return(OSA_ADB_XDR_FAILURE); + return(KADM5_XDR_FAILURE); } tl_data.tl_data_type = KRB5_TL_KADM_DATA; tl_data.tl_data_length = xdr_getpos(&xdrs); @@ -395,7 +392,7 @@ kdb_iter_func(krb5_pointer data, krb5_db_entry *kdb) } krb5_error_code -kdb_iter_entry(kadm5_server_handle_t handle, +kdb_iter_entry(kadm5_server_handle_t handle, char *match_entry, void (*iter_fct)(void *, krb5_principal), void *data) { iter_data id; @@ -404,11 +401,10 @@ kdb_iter_entry(kadm5_server_handle_t handle, id.func = iter_fct; id.data = data; - ret = krb5_db_iterate(handle->context, kdb_iter_func, &id); + ret = krb5_db_iterate(handle->context, match_entry, kdb_iter_func, &id); if (ret) return(ret); return(0); } - diff --git a/src/lib/kadm5/srv/server_misc.c b/src/lib/kadm5/srv/server_misc.c index 02c7dced6..4f15fd3b2 100644 --- a/src/lib/kadm5/srv/server_misc.c +++ b/src/lib/kadm5/srv/server_misc.c @@ -11,7 +11,6 @@ static char *rcsid = "$Header$"; #include "k5-int.h" #include #include -#include "adb.h" #include /* for strcasecmp */ @@ -22,22 +21,17 @@ static char *rcsid = "$Header$"; kadm5_ret_t adb_policy_init(kadm5_server_handle_t handle) { - osa_adb_ret_t ret; - if(handle->policy_db == (osa_adb_policy_t) NULL) - if((ret = osa_adb_open_policy(&handle->policy_db, - &handle->params)) != OSA_ADB_OK) - return ret; - return KADM5_OK; + /* now policy is initialized as part of database. No seperate call needed */ + if( krb5_db_inited( handle->context ) ) + return KADM5_OK; + + return krb5_db_open( handle->context, NULL, KRB5_KDB_OPEN_RW ); } kadm5_ret_t adb_policy_close(kadm5_server_handle_t handle) { - osa_adb_ret_t ret; - if(handle->policy_db != (osa_adb_policy_t) NULL) - if((ret = osa_adb_close_policy(handle->policy_db)) != OSA_ADB_OK) - return ret; - handle->policy_db = NULL; + /* will be taken care by database close */ return KADM5_OK; } @@ -185,3 +179,4 @@ passwd_check(kadm5_server_handle_t handle, } return KADM5_OK; } + diff --git a/src/lib/kadm5/srv/svr_iters.c b/src/lib/kadm5/srv/svr_iters.c index 8c04d7857..ea1ee27cc 100644 --- a/src/lib/kadm5/srv/svr_iters.c +++ b/src/lib/kadm5/srv/svr_iters.c @@ -21,7 +21,6 @@ static char *rcsid = "$Header$"; #include #include #include -#include "adb.h" #ifdef SOLARIS_REGEXPS #include #endif @@ -230,18 +229,18 @@ static kadm5_ret_t kadm5_get_either(int princ, if (princ) { data.context = handle->context; - ret = kdb_iter_entry(handle, get_princs_iter, (void *) &data); + ret = kdb_iter_entry(handle, exp, get_princs_iter, (void *) &data); } else { - ret = osa_adb_iter_policy(handle->policy_db, get_pols_iter, (void *)&data); + ret = krb5_db_iter_policy(handle->context, exp, get_pols_iter, (void *)&data); } free(regexp); #ifdef POSIX_REGEXPS regfree(&data.preg); #endif - if (ret == OSA_ADB_OK && data.malloc_failed) + if ( !ret && data.malloc_failed) ret = ENOMEM; - if (ret != OSA_ADB_OK) { + if ( ret ) { for (i = 0; i < data.n_names; i++) free(data.names[i]); free(data.names); diff --git a/src/lib/kadm5/srv/svr_policy.c b/src/lib/kadm5/srv/svr_policy.c index d03cfd0b6..24398c1f4 100644 --- a/src/lib/kadm5/srv/svr_policy.c +++ b/src/lib/kadm5/srv/svr_policy.c @@ -10,7 +10,6 @@ static char *rcsid = "$Header$"; #include #include -#include "adb.h" #include "server_internal.h" #include @@ -47,6 +46,8 @@ kadm5_create_policy(void *server_handle, { CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + if (mask & KADM5_REF_COUNT) return KADM5_BAD_MASK; else @@ -139,10 +140,10 @@ kadm5_create_policy_internal(void *server_handle, pent.policy_refcnt = 0; else pent.policy_refcnt = entry->policy_refcnt; - if ((ret = osa_adb_create_policy(handle->policy_db, &pent)) == OSA_ADB_OK) - return KADM5_OK; - else + if ((ret = krb5_db_create_policy(handle->context, &pent))) return ret; + else + return KADM5_OK; } kadm5_ret_t @@ -151,24 +152,30 @@ kadm5_delete_policy(void *server_handle, kadm5_policy_t name) kadm5_server_handle_t handle = server_handle; osa_policy_ent_t entry; int ret; + int cnt=1; CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + if(name == (kadm5_policy_t) NULL) return EINVAL; if(strlen(name) == 0) return KADM5_BAD_POLICY; - if ((ret = osa_adb_get_policy(handle->policy_db, name, &entry)) != OSA_ADB_OK) + if((ret = krb5_db_get_policy(handle->context, name, &entry,&cnt))) return ret; + if( cnt != 1 ) + return KADM5_UNK_POLICY; + if(entry->policy_refcnt != 0) { - osa_free_policy_ent(entry); + krb5_db_free_policy(handle->context, entry); return KADM5_POLICY_REF; } - osa_free_policy_ent(entry); - if ((ret = osa_adb_destroy_policy(handle->policy_db, name)) == OSA_ADB_OK) - return KADM5_OK; - else + krb5_db_free_policy(handle->context, entry); + if ((ret = krb5_db_delete_policy(handle->context, name))) return ret; + else + return KADM5_OK; } kadm5_ret_t @@ -177,6 +184,8 @@ kadm5_modify_policy(void *server_handle, { CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + if (mask & KADM5_REF_COUNT) return KADM5_BAD_MASK; else @@ -190,6 +199,7 @@ kadm5_modify_policy_internal(void *server_handle, kadm5_server_handle_t handle = server_handle; osa_policy_ent_t p; int ret; + int cnt=1; CHECK_HANDLE(server_handle); @@ -200,26 +210,22 @@ kadm5_modify_policy_internal(void *server_handle, if((mask & KADM5_POLICY)) return KADM5_BAD_MASK; - switch ((ret = osa_adb_get_policy(handle->policy_db, entry->policy, &p))) { - case OSA_ADB_OK: - break; - case OSA_ADB_NOENT: + ret = krb5_db_get_policy(handle->context, entry->policy, &p, &cnt); + if( ret && (cnt==0) ) return KADM5_UNK_POLICY; - default: - break; - } + if ((mask & KADM5_PW_MAX_LIFE)) p->pw_max_life = entry->pw_max_life; if ((mask & KADM5_PW_MIN_LIFE)) { if(entry->pw_min_life > p->pw_max_life && p->pw_max_life != 0) { - osa_free_policy_ent(p); + krb5_db_free_policy(handle->context, p); return KADM5_BAD_MIN_PASS_LIFE; } p->pw_min_life = entry->pw_min_life; } if ((mask & KADM5_PW_MIN_LENGTH)) { if(entry->pw_min_length < MIN_PW_LENGTH) { - osa_free_policy_ent(p); + krb5_db_free_policy(handle->context, p); return KADM5_BAD_LENGTH; } p->pw_min_length = entry->pw_min_length; @@ -227,7 +233,7 @@ kadm5_modify_policy_internal(void *server_handle, if ((mask & KADM5_PW_MIN_CLASSES)) { if(entry->pw_min_classes > MAX_PW_CLASSES || entry->pw_min_classes < MIN_PW_CLASSES) { - osa_free_policy_ent(p); + krb5_db_free_policy(handle->context, p); return KADM5_BAD_CLASS; } p->pw_min_classes = entry->pw_min_classes; @@ -235,22 +241,15 @@ kadm5_modify_policy_internal(void *server_handle, if ((mask & KADM5_PW_HISTORY_NUM)) { if(entry->pw_history_num < MIN_PW_HISTORY || entry->pw_history_num > MAX_PW_HISTORY) { - osa_free_policy_ent(p); + krb5_db_free_policy(handle->context, p); return KADM5_BAD_HISTORY; } p->pw_history_num = entry->pw_history_num; } if ((mask & KADM5_REF_COUNT)) p->policy_refcnt = entry->policy_refcnt; - switch ((ret = osa_adb_put_policy(handle->policy_db, p))) { - case OSA_ADB_OK: - ret = KADM5_OK; - break; - case OSA_ADB_NOENT: /* this should not happen here ... */ - ret = KADM5_UNK_POLICY; - break; - } - osa_free_policy_ent(p); + ret = krb5_db_put_policy(handle->context, p); + krb5_db_free_policy(handle->context, p); return ret; } @@ -262,9 +261,12 @@ kadm5_get_policy(void *server_handle, kadm5_policy_t name, kadm5_policy_ent_rec entry_local, **entry_orig, *new; int ret; kadm5_server_handle_t handle = server_handle; + int cnt=1; CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + /* * In version 1, entry is a pointer to a kadm5_policy_ent_t that * should be filled with allocated memory. @@ -279,16 +281,14 @@ kadm5_get_policy(void *server_handle, kadm5_policy_t name, return EINVAL; if(strlen(name) == 0) return KADM5_BAD_POLICY; - switch((ret = osa_adb_get_policy(handle->policy_db, name, &t))) { - case OSA_ADB_OK: - break; - case OSA_ADB_NOENT: - return KADM5_UNK_POLICY; - default: + if((ret = krb5_db_get_policy(handle->context, name, &t, &cnt))) return ret; - } + + if( cnt != 1 ) + return KADM5_UNK_POLICY; + if ((entry->policy = (char *) malloc(strlen(t->name) + 1)) == NULL) { - osa_free_policy_ent(t); + krb5_db_free_policy(handle->context, t); return ENOMEM; } strcpy(entry->policy, t->name); @@ -298,13 +298,13 @@ kadm5_get_policy(void *server_handle, kadm5_policy_t name, entry->pw_min_classes = t->pw_min_classes; entry->pw_history_num = t->pw_history_num; entry->policy_refcnt = t->policy_refcnt; - osa_free_policy_ent(t); + krb5_db_free_policy(handle->context, t); if (handle->api_version == KADM5_API_VERSION_1) { new = (kadm5_policy_ent_t) malloc(sizeof(kadm5_policy_ent_rec)); if (new == NULL) { free(entry->policy); - osa_free_policy_ent(t); + krb5_db_free_policy(handle->context, t); return ENOMEM; } *new = *entry; diff --git a/src/lib/kadm5/srv/svr_principal.c b/src/lib/kadm5/srv/svr_principal.c index 7dc2d8f6b..f1a0717e9 100644 --- a/src/lib/kadm5/srv/svr_principal.c +++ b/src/lib/kadm5/srv/svr_principal.c @@ -11,7 +11,6 @@ static char *rcsid = "$Header$"; #include #include #include -#include "adb.h" #include "k5-int.h" #include #include @@ -35,6 +34,79 @@ static int decrypt_key_data(krb5_context context, int n_key_data, krb5_key_data *key_data, krb5_keyblock **keyblocks, int *n_keys); +static krb5_error_code +kadm5_copy_principal(krb5_context context, krb5_const_principal inprinc, krb5_principal *outprinc) +{ + register krb5_principal tempprinc; + register int i, nelems; + + tempprinc = (krb5_principal)krb5_db_alloc(context, NULL, sizeof(krb5_principal_data)); + + if (tempprinc == 0) + return ENOMEM; + + memcpy(tempprinc, inprinc, sizeof(krb5_principal_data)); + + nelems = (int) krb5_princ_size(context, inprinc); + tempprinc->data = krb5_db_alloc(context, NULL, nelems * sizeof(krb5_data)); + + if (tempprinc->data == 0) { + krb5_db_free(context, (char *)tempprinc); + return ENOMEM; + } + + for (i = 0; i < nelems; i++) { + unsigned int len = krb5_princ_component(context, inprinc, i)->length; + krb5_princ_component(context, tempprinc, i)->length = len; + if (((krb5_princ_component(context, tempprinc, i)->data = + krb5_db_alloc(context, NULL, len)) == 0) && len) { + while (--i >= 0) + krb5_db_free(context, krb5_princ_component(context, tempprinc, i)->data); + krb5_db_free (context, tempprinc->data); + krb5_db_free (context, tempprinc); + return ENOMEM; + } + if (len) + memcpy(krb5_princ_component(context, tempprinc, i)->data, + krb5_princ_component(context, inprinc, i)->data, len); + } + + tempprinc->realm.data = + krb5_db_alloc(context, NULL, tempprinc->realm.length = inprinc->realm.length); + if (!tempprinc->realm.data && tempprinc->realm.length) { + for (i = 0; i < nelems; i++) + krb5_db_free(context, krb5_princ_component(context, tempprinc, i)->data); + krb5_db_free(context, tempprinc->data); + krb5_db_free(context, tempprinc); + return ENOMEM; + } + if (tempprinc->realm.length) + memcpy(tempprinc->realm.data, inprinc->realm.data, + inprinc->realm.length); + + *outprinc = tempprinc; + return 0; +} + +static void +kadm5_free_principal(krb5_context context, krb5_principal val) +{ + register krb5_int32 i; + + if (!val) + return; + + if (val->data) { + i = krb5_princ_size(context, val); + while(--i >= 0) + krb5_db_free(context, krb5_princ_component(context, val, i)->data); + krb5_db_free(context, val->data); + } + if (val->realm.data) + krb5_db_free(context, val->realm.data); + krb5_db_free(context, val); +} + /* * XXX Functions that ought to be in libkrb5.a, but aren't. */ @@ -98,8 +170,8 @@ static void cleanup_key_data(context, count, data) for (i = 0; i < count; i++) for (j = 0; j < data[i].key_data_ver; j++) if (data[i].key_data_length[j]) - free(data[i].key_data_contents[j]); - free(data); + krb5_db_free(context, data[i].key_data_contents[j]); + krb5_db_free(context, data); } kadm5_ret_t @@ -127,6 +199,8 @@ kadm5_create_principal_3(void *server_handle, CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + /* * Argument sanity checking, and opening up the DB */ @@ -231,20 +305,37 @@ kadm5_create_principal_3(void *server_handle, to free the entire kdb entry, and that will try to free the principal. */ - if ((ret = krb5_copy_principal(handle->context, - entry->principal, &(kdb.princ)))) { + if ((ret = kadm5_copy_principal(handle->context, + entry->principal, &(kdb.princ)))) { if (mask & KADM5_POLICY) (void) kadm5_free_policy_ent(handle->lhandle, &polent); return(ret); } if ((ret = krb5_dbe_update_last_pwd_change(handle->context, &kdb, now))) { - krb5_dbe_free_contents(handle->context, &kdb); + krb5_db_free_principal(handle->context, &kdb, 1); if (mask & KADM5_POLICY) (void) kadm5_free_policy_ent(handle->lhandle, &polent); return(ret); } + if (mask & KADM5_TL_DATA) { + /* splice entry->tl_data onto the front of kdb.tl_data */ + tl_data_orig = kdb.tl_data; + for (tl_data_tail = entry->tl_data; tl_data_tail; + tl_data_tail = tl_data_tail->tl_data_next) + { + ret = krb5_dbe_update_tl_data(handle->context, &kdb, tl_data_tail); + if( ret ) + { + krb5_db_free_principal(handle->context, &kdb, 1); + if (mask & KADM5_POLICY) + (void) kadm5_free_policy_ent(handle->lhandle, &polent); + return ret; + } + } + } + /* initialize the keys */ if ((ret = krb5_dbe_cpw(handle->context, &master_keyblock, @@ -253,7 +344,7 @@ kadm5_create_principal_3(void *server_handle, password, (mask & KADM5_KVNO)?entry->kvno:1, FALSE, &kdb))) { - krb5_dbe_free_contents(handle->context, &kdb); + krb5_db_free_principal(handle->context, &kdb, 1); if (mask & KADM5_POLICY) (void) kadm5_free_policy_ent(handle->lhandle, &polent); return(ret); @@ -282,33 +373,17 @@ kadm5_create_principal_3(void *server_handle, if ((ret = kadm5_modify_policy_internal(handle->lhandle, &polent, KADM5_REF_COUNT)) != KADM5_OK) { - krb5_dbe_free_contents(handle->context, &kdb); + krb5_db_free_principal(handle->context, &kdb, 1); if (mask & KADM5_POLICY) (void) kadm5_free_policy_ent(handle->lhandle, &polent); return(ret); } } - if (mask & KADM5_TL_DATA) { - /* splice entry->tl_data onto the front of kdb.tl_data */ - tl_data_orig = kdb.tl_data; - for (tl_data_tail = entry->tl_data; tl_data_tail->tl_data_next; - tl_data_tail = tl_data_tail->tl_data_next) - ; - tl_data_tail->tl_data_next = kdb.tl_data; - kdb.tl_data = entry->tl_data; - } - /* store the new db entry */ ret = kdb_put_entry(handle, &kdb, &adb); - if (mask & KADM5_TL_DATA) { - /* remove entry->tl_data from the front of kdb.tl_data */ - tl_data_tail->tl_data_next = NULL; - kdb.tl_data = tl_data_orig; - } - - krb5_dbe_free_contents(handle->context, &kdb); + krb5_db_free_principal(handle->context, &kdb, 1); if (ret) { if ((mask & KADM5_POLICY)) { @@ -346,6 +421,8 @@ kadm5_delete_principal(void *server_handle, krb5_principal principal) CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + if (principal == NULL) return EINVAL; @@ -392,6 +469,8 @@ kadm5_modify_principal(void *server_handle, CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + if((mask & KADM5_PRINCIPAL) || (mask & KADM5_LAST_PWD_CHANGE) || (mask & KADM5_MOD_TIME) || (mask & KADM5_MOD_NAME) || (mask & KADM5_MKVNO) || (mask & KADM5_AUX_ATTRIBUTES) || @@ -534,34 +613,18 @@ kadm5_modify_principal(void *server_handle, } if (mask & KADM5_TL_DATA) { - krb5_tl_data *tl, *tl2; - /* - * Replace kdb.tl_data with what was passed in. The - * KRB5_TL_KADM_DATA will be re-added (based on adb) by - * kdb_put_entry, below. - * - * Note that we have to duplicate the passed in tl_data - * before adding it to kdb. The reason is that kdb_put_entry - * will add its own tl_data entries that we will need to - * free, but we cannot free the caller's tl_data (an - * alternative would be to scan the tl_data after put_entry - * and only free those entries that were not passed in). - */ - while (kdb.tl_data) { - tl = kdb.tl_data->tl_data_next; - free(kdb.tl_data->tl_data_contents); - free(kdb.tl_data); - kdb.tl_data = tl; - } + krb5_tl_data *tl; + + /* may have to change the version number of the API. Updates the list with the given tl_data rather than over-writting */ - kdb.n_tl_data = entry->n_tl_data; - kdb.tl_data = NULL; - tl2 = entry->tl_data; - while (tl2) { - tl = dup_tl_data(tl2); - tl->tl_data_next = kdb.tl_data; - kdb.tl_data = tl; - tl2 = tl2->tl_data_next; + for (tl = entry->tl_data; tl; + tl = tl->tl_data_next) + { + ret = krb5_dbe_update_tl_data(handle->context, &kdb, tl); + if( ret ) + { + goto done; + } } } @@ -593,6 +656,8 @@ kadm5_rename_principal(void *server_handle, CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + if (source == NULL || target == NULL) return EINVAL; @@ -614,8 +679,8 @@ kadm5_rename_principal(void *server_handle, } } - krb5_free_principal(handle->context, kdb.princ); - ret = krb5_copy_principal(handle->context, target, &kdb.princ); + kadm5_free_principal(handle->context, kdb.princ); + ret = kadm5_copy_principal(handle->context, target, &kdb.princ); if (ret) { kdb.princ = NULL; /* so freeing the dbe doesn't lose */ goto done; @@ -638,7 +703,7 @@ kadm5_get_principal(void *server_handle, krb5_principal principal, { krb5_db_entry kdb; osa_princ_ent_rec adb; - osa_adb_ret_t ret = 0; + krb5_error_code ret = 0; long mask; int i; kadm5_server_handle_t handle = server_handle; @@ -646,6 +711,8 @@ kadm5_get_principal(void *server_handle, krb5_principal principal, CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + /* * In version 1, all the defined fields are always returned. * entry is a pointer to a kadm5_principal_ent_t_v1 that should be @@ -1222,6 +1289,8 @@ kadm5_chpass_principal_3(void *server_handle, CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + hist_added = 0; memset(&hist, 0, sizeof(hist)); @@ -1373,7 +1442,7 @@ done: free_history_entry(handle->context, &hist); kdb_free_entry(handle, &kdb, &adb); kdb_free_entry(handle, &kdb_save, NULL); - krb5_dbe_free_contents(handle->context, &kdb); + krb5_db_free_principal(handle->context, &kdb, 1); if (have_pol && (ret2 = kadm5_free_policy_ent(handle->lhandle, &pol)) && !ret) @@ -1409,6 +1478,8 @@ kadm5_randkey_principal_3(void *server_handle, int ret, last_pwd, have_pol = 0; kadm5_server_handle_t handle = server_handle; + krb5_db_clr_error(); + if (keyblocks) *keyblocks = NULL; @@ -1538,11 +1609,16 @@ kadm5_setv4key_principal(void *server_handle, krb5_int32 now; kadm5_policy_ent_rec pol; krb5_keysalt keysalt; - int i, kvno, ret, have_pol = 0; + int i, k, kvno, ret, have_pol = 0; #if 0 int last_pwd; #endif kadm5_server_handle_t handle = server_handle; + krb5_key_data tmp_key_data; + + krb5_db_clr_error(); + + memset( &tmp_key_data, 0, sizeof(tmp_key_data)); CHECK_HANDLE(server_handle); @@ -1566,7 +1642,7 @@ kadm5_setv4key_principal(void *server_handle, if (kdb.key_data != NULL) cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data); - kdb.key_data = (krb5_key_data*)malloc(sizeof(krb5_key_data)); + kdb.key_data = (krb5_key_data*)krb5_db_alloc(handle->context, NULL, sizeof(krb5_key_data)); if (kdb.key_data == NULL) return ENOMEM; memset(kdb.key_data, 0, sizeof(krb5_key_data)); @@ -1576,13 +1652,39 @@ kadm5_setv4key_principal(void *server_handle, keysalt.data.length = 0; keysalt.data.data = NULL; + /* use tmp_key_data as temporary location and reallocate later */ ret = krb5_dbekd_encrypt_key_data(handle->context, &master_keyblock, keyblock, &keysalt, kvno + 1, - kdb.key_data); + &tmp_key_data); if (ret) { goto done; } + for( k = 0; k < tmp_key_data.key_data_ver; k++ ) + { + kdb.key_data->key_data_type[k] = tmp_key_data.key_data_type[k]; + kdb.key_data->key_data_length[k] = tmp_key_data.key_data_length[k]; + if( tmp_key_data.key_data_contents[k] ) + { + kdb.key_data->key_data_contents[k] = krb5_db_alloc(handle->context, NULL, tmp_key_data.key_data_length[k]); + if( kdb.key_data->key_data_contents[k] == NULL ) + { + cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data); + kdb.key_data = NULL; + kdb.n_key_data = 0; + ret = ENOMEM; + goto done; + } + memcpy( kdb.key_data->key_data_contents[k], tmp_key_data.key_data_contents[k], tmp_key_data.key_data_length[k]); + + memset( tmp_key_data.key_data_contents[k], 0, tmp_key_data.key_data_length[k]); + free( tmp_key_data.key_data_contents[k] ); + tmp_key_data.key_data_contents[k] = NULL; + } + } + + + kdb.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; ret = krb5_timeofday(handle->context, &now); @@ -1646,6 +1748,15 @@ kadm5_setv4key_principal(void *server_handle, ret = KADM5_OK; done: + for( i = 0; i < tmp_key_data.key_data_ver; i++ ) + { + if( tmp_key_data.key_data_contents[i] ) + { + memset( tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]); + free( tmp_key_data.key_data_contents[i] ); + } + } + kdb_free_entry(handle, &kdb, &adb); if (have_pol) kadm5_free_policy_ent(handle->lhandle, &pol); @@ -1679,16 +1790,20 @@ kadm5_setkey_principal_3(void *server_handle, kadm5_policy_ent_rec pol; krb5_key_data *old_key_data; int n_old_keys; - int i, j, kvno, ret, have_pol = 0; + int i, j, k, kvno, ret, have_pol = 0; #if 0 int last_pwd; #endif kadm5_server_handle_t handle = server_handle; krb5_boolean similar; krb5_keysalt keysalt; + krb5_key_data tmp_key_data; + krb5_key_data *tptr; CHECK_HANDLE(server_handle); + krb5_db_clr_error(); + if (principal == NULL || keyblocks == NULL) return EINVAL; if (hist_princ && /* this will be NULL when initializing the databse */ @@ -1733,10 +1848,14 @@ kadm5_setkey_principal_3(void *server_handle, old_key_data = NULL; } - kdb.key_data = (krb5_key_data*)malloc((n_keys+n_old_keys) - *sizeof(krb5_key_data)); + kdb.key_data = (krb5_key_data*)krb5_db_alloc(handle->context, NULL, (n_keys+n_old_keys) + *sizeof(krb5_key_data)); if (kdb.key_data == NULL) - return ENOMEM; + { + ret= ENOMEM; + goto done; + } + memset(kdb.key_data, 0, (n_keys+n_old_keys)*sizeof(krb5_key_data)); kdb.n_key_data = 0; @@ -1746,20 +1865,50 @@ kadm5_setkey_principal_3(void *server_handle, keysalt.data.length = 0; keysalt.data.data = NULL; if (ks_tuple[i].ks_enctype != keyblocks[i].enctype) { - cleanup_key_data(handle->context, kdb.n_key_data, - kdb.key_data); - return KADM5_SETKEY3_ETYPE_MISMATCH; + ret= KADM5_SETKEY3_ETYPE_MISMATCH; + goto done; } } + memset( &tmp_key_data, 0, sizeof(tmp_key_data)); + ret = krb5_dbekd_encrypt_key_data(handle->context, &master_keyblock, &keyblocks[i], n_ks_tuple ? &keysalt : NULL, kvno + 1, - &kdb.key_data[i]); + &tmp_key_data); if (ret) { - cleanup_key_data(handle->context, kdb.n_key_data, kdb.key_data); - return ret; + goto done; + } + tptr = &kdb.key_data[i]; + for( k = 0; k < tmp_key_data.key_data_ver; k++ ) + { + tptr->key_data_type[k] = tmp_key_data.key_data_type[k]; + tptr->key_data_length[k] = tmp_key_data.key_data_length[k]; + if( tmp_key_data.key_data_contents[k] ) + { + tptr->key_data_contents[k] = krb5_db_alloc(handle->context, NULL, tmp_key_data.key_data_length[k]); + if( tptr->key_data_contents[k] == NULL ) + { + int i1; + for( i1 = k; i1 < tmp_key_data.key_data_ver; i1++ ) + { + if( tmp_key_data.key_data_contents[i1] ) + { + memset( tmp_key_data.key_data_contents[i1], 0, tmp_key_data.key_data_length[i1]); + free( tmp_key_data.key_data_contents[i1] ); + } + } + + ret = ENOMEM; + goto done; + } + memcpy( tptr->key_data_contents[k], tmp_key_data.key_data_contents[k], tmp_key_data.key_data_length[k]); + + memset( tmp_key_data.key_data_contents[k], 0, tmp_key_data.key_data_length[k]); + free( tmp_key_data.key_data_contents[k] ); + tmp_key_data.key_data_contents[k] = NULL; + } } kdb.n_key_data++; } @@ -1770,6 +1919,10 @@ kadm5_setkey_principal_3(void *server_handle, memset(&old_key_data[i], 0, sizeof (krb5_key_data)); kdb.n_key_data++; } + + if( old_key_data ) + krb5_db_free(handle->context, old_key_data); + /* assert(kdb.n_key_data == n_keys + n_old_keys) */ kdb.attributes &= ~KRB5_KDB_REQUIRES_PWCHANGE; @@ -1862,6 +2015,14 @@ static int decrypt_key_data(krb5_context context, &key_data[i], &keys[i], NULL); if (ret) { + for(; i >= 0; i-- ) + { + if( keys[i].contents ) + { + memset( keys[i].contents, 0, keys[i].length ); + free( keys[i].contents ); + } + } memset((char *) keys, 0, n_key_data*sizeof(krb5_keyblock)); free(keys); @@ -1946,3 +2107,4 @@ kadm5_ret_t kadm5_decrypt_key(void *server_handle, return KADM5_OK; } + diff --git a/src/lib/kadm5/unit-test/ChangeLog b/src/lib/kadm5/unit-test/ChangeLog index 4b0777e89..67c82bcd3 100644 --- a/src/lib/kadm5/unit-test/ChangeLog +++ b/src/lib/kadm5/unit-test/ChangeLog @@ -1,3 +1,15 @@ +2005-06-20 Ken Raeburn + + Novell merge. + * Makefile.in: + * destroy-test.c: + * handle-test.c: + * init-test.c: + * iter-test.c: + * lock-test.c: + * randkey-test.c: + * setkey-test.c: + 2005-02-10 Tom Yu * api.2/init-v2.exp: Handle improved error codes from diff --git a/src/lib/kadm5/unit-test/Makefile.in b/src/lib/kadm5/unit-test/Makefile.in index 5d4fc1f70..242e9c256 100644 --- a/src/lib/kadm5/unit-test/Makefile.in +++ b/src/lib/kadm5/unit-test/Makefile.in @@ -5,6 +5,7 @@ BUILDTOP=$(REL)..$(S)..$(S).. DEFINES = -DUSE_KADM5_API_VERSION=1 PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) +KDB_DEP_LIB=-ldl -lpthread all:: init-test destroy-test client-handle-test client-iter-test all:: randkey-test server-handle-test lock-test server-iter-test @@ -40,26 +41,26 @@ client-setkey-test: setkey-test.o $(KADMCLNT_DEPLIBS) $(KRB5_BASE_DEPLIBS) randkey-test: randkey-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o randkey-test randkey-test.o \ - $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) + $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) server-handle-test: handle-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o server-handle-test handle-test.o \ - $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) + $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) lock-test: lock-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o lock-test lock-test.o \ - $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) + $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) server-iter-test: iter-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o server-iter-test iter-test.o \ - $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) + $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) setkey-test.o: $(SRCTOP)/lib/kadm5/unit-test/setkey-test.c $(CC) $(ALL_CFLAGS) -UUSE_KADM5_API_VERSION -DUSE_KADM5_API_VERSION=2 -c $(SRCTOP)/lib/kadm5/unit-test/setkey-test.c server-setkey-test: setkey-test.o $(KADMSRV_DEPLIBS) $(KRB5_BASE_DEPLIBS) $(CC_LINK) -o server-setkey-test setkey-test.o \ - $(KADMSRV_LIBS) $(KRB5_BASE_LIBS) + $(KADMSRV_LIBS) $(KDB_DEP_LIB) $(KRB5_BASE_LIBS) # # The unit-test targets diff --git a/src/lib/kadm5/unit-test/destroy-test.c b/src/lib/kadm5/unit-test/destroy-test.c index 02bfb7ec9..6d7435c45 100644 --- a/src/lib/kadm5/unit-test/destroy-test.c +++ b/src/lib/kadm5/unit-test/destroy-test.c @@ -22,7 +22,7 @@ int main() for(x = 0; x < TEST_NUM; x++) { ret = ovsec_kadm_init("admin", "admin", "ovsec_adm/admin", 0, OVSEC_KADM_STRUCT_VERSION, - OVSEC_KADM_API_VERSION_1, + OVSEC_KADM_API_VERSION_1, NULL, &server_handle); if(ret != OVSEC_KADM_OK) { com_err("test", ret, "init"); diff --git a/src/lib/kadm5/unit-test/handle-test.c b/src/lib/kadm5/unit-test/handle-test.c index aa71df483..6743e6e8e 100644 --- a/src/lib/kadm5/unit-test/handle-test.c +++ b/src/lib/kadm5/unit-test/handle-test.c @@ -25,7 +25,7 @@ int main(int argc, char *argv[]) krb5_init_context(&context); ret = ovsec_kadm_init("admin/none", "admin", "ovsec_adm/admin", 0, - OVSEC_KADM_STRUCT_VERSION, OVSEC_KADM_API_VERSION_1, + OVSEC_KADM_STRUCT_VERSION, OVSEC_KADM_API_VERSION_1, NULL, &server_handle); if(ret != OVSEC_KADM_OK) { com_err("test", ret, "init"); diff --git a/src/lib/kadm5/unit-test/init-test.c b/src/lib/kadm5/unit-test/init-test.c index 86b356686..9677698a7 100644 --- a/src/lib/kadm5/unit-test/init-test.c +++ b/src/lib/kadm5/unit-test/init-test.c @@ -14,7 +14,7 @@ int main() memset(¶ms, 0, sizeof(params)); params.mask |= KADM5_CONFIG_NO_AUTH; ret = kadm5_init("admin", "admin", NULL, ¶ms, - KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, + KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, NULL, &server_handle); if (ret == KADM5_RPC_ERROR) exit(0); diff --git a/src/lib/kadm5/unit-test/iter-test.c b/src/lib/kadm5/unit-test/iter-test.c index 4c85fe763..4b85a5490 100644 --- a/src/lib/kadm5/unit-test/iter-test.c +++ b/src/lib/kadm5/unit-test/iter-test.c @@ -16,7 +16,7 @@ int main(int argc, char **argv) ret = ovsec_kadm_init("admin", "admin", OVSEC_KADM_ADMIN_SERVICE, 0, OVSEC_KADM_STRUCT_VERSION, - OVSEC_KADM_API_VERSION_1, + OVSEC_KADM_API_VERSION_1, NULL, &server_handle); if (ret != OVSEC_KADM_OK) { com_err("iter-test", ret, "while initializing"); diff --git a/src/lib/kadm5/unit-test/lock-test.c b/src/lib/kadm5/unit-test/lock-test.c index 256954c85..24ff74a91 100644 --- a/src/lib/kadm5/unit-test/lock-test.c +++ b/src/lib/kadm5/unit-test/lock-test.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include char *whoami; @@ -20,8 +20,7 @@ static void usage() int main(int argc, char **argv) { - osa_adb_ret_t ret; - osa_adb_policy_t policy_db; + krb5_error_code ret; osa_policy_ent_t entry; krb5_context context; kadm5_config_params params; @@ -36,7 +35,7 @@ int main(int argc, char **argv) } initialize_ovk_error_table(); - initialize_adb_error_table(); +/* initialize_adb_error_table(); */ initialize_ovku_error_table(); params.mask = 0; @@ -52,8 +51,8 @@ int main(int argc, char **argv) exit(1); } - ret = osa_adb_open_policy(&policy_db, ¶ms); - if (ret != OSA_ADB_OK) { + ret = krb5_db_open( context, NULL, KRB5_KDB_OPEN_RW); + if (ret) { com_err(whoami, ret, "while opening database"); exit(1); } @@ -61,38 +60,39 @@ int main(int argc, char **argv) argc--; argv++; while (argc) { if (strcmp(*argv, "shared") == 0) { - ret = osa_adb_get_lock(policy_db, OSA_ADB_SHARED); - if (ret != OSA_ADB_OK) + ret = krb5_db_lock(context, KRB5_DB_LOCKMODE_SHARED); + if (ret) com_err(whoami, ret, "while getting shared lock"); else printf("shared\n"); } else if (strcmp(*argv, "exclusive") == 0) { - ret = osa_adb_get_lock(policy_db, OSA_ADB_EXCLUSIVE); - if (ret != OSA_ADB_OK) + ret = krb5_db_lock(context, KRB5_DB_LOCKMODE_EXCLUSIVE ); + if (ret) com_err(whoami, ret, "while getting exclusive lock"); else printf("exclusive\n"); } else if (strcmp(*argv, "permanent") == 0) { - ret = osa_adb_get_lock(policy_db, OSA_ADB_PERMANENT); - if (ret != OSA_ADB_OK) + ret = krb5_db_lock(context, KRB5_DB_LOCKMODE_EXCLUSIVE ); + if (ret) com_err(whoami, ret, "while getting permanent lock"); else printf("permanent\n"); } else if (strcmp(*argv, "release") == 0) { - ret = osa_adb_release_lock(policy_db); - if (ret != OSA_ADB_OK) + ret = krb5_db_unlock(context); + if (ret) com_err(whoami, ret, "while releasing lock"); else printf("released\n"); } else if (strcmp(*argv, "get") == 0) { + int cnt = 1; argc--; argv++; if (!argc) usage(); - if ((ret = osa_adb_get_policy(policy_db, *argv, - &entry)) != OSA_ADB_OK) { + if ((ret = krb5_db_get_policy(context, *argv, + &entry, &cnt)) ) { com_err(whoami, ret, "while getting policy"); } else { printf("retrieved\n"); - osa_free_policy_ent(entry); + krb5_db_free_policy(context, entry); } } else if (strcmp(*argv, "wait") == 0) { getchar(); @@ -105,8 +105,8 @@ int main(int argc, char **argv) argc--; argv++; } - ret = osa_adb_close_policy(policy_db); - if (ret != OSA_ADB_OK) { + ret = krb5_db_fini(context); + if (ret) { com_err(whoami, ret, "while closing database"); exit(1); } diff --git a/src/lib/kadm5/unit-test/randkey-test.c b/src/lib/kadm5/unit-test/randkey-test.c index cddc165df..5722302de 100644 --- a/src/lib/kadm5/unit-test/randkey-test.c +++ b/src/lib/kadm5/unit-test/randkey-test.c @@ -23,7 +23,7 @@ int main() krb5_parse_name(context, "testuser", &tprinc); ret = ovsec_kadm_init("admin", "admin", "ovsec_adm/admin", 0, OVSEC_KADM_STRUCT_VERSION, - OVSEC_KADM_API_VERSION_1, + OVSEC_KADM_API_VERSION_1, NULL, &server_handle); if(ret != OVSEC_KADM_OK) { com_err("test", ret, "init"); diff --git a/src/lib/kadm5/unit-test/setkey-test.c b/src/lib/kadm5/unit-test/setkey-test.c index 5b791d8f3..af78114de 100644 --- a/src/lib/kadm5/unit-test/setkey-test.c +++ b/src/lib/kadm5/unit-test/setkey-test.c @@ -119,7 +119,7 @@ main(int argc, char **argv) } ret = kadm5_init(authprinc, NULL, KADM5_ADMIN_SERVICE, NULL, - KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, + KADM5_STRUCT_VERSION, KADM5_API_VERSION_2, NULL, &handle); if (ret) { com_err(whoami, ret, "while initializing connection"); diff --git a/src/lib/kdb/ChangeLog b/src/lib/kdb/ChangeLog index 99e6b58ca..740cef026 100644 --- a/src/lib/kdb/ChangeLog +++ b/src/lib/kdb/ChangeLog @@ -1,3 +1,30 @@ +2005-06-20 Ken Raeburn + + Novell merge. + * Makefile.in: + * adb_err.et: + * configure.in: + * decrypt_key.c: + * encrypt_key.c: + * err_handle.c: + * err_handle.h: + * fetch_mkey.c: + * kdb5.c: + * kdb5.h: + * kdb_compat.h: + * kdb_cpw.c: + * kdb_db2.c: + * kdb_db2.h: + * kdb_default.c: + * kdb_xdr.c: + * keytab.c: + * libkrb5.exports: + * setup_mkey.c: + * store_mkey.c: + * t_kdb.c: + * t_krb5.conf: + * verify_mky.c: + 2005-06-09 Ken Raeburn * kdb_dbm.c: Unused file deleted. diff --git a/src/lib/kdb/Makefile.in b/src/lib/kdb/Makefile.in index 396ce1ef4..84c94c2f5 100644 --- a/src/lib/kdb/Makefile.in +++ b/src/lib/kdb/Makefile.in @@ -6,6 +6,8 @@ KRB5_RUN_ENV = @KRB5_RUN_ENV@ KRB5_CONFIG_SETUP = KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf ; export KRB5_CONFIG ; PROG_LIBPATH=-L$(TOPLIBD) PROG_RPATH=$(KRB5_LIBDIR) +CFLAGS=@CFLAGS@ -DKDB5_USE_LIB_KDB_DB2 +LOCALINCLUDES= -I. LIBBASE=kdb5 LIBMAJOR=4 @@ -29,30 +31,29 @@ DBOBJLISTS-k5 = $(DBDIR)/hash/OBJS.ST $(DBDIR)/btree/OBJS.ST \ all:: +adb_err.$(OBJEXT): adb_err.c +adb_err.c adb_err.h: $(srcdir)/adb_err.et + SRCS= \ - $(srcdir)/keytab.c \ + $(srcdir)/kdb5.c \ $(srcdir)/encrypt_key.c \ $(srcdir)/decrypt_key.c \ + $(srcdir)/kdb_default.c \ $(srcdir)/kdb_cpw.c \ - $(srcdir)/kdb_db2.c \ - $(srcdir)/kdb_xdr.c \ - $(srcdir)/verify_mky.c \ - $(srcdir)/fetch_mkey.c \ - $(srcdir)/setup_mkey.c \ - $(srcdir)/store_mkey.c + adb_err.c \ + $(srcdir)/err_handle.c \ + $(srcdir)/keytab.c STOBJLISTS=OBJS.ST $(DBOBJLISTS) STLIBOBJS= \ - keytab.o \ + kdb5.o \ encrypt_key.o \ decrypt_key.o \ + kdb_default.o \ kdb_cpw.o \ - kdb_db2.o \ - kdb_xdr.o \ - verify_mky.o \ - fetch_mkey.o \ - setup_mkey.o \ - store_mkey.o + adb_err.o \ + err_handle.o \ + keytab.o all-unix:: all-liblinks install-unix:: install-libs @@ -78,14 +79,14 @@ clean:: # Makefile dependencies follow. This must be the last section in # the Makefile.in file # -keytab.so keytab.po $(OUTPRE)keytab.$(OBJEXT): keytab.c \ - $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ - $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ - $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(SRCTOP)/include/krb5/kdb_kt.h $(SRCTOP)/include/krb5/kdb.h +kdb5.so kdb5.po $(OUTPRE)kdb5.$(OBJEXT): kdb5.c $(SRCTOP)/include/k5-int.h \ + $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \ + $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ + $(SRCTOP)/include/krb5/kdb.h $(BUILDTOP)/include/krb5/osconf.h \ + kdb5.h err_handle.h ./adb_err.h encrypt_key.so encrypt_key.po $(OUTPRE)encrypt_key.$(OBJEXT): \ encrypt_key.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ @@ -100,54 +101,35 @@ decrypt_key.so decrypt_key.po $(OUTPRE)decrypt_key.$(OBJEXT): \ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h -kdb_cpw.so kdb_cpw.po $(OUTPRE)kdb_cpw.$(OBJEXT): kdb_cpw.c \ - $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ - $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ - $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(SRCTOP)/include/krb5/adm.h -kdb_db2.so kdb_db2.po $(OUTPRE)kdb_db2.$(OBJEXT): kdb_db2.c \ - $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ - $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ - $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ - $(DB_DEPS) kdb_compat.h kdb_db2.h -kdb_xdr.so kdb_xdr.po $(OUTPRE)kdb_xdr.$(OBJEXT): kdb_xdr.c \ - $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ - $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ - $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h -verify_mky.so verify_mky.po $(OUTPRE)verify_mky.$(OBJEXT): \ - verify_mky.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ - $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ - $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ - $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h -fetch_mkey.so fetch_mkey.po $(OUTPRE)fetch_mkey.$(OBJEXT): \ - fetch_mkey.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ +kdb_default.so kdb_default.po $(OUTPRE)kdb_default.$(OBJEXT): \ + kdb_default.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h -setup_mkey.so setup_mkey.po $(OUTPRE)setup_mkey.$(OBJEXT): \ - setup_mkey.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ +kdb_cpw.so kdb_cpw.po $(OUTPRE)kdb_cpw.$(OBJEXT): kdb_cpw.c \ + $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h -store_mkey.so store_mkey.po $(OUTPRE)store_mkey.$(OBJEXT): \ - store_mkey.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ +adb_err.so adb_err.po $(OUTPRE)adb_err.$(OBJEXT): adb_err.c \ + $(COM_ERR_DEPS) +err_handle.so err_handle.po $(OUTPRE)err_handle.$(OBJEXT): \ + err_handle.c err_handle.h $(SRCTOP)/include/k5-int.h \ + $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \ + $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ + $(SRCTOP)/include/krb5/kdb.h +keytab.so keytab.po $(OUTPRE)keytab.$(OBJEXT): keytab.c \ + $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ - $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h + $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ + $(SRCTOP)/include/krb5/kdb_kt.h $(SRCTOP)/include/krb5/kdb.h diff --git a/src/lib/kdb/adb_err.et b/src/lib/kdb/adb_err.et new file mode 100644 index 000000000..394802571 --- /dev/null +++ b/src/lib/kdb/adb_err.et @@ -0,0 +1,16 @@ +error_table adb +error_code OSA_ADB_NOERR, "No Error" +error_code OSA_ADB_DUP, "Principal or policy already exists" +error_code OSA_ADB_NOENT, "Principal or policy does not exist" +error_code OSA_ADB_DBINIT, "Database not initialized" +error_code OSA_ADB_BAD_POLICY, "Invalid policy name" +error_code OSA_ADB_BAD_PRINC, "Invalid principal name" +error_code OSA_ADB_BAD_DB, "Database inconsistency detected" +error_code OSA_ADB_XDR_FAILURE, "XDR encoding error" +error_code OSA_ADB_FAILURE, "Failure!" +error_code OSA_ADB_BADLOCKMODE, "Bad lock mode" +error_code OSA_ADB_CANTLOCK_DB, "Cannot lock database" +error_code OSA_ADB_NOTLOCKED, "Database not locked" +error_code OSA_ADB_NOLOCKFILE, "KADM5 administration database lock file missing" +error_code OSA_ADB_NOEXCL_PERM, "Insufficient permission to lock file" +end diff --git a/src/lib/kdb/configure.in b/src/lib/kdb/configure.in index dc002d878..4f06b3204 100644 --- a/src/lib/kdb/configure.in +++ b/src/lib/kdb/configure.in @@ -4,6 +4,7 @@ AC_CHECK_HEADERS(unistd.h) AC_TYPE_MODE_T AC_TYPE_OFF_T +AC_CHECK_HEADERS(pthread.h) AC_CHECK_FUNCS(srand48 srand srandom umask) dnl AIX is unusual in that it wants all symbols resolved at link time @@ -19,4 +20,5 @@ dnl The following is for check... KRB5_BUILD_PROGRAM KRB5_BUILD_LIBOBJS KRB5_BUILD_LIBRARY_WITH_DEPS -V5_AC_OUTPUT_MAKEFILE +AC_CONFIG_SUBDIRS(kdb_db2) +V5_AC_OUTPUT_MAKEFILE(. kdb_db2) diff --git a/src/lib/kdb/decrypt_key.c b/src/lib/kdb/decrypt_key.c index 765e6f377..53d02ffb7 100644 --- a/src/lib/kdb/decrypt_key.c +++ b/src/lib/kdb/decrypt_key.c @@ -62,12 +62,11 @@ */ krb5_error_code -krb5_dbekd_decrypt_key_data(context, mkey, key_data, dbkey, keysalt) - krb5_context context; - const krb5_keyblock * mkey; - const krb5_key_data * key_data; - krb5_keyblock * dbkey; - krb5_keysalt * keysalt; +krb5_dbekd_decrypt_key_data( krb5_context context, + const krb5_keyblock * mkey, + const krb5_key_data * key_data, + krb5_keyblock * dbkey, + krb5_keysalt * keysalt) { krb5_error_code retval = 0; krb5_int16 tmplen; diff --git a/src/lib/kdb/encrypt_key.c b/src/lib/kdb/encrypt_key.c index aa259f900..13686a4ed 100644 --- a/src/lib/kdb/encrypt_key.c +++ b/src/lib/kdb/encrypt_key.c @@ -62,13 +62,12 @@ */ krb5_error_code -krb5_dbekd_encrypt_key_data(context, mkey, dbkey, keysalt, keyver, key_data) - krb5_context context; - const krb5_keyblock * mkey; - const krb5_keyblock * dbkey; - const krb5_keysalt * keysalt; - int keyver; - krb5_key_data * key_data; +krb5_dbekd_encrypt_key_data( krb5_context context, + const krb5_keyblock * mkey, + const krb5_keyblock * dbkey, + const krb5_keysalt * keysalt, + int keyver, + krb5_key_data * key_data) { krb5_error_code retval; krb5_octet * ptr; diff --git a/src/lib/kdb/err_handle.c b/src/lib/kdb/err_handle.c new file mode 100644 index 000000000..7d54441cb --- /dev/null +++ b/src/lib/kdb/err_handle.c @@ -0,0 +1,193 @@ +/********************************************************************** +* +* C %name: err_handle.c % +* Instance: idc_sec_1 +* Description: +* %created_by: spradeep % +* %date_created: Thu Apr 7 14:05:00 2005 % +* +**********************************************************************/ +#ifndef lint +static char *_csrc = "@(#) %filespec: err_handle.c~1 % (%full_filespec: err_handle.c~1:csrc:idc_sec#1 %)"; +#endif + +/* This file should be ideally be in util/et. But, for now thread + safety requirement stops me from putting there. if I do, then all + the applications have to link to pthread. */ + +#ifdef HAVE_PTHREAD_H +#include +#endif +#include "err_handle.h" +#include + +#ifdef NOVELL +krb5_errcode_2_string_func old_error_2_string = NULL; +#endif + +typedef struct { + char krb5_err_str[KRB5_MAX_ERR_STR + 1]; + long err_code; + krb5_err_subsystem subsystem; + krb5_context kcontext; +} krb5_err_struct_t; + +#ifdef HAVE_PTHREAD_H +static void tsd_key_destructor(void *data) +{ + free(data); +} + +static pthread_key_t krb5_err_key; + +static void init_err_handling( void ) +{ + assert(!pthread_key_create(&krb5_err_key, tsd_key_destructor)); +#ifdef NOVELL + old_error_2_string = error_message; + error_message = krb5_get_err_string; +#endif +} + +static pthread_once_t krb5_key_create = PTHREAD_ONCE_INIT; + +krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str ) +{ + int ret; + krb5_err_struct_t *err_struct; + pthread_once(&krb5_key_create, init_err_handling); + + err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key); + if( err_struct == NULL ) + { + err_struct = calloc(sizeof(krb5_err_struct_t), 1); + if( err_struct == NULL ) + return ENOMEM; + + if((ret = pthread_setspecific(krb5_err_key, err_struct))) + { + free( err_struct ); + return ret; + } + } + + err_struct->subsystem = subsystem; + err_struct->err_code = err_code; + err_struct->kcontext = kcontext; + if( err_struct->subsystem == krb5_err_have_str ) + { + strncpy( err_struct->krb5_err_str, str, sizeof(err_struct->krb5_err_str) ); + err_struct->krb5_err_str[KRB5_MAX_ERR_STR] = '\0'; + } + + return 0; +} + +const char * KRB5_CALLCONV krb5_get_err_string(long err_code) +{ + krb5_err_struct_t *err_struct; + pthread_once(&krb5_key_create, init_err_handling); + + err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key); + if( err_struct && (err_struct->subsystem == krb5_err_have_str) && (err_code == err_struct->err_code) ) + { + /* checking error code is for safety. + In case, the caller ignores a database error and calls other calls before doing com_err. + Though not perfect, caller should call krb5_clr_error before this*/ + err_struct->subsystem = krb5_err_unknown; + return err_struct->krb5_err_str; + } + + if( err_struct && (err_struct->subsystem == krb5_err_db) && (err_code == err_struct->err_code) ) + { + err_struct->subsystem = krb5_err_unknown; + return krb5_db_errcode2string(err_struct->kcontext, err_code); + } + + /* Error strings are not generated here. the remaining two cases are handled by the default error string convertor */ +#ifdef NOVELL + return old_error_2_string(err_code); +#else + return error_message (err_code); +#endif +} + +void krb5_clr_error() +{ + krb5_err_struct_t *err_struct; + pthread_once(&krb5_key_create, init_err_handling); + + err_struct = (krb5_err_struct_t*) pthread_getspecific(krb5_err_key); + if( err_struct ) + err_struct->subsystem = krb5_err_unknown; +} + +#else +krb5_err_struct_t krb5_err = {{0}, 0, 0, 0}; +krb5_boolean krb5_init_once = TRUE; + +static void init_err_handling( void ) +{ + if( krb5_init_once ) + { + old_error_2_string = error_message; + error_message = krb5_get_err_string; + krb5_init_once = FALSE; + } +} + +krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str ) +{ + krb5_err_struct_t *err_struct = &krb5_err; + + init_err_handling(); /* takes care for multiple inits */ + + err_struct->subsystem = subsystem; + err_struct->err_code = err_code; + err_struct->kcontext = kcontext; + if( err_struct->subsystem == krb5_err_have_str ) + { + strncpy( err_struct->krb5_err_str, str, sizeof(err_struct->krb5_err_str) ); + err_struct->krb5_err_str[KRB5_MAX_ERR_STR] = '\0'; + } + + return 0; +} + +const char * KRB5_CALLCONV krb5_get_err_string(long err_code) +{ + krb5_err_struct_t *err_struct = &krb5_err; + + init_err_handling(); /* takes care for multiple inits */ + + if( (err_struct->subsystem == krb5_err_have_str) && (err_code == err_struct->err_code) ) + { + /* checking error code is for safety. + In case, the caller ignores a database error and calls other calls before doing com_err. + Though not perfect, caller should call krb5_clr_error before this*/ + err_struct->subsystem = krb5_err_unknown; + return err_struct->krb5_err_str; + } + + if( (err_struct->subsystem == krb5_err_db) && (err_code == err_struct->err_code) ) + { + err_struct->subsystem = krb5_err_unknown; + return krb5_db_errcode2string(err_struct->kcontext, err_code); + } + + /* it is not generated here. the remaining two cases are handled by the default error string convertor */ + return old_error_2_string(err_code); + +} + +void krb5_clr_error() +{ + krb5_err_struct_t *err_struct = &krb5_err; + + init_err_handling(); /* takes care for multiple inits */ + + err_struct->subsystem = krb5_err_unknown; +} + + +#endif diff --git a/src/lib/kdb/err_handle.h b/src/lib/kdb/err_handle.h new file mode 100644 index 000000000..e123afc9f --- /dev/null +++ b/src/lib/kdb/err_handle.h @@ -0,0 +1,32 @@ +/********************************************************************** +* +* C Header: err_handle.h +* Instance: idc_sec_1 +* Description: +* %created_by: spradeep % +* %date_created: Thu Apr 7 14:05:33 2005 % +* +**********************************************************************/ +#ifndef _idc_sec_1_err_handle_h_H +#define _idc_sec_1_err_handle_h_H +#include + +/* Everything else goes here */ + +#define KRB5_MAX_ERR_STR 1024 +typedef enum krb5_err_subsystem { krb5_err_unknown = 0, /* no error or unknown system. Has to be probed */ + krb5_err_system, /* error in system call */ + krb5_err_krblib, /* error in kerberos library call, should lookup in the error table */ + krb5_err_have_str, /* error message is available in the string */ + krb5_err_db /* error is a database error, should be handled by calling DB */ +} krb5_err_subsystem; + +typedef krb5_error_code (*krb5_set_err_func_t)( krb5_context, krb5_err_subsystem, long, char*); + +krb5_error_code krb5_set_err( krb5_context kcontext, krb5_err_subsystem subsystem, long err_code, char *str ); + +const char * KRB5_CALLCONV krb5_get_err_string(long err_code); + +void krb5_clr_error(void); + +#endif diff --git a/src/lib/kdb/fetch_mkey.c b/src/lib/kdb/fetch_mkey.c deleted file mode 100644 index 5d63b8c0e..000000000 --- a/src/lib/kdb/fetch_mkey.c +++ /dev/null @@ -1,182 +0,0 @@ -/* - * lib/kdb/fetch_mkey.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * krb5_db_fetch_mkey(): - * Fetch a database master key from somewhere. - */ - -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government. It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#include "k5-int.h" - -/* these are available to other funcs, and the pointers may be reassigned */ - -char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1; -char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2; - -/* - * Get the KDC database master key from somewhere, filling it into *key. - * - * key->enctype should be set to the desired key type. - * - * if fromkeyboard is TRUE, then the master key is read as a password - * from the user's terminal. In this case, - * eblock should point to a block with an appropriate string_to_key function. - * if twice is TRUE, the password is read twice for verification. - * - * mname is the name of the key sought; this can be used by the string_to_key - * function or by some other method to isolate the desired key. - * - */ - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -krb5_error_code -krb5_db_fetch_mkey(context, mname, etype, fromkeyboard, twice, keyfile, - salt, key) - krb5_context context; - krb5_principal mname; - krb5_enctype etype; - krb5_boolean fromkeyboard; - krb5_boolean twice; - char *keyfile; - krb5_data * salt; - krb5_keyblock * key; -{ - krb5_error_code retval; - char password[BUFSIZ]; - krb5_data pwd; - unsigned int size = sizeof(password); - - if (fromkeyboard) { - krb5_data scratch; - - if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1, - twice ? krb5_mkey_pwd_prompt2 : 0, - password, &size))) - return(retval); - - pwd.data = password; - pwd.length = size; - if (!salt) { - retval = krb5_principal2salt(context, mname, &scratch); - if (retval) - return retval; - } - retval = krb5_c_string_to_key(context, etype, &pwd, salt?salt:&scratch, - key); - - if (!salt) - krb5_xfree(scratch.data); - memset(password, 0, sizeof(password)); /* erase it */ - return retval; - - } else { - /* from somewhere else */ - krb5_ui_2 enctype; - char defkeyfile[MAXPATHLEN+1]; - krb5_data *realm = krb5_princ_realm(context, mname); - FILE *kf; - - retval = 0; - key->magic = KV5M_KEYBLOCK; - (void) strcpy(defkeyfile, DEFAULT_KEYFILE_STUB); - (void) strncat(defkeyfile, realm->data, - min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, - realm->length)); - defkeyfile[sizeof(defkeyfile) - 1] = '\0'; - -#ifdef ANSI_STDIO - if (!(kf = fopen((keyfile) ? keyfile : defkeyfile, "rb"))) -#else - if (!(kf = fopen((keyfile) ? keyfile : defkeyfile, "r"))) -#endif - return KRB5_KDB_CANTREAD_STORED; - if (fread((krb5_pointer) &enctype, 2, 1, kf) != 1) { - retval = KRB5_KDB_CANTREAD_STORED; - goto errout; - } - if (key->enctype == ENCTYPE_UNKNOWN) - key->enctype = enctype; - else if (enctype != key->enctype) { - retval = KRB5_KDB_BADSTORED_MKEY; - goto errout; - } - if (fread((krb5_pointer) &key->length, - sizeof(key->length), 1, kf) != 1) { - retval = KRB5_KDB_CANTREAD_STORED; - goto errout; - } - if (!key->length || ((int) key->length) < 0) { - retval = KRB5_KDB_BADSTORED_MKEY; - goto errout; - } - - if (!(key->contents = (krb5_octet *)malloc(key->length))) { - retval = ENOMEM; - goto errout; - } - if (fread((krb5_pointer) key->contents, - sizeof(key->contents[0]), key->length, kf) - != key->length) { - retval = KRB5_KDB_CANTREAD_STORED; - memset(key->contents, 0, key->length); - free(key->contents); - key->contents = 0; - } else - retval = 0; - - errout: - (void) fclose(kf); - return retval; - } -} diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c new file mode 100644 index 000000000..c4afa1b25 --- /dev/null +++ b/src/lib/kdb/kdb5.c @@ -0,0 +1,2051 @@ +/* + * Include files + */ + +#ifdef HAVE_PTHREAD_H +#include +#endif + +#include +#include +#include +#include +#include +#include "kdb5.h" +#include + +/* currently DB2 policy related errors are exported from DAL. But other databases should set_err function to return string */ +#include "adb_err.h" + + +/* + * Type definitions + */ +#define KRB5_TL_DB_ARGS 0x7fff + +/* + * internal static variable + */ + +#ifdef HAVE_PTHREAD_H +/* static pthread_once_t db_inited = PTHREAD_ONCE_INIT; */ +static pthread_mutex_t db_lock = PTHREAD_MUTEX_INITIALIZER; +#else +/* static int db_inited = 0; */ +#endif + + +#ifdef _KDB5_STATIC_LINK +#undef _KDB5_DYNAMIC_LINK +#else +#undef _KDB5_DYNAMIC_LINK +/* to avoid redefinition problem */ +#define _KDB5_DYNAMIC_LINK +#endif + + +static db_library lib_list; + +/* + * Helper Functions + */ +#ifdef HAVE_PTHREAD_H + +/* + * KNOWN ISSUES with locking: This code does not handle a scenario where a library is thread-safe for different DB contexts, + * but not with the same context. It locks the complete DB library. If this is not the scenario, then lock has to be moved from + * db_library to kdb5_dal_handle. For now doing a pessimistic locking. + * + * If any thread does a DB lock, all the other threads are barred from accessing DB using this context (infact library + * because of the previous defect). + * This is with the assumption that, DB's lock code will take care of excluding other processes/machines from + * using the DB. But there could be a scenario where access by some other thread using the same context might corrupt the database. + */ + +static int kdb_lock_list() +{ + return pthread_mutex_lock( &db_lock ); +} + +static int kdb_unlock_list() +{ + return pthread_mutex_unlock( &db_lock ); +} + +static int kdb_init_lib_lock( db_library lib ) +{ + krb5_error_code retval; + if( (retval= pthread_mutex_init( &lib->lib_lock, NULL ))) + { + return retval; + } + + lib->lock_holder = pthread_self(); + lib->excl = 0; + lib->recursive_cnt = 0; + + return pthread_cond_init( &lib->unlocked, NULL ); +} + +static int kdb_destroy_lib_lock ( db_library lib ) +{ + krb5_error_code retval; + if( (retval = pthread_mutex_destroy( &lib->lib_lock )) ) + { + return retval; + } + + return pthread_cond_destroy( &lib->unlocked ); +} + +static int kdb_lock_lib_lock( db_library lib, krb5_boolean exclusive ) +{ + /* since, handle locked by one thread should not allow another thread to continue */ + krb5_error_code retval = 0; + pthread_t myid = pthread_self(); + + if( (retval = pthread_mutex_lock( &lib->lib_lock )) ) + return retval; + + while( (exclusive && (lib->excl || lib->recursive_cnt)) || + (!pthread_equal(lib->lock_holder, myid) && !lib->vftabl.is_thread_safe && lib->recursive_cnt) ) + { + /* exclusive lock held or some one using lock when exclusive is requested or library not-re-entrent */ + if( (retval = pthread_cond_wait(&lib->unlocked, &lib->lib_lock)) ) + return retval; + } + + /* exclusive lock and recursive_cnt allow a thread to lock even it already holds a lock */ + if( exclusive ) + lib->excl++; + + lib->recursive_cnt++; + + lib->lock_holder = myid; + + return pthread_mutex_unlock( &lib->lib_lock ); +} + +static int kdb_unlock_lib_lock( db_library lib, krb5_boolean exclusive ) +{ + krb5_error_code retval = 0; + + if( (retval = pthread_mutex_lock( &lib->lib_lock )) ) + return retval; + + lib->recursive_cnt--; + if( exclusive ) + lib->excl--; + + if( (retval = pthread_cond_broadcast( &lib->unlocked )) ) + return retval; + + return pthread_mutex_unlock( &lib->lib_lock ); +} + +#else /* no PTHREAD */ + +/* program is not using pthread. So, threads wont be there. No need to lock */ +#define kdb_lock_list() 0 +#define kdb_unlock_list() 0 +#define kdb_init_lib_lock(a) 0 +#define kdb_destroy_lib_lock(a) 0 +#define kdb_lock_lib_lock(a, b) 0 +#define kdb_unlock_lib_lock(a, b) 0 + +#endif /* end of HAVE_PTHREAD_H */ + + +static char * kdb_get_conf_section( krb5_context kcontext ) +{ + krb5_error_code status = 0; + char *result = NULL; + char *value = NULL; + + /* profile has to be initialized. If profile is not initialized, expect nothing less than a crash */ + status = profile_get_string( kcontext->profile, KDB_REALM_SECTION, /* realms */ + kcontext->default_realm, KDB_MODULE_POINTER, /* under the realm name, database_module */ + kcontext->default_realm, /* default value is the realm name itself */ + &value ); + + if( status ) + { + /* some problem */ + result = strdup( kcontext->default_realm ); + /* let NULL be handled by the caller */ + } + else + { + result = strdup( value ); + /* free profile string */ + profile_release_string( value ); + } + + return result; +} + +static char * kdb_get_library_name( krb5_context kcontext ) +{ + krb5_error_code status = 0; + char *result = NULL; + char *value = NULL; + char *lib = NULL; + + status = profile_get_string( kcontext->profile, KDB_REALM_SECTION, /* realms */ + kcontext->default_realm, KDB_MODULE_POINTER, /* under the realm name, database_module */ + kcontext->default_realm, /* default value is the realm name itself */ + &value ); + if( status ) + { + goto clean_n_exit; + } + + /* we got the module section. Get the library name from the module */ + status = profile_get_string( kcontext->profile, KDB_MODULE_SECTION, + value, KDB_LIB_POINTER, + "kdb_db2", /* default to db2 */ + &lib ); + + if( status ) + { + goto clean_n_exit; + } + + result = strdup( lib ); + clean_n_exit: + if( value ) + { + /* free profile string */ + profile_release_string( value ); + } + + if( lib ) + { + /* free profile string */ + profile_release_string( lib ); + } + + if( status ) + { + /* any error default to db2 */ + result = strdup( "kdb_db2" ); + } + return result; +} + +static void kdb_setup_opt_functions ( db_library lib ) +{ + if ( lib->vftabl.set_master_key == NULL ) + { + lib->vftabl.set_master_key = kdb_def_set_mkey; + } + + if ( lib->vftabl.get_master_key == NULL ) + { + lib->vftabl.get_master_key = kdb_def_get_mkey; + } + + if( lib->vftabl.fetch_master_key == NULL ) + { + lib->vftabl.fetch_master_key = krb5_db_def_fetch_mkey; + } + + if( lib->vftabl.verify_master_key == NULL ) + { + lib->vftabl.verify_master_key = krb5_def_verify_master_key; + } + + if( lib->vftabl.dbe_search_enctype == NULL ) + { + lib->vftabl.dbe_search_enctype = krb5_dbe_def_search_enctype; + } + + if( lib->vftabl.db_change_pwd == NULL ) + { + lib->vftabl.db_change_pwd = krb5_dbe_def_cpw; + } + + if( lib->vftabl.store_master_key == NULL ) + { + lib->vftabl.store_master_key = krb5_def_store_mkey; + } +} + +static int kdb_db2_pol_err_loaded = 0; +#ifdef _KDB5_STATIC_LINK +#define DEF_SYMBOL(a) extern kdb_vftabl krb5_db_vftabl_ ## a +#define GET_SYMBOL(a) (krb5_db_vftabl_ ## a) +static krb5_error_code kdb_load_library( krb5_context kcontext, char *lib_name, db_library *lib ) +{ + krb5_error_code status; + void *vftabl_addr = NULL; + char buf[KRB5_MAX_ERR_STR]; + + if( !strcmp("kdb_db2", lib_name) && (kdb_db2_pol_err_loaded == 0) ) + { + initialize_adb_error_table(); + kdb_db2_pol_err_loaded = 1; + } + + *lib = calloc( (size_t)1, sizeof(**lib)); + if( *lib == NULL ) + { + status = ENOMEM; + goto clean_n_exit; + } + + status = kdb_init_lib_lock( *lib ); + if( status ) + { + goto clean_n_exit; + } + + strcpy( (*lib)->name, lib_name ); + +#if !defined(KDB5_USE_LIB_KDB_DB2) && !defined(KDB5_USE_LIB_TEST) +#error No database module defined +#endif + +#ifdef KDB5_USE_LIB_KDB_DB2 + if( strcmp( lib_name, "kdb_db2" ) == 0 ) + { + DEF_SYMBOL(kdb_db2); + vftabl_addr = (void*)& GET_SYMBOL(kdb_db2); + } + else +#endif +#ifdef KDB5_USE_LIB_TEST + if( strcmp( lib_name, "test" ) == 0 ) + { + DEF_SYMBOL(test); + vftabl_addr = (void*) &GET_SYMBOL(test); + } else +#endif + { + sprintf( buf, "Program not built to support %s database type\n", lib_name ); + status = -1; + krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); + goto clean_n_exit; + } + + memcpy( &(*lib)->vftabl, vftabl_addr, sizeof(kdb_vftabl)); + + kdb_setup_opt_functions( *lib ); + + if( (status=(*lib)->vftabl.init_library(krb5_set_err)) ) + { + /* ERROR. library not initialized cleanly */ + sprintf( buf, "%s library initialization failed, error code %ld\n", lib_name, status ); + status = -1; + krb5_db_set_err(kcontext, krb5_err_have_str, status, buf); + goto clean_n_exit; + } + + + clean_n_exit: + if( status ) + { + free(*lib), *lib = NULL; + } + return status; +} + +#else + +static char *db_dl_location[] = DEFAULT_KDB_LIB_PATH; + +static krb5_error_code kdb_load_library( krb5_context kcontext, char *lib_name, db_library *lib ) +{ + krb5_error_code status = 0; + char dl_name[1024]; + int ndx; + void *vftabl_addr; + char *err_str = NULL; + + if( !strcmp("kdb_db2", lib_name) && (kdb_db2_pol_err_loaded == 0) ) + { + initialize_adb_error_table(); + kdb_db2_pol_err_loaded = 1; + } + + *lib = calloc( (size_t)1, sizeof(**lib)); + if( *lib == NULL ) + { + status = ENOMEM; + goto clean_n_exit; + } + + status = kdb_init_lib_lock( *lib ); + if( status ) + { + goto clean_n_exit; + } + + strcpy( (*lib)->name, lib_name ); + + for( ndx = 0; db_dl_location[ndx]; ndx++ ) + { + sprintf(dl_name, "%s/lib%s.so", db_dl_location[ndx], lib_name); + (*lib)->dl_handle = dlopen( dl_name, RTLD_NOW ); + if( (*lib)->dl_handle ) + { + /* found the module */ + sprintf( dl_name, "krb5_db_vftabl_%s", lib_name ); + + dlerror(); + vftabl_addr = dlsym( (*lib)->dl_handle, dl_name ); + if( vftabl_addr ) + { + memcpy( &(*lib)->vftabl, vftabl_addr, sizeof(kdb_vftabl)); + + kdb_setup_opt_functions( *lib ); + + if( (status = (*lib)->vftabl.init_library(krb5_set_err)) ) + { + /* ERROR. library not initialized cleanly */ + goto clean_n_exit; + + } + } + else + { + status = -1; + krb5_set_err(kcontext, krb5_err_have_str, status, dlerror()); + goto clean_n_exit; + } + break; + } + else + { + /* set the error. Later if we find everything fine.. we will reset this */ + err_str = dlerror(); +/* fprintf(stderr, "Error loading library %s\n", t); */ + } + } + + if( ! (*lib)->dl_handle ) + { + /* library not found in the given list. Error str is already set */ + status = -1; + krb5_set_err(kcontext, krb5_err_have_str, status, err_str); + goto clean_n_exit; + } + + clean_n_exit: + if( status ) + { + if( *lib ) + { + kdb_destroy_lib_lock( *lib ); + if( (*lib)->dl_handle ) + { + dlclose( (*lib)->dl_handle ); + } + free(*lib); + *lib = NULL; + } + } + return status; +} + +#endif /* end of _KDB5_STATIC_LINK */ + +static krb5_error_code kdb_find_library( krb5_context kcontext, char *lib_name, db_library *lib) +{ + /* lock here so that no two threads try to do the same at the same time */ + krb5_error_code status = 0; + int locked = 0; + db_library curr_elt, prev_elt = NULL; + + if( (status = kdb_lock_list()) != 0 ) + { + goto clean_n_exit; + } + locked = 1; + + curr_elt = lib_list; + while ( curr_elt != NULL ) + { + if( strcmp( lib_name, curr_elt->name ) == 0 ) + { + *lib = curr_elt; + goto clean_n_exit; + } + prev_elt = curr_elt; + curr_elt = curr_elt->next; + } + + /* module not found. create and add to list */ + status = kdb_load_library( kcontext, lib_name, lib); + if( status ) + { + goto clean_n_exit; + } + + if( prev_elt ) + { + /* prev_elt points to the last element in the list */ + prev_elt->next = *lib; + (*lib)->prev = prev_elt; + } + else + { + lib_list = *lib; + } + + clean_n_exit: + if( *lib ) + { + (*lib)->reference_cnt++; + } + + if( locked ) + { + kdb_unlock_list(); + } + + return status; +} + + +static krb5_error_code kdb_free_library( db_library lib) +{ + krb5_error_code status = 0; + int locked = 0; + + if( (status = kdb_lock_list()) != 0 ) + { + goto clean_n_exit; + } + locked = 1; + + lib->reference_cnt--; + + if( lib->reference_cnt == 0 ) + { + status = lib->vftabl.fini_library(); + if( status ) + { + goto clean_n_exit; + } + + /* close the library */ + if( lib->dl_handle ) + { + dlclose( lib->dl_handle ); + } + + kdb_destroy_lib_lock( lib ); + + if( lib->prev == NULL ) + { + /* first element in the list */ + lib_list = lib->next; + } + else + { + lib->prev->next = lib->next; + } + + if( lib->next ) + { + lib->next->prev = lib->prev; + } + free(lib); + } + + clean_n_exit: + if( locked ) + { + kdb_unlock_list(); + } + + return status; +} + +static krb5_error_code kdb_setup_lib_handle( krb5_context kcontext ) +{ + char *library = NULL; + krb5_error_code status = 0; + db_library lib = NULL; + kdb5_dal_handle *dal_handle = NULL; + + dal_handle = calloc( (size_t)1, sizeof(kdb5_dal_handle) ); + if( dal_handle == NULL ) + { + status = ENOMEM; + goto clean_n_exit; + } + + library = kdb_get_library_name( kcontext ); + if( library == NULL ) + { + status = -1; + goto clean_n_exit; + } + + status = kdb_find_library( kcontext, library, &lib ); + if( status ) + { + goto clean_n_exit; + } + + dal_handle->lib_handle = lib; + kcontext->db_context = (void *) dal_handle; + + clean_n_exit: + free(library); + + if( status ) + { + free( dal_handle ); + if( lib ) + { + kdb_free_library( lib ); + } + } + + return status; +} + + +static krb5_error_code kdb_free_lib_handle( krb5_context kcontext ) +{ + krb5_error_code status = 0; + + status = kdb_free_library( ((kdb5_dal_handle *)kcontext->db_context)->lib_handle ); + if( status ) + { + goto clean_n_exit; + } + + free( kcontext->db_context ); + kcontext->db_context = NULL; + + clean_n_exit: + return status; +} + +/* + * External functions... DAL API + */ +void krb5_db_clr_error() +{ + krb5_clr_error(); +} + +krb5_error_code krb5_db_open( krb5_context kcontext, char **db_args, int mode ) +{ + krb5_error_code status = 0; + char *section = NULL; + kdb5_dal_handle *dal_handle; + char buf[KRB5_MAX_ERR_STR]; + + section = kdb_get_conf_section( kcontext ); + if( section == NULL ) + { + sprintf( buf, "unable to determine configuration section for realm %s\n", kcontext->default_realm ); + status = -1; + krb5_set_err(kcontext, krb5_err_have_str, status, buf); + goto clean_n_exit; + } + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.init_module(kcontext, section, db_args, mode ); + + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + if( section ) + free(section); + return status; +} + +const char * krb5_db_errcode2string ( krb5_context kcontext, long err_code ) +{ + const char *err_str = NULL; + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + err_str = dal_handle->lib_handle->vftabl.errcode_2_string(kcontext, err_code ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return err_str; +} + + +krb5_error_code krb5_db_inited ( krb5_context kcontext ) +{ + return !(kcontext && kcontext->db_context && + ((kdb5_dal_handle*)kcontext->db_context)->db_context); +} + +krb5_error_code krb5_db_create ( krb5_context kcontext, char **db_args ) +{ + krb5_error_code status = 0; + char *section = NULL; + kdb5_dal_handle *dal_handle; + char buf[KRB5_MAX_ERR_STR]; + + section = kdb_get_conf_section( kcontext ); + if( section == NULL ) + { + sprintf( buf, "unable to determine configuration section for realm %s\n", kcontext->default_realm ); + status = -1; + krb5_set_err(kcontext, krb5_err_have_str, status, buf); + goto clean_n_exit; + } + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_create(kcontext, section, db_args ); + + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + if( section ) + free(section); + return status; +} + +krb5_error_code krb5_db_fini ( krb5_context kcontext ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + /* module not loaded. So nothing to be done */ + goto clean_n_exit; + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.fini_module( kcontext ); + + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + if( status ) + { + goto clean_n_exit; + } + + status = kdb_free_lib_handle( kcontext ); + + clean_n_exit: + return status; +} + + +krb5_error_code krb5_db_destroy ( krb5_context kcontext, char **db_args ) +{ + krb5_error_code status = 0; + char * section = NULL; + kdb5_dal_handle *dal_handle; + char buf[KRB5_MAX_ERR_STR]; + + section = kdb_get_conf_section( kcontext ); + if( section == NULL ) + { + sprintf( buf, "unable to determine configuration section for realm %s\n", kcontext->default_realm ); + status = -1; + krb5_set_err(kcontext, krb5_err_have_str, status, buf); + goto clean_n_exit; + } + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_destroy(kcontext, section, db_args ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + if( section ) + free(section); + return status; +} + +krb5_error_code krb5_db_get_age ( krb5_context kcontext, char *db_name, time_t *t ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_get_age(kcontext, db_name, t ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_set_option ( krb5_context kcontext, int option, void *value ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_set_option(kcontext, option, value ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_lock ( krb5_context kcontext, int lock_mode ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + /* acquire an exclusive lock, ensures no other thread uses this context */ + status = kdb_lock_lib_lock( dal_handle->lib_handle, TRUE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_lock(kcontext, lock_mode ); + + /* exclusive lock is still held, so no other thread could use this context */ + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_unlock ( krb5_context kcontext ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + /* normal lock acquired and exclusive lock released */ + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_unlock( kcontext ); + + kdb_unlock_lib_lock( dal_handle->lib_handle, TRUE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_get_principal ( krb5_context kcontext, + krb5_const_principal search_for, + krb5_db_entry *entries, + int *nentries, + krb5_boolean *more ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_get_principal(kcontext, search_for, + entries, nentries, more); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_free_principal ( krb5_context kcontext, + krb5_db_entry *entry, + int count ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_free_principal( kcontext, entry, count ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + + +krb5_error_code krb5_db_put_principal ( krb5_context kcontext, + krb5_db_entry *entries, + int *nentries ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + char **db_args = NULL; + krb5_tl_data *prev, *curr, *next; + int db_args_size = 0; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + /* Giving db_args as part of tl data causes, db2 to store the tl_data as such. + To prevent this, tl_data is collated and passed as a sepearte argument. Currently supports only one principal. + but passing it as a seperate argument makes it difficult for kadmin remote to pass arguments to server */ + prev=NULL, curr=entries->tl_data; + while(curr) + { + if( curr->tl_data_type == KRB5_TL_DB_ARGS ) + { + char **t; + /* since this is expected to be NULL terminated string and this could come from any client, do a check + before passing it to db. */ + if( ((char*) curr->tl_data_contents)[curr->tl_data_length-1] != '\0' ) + { + /* not null terminated. Dangerous input */ + status = EINVAL; + goto clean_n_exit; + } + + db_args_size++; + t = realloc( db_args, sizeof(char*) * (db_args_size+1)); /* 1 for NULL */ + if( t == NULL ) + { + status = ENOMEM; + goto clean_n_exit; + } + + db_args = t; + db_args[db_args_size-1] = (char*)curr->tl_data_contents; + db_args[db_args_size] = NULL; + + next = curr->tl_data_next; + if( prev == NULL ) + { + /* current node is the first in the linked list. remove it */ + entries->tl_data = curr->tl_data_next; + } + else + { + prev->tl_data_next = curr->tl_data_next; + } + entries->n_tl_data--; + krb5_db_free( kcontext, curr ); + + /* previous does not change */ + curr = next; + } + else + { + prev = curr; + curr = curr->tl_data_next; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_put_principal( kcontext, entries, + nentries, db_args ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + while( db_args_size ) + { + if( db_args[db_args_size-1] ) + krb5_db_free(kcontext, db_args[db_args_size-1]); + + db_args_size--; + } + + if( db_args ) + free(db_args); + + return status; +} + +krb5_error_code krb5_db_delete_principal ( krb5_context kcontext, + krb5_principal search_for, + int *nentries ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_delete_principal( kcontext, search_for, nentries ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_iterate ( krb5_context kcontext, + char *match_entry, + int (*func) (krb5_pointer, krb5_db_entry *), + krb5_pointer func_arg ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_iterate( kcontext, + match_entry, + func, + func_arg ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_supported_realms ( krb5_context kcontext, + char **realms ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_supported_realms( kcontext, realms ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_free_supported_realms ( krb5_context kcontext, + char **realms ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_free_supported_realms( kcontext, realms ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_set_master_key_ext ( krb5_context kcontext, + char *pwd, + krb5_keyblock *key ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.set_master_key( kcontext, + pwd, + key ); + + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_set_mkey ( krb5_context context, + krb5_keyblock *key) +{ + return krb5_db_set_master_key_ext ( context, NULL, key ); +} + + +krb5_error_code krb5_db_get_mkey ( krb5_context kcontext, + krb5_keyblock **key ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + /* lets use temp key and copy it later to avoid memory problems when freed by the caller */ + status = dal_handle->lib_handle->vftabl.get_master_key( kcontext, + key ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_store_master_key ( krb5_context kcontext, + char *db_arg, + krb5_principal mname, + krb5_keyblock *key, + char *master_pwd) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.store_master_key( kcontext, + db_arg, + mname, + key, + master_pwd); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + + +char *krb5_mkey_pwd_prompt1 = KRB5_KDC_MKEY_1; +char *krb5_mkey_pwd_prompt2 = KRB5_KDC_MKEY_2; + + +krb5_error_code krb5_db_fetch_mkey ( krb5_context context, + krb5_principal mname, + krb5_enctype etype, + krb5_boolean fromkeyboard, + krb5_boolean twice, + char *db_args, + krb5_data *salt, + krb5_keyblock *key) +{ + krb5_error_code retval; + char password[BUFSIZ]; + krb5_data pwd; + unsigned int size = sizeof(password); + int kvno; + krb5_keyblock tmp_key; + + memset( &tmp_key, 0, sizeof(tmp_key) ); + + if (fromkeyboard) { + krb5_data scratch; + + if ((retval = krb5_read_password(context, krb5_mkey_pwd_prompt1, + twice ? krb5_mkey_pwd_prompt2 : 0, + password, &size))) + { + goto clean_n_exit; + } + + pwd.data = password; + pwd.length = size; + if (!salt) { + retval = krb5_principal2salt(context, mname, &scratch); + if (retval) + goto clean_n_exit; + } + retval = krb5_c_string_to_key(context, etype, &pwd, salt?salt:&scratch, + key); + + if (!salt) + krb5_xfree(scratch.data); + memset(password, 0, sizeof(password)); /* erase it */ + + } else { + kdb5_dal_handle *dal_handle; + + if( context->db_context == NULL ) + { + retval = kdb_setup_lib_handle( context ); + if( retval ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) context->db_context; + retval = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( retval ) + { + goto clean_n_exit; + } + + tmp_key.enctype = key->enctype; + retval = dal_handle->lib_handle->vftabl.fetch_master_key( context, + mname, + &tmp_key, + &kvno, + db_args); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + if( retval ) + { + goto clean_n_exit; + } + + key->contents = malloc( tmp_key.length ); + if( key->contents == NULL ) + { + retval = ENOMEM; + goto clean_n_exit; + } + + key->magic = tmp_key.magic; + key->enctype = tmp_key.enctype; + key->length = tmp_key.length; + memcpy(key->contents, tmp_key.contents, tmp_key.length); + } + + clean_n_exit: + if( tmp_key.contents ) + { + memset( tmp_key.contents, 0, tmp_key.length ); + krb5_db_free( context, tmp_key.contents ); + } + return retval; +} + + +krb5_error_code krb5_db_verify_master_key ( krb5_context kcontext, + krb5_principal mprinc, + krb5_keyblock *mkey ) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.verify_master_key( kcontext, + mprinc, + mkey ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + + +void *krb5_db_alloc( krb5_context kcontext, + void *ptr, + size_t size ) +{ + krb5_error_code status; + kdb5_dal_handle *dal_handle; + void *new_ptr = NULL; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + + new_ptr = dal_handle->lib_handle->vftabl.db_alloc( kcontext, + ptr, + size ); + + clean_n_exit: + return new_ptr; +} + +void krb5_db_free( krb5_context kcontext, + void *ptr) +{ + krb5_error_code status; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + + dal_handle->lib_handle->vftabl.db_free( kcontext, + ptr ); + + clean_n_exit: + return; +} + +/* has to be modified */ + +krb5_error_code +krb5_dbe_find_enctype( krb5_context kcontext, + krb5_db_entry *dbentp, + krb5_int32 ktype, + krb5_int32 stype, + krb5_int32 kvno, + krb5_key_data **kdatap) +{ + krb5_int32 start = 0; + return krb5_dbe_search_enctype( kcontext, dbentp, &start, ktype, stype, kvno, kdatap ); +} + + +krb5_error_code krb5_dbe_search_enctype ( krb5_context kcontext, + krb5_db_entry *dbentp, + krb5_int32 *start, + krb5_int32 ktype, + krb5_int32 stype, + krb5_int32 kvno, + krb5_key_data **kdatap) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.dbe_search_enctype( kcontext, + dbentp, + start, + ktype, + stype, + kvno, + kdatap ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + + +#define REALM_SEP_STRING "@" + +krb5_error_code +krb5_db_setup_mkey_name ( krb5_context context, + const char *keyname, + const char *realm, + char **fullname, + krb5_principal *principal) +{ + krb5_error_code retval; + size_t keylen; + size_t rlen = strlen(realm); + char *fname; + + if (!keyname) + keyname = KRB5_KDB_M_NAME; /* XXX external? */ + + keylen = strlen(keyname); + + fname = malloc(keylen+rlen+strlen(REALM_SEP_STRING)+1); + if (!fname) + return ENOMEM; + + strcpy(fname, keyname); + strcat(fname, REALM_SEP_STRING); + strcat(fname, realm); + + if ((retval = krb5_parse_name(context, fname, principal))) + return retval; + if (fullname) + *fullname = fname; + else + free(fname); + return 0; +} + + + + +krb5_error_code +krb5_dbe_lookup_last_pwd_change(context, entry, stamp) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp * stamp; +{ + krb5_tl_data tl_data; + krb5_error_code code; + krb5_int32 tmp; + + tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; + + if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) + return(code); + + if (tl_data.tl_data_length != 4) { + *stamp = 0; + return(0); + } + + krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp); + + *stamp = (krb5_timestamp) tmp; + + return(0); +} + +krb5_error_code +krb5_dbe_lookup_tl_data(context, entry, ret_tl_data) + krb5_context context; + krb5_db_entry * entry; + krb5_tl_data * ret_tl_data; +{ + krb5_tl_data *tl_data; + + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { + if (tl_data->tl_data_type == ret_tl_data->tl_data_type) { + *ret_tl_data = *tl_data; + return(0); + } + } + + /* if the requested record isn't found, return zero bytes. + if it ever means something to have a zero-length tl_data, + this code and its callers will have to be changed */ + + ret_tl_data->tl_data_length = 0; + ret_tl_data->tl_data_contents = NULL; + return(0); +} + +krb5_error_code +krb5_dbe_create_key_data(context, entry) + krb5_context context; + krb5_db_entry * entry; +{ + if ((entry->key_data = + (krb5_key_data *) krb5_db_alloc(context, entry->key_data, + (sizeof(krb5_key_data)* + (entry->n_key_data + 1)))) == NULL) + return(ENOMEM); + + + memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data)); + entry->n_key_data++; + + return 0; +} + +krb5_error_code +krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp mod_date; + krb5_const_principal mod_princ; +{ + krb5_tl_data tl_data; + + krb5_error_code retval = 0; + krb5_octet * nextloc = 0; + char * unparse_mod_princ = 0; + unsigned int unparse_mod_princ_size; + + if ((retval = krb5_unparse_name(context, mod_princ, + &unparse_mod_princ))) + return(retval); + + unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; + + if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) + == NULL) { + free(unparse_mod_princ); + return(ENOMEM); + } + + tl_data.tl_data_type = KRB5_TL_MOD_PRINC; + tl_data.tl_data_length = unparse_mod_princ_size + 4; + tl_data.tl_data_contents = nextloc; + + /* Mod Date */ + krb5_kdb_encode_int32(mod_date, nextloc); + + /* Mod Princ */ + memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size); + + retval = krb5_dbe_update_tl_data(context, entry, &tl_data); + + free(unparse_mod_princ); + free(nextloc); + + return(retval); +} + +krb5_error_code +krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp * mod_time; + krb5_principal * mod_princ; +{ + krb5_tl_data tl_data; + krb5_error_code code; + + tl_data.tl_data_type = KRB5_TL_MOD_PRINC; + + if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) + return(code); + + if ((tl_data.tl_data_length < 5) || + (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0')) + return(KRB5_KDB_TRUNCATED_RECORD); + + /* Mod Date */ + krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time); + + /* Mod Princ */ + if ((code = krb5_parse_name(context, + (const char *) (tl_data.tl_data_contents+4), + mod_princ))) + return(code); + + return(0); +} + + +krb5_error_code +krb5_dbe_update_last_pwd_change(context, entry, stamp) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp stamp; +{ + krb5_tl_data tl_data; + krb5_octet buf[4]; /* this is the encoded size of an int32 */ + + tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; + tl_data.tl_data_length = sizeof(buf); + krb5_kdb_encode_int32((krb5_int32) stamp, buf); + tl_data.tl_data_contents = buf; + + return(krb5_dbe_update_tl_data(context, entry, &tl_data)); +} + + +krb5_error_code +krb5_dbe_update_tl_data(context, entry, new_tl_data) + krb5_context context; + krb5_db_entry * entry; + krb5_tl_data * new_tl_data; +{ + krb5_tl_data * tl_data = NULL; + krb5_octet * tmp; + + /* copy the new data first, so we can fail cleanly if malloc() + fails */ + if ((tmp = (krb5_octet *) krb5_db_alloc(context, NULL, new_tl_data->tl_data_length)) == NULL) + return(ENOMEM); + + /* Find an existing entry of the specified type and point at + it, or NULL if not found */ + + if( new_tl_data->tl_data_type != KRB5_TL_DB_ARGS ) /* db_args can be multiple */ + { + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) + if (tl_data->tl_data_type == new_tl_data->tl_data_type) + break; + } + + /* if necessary, chain a new record in the beginning and point at it */ + + if (!tl_data) { + if ((tl_data = (krb5_tl_data *) krb5_db_alloc(context, NULL, sizeof(krb5_tl_data))) + == NULL) { + free(tmp); + return(ENOMEM); + } + memset( tl_data, 0, sizeof(krb5_tl_data)); + tl_data->tl_data_next = entry->tl_data; + entry->tl_data = tl_data; + entry->n_tl_data++; + } + + /* fill in the record */ + + if (tl_data->tl_data_contents) + krb5_db_free(context, tl_data->tl_data_contents); + + tl_data->tl_data_type = new_tl_data->tl_data_type; + tl_data->tl_data_length = new_tl_data->tl_data_length; + tl_data->tl_data_contents = tmp; + memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length); + + return(0); +} + + + +/* change password functions */ +krb5_error_code +krb5_dbe_cpw( krb5_context kcontext, + krb5_keyblock * master_key, + krb5_key_salt_tuple * ks_tuple, + int ks_tuple_count, + char * passwd, + int new_kvno, + krb5_boolean keepold, + krb5_db_entry * db_entry) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_change_pwd( kcontext, + master_key, + ks_tuple, + ks_tuple_count, + passwd, + new_kvno, + keepold, + db_entry ); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + + +/* policy management functions */ +krb5_error_code krb5_db_create_policy( krb5_context kcontext, osa_policy_ent_t policy) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_create_policy(kcontext, policy); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_get_policy ( krb5_context kcontext, char *name, osa_policy_ent_t *policy, int *cnt) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_get_policy(kcontext, name, policy, cnt); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_put_policy( krb5_context kcontext, osa_policy_ent_t policy) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_put_policy(kcontext, policy); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_iter_policy( krb5_context kcontext, char *match_entry, osa_adb_iter_policy_func func, void *data) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_iter_policy(kcontext, match_entry, func, data); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +krb5_error_code krb5_db_delete_policy( krb5_context kcontext, char *policy) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + status = dal_handle->lib_handle->vftabl.db_delete_policy(kcontext, policy); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return status; +} + +void krb5_db_free_policy( krb5_context kcontext, osa_policy_ent_t policy) +{ + krb5_error_code status = 0; + kdb5_dal_handle *dal_handle; + + if( kcontext->db_context == NULL ) + { + status = kdb_setup_lib_handle( kcontext ); + if( status ) + { + goto clean_n_exit; + } + } + + dal_handle = (kdb5_dal_handle *) kcontext->db_context; + status = kdb_lock_lib_lock( dal_handle->lib_handle, FALSE ); + if( status ) + { + goto clean_n_exit; + } + + dal_handle->lib_handle->vftabl.db_free_policy(kcontext, policy); + kdb_unlock_lib_lock( dal_handle->lib_handle, FALSE ); + + clean_n_exit: + return; +} + diff --git a/src/lib/kdb/kdb5.h b/src/lib/kdb/kdb5.h new file mode 100644 index 000000000..93b594a52 --- /dev/null +++ b/src/lib/kdb/kdb5.h @@ -0,0 +1,219 @@ +#ifndef _KRB5_KDB5_H_ +#define _KRB5_KDB5_H_ + +#if HAVE_UNISTD_H +#include +#endif + +#include +#include +#include +#include +#include "err_handle.h" + +#define KDB_MAX_DB_NAME 128 +#define KDB_REALM_SECTION "realms" +#define KDB_MODULE_POINTER "database_module" +#define KDB_MODULE_SECTION "db_modules" +#define KDB_LIB_POINTER "db_library" +#define KDB_DATABASE_CONF_FILE DEFAULT_SECURE_PROFILE_PATH +#define KDB_DATABASE_ENV_PROF KDC_PROFILE_ENV + +#define KRB5_KDB_OPEN_RW 0 +#define KRB5_KDB_OPEN_RO 1 + +#define KRB5_KDB_OPT_SET_DB_NAME 0 +#define KRB5_KDB_OPT_SET_LOCK_MODE 1 + +#define KRB5_DB_GET_DB_CONTEXT(kcontext) ( ((kdb5_dal_handle*) (kcontext)->db_context)->db_context ) +#define KRB5_DB_GET_PROFILE(kcontext) ( (kcontext)->profile ) +#define KRB5_DB_GET_REALM(kcontext) ( (kcontext)->default_realm ) + +#ifndef KRB5_DB_LOCKMODE_SHARED +#define KRB5_DB_LOCKMODE_SHARED 0x0001 +#endif + +#ifndef KRB5_DB_LOCKMODE_EXCLUSIVE +#define KRB5_DB_LOCKMODE_EXCLUSIVE 0x0002 +#endif + +#ifndef KRB5_DB_LOCKMODE_DONTBLOCK +#define KRB5_DB_LOCKMODE_DONTBLOCK 0x0004 +#endif + +#ifndef KRB5_DB_LOCKMODE_PERMANENT +#define KRB5_DB_LOCKMODE_PERMANENT 0x0008 +#endif + +typedef struct _kdb_vftabl{ + short int maj_ver; + short int min_ver; + + short int is_thread_safe; + + krb5_error_code (*init_library)(krb5_set_err_func_t); + krb5_error_code (*fini_library)(); + krb5_error_code (*init_module) ( krb5_context kcontext, + char * conf_section, + char ** db_args, + int mode ); + + krb5_error_code (*fini_module) ( krb5_context kcontext ); + + krb5_error_code (*db_create) ( krb5_context kcontext, + char * conf_section, + char ** db_args ); + + krb5_error_code (*db_destroy) ( krb5_context kcontext, + char *conf_section, + char ** db_args ); + + krb5_error_code (*db_get_age) ( krb5_context kcontext, + char *db_name, + time_t *age ); + + krb5_error_code (*db_set_option) ( krb5_context kcontext, + int option, + void *value ); + + krb5_error_code (*db_lock) ( krb5_context kcontext, + int mode ); + + krb5_error_code (*db_unlock) ( krb5_context kcontext); + + krb5_error_code (*db_get_principal) ( krb5_context kcontext, + krb5_const_principal search_for, + krb5_db_entry *entries, + int *nentries, + krb5_boolean *more ); + + krb5_error_code (*db_free_principal) ( krb5_context kcontext, + krb5_db_entry *entry, + int count ); + + krb5_error_code (*db_put_principal) ( krb5_context kcontext, + krb5_db_entry *entries, + int *nentries, + char **db_args); + + krb5_error_code (*db_delete_principal) ( krb5_context kcontext, + krb5_const_principal search_for, + int *nentries ); + + krb5_error_code (*db_iterate) ( krb5_context kcontext, + char *match_entry, + int (*func) (krb5_pointer, krb5_db_entry *), + krb5_pointer func_arg ); + + krb5_error_code (*db_create_policy) ( krb5_context kcontext, + osa_policy_ent_t policy ); + + krb5_error_code (*db_get_policy) ( krb5_context kcontext, + char *name, + osa_policy_ent_t *policy, + int *cnt); + + krb5_error_code (*db_put_policy) ( krb5_context kcontext, + osa_policy_ent_t policy ); + + krb5_error_code (*db_iter_policy) ( krb5_context kcontext, + char *match_entry, + osa_adb_iter_policy_func func, + void *data ); + + + krb5_error_code (*db_delete_policy) ( krb5_context kcontext, + char *policy ); + + void (*db_free_policy) ( krb5_context kcontext, + osa_policy_ent_t val ); + + krb5_error_code (*db_supported_realms) ( krb5_context kcontext, + char **realms ); + + krb5_error_code (*db_free_supported_realms) ( krb5_context kcontext, + char **realms ); + + + const char * (*errcode_2_string) ( krb5_context kcontext, + long err_code ); + + void * (*db_alloc) (krb5_context kcontext, void *ptr, size_t size); + void (*db_free) (krb5_context kcontext, void *ptr); + + + + /* optional functions */ + krb5_error_code (*set_master_key) ( krb5_context kcontext, + char *pwd, + krb5_keyblock *key); + + krb5_error_code (*get_master_key) ( krb5_context kcontext, + krb5_keyblock **key); + + + krb5_error_code (*setup_master_key_name) ( krb5_context kcontext, + char *keyname, + char *realm, + char **fullname, + krb5_principal *principal); + + krb5_error_code (*store_master_key) ( krb5_context kcontext, + char *db_arg, + krb5_principal mname, + krb5_keyblock *key, + char *master_pwd); + + krb5_error_code (*fetch_master_key) ( krb5_context kcontext, + krb5_principal mname, + krb5_keyblock *key, + int *kvno, + char *db_args); + + krb5_error_code (*verify_master_key) ( krb5_context kcontext, + krb5_principal mprinc, + krb5_keyblock *mkey ); + + krb5_error_code (*dbe_search_enctype) ( krb5_context kcontext, + krb5_db_entry *dbentp, + krb5_int32 *start, + krb5_int32 ktype, + krb5_int32 stype, + krb5_int32 kvno, + krb5_key_data **kdatap); + + + krb5_error_code + (*db_change_pwd) ( krb5_context context, + krb5_keyblock * master_key, + krb5_key_salt_tuple * ks_tuple, + int ks_tuple_count, + char * passwd, + int new_kvno, + krb5_boolean keepold, + krb5_db_entry * db_entry); + +} kdb_vftabl; + +typedef struct _db_library { + char name[KDB_MAX_DB_NAME]; + int reference_cnt; +#ifdef HAVE_PTHREAD_H + pthread_mutex_t lib_lock; + pthread_cond_t unlocked; /* To check whether some one has called db_unlock */ + int recursive_cnt; /* this is used as lock to help recursive locking */ + pthread_t lock_holder; + int excl; +#endif + void *dl_handle; + kdb_vftabl vftabl; + struct _db_library *next, *prev; +} *db_library; + +typedef struct _kdb5_dal_handle +{ + void *db_context; /* helps us to change db_library without affecting modules to some extend */ + db_library lib_handle; +} kdb5_dal_handle; + +#endif /* end of _KRB5_KDB5_H_ */ diff --git a/src/lib/kdb/kdb_compat.h b/src/lib/kdb/kdb_compat.h deleted file mode 100644 index 540d4a249..000000000 --- a/src/lib/kdb/kdb_compat.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * lib/kdb/kdb_compat.h - * - * Copyright 1994 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * KDC Database interface definitions. - */ - - -typedef struct _old_krb5_encrypted_keyblock { - krb5_enctype enctype; - int length; - krb5_octet *contents; -} old_krb5_encrypted_keyblock; - -typedef struct old_krb5_principal_data { - krb5_magic magic; - krb5_data realm; - krb5_data *data; /* An array of strings */ - krb5_int32 length; - krb5_int32 type; -} old_krb5_principal_data; - -typedef old_krb5_principal_data *old_krb5_principal; - - -/* - * Note --- this structure cannot be modified without changing the - * database version number in libkdb.a - */ -typedef struct _old_krb5_db_entry { - old_krb5_principal principal; - old_krb5_encrypted_keyblock key; - krb5_kvno kvno; - krb5_deltat max_life; - krb5_deltat max_renewable_life; - krb5_kvno mkvno; /* master encryption key vno */ - - krb5_timestamp expiration; /* This is when the client expires */ - krb5_timestamp pw_expiration; /* This is when its password does */ - krb5_timestamp last_pwd_change; /* Last time of password change */ - krb5_timestamp last_success; /* Last successful password */ - - krb5_timestamp last_failed; /* Last failed password attempt */ - krb5_kvno fail_auth_count; /* # of failed password attempts */ - - old_krb5_principal mod_name; - krb5_timestamp mod_date; - krb5_flags attributes; - krb5_int32 salt_type:8, - salt_length:24; - krb5_octet *salt; - old_krb5_encrypted_keyblock alt_key; - krb5_int32 alt_salt_type:8, - alt_salt_length:24; - krb5_octet *alt_salt; - - krb5_int32 expansion[8]; -} old_krb5_db_entry; - diff --git a/src/lib/kdb/kdb_cpw.c b/src/lib/kdb/kdb_cpw.c index 962a2b540..f873a3945 100644 --- a/src/lib/kdb/kdb_cpw.c +++ b/src/lib/kdb/kdb_cpw.c @@ -52,7 +52,6 @@ */ #include "k5-int.h" -#include "krb5/adm.h" #include #include @@ -86,11 +85,11 @@ cleanup_key_data(context, count, data) for (i = 0; i < count; i++) { for (j = 0; j < data[i].key_data_ver; j++) { if (data[i].key_data_length[j]) { - free(data[i].key_data_contents[j]); + krb5_db_free(context, data[i].key_data_contents[j]); } } } - free(data); + krb5_db_free(context, data); } static krb5_error_code @@ -106,8 +105,13 @@ add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno) krb5_keyblock key; krb5_db_entry krbtgt_entry; krb5_boolean more; - int max_kvno, one, i, j; + int max_kvno, one, i, j, k; krb5_error_code retval; + krb5_key_data tmp_key_data; + krb5_key_data *tptr; + + memset( &tmp_key_data, 0, sizeof(tmp_key_data)); + retval = krb5_build_principal_ext(context, &krbtgt_princ, db_entry->princ->realm.length, @@ -176,19 +180,59 @@ add_key_rnd(context, master_key, ks_tuple, ks_tuple_count, db_entry, kvno) &key))) goto add_key_rnd_err; + + /* db library will free this. Since, its a so, it could actually be using different memory management + function. So, its better if the memory is allocated by the db's malloc. So, a temporary memory is used + here which will later be copied to the db_entry */ retval = krb5_dbekd_encrypt_key_data(context, master_key, &key, NULL, kvno, - &db_entry->key_data[db_entry->n_key_data-1]); + &tmp_key_data); krb5_free_keyblock_contents(context, &key); - - if (retval) + if( retval ) goto add_key_rnd_err; + + tptr = &db_entry->key_data[db_entry->n_key_data-1]; + + tptr->key_data_ver = tmp_key_data.key_data_ver; + tptr->key_data_kvno = tmp_key_data.key_data_kvno; + + for( k = 0; k < tmp_key_data.key_data_ver; k++ ) + { + tptr->key_data_type[k] = tmp_key_data.key_data_type[k]; + tptr->key_data_length[k] = tmp_key_data.key_data_length[k]; + if( tmp_key_data.key_data_contents[k] ) + { + tptr->key_data_contents[k] = krb5_db_alloc(context, NULL, tmp_key_data.key_data_length[k]); + if( tptr->key_data_contents[k] == NULL ) + { + cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); + db_entry->key_data = NULL; + db_entry->n_key_data = 0; + retval = ENOMEM; + goto add_key_rnd_err; + } + memcpy( tptr->key_data_contents[k], tmp_key_data.key_data_contents[k], tmp_key_data.key_data_length[k]); + + memset( tmp_key_data.key_data_contents[k], 0, tmp_key_data.key_data_length[k]); + free( tmp_key_data.key_data_contents[k] ); + tmp_key_data.key_data_contents[k] = NULL; + } + } + } add_key_rnd_err: krb5_db_free_principal(context, &krbtgt_entry, one); + for( i = 0; i < tmp_key_data.key_data_ver; i++ ) + { + if( tmp_key_data.key_data_contents[i] ) + { + memset( tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]); + free( tmp_key_data.key_data_contents[i] ); + } + } return(retval); } @@ -242,6 +286,7 @@ krb5_dbe_crk(context, master_key, ks_tuple, ks_tuple_count, keepold, db_entry) db_entry->key_data[i+n_new_key_data] = key_data[i]; memset(&key_data[i], 0, sizeof(krb5_key_data)); } + krb5_db_free(context, key_data); /* we moved the cotents to new memory. But, the original block which contained the data */ } else { cleanup_key_data(context, key_data_count, key_data); } @@ -321,7 +366,11 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, krb5_keysalt key_salt; krb5_keyblock key; krb5_data pwd; - int i, j; + int i, j, k; + krb5_key_data tmp_key_data; + krb5_key_data *tptr; + + memset( &tmp_key_data, 0, sizeof(tmp_key_data)); retval = 0; @@ -424,18 +473,56 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, key_salt.data.length = krb5_princ_realm(context, db_entry->princ)->length; - if ((retval = krb5_dbekd_encrypt_key_data(context, master_key, &key, - (const krb5_keysalt *)&key_salt, - kvno, &db_entry->key_data[db_entry->n_key_data-1]))) { - if (key_salt.data.data) - free(key_salt.data.data); - krb5_xfree(key.contents); - return(retval); - } + /* memory allocation to be done by db. So, use temporary block and later copy + it to the memory allocated by db */ + retval = krb5_dbekd_encrypt_key_data(context, master_key, &key, + (const krb5_keysalt *)&key_salt, + kvno, &tmp_key_data); if (key_salt.data.data) - free(key_salt.data.data); + free(key_salt.data.data); krb5_xfree(key.contents); + + if( retval ) + return retval; + + tptr = &db_entry->key_data[db_entry->n_key_data-1]; + + tptr->key_data_ver = tmp_key_data.key_data_ver; + tptr->key_data_kvno = tmp_key_data.key_data_kvno; + + for( k = 0; k < tmp_key_data.key_data_ver; k++ ) + { + tptr->key_data_type[k] = tmp_key_data.key_data_type[k]; + tptr->key_data_length[k] = tmp_key_data.key_data_length[k]; + if( tmp_key_data.key_data_contents[k] ) + { + tptr->key_data_contents[k] = krb5_db_alloc(context, NULL, tmp_key_data.key_data_length[k]); + if( tptr->key_data_contents[k] == NULL ) + { + cleanup_key_data(context, db_entry->n_key_data, db_entry->key_data); + db_entry->key_data = NULL; + db_entry->n_key_data = 0; + retval = ENOMEM; + goto add_key_pwd_err; + } + memcpy( tptr->key_data_contents[k], tmp_key_data.key_data_contents[k], tmp_key_data.key_data_length[k]); + + memset( tmp_key_data.key_data_contents[k], 0, tmp_key_data.key_data_length[k]); + free( tmp_key_data.key_data_contents[k] ); + tmp_key_data.key_data_contents[k] = NULL; + } + } + } + add_key_pwd_err: + for( i = 0; i < tmp_key_data.key_data_ver; i++ ) + { + if( tmp_key_data.key_data_contents[i] ) + { + memset( tmp_key_data.key_data_contents[i], 0, tmp_key_data.key_data_length[i]); + free( tmp_key_data.key_data_contents[i] ); + } } + return(retval); } @@ -446,7 +533,7 @@ add_key_pwd(context, master_key, ks_tuple, ks_tuple_count, passwd, * As a side effect all old keys are nuked if keepold is false. */ krb5_error_code -krb5_dbe_cpw(context, master_key, ks_tuple, ks_tuple_count, passwd, +krb5_dbe_def_cpw(context, master_key, ks_tuple, ks_tuple_count, passwd, new_kvno, keepold, db_entry) krb5_context context; krb5_keyblock * master_key; @@ -495,6 +582,7 @@ krb5_dbe_cpw(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry->key_data[i+n_new_key_data] = key_data[i]; memset(&key_data[i], 0, sizeof(krb5_key_data)); } + krb5_db_free( context, key_data ); } else { cleanup_key_data(context, key_data_count, key_data); } @@ -556,3 +644,5 @@ krb5_dbe_apw(context, master_key, ks_tuple, ks_tuple_count, passwd, db_entry) } return(retval); } + + diff --git a/src/lib/kdb/kdb_db2.c b/src/lib/kdb/kdb_db2.c deleted file mode 100644 index bcd08a2fb..000000000 --- a/src/lib/kdb/kdb_db2.c +++ /dev/null @@ -1,1434 +0,0 @@ -/* - * lib/kdb/kdb_db2.c - * - * Copyright 1997 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -/* - * Copyright (C) 1998 by the FundsXpress, INC. - * - * All rights reserved. - * - * Export of this software from the United States of America may require - * a specific license from the United States Government. It is the - * responsibility of any person or organization contemplating export to - * obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of FundsXpress. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. FundsXpress makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -#if HAVE_UNISTD_H -#include -#endif - -#include "k5-int.h" -#include -#include -#include -#include - -#define OLD_COMPAT_VERSION_1 - -#ifdef OLD_COMPAT_VERSION_1 -#include "kdb_compat.h" -#endif - -#include "kdb_db2.h" - -static char *gen_dbsuffix - (char *, char * ); -static krb5_error_code krb5_db2_db_start_update - (krb5_context); -static krb5_error_code krb5_db2_db_end_update - (krb5_context); -static krb5_error_code krb5_db2_db_set_hashfirst - (krb5_context, int); - -static char default_db_name[] = DEFAULT_KDB_FILE; - -/* - * Locking: - * - * There are two distinct locking protocols used. One is designed to - * lock against processes (the admin_server, for one) which make - * incremental changes to the database; the other is designed to lock - * against utilities (kdb5_edit, kpropd, kdb5_convert) which replace the - * entire database in one fell swoop. - * - * The first locking protocol is implemented using flock() in the - * krb_dbl_lock() and krb_dbl_unlock routines. - * - * The second locking protocol is necessary because DBM "files" are - * actually implemented as two separate files, and it is impossible to - * atomically rename two files simultaneously. It assumes that the - * database is replaced only very infrequently in comparison to the time - * needed to do a database read operation. - * - * A third file is used as a "version" semaphore; the modification - * time of this file is the "version number" of the database. - * At the start of a read operation, the reader checks the version - * number; at the end of the read operation, it checks again. If the - * version number changed, or if the semaphore was nonexistant at - * either time, the reader sleeps for a second to let things - * stabilize, and then tries again; if it does not succeed after - * KRB5_DBM_MAX_RETRY attempts, it gives up. - * - * On update, the semaphore file is deleted (if it exists) before any - * update takes place; at the end of the update, it is replaced, with - * a version number strictly greater than the version number which - * existed at the start of the update. - * - * If the system crashes in the middle of an update, the semaphore - * file is not automatically created on reboot; this is a feature, not - * a bug, since the database may be inconsistant. Note that the - * absence of a semaphore file does not prevent another _update_ from - * taking place later. Database replacements take place automatically - * only on slave servers; a crash in the middle of an update will be - * fixed by the next slave propagation. A crash in the middle of an - * update on the master would be somewhat more serious, but this would - * likely be noticed by an administrator, who could fix the problem and - * retry the operation. - */ - -#define free_dbsuffix(name) free(name) - -/* - * Routines to deal with context. - */ -#define k5db2_inited(c) (c && c->db_context && \ - ((krb5_db2_context *) c->db_context)->db_inited) - -/* - * Restore the default context. - */ -static void -k5db2_clear_context(dbctx) - krb5_db2_context *dbctx; -{ - /* - * Free any dynamically allocated memory. File descriptors and locks - * are the caller's problem. - */ - if (dbctx->db_lf_name) - free(dbctx->db_lf_name); - if (dbctx->db_name && (dbctx->db_name != default_db_name)) - free(dbctx->db_name); - /* - * Clear the structure and reset the defaults. - */ - memset((char *) dbctx, 0, sizeof(krb5_db2_context)); - dbctx->db_name = default_db_name; - dbctx->db_nb_locks = FALSE; -} - -static krb5_error_code -k5db2_init_context(context) - krb5_context context; -{ - krb5_db2_context *db_ctx; - - if (context->db_context == NULL) { - db_ctx = (krb5_db2_context *) malloc(sizeof(krb5_db2_context)); - if (db_ctx == NULL) - return ENOMEM; - else { - memset((char *) db_ctx, 0, sizeof(krb5_db2_context)); - k5db2_clear_context((krb5_db2_context *)db_ctx); - context->db_context = (void *) db_ctx; - } - } - return(0); -} - -/* - * Utility routine: generate name of database file. - */ - -static char * -gen_dbsuffix(db_name, sfx) - char *db_name; - char *sfx; -{ - char *dbsuffix; - - if (sfx == NULL) - return((char *) NULL); - - dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1); - if (!dbsuffix) - return(0); - (void) strcpy(dbsuffix, db_name); - (void) strcat(dbsuffix, sfx); - return dbsuffix; -} - -static DB * -k5db2_dbopen(dbc, fname, flags, mode) - krb5_db2_context *dbc; - char *fname; - int flags; - int mode; -{ - DB *db; - BTREEINFO bti; - HASHINFO hashi; - - bti.flags = 0; - bti.cachesize = 0; - bti.psize = 4096; - bti.lorder = 0; - bti.minkeypage = 0; - bti.compare = NULL; - bti.prefix = NULL; - - hashi.bsize = 4096; - hashi.cachesize = 0; - hashi.ffactor = 40; - hashi.hash = NULL; - hashi.lorder = 0; - hashi.nelem = 1; - - db = dbopen(fname, flags, mode, - dbc->hashfirst ? DB_HASH : DB_BTREE, - dbc->hashfirst ? (void *) &hashi : (void *) &bti); - if (db != NULL) - return db; - switch (errno) { -#ifdef EFTYPE - case EFTYPE: -#endif - case EINVAL: - db = dbopen(fname, flags, mode, - dbc->hashfirst ? DB_BTREE : DB_HASH, - dbc->hashfirst ? (void *) &bti : (void *) &hashi); - if (db != NULL) - dbc->hashfirst = !dbc->hashfirst; - default: - return db; - } -} - -static krb5_error_code -krb5_db2_db_set_hashfirst(context, hashfirst) - krb5_context context; - int hashfirst; -{ - krb5_db2_context *dbc; - - if (k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - dbc = (krb5_db2_context *) context->db_context; - dbc->hashfirst = hashfirst; - return 0; -} - -/* - * initialization for data base routines. - */ - -krb5_error_code -krb5_db2_db_init(context) - krb5_context context; -{ - char *filename = NULL; - krb5_db2_context *db_ctx; - krb5_error_code retval; - - if (k5db2_inited(context)) - return 0; - - /* Check for presence of our context, if not present, allocate one. */ - if ((retval = k5db2_init_context(context))) - return(retval); - - db_ctx = context->db_context; - db_ctx->db = NULL; - - if (!(filename = gen_dbsuffix(db_ctx->db_name, KDB2_LOCK_EXT))) - return ENOMEM; - db_ctx->db_lf_name = filename; /* so it gets freed by clear_context */ - - /* - * should be opened read/write so that write locking can work with - * POSIX systems - */ - if ((db_ctx->db_lf_file = open(filename, O_RDWR, 0666)) < 0) { - if ((db_ctx->db_lf_file = open(filename, O_RDONLY, 0666)) < 0) { - retval = errno; - goto err_out; - } - } - db_ctx->db_inited++; - - if ((retval = krb5_db2_db_get_age(context, NULL, &db_ctx->db_lf_time))) - goto err_out; - - return 0; - -err_out: - db_ctx->db = NULL; - k5db2_clear_context(db_ctx); - return (retval); -} - -/* - * gracefully shut down database--must be called by ANY program that does - * a krb5_db2_db_init - */ -krb5_error_code -krb5_db2_db_fini(context) - krb5_context context; -{ - krb5_error_code retval = 0; - krb5_db2_context *db_ctx; - - db_ctx = (krb5_db2_context *) context->db_context; - - if (k5db2_inited(context)) { - if (close(db_ctx->db_lf_file)) - retval = errno; - else - retval = 0; - } - if (db_ctx) { - k5db2_clear_context(db_ctx); - free(context->db_context); - context->db_context = NULL; - } - return retval; -} - -krb5_error_code -krb5_db2_db_open_database(context) - krb5_context context; -{ - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - return 0; -} - -krb5_error_code -krb5_db2_db_close_database(context) - krb5_context context; -{ - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - return 0; -} - -/* - * Set/Get the master key associated with the database - */ -krb5_error_code -krb5_db2_db_set_mkey(context, key) - krb5_context context; - krb5_keyblock *key; -{ - krb5_db2_context *db_ctx; - - if (!k5db2_inited(context)) - return(KRB5_KDB_DBNOTINITED); - - db_ctx = context->db_context; - db_ctx->db_master_key = key; - return 0; -} - -krb5_error_code -krb5_db2_db_get_mkey(context, key) - krb5_context context; - krb5_keyblock **key; -{ - krb5_db2_context *db_ctx; - - if (!k5db2_inited(context)) - return(KRB5_KDB_DBNOTINITED); - - db_ctx = context->db_context; - *key = db_ctx->db_master_key; - - return 0; -} - -/* - * Set the "name" of the current database to some alternate value. - * - * Passing a null pointer as "name" will set back to the default. - * If the alternate database doesn't exist, nothing is changed. - * - * XXX rethink this - */ - -krb5_error_code -krb5_db2_db_set_name(context, name) - krb5_context context; - char *name; -{ - DB *db; - krb5_db2_context *db_ctx; - krb5_error_code kret; - - if (k5db2_inited(context)) - return KRB5_KDB_DBINITED; - - /* Check for presence of our context, if not present, allocate one. */ - if ((kret = k5db2_init_context(context))) - return(kret); - - if (name == NULL) - name = default_db_name; - - db_ctx = context->db_context; - db = k5db2_dbopen(db_ctx, name, O_RDONLY, 0); - if (db == NULL) - return errno; - - db_ctx->db_name = strdup(name); - (*db->close)(db); - return 0; -} - -/* - * Return the last modification time of the database. - * - * Think about using fstat. - */ - -krb5_error_code -krb5_db2_db_get_age(context, db_name, age) - krb5_context context; - char *db_name; - time_t *age; -{ - krb5_db2_context *db_ctx; - struct stat st; - - if (!k5db2_inited(context)) - return(KRB5_KDB_DBNOTINITED); - db_ctx = (krb5_db2_context *) context->db_context; - if (fstat (db_ctx->db_lf_file, &st) < 0) - *age = -1; - else - *age = st.st_mtime; - return 0; -} - -/* - * Remove the semaphore file; indicates that database is currently - * under renovation. - * - * This is only for use when moving the database out from underneath - * the server (for example, during slave updates). - */ - -static krb5_error_code -krb5_db2_db_start_update(context) - krb5_context context; -{ - return 0; -} - -static krb5_error_code -krb5_db2_db_end_update(context) - krb5_context context; -{ - krb5_error_code retval; - krb5_db2_context *db_ctx; - struct stat st; - time_t now; - struct utimbuf utbuf; - - if (!k5db2_inited(context)) - return(KRB5_KDB_DBNOTINITED); - - retval = 0; - db_ctx = context->db_context; - now = time((time_t *) NULL); - if (fstat(db_ctx->db_lf_file, &st) == 0) { - if (st.st_mtime >= now) { - utbuf.actime = st.st_mtime+1; - utbuf.modtime = st.st_mtime+1; - if (utime(db_ctx->db_lf_name, &utbuf)) - retval = errno; - } - else { - if (utime(db_ctx->db_lf_name, (struct utimbuf *) NULL)) - retval = errno; - } - } - else - retval = errno; - if (!retval) { - if (fstat(db_ctx->db_lf_file, &st) == 0) - db_ctx->db_lf_time = st.st_mtime; - else - retval = errno; - } - return(retval); -} - -krb5_error_code -krb5_db2_db_lock(context, mode) - krb5_context context; - int mode; -{ - krb5_db2_context *db_ctx; - int krb5_lock_mode; - DB *db; - krb5_error_code retval; - time_t mod_time; - - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - - db_ctx = (krb5_db2_context *) context->db_context; - if (db_ctx->db_locks_held && (db_ctx->db_lock_mode >= mode)) { - /* No need to upgrade lock, just return */ - db_ctx->db_locks_held++; - return(0); - } - - if ((mode != KRB5_LOCKMODE_SHARED) && (mode != KRB5_LOCKMODE_EXCLUSIVE)) - return KRB5_KDB_BADLOCKMODE; - - if (db_ctx->db_nb_locks) - krb5_lock_mode = mode | KRB5_LOCKMODE_DONTBLOCK; - else - krb5_lock_mode = mode; - retval = krb5_lock_file(context, db_ctx->db_lf_file, krb5_lock_mode); - switch (retval) { - case EBADF: - if (mode == KRB5_LOCKMODE_EXCLUSIVE) - return KRB5_KDB_CANTLOCK_DB; - default: - return retval; - case 0: - break; - } - - if ((retval = krb5_db2_db_get_age(context, NULL, &mod_time))) - goto lock_error; - - db = k5db2_dbopen(db_ctx, db_ctx->db_name, - mode == KRB5_LOCKMODE_SHARED ? O_RDONLY : O_RDWR, - 0600); - if (db) { - db_ctx->db_lf_time = mod_time; - db_ctx->db = db; - } else { - retval = errno; - db_ctx->db = NULL; - goto lock_error; - } - - db_ctx->db_lock_mode = mode; - db_ctx->db_locks_held++; - return 0; - -lock_error:; - db_ctx->db_lock_mode = 0; - db_ctx->db_locks_held = 0; - (void) krb5_db2_db_unlock(context); - return retval; -} - -krb5_error_code -krb5_db2_db_unlock(context) - krb5_context context; -{ - krb5_db2_context *db_ctx; - DB *db; - krb5_error_code retval; - - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - - db_ctx = (krb5_db2_context *) context->db_context; - if (!db_ctx->db_locks_held) /* lock already unlocked */ - return KRB5_KDB_NOTLOCKED; - db = db_ctx->db; - if (--(db_ctx->db_locks_held) == 0) { - (*db->close)(db); - db_ctx->db = NULL; - - retval = krb5_lock_file(context, db_ctx->db_lf_file, - KRB5_LOCKMODE_UNLOCK); - db_ctx->db_lock_mode = 0; - return(retval); - } - return 0; -} - -/* - * Create the database, assuming it's not there. - */ -krb5_error_code -krb5_db2_db_create(context, db_name, flags) - krb5_context context; - char *db_name; - krb5_int32 flags; -{ - register krb5_error_code retval = 0; - char *okname; - int fd; - krb5_db2_context *db_ctx; - DB *db; - - if ((retval = k5db2_init_context(context))) - return(retval); - - db_ctx = (krb5_db2_context *) context->db_context; - switch (flags) { - case KRB5_KDB_CREATE_HASH: - if ((retval = krb5_db2_db_set_hashfirst(context, TRUE))) - return retval; - break; - case KRB5_KDB_CREATE_BTREE: - case 0: - if ((retval = krb5_db2_db_set_hashfirst(context, FALSE))) - return retval; - break; - default: - return KRB5_KDB_BAD_CREATEFLAGS; - } - db = k5db2_dbopen(db_ctx, db_name, O_RDWR|O_CREAT|O_EXCL, 0600); - if (db == NULL) - retval = errno; - else - (*db->close)(db); - if (retval == 0) { - okname = gen_dbsuffix(db_name, KDB2_LOCK_EXT); - if (!okname) - retval = ENOMEM; - else { - fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600); - if (fd < 0) - retval = errno; - else - close(fd); - free_dbsuffix(okname); - } - } - return retval; -} - -/* - * Destroy the database. Zero's out all of the files, just to be sure. - */ -static krb5_error_code -destroy_file_suffix(dbname, suffix) - char *dbname; - char *suffix; -{ - char *filename; - struct stat statb; - int nb,fd; - unsigned int j; - off_t pos; - char buf[BUFSIZ]; - char zbuf[BUFSIZ]; - int dowrite; - - filename = gen_dbsuffix(dbname, suffix); - if (filename == 0) - return ENOMEM; - if ((fd = open(filename, O_RDWR, 0)) < 0) { - free(filename); - return errno; - } - /* fstat() will probably not fail unless using a remote filesystem - (which is inappropriate for the kerberos database) so this check - is mostly paranoia. */ - if (fstat(fd, &statb) == -1) { - int retval = errno; - free(filename); - return retval; - } - /* - * Stroll through the file, reading in BUFSIZ chunks. If everything - * is zero, then we're done for that block, otherwise, zero the block. - * We would like to just blast through everything, but some DB - * implementations make holey files and writing data to the holes - * causes actual blocks to be allocated which is no good, since - * we're just about to unlink it anyways. - */ - memset(zbuf, 0, BUFSIZ); - pos = 0; - while (pos < statb.st_size) { - dowrite = 0; - nb = read(fd, buf, BUFSIZ); - if (nb < 0) { - int retval = errno; - free(filename); - return retval; - } - for (j=0; jdb_context) { - tmpcontext = 1; - if ((retval1 = k5db2_init_context(context))) - return(retval1); - } - - retval1 = retval2 = 0; - retval1 = destroy_file_suffix(dbname, ""); - retval2 = destroy_file_suffix(dbname, KDB2_LOCK_EXT); - - if (tmpcontext) { - k5db2_clear_context((krb5_db2_context *) context->db_context); - free(context->db_context); - context->db_context = NULL; - } - - if (retval1 || retval2) - return (retval1 ? retval1 : retval2); - else - return 0; -} - -/* - * "Atomically" rename the database in a way that locks out read - * access in the middle of the rename. - * - * Not perfect; if we crash in the middle of an update, we don't - * necessarily know to complete the transaction the rename, but... - * - * Since the rename operation happens outside the init/fini bracket, we - * have to go through the same stuff that we went through up in db_destroy. - */ -krb5_error_code -krb5_db2_db_rename(context, from, to) - krb5_context context; - char *from; - char *to; -{ - DB *db; - char *fromok; - krb5_error_code retval; - krb5_db2_context *s_context, *db_ctx; - - s_context = context->db_context; - context->db_context = NULL; - if ((retval = k5db2_init_context(context))) - return retval; - db_ctx = (krb5_db2_context *) context->db_context; - - /* - * Create the database if it does not already exist; the - * files must exist because krb5_db2_db_lock, called below, - * will fail otherwise. - */ - db = k5db2_dbopen(db_ctx, to, O_RDWR|O_CREAT, 0600); - if (db == NULL) { - retval = errno; - goto errout; - } - else - (*db->close)(db); - /* - * Set the database to the target, so that other processes sharing - * the target will stop their activity, and notice the new database. - */ - retval = krb5_db2_db_set_name(context, to); - if (retval) - goto errout; - - db_ctx->db_lf_name = gen_dbsuffix(db_ctx->db_name, KDB2_LOCK_EXT); - if (db_ctx->db_lf_name == NULL) { - retval = ENOMEM; - goto errout; - } - db_ctx->db_lf_file = open(db_ctx->db_lf_name, O_RDWR|O_CREAT, 0600); - if (db_ctx->db_lf_file < 0) { - retval = errno; - goto errout; - } - - db_ctx->db_inited = 1; - - retval = krb5_db2_db_get_age(context, NULL, &db_ctx->db_lf_time); - if (retval) - goto errout; - - fromok = gen_dbsuffix(from, KDB2_LOCK_EXT); - if (fromok == NULL) { - retval = ENOMEM; - goto errout; - } - - if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) - goto errfromok; - - if ((retval = krb5_db2_db_start_update(context))) - goto errfromok; - - if (rename(from, to)) { - retval = errno; - goto errfromok; - } - if (unlink(fromok)) { - retval = errno; - goto errfromok; - } - retval = krb5_db2_db_end_update(context); -errfromok: - free_dbsuffix(fromok); -errout: - if (context->db_context) { - if (db_ctx->db_lf_file >= 0) { - krb5_db2_db_unlock(context); - close(db_ctx->db_lf_file); - } - k5db2_clear_context((krb5_db2_context *) context->db_context); - free(context->db_context); - } - - context->db_context = s_context; - (void) krb5_db2_db_unlock(context); /* unlock saved context db */ - - return retval; -} - -/* - * look up a principal in the data base. - * returns number of entries found, and whether there were - * more than requested. - */ - -krb5_error_code -krb5_db2_db_get_principal(context, searchfor, entries, nentries, more) - krb5_context context; - krb5_const_principal searchfor; - krb5_db_entry *entries; /* filled in */ - int *nentries; /* how much room/how many found */ - krb5_boolean *more; /* are there more? */ -{ - krb5_db2_context *db_ctx; - krb5_error_code retval; - DB *db; - DBT key, contents; - krb5_data keydata, contdata; - int trynum, dbret; - - *more = FALSE; - *nentries = 0; - - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - - db_ctx = (krb5_db2_context *) context->db_context; - for (trynum = 0; trynum < KRB5_DB2_MAX_RETRY; trynum++) { - if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_SHARED))) { - if (db_ctx->db_nb_locks) - return(retval); - sleep(1); - continue; - } - break; - } - if (trynum == KRB5_DB2_MAX_RETRY) - return KRB5_KDB_DB_INUSE; - - /* XXX deal with wildcard lookups */ - retval = krb5_encode_princ_dbkey(context, &keydata, searchfor); - if (retval) - goto cleanup; - key.data = keydata.data; - key.size = keydata.length; - - db = db_ctx->db; - dbret = (*db->get)(db, &key, &contents, 0); - retval = errno; - krb5_free_data_contents(context, &keydata); - switch (dbret) { - case 1: - retval = 0; - case -1: - default: - *nentries = 0; - goto cleanup; - case 0: - contdata.data = contents.data; - contdata.length = contents.size; - retval = krb5_decode_princ_contents(context, &contdata, entries); - if (!retval) - *nentries = 1; - break; - } - -cleanup: - (void) krb5_db2_db_unlock(context); /* unlock read lock */ - return retval; -} - -/* - Free stuff returned by krb5_db2_db_get_principal. - */ -void -krb5_db2_db_free_principal(context, entries, nentries) - krb5_context context; - krb5_db_entry *entries; - int nentries; -{ - register int i; - for (i = 0; i < nentries; i++) - krb5_dbe_free_contents(context, &entries[i]); - return; -} - -/* - Stores the *"nentries" entry structures pointed to by "entries" in the - database. - - *"nentries" is updated upon return to reflect the number of records - acutally stored; the first *"nstored" records will have been stored in the - database (even if an error occurs). - - */ - -krb5_error_code -krb5_db2_db_put_principal(context, entries, nentries) - krb5_context context; - krb5_db_entry *entries; - register int *nentries; /* number of entry structs to update */ -{ - int i, n, dbret; - DB *db; - DBT key, contents; - krb5_data contdata, keydata; - krb5_error_code retval; - krb5_db2_context *db_ctx; - - n = *nentries; - *nentries = 0; - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - - db_ctx = (krb5_db2_context *) context->db_context; - if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) - return retval; - - db = db_ctx->db; - if ((retval = krb5_db2_db_start_update(context))) { - (void)krb5_db2_db_unlock(context); - return retval; - } - - /* for each one, stuff temps, and do replace/append */ - for (i = 0; i < n; i++) { - retval = krb5_encode_princ_contents(context, &contdata, entries); - if (retval) - break; - contents.data = contdata.data; - contents.size = contdata.length; - retval = krb5_encode_princ_dbkey(context, &keydata, entries->princ); - if (retval) { - krb5_free_data_contents(context, &contdata); - break; - } - - key.data = keydata.data; - key.size = keydata.length; - dbret = (*db->put)(db, &key, &contents, 0); - retval = dbret ? errno : 0; - krb5_free_data_contents(context, &keydata); - krb5_free_data_contents(context, &contdata); - if (retval) - break; - entries++; /* bump to next struct */ - } - - (void)krb5_db2_db_end_update(context); - (void)krb5_db2_db_unlock(context); /* unlock database */ - *nentries = i; - return(retval); -} - -/* - * delete a principal from the data base. - * returns number of entries removed - */ - -krb5_error_code -krb5_db2_db_delete_principal(context, searchfor, nentries) - krb5_context context; - krb5_const_principal searchfor; - int *nentries; /* how many found & deleted */ -{ - krb5_error_code retval; - krb5_db_entry entry; - krb5_db2_context *db_ctx; - DB *db; - DBT key, contents; - krb5_data keydata, contdata; - int i, dbret; - - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - - db_ctx = (krb5_db2_context *) context->db_context; - if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) - return(retval); - - if ((retval = krb5_db2_db_start_update(context))) { - (void) krb5_db2_db_unlock(context); /* unlock write lock */ - return(retval); - } - - if ((retval = krb5_encode_princ_dbkey(context, &keydata, searchfor))) - goto cleanup; - key.data = keydata.data; - key.size = keydata.length; - - db = db_ctx->db; - dbret = (*db->get)(db, &key, &contents, 0); - retval = errno; - switch (dbret) { - case 1: - retval = KRB5_KDB_NOENTRY; - case -1: - default: - *nentries = 0; - goto cleankey; - case 0: - ; - } - memset((char *)&entry, 0, sizeof(entry)); - contdata.data = contents.data; - contdata.length = contents.size; - retval = krb5_decode_princ_contents(context, &contdata, &entry); - if (retval) - goto cleankey; - *nentries = 1; - - /* Clear encrypted key contents */ - for (i = 0; i < entry.n_key_data; i++) { - if (entry.key_data[i].key_data_length[0]) { - memset((char *)entry.key_data[i].key_data_contents[0], 0, - (unsigned) entry.key_data[i].key_data_length[0]); - } - } - - retval = krb5_encode_princ_contents(context, &contdata, &entry); - krb5_dbe_free_contents(context, &entry); - if (retval) - goto cleankey; - - contents.data = contdata.data; - contents.size = contdata.length; - dbret = (*db->put)(db, &key, &contents, 0); - retval = dbret ? errno : 0; - krb5_free_data_contents(context, &contdata); - if (retval) - goto cleankey; - dbret = (*db->del)(db, &key, 0); - retval = dbret ? errno : 0; -cleankey: - krb5_free_data_contents(context, &keydata); - -cleanup: - (void) krb5_db2_db_end_update(context); - (void) krb5_db2_db_unlock(context); /* unlock write lock */ - return retval; -} - -krb5_error_code -krb5_db2_db_iterate_ext(context, func, func_arg, backwards, recursive) - krb5_context context; - krb5_error_code (*func) (krb5_pointer, krb5_db_entry *); - krb5_pointer func_arg; - int backwards, recursive; -{ - krb5_db2_context *db_ctx; - DB *db; - DBT key, contents; - krb5_data contdata; - krb5_db_entry entries; - krb5_error_code retval; - int dbret; - void *cookie; - - cookie = NULL; - if (!k5db2_inited(context)) - return KRB5_KDB_DBNOTINITED; - - db_ctx = (krb5_db2_context *) context->db_context; - retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_SHARED); - - if (retval) - return retval; - - db = db_ctx->db; - if (recursive && db->type != DB_BTREE) { - (void)krb5_db2_db_unlock(context); - return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */ - } - - if (!recursive) { - dbret = (*db->seq)(db, &key, &contents, - backwards ? R_LAST : R_FIRST); - } else { -#ifdef HAVE_BT_RSEQ - dbret = bt_rseq(db, &key, &contents, &cookie, - backwards ? R_LAST : R_FIRST); -#else - (void)krb5_db2_db_unlock(context); - return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */ -#endif - } - while (dbret == 0) { - contdata.data = contents.data; - contdata.length = contents.size; - retval = krb5_decode_princ_contents(context, &contdata, &entries); - if (retval) - break; - retval = (*func)(func_arg, &entries); - krb5_dbe_free_contents(context, &entries); - if (retval) - break; - if (!recursive) { - dbret = (*db->seq)(db, &key, &contents, - backwards ? R_PREV : R_NEXT); - } else { -#ifdef HAVE_BT_RSEQ - dbret = bt_rseq(db, &key, &contents, &cookie, - backwards ? R_PREV : R_NEXT); -#else - (void)krb5_db2_db_unlock(context); - return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */ -#endif - } - } - switch (dbret) { - case 1: - case 0: - break; - case -1: - default: - retval = errno; - } - (void) krb5_db2_db_unlock(context); - return retval; -} - -krb5_error_code -krb5_db2_db_iterate(context, func, func_arg) - krb5_context context; - krb5_error_code (*func) (krb5_pointer, krb5_db_entry *); - krb5_pointer func_arg; -{ - return krb5_db2_db_iterate_ext(context, func, func_arg, 0, 0); -} - -krb5_boolean -krb5_db2_db_set_lockmode(context, mode) - krb5_context context; - krb5_boolean mode; -{ - krb5_boolean old; - krb5_db2_context *db_ctx; - - old = mode; - if ((db_ctx = (krb5_db2_context *) context->db_context)) { - old = db_ctx->db_nb_locks; - db_ctx->db_nb_locks = mode; - } - return old; -} - -/* - * Context serialization operations. - * - * Ick, this is really gross. --- tlyu - */ - -/* - * kdb5_context_size() - Determine size required to serialize. - */ -static krb5_error_code -kdb5_context_size(kcontext, arg, sizep) - krb5_context kcontext; - krb5_pointer arg; - size_t *sizep; -{ - krb5_error_code kret; - size_t required; - krb5_db2_context *dbctx; - - /* - * The database context requires at minimum: - * krb5_int32 for KV5M_DB_CONTEXT - * krb5_int32 for db_inited - * krb5_int32 for database lockfile non-blocking flag - * krb5_int32 for database lockfile lock count - * krb5_int32 for database lockfile lock mode - * krb5_int32 for length of database name. - * krb5_int32 for KV5M_DB_CONTEXT - */ - kret = EINVAL; - if ((dbctx = (krb5_db2_context *) arg)) { - required = (sizeof(krb5_int32) * 7); - if (dbctx->db_inited && dbctx->db_name) - required += strlen(dbctx->db_name); - kret = 0; - *sizep += required; - } - return(kret); -} - -/* - * kdb5_context_externalize() - Externalize the database context. - */ -static krb5_error_code -kdb5_context_externalize(kcontext, arg, buffer, lenremain) - krb5_context kcontext; - krb5_pointer arg; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_db2_context *dbctx; - size_t required; - krb5_octet *bp; - size_t remain; - - required = 0; - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - if ((dbctx = (krb5_db2_context *) arg)) { - kret = ENOMEM; - if (!kdb5_context_size(kcontext, arg, &required) && - (required <= remain)) { - /* Write magic number */ - (void) krb5_ser_pack_int32(KV5M_DB_CONTEXT, &bp, &remain); - - /* Write inited flag */ - (void) krb5_ser_pack_int32((krb5_int32) dbctx->db_inited, - &bp, &remain); - - /* Write blocking lock lockmode */ - (void) krb5_ser_pack_int32((krb5_int32) dbctx->db_nb_locks, - &bp, &remain); - - /* Write lock count */ - (void) krb5_ser_pack_int32((krb5_int32) - (dbctx->db_inited) ? - dbctx->db_locks_held : 0, - &bp, &remain); - - /* Write lock mode */ - (void) krb5_ser_pack_int32((krb5_int32) - (dbctx->db_inited) ? - dbctx->db_lock_mode : 0, - &bp, &remain); - - /* Write length of database name */ - (void) krb5_ser_pack_int32((dbctx->db_inited && dbctx->db_name) ? - (krb5_int32) strlen(dbctx->db_name) : 0, - &bp, &remain); - if (dbctx->db_inited && dbctx->db_name) - (void) krb5_ser_pack_bytes((krb5_octet *) dbctx->db_name, - strlen(dbctx->db_name), - &bp, &remain); - - /* Write trailer */ - (void) krb5_ser_pack_int32(KV5M_DB_CONTEXT, &bp, &remain); - kret = 0; - *buffer = bp; - *lenremain = remain; - } - } - return(kret); -} - -/* - * kdb5_context_internalize() - Internalize the database context. - */ -static krb5_error_code -kdb5_context_internalize(kcontext, argp, buffer, lenremain) - krb5_context kcontext; - krb5_pointer *argp; - krb5_octet **buffer; - size_t *lenremain; -{ - krb5_error_code kret; - krb5_context tmpctx; - krb5_db2_context *dbctx; - krb5_int32 ibuf; - krb5_octet *bp; - size_t remain; - krb5_int32 iflag; - krb5_int32 nb_lockmode; - krb5_int32 lockcount; - krb5_int32 lockmode; - krb5_int32 dbnamelen; - krb5_boolean nb_lock; - char *dbname; - - bp = *buffer; - remain = *lenremain; - kret = EINVAL; - dbctx = (krb5_db2_context *) NULL; - /* Read our magic number */ - if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) - ibuf = 0; - if (ibuf == KV5M_DB_CONTEXT) { - kret = ENOMEM; - - if (!(kret = krb5_ser_unpack_int32(&iflag, &bp, &remain)) && - !(kret = krb5_ser_unpack_int32(&nb_lockmode, &bp, &remain)) && - !(kret = krb5_ser_unpack_int32(&lockcount, &bp, &remain)) && - !(kret = krb5_ser_unpack_int32(&lockmode, &bp, &remain)) && - !(kret = krb5_ser_unpack_int32(&dbnamelen, &bp, &remain)) && - !(kret = krb5_init_context(&tmpctx))) { - if (iflag) { - dbname = (char *) NULL; - if (dbnamelen && - (dbname = (char *) malloc((size_t) (dbnamelen+1)))) { - kret = krb5_ser_unpack_bytes((krb5_octet *) dbname, - (size_t) dbnamelen, - &bp, &remain); - if (!kret) - dbname[dbnamelen] = '\0'; - } - if (!kret && - (!dbname || !(kret = krb5_db_set_name(tmpctx, dbname))) && - !(kret = krb5_db_init(tmpctx))) { - dbctx = (krb5_db2_context *) tmpctx->db_context; - (void) krb5_db2_db_set_lockmode(tmpctx, 0); - if (lockmode) - kret = krb5_db_lock(tmpctx, lockmode); - if (!kret && lockmode) - dbctx->db_locks_held = lockcount; - nb_lock = nb_lockmode & 0xff; - (void) krb5_db2_db_set_lockmode(tmpctx, nb_lock); - } - if (dbname) - krb5_xfree(dbname); - } - if (!kret) - kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); - if (kret || (ibuf != KV5M_DB_CONTEXT)) - kret = EINVAL; - - if (kret) { - if (dbctx) - krb5_db_fini(tmpctx); - } - else - tmpctx->db_context = NULL; - krb5_free_context(tmpctx); - } - } - if (!kret) { - *buffer = bp; - *lenremain = remain; - *argp = (krb5_pointer) dbctx; - } - return(kret); -} - -/* Dispatch entry */ -static const krb5_ser_entry kdb5_context_ser_entry = { - KV5M_DB_CONTEXT, /* Type */ - kdb5_context_size, /* Sizer routine */ - kdb5_context_externalize, /* Externalize routine */ - kdb5_context_internalize /* Externalize routine */ -}; - -/* - * Register serializer. - */ -krb5_error_code -krb5_ser_db_context_init(kcontext) - krb5_context kcontext; -{ - return(krb5_register_serializer(kcontext, &kdb5_context_ser_entry)); -} diff --git a/src/lib/kdb/kdb_db2.h b/src/lib/kdb/kdb_db2.h deleted file mode 100644 index 80f949596..000000000 --- a/src/lib/kdb/kdb_db2.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * lib/kdb/kdb_db2.h - * - * Copyright 1997 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * KDC Database backend definitions for Berkely DB. - */ -#ifndef KRB5_KDB_DB2_H - -/* renaming kludge */ -#define krb5_db2_db_set_name krb5_db_set_name -#define krb5_db2_db_set_nonblocking krb5_db_set_nonblocking -#define krb5_db2_db_init krb5_db_init -#define krb5_db2_db_fini krb5_db_fini -#define krb5_db2_db_get_age krb5_db_get_age -#define krb5_db2_db_create krb5_db_create -#define krb5_db2_db_destroy krb5_db_destroy -#define krb5_db2_db_rename krb5_db_rename -#define krb5_db2_db_get_principal krb5_db_get_principal -#define krb5_db2_db_free_principal krb5_db_free_principal -#define krb5_db2_db_put_principal krb5_db_put_principal -#define krb5_db2_db_delete_principal krb5_db_delete_principal -#define krb5_db2_db_iterate_ext krb5_db_iterate_ext -#define krb5_db2_db_iterate krb5_db_iterate -#define krb5_db2_db_lock krb5_db_lock -#define krb5_db2_db_unlock krb5_db_unlock -#define krb5_db2_db_set_lockmode krb5_db_set_lockmode -#define krb5_db2_db_close_database krb5_db_close_database -#define krb5_db2_db_open_database krb5_db_open_database -#define krb5_db2_db_set_mkey krb5_db_set_mkey -#define krb5_db2_db_get_mkey krb5_db_get_mkey - -typedef struct _krb5_db2_context { - krb5_boolean db_inited; /* Context initialized */ - char * db_name; /* Name of database */ - DB * db; /* DB handle */ - krb5_boolean hashfirst; /* Try hash database type first */ - char * db_lf_name; /* Name of lock file */ - int db_lf_file; /* File descriptor of lock file */ - time_t db_lf_time; /* Time last updated */ - int db_locks_held; /* Number of times locked */ - int db_lock_mode; /* Last lock mode, e.g. greatest*/ - krb5_boolean db_nb_locks; /* [Non]Blocking lock modes */ - krb5_keyblock *db_master_key; /* Master key of database */ -} krb5_db2_context; - -#define KRB5_DB2_MAX_RETRY 5 - -#define KDB2_LOCK_EXT ".ok" - -krb5_error_code krb5_db2_db_set_name - (krb5_context, - char * ); -krb5_error_code krb5_db2_db_init - (krb5_context); -krb5_error_code krb5_db2_db_fini - (krb5_context); -krb5_error_code krb5_db2_db_get_age - (krb5_context, - char *, - time_t * ); -krb5_error_code krb5_db2_db_create - (krb5_context, - char *, - krb5_int32); -krb5_error_code krb5_db2_db_destroy - (krb5_context, - char * ); -krb5_error_code krb5_db2_db_rename - (krb5_context, - char *, - char * ); -krb5_error_code krb5_db2_db_get_principal - (krb5_context, - krb5_const_principal, - krb5_db_entry *, - int *, - krb5_boolean * ); -void krb5_db2_db_free_principal - (krb5_context, - krb5_db_entry *, - int ); -krb5_error_code krb5_db2_db_put_principal - (krb5_context, - krb5_db_entry *, - int * ); -krb5_error_code krb5_db2_db_iterate_ext - (krb5_context, - krb5_error_code (*) (krb5_pointer, - krb5_db_entry *), - krb5_pointer, int, int ); -krb5_error_code krb5_db2_db_iterate - (krb5_context, - krb5_error_code (*) (krb5_pointer, - krb5_db_entry *), - krb5_pointer ); -krb5_error_code krb5_db2_db_set_nonblocking - (krb5_context, - krb5_boolean, - krb5_boolean * ); -krb5_boolean krb5_db2_db_set_lockmode - (krb5_context, - krb5_boolean ); -krb5_error_code krb5_db2_db_open_database - (krb5_context); -krb5_error_code krb5_db2_db_close_database - (krb5_context); - -#endif /* KRB5_KDB_DB2_H */ diff --git a/src/lib/kdb/kdb_db2/ChangeLog b/src/lib/kdb/kdb_db2/ChangeLog new file mode 100644 index 000000000..6ebc2a0e8 --- /dev/null +++ b/src/lib/kdb/kdb_db2/ChangeLog @@ -0,0 +1,17 @@ +2005-06-20 Ken Raeburn + + Novell merge. + * Makefile.in: + * adb_openclose.c: + * adb_policy.c: + * configure.in: + * db2_exp.c: + * kdb_compat.h: + * kdb_db2.c: + * kdb_db2.h: + * kdb_xdr.c: + * kdb_xdr.h: + * libkdb_db2.exports: + * pol_xdr.c: + * policy_db.h: + diff --git a/src/lib/kdb/kdb_db2/Makefile.in b/src/lib/kdb/kdb_db2/Makefile.in new file mode 100644 index 000000000..ebd39f0c7 --- /dev/null +++ b/src/lib/kdb/kdb_db2/Makefile.in @@ -0,0 +1,150 @@ +thisconfigdir=. +myfulldir=lib/kdb/kdb_db2 +mydir=. +BUILDTOP=$(REL)..$(S)..$(S).. +KRB5_RUN_ENV = @KRB5_RUN_ENV@ +KRB5_CONFIG_SETUP = KRB5_CONFIG=$(SRCTOP)/config-files/krb5.conf ; export KRB5_CONFIG ; +PROG_LIBPATH=-L$(TOPLIBD) +PROG_RPATH=$(KRB5_LIBDIR) + +LOCALINCLUDES = -I.. + +LIBBASE=kdb_db2 +LIB=$(LIBBASE) +LIBMAJOR=4 +LIBMINOR=0 +RELDIR=kdb/kdb_db2 +SO_EXT=.so +# Depends on libk5crypto and libkrb5 + +SHLIB_EXPDEPS = \ + $(TOPLIBD)/libk5crypto$(SHLIBEXT) \ + $(TOPLIBD)/libkrb5$(SHLIBEXT) +SHLIB_EXPLIBS=-lkrb5 -lcom_err -lk5crypto $(KDB5_DB_LIB) $(LIBS) +SHLIB_DIRS=-L$(TOPLIBD) +SHLIB_RDIRS=$(KRB5_LIBDIR) + +DBDIR = $(BUILDTOP)/util/db2 +DBOBJLISTS = $(DBOBJLISTS-@DB_VERSION@) +DBOBJLISTS-sys = +DBOBJLISTS-k5 = $(DBDIR)/hash/OBJS.ST $(DBDIR)/btree/OBJS.ST \ + $(DBDIR)/db/OBJS.ST $(DBDIR)/mpool/OBJS.ST $(DBDIR)/recno/OBJS.ST \ + $(DBDIR)/clib/OBJS.ST + +all:: lib$(LIB)$(SO_EXT) + +SRCS= \ + $(srcdir)/kdb_xdr.c \ + $(srcdir)/adb_openclose.c \ + $(srcdir)/adb_policy.c \ + $(srcdir)/kdb_db2.c \ + $(srcdir)/pol_xdr.c \ + $(srcdir)/db2_exp.c + +STOBJLISTS=OBJS.ST $(DBOBJLISTS) +STLIBOBJS= \ + kdb_xdr.o \ + adb_openclose.o \ + adb_policy.o \ + kdb_db2.o \ + pol_xdr.o \ + db2_exp.o + +all-unix:: all-liblinks +install-unix:: install-libs +clean-unix:: clean-liblinks clean-libs clean-libobjs + +lib$(LIB)$(SO_EXT): db2_exp.o # lib$(LIB)$(STLIBEXT) + $(CC) -shared -o $@ -L$(TOPLIBD) $^ -lgssrpc -ldb $(SHLIB_EXPLIBS) + +clean:: + $(RM) lib$(LIB)$(SO_EXT) db2_exp.o + + +t_kdb: t_kdb.o $(OBJS) $(KDB5_DEPLIBS) $(KRB5_BASE_DEPLIBS) + $(CC_LINK) -o t_kdb t_kdb.o $(OBJS) $(KDB5_LIBS) $(KRB5_BASE_LIBS) + +check:: t_kdb + $(RM) test_db + $(KRB5_CONFIG_SETUP) $(KRB5_RUN_ENV) ./t_kdb -tcv + $(KRB5_CONFIG_SETUP) $(KRB5_RUN_ENV) ./t_kdb -tcvr + +clean:: + $(RM) t_kdb t_kdb.o + + +adb_openclose.c adb_policy.c : ../adb_err.h + +# @lib_frag@ +# @libobj_frag@ + +# +++ Dependency line eater +++ +# +# Makefile dependencies follow. This must be the last section in +# the Makefile.in file +# +kdb_xdr.so kdb_xdr.po $(OUTPRE)kdb_xdr.$(OBJEXT): kdb_xdr.c \ + $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ + $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ + $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ + kdb_xdr.h +adb_openclose.so adb_openclose.po $(OUTPRE)adb_openclose.$(OBJEXT): \ + adb_openclose.c $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ + $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ + $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ + policy_db.h $(SRCTOP)/include/krb5/kdb.h $(DB_DEPS) \ + $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ + $(BUILDTOP)/include/gssrpc/xdr.h ../adb_err.h +adb_policy.so adb_policy.po $(OUTPRE)adb_policy.$(OBJEXT): \ + adb_policy.c policy_db.h $(SRCTOP)/include/k5-int.h \ + $(BUILDTOP)/include/krb5/osconf.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-platform.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/k5-thread.h $(BUILDTOP)/include/krb5.h \ + $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ + $(SRCTOP)/include/krb5/kdb.h $(SRCTOP)/include/krb5/kdb.h \ + $(DB_DEPS) $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ + $(BUILDTOP)/include/gssrpc/xdr.h ../adb_err.h +kdb_db2.so kdb_db2.po $(OUTPRE)kdb_db2.$(OBJEXT): kdb_db2.c \ + $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ + $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ + $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ + $(DB_DEPS) $(srcdir)/../kdb5.h $(SRCTOP)/include/k5-int.h \ + $(srcdir)/../err_handle.h kdb_db2.h policy_db.h $(SRCTOP)/include/krb5/kdb.h \ + $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ + $(BUILDTOP)/include/gssrpc/xdr.h ../adb_err.h kdb_xdr.h \ + kdb_compat.h +pol_xdr.so pol_xdr.po $(OUTPRE)pol_xdr.$(OBJEXT): pol_xdr.c \ + $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/gssrpc/rpc.h \ + $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ + $(BUILDTOP)/include/gssrpc/xdr.h $(BUILDTOP)/include/gssrpc/auth.h \ + $(BUILDTOP)/include/gssrpc/clnt.h $(BUILDTOP)/include/gssrpc/rpc_msg.h \ + $(BUILDTOP)/include/gssrpc/auth_unix.h $(BUILDTOP)/include/gssrpc/auth_gss.h \ + $(BUILDTOP)/include/gssapi/gssapi.h $(BUILDTOP)/include/gssrpc/svc_auth.h \ + $(BUILDTOP)/include/gssrpc/svc.h $(SRCTOP)/include/krb5/kdb.h \ + policy_db.h $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ + $(BUILDTOP)/include/profile.h $(SRCTOP)/include/port-sockets.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/socket-utils.h \ + $(SRCTOP)/include/krb5/kdb.h $(DB_DEPS) ../adb_err.h +db2_exp.so db2_exp.po $(OUTPRE)db2_exp.$(OBJEXT): db2_exp.c \ + $(SRCTOP)/include/k5-int.h $(BUILDTOP)/include/krb5/osconf.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-platform.h \ + $(BUILDTOP)/include/krb5/autoconf.h $(SRCTOP)/include/k5-thread.h \ + $(BUILDTOP)/include/krb5.h $(COM_ERR_DEPS) $(BUILDTOP)/include/profile.h \ + $(SRCTOP)/include/port-sockets.h $(BUILDTOP)/include/krb5/autoconf.h \ + $(SRCTOP)/include/socket-utils.h $(SRCTOP)/include/krb5/kdb.h \ + $(DB_DEPS) $(srcdir)/../kdb5.h $(SRCTOP)/include/k5-int.h \ + $(srcdir)/../err_handle.h kdb_db2.h policy_db.h $(SRCTOP)/include/krb5/kdb.h \ + $(BUILDTOP)/include/gssrpc/types.h $(BUILDTOP)/include/gssrpc/rename.h \ + $(BUILDTOP)/include/gssrpc/xdr.h ../adb_err.h kdb_xdr.h diff --git a/src/lib/kdb/kdb_db2/adb_openclose.c b/src/lib/kdb/kdb_db2/adb_openclose.c new file mode 100644 index 000000000..97ce1123b --- /dev/null +++ b/src/lib/kdb/kdb_db2/adb_openclose.c @@ -0,0 +1,412 @@ +/* + * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved + * + * $Header$ + */ + +#if !defined(lint) && !defined(__CODECENTER__) +static char *rcsid = "$Header$"; +#endif + +#include +#include +#include +#include +#include "policy_db.h" +#include +#include + +#define MAX_LOCK_TRIES 5 + +struct _locklist { + osa_adb_lock_ent lockinfo; + struct _locklist *next; +}; + +krb5_error_code osa_adb_create_db(char *filename, char *lockfilename, + int magic) +{ + int lf; + DB *db; + BTREEINFO btinfo; + + memset(&btinfo, 0, sizeof(btinfo)); + btinfo.flags = 0; + btinfo.cachesize = 0; + btinfo.psize = 4096; + btinfo.lorder = 0; + btinfo.minkeypage = 0; + btinfo.compare = NULL; + btinfo.prefix = NULL; + db = dbopen(filename, O_RDWR | O_CREAT | O_EXCL, 0600, DB_BTREE, &btinfo); + if (db == NULL) + return errno; + if (db->close(db) < 0) + return errno; + + /* only create the lock file if we successfully created the db */ + lf = THREEPARAMOPEN(lockfilename, O_RDWR | O_CREAT | O_EXCL, 0600); + if (lf == -1) + return errno; + (void) close(lf); + + return OSA_ADB_OK; +} + +krb5_error_code osa_adb_destroy_db(char *filename, char *lockfilename, + int magic) +{ + /* the admin databases do not contain security-critical data */ + if (unlink(filename) < 0 || + unlink(lockfilename) < 0) + return errno; + return OSA_ADB_OK; +} + +krb5_error_code osa_adb_rename_db(char *filefrom, char *lockfrom, + char *fileto, char *lockto, int magic) +{ + osa_adb_db_t fromdb, todb; + krb5_error_code ret; + + /* make sure todb exists */ + if ((ret = osa_adb_create_db(fileto, lockto, magic)) && + ret != EEXIST) + return ret; + + if ((ret = osa_adb_init_db(&fromdb, filefrom, lockfrom, magic))) + return ret; + if ((ret = osa_adb_init_db(&todb, fileto, lockto, magic))) { + (void) osa_adb_fini_db(fromdb, magic); + return ret; + } + if ((ret = osa_adb_get_lock(fromdb, KRB5_DB_LOCKMODE_PERMANENT))) { + (void) osa_adb_fini_db(fromdb, magic); + (void) osa_adb_fini_db(todb, magic); + return ret; + } + if ((ret = osa_adb_get_lock(todb, KRB5_DB_LOCKMODE_PERMANENT))) { + (void) osa_adb_fini_db(fromdb, magic); + (void) osa_adb_fini_db(todb, magic); + return ret; + } + if ((rename(filefrom, fileto) < 0)) { + (void) osa_adb_fini_db(fromdb, magic); + (void) osa_adb_fini_db(todb, magic); + return errno; + } + /* + * Do not release the lock on fromdb because it is being renamed + * out of existence; no one can ever use it again. + */ + if ((ret = osa_adb_release_lock(todb))) { + (void) osa_adb_fini_db(fromdb, magic); + (void) osa_adb_fini_db(todb, magic); + return ret; + } + + (void) osa_adb_fini_db(fromdb, magic); + (void) osa_adb_fini_db(todb, magic); + return 0; +} + +krb5_error_code osa_adb_init_db(osa_adb_db_t *dbp, char *filename, + char *lockfilename, int magic) +{ + osa_adb_db_t db; + static struct _locklist *locklist = NULL; + struct _locklist *lockp; + krb5_error_code code; + + if (dbp == NULL || filename == NULL) + return EINVAL; + + db = (osa_adb_princ_t) malloc(sizeof(osa_adb_db_ent)); + if (db == NULL) + return ENOMEM; + + memset(db, 0, sizeof(*db)); + db->info.hash = NULL; + db->info.bsize = 256; + db->info.ffactor = 8; + db->info.nelem = 25000; + db->info.lorder = 0; + + db->btinfo.flags = 0; + db->btinfo.cachesize = 0; + db->btinfo.psize = 4096; + db->btinfo.lorder = 0; + db->btinfo.minkeypage = 0; + db->btinfo.compare = NULL; + db->btinfo.prefix = NULL; + /* + * A process is allowed to open the same database multiple times + * and access it via different handles. If the handles use + * distinct lockinfo structures, things get confused: lock(A), + * lock(B), release(B) will result in the kernel unlocking the + * lock file but handle A will still think the file is locked. + * Therefore, all handles using the same lock file must share a + * single lockinfo structure. + * + * It is not sufficient to have a single lockinfo structure, + * however, because a single process may also wish to open + * multiple different databases simultaneously, with different + * lock files. This code used to use a single static lockinfo + * structure, which means that the second database opened used + * the first database's lock file. This was Bad. + * + * We now maintain a linked list of lockinfo structures, keyed by + * lockfilename. An entry is added when this function is called + * with a new lockfilename, and all subsequent calls with that + * lockfilename use the existing entry, updating the refcnt. + * When the database is closed with fini_db(), the refcnt is + * decremented, and when it is zero the lockinfo structure is + * freed and reset. The entry in the linked list, however, is + * never removed; it will just be reinitialized the next time + * init_db is called with the right lockfilename. + */ + + /* find or create the lockinfo structure for lockfilename */ + lockp = locklist; + while (lockp) { + if (strcmp(lockp->lockinfo.filename, lockfilename) == 0) + break; + else + lockp = lockp->next; + } + if (lockp == NULL) { + /* doesn't exist, create it, add to list */ + lockp = (struct _locklist *) malloc(sizeof(*lockp)); + if (lockp == NULL) { + free(db); + return ENOMEM; + } + memset(lockp, 0, sizeof(*lockp)); + lockp->next = locklist; + locklist = lockp; + } + + /* now initialize lockp->lockinfo if necessary */ + if (lockp->lockinfo.lockfile == NULL) { + if ((code = krb5_init_context(&lockp->lockinfo.context))) { + free(db); + return((krb5_error_code) code); + } + + /* + * needs be open read/write so that write locking can work with + * POSIX systems + */ + lockp->lockinfo.filename = strdup(lockfilename); + if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r+")) == NULL) { + /* + * maybe someone took away write permission so we could only + * get shared locks? + */ + if ((lockp->lockinfo.lockfile = fopen(lockfilename, "r")) + == NULL) { + free(db); + return OSA_ADB_NOLOCKFILE; + } + } + lockp->lockinfo.lockmode = lockp->lockinfo.lockcnt = 0; + } + + /* lockp is set, lockinfo is initialized, update the reference count */ + db->lock = &lockp->lockinfo; + db->lock->refcnt++; + + db->opencnt = 0; + db->filename = strdup(filename); + db->magic = magic; + + *dbp = db; + + return OSA_ADB_OK; +} + +krb5_error_code osa_adb_fini_db(osa_adb_db_t db, int magic) +{ + if (db->magic != magic) + return EINVAL; + if (db->lock->refcnt == 0) { + /* barry says this can't happen */ + return OSA_ADB_FAILURE; + } else { + db->lock->refcnt--; + } + + if (db->lock->refcnt == 0) { + /* + * Don't free db->lock->filename, it is used as a key to + * find the lockinfo entry in the linked list. If the + * lockfile doesn't exist, we must be closing the database + * after trashing it. This has to be allowed, so don't + * generate an error. + */ + if (db->lock->lockmode != KRB5_DB_LOCKMODE_PERMANENT) + (void) fclose(db->lock->lockfile); + db->lock->lockfile = NULL; + krb5_free_context(db->lock->context); + } + + db->magic = 0; + free(db->filename); + free(db); + return OSA_ADB_OK; +} + +krb5_error_code osa_adb_get_lock(osa_adb_db_t db, int mode) +{ + int tries, gotlock, perm, krb5_mode, ret = 0; + + if (db->lock->lockmode >= mode) { + /* No need to upgrade lock, just incr refcnt and return */ + db->lock->lockcnt++; + return(OSA_ADB_OK); + } + + perm = 0; + switch (mode) { + case KRB5_DB_LOCKMODE_PERMANENT: + perm = 1; + case KRB5_DB_LOCKMODE_EXCLUSIVE: + krb5_mode = KRB5_LOCKMODE_EXCLUSIVE; + break; + case KRB5_DB_LOCKMODE_SHARED: + krb5_mode = KRB5_LOCKMODE_SHARED; + break; + default: + return(EINVAL); + } + + for (gotlock = tries = 0; tries < MAX_LOCK_TRIES; tries++) { + if ((ret = krb5_lock_file(db->lock->context, + fileno(db->lock->lockfile), + krb5_mode|KRB5_LOCKMODE_DONTBLOCK)) == 0) { + gotlock++; + break; + } else if (ret == EBADF && mode == KRB5_DB_LOCKMODE_EXCLUSIVE) + /* tried to exclusive-lock something we don't have */ + /* write access to */ + return OSA_ADB_NOEXCL_PERM; + + sleep(1); + } + + /* test for all the likely "can't get lock" error codes */ + if (ret == EACCES || ret == EAGAIN || ret == EWOULDBLOCK) + return OSA_ADB_CANTLOCK_DB; + else if (ret != 0) + return ret; + + /* + * If the file no longer exists, someone acquired a permanent + * lock. If that process terminates its exclusive lock is lost, + * but if we already had the file open we can (probably) lock it + * even though it has been unlinked. So we need to insist that + * it exist. + */ + if (access(db->lock->filename, F_OK) < 0) { + (void) krb5_lock_file(db->lock->context, + fileno(db->lock->lockfile), + KRB5_LOCKMODE_UNLOCK); + return OSA_ADB_NOLOCKFILE; + } + + /* we have the shared/exclusive lock */ + + if (perm) { + if (unlink(db->lock->filename) < 0) { + /* somehow we can't delete the file, but we already */ + /* have the lock, so release it and return */ + + ret = errno; + (void) krb5_lock_file(db->lock->context, + fileno(db->lock->lockfile), + KRB5_LOCKMODE_UNLOCK); + + /* maybe we should return CANTLOCK_DB.. but that would */ + /* look just like the db was already locked */ + return ret; + } + + /* this releases our exclusive lock.. which is okay because */ + /* now no one else can get one either */ + (void) fclose(db->lock->lockfile); + } + + db->lock->lockmode = mode; + db->lock->lockcnt++; + return OSA_ADB_OK; +} + +krb5_error_code osa_adb_release_lock(osa_adb_db_t db) +{ + int ret, fd; + + if (!db->lock->lockcnt) /* lock already unlocked */ + return OSA_ADB_NOTLOCKED; + + if (--db->lock->lockcnt == 0) { + if (db->lock->lockmode == KRB5_DB_LOCKMODE_PERMANENT) { + /* now we need to create the file since it does not exist */ + fd = THREEPARAMOPEN(db->lock->filename,O_RDWR | O_CREAT | O_EXCL, + 0600); + if ((db->lock->lockfile = fdopen(fd, "w+")) == NULL) + return OSA_ADB_NOLOCKFILE; + } else if ((ret = krb5_lock_file(db->lock->context, + fileno(db->lock->lockfile), + KRB5_LOCKMODE_UNLOCK))) + return ret; + + db->lock->lockmode = 0; + } + return OSA_ADB_OK; +} + +krb5_error_code osa_adb_open_and_lock(osa_adb_princ_t db, int locktype) +{ + int ret; + + ret = osa_adb_get_lock(db, locktype); + if (ret != OSA_ADB_OK) + return ret; + if (db->opencnt) + goto open_ok; + + db->db = dbopen(db->filename, O_RDWR, 0600, DB_BTREE, &db->btinfo); + if (db->db != NULL) + goto open_ok; + switch (errno) { +#ifdef EFTYPE + case EFTYPE: +#endif + case EINVAL: + db->db = dbopen(db->filename, O_RDWR, 0600, DB_HASH, &db->info); + if (db->db != NULL) + goto open_ok; + default: + (void) osa_adb_release_lock(db); + if (errno == EINVAL) + return OSA_ADB_BAD_DB; + return errno; + } +open_ok: + db->opencnt++; + return OSA_ADB_OK; +} + +krb5_error_code osa_adb_close_and_unlock(osa_adb_princ_t db) +{ + if (--db->opencnt) + return osa_adb_release_lock(db); + if(db->db != NULL && db->db->close(db->db) == -1) { + (void) osa_adb_release_lock(db); + return OSA_ADB_FAILURE; + } + + db->db = NULL; + + return(osa_adb_release_lock(db)); +} diff --git a/src/lib/kdb/kdb_db2/adb_policy.c b/src/lib/kdb/kdb_db2/adb_policy.c new file mode 100644 index 000000000..e338cbbd0 --- /dev/null +++ b/src/lib/kdb/kdb_db2/adb_policy.c @@ -0,0 +1,389 @@ +/* + * Copyright 1993 OpenVision Technologies, Inc., All Rights Reserved + * + * $Header$ + */ + +#if !defined(lint) && !defined(__CODECENTER__) +static char *rcsid = "$Header$"; +#endif + +#include +#include +#include "policy_db.h" +#include +#include +#include + +#define OPENLOCK(db, mode) \ +{ \ + int olret; \ + if (db == NULL) \ + return EINVAL; \ + else if (db->magic != OSA_ADB_POLICY_DB_MAGIC) \ + return OSA_ADB_DBINIT; \ + else if ((olret = osa_adb_open_and_lock(db, mode)) != OSA_ADB_OK) \ + return olret; \ + } + +#define CLOSELOCK(db) \ +{ \ + int cl_ret; \ + if ((cl_ret = osa_adb_close_and_unlock(db)) != OSA_ADB_OK) \ + return cl_ret; \ +} + + +/* + * Function: osa_adb_create_policy + * + * Purpose: create a policy entry in the policy db. + * + * Arguments: + * entry (input) pointer to the entry to be added + * OSA_ADB_OK on success, else error code. + * + * Requires: + * entry have a valid name. + * + * Effects: + * creates the entry in the db + * + * Modifies: + * the policy db. + * + */ +krb5_error_code +osa_adb_create_policy(osa_adb_policy_t db, osa_policy_ent_t entry) +{ + DBT dbkey; + DBT dbdata; + XDR xdrs; + int ret; + + OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); + + if(entry->name == NULL) { + ret = EINVAL; + goto error; + } + dbkey.data = entry->name; + dbkey.size = (strlen(entry->name) + 1); + + switch(db->db->get(db->db, &dbkey, &dbdata, 0)) { + case 0: + ret = OSA_ADB_DUP; + goto error; + case 1: + break; + default: + ret = errno; + goto error; + } + xdralloc_create(&xdrs, XDR_ENCODE); + if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { + xdr_destroy(&xdrs); + ret = OSA_ADB_XDR_FAILURE; + goto error; + } + dbdata.data = xdralloc_getdata(&xdrs); + dbdata.size = xdr_getpos(&xdrs); + switch(db->db->put(db->db, &dbkey, &dbdata, R_NOOVERWRITE)) { + case 0: + if((db->db->sync(db->db, 0)) == -1) + ret = OSA_ADB_FAILURE; + ret = OSA_ADB_OK; + break; + case 1: + ret = OSA_ADB_DUP; + break; + default: + ret = OSA_ADB_FAILURE; + break; + } + xdr_destroy(&xdrs); + +error: + CLOSELOCK(db); + return ret; +} + +/* + * Function: osa_adb_destroy_policy + * + * Purpose: destroy a policy entry + * + * Arguments: + * db (input) database handle + * name (input) name of policy + * OSA_ADB_OK on success, or error code. + * + * Requires: + * db being valid. + * name being non-null. + * Effects: + * deletes policy from db. + * + * Modifies: + * policy db. + * + */ +krb5_error_code +osa_adb_destroy_policy(osa_adb_policy_t db, char *name) +{ + DBT dbkey; + int status, ret; + + OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); + + if(name == NULL) { + ret = EINVAL; + goto error; + } + dbkey.data = name; + dbkey.size = (strlen(name) + 1); + + status = db->db->del(db->db, &dbkey, 0); + switch(status) { + case 1: + ret = OSA_ADB_NOENT; + goto error; + case 0: + if ((db->db->sync(db->db, 0)) == -1) { + ret = OSA_ADB_FAILURE; + goto error; + } + ret = OSA_ADB_OK; + break; + default: + ret = OSA_ADB_FAILURE; + goto error; + } + +error: + CLOSELOCK(db); + return ret; +} + +/* + * Function: osa_adb_get_policy + * + * Purpose: retrieve policy + * + * Arguments: + * db (input) db handle + * name (input) name of policy + * entry (output) policy entry + * cnt (inout) Number of entries + * 0 on success, error code on failure. + * + * Requires: + * Effects: + * Modifies: + */ +krb5_error_code +osa_adb_get_policy(osa_adb_policy_t db, char *name, + osa_policy_ent_t *entry, int *cnt) +{ + DBT dbkey; + DBT dbdata; + XDR xdrs; + int ret; + char *aligned_data; + + OPENLOCK(db, KRB5_DB_LOCKMODE_SHARED); + + *cnt = 1; + + if(name == NULL) { + ret = EINVAL; + goto error; + } + dbkey.data = name; + dbkey.size = (strlen(dbkey.data) + 1); + dbdata.data = NULL; + dbdata.size = 0; + switch((db->db->get(db->db, &dbkey, &dbdata, 0))) { + case 1: + ret = 0; + *cnt = 0; + goto error; + case 0: + break; + default: + ret = OSA_ADB_FAILURE; + goto error; + } + if (!(*(entry) = (osa_policy_ent_t)malloc(sizeof(osa_policy_ent_rec)))) { + ret = ENOMEM; + goto error; + } + if (!(aligned_data = (char *) malloc(dbdata.size))) { + ret = ENOMEM; + goto error; + } + memcpy(aligned_data, dbdata.data, dbdata.size); + memset(*entry, 0, sizeof(osa_policy_ent_rec)); + xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE); + if (!xdr_osa_policy_ent_rec(&xdrs, *entry)) + ret = OSA_ADB_FAILURE; + else ret = OSA_ADB_OK; + xdr_destroy(&xdrs); + free(aligned_data); + +error: + CLOSELOCK(db); + return ret; +} + +/* + * Function: osa_adb_put_policy + * + * Purpose: update a policy in the dababase + * + * Arguments: + * db (input) db handle + * entry (input) policy entry + * 0 on success error code on failure. + * + * Requires: + * [requires] + * + * Effects: + * [effects] + * + * Modifies: + * [modifies] + * + */ +krb5_error_code +osa_adb_put_policy(osa_adb_policy_t db, osa_policy_ent_t entry) +{ + DBT dbkey; + DBT dbdata; + DBT tmpdb; + XDR xdrs; + int ret; + + OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); + + if(entry->name == NULL) { + ret = EINVAL; + goto error; + } + dbkey.data = entry->name; + dbkey.size = (strlen(entry->name) + 1); + switch(db->db->get(db->db, &dbkey, &tmpdb, 0)) { + case 0: + break; + case 1: + ret = OSA_ADB_NOENT; + goto error; + default: + ret = OSA_ADB_FAILURE; + goto error; + } + xdralloc_create(&xdrs, XDR_ENCODE); + if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { + xdr_destroy(&xdrs); + ret = OSA_ADB_XDR_FAILURE; + goto error; + } + dbdata.data = xdralloc_getdata(&xdrs); + dbdata.size = xdr_getpos(&xdrs); + switch(db->db->put(db->db, &dbkey, &dbdata, 0)) { + case 0: + if((db->db->sync(db->db, 0)) == -1) + ret = OSA_ADB_FAILURE; + ret = OSA_ADB_OK; + break; + default: + ret = OSA_ADB_FAILURE; + break; + } + xdr_destroy(&xdrs); + +error: + CLOSELOCK(db); + return ret; +} + +/* + * Function: osa_adb_iter_policy + * + * Purpose: iterate over the policy database. + * + * Arguments: + * db (input) db handle + * func (input) fucntion pointer to call + * data opaque data type + * 0 on success error code on failure + * + * Requires: + * Effects: + * Modifies: + */ +krb5_error_code +osa_adb_iter_policy(osa_adb_policy_t db, osa_adb_iter_policy_func func, + void *data) +{ + DBT dbkey, + dbdata; + XDR xdrs; + int ret; + osa_policy_ent_t entry; + char *aligned_data; + + OPENLOCK(db, KRB5_DB_LOCKMODE_EXCLUSIVE); /* hmmm */ + + if((ret = db->db->seq(db->db, &dbkey, &dbdata, R_FIRST)) == -1) { + ret = errno; + goto error; + } + + while (ret == 0) { + if (!(entry = (osa_policy_ent_t) malloc(sizeof(osa_policy_ent_rec)))) { + ret = ENOMEM; + goto error; + } + + if(!(aligned_data = (char *) malloc(dbdata.size))) { + ret = ENOMEM; + goto error; + } + memcpy(aligned_data, dbdata.data, dbdata.size); + + memset(entry, 0, sizeof(osa_policy_ent_rec)); + xdrmem_create(&xdrs, aligned_data, dbdata.size, XDR_DECODE); + if(!xdr_osa_policy_ent_rec(&xdrs, entry)) { + xdr_destroy(&xdrs); + free(aligned_data); + ret = OSA_ADB_FAILURE; + goto error; + } + (*func)(data, entry); + xdr_destroy(&xdrs); + free(aligned_data); + osa_free_policy_ent(entry); + ret = db->db->seq(db->db, &dbkey, &dbdata, R_NEXT); + } + if(ret == -1) + ret = errno; + else ret = OSA_ADB_OK; + +error: + CLOSELOCK(db); + return ret; +} + +void +osa_free_policy_ent(osa_policy_ent_t val) +{ + XDR xdrs; + + xdrmem_create(&xdrs, NULL, 0, XDR_FREE); + + xdr_osa_policy_ent_rec(&xdrs, val); + + free(val); +} diff --git a/src/lib/kdb/kdb_db2/configure.in b/src/lib/kdb/kdb_db2/configure.in new file mode 100644 index 000000000..dc002d878 --- /dev/null +++ b/src/lib/kdb/kdb_db2/configure.in @@ -0,0 +1,22 @@ +AC_INIT(configure.in) +CONFIG_RULES +AC_CHECK_HEADERS(unistd.h) +AC_TYPE_MODE_T +AC_TYPE_OFF_T + +AC_CHECK_FUNCS(srand48 srand srandom umask) + +dnl AIX is unusual in that it wants all symbols resolved at link time +dnl Fortunately, it will allow us to link the kdb library now, even if +dnl it is linked again later. +case $krb5_cv_host in +*-*-aix*) + LIBS="$LIBS -ldb" + ;; +esac +KRB5_RUN_FLAGS +dnl The following is for check... +KRB5_BUILD_PROGRAM +KRB5_BUILD_LIBOBJS +KRB5_BUILD_LIBRARY_WITH_DEPS +V5_AC_OUTPUT_MAKEFILE diff --git a/src/lib/kdb/kdb_db2/db2_exp.c b/src/lib/kdb/kdb_db2/db2_exp.c new file mode 100644 index 000000000..f511487f1 --- /dev/null +++ b/src/lib/kdb/kdb_db2/db2_exp.c @@ -0,0 +1,64 @@ +/********************************************************************** +* +* C %name: db2_exp.c % +* Instance: idc_sec_2 +* Description: +* %created_by: spradeep % +* %date_created: Tue Apr 5 11:44:00 2005 % +* +**********************************************************************/ +#ifndef lint +static char *_csrc = "@(#) %filespec: db2_exp.c~5 % (%full_filespec: db2_exp.c~5:csrc:idc_sec#2 %)"; +#endif + +#if HAVE_UNISTD_H +#include +#endif + +#include "k5-int.h" +#include +#include +#include +#include +#include "../kdb5.h" +#include "kdb_db2.h" +#include "kdb_xdr.h" +#include "policy_db.h" + +/* + * Exposed API + */ + +kdb_vftabl krb5_db_vftabl_kdb_db2 = { + 1, /* major version number 1 */ + 0, /* minor version number 0 */ + 0, /* TBD. Not sure whether thread safe. For now, its not */ + /* init_library */ krb5_db2_lib_init, + /* fini_library */ krb5_db2_lib_cleanup, + /* init_module */ krb5_db2_open, + /* fini_module */ krb5_db2_db_fini, + /* db_create */ krb5_db2_create, + /* db_destroy */ krb5_db2_destroy, + /* db_get_age */ krb5_db2_db_get_age, + /* db_set_option */ krb5_db2_db_set_option, + /* db_lock */ krb5_db2_db_lock, + /* db_unlock */ krb5_db2_db_unlock, + /* db_get_principal */ krb5_db2_db_get_principal, + /* db_free_principal */ krb5_db2_db_free_principal, + /* db_put_principal */ krb5_db2_db_put_principal, + /* db_delete_principal */ krb5_db2_db_delete_principal, + /* db_iterate */ krb5_db2_db_iterate, + /* db_create_policy */ krb5_db2_create_policy, + /* db_get_policy */ krb5_db2_get_policy, + /* db_put_policy */ krb5_db2_put_policy, + /* db_iter_policy */ krb5_db2_iter_policy, + /* db_delete_policy */ krb5_db2_delete_policy, + /* db_free_policy */ krb5_db2_free_policy, + /* db_supported_realms */ NULL, + /* db_free_supported_realms */ NULL, + /* errcode_2_string */ NULL, + /* db_alloc */ krb5_db2_alloc, + /* db_free */ krb5_db2_free, + /* set_master_key */ krb5_db2_set_master_key_ext, + /* get_master_key */ krb5_db2_db_get_mkey +}; diff --git a/src/lib/kdb/kdb_db2/kdb_compat.h b/src/lib/kdb/kdb_db2/kdb_compat.h new file mode 100644 index 000000000..540d4a249 --- /dev/null +++ b/src/lib/kdb/kdb_db2/kdb_compat.h @@ -0,0 +1,81 @@ +/* + * lib/kdb/kdb_compat.h + * + * Copyright 1994 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * KDC Database interface definitions. + */ + + +typedef struct _old_krb5_encrypted_keyblock { + krb5_enctype enctype; + int length; + krb5_octet *contents; +} old_krb5_encrypted_keyblock; + +typedef struct old_krb5_principal_data { + krb5_magic magic; + krb5_data realm; + krb5_data *data; /* An array of strings */ + krb5_int32 length; + krb5_int32 type; +} old_krb5_principal_data; + +typedef old_krb5_principal_data *old_krb5_principal; + + +/* + * Note --- this structure cannot be modified without changing the + * database version number in libkdb.a + */ +typedef struct _old_krb5_db_entry { + old_krb5_principal principal; + old_krb5_encrypted_keyblock key; + krb5_kvno kvno; + krb5_deltat max_life; + krb5_deltat max_renewable_life; + krb5_kvno mkvno; /* master encryption key vno */ + + krb5_timestamp expiration; /* This is when the client expires */ + krb5_timestamp pw_expiration; /* This is when its password does */ + krb5_timestamp last_pwd_change; /* Last time of password change */ + krb5_timestamp last_success; /* Last successful password */ + + krb5_timestamp last_failed; /* Last failed password attempt */ + krb5_kvno fail_auth_count; /* # of failed password attempts */ + + old_krb5_principal mod_name; + krb5_timestamp mod_date; + krb5_flags attributes; + krb5_int32 salt_type:8, + salt_length:24; + krb5_octet *salt; + old_krb5_encrypted_keyblock alt_key; + krb5_int32 alt_salt_type:8, + alt_salt_length:24; + krb5_octet *alt_salt; + + krb5_int32 expansion[8]; +} old_krb5_db_entry; + diff --git a/src/lib/kdb/kdb_db2/kdb_db2.c b/src/lib/kdb/kdb_db2/kdb_db2.c new file mode 100644 index 000000000..2ac462e89 --- /dev/null +++ b/src/lib/kdb/kdb_db2/kdb_db2.c @@ -0,0 +1,2000 @@ +/* + * lib/kdb/kdb_db2.c + * + * Copyright 1997 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +/* + * Copyright (C) 1998 by the FundsXpress, INC. + * + * All rights reserved. + * + * Export of this software from the United States of America may require + * a specific license from the United States Government. It is the + * responsibility of any person or organization contemplating export to + * obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of FundsXpress. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. FundsXpress makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if HAVE_UNISTD_H +#include +#endif + +#include "k5-int.h" +#include +#include +#include +#include +#include "../kdb5.h" +#include "kdb_db2.h" +#include "kdb_xdr.h" +#include "policy_db.h" + +#define KDB_DB2_DATABASE_NAME "database_name" + +#define OLD_COMPAT_VERSION_1 + +#ifdef OLD_COMPAT_VERSION_1 +#include "kdb_compat.h" +#endif + +#include "kdb_db2.h" + +static char *gen_dbsuffix + (char *, char * ); + +static krb5_error_code krb5_db2_db_start_update + (krb5_context); +static krb5_error_code krb5_db2_db_end_update + (krb5_context); + +krb5_error_code +krb5_db2_db_set_name(krb5_context,char*); + +krb5_error_code krb5_db2_db_lock +( krb5_context, int ); + +static krb5_error_code krb5_db2_db_set_hashfirst + (krb5_context, int); + +static char default_db_name[] = DEFAULT_KDB_FILE; +krb5_set_err_func_t krb5_db2_dal_err_funcp = NULL; + +/* + * Locking: + * + * There are two distinct locking protocols used. One is designed to + * lock against processes (the admin_server, for one) which make + * incremental changes to the database; the other is designed to lock + * against utilities (kdb5_edit, kpropd, kdb5_convert) which replace the + * entire database in one fell swoop. + * + * The first locking protocol is implemented using flock() in the + * krb_dbl_lock() and krb_dbl_unlock routines. + * + * The second locking protocol is necessary because DBM "files" are + * actually implemented as two separate files, and it is impossible to + * atomically rename two files simultaneously. It assumes that the + * database is replaced only very infrequently in comparison to the time + * needed to do a database read operation. + * + * A third file is used as a "version" semaphore; the modification + * time of this file is the "version number" of the database. + * At the start of a read operation, the reader checks the version + * number; at the end of the read operation, it checks again. If the + * version number changed, or if the semaphore was nonexistant at + * either time, the reader sleeps for a second to let things + * stabilize, and then tries again; if it does not succeed after + * KRB5_DBM_MAX_RETRY attempts, it gives up. + * + * On update, the semaphore file is deleted (if it exists) before any + * update takes place; at the end of the update, it is replaced, with + * a version number strictly greater than the version number which + * existed at the start of the update. + * + * If the system crashes in the middle of an update, the semaphore + * file is not automatically created on reboot; this is a feature, not + * a bug, since the database may be inconsistant. Note that the + * absence of a semaphore file does not prevent another _update_ from + * taking place later. Database replacements take place automatically + * only on slave servers; a crash in the middle of an update will be + * fixed by the next slave propagation. A crash in the middle of an + * update on the master would be somewhat more serious, but this would + * likely be noticed by an administrator, who could fix the problem and + * retry the operation. + */ + +#define free_dbsuffix(name) free(name) + +/* + * Routines to deal with context. + */ +#define k5db2_inited(c) (c && c->db_context \ + && ((kdb5_dal_handle*)c->db_context)->db_context \ + && ((krb5_db2_context *) ((kdb5_dal_handle*)c->db_context)->db_context)->db_inited) + + +static +krb5_error_code +krb5_db2_get_db_opt( char *input, char **opt, char **val ) +{ + char *pos = strchr(input, '='); + if( pos == NULL ) + { + *opt = NULL; + *val = strdup(input); + if( *val == NULL ) + { + return ENOMEM; + } + } + else + { + *opt = malloc( (pos - input) + 1 ); + *val = strdup( pos + 1 ); + if( !*opt || !*val ) + { + return ENOMEM; + } + memcpy( *opt, input, pos - input); + (*opt)[pos - input] = '\0'; + } + return (0); + +} + +/* + * Restore the default context. + */ +static void +k5db2_clear_context(dbctx) + krb5_db2_context *dbctx; +{ + /* + * Free any dynamically allocated memory. File descriptors and locks + * are the caller's problem. + */ + if (dbctx->db_lf_name) + free(dbctx->db_lf_name); + if (dbctx->db_name && (dbctx->db_name != default_db_name)) + free(dbctx->db_name); + /* + * Clear the structure and reset the defaults. + */ + memset((char *) dbctx, 0, sizeof(krb5_db2_context)); + dbctx->db_name = default_db_name; + dbctx->db_nb_locks = FALSE; +} + + +static krb5_error_code +k5db2_init_context(context) + krb5_context context; +{ + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + + dal_handle = (kdb5_dal_handle*) context->db_context; + + if ( dal_handle->db_context == NULL) { + db_ctx = (krb5_db2_context *) malloc(sizeof(krb5_db2_context)); + if (db_ctx == NULL) + return ENOMEM; + else { + memset((char *) db_ctx, 0, sizeof(krb5_db2_context)); + k5db2_clear_context((krb5_db2_context *)db_ctx); + dal_handle->db_context = (void *) db_ctx; + } + } + return(0); +} + + +/* + * Utility routine: generate name of database file. + */ + +static char * +gen_dbsuffix(db_name, sfx) + char *db_name; + char *sfx; +{ + char *dbsuffix; + + if (sfx == NULL) + return((char *) NULL); + + dbsuffix = malloc (strlen(db_name) + strlen(sfx) + 1); + if (!dbsuffix) + return(0); + (void) strcpy(dbsuffix, db_name); + (void) strcat(dbsuffix, sfx); + return dbsuffix; +} + + +static DB * +k5db2_dbopen(dbc, fname, flags, mode) + krb5_db2_context *dbc; + char *fname; + int flags; + int mode; +{ + DB *db; + BTREEINFO bti; + HASHINFO hashi; + + bti.flags = 0; + bti.cachesize = 0; + bti.psize = 4096; + bti.lorder = 0; + bti.minkeypage = 0; + bti.compare = NULL; + bti.prefix = NULL; + + hashi.bsize = 4096; + hashi.cachesize = 0; + hashi.ffactor = 40; + hashi.hash = NULL; + hashi.lorder = 0; + hashi.nelem = 1; + + db = dbopen(fname, flags, mode, + dbc->hashfirst ? DB_HASH : DB_BTREE, + dbc->hashfirst ? (void *) &hashi : (void *) &bti); + if (db != NULL) + return db; + switch (errno) { +#ifdef EFTYPE + case EFTYPE: +#endif + case EINVAL: + db = dbopen(fname, flags, mode, + dbc->hashfirst ? DB_BTREE : DB_HASH, + dbc->hashfirst ? (void *) &bti : (void *) &hashi); + if (db != NULL) + dbc->hashfirst = !dbc->hashfirst; + default: + return db; + } +} + +static krb5_error_code +krb5_db2_db_set_hashfirst(context, hashfirst) + krb5_context context; + int hashfirst; +{ + krb5_db2_context *dbc; + kdb5_dal_handle *dal_handle; + + if (k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + dal_handle = (kdb5_dal_handle*) context->db_context; + dbc = (krb5_db2_context *) dal_handle->db_context; + dbc->hashfirst = hashfirst; + return 0; +} + +/* + * initialization for data base routines. + */ + +krb5_error_code +krb5_db2_db_init(context) + krb5_context context; +{ + char *filename = NULL; + krb5_db2_context *db_ctx; + krb5_error_code retval; + kdb5_dal_handle *dal_handle; + char policy_db_name[1024], policy_lock_name[1024]; + + if (k5db2_inited(context)) + return 0; + + /* Check for presence of our context, if not present, allocate one. */ + if ((retval = k5db2_init_context(context))) + return(retval); + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = dal_handle->db_context; + db_ctx->db = NULL; + + if (!(filename = gen_dbsuffix(db_ctx->db_name, KDB2_LOCK_EXT))) + return ENOMEM; + db_ctx->db_lf_name = filename; /* so it gets freed by clear_context */ + + /* + * should be opened read/write so that write locking can work with + * POSIX systems + */ + if ((db_ctx->db_lf_file = open(filename, O_RDWR, 0666)) < 0) { + if ((db_ctx->db_lf_file = open(filename, O_RDONLY, 0666)) < 0) { + retval = errno; + goto err_out; + } + } + db_ctx->db_inited++; + + if ((retval = krb5_db2_db_get_age(context, NULL, &db_ctx->db_lf_time))) + goto err_out; + + sprintf( policy_db_name, "%s.kadm5", db_ctx->db_name ); + sprintf( policy_lock_name, "%s.lock", policy_db_name ); + + if( (retval = osa_adb_init_db(&db_ctx->policy_db, policy_db_name, + policy_lock_name, OSA_ADB_POLICY_DB_MAGIC)) ) + { + goto err_out; + } + return 0; + +err_out: + db_ctx->db = NULL; + k5db2_clear_context(db_ctx); + return (retval); +} + + +/* + * gracefully shut down database--must be called by ANY program that does + * a krb5_db2_db_init + */ +krb5_error_code +krb5_db2_db_fini(context) + krb5_context context; +{ + krb5_error_code retval = 0; + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + + dal_handle = (kdb5_dal_handle*) context->db_context; + if( dal_handle == NULL ) + { + return 0; + } + + db_ctx = (krb5_db2_context *) dal_handle->db_context; + + if (k5db2_inited(context)) { + if (close(db_ctx->db_lf_file)) + retval = errno; + else + retval = 0; + } + if (db_ctx) { + if( db_ctx->policy_db ) + { + retval = osa_adb_fini_db(db_ctx->policy_db, OSA_ADB_POLICY_DB_MAGIC); + if( retval ) + return retval; + } + + k5db2_clear_context(db_ctx); + /* free(dal_handle->db_context); */ + dal_handle->db_context = NULL; + } + return retval; +} + +#if 0 // pradx + +krb5_error_code +krb5_db2_db_open_database(context) + krb5_context context; +{ + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + return 0; +} + +krb5_error_code +krb5_db2_db_close_database(context) + krb5_context context; +{ + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + return 0; +} + +#endif // 0 -pradx + +/* + * Set/Get the master key associated with the database + */ +krb5_error_code +krb5_db2_db_set_mkey(context, key) + krb5_context context; + krb5_keyblock *key; +{ + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + + if (!k5db2_inited(context)) + return(KRB5_KDB_DBNOTINITED); + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = dal_handle->db_context; + db_ctx->db_master_key = key; + return 0; +} + +krb5_error_code +krb5_db2_db_get_mkey(context, key) + krb5_context context; + krb5_keyblock **key; +{ + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + + if (!k5db2_inited(context)) + return(KRB5_KDB_DBNOTINITED); + + dal_handle = (kdb5_dal_handle*)context->db_context; + db_ctx = dal_handle->db_context; + *key = db_ctx->db_master_key; + + return 0; +} + +/* + * Set the "name" of the current database to some alternate value. + * + * Passing a null pointer as "name" will set back to the default. + * If the alternate database doesn't exist, nothing is changed. + * + * XXX rethink this + */ + +krb5_error_code +krb5_db2_db_set_name(context, name) + krb5_context context; + char *name; +{ + DB *db; + krb5_db2_context *db_ctx; + krb5_error_code kret; + kdb5_dal_handle *dal_handle; + + if (k5db2_inited(context)) + return KRB5_KDB_DBINITED; + + /* Check for presence of our context, if not present, allocate one. */ + if ((kret = k5db2_init_context(context))) + return(kret); + + if (name == NULL) + name = default_db_name; + + dal_handle = (kdb5_dal_handle*)context->db_context; + db_ctx = dal_handle->db_context; + db = k5db2_dbopen(db_ctx, name, O_RDONLY, 0); + if (db == NULL) + return errno; + + db_ctx->db_name = strdup(name); + (*db->close)(db); + return 0; +} + +/* + * Return the last modification time of the database. + * + * Think about using fstat. + */ + +krb5_error_code +krb5_db2_db_get_age(context, db_name, age) + krb5_context context; + char *db_name; + time_t *age; +{ + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + struct stat st; + + if (!k5db2_inited(context)) + return(KRB5_KDB_DBNOTINITED); + dal_handle = (kdb5_dal_handle *) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + + if (fstat (db_ctx->db_lf_file, &st) < 0) + *age = -1; + else + *age = st.st_mtime; + return 0; +} + +/* + * Remove the semaphore file; indicates that database is currently + * under renovation. + * + * This is only for use when moving the database out from underneath + * the server (for example, during slave updates). + */ + +static krb5_error_code +krb5_db2_db_start_update(context) + krb5_context context; +{ + return 0; +} + +static krb5_error_code +krb5_db2_db_end_update(context) + krb5_context context; +{ + krb5_error_code retval; + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + struct stat st; + time_t now; + struct utimbuf utbuf; + + if (!k5db2_inited(context)) + return(KRB5_KDB_DBNOTINITED); + + retval = 0; + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = dal_handle->db_context; + now = time((time_t *) NULL); + if (fstat(db_ctx->db_lf_file, &st) == 0) { + if (st.st_mtime >= now) { + utbuf.actime = st.st_mtime+1; + utbuf.modtime = st.st_mtime+1; + if (utime(db_ctx->db_lf_name, &utbuf)) + retval = errno; + } + else { + if (utime(db_ctx->db_lf_name, (struct utimbuf *) NULL)) + retval = errno; + } + } + else + retval = errno; + if (!retval) { + if (fstat(db_ctx->db_lf_file, &st) == 0) + db_ctx->db_lf_time = st.st_mtime; + else + retval = errno; + } + return(retval); +} + +krb5_error_code +krb5_db2_db_lock(context, in_mode) + krb5_context context; + int in_mode; +{ + krb5_db2_context *db_ctx; + int krb5_lock_mode; + DB *db; + krb5_error_code retval; + time_t mod_time; + kdb5_dal_handle *dal_handle; + int mode = in_mode & ~KRB5_DB_LOCKMODE_PERMANENT; /* permanent is not available for principal db */ + + switch( in_mode ) + { + case KRB5_DB_LOCKMODE_PERMANENT: + mode = KRB5_DB_LOCKMODE_EXCLUSIVE; + break; + case KRB5_DB_LOCKMODE_EXCLUSIVE: + mode = KRB5_LOCKMODE_EXCLUSIVE; + break; + + case KRB5_DB_LOCKMODE_SHARED: + mode = KRB5_LOCKMODE_SHARED; + break; + default: + return EINVAL; + } + + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + if (db_ctx->db_locks_held && (db_ctx->db_lock_mode >= mode)) { + /* No need to upgrade lock, just return */ + db_ctx->db_locks_held++; + goto policy_lock; + } + + if ((mode != KRB5_LOCKMODE_SHARED) && (mode != KRB5_LOCKMODE_EXCLUSIVE)) + return KRB5_KDB_BADLOCKMODE; + + if (db_ctx->db_nb_locks) + krb5_lock_mode = mode | KRB5_LOCKMODE_DONTBLOCK; + else + krb5_lock_mode = mode; + retval = krb5_lock_file(context, db_ctx->db_lf_file, krb5_lock_mode); + switch (retval) { + case EBADF: + if (mode == KRB5_LOCKMODE_EXCLUSIVE) + return KRB5_KDB_CANTLOCK_DB; + default: + return retval; + case 0: + break; + } + + if ((retval = krb5_db2_db_get_age(context, NULL, &mod_time))) + goto lock_error; + + db = k5db2_dbopen(db_ctx, db_ctx->db_name, + mode == KRB5_LOCKMODE_SHARED ? O_RDONLY : O_RDWR, + 0600); + if (db) { + db_ctx->db_lf_time = mod_time; + db_ctx->db = db; + } else { + retval = errno; + db_ctx->db = NULL; + goto lock_error; + } + + db_ctx->db_lock_mode = mode; + db_ctx->db_locks_held++; + + policy_lock: + if((retval=osa_adb_get_lock(db_ctx->policy_db, in_mode))) + { + krb5_db2_db_unlock(context); + } + return retval; + +lock_error:; + db_ctx->db_lock_mode = 0; + db_ctx->db_locks_held = 0; + krb5_db2_db_unlock(context); + return retval; +} + + +krb5_error_code +krb5_db2_db_unlock(context) + krb5_context context; +{ + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + DB *db; + krb5_error_code retval; + + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + + if( (retval = osa_adb_release_lock(db_ctx->policy_db)) ) + { + return retval; + } + + if (!db_ctx->db_locks_held) /* lock already unlocked */ + return KRB5_KDB_NOTLOCKED; + db = db_ctx->db; + if (--(db_ctx->db_locks_held) == 0) { + (*db->close)(db); + db_ctx->db = NULL; + + retval = krb5_lock_file(context, db_ctx->db_lf_file, + KRB5_LOCKMODE_UNLOCK); + db_ctx->db_lock_mode = 0; + return(retval); + } + return 0; +} + +/* + * Create the database, assuming it's not there. + */ +krb5_error_code +krb5_db2_db_create(context, db_name, flags) + krb5_context context; + char *db_name; + krb5_int32 flags; +{ + register krb5_error_code retval = 0; + kdb5_dal_handle *dal_handle; + char *okname; + int fd; + krb5_db2_context *db_ctx; + DB *db; + char policy_db_name[1024], policy_lock_name[1024]; + + if ((retval = k5db2_init_context(context))) + return(retval); + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + switch (flags) { + case KRB5_KDB_CREATE_HASH: + if ((retval = krb5_db2_db_set_hashfirst(context, TRUE))) + return retval; + break; + case KRB5_KDB_CREATE_BTREE: + case 0: + if ((retval = krb5_db2_db_set_hashfirst(context, FALSE))) + return retval; + break; + default: + return KRB5_KDB_BAD_CREATEFLAGS; + } + db = k5db2_dbopen(db_ctx, db_name, O_RDWR|O_CREAT|O_EXCL, 0600); + if (db == NULL) + retval = errno; + else + (*db->close)(db); + if (retval == 0) { + okname = gen_dbsuffix(db_name, KDB2_LOCK_EXT); + if (!okname) + retval = ENOMEM; + else { + fd = open (okname, O_CREAT|O_RDWR|O_TRUNC, 0600); + if (fd < 0) + retval = errno; + else + close(fd); + free_dbsuffix(okname); + } + } + + sprintf( policy_db_name, "%s.kadm5", db_name ); + sprintf( policy_lock_name, "%s.lock", policy_db_name ); + + retval = osa_adb_create_db( policy_db_name, + policy_lock_name, OSA_ADB_POLICY_DB_MAGIC); + + + return retval; +} + +/* + * Destroy the database. Zero's out all of the files, just to be sure. + */ +static krb5_error_code +destroy_file_suffix(dbname, suffix) + char *dbname; + char *suffix; +{ + char *filename; + struct stat statb; + int nb,fd; + unsigned int j; + off_t pos; + char buf[BUFSIZ]; + char zbuf[BUFSIZ]; + int dowrite; + + filename = gen_dbsuffix(dbname, suffix); + if (filename == 0) + return ENOMEM; + if ((fd = open(filename, O_RDWR, 0)) < 0) { + free(filename); + return errno; + } + /* fstat() will probably not fail unless using a remote filesystem + (which is inappropriate for the kerberos database) so this check + is mostly paranoia. */ + if (fstat(fd, &statb) == -1) { + int retval = errno; + free(filename); + return retval; + } + /* + * Stroll through the file, reading in BUFSIZ chunks. If everything + * is zero, then we're done for that block, otherwise, zero the block. + * We would like to just blast through everything, but some DB + * implementations make holey files and writing data to the holes + * causes actual blocks to be allocated which is no good, since + * we're just about to unlink it anyways. + */ + memset(zbuf, 0, BUFSIZ); + pos = 0; + while (pos < statb.st_size) { + dowrite = 0; + nb = read(fd, buf, BUFSIZ); + if (nb < 0) { + int retval = errno; + free(filename); + return retval; + } + for (j=0; jdb_context || !((kdb5_dal_handle*)context->db_context)->db_context ) { + tmpcontext = 1; + if ((retval1 = k5db2_init_context(context))) + return(retval1); + } + + retval1 = retval2 = 0; + retval1 = destroy_file_suffix(dbname, ""); + retval2 = destroy_file_suffix(dbname, KDB2_LOCK_EXT); + + if (tmpcontext) { + k5db2_clear_context((krb5_db2_context *) ((kdb5_dal_handle*)context->db_context)->db_context ); + free(((kdb5_dal_handle*)context->db_context)->db_context); + ((kdb5_dal_handle*)context->db_context)->db_context = NULL; + } + + if (retval1 || retval2) + return (retval1 ? retval1 : retval2); + + sprintf( policy_db_name, "%s.kadm5", dbname ); + sprintf( policy_lock_name, "%s.lock", policy_db_name ); + + retval1 = osa_adb_destroy_db( policy_db_name, + policy_lock_name, OSA_ADB_POLICY_DB_MAGIC); + + return retval1; +} + +#if 0 // -pradx + +/* + * "Atomically" rename the database in a way that locks out read + * access in the middle of the rename. + * + * Not perfect; if we crash in the middle of an update, we don't + * necessarily know to complete the transaction the rename, but... + * + * Since the rename operation happens outside the init/fini bracket, we + * have to go through the same stuff that we went through up in db_destroy. + */ +krb5_error_code +krb5_db2_db_rename(context, from, to) + krb5_context context; + char *from; + char *to; +{ + DB *db; + char *fromok; + krb5_error_code retval; + kdb5_dal_handle *dal_handle; + krb5_db2_context *s_context, *db_ctx; + + dal_handle = (kdb5_dal_handle*) context->db_context; + s_context = dal_handle->db_context; + dal_handle->db_context = NULL; + if ((retval = k5db2_init_context(context))) + return retval; + db_ctx = (krb5_db2_context *) ((kdb5_dal_handle*)context->db_context)->db_context; + + /* + * Create the database if it does not already exist; the + * files must exist because krb5_db2_db_lock, called below, + * will fail otherwise. + */ + db = k5db2_dbopen(db_ctx, to, O_RDWR|O_CREAT, 0600); + if (db == NULL) { + retval = errno; + goto errout; + } + else + (*db->close)(db); + /* + * Set the database to the target, so that other processes sharing + * the target will stop their activity, and notice the new database. + */ + retval = krb5_db2_db_set_name(context, to); + if (retval) + goto errout; + + db_ctx->db_lf_name = gen_dbsuffix(db_ctx->db_name, KDB2_LOCK_EXT); + if (db_ctx->db_lf_name == NULL) { + retval = ENOMEM; + goto errout; + } + db_ctx->db_lf_file = open(db_ctx->db_lf_name, O_RDWR|O_CREAT, 0600); + if (db_ctx->db_lf_file < 0) { + retval = errno; + goto errout; + } + + db_ctx->db_inited = 1; + + retval = krb5_db2_db_get_age(context, NULL, &db_ctx->db_lf_time); + if (retval) + goto errout; + + fromok = gen_dbsuffix(from, KDB2_LOCK_EXT); + if (fromok == NULL) { + retval = ENOMEM; + goto errout; + } + + if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) + goto errfromok; + + if ((retval = krb5_db2_db_start_update(context))) + goto errfromok; + + if (rename(from, to)) { + retval = errno; + goto errfromok; + } + if (unlink(fromok)) { + retval = errno; + goto errfromok; + } + retval = krb5_db2_db_end_update(context); +errfromok: + free_dbsuffix(fromok); +errout: + if ( ((kdb5_dal_handle*)context->db_context)->db_context ) { + if (db_ctx->db_lf_file >= 0) { + krb5_db2_db_unlock(context); + close(db_ctx->db_lf_file); + } + k5db2_clear_context((krb5_db2_context *) ((kdb5_dal_handle*)context->db_context)->db_context); + free(((kdb5_dal_handle*)context->db_context)->db_context); + } + + ((kdb5_dal_handle*)context->db_context)->db_context = s_context; + (void) krb5_db2_db_unlock(context); /* unlock saved context db */ + + return retval; +} + +#endif // 0 - pradx + +/* + * look up a principal in the data base. + * returns number of entries found, and whether there were + * more than requested. + */ + +krb5_error_code +krb5_db2_db_get_principal(context, searchfor, entries, nentries, more) + krb5_context context; + krb5_const_principal searchfor; + krb5_db_entry *entries; /* filled in */ + int *nentries; /* how much room/how many found */ + krb5_boolean *more; /* are there more? */ +{ + krb5_db2_context *db_ctx; + krb5_error_code retval; + DB *db; + DBT key, contents; + krb5_data keydata, contdata; + int try, dbret; + kdb5_dal_handle *dal_handle; + + *more = FALSE; + *nentries = 0; + + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + + for (try = 0; try < KRB5_DB2_MAX_RETRY; try++) { + if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_SHARED))) { + if (db_ctx->db_nb_locks) + return(retval); + sleep(1); + continue; + } + break; + } + if (try == KRB5_DB2_MAX_RETRY) + return KRB5_KDB_DB_INUSE; + + /* XXX deal with wildcard lookups */ + retval = krb5_encode_princ_dbkey(context, &keydata, searchfor); + if (retval) + goto cleanup; + key.data = keydata.data; + key.size = keydata.length; + + db = db_ctx->db; + dbret = (*db->get)(db, &key, &contents, 0); + retval = errno; + krb5_free_data_contents(context, &keydata); + switch (dbret) { + case 1: + retval = 0; + case -1: + default: + *nentries = 0; + goto cleanup; + case 0: + contdata.data = contents.data; + contdata.length = contents.size; + retval = krb5_decode_princ_contents(context, &contdata, entries); + if (!retval) + *nentries = 1; + break; + } + +cleanup: + (void) krb5_db2_db_unlock(context); /* unlock read lock */ + return retval; +} + +/* + Free stuff returned by krb5_db2_db_get_principal. + */ +krb5_error_code +krb5_db2_db_free_principal(context, entries, nentries) + krb5_context context; + krb5_db_entry *entries; + int nentries; +{ + register int i; + for (i = 0; i < nentries; i++) + krb5_dbe_free_contents(context, &entries[i]); + return 0; +} + +/* + Stores the *"nentries" entry structures pointed to by "entries" in the + database. + + *"nentries" is updated upon return to reflect the number of records + acutally stored; the first *"nstored" records will have been stored in the + database (even if an error occurs). + + */ + +krb5_error_code +krb5_db2_db_put_principal(context, entries, nentries, db_args) + krb5_context context; + krb5_db_entry *entries; + register int *nentries; /* number of entry structs to update */ + char **db_args; +{ + int i, n, dbret; + DB *db; + DBT key, contents; + krb5_data contdata, keydata; + krb5_error_code retval; + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + + if( db_args ) + { + /* DB2 does not support db_args DB arguments for principal */ + char buf[KRB5_MAX_ERR_STR]; + sprintf(buf, "Unsupported argument \"%s\" for db2", db_args[0]); + krb5_db2_dal_err_funcp( context, krb5_err_have_str, EINVAL, buf); + return EINVAL; + } + + n = *nentries; + *nentries = 0; + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) + return retval; + + db = db_ctx->db; + if ((retval = krb5_db2_db_start_update(context))) { + (void)krb5_db2_db_unlock(context); + return retval; + } + + /* for each one, stuff temps, and do replace/append */ + for (i = 0; i < n; i++) { + retval = krb5_encode_princ_contents(context, &contdata, entries); + if (retval) + break; + contents.data = contdata.data; + contents.size = contdata.length; + retval = krb5_encode_princ_dbkey(context, &keydata, entries->princ); + if (retval) { + krb5_free_data_contents(context, &contdata); + break; + } + + key.data = keydata.data; + key.size = keydata.length; + dbret = (*db->put)(db, &key, &contents, 0); + retval = dbret ? errno : 0; + krb5_free_data_contents(context, &keydata); + krb5_free_data_contents(context, &contdata); + if (retval) + break; + entries++; /* bump to next struct */ + } + + (void)krb5_db2_db_end_update(context); + (void)krb5_db2_db_unlock(context); /* unlock database */ + *nentries = i; + return(retval); +} + +/* + * delete a principal from the data base. + * returns number of entries removed + */ + +krb5_error_code +krb5_db2_db_delete_principal(context, searchfor, nentries) + krb5_context context; + krb5_const_principal searchfor; + int *nentries; /* how many found & deleted */ +{ + krb5_error_code retval; + krb5_db_entry entry; + krb5_db2_context *db_ctx; + DB *db; + DBT key, contents; + krb5_data keydata, contdata; + int i, dbret; + kdb5_dal_handle *dal_handle; + + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + if ((retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_EXCLUSIVE))) + return(retval); + + if ((retval = krb5_db2_db_start_update(context))) { + (void) krb5_db2_db_unlock(context); /* unlock write lock */ + return(retval); + } + + if ((retval = krb5_encode_princ_dbkey(context, &keydata, searchfor))) + goto cleanup; + key.data = keydata.data; + key.size = keydata.length; + + db = db_ctx->db; + dbret = (*db->get)(db, &key, &contents, 0); + retval = errno; + switch (dbret) { + case 1: + retval = KRB5_KDB_NOENTRY; + case -1: + default: + *nentries = 0; + goto cleankey; + case 0: + ; + } + memset((char *)&entry, 0, sizeof(entry)); + contdata.data = contents.data; + contdata.length = contents.size; + retval = krb5_decode_princ_contents(context, &contdata, &entry); + if (retval) + goto cleankey; + *nentries = 1; + + /* Clear encrypted key contents */ + for (i = 0; i < entry.n_key_data; i++) { + if (entry.key_data[i].key_data_length[0]) { + memset((char *)entry.key_data[i].key_data_contents[0], 0, + (unsigned) entry.key_data[i].key_data_length[0]); + } + } + + retval = krb5_encode_princ_contents(context, &contdata, &entry); + krb5_dbe_free_contents(context, &entry); + if (retval) + goto cleankey; + + contents.data = contdata.data; + contents.size = contdata.length; + dbret = (*db->put)(db, &key, &contents, 0); + retval = dbret ? errno : 0; + krb5_free_data_contents(context, &contdata); + if (retval) + goto cleankey; + dbret = (*db->del)(db, &key, 0); + retval = dbret ? errno : 0; +cleankey: + krb5_free_data_contents(context, &keydata); + +cleanup: + (void) krb5_db2_db_end_update(context); + (void) krb5_db2_db_unlock(context); /* unlock write lock */ + return retval; +} + +krb5_error_code +krb5_db2_db_iterate_ext(context, func, func_arg, backwards, recursive) + krb5_context context; + krb5_error_code (*func) (krb5_pointer, krb5_db_entry *); + krb5_pointer func_arg; + int backwards, recursive; +{ + krb5_db2_context *db_ctx; + DB *db; + DBT key, contents; + krb5_data contdata; + krb5_db_entry entries; + krb5_error_code retval; + kdb5_dal_handle *dal_handle; + int dbret; + void *cookie; + + cookie = NULL; + if (!k5db2_inited(context)) + return KRB5_KDB_DBNOTINITED; + + dal_handle = (kdb5_dal_handle*) context->db_context; + db_ctx = (krb5_db2_context *) dal_handle->db_context; + retval = krb5_db2_db_lock(context, KRB5_LOCKMODE_SHARED); + + if (retval) + return retval; + + db = db_ctx->db; + if (recursive && db->type != DB_BTREE) { + (void)krb5_db2_db_unlock(context); + return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */ + } + + if (!recursive) { + dbret = (*db->seq)(db, &key, &contents, + backwards ? R_LAST : R_FIRST); + } else { +#ifdef HAVE_BT_RSEQ + dbret = bt_rseq(db, &key, &contents, &cookie, + backwards ? R_LAST : R_FIRST); +#else + (void)krb5_db2_db_unlock(context); + return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */ +#endif + } + while (dbret == 0) { + contdata.data = contents.data; + contdata.length = contents.size; + retval = krb5_decode_princ_contents(context, &contdata, &entries); + if (retval) + break; + retval = (*func)(func_arg, &entries); + krb5_dbe_free_contents(context, &entries); + if (retval) + break; + if (!recursive) { + dbret = (*db->seq)(db, &key, &contents, + backwards ? R_PREV : R_NEXT); + } else { +#ifdef HAVE_BT_RSEQ + dbret = bt_rseq(db, &key, &contents, &cookie, + backwards ? R_PREV : R_NEXT); +#else + (void)krb5_db2_db_unlock(context); + return KRB5_KDB_UK_RERROR; /* Not optimal, but close enough. */ +#endif + } + } + switch (dbret) { + case 1: + case 0: + break; + case -1: + default: + retval = errno; + } + (void) krb5_db2_db_unlock(context); + return retval; +} + +krb5_error_code +krb5_db2_db_iterate( krb5_context context, + char *match_expr, + krb5_error_code (*func) (krb5_pointer, krb5_db_entry *), + krb5_pointer func_arg ) +{ + return krb5_db2_db_iterate_ext(context, func, func_arg, 0, 0); +} + + +krb5_boolean +krb5_db2_db_set_lockmode(context, mode) + krb5_context context; + krb5_boolean mode; +{ + krb5_boolean old; + krb5_db2_context *db_ctx; + kdb5_dal_handle *dal_handle; + + dal_handle = (kdb5_dal_handle*) context->db_context; + old = mode; + if ( dal_handle && (db_ctx = (krb5_db2_context *) dal_handle->db_context)) { + old = db_ctx->db_nb_locks; + db_ctx->db_nb_locks = mode; + } + return old; +} + +#if 0 // -pradx +/* + * Context serialization operations. + * + * Ick, this is really gross. --- tlyu + */ + +/* + * kdb5_context_size() - Determine size required to serialize. + */ +static krb5_error_code +kdb5_context_size(kcontext, arg, sizep) + krb5_context kcontext; + krb5_pointer arg; + size_t *sizep; +{ + krb5_error_code kret; + size_t required; + krb5_db2_context *dbctx; + + /* + * The database context requires at minimum: + * krb5_int32 for KV5M_DB_CONTEXT + * krb5_int32 for db_inited + * krb5_int32 for database lockfile non-blocking flag + * krb5_int32 for database lockfile lock count + * krb5_int32 for database lockfile lock mode + * krb5_int32 for length of database name. + * krb5_int32 for KV5M_DB_CONTEXT + */ + kret = EINVAL; + if ((dbctx = (krb5_db2_context *) arg)) { + required = (sizeof(krb5_int32) * 7); + if (dbctx->db_inited && dbctx->db_name) + required += strlen(dbctx->db_name); + kret = 0; + *sizep += required; + } + return(kret); +} + +/* + * kdb5_context_externalize() - Externalize the database context. + */ +static krb5_error_code +kdb5_context_externalize(kcontext, arg, buffer, lenremain) + krb5_context kcontext; + krb5_pointer arg; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_db2_context *dbctx; + size_t required; + krb5_octet *bp; + size_t remain; + + required = 0; + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + if ((dbctx = (krb5_db2_context *) arg)) { + kret = ENOMEM; + if (!kdb5_context_size(kcontext, arg, &required) && + (required <= remain)) { + /* Write magic number */ + (void) krb5_ser_pack_int32(KV5M_DB_CONTEXT, &bp, &remain); + + /* Write inited flag */ + (void) krb5_ser_pack_int32((krb5_int32) dbctx->db_inited, + &bp, &remain); + + /* Write blocking lock lockmode */ + (void) krb5_ser_pack_int32((krb5_int32) dbctx->db_nb_locks, + &bp, &remain); + + /* Write lock count */ + (void) krb5_ser_pack_int32((krb5_int32) + (dbctx->db_inited) ? + dbctx->db_locks_held : 0, + &bp, &remain); + + /* Write lock mode */ + (void) krb5_ser_pack_int32((krb5_int32) + (dbctx->db_inited) ? + dbctx->db_lock_mode : 0, + &bp, &remain); + + /* Write length of database name */ + (void) krb5_ser_pack_int32((dbctx->db_inited && dbctx->db_name) ? + (krb5_int32) strlen(dbctx->db_name) : 0, + &bp, &remain); + if (dbctx->db_inited && dbctx->db_name) + (void) krb5_ser_pack_bytes((krb5_octet *) dbctx->db_name, + strlen(dbctx->db_name), + &bp, &remain); + + /* Write trailer */ + (void) krb5_ser_pack_int32(KV5M_DB_CONTEXT, &bp, &remain); + kret = 0; + *buffer = bp; + *lenremain = remain; + } + } + return(kret); +} + +/* + * kdb5_context_internalize() - Internalize the database context. + */ +static krb5_error_code +kdb5_context_internalize(kcontext, argp, buffer, lenremain) + krb5_context kcontext; + krb5_pointer *argp; + krb5_octet **buffer; + size_t *lenremain; +{ + krb5_error_code kret; + krb5_context tmpctx; + krb5_db2_context *dbctx; + krb5_int32 ibuf; + krb5_octet *bp; + size_t remain; + krb5_int32 iflag; + krb5_int32 nb_lockmode; + krb5_int32 lockcount; + krb5_int32 lockmode; + krb5_int32 dbnamelen; + krb5_boolean nb_lock; + char *dbname; + + bp = *buffer; + remain = *lenremain; + kret = EINVAL; + dbctx = (krb5_db2_context *) NULL; + /* Read our magic number */ + if (krb5_ser_unpack_int32(&ibuf, &bp, &remain)) + ibuf = 0; + if (ibuf == KV5M_DB_CONTEXT) { + kret = ENOMEM; + + if (!(kret = krb5_ser_unpack_int32(&iflag, &bp, &remain)) && + !(kret = krb5_ser_unpack_int32(&nb_lockmode, &bp, &remain)) && + !(kret = krb5_ser_unpack_int32(&lockcount, &bp, &remain)) && + !(kret = krb5_ser_unpack_int32(&lockmode, &bp, &remain)) && + !(kret = krb5_ser_unpack_int32(&dbnamelen, &bp, &remain)) && + !(kret = krb5_init_context(&tmpctx))) { + if (iflag) { + dbname = (char *) NULL; + if (dbnamelen && + (dbname = (char *) malloc((size_t) (dbnamelen+1)))) { + kret = krb5_ser_unpack_bytes((krb5_octet *) dbname, + (size_t) dbnamelen, + &bp, &remain); + if (!kret) + dbname[dbnamelen] = '\0'; + } + if (!kret && + (!dbname || !(kret = krb5_db_set_name(tmpctx, dbname))) && + !(kret = krb5_db_init(tmpctx))) { + dbctx = (krb5_db2_context *) tmpctx->db_context; + (void) krb5_db2_db_set_lockmode(tmpctx, 0); + if (lockmode) + kret = krb5_db2_db_lock(tmpctx, lockmode); + if (!kret && lockmode) + dbctx->db_locks_held = lockcount; + nb_lock = nb_lockmode & 0xff; + (void) krb5_db2_db_set_lockmode(tmpctx, nb_lock); + } + if (dbname) + krb5_xfree(dbname); + } + if (!kret) + kret = krb5_ser_unpack_int32(&ibuf, &bp, &remain); + if (kret || (ibuf != KV5M_DB_CONTEXT)) + kret = EINVAL; + + if (kret) { + if (dbctx) + krb5_db_fini(tmpctx); + } + else + tmpctx->db_context = NULL; + krb5_free_context(tmpctx); + } + } + if (!kret) { + *buffer = bp; + *lenremain = remain; + *argp = (krb5_pointer) dbctx; + } + return(kret); +} + +/* Dispatch entry */ +static const krb5_ser_entry kdb5_context_ser_entry = { + KV5M_DB_CONTEXT, /* Type */ + kdb5_context_size, /* Sizer routine */ + kdb5_context_externalize, /* Externalize routine */ + kdb5_context_internalize /* Externalize routine */ +}; + +/* + * Register serializer. + */ +krb5_error_code +krb5_ser_db_context_init(kcontext) + krb5_context kcontext; +{ + return(krb5_register_serializer(kcontext, &kdb5_context_ser_entry)); +} + +#endif // 0 - pradx + +/* + * DAL API functions + */ +krb5_error_code krb5_db2_lib_init(krb5_set_err_func_t set_err) +{ + krb5_db2_dal_err_funcp = set_err; + return 0; +} + +krb5_error_code krb5_db2_lib_cleanup() +{ + /* right now, no cleanup required */ + return 0; +} + +krb5_error_code krb5_db2_open( krb5_context kcontext, + char *conf_section, + char **db_args, + int mode ) +{ + krb5_error_code status = 0; + char **t_ptr = db_args; + char db_name_set = 0; + + if (k5db2_inited(kcontext)) + return 0; + + + while ( t_ptr && *t_ptr ) + { + char *opt = NULL, *val = NULL; + + krb5_db2_get_db_opt( *t_ptr, &opt, &val ); + if( opt && !strcmp( opt, "dbname" ) ) + { + status = krb5_db2_db_set_name( kcontext, val ); + if( status ) + { + free(opt); + free(val); + goto clean_n_exit; + } + db_name_set = 1; + } + /* ignore hash argument. Might have been passed from create */ + else if( !opt || strcmp( opt, "hash") ) + { + char buf[KRB5_MAX_ERR_STR]; + sprintf(buf, "Unsupported argument \"%s\" for db2", opt?opt:val); + krb5_db2_dal_err_funcp( kcontext, krb5_err_have_str, EINVAL, buf); + free(opt); + free(val); + return EINVAL; + } + + free(opt); + free(val); + t_ptr++; + } + + if( !db_name_set ) + { + char *value = NULL; + status = profile_get_string( KRB5_DB_GET_PROFILE(kcontext), KDB_MODULE_SECTION, + conf_section, KDB_DB2_DATABASE_NAME, /* under given conf section */ + NULL, &value ); + + + if( value == NULL ) + { + /* special case for db2. We might actually be looking at old type config file where database is specified as part of realm */ + status = profile_get_string( KRB5_DB_GET_PROFILE(kcontext), KDB_REALM_SECTION, + KRB5_DB_GET_REALM(kcontext), KDB_DB2_DATABASE_NAME, /* under given realm */ + default_db_name, &value ); + if( status ) + { + goto clean_n_exit; + } + } + + status = krb5_db2_db_set_name( kcontext, value ); + profile_release_string( value ); + if( status ) + { + goto clean_n_exit; + } + + } + + status = krb5_db2_db_init( kcontext ); + + clean_n_exit: + return status; +} + + +krb5_error_code krb5_db2_create( krb5_context kcontext, + char *conf_section, + char **db_args ) +{ + krb5_error_code status = 0; + char **t_ptr = db_args; + char db_name_set = 0; + krb5_int32 flags = KRB5_KDB_CREATE_BTREE; + char *db_name = NULL; + + if (k5db2_inited(kcontext)) + return 0; + + + while ( t_ptr && *t_ptr ) + { + char *opt = NULL, *val = NULL; + + krb5_db2_get_db_opt( *t_ptr, &opt, &val ); + if( opt && !strcmp( opt, "dbname" ) ) + { + db_name = strdup(val); + status = krb5_db2_db_set_name( kcontext, val ); + if( !status ) + { + status = EEXIST; + free(opt); + free(val); + goto clean_n_exit; + } + db_name_set = 1; + } + /* ignore hash argument. Might have been passed from create */ + else if( opt && !strcmp( opt, "hash") ) + { + flags=KRB5_KDB_CREATE_HASH; + } + else + { + char buf[KRB5_MAX_ERR_STR]; + sprintf(buf, "Unsupported argument \"%s\" for db2", opt?opt:val); + krb5_db2_dal_err_funcp( kcontext, krb5_err_have_str, EINVAL, buf); + free(opt); + free(val); + return EINVAL; + } + + free(opt); + free(val); + t_ptr++; + } + + if( !db_name_set ) + { + char *value = NULL; + status = profile_get_string( KRB5_DB_GET_PROFILE(kcontext), KDB_MODULE_SECTION, + conf_section, KDB_DB2_DATABASE_NAME, /* under given conf section */ + NULL, &value ); + + + if( value == NULL ) + { + /* special case for db2. We might actually be looking at old type config file where database is specified as part of realm */ + status = profile_get_string( KRB5_DB_GET_PROFILE(kcontext), KDB_REALM_SECTION, + KRB5_DB_GET_REALM(kcontext), KDB_DB2_DATABASE_NAME, /* under given realm */ + default_db_name, &value ); + if( status ) + { + goto clean_n_exit; + } + } + + db_name = strdup( value ); + status = krb5_db2_db_set_name( kcontext, value ); + profile_release_string( value ); + if( !status ) + { + status = EEXIST; + goto clean_n_exit; + } + + } + + status = krb5_db2_db_create( kcontext, db_name, flags ); + if( status ) + goto clean_n_exit; + /* db2 has a problem of needing to close and open the database again. This removes that need */ + status = krb5_db2_db_fini(kcontext); + if( status ) + goto clean_n_exit; + + status = krb5_db2_open( kcontext, conf_section, db_args, KRB5_KDB_OPEN_RW ); + + clean_n_exit: + if( db_name ) + free( db_name ); + return status; +} + +krb5_error_code krb5_db2_destroy( krb5_context kcontext, + char *conf_section, + char **db_args ) +{ + krb5_error_code status = 0; + char **t_ptr = db_args; + char db_name_set = 0; + char *db_name = NULL; + + while ( t_ptr && *t_ptr ) + { + char *opt = NULL, *val = NULL; + + krb5_db2_get_db_opt( *t_ptr, &opt, &val ); + if( opt && !strcmp( opt, "dbname" ) ) + { + db_name = strdup(val); + status = krb5_db2_db_set_name( kcontext, val ); + if( status ) + { + free(opt); + free(val); + goto clean_n_exit; + } + db_name_set = 1; + } + /* ignore hash argument. Might have been passed from create */ + else if( !opt || strcmp( opt, "hash") ) + { + free(opt); + free(val); + return EINVAL; + } + + free(opt); + free(val); + t_ptr++; + } + + if( !db_name_set ) + { + char *value = NULL; + status = profile_get_string( KRB5_DB_GET_PROFILE(kcontext), KDB_MODULE_SECTION, + conf_section, KDB_DB2_DATABASE_NAME, /* under given conf section */ + NULL, &value ); + + + if( value == NULL ) + { + /* special case for db2. We might actually be looking at old type config file where database is specified as part of realm */ + status = profile_get_string( KRB5_DB_GET_PROFILE(kcontext), KDB_REALM_SECTION, + KRB5_DB_GET_REALM(kcontext), KDB_DB2_DATABASE_NAME, /* under given realm */ + default_db_name, &value ); + if( status ) + { + goto clean_n_exit; + } + } + + db_name = strdup(value); + status = krb5_db2_db_set_name( kcontext, value ); + profile_release_string( value ); + if( status ) + { + goto clean_n_exit; + } + + } + + status = krb5_db2_db_destroy( kcontext, db_name ); + + clean_n_exit: + if( db_name ) + free(db_name); + return status; +} + +krb5_error_code krb5_db2_set_master_key_ext ( krb5_context kcontext, + char *pwd, + krb5_keyblock *key) +{ + return krb5_db2_db_set_mkey( kcontext, key ); +} + +krb5_error_code krb5_db2_db_set_option ( krb5_context kcontext, int option, void *value ) +{ + krb5_error_code status = 0; + krb5_boolean oldval; + + switch(option) + { + case KRB5_KDB_OPT_SET_DB_NAME: + status = krb5_db2_db_set_name( kcontext, (char *)value); + break; + + case KRB5_KDB_OPT_SET_LOCK_MODE: + oldval = krb5_db2_db_set_lockmode( kcontext, *((krb5_boolean*)value) ); + *((krb5_boolean*)value) = oldval; + break; + + default: + status = -1; /* TBD */ + break; + } + + return status; +} + +void * krb5_db2_alloc( krb5_context kcontext, void *ptr, size_t size ) +{ + return realloc(ptr, size); +} + +void krb5_db2_free( krb5_context kcontext, void *ptr ) +{ + free(ptr); +} + + +/* policy functions */ +krb5_error_code krb5_db2_create_policy( krb5_context kcontext, + osa_policy_ent_t policy ) +{ + kdb5_dal_handle *dal_handle; + krb5_db2_context *dbc; + + dal_handle = (kdb5_dal_handle*) kcontext->db_context; + dbc = (krb5_db2_context*) dal_handle->db_context; + + return osa_adb_create_policy( dbc->policy_db, policy ); +} + +krb5_error_code krb5_db2_get_policy ( krb5_context kcontext, + char *name, + osa_policy_ent_t *policy, + int *cnt) +{ + kdb5_dal_handle *dal_handle; + krb5_db2_context *dbc; + + dal_handle = (kdb5_dal_handle*) kcontext->db_context; + dbc = (krb5_db2_context*) dal_handle->db_context; + + return osa_adb_get_policy( dbc->policy_db, name, policy, cnt ); +} + +krb5_error_code krb5_db2_put_policy ( krb5_context kcontext, + osa_policy_ent_t policy ) +{ + kdb5_dal_handle *dal_handle; + krb5_db2_context *dbc; + + dal_handle = (kdb5_dal_handle*) kcontext->db_context; + dbc = (krb5_db2_context*) dal_handle->db_context; + + return osa_adb_put_policy( dbc->policy_db, policy ); +} + +krb5_error_code krb5_db2_iter_policy ( krb5_context kcontext, + char *match_entry, + osa_adb_iter_policy_func func, + void *data ) +{ + kdb5_dal_handle *dal_handle; + krb5_db2_context *dbc; + + dal_handle = (kdb5_dal_handle*) kcontext->db_context; + dbc = (krb5_db2_context*) dal_handle->db_context; + + return osa_adb_iter_policy( dbc->policy_db, func, data ); +} + + +krb5_error_code krb5_db2_delete_policy ( krb5_context kcontext, + char *policy ) +{ + kdb5_dal_handle *dal_handle; + krb5_db2_context *dbc; + + dal_handle = (kdb5_dal_handle*) kcontext->db_context; + dbc = (krb5_db2_context*) dal_handle->db_context; + + return osa_adb_destroy_policy( dbc->policy_db, policy ); +} + + +void krb5_db2_free_policy( krb5_context kcontext, + osa_policy_ent_t entry ) +{ + osa_free_policy_ent(entry); +} + diff --git a/src/lib/kdb/kdb_db2/kdb_db2.h b/src/lib/kdb/kdb_db2/kdb_db2.h new file mode 100644 index 000000000..ba03ea36f --- /dev/null +++ b/src/lib/kdb/kdb_db2/kdb_db2.h @@ -0,0 +1,216 @@ +/* + * lib/kdb/kdb_db2.h + * + * Copyright 1997 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + * + * KDC Database backend definitions for Berkely DB. + */ +#ifndef KRB5_KDB_DB2_H +#define KRB5_KDB_DB2_H + +#include "policy_db.h" + +typedef struct _krb5_db2_context { + krb5_boolean db_inited; /* Context initialized */ + char * db_name; /* Name of database */ + DB * db; /* DB handle */ + krb5_boolean hashfirst; /* Try hash database type first */ + char * db_lf_name; /* Name of lock file */ + int db_lf_file; /* File descriptor of lock file */ + time_t db_lf_time; /* Time last updated */ + int db_locks_held; /* Number of times locked */ + int db_lock_mode; /* Last lock mode, e.g. greatest*/ + krb5_boolean db_nb_locks; /* [Non]Blocking lock modes */ + krb5_keyblock *db_master_key; /* Master key of database */ + osa_adb_policy_t policy_db; +} krb5_db2_context; + +#define KRB5_DB2_MAX_RETRY 5 + +#define KDB2_LOCK_EXT ".ok" + +krb5_error_code krb5_db2_db_set_name + (krb5_context, + char * ); +krb5_error_code krb5_db2_db_init + (krb5_context); +krb5_error_code krb5_db2_db_fini + (krb5_context); +krb5_error_code krb5_db2_db_get_age + (krb5_context, + char *, + time_t * ); +krb5_error_code krb5_db2_db_create + (krb5_context, + char *, + krb5_int32); +krb5_error_code krb5_db2_db_destroy + (krb5_context, + char * ); +krb5_error_code krb5_db2_db_rename + (krb5_context, + char *, + char * ); +krb5_error_code krb5_db2_db_get_principal + (krb5_context, + krb5_const_principal, + krb5_db_entry *, + int *, + krb5_boolean * ); +krb5_error_code krb5_db2_db_free_principal + (krb5_context, + krb5_db_entry *, + int ); +krb5_error_code krb5_db2_db_put_principal + (krb5_context, + krb5_db_entry *, + int *, + char **db_args + ); +krb5_error_code krb5_db2_db_iterate_ext + (krb5_context, + krb5_error_code (*) (krb5_pointer, + krb5_db_entry *), + krb5_pointer, int, int ); +krb5_error_code krb5_db2_db_iterate +(krb5_context,char *, + krb5_error_code (*) (krb5_pointer, + krb5_db_entry *), + krb5_pointer ); +krb5_error_code krb5_db2_db_set_nonblocking + (krb5_context, + krb5_boolean, + krb5_boolean * ); +krb5_boolean krb5_db2_db_set_lockmode + (krb5_context, + krb5_boolean ); +krb5_error_code krb5_db2_db_open_database + (krb5_context); +krb5_error_code krb5_db2_db_close_database + (krb5_context); + +krb5_error_code +krb5_db2_set_master_key_ext ( krb5_context kcontext, + char *pwd, + krb5_keyblock *key); + +krb5_error_code +krb5_db2_db_set_mkey( krb5_context context, + krb5_keyblock *key); + +krb5_error_code +krb5_db2_db_get_mkey( krb5_context context, + krb5_keyblock **key); + +krb5_error_code +krb5_db2_db_put_principal( krb5_context context, + krb5_db_entry *entries, + register int *nentries, + char **db_args); + +krb5_error_code +krb5_db2_db_delete_principal(krb5_context context, + krb5_const_principal searchfor, + int *nentries); + +krb5_error_code krb5_db2_lib_init(krb5_set_err_func_t); + +krb5_error_code krb5_db2_lib_cleanup(void); + +krb5_error_code +krb5_db2_db_unlock(krb5_context); + +krb5_error_code +krb5_db2_db_set_option ( krb5_context kcontext, + int option, + void *value ); + +krb5_error_code +krb5_db2_db_lock( krb5_context context, + int in_mode); + + +krb5_error_code +krb5_db2_open( krb5_context kcontext, + char *conf_section, + char **db_args, + int mode ); + +krb5_error_code krb5_db2_create( krb5_context kcontext, + char *conf_section, + char **db_args ); + +krb5_error_code krb5_db2_destroy( krb5_context kcontext, + char *conf_section, + char **db_args ); + +const char * krb5_db2_err2str( krb5_context kcontext, + long err_code ); + +void * +krb5_db2_alloc( krb5_context kcontext, + void *ptr, + size_t size ); + +void +krb5_db2_free( krb5_context kcontext, + void *ptr ); + + + + + +/* policy management functions */ +krb5_error_code +krb5_db2_create_policy(krb5_context context, osa_policy_ent_t entry); + +krb5_error_code krb5_db2_get_policy ( krb5_context kcontext, + char *name, + osa_policy_ent_t *policy, + int *cnt); + +krb5_error_code krb5_db2_get_policy ( krb5_context kcontext, + char *name, + osa_policy_ent_t *policy, + int *cnt); + +krb5_error_code krb5_db2_put_policy ( krb5_context kcontext, + osa_policy_ent_t policy ); + +krb5_error_code krb5_db2_iter_policy ( krb5_context kcontext, + char *match_entry, + osa_adb_iter_policy_func func, + void *data ); + +krb5_error_code krb5_db2_delete_policy ( krb5_context kcontext, + char *policy ); + +void krb5_db2_free_policy( krb5_context kcontext, + osa_policy_ent_t entry ); + + + +extern krb5_set_err_func_t krb5_db2_dal_err_funcp; + +#endif /* KRB5_KDB_DB2_H */ diff --git a/src/lib/kdb/kdb_db2/kdb_xdr.c b/src/lib/kdb/kdb_db2/kdb_xdr.c new file mode 100644 index 000000000..a5332ea6d --- /dev/null +++ b/src/lib/kdb/kdb_db2/kdb_xdr.c @@ -0,0 +1,816 @@ +/* + * lib/kdb/kdb_xdr.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +#include "k5-int.h" +#include +#include +#include +#include "kdb_xdr.h" + +#define safe_realloc(p,n) ((p)?(realloc(p,n)):(malloc(n))) + +krb5_error_code +krb5_dbe_create_key_data(context, entry) + krb5_context context; + krb5_db_entry * entry; +{ + if ((entry->key_data = + (krb5_key_data *) safe_realloc(entry->key_data, + (sizeof(krb5_key_data)* + (entry->n_key_data + 1)))) == NULL) + return(ENOMEM); + + + memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data)); + entry->n_key_data++; + + return 0; +} + +krb5_error_code +krb5_dbe_update_tl_data(context, entry, new_tl_data) + krb5_context context; + krb5_db_entry * entry; + krb5_tl_data * new_tl_data; +{ + krb5_tl_data * tl_data; + krb5_octet * tmp; + + /* copy the new data first, so we can fail cleanly if malloc() + fails */ + + if ((tmp = (krb5_octet *) malloc(new_tl_data->tl_data_length)) == NULL) + return(ENOMEM); + + /* Find an existing entry of the specified type and point at + it, or NULL if not found */ + + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) + if (tl_data->tl_data_type == new_tl_data->tl_data_type) + break; + + /* if necessary, chain a new record in the beginning and point at it */ + + if (!tl_data) { + if ((tl_data = (krb5_tl_data *) calloc(1, sizeof(krb5_tl_data))) + == NULL) { + free(tmp); + return(ENOMEM); + } + tl_data->tl_data_next = entry->tl_data; + entry->tl_data = tl_data; + entry->n_tl_data++; + } + + /* fill in the record */ + + if (tl_data->tl_data_contents) + free(tl_data->tl_data_contents); + + tl_data->tl_data_type = new_tl_data->tl_data_type; + tl_data->tl_data_length = new_tl_data->tl_data_length; + tl_data->tl_data_contents = tmp; + memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length); + + return(0); +} + +krb5_error_code +krb5_dbe_lookup_tl_data(context, entry, ret_tl_data) + krb5_context context; + krb5_db_entry * entry; + krb5_tl_data * ret_tl_data; +{ + krb5_tl_data *tl_data; + + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { + if (tl_data->tl_data_type == ret_tl_data->tl_data_type) { + *ret_tl_data = *tl_data; + return(0); + } + } + + /* if the requested record isn't found, return zero bytes. + if it ever means something to have a zero-length tl_data, + this code and its callers will have to be changed */ + + ret_tl_data->tl_data_length = 0; + ret_tl_data->tl_data_contents = NULL; + return(0); +} + +krb5_error_code +krb5_dbe_update_last_pwd_change(context, entry, stamp) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp stamp; +{ + krb5_tl_data tl_data; + krb5_octet buf[4]; /* this is the encoded size of an int32 */ + + tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; + tl_data.tl_data_length = sizeof(buf); + krb5_kdb_encode_int32((krb5_int32) stamp, buf); + tl_data.tl_data_contents = buf; + + return(krb5_dbe_update_tl_data(context, entry, &tl_data)); +} + +krb5_error_code +krb5_dbe_lookup_last_pwd_change(context, entry, stamp) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp * stamp; +{ + krb5_tl_data tl_data; + krb5_error_code code; + krb5_int32 tmp; + + tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; + + if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) + return(code); + + if (tl_data.tl_data_length != 4) { + *stamp = 0; + return(0); + } + + krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp); + + *stamp = (krb5_timestamp) tmp; + + return(0); +} + +/* it seems odd that there's no function to remove a tl_data, but if + I need one, I'll add one */ + +krb5_error_code +krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp mod_date; + krb5_const_principal mod_princ; +{ + krb5_tl_data tl_data; + + krb5_error_code retval = 0; + krb5_octet * nextloc = 0; + char * unparse_mod_princ = 0; + unsigned int unparse_mod_princ_size; + + if ((retval = krb5_unparse_name(context, mod_princ, + &unparse_mod_princ))) + return(retval); + + unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; + + if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) + == NULL) { + free(unparse_mod_princ); + return(ENOMEM); + } + + tl_data.tl_data_type = KRB5_TL_MOD_PRINC; + tl_data.tl_data_length = unparse_mod_princ_size + 4; + tl_data.tl_data_contents = nextloc; + + /* Mod Date */ + krb5_kdb_encode_int32(mod_date, nextloc); + + /* Mod Princ */ + memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size); + + retval = krb5_dbe_update_tl_data(context, entry, &tl_data); + + free(unparse_mod_princ); + free(nextloc); + + return(retval); +} + +krb5_error_code +krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ) + krb5_context context; + krb5_db_entry * entry; + krb5_timestamp * mod_time; + krb5_principal * mod_princ; +{ + krb5_tl_data tl_data; + krb5_error_code code; + + tl_data.tl_data_type = KRB5_TL_MOD_PRINC; + + if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) + return(code); + + if ((tl_data.tl_data_length < 5) || + (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0')) + return(KRB5_KDB_TRUNCATED_RECORD); + + /* Mod Date */ + krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time); + + /* Mod Princ */ + if ((code = krb5_parse_name(context, + (const char *) (tl_data.tl_data_contents+4), + mod_princ))) + return(code); + + return(0); +} + +krb5_error_code +krb5_encode_princ_dbkey(context, key, principal) + krb5_context context; + krb5_data *key; + krb5_const_principal principal; +{ + char *princ_name; + krb5_error_code retval; + + if (!(retval = krb5_unparse_name(context, principal, &princ_name))) { + /* need to store the NULL for decoding */ + key->length = strlen(princ_name)+1; + key->data = princ_name; + } + return(retval); +} + +void +krb5_free_princ_dbkey(context, key) + krb5_context context; + krb5_data *key; +{ + (void) krb5_free_data_contents(context, key); +} + +krb5_error_code +krb5_encode_princ_contents(context, content, entry) + krb5_context context; + krb5_data * content; + krb5_db_entry * entry; +{ + int i, j; + unsigned int unparse_princ_size; + char * unparse_princ; + char * nextloc; + krb5_tl_data * tl_data; + krb5_error_code retval; + krb5_int16 psize16; + + /* + * Generate one lump of data from the krb5_db_entry. + * This data must be independent of byte order of the machine, + * compact and extensible. + */ + + /* + * First allocate enough space for all the data. + * Need 2 bytes for the length of the base structure + * then 36 [ 8 * 4 + 2 * 2] bytes for the base information + * [ attributes, max_life, max_renewable_life, expiration, + * pw_expiration, last_success, last_failed, fail_auth_count ] + * [ n_key_data, n_tl_data ] + * then XX bytes [ e_length ] for the extra data [ e_data ] + * then XX bytes [ 2 for length + length for string ] for the principal, + * then (4 [type + length] + tl_data_length) bytes per tl_data + * then (4 + (4 + key_data_length) per key_data_contents) bytes per key_data + */ + content->length = entry->len + entry->e_length; + + if ((retval = krb5_unparse_name(context, entry->princ, &unparse_princ))) + return(retval); + + unparse_princ_size = strlen(unparse_princ) + 1; + content->length += unparse_princ_size; + content->length += 2; + + i = 0; + /* tl_data is a linked list */ + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { + content->length += tl_data->tl_data_length; + content->length += 4; /* type, length */ + i++; + } + + if (i != entry->n_tl_data) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto epc_error; + } + + /* key_data is an array */ + for (i = 0; i < entry->n_key_data; i++) { + content->length += 4; /* Version, KVNO */ + for (j = 0; j < entry->key_data[i].key_data_ver; j++) { + content->length += entry->key_data[i].key_data_length[j]; + content->length += 4; /* type + length */ + } + } + + if ((content->data = malloc(content->length)) == NULL) { + retval = ENOMEM; + goto epc_error; + } + + /* + * Now we go through entry again, this time copying data + * These first entries are always saved regardless of version + */ + nextloc = content->data; + + /* Base Length */ + krb5_kdb_encode_int16(entry->len, nextloc); + nextloc += 2; + + /* Attributes */ + krb5_kdb_encode_int32(entry->attributes, nextloc); + nextloc += 4; + + /* Max Life */ + krb5_kdb_encode_int32(entry->max_life, nextloc); + nextloc += 4; + + /* Max Renewable Life */ + krb5_kdb_encode_int32(entry->max_renewable_life, nextloc); + nextloc += 4; + + /* When the client expires */ + krb5_kdb_encode_int32(entry->expiration, nextloc); + nextloc += 4; + + /* When its passwd expires */ + krb5_kdb_encode_int32(entry->pw_expiration, nextloc); + nextloc += 4; + + /* Last successful passwd */ + krb5_kdb_encode_int32(entry->last_success, nextloc); + nextloc += 4; + + /* Last failed passwd attempt */ + krb5_kdb_encode_int32(entry->last_failed, nextloc); + nextloc += 4; + + /* # of failed passwd attempt */ + krb5_kdb_encode_int32(entry->fail_auth_count, nextloc); + nextloc += 4; + + /* # tl_data strutures */ + krb5_kdb_encode_int16(entry->n_tl_data, nextloc); + nextloc += 2; + + /* # key_data strutures */ + krb5_kdb_encode_int16(entry->n_key_data, nextloc); + nextloc += 2; + + /* Put extended fields here */ + if (entry->len != KRB5_KDB_V1_BASE_LENGTH) + abort(); + + /* Any extra data that this version doesn't understand. */ + if (entry->e_length) { + memcpy(nextloc, entry->e_data, entry->e_length); + nextloc += entry->e_length; + } + + /* + * Now we get to the principal. + * To squeze a few extra bytes out it is always assumed to come + * after the base type. + */ + psize16 = (krb5_int16) unparse_princ_size; + krb5_kdb_encode_int16(psize16, nextloc); + nextloc += 2; + (void) memcpy(nextloc, unparse_princ, unparse_princ_size); + nextloc += unparse_princ_size; + + /* tl_data is a linked list, of type, legth, contents */ + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { + krb5_kdb_encode_int16(tl_data->tl_data_type, nextloc); + nextloc += 2; + krb5_kdb_encode_int16(tl_data->tl_data_length, nextloc); + nextloc += 2; + + memcpy(nextloc, tl_data->tl_data_contents, tl_data->tl_data_length); + nextloc += tl_data->tl_data_length; + } + + /* key_data is an array */ + for (i = 0; i < entry->n_key_data; i++) { + krb5_kdb_encode_int16(entry->key_data[i].key_data_ver, nextloc); + nextloc += 2; + krb5_kdb_encode_int16(entry->key_data[i].key_data_kvno, nextloc); + nextloc += 2; + + for (j = 0; j < entry->key_data[i].key_data_ver; j++) { + krb5_int16 type = entry->key_data[i].key_data_type[j]; + krb5_ui_2 length = entry->key_data[i].key_data_length[j]; + + krb5_kdb_encode_int16(type, nextloc); + nextloc += 2; + krb5_kdb_encode_int16(length, nextloc); + nextloc += 2; + + if (length) { + memcpy(nextloc, entry->key_data[i].key_data_contents[j],length); + nextloc += length; + } + } + } + +epc_error:; + free(unparse_princ); + return retval; +} + +void +krb5_free_princ_contents(context, contents) + krb5_context context; + krb5_data *contents; +{ + krb5_free_data_contents(context, contents); + return; +} + +krb5_error_code +krb5_decode_princ_contents(context, content, entry) + krb5_context context; + krb5_data * content; + krb5_db_entry * entry; +{ + int sizeleft, i; + char * nextloc; + krb5_tl_data ** tl_data; + krb5_int16 i16; + + krb5_error_code retval; + + /* Zero out entry and NULL pointers */ + memset(entry, 0, sizeof(krb5_db_entry)); + + /* + * undo the effects of encode_princ_contents. + * + * The first part is decoding the base type. If the base type is + * bigger than the original base type then the additional fields + * need to be filled in. If the base type is larger than any + * known base type the additional data goes in e_data. + */ + + /* First do the easy stuff */ + nextloc = content->data; + sizeleft = content->length; + if ((sizeleft -= KRB5_KDB_V1_BASE_LENGTH) < 0) + return KRB5_KDB_TRUNCATED_RECORD; + + /* Base Length */ + krb5_kdb_decode_int16(nextloc, entry->len); + nextloc += 2; + + /* Attributes */ + krb5_kdb_decode_int32(nextloc, entry->attributes); + nextloc += 4; + + /* Max Life */ + krb5_kdb_decode_int32(nextloc, entry->max_life); + nextloc += 4; + + /* Max Renewable Life */ + krb5_kdb_decode_int32(nextloc, entry->max_renewable_life); + nextloc += 4; + + /* When the client expires */ + krb5_kdb_decode_int32(nextloc, entry->expiration); + nextloc += 4; + + /* When its passwd expires */ + krb5_kdb_decode_int32(nextloc, entry->pw_expiration); + nextloc += 4; + + /* Last successful passwd */ + krb5_kdb_decode_int32(nextloc, entry->last_success); + nextloc += 4; + + /* Last failed passwd attempt */ + krb5_kdb_decode_int32(nextloc, entry->last_failed); + nextloc += 4; + + /* # of failed passwd attempt */ + krb5_kdb_decode_int32(nextloc, entry->fail_auth_count); + nextloc += 4; + + /* # tl_data strutures */ + krb5_kdb_decode_int16(nextloc, entry->n_tl_data); + nextloc += 2; + + if (entry->n_tl_data < 0) + return KRB5_KDB_TRUNCATED_RECORD; + + /* # key_data strutures */ + krb5_kdb_decode_int16(nextloc, entry->n_key_data); + nextloc += 2; + + if (entry->n_key_data < 0) + return KRB5_KDB_TRUNCATED_RECORD; + + /* Check for extra data */ + if (entry->len > KRB5_KDB_V1_BASE_LENGTH) { + entry->e_length = entry->len - KRB5_KDB_V1_BASE_LENGTH; + if ((entry->e_data = (krb5_octet *)malloc(entry->e_length))) { + memcpy(entry->e_data, nextloc, entry->e_length); + nextloc += entry->e_length; + } else { + return ENOMEM; + } + } + + /* + * Get the principal name for the entry + * (stored as a string which gets unparsed.) + */ + if ((sizeleft -= 2) < 0) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto error_out; + } + + i = 0; + krb5_kdb_decode_int16(nextloc, i16); + i = (int) i16; + nextloc += 2; + + if ((retval = krb5_parse_name(context, nextloc, &(entry->princ)))) + goto error_out; + if (((size_t) i != (strlen(nextloc) + 1)) || (sizeleft < i)) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto error_out; + } + sizeleft -= i; + nextloc += i; + + /* tl_data is a linked list */ + tl_data = &entry->tl_data; + for (i = 0; i < entry->n_tl_data; i++) { + if ((sizeleft -= 4) < 0) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto error_out; + } + if ((*tl_data = (krb5_tl_data *) + malloc(sizeof(krb5_tl_data))) == NULL) { + retval = ENOMEM; + goto error_out; + } + (*tl_data)->tl_data_next = NULL; + (*tl_data)->tl_data_contents = NULL; + krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_type); + nextloc += 2; + krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_length); + nextloc += 2; + + if ((sizeleft -= (*tl_data)->tl_data_length) < 0) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto error_out; + } + if (((*tl_data)->tl_data_contents = (krb5_octet *) + malloc((*tl_data)->tl_data_length)) == NULL) { + retval = ENOMEM; + goto error_out; + } + memcpy((*tl_data)->tl_data_contents,nextloc,(*tl_data)->tl_data_length); + nextloc += (*tl_data)->tl_data_length; + tl_data = &((*tl_data)->tl_data_next); + } + + /* key_data is an array */ + if (entry->n_key_data && ((entry->key_data = (krb5_key_data *) + malloc(sizeof(krb5_key_data) * entry->n_key_data)) == NULL)) { + retval = ENOMEM; + goto error_out; + } + for (i = 0; i < entry->n_key_data; i++) { + krb5_key_data * key_data; + int j; + + if ((sizeleft -= 4) < 0) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto error_out; + } + key_data = entry->key_data + i; + memset(key_data, 0, sizeof(krb5_key_data)); + krb5_kdb_decode_int16(nextloc, key_data->key_data_ver); + nextloc += 2; + krb5_kdb_decode_int16(nextloc, key_data->key_data_kvno); + nextloc += 2; + + /* key_data_ver determins number of elements and how to unparse them. */ + if (key_data->key_data_ver <= KRB5_KDB_V1_KEY_DATA_ARRAY) { + for (j = 0; j < key_data->key_data_ver; j++) { + if ((sizeleft -= 4) < 0) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto error_out; + } + krb5_kdb_decode_int16(nextloc, key_data->key_data_type[j]); + nextloc += 2; + krb5_kdb_decode_int16(nextloc, key_data->key_data_length[j]); + nextloc += 2; + + if ((sizeleft -= key_data->key_data_length[j]) < 0) { + retval = KRB5_KDB_TRUNCATED_RECORD; + goto error_out; + } + if (key_data->key_data_length[j]) { + if ((key_data->key_data_contents[j] = (krb5_octet *) + malloc(key_data->key_data_length[j])) == NULL) { + retval = ENOMEM; + goto error_out; + } + memcpy(key_data->key_data_contents[j], nextloc, + key_data->key_data_length[j]); + nextloc += key_data->key_data_length[j]; + } + } + } else { + /* This isn't right. I'll fix it later */ + abort(); + } + } + return 0; + +error_out:; + krb5_dbe_free_contents(context, entry); + return retval; +} + +void +krb5_dbe_free_contents(context, entry) + krb5_context context; + krb5_db_entry * entry; +{ + krb5_tl_data * tl_data_next; + krb5_tl_data * tl_data; + int i, j; + + if (entry->e_data) + free(entry->e_data); + if (entry->princ) + krb5_free_principal(context, entry->princ); + for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) { + tl_data_next = tl_data->tl_data_next; + if (tl_data->tl_data_contents) + free(tl_data->tl_data_contents); + free(tl_data); + } + if (entry->key_data) { + for (i = 0; i < entry->n_key_data; i++) { + for (j = 0; j < entry->key_data[i].key_data_ver; j++) { + if (entry->key_data[i].key_data_length[j]) { + if (entry->key_data[i].key_data_contents[j]) { + memset(entry->key_data[i].key_data_contents[j], + 0, + (unsigned) entry->key_data[i].key_data_length[j]); + free (entry->key_data[i].key_data_contents[j]); + } + } + entry->key_data[i].key_data_contents[j] = NULL; + entry->key_data[i].key_data_length[j] = 0; + entry->key_data[i].key_data_type[j] = 0; + } + } + free(entry->key_data); + } + memset(entry, 0, sizeof(*entry)); + return; +} + +/* + * Given a particular enctype and optional salttype and kvno, find the + * most appropriate krb5_key_data entry of the database entry. + * + * If stype or kvno is negative, it is ignored. + * If kvno is 0 get the key which is maxkvno for the princ and matches + * the other attributes. + */ +krb5_error_code +krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) + krb5_context kcontext; + krb5_db_entry *dbentp; + krb5_int32 *start; + krb5_int32 ktype; + krb5_int32 stype; + krb5_int32 kvno; + krb5_key_data **kdatap; +{ + int i, idx; + int maxkvno; + krb5_key_data *datap; + krb5_error_code ret; + + ret = 0; + if (kvno == -1 && stype == -1 && ktype == -1) + kvno = 0; + + if (kvno == 0) { + /* Get the max key version */ + for (i = 0; i < dbentp->n_key_data; i++) { + if (kvno < dbentp->key_data[i].key_data_kvno) { + kvno = dbentp->key_data[i].key_data_kvno; + } + } + } + + maxkvno = -1; + datap = (krb5_key_data *) NULL; + for (i = *start; i < dbentp->n_key_data; i++) { + krb5_boolean similar; + krb5_int32 db_stype; + + ret = 0; + if (dbentp->key_data[i].key_data_ver > 1) { + db_stype = dbentp->key_data[i].key_data_type[1]; + } else { + db_stype = KRB5_KDB_SALTTYPE_NORMAL; + } + + /* + * Filter out non-permitted enctypes. + */ + if (!krb5_is_permitted_enctype(kcontext, + dbentp->key_data[i].key_data_type[0])) { + ret = KRB5_KDB_NO_PERMITTED_KEY; + continue; + } + + + if (ktype > 0) { + if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype, + dbentp->key_data[i].key_data_type[0], + &similar))) + + return(ret); + } + + if (((ktype <= 0) || similar) && + ((db_stype == stype) || (stype < 0))) { + if (kvno >= 0) { + if (kvno == dbentp->key_data[i].key_data_kvno) { + datap = &dbentp->key_data[i]; + idx = i; + maxkvno = kvno; + break; + } + } else { + if (dbentp->key_data[i].key_data_kvno > maxkvno) { + maxkvno = dbentp->key_data[i].key_data_kvno; + datap = &dbentp->key_data[i]; + idx = i; + } + } + } + } + if (maxkvno < 0) + return ret ? ret : KRB5_KDB_NO_MATCHING_KEY; + *kdatap = datap; + *start = idx+1; + return 0; +} + +krb5_error_code +krb5_dbe_find_enctype(kcontext, dbentp, ktype, stype, kvno, kdatap) + krb5_context kcontext; + krb5_db_entry *dbentp; + krb5_int32 ktype; + krb5_int32 stype; + krb5_int32 kvno; + krb5_key_data **kdatap; +{ + krb5_int32 start = 0; + + return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype, + kvno, kdatap); +} + + diff --git a/src/lib/kdb/kdb_db2/kdb_xdr.h b/src/lib/kdb/kdb_db2/kdb_xdr.h new file mode 100644 index 000000000..2ee068fbd --- /dev/null +++ b/src/lib/kdb/kdb_db2/kdb_xdr.h @@ -0,0 +1,32 @@ +#ifndef _KDB2_XDR_H +#define _KDB2_XDR_H + +krb5_error_code +krb5_encode_princ_dbkey( krb5_context context, + krb5_data *key, + krb5_const_principal principal); + +krb5_error_code +krb5_decode_princ_contents( krb5_context context, + krb5_data * content, + krb5_db_entry * entry); + +void +krb5_dbe_free_contents( krb5_context context, + krb5_db_entry * entry); + +krb5_error_code +krb5_encode_princ_contents( krb5_context context, + krb5_data * content, + krb5_db_entry * entry); + + +void +krb5_free_princ_dbkey( krb5_context context, + krb5_data *key); + +void +krb5_free_princ_contents( krb5_context context, + krb5_data *contents); + +#endif diff --git a/src/lib/kdb/kdb_db2/libkdb_db2.exports b/src/lib/kdb/kdb_db2/libkdb_db2.exports new file mode 100644 index 000000000..b6902ebda --- /dev/null +++ b/src/lib/kdb/kdb_db2/libkdb_db2.exports @@ -0,0 +1 @@ +krb5_db_vftabl_kdb_db2 diff --git a/src/lib/kdb/kdb_db2/pol_xdr.c b/src/lib/kdb/kdb_db2/pol_xdr.c new file mode 100644 index 000000000..37761080a --- /dev/null +++ b/src/lib/kdb/kdb_db2/pol_xdr.c @@ -0,0 +1,88 @@ +#include +#include +#include +#include +#include "policy_db.h" +#ifdef HAVE_MEMORY_H +#include +#endif + +bool_t xdr_nullstring(XDR *xdrs, char **objp) +{ + u_int size; + + if (xdrs->x_op == XDR_ENCODE) { + if (*objp == NULL) + size = 0; + else + size = strlen(*objp) + 1; + } + if (! xdr_u_int(xdrs, &size)) { + return FALSE; + } + switch (xdrs->x_op) { + case XDR_DECODE: + if (size == 0) { + *objp = NULL; + return TRUE; + } else if (*objp == NULL) { + *objp = (char *) mem_alloc(size); + if (*objp == NULL) { + errno = ENOMEM; + return FALSE; + } + } + return (xdr_opaque(xdrs, *objp, size)); + + case XDR_ENCODE: + if (size != 0) + return (xdr_opaque(xdrs, *objp, size)); + return TRUE; + + case XDR_FREE: + if (*objp != NULL) + mem_free(*objp, size); + *objp = NULL; + return TRUE; + } + + return FALSE; +} + + + +bool_t +xdr_osa_policy_ent_rec(XDR *xdrs, osa_policy_ent_t objp) +{ + switch (xdrs->x_op) { + case XDR_ENCODE: + objp->version = OSA_ADB_POLICY_VERSION_1; + /* fall through */ + case XDR_FREE: + if (!xdr_int(xdrs, &objp->version)) + return FALSE; + break; + case XDR_DECODE: + if (!xdr_int(xdrs, &objp->version)) + return FALSE; + if (objp->version != OSA_ADB_POLICY_VERSION_1) + return FALSE; + break; + } + + if(!xdr_nullstring(xdrs, &objp->name)) + return (FALSE); + if (!xdr_u_int32(xdrs, &objp->pw_min_life)) + return (FALSE); + if (!xdr_u_int32(xdrs, &objp->pw_max_life)) + return (FALSE); + if (!xdr_u_int32(xdrs, &objp->pw_min_length)) + return (FALSE); + if (!xdr_u_int32(xdrs, &objp->pw_min_classes)) + return (FALSE); + if (!xdr_u_int32(xdrs, &objp->pw_history_num)) + return (FALSE); + if (!xdr_u_int32(xdrs, &objp->policy_refcnt)) + return (FALSE); + return (TRUE); +} diff --git a/src/lib/kdb/kdb_db2/policy_db.h b/src/lib/kdb/kdb_db2/policy_db.h new file mode 100644 index 000000000..772b24d07 --- /dev/null +++ b/src/lib/kdb/kdb_db2/policy_db.h @@ -0,0 +1,87 @@ +/* + * Data Types for policy and principal information that + * exists in the respective databases. + * + * $Header$ + * + * This file was originally created with rpcgen. + * It has been hacked up since then. + */ + +#ifndef __ADB_H__ +#define __ADB_H__ +#include +#include "k5-int.h" +#include +#include +#include +#include +#include "adb_err.h" +#include + +typedef long osa_adb_ret_t; + +#define OSA_ADB_POLICY_DB_MAGIC 0x12345A00 + +#define OSA_ADB_POLICY_VERSION_MASK 0x12345D00 +#define OSA_ADB_POLICY_VERSION_1 0x12345D01 + + + +typedef struct _osa_adb_db_lock_ent_t { + FILE *lockfile; + char *filename; + int refcnt, lockmode, lockcnt; + krb5_context context; +} osa_adb_lock_ent, *osa_adb_lock_t; + +typedef struct _osa_adb_db_ent_t { + int magic; + DB *db; + HASHINFO info; + BTREEINFO btinfo; + char *filename; + osa_adb_lock_t lock; + int opencnt; +} osa_adb_db_ent, *osa_adb_db_t, *osa_adb_princ_t, *osa_adb_policy_t; + +/* + * Return Code (the rest are in adb_err.h) + */ + +#define OSA_ADB_OK 0 + +/* + * Functions + */ + +krb5_error_code osa_adb_create_db(char *filename, char *lockfile, int magic); +krb5_error_code osa_adb_destroy_db(char *filename, char *lockfile, int magic); +krb5_error_code osa_adb_rename_db(char *filefrom, char *lockfrom, + char *fileto, char *lockto, int magic); +krb5_error_code osa_adb_init_db(osa_adb_db_t *dbp, char *filename, + char *lockfile, int magic); +krb5_error_code osa_adb_fini_db(osa_adb_db_t db, int magic); +krb5_error_code osa_adb_get_lock(osa_adb_db_t db, int mode); +krb5_error_code osa_adb_release_lock(osa_adb_db_t db); +krb5_error_code osa_adb_open_and_lock(osa_adb_princ_t db, int locktype); +krb5_error_code osa_adb_close_and_unlock(osa_adb_princ_t db); +krb5_error_code osa_adb_close_policy(osa_adb_policy_t db); +krb5_error_code osa_adb_create_policy(osa_adb_policy_t db, + osa_policy_ent_t entry); +krb5_error_code osa_adb_destroy_policy(osa_adb_policy_t db, + char * name); +krb5_error_code osa_adb_get_policy(osa_adb_policy_t db, + char * name, + osa_policy_ent_t *entry, + int *cnt); +krb5_error_code osa_adb_put_policy(osa_adb_policy_t db, + osa_policy_ent_t entry); +krb5_error_code osa_adb_iter_policy(osa_adb_policy_t db, + osa_adb_iter_policy_func func, + void * data); +void osa_free_policy_ent(osa_policy_ent_t val); + +bool_t xdr_osa_policy_ent_rec(XDR *xdrs, osa_policy_ent_t objp); + +#endif /* __ADB_H__ */ diff --git a/src/lib/kdb/kdb_default.c b/src/lib/kdb/kdb_default.c new file mode 100644 index 000000000..07d1cef3b --- /dev/null +++ b/src/lib/kdb/kdb_default.c @@ -0,0 +1,329 @@ +/* + * lib/kdb/kdb_helper.c + * + * Copyright 1995 by the Massachusetts Institute of Technology. + * All Rights Reserved. + * + * Export of this software from the United States of America may + * require a specific license from the United States Government. + * It is the responsibility of any person or organization contemplating + * export to obtain such a license before exporting. + * + * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + * distribute this software and its documentation for any purpose and + * without fee is hereby granted, provided that the above copyright + * notice appear in all copies and that both that copyright notice and + * this permission notice appear in supporting documentation, and that + * the name of M.I.T. not be used in advertising or publicity pertaining + * to distribution of the software without specific, written prior + * permission. Furthermore if you modify this software you must label + * your software as modified software and not distribute it in such a + * fashion that it might be confused with the original M.I.T. software. + * M.I.T. makes no representations about the suitability of + * this software for any purpose. It is provided "as is" without express + * or implied warranty. + * + */ + +#include "k5-int.h" +#include +#include +#include + + +/* + * Given a particular enctype and optional salttype and kvno, find the + * most appropriate krb5_key_data entry of the database entry. + * + * If stype or kvno is negative, it is ignored. + * If kvno is 0 get the key which is maxkvno for the princ and matches + * the other attributes. + */ +krb5_error_code +krb5_dbe_def_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) + krb5_context kcontext; + krb5_db_entry *dbentp; + krb5_int32 *start; + krb5_int32 ktype; + krb5_int32 stype; + krb5_int32 kvno; + krb5_key_data **kdatap; +{ + int i, idx; + int maxkvno; + krb5_key_data *datap; + krb5_error_code ret; + + ret = 0; + if (kvno == -1 && stype == -1 && ktype == -1) + kvno = 0; + + if (kvno == 0) { + /* Get the max key version */ + for (i = 0; i < dbentp->n_key_data; i++) { + if (kvno < dbentp->key_data[i].key_data_kvno) { + kvno = dbentp->key_data[i].key_data_kvno; + } + } + } + + maxkvno = -1; + datap = (krb5_key_data *) NULL; + for (i = *start; i < dbentp->n_key_data; i++) { + krb5_boolean similar; + krb5_int32 db_stype; + + ret = 0; + if (dbentp->key_data[i].key_data_ver > 1) { + db_stype = dbentp->key_data[i].key_data_type[1]; + } else { + db_stype = KRB5_KDB_SALTTYPE_NORMAL; + } + + /* + * Filter out non-permitted enctypes. + */ + if (!krb5_is_permitted_enctype(kcontext, + dbentp->key_data[i].key_data_type[0])) { + ret = KRB5_KDB_NO_PERMITTED_KEY; + continue; + } + + + if (ktype > 0) { + if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype, + dbentp->key_data[i].key_data_type[0], + &similar))) + + return(ret); + } + + if (((ktype <= 0) || similar) && + ((db_stype == stype) || (stype < 0))) { + if (kvno >= 0) { + if (kvno == dbentp->key_data[i].key_data_kvno) { + datap = &dbentp->key_data[i]; + idx = i; + maxkvno = kvno; + break; + } + } else { + if (dbentp->key_data[i].key_data_kvno > maxkvno) { + maxkvno = dbentp->key_data[i].key_data_kvno; + datap = &dbentp->key_data[i]; + idx = i; + } + } + } + } + if (maxkvno < 0) + return ret ? ret : KRB5_KDB_NO_MATCHING_KEY; + *kdatap = datap; + *start = idx+1; + return 0; +} + +/* + * kdb default functions. Ideally, some other file should have this functions. For now, TBD. + */ +#ifndef min +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +krb5_error_code +krb5_def_store_mkey(context, keyfile, mname, key, master_pwd) + krb5_context context; + char *keyfile; + krb5_principal mname; + krb5_keyblock *key; + char *master_pwd; +{ + FILE *kf; + krb5_error_code retval = 0; + krb5_ui_2 enctype; + char defkeyfile[MAXPATHLEN+1]; + krb5_data *realm = krb5_princ_realm(context, mname); +#if HAVE_UMASK + mode_t oumask; +#endif + + if (!keyfile) { + (void) strcpy(defkeyfile, DEFAULT_KEYFILE_STUB); + (void) strncat(defkeyfile, realm->data, + min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, + realm->length)); + defkeyfile[sizeof(defkeyfile) - 1] = '\0'; + keyfile = defkeyfile; + } + +#if HAVE_UMASK + oumask = umask(077); +#endif +#ifdef ANSI_STDIO + if (!(kf = fopen(keyfile, "wb"))) +#else + if (!(kf = fopen(keyfile, "w"))) +#endif + { +#if HAVE_UMASK + (void) umask(oumask); +#endif + return errno; + } + enctype = key->enctype; + if ((fwrite((krb5_pointer) &enctype, + 2, 1, kf) != 1) || + (fwrite((krb5_pointer) &key->length, + sizeof(key->length), 1, kf) != 1) || + (fwrite((krb5_pointer) key->contents, + sizeof(key->contents[0]), (unsigned) key->length, + kf) != key->length)) { + retval = errno; + (void) fclose(kf); + } + if (fclose(kf) == EOF) + retval = errno; +#if HAVE_UMASK + (void) umask(oumask); +#endif + return retval; +} + + +krb5_error_code +krb5_db_def_fetch_mkey( krb5_context context, + krb5_principal mname, + krb5_keyblock *key, + int *kvno, + char *db_args) +{ + krb5_error_code retval; + krb5_ui_2 enctype; + char defkeyfile[MAXPATHLEN+1]; + krb5_data *realm = krb5_princ_realm(context, mname); + FILE *kf = NULL; + + retval = 0; + key->magic = KV5M_KEYBLOCK; + (void) strcpy(defkeyfile, DEFAULT_KEYFILE_STUB); + (void) strncat(defkeyfile, realm->data, + min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, + realm->length)); + defkeyfile[sizeof(defkeyfile) - 1] = '\0'; + +#ifdef ANSI_STDIO + if (!(kf = fopen((db_args) ? db_args : defkeyfile, "rb"))) +#else + if (!(kf = fopen((db_args) ? db_args : defkeyfile, "r"))) +#endif + return KRB5_KDB_CANTREAD_STORED; + + if (fread((krb5_pointer) &enctype, 2, 1, kf) != 1) { + retval = KRB5_KDB_CANTREAD_STORED; + goto errout; + } + + if (key->enctype == ENCTYPE_UNKNOWN) + key->enctype = enctype; + else if (enctype != key->enctype) { + retval = KRB5_KDB_BADSTORED_MKEY; + goto errout; + } + + if (fread((krb5_pointer) &key->length, + sizeof(key->length), 1, kf) != 1) { + retval = KRB5_KDB_CANTREAD_STORED; + goto errout; + } + + if (!key->length || ((int) key->length) < 0) { + retval = KRB5_KDB_BADSTORED_MKEY; + goto errout; + } + + if (!(key->contents = (krb5_octet *)malloc(key->length))) { + retval = ENOMEM; + goto errout; + } + + if (fread((krb5_pointer) key->contents, + sizeof(key->contents[0]), key->length, kf) + != key->length) { + retval = KRB5_KDB_CANTREAD_STORED; + memset(key->contents, 0, key->length); + free(key->contents); + key->contents = 0; + } else + retval = 0; + + *kvno = 0; + + errout: + (void) fclose(kf); + return retval; + +} + + +krb5_error_code +krb5_def_verify_master_key(context, mprinc, mkey) + krb5_context context; + krb5_principal mprinc; + krb5_keyblock *mkey; +{ + krb5_error_code retval; + krb5_db_entry master_entry; + int nprinc; + krb5_boolean more; + krb5_keyblock tempkey; + + nprinc = 1; + if ((retval = krb5_db_get_principal(context, mprinc, + &master_entry, &nprinc, &more))) + return(retval); + + if (nprinc != 1) { + if (nprinc) + krb5_db_free_principal(context, &master_entry, nprinc); + return(KRB5_KDB_NOMASTERKEY); + } else if (more) { + krb5_db_free_principal(context, &master_entry, nprinc); + return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); + } + + if ((retval = krb5_dbekd_decrypt_key_data(context, mkey, + &master_entry.key_data[0], + &tempkey, NULL))) { + krb5_db_free_principal(context, &master_entry, nprinc); + return retval; + } + + if (mkey->length != tempkey.length || + memcmp((char *)mkey->contents, + (char *)tempkey.contents,mkey->length)) { + retval = KRB5_KDB_BADMASTERKEY; + } + + memset((char *)tempkey.contents, 0, tempkey.length); + krb5_xfree(tempkey.contents); + krb5_db_free_principal(context, &master_entry, nprinc); + + return retval; +} + + +krb5_error_code kdb_def_set_mkey ( krb5_context kcontext, + char *pwd, + krb5_keyblock *key ) +{ + printf("default set master key\n"); + return 0; +} + +krb5_error_code kdb_def_get_mkey ( krb5_context kcontext, + krb5_keyblock **key ) +{ + printf("default get master key\n"); + return 0; +} + diff --git a/src/lib/kdb/kdb_xdr.c b/src/lib/kdb/kdb_xdr.c deleted file mode 100644 index fb0a41ea4..000000000 --- a/src/lib/kdb/kdb_xdr.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * lib/kdb/kdb_xdr.c - * - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -#include "k5-int.h" -#include -#include -#include - -#define safe_realloc(p,n) ((p)?(realloc(p,n)):(malloc(n))) - -krb5_error_code -krb5_dbe_create_key_data(context, entry) - krb5_context context; - krb5_db_entry * entry; -{ - if ((entry->key_data = - (krb5_key_data *) safe_realloc(entry->key_data, - (sizeof(krb5_key_data)* - (entry->n_key_data + 1)))) == NULL) - return(ENOMEM); - - - memset(entry->key_data + entry->n_key_data, 0, sizeof(krb5_key_data)); - entry->n_key_data++; - - return 0; -} - -krb5_error_code -krb5_dbe_update_tl_data(context, entry, new_tl_data) - krb5_context context; - krb5_db_entry * entry; - krb5_tl_data * new_tl_data; -{ - krb5_tl_data * tl_data; - krb5_octet * tmp; - - /* copy the new data first, so we can fail cleanly if malloc() - fails */ - - if ((tmp = (krb5_octet *) malloc(new_tl_data->tl_data_length)) == NULL) - return(ENOMEM); - - /* Find an existing entry of the specified type and point at - it, or NULL if not found */ - - for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) - if (tl_data->tl_data_type == new_tl_data->tl_data_type) - break; - - /* if necessary, chain a new record in the beginning and point at it */ - - if (!tl_data) { - if ((tl_data = (krb5_tl_data *) calloc(1, sizeof(krb5_tl_data))) - == NULL) { - free(tmp); - return(ENOMEM); - } - tl_data->tl_data_next = entry->tl_data; - entry->tl_data = tl_data; - entry->n_tl_data++; - } - - /* fill in the record */ - - if (tl_data->tl_data_contents) - free(tl_data->tl_data_contents); - - tl_data->tl_data_type = new_tl_data->tl_data_type; - tl_data->tl_data_length = new_tl_data->tl_data_length; - tl_data->tl_data_contents = tmp; - memcpy(tmp, new_tl_data->tl_data_contents, tl_data->tl_data_length); - - return(0); -} - -krb5_error_code -krb5_dbe_lookup_tl_data(context, entry, ret_tl_data) - krb5_context context; - krb5_db_entry * entry; - krb5_tl_data * ret_tl_data; -{ - krb5_tl_data *tl_data; - - for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { - if (tl_data->tl_data_type == ret_tl_data->tl_data_type) { - *ret_tl_data = *tl_data; - return(0); - } - } - - /* if the requested record isn't found, return zero bytes. - if it ever means something to have a zero-length tl_data, - this code and its callers will have to be changed */ - - ret_tl_data->tl_data_length = 0; - ret_tl_data->tl_data_contents = NULL; - return(0); -} - -krb5_error_code -krb5_dbe_update_last_pwd_change(context, entry, stamp) - krb5_context context; - krb5_db_entry * entry; - krb5_timestamp stamp; -{ - krb5_tl_data tl_data; - krb5_octet buf[4]; /* this is the encoded size of an int32 */ - - tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; - tl_data.tl_data_length = sizeof(buf); - krb5_kdb_encode_int32((krb5_int32) stamp, buf); - tl_data.tl_data_contents = buf; - - return(krb5_dbe_update_tl_data(context, entry, &tl_data)); -} - -krb5_error_code -krb5_dbe_lookup_last_pwd_change(context, entry, stamp) - krb5_context context; - krb5_db_entry * entry; - krb5_timestamp * stamp; -{ - krb5_tl_data tl_data; - krb5_error_code code; - krb5_int32 tmp; - - tl_data.tl_data_type = KRB5_TL_LAST_PWD_CHANGE; - - if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) - return(code); - - if (tl_data.tl_data_length != 4) { - *stamp = 0; - return(0); - } - - krb5_kdb_decode_int32(tl_data.tl_data_contents, tmp); - - *stamp = (krb5_timestamp) tmp; - - return(0); -} - -/* it seems odd that there's no function to remove a tl_data, but if - I need one, I'll add one */ - -krb5_error_code -krb5_dbe_update_mod_princ_data(context, entry, mod_date, mod_princ) - krb5_context context; - krb5_db_entry * entry; - krb5_timestamp mod_date; - krb5_const_principal mod_princ; -{ - krb5_tl_data tl_data; - - krb5_error_code retval = 0; - krb5_octet * nextloc = 0; - char * unparse_mod_princ = 0; - unsigned int unparse_mod_princ_size; - - if ((retval = krb5_unparse_name(context, mod_princ, - &unparse_mod_princ))) - return(retval); - - unparse_mod_princ_size = strlen(unparse_mod_princ) + 1; - - if ((nextloc = (krb5_octet *) malloc(unparse_mod_princ_size + 4)) - == NULL) { - free(unparse_mod_princ); - return(ENOMEM); - } - - tl_data.tl_data_type = KRB5_TL_MOD_PRINC; - tl_data.tl_data_length = unparse_mod_princ_size + 4; - tl_data.tl_data_contents = nextloc; - - /* Mod Date */ - krb5_kdb_encode_int32(mod_date, nextloc); - - /* Mod Princ */ - memcpy(nextloc+4, unparse_mod_princ, unparse_mod_princ_size); - - retval = krb5_dbe_update_tl_data(context, entry, &tl_data); - - free(unparse_mod_princ); - free(nextloc); - - return(retval); -} - -krb5_error_code -krb5_dbe_lookup_mod_princ_data(context, entry, mod_time, mod_princ) - krb5_context context; - krb5_db_entry * entry; - krb5_timestamp * mod_time; - krb5_principal * mod_princ; -{ - krb5_tl_data tl_data; - krb5_error_code code; - - tl_data.tl_data_type = KRB5_TL_MOD_PRINC; - - if ((code = krb5_dbe_lookup_tl_data(context, entry, &tl_data))) - return(code); - - if ((tl_data.tl_data_length < 5) || - (tl_data.tl_data_contents[tl_data.tl_data_length-1] != '\0')) - return(KRB5_KDB_TRUNCATED_RECORD); - - /* Mod Date */ - krb5_kdb_decode_int32(tl_data.tl_data_contents, *mod_time); - - /* Mod Princ */ - if ((code = krb5_parse_name(context, - (const char *) (tl_data.tl_data_contents+4), - mod_princ))) - return(code); - - return(0); -} - -krb5_error_code -krb5_encode_princ_dbkey(context, key, principal) - krb5_context context; - krb5_data *key; - krb5_const_principal principal; -{ - char *princ_name; - krb5_error_code retval; - - if (!(retval = krb5_unparse_name(context, principal, &princ_name))) { - /* need to store the NULL for decoding */ - key->length = strlen(princ_name)+1; - key->data = princ_name; - } - return(retval); -} - -void -krb5_free_princ_dbkey(context, key) - krb5_context context; - krb5_data *key; -{ - (void) krb5_free_data_contents(context, key); -} - -krb5_error_code -krb5_encode_princ_contents(context, content, entry) - krb5_context context; - krb5_data * content; - krb5_db_entry * entry; -{ - int i, j; - unsigned int unparse_princ_size; - char * unparse_princ; - char * nextloc; - krb5_tl_data * tl_data; - krb5_error_code retval; - krb5_int16 psize16; - - /* - * Generate one lump of data from the krb5_db_entry. - * This data must be independent of byte order of the machine, - * compact and extensible. - */ - - /* - * First allocate enough space for all the data. - * Need 2 bytes for the length of the base structure - * then 36 [ 8 * 4 + 2 * 2] bytes for the base information - * [ attributes, max_life, max_renewable_life, expiration, - * pw_expiration, last_success, last_failed, fail_auth_count ] - * [ n_key_data, n_tl_data ] - * then XX bytes [ e_length ] for the extra data [ e_data ] - * then XX bytes [ 2 for length + length for string ] for the principal, - * then (4 [type + length] + tl_data_length) bytes per tl_data - * then (4 + (4 + key_data_length) per key_data_contents) bytes per key_data - */ - content->length = entry->len + entry->e_length; - - if ((retval = krb5_unparse_name(context, entry->princ, &unparse_princ))) - return(retval); - - unparse_princ_size = strlen(unparse_princ) + 1; - content->length += unparse_princ_size; - content->length += 2; - - i = 0; - /* tl_data is a linked list */ - for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { - content->length += tl_data->tl_data_length; - content->length += 4; /* type, length */ - i++; - } - - if (i != entry->n_tl_data) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto epc_error; - } - - /* key_data is an array */ - for (i = 0; i < entry->n_key_data; i++) { - content->length += 4; /* Version, KVNO */ - for (j = 0; j < entry->key_data[i].key_data_ver; j++) { - content->length += entry->key_data[i].key_data_length[j]; - content->length += 4; /* type + length */ - } - } - - if ((content->data = malloc(content->length)) == NULL) { - retval = ENOMEM; - goto epc_error; - } - - /* - * Now we go through entry again, this time copying data - * These first entries are always saved regardless of version - */ - nextloc = content->data; - - /* Base Length */ - krb5_kdb_encode_int16(entry->len, nextloc); - nextloc += 2; - - /* Attributes */ - krb5_kdb_encode_int32(entry->attributes, nextloc); - nextloc += 4; - - /* Max Life */ - krb5_kdb_encode_int32(entry->max_life, nextloc); - nextloc += 4; - - /* Max Renewable Life */ - krb5_kdb_encode_int32(entry->max_renewable_life, nextloc); - nextloc += 4; - - /* When the client expires */ - krb5_kdb_encode_int32(entry->expiration, nextloc); - nextloc += 4; - - /* When its passwd expires */ - krb5_kdb_encode_int32(entry->pw_expiration, nextloc); - nextloc += 4; - - /* Last successful passwd */ - krb5_kdb_encode_int32(entry->last_success, nextloc); - nextloc += 4; - - /* Last failed passwd attempt */ - krb5_kdb_encode_int32(entry->last_failed, nextloc); - nextloc += 4; - - /* # of failed passwd attempt */ - krb5_kdb_encode_int32(entry->fail_auth_count, nextloc); - nextloc += 4; - - /* # tl_data strutures */ - krb5_kdb_encode_int16(entry->n_tl_data, nextloc); - nextloc += 2; - - /* # key_data strutures */ - krb5_kdb_encode_int16(entry->n_key_data, nextloc); - nextloc += 2; - - /* Put extended fields here */ - if (entry->len != KRB5_KDB_V1_BASE_LENGTH) - abort(); - - /* Any extra data that this version doesn't understand. */ - if (entry->e_length) { - memcpy(nextloc, entry->e_data, entry->e_length); - nextloc += entry->e_length; - } - - /* - * Now we get to the principal. - * To squeze a few extra bytes out it is always assumed to come - * after the base type. - */ - psize16 = (krb5_int16) unparse_princ_size; - krb5_kdb_encode_int16(psize16, nextloc); - nextloc += 2; - (void) memcpy(nextloc, unparse_princ, unparse_princ_size); - nextloc += unparse_princ_size; - - /* tl_data is a linked list, of type, legth, contents */ - for (tl_data = entry->tl_data; tl_data; tl_data = tl_data->tl_data_next) { - krb5_kdb_encode_int16(tl_data->tl_data_type, nextloc); - nextloc += 2; - krb5_kdb_encode_int16(tl_data->tl_data_length, nextloc); - nextloc += 2; - - memcpy(nextloc, tl_data->tl_data_contents, tl_data->tl_data_length); - nextloc += tl_data->tl_data_length; - } - - /* key_data is an array */ - for (i = 0; i < entry->n_key_data; i++) { - krb5_kdb_encode_int16(entry->key_data[i].key_data_ver, nextloc); - nextloc += 2; - krb5_kdb_encode_int16(entry->key_data[i].key_data_kvno, nextloc); - nextloc += 2; - - for (j = 0; j < entry->key_data[i].key_data_ver; j++) { - krb5_int16 type = entry->key_data[i].key_data_type[j]; - krb5_ui_2 length = entry->key_data[i].key_data_length[j]; - - krb5_kdb_encode_int16(type, nextloc); - nextloc += 2; - krb5_kdb_encode_int16(length, nextloc); - nextloc += 2; - - if (length) { - memcpy(nextloc, entry->key_data[i].key_data_contents[j],length); - nextloc += length; - } - } - } - -epc_error:; - free(unparse_princ); - return retval; -} - -void -krb5_free_princ_contents(context, contents) - krb5_context context; - krb5_data *contents; -{ - krb5_free_data_contents(context, contents); - return; -} - -krb5_error_code -krb5_decode_princ_contents(context, content, entry) - krb5_context context; - krb5_data * content; - krb5_db_entry * entry; -{ - int sizeleft, i; - char * nextloc; - krb5_tl_data ** tl_data; - krb5_int16 i16; - - krb5_error_code retval; - - /* Zero out entry and NULL pointers */ - memset(entry, 0, sizeof(krb5_db_entry)); - - /* - * undo the effects of encode_princ_contents. - * - * The first part is decoding the base type. If the base type is - * bigger than the original base type then the additional fields - * need to be filled in. If the base type is larger than any - * known base type the additional data goes in e_data. - */ - - /* First do the easy stuff */ - nextloc = content->data; - sizeleft = content->length; - if ((sizeleft -= KRB5_KDB_V1_BASE_LENGTH) < 0) - return KRB5_KDB_TRUNCATED_RECORD; - - /* Base Length */ - krb5_kdb_decode_int16(nextloc, entry->len); - nextloc += 2; - - /* Attributes */ - krb5_kdb_decode_int32(nextloc, entry->attributes); - nextloc += 4; - - /* Max Life */ - krb5_kdb_decode_int32(nextloc, entry->max_life); - nextloc += 4; - - /* Max Renewable Life */ - krb5_kdb_decode_int32(nextloc, entry->max_renewable_life); - nextloc += 4; - - /* When the client expires */ - krb5_kdb_decode_int32(nextloc, entry->expiration); - nextloc += 4; - - /* When its passwd expires */ - krb5_kdb_decode_int32(nextloc, entry->pw_expiration); - nextloc += 4; - - /* Last successful passwd */ - krb5_kdb_decode_int32(nextloc, entry->last_success); - nextloc += 4; - - /* Last failed passwd attempt */ - krb5_kdb_decode_int32(nextloc, entry->last_failed); - nextloc += 4; - - /* # of failed passwd attempt */ - krb5_kdb_decode_int32(nextloc, entry->fail_auth_count); - nextloc += 4; - - /* # tl_data strutures */ - krb5_kdb_decode_int16(nextloc, entry->n_tl_data); - nextloc += 2; - - if (entry->n_tl_data < 0) - return KRB5_KDB_TRUNCATED_RECORD; - - /* # key_data strutures */ - krb5_kdb_decode_int16(nextloc, entry->n_key_data); - nextloc += 2; - - if (entry->n_key_data < 0) - return KRB5_KDB_TRUNCATED_RECORD; - - /* Check for extra data */ - if (entry->len > KRB5_KDB_V1_BASE_LENGTH) { - entry->e_length = entry->len - KRB5_KDB_V1_BASE_LENGTH; - if ((entry->e_data = (krb5_octet *)malloc(entry->e_length))) { - memcpy(entry->e_data, nextloc, entry->e_length); - nextloc += entry->e_length; - } else { - return ENOMEM; - } - } - - /* - * Get the principal name for the entry - * (stored as a string which gets unparsed.) - */ - if ((sizeleft -= 2) < 0) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto error_out; - } - - i = 0; - krb5_kdb_decode_int16(nextloc, i16); - i = (int) i16; - nextloc += 2; - - if ((retval = krb5_parse_name(context, nextloc, &(entry->princ)))) - goto error_out; - if (((size_t) i != (strlen(nextloc) + 1)) || (sizeleft < i)) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto error_out; - } - sizeleft -= i; - nextloc += i; - - /* tl_data is a linked list */ - tl_data = &entry->tl_data; - for (i = 0; i < entry->n_tl_data; i++) { - if ((sizeleft -= 4) < 0) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto error_out; - } - if ((*tl_data = (krb5_tl_data *) - malloc(sizeof(krb5_tl_data))) == NULL) { - retval = ENOMEM; - goto error_out; - } - (*tl_data)->tl_data_next = NULL; - (*tl_data)->tl_data_contents = NULL; - krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_type); - nextloc += 2; - krb5_kdb_decode_int16(nextloc, (*tl_data)->tl_data_length); - nextloc += 2; - - if ((sizeleft -= (*tl_data)->tl_data_length) < 0) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto error_out; - } - if (((*tl_data)->tl_data_contents = (krb5_octet *) - malloc((*tl_data)->tl_data_length)) == NULL) { - retval = ENOMEM; - goto error_out; - } - memcpy((*tl_data)->tl_data_contents,nextloc,(*tl_data)->tl_data_length); - nextloc += (*tl_data)->tl_data_length; - tl_data = &((*tl_data)->tl_data_next); - } - - /* key_data is an array */ - if (entry->n_key_data && ((entry->key_data = (krb5_key_data *) - malloc(sizeof(krb5_key_data) * entry->n_key_data)) == NULL)) { - retval = ENOMEM; - goto error_out; - } - for (i = 0; i < entry->n_key_data; i++) { - krb5_key_data * key_data; - int j; - - if ((sizeleft -= 4) < 0) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto error_out; - } - key_data = entry->key_data + i; - memset(key_data, 0, sizeof(krb5_key_data)); - krb5_kdb_decode_int16(nextloc, key_data->key_data_ver); - nextloc += 2; - krb5_kdb_decode_int16(nextloc, key_data->key_data_kvno); - nextloc += 2; - - /* key_data_ver determins number of elements and how to unparse them. */ - if (key_data->key_data_ver <= KRB5_KDB_V1_KEY_DATA_ARRAY) { - for (j = 0; j < key_data->key_data_ver; j++) { - if ((sizeleft -= 4) < 0) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto error_out; - } - krb5_kdb_decode_int16(nextloc, key_data->key_data_type[j]); - nextloc += 2; - krb5_kdb_decode_int16(nextloc, key_data->key_data_length[j]); - nextloc += 2; - - if ((sizeleft -= key_data->key_data_length[j]) < 0) { - retval = KRB5_KDB_TRUNCATED_RECORD; - goto error_out; - } - if (key_data->key_data_length[j]) { - if ((key_data->key_data_contents[j] = (krb5_octet *) - malloc(key_data->key_data_length[j])) == NULL) { - retval = ENOMEM; - goto error_out; - } - memcpy(key_data->key_data_contents[j], nextloc, - key_data->key_data_length[j]); - nextloc += key_data->key_data_length[j]; - } - } - } else { - /* This isn't right. I'll fix it later */ - abort(); - } - } - return 0; - -error_out:; - krb5_dbe_free_contents(context, entry); - return retval; -} - -void -krb5_dbe_free_contents(context, entry) - krb5_context context; - krb5_db_entry * entry; -{ - krb5_tl_data * tl_data_next; - krb5_tl_data * tl_data; - int i, j; - - if (entry->e_data) - free(entry->e_data); - if (entry->princ) - krb5_free_principal(context, entry->princ); - for (tl_data = entry->tl_data; tl_data; tl_data = tl_data_next) { - tl_data_next = tl_data->tl_data_next; - if (tl_data->tl_data_contents) - free(tl_data->tl_data_contents); - free(tl_data); - } - if (entry->key_data) { - for (i = 0; i < entry->n_key_data; i++) { - for (j = 0; j < entry->key_data[i].key_data_ver; j++) { - if (entry->key_data[i].key_data_length[j]) { - if (entry->key_data[i].key_data_contents[j]) { - memset(entry->key_data[i].key_data_contents[j], - 0, - (unsigned) entry->key_data[i].key_data_length[j]); - free (entry->key_data[i].key_data_contents[j]); - } - } - entry->key_data[i].key_data_contents[j] = NULL; - entry->key_data[i].key_data_length[j] = 0; - entry->key_data[i].key_data_type[j] = 0; - } - } - free(entry->key_data); - } - memset(entry, 0, sizeof(*entry)); - return; -} - -/* - * Given a particular enctype and optional salttype and kvno, find the - * most appropriate krb5_key_data entry of the database entry. - * - * If stype or kvno is negative, it is ignored. - * If kvno is 0 get the key which is maxkvno for the princ and matches - * the other attributes. - */ -krb5_error_code -krb5_dbe_search_enctype(kcontext, dbentp, start, ktype, stype, kvno, kdatap) - krb5_context kcontext; - krb5_db_entry *dbentp; - krb5_int32 *start; - krb5_int32 ktype; - krb5_int32 stype; - krb5_int32 kvno; - krb5_key_data **kdatap; -{ - int i, idx; - int maxkvno; - krb5_key_data *datap; - krb5_error_code ret; - - ret = 0; - if (kvno == -1 && stype == -1 && ktype == -1) - kvno = 0; - - if (kvno == 0) { - /* Get the max key version */ - for (i = 0; i < dbentp->n_key_data; i++) { - if (kvno < dbentp->key_data[i].key_data_kvno) { - kvno = dbentp->key_data[i].key_data_kvno; - } - } - } - - maxkvno = -1; - datap = (krb5_key_data *) NULL; - for (i = *start; i < dbentp->n_key_data; i++) { - krb5_boolean similar; - krb5_int32 db_stype; - - ret = 0; - if (dbentp->key_data[i].key_data_ver > 1) { - db_stype = dbentp->key_data[i].key_data_type[1]; - } else { - db_stype = KRB5_KDB_SALTTYPE_NORMAL; - } - - /* - * Filter out non-permitted enctypes. - */ - if (!krb5_is_permitted_enctype(kcontext, - dbentp->key_data[i].key_data_type[0])) { - ret = KRB5_KDB_NO_PERMITTED_KEY; - continue; - } - - - if (ktype > 0) { - if ((ret = krb5_c_enctype_compare(kcontext, (krb5_enctype) ktype, - dbentp->key_data[i].key_data_type[0], - &similar))) - return(ret); - } - - if (((ktype <= 0) || similar) && - ((db_stype == stype) || (stype < 0))) { - if (kvno >= 0) { - if (kvno == dbentp->key_data[i].key_data_kvno) { - datap = &dbentp->key_data[i]; - idx = i; - maxkvno = kvno; - break; - } - } else { - if (dbentp->key_data[i].key_data_kvno > maxkvno) { - maxkvno = dbentp->key_data[i].key_data_kvno; - datap = &dbentp->key_data[i]; - idx = i; - } - } - } - } - if (maxkvno < 0) - return ret ? ret : KRB5_KDB_NO_MATCHING_KEY; - *kdatap = datap; - *start = idx+1; - return 0; -} - -krb5_error_code -krb5_dbe_find_enctype(kcontext, dbentp, ktype, stype, kvno, kdatap) - krb5_context kcontext; - krb5_db_entry *dbentp; - krb5_int32 ktype; - krb5_int32 stype; - krb5_int32 kvno; - krb5_key_data **kdatap; -{ - krb5_int32 start = 0; - - return krb5_dbe_search_enctype(kcontext, dbentp, &start, ktype, stype, - kvno, kdatap); -} - - diff --git a/src/lib/kdb/keytab.c b/src/lib/kdb/keytab.c index 679ecad65..227a42e08 100644 --- a/src/lib/kdb/keytab.c +++ b/src/lib/kdb/keytab.c @@ -140,20 +140,19 @@ krb5_ktkdb_get_entry(in_context, id, principal, kvno, enctype, entry) xrealm_tgt = is_xrealm_tgt(context, principal); - /* Open database */ - /* krb5_db_init(context); */ - if ((kerror = krb5_db_open_database(context))) + /* Check whether database is inited. Open is commented */ + if ((kerror = krb5_db_inited(context))) return(kerror); /* get_principal */ kerror = krb5_db_get_principal(context, principal, & db_entry, &n, &more); if (kerror) { - krb5_db_close_database(context); + /* krb5_db_close_database(context); */ return(kerror); } if (n != 1) { - krb5_db_close_database(context); + /* krb5_db_close_database(context); */ return KRB5_KT_NOTFOUND; } @@ -207,8 +206,8 @@ krb5_ktkdb_get_entry(in_context, id, principal, kvno, enctype, entry) /* Close database */ error: - krb5_dbe_free_contents(context, &db_entry); - krb5_db_close_database(context); + krb5_db_free_principal(context, &db_entry, 1); + /* krb5_db_close_database(context); */ return(kerror); } diff --git a/src/lib/kdb/libkdb5.exports b/src/lib/kdb/libkdb5.exports index 47e1f0e7b..c9d53fb3d 100644 --- a/src/lib/kdb/libkdb5.exports +++ b/src/lib/kdb/libkdb5.exports @@ -97,6 +97,11 @@ kdb2_mpool_put kdb2_mpool_sync kdb2_nextkey kdb2_store +krb5_db_open +krb5_db_inited +krb5_db_clr_error +krb5_db_alloc +krb5_db_free krb5_db_close_database krb5_db_create krb5_db_delete_principal @@ -120,6 +125,7 @@ krb5_db_set_name krb5_db_setup_mkey_name krb5_db_store_mkey krb5_db_unlock +krb5_db_store_master_key krb5_db_verify_master_key krb5_dbe_apw krb5_dbe_ark @@ -150,3 +156,10 @@ krb5_ktkdb_set_context krb5_mkey_pwd_prompt1 krb5_mkey_pwd_prompt2 krb5_ser_db_context_init +krb5_db_create_policy +krb5_db_get_policy +krb5_db_put_policy +krb5_db_iter_policy +krb5_db_delete_policy +krb5_db_free_policy +krb5_db_vftabl_kdb_db2 diff --git a/src/lib/kdb/setup_mkey.c b/src/lib/kdb/setup_mkey.c deleted file mode 100644 index 61f1ef3e6..000000000 --- a/src/lib/kdb/setup_mkey.c +++ /dev/null @@ -1,74 +0,0 @@ -/* - * lib/kdb/setup_mkey.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * krb5_kdb_setup_mkey() - */ - -#include "k5-int.h" - -/* - * Given a key name and a realm name, construct a principal which can be used - * to fetch the master key from the database. - * - * If the key name is NULL, the default key name will be used. - */ - -#define REALM_SEP_STRING "@" - -krb5_error_code -krb5_db_setup_mkey_name(context, keyname, realm, fullname, principal) - krb5_context context; - const char *keyname; - const char *realm; - char **fullname; - krb5_principal *principal; -{ - krb5_error_code retval; - size_t keylen; - size_t rlen = strlen(realm); - char *fname; - - if (!keyname) - keyname = KRB5_KDB_M_NAME; /* XXX external? */ - - keylen = strlen(keyname); - - fname = malloc(keylen+rlen+strlen(REALM_SEP_STRING)+1); - if (!fname) - return ENOMEM; - - strcpy(fname, keyname); - strcat(fname, REALM_SEP_STRING); - strcat(fname, realm); - - if ((retval = krb5_parse_name(context, fname, principal))) - return retval; - if (fullname) - *fullname = fname; - else - free(fname); - return 0; -} diff --git a/src/lib/kdb/store_mkey.c b/src/lib/kdb/store_mkey.c deleted file mode 100644 index 587850e26..000000000 --- a/src/lib/kdb/store_mkey.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * lib/kdb/store_mkey.c - * - * Copyright 1990 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * krb5_db_store_mkey(): - * Store a database master key in a file. - */ - - -#include -#include "k5-int.h" - -/* Just in case sysincl.h didn't get it */ - -#ifndef MAXPATHLEN -#define MAXPATHLEN 1024 -#endif - -/* - * Put the KDC database master key into a file. If keyfile is NULL, - * then a default name derived from the principal name mname is used. - */ - -#ifndef min -#define min(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -krb5_error_code -krb5_db_store_mkey(context, keyfile, mname, key) - krb5_context context; - char *keyfile; - krb5_principal mname; - krb5_keyblock *key; -{ - FILE *kf; - krb5_error_code retval = 0; - krb5_ui_2 enctype; - char defkeyfile[MAXPATHLEN+1]; - krb5_data *realm = krb5_princ_realm(context, mname); -#if HAVE_UMASK - mode_t oumask; -#endif - - if (!keyfile) { - (void) strcpy(defkeyfile, DEFAULT_KEYFILE_STUB); - (void) strncat(defkeyfile, realm->data, - min(sizeof(defkeyfile)-sizeof(DEFAULT_KEYFILE_STUB)-1, - realm->length)); - defkeyfile[sizeof(defkeyfile) - 1] = '\0'; - keyfile = defkeyfile; - } - -#if HAVE_UMASK - oumask = umask(077); -#endif -#ifdef ANSI_STDIO - if (!(kf = fopen(keyfile, "wb"))) -#else - if (!(kf = fopen(keyfile, "w"))) -#endif - { -#if HAVE_UMASK - (void) umask(oumask); -#endif - return errno; - } - enctype = key->enctype; - if ((fwrite((krb5_pointer) &enctype, - 2, 1, kf) != 1) || - (fwrite((krb5_pointer) &key->length, - sizeof(key->length), 1, kf) != 1) || - (fwrite((krb5_pointer) key->contents, - sizeof(key->contents[0]), (unsigned) key->length, - kf) != key->length)) { - retval = errno; - (void) fclose(kf); - } - if (fclose(kf) == EOF) - retval = errno; -#if HAVE_UMASK - (void) umask(oumask); -#endif - return retval; -} diff --git a/src/lib/kdb/t_kdb.c b/src/lib/kdb/t_kdb.c deleted file mode 100644 index 769d3e68b..000000000 --- a/src/lib/kdb/t_kdb.c +++ /dev/null @@ -1,1091 +0,0 @@ -/* - * lib/kdb/t_kdb.c - * - * Copyright 1995 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - */ - -/* - * t_kdb.c - Test [and optionally obtain timing information about] the - * Kerberos database functions. - */ - -#define KDB5_DISPATCH -#include "k5-int.h" -#include -#include -#include -#include "com_err.h" - -#if HAVE_SRAND48 -#define RAND() lrand48() -#define SRAND(a) srand48(a) -#define RAND_TYPE long -#elif HAVE_SRAND -#define RAND() rand() -#define SRAND(a) srand(a) -#define RAND_TYPE int -#elif HAVE_SRANDOM -#define RAND() random() -#define SRAND(a) srandom(a) -#define RAND_TYPE long -#else /* no random */ -need a random number generator -#endif /* no random */ - -#define T_KDB_N_PASSES 100 -#define T_KDB_DEF_DB "test_db" -#define MAX_PNAME_LEN 1024 -#define MAX_PRINC_COMPS 8 -#define MAX_COMP_SIZE 32 - -#define RANDOM(a,b) (a + (RAND() % (b-a))) - -enum dbtype { DB_UFO, DB_DEFAULT, DB_BERKELEY, DB_DBM }; - -char *programname = (char *) NULL; -krb5_data mprinc_data_entries[] = { - { 0, sizeof("master")-1, "master"}, - { 0, sizeof("key")-1, "key"} -}; - -krb5_principal_data master_princ_data = { - 0, /* Magic number */ - { 0, sizeof("test.realm")-1, "test.realm"}, /* Realm */ - mprinc_data_entries, /* Name/instance */ - sizeof(mprinc_data_entries)/ - sizeof(mprinc_data_entries[0]), /* Number */ - KRB5_NT_SRV_INST /* Type */ -}; - -struct timeval tstart_time, tend_time; -struct timezone dontcare; -krb5_principal *recorded_principals = (krb5_principal *) NULL; -char **recorded_names = (char **) NULL; - -#ifdef BERK_DB_DBM -extern DBM *db_dbm_open (char *, int, int); -extern void db_dbm_close (DBM *); -extern datum db_dbm_fetch (DBM *, datum); -extern datum db_dbm_firstkey (DBM *); -extern datum db_dbm_nextkey (DBM *); -extern int db_dbm_delete (DBM *, datum); -extern int db_dbm_store (DBM *, datum, datum, int); -extern int db_dbm_error (DBM *); -extern int db_dbm_clearerr (DBM *); -extern int db_dbm_dirfno (DBM *); - -static kdb5_dispatch_table berkeley_dispatch = { - "Berkeley Hashed Database", - ".db", /* Index file name ext */ - (char *) NULL, /* Data file name ext */ - ".ok", /* Lock file name ext */ - db_dbm_open, /* Open Database */ - db_dbm_close, /* Close Database */ - db_dbm_fetch, /* Fetch Key */ - db_dbm_firstkey, /* Fetch First Key */ - db_dbm_nextkey, /* Fetch Next Key */ - db_dbm_delete, /* Delete Key */ - db_dbm_store, /* Store Key */ - db_dbm_error, /* Get Database Error */ - db_dbm_clearerr, /* Clear Database Error */ - db_dbm_dirfno, /* Get Database FD num */ - (int (*)()) NULL /* Get Database FD num */ -}; -#endif - -#if defined(NDBM) || defined(ODBM) -/* - * The following prototypes are necessary in case dbm_error and - * dbm_clearerr are in the library but not prototyped - * (e.g. NetBSD-1.0) - */ -#ifdef MISSING_ERROR_PROTO -int dbm_error (DBM *); -#endif -#ifdef MISSING_CLEARERR_PROTO -int dbm_clearerr (DBM *); -#endif - -static kdb5_dispatch_table dbm_dispatch = { - "Stock [N]DBM Database", - ".dir", /* Index file name ext */ - ".pag", /* Data file name ext */ - ".ok", /* Lock file name ext */ - dbm_open, /* Open Database */ - dbm_close, /* Close Database */ - dbm_fetch, /* Fetch Key */ - dbm_firstkey, /* Fetch First Key */ - dbm_nextkey, /* Fetch Next Key */ - dbm_delete, /* Delete Key */ - dbm_store, /* Store Key */ - /* - * The following are #ifdef'd because they have the potential to be - * macros rather than functions. - */ -#ifdef dbm_error - (int (*)()) NULL, /* Get Database Error */ -#else /* dbm_error */ -#ifdef HAVE_DBM_ERROR - dbm_error, /* Get Database Error */ -#else - (int (*)()) NULL, /* Get Database Error */ -#endif -#endif /* dbm_error */ -#ifdef dbm_clearerr - (int (*)()) NULL, /* Clear Database Error */ -#else /* dbm_clearerr */ -#ifdef HAVE_DBM_CLEARERR - dbm_clearerr, /* Clear Database Error */ -#else - (int (*)()) NULL, /* Clear Database Error */ -#endif -#endif /* dbm_clearerr */ -#ifdef dbm_dirfno - (int (*)()) NULL, /* Get Database FD num */ -#else /* dbm_dirfno */ - dbm_dirfno, /* Get Database FD num */ -#endif /* dbm_dirfno */ -#ifdef dbm_pagfno - (int (*)()) NULL, /* Get Database FD num */ -#else /* dbm_pagfno */ - dbm_pagfno, /* Get Database FD num */ -#endif /* dbm_pagfno */ -}; -#endif /* NDBM || ODBM */ - - -/* - * Timer macros. - */ -#define swatch_on() ((void) gettimeofday(&tstart_time, &dontcare)) -#define swatch_eltime() ((gettimeofday(&tend_time, &dontcare)) ? -1.0 : \ - (((float) (tend_time.tv_sec - \ - tstart_time.tv_sec)) + \ - (((float) (tend_time.tv_usec - \ - tstart_time.tv_usec))/1000000.0))) - -/* - * Free all principals and names in the recorded names list. - */ -static void -free_principals(kcontext, nentries) - krb5_context kcontext; - int nentries; -{ - int i; - if (recorded_principals) { - for (i=0; ienctype, &lkey); - if (kret) - goto out; - rkey = &lkey; - } else - rkey = key; - - if ((kret = krb5_dbe_create_key_data(kcontext, &dbent))) - goto out; - if ((kret = krb5_dbekd_encrypt_key_data(kcontext, mkey, rkey, NULL, 1, - &dbent.key_data[0]))) - goto out; - - if (!key) - krb5_free_keyblock_contents(kcontext, rkey); - - kret = krb5_db_put_principal(kcontext, &dbent, &nentries); - if ((!kret) && (nentries != 1)) - kret = KRB5_KDB_UK_SERROR; - out: - krb5_dbe_free_contents(kcontext, &dbent); - return(kret); -} - -/* - * Generate a principal name. - */ -static krb5_error_code -gen_principal(kcontext, realm, do_rand, n, princp, namep) - krb5_context kcontext; - char *realm; - int do_rand; - int n; - krb5_principal *princp; - char **namep; -{ - static char pnamebuf[MAX_PNAME_LEN]; - static char *instnames[] = { - "instance1", "xxx2", "whereami3", "ABCDEFG4", "foofoo5" }; - static char *princnames[] = { - "princ1", "user2", "service3" }; - - krb5_error_code kret; - char *instname; - char *princbase; - int ncomps; - int i, complen, j; - char *cp; - - if (do_rand) { - ncomps = RANDOM(1,MAX_PRINC_COMPS); - cp = pnamebuf; - for (i=0; i= pnamebuf + sizeof(pnamebuf)) - break; - } - if(cp + strlen(realm) >= pnamebuf + sizeof(pnamebuf)) - break; - *cp = '/'; - cp++; - } - if(cp + strlen(realm) < pnamebuf + sizeof(pnamebuf)) { - cp[-1] = '@'; - strcpy(cp, realm); - } else { - strcpy(cp , ""); - } - } - else { - instname = instnames[n % (sizeof(instnames)/sizeof(instnames[0]))]; - princbase = princnames[n % (sizeof(princnames)/sizeof(princnames[0]))]; - sprintf(pnamebuf, "%s%d/%s@%s", princbase, n, instname, realm); - } - kret = krb5_parse_name(kcontext, pnamebuf, princp); - *namep = (!kret) ? pnamebuf : (char *) NULL; - return(kret); -} - -/* - * Find a principal in the database. - */ -static krb5_error_code -find_principal(kcontext, principal, docompare) - krb5_context kcontext; - krb5_principal principal; - krb5_boolean docompare; -{ - krb5_error_code kret; - krb5_db_entry dbent; - krb5_principal mod_princ; - krb5_timestamp mod_time; - int how_many; - krb5_boolean more; - - more = 0; - how_many = 1; - if ((kret = krb5_db_get_principal(kcontext, principal, &dbent, - &how_many, &more))) - return(kret); - if (how_many == 0) - return(KRB5_KDB_NOENTRY); - - if ((kret = krb5_dbe_lookup_mod_princ_data(kcontext, &dbent, - &mod_time, &mod_princ))) - - return(kret); - - if (docompare) { - if ((dbent.max_life != KRB5_KDB_MAX_LIFE) || - (dbent.max_renewable_life != KRB5_KDB_MAX_RLIFE) || - (dbent.expiration != KRB5_KDB_EXPIRATION) || - (dbent.attributes != KRB5_KDB_DEF_FLAGS) || - !krb5_principal_compare(kcontext, principal, dbent.princ) || - !krb5_principal_compare(kcontext, principal, mod_princ)) - kret = KRB5_PRINC_NOMATCH; - } - - krb5_db_free_principal(kcontext, &dbent, how_many); - krb5_free_principal(kcontext, mod_princ); - if (!kret) - return(((how_many == 1) && (more == 0)) ? 0 : KRB5KRB_ERR_GENERIC); - else - return(kret); - -} - -/* - * Delete a principal. - */ -static krb5_error_code -delete_principal(kcontext, principal) - krb5_context kcontext; - krb5_principal principal; -{ - krb5_error_code kret; - int num2delete; - - num2delete = 1; - if ((kret = krb5_db_delete_principal(kcontext, principal, &num2delete))) - return(kret); - return((num2delete == 1) ? 0 : KRB5KRB_ERR_GENERIC); -} - -static int -do_testing(db, passes, verbose, timing, rcases, check, save_db, dontclean, - ptest, hash) - char *db; - int passes; - int verbose; - int timing; - int rcases; - int check; - int save_db; - int dontclean; - int ptest; - int hash; -{ - krb5_error_code kret; - krb5_context kcontext; - char *op, *linkage, *oparg; - krb5_principal master_princ; - int master_princ_set = 0; - char *mkey_name; - char *realm; - char *mkey_fullname; - char *master_passwd; - krb5_data salt_data; - krb5_encrypt_block master_encblock; - krb5_keyblock master_keyblock; - krb5_data passwd; - krb5_pointer rseed; - krb5_boolean db_open, db_created; - int passno; - krb5_principal principal; - char *pname; - float elapsed; - krb5_keyblock stat_kb; - krb5_int32 crflags; - - mkey_name = "master/key"; - realm = master_princ_data.realm.data; - mkey_fullname = (char *) NULL; - master_princ = (krb5_principal) NULL; - master_passwd = "master_password"; - db_open = 0; - db_created = 0; - linkage = ""; - oparg = ""; - crflags = hash ? KRB5_KDB_CREATE_HASH : KRB5_KDB_CREATE_BTREE; - - memset(&master_keyblock, 0, sizeof(master_keyblock)); - - /* Set up some initial context */ - op = "initializing krb5"; - kret = krb5_init_context(&kcontext); - if (kret) - goto goodbye; - - /* - * The database had better not exist. - */ - op = "making sure database doesn't exist"; - if (!(kret = krb5_db_set_name(kcontext, db))) { - kret = EEXIST; - goto goodbye; - } - - /* Set up the master key name */ - op = "setting up master key name"; - if ((kret = krb5_db_setup_mkey_name(kcontext, mkey_name, realm, - &mkey_fullname, &master_princ))) - goto goodbye; - - master_princ_set = 1; - if (verbose) - fprintf(stdout, "%s: Initializing '%s', master key is '%s'\n", - programname, db, mkey_fullname); - - free(mkey_fullname); - mkey_fullname = 0; - - op = "salting master key"; - if ((kret = krb5_principal2salt(kcontext, master_princ, &salt_data))) - goto goodbye; - - op = "converting master key"; - krb5_use_enctype(kcontext, &master_encblock, DEFAULT_KDC_ENCTYPE); - master_keyblock.enctype = DEFAULT_KDC_ENCTYPE; - passwd.length = strlen(master_passwd); - passwd.data = master_passwd; - if ((kret = krb5_string_to_key(kcontext, &master_encblock, - &master_keyblock, &passwd, &salt_data))) - goto goodbye; - /* Clean up */ - free(salt_data.data); - - /* Process master key */ - op = "processing master key"; - if ((kret = krb5_process_key(kcontext, &master_encblock, - &master_keyblock))) - goto goodbye; - - /* Initialize random key generator */ - op = "initializing random key generator"; - if ((kret = krb5_init_random_key(kcontext, - &master_encblock, - &master_keyblock, - &rseed))) - goto goodbye; - - /* Create database */ - op = "creating database"; - if ((kret = krb5_db_create(kcontext, db, crflags))) - goto goodbye; - - db_created = 1; - - /* Set this database as active. */ - op = "setting active database"; - if ((kret = krb5_db_set_name(kcontext, db))) - goto goodbye; - - /* Initialize database */ - op = "initializing database"; - if ((kret = krb5_db_init(kcontext))) - goto goodbye; - - db_open = 1; - op = "adding master principal"; - if ((kret = add_principal(kcontext, - master_princ, - &master_keyblock, - &master_keyblock))) - goto goodbye; - - - stat_kb.enctype = DEFAULT_KDC_ENCTYPE; - stat_kb.length = 8; - stat_kb.contents = (krb5_octet *) "helpmeee"; - - /* We are now ready to proceed to test. */ - if (verbose) - fprintf(stdout, "%s: Beginning %stest\n", - programname, (rcases) ? "random " : ""); - init_princ_recording(kcontext, passes); - if (rcases) { - struct tacc { - float t_time; - int t_number; - } accumulated[3]; - int i, nvalid, discrim, highwater, coinflip; - krb5_keyblock *kbp; - - /* Generate random cases */ - for (i=0; i<3; i++) { - accumulated[i].t_time = 0.0; - accumulated[i].t_number = 0; - } - - /* - * Generate principal names. - */ - if (verbose > 1) - fprintf(stdout, "%s: generating %d names\n", - programname, passes); - for (passno=0; passno passes) - nvalid = passes; - - if (verbose > 1) - fprintf(stdout, "%s: priming database with %d principals\n", - programname, nvalid); - highwater = 0; - for (passno=0; passno 4) - fprintf(stderr, "*A(%s)\n", playback_name(passno)); - highwater++; - } - - if (verbose > 1) - fprintf(stderr, "%s: beginning random loop\n", programname); - /* Loop through some number of times and pick random operations */ - for (i=0; i<3*passes; i++) { - discrim = RANDOM(0,100); - - /* Add a principal 25% of the time, if possible */ - if ((discrim < 25) && (nvalid < passes)) { - op = "adding principal"; - coinflip = RANDOM(0,2); - kbp = (coinflip) ? &stat_kb : (krb5_keyblock *) NULL; - if (timing) { - swatch_on(); - } - if ((kret = add_principal(kcontext, - playback_principal(nvalid), - &master_keyblock, kbp))) { - oparg = playback_name(nvalid); - goto cya; - } - if (timing) { - elapsed = swatch_eltime(); - accumulated[0].t_time += elapsed; - accumulated[0].t_number++; - } - if (verbose > 4) - fprintf(stderr, "*A(%s)\n", playback_name(nvalid)); - nvalid++; - if (nvalid > highwater) - highwater = nvalid; - } - /* Delete a principal 15% of the time, if possible */ - else if ((discrim > 85) && (nvalid > 10)) { - op = "deleting principal"; - if (timing) { - swatch_on(); - } - if ((kret = delete_principal(kcontext, - playback_principal(nvalid-1)))) { - oparg = playback_name(nvalid-1); - goto cya; - } - if (timing) { - elapsed = swatch_eltime(); - accumulated[2].t_time += elapsed; - accumulated[2].t_number++; - } - if (verbose > 4) - fprintf(stderr, "XD(%s)\n", playback_name(nvalid-1)); - nvalid--; - } - /* Otherwise, find a principal */ - else { - op = "looking up principal"; - passno = RANDOM(0, nvalid); - if (timing) { - swatch_on(); - } - if ((kret = find_principal(kcontext, - playback_principal(passno), - check))) { - oparg = playback_name(passno); - goto cya; - } - if (timing) { - elapsed = swatch_eltime(); - accumulated[1].t_time += elapsed; - accumulated[1].t_number++; - } - if (verbose > 4) - fprintf(stderr, "-S(%s)\n", playback_name(passno)); - } - } - - if (!dontclean) { - /* Clean up the remaining principals */ - if (verbose > 1) - fprintf(stdout, "%s: deleting remaining %d principals\n", - programname, nvalid); - for (passno=0; passno 4) - fprintf(stderr, "XD(%s)\n", playback_name(passno)); - } - } - cya: - if (verbose) - fprintf(stdout, - "%s: highwater mark was %d principals\n", - programname, highwater); - if (accumulated[0].t_number && timing) - fprintf(stdout, - "%s: performed %8d additions in %9.4f seconds (%9.4f/add)\n", - programname, accumulated[0].t_number, - accumulated[0].t_time, - accumulated[0].t_time / (float) accumulated[0].t_number); - if (accumulated[1].t_number && timing) - fprintf(stdout, - "%s: performed %8d lookups in %9.4f seconds (%9.4f/search)\n", - programname, accumulated[1].t_number, - accumulated[1].t_time, - accumulated[1].t_time / (float) accumulated[1].t_number); - if (accumulated[2].t_number && timing) - fprintf(stdout, - "%s: performed %8d deletions in %9.4f seconds (%9.4f/delete)\n", - programname, accumulated[2].t_number, - accumulated[2].t_time, - accumulated[2].t_time / (float) accumulated[2].t_number); - if (kret) - goto goodbye; - } - else { - /* - * Generate principal names. - */ - for (passno=0; passno 4) - fprintf(stderr, "*A(%s)\n", playback_name(passno)); - } - if (timing) { - elapsed = swatch_eltime(); - fprintf(stdout, - "%s: added %d principals in %9.4f seconds (%9.4f/add)\n", - programname, passes, elapsed, elapsed/((float) passes)); - } - - /* - * Lookup principals. - */ - if (timing) { - swatch_on(); - } - for (passno=0; passno 4) - fprintf(stderr, "-S(%s)\n", playback_name(passno)); - } - if (timing) { - elapsed = swatch_eltime(); - fprintf(stdout, - "%s: found %d principals in %9.4f seconds (%9.4f/search)\n", - programname, passes, elapsed, elapsed/((float) passes)); - } - - /* - * Delete principals. - */ - if (!dontclean) { - if (timing) { - swatch_on(); - } - for (passno=passes-1; passno>=0; passno--) { - op = "deleting principal"; - if ((kret = delete_principal(kcontext, - playback_principal(passno)))) - goto goodbye; - if (verbose > 4) - fprintf(stderr, "XD(%s)\n", playback_name(passno)); - } - if (timing) { - elapsed = swatch_eltime(); - fprintf(stdout, - "%s: deleted %d principals in %9.4f seconds (%9.4f/delete)\n", - programname, passes, elapsed, - elapsed/((float) passes)); - } - } - - } - - goodbye: - if(master_princ_set) { - krb5_free_principal(kcontext, master_princ); - } - if (kret) - fprintf(stderr, "%s: error while %s %s%s(%s)\n", - programname, op, linkage, oparg, error_message(kret)); - - if (!kret && ptest) { - int nper; - pid_t children[32], child; - int nprocs, existat, i, j, fd; - - nprocs = ptest + 1; - if (nprocs > 32) - nprocs = 32; - - nper = passes / nprocs; - unlink("./test.lock"); - for (i=0; i 4) - fprintf(stderr, "*A[%ld](%s)\n", (long) getpid(), - playback_name(base+j)); - } - for (j=0; (j 4) - fprintf(stderr, "-S[%ld](%s)\n", (long) getpid(), - playback_name(base+j)); - } - for (j=0; (j 4) - fprintf(stderr, "XD[%ld](%s)\n", (long) getpid(), - playback_name(base+j)); - } - krb5_db_fini(ccontext); - krb5_free_context(ccontext); - exit((kret) ? 1 : 0); - } - else - children[i] = child; - } - fd = open("./test.lock", O_CREAT|O_RDWR|O_EXCL, 0666); - close(fd); - sleep(1); - unlink("./test.lock"); - for (i=0; i] - Use as the number of passes. - * [-c] - Check contents. - * [-v] - Verbose output. - * [-d ] - Database name. - * [-s] - Save database even on successful completion. - * [-D] - Leave database dirty. - */ -int -main(argc, argv) - int argc; - char *argv[]; -{ - int option; - extern char *optarg; - - int do_time, do_random, num_passes, check_cont, verbose, error; - int save_db, dont_clean, do_ptest, hash; - char *db_name; - - programname = argv[0]; - if (strrchr(programname, (int) '/')) - programname = strrchr(programname, (int) '/') + 1; - SRAND((RAND_TYPE)time((void *) NULL)); - - /* Default values. */ - do_time = 0; - do_random = 0; - num_passes = T_KDB_N_PASSES; - check_cont = 0; - verbose = 0; - db_name = T_KDB_DEF_DB; - save_db = 0; - dont_clean = 0; - error = 0; - do_ptest = 0; - hash = 0; - - /* Parse argument list */ - while ((option = getopt(argc, argv, "cd:n:prstvDh")) != -1) { - switch (option) { - case 'c': - check_cont = 1; - break; - case 'd': - db_name = optarg; - break; - case 'n': - if (sscanf(optarg, "%d", &num_passes) != 1) { - fprintf(stderr, "%s: %s is not a valid number for %c option\n", - programname, optarg, option); - error++; - } - break; - case 'p': - do_ptest++; - break; - case 'r': - do_random = 1; - break; - case 's': - save_db = 1; - break; - case 't': - do_time = 1; - break; - case 'v': - verbose++; - break; - case 'D': - dont_clean = 1; - break; - case 'h': - hash = 1; - break; - default: - error++; - break; - } - } - if (error) - fprintf(stderr, "%s: usage is %s [-cprstv] [-d ] [-n ]\n", - programname, programname); - else - error = do_testing(db_name, - num_passes, - verbose, - do_time, - do_random, - check_cont, - save_db, - dont_clean, - do_ptest, - hash); - return(error); -} - - diff --git a/src/lib/kdb/t_krb5.conf b/src/lib/kdb/t_krb5.conf deleted file mode 100644 index 5882d9770..000000000 --- a/src/lib/kdb/t_krb5.conf +++ /dev/null @@ -1,29 +0,0 @@ -[libdefaults] - ticket_lifetime = 600 - default_realm = ATHENA.MIT.EDU - -[realms] - ATHENA.MIT.EDU = { - kdc = KERBEROS-2.MIT.EDU:88 - kdc = KERBEROS.MIT.EDU - kdc = KERBEROS-1.MIT.EDU - admin_server = KERBEROS.MIT.EDU - default_domain = MIT.EDU - v4_instance_convert = { - mit = mit.edu - lithium = lithium.lcs.mit.edu - } - } - CYGNUS.COM = { - kdc = KERBEROS-1.CYGNUS.COM - kdc = KERBEROS.CYGNUS.COM - admin_server = KERBEROS.MIT.EDU - } - -[domain_realm] - .mit.edu = ATHENA.MIT.EDU - mit.edu = ATHENA.MIT.EDU - .media.mit.edu = MEDIA-LAB.MIT.EDU - media.mit.edu = MEDIA-LAB.MIT.EDU - .ucsc.edu = CATS.UCSC.EDU - diff --git a/src/lib/kdb/verify_mky.c b/src/lib/kdb/verify_mky.c deleted file mode 100644 index 452dc45ba..000000000 --- a/src/lib/kdb/verify_mky.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * lib/kdb/verify_mky.c - * - * Copyright 1990,1991 by the Massachusetts Institute of Technology. - * All Rights Reserved. - * - * Export of this software from the United States of America may - * require a specific license from the United States Government. - * It is the responsibility of any person or organization contemplating - * export to obtain such a license before exporting. - * - * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and - * distribute this software and its documentation for any purpose and - * without fee is hereby granted, provided that the above copyright - * notice appear in all copies and that both that copyright notice and - * this permission notice appear in supporting documentation, and that - * the name of M.I.T. not be used in advertising or publicity pertaining - * to distribution of the software without specific, written prior - * permission. Furthermore if you modify this software you must label - * your software as modified software and not distribute it in such a - * fashion that it might be confused with the original M.I.T. software. - * M.I.T. makes no representations about the suitability of - * this software for any purpose. It is provided "as is" without express - * or implied warranty. - * - * - * krb5_db_verify_master_key(); - */ - -#include "k5-int.h" - -/* - * Verify that the master key in *mkey matches the database entry - * for mprinc. - */ - -krb5_error_code -krb5_db_verify_master_key(context, mprinc, mkey) - krb5_context context; - krb5_principal mprinc; - krb5_keyblock *mkey; -{ - krb5_error_code retval; - krb5_db_entry master_entry; - int nprinc; - krb5_boolean more; - krb5_keyblock tempkey; - - nprinc = 1; - if ((retval = krb5_db_get_principal(context, mprinc, - &master_entry, &nprinc, &more))) - return(retval); - - if (nprinc != 1) { - if (nprinc) - krb5_db_free_principal(context, &master_entry, nprinc); - return(KRB5_KDB_NOMASTERKEY); - } else if (more) { - krb5_db_free_principal(context, &master_entry, nprinc); - return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE); - } - - if ((retval = krb5_dbekd_decrypt_key_data(context, mkey, - &master_entry.key_data[0], - &tempkey, NULL))) { - krb5_db_free_principal(context, &master_entry, nprinc); - return retval; - } - - if (mkey->length != tempkey.length || - memcmp((char *)mkey->contents, - (char *)tempkey.contents,mkey->length)) { - retval = KRB5_KDB_BADMASTERKEY; - } - - memset((char *)tempkey.contents, 0, tempkey.length); - krb5_xfree(tempkey.contents); - krb5_db_free_principal(context, &master_entry, nprinc); - - return retval; -} diff --git a/src/lib/krb5.saber.source b/src/lib/krb5.saber.source deleted file mode 100644 index a4c374a33..000000000 --- a/src/lib/krb5.saber.source +++ /dev/null @@ -1,18 +0,0 @@ -setopt load_flags -I/usr/athena/include -I/u2/krb5/include -I/mit/krb5/src/include -DNARROW_PROTOTYPES -load /mit/krb5/src/lib/cryptoconf.c /mit/krb5/src/lib/syslog.c /mit/krb5/src/lib/strdup.c - -load /mit/krb5/src/lib/krb/addr_comp.c /mit/krb5/src/lib/krb/addr_order.c /mit/krb5/src/lib/krb/addr_srch.c /u2/krb5/lib/krb/bld_pr_ext.o /u2/krb5/lib/krb/bld_princ.o /mit/krb5/src/lib/krb/conv_princ.c /mit/krb5/src/lib/krb/copy_addrs.c /mit/krb5/src/lib/krb/copy_auth.c /mit/krb5/src/lib/krb/copy_athctr.c /mit/krb5/src/lib/krb/copy_checksum.c /mit/krb5/src/lib/krb/copy_creds.c /mit/krb5/src/lib/krb/copy_data.c /mit/krb5/src/lib/krb/copy_key.c /mit/krb5/src/lib/krb/copy_princ.c /mit/krb5/src/lib/krb/copy_tick.c /mit/krb5/src/lib/krb/cp_key_cnt.c /mit/krb5/src/lib/krb/decode_kdc.c /mit/krb5/src/lib/krb/decrypt_tk.c /mit/krb5/src/lib/krb/encode_kdc.c /mit/krb5/src/lib/krb/encrypt_tk.c /mit/krb5/src/lib/krb/free_rtree.c /mit/krb5/src/lib/krb/faddr_ordr.c /mit/krb5/src/lib/krb/gc_frm_kdc.c /mit/krb5/src/lib/krb/gc_via_tgt.c /mit/krb5/src/lib/krb/gc_2tgt.c /mit/krb5/src/lib/krb/gen_seqnum.c /mit/krb5/src/lib/krb/gen_subkey.c /mit/krb5/src/lib/krb/get_creds.c /mit/krb5/src/lib/krb/get_in_tkt.c /mit/krb5/src/lib/krb/in_tkt_pwd.c /mit/krb5/src/lib/krb/in_tkt_sky.c /mit/krb5/src/lib/krb/kdc_rep_dc.c /mit/krb5/src/lib/krb/krbconfig.c /mit/krb5/src/lib/krb/mk_error.c /mit/krb5/src/lib/krb/mk_priv.c /mit/krb5/src/lib/krb/mk_rep.c /mit/krb5/src/lib/krb/mk_req.c /mit/krb5/src/lib/krb/mk_req_ext.c /mit/krb5/src/lib/krb/mk_safe.c /mit/krb5/src/lib/krb/parse.c /mit/krb5/src/lib/krb/pr_to_salt.c /mit/krb5/src/lib/krb/princ_comp.c /mit/krb5/src/lib/krb/rd_error.c /mit/krb5/src/lib/krb/rd_priv.c /mit/krb5/src/lib/krb/rd_rep.c /mit/krb5/src/lib/krb/rd_req.c /mit/krb5/src/lib/krb/rd_req_sim.c /mit/krb5/src/lib/krb/rd_req_dec.c /mit/krb5/src/lib/krb/rd_safe.c /mit/krb5/src/lib/krb/recvauth.c /mit/krb5/src/lib/krb/sendauth.c /mit/krb5/src/lib/krb/send_tgs.c /mit/krb5/src/lib/krb/srv_rcache.c /mit/krb5/src/lib/krb/tgtname.c /mit/krb5/src/lib/krb/unparse.c /mit/krb5/src/lib/krb/walk_rtree.c - -load -DPEPSY_LINKABLE_FUNCS -I/usr/athena/include -I/u2/krb5/include -I/mit/krb5/src/include -DNARROW_PROTOTYPES /u2/krb5/src/lib/asn.1/KRB5_tables.c /mit/krb5/src/lib/asn.1/encode.c /mit/krb5/src/lib/asn.1/decode.c /mit/krb5/src/lib/asn.1/adat2kadat.c /mit/krb5/src/lib/asn.1/addr2kaddr.c /mit/krb5/src/lib/asn.1/adr2kadr.c /mit/krb5/src/lib/asn.1/aprp2kaprp.c /mit/krb5/src/lib/asn.1/aprq2kaprq.c /mit/krb5/src/lib/asn.1/arep2karep.c /mit/krb5/src/lib/asn.1/auth2kauth.c /mit/krb5/src/lib/asn.1/cvt_flags.c /mit/krb5/src/lib/asn.1/ck2kck.c /mit/krb5/src/lib/asn.1/edat2kedat.c /mit/krb5/src/lib/asn.1/ekrp2kekrp.c /mit/krb5/src/lib/asn.1/enck2kkey.c /mit/krb5/src/lib/asn.1/err2kerr.c /mit/krb5/src/lib/asn.1/etpt2ketpt.c /mit/krb5/src/lib/asn.1/g2unix.c /mit/krb5/src/lib/asn.1/kadat2adat.c /mit/krb5/src/lib/asn.1/kaddr2addr.c /mit/krb5/src/lib/asn.1/kadr2adr.c /mit/krb5/src/lib/asn.1/kaprp2aprp.c /mit/krb5/src/lib/asn.1/kaprq2aprq.c /mit/krb5/src/lib/asn.1/karep2arep.c /mit/krb5/src/lib/asn.1/kauth2auth.c /mit/krb5/src/lib/asn.1/kck2ck.c /mit/krb5/src/lib/asn.1/kdcr2kkdcr.c /mit/krb5/src/lib/asn.1/kdcr2ktgsr.c /mit/krb5/src/lib/asn.1/kedat2edat.c /mit/krb5/src/lib/asn.1/kekrp2ekrp.c /mit/krb5/src/lib/asn.1/kerr2err.c /mit/krb5/src/lib/asn.1/ketpt2etpt.c /mit/krb5/src/lib/asn.1/kkdcr2kdcr.c /mit/krb5/src/lib/asn.1/kkey2enck.c /mit/krb5/src/lib/asn.1/klsrq2lsrq.c /mit/krb5/src/lib/asn.1/kprep2prep.c /mit/krb5/src/lib/asn.1/kprin2prin.c /mit/krb5/src/lib/asn.1/kpriv2priv.c /mit/krb5/src/lib/asn.1/ksafe2safe.c /mit/krb5/src/lib/asn.1/ktran2tran.c /mit/krb5/src/lib/asn.1/ktgrq2tgrq.c /mit/krb5/src/lib/asn.1/ktgsr2kdcr.c /mit/krb5/src/lib/asn.1/ktkt2tkt.c /mit/krb5/src/lib/asn.1/lsrq2klsrq.c /mit/krb5/src/lib/asn.1/prep2kprep.c /mit/krb5/src/lib/asn.1/prin2kprin.c /mit/krb5/src/lib/asn.1/priv2kpriv.c /mit/krb5/src/lib/asn.1/qbuf2data.c /mit/krb5/src/lib/asn.1/safe2ksafe.c /mit/krb5/src/lib/asn.1/tran2ktran.c /mit/krb5/src/lib/asn.1/tgrq2ktgrq.c /mit/krb5/src/lib/asn.1/tkt2ktkt.c /mit/krb5/src/lib/asn.1/u2gen.c /mit/krb5/src/lib/asn.1/kasrp2kdcr.c /mit/krb5/src/lib/asn.1/kpwd2pwd.c /mit/krb5/src/lib/asn.1/kpwds2pwds.c /mit/krb5/src/lib/asn.1/pwd2kpwd.c /mit/krb5/src/lib/asn.1/pwds2kpwds.c - -load /mit/krb5/src/lib/free/f_addr.c /mit/krb5/src/lib/free/f_address.c /mit/krb5/src/lib/free/f_arep_enc.c /mit/krb5/src/lib/free/f_ap_rep.c /mit/krb5/src/lib/free/f_ap_req.c /mit/krb5/src/lib/free/f_authdata.c /mit/krb5/src/lib/free/f_authent.c /mit/krb5/src/lib/free/f_cksum.c /mit/krb5/src/lib/free/f_creds.c /mit/krb5/src/lib/free/f_cred_cnt.c /mit/krb5/src/lib/free/f_enc_kdc.c /mit/krb5/src/lib/free/f_enc_tkt.c /mit/krb5/src/lib/free/f_error.c /mit/krb5/src/lib/free/f_kdc_rep.c /mit/krb5/src/lib/free/f_kdc_req.c /mit/krb5/src/lib/free/f_keyblock.c /mit/krb5/src/lib/free/f_last_req.c /mit/krb5/src/lib/free/f_padata.c /mit/krb5/src/lib/free/f_princ.c /mit/krb5/src/lib/free/f_priv.c /mit/krb5/src/lib/free/f_priv_enc.c /mit/krb5/src/lib/free/f_safe.c /mit/krb5/src/lib/free/f_ticket.c /mit/krb5/src/lib/free/f_tickets.c /mit/krb5/src/lib/free/f_tgt_cred.c /mit/krb5/src/lib/free/f_tkt_auth.c - -load /mit/krb5/src/lib/keytab/ktadd.c /mit/krb5/src/lib/keytab/ktbase.c /mit/krb5/src/lib/keytab/ktdefault.c /mit/krb5/src/lib/keytab/ktfr_entry.c /mit/krb5/src/lib/keytab/ktremove.c /mit/krb5/src/lib/keytab/read_servi.c - -load /mit/krb5/src/lib/keytab/file/ktf_add.c /mit/krb5/src/lib/keytab/file/ktf_endget.c /mit/krb5/src/lib/keytab/file/ktf_next.c /mit/krb5/src/lib/keytab/file/ktf_resolv.c /mit/krb5/src/lib/keytab/file/ktf_wops.c /mit/krb5/src/lib/keytab/file/ktf_close.c /mit/krb5/src/lib/keytab/file/ktf_get_en.c /mit/krb5/src/lib/keytab/file/ktf_ops.c /mit/krb5/src/lib/keytab/file/ktf_ssget.c /mit/krb5/src/lib/keytab/file/ktf_wreslv.c /mit/krb5/src/lib/keytab/file/ktf_defops.c /mit/krb5/src/lib/keytab/file/ktf_get_na.c /mit/krb5/src/lib/keytab/file/ktf_remove.c /mit/krb5/src/lib/keytab/file/ktf_util.c - -load /mit/krb5/src/lib/ccache/ccbase.c /mit/krb5/src/lib/ccache/ccdefault.c /mit/krb5/src/lib/ccache/ccdefops.c - -load /mit/krb5/src/lib/ccache/file/fcc_close.c /mit/krb5/src/lib/ccache/file/fcc_destry.c /mit/krb5/src/lib/ccache/file/fcc_eseq.c /mit/krb5/src/lib/ccache/file/fcc_gennew.c /mit/krb5/src/lib/ccache/file/fcc_getnam.c /mit/krb5/src/lib/ccache/file/fcc_gprin.c /mit/krb5/src/lib/ccache/file/fcc_init.c /mit/krb5/src/lib/ccache/file/fcc_nseq.c /mit/krb5/src/lib/ccache/file/fcc_read.c /mit/krb5/src/lib/ccache/file/fcc_reslv.c /mit/krb5/src/lib/ccache/file/fcc_retrv.c /mit/krb5/src/lib/ccache/file/fcc_sseq.c /mit/krb5/src/lib/ccache/file/fcc_store.c /mit/krb5/src/lib/ccache/file/fcc_skip.c /mit/krb5/src/lib/ccache/file/fcc_ops.c /mit/krb5/src/lib/ccache/file/fcc_write.c /mit/krb5/src/lib/ccache/file/fcc_sflags.c /mit/krb5/src/lib/ccache/file/fcc_defops.c /mit/krb5/src/lib/ccache/file/fcc_errs.c /mit/krb5/src/lib/ccache/file/fcc_maybe.c - -load -I. -I/usr/athena/include -I/u2/krb5/include -I/mit/krb5/src/include -DNARROW_PROTOTYPES /mit/krb5/src/lib/rcache/rc_base.c /mit/krb5/src/lib/rcache/rc_dfl.c /mit/krb5/src/lib/rcache/rc_io.c /mit/krb5/src/lib/rcache/rcdef.c /mit/krb5/src/lib/rcache/rc_conv.c -- cgit