krb5 commit: Allow KDB module stacking

ghudson at mit.edu ghudson at mit.edu
Wed Dec 11 22:05:02 EST 2024


https://github.com/krb5/krb5/commit/39d859c754d42cad23753acb98ff92d956c092e4
commit 39d859c754d42cad23753acb98ff92d956c092e4
Author: Andreas Schneider <asn at samba.org>
Date:   Fri Nov 29 11:04:00 2024 +0100

    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 at 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 745b24f35..d2252d505 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 943a850d4..a0897f5e8 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 97dc5c0d3..574bab92f 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


More information about the cvs-krb5 mailing list