From 28ca91cd71ea64c62419e996c38031bdae01f908 Mon Sep 17 00:00:00 2001 From: Greg Hudson Date: Wed, 18 Jan 2017 11:40:49 -0500 Subject: [PATCH 1/2] Explicitly copy KDB vtable fields In preparation for bumping the kdb_vftabl minor version, use explicit field assignments when copying the module vtable to the internal copy, so that we can conditionalize assignments for minor versions greater than 0. ticket: 8538 --- src/lib/kdb/kdb5.c | 81 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 59 insertions(+), 22 deletions(-) diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index a3139a7dce..ee41272312 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -283,24 +283,63 @@ clean_n_exit: } static void -kdb_setup_opt_functions(db_library lib) -{ - if (lib->vftabl.fetch_master_key == NULL) - lib->vftabl.fetch_master_key = krb5_db_def_fetch_mkey; - if (lib->vftabl.fetch_master_key_list == NULL) - lib->vftabl.fetch_master_key_list = krb5_def_fetch_mkey_list; - if (lib->vftabl.store_master_key_list == NULL) - lib->vftabl.store_master_key_list = krb5_def_store_mkey_list; - if (lib->vftabl.dbe_search_enctype == NULL) - lib->vftabl.dbe_search_enctype = krb5_dbe_def_search_enctype; - if (lib->vftabl.change_pwd == NULL) - lib->vftabl.change_pwd = krb5_dbe_def_cpw; - if (lib->vftabl.decrypt_key_data == NULL) - lib->vftabl.decrypt_key_data = krb5_dbe_def_decrypt_key_data; - if (lib->vftabl.encrypt_key_data == NULL) - lib->vftabl.encrypt_key_data = krb5_dbe_def_encrypt_key_data; - if (lib->vftabl.rename_principal == NULL) - lib->vftabl.rename_principal = krb5_db_def_rename_principal; +copy_vtable(const kdb_vftabl *in, kdb_vftabl *out) +{ + /* Copy fields for minor version 0. */ + out->maj_ver = in->maj_ver; + out->min_ver = in->min_ver; + out->init_library = in->init_library; + out->fini_library = in->fini_library; + out->init_module = in->init_module; + out->fini_module = in->fini_module; + out->create = in->create; + out->destroy = in->destroy; + out->get_age = in->get_age; + out->lock = in->lock; + out->unlock = in->unlock; + out->get_principal = in->get_principal; + out->put_principal = in->put_principal; + out->delete_principal = in->delete_principal; + out->rename_principal = in->rename_principal; + out->iterate = in->iterate; + out->create_policy = in->create_policy; + out->get_policy = in->get_policy; + out->put_policy = in->put_policy; + out->iter_policy = in->iter_policy; + out->delete_policy = in->delete_policy; + out->fetch_master_key = in->fetch_master_key; + out->fetch_master_key_list = in->fetch_master_key_list; + out->store_master_key_list = in->store_master_key_list; + out->dbe_search_enctype = in->dbe_search_enctype; + out->change_pwd = in->change_pwd; + out->promote_db = in->promote_db; + out->decrypt_key_data = in->decrypt_key_data; + out->encrypt_key_data = in->encrypt_key_data; + out->sign_authdata = in->sign_authdata; + out->check_transited_realms = in->check_transited_realms; + out->check_policy_as = in->check_policy_as; + out->check_policy_tgs = in->check_policy_tgs; + out->audit_as_req = in->audit_as_req; + out->refresh_config = in->refresh_config; + out->check_allowed_to_delegate = in->check_allowed_to_delegate; + + /* Set defaults for optional fields. */ + if (out->fetch_master_key == NULL) + out->fetch_master_key = krb5_db_def_fetch_mkey; + if (out->fetch_master_key_list == NULL) + out->fetch_master_key_list = krb5_def_fetch_mkey_list; + if (out->store_master_key_list == NULL) + out->store_master_key_list = krb5_def_store_mkey_list; + if (out->dbe_search_enctype == NULL) + out->dbe_search_enctype = krb5_dbe_def_search_enctype; + if (out->change_pwd == NULL) + out->change_pwd = krb5_dbe_def_cpw; + if (out->decrypt_key_data == NULL) + out->decrypt_key_data = krb5_dbe_def_decrypt_key_data; + if (out->encrypt_key_data == NULL) + out->encrypt_key_data = krb5_dbe_def_encrypt_key_data; + if (out->rename_principal == NULL) + out->rename_principal = krb5_db_def_rename_principal; } #ifdef STATIC_PLUGINS @@ -334,8 +373,7 @@ kdb_load_library(krb5_context kcontext, char *lib_name, db_library *libptr) return ENOMEM; strlcpy(lib->name, lib_name, sizeof(lib->name)); - memcpy(&lib->vftabl, vftabl_addr, sizeof(kdb_vftabl)); - kdb_setup_opt_functions(lib); + copy_vtable(vftabl_addr, &lib->vftabl); status = lib->vftabl.init_library(); if (status) @@ -433,8 +471,7 @@ kdb_load_library(krb5_context kcontext, char *lib_name, db_library *lib) goto clean_n_exit; } - memcpy(&(*lib)->vftabl, vftabl_addrs[0], sizeof(kdb_vftabl)); - kdb_setup_opt_functions(*lib); + copy_vtable(vftabl_addrs[0], &(*lib)->vftabl); if ((status = (*lib)->vftabl.init_library())) goto clean_n_exit; -- 2.11.0 From 82a163b99f1f6228f98b433892444372b18ecdb3 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 18 Jan 2017 11:52:48 +0100 Subject: [PATCH 2/2] Add free_principal_e_data KDB method Add an optional method to kdb_vftabl to free e_data pointer in a principal entry, in case it was populated by a module using a more complex structure than a single memory region. [ghudson@mit.edu: handled minor version bump; simplified code; rewrote commit message] ticket: 8538 target_version: 1.15-next tags: pullup --- src/include/kdb.h | 11 +++++++++++ src/lib/kdb/kdb5.c | 14 +++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/include/kdb.h b/src/include/kdb.h index e9d1a84ba1..da04724fce 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -1382,6 +1382,17 @@ typedef struct _kdb_vftabl { krb5_const_principal client, const krb5_db_entry *server, krb5_const_principal proxy); + + /* End of minor version 0. */ + + /* + * Optional: Free the e_data pointer of a database entry. If this method + * is not implemented, the e_data pointer in principal entries will be + * freed with free() as seen by libkdb5. + */ + void (*free_principal_e_data)(krb5_context kcontext, krb5_octet *e_data); + + /* End of minor version 1 for major version 6. */ } kdb_vftabl; #endif /* !defined(_WIN32) */ diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index ee41272312..4adf0fcbb2 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -323,6 +323,12 @@ copy_vtable(const kdb_vftabl *in, kdb_vftabl *out) out->refresh_config = in->refresh_config; out->check_allowed_to_delegate = in->check_allowed_to_delegate; + /* Copy fields for minor version 1 (major version 6). */ + assert(KRB5_KDB_DAL_MAJOR_VERSION == 6); + out->free_principal_e_data = NULL; + if (in->min_ver >= 1) + out->free_principal_e_data = in->free_principal_e_data; + /* Set defaults for optional fields. */ if (out->fetch_master_key == NULL) out->fetch_master_key = krb5_db_def_fetch_mkey; @@ -820,11 +826,17 @@ free_tl_data(krb5_tl_data *list) void krb5_db_free_principal(krb5_context kcontext, krb5_db_entry *entry) { + kdb_vftabl *v; int i; if (entry == NULL) return; - free(entry->e_data); + if (entry->e_data != NULL) { + if (get_vftabl(kcontext, &v) == 0 && v->free_principal_e_data != NULL) + v->free_principal_e_data(kcontext, entry->e_data); + else + free(entry->e_data); + } krb5_free_principal(kcontext, entry->princ); free_tl_data(entry->tl_data); for (i = 0; i < entry->n_key_data; i++) -- 2.11.0