summaryrefslogtreecommitdiffstats
path: root/src/kdc
diff options
context:
space:
mode:
Diffstat (limited to 'src/kdc')
-rw-r--r--src/kdc/kdc_preauth.c98
1 files changed, 53 insertions, 45 deletions
diff --git a/src/kdc/kdc_preauth.c b/src/kdc/kdc_preauth.c
index 16af527a64..dfbb5fcc90 100644
--- a/src/kdc/kdc_preauth.c
+++ b/src/kdc/kdc_preauth.c
@@ -109,15 +109,15 @@ typedef krb5_error_code (*freepa_proc)
(krb5_context, void *pa_module_context, void **pa_request_context);
typedef krb5_error_code (*init_proc)
- (krb5_context, krb5_preauthtype, void **);
+ (krb5_context, void **);
typedef void (*fini_proc)
- (krb5_context, krb5_preauthtype, void *);
+ (krb5_context, void *);
typedef struct _krb5_preauth_systems {
const char *name;
int type;
int flags;
- void *pa_sys_context;
+ void *plugin_context;
init_proc init;
fini_proc fini;
edata_proc get_edata;
@@ -301,8 +301,7 @@ load_preauth_plugins(krb5_context context)
void **preauth_plugins_ftables;
struct krb5plugin_preauth_server_ftable_v0 *ftable;
int module_count, i, j, k;
- krb5_preauthtype pa_type;
- void *pa_sys_context;
+ void *plugin_context;
init_proc server_init_proc;
memset(&err, 0, sizeof(err));
@@ -349,6 +348,7 @@ load_preauth_plugins(krb5_context context)
* 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);
return ENOMEM;
}
@@ -361,15 +361,14 @@ load_preauth_plugins(krb5_context context)
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. */
- pa_sys_context = NULL;
- pa_type = static_preauth_systems[i].type;
+ plugin_context = NULL;
server_init_proc = static_preauth_systems[i].init;
if ((server_init_proc != NULL) &&
- ((*server_init_proc)(context, pa_type, &pa_sys_context) != 0)) {
+ ((*server_init_proc)(context, &plugin_context) != 0)) {
memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
continue;
}
- preauth_systems[k].pa_sys_context = pa_sys_context;
+ preauth_systems[k].plugin_context = plugin_context;
k++;
}
@@ -383,28 +382,34 @@ load_preauth_plugins(krb5_context context)
(ftable->return_proc == NULL)) {
continue;
}
+ plugin_context = NULL;
for (j = 0;
ftable->pa_type_list != NULL &&
ftable->pa_type_list[j] > 0;
j++) {
- /* Try to initialize the module. If it fails, we'll remove it
+ /* Try to initialize the plugin. If it fails, we'll remove it
* from the list of modules we'll be using. */
- pa_sys_context = NULL;
- server_init_proc = ftable->init_proc;
- pa_type = ftable->pa_type_list[j];
- if ((server_init_proc != NULL) &&
- ((*server_init_proc)(context, pa_type,
- &pa_sys_context) != 0)) {
- memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
- continue;
+ if (j == 0) {
+ server_init_proc = ftable->init_proc;
+ if ((server_init_proc != NULL) &&
+ ((*server_init_proc)(context, &plugin_context) != 0)) {
+ memset(&preauth_systems[k], 0, sizeof(preauth_systems[k]));
+ continue;
+ }
}
preauth_systems[k].name = ftable->name;
- pa_type = ftable->pa_type_list[j];
- preauth_systems[k].type = pa_type;
- preauth_systems[k].flags = ftable->flags_proc(context, pa_type);
- preauth_systems[k].pa_sys_context = pa_sys_context;
+ 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;
- preauth_systems[k].fini = ftable->fini_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;
@@ -413,6 +418,7 @@ load_preauth_plugins(krb5_context context)
k++;
}
}
+ krb5int_free_plugin_dir_data(preauth_plugins_ftables);
}
n_preauth_systems = k;
/* Add the end-of-list marker. */
@@ -429,8 +435,7 @@ unload_preauth_plugins(krb5_context context)
for (i = 0; i < n_preauth_systems; i++) {
if (preauth_systems[i].fini != NULL) {
(*preauth_systems[i].fini)(context,
- preauth_systems[i].type,
- preauth_systems[i].pa_sys_context);
+ preauth_systems[i].plugin_context);
}
memset(&preauth_systems[i], 0, sizeof(preauth_systems[i]));
}
@@ -506,7 +511,7 @@ free_padata_context(krb5_context kcontext, void **padata_context)
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->pa_sys_context;
+ mctx = preauth_system->plugin_context;
if (preauth_system->free_pa_request_context != NULL) {
pctx = &context->contexts[i].pa_context;
(*preauth_system->free_pa_request_context)(kcontext, mctx,
@@ -721,25 +726,28 @@ sort_pa_order(krb5_context context, krb5_kdc_req *request, int *pa_order)
}
}
- /* Now sort just the modules which replace the key, placing those which
- * handle the pa_data types provided by the client ahead of the others. */
- for (i = 0; preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY; i++) {
- continue;
- }
- n_key_replacers = i;
- for (i = 0; i < n_key_replacers; i++) {
- if (pa_list_includes(request->padata,
- preauth_systems[pa_order[i]].type))
+ if (request->padata != NULL) {
+ /* Now reorder the subset of modules which replace the key,
+ * bubbling those which handle pa_data types provided by the
+ * client ahead of the others. */
+ for (i = 0; preauth_systems[pa_order[i]].flags & PA_REPLACES_KEY; i++) {
continue;
- for (j = i + 1; j < n_key_replacers; j++) {
+ }
+ n_key_replacers = i;
+ for (i = 0; i < n_key_replacers; i++) {
if (pa_list_includes(request->padata,
- preauth_systems[pa_order[j]].type)) {
- k = pa_order[j];
- pa_order[j] = pa_order[i];
- pa_order[i] = k;
- break;
+ preauth_systems[pa_order[i]].type))
+ continue;
+ for (j = i + 1; j < n_key_replacers; j++) {
+ if (pa_list_includes(request->padata,
+ preauth_systems[pa_order[j]].type)) {
+ k = pa_order[j];
+ pa_order[j] = pa_order[i];
+ pa_order[i] = k;
+ break;
+ }
}
- }
+ }
}
#ifdef DEBUG
krb5_klog_syslog(LOG_DEBUG, "original preauth mechanism list:");
@@ -827,7 +835,7 @@ void get_preauth_hint_list(krb5_kdc_req *request, krb5_db_entry *client,
(*pa)->pa_type = ap->type;
if (ap->get_edata) {
retval = (ap->get_edata)(kdc_context, request, client, server,
- get_entry_data, ap->pa_sys_context, *pa);
+ get_entry_data, ap->plugin_context, *pa);
if (retval) {
/* just failed on this type, continue */
free(*pa);
@@ -899,7 +907,7 @@ 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->pa_sys_context,
+ get_entry_data, pa_sys->plugin_context,
pa_context);
if (retval) {
const char * emsg = krb5_get_error_message (context, retval);
@@ -1046,7 +1054,7 @@ 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->pa_sys_context,
+ get_entry_data, ap->plugin_context,
pa_context))) {
goto cleanup;
}