diff options
author | Andrew Bartlett <abartlet@samba.org> | 2005-09-28 01:09:10 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:39:04 -0500 |
commit | 8407a1a8665e188d9dc6774ce1535802e4e3cb29 (patch) | |
tree | a3823cbe5ff8762794eda3aba80d8acf9f0573f0 /source4/heimdal | |
parent | 0b2c6aec9217c40324dddcc2fef376f5a8c5c27d (diff) | |
download | samba-8407a1a8665e188d9dc6774ce1535802e4e3cb29.tar.gz samba-8407a1a8665e188d9dc6774ce1535802e4e3cb29.tar.xz samba-8407a1a8665e188d9dc6774ce1535802e4e3cb29.zip |
r10561: This patch takes over KDC socket routines in Heimdal, and directs them
at the Samba4 socket layer.
The intention here is to ensure that other events may be processed while
heimdal is waiting on the KDC. The interface is designed to be
sufficiently flexible, so that the plugin may choose how to time
communication with the KDC (ie multiple outstanding requests, looking
for a functional KDC).
I've hacked the socket layer out of cldap.c to handle this very
specific case of one udp packet and reply. Likewise I also handle
TCP, stolen from the winbind code.
This same plugin system might also be useful for a self-contained
testing mode in Heimdal, in conjunction with libkdc. I would suggest
using socket-wrapper instead however.
Andrew Bartlett
(This used to be commit 3b09f9e8f9f6f645cd03073ef833c8d0fb0d84e2)
Diffstat (limited to 'source4/heimdal')
-rw-r--r-- | source4/heimdal/lib/krb5/context.c | 1 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/krb5-protos.h | 5 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/krb5.h | 8 | ||||
-rw-r--r-- | source4/heimdal/lib/krb5/send_to_kdc.c | 55 |
4 files changed, 61 insertions, 8 deletions
diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index 3140f1b08f1..594665235b9 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -263,6 +263,7 @@ krb5_free_context(krb5_context context) krb5_closelog(context, context->warn_dest); krb5_set_extra_addresses(context, NULL); krb5_set_ignore_addresses(context, NULL); + free(context->send_and_recv); if (context->mutex != NULL) { HEIMDAL_MUTEX_destroy(context->mutex); free(context->mutex); diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h index 8db553e6e3a..681ac4189b1 100644 --- a/source4/heimdal/lib/krb5/krb5-protos.h +++ b/source4/heimdal/lib/krb5/krb5-protos.h @@ -3432,6 +3432,11 @@ krb5_write_safe_message ( krb5_error_code KRB5_LIB_FUNCTION krb5_xfree (void */*ptr*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_send_recv_func(krb5_context context, + krb5_send_and_recv_func_t func, + krb5_send_and_recv_close_func_t close_fn, + void *data); #ifdef __cplusplus } diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 90b239cf0d7..800683ef0ce 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -444,6 +444,7 @@ typedef struct krb5_context_data { void *mutex; /* protects error_string/error_buf */ int large_msg_size; krb5_boolean fdns; /* Lookup hostnames to find full name, or send as-is */ + struct send_and_recv *send_and_recv; /* Alternate functions for KDC communication */ } krb5_context_data; enum { @@ -744,6 +745,13 @@ enum { KRB5_KRBHST_FLAGS_LARGE_MSG = 2 }; +typedef int (*krb5_send_and_recv_func_t)(krb5_context, + void *, + krb5_krbhst_info *, + const krb5_data *, + krb5_data *); +typedef void (*krb5_send_and_recv_close_func_t)(krb5_context, void*); + struct credentials; /* this is to keep the compiler happy */ struct getargs; struct sockaddr; diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index d55f8dc6920..7bb4adabbd7 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -35,6 +35,30 @@ RCSID("$Id: send_to_kdc.c,v 1.56 2005/06/17 04:33:11 lha Exp $"); +struct send_and_recv { + krb5_send_and_recv_func_t func; + krb5_send_and_recv_close_func_t close; + void *data; +}; + +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_send_recv_func(krb5_context context, + krb5_send_and_recv_func_t func, + krb5_send_and_recv_close_func_t close_fn, + void *data) +{ + free(context->send_and_recv); + context->send_and_recv = malloc(sizeof(*context->send_and_recv)); + if (!context->send_and_recv) { + return ENOMEM; + } + context->send_and_recv->func = func; + context->send_and_recv->close = close_fn; + context->send_and_recv->data = data; + return 0; +} + + /* * send the data in `req' on the socket `fd' (which is datagram iff udp) * waiting `tmout' for a reply and returning the reply in `rep'. @@ -329,11 +353,27 @@ krb5_sendto (krb5_context context, while (krb5_krbhst_next(context, handle, &hi) == 0) { struct addrinfo *ai, *a; + if (context->send_and_recv) { + ret = context->send_and_recv->func(context, + context->send_and_recv->data, + hi, send_data, receive); + if (ret) { + continue; + } else if (receive->length != 0) { + return 0; + } else { + continue; + } + } + if(hi->proto == KRB5_KRBHST_HTTP && context->http_proxy) { - if (send_via_proxy (context, hi, send_data, receive)) + if (send_via_proxy (context, hi, send_data, receive)) { + /* Try again, with next host */ continue; - else - goto out; + } else { + /* Success */ + return 0; + } } ret = krb5_krbhst_get_addrinfo(context, hi, &ai); @@ -363,16 +403,15 @@ krb5_sendto (krb5_context context, break; } close (fd); - if(ret == 0 && receive->length != 0) - goto out; + if(ret == 0 && receive->length != 0) { + return 0; + } } } krb5_krbhst_reset(context, handle); } krb5_clear_error_string (context); - ret = KRB5_KDC_UNREACH; -out: - return ret; + return KRB5_KDC_UNREACH; } krb5_error_code KRB5_LIB_FUNCTION |