Convert preauth_plugin.h to new plugin framework
authorGreg Hudson <ghudson@mit.edu>
Fri, 17 Jun 2011 13:44:33 +0000 (13:44 +0000)
committerGreg Hudson <ghudson@mit.edu>
Fri, 17 Jun 2011 13:44:33 +0000 (13:44 +0000)
The preauth plugin interface was introduced in 1.6 but was never made
a public API.  In preparation for making it public in 1.10, convert it
to use the new plugin framework.  This will require changes to any
existing preauth plugins.

A number of symbols were renamed for namespace cleanliness, and
abstract types were introduced for module data and module per-request
data for better type safety.

On the consumer end (preauth2.c and kdc_preauth.c), this is a pretty
rough conversion.  Eventually we should create proper consumer APIs
with module handles, and the flat lists of preauth types should hold
pointers to module handles rather than copies of the vtables.  The
built-in preauth type handlers should then be converted to built-in
module providers linked into the consumer code (as should encrypted
challenge, since it has no external dependencies).  None of this will
impact the provider API for preauth plugins, so it can wait.

ticket: 6921

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24970 dc483132-0cff-0310-8789-dd5450dbe970

28 files changed:
src/include/k5-int.h
src/include/krb5/preauth_plugin.h
src/kdc/do_as_req.c
src/kdc/kdc_preauth.c
src/kdc/kdc_util.h
src/lib/krb5/krb/copy_ctx.c
src/lib/krb5/krb/get_in_tkt.c
src/lib/krb5/krb/gic_opt_set_pa.c
src/lib/krb5/krb/init_creds_ctx.h
src/lib/krb5/krb/plugin.c
src/lib/krb5/krb/preauth2.c
src/lib/krb5/libkrb5.exports
src/lib/krb5/os/init_os_ctx.c
src/plugins/preauth/cksum_body/cksum_body.exports
src/plugins/preauth/cksum_body/cksum_body_main.c
src/plugins/preauth/encrypted_challenge/encrypted_challenge.exports
src/plugins/preauth/encrypted_challenge/encrypted_challenge_main.c
src/plugins/preauth/fast_factor.h
src/plugins/preauth/pkinit/pkinit.exports
src/plugins/preauth/pkinit/pkinit_clnt.c
src/plugins/preauth/pkinit/pkinit_srv.c
src/plugins/preauth/securid_sam2/securid_sam2_main.c
src/plugins/preauth/wpse/wpse.exports
src/plugins/preauth/wpse/wpse_main.c
src/tests/dejagnu/Makefile.in
src/tests/dejagnu/config/default.exp
src/tests/dejagnu/krb-standalone/standalone.exp
src/util/k5test.py

index 86ec114b0a31bdeeba9ee5fcd5bd7570ffa030cb..76993f397af7838167e4c3c78a2b7f29fb12b6ee 100644 (file)
@@ -809,48 +809,11 @@ error(MIT_DES_KEYSIZE does not equal KRB5_MIT_DES_KEYSIZE)
  * expanded in the future as new types of requests are defined which
  * may require other things to be passed through. */
 struct krb5int_fast_request_state;
