summaryrefslogtreecommitdiffstats
path: root/source4/heimdal
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2005-09-28 01:09:10 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:39:04 -0500
commit8407a1a8665e188d9dc6774ce1535802e4e3cb29 (patch)
treea3823cbe5ff8762794eda3aba80d8acf9f0573f0 /source4/heimdal
parent0b2c6aec9217c40324dddcc2fef376f5a8c5c27d (diff)
downloadsamba-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.c1
-rw-r--r--source4/heimdal/lib/krb5/krb5-protos.h5
-rw-r--r--source4/heimdal/lib/krb5/krb5.h8
-rw-r--r--source4/heimdal/lib/krb5/send_to_kdc.c55
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