]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Use library malloc for principal, policy entries
authorGreg Hudson <ghudson@mit.edu>
Tue, 17 May 2016 02:54:06 +0000 (22:54 -0400)
committerGreg Hudson <ghudson@mit.edu>
Thu, 26 May 2016 15:20:05 +0000 (11:20 -0400)
Alter the KDB module contract to require that KDB modules use an
allocator compatible with the malloc() seen by libkrb5 and libkdb5.
Change krb5_db_alloc() and krb5_db_free() to provide access to this
allocator.  Remove free_principal, free_policy, alloc, and free from
the KDB interface and from all in-tree KDB modules.

ticket: 8414 (new)

16 files changed:
src/include/kdb.h
src/lib/kdb/kdb5.c
src/plugins/kdb/db2/db2_exp.c
src/plugins/kdb/db2/kdb_db2.c
src/plugins/kdb/db2/kdb_db2.h
src/plugins/kdb/db2/kdb_xdr.c
src/plugins/kdb/db2/lockout.c
src/plugins/kdb/ldap/ldap_exp.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h
src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.c
src/plugins/kdb/ldap/libkdb_ldap/ldap_pwd_policy.h
src/plugins/kdb/ldap/libkdb_ldap/libkdb_ldap.exports
src/plugins/kdb/ldap/libkdb_ldap/lockout.c
src/plugins/kdb/test/kdb_test.c

index a2ac3d32f1822977fa66c4522be930abe0ba3004..df02ec6d3ce9177720339ede88c6e720442c1cec 100644 (file)
@@ -548,10 +548,18 @@ krb5_dbe_update_mod_princ_data( krb5_context          context,
                                 krb5_timestamp        mod_date,
                                 krb5_const_principal  mod_princ);
 
+/*
+ * These are wrappers around realloc() and free().  Applications and KDB
+ * modules can use them when manipulating principal and policy entries to
+ * ensure that they allocate and free memory in a manner compatible with the
+ * library.  Using libkrb5 or libkbd5 functions to construct values (such as
+ * krb5_copy_principal() to construct the princ field of a krb5_db_entry) is
+ * also safe.  On Unix platforms, just using malloc() and free() is safe as
+ * long as the application or module does not use a malloc replacement.
+ */
 void *krb5_db_alloc( krb5_context kcontext,
                      void *ptr,
                      size_t size );
-
 void krb5_db_free( krb5_context kcontext,
                    void *ptr);
 
@@ -868,6 +876,11 @@ krb5_dbe_free_string(krb5_context, char *);
  * The documentation in these comments describes the DAL as it is currently
  * implemented and used, not as it should be.  So if anything seems off, that
  * probably means the current state of things is off.
