summaryrefslogtreecommitdiffstats
path: root/source4/kdc
diff options
context:
space:
mode:
Diffstat (limited to 'source4/kdc')
-rw-r--r--source4/kdc/config.mk6
-rw-r--r--source4/kdc/hdb-ldb.c13
-rw-r--r--source4/kdc/kdc.c86
-rw-r--r--source4/kdc/kdc.h19
4 files changed, 80 insertions, 44 deletions
diff --git a/source4/kdc/config.mk b/source4/kdc/config.mk
index c6c4f4c5c10..220b7e633c9 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 601821fc42d..caa5a5c801c 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 1f807e90ac5..21461c0f098 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 2289b504ccf..2e81679e576 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;
-
};
+