diff options
Diffstat (limited to 'source4')
-rw-r--r-- | source4/kdc/config.mk | 6 | ||||
-rw-r--r-- | source4/kdc/hdb-ldb.c | 13 | ||||
-rw-r--r-- | source4/kdc/kdc.c | 86 | ||||
-rw-r--r-- | source4/kdc/kdc.h | 19 |
4 files changed, 80 insertions, 44 deletions
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk index c6c4f4c5c1..220b7e633c 100644 --- a/source4/kdc/config.mk +++ b/source4/kdc/config.mk @@ -1,12 +1,12 @@ -# CLDAP server subsystem +# KDC server subsystem ####################### -# Start SUBSYSTEM CLDAPD +# Start SUBSYSTEM KDC [SUBSYSTEM::KDC] INIT_OBJ_FILES = \ kdc/kdc.o \ kdc/hdb-ldb.o REQUIRED_SUBSYSTEMS = \ SOCKET -# End SUBSYSTEM CLDAPD +# End SUBSYSTEM KDC ####################### diff --git a/source4/kdc/hdb-ldb.c b/source4/kdc/hdb-ldb.c index 601821fc42..caa5a5c801 100644 --- a/source4/kdc/hdb-ldb.c +++ b/source4/kdc/hdb-ldb.c @@ -35,16 +35,9 @@ #include "includes.h" #include "kdc.h" #include "ads.h" -#include <hdb.h> -#include <unistd.h> -#include <stdint.h> -#include <stdio.h> -#include <stdarg.h> - -#include <ldb.h> -#include <talloc.h> - -#include <ctype.h> +#include "hdb.h" +#include "lib/ldb/include/ldb.h" +#include "system/iconv.h" static const char * const krb5_attrs[] = { diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c index 1f807e90ac..21461c0f09 100644 --- a/source4/kdc/kdc.c +++ b/source4/kdc/kdc.c @@ -27,35 +27,63 @@ #include "lib/socket/socket.h" #include "kdc/kdc.h" #include "system/network.h" +#include "dlinklist.h" -/* - */ +/* + handle fd send events on a KDC socket +*/ +static void kdc_send_handler(struct kdc_socket *kdc_socket) +{ + while (kdc_socket->send_queue) { + struct kdc_reply *rep = kdc_socket->send_queue; + NTSTATUS status; + size_t sendlen; + + status = socket_sendto(kdc_socket->sock, &rep->packet, &sendlen, 0, + rep->dest_address, rep->dest_port); + if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { + break; + } + + DLIST_REMOVE(kdc_socket->send_queue, rep); + talloc_free(rep); + } -static void kdc_recv_handler(struct event_context *ev, struct fd_event *fde, - struct kdc_socket *kdc_socket) + if (kdc_socket->send_queue == NULL) { + EVENT_FD_NOT_WRITEABLE(kdc_socket->fde); + } +} + + +/* + handle fd recv events on a KDC socket +*/ +static void kdc_recv_handler(struct kdc_socket *kdc_socket) { - TALLOC_CTX *tmp_ctx = talloc_new(kdc_socket); NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(kdc_socket); DATA_BLOB blob; + struct kdc_reply *rep; krb5_data reply; size_t nread, dsize; const char *src_addr; int src_port; struct sockaddr_in src_sock_addr; struct ipv4_addr addr; - + status = socket_pending(kdc_socket->sock, &dsize); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - - blob = data_blob_talloc(tmp_ctx, NULL, dsize); + + blob = data_blob_talloc(kdc_socket, NULL, dsize); if (blob.data == NULL) { + /* hope this is a temporary low memory condition */ talloc_free(tmp_ctx); return; } - + status = socket_recvfrom(kdc_socket->sock, blob.data, blob.length, &nread, 0, &src_addr, &src_port); if (!NT_STATUS_IS_OK(status)) { @@ -84,18 +112,28 @@ static void kdc_recv_handler(struct event_context *ev, struct fd_event *fde, blob.data, blob.length, &reply, src_addr, - &src_sock_addr) != -1) { - size_t sendlen = reply.length; - DATA_BLOB reply_blob; - reply_blob.data = reply.data; - reply_blob.length = reply.length; - - /* Send the reply on it's way */ - socket_sendto(kdc_socket->sock, &reply_blob, &sendlen, 0, - src_addr, src_port); + (struct sockaddr *)&src_sock_addr) == -1) { + talloc_free(tmp_ctx); + return; + } - krb5_data_free(&reply); + /* queue a pending reply */ + rep = talloc(kdc_socket, struct kdc_reply); + if (rep == NULL) { + talloc_free(tmp_ctx); + return; + } + rep->dest_address = talloc_steal(rep, src_addr); + rep->dest_port = src_port; + rep->packet = data_blob_talloc(rep, reply.data, reply.length); + if (rep->packet.data == NULL) { + talloc_free(rep); + talloc_free(tmp_ctx); + return; } + + DLIST_ADD_END(kdc_socket->send_queue, rep, struct kdc_reply *); + EVENT_FD_WRITEABLE(kdc_socket->fde); talloc_free(tmp_ctx); } @@ -107,12 +145,13 @@ static void kdc_socket_handler(struct event_context *ev, struct fd_event *fde, { struct kdc_socket *kdc_socket = talloc_get_type(private, struct kdc_socket); if (flags & EVENT_FD_WRITE) { - /* not sure on write events yet */ + kdc_send_handler(kdc_socket); } else if (flags & EVENT_FD_READ) { - kdc_recv_handler(ev, fde, kdc_socket); + kdc_recv_handler(kdc_socket); } } + /* start listening on the given address */ @@ -131,15 +170,14 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address) } kdc_socket->kdc = kdc; + kdc_socket->send_queue = NULL; talloc_steal(kdc_socket, kdc_socket->sock); kdc_socket->fde = event_add_fd(kdc->task->event_ctx, kdc, - socket_get_fd(kdc_socket->sock), 0, + socket_get_fd(kdc_socket->sock), EVENT_FD_READ, kdc_socket_handler, kdc_socket); - EVENT_FD_READABLE(kdc_socket->fde); - status = socket_listen(kdc_socket->sock, address, lp_krb5_port(), 0, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to bind to %s:%d - %s\n", diff --git a/source4/kdc/kdc.h b/source4/kdc/kdc.h index 2289b504cc..2e81679e57 100644 --- a/source4/kdc/kdc.h +++ b/source4/kdc/kdc.h @@ -27,8 +27,16 @@ krb5_error_code hdb_ldb_create(krb5_context context, struct HDB **db, const char *arg); +/* hold all the info needed to send a reply */ +struct kdc_reply { + struct kdc_reply *next, *prev; + const char *dest_address; + int dest_port; + DATA_BLOB packet; +}; + /* - top level context structure for the cldap server + top level context structure for the kdc server */ struct kdc_server { struct task_server *task; @@ -36,16 +44,13 @@ struct kdc_server { krb5_context krb5_context; }; +/* hold information about one kdc socket */ struct kdc_socket { struct socket_context *sock; - struct event_context *event_ctx; - struct kdc_server *kdc; - - /* the fd event */ struct fd_event *fde; - /* a queue of outgoing replies */ + /* a queue of outgoing replies that have been deferred */ struct kdc_reply *send_queue; - }; + |