+ *
+ * Modules must allocate memory for principal entries, policy entries, and
+ * other structures using an allocator compatible with malloc() as seen by
+ * libkdb5 and libkrb5.  Modules may link against libkdb5 and call
+ * krb5_db_alloc() to be certain that the same malloc implementation is used.
  */
 
 typedef struct _kdb_vftabl {
@@ -1014,14 +1027,6 @@ typedef struct _kdb_vftabl {
                                      unsigned int flags,
                                      krb5_db_entry **entry);
 
-    /*
-     * Mandatory: Free a database entry.  The entry may have been constructed
-     * by the caller (using the db_alloc function to allocate associated
-     * memory); thus, a plugin must allocate each field of a principal entry
-     * separately.
-     */
-    void (*free_principal)(krb5_context kcontext, krb5_db_entry *entry);
-
     /*
      * Optional: Create or modify a principal entry.  db_args communicates
      * command-line arguments for module-specific flags.
@@ -1104,23 +1109,6 @@ typedef struct _kdb_vftabl {
      */
     krb5_error_code (*delete_policy)(krb5_context kcontext, char *policy);
 
-    /* Optional: Free a policy entry returned by db_get_policy. */
-    void (*free_policy)(krb5_context kcontext, osa_policy_ent_t val);
-
-    /*
-     * Mandatory: Has the semantics of realloc(ptr, size).  Callers use this to
-     * allocate memory for new or changed principal entries, so the module
-     * should expect to potentially see this memory in db_free_principal.
-     */
-    void *(*alloc)(krb5_context kcontext, void *ptr, size_t size);
-
-    /*
-     * Mandatory: Has the semantics of free(ptr).  Callers use this to free
-     * fields from a principal entry (such as key data) before changing it in
-     * place, and in some cases to free data they allocated with db_alloc.
-     */
-    void (*free)(krb5_context kcontext, void *ptr);
-
     /*
      * Optional with default: Retrieve a master keyblock from the stash file
      * db_args, filling in *key and *kvno.  mname is the name of the master
index 168a25daaf55a1a70fc067be7a9a86453dd0f74c..20e86987db624863d6f15ed9d1b324f7d0e289e7 100644 (file)
@@ -766,16 +766,32 @@ krb5_db_get_principal(krb5_context kcontext, krb5_const_principal search_for,
     return 0;
 }
 
+static void
+free_tl_data(krb5_tl_data *list)
+{
+    krb5_tl_data *next;
+
+    for (; list != NULL; list = next) {
+        next = list->tl_data_next;
+        free(list->tl_data_contents);
+        free(list);
+    }
+}
+
 void
 krb5_db_free_principal(krb5_context kcontext, krb5_db_entry *entry)
 {
-    krb5_error_code status = 0;
-    kdb_vftabl *v;
+    int i;
 
-    status = get_vftabl(kcontext, &v);
-    if (status)
+    if (entry == NULL)
         return;
-    v->free_principal(kcontext, entry);
+    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++)
+        krb5_dbe_free_key_data_contents(kcontext, &entry->key_data[i]);
+    free(entry->key_data);
+    free(entry);
 }
 
 static void
@@ -1332,25 +1348,13 @@ krb5_dbe_find_mkey(krb5_context context, krb5_db_entry *entry,
 void   *
 krb5_db_alloc(krb5_context kcontext, void *ptr, size_t size)
 {
-    krb5_error_code status;
-    kdb_vftabl *v;
-
-    status = get_vftabl(kcontext, &v);
-    if (status)
-        return NULL;
-    return v->alloc(kcontext, ptr, size);
+    return realloc(ptr, size);
 }
 
 void
 krb5_db_free(krb5_context kcontext, void *ptr)
 {
-    krb5_error_code status;
-    kdb_vftabl *v;
-
-    status = get_vftabl(kcontext, &v);
-    if (status)
-        return;
-    v->free(kcontext, ptr);
+    free(ptr);
 }
 
 /* has to be modified */
@@ -2441,13 +2445,12 @@ krb5_db_delete_policy(krb5_context kcontext, char *policy)
 void
 krb5_db_free_policy(krb5_context kcontext, osa_policy_ent_t policy)
 {
-    krb5_error_code status = 0;
-    kdb_vftabl *v;
-
-    status = get_vftabl(kcontext, &v);
-    if (status || v->free_policy == NULL)
+    if (policy == NULL)
         return;
-    v->free_policy(kcontext, policy);
+    free(policy->name);
+    free(policy->allowed_keysalts);
+    free_tl_data(policy->tl_data);
+    free(policy);
 }
 
 krb5_error_code
index a666123059630faed1d32b7149dd6c0a0096ff74..1a41481f9faed7121333b53250cc789ff6ae5e4c 100644 (file)
@@ -117,10 +117,6 @@ WRAP_K (krb5_db2_get_principal,
          unsigned int f,
          krb5_db_entry **d),
         (ctx, p, f, d));
