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)
|
int flags)
|
||||||
{
|
{
|
||||||
krb5_error_code ret;
|
krb5_error_code ret;
|
||||||
krb5_krbhst_handle handle;
|
krb5_sendto_ctx ctx;
|
||||||
int type;
|
|
||||||
|
|
||||||
if ((flags & KRB5_KRBHST_FLAGS_MASTER) || context->use_admin_kdc)
|
ret = krb5_sendto_ctx_alloc(context, &ctx);
|
||||||
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);
|
|
||||||
if (ret)
|
if (ret)
|
||||||
return 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);
|
ret = krb5_sendto_context(context, ctx, send_data, *realm, receive);
|
||||||
krb5_krbhst_free(context, handle);
|
krb5_sendto_ctx_free(context, ctx);
|
||||||
if (ret == KRB5_KDC_UNREACH)
|
|
||||||
krb5_set_error_string(context,
|
|
||||||
"unable to reach any KDC in realm %s", *realm);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -458,4 +448,129 @@ krb5_set_send_to_kdc_func(krb5_context context,
|
|||||||
return 0;
|
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