Add hooks for processing the reply from the server.
git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@21058 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
@@ -413,26 +413,16 @@ krb5_sendto_kdc_flags(krb5_context context,
|
||||
int flags)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_krbhst_handle handle;
|
||||
int type;
|
||||
krb5_sendto_ctx ctx;
|
||||
|
||||
if ((flags & KRB5_KRBHST_FLAGS_MASTER) || context->use_admin_kdc)
|
||||
type = KRB5_KRBHST_ADMIN;
|
||||
else
|
||||
type = KRB5_KRBHST_KDC;
|
||||
|
||||
if (send_data->length > context->large_msg_size)
|
||||
flags |= KRB5_KRBHST_FLAGS_LARGE_MSG;
|
||||
|
||||
ret = krb5_krbhst_init_flags(context, *realm, type, flags, &handle);
|
||||
ret = krb5_sendto_ctx_alloc(context, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
krb5_sendto_ctx_add_flags(ctx, flags);
|
||||
krb5_sendto_ctx_set_func(ctx, _krb5_kdc_retry, NULL);
|
||||
|
||||
ret = krb5_sendto(context, send_data, handle, receive);
|
||||
krb5_krbhst_free(context, handle);
|
||||
if (ret == KRB5_KDC_UNREACH)
|
||||
krb5_set_error_string(context,
|
||||
"unable to reach any KDC in realm %s", *realm);
|
||||
ret = krb5_sendto_context(context, ctx, send_data, *realm, receive);
|
||||
krb5_sendto_ctx_free(context, ctx);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -458,4 +448,129 @@ krb5_set_send_to_kdc_func(krb5_context context,
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct krb5_sendto_ctx {
|
||||
int flags;
|
||||
int type;
|
||||
krb5_sendto_ctx_func func;
|
||||
void *data;
|
||||
};
|
||||
|
||||
krb5_error_code KRB5_LIB_FUNCTION
|
||||
krb5_sendto_ctx_alloc(krb5_context context, krb5_sendto_ctx *ctx)
|
||||
{
|
||||
*ctx = calloc(1, sizeof(**ctx));
|
||||
if (*ctx == NULL) {
|
||||
krb5_set_error_string(context, "out of memory");
|
||||
return ENOMEM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KRB5_LIB_FUNCTION
|
||||
krb5_sendto_ctx_add_flags(krb5_sendto_ctx ctx, int flags)
|
||||
{
|
||||
ctx->flags |= flags;
|
||||
}
|
||||
|
||||
int KRB5_LIB_FUNCTION
|
||||
krb5_sendto_ctx_get_flags(krb5_sendto_ctx ctx)
|
||||
{
|
||||
return ctx->flags;
|
||||
}
|
||||
|
||||
void KRB5_LIB_FUNCTION
|
||||
krb5_sendto_ctx_set_type(krb5_sendto_ctx ctx, int type)
|
||||
{
|
||||
ctx->type = type;
|
||||
}
|
||||
|
||||
|
||||
void KRB5_LIB_FUNCTION
|
||||
krb5_sendto_ctx_set_func(krb5_sendto_ctx ctx,
|
||||
krb5_sendto_ctx_func func,
|
||||
void *data)
|
||||
{
|
||||
ctx->func = func;
|
||||
ctx->data = data;
|
||||
}
|
||||
|
||||
void KRB5_LIB_FUNCTION
|
||||
krb5_sendto_ctx_free(krb5_context context, krb5_sendto_ctx ctx)
|
||||
{
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
free(ctx);
|
||||
}
|
||||
|
||||
krb5_error_code KRB5_LIB_FUNCTION
|
||||
krb5_sendto_context(krb5_context context,
|
||||
krb5_sendto_ctx ctx,
|
||||
const krb5_data *send_data,
|
||||
const krb5_realm realm,
|
||||
krb5_data *receive)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
krb5_krbhst_handle handle = NULL;
|
||||
int type, freectx = 0;
|
||||
int action;
|
||||
|
||||
krb5_data_zero(receive);
|
||||
|
||||
if (ctx == NULL) {
|
||||
freectx = 1;
|
||||
ret = krb5_sendto_ctx_alloc(context, &ctx);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
type = ctx->type;
|
||||
if (type == 0) {
|
||||
if ((ctx->flags & KRB5_KRBHST_FLAGS_MASTER) || context->use_admin_kdc)
|
||||
type = KRB5_KRBHST_ADMIN;
|
||||
else
|
||||
type = KRB5_KRBHST_KDC;
|
||||
}
|
||||
|
||||
if (send_data->length > context->large_msg_size)
|
||||
ctx->flags |= KRB5_KRBHST_FLAGS_LARGE_MSG;
|
||||
|
||||
/* loop until we get back a appropriate response */
|
||||
|
||||
do {
|
||||
action = KRB5_SENDTO_DONE;
|
||||
|
||||
krb5_data_free(receive);
|
||||
|
||||
if (handle == NULL) {
|
||||
ret = krb5_krbhst_init_flags(context, realm, type,
|
||||
ctx->flags, &handle);
|
||||
if (ret) {
|
||||
if (freectx)
|
||||
krb5_sendto_ctx_free(context, ctx);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = krb5_sendto(context, send_data, handle, receive);
|
||||
if (ret)
|
||||
break;
|
||||
if (ctx->func) {
|
||||
ret = (*ctx->func)(context, ctx, ctx->data, receive, &action);
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
if (action != KRB5_SENDTO_CONTINUE) {
|
||||
krb5_krbhst_free(context, handle);
|
||||
handle = NULL;
|
||||
}
|
||||
} while (action != KRB5_SENDTO_DONE);
|
||||
if (handle)
|
||||
krb5_krbhst_free(context, handle);
|
||||
if (ret == KRB5_KDC_UNREACH)
|
||||
krb5_set_error_string(context,
|
||||
"unable to reach any KDC in realm %s", realm);
|
||||
if (ret)
|
||||
krb5_data_free(receive);
|
||||
if (freectx)
|
||||
krb5_sendto_ctx_free(context, ctx);
|
||||
return ret;
|
||||
}
|
||||
|
Reference in New Issue
Block a user