-WRAP_VOID (krb5_db2_free_principal,
-           (krb5_context ctx,
-            krb5_db_entry *d),
-           (ctx, d));
 WRAP_K (krb5_db2_put_principal,
         (krb5_context ctx,
          krb5_db_entry *d,
@@ -158,9 +154,6 @@ WRAP_K (krb5_db2_iter_policy,
 WRAP_K (krb5_db2_delete_policy,
         ( krb5_context kcontext, char *policy ),
         (kcontext, policy));
-WRAP_VOID (krb5_db2_free_policy,
-           ( krb5_context kcontext, osa_policy_ent_t entry ),
-           (kcontext, entry));
 
 WRAP_K (krb5_db2_promote_db,
         ( krb5_context kcontext, char *conf_section, char **db_args ),
@@ -215,7 +208,6 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_db2, kdb_function_table) = {
     /* lock */                          wrap_krb5_db2_lock,
     /* unlock */                        wrap_krb5_db2_unlock,
     /* get_principal */                 wrap_krb5_db2_get_principal,
-    /* free_principal */                wrap_krb5_db2_free_principal,
     /* put_principal */                 wrap_krb5_db2_put_principal,
     /* delete_principal */              wrap_krb5_db2_delete_principal,
     /* rename_principal */              NULL,
@@ -225,9 +217,6 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_db2, kdb_function_table) = {
     /* put_policy */                    wrap_krb5_db2_put_policy,
     /* iter_policy */                   wrap_krb5_db2_iter_policy,
     /* delete_policy */                 wrap_krb5_db2_delete_policy,
-    /* free_policy */                   wrap_krb5_db2_free_policy,
-    /* alloc */                         krb5_db2_alloc,
-    /* free */                          krb5_db2_free,
     /* blah blah blah */ 0,0,0,0,0,
     /* promote_db */                    wrap_krb5_db2_promote_db,
     0, 0, 0, 0,
index 09d96d52415e2666d890a245d95fe4d573801bf5..84dadc326333972c69e08335c8c6eea5dc245219 100644 (file)
@@ -802,13 +802,6 @@ cleanup:
     return retval;
 }
 
-/* Free an entry returned by krb5_db2_get_principal. */
-void
-krb5_db2_free_principal(krb5_context context, krb5_db_entry *entry)
-{
-    krb5_dbe_free(context, entry);
-}
-
 krb5_error_code
 krb5_db2_put_principal(krb5_context context, krb5_db_entry *entry,
                        char **db_args)
@@ -912,7 +905,7 @@ krb5_db2_delete_principal(krb5_context context, krb5_const_principal searchfor)
     }
 
     retval = krb5_encode_princ_entry(context, &contdata, entry);
-    krb5_dbe_free(context, entry);
+    krb5_db_free_principal(context, entry);
     if (retval)
         goto cleankey;
 
@@ -1074,7 +1067,7 @@ curs_run_cb(iter_curs *curs, ctx_iterate_cb func, krb5_pointer func_arg)
 
     k5_mutex_unlock(krb5_db2_mutex);
     retval = (*func)(func_arg, entry);
-    krb5_dbe_free(ctx, entry);
+    krb5_db_free_principal(ctx, entry);
     k5_mutex_lock(krb5_db2_mutex);
     if (dbc->unlockiter) {
         lockerr = curs_lock(curs);
@@ -1256,18 +1249,6 @@ cleanup:
     return status;
 }
 
-void   *
-krb5_db2_alloc(krb5_context context, void *ptr, size_t size)
-{
-    return realloc(ptr, size);
-}
-
-void
-krb5_db2_free(krb5_context context, void *ptr)
-{
-    free(ptr);
-}
-
 /* policy functions */
 krb5_error_code
 krb5_db2_create_policy(krb5_context context, osa_policy_ent_t policy)
index 2db74ceb76aad3628e293c8a8328feb303272fea..b1b50c8286d6d19f4398ff4a28252c4f2b8d1eb7 100644 (file)
@@ -55,7 +55,6 @@ krb5_error_code krb5_db2_fini(krb5_context);
 krb5_error_code krb5_db2_get_age(krb5_context, char *, time_t *);
 krb5_error_code krb5_db2_get_principal(krb5_context, krb5_const_principal,
                                        unsigned int, krb5_db_entry **);
-void krb5_db2_free_principal(krb5_context, krb5_db_entry *);
 krb5_error_code krb5_db2_put_principal(krb5_context, krb5_db_entry *,
                                        char **db_args);
 krb5_error_code krb5_db2_iterate(krb5_context, char *,
@@ -93,8 +92,6 @@ 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 */
@@ -113,7 +110,6 @@ krb5_error_code krb5_db2_iter_policy(krb5_context kcontext, char *match_entry,
 
 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);
 
 /* Thread-safety wrapper slapped on top of original implementation.  */
 extern k5_mutex_t *krb5_db2_mutex;
index b587f8e97a1b4c020dd30c02653d86dc21fc2f1e..c9f5f047dafea8d95102d2c9a38f8ad6cdfdb97b 100644 (file)
@@ -427,39 +427,6 @@ krb5_decode_princ_entry(krb5_context context, krb5_data *content,
     return 0;
 
 error_out:
-    krb5_dbe_free(context, entry);
+    krb5_db_free_principal(context, entry);
     return retval;
 }
-
-void
-krb5_dbe_free(krb5_context context, krb5_db_entry *entry)
-{
-    krb5_tl_data        * tl_data_next;
-    krb5_tl_data        * tl_data;
-    int i, j;
-
-    if (entry == NULL)
-        return;
-    free(entry->e_data);
-    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;
-        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]) {
-                    zapfree(entry->key_data[i].key_data_contents[j],
-                            entry->key_data[i].key_data_length[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);
-    }
-    free(entry);
-}
index ba542128b07dd618939adf03fb5d511cc0395eb4..7d151b55b35a89fab019ca0bde37ca2eb3fcb101 100644 (file)
@@ -75,7 +75,7 @@ lookup_lockout_policy(krb5_context context,
             *pw_max_fail = policy->pw_max_fail;
             *pw_failcnt_interval = policy->pw_failcnt_interval;
             *pw_lockout_duration = policy->pw_lockout_duration;
-            krb5_db2_free_policy(context, policy);
+            krb5_db_free_policy(context, policy);
         }
     }
 
index d524941ef26020e481a49b8db312f5f7b946ca1c..1d7cd14cad0cd68e166ab035ebe68e67246b653f 100644 (file)
@@ -58,7 +58,6 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_ldap, kdb_function_table) = {
     /* lock */                              krb5_ldap_lock,
     /* unlock */                            krb5_ldap_unlock,
     /* get_principal */                     krb5_ldap_get_principal,
-    /* free_principal */                    krb5_ldap_free_principal,
     /* put_principal */                     krb5_ldap_put_principal,
     /* delete_principal */                  krb5_ldap_delete_principal,
     /* rename_principal */                  krb5_ldap_rename_principal,
@@ -68,9 +67,6 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_ldap, kdb_function_table) = {
     /* put_policy */                        krb5_ldap_put_password_policy,
     /* iter_policy */                       krb5_ldap_iterate_password_policy,
     /* delete_policy */                     krb5_ldap_delete_password_policy,
-    /* free_policy */                       krb5_ldap_free_password_policy,
-    /* alloc */                             krb5_ldap_alloc,
-    /* free */                              krb5_ldap_free,
     /* optional functions */
     /* fetch_master_key */                  NULL /* krb5_ldap_fetch_mkey */,
     /* fetch_master_key_list */             NULL,
index 56839ffbdbee696e491d1bdd82fb56331f8088c6..00c2c884676f0438d6acce5d3bc7251b138d2106 100644 (file)
@@ -128,15 +128,6 @@ krb5_dbe_free_contents(krb5_context context, krb5_db_entry *entry)
 }
 
 
