From 39d859c754d42cad23753acb98ff92d956c092e4 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Fri, 29 Nov 2024 11:04:00 +0100 Subject: [PATCH] Allow KDB module stacking Add an API krb5_db_load_module() to cause the KDB handle for a context to use a specified KDB module instead of the configured one. [ghudson@mit.edu: Renamed new API; added comment; wrote commit message. Also contains work by Alexander Bokovoy.] ticket: 9156 (new) --- src/include/kdb.h | 12 ++++++- src/lib/kdb/kdb5.c | 65 +++++++++++++++++++++---------------- src/lib/kdb/libkdb5.exports | 1 + 3 files changed, 49 insertions(+), 29 deletions(-) diff --git a/src/include/kdb.h b/src/include/kdb.h index 745b24f351..d2252d505b 100644 --- a/src/include/kdb.h +++ b/src/include/kdb.h @@ -353,7 +353,17 @@ extern char *krb5_mkey_pwd_prompt2; #define KRB5_DB_LOCKMODE_EXCLUSIVE 0x0002 #define KRB5_DB_LOCKMODE_PERMANENT 0x0008 -/* libkdb.spec */ +/* + * Load the specified KDB module, to be used for KDB operations with kcontext. + * This function must be called prior to any KDB operations with kcontext. + * name will be looked up relative to the configured database directories, with + * platform-specific suffixes suitable for shared objects. This function can + * be used to implement one KDB module in terms of another, but the outer + * module must supply a separate krb5_context from the one passed to its + * methods. + */ +krb5_error_code krb5_db_load_module(krb5_context kcontext, const char *name); + krb5_error_code krb5_db_setup_lib_handle(krb5_context kcontext); krb5_error_code krb5_db_open( krb5_context kcontext, char **db_args, int mode ); krb5_error_code krb5_db_init ( krb5_context kcontext ); diff --git a/src/lib/kdb/kdb5.c b/src/lib/kdb/kdb5.c index 943a850d46..a0897f5e88 100644 --- a/src/lib/kdb/kdb5.c +++ b/src/lib/kdb/kdb5.c @@ -353,7 +353,7 @@ extern kdb_vftabl krb5_ldap_kdb_function_table; #endif static krb5_error_code -kdb_load_library(krb5_context kcontext, char *lib_name, db_library *libptr) +load_library(krb5_context kcontext, const char *lib_name, db_library *libptr) { krb5_error_code status; db_library lib; @@ -396,7 +396,7 @@ static char *db_dl_location[] = DEFAULT_KDB_LIB_PATH; #define db_dl_n_locations (sizeof(db_dl_location) / sizeof(db_dl_location[0])) static krb5_error_code -kdb_load_library(krb5_context kcontext, char *lib_name, db_library *lib) +load_library(krb5_context kcontext, const char *lib_name, db_library *lib) { krb5_error_code status = 0; int ndx; @@ -496,7 +496,7 @@ clean_n_exit: #endif /* end of _KDB5_STATIC_LINK */ static krb5_error_code -kdb_find_library(krb5_context kcontext, char *lib_name, db_library *lib) +find_library(krb5_context kcontext, const 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; @@ -524,7 +524,7 @@ kdb_find_library(krb5_context kcontext, char *lib_name, db_library *lib) } /* module not found. create and add to list */ - status = kdb_load_library(kcontext, lib_name, lib); + status = load_library(kcontext, lib_name, lib); if (status) goto clean_n_exit; @@ -585,43 +585,52 @@ clean_n_exit: } krb5_error_code -krb5_db_setup_lib_handle(krb5_context kcontext) +krb5_db_load_module(krb5_context kcontext, const char *name) { - char *library = NULL; - krb5_error_code status = 0; + krb5_error_code ret; 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; - } + if (name == NULL) + return EINVAL; + if (kcontext->dal_handle != NULL) + return EEXIST; - status = kdb_get_library_name(kcontext, &library); - if (library == NULL) { - k5_prependmsg(kcontext, status, - _("Cannot initialize database library")); - goto clean_n_exit; - } + dal_handle = k5alloc(sizeof(*dal_handle), &ret); + if (dal_handle == NULL) + goto cleanup; - status = kdb_find_library(kcontext, library, &lib); - if (status) - goto clean_n_exit; + ret = find_library(kcontext, name, &lib); + if (ret) + goto cleanup; dal_handle->lib_handle = lib; kcontext->dal_handle = dal_handle; + lib = NULL; + dal_handle = NULL; -clean_n_exit: - free(library); +cleanup: + free(dal_handle); + if (lib != NULL) + kdb_free_library(lib); + return ret; +} - if (status) { - free(dal_handle); - if (lib) - kdb_free_library(lib); +krb5_error_code +krb5_db_setup_lib_handle(krb5_context kcontext) +{ + char *library = NULL; + krb5_error_code ret; + + ret = kdb_get_library_name(kcontext, &library); + if (library == NULL) { + k5_prependmsg(kcontext, ret, _("Cannot initialize database library")); + return ret; } - return status; + ret = krb5_db_load_module(kcontext, library); + free(library); + return ret; } static krb5_error_code diff --git a/src/lib/kdb/libkdb5.exports b/src/lib/kdb/libkdb5.exports index 97dc5c0d3e..574bab92f6 100644 --- a/src/lib/kdb/libkdb5.exports +++ b/src/lib/kdb/libkdb5.exports @@ -1,3 +1,4 @@ +krb5_db_load_module krb5_db_setup_lib_handle krb5_db_open krb5_db_inited -- 2.47.2