-typedef struct _krb5_preauth_client_rock {
-    krb5_magic      magic;
+struct krb5_clpreauth_rock_st {
+    krb5_magic magic;
     krb5_enctype *etype;
     struct krb5int_fast_request_state *fast_state;
-} krb5_preauth_client_rock;
-
-/* This structure lets us keep track of all of the modules which are loaded,
- * turning the list of modules and their lists of implemented preauth types
- * into a single list which we can walk easily. */
-typedef struct _krb5_preauth_context {
-    int n_modules;
-    struct _krb5_preauth_context_module {
-        /* Which of the possibly more than one preauth types which the
-         * module supports we're using at this point in the list. */
-        krb5_preauthtype pa_type;
-        /* Encryption types which the client claims to support -- we
-         * copy them directly into the krb5_kdc_req structure during
-         * krb5_preauth_prepare_request(). */
-        krb5_enctype *enctypes;
-        /* The plugin's per-plugin context and a function to clear it. */
-        void *plugin_context;
-        preauth_client_plugin_fini_proc client_fini;
-        /* The module's table, and some of its members, copied here for
-         * convenience when we populated the list. */
-        struct krb5plugin_preauth_client_ftable_v1 *ftable;
-        const char *name;
-        int flags, use_count;
-        preauth_client_process_proc client_process;
-        preauth_client_tryagain_proc client_tryagain;
-        preauth_client_supply_gic_opts_proc client_supply_gic_opts;
-        preauth_client_request_init_proc client_req_init;
-        preauth_client_request_fini_proc client_req_fini;
-        /* The per-request context which the client_req_init() function
-         * might allocate, which we'll need to clean up later by
-         * calling the client_req_fini() function. */
-        void *request_context;
-        /* A pointer to the request_context pointer.  All modules within
-         * a plugin will point at the request_context of the first
-         * module within the plugin. */
-        void **request_context_pp;
-    } *modules;
-} krb5_preauth_context;
+};
 
 typedef struct _krb5_pa_enc_ts {
     krb5_timestamp      patimestamp;
@@ -1121,7 +1084,7 @@ krb5_do_preauth(krb5_context context, krb5_kdc_req *request,
                 krb5_data *s2kparams, krb5_enctype *etype,
                 krb5_keyblock *as_key, krb5_prompter_fct prompter,
                 void *prompter_data, krb5_gic_get_as_key_fct gak_fct,
-                void *gak_data, krb5_preauth_client_rock *get_data_rock,
+                void *gak_data, krb5_clpreauth_rock preauth_rock,
                 krb5_gic_opt_ext *opte);
 
 krb5_error_code KRB5_CALLCONV
@@ -1134,7 +1097,7 @@ krb5_do_preauth_tryagain(krb5_context context, krb5_kdc_req *request,
                          krb5_enctype *etype, krb5_keyblock *as_key,
                          krb5_prompter_fct prompter, void *prompter_data,
                          krb5_gic_get_as_key_fct gak_fct, void *gak_data,
-                         krb5_preauth_client_rock *get_data_rock,
+                         krb5_clpreauth_rock preauth_rock,
                          krb5_gic_opt_ext *opte);
 
 void KRB5_CALLCONV krb5_init_preauth_context(krb5_context);
@@ -1411,9 +1374,11 @@ struct plugin_interface {
 
 /* A list of plugin interface IDs.  Make sure to increment
  * PLUGIN_NUM_INTERFACES when a new interface is added. */
-#define PLUGIN_INTERFACE_PWQUAL 0
-#define PLUGIN_INTERFACE_KADM5_HOOK 1
-#define PLUGIN_NUM_INTERFACES   2
+#define PLUGIN_INTERFACE_PWQUAL      0
+#define PLUGIN_INTERFACE_KADM5_HOOK  1
+#define PLUGIN_INTERFACE_CLPREAUTH   2
+#define PLUGIN_INTERFACE_KDCPREAUTH  3
+#define PLUGIN_NUM_INTERFACES        4
 
 /* Retrieve the plugin module of type interface_id and name modname,
  * storing the result into module. */
@@ -1452,6 +1417,7 @@ k5_plugin_free_context(krb5_context context);
 struct _kdb5_dal_handle;        /* private, in kdb5.h */
 typedef struct _kdb5_dal_handle kdb5_dal_handle;
 struct _kdb_log_context;
+typedef struct krb5_preauth_context_st krb5_preauth_context;
 struct _krb5_context {
     krb5_magic      magic;
     krb5_enctype    *in_tkt_etypes;
@@ -1490,7 +1456,6 @@ struct _krb5_context {
     void (**locate_fptrs)(void);
 
     /* preauth module stuff */
-    struct plugin_dir_handle preauth_plugins;
     krb5_preauth_context *preauth_context;
 
     /* error detail info */
index 21140cb45b36b3929bf110502a9929fb70972f8c..2ddacdabbaf6ea7cc5bd953ea860022d4445af74 100644 (file)
@@ -1,7 +1,7 @@
 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
 /*
  * Copyright (c) 2006 Red Hat, Inc.
- * Portions copyright (c) 2006 Massachusetts Institute of Technology
+ * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology
  * All Rights Reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* Preauthentication plugin definitions for Kerberos 5 */
+/*
+ * Declarations for preauth plugin module implementors.
+ *
+ * This header defines two preauth interfaces, clpreauth and kdcpreauth.  A
+ * shared object can implement both interfaces or it can implement just one.
+ *
+ *
+ * The clpreauth interface has a single supported major version, which is
+ * 1.  Major version 1 has a current minor version of 1.  clpreauth modules
+ * should define a function named clpreauth_<modulename>_initvt, matching
+ * the signature:
+ *
+ *   krb5_error_code
+ *   clpreauth_modname_initvt(krb5_context context, int maj_ver,
+ *                            int min_ver, krb5_plugin_vtable vtable);
+ *
+ * The kdcpreauth interface has a single supported major version, which is 1.
+ * Major version 1 has a current minor version of 1.  kdcpreauth modules should
+ * define a function named kdcpreauth_<modulename>_initvt, matching the
+ * signature:
+ *
+ *   krb5_error_code
+ *   kdcpreauth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ *                             krb5_plugin_vtable vtable);
+ *
+ * For both interfaces, the initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ *   return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for the interface and maj_ver:
+ *     clpreauth, maj_ver == 1:  Cast to krb5_clpreauth_vtable
+ *     kdcpreauth, maj_ver == 1: Cast to krb5_kdcpreauth_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ *   supplied min_ver.  Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
 
 #ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED
 #define KRB5_PREAUTH_PLUGIN_H_INCLUDED
 #include <krb5/krb5.h>
-
-/*
- * While arguments of these types are passed-in, for the most part a preauth
- * module can treat them as opaque.  If we need keying data, we can ask for
- * it directly.
- */
-struct _krb5_db_entry_new;
-struct _krb5_key_data;
-struct _krb5_preauth_client_rock;
+#include <krb5/plugin.h>
 
 /*
  * Preauth mechanism property flags, unified from previous definitions in the
@@ -58,444 +88,390 @@ struct _krb5_preauth_client_rock;
  * REAL mechanism callbacks (client-only). */
 #define PA_INFO         0x00000002
 
-/* Causes the KDC to include this mechanism in a list of supported preauth
+/*
+ * Causes the KDC to include this mechanism in a list of supported preauth
  * types if the user's DB entry flags the user as requiring hardware-based
- * preauthentication (server-only). */
+ * preauthentication (KDC-only).
+ */
 #define PA_HARDWARE     0x00000004
 
-/* Causes the KDC to include this mechanism in a list of supported preauth
+/*
+ * Causes the KDC to include this mechanism in a list of supported preauth
  * types if the user's DB entry flags the user as requiring preauthentication,
  * and to fail preauthentication if we can't verify the client data.  The
- * flipside of PA_SUFFICIENT (server-only). */
+ * flipside of PA_SUFFICIENT (KDC-only).
+ */
 #define PA_REQUIRED     0x00000008
 
-/* Causes the KDC to include this mechanism in a list of supported preauth
+/*
+ * Causes the KDC to include this mechanism in a list of supported preauth
  * types if the user's DB entry flags the user as requiring preauthentication,
  * and to mark preauthentication as successful if we can verify the client
- * data.  The flipside of PA_REQUIRED (server-only). */
+ * data.  The flipside of PA_REQUIRED (KDC-only).
+ */
 #define PA_SUFFICIENT   0x00000010
 
-/* Marks this preauthentication mechanism as one which changes the key which is
+/*
+ * Marks this preauthentication mechanism as one which changes the key which is
  * used for encrypting the response to the client.  Modules which have this
- * flag have their server_return_proc called before modules which do not, and
- * are passed over if a previously-called module has modified the encrypting
- * key (server-only). */
+ * flag have their server_return_fn called before modules which do not, and are
+ * passed over if a previously-called module has modified the encrypting key
+ * (KDC-only).
+ */
 #define PA_REPLACES_KEY 0x00000020
 
-/* Causes the KDC to check with this preauthentication module even if the
- * client has no entry in the realm database.  If the module returns a success
- * code, continue processing and assume that its return_padata callback will
- * supply us with a key for encrypting the AS reply (server-only). */
-/* #define PA_VIRTUAL   (0x00000040 | PA_REPLACES_KEY) */
-
-/* Not really a padata type, so don't include it in any list of preauth types
- * which gets sent over the wire. */
+/*
+ * Not really a padata type, so don't include it in any list of preauth types
+ * which gets sent over the wire.
+ */
 #define PA_PSEUDO       0x00000080
 
 
-/***************************************************************************
- *
- * Client-side preauthentication plugin interface definition.
- *
- ***************************************************************************/
+/*
+ * clpreauth plugin interface definition.
+ */
+
+/* Abstract type for a client request information handle. */
+typedef struct krb5_clpreauth_rock_st *krb5_clpreauth_rock;
+
+/* Abstract types for module data and per-request module data. */
+typedef struct krb5_clpreauth_moddata_st *krb5_clpreauth_moddata;
+typedef struct krb5_clpreauth_modreq_st *krb5_clpreauth_modreq;
 
 /*
- * A callback which will obtain the user's long-term AS key by prompting the
- * user for the password, then salting it properly, and so on.  For the moment,
- * it's identical to the get_as_key callback used inside of libkrb5, but we
- * define a new typedef here instead of making the existing one public to
- * isolate ourselves from potential future changes.
+ * Provided by krb5: a callback which will obtain the user's long-term AS key
+ * by prompting the user for the password, then salting it properly, and so on.
+ * For the moment, it's identical to the get_as_key callback used inside of
+ * libkrb5, but we define a new typedef here instead of making the existing one
+ * public to isolate ourselves from potential future changes.
  */
 typedef krb5_error_code
-(*preauth_get_as_key_proc)(krb5_context,
-                           krb5_principal,
-                           krb5_enctype,
-                           krb5_prompter_fct,
-                           void *prompter_data,
-                           krb5_data *salt,
-                           krb5_data *s2kparams,
-                           krb5_keyblock *as_key,
-                           void *gak_data);
+(*krb5_clpreauth_get_as_key_fn)(krb5_context context,
+                                krb5_principal princ,
+                                krb5_enctype enctype,
+                                krb5_prompter_fct prompter,
+                                void *prompter_data,
+                                krb5_data *salt,
+                                krb5_data *s2kparams,
+                                krb5_keyblock *as_key,
+                                void *gak_data);
 
 /*
- * A client module's callback functions are allowed to request various
- * information to enable it to process a request.
+ * Provided by krb5: a client module's callback functions are allowed to
+ * request various information to enable it to process a request.
  */
-enum krb5plugin_preauth_client_request_type {
-    /* The returned krb5_data item holds the enctype expected to be  used to encrypt the
-     * encrypted portion of the AS_REP packet. When handling a
-     * PREAUTH_REQUIRED error, this typically comes from etype-info2.
-     * When handling an AS reply, it is initialized from the AS reply itself.*/
-    krb5plugin_preauth_client_get_etype = 1,
-    /* Free the data returned from krb5plugin_preauth_client_req_get_etype */
-    krb5plugin_preauth_client_free_etype = 2,
-    /* The returned krb5_data contains the FAST armor key in a
-     * krb5_keyblock.  Returns success with a NULL data item in the
-     * krb5_data if the client library supports FAST but is not using it.*/
-    krb5plugin_preauth_client_fast_armor = 3,
-    /* Frees return from KRB5PLUGIN_PREAUTH_CLIENT_FAST_ARMOR.  It is
-     * acceptable to set data to NULL and free the keyblock using
-     * krb5_free_keyblock; in that case, this frees the krb5_data
-     * only.*/
-    krb5plugin_preauth_client_free_fast_armor = 4
+enum krb5_clpreauth_request_type {
+    /*
+     * The returned krb5_data item holds the enctype expected to be used to
+     * encrypt the encrypted portion of the AS_REP packet. When handling a
+     * PREAUTH_REQUIRED error, this typically comes from etype-info2.  When
+     * handling an AS reply, it is initialized from the AS reply itself.
+     */
+    krb5_clpreauth_get_etype = 1,
+
+    /* Free the data returned from krb5plugin_clpreauth_req_get_etype */
+    krb5_clpreauth_free_etype = 2,
+
+    /*
+     * The returned krb5_data contains the FAST armor key in a krb5_keyblock.
+     * Returns success with a NULL data item in the krb5_data if the client
+     * library supports FAST but is not using it.
+     */
+    krb5_clpreauth_fast_armor = 3,
+
+    /*
+     * Frees return from KRB5PLUGIN_CLPREAUTH_FAST_ARMOR.  It is
+     * acceptable to set data->data to NULL and free the keyblock using
+     * krb5_free_keyblock; in that case, this frees the krb5_data only.
+     */
+    krb5_clpreauth_free_fast_armor = 4
 };
 typedef krb5_error_code
-(*preauth_get_client_data_proc)(krb5_context,
-                                struct _krb5_preauth_client_rock *,
-                                krb5_int32 request_type,
-                                krb5_data **);
-
-/* Per-plugin initialization/cleanup.  The init function is called
- * by libkrb5 when the plugin is loaded, and the fini function is
- * called before the plugin is unloaded.  Both are optional and
- * may be called multiple times in case the plugin is used in
- * multiple contexts.  The returned context lives the lifetime of
- * the krb5_context */
+(*krb5_clpreauth_get_data_fn)(krb5_context context,
+                              krb5_clpreauth_rock rock,
+                              krb5_int32 request_type, krb5_data **data);
+
+/*
+ * Optional: per-plugin initialization/cleanup.  The init function is called by
+ * libkrb5 when the plugin is loaded, and the fini function is called before
+ * the plugin is unloaded.  These may be called multiple times in case the
+ * plugin is used in multiple contexts.  The returned context lives the
+ * lifetime of the krb5_context.
+ */
 typedef krb5_error_code
-(*preauth_client_plugin_init_proc)(krb5_context context,
-                                   void **plugin_context);
+(*krb5_clpreauth_init_fn)(krb5_context context,
+                          krb5_clpreauth_moddata *moddata_out);
 typedef void
-(*preauth_client_plugin_fini_proc)(krb5_context context,
-                                   void *plugin_context);
+(*krb5_clpreauth_fini_fn)(krb5_context context,
+                          krb5_clpreauth_moddata moddata);
 
-/* A callback which returns flags indicating if the module is a "real" or
- * an "info" mechanism, and so on.  This function is called for each entry
- * in the client_pa_type_list. */
+/*
+ * Mandatory: Return flags indicating if the module is a "real" or an "info"
+ * mechanism, and so on.  This function is called for each entry in the
+ * client_pa_type_list.
+ */
 typedef int
-(*preauth_client_get_flags_proc)(krb5_context context,
-                                 krb5_preauthtype pa_type);
+(*krb5_clpreauth_get_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
 
-/* Per-request initialization/cleanup.  The request_init function is
+/*
+ * Optional: per-request initialization/cleanup.  The request_init function is
  * called when beginning to process a get_init_creds request and the
- * request_fini function is called when processing of the request is
- * complete.  This is optional.  It may be called multiple times in
- * the lifetime of a krb5_context. */
+ * request_fini function is called when processing of the request is complete.
+ * This is optional.  It may be called multiple times in the lifetime of a
+ * krb5_context.
+ */
 typedef void
-(*preauth_client_request_init_proc)(krb5_context context,
-                                    void *plugin_context,
-                                    void **request_context);
+(*krb5_clpreauth_request_init_fn)(krb5_context context,
+                                  krb5_clpreauth_moddata moddata,
+                                  krb5_clpreauth_modreq *modreq_out);
 typedef void
-(*preauth_client_request_fini_proc)(krb5_context context,
-                                    void *plugin_context,
-                                    void *request_context);
-
-/* Client function which processes server-supplied data in pa_data,
- * returns created data in out_pa_data, storing any of its own state in
- * client_context if data for the associated preauthentication type is
- * needed.  It is also called after the AS-REP is received if the AS-REP
- * includes preauthentication data of the associated type.
- * NOTE! the encoded_previous_request will be NULL the first time this
- * function is called, because it is expected to only ever contain the data
- * obtained from a previous call to this function. */
-typedef krb5_error_code
-(*preauth_client_process_proc)(krb5_context context,
-                               void *plugin_context,
-                               void *request_context,
-                               krb5_get_init_creds_opt *opt,
-                               preauth_get_client_data_proc get_data_proc,
-                               struct _krb5_preauth_client_rock *rock,
-                               krb5_kdc_req *request,
-                               krb5_data *encoded_request_body,
-                               krb5_data *encoded_previous_request,
-                               krb5_pa_data *pa_data,
-                               krb5_prompter_fct prompter,
-                               void *prompter_data,
-                               preauth_get_as_key_proc gak_fct,
-                               void *gak_data,
-                               krb5_data *salt,
-                               krb5_data *s2kparams,
-                               krb5_keyblock *as_key,
-                               krb5_pa_data ***out_pa_data);
-
-/* Client function which can attempt to use e-data in the error response to
- * try to recover from the given error.  If this function is not NULL, and
- * it stores data in out_pa_data which is different data from the contents
- * of in_pa_data, then the client library will retransmit the request. */
+(*krb5_clpreauth_request_fini_fn)(krb5_context context,
+                                  krb5_clpreauth_moddata moddata,
+                                  krb5_clpreauth_modreq modreq);
+
+/*
+ * Mandatory: process server-supplied data in pa_data and returns created data
+ * in out_pa_data.  It is also called after the AS-REP is received if the
+ * AS-REP includes preauthentication data of the associated type.  NOTE: the
+ * encoded_previous_request will be NULL the first time this function is
+ * called, because it is expected to only ever contain the data obtained from a
+ * previous call to this function.
+ */
 typedef krb5_error_code
-(*preauth_client_tryagain_proc)(krb5_context context,
-                                void *plugin_context,
-                                void *request_context,
-                                krb5_get_init_creds_opt *opt,
-                                preauth_get_client_data_proc get_data_proc,
-                                struct _krb5_preauth_client_rock *rock,
-                                krb5_kdc_req *request,
-                                krb5_data *encoded_request_body,
-                                krb5_data *encoded_previous_request,
-                                krb5_pa_data *in_pa_data,
-                                krb5_error *error,
-                                krb5_prompter_fct prompter,
-                                void *prompter_data,
-                                preauth_get_as_key_proc gak_fct,
-                                void *gak_data,
-                                krb5_data *salt,
-                                krb5_data *s2kparams,
-                                krb5_keyblock *as_key,
-                                krb5_pa_data ***out_pa_data);
+(*krb5_clpreauth_process_fn)(krb5_context context,
+                             krb5_clpreauth_moddata moddata,
+                             krb5_clpreauth_modreq modreq,
+                             krb5_get_init_creds_opt *opt,
+                             krb5_clpreauth_get_data_fn get_data,
+                             krb5_clpreauth_rock rock,
+                             krb5_kdc_req *request,
+                             krb5_data *encoded_request_body,
+                             krb5_data *encoded_previous_request,
+                             krb5_pa_data *pa_data,
+                             krb5_prompter_fct prompter, void *prompter_data,
+                             krb5_clpreauth_get_as_key_fn gak_fct,
+                             void *gak_data,
+                             krb5_data *salt, krb5_data *s2kparams,
+                             krb5_keyblock *as_key,
+                             krb5_pa_data ***out_pa_data);
 
 /*
- * Client function which receives krb5_get_init_creds_opt information.
- * The attr and value information supplied should be copied locally by
- * the module if it wishes to reference it after returning from this call.
+ * Optional: Attempt to use e-data in the error response to try to recover from
+ * the given error.  If this function is provided, and it stores data in
+ * out_pa_data which is different data from the contents of in_pa_data, then
+ * the client library will retransmit the request.
  */
 typedef krb5_error_code
-(*preauth_client_supply_gic_opts_proc)(krb5_context context,
-                                       void *plugin_context,
-                                       krb5_get_init_creds_opt *opt,
-                                       const char *attr,
-                                       const char *value);
+(*krb5_clpreauth_tryagain_fn)(krb5_context context,
+                              krb5_clpreauth_moddata moddata,
+                              krb5_clpreauth_modreq modreq,
+                              krb5_get_init_creds_opt *opt,
+                              krb5_clpreauth_get_data_fn get_data,
+                              krb5_clpreauth_rock rock,
+                              krb5_kdc_req *request,
+                              krb5_data *encoded_request_body,
+                              krb5_data *encoded_previous_request,
+                              krb5_pa_data *in_pa_data,
+                              krb5_error *error,
+                              krb5_prompter_fct prompter, void *prompter_data,
+                              krb5_clpreauth_get_as_key_fn gak_fct,
+                              void *gak_data,
+                              krb5_data *salt, krb5_data *s2kparams,
+                              krb5_keyblock *as_key,
+                              krb5_pa_data ***out_pa_data);
 
 /*
- * The function table / structure which a preauth client module must export as
- * "preauthentication_client_0".  If the interfaces work correctly, future
- * versions of the table will add either more callbacks or more arguments to
- * callbacks, and in both cases we'll be able to wrap the v0 functions.
+ * Optional: receive krb5_get_init_creds_opt information.  The attr and value
+ * information supplied should be copied into moddata by the module if it
+ * wishes to reference it after returning from this call.
  */
-typedef struct krb5plugin_preauth_client_ftable_v1 {
-    /* Not-usually-visible name. */
+typedef krb5_error_code
+(*krb5_clpreauth_supply_gic_opts_fn)(krb5_context context,
+                                     krb5_clpreauth_moddata moddata,
+                                     krb5_get_init_creds_opt *opt,
+                                     const char *attr, const char *value);
+
+typedef struct krb5_clpreauth_vtable_st {
+    /* Mandatory: name of module. */
     char *name;
 
-    /* Pointer to zero-terminated list of pa_types which this module can
-     * provide services for. */
+    /* Mandatory: pointer to zero-terminated list of pa_types which this module
+     * can provide services for. */
     krb5_preauthtype *pa_type_list;
 
-    /* Pointer to zero-terminated list of enc_types which this module claims
-     * to add support for. */
+    /* Optional: pointer to zero-terminated list of enc_types which this module
+     * claims to add support for. */
     krb5_enctype *enctype_list;
 
-    /* Per-plugin initialization/cleanup.  The init function is called
-     * by libkrb5 when the plugin is loaded, and the fini function is
-     * called before the plugin is unloaded.  Both are optional and
-     * may be called multiple times in case the plugin is used in
-     * multiple contexts.  The returned context lives the lifetime of
-     * the krb5_context */
-    preauth_client_plugin_init_proc init;
-    preauth_client_plugin_fini_proc fini;
-
-    /* A callback which returns flags indicating if the module is a "real" or
-     * an "info" mechanism, and so on.  This function is called for each entry
-     * in the client_pa_type_list. */
-    preauth_client_get_flags_proc flags;
-
-    /* Per-request initialization/cleanup.  The request_init function is
-     * called when beginning to process a get_init_creds request and the
-     * request_fini function is called when processing of the request is
-     * complete.  This is optional.  It may be called multiple times in
-     * the lifetime of a krb5_context. */
-    preauth_client_request_init_proc request_init;
-    preauth_client_request_fini_proc request_fini;
-
-    /* Client function which processes server-supplied data in pa_data,
-     * returns created data in out_pa_data, storing any of its own state in
-     * client_context if data for the associated preauthentication type is
-     * needed.  It is also called after the AS-REP is received if the AS-REP
-     * includes preauthentication data of the associated type.
-     * NOTE! the encoded_previous_request will be NULL the first time this
-     * function is called, because it is expected to only ever contain the data
-     * obtained from a previous call to this function. */
-    preauth_client_process_proc process;
-
-    /* Client function which can attempt to use e-data in the error response to
-     * try to recover from the given error.  If this function is not NULL, and
-     * it stores data in out_pa_data which is different data from the contents
-     * of in_pa_data, then the client library will retransmit the request. */
-    preauth_client_tryagain_proc tryagain;
+    krb5_clpreauth_init_fn init;
+    krb5_clpreauth_fini_fn fini;
+    krb5_clpreauth_get_flags_fn flags;
+    krb5_clpreauth_request_init_fn request_init;
+    krb5_clpreauth_request_fini_fn request_fini;
+    krb5_clpreauth_process_fn process;
+    krb5_clpreauth_tryagain_fn tryagain;
+    krb5_clpreauth_supply_gic_opts_fn gic_opts;
+    /* Minor version 1 ends here. */
+} *krb5_clpreauth_vtable;
 
-    /*
-     * Client function which receives krb5_get_init_creds_opt information.
-     * The attr and value information supplied should be copied locally by
-     * the module if it wishes to reference it after returning from this call.
-     */
-    preauth_client_supply_gic_opts_proc gic_opts;
 
-} krb5plugin_preauth_client_ftable_v1;
+/*
+ * kdcpreauth plugin interface definition.
+ */
 
+/* While arguments of these types are passed in, they are opaque to kdcpreauth
+ * modules. */
+struct _krb5_db_entry_new;
+struct _krb5_key_data;
 
-/***************************************************************************
- *
- * Server-side preauthentication plugin interface definition.
- *
- ***************************************************************************/
+/* Abstract type for module data and per-request module data. */
+typedef struct krb5_kdcpreauth_moddata_st *krb5_kdcpreauth_moddata;
+typedef struct krb5_kdcpreauth_modreq_st *krb5_kdcpreauth_modreq;
 
 /*
- * A server module's callback functions are allowed to request specific types
- * of information about the given client or server record or request, even
- * though the database records themselves are opaque to the module.
+ * Provided by krb5: a kdcpreauth module's callback functions are allowed to
+ * request specific types of information about the given client or server
+ * record or request, even though the database records themselves are opaque to
+ * the module.
  */
-enum krb5plugin_preauth_entry_request_type {
+enum krb5_kdcpreauth_request_type {
     /* The returned krb5_data item holds a DER-encoded X.509 certificate. */
-    krb5plugin_preauth_entry_request_certificate = 1,
+    krb5_kdcpreauth_request_certificate = 1,
     /* The returned krb5_data_item holds a krb5_deltat. */
-    krb5plugin_preauth_entry_max_time_skew = 2,
-    /* The returned krb5_data_item holds an array of krb5_keyblock structures,
-     * terminated by an entry with key type = 0.
-     * Each keyblock should have its contents freed in turn, and then the data
-     * item itself should be freed. */
-    krb5plugin_preauth_keys = 3,
-    /* The returned krb5_data_item holds the request structure, re-encoded
+    krb5_kdcpreauth_max_time_skew = 2,
+    /*
+     * The returned krb5_data_item holds an array of krb5_keyblock structures,
+     * terminated by an entry with key type = 0.  Each keyblock should have its
+     * contents freed in turn, and then the data item itself should be freed.
+     */
+    krb5_kdcpreauth_keys = 3,
+    /*
+     * The returned krb5_data_item holds the request structure, re-encoded
      * using DER.  Unless the client implementation is the same as the server
      * implementation, there's a good chance that the result will not match
-     * what the client sent, so don't go creating any fatal errors if it
-     * doesn't match up. */
-    krb5plugin_preauth_request_body = 4,
-    /* The returned krb5_data contains a krb5_keyblock with the FAST
-       armor key.  The data member is NULL if this method is not part
-       of a FAST tunnel */
-    krb5plugin_preauth_fast_armor = 5,
-    /* Frees a fast armor key; it is acceptable to set data to NULL
-       and free the keyblock using krb5_free_keyblock; in that  case,
-       this function simply frees the data*/
-    krb5plugin_preauth_free_fast_armor = 6
+     * what the client sent, so don't create any fatal errors if it doesn't
+     * match up.
+     */
+    krb5_kdcpreauth_request_body = 4,
+    /*
+     * The returned krb5_data contains a krb5_keyblock with the FAST armor key.
+     * The data member is NULL if this method is not part of a FAST tunnel.
+     */
+    krb5_kdcpreauth_fast_armor = 5,
+    /*
+     * Frees a fast armor key. It is acceptable to set data to NULL and free
+     * the keyblock using krb5_free_keyblock; in that case, this function
+     * simply frees the data.
+     */
+    krb5_kdcpreauth_free_fast_armor = 6
 };
-
 typedef krb5_error_code
-(*preauth_get_entry_data_proc)(krb5_context,
-                               krb5_kdc_req *,
-                               struct _krb5_db_entry_new *,
+(*krb5_kdcpreauth_get_data_fn)(krb5_context context, krb5_kdc_req *request,
+                               struct _krb5_db_entry_new *entry,
                                krb5_int32 request_type,
                                krb5_data **);
 
-/* Preauth plugin initialization function */
+/* Optional: preauth plugin initialization function. */
 typedef krb5_error_code
-(*preauth_server_init_proc)(krb5_context context,
-                            void **plugin_context,
-                            const char** realmnames);
+(*krb5_kdcpreauth_init_fn)(krb5_context context,
+                           krb5_kdcpreauth_moddata *moddata_out,
+                           const char **realmnames);
 
-/* Preauth plugin cleanup function */
+/* Optional: preauth plugin cleanup function. */
 typedef void
-(*preauth_server_fini_proc)(krb5_context context, void *plugin_context);
-
-/* Return the flags which the KDC should use for this module.  This is a
- * callback instead of a static value because the module may or may not
- * wish to count itself as a hardware preauthentication module (in other
- * words, the flags may be affected by the configuration, for example if a
- * site administrator can force a particular preauthentication type to be
- * supported using only hardware).  This function is called for each entry
- * entry in the server_pa_type_list. */
+(*krb5_kdcpreauth_fini_fn)(krb5_context context,
+                           krb5_kdcpreauth_moddata moddata);
+
+/*
+ * Optional: return the flags which the KDC should use for this module.  This
+ * is a callback instead of a static value because the module may or may not
+ * wish to count itself as a hardware preauthentication module (in other words,
+ * the flags may be affected by the configuration, for example if a site
+ * administrator can force a particular preauthentication type to be supported
+ * using only hardware).  This function is called for each entry entry in the
+ * server_pa_type_list.
+ */
 typedef int
-(*preauth_server_flags_proc)(krb5_context context, krb5_preauthtype patype);
-
-/* Get preauthentication data to send to the client as part of the "you
- * need to use preauthentication" error.  The module doesn't need to
- * actually provide data if the protocol doesn't require it, but it should
- * return either zero or non-zero to control whether its padata type is
- * included in the list which is sent back to the client.  Is not allowed
- * to create a context because we have no guarantee that the client will
- * ever call again (or that it will hit this server if it does), in which
- * case a context might otherwise hang around forever. */
+(*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype patype);
+
+/*
+ * Optional: fill in pa_out->length and pa_out->contents with data to send to
+ * the client as part of the "you need to use preauthentication" error.  If
+ * this function returns non-zero, the padata type will not be included in the
+ * list; if this function is not provided or returns zero without changing
+ * pa_out, the padata type will be included in the list with an empty value.
+ * This function not allowed to create a context because we have no guarantee
+ * that the client will ever call again (or that it will hit this server if it
+ * does), in which case a context might otherwise hang around forever.
+ */
 typedef krb5_error_code
-(*preauth_server_edata_proc)(krb5_context,
-                             krb5_kdc_req *request,
-                             struct _krb5_db_entry_new *client,
-                             struct _krb5_db_entry_new *server,
-                             preauth_get_entry_data_proc,
-                             void *pa_module_context,
-                             krb5_pa_data *data);
+(*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request,
+                            struct _krb5_db_entry_new *client,
+                            struct _krb5_db_entry_new *server,
+                            krb5_kdcpreauth_get_data_fn get_data,
+                            krb5_kdcpreauth_moddata moddata,
+                            krb5_pa_data *pa_out);
 
-/* Verify preauthentication data sent by the client, setting the
+/*
+ * Optional: verify preauthentication data sent by the client, setting the
  * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
  * field as appropriate, and returning nonzero on failure.  Can create
- * context data for consumption by the return_proc or freepa_proc below. */
-typedef krb5_error_code
-(*preauth_server_verify_proc)(krb5_context context,
-                              struct _krb5_db_entry_new *client,
-                              krb5_data *req_pkt,
-                              krb5_kdc_req *request,
-                              krb5_enc_tkt_part *enc_tkt_reply,
-                              krb5_pa_data *data,
-                              preauth_get_entry_data_proc,
-                              void *pa_module_context,
-                              void **pa_request_context,
-                              krb5_data **e_data,
-                              krb5_authdata ***authz_data);
-
-/* Generate preauthentication response data to send to the client as part
- * of the AS-REP.  If it needs to override the key which is used to encrypt
- * the response, it can do so.  The module is expected (but not required,
- * if a preauth_server_free_reqcontext_proc is also provided) to free any
- * context data it saved in "pa_request_context". */
-typedef krb5_error_code
-(*preauth_server_return_proc)(krb5_context context,
-                              krb5_pa_data * padata,
-                              struct _krb5_db_entry_new *client,
-                              krb5_data *req_pkt,
-                              krb5_kdc_req *request,
-                              krb5_kdc_rep *reply,
-                              struct _krb5_key_data *client_keys,
-                              krb5_keyblock *encrypting_key,
-                              krb5_pa_data **send_pa,
-                              preauth_get_entry_data_proc,
-                              void *pa_module_context,
-                              void **pa_request_context);
-
-/* Free up the server-side per-request context, in cases where
- * server_return_proc() didn't or for whatever reason was not called.
- * Can be NULL. */
+ * per-request module data for consumption by the return_fn or free_modreq_fn
+ * below.
+ */
 typedef krb5_error_code
-(*preauth_server_free_reqcontext_proc)(krb5_context,
-                                       void *pa_module_context,
-                                       void **request_pa_context);
+(*krb5_kdcpreauth_verify_fn)(krb5_context context,
+                             struct _krb5_db_entry_new *client,
+                             krb5_data *req_pkt, krb5_kdc_req *request,
+                             krb5_enc_tkt_part *enc_tkt_reply,
+                             krb5_pa_data *data,
+                             krb5_kdcpreauth_get_data_fn get_data,
+                             krb5_kdcpreauth_moddata moddata,
+                             krb5_kdcpreauth_modreq *modreq_out,
+                             krb5_data **e_data_out,
+                             krb5_authdata ***authz_data_out);
 
 /*
- * The function table / structure which a preauth server module must export as
- * "preauthentication_server_0".  NOTE: replace "0" with "1" for the type and
- * variable names if this gets picked up by upstream.  If the interfaces work
- * correctly, future versions of the table will add either more callbacks or
- * more arguments to callbacks, and in both cases we'll be able to wrap the v0
- * functions.
+ * Optional: generate preauthentication response data to send to the client as
+ * part of the AS-REP.  If it needs to override the key which is used to
+ * encrypt the response, it can do so.
  */
-typedef struct krb5plugin_preauth_server_ftable_v1 {
-    /* Not-usually-visible name. */
+typedef krb5_error_code
+(*krb5_kdcpreauth_return_fn)(krb5_context context,
+                             krb5_pa_data *padata,
+                             struct _krb5_db_entry_new *client,
+                             krb5_data *req_pkt,
+                             krb5_kdc_req *request,
+                             krb5_kdc_rep *reply,
+                             struct _krb5_key_data *client_keys,
+                             krb5_keyblock *encrypting_key,
+                             krb5_pa_data **send_pa_out,
+                             krb5_kdcpreauth_get_data_fn,
+                             krb5_kdcpreauth_moddata moddata,
+                             krb5_kdcpreauth_modreq modreq);
+
+/* Optional: free a per-request context. */
+typedef void
+(*krb5_kdcpreauth_free_modreq_fn)(krb5_context,
+                                  krb5_kdcpreauth_moddata moddata,
+                                  krb5_kdcpreauth_modreq modreq);
+
+typedef struct krb5_kdcpreauth_vtable_st {
+    /* Mandatory: name of module. */
     char *name;
 
-    /* Pointer to zero-terminated list of pa_types which this module can
-     * provide services for. */
+    /* Mandatory: pointer to zero-terminated list of pa_types which this module
+     * can provide services for. */
     krb5_preauthtype *pa_type_list;
 
-    /* Per-plugin initialization/cleanup.  The init function is called by the
-     * KDC when the plugin is loaded, and the fini function is called before
-     * the plugin is unloaded.  Both are optional. */
-    preauth_server_init_proc init_proc;
-    preauth_server_fini_proc fini_proc;
-
-    /* Return the flags which the KDC should use for this module.  This is a
-     * callback instead of a static value because the module may or may not
-     * wish to count itself as a hardware preauthentication module (in other
-     * words, the flags may be affected by the configuration, for example if a
-     * site administrator can force a particular preauthentication type to be
-     * supported using only hardware).  This function is called for each entry
-     * entry in the server_pa_type_list. */
-    preauth_server_flags_proc flags_proc;
-
-    /* Get preauthentication data to send to the client as part of the "you
-     * need to use preauthentication" error.  The module doesn't need to
-     * actually provide data if the protocol doesn't require it, but it should
-     * return either zero or non-zero to control whether its padata type is
-     * included in the list which is sent back to the client.  Is not allowed
-     * to create a context because we have no guarantee that the client will
-     * ever call again (or that it will hit this server if it does), in which
-     * case a context might otherwise hang around forever. */
-    preauth_server_edata_proc edata_proc;
-
-    /* Verify preauthentication data sent by the client, setting the
-     * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
-     * field as appropriate, and returning nonzero on failure.  Can create
-     * context data for consumption by the return_proc or freepa_proc below. */
-    preauth_server_verify_proc verify_proc;
-
-    /* Generate preauthentication response data to send to the client as part
-     * of the AS-REP.  If it needs to override the key which is used to encrypt
-     * the response, it can do so.  The module is expected (but not required,
-     * if a freepa_proc is also provided) to free any context data it saved in
-     * "request_pa_context". */
-    preauth_server_return_proc return_proc;
-
-    /* Free up the server-side per-request context, in cases where
-     * server_return_proc() didn't or for whatever reason was not called.
-     * Can be NULL. */
-    preauth_server_free_reqcontext_proc freepa_reqcontext_proc;
-
-} krb5plugin_preauth_server_ftable_v1;
-
+    krb5_kdcpreauth_init_fn init;
+    krb5_kdcpreauth_fini_fn fini;
+    krb5_kdcpreauth_flags_fn flags;
+    krb5_kdcpreauth_edata_fn edata;
+    krb5_kdcpreauth_verify_fn verify;
+    krb5_kdcpreauth_return_fn return_padata;
+    krb5_kdcpreauth_free_modreq_fn free_modreq;
+} *krb5_kdcpreauth_vtable;
 
 /*
  * This function allows a preauth plugin to obtain preauth
@@ -503,7 +479,7 @@ typedef struct krb5plugin_preauth_server_ftable_v1 {
  * should be freed by calling krb5_get_init_creds_opt_free_pa().
  *
  * The 'opt' pointer supplied to this function must have been
- * obtained using krb5_get_init_creds_opt_alloc()
+ * obtained using krb5_get_init_creds_opt_alloc().
  */
 krb5_error_code KRB5_CALLCONV
 krb5_get_init_creds_opt_get_pa(krb5_context context,
index d4bef893304df2f3f432fb12699bb6c4b08ea175..87bccdb59ff1d4a9dbed7e87fe6f44b8bc962dcd 100644 (file)
@@ -616,8 +616,7 @@ errout:
     /* fall through */
 
 egress:
-    if (pa_context)
-        free_padata_context(kdc_context, &pa_context);
+    free_padata_context(kdc_context, pa_context);
     if (as_encrypting_key)
         krb5_free_keyblock(kdc_context, as_encrypting_key);
     if (errcode)
index 8378e997d9ede1d7d8356c4c7326b598f4b40c8b..d0a57b5fcbb5648f835f3d268aed7900cad1fad4 100644 (file)
 #include <assert.h>
 #include "../include/krb5/preauth_plugin.h"
 
-#if TARGET_OS_MAC
-static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR,
-                                 LIBDIR "/krb5/plugins/preauth",
-                                 NULL }; /* should be a list */
-#else
-static const char *objdirs[] = { LIBDIR "/krb5/plugins/preauth", NULL };
-#endif
-
-typedef struct _krb5_preauth_systems {
+typedef struct preauth_system_st {
     const char *name;
-    int         type;
-    int         flags;
-    void       *plugin_context;
-    preauth_server_init_proc    init;
-    preauth_server_fini_proc    fini;
-    preauth_server_edata_proc   get_edata;
-    preauth_server_verify_proc  verify_padata;
-    preauth_server_return_proc  return_padata;
-    preauth_server_free_reqcontext_proc free_pa_reqctx;
-} krb5_preauth_systems;
+    int type;
+    int flags;
+    krb5_kdcpreauth_moddata moddata;
+    krb5_kdcpreauth_init_fn init;
+    krb5_kdcpreauth_fini_fn fini;
+    krb5_kdcpreauth_edata_fn get_edata;
+    krb5_kdcpreauth_verify_fn verify_padata;
+    krb5_kdcpreauth_return_fn return_padata;
+    krb5_kdcpreauth_free_modreq_fn free_modreq;
+} preauth_system;
 
 static krb5_error_code
-verify_enc_timestamp (krb5_context, krb5_db_entry *client,
-                      krb5_data *req_pkt,
-                      krb5_kdc_req *request,
-                      krb5_enc_tkt_part * enc_tkt_reply, krb5_pa_data *data,
-                      preauth_get_entry_data_proc get_entry_data,
-                      void *pa_system_context,
-                      void **pa_request_context,
-                      krb5_data **e_data,
-                      krb5_authdata ***authz_data);
+verify_enc_timestamp(krb5_context, krb5_db_entry *client, krb5_data *req_pkt,
+                     krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
+                     krb5_pa_data *data,
+                     krb5_kdcpreauth_get_data_fn get_entry_data,
+                     krb5_kdcpreauth_moddata moddata,
+                     krb5_kdcpreauth_modreq *modreq_out, krb5_data **e_data,
+                     krb5_authdata ***authz_data);
 
 static krb5_error_code
-get_enc_ts(krb5_context, krb5_kdc_req *request,
+get_enc_ts(krb5_context context, krb5_kdc_req *request,
            krb5_db_entry *client, krb5_db_entry *server,
-           preauth_get_entry_data_proc get_entry_data,
-           void *pa_system_context,
-           krb5_pa_data *data);
+           krb5_kdcpreauth_get_data_fn get_entry_data,
+           krb5_kdcpreauth_moddata modata, krb5_pa_data *data);
 
 static krb5_error_code
-get_etype_info(krb5_context, krb5_kdc_req *request,
+get_etype_info(krb5_context context, krb5_kdc_req *request,
                krb5_db_entry *client, krb5_db_entry *server,
-               preauth_get_entry_data_proc get_entry_data,
-               void *pa_system_context,
-               krb5_pa_data *data);
+               krb5_kdcpreauth_get_data_fn get_entry_data,
+               krb5_kdcpreauth_moddata moddata, krb5_pa_data *data);
 
 static krb5_error_code
 get_etype_info2(krb5_context context, krb5_kdc_req *request,
                 krb5_db_entry *client, krb5_db_entry *server,
-                preauth_get_entry_data_proc get_entry_data,
-                void *pa_system_context,
-                krb5_pa_data *pa_data);
+                krb5_kdcpreauth_get_data_fn get_entry_data,
+                krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data);
 
 static krb5_error_code
 etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata,
@@ -154,40 +141,31 @@ etype_info_as_rep_helper(krb5_context context, krb5_pa_data * padata,
                          int etype_info2);
 
 static krb5_error_code
-return_etype_info(krb5_context, krb5_pa_data * padata,
-                  krb5_db_entry *client,
-                  krb5_data *req_pkt,
-                  krb5_kdc_req *request, krb5_kdc_rep *reply,
-                  krb5_key_data *client_key,
-                  krb5_keyblock *encrypting_key,
-                  krb5_pa_data **send_pa,
-                  preauth_get_entry_data_proc get_entry_data,
-                  void *pa_system_context,
-                  void **pa_request_context);
+return_etype_info(krb5_context, krb5_pa_data *padata, krb5_db_entry *client,
+                  krb5_data *req_pkt, krb5_kdc_req *request,
+                  krb5_kdc_rep *reply, krb5_key_data *client_key,
+                  krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
+                  krb5_kdcpreauth_get_data_fn get_entry_data,
+                  krb5_kdcpreauth_moddata moddata,
+                  krb5_kdcpreauth_modreq modreq);
 
 static krb5_error_code
-return_etype_info2(krb5_context, krb5_pa_data * padata,
-                   krb5_db_entry *client,
-                   krb5_data *req_pkt,
-                   krb5_kdc_req *request, krb5_kdc_rep *reply,
-                   krb5_key_data *client_key,
-                   krb5_keyblock *encrypting_key,
-                   krb5_pa_data **send_pa,
-                   preauth_get_entry_data_proc get_entry_data,
-                   void *pa_system_context,
-                   void **pa_request_context);
+return_etype_info2(krb5_context, krb5_pa_data *padata, krb5_db_entry *client,
+                   krb5_data *req_pkt, krb5_kdc_req *request,
+                   krb5_kdc_rep *reply, krb5_key_data *client_key,
+                   krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
+                   krb5_kdcpreauth_get_data_fn get_entry_data,
+                   krb5_kdcpreauth_moddata moddata,
+                   krb5_kdcpreauth_modreq modreq);
 
 static krb5_error_code
-return_pw_salt(krb5_context, krb5_pa_data * padata,
-               krb5_db_entry *client,
-               krb5_data *req_pkt,
-               krb5_kdc_req *request, krb5_kdc_rep *reply,
-               krb5_key_data *client_key,
-               krb5_keyblock *encrypting_key,
+return_pw_salt(krb5_context, krb5_pa_data *padata, krb5_db_entry *client,
+               krb5_data *req_pkt, krb5_kdc_req *request, krb5_kdc_rep *reply,
+               krb5_key_data *client_key, krb5_keyblock *encrypting_key,
                krb5_pa_data **send_pa,
-               preauth_get_entry_data_proc get_entry_data,
-               void *pa_system_context,
-               void **pa_request_context);
+               krb5_kdcpreauth_get_data_fn get_entry_data,
+               krb5_kdcpreauth_moddata moddata,
+               krb5_kdcpreauth_modreq modreq);
 
 
 #if APPLE_PKINIT
@@ -227,7 +205,7 @@ static krb5_error_code return_pkinit_response(
     void **pa_request_context);
 #endif /* APPLE_PKINIT */
 
-static krb5_preauth_systems static_preauth_systems[] = {
+static preauth_system static_preauth_systems[] = {
 #if APPLE_PKINIT
     {
         "pkinit",
@@ -239,7 +217,7 @@ static krb5_preauth_systems static_preauth_systems[] = {
         get_pkinit_edata,
         verify_pkinit_request,
         return_pkinit_response,
-        NULL                    /* free_pa_request_context */
+        NULL                    /* free_modreq */
     },
 #endif /* APPLE_PKINIT */
     {
@@ -318,219 +296,168 @@ static krb5_preauth_systems static_preauth_systems[] = {
         return_server_referral
     },
 #endif
-    { "[end]", -1,}
 };
 
-static krb5_preauth_systems *preauth_systems;
-static int n_preauth_systems;
-static struct plugin_dir_handle preauth_plugins;
+#define NUM_STATIC_PREAUTH_SYSTEMS (sizeof(static_preauth_systems) / \
+                                    sizeof(*static_preauth_systems))
 
-/* Open plugin directories for preauth modules. */
-static krb5_error_code
-open_preauth_plugin_dirs(krb5_context ctx)
+static preauth_system *preauth_systems;
+static size_t n_preauth_systems;
+
+/* Get all available kdcpreauth vtables and a count of preauth types they
+ * support.  Return an empty list on failure. */
+static void
+get_plugin_vtables(krb5_context context,
+                   struct krb5_kdcpreauth_vtable_st **vtables_out,
+                   size_t *n_tables_out, size_t *n_systems_out)
 {
-    static const char *path[] = {
-        KRB5_CONF_LIBDEFAULTS, KRB5_CONF_PREAUTH_MODULE_DIR, NULL,
-    };
-    char **profpath = NULL;
-    const char **dirs;
-    krb5_error_code ret;
+    krb5_plugin_initvt_fn *plugins = NULL, *pl;
+    struct krb5_kdcpreauth_vtable_st *vtables;
+    size_t count, n_tables, n_systems, i;
+
+    *vtables_out = NULL;
+    *n_tables_out = *n_systems_out = 0;
+
+    /* Auto-register pkinit and encrypted challenge if possible. */
+    k5_plugin_register_dyn(context, PLUGIN_INTERFACE_KDCPREAUTH, "pkinit",
+                           "preauth");
+    k5_plugin_register_dyn(context, PLUGIN_INTERFACE_KDCPREAUTH,
+                           "encrypted_challenge", "preauth");
 
-    ret = profile_get_values(ctx->profile, path, &profpath);
-    if (ret != 0 && ret != PROF_NO_RELATION)
-        return ret;
-    dirs = (profpath != NULL) ? (const char **) profpath : objdirs;
-    ret = krb5int_open_plugin_dirs(dirs, NULL, &preauth_plugins, &ctx->err);
-    profile_free_list(profpath);
-    return ret;
+    if (k5_plugin_load_all(context, PLUGIN_INTERFACE_KDCPREAUTH, &plugins))
+        return;
+    for (count = 0; plugins[count]; count++);
+    vtables = calloc(count + 1, sizeof(*vtables));
+    if (vtables == NULL)
+        goto cleanup;
+    for (pl = plugins, n_tables = 0; *pl != NULL; pl++) {
+        if ((*pl)(context, 1, 1, (krb5_plugin_vtable)&vtables[n_tables]) == 0)
+            n_tables++;
+    }
+    for (i = 0, n_systems = 0; i < n_tables; i++) {
+        for (count = 0; vtables[i].pa_type_list[count] > 0; count++);
+        n_systems += count;
+    }
+    *vtables_out = vtables;
+    *n_tables_out = n_tables;
+    *n_systems_out = n_systems;
+
+cleanup:
+    k5_plugin_free_modules(context, plugins);
 }
 
-krb5_error_code
-load_preauth_plugins(krb5_context context)
+/* Make a list of realm names.  The caller should free the list container but
+ * not the list elements (which are aliases into kdc_realmlist). */
+static krb5_error_code
+get_realm_names(const char ***list_out)
 {
-    void **preauth_plugins_ftables;
-    struct krb5plugin_preauth_server_ftable_v1 *ftable;
-    size_t module_count, i, j, k;
-    void *plugin_context;
-    preauth_server_init_proc server_init_proc = NULL;
-    char **kdc_realm_names = NULL;
-
-    /* Attempt to load all of the preauth plugins we can find. */
-    PLUGIN_DIR_INIT(&preauth_plugins);
-    if (PLUGIN_DIR_OPEN(&preauth_plugins) == 0) {
-        if (open_preauth_plugin_dirs(context) != 0)
-            return KRB5_PLUGIN_NO_HANDLE;
-    }
-
-    /* Get the method tables provided by the loaded plugins. */
-    preauth_plugins_ftables = NULL;
-    if (krb5int_get_plugin_dir_data(&preauth_plugins,
-                                    "preauthentication_server_1",
-                                    &preauth_plugins_ftables, &context->err) != 0) {
-        return KRB5_PLUGIN_NO_HANDLE;
-    }
-
-    /* Count the valid modules. */
-    module_count = sizeof(static_preauth_systems)
-        / sizeof(static_preauth_systems[0]);
-    if (preauth_plugins_ftables != NULL) {
-        for (i = 0; preauth_plugins_ftables[i] != NULL; i++) {
-            ftable = preauth_plugins_ftables[i];
-            if ((ftable->flags_proc == NULL) &&
-                (ftable->edata_proc == NULL) &&
-                (ftable->verify_proc == NULL) &&
-                (ftable->return_proc == NULL)) {
-                continue;
-            }
-            for (j = 0;
-                 ftable->pa_type_list != NULL &&
-                     ftable->pa_type_list[j] > 0;
-                 j++) {
-                module_count++;
-            }
-        }
-    }
+    const char **list;
+    int i;
 
-    /* Build the complete list of supported preauthentication options, and
-     * leave room for a terminator entry. */
-    preauth_systems = malloc(sizeof(krb5_preauth_systems) * (module_count + 1));
-    if (preauth_systems == NULL) {
-        krb5int_free_plugin_dir_data(preauth_plugins_ftables);
+    list = calloc(kdc_numrealms + 1, sizeof(*list));
+    if (list == NULL)
         return ENOMEM;
-    }
+    for (i = 0; i < kdc_numrealms; i++)
+        list[i] = kdc_realmlist[i]->realm_name;
+    list[i] = NULL;
+    *list_out = list;
+    return 0;
+}
 
-    /* Build a list of the names of the supported realms for this KDC.
-     * The list of names is terminated with a NULL. */
-    kdc_realm_names = malloc(sizeof(char *) * (kdc_numrealms + 1));
-    if (kdc_realm_names == NULL) {
-        krb5int_free_plugin_dir_data(preauth_plugins_ftables);
-        return ENOMEM;
-    }
-    for (i = 0; i < (size_t)kdc_numrealms; i++) {
-        kdc_realm_names[i] = kdc_realmlist[i]->realm_name;
-    }
-    kdc_realm_names[i] = NULL;
+void
+load_preauth_plugins(krb5_context context)
+{
+    krb5_error_code ret;
+    struct krb5_kdcpreauth_vtable_st *vtables = NULL, *vt;
+    size_t n_systems, n_tables, i, j;
+    krb5_kdcpreauth_moddata moddata;
+    const char **realm_names = NULL, *emsg;
+    preauth_system *sys;
+
+    /* Get all available kdcpreauth vtables. */
+    get_plugin_vtables(context, &vtables, &n_tables, &n_systems);
+
+    /* Allocate the list of static and plugin preauth systems. */
+    n_systems += NUM_STATIC_PREAUTH_SYSTEMS;
+    preauth_systems = calloc(n_systems + 1, sizeof(preauth_system));
+    if (preauth_systems == NULL)
+        goto cleanup;
 
-    /* Add the locally-supplied mechanisms to the dynamic list first. */
-    for (i = 0, k = 0;
-         i < sizeof(static_preauth_systems) / sizeof(static_preauth_systems[0]);
-         i++) {
-        if (static_preauth_systems[i].type == -1)
-            break;
-        preauth_systems[k] = static_preauth_systems[i];
-        /* Try to initialize the preauth system.  If it fails, we'll remove it
-         * from the list of systems we'll be using. */
-        plugin_context = NULL;
-        server_init_proc = static_preauth_systems[i].init;
-        if ((server_init_proc != NULL) &&
-            ((*server_init_proc)(context, &plugin_context,
-                                 (const char **)kdc_realm_names) != 0)) {
-            memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
-            continue;
-        }
-        preauth_systems[k].plugin_context = plugin_context;
-        k++;
-    }
-
-    /* Now add the dynamically-loaded mechanisms to the list. */
-    if (preauth_plugins_ftables != NULL) {
-        for (i = 0; preauth_plugins_ftables[i] != NULL; i++) {
-            ftable = preauth_plugins_ftables[i];
-            if ((ftable->flags_proc == NULL) &&
-                (ftable->edata_proc == NULL) &&
-                (ftable->verify_proc == NULL) &&
-                (ftable->return_proc == NULL)) {
+    if (get_realm_names(&realm_names))
+        goto cleanup;
+
+    /* Add the static system to the list first.  No static systems require
+     * initialization, so just make a direct copy. */
+    memcpy(preauth_systems, static_preauth_systems,
+           sizeof(static_preauth_systems));
+
+    /* Add the dynamically-loaded mechanisms to the list. */
+    n_systems = NUM_STATIC_PREAUTH_SYSTEMS;
+    for (i = 0; i < n_tables; i++) {
+        /* Try to initialize this module. */
+        vt = &vtables[i];
+        moddata = NULL;
+        if (vt->init) {
+            ret = vt->init(context, &moddata, realm_names);
+            if (ret) {
+                emsg = krb5_get_error_message(context, ret);
+                krb5_klog_syslog(LOG_ERR, _("preauth %s failed to "
+                                            "initialize: %s"), vt->name, emsg);
+                krb5_free_error_message(context, emsg);
                 continue;
             }
-            plugin_context = NULL;
-            for (j = 0;
-                 ftable->pa_type_list != NULL &&
-                     ftable->pa_type_list[j] > 0;
-                 j++) {
-                /* Try to initialize the plugin.  If it fails, we'll remove it
-                 * from the list of modules we'll be using. */
-                if (j == 0) {
-                    server_init_proc = ftable->init_proc;
-                    if (server_init_proc != NULL) {
-                        krb5_error_code initerr;
-                        initerr = (*server_init_proc)(context, &plugin_context,
-                                                      (const char **)kdc_realm_names);
-                        if (initerr) {
-                            const char *emsg;
-                            emsg = krb5_get_error_message(context, initerr);
-                            krb5_klog_syslog(LOG_ERR, _("preauth %s failed to "
-                                                        "initialize: %s"),
-                                             ftable->name, emsg);
-                            krb5_free_error_message(context, emsg);
-                            memset(&preauth_systems[k], 0,
-                                   sizeof(preauth_systems[k]));
-
-                            break;      /* skip all modules in this plugin */
-                        }
-                    }
-                }
-                preauth_systems[k].name = ftable->name;
-                preauth_systems[k].type = ftable->pa_type_list[j];
-                if (ftable->flags_proc != NULL)
-                    preauth_systems[k].flags = ftable->flags_proc(context,
-                                                                  preauth_systems[k].type);
-                else
-                    preauth_systems[k].flags = 0;
-                preauth_systems[k].plugin_context = plugin_context;
-                preauth_systems[k].init = server_init_proc;
-                /* Only call fini once for each plugin */
-                if (j == 0)
-                    preauth_systems[k].fini = ftable->fini_proc;
-                else
-                    preauth_systems[k].fini = NULL;
-                preauth_systems[k].get_edata = ftable->edata_proc;
-                preauth_systems[k].verify_padata = ftable->verify_proc;
-                preauth_systems[k].return_padata = ftable->return_proc;
-                preauth_systems[k].free_pa_reqctx =
-                    ftable->freepa_reqcontext_proc;
-                k++;
-            }
         }
-        krb5int_free_plugin_dir_data(preauth_plugins_ftables);
+        /* Add this module to the systems list once for each pa type. */
+        for (j = 0; vt->pa_type_list[j] > 0; j++) {
+            sys = &preauth_systems[n_systems];
+            sys->name = vt->name;
+            sys->type = vt->pa_type_list[j];
+            sys->flags = (vt->flags) ? vt->flags(context, sys->type) : 0;
+            sys->moddata = moddata;
+            sys->init = vt->init;
+            /* Only call fini once for each plugin. */
+            sys->fini = (j == 0) ? vt->fini : NULL;
+            sys->get_edata = vt->edata;
+            sys->verify_padata = vt->verify;
+            sys->return_padata = vt->return_padata;
+            sys->free_modreq = vt->free_modreq;
+            n_systems++;
+        }
     }
-    free(kdc_realm_names);
-    n_preauth_systems = k;
+    n_preauth_systems = n_systems;
     /* Add the end-of-list marker. */
-    preauth_systems[k].name = "[end]";
-    preauth_systems[k].type = -1;
-    return 0;
+    preauth_systems[n_systems].name = "[end]";
+    preauth_systems[n_systems].type = -1;
+
+cleanup:
+    free(vtables);
+    free(realm_names);
 }
 
-krb5_error_code
+void
 unload_preauth_plugins(krb5_context context)
 {
-    int i;
-    if (preauth_systems != NULL) {
-        for (i = 0; i < n_preauth_systems; i++) {
-            if (preauth_systems[i].fini != NULL) {
-                (*preauth_systems[i].fini)(context,
-                                           preauth_systems[i].plugin_context);
-            }
-            memset(&preauth_systems[i], 0, sizeof(preauth_systems[i]));
-        }
-        free(preauth_systems);
-        preauth_systems = NULL;
-        n_preauth_systems = 0;
-        krb5int_close_plugin_dirs(&preauth_plugins);
+    size_t i;
+
+    for (i = 0; i < n_preauth_systems; i++) {
+        if (preauth_systems[i].fini)
+            preauth_systems[i].fini(context, preauth_systems[i].moddata);
     }
-    return 0;
+    free(preauth_systems);
+    preauth_systems = NULL;
+    n_preauth_systems = 0;
 }
 
 /*
- * The make_padata_context() function creates a space for storing any context
- * information which will be needed by return_padata() later.  Each preauth
- * type gets a context storage location of its own.
+ * The make_padata_context() function creates a space for storing any
+ * request-specific module data which will be needed by return_padata() later.
+ * Each preauth type gets a storage location of its own.
  */
 struct request_pa_context {
     int n_contexts;
     struct {
-        krb5_preauth_systems *pa_system;
-        void *pa_context;
+        preauth_system *pa_system;
+        krb5_kdcpreauth_modreq modreq;
     } *contexts;
 };
 
@@ -556,7 +483,7 @@ make_padata_context(krb5_context context, void **padata_context)
 
     for (i = 0; i < ret->n_contexts; i++) {
         ret->contexts[i].pa_system = &preauth_systems[i];
-        ret->contexts[i].pa_context = NULL;
+        ret->contexts[i].modreq = NULL;
     }
 
     *padata_context = ret;
@@ -569,35 +496,25 @@ make_padata_context(krb5_context context, void **padata_context)
  * which the check_padata() function created but which weren't already cleaned
  * up by return_padata().
  */
-krb5_error_code
-free_padata_context(krb5_context kcontext, void **padata_context)
+void
+free_padata_context(krb5_context kcontext, void *padata_context)
 {
-    struct request_pa_context *context;
-    krb5_preauth_systems *preauth_system;
-    void **pctx, *mctx;
+    struct request_pa_context *context = padata_context;
+    preauth_system *sys;
     int i;
 
-    if (padata_context == NULL)
-        return 0;
-
-    context = *padata_context;
-
+    if (context == NULL)
+        return;
     for (i = 0; i < context->n_contexts; i++) {
-        if (context->contexts[i].pa_context != NULL) {
-            preauth_system = context->contexts[i].pa_system;
-            mctx = preauth_system->plugin_context;
-            if (preauth_system->free_pa_reqctx != NULL) {
-                pctx = &context->contexts[i].pa_context;
-                (*preauth_system->free_pa_reqctx)(kcontext, mctx, pctx);
-            }
-            context->contexts[i].pa_context = NULL;
-        }
+        sys = context->contexts[i].pa_system;
+        if (!sys->free_modreq || !context->contexts[i].modreq)
+            continue;
+        sys->free_modreq(kcontext, sys->moddata, context->contexts[i].modreq);
+        context->contexts[i].modreq = NULL;
     }
 
     free(context->contexts);
     free(context);
-
-    return 0;
 }
 
 /* Retrieve a specified tl_data item from the given entry, and return its
@@ -637,10 +554,8 @@ get_entry_tl_data(krb5_context context, krb5_db_entry *entry,
  * modules.
  */
 static krb5_error_code
-get_entry_data(krb5_context context,
-               krb5_kdc_req *request, krb5_db_entry *entry,
-               krb5_int32  type,
-               krb5_data **result)
+get_entry_data(krb5_context context, krb5_kdc_req *request,
+               krb5_db_entry *entry, krb5_int32 type, krb5_data **result)
 {
     int i, k;
     krb5_data *ret;
@@ -651,11 +566,11 @@ get_entry_data(krb5_context context,
     struct kdc_request_state *state = request->kdc_state;
 
     switch (type) {
-    case krb5plugin_preauth_entry_request_certificate:
+    case krb5_kdcpreauth_request_certificate:
         return get_entry_tl_data(context, entry,
                                  KRB5_TL_USER_CERTIFICATE, result);
         break;
-    case krb5plugin_preauth_entry_max_time_skew:
+    case krb5_kdcpreauth_max_time_skew:
         ret = malloc(sizeof(krb5_data));
         if (ret == NULL)
             return ENOMEM;
@@ -670,7 +585,7 @@ get_entry_data(krb5_context context,
         *result = ret;
         return 0;
         break;
-    case krb5plugin_preauth_keys:
+    case krb5_kdcpreauth_keys:
         ret = malloc(sizeof(krb5_data));
         if (ret == NULL)
             return ENOMEM;
@@ -705,7 +620,7 @@ get_entry_data(krb5_context context,
             free(ret);
         }
         break;
-    case krb5plugin_preauth_request_body:
+    case krb5_kdcpreauth_request_body:
         ret = NULL;
         encode_krb5_kdc_req_body(request, &ret);
         if (ret != NULL) {
@@ -714,7 +629,7 @@ get_entry_data(krb5_context context,
         }
         return ASN1_PARSE_ERROR;
         break;
-    case krb5plugin_preauth_fast_armor:
+    case krb5_kdcpreauth_fast_armor:
         ret = calloc(1, sizeof(krb5_data));
         if (ret == NULL)
             return ENOMEM;
@@ -731,7 +646,7 @@ get_entry_data(krb5_context context,
         }
         free(ret);
         return error;
-    case krb5plugin_preauth_free_fast_armor:
+    case krb5_kdcpreauth_free_fast_armor:
         if ((*result)->data) {
             keys = (krb5_keyblock *) (*result)->data;
             krb5_free_keyblock(context, keys);
@@ -745,9 +660,9 @@ get_entry_data(krb5_context context,
 }
 
 static krb5_error_code
-find_pa_system(int type, krb5_preauth_systems **preauth)
+find_pa_system(int type, preauth_system **preauth)
 {
-    krb5_preauth_systems *ap;
+    preauth_system *ap;
 
     ap = preauth_systems ? preauth_systems : static_preauth_systems;
     while ((ap->type != -1) && (ap->type != type))
@@ -758,21 +673,20 @@ find_pa_system(int type, krb5_preauth_systems **preauth)
     return 0;
 }
 
+/* Find a pointer to the request-specific module data for pa_sys. */
 static krb5_error_code
-find_pa_context(krb5_preauth_systems *pa_sys,
-                struct request_pa_context *context,
-                void ***pa_context)
+find_modreq(preauth_system *pa_sys, struct request_pa_context *context,
+            krb5_kdcpreauth_modreq **modreq_out)
 {
     int i;
 
-    *pa_context = 0;
-
+    *modreq_out = NULL;
     if (context == NULL)
         return KRB5KRB_ERR_GENERIC;
 
     for (i = 0; i < context->n_contexts; i++) {
         if (context->contexts[i].pa_system == pa_sys) {
-            *pa_context = &context->contexts[i].pa_context;
+            *modreq_out = &context->contexts[i].modreq;
             return 0;
         }
     }
@@ -797,7 +711,7 @@ pa_list_includes(krb5_pa_data **pa_data, krb5_preauthtype pa_type)
 static void
 sort_pa_order(krb5_context context, krb5_kdc_req *request, int *pa_order)
 {
-    int i, j, k, n_repliers, n_key_replacers;
+    size_t i, j, k, n_repliers, n_key_replacers;
 
     /* First, set up the default order. */
     i = 0;
@@ -909,7 +823,7 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
                       krb5_db_entry *server, krb5_data *e_data)
 {
     int hw_only;
-    krb5_preauth_systems *ap;
+    preauth_system *ap;
     krb5_pa_data **pa_data, **pa;
     krb5_data *edat;
     krb5_error_code retval;
@@ -937,8 +851,8 @@ get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
         (*pa)->magic = KV5M_PA_DATA;
         (*pa)->pa_type = ap->type;
         if (ap->get_edata) {
-            retval = (ap->get_edata)(kdc_context, request, client, server,
-                                     get_entry_data, ap->plugin_context, *pa);
+            retval = ap->get_edata(kdc_context, request, client, server,
+                                   get_entry_data, ap->moddata, *pa);
             if (retval) {
                 /* just failed on this type, continue */
                 free(*pa);
@@ -1033,8 +947,8 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
 {
     krb5_error_code retval = 0;
     krb5_pa_data **padata;
-    krb5_preauth_systems *pa_sys;
-    void **pa_context;
+    preauth_system *pa_sys;
+    krb5_kdcpreauth_modreq *modreq_ptr;
     krb5_data *pa_e_data = NULL, *tmp_e_data = NULL;
     int pa_ok = 0, pa_found = 0;
     krb5_error_code saved_retval = 0;
@@ -1058,7 +972,7 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
 #endif
         if (find_pa_system((*padata)->pa_type, &pa_sys))
             continue;
-        if (find_pa_context(pa_sys, *padata_context, &pa_context))
+        if (find_modreq(pa_sys, *padata_context, &modreq_ptr))
             continue;
 #ifdef DEBUG
         krb5_klog_syslog (LOG_DEBUG, ".. pa_type %s", pa_sys->name);
@@ -1068,8 +982,9 @@ check_padata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
         pa_found++;
         retval = pa_sys->verify_padata(context, client, req_pkt, request,
                                        enc_tkt_reply, *padata,
-                                       get_entry_data, pa_sys->plugin_context,
-                                       pa_context, &tmp_e_data, &tmp_authz_data);
+                                       get_entry_data, pa_sys->moddata,
+                                       modreq_ptr, &tmp_e_data,
+                                       &tmp_authz_data);
         if (retval) {
             emsg = krb5_get_error_message (context, retval);
             krb5_klog_syslog (LOG_INFO, "preauth (%s) verify failure: %s",
@@ -1211,11 +1126,11 @@ return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
     krb5_pa_data **             send_pa;
     krb5_pa_data *              pa = 0;
     krb5_pa_data null_item;
-    krb5_preauth_systems *      ap;
+    preauth_system *            ap;
     int *                       pa_order;
     int *                       pa_type;
     int                         size = 0;
-    void **                     pa_context;
+    krb5_kdcpreauth_modreq      *modreq_ptr;
     krb5_boolean                key_modified;
     krb5_keyblock               original_key;
     if ((!*padata_context) &&
@@ -1265,7 +1180,7 @@ return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
             continue;
         if (ap->return_padata == 0)
             continue;
-        if (find_pa_context(ap, *padata_context, &pa_context))
+        if (find_modreq(ap, *padata_context, &modreq_ptr))
             continue;
         pa = &null_item;
         null_item.pa_type = ap->type;
@@ -1280,8 +1195,8 @@ return_padata(krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
         if ((retval = ap->return_padata(context, pa, client, req_pkt,
                                         request, reply,
                                         client_key, encrypting_key, send_pa,
-                                        get_entry_data, ap->plugin_context,
-                                        pa_context))) {
+                                        get_entry_data, ap->moddata,
+                                        *modreq_ptr))) {
             goto cleanup;
         }
 
@@ -1320,9 +1235,8 @@ request_contains_enctype(krb5_context context,  const krb5_kdc_req *request,
 static krb5_error_code
 get_enc_ts(krb5_context context, krb5_kdc_req *request,
            krb5_db_entry *client, krb5_db_entry *server,
-           preauth_get_entry_data_proc get_entry_data_proc,
-           void *pa_system_context,
-           krb5_pa_data *data)
+           krb5_kdcpreauth_get_data_fn get_entry_data_proc,
+           krb5_kdcpreauth_moddata moddata, krb5_pa_data *data)
 {
     struct kdc_request_state *state = request->kdc_state;
     if (state->armor_key)
@@ -1333,12 +1247,11 @@ get_enc_ts(krb5_context context, krb5_kdc_req *request,
 
 static krb5_error_code
 verify_enc_timestamp(krb5_context context, krb5_db_entry *client,
-                     krb5_data *req_pkt,
-                     krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply,
-                     krb5_pa_data *pa,
-                     preauth_get_entry_data_proc ets_get_entry_data,
-                     void *pa_system_context,
-                     void **pa_request_context,
+                     krb5_data *req_pkt, krb5_kdc_req *request,
+                     krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *pa,
+                     krb5_kdcpreauth_get_data_fn ets_get_entry_data,
+                     krb5_kdcpreauth_moddata moddata,
+                     krb5_kdcpreauth_modreq *modreq_out,
                      krb5_data **e_data,
                      krb5_authdata ***authz_data)
 {
@@ -1580,9 +1493,8 @@ cleanup:
 static krb5_error_code
 get_etype_info(krb5_context context, krb5_kdc_req *request,
                krb5_db_entry *client, krb5_db_entry *server,
-               preauth_get_entry_data_proc etype_get_entry_data,
-               void *pa_system_context,
-               krb5_pa_data *pa_data)
+               krb5_kdcpreauth_get_data_fn etype_get_entry_data,
+               krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data)
 {
     int i;
     for (i=0;  i < request->nktypes; i++) {
@@ -1597,9 +1509,8 @@ get_etype_info(krb5_context context, krb5_kdc_req *request,
 static krb5_error_code
 get_etype_info2(krb5_context context, krb5_kdc_req *request,
                 krb5_db_entry *client, krb5_db_entry *server,
-                preauth_get_entry_data_proc etype_get_entry_data,
-                void *pa_system_context,
-                krb5_pa_data *pa_data)
+                krb5_kdcpreauth_get_data_fn etype_get_entry_data,
+                krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data)
 {
     return etype_info_helper( context, request, client, server, pa_data, 1);
 }
@@ -1689,9 +1600,9 @@ return_etype_info2(krb5_context context, krb5_pa_data * padata,
                    krb5_key_data *client_key,
                    krb5_keyblock *encrypting_key,
                    krb5_pa_data **send_pa,
-                   preauth_get_entry_data_proc etype_get_entry_data,
-                   void *pa_system_context,
-                   void **pa_request_context)
+                   krb5_kdcpreauth_get_data_fn etype_get_entry_data,
+                   krb5_kdcpreauth_moddata moddata,
+                   krb5_kdcpreauth_modreq modreq)
 {
     return etype_info_as_rep_helper(context, padata, client, request, reply,
                                     client_key, encrypting_key, send_pa, 1);
@@ -1706,9 +1617,9 @@ return_etype_info(krb5_context context, krb5_pa_data * padata,
                   krb5_key_data *client_key,
                   krb5_keyblock *encrypting_key,
                   krb5_pa_data **send_pa,
-                  preauth_get_entry_data_proc etypeget_entry_data,
-                  void *pa_system_context,
-                  void **pa_request_context)
+                  krb5_kdcpreauth_get_data_fn etypeget_entry_data,
+                  krb5_kdcpreauth_moddata moddata,
+                  krb5_kdcpreauth_modreq modreq)
 {
     return etype_info_as_rep_helper(context, padata, client, request, reply,
                                     client_key, encrypting_key, send_pa, 0);
@@ -1716,12 +1627,13 @@ return_etype_info(krb5_context context, krb5_pa_data * padata,
 
 static krb5_error_code
 return_pw_salt(krb5_context context, krb5_pa_data *in_padata,
-               krb5_db_entry *client, krb5_data *req_pkt, krb5_kdc_req *request,
-               krb5_kdc_rep *reply, krb5_key_data *client_key,
-               krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
-               preauth_get_entry_data_proc etype_get_entry_data,
-               void *pa_system_context,
-               void **pa_request_context)
+               krb5_db_entry *client, krb5_data *req_pkt,
+               krb5_kdc_req *request, krb5_kdc_rep *reply,
+               krb5_key_data *client_key, krb5_keyblock *encrypting_key,
+               krb5_pa_data **send_pa,
+               krb5_kdcpreauth_get_data_fn etype_get_entry_data,
+               krb5_kdcpreauth_moddata moddata,
+               krb5_kdcpreauth_modreq modreq)
 {
     krb5_error_code     retval;
     krb5_pa_data *      padata;
index 2f85b0274ea3c9f39d0141369912100cac595467..20e8ac46dd0fcad2b92e62d0140a4b3488a40608 100644 (file)
@@ -170,9 +170,9 @@ get_preauth_hint_list (krb5_kdc_req * request,
                        krb5_db_entry *client,
                        krb5_db_entry *server,
                        krb5_data *e_data);
-krb5_error_code
+void
 load_preauth_plugins(krb5_context context);
-krb5_error_code
+void
 unload_preauth_plugins(krb5_context context);
 
 krb5_error_code
@@ -189,8 +189,8 @@ return_padata (krb5_context context, krb5_db_entry *client,
                krb5_key_data *client_key, krb5_keyblock *encrypting_key,
                void **padata_context);
 
-krb5_error_code
-free_padata_context (krb5_context context, void **padata_context);
+void
+free_padata_context(krb5_context context, void *padata_context);
 
 krb5_pa_data *
 find_pa_data (krb5_pa_data **padata, krb5_preauthtype pa_type);
index c5247211908843b1fde969377076c2f43b7f89fe..9d2c3e4918f2863776a693832eeeff9a523cfe7b 100644 (file)
@@ -79,9 +79,6 @@ krb5_copy_context(krb5_context ctx, krb5_context *nctx_out)
     nctx->prompt_types = NULL;
     nctx->os_context.default_ccname = NULL;
 
-    memset(&nctx->preauth_plugins, 0, sizeof(nctx->preauth_plugins));
-    nctx->preauth_context = NULL;
-
     memset(&nctx->libkrb5_plugins, 0, sizeof(nctx->libkrb5_plugins));
     nctx->vtbl = NULL;
     nctx->locate_fptrs = NULL;
index fc00e21d7b3d9406c1c0d8356f2593b7a363fc47..2968bd7ba01d6995ed0b8f269caed4441bd0befe 100644 (file)
@@ -705,7 +705,7 @@ restart_init_creds_loop(krb5_context context, krb5_init_creds_context ctx,
     code = krb5int_fast_make_state(context, &ctx->fast_state);
     if (code != 0)
         goto cleanup;
-    ctx->get_data_rock.fast_state = ctx->fast_state;
+    ctx->preauth_rock.fast_state = ctx->fast_state;
     krb5_preauth_request_context_init(context);
     if (ctx->encoded_request_body) {
         krb5_free_data(context, ctx->encoded_request_body);
@@ -837,8 +837,8 @@ krb5_init_creds_init(krb5_context context,
 
     opte = ctx->opte;
 
-    ctx->get_data_rock.magic = CLIENT_ROCK_MAGIC;
-    ctx->get_data_rock.etype = &ctx->etype;
+    ctx->preauth_rock.magic = CLIENT_ROCK_MAGIC;
+    ctx->preauth_rock.etype = &ctx->etype;
 
     /* Initialise request parameters as per krb5_get_init_creds() */
     ctx->request->kdc_options = context->kdc_default_options;
@@ -1116,7 +1116,7 @@ init_creds_step_request(krb5_context context,
                                ctx->prompter_data,
                                ctx->gak_fct,
                                ctx->gak_data,
-                               &ctx->get_data_rock,
+                               &ctx->preauth_rock,
                                ctx->opte);
         if (code != 0)
             goto cleanup;
@@ -1141,7 +1141,7 @@ init_creds_step_request(krb5_context context,
                                             ctx->prompter_data,
                                             ctx->gak_fct,
                                             ctx->gak_data,
-                                            &ctx->get_data_rock,
+                                            &ctx->preauth_rock,
                                             ctx->opte);
         } else {
             /* No preauth supplied, so can't query the plugins. */
@@ -1373,7 +1373,7 @@ init_creds_step_reply(krb5_context context,
                            ctx->prompter_data,
                            ctx->gak_fct,
                            ctx->gak_data,
-                           &ctx->get_data_rock,
+                           &ctx->preauth_rock,
                            ctx->opte);
     if (code != 0)
         goto cleanup;
index a60cc3b2f31e4e9d31ed26c04e3217d0a27f6a6d..1e79c4232982952edf48f85779d5626337bbc881 100644 (file)
@@ -97,50 +97,3 @@ krb5_get_init_creds_opt_set_pa(krb5_context context,
     retval = krb5_preauth_supply_preauth_data(context, opte, attr, value);
     return retval;
 }
-
-/*
- * Give all the preauth plugins a look at the preauth option which
- * has just been set
- */
-krb5_error_code
-krb5_preauth_supply_preauth_data(krb5_context context,
-                                 krb5_gic_opt_ext *opte,
-                                 const char *attr,
-                                 const char *value)
-{
-    krb5_error_code retval = 0;
-    int i;
-    void *pctx;
-    const char *emsg = NULL;
-
-    if (context->preauth_context == NULL)
-        krb5_init_preauth_context(context);
-    if (context->preauth_context == NULL) {
-        retval = EINVAL;
-        krb5int_set_error(&context->err, retval,
-                          _("Unable to initialize preauth context"));
-        return retval;
-    }
-
-    /*
-     * Go down the list of preauth modules, and supply them with the
-     * attribute/value pair.
-     */
-    for (i = 0; i < context->preauth_context->n_modules; i++) {
-        if (context->preauth_context->modules[i].client_supply_gic_opts == NULL)
-            continue;
-        pctx = context->preauth_context->modules[i].plugin_context;
-        retval = (*context->preauth_context->modules[i].client_supply_gic_opts)
-            (context, pctx,
-             (krb5_get_init_creds_opt *)opte, attr, value);
-        if (retval) {
-            emsg = krb5_get_error_message(context, retval);
-            krb5int_set_error(&context->err, retval,
-                              _("Preauth plugin %s: %s"),
-                              context->preauth_context->modules[i].name, emsg);
-            krb5_free_error_message(context, emsg);
-            break;
-        }
-    }
-    return retval;
-}
index 6a762982c0b7fbe10a6e7e1e157463f2e7083313..de43163d85f134f61cf142cb44d827c4929c3e6f 100644 (file)
@@ -29,7 +29,7 @@ struct _krb5_init_creds_context {
     krb5_data s2kparams;
     krb5_keyblock as_key;
     krb5_enctype etype;
-    krb5_preauth_client_rock get_data_rock;
+    struct krb5_clpreauth_rock_st preauth_rock;
     krb5_boolean enc_pa_rep_permitted;
     krb5_boolean have_restarted;
     krb5_boolean sent_nontrivial_preauth;
index a9d6b06a7be7d2bc571eb91be85e50492a935d1c..6f164e0a6857feddba5a312be88ef092a07ac54a 100644 (file)
@@ -28,7 +28,9 @@
 
 const char *interface_names[PLUGIN_NUM_INTERFACES] = {
     "pwqual",
-    "kadm5_hook"
+    "kadm5_hook",
+    "clpreauth",
+    "kdcpreauth"
 };
 
 /* Return the context's interface structure for id, or NULL if invalid. */
index 82b422eac8c4382747d271b7776f23e042908d03..ef866b1a2437909d891ef94f0925af710647faac 100644 (file)
 #include <unistd.h>
 #endif
 
-#if TARGET_OS_MAC
-static const char *objdirs[] = { KRB5_PLUGIN_BUNDLE_DIR,
-                                 LIBDIR "/krb5/plugins/preauth",
-                                 NULL };
-#else
-static const char *objdirs[] = { LIBDIR "/krb5/plugins/preauth", NULL };
-#endif
+/* This structure lets us keep track of all of the modules which are loaded,
+ * turning the list of modules and their lists of implemented preauth types
+ * into a single list which we can walk easily. */
+struct krb5_preauth_context_st {
+    int n_modules;
+    struct krb5_preauth_context_module_st {
+        /* Which of the possibly more than one preauth types which the
+         * module supports we're using at this point in the list. */
+        krb5_preauthtype pa_type;
+        /* Encryption types which the client claims to support -- we
+         * copy them directly into the krb5_kdc_req structure during
+         * krb5_preauth_prepare_request(). */
+        krb5_enctype *enctypes;
+        /* The plugin's module data and a function to clear it. */
+        krb5_clpreauth_moddata moddata;
+        krb5_clpreauth_fini_fn client_fini;
+        /* The module's table, and some of its members, copied here for
+         * convenience when we populated the list. */
+        const char *name;
+        int flags, use_count;
+        krb5_clpreauth_process_fn client_process;
+        krb5_clpreauth_tryagain_fn client_tryagain;
+        krb5_clpreauth_supply_gic_opts_fn client_supply_gic_opts;
+        krb5_clpreauth_request_init_fn client_req_init;
+        krb5_clpreauth_request_fini_fn client_req_fini;
+        /* The per-request context which the client_req_init() function
+         * might allocate, which we'll need to clean up later by
+         * calling the client_req_fini() function. */
+        krb5_clpreauth_modreq modreq;
+        /* A pointer to the request_context pointer.  All modules within
+         * a plugin will point at the request_context of the first
+         * module within the plugin. */
+        krb5_clpreauth_modreq *modreq_p;
+    } *modules;
+};
 
 typedef krb5_error_code (*pa_function)(krb5_context,
                                        krb5_kdc_req *request,
@@ -70,27 +98,6 @@ typedef struct _pa_types_t {
     int flags;
 } pa_types_t;
 
-/* Open plugin directories for preauth modules. */
-static krb5_error_code
-open_preauth_plugin_dirs(krb5_context ctx)
-{
-    static const char *path[] = {
-        KRB5_CONF_LIBDEFAULTS, KRB5_CONF_PREAUTH_MODULE_DIR, NULL,
-    };
-    char **profpath = NULL;
-    const char **dirs;
-    krb5_error_code ret;
-
-    ret = profile_get_values(ctx->profile, path, &profpath);
-    if (ret != 0 && ret != PROF_NO_RELATION)
-        return ret;
-    dirs = (profpath != NULL) ? (const char **) profpath : objdirs;
-    ret = krb5int_open_plugin_dirs(dirs, NULL, &ctx->preauth_plugins,
-                                   &ctx->err);
-    profile_free_list(profpath);
-    return ret;
-}
-
 /* Create the per-krb5_context context. This means loading the modules
  * if we haven't done that yet (applications which never obtain initial
  * credentials should never hit this routine), breaking up the module's
@@ -99,101 +106,88 @@ open_preauth_plugin_dirs(krb5_context ctx)
 void KRB5_CALLCONV
 krb5_init_preauth_context(krb5_context kcontext)
 {
-    int n_modules, n_tables, i, j, k;
-    void **tables;
-    struct krb5plugin_preauth_client_ftable_v1 *table;
+    int n_tables, n_modules, i, count;
+    krb5_plugin_initvt_fn *plugins = NULL, *pl;
+    struct krb5_clpreauth_vtable_st *vtables = NULL, *vt;
+    struct krb5_preauth_context_module_st *mod;
     krb5_preauth_context *context = NULL;
-    void *plugin_context;
-    krb5_preauthtype pa_type;
-    void **rcpp;
+    krb5_clpreauth_moddata moddata;
+    krb5_preauthtype pa_type, *pat;
+    krb5_boolean first;
+    krb5_clpreauth_modreq *rcpp;
 
     /* Only do this once for each krb5_context */
     if (kcontext->preauth_context != NULL)
         return;
 
-    /* load the plugins for the current context */
-    if (PLUGIN_DIR_OPEN(&kcontext->preauth_plugins) == 0) {
-        if (open_preauth_plugin_dirs(kcontext) != 0)
-            return;
-    }
+    /* Auto-register pkinit and encrypted challenge if possible. */
+    k5_plugin_register_dyn(kcontext, PLUGIN_INTERFACE_CLPREAUTH, "pkinit",
+                           "preauth");
+    k5_plugin_register_dyn(kcontext, PLUGIN_INTERFACE_CLPREAUTH,
+                           "encrypted_challenge", "preauth");
 
-    /* pull out the module function tables for all of the modules */
-    tables = NULL;
-    if (krb5int_get_plugin_dir_data(&kcontext->preauth_plugins,
-                                    "preauthentication_client_1",
-                                    &tables,
-                                    &kcontext->err) != 0) {
-        return;
-    }
-    if (tables == NULL) {
+    /* Get all available clpreauth vtables. */
+    if (k5_plugin_load_all(kcontext, PLUGIN_INTERFACE_CLPREAUTH, &plugins))
         return;
+    for (count = 0; plugins[count] != NULL; count++);
+    vtables = calloc(count, sizeof(*vtables));
+    if (vtables == NULL)
+        goto cleanup;
+    for (pl = plugins, n_tables = 0; *pl != NULL; pl++) {
+        if ((*pl)(kcontext, 1, 1, (krb5_plugin_vtable)&vtables[n_tables]) == 0)
+            n_tables++;
     }
 
-    /* count how many modules we ended up loading, and how many preauth
-     * types we may claim to support as a result */
+    /* Count how many modules we ended up loading, and how many preauth
+     * types we may claim to support as a result. */
     n_modules = 0;
-    for (n_tables = 0;
-         (tables != NULL) && (tables[n_tables] != NULL);
-         n_tables++) {
-        table = tables[n_tables];
-        if ((table->pa_type_list != NULL) && (table->process != NULL)) {
-            for (j = 0; table->pa_type_list[j] > 0; j++) {
-                n_modules++;
-            }
-        }
+    for (i = 0; i < n_tables; i++) {
+        for (count = 0; vtables[i].pa_type_list[count] > 0; count++);
+        n_modules += count;
     }
 
-    /* allocate the space we need */
+    /* Allocate the space we need. */
     context = malloc(sizeof(*context));
-    if (context == NULL) {
-        krb5int_free_plugin_dir_data(tables);
-        return;
-    }
-    context->modules = calloc(n_modules, sizeof(context->modules[0]));
-    if (context->modules == NULL) {
-        krb5int_free_plugin_dir_data(tables);
-        free(context);
-        return;
-    }
-    context->n_modules = n_modules;
+    if (context == NULL)
+        goto cleanup;
+    context->modules = calloc(n_modules, sizeof(*context->modules));
+    if (context->modules == NULL)
+        goto cleanup;
 
     /* fill in the structure */
-    k = 0;
+    n_modules = 0;
     for (i = 0; i < n_tables; i++) {
-        table = tables[i];
-        if ((table->pa_type_list != NULL) && (table->process != NULL)) {
-            plugin_context = NULL;
-            if ((table->init != NULL) &&
-                ((*table->init)(kcontext, &plugin_context) != 0)) {
+        vt = &vtables[i];
+        if ((vt->pa_type_list != NULL) && (vt->process != NULL)) {
+            moddata = NULL;
+            if (vt->init != NULL && vt->init(kcontext, &moddata) != 0) {
 #ifdef DEBUG
-                fprintf (stderr, "init err, skipping module \"%s\"\n",
-                         table->name);
+                fprintf(stderr, "init err, skipping module \"%s\"\n",
+                        vt->name);
 #endif
                 continue;
             }
 
             rcpp = NULL;
-            for (j = 0; table->pa_type_list[j] > 0; j++) {
-                pa_type = table->pa_type_list[j];
-                context->modules[k].pa_type = pa_type;
-                context->modules[k].enctypes = table->enctype_list;
-                context->modules[k].plugin_context = plugin_context;
+            for (pat = vt->pa_type_list, first = TRUE; *pat > 0;
+                 pat++, first = FALSE) {
+                pa_type = *pat;
+                mod = &context->modules[n_modules];
+                mod->pa_type = pa_type;
+                mod->enctypes = vt->enctype_list;
+                mod->moddata = moddata;
                 /* Only call client_fini once per plugin */
-                if (j == 0)
-                    context->modules[k].client_fini = table->fini;
-                else
-                    context->modules[k].client_fini = NULL;
-                context->modules[k].ftable = table;
-                context->modules[k].name = table->name;
-                context->modules[k].flags = (*table->flags)(kcontext, pa_type);
-                context->modules[k].use_count = 0;
-                context->modules[k].client_process = table->process;
-                context->modules[k].client_tryagain = table->tryagain;
-                if (j == 0)
-                    context->modules[k].client_supply_gic_opts = table->gic_opts;
+                if (first)
+                    mod->client_fini = vt->fini;
                 else
-                    context->modules[k].client_supply_gic_opts = NULL;
-                context->modules[k].request_context = NULL;
+                    mod->client_fini = NULL;
+                mod->name = vt->name;
+                mod->flags = (*vt->flags)(kcontext, pa_type);
+                mod->use_count = 0;
+                mod->client_process = vt->process;
+                mod->client_tryagain = vt->tryagain;
+                mod->client_supply_gic_opts = first ? vt->gic_opts : NULL;
+                mod->modreq = NULL;
                 /*
                  * Only call request_init and request_fini once per plugin.
                  * Only the first module within each plugin will ever
@@ -202,29 +196,35 @@ krb5_init_preauth_context(krb5_context kcontext)
                  * to that entry's request_context.  That way all the
                  * modules within the plugin share the same request_context
                  */
-                if (j == 0) {
-                    context->modules[k].client_req_init = table->request_init;
-                    context->modules[k].client_req_fini = table->request_fini;
-                    rcpp = &context->modules[k].request_context;
+                if (first) {
+                    mod->client_req_init = vt->request_init;
+                    mod->client_req_fini = vt->request_fini;
+                    rcpp = &mod->modreq;
                 } else {
-                    context->modules[k].client_req_init = NULL;
-                    context->modules[k].client_req_fini = NULL;
+                    mod->client_req_init = NULL;
+                    mod->client_req_fini = NULL;
                 }
-                context->modules[k].request_context_pp = rcpp;
+                mod->modreq_p = rcpp;
 #ifdef DEBUG
-                fprintf (stderr, "init module \"%s\", pa_type %d, flag %d\n",
-                         context->modules[k].name,
-                         context->modules[k].pa_type,
-                         context->modules[k].flags);
+                fprintf(stderr, "init module \"%s\", pa_type %d, flag %d\n",
+                        mod->name, mod->pa_type, mod->flags);
 #endif
-                k++;
+                n_modules++;
             }
         }
     }
-    krb5int_free_plugin_dir_data(tables);
+    context->n_modules = n_modules;
 
-    /* return the result */
+    /* Place the constructed preauth context into the krb5 context. */
     kcontext->preauth_context = context;
+    context = NULL;
+
+cleanup:
+    if (context)
+        free(context->modules);
+    free(context);
+    k5_plugin_free_modules(kcontext, plugins);
+    free(vtables);
 }
 
 /* Zero the use counts for the modules herein.  Usually used before we
@@ -249,23 +249,19 @@ void KRB5_CALLCONV
 krb5_free_preauth_context(krb5_context context)
 {
     int i;
-    void *pctx;
-    if (context && context->preauth_context != NULL) {
-        for (i = 0; i < context->preauth_context->n_modules; i++) {
-            pctx = context->preauth_context->modules[i].plugin_context;
-            if (context->preauth_context->modules[i].client_fini != NULL) {
-                (*context->preauth_context->modules[i].client_fini)(context, pctx);
-            }
-            memset(&context->preauth_context->modules[i], 0,
-                   sizeof(context->preauth_context->modules[i]));
-        }
-        if (context->preauth_context->modules != NULL) {
-            free(context->preauth_context->modules);
-            context->preauth_context->modules = NULL;
-        }
-        free(context->preauth_context);
-        context->preauth_context = NULL;
-    }
+    struct krb5_preauth_context_module_st *mod;
+
+    if (context == NULL || context->preauth_context == NULL)
+        return;
+    for (i = 0; i < context->preauth_context->n_modules; i++) {
+        mod = &context->preauth_context->modules[i];
+        if (mod->client_fini != NULL)
+            mod->client_fini(context, mod->moddata);
+        zap(mod, sizeof(*mod));
+    }
+    free(context->preauth_context->modules);
+    free(context->preauth_context);
+    context->preauth_context = NULL;
 }
 
 /* Initialize the per-AS-REQ context. This means calling the client_req_init
@@ -274,19 +270,16 @@ void KRB5_CALLCONV
 krb5_preauth_request_context_init(krb5_context context)
 {
     int i;
-    void *rctx, *pctx;
+    struct krb5_preauth_context_module_st *mod;
 
-    /* Limit this to only one attempt per context? */
     if (context->preauth_context == NULL)
         krb5_init_preauth_context(context);
-    if (context->preauth_context != NULL) {
-        for (i = 0; i < context->preauth_context->n_modules; i++) {
-            pctx = context->preauth_context->modules[i].plugin_context;
-            if (context->preauth_context->modules[i].client_req_init != NULL) {
-                rctx = context->preauth_context->modules[i].request_context_pp;
-                (*context->preauth_context->modules[i].client_req_init) (context, pctx, rctx);
-            }
-        }
+    if (context->preauth_context == NULL)
+        return;
+    for (i = 0; i < context->preauth_context->n_modules; i++) {
+        mod = &context->preauth_context->modules[i];
+        if (mod->client_req_init != NULL)
+            mod->client_req_init(context, mod->moddata, mod->modreq_p);
     }
 }
 
@@ -296,17 +289,16 @@ void KRB5_CALLCONV
 krb5_preauth_request_context_fini(krb5_context context)
 {
     int i;
-    void *rctx, *pctx;
-    if (context->preauth_context != NULL) {
-        for (i = 0; i < context->preauth_context->n_modules; i++) {
-            pctx = context->preauth_context->modules[i].plugin_context;
-            rctx = context->preauth_context->modules[i].request_context;
-            if (rctx != NULL) {
-                if (context->preauth_context->modules[i].client_req_fini != NULL) {
-                    (*context->preauth_context->modules[i].client_req_fini)(context, pctx, rctx);
-                }
-                context->preauth_context->modules[i].request_context = NULL;
-            }
+    struct krb5_preauth_context_module_st *mod;
+
+    if (context->preauth_context == NULL)
+        return;
+    for (i = 0; i < context->preauth_context->n_modules; i++) {
+        mod = &context->preauth_context->modules[i];
+        if (mod->modreq != NULL) {
+            if (mod->client_req_fini != NULL)
+                mod->client_req_fini(context, mod->moddata, mod->modreq);
+            mod->modreq = NULL;
         }
     }
 }
@@ -390,10 +382,8 @@ grow_pa_list(krb5_pa_data ***out_pa_list, int *out_pa_list_size,
  */
 
 static krb5_error_code
-client_data_proc(krb5_context kcontext,
-                 krb5_preauth_client_rock *rock,
-                 krb5_int32 request_type,
-                 krb5_data **retdata)
+client_data_proc(krb5_context kcontext, krb5_clpreauth_rock rock,
+                 krb5_int32 request_type, krb5_data **retdata)
 {
     krb5_data *ret;
     krb5_error_code retval;
@@ -405,7 +395,7 @@ client_data_proc(krb5_context kcontext,
         return EINVAL;
 
     switch (request_type) {
-    case krb5plugin_preauth_client_get_etype:
+    case krb5_clpreauth_get_etype:
     {
         krb5_enctype *eptr;
         ret = malloc(sizeof(krb5_data));
@@ -424,7 +414,7 @@ client_data_proc(krb5_context kcontext,
         return 0;
     }
     break;
-    case krb5plugin_preauth_client_free_etype:
+    case krb5_clpreauth_free_etype:
         ret = *retdata;
         if (ret == NULL)
             return 0;
@@ -433,7 +423,7 @@ client_data_proc(krb5_context kcontext,
         free(ret);
         return 0;
         break;
-    case krb5plugin_preauth_client_fast_armor: {
+    case krb5_clpreauth_fast_armor: {
         krb5_keyblock *key = NULL;
         ret = calloc(1, sizeof(krb5_data));
         if (ret == NULL)
@@ -455,7 +445,7 @@ client_data_proc(krb5_context kcontext,
             free(ret);
         return retval;
     }
-    case krb5plugin_preauth_client_free_fast_armor:
+    case krb5_clpreauth_free_fast_armor:
         ret = *retdata;
         if (ret) {
             if (ret->data)
@@ -508,11 +498,11 @@ run_preauth_plugins(krb5_context kcontext,
                     krb5_pa_data *in_padata,
                     krb5_prompter_fct prompter,
                     void *prompter_data,
-                    preauth_get_as_key_proc gak_fct,
+                    krb5_clpreauth_get_as_key_fn gak_fct,
                     krb5_data *salt,
                     krb5_data *s2kparams,
                     void *gak_data,
-                    krb5_preauth_client_rock *get_data_rock,
+                    krb5_clpreauth_rock preauth_rock,
                     krb5_keyblock *as_key,
                     krb5_pa_data ***out_pa_list,
                     int *out_pa_list_size,
@@ -523,7 +513,7 @@ run_preauth_plugins(krb5_context kcontext,
     int i;
     krb5_pa_data **out_pa_data;
     krb5_error_code ret;
-    struct _krb5_preauth_context_module *module;
+    struct krb5_preauth_context_module_st *module;
 
     if (kcontext->preauth_context == NULL) {
         return ENOENT;
@@ -551,19 +541,14 @@ run_preauth_plugins(krb5_context kcontext,
         fprintf(stderr, "using module \"%s\" (%d), flags = %d\n",
                 module->name, module->pa_type, module->flags);
 #endif
-        ret = module->client_process(kcontext,
-                                     module->plugin_context,
-                                     *module->request_context_pp,
+        ret = module->client_process(kcontext, module->moddata,
+                                     *module->modreq_p,
                                      (krb5_get_init_creds_opt *)opte,
-                                     client_data_proc,
-                                     get_data_rock,
-                                     request,
-                                     encoded_request_body,
-                                     encoded_previous_request,
-                                     in_padata,
-                                     prompter, prompter_data,
-                                     gak_fct, gak_data, salt, s2kparams,
-                                     as_key,
+                                     client_data_proc, preauth_rock,
+                                     request, encoded_request_body,
+                                     encoded_previous_request, in_padata,
+                                     prompter, prompter_data, gak_fct,
+                                     gak_data, salt, s2kparams, as_key,
                                      &out_pa_data);
         TRACE_PREAUTH_PROCESS(kcontext, module->name, module->pa_type,
                               module->flags, ret);
@@ -1517,13 +1502,13 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
                          krb5_keyblock *as_key,
                          krb5_prompter_fct prompter, void *prompter_data,
                          krb5_gic_get_as_key_fct gak_fct, void *gak_data,
-                         krb5_preauth_client_rock *get_data_rock,
+                         krb5_clpreauth_rock preauth_rock,
                          krb5_gic_opt_ext *opte)
 {
     krb5_error_code ret;
     krb5_pa_data **out_padata;
     krb5_preauth_context *context;
-    struct _krb5_preauth_context_module *module;
+    struct krb5_preauth_context_module_st *module;
     int i, j;
     int out_pa_list_size = 0;
 
@@ -1548,12 +1533,11 @@ krb5_do_preauth_tryagain(krb5_context kcontext,
             if (module->client_tryagain == NULL) {
                 continue;
             }
-            if ((*module->client_tryagain)(kcontext,
-                                           module->plugin_context,
-                                           *module->request_context_pp,
+            if ((*module->client_tryagain)(kcontext, module->moddata,
+                                           *module->modreq_p,
                                            (krb5_get_init_creds_opt *)opte,
                                            client_data_proc,
-                                           get_data_rock,
+                                           preauth_rock,
                                            request,
                                            encoded_request_body,
                                            encoded_previous_request,
@@ -1589,8 +1573,7 @@ krb5_do_preauth(krb5_context context,
                 krb5_keyblock *as_key,
                 krb5_prompter_fct prompter, void *prompter_data,
                 krb5_gic_get_as_key_fct gak_fct, void *gak_data,
-                krb5_preauth_client_rock *get_data_rock,
-                krb5_gic_opt_ext *opte)
+                krb5_clpreauth_rock preauth_rock, krb5_gic_opt_ext *opte)
 {
     unsigned int h;
     int i, j, out_pa_list_size;
@@ -1769,7 +1752,7 @@ krb5_do_preauth(krb5_context context,
                                               gak_fct,
                                               salt, s2kparams,
                                               gak_data,
-                                              get_data_rock,
+                                              preauth_rock,
                                               as_key,
                                               &out_pa_list,
                                               &out_pa_list_size,
@@ -1803,3 +1786,47 @@ cleanup:
         krb5_free_etype_info(context, etype_info);
     return (ret);
 }
+
+/*
+ * Give all the preauth plugins a look at the preauth option which
+ * has just been set
+ */
+krb5_error_code
+krb5_preauth_supply_preauth_data(krb5_context context, krb5_gic_opt_ext *opte,
+                                 const char *attr, const char *value)
+{
+    krb5_error_code retval = 0;
+    int i;
+    struct krb5_preauth_context_module_st *mod;
+    const char *emsg = NULL;
+
+    if (context->preauth_context == NULL)
+        krb5_init_preauth_context(context);
+    if (context->preauth_context == NULL) {
+        retval = EINVAL;
+        krb5_set_error_message(context, retval,
+                               _("Unable to initialize preauth context"));
+        return retval;
+    }
+
+    /*
+     * Go down the list of preauth modules, and supply them with the
+     * attribute/value pair.
+     */
+    for (i = 0; i < context->preauth_context->n_modules; i++) {
+        mod = &context->preauth_context->modules[i];
+        if (mod->client_supply_gic_opts == NULL)
+            continue;
+        retval = mod->client_supply_gic_opts(context, mod->moddata,
+                                             (krb5_get_init_creds_opt *)opte,
+                                             attr, value);
+        if (retval) {
+            emsg = krb5_get_error_message(context, retval);
+            krb5_set_error_message(context, retval, _("Preauth plugin %s: %s"),
+                                   mod->name, emsg);
+            krb5_free_error_message(context, emsg);
+            break;
+        }
+    }
+    return retval;
+}
index b531b70b5ccc040c1a9aad02039db0be17b12cbf..edc4b1fc586e8f8b5cf7c8dbac66ca33ac024636 100644 (file)
@@ -114,6 +114,7 @@ k5_plugin_free_modules
 k5_plugin_load
 k5_plugin_load_all
 k5_plugin_register
+k5_plugin_register_dyn
 krb524_convert_creds_kdc
 krb524_init_ets
 krb5_425_conv_principal
index 6cb9b1680391a85c741b3ec5c28a9682e43fdb5b..9387cf872009a00d7c256647271b79305771c5c8 100644 (file)
@@ -376,7 +376,6 @@ krb5_os_init_context(krb5_context ctx, krb5_boolean kdc)
 
     ctx->vtbl = 0;
     PLUGIN_DIR_INIT(&ctx->libkrb5_plugins);
-    PLUGIN_DIR_INIT(&ctx->preauth_plugins);
     ctx->preauth_context = NULL;
 
     retval = os_init_paths(ctx, kdc);
@@ -477,7 +476,6 @@ krb5_os_free_context(krb5_context ctx)
         krb5_free_preauth_context(ctx);
         ctx->preauth_context = NULL;
     }
-    krb5int_close_plugin_dirs (&ctx->preauth_plugins);
     krb5int_close_plugin_dirs (&ctx->libkrb5_plugins);
 
 #ifdef _WIN32
index 98e96c399b5f6550066ea8fc2959fa58864670bb..df335ca64b7e556d4888f3daae72be89f469b342 100644 (file)
@@ -1,2 +1,2 @@
-preauthentication_client_1
-preauthentication_server_1
+clpreauth_cksum_body_initvt
+kdcpreauth_cksum_body_initvt
index 2759045b0971feefd7a8114e3b62b6df59890641..e79b84a12ac2e59e9febf8a65c73597cb1f09bab 100644 (file)
@@ -80,18 +80,18 @@ client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type)
 
 static krb5_error_code
 client_process(krb5_context kcontext,
-               void *client_plugin_context,
-               void *client_request_context,
+               krb5_clpreauth_moddata moddata,
+               krb5_clpreauth_modreq modreq,
                krb5_get_init_creds_opt *opt,
-               preauth_get_client_data_proc client_get_data_proc,
-               struct _krb5_preauth_client_rock *rock,
+               krb5_clpreauth_get_data_fn client_get_data_proc,
+               krb5_clpreauth_rock rock,
                krb5_kdc_req *request,
                krb5_data *encoded_request_body,
                krb5_data *encoded_previous_request,
                krb5_pa_data *pa_data,
                krb5_prompter_fct prompter,
                void *prompter_data,
-               preauth_get_as_key_proc gak_fct,
+               krb5_clpreauth_get_as_key_fn gak_fct,
                void *gak_data,
                krb5_data *salt, krb5_data *s2kparams,
                krb5_keyblock *as_key,
@@ -229,7 +229,7 @@ client_process(krb5_context kcontext,
 
 static krb5_error_code
 client_gic_opt(krb5_context kcontext,
-               void *plugin_context,
+               krb5_clpreauth_moddata moddata,
                krb5_get_init_creds_opt *opt,
                const char *attr,
                const char *value)
@@ -243,7 +243,8 @@ client_gic_opt(krb5_context kcontext,
 
 /* Initialize and tear down the server-side module, and do stat tracking. */
 static krb5_error_code
-server_init(krb5_context kcontext, void **module_context, const char **realmnames)
+server_init(krb5_context kcontext, krb5_kdcpreauth_moddata *moddata_out,
+            const char **realmnames)
 {
     struct server_stats *stats;
     stats = malloc(sizeof(struct server_stats));
@@ -251,14 +252,14 @@ server_init(krb5_context kcontext, void **module_context, const char **realmname
         return ENOMEM;
     stats->successes = 0;
     stats->failures = 0;
-    *module_context = stats;
+    *moddata_out = (krb5_kdcpreauth_moddata)stats;
     return 0;
 }
 static void
-server_fini(krb5_context kcontext, void *module_context)
+server_fini(krb5_context kcontext, krb5_kdcpreauth_moddata moddata)
 {
     struct server_stats *stats;
-    stats = module_context;
+    stats = (struct server_stats *)moddata;
     if (stats != NULL) {
 #ifdef DEBUG
         fprintf(stderr, "Total: %d clients failed, %d succeeded.\n",
@@ -275,8 +276,8 @@ server_get_edata(krb5_context kcontext,
                  krb5_kdc_req *request,
                  struct _krb5_db_entry_new *client,
                  struct _krb5_db_entry_new *server,
-                 preauth_get_entry_data_proc server_get_entry_data,
-                 void *pa_module_context,
+                 krb5_kdcpreauth_get_data_fn server_get_entry_data,
+                 krb5_kdcpreauth_moddata moddata,
                  krb5_pa_data *data)
 {
     krb5_data *key_data;
@@ -287,7 +288,7 @@ server_get_edata(krb5_context kcontext,
     /* Retrieve the client's keys. */
     key_data = NULL;
     if ((*server_get_entry_data)(kcontext, request, client,
-                                 krb5plugin_preauth_keys, &key_data) != 0) {
+                                 krb5_kdcpreauth_keys, &key_data) != 0) {
 #ifdef DEBUG
         fprintf(stderr, "Error retrieving client keys.\n");
 #endif
@@ -335,9 +336,9 @@ server_verify(krb5_context kcontext,
               krb5_kdc_req *request,
               krb5_enc_tkt_part *enc_tkt_reply,
               krb5_pa_data *data,
-              preauth_get_entry_data_proc server_get_entry_data,
-              void *pa_module_context,
-              void **pa_request_context,
+              krb5_kdcpreauth_get_data_fn server_get_entry_data,
+              krb5_kdcpreauth_moddata moddata,
+              krb5_kdcpreauth_modreq *modreq_out,
               krb5_data **e_data,
               krb5_authdata ***authz_data)
 {
@@ -356,7 +357,7 @@ server_verify(krb5_context kcontext,
     test_svr_req_ctx *svr_req_ctx;
     krb5_authdata **my_authz_data = NULL;
 
-    stats = pa_module_context;
+    stats = (struct server_stats *)moddata;
 
 #ifdef DEBUG
     fprintf(stderr, "cksum_body: server_verify\n");
@@ -392,7 +393,7 @@ server_verify(krb5_context kcontext,
     /* Pull up the client's keys. */
     key_data = NULL;
     if ((*server_get_entry_data)(kcontext, request, client,
-                                 krb5plugin_preauth_keys, &key_data) != 0) {
+                                 krb5_kdcpreauth_keys, &key_data) != 0) {
 #ifdef DEBUG
         fprintf(stderr, "Error retrieving client keys.\n");
 #endif
@@ -449,7 +450,7 @@ server_verify(krb5_context kcontext,
      * will probably work if it's us on both ends, though. */
     req_body = NULL;
     if ((*server_get_entry_data)(kcontext, request, client,
-                                 krb5plugin_preauth_request_body,
+                                 krb5_kdcpreauth_request_body,
                                  &req_body) != 0) {
         krb5_free_keyblock(kcontext, key);
         stats->failures++;
@@ -572,7 +573,7 @@ server_verify(krb5_context kcontext,
                 svr_req_ctx);
 #endif
     }
-    *pa_request_context = svr_req_ctx;
+    *modreq_out = (krb5_kdcpreauth_modreq)svr_req_ctx;
 
     /* Note that preauthentication succeeded. */
     enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
@@ -591,9 +592,9 @@ server_return(krb5_context kcontext,
               struct _krb5_key_data *client_key,
               krb5_keyblock *encrypting_key,
               krb5_pa_data **send_pa,
-              preauth_get_entry_data_proc server_get_entry_data,
-              void *pa_module_context,
-              void **pa_request_context)
+              krb5_kdcpreauth_get_data_fn server_get_entry_data,
+              krb5_kdcpreauth_moddata moddata,
+              krb5_kdcpreauth_modreq modreq)
 {
     /* We don't need to send data back on the return trip. */
     *send_pa = NULL;
@@ -601,34 +602,32 @@ server_return(krb5_context kcontext,
 }
 
 /* Test server request context freeing */
-static krb5_error_code
-server_free_reqctx(krb5_context kcontext,
-                   void *pa_module_context,
-                   void **pa_request_context)
+static void
+server_free_modreq(krb5_context kcontext,
+                   krb5_kdcpreauth_moddata moddata,
+                   krb5_kdcpreauth_modreq modreq)
 {
     test_svr_req_ctx *svr_req_ctx;
 #ifdef DEBUG
-    fprintf(stderr, "server_free_reqctx: entered!\n");
+    fprintf(stderr, "server_free_modreq: entered!\n");
 #endif
-    if (pa_request_context == NULL)
-        return 0;
+    if (modreq == NULL)
+        return;
 
-    svr_req_ctx = *pa_request_context;
+    svr_req_ctx = (test_svr_req_ctx *)modreq;
     if (svr_req_ctx == NULL)
-        return 0;
+        return;
 
     if (svr_req_ctx->value1 != 111111 || svr_req_ctx->value2 != 222222) {
-        fprintf(stderr, "server_free_reqctx: got invalid req context "
+        fprintf(stderr, "server_free_modreq: got invalid req context "
                 "at %p with values %d and %d\n",
                 svr_req_ctx, svr_req_ctx->value1, svr_req_ctx->value2);
-        return EINVAL;
+        return;
     }
 #ifdef DEBUG
-    fprintf(stderr, "server_free_reqctx: freeing context at %p\n", svr_req_ctx);
+    fprintf(stderr, "server_free_modreq: freeing context at %p\n", svr_req_ctx);
 #endif
     free(svr_req_ctx);
-    *pa_request_context = NULL;
-    return 0;
 }
 
 static int
@@ -644,28 +643,47 @@ static krb5_preauthtype supported_server_pa_types[] = {
     KRB5_PADATA_CKSUM_BODY_REQ, 0,
 };
 
-struct krb5plugin_preauth_client_ftable_v1 preauthentication_client_1 = {
-    "cksum_body",                           /* name */
-    &supported_client_pa_types[0],          /* pa_type_list */
-    NULL,                                   /* enctype_list */
-    NULL,                                   /* plugin init function */
-    NULL,                                   /* plugin fini function */
-    client_get_flags,                       /* get flags function */
-    NULL,                                   /* request init function */
-    NULL,                                   /* request fini function */
-    client_process,                         /* process function */
-    NULL,                                   /* try_again function */
-    client_gic_opt                          /* get init creds opt function */
-};
+krb5_error_code
+clpreauth_cksum_body_initvt(krb5_context context, int maj_ver,
+                            int min_ver, krb5_plugin_vtable vtable);
+krb5_error_code
+kdcpreauth_cksum_body_initvt(krb5_context context, int maj_ver,
+                             int min_ver, krb5_plugin_vtable vtable);
 
-struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = {
-    "cksum_body",
-    &supported_server_pa_types[0],
-    server_init,
-    server_fini,
-    server_get_flags,
-    server_get_edata,
-    server_verify,
-    server_return,
-    server_free_reqctx
-};
+krb5_error_code
+clpreauth_cksum_body_initvt(krb5_context context, int maj_ver,
+                            int min_ver, krb5_plugin_vtable vtable)
+{
+    krb5_clpreauth_vtable vt;
+
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_clpreauth_vtable)vtable;
+    vt->name = "cksum_body";
+    vt->pa_type_list = supported_client_pa_types;
+    vt->flags = client_get_flags;
+    vt->process = client_process;
+    vt->gic_opts = client_gic_opt;
+    return 0;
+}
+
+krb5_error_code
+kdcpreauth_cksum_body_initvt(krb5_context context, int maj_ver,
+                             int min_ver, krb5_plugin_vtable vtable)
+{
+    krb5_kdcpreauth_vtable vt;
+
+    if (maj_ver != -1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_kdcpreauth_vtable)vtable;
+    vt->name = "cksum_body";
+    vt->pa_type_list = supported_server_pa_types;
+    vt->init = server_init;
+    vt->fini = server_fini;
+    vt->flags = server_get_flags;
+    vt->edata = server_get_edata;
+    vt->verify = server_verify;
+    vt->return_padata = server_return;
+    vt->free_modreq = server_free_modreq;
+    return 0;
+}
index 98e96c399b5f6550066ea8fc2959fa58864670bb..651dcea1c4314c490fb926aeacb2ddc8bd740496 100644 (file)
@@ -1,2 +1,2 @@
-preauthentication_client_1
-preauthentication_server_1
+clpreauth_encrypted_challenge_initvt
+kdcpreauth_encrypted_challenge_initvt
index 833385c6378f822f2f129c2c9f5b8281561905b7..58a659246d31c0f907a63a3bd363c26e2aacfef1 100644 (file)
@@ -41,14 +41,14 @@ preauth_flags(krb5_context context, krb5_preauthtype pa_type)
 }
 
 static krb5_error_code
-process_preauth(krb5_context context, void *plugin_context,
-                void *request_context, krb5_get_init_creds_opt *opt,
-                preauth_get_client_data_proc get_data_proc,
-                struct _krb5_preauth_client_rock *rock, krb5_kdc_req *request,
+process_preauth(krb5_context context, krb5_clpreauth_moddata moddata,
+                krb5_clpreauth_modreq modreq, krb5_get_init_creds_opt *opt,
+                krb5_clpreauth_get_data_fn get_data_proc,
+                krb5_clpreauth_rock rock, krb5_kdc_req *request,
                 krb5_data *encoded_request_body,
                 krb5_data *encoded_previous_request, krb5_pa_data *padata,
                 krb5_prompter_fct prompter, void *prompter_data,
-                preauth_get_as_key_proc gak_fct, void *gak_data,
+                krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data,
                 krb5_data *salt, krb5_data *s2kparams, krb5_keyblock *as_key,
                 krb5_pa_data ***out_padata)
 {
@@ -63,7 +63,8 @@ process_preauth(krb5_context context, void *plugin_context,
     retval = fast_get_armor_key(context, get_data_proc, rock, &armor_key);
     if (retval || armor_key == NULL)
         return 0;
-    retval = get_data_proc(context, rock, krb5plugin_preauth_client_get_etype, &etype_data);
+    retval = get_data_proc(context, rock, krb5_clpreauth_get_etype,
+                           &etype_data);
     if (retval == 0) {
         enctype = *((krb5_enctype *)etype_data->data);
         if (as_key->length == 0 ||as_key->enctype != enctype)
@@ -163,8 +164,7 @@ process_preauth(krb5_context context, void *plugin_context,
     if (armor_key)
         krb5_free_keyblock(context, armor_key);
     if (etype_data != NULL)
-        get_data_proc(context, rock, krb5plugin_preauth_client_free_etype,
-                      &etype_data);
+        get_data_proc(context, rock, krb5_clpreauth_free_etype, &etype_data);
     return retval;
 }
 
@@ -173,12 +173,13 @@ static krb5_error_code
 kdc_include_padata(krb5_context context, krb5_kdc_req *request,
                    struct _krb5_db_entry_new *client,
                    struct _krb5_db_entry_new *server,
-                   preauth_get_entry_data_proc get_entry_proc,
-                   void *pa_module_context, krb5_pa_data *data)
+                   krb5_kdcpreauth_get_data_fn get_data_proc,
+                   krb5_kdcpreauth_moddata moddata, krb5_pa_data *data)
 {
     krb5_error_code retval = 0;
     krb5_keyblock *armor_key = NULL;
-    retval = fast_kdc_get_armor_key(context, get_entry_proc, request, client, &armor_key);
+    retval = fast_kdc_get_armor_key(context, get_data_proc, request, client,
+                                    &armor_key);
     if (retval)
         return retval;
     if (armor_key == 0)
@@ -191,8 +192,9 @@ static krb5_error_code
 kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
                    krb5_data *req_pkt, krb5_kdc_req *request,
                    krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *data,
-                   preauth_get_entry_data_proc get_entry_proc,
-                   void *pa_module_context, void **pa_request_context,
+                   krb5_kdcpreauth_get_data_fn get_entry_proc,
+                   krb5_kdcpreauth_moddata moddata,
+                   krb5_kdcpreauth_modreq *modreq_out,
                    krb5_data **e_data, krb5_authdata ***authz_data)
 {
     krb5_error_code retval = 0;
@@ -205,6 +207,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
     krb5_keyblock *client_keys = NULL;
     krb5_data *client_data = NULL;
     krb5_keyblock *challenge_key = NULL;
+    krb5_keyblock *kdc_challenge_key;
     int i = 0;
 
     plain.data = NULL;
@@ -228,7 +231,7 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
     }
     if (retval == 0)
         retval = get_entry_proc(context, request, client,
-                                krb5plugin_preauth_keys, &client_data);
+                                krb5_kdcpreauth_keys, &client_data);
     if (retval == 0) {
         client_keys = (krb5_keyblock *) client_data->data;
         for (i = 0; client_keys[i].enctype&& (retval == 0); i++ ) {
@@ -273,9 +276,10 @@ kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
              * considered this a success, so the return value is ignored.
              */
             fast_kdc_replace_reply_key(context, get_entry_proc, request);
-            krb5_c_fx_cf2_simple(context, armor_key, "kdcchallengearmor",
-                                 &client_keys[i], "challengelongterm",
-                                 (krb5_keyblock **) pa_request_context);
+            if (krb5_c_fx_cf2_simple(context, armor_key, "kdcchallengearmor",
+                                     &client_keys[i], "challengelongterm",
+                                     &kdc_challenge_key) == 0)
+                *modreq_out = (krb5_kdcpreauth_modreq)kdc_challenge_key;
         } else { /*skew*/
             retval = KRB5KRB_AP_ERR_SKEW;
         }
@@ -302,11 +306,12 @@ kdc_return_preauth(krb5_context context, krb5_pa_data *padata,
                    krb5_kdc_req *request, krb5_kdc_rep *reply,
                    struct _krb5_key_data *client_keys,
                    krb5_keyblock *encrypting_key, krb5_pa_data **send_pa,
-                   preauth_get_entry_data_proc get_entry_proc,
-                   void *pa_module_context, void **pa_request_context)
+                   krb5_kdcpreauth_get_data_fn get_entry_proc,
+                   krb5_kdcpreauth_moddata moddata,
+                   krb5_kdcpreauth_modreq modreq)
 {
     krb5_error_code retval = 0;
-    krb5_keyblock *challenge_key = *pa_request_context;
+    krb5_keyblock *challenge_key = (krb5_keyblock *)modreq;
     krb5_pa_enc_ts ts;
     krb5_data *plain = NULL;
     krb5_enc_data enc;
@@ -318,8 +323,6 @@ kdc_return_preauth(krb5_context context, krb5_pa_data *padata,
         return 0;
     if (challenge_key == NULL)
         return 0;
-    * pa_request_context = NULL; /*this function will free the
-                                  * challenge key*/
     enc.ciphertext.data = NULL; /* In case of error pass through */
 
     retval = krb5_us_timeofday(context, &ts.patimestamp, &ts.pausec);
@@ -355,37 +358,45 @@ kdc_return_preauth(krb5_context context, krb5_pa_data *padata,
     return retval;
 }
 
-static int
-kdc_preauth_flags(krb5_context context, krb5_preauthtype patype)
+krb5_preauthtype supported_pa_types[] = {
+    KRB5_PADATA_ENCRYPTED_CHALLENGE, 0};
+
+krb5_error_code
+kdcpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
+                                      int min_ver, krb5_plugin_vtable vtable);
+krb5_error_code
+clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
+                                     int min_ver, krb5_plugin_vtable vtable);
+
+krb5_error_code
+kdcpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
+                                      int min_ver, krb5_plugin_vtable vtable)
 {
+    krb5_kdcpreauth_vtable vt;
+
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_kdcpreauth_vtable)vtable;
+    vt->name = "encrypted_challenge";
+    vt->pa_type_list = supported_pa_types;
+    vt->edata = kdc_include_padata;
+    vt->verify = kdc_verify_preauth;
+    vt->return_padata = kdc_return_preauth;
     return 0;
 }
 
-krb5_preauthtype supported_pa_types[] = {
-    KRB5_PADATA_ENCRYPTED_CHALLENGE, 0};
-
-struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = {
-    "Encrypted challenge",
-    &supported_pa_types[0],
-    NULL,
-    NULL,
-    kdc_preauth_flags,
-    kdc_include_padata,
-    kdc_verify_preauth,
-    kdc_return_preauth,
-    NULL
-};
+krb5_error_code
+clpreauth_encrypted_challenge_initvt(krb5_context context, int maj_ver,
+                                     int min_ver, krb5_plugin_vtable vtable)
+{
+    krb5_clpreauth_vtable vt;
 
-struct krb5plugin_preauth_client_ftable_v1 preauthentication_client_1 = {
-    "Encrypted Challenge",                /* name */
-    &supported_pa_types[0],        /* pa_type_list */
-    NULL,                    /* enctype_list */
-    NULL,                    /* plugin init function */
-    NULL,                    /* plugin fini function */
-    preauth_flags,                /* get flags function */
-    NULL,                    /* request init function */
-    NULL,                    /* request fini function */
-    process_preauth,                /* process function */
-    NULL,                    /* try_again function */
-    NULL                /* get init creds opt function */
-};
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_clpreauth_vtable)vtable;
+    vt->name = "encrypted_challenge";
+    vt->pa_type_list = supported_pa_types;
+    vt->flags = preauth_flags;
+    vt->process = process_preauth;
+    return 0;
+}
index 52f4fa2e82fafd258593178e8f11a9a4f3278b1f..f585bc22c39cc0a577ead3367ecd8b9c810eb42d 100644 (file)
@@ -5,38 +5,36 @@
  * Returns failure if the client library does not support FAST.
  */
 static inline krb5_error_code
-fast_get_armor_key(krb5_context context, preauth_get_client_data_proc get_data,
-                   struct _krb5_preauth_client_rock *rock,
-                   krb5_keyblock **armor_key)
+fast_get_armor_key(krb5_context context, krb5_clpreauth_get_data_fn get_data,
+                   krb5_clpreauth_rock rock, krb5_keyblock **armor_key)
 {
     krb5_error_code retval = 0;
     krb5_data *data;
-    retval = get_data(context, rock, krb5plugin_preauth_client_fast_armor, &data);
+    retval = get_data(context, rock, krb5_clpreauth_fast_armor, &data);
     if (retval == 0) {
         *armor_key = (krb5_keyblock *) data->data;
         data->data = NULL;
-        get_data(context, rock, krb5plugin_preauth_client_free_fast_armor,
-                 &data);
+        get_data(context, rock, krb5_clpreauth_free_fast_armor, &data);
     }
     return retval;
 }
 
 static inline krb5_error_code
 fast_kdc_get_armor_key(krb5_context context,
-                       preauth_get_entry_data_proc get_entry,
+                       krb5_kdcpreauth_get_data_fn get_entry,
                        krb5_kdc_req *request,
                        struct _krb5_db_entry_new *client,
                        krb5_keyblock **armor_key)
 {
     krb5_error_code retval;
     krb5_data *data;
-    retval = get_entry(context, request, client,  krb5plugin_preauth_fast_armor,
+    retval = get_entry(context, request, client, krb5_kdcpreauth_fast_armor,
                        &data);
     if (retval == 0) {
         *armor_key = (krb5_keyblock *) data->data;
         data->data = NULL;
         get_entry(context, request, client,
-                  krb5plugin_preauth_free_fast_armor, &data);
+                  krb5_kdcpreauth_free_fast_armor, &data);
     }
     return retval;
 }
@@ -45,7 +43,7 @@ fast_kdc_get_armor_key(krb5_context context,
 
 static inline krb5_error_code
 fast_kdc_replace_reply_key(krb5_context context,
-                           preauth_get_entry_data_proc get_data,
+                           krb5_kdcpreauth_get_data_fn get_data,
                            krb5_kdc_req *request)
 {
     return 0;
@@ -53,8 +51,8 @@ fast_kdc_replace_reply_key(krb5_context context,
 
 static inline krb5_error_code
 fast_set_kdc_verified(krb5_context context,
-                      preauth_get_client_data_proc get_data,
-                      struct _krb5_preauth_client_rock *rock)
+                      krb5_clpreauth_get_data_fn get_data,
+                      krb5_clpreauth_rock rock)
 {
     return 0;
 }
index 98e96c399b5f6550066ea8fc2959fa58864670bb..e77fa3ef0b9da8840fde86cf155f38b6e35dd322 100644 (file)
@@ -1,2 +1,2 @@
-preauthentication_client_1
-preauthentication_server_1
+clpreauth_pkinit_initvt
+kdcpreauth_pkinit_initvt
index 6888c1b07bab68adf71b55d560d7936bfba48aec..cf95bd57b23991c88ea7f5cf8198c8f663bca1f5 100644 (file)
@@ -71,7 +71,8 @@ pkinit_as_rep_parse(krb5_context context, pkinit_context plgctx,
                     krb5_kdc_req *request, const krb5_data *as_rep,
                     krb5_keyblock *key_block, krb5_enctype etype, krb5_data *);
 
-static void pkinit_client_plugin_fini(krb5_context context, void *blob);
+static void pkinit_client_plugin_fini(krb5_context context,
+                                      krb5_clpreauth_moddata moddata);
 
 static krb5_error_code
 pa_pkinit_gen_req(krb5_context context,
@@ -975,31 +976,25 @@ pkinit_client_profile(krb5_context context,
 }
 
 static krb5_error_code
-pkinit_client_process(krb5_context context,
-                      void *plugin_context,
-                      void *request_context,
+pkinit_client_process(krb5_context context, krb5_clpreauth_moddata moddata,
+                      krb5_clpreauth_modreq modreq,
                       krb5_get_init_creds_opt *gic_opt,
-                      preauth_get_client_data_proc get_data_proc,
-                      struct _krb5_preauth_client_rock *rock,
-                      krb5_kdc_req *request,
+                      krb5_clpreauth_get_data_fn get_data_proc,
+                      krb5_clpreauth_rock rock, krb5_kdc_req *request,
                       krb5_data *encoded_request_body,
                       krb5_data *encoded_previous_request,
                       krb5_pa_data *in_padata,
-                      krb5_prompter_fct prompter,
-                      void *prompter_data,
-                      preauth_get_as_key_proc gak_fct,
-                      void *gak_data,
-                      krb5_data *salt,
-                      krb5_data *s2kparams,
-                      krb5_keyblock *as_key,
-                      krb5_pa_data ***out_padata)
+                      krb5_prompter_fct prompter, void *prompter_data,
+                      krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data,
+                      krb5_data *salt, krb5_data *s2kparams,
+                      krb5_keyblock *as_key, krb5_pa_data ***out_padata)
 {
     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
     krb5_enctype enctype = -1;
     krb5_data *cdata = NULL;
     int processing_request = 0;
-    pkinit_context plgctx = (pkinit_context)plugin_context;
-    pkinit_req_context reqctx = (pkinit_req_context)request_context;
+    pkinit_context plgctx = (pkinit_context)moddata;
+    pkinit_req_context reqctx = (pkinit_req_context)modreq;
     krb5_keyblock *armor_key = NULL;
 
     pkiDebug("pkinit_client_process %p %p %p %p\n",
@@ -1061,16 +1056,15 @@ pkinit_client_process(krb5_context context,
         /*
          * Get the enctype of the reply.
          */
-        retval = (*get_data_proc)(context, rock,
-                                  krb5plugin_preauth_client_get_etype, &cdata);
+        retval = (*get_data_proc)(context, rock, krb5_clpreauth_get_etype,
+                                  &cdata);
         if (retval) {
             pkiDebug("get_data_proc returned %d (%s)\n",
                      retval, error_message(retval));
             return retval;
         }
         enctype = *((krb5_enctype *)cdata->data);
-        (*get_data_proc)(context, rock,
-                         krb5plugin_preauth_client_free_etype, &cdata);
+        (*get_data_proc)(context, rock, krb5_clpreauth_free_etype, &cdata);
         retval = pa_pkinit_parse_rep(context, plgctx, reqctx, request,
                                      in_padata, enctype, as_key,
                                      encoded_previous_request);
@@ -1082,29 +1076,22 @@ pkinit_client_process(krb5_context context,
 }
 
 static krb5_error_code
-pkinit_client_tryagain(krb5_context context,
-                       void *plugin_context,
-                       void *request_context,
+pkinit_client_tryagain(krb5_context context, krb5_clpreauth_moddata moddata,
+                       krb5_clpreauth_modreq modreq,
                        krb5_get_init_creds_opt *gic_opt,
-                       preauth_get_client_data_proc get_data_proc,
-                       struct _krb5_preauth_client_rock *rock,
-                       krb5_kdc_req *request,
+                       krb5_clpreauth_get_data_fn get_data_proc,
+                       krb5_clpreauth_rock rock, krb5_kdc_req *request,
                        krb5_data *encoded_request_body,
                        krb5_data *encoded_previous_request,
-                       krb5_pa_data *in_padata,
-                       krb5_error *err_reply,
-                       krb5_prompter_fct prompter,
-                       void *prompter_data,
-                       preauth_get_as_key_proc gak_fct,
-                       void *gak_data,
-                       krb5_data *salt,
-                       krb5_data *s2kparams,
-                       krb5_keyblock *as_key,
-                       krb5_pa_data ***out_padata)
+                       krb5_pa_data *in_padata, krb5_error *err_reply,
+                       krb5_prompter_fct prompter, void *prompter_data,
+                       krb5_clpreauth_get_as_key_fn gak_fct, void *gak_data,
+                       krb5_data *salt, krb5_data *s2kparams,
+                       krb5_keyblock *as_key, krb5_pa_data ***out_padata)
 {
     krb5_error_code retval = KRB5KDC_ERR_PREAUTH_FAILED;
-    pkinit_context plgctx = (pkinit_context)plugin_context;
-    pkinit_req_context reqctx = (pkinit_req_context)request_context;
+    pkinit_context plgctx = (pkinit_context)moddata;
+    pkinit_req_context reqctx = (pkinit_req_context)modreq;
     krb5_typed_data **typed_data = NULL;
     krb5_data scratch;
     krb5_external_principal_identifier **krb5_trusted_certifiers = NULL;
@@ -1202,14 +1189,14 @@ static krb5_preauthtype supported_client_pa_types[] = {
 
 static void
 pkinit_client_req_init(krb5_context context,
-                       void *plugin_context,
-                       void **request_context)
+                       krb5_clpreauth_moddata moddata,
+                       krb5_clpreauth_modreq *modreq_out)
 {
     krb5_error_code retval = ENOMEM;
     pkinit_req_context reqctx = NULL;
-    pkinit_context plgctx = plugin_context;
+    pkinit_context plgctx = (pkinit_context)moddata;
 
-    *request_context = NULL;
+    *modreq_out = NULL;
 
     reqctx = malloc(sizeof(*reqctx));
     if (reqctx == NULL)
@@ -1244,7 +1231,7 @@ pkinit_client_req_init(krb5_context context,
     if (retval)
         goto cleanup;
 
-    *request_context = (void *) reqctx;
+    *modreq_out = (krb5_clpreauth_modreq)reqctx;
     pkiDebug("%s: returning reqctx at %p\n", __FUNCTION__, reqctx);
 
 cleanup:
@@ -1264,11 +1251,10 @@ cleanup:
 }
 
 static void
-pkinit_client_req_fini(krb5_context context,
-                       void *plugin_context,
-                       void *request_context)
+pkinit_client_req_fini(krb5_context context, krb5_clpreauth_moddata moddata,
+                       krb5_clpreauth_modreq modreq)
 {
-    pkinit_req_context reqctx = request_context;
+    pkinit_req_context reqctx = (pkinit_req_context)modreq;
 
     pkiDebug("%s: received reqctx at %p\n", __FUNCTION__, reqctx);
     if (reqctx == NULL)
@@ -1295,7 +1281,8 @@ pkinit_client_req_fini(krb5_context context,
 }
 
 static int
-pkinit_client_plugin_init(krb5_context context, void **blob)
+pkinit_client_plugin_init(krb5_context context,
+                          krb5_clpreauth_moddata *moddata_out)
 {
     krb5_error_code retval = ENOMEM;
     pkinit_context ctx = NULL;
@@ -1325,21 +1312,21 @@ pkinit_client_plugin_init(krb5_context context, void **blob)
     if (retval)
         goto errout;
 
-    *blob = ctx;
+    *moddata_out = (krb5_clpreauth_moddata)ctx;
 
     pkiDebug("%s: returning plgctx at %p\n", __FUNCTION__, ctx);
 
 errout:
     if (retval)
-        pkinit_client_plugin_fini(context, ctx);
+        pkinit_client_plugin_fini(context, (krb5_clpreauth_moddata)ctx);
 
     return retval;
 }
 
 static void
-pkinit_client_plugin_fini(krb5_context context, void *blob)
+pkinit_client_plugin_fini(krb5_context context, krb5_clpreauth_moddata moddata)
 {
-    pkinit_context ctx = blob;
+    pkinit_context ctx = (pkinit_context)moddata;
 
     if (ctx == NULL || ctx->magic != PKINIT_CTX_MAGIC) {
         pkiDebug("pkinit_lib_fini: got bad plgctx (%p)!\n", ctx);
@@ -1425,14 +1412,13 @@ handle_gic_opt(krb5_context context,
 }
 
 static krb5_error_code
-pkinit_client_gic_opt(krb5_context context,
-                      void *plugin_context,
+pkinit_client_gic_opt(krb5_context context, krb5_clpreauth_moddata moddata,
                       krb5_get_init_creds_opt *gic_opt,
                       const char *attr,
                       const char *value)
 {
     krb5_error_code retval;
-    pkinit_context plgctx = plugin_context;
+    pkinit_context plgctx = (pkinit_context)moddata;
 
     pkiDebug("(pkinit) received '%s' = '%s'\n", attr, value);
     retval = handle_gic_opt(context, plgctx, attr, value);
@@ -1442,20 +1428,28 @@ pkinit_client_gic_opt(krb5_context context,
     return 0;
 }
 
-/* Only necessary for static plugin linking support. */
-#include "k5-plugin.h"
-
-struct krb5plugin_preauth_client_ftable_v1
-PLUGIN_SYMBOL_NAME(krb5_preauth, preauthentication_client_1) = {
-    "pkinit",                   /* name */
-    supported_client_pa_types,  /* pa_type_list */
-    NULL,                       /* enctype_list */
-    pkinit_client_plugin_init,  /* (*init) */
-    pkinit_client_plugin_fini,  /* (*fini) */
-    pkinit_client_get_flags,    /* (*flags) */
-    pkinit_client_req_init,     /* (*client_req_init) */
-    pkinit_client_req_fini,     /* (*client_req_fini) */
-    pkinit_client_process,      /* (*process) */
-    pkinit_client_tryagain,     /* (*tryagain) */
-    pkinit_client_gic_opt       /* (*gic_opt) */
-};
+krb5_error_code
+clpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver,
+                        krb5_plugin_vtable vtable);
+
+krb5_error_code
+clpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver,
+                        krb5_plugin_vtable vtable)
+{
+    krb5_clpreauth_vtable vt;
+
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_clpreauth_vtable)vtable;
+    vt->name = "pkinit";
+    vt->pa_type_list = supported_client_pa_types;
+    vt->init = pkinit_client_plugin_init;
+    vt->fini = pkinit_client_plugin_fini;
+    vt->flags = pkinit_client_get_flags;
+    vt->request_init = pkinit_client_req_init;
+    vt->request_fini = pkinit_client_req_fini;
+    vt->process = pkinit_client_process;
+    vt->tryagain = pkinit_client_tryagain;
+    vt->gic_opts = pkinit_client_gic_opt;
+    return 0;
+}
index 2a33e93311416aeadcf396991d2ca05f968a7f8e..d87d570315307b14cc5f1e8ee7a23ea1cd2f72c7 100644 (file)
@@ -50,10 +50,12 @@ pkinit_server_plugin_fini_realm(krb5_context context,
                                 pkinit_kdc_context plgctx);
 
 static void
-pkinit_server_plugin_fini(krb5_context context, void *blob);
+pkinit_server_plugin_fini(krb5_context context,
+                          krb5_kdcpreauth_moddata moddata);
 
 static pkinit_kdc_context
-pkinit_find_realm_context(krb5_context context, void *pa_plugin_context,
+pkinit_find_realm_context(krb5_context context,
+                          krb5_kdcpreauth_moddata moddata,
                           krb5_principal princ);
 
 static krb5_error_code
@@ -97,12 +99,12 @@ cleanup:
 
 static krb5_error_code
 pkinit_server_get_edata(krb5_context context,
-                        krb5_kdc_req * request,
-                        struct _krb5_db_entry_new * client,
-                        struct _krb5_db_entry_new * server,
-                        preauth_get_entry_data_proc server_get_entry_data,
-                        void *pa_plugin_context,
-                        krb5_pa_data * data)
+                        krb5_kdc_req *request,
+                        struct _krb5_db_entry_new *client,
+                        struct _krb5_db_entry_new *server,
+                        krb5_kdcpreauth_get_data_fn server_get_entry_data,
+                        krb5_kdcpreauth_moddata moddata,
+                        krb5_pa_data *data)
 {
     krb5_error_code retval = 0;
     pkinit_kdc_context plgctx = NULL;
@@ -123,8 +125,7 @@ pkinit_server_get_edata(krb5_context context,
      * If we don't have a realm context for the given realm,
      * don't tell the client that we support pkinit!
      */
-    plgctx = pkinit_find_realm_context(context, pa_plugin_context,
-                                       request->server);
+    plgctx = pkinit_find_realm_context(context, moddata, request->server);
     if (plgctx == NULL)
         retval = EINVAL;
 
@@ -292,9 +293,9 @@ pkinit_server_verify_padata(krb5_context context,
                             krb5_kdc_req * request,
                             krb5_enc_tkt_part * enc_tkt_reply,
                             krb5_pa_data * data,
-                            preauth_get_entry_data_proc server_get_entry_data,
-                            void *pa_plugin_context,
-                            void **pa_request_context,
+                            krb5_kdcpreauth_get_data_fn server_get_entry_data,
+                            krb5_kdcpreauth_moddata moddata,
+                            krb5_kdcpreauth_modreq *modreq_out,
                             krb5_data **e_data,
                             krb5_authdata ***authz_data)
 {
@@ -328,11 +329,10 @@ pkinit_server_verify_padata(krb5_context context,
         return EINVAL;
     }
 
-    if (pa_plugin_context == NULL || e_data == NULL)
+    if (moddata == NULL || e_data == NULL)
         return EINVAL;
 
-    plgctx = pkinit_find_realm_context(context, pa_plugin_context,
-                                       request->server);
+    plgctx = pkinit_find_realm_context(context, moddata, request->server);
     if (plgctx == NULL)
         return 0;
 
@@ -562,7 +562,7 @@ pkinit_server_verify_padata(krb5_context context,
     }
     /* remember to set the PREAUTH flag in the reply */
     enc_tkt_reply->flags |= TKT_FLG_PRE_AUTH;
-    *pa_request_context = reqctx;
+    *modreq_out = (krb5_kdcpreauth_modreq)reqctx;
     reqctx = NULL;
 
 cleanup:
@@ -668,9 +668,9 @@ pkinit_server_return_padata(krb5_context context,
                             struct _krb5_key_data * client_key,
                             krb5_keyblock * encrypting_key,
                             krb5_pa_data ** send_pa,
-                            preauth_get_entry_data_proc server_get_entry_data,
-                            void *pa_plugin_context,
-                            void **pa_request_context)
+                            krb5_kdcpreauth_get_data_fn server_get_entry_data,
+                            krb5_kdcpreauth_moddata moddata,
+                            krb5_kdcpreauth_modreq modreq)
 {
     krb5_error_code retval = 0;
     krb5_data scratch = {0, 0, NULL};
@@ -708,20 +708,19 @@ pkinit_server_return_padata(krb5_context context,
     if (padata->length <= 0 || padata->contents == NULL)
         return 0;
 
-    if (pa_request_context == NULL || *pa_request_context == NULL) {
+    if (modreq == NULL) {
         pkiDebug("missing request context \n");
         return EINVAL;
     }
 
-    plgctx = pkinit_find_realm_context(context, pa_plugin_context,
-                                       request->server);
+    plgctx = pkinit_find_realm_context(context, moddata, request->server);
     if (plgctx == NULL) {
         pkiDebug("Unable to locate correct realm context\n");
         return ENOENT;
     }
 
     pkiDebug("pkinit_return_padata: entered!\n");
-    reqctx = (pkinit_kdc_req_context)*pa_request_context;
+    reqctx = (pkinit_kdc_req_context)modreq;
 
     if (encrypting_key->contents) {
         free(encrypting_key->contents);
@@ -1169,13 +1168,14 @@ errout:
 }
 
 static pkinit_kdc_context
-pkinit_find_realm_context(krb5_context context, void *pa_plugin_context,
+pkinit_find_realm_context(krb5_context context,
+                          krb5_kdcpreauth_moddata moddata,
                           krb5_principal princ)
 {
     int i;
-    pkinit_kdc_context *realm_contexts = pa_plugin_context;
+    pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata;
 
-    if (pa_plugin_context == NULL)
+    if (moddata == NULL)
         return NULL;
 
     for (i = 0; realm_contexts[i] != NULL; i++) {
@@ -1254,7 +1254,8 @@ errout:
 }
 
 static int
-pkinit_server_plugin_init(krb5_context context, void **blob,
+pkinit_server_plugin_init(krb5_context context,
+                          krb5_kdcpreauth_moddata *moddata_out,
                           const char **realmnames)
 {
     krb5_error_code retval = ENOMEM;
@@ -1289,13 +1290,15 @@ pkinit_server_plugin_init(krb5_context context, void **blob,
         goto errout;
     }
 
-    *blob = realm_contexts;
+    *moddata_out = (krb5_kdcpreauth_moddata)realm_contexts;
     retval = 0;
     pkiDebug("%s: returning context at %p\n", __FUNCTION__, realm_contexts);
 
 errout:
-    if (retval)
-        pkinit_server_plugin_fini(context, realm_contexts);
+    if (retval) {
+        pkinit_server_plugin_fini(context,
+                                  (krb5_kdcpreauth_moddata)realm_contexts);
+    }
 
     return retval;
 }
@@ -1316,9 +1319,10 @@ pkinit_server_plugin_fini_realm(krb5_context context, pkinit_kdc_context plgctx)
 }
 
 static void
-pkinit_server_plugin_fini(krb5_context context, void *blob)
+pkinit_server_plugin_fini(krb5_context context,
+                          krb5_kdcpreauth_moddata moddata)
 {
-    pkinit_kdc_context *realm_contexts = blob;
+    pkinit_kdc_context *realm_contexts = (pkinit_kdc_context *)moddata;
     int i;
 
     if (realm_contexts == NULL)
@@ -1379,18 +1383,26 @@ pkinit_fini_kdc_req_context(krb5_context context, void *ctx)
     free(reqctx);
 }
 
-/* Only necessary for static plugin linking support. */
-#include "k5-plugin.h"
-
-struct krb5plugin_preauth_server_ftable_v1
-PLUGIN_SYMBOL_NAME(krb5_pkinit, preauthentication_server_1) = {
-    "pkinit",                   /* name */
-    supported_server_pa_types,  /* pa_type_list */
-    pkinit_server_plugin_init,  /* (*init_proc) */
-    pkinit_server_plugin_fini,  /* (*fini_proc) */
-    pkinit_server_get_flags,    /* (*flags_proc) */
-    pkinit_server_get_edata,    /* (*edata_proc) */
-    pkinit_server_verify_padata,/* (*verify_proc) */
-    pkinit_server_return_padata,/* (*return_proc) */
-    NULL,                       /* (*freepa_reqcontext_proc) */
-};
+krb5_error_code
+kdcpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver,
+                         krb5_plugin_vtable vtable);
+
+krb5_error_code
+kdcpreauth_pkinit_initvt(krb5_context context, int maj_ver, int min_ver,
+                         krb5_plugin_vtable vtable)
+{
+    krb5_kdcpreauth_vtable vt;
+
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_kdcpreauth_vtable)vtable;
+    vt->name = "pkinit";
+    vt->pa_type_list = supported_server_pa_types;
+    vt->init = pkinit_server_plugin_init;
+    vt->fini = pkinit_server_plugin_fini;
+    vt->flags = pkinit_server_get_flags;
+    vt->edata = pkinit_server_get_edata;
+    vt->verify = pkinit_server_verify_padata;
+    vt->return_padata = pkinit_server_return_padata;
+    return 0;
+}
index 49b497ef0ec326045000e3269118b20a18b68cae..6bc65e85eef15f125bab7a7d77b1592bbebd594c 100644 (file)
@@ -116,8 +116,8 @@ static krb5_error_code
 kdc_include_padata(krb5_context context, krb5_kdc_req *request,
                    struct _krb5_db_entry_new *client,
                    struct _krb5_db_entry_new *server,
-                   preauth_get_entry_data_proc get_entry_proc,
-                   void *pa_module_context, krb5_pa_data *pa_data)
+                   krb5_kdcpreauth_get_data_fn get_entry_proc,
+                   krb5_kdcpreauth_moddata moddata, krb5_pa_data *pa_data)
 {
     krb5_error_code retval;
     krb5_data *client_keys_data = NULL;
@@ -138,7 +138,7 @@ kdc_include_padata(krb5_context context, krb5_kdc_req *request,
     if (retval)
         return retval;
     retval = get_entry_proc(context, request, client,
-                            krb5plugin_preauth_keys, &client_keys_data);
+                            krb5_kdcpreauth_keys, &client_keys_data);
     if (retval)
         goto cleanup;
     client_key = (krb5_keyblock *) client_keys_data->data;
@@ -206,8 +206,9 @@ static krb5_error_code
 kdc_verify_preauth(krb5_context context, struct _krb5_db_entry_new *client,
                    krb5_data *req_pkt, krb5_kdc_req *request,
                    krb5_enc_tkt_part *enc_tkt_reply, krb5_pa_data *pa_data,
-                   preauth_get_entry_data_proc get_entry_proc,
-                   void *pa_module_context, void **opaque,
+                   krb5_kdcpreauth_get_data_fn get_entry_proc,
+                   krb5_kdcpreauth_moddata moddata,
+                   krb5_kdcpreauth_modreq *modreq_out,
                    krb5_data **e_data, krb5_authdata ***authz_data)
 {
     krb5_error_code retval, saved_retval = 0;
@@ -294,14 +295,23 @@ kdc_preauth_flags(krb5_context context, krb5_preauthtype patype)
 krb5_preauthtype supported_pa_types[] = {
     KRB5_PADATA_SAM_RESPONSE_2, 0};
 
-struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = {
-    "SAM2",
-    &supported_pa_types[0],
-    NULL,
-    NULL,
-    kdc_preauth_flags,
-    kdc_include_padata,
-    kdc_verify_preauth,
-    NULL,
-    NULL
-};
+krb5_error_code
+kdcpreauth_securid_sam2_initvt(krb5_context context, int maj_ver, int min_ver,
+                               krb5_plugin_vtable vtable);
+
+krb5_error_code
+kdcpreauth_securid_sam2_initvt(krb5_context context, int maj_ver, int min_ver,
+                               krb5_plugin_vtable vtable)
+{
+    krb5_kdcpreauth_vtable vt;
+
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_kdcpreauth_vtable)vtable;
+    vt->name = "securid_sam2";
+    vt->pa_type_list = supported_pa_types;
+    vt->flags = kdc_preauth_flags;
+    vt->edata = kdc_include_padata;
+    vt->verify = kdc_verify_preauth;
+    return 0;
+}
index 98e96c399b5f6550066ea8fc2959fa58864670bb..4cc48a88312587bd95d87d11aba194ab6daf83ec 100644 (file)
@@ -1,2 +1,2 @@
-preauthentication_client_1
-preauthentication_server_1
+clpreauth_wpse_initvt
+kdcpreauth_wpse_initvt
index 14e994d4208ccc4bb4fb967f77f92cd68aa9bb67..866286c1bc2b8ca0fd74c48b50dd064ecc03af11 100644 (file)
@@ -59,7 +59,7 @@ client_get_flags(krb5_context kcontext, krb5_preauthtype pa_type)
 }
 
 static krb5_error_code
-client_init(krb5_context kcontext, void **ctx)
+client_init(krb5_context kcontext, krb5_clpreauth_moddata *moddata_out)
 {
     int *pctx;
 
@@ -67,16 +67,16 @@ client_init(krb5_context kcontext, void **ctx)
     if (pctx == NULL)
         return ENOMEM;
     *pctx = 0;
-    *ctx = pctx;
+    *moddata_out = (krb5_clpreauth_moddata)pctx;
     return 0;
 }
 
 static void
-client_fini(krb5_context kcontext, void *ctx)
+client_fini(krb5_context kcontext, krb5_clpreauth_moddata moddata)
 {
     int *pctx;
 
-    pctx = ctx;
+    pctx = (int *)moddata;
     if (pctx) {
 #ifdef DEBUG
         fprintf(stderr, "wpse module called total of %d times\n", *pctx);
@@ -87,18 +87,18 @@ client_fini(krb5_context kcontext, void *ctx)
 
 static krb5_error_code
 client_process(krb5_context kcontext,
-               void *plugin_context,
-               void *request_context,
+               krb5_clpreauth_moddata moddata,
+               krb5_clpreauth_modreq modreq,
                krb5_get_init_creds_opt *opt,
-               preauth_get_client_data_proc client_get_data_proc,
-               struct _krb5_preauth_client_rock *rock,
+               krb5_clpreauth_get_data_fn client_get_data_proc,
+               krb5_clpreauth_rock rock,
                krb5_kdc_req *request,
                krb5_data *encoded_request_body,
                krb5_data *encoded_previous_request,
                krb5_pa_data *pa_data,
                krb5_prompter_fct prompter,
                void *prompter_data,
-               preauth_get_as_key_proc gak_fct,
+               krb5_clpreauth_get_as_key_fn gak_fct,
                void *gak_data,
                krb5_data *salt, krb5_data *s2kparams,
                krb5_keyblock *as_key,
@@ -115,7 +115,7 @@ client_process(krb5_context kcontext,
             pa_data->length, pa_data->pa_type);
 #endif
 
-    pctx = plugin_context;
+    pctx = (int *)moddata;
     if (pctx) {
         (*pctx)++;
     }
@@ -176,11 +176,12 @@ typedef struct _wpse_req_ctx
 } wpse_req_ctx;
 
 static void
-client_req_init(krb5_context kcontext, void *plugin_context, void **req_context_p)
+client_req_init(krb5_context kcontext, krb5_clpreauth_moddata moddata,
+                krb5_clpreauth_modreq *modreq_out)
 {
     wpse_req_ctx *ctx;
 
-    *req_context_p = NULL;
+    *modreq_out = NULL;
 
     /* Allocate a request context. Useful for verifying that we do in fact
      * do per-request cleanup. */
@@ -190,13 +191,14 @@ client_req_init(krb5_context kcontext, void *plugin_context, void **req_context_
     ctx->magic = WPSE_MAGIC;
     ctx->value = 0xc0dec0de;
 
-    *req_context_p = ctx;
+    *modreq_out = (krb5_clpreauth_modreq)ctx;
 }
 
 static void
-client_req_cleanup(krb5_context kcontext, void *plugin_context, void *req_context)
+client_req_cleanup(krb5_context kcontext, krb5_clpreauth_moddata moddata,
+                   krb5_clpreauth_modreq modreq)
 {
-    wpse_req_ctx *ctx = (wpse_req_ctx *)req_context;
+    wpse_req_ctx *ctx = (wpse_req_ctx *)modreq;
 
     if (ctx) {
 #ifdef DEBUG
@@ -217,7 +219,7 @@ client_req_cleanup(krb5_context kcontext, void *plugin_context, void *req_contex
 
 static krb5_error_code
 client_gic_opt(krb5_context kcontext,
-               void *plugin_context,
+               krb5_clpreauth_moddata moddata,
                krb5_get_init_creds_opt *opt,
                const char *attr,
                const char *value)
@@ -231,15 +233,12 @@ client_gic_opt(krb5_context kcontext,
 
 
 /* Free state. */
-static krb5_error_code
-server_free_pa_request_context(krb5_context kcontext, void *plugin_context,
-                               void **request_context)
+static void
+server_free_modreq(krb5_context kcontext,
+                   krb5_kdcpreauth_moddata moddata,
+                   krb5_kdcpreauth_modreq modreq)
 {
-    if (*request_context != NULL) {
-        free(*request_context);
-        *request_context = NULL;
-    }
-    return 0;
+    free(modreq);
 }
 
 /* Obtain and return any preauthentication data (which is destined for the
@@ -249,8 +248,8 @@ server_get_edata(krb5_context kcontext,
                  krb5_kdc_req *request,
                  struct _krb5_db_entry_new *client,
                  struct _krb5_db_entry_new *server,
-                 preauth_get_entry_data_proc server_get_entry_data,
-                 void *pa_module_context,
+                 krb5_kdcpreauth_get_data_fn server_get_entry_data,
+                 krb5_kdcpreauth_moddata moddata,
                  krb5_pa_data *data)
 {
     /* Return zero bytes of data. */
@@ -267,9 +266,9 @@ server_verify(krb5_context kcontext,
               krb5_kdc_req *request,
               krb5_enc_tkt_part *enc_tkt_reply,
               krb5_pa_data *data,
-              preauth_get_entry_data_proc server_get_entry_data,
-              void *pa_module_context,
-              void **pa_request_context,
+              krb5_kdcpreauth_get_data_fn server_get_entry_data,
+              krb5_kdcpreauth_moddata moddata,
+              krb5_kdcpreauth_modreq *modreq_out,
               krb5_data **e_data,
               krb5_authdata ***authz_data)
 {
@@ -292,8 +291,7 @@ server_verify(krb5_context kcontext,
     enc_tkt_reply->flags |= TKT_FLG_HW_AUTH;
     /* Allocate a context. Useful for verifying that we do in fact do
      * per-request cleanup. */
-    if (*pa_request_context == NULL)
-        *pa_request_context = malloc(4);
+    *modreq_out = malloc(4);
 
     /*
      * Return some junk authorization data just to exercise the
@@ -373,9 +371,8 @@ server_return(krb5_context kcontext,
               struct _krb5_key_data *client_key,
               krb5_keyblock *encrypting_key,
               krb5_pa_data **send_pa,
-              preauth_get_entry_data_proc server_get_entry_data,
-              void *pa_module_context,
-              void **pa_request_context)
+              krb5_kdcpreauth_get_data_fn server_get_entry_data,
+              krb5_kdcpreauth_moddata moddata, krb5_kdcpreauth_modreq modreq)
 {
     /* This module does a couple of dumb things.  It tags its reply with
      * the same type as the initial challenge (expecting the client to sort
@@ -447,28 +444,49 @@ server_get_flags(krb5_context kcontext, krb5_preauthtype pa_type)
 static krb5_preauthtype supported_client_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0};
 static krb5_preauthtype supported_server_pa_types[] = {KRB5_PADATA_WPSE_REQ, 0};
 
-struct krb5plugin_preauth_client_ftable_v1 preauthentication_client_1 = {
-    "wpse",                                 /* name */
-    &supported_client_pa_types[0],          /* pa_type_list */
-    NULL,                                   /* enctype_list */
-    client_init,                            /* plugin init function */
-    client_fini,                            /* plugin fini function */
-    client_get_flags,                       /* get flags function */
-    client_req_init,                        /* request init function */
-    client_req_cleanup,                     /* request fini function */
-    client_process,                         /* process function */
-    NULL,                                   /* try_again function */
-    client_gic_opt                          /* get init creds opts function */
-};
-
-struct krb5plugin_preauth_server_ftable_v1 preauthentication_server_1 = {
-    "wpse",
-    &supported_server_pa_types[0],
-    NULL,
-    NULL,
-    server_get_flags,
-    server_get_edata,
-    server_verify,
-    server_return,
-    server_free_pa_request_context,
-};
+krb5_error_code
+clpreauth_wpse_initvt(krb5_context context, int maj_ver,
+                      int min_ver, krb5_plugin_vtable vtable);
+krb5_error_code
+kdcpreauth_wpse_initvt(krb5_context context, int maj_ver,
+                       int min_ver, krb5_plugin_vtable vtable);
+
+krb5_error_code
+clpreauth_wpse_initvt(krb5_context context, int maj_ver,
+                      int min_ver, krb5_plugin_vtable vtable)
+{
+    krb5_clpreauth_vtable vt;
+
+    if (maj_ver != 1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_clpreauth_vtable)vtable;
+    vt->name = "wpse";
+    vt->pa_type_list = supported_client_pa_types;
+    vt->init = client_init;
+    vt->fini = client_fini;
+    vt->flags = client_get_flags;
+    vt->request_init = client_req_init;
+    vt->request_fini = client_req_cleanup;
+    vt->process = client_process;
+    vt->gic_opts = client_gic_opt;
+    return 0;
+}
+
+krb5_error_code
+kdcpreauth_wpse_initvt(krb5_context context, int maj_ver,
+                       int min_ver, krb5_plugin_vtable vtable)
+{
+    krb5_kdcpreauth_vtable vt;
+
+    if (maj_ver != -1)
+        return KRB5_PLUGIN_VER_NOTSUPP;
+    vt = (krb5_kdcpreauth_vtable)vtable;
+    vt->name = "wpse";
+    vt->pa_type_list = supported_server_pa_types;
+    vt->flags = server_get_flags;
+    vt->edata = server_get_edata;
+    vt->verify = server_verify;
+    vt->return_padata = server_return;
+    vt->free_modreq = server_free_modreq;
+    return 0;
+}
index 85c7ab9d1e2923eaf3c359c8087e93d53f6c4233..ffdfbd617519d7060a659f2aacd845f4121da669 100644 (file)
@@ -41,6 +41,6 @@ site.exp: runenv.vals Makefile
        echo "set runvarlist [list `cat runenv.vals | tr '\n' ' '`]" | \
                sed -e 's%=\.%='`pwd`'/.%g' > site.exp
        echo "set KRB5_DB_MODULE_DIR {$(KRB5_DB_MODULE_DIR)}" >> site.exp
-       echo "set KRB5_PA_MODULE_DIR {$(KRB5_PA_MODULE_DIR)}" >> site.exp
+       echo "set MODULE_DIR {$(MODULE_DIR)}" >> site.exp
        echo "set PRIOCNTL_HACK @PRIOCNTL_HACK@" >> site.exp
 
index cbe46003185ae1d8df71c6d6e363e5f5ee789569..3a997e58d3ab4e7e0424f99e891c450de97d33db 100644 (file)
@@ -918,7 +918,7 @@ proc setup_krb5_conf { {type client} } {
     global mode
     global portbase
     global KRB5_DB_MODULE_DIR
-    global KRB5_PA_MODULE_DIR
+    global MODULE_DIR
     global srcdir
 
     set pkinit_certs [findfile "[pwd]/$srcdir/pkinit-certs" "[pwd]/$srcdir/pkinit-certs" "$srcdir/pkinit-certs"]
@@ -950,7 +950,7 @@ proc setup_krb5_conf { {type client} } {
        if { $mode == "tcp" } {
            puts $conffile "    udp_preference_limit = 1"
        }
-       puts $conffile "        preauth_module_dir = $tmppwd/../../../util/fakedest$KRB5_PA_MODULE_DIR"
+       puts $conffile "        plugin_base_dir = $tmppwd/../../../util/fakedest$MODULE_DIR"
        puts $conffile ""
        puts $conffile "\[realms\]"
        puts $conffile "        $REALMNAME = \{"
index dbaf95dbd75983ac6043d62cd4c9c557acb25517..03a5d52e0887ed559b0b93dcae62115da36d1326 100644 (file)
@@ -139,7 +139,7 @@ proc doit { } {
     global portbase
     global mode
     global tmppwd
-    global KRB5_PA_MODULE_DIR
+    global MODULE_DIR
 
     setup_kerberos_env kdc
 
@@ -235,7 +235,7 @@ proc doit { } {
     }
 
     # If we have anonymous  then test it
-    if [file exists "$tmppwd/../../../util/fakedest$KRB5_PA_MODULE_DIR/pkinit.so" ] {
+    if [file exists "$tmppwd/../../../util/fakedest$MODULE_DIR/preauth/pkinit.so" ] {
        kinit_anonymous "WELLKNOWN/ANONYMOUS"
     }
 
index 4a54ba6db00b3db105f7d150c43ea6524bf16086..89551dde5915a4518306828f8784c89d96742161 100644 (file)
@@ -915,7 +915,7 @@ _default_krb5_conf = {
         'libdefaults' : {
             'default_realm' : '$realm',
             'dns_lookup_kdc' : 'false',
-            'preauth_module_dir' : '$plugins/preauth'
+            'plugin_base_dir' : '$plugins'
         },
         'realms' : {
             '$realm' : {