X-Git-Url: http://git.samba.org/samba.git/?p=jelmer%2Fsamba4-debian.git;a=blobdiff_plain;f=source%2Fkdc%2Fkdc.c;h=6c1f20bf134a3f32c66b5408be3f56af3eba52b3;hp=2fd5674f79456bcc0d2441b4001ce58a3e94f428;hb=7780bf285fdfc30f89409d0436bad0d4b6de5cd4;hpb=526f20bbecc9bbd607595637c15fc4001d3f0c70
diff --git a/source/kdc/kdc.c b/source/kdc/kdc.c
index 2fd5674f7..6c1f20bf1 100644
--- a/source/kdc/kdc.c
+++ b/source/kdc/kdc.c
@@ -9,7 +9,7 @@
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
+ the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
@@ -18,8 +18,7 @@
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ along with this program. If not, see .
*/
#include "includes.h"
@@ -31,11 +30,19 @@
#include "lib/socket/socket.h"
#include "kdc/kdc.h"
#include "system/network.h"
-#include "dlinklist.h"
+#include "lib/util/dlinklist.h"
#include "lib/messaging/irpc.h"
#include "lib/stream/packet.h"
#include "librpc/gen_ndr/samr.h"
-#include "netif/netif.h"
+#include "lib/socket/netif.h"
+#include "heimdal/kdc/windc_plugin.h"
+#include "heimdal/lib/krb5/krb5_locl.h"
+#include "heimdal/kdc/kdc_locl.h"
+#include "param/param.h"
+
+
+/* Disgusting hack to get a mem_ctx into the hdb plugin, when used as a keytab */
+TALLOC_CTX *kdc_mem_ctx;
/* hold all the info needed to send a reply */
struct kdc_reply {
@@ -44,12 +51,13 @@ struct kdc_reply {
DATA_BLOB packet;
};
-typedef BOOL (*kdc_process_fn_t)(struct kdc_server *kdc,
+typedef bool (*kdc_process_fn_t)(struct kdc_server *kdc,
TALLOC_CTX *mem_ctx,
DATA_BLOB *input,
DATA_BLOB *reply,
struct socket_address *peer_addr,
- struct socket_address *my_addr);
+ struct socket_address *my_addr,
+ int datagram);
/* hold information about one kdc socket */
struct kdc_socket {
@@ -87,7 +95,7 @@ static void kdc_send_handler(struct kdc_socket *kdc_socket)
NTSTATUS status;
size_t sendlen;
- status = socket_sendto(kdc_socket->sock, &rep->packet, &sendlen, 0,
+ status = socket_sendto(kdc_socket->sock, &rep->packet, &sendlen,
rep->dest);
if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
break;
@@ -127,14 +135,14 @@ static void kdc_recv_handler(struct kdc_socket *kdc_socket)
return;
}
- blob = data_blob_talloc(kdc_socket, NULL, dsize);
+ blob = data_blob_talloc(tmp_ctx, 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,
+ status = socket_recvfrom(kdc_socket->sock, blob.data, blob.length, &nread,
tmp_ctx, &src);
if (!NT_STATUS_IS_OK(status)) {
talloc_free(tmp_ctx);
@@ -157,7 +165,8 @@ static void kdc_recv_handler(struct kdc_socket *kdc_socket)
tmp_ctx,
&blob,
&reply,
- src, my_addr);
+ src, my_addr,
+ 1 /* Datagram */);
if (!ret) {
talloc_free(tmp_ctx);
return;
@@ -240,7 +249,8 @@ static NTSTATUS kdc_tcp_recv(void *private, DATA_BLOB blob)
&input,
&reply,
src_addr,
- my_addr);
+ my_addr,
+ 0 /* Not datagram */);
if (!ret) {
talloc_free(tmp_ctx);
return NT_STATUS_INTERNAL_ERROR;
@@ -301,15 +311,19 @@ static void kdc_tcp_send(struct stream_connection *conn, uint16_t flags)
calling conventions
*/
-static BOOL kdc_process(struct kdc_server *kdc,
+static bool kdc_process(struct kdc_server *kdc,
TALLOC_CTX *mem_ctx,
DATA_BLOB *input,
DATA_BLOB *reply,
struct socket_address *peer_addr,
- struct socket_address *my_addr)
+ struct socket_address *my_addr,
+ int datagram_reply)
{
int ret;
krb5_data k5_reply;
+ krb5_data_zero(&k5_reply);
+
+ krb5_kdc_update_time(NULL);
DEBUG(10,("Received KDC packet of length %lu from %s:%d\n",
(long)input->length - 4, peer_addr->addr, peer_addr->port));
@@ -319,14 +333,19 @@ static BOOL kdc_process(struct kdc_server *kdc,
input->data, input->length,
&k5_reply,
peer_addr->addr,
- peer_addr->sockaddr);
+ peer_addr->sockaddr,
+ datagram_reply);
if (ret == -1) {
*reply = data_blob(NULL, 0);
- return False;
+ return false;
}
- *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
- krb5_data_free(&k5_reply);
- return True;
+ if (k5_reply.length) {
+ *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
+ krb5_free_data_contents(kdc->smb_krb5_context->krb5_context, &k5_reply);
+ } else {
+ *reply = data_blob(NULL, 0);
+ }
+ return true;
}
/*
@@ -389,15 +408,14 @@ static const struct stream_server_ops kpasswdd_tcp_stream_ops = {
/*
start listening on the given address
*/
-static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address)
+static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address,
+ uint16_t kdc_port, uint16_t kpasswd_port)
{
const struct model_ops *model_ops;
struct kdc_socket *kdc_socket;
struct kdc_socket *kpasswd_socket;
struct socket_address *kdc_address, *kpasswd_address;
NTSTATUS status;
- uint16_t kdc_port = lp_krb5_port();
- uint16_t kpasswd_port = lp_kpasswd_port();
kdc_socket = talloc(kdc, struct kdc_socket);
NT_STATUS_HAVE_NO_MEMORY(kdc_socket);
@@ -498,7 +516,7 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address)
/*
setup our listening sockets on the configured network interfaces
*/
-static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc)
+static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_context *lp_ctx)
{
int num_interfaces = iface_count();
TALLOC_CTX *tmp_ctx = talloc_new(kdc);
@@ -508,7 +526,8 @@ static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc)
for (i=0; ilp_ctx)) {
case ROLE_STANDALONE:
task_server_terminate(task, "kdc: no KDC required in standalone configuration");
return;
case ROLE_DOMAIN_MEMBER:
task_server_terminate(task, "kdc: no KDC required in member server configuration");
return;
- case ROLE_DOMAIN_PDC:
- case ROLE_DOMAIN_BDC:
+ case ROLE_DOMAIN_CONTROLLER:
/* Yes, we want a KDC */
break;
}
@@ -554,17 +582,9 @@ static void kdc_task_init(struct task_server *task)
kdc->task = task;
- /* Setup the KDC configuration */
- kdc->config = talloc(kdc, krb5_kdc_configuration);
- if (!kdc->config) {
- task_server_terminate(task, "kdc: out of memory");
- return;
- }
- krb5_kdc_default_config(kdc->config);
-
initialize_krb5_error_table();
- ret = smb_krb5_init_context(kdc, &kdc->smb_krb5_context);
+ ret = smb_krb5_init_context(kdc, task->event_ctx, task->lp_ctx, &kdc->smb_krb5_context);
if (ret) {
DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
error_message(ret)));
@@ -574,8 +594,15 @@ static void kdc_task_init(struct task_server *task)
krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);
+ ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
+ &kdc->config);
+ if(ret) {
+ task_server_terminate(task, "kdc: failed to get KDC configuration");
+ return;
+ }
+
kdc->config->logf = kdc->smb_krb5_context->logf;
- kdc->config->db = talloc(kdc->config, struct HDB *);
+ kdc->config->db = talloc(kdc, struct HDB *);
if (!kdc->config->db) {
task_server_terminate(task, "kdc: out of memory");
return;
@@ -594,8 +621,22 @@ static void kdc_task_init(struct task_server *task)
task_server_terminate(task, "kdc: failed to register hdb keytab");
return;
}
+
+ /* Registar WinDC hooks */
+ ret = _krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
+ PLUGIN_TYPE_DATA, "windc",
+ &windc_plugin_table);
+ if(ret) {
+ task_server_terminate(task, "kdc: failed to register hdb keytab");
+ return;
+ }
+
+ krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
+
+ kdc_mem_ctx = kdc->smb_krb5_context;
+
/* start listening on the configured network interfaces */
- status = kdc_startup_interfaces(kdc);
+ status = kdc_startup_interfaces(kdc, task->lp_ctx);
if (!NT_STATUS_IS_OK(status)) {
task_server_terminate(task, "kdc failed to setup interfaces");
return;