Kevin's going to fix this correctly, but for now make the module_context one that is shared between all of the mechanisms a given module implements. Index: src/lib/krb5/krb/preauth2.c =================================================================== --- src/lib/krb5/krb/preauth2.c (revision 18750) +++ src/lib/krb5/krb/preauth2.c (working copy) @@ -80,7 +80,7 @@ * convenience when we populated the list. */ struct krb5plugin_preauth_client_ftable_v0 *ftable; const char *name; - int flags, use_count; + int flags, use_count, is_lead; krb5_error_code (*client_process)(krb5_context context, void *module_context, void **request_context, @@ -122,11 +122,11 @@ krb5_init_preauth_context(krb5_context kcontext, krb5_preauth_context **preauth_context) { - int n_modules, n_tables, i, j, k; + int n_modules, n_tables, i, j, k, module_first; void **tables; struct krb5plugin_preauth_client_ftable_v0 *table; krb5_preauth_context *context; - void *module_context; + void **module_context; krb5_preauthtype pa_type; /* load the plugins for the current context */ @@ -181,12 +183,13 @@ k = 0; for (i = 0; i < n_tables; i++) { table = tables[i]; + module_first = k; if ((table->pa_type_list != NULL) && (table->process != NULL)) { for (j = 0; table->pa_type_list[j] > 0; j++) { pa_type = table->pa_type_list[j]; - module_context = NULL; + module_context = &context->modules[module_first].module_context; if ((table->init != NULL) && - ((*table->init)(kcontext, pa_type, &module_context) != 0)) { + ((*table->init)(kcontext, pa_type, module_context) != 0)) { #ifdef DEBUG fprintf (stderr, "skip module \"%s\", pa_type %d\n", table->name, pa_type); @@ -195,12 +198,12 @@ } context->modules[k].pa_type = pa_type; context->modules[k].enctypes = table->enctype_list; - context->modules[k].module_context = module_context; context->modules[k].client_fini = table->fini; 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[module_first].is_lead++; context->modules[k].client_process = table->process; context->modules[k].client_tryagain = table->tryagain; context->modules[k].client_cleanup = table->cleanup; @@ -260,6 +264,7 @@ pa_type = preauth_context->modules[i].pa_type; (*preauth_context->modules[i].client_fini)(context, pa_type, mctx); + preauth_context->modules[i].module_context = NULL; } memset(&preauth_context->modules[i], 0, sizeof(preauth_context->modules[i])); @@ -387,6 +392,7 @@ krb5_pa_data *out_pa_data; krb5_error_code ret; struct _krb5_preauth_context_module *module; + void *module_context; if (preauth_context == NULL) { return ENOENT; @@ -394,6 +400,9 @@ /* iterate over all loaded modules */ for (i = 0; i < preauth_context->n_modules; i++) { module = &preauth_context->modules[i]; + if (module->is_lead) { + module_context = module->module_context; + } /* skip over those which don't match the preauth type */ if (module->pa_type != in_padata->pa_type) continue; @@ -418,7 +427,7 @@ module->name, module->pa_type, module->flags); #endif ret = module->client_process(kcontext, - module->module_context, + module_context, &module->request_context, request, encoded_request_body,