bb476e1e6578c31440607a421dc183fbde3f21f3
[obnox/samba/samba-obnox.git] / source4 / kdc / kdc.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    KDC Server startup
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2008
7    Copyright (C) Andrew Tridgell        2005
8    Copyright (C) Stefan Metzmacher      2005
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "smbd/process_model.h"
26 #include "lib/tsocket/tsocket.h"
27 #include "libcli/util/tstream.h"
28 #include "lib/messaging/irpc.h"
29 #include "librpc/gen_ndr/ndr_irpc.h"
30 #include "librpc/gen_ndr/ndr_krb5pac.h"
31 #include "lib/stream/packet.h"
32 #include "lib/socket/netif.h"
33 #include "param/param.h"
34 #include "kdc/kdc-glue.h"
35 #include "kdc/pac-glue.h"
36 #include "dsdb/samdb/samdb.h"
37 #include "auth/session.h"
38
39 NTSTATUS server_service_kdc_init(void);
40
41 extern struct krb5plugin_windc_ftable windc_plugin_table;
42
43 static NTSTATUS kdc_proxy_unavailable_error(struct kdc_server *kdc,
44                                             TALLOC_CTX *mem_ctx,
45                                             DATA_BLOB *out)
46 {
47         int kret;
48         krb5_data k5_error_blob;
49
50         kret = krb5_mk_error(kdc->smb_krb5_context->krb5_context,
51                              KRB5KDC_ERR_SVC_UNAVAILABLE, NULL, NULL,
52                              NULL, NULL, NULL, NULL, &k5_error_blob);
53         if (kret != 0) {
54                 DEBUG(2,(__location__ ": Unable to form krb5 error reply\n"));
55                 return NT_STATUS_INTERNAL_ERROR;
56         }
57
58         *out = data_blob_talloc(mem_ctx, k5_error_blob.data, k5_error_blob.length);
59         krb5_data_free(&k5_error_blob);
60         if (!out->data) {
61                 return NT_STATUS_NO_MEMORY;
62         }
63
64         return NT_STATUS_OK;
65 }
66
67 typedef enum kdc_process_ret (*kdc_process_fn_t)(struct kdc_server *kdc,
68                                                  TALLOC_CTX *mem_ctx,
69                                                  DATA_BLOB *input,
70                                                  DATA_BLOB *reply,
71                                                  struct tsocket_address *peer_addr,
72                                                  struct tsocket_address *my_addr,
73                                                  int datagram);
74
75 /* hold information about one kdc socket */
76 struct kdc_socket {
77         struct kdc_server *kdc;
78         struct tsocket_address *local_address;
79         kdc_process_fn_t process;
80 };
81
82 struct kdc_tcp_call {
83         struct kdc_tcp_connection *kdc_conn;
84         DATA_BLOB in;
85         DATA_BLOB out;
86         uint8_t out_hdr[4];
87         struct iovec out_iov[2];
88 };
89
90 /*
91   state of an open tcp connection
92 */
93 struct kdc_tcp_connection {
94         /* stream connection we belong to */
95         struct stream_connection *conn;
96
97         /* the kdc_server the connection belongs to */
98         struct kdc_socket *kdc_socket;
99
100         struct tstream_context *tstream;
101
102         struct tevent_queue *send_queue;
103 };
104
105
106 static void kdc_tcp_terminate_connection(struct kdc_tcp_connection *kdcconn, const char *reason)
107 {
108         stream_terminate_connection(kdcconn->conn, reason);
109 }
110
111 static void kdc_tcp_recv(struct stream_connection *conn, uint16_t flags)
112 {
113         struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data,
114                                                              struct kdc_tcp_connection);
115         /* this should never be triggered! */
116         kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_recv: called");
117 }
118
119 static void kdc_tcp_send(struct stream_connection *conn, uint16_t flags)
120 {
121         struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data,
122                                                              struct kdc_tcp_connection);
123         /* this should never be triggered! */
124         kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_send: called");
125 }
126
127 /**
128    Wrapper for krb5_kdc_process_krb5_request, converting to/from Samba
129    calling conventions
130 */
131
132 static enum kdc_process_ret kdc_process(struct kdc_server *kdc,
133                                         TALLOC_CTX *mem_ctx,
134                                         DATA_BLOB *input,
135                                         DATA_BLOB *reply,
136                                         struct tsocket_address *peer_addr,
137                                         struct tsocket_address *my_addr,
138                                         int datagram_reply)
139 {
140         int ret;
141         char *pa;
142         struct sockaddr_storage ss;
143         krb5_data k5_reply;
144         krb5_data_zero(&k5_reply);
145
146         krb5_kdc_update_time(NULL);
147
148         ret = tsocket_address_bsd_sockaddr(peer_addr, (struct sockaddr *) &ss,
149                                 sizeof(struct sockaddr_storage));
150         if (ret < 0) {
151                 return KDC_PROCESS_FAILED;
152         }
153         pa = tsocket_address_string(peer_addr, mem_ctx);
154         if (pa == NULL) {
155                 return KDC_PROCESS_FAILED;
156         }
157
158         DEBUG(10,("Received KDC packet of length %lu from %s\n",
159                                 (long)input->length - 4, pa));
160
161         ret = krb5_kdc_process_krb5_request(kdc->smb_krb5_context->krb5_context,
162                                             kdc->config,
163                                             input->data, input->length,
164                                             &k5_reply,
165                                             pa,
166                                             (struct sockaddr *) &ss,
167                                             datagram_reply);
168         if (ret == -1) {
169                 *reply = data_blob(NULL, 0);
170                 return KDC_PROCESS_FAILED;
171         }
172
173         if (ret == HDB_ERR_NOT_FOUND_HERE) {
174                 *reply = data_blob(NULL, 0);
175                 return KDC_PROCESS_PROXY;
176         }
177
178         if (k5_reply.length) {
179                 *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
180                 krb5_data_free(&k5_reply);
181         } else {
182                 *reply = data_blob(NULL, 0);
183         }
184         return KDC_PROCESS_OK;
185 }
186
187 static void kdc_tcp_call_proxy_done(struct tevent_req *subreq);
188 static void kdc_tcp_call_writev_done(struct tevent_req *subreq);
189
190 static void kdc_tcp_call_loop(struct tevent_req *subreq)
191 {
192         struct kdc_tcp_connection *kdc_conn = tevent_req_callback_data(subreq,
193                                       struct kdc_tcp_connection);
194         struct kdc_tcp_call *call;
195         NTSTATUS status;
196         enum kdc_process_ret ret;
197
198         call = talloc(kdc_conn, struct kdc_tcp_call);
199         if (call == NULL) {
200                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
201                                 "no memory for kdc_tcp_call");
202                 return;
203         }
204         call->kdc_conn = kdc_conn;
205
206         status = tstream_read_pdu_blob_recv(subreq,
207                                             call,
208                                             &call->in);
209         TALLOC_FREE(subreq);
210         if (!NT_STATUS_IS_OK(status)) {
211                 const char *reason;
212
213                 reason = talloc_asprintf(call, "kdc_tcp_call_loop: "
214                                          "tstream_read_pdu_blob_recv() - %s",
215                                          nt_errstr(status));
216                 if (!reason) {
217                         reason = nt_errstr(status);
218                 }
219
220                 kdc_tcp_terminate_connection(kdc_conn, reason);
221                 return;
222         }
223
224         DEBUG(10,("Received krb5 TCP packet of length %lu from %s\n",
225                  (long) call->in.length,
226                  tsocket_address_string(kdc_conn->conn->remote_address, call)));
227
228         /* skip length header */
229         call->in.data +=4;
230         call->in.length -= 4;
231
232         /* Call krb5 */
233         ret = kdc_conn->kdc_socket->process(kdc_conn->kdc_socket->kdc,
234                                            call,
235                                            &call->in,
236                                            &call->out,
237                                            kdc_conn->conn->remote_address,
238                                            kdc_conn->conn->local_address,
239                                            0 /* Stream */);
240         if (ret == KDC_PROCESS_FAILED) {
241                 kdc_tcp_terminate_connection(kdc_conn,
242                                 "kdc_tcp_call_loop: process function failed");
243                 return;
244         }
245
246         if (ret == KDC_PROCESS_PROXY) {
247                 uint16_t port;
248
249                 if (!kdc_conn->kdc_socket->kdc->am_rodc) {
250                         kdc_tcp_terminate_connection(kdc_conn,
251                                                      "kdc_tcp_call_loop: proxying requested when not RODC");
252                         return;
253                 }
254                 port = tsocket_address_inet_port(kdc_conn->conn->local_address);
255
256                 subreq = kdc_tcp_proxy_send(call,
257                                             kdc_conn->conn->event.ctx,
258                                             kdc_conn->kdc_socket->kdc,
259                                             port,
260                                             call->in);
261                 if (subreq == NULL) {
262                         kdc_tcp_terminate_connection(kdc_conn,
263                                 "kdc_tcp_call_loop: kdc_tcp_proxy_send failed");
264                         return;
265                 }
266                 tevent_req_set_callback(subreq, kdc_tcp_call_proxy_done, call);
267                 return;
268         }
269
270         /* First add the length of the out buffer */
271         RSIVAL(call->out_hdr, 0, call->out.length);
272         call->out_iov[0].iov_base = (char *) call->out_hdr;
273         call->out_iov[0].iov_len = 4;
274
275         call->out_iov[1].iov_base = (char *) call->out.data;
276         call->out_iov[1].iov_len = call->out.length;
277
278         subreq = tstream_writev_queue_send(call,
279                                            kdc_conn->conn->event.ctx,
280                                            kdc_conn->tstream,
281                                            kdc_conn->send_queue,
282                                            call->out_iov, 2);
283         if (subreq == NULL) {
284                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
285                                 "no memory for tstream_writev_queue_send");
286                 return;
287         }
288         tevent_req_set_callback(subreq, kdc_tcp_call_writev_done, call);
289
290         /*
291          * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
292          * packet_full_request_u32 provides the pdu length then.
293          */
294         subreq = tstream_read_pdu_blob_send(kdc_conn,
295                                             kdc_conn->conn->event.ctx,
296                                             kdc_conn->tstream,
297                                             4, /* initial_read_size */
298                                             packet_full_request_u32,
299                                             kdc_conn);
300         if (subreq == NULL) {
301                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
302                                 "no memory for tstream_read_pdu_blob_send");
303                 return;
304         }
305         tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
306 }
307
308 static void kdc_tcp_call_proxy_done(struct tevent_req *subreq)
309 {
310         struct kdc_tcp_call *call = tevent_req_callback_data(subreq,
311                         struct kdc_tcp_call);
312         struct kdc_tcp_connection *kdc_conn = call->kdc_conn;
313         NTSTATUS status;
314
315         status = kdc_tcp_proxy_recv(subreq, call, &call->out);
316         TALLOC_FREE(subreq);
317         if (!NT_STATUS_IS_OK(status)) {
318                 /* generate an error packet */
319                 status = kdc_proxy_unavailable_error(kdc_conn->kdc_socket->kdc,
320                                                      call, &call->out);
321         }
322
323         if (!NT_STATUS_IS_OK(status)) {
324                 const char *reason;
325
326                 reason = talloc_asprintf(call, "kdc_tcp_call_proxy_done: "
327                                          "kdc_proxy_unavailable_error - %s",
328                                          nt_errstr(status));
329                 if (!reason) {
330                         reason = "kdc_tcp_call_proxy_done: kdc_proxy_unavailable_error() failed";
331                 }
332
333                 kdc_tcp_terminate_connection(call->kdc_conn, reason);
334                 return;
335         }
336
337         /* First add the length of the out buffer */
338         RSIVAL(call->out_hdr, 0, call->out.length);
339         call->out_iov[0].iov_base = (char *) call->out_hdr;
340         call->out_iov[0].iov_len = 4;
341
342         call->out_iov[1].iov_base = (char *) call->out.data;
343         call->out_iov[1].iov_len = call->out.length;
344
345         subreq = tstream_writev_queue_send(call,
346                                            kdc_conn->conn->event.ctx,
347                                            kdc_conn->tstream,
348                                            kdc_conn->send_queue,
349                                            call->out_iov, 2);
350         if (subreq == NULL) {
351                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
352                                 "no memory for tstream_writev_queue_send");
353                 return;
354         }
355         tevent_req_set_callback(subreq, kdc_tcp_call_writev_done, call);
356
357         /*
358          * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
359          * packet_full_request_u32 provides the pdu length then.
360          */
361         subreq = tstream_read_pdu_blob_send(kdc_conn,
362                                             kdc_conn->conn->event.ctx,
363                                             kdc_conn->tstream,
364                                             4, /* initial_read_size */
365                                             packet_full_request_u32,
366                                             kdc_conn);
367         if (subreq == NULL) {
368                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
369                                 "no memory for tstream_read_pdu_blob_send");
370                 return;
371         }
372         tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
373 }
374
375 static void kdc_tcp_call_writev_done(struct tevent_req *subreq)
376 {
377         struct kdc_tcp_call *call = tevent_req_callback_data(subreq,
378                         struct kdc_tcp_call);
379         int sys_errno;
380         int rc;
381
382         rc = tstream_writev_queue_recv(subreq, &sys_errno);
383         TALLOC_FREE(subreq);
384         if (rc == -1) {
385                 const char *reason;
386
387                 reason = talloc_asprintf(call, "kdc_tcp_call_writev_done: "
388                                          "tstream_writev_queue_recv() - %d:%s",
389                                          sys_errno, strerror(sys_errno));
390                 if (!reason) {
391                         reason = "kdc_tcp_call_writev_done: tstream_writev_queue_recv() failed";
392                 }
393
394                 kdc_tcp_terminate_connection(call->kdc_conn, reason);
395                 return;
396         }
397
398         /* We don't care about errors */
399
400         talloc_free(call);
401 }
402
403 /*
404   called when we get a new connection
405 */
406 static void kdc_tcp_accept(struct stream_connection *conn)
407 {
408         struct kdc_socket *kdc_socket;
409         struct kdc_tcp_connection *kdc_conn;
410         struct tevent_req *subreq;
411         int rc;
412
413         kdc_conn = talloc_zero(conn, struct kdc_tcp_connection);
414         if (kdc_conn == NULL) {
415                 stream_terminate_connection(conn,
416                                 "kdc_tcp_accept: out of memory");
417                 return;
418         }
419
420         kdc_conn->send_queue = tevent_queue_create(conn, "kdc_tcp_accept");
421         if (kdc_conn->send_queue == NULL) {
422                 stream_terminate_connection(conn,
423                                 "kdc_tcp_accept: out of memory");
424                 return;
425         }
426
427         kdc_socket = talloc_get_type(conn->private_data, struct kdc_socket);
428
429         TALLOC_FREE(conn->event.fde);
430
431         rc = tstream_bsd_existing_socket(kdc_conn,
432                         socket_get_fd(conn->socket),
433                         &kdc_conn->tstream);
434         if (rc < 0) {
435                 stream_terminate_connection(conn,
436                                 "kdc_tcp_accept: out of memory");
437                 return;
438         }
439
440         kdc_conn->conn = conn;
441         kdc_conn->kdc_socket = kdc_socket;
442         conn->private_data = kdc_conn;
443
444         /*
445          * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
446          * packet_full_request_u32 provides the pdu length then.
447          */
448         subreq = tstream_read_pdu_blob_send(kdc_conn,
449                                             kdc_conn->conn->event.ctx,
450                                             kdc_conn->tstream,
451                                             4, /* initial_read_size */
452                                             packet_full_request_u32,
453                                             kdc_conn);
454         if (subreq == NULL) {
455                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_accept: "
456                                 "no memory for tstream_read_pdu_blob_send");
457                 return;
458         }
459         tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
460 }
461
462 static const struct stream_server_ops kdc_tcp_stream_ops = {
463         .name                   = "kdc_tcp",
464         .accept_connection      = kdc_tcp_accept,
465         .recv_handler           = kdc_tcp_recv,
466         .send_handler           = kdc_tcp_send
467 };
468
469 /* hold information about one kdc/kpasswd udp socket */
470 struct kdc_udp_socket {
471         struct kdc_socket *kdc_socket;
472         struct tdgram_context *dgram;
473         struct tevent_queue *send_queue;
474 };
475
476 struct kdc_udp_call {
477         struct kdc_udp_socket *sock;
478         struct tsocket_address *src;
479         DATA_BLOB in;
480         DATA_BLOB out;
481 };
482
483 static void kdc_udp_call_proxy_done(struct tevent_req *subreq);
484 static void kdc_udp_call_sendto_done(struct tevent_req *subreq);
485
486 static void kdc_udp_call_loop(struct tevent_req *subreq)
487 {
488         struct kdc_udp_socket *sock = tevent_req_callback_data(subreq,
489                                       struct kdc_udp_socket);
490         struct kdc_udp_call *call;
491         uint8_t *buf;
492         ssize_t len;
493         int sys_errno;
494         enum kdc_process_ret ret;
495
496         call = talloc(sock, struct kdc_udp_call);
497         if (call == NULL) {
498                 talloc_free(call);
499                 goto done;
500         }
501         call->sock = sock;
502
503         len = tdgram_recvfrom_recv(subreq, &sys_errno,
504                                    call, &buf, &call->src);
505         TALLOC_FREE(subreq);
506         if (len == -1) {
507                 talloc_free(call);
508                 goto done;
509         }
510
511         call->in.data = buf;
512         call->in.length = len;
513
514         DEBUG(10,("Received krb5 UDP packet of length %lu from %s\n",
515                  (long)call->in.length,
516                  tsocket_address_string(call->src, call)));
517
518         /* Call krb5 */
519         ret = sock->kdc_socket->process(sock->kdc_socket->kdc,
520                                        call,
521                                        &call->in,
522                                        &call->out,
523                                        call->src,
524                                        sock->kdc_socket->local_address,
525                                        1 /* Datagram */);
526         if (ret == KDC_PROCESS_FAILED) {
527                 talloc_free(call);
528                 goto done;
529         }
530
531         if (ret == KDC_PROCESS_PROXY) {
532                 uint16_t port;
533
534                 if (!sock->kdc_socket->kdc->am_rodc) {
535                         DEBUG(0,("kdc_udp_call_loop: proxying requested when not RODC"));
536                         talloc_free(call);
537                         goto done;
538                 }
539
540                 port = tsocket_address_inet_port(sock->kdc_socket->local_address);
541
542                 subreq = kdc_udp_proxy_send(call,
543                                             sock->kdc_socket->kdc->task->event_ctx,
544                                             sock->kdc_socket->kdc,
545                                             port,
546                                             call->in);
547                 if (subreq == NULL) {
548                         talloc_free(call);
549                         goto done;
550                 }
551                 tevent_req_set_callback(subreq, kdc_udp_call_proxy_done, call);
552                 goto done;
553         }
554
555         subreq = tdgram_sendto_queue_send(call,
556                                           sock->kdc_socket->kdc->task->event_ctx,
557                                           sock->dgram,
558                                           sock->send_queue,
559                                           call->out.data,
560                                           call->out.length,
561                                           call->src);
562         if (subreq == NULL) {
563                 talloc_free(call);
564                 goto done;
565         }
566         tevent_req_set_callback(subreq, kdc_udp_call_sendto_done, call);
567
568 done:
569         subreq = tdgram_recvfrom_send(sock,
570                                       sock->kdc_socket->kdc->task->event_ctx,
571                                       sock->dgram);
572         if (subreq == NULL) {
573                 task_server_terminate(sock->kdc_socket->kdc->task,
574                                       "no memory for tdgram_recvfrom_send",
575                                       true);
576                 return;
577         }
578         tevent_req_set_callback(subreq, kdc_udp_call_loop, sock);
579 }
580
581 static void kdc_udp_call_proxy_done(struct tevent_req *subreq)
582 {
583         struct kdc_udp_call *call =
584                 tevent_req_callback_data(subreq,
585                 struct kdc_udp_call);
586         NTSTATUS status;
587
588         status = kdc_udp_proxy_recv(subreq, call, &call->out);
589         TALLOC_FREE(subreq);
590         if (!NT_STATUS_IS_OK(status)) {
591                 /* generate an error packet */
592                 status = kdc_proxy_unavailable_error(call->sock->kdc_socket->kdc,
593                                                      call, &call->out);
594         }
595
596         if (!NT_STATUS_IS_OK(status)) {
597                 talloc_free(call);
598                 return;
599         }
600
601         subreq = tdgram_sendto_queue_send(call,
602                                           call->sock->kdc_socket->kdc->task->event_ctx,
603                                           call->sock->dgram,
604                                           call->sock->send_queue,
605                                           call->out.data,
606                                           call->out.length,
607                                           call->src);
608         if (subreq == NULL) {
609                 talloc_free(call);
610                 return;
611         }
612
613         tevent_req_set_callback(subreq, kdc_udp_call_sendto_done, call);
614 }
615
616 static void kdc_udp_call_sendto_done(struct tevent_req *subreq)
617 {
618         struct kdc_udp_call *call = tevent_req_callback_data(subreq,
619                                        struct kdc_udp_call);
620         int sys_errno;
621
622         tdgram_sendto_queue_recv(subreq, &sys_errno);
623
624         /* We don't care about errors */
625
626         talloc_free(call);
627 }
628
629 /*
630   start listening on the given address
631 */
632 static NTSTATUS kdc_add_socket(struct kdc_server *kdc,
633                                const struct model_ops *model_ops,
634                                const char *name,
635                                const char *address,
636                                uint16_t port,
637                                kdc_process_fn_t process,
638                                bool udp_only)
639 {
640         struct kdc_socket *kdc_socket;
641         struct kdc_udp_socket *kdc_udp_socket;
642         struct tevent_req *udpsubreq;
643         NTSTATUS status;
644         int ret;
645
646         kdc_socket = talloc(kdc, struct kdc_socket);
647         NT_STATUS_HAVE_NO_MEMORY(kdc_socket);
648
649         kdc_socket->kdc = kdc;
650         kdc_socket->process = process;
651
652         ret = tsocket_address_inet_from_strings(kdc_socket, "ip",
653                                                 address, port,
654                                                 &kdc_socket->local_address);
655         if (ret != 0) {
656                 status = map_nt_error_from_unix_common(errno);
657                 return status;
658         }
659
660         if (!udp_only) {
661                 status = stream_setup_socket(kdc->task,
662                                              kdc->task->event_ctx,
663                                              kdc->task->lp_ctx,
664                                              model_ops,
665                                              &kdc_tcp_stream_ops,
666                                              "ip", address, &port,
667                                              lpcfg_socket_options(kdc->task->lp_ctx),
668                                              kdc_socket);
669                 if (!NT_STATUS_IS_OK(status)) {
670                         DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
671                                  address, port, nt_errstr(status)));
672                         talloc_free(kdc_socket);
673                         return status;
674                 }
675         }
676
677         kdc_udp_socket = talloc(kdc_socket, struct kdc_udp_socket);
678         NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket);
679
680         kdc_udp_socket->kdc_socket = kdc_socket;
681
682         ret = tdgram_inet_udp_socket(kdc_socket->local_address,
683                                      NULL,
684                                      kdc_udp_socket,
685                                      &kdc_udp_socket->dgram);
686         if (ret != 0) {
687                 status = map_nt_error_from_unix_common(errno);
688                 DEBUG(0,("Failed to bind to %s:%u UDP - %s\n",
689                          address, port, nt_errstr(status)));
690                 return status;
691         }
692
693         kdc_udp_socket->send_queue = tevent_queue_create(kdc_udp_socket,
694                                                          "kdc_udp_send_queue");
695         NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket->send_queue);
696
697         udpsubreq = tdgram_recvfrom_send(kdc_udp_socket,
698                                          kdc->task->event_ctx,
699                                          kdc_udp_socket->dgram);
700         NT_STATUS_HAVE_NO_MEMORY(udpsubreq);
701         tevent_req_set_callback(udpsubreq, kdc_udp_call_loop, kdc_udp_socket);
702
703         return NT_STATUS_OK;
704 }
705
706
707 /*
708   setup our listening sockets on the configured network interfaces
709 */
710 static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_context *lp_ctx,
711                                        struct interface *ifaces)
712 {
713         const struct model_ops *model_ops;
714         int num_interfaces;
715         TALLOC_CTX *tmp_ctx = talloc_new(kdc);
716         NTSTATUS status;
717         int i;
718         uint16_t kdc_port = lpcfg_krb5_port(lp_ctx);
719         uint16_t kpasswd_port = lpcfg_kpasswd_port(lp_ctx);
720         bool done_wildcard = false;
721
722         /* within the kdc task we want to be a single process, so
723            ask for the single process model ops and pass these to the
724            stream_setup_socket() call. */
725         model_ops = process_model_startup("single");
726         if (!model_ops) {
727                 DEBUG(0,("Can't find 'single' process model_ops\n"));
728                 return NT_STATUS_INTERNAL_ERROR;
729         }
730
731         num_interfaces = iface_list_count(ifaces);
732
733         /* if we are allowing incoming packets from any address, then
734            we need to bind to the wildcard address */
735         if (!lpcfg_bind_interfaces_only(lp_ctx)) {
736                 int num_binds = 0;
737                 char **wcard = iface_list_wildcard(kdc);
738                 NT_STATUS_HAVE_NO_MEMORY(wcard);
739                 for (i=0; wcard[i]; i++) {
740                         if (kdc_port) {
741                                 status = kdc_add_socket(kdc, model_ops,
742                                                         "kdc", wcard[i], kdc_port,
743                                                         kdc_process, false);
744                                 if (NT_STATUS_IS_OK(status)) {
745                                         num_binds++;
746                                 }
747                         }
748
749                         if (kpasswd_port) {
750                                 status = kdc_add_socket(kdc, model_ops,
751                                                         "kpasswd", wcard[i], kpasswd_port,
752                                                         kpasswdd_process, false);
753                                 if (NT_STATUS_IS_OK(status)) {
754                                         num_binds++;
755                                 }
756                         }
757                 }
758                 talloc_free(wcard);
759                 if (num_binds == 0) {
760                         return NT_STATUS_INVALID_PARAMETER_MIX;
761                 }
762                 done_wildcard = true;
763         }
764
765         for (i=0; i<num_interfaces; i++) {
766                 const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
767
768                 if (kdc_port) {
769                         status = kdc_add_socket(kdc, model_ops,
770                                                 "kdc", address, kdc_port,
771                                                 kdc_process, done_wildcard);
772                         NT_STATUS_NOT_OK_RETURN(status);
773                 }
774
775                 if (kpasswd_port) {
776                         status = kdc_add_socket(kdc, model_ops,
777                                                 "kpasswd", address, kpasswd_port,
778                                                 kpasswdd_process, done_wildcard);
779                         NT_STATUS_NOT_OK_RETURN(status);
780                 }
781         }
782
783         talloc_free(tmp_ctx);
784
785         return NT_STATUS_OK;
786 }
787
788 static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
789                                  struct kdc_check_generic_kerberos *r)
790 {
791         struct PAC_Validate pac_validate;
792         DATA_BLOB srv_sig;
793         struct PAC_SIGNATURE_DATA kdc_sig;
794         struct kdc_server *kdc = talloc_get_type(msg->private_data, struct kdc_server);
795         enum ndr_err_code ndr_err;
796         int ret;
797         hdb_entry_ex ent;
798         krb5_principal principal;
799
800         /* There is no reply to this request */
801         r->out.generic_reply = data_blob(NULL, 0);
802
803         ndr_err = ndr_pull_struct_blob(&r->in.generic_request, msg, &pac_validate,
804                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
805         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
806                 return NT_STATUS_INVALID_PARAMETER;
807         }
808
809         if (pac_validate.MessageType != NETLOGON_GENERIC_KRB5_PAC_VALIDATE) {
810                 /* We don't implement any other message types - such as certificate validation - yet */
811                 return NT_STATUS_INVALID_PARAMETER;
812         }
813
814         if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength)
815             || pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength
816             || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
817                 return NT_STATUS_INVALID_PARAMETER;
818         }
819
820         srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data,
821                                   pac_validate.ChecksumLength);
822
823         ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal,
824                                   lpcfg_realm(kdc->task->lp_ctx),
825                                   "krbtgt", lpcfg_realm(kdc->task->lp_ctx),
826                                   NULL);
827
828         if (ret != 0) {
829                 return NT_STATUS_NO_MEMORY;
830         }
831
832         ret = kdc->config->db[0]->hdb_fetch_kvno(kdc->smb_krb5_context->krb5_context,
833                                                  kdc->config->db[0],
834                                                  principal,
835                                                  HDB_F_GET_KRBTGT | HDB_F_DECRYPT,
836                                                  0,
837                                                  &ent);
838         
839         if (ret != 0) {
840                 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
841                 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
842
843                 return NT_STATUS_LOGON_FAILURE;
844         }
845
846         kdc_sig.type = pac_validate.SignatureType;
847         kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
848                                             pac_validate.SignatureLength);
849
850         ret = kdc_check_pac(kdc->smb_krb5_context->krb5_context, srv_sig, &kdc_sig, &ent);
851
852         hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
853         krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
854
855         if (ret != 0) {
856                 return NT_STATUS_LOGON_FAILURE;
857         }
858
859         return NT_STATUS_OK;
860 }
861
862
863 /*
864   startup the kdc task
865 */
866 static void kdc_task_init(struct task_server *task)
867 {
868         struct kdc_server *kdc;
869         NTSTATUS status;
870         krb5_error_code ret;
871         struct interface *ifaces;
872         int ldb_ret;
873
874         switch (lpcfg_server_role(task->lp_ctx)) {
875         case ROLE_STANDALONE:
876                 task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
877                 return;
878         case ROLE_DOMAIN_MEMBER:
879                 task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
880                 return;
881         case ROLE_DOMAIN_PDC:
882         case ROLE_DOMAIN_BDC:
883                 task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true);
884                 return;
885         case ROLE_ACTIVE_DIRECTORY_DC:
886                 /* Yes, we want a KDC */
887                 break;
888         }
889
890         load_interface_list(task, task->lp_ctx, &ifaces);
891
892         if (iface_list_count(ifaces) == 0) {
893                 task_server_terminate(task, "kdc: no network interfaces configured", false);
894                 return;
895         }
896
897         task_server_set_title(task, "task[kdc]");
898
899         kdc = talloc_zero(task, struct kdc_server);
900         if (kdc == NULL) {
901                 task_server_terminate(task, "kdc: out of memory", true);
902                 return;
903         }
904
905         kdc->task = task;
906
907
908         /* get a samdb connection */
909         kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx,
910                                    system_session(kdc->task->lp_ctx), 0);
911         if (!kdc->samdb) {
912                 DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
913                 task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
914                 return;
915         }
916
917         ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
918         if (ldb_ret != LDB_SUCCESS) {
919                 DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
920                           ldb_errstring(kdc->samdb)));
921                 task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
922                 return;
923         }
924
925         kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5);
926
927         initialize_krb5_error_table();
928
929         ret = smb_krb5_init_context(kdc, task->lp_ctx, &kdc->smb_krb5_context);
930         if (ret) {
931                 DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
932                          error_message(ret)));
933                 task_server_terminate(task, "kdc: krb5_init_context failed", true);
934                 return;
935         }
936
937         krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);
938
939         ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
940                                   &kdc->config);
941         if(ret) {
942                 task_server_terminate(task, "kdc: failed to get KDC configuration", true);
943                 return;
944         }
945
946         kdc->config->logf = (krb5_log_facility *)kdc->smb_krb5_context->pvt_log_data;
947         kdc->config->db = talloc(kdc, struct HDB *);
948         if (!kdc->config->db) {
949                 task_server_terminate(task, "kdc: out of memory", true);
950                 return;
951         }
952         kdc->config->num_db = 1;
953
954         /*
955          * This restores the behavior before
956          * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3
957          * s4:heimdal: import lorikeet-heimdal-201107150856
958          * (commit 48936803fae4a2fb362c79365d31f420c917b85b)
959          *
960          * as_use_strongest_session_key,preauth_use_strongest_session_key
961          * and tgs_use_strongest_session_key are input to the
962          * _kdc_find_etype() function. The old bahavior is in
963          * the use_strongest_session_key=FALSE code path.
964          * (The only remaining difference in _kdc_find_etype()
965          *  is the is_preauth parameter.)
966          *
967          * The old behavior in the _kdc_get_preferred_key()
968          * function is use_strongest_server_key=TRUE.
969          */
970         kdc->config->as_use_strongest_session_key = false;
971         kdc->config->preauth_use_strongest_session_key = false;
972         kdc->config->tgs_use_strongest_session_key = false;
973         kdc->config->use_strongest_server_key = true;
974
975         /* Register hdb-samba4 hooks for use as a keytab */
976
977         kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
978         if (!kdc->base_ctx) {
979                 task_server_terminate(task, "kdc: out of memory", true);
980                 return;
981         }
982
983         kdc->base_ctx->ev_ctx = task->event_ctx;
984         kdc->base_ctx->lp_ctx = task->lp_ctx;
985
986         status = hdb_samba4_create_kdc(kdc->base_ctx,
987                                        kdc->smb_krb5_context->krb5_context,
988                                        &kdc->config->db[0]);
989         if (!NT_STATUS_IS_OK(status)) {
990                 task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
991                 return;
992         }
993
994         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
995                                    PLUGIN_TYPE_DATA, "hdb",
996                                    &hdb_samba4_interface);
997         if(ret) {
998                 task_server_terminate(task, "kdc: failed to register hdb plugin", true);
999                 return;
1000         }
1001
1002         ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
1003         if(ret) {
1004                 task_server_terminate(task, "kdc: failed to register keytab plugin", true);
1005                 return;
1006         }
1007
1008         /* Register WinDC hooks */
1009         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
1010                                    PLUGIN_TYPE_DATA, "windc",
1011                                    &windc_plugin_table);
1012         if(ret) {
1013                 task_server_terminate(task, "kdc: failed to register windc plugin", true);
1014                 return;
1015         }
1016
1017         ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
1018
1019         if(ret) {
1020                 task_server_terminate(task, "kdc: failed to init windc plugin", true);
1021                 return;
1022         }
1023
1024         ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc->config);
1025
1026         if(ret) {
1027                 task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
1028                 return;
1029         }
1030
1031         /* start listening on the configured network interfaces */
1032         status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces);
1033         if (!NT_STATUS_IS_OK(status)) {
1034                 task_server_terminate(task, "kdc failed to setup interfaces", true);
1035                 return;
1036         }
1037
1038         status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
1039                                kdc_check_generic_kerberos, kdc);
1040         if (!NT_STATUS_IS_OK(status)) {
1041                 task_server_terminate(task, "kdc failed to setup monitoring", true);
1042                 return;
1043         }
1044
1045         irpc_add_name(task->msg_ctx, "kdc_server");
1046 }
1047
1048
1049 /* called at smbd startup - register ourselves as a server service */
1050 NTSTATUS server_service_kdc_init(void)
1051 {
1052         return register_server_service("kdc", kdc_task_init);
1053 }