#include "k5-int.h"
#include "kdc_util.h"
#include "extern.h"
#include <stdio.h>
#include "adm_proto.h"
#include <syslog.h>
#include <assert.h>
#include "../include/krb5/authdata_plugin.h"
#if TARGET_OS_MAC
static const char *objdirs[] = { KRB5_AUTHDATA_PLUGIN_BUNDLE_DIR, LIBDIR "/krb5/plugins/authdata", NULL };
#else
static const char *objdirs[] = { LIBDIR "/krb5/plugins/authdata", NULL };
#endif
typedef krb5_error_code (*authdata_proc)
(krb5_context, krb5_db_entry *client,
krb5_data *req_pkt,
krb5_kdc_req *request,
krb5_enc_tkt_part * enc_tkt_reply);
typedef krb5_error_code (*init_proc)
(krb5_context, void **);
typedef void (*fini_proc)
(krb5_context, void *);
typedef struct _krb5_authdata_systems {
const char *name;
int type;
int flags;
void *plugin_context;
init_proc init;
fini_proc fini;
authdata_proc handle_authdata;
} krb5_authdata_systems;
static krb5_authdata_systems static_authdata_systems[] = {
{ "[end]", -1,}
};
static krb5_authdata_systems *authdata_systems;
static int n_authdata_systems;
static struct plugin_dir_handle authdata_plugins;
krb5_error_code
load_authdata_plugins(krb5_context context)
{
struct errinfo err;
void **authdata_plugins_ftables = NULL;
struct krb5plugin_authdata_ftable_v0 *ftable = NULL;
int module_count, i, k;
init_proc server_init_proc = NULL;
memset(&err, 0, sizeof(err));
PLUGIN_DIR_INIT(&authdata_plugins);
if (PLUGIN_DIR_OPEN(&authdata_plugins) == 0) {
if (krb5int_open_plugin_dirs(objdirs, NULL,
&authdata_plugins, &err) != 0) {
return KRB5_PLUGIN_NO_HANDLE;
}
}
authdata_plugins_ftables = NULL;
n_authdata_systems = 0;
if (krb5int_get_plugin_dir_data(&authdata_plugins,
"authdata_server_0",
&authdata_plugins_ftables, &err) != 0) {
return KRB5_PLUGIN_NO_HANDLE;
}
module_count = sizeof(static_authdata_systems)
/ sizeof(static_authdata_systems[0]);
if (authdata_plugins_ftables != NULL) {
for (i = 0; authdata_plugins_ftables[i] != NULL; i++) {
ftable = authdata_plugins_ftables[i];
if ((ftable->authdata_proc != NULL)) {
module_count++;
}
}
}
authdata_systems = calloc((module_count + 1), sizeof(krb5_authdata_systems) );
if (authdata_systems == NULL) {
krb5int_free_plugin_dir_data(authdata_plugins_ftables);
return ENOMEM;
}
for (i = 0, k = 0;
i < sizeof(static_authdata_systems) / sizeof(static_authdata_systems[0]);
i++) {
if (static_authdata_systems[i].type == -1)
break;
authdata_systems[k] = static_authdata_systems[i];
server_init_proc = static_authdata_systems[i].init;
if ((server_init_proc != NULL) &&
((*server_init_proc)(context, NULL ) != 0)) {
memset(&authdata_systems[k], 0, sizeof(authdata_systems[k]));
continue;
}
k++;
}
if (authdata_plugins_ftables != NULL) {
for (i = 0; authdata_plugins_ftables[i] != NULL; i++) {
ftable = authdata_plugins_ftables[i];
if ((ftable->authdata_proc == NULL)) {
continue;
}
server_init_proc = ftable->init_proc;
krb5_error_code initerr;
if ((server_init_proc != NULL) &&
((initerr = (*server_init_proc)(context, NULL )) != 0)) {
const char *emsg;
emsg = krb5_get_error_message(context, initerr);
if (emsg) {
krb5_klog_syslog(LOG_ERR,
"authdata %s failed to initialize: %s",
ftable->name, emsg);
krb5_free_error_message(context, emsg);
}
memset(&authdata_systems[k], 0, sizeof(authdata_systems[k]));
continue;
}
authdata_systems[k].name = ftable->name;
authdata_systems[k].init = server_init_proc;
authdata_systems[k].fini = ftable->fini_proc;
authdata_systems[k].handle_authdata = ftable->authdata_proc;
k++;
}
}
n_authdata_systems = k;
authdata_systems[k].name = "[end]";
authdata_systems[k].type = -1;
return 0;
}
krb5_error_code
unload_authdata_plugins(krb5_context context)
{
int i;
if (authdata_systems != NULL) {
for (i = 0; i < n_authdata_systems; i++) {
if (authdata_systems[i].fini != NULL) {
(*authdata_systems[i].fini)(context,
authdata_systems[i].plugin_context);
}
memset(&authdata_systems[i], 0, sizeof(authdata_systems[i]));
}
free(authdata_systems);
authdata_systems = NULL;
n_authdata_systems = 0;
krb5int_close_plugin_dirs(&authdata_plugins);
}
return 0;
}
krb5_error_code
handle_authdata (krb5_context context, krb5_db_entry *client, krb5_data *req_pkt,
krb5_kdc_req *request, krb5_enc_tkt_part *enc_tkt_reply)
{
krb5_error_code retval = 0;
krb5_authdata_systems *authdata_sys;
int i;
const char *emsg;
krb5_klog_syslog (LOG_DEBUG, "handling authdata");
for (authdata_sys = authdata_systems, i = 0; authdata_sys != NULL && i < n_authdata_systems; i++) {
if (authdata_sys[i].handle_authdata && authdata_sys[i].type != -1) {
retval = authdata_sys[i].handle_authdata(context, client, req_pkt, request,
enc_tkt_reply);
if (retval) {
emsg = krb5_get_error_message (context, retval);
krb5_klog_syslog (LOG_INFO, "authdata (%s) handling failure: %s",
authdata_sys[i].name, emsg);
krb5_free_error_message (context, emsg);
} else {
krb5_klog_syslog (LOG_DEBUG, ".. .. ok");
}
}
}
return 0;
}