-void
-krb5_ldap_free_principal(krb5_context kcontext, krb5_db_entry *entry)
-{
-    if (entry == NULL)
-        return;
-    krb5_dbe_free_contents(kcontext, entry);
-    free(entry);
-}
-
 krb5_error_code
 krb5_ldap_iterate(krb5_context context, char *match_expr,
                   krb5_error_code (*func)(krb5_pointer, krb5_db_entry *),
@@ -345,7 +336,7 @@ cleanup:
     if (DN)
         free (DN);
 
-    krb5_ldap_free_principal(context, entry);
+    krb5_db_free_principal(context, entry);
 
     ldap_mods_free(mods, 1);
     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
@@ -563,7 +554,7 @@ cleanup:
     free(dn);
     free(suser);
     free(tuser);
-    krb5_ldap_free_principal(context, entry);
+    krb5_db_free_principal(context, entry);
     ldap_mods_free(mods, 1);
     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
     return st;
index 752f54f2838d8a17d01438f908dcc25897d01e1c..a3f3c3cf6e0b41f36fc6b7b1adaed4d7860c4414 100644 (file)
@@ -108,8 +108,6 @@ krb5_ldap_delete_principal(krb5_context, krb5_const_principal);
 krb5_error_code
 krb5_ldap_rename_principal(krb5_context context, krb5_const_principal source,
                            krb5_const_principal target);
-void
-krb5_ldap_free_principal(krb5_context, krb5_db_entry *);
 
 krb5_error_code
 krb5_ldap_iterate(krb5_context, char *,
index 74bc361515186f70de4fb3f9548ba2874c1db342..7deafb1b8e004d98a396e77d5087a8de0d4d75ba 100644 (file)
@@ -224,7 +224,7 @@ krb5_ldap_get_principal(krb5_context context, krb5_const_principal searchfor,
 
 cleanup:
     ldap_msgfree(result);
-    krb5_ldap_free_principal(context, entry);
+    krb5_db_free_principal(context, entry);
 
     if (filter)
         free (filter);
index 6779f51c7bf93249a47a30f95d4e32a4b05444b0..838583a1f966950a526bde7b6cb8f82bc6fd129f 100644 (file)
@@ -324,7 +324,7 @@ cleanup:
     ldap_msgfree(result);
     if (st != 0) {
         if (*policy != NULL) {
-            krb5_ldap_free_password_policy(context, *policy);
+            krb5_db_free_policy(context, *policy);
             *policy = NULL;
         }
     }
@@ -453,7 +453,7 @@ krb5_ldap_iterate_password_policy(krb5_context context, char *match_expr,
             goto cleanup;
 
         (*func)(func_arg, entry);
-        krb5_ldap_free_password_policy(context, entry);
+        krb5_db_free_policy(context, entry);
         entry = NULL;
 
         free(policy);
@@ -467,16 +467,3 @@ cleanup:
     krb5_ldap_put_handle_to_pool(ldap_context, ldap_server_handle);
     return st;
 }
-
-void
-krb5_ldap_free_password_policy (context, entry)
-    krb5_context                context;
-    osa_policy_ent_t            entry;
-{
-    if (entry) {
-        free(entry->name);
-        free(entry->allowed_keysalts);
-        free(entry);
-    }
-    return;
-}
index 39e46cc30763727a6a4958ce0f7bb3d786c3be21..81c565963cb90a65258fc38174a5faf325ca95a5 100644 (file)
@@ -48,7 +48,4 @@ krb5_ldap_iterate_password_policy(krb5_context, char *,
                                   void (*)(krb5_pointer, osa_policy_ent_t),
                                   krb5_pointer);
 
-void
-krb5_ldap_free_password_policy(krb5_context kcontext, osa_policy_ent_t entry);
-
 #endif
index 9d1db88ef3c593b1a2676d0fb10736b2db45a07a..2342f1db8fff3542cbb713d1d2a97d4bcb451ecf 100644 (file)
@@ -10,7 +10,6 @@ krb5_ldap_put_principal
 krb5_ldap_get_principal
 krb5_ldap_delete_principal
 krb5_ldap_rename_principal
-krb5_ldap_free_principal
 krb5_ldap_iterate
 krb5_ldap_read_krbcontainer_dn
 krb5_ldap_list_realm
@@ -30,13 +29,10 @@ krb5_ldap_create_password_policy
 krb5_ldap_put_password_policy
 krb5_ldap_get_password_policy
 krb5_ldap_delete_password_policy
-krb5_ldap_free_password_policy
 krb5_ldap_iterate_password_policy
 krb5_dbe_free_contents
 krb5_ldap_free_server_params
 krb5_ldap_free_server_context_params
-krb5_ldap_alloc
-krb5_ldap_free
 krb5_ldap_delete_realm_1
 krb5_ldap_lock
 krb5_ldap_unlock
index 5a225d4a9be4377b07cdb6eb5362f52cc9f9414c..0fc56c2fe7bdf91ad0610c0ef49f49da7c9b3311 100644 (file)
@@ -71,7 +71,7 @@ lookup_lockout_policy(krb5_context context,
             *pw_failcnt_interval = policy->pw_failcnt_interval;
             *pw_lockout_duration = policy->pw_lockout_duration;
         }
-        krb5_ldap_free_password_policy(context, policy);
+        krb5_db_free_policy(context, policy);
     }
 
     xdrmem_create(&xdrs, NULL, 0, XDR_FREE);
index d8c2c541ea95549d6f4eb233280e92b958f2f0fd..01f17b6edb2d4f9d29f0e5cb8fd26cf9269e5609 100644 (file)
@@ -393,48 +393,6 @@ cleanup:
     return ret;
 }
 
-static void
-test_free_principal(krb5_context context, krb5_db_entry *entry)
-{
-    krb5_tl_data *tl, *next;
-    int i, j;
-
-    if (entry == NULL)
-        return;
-    free(entry->e_data);
-    krb5_free_principal(context, entry->princ);
-    for (tl = entry->tl_data; tl != NULL; tl = next) {
-        next = tl->tl_data_next;
-        free(tl->tl_data_contents);
-        free(tl);
-    }
-    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]) {
-                zapfree(entry->key_data[i].key_data_contents[j],
-                        entry->key_data[i].key_data_length[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);
-    free(entry);
-}
-
-static void *
-test_alloc(krb5_context context, void *ptr, size_t size)
-{
-    return realloc(ptr, size);
-}
-
-static void
-test_free(krb5_context context, void *ptr)
-{
-    free(ptr);
-}
-
 static krb5_error_code
 test_fetch_master_key(krb5_context context, krb5_principal mname,
                       krb5_keyblock *key_out, krb5_kvno *kvno_out,
@@ -556,7 +514,6 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = {
     NULL, /* lock */
     NULL, /* unlock */
     test_get_principal,
-    test_free_principal,
     NULL, /* put_principal */
     NULL, /* delete_principal */
     NULL, /* rename_principal */
@@ -566,9 +523,6 @@ kdb_vftabl PLUGIN_SYMBOL_NAME(krb5_test, kdb_function_table) = {
     NULL, /* put_policy */
     NULL, /* iter_policy */
     NULL, /* delete_policy */
-    NULL, /* free_policy */
-    test_alloc,
-    test_free,
     test_fetch_master_key,
     test_fetch_master_key_list,
     NULL, /* store_master_key_list */