d1ce527b24a73f3ddb05729e8d5ce7f69446ce43
[samba.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         ssize_t ret;
621         int sys_errno;
622
623         ret = tdgram_sendto_queue_recv(subreq, &sys_errno);
624
625         /* We don't care about errors */
626
627         talloc_free(call);
628 }
629
630 /*
631   start listening on the given address
632 */
633 static NTSTATUS kdc_add_socket(struct kdc_server *kdc,
634                                const struct model_ops *model_ops,
635                                const char *name,
636                                const char *address,
637                                uint16_t port,
638                                kdc_process_fn_t process,
639                                bool udp_only)
640 {
641         struct kdc_socket *kdc_socket;
642         struct kdc_udp_socket *kdc_udp_socket;
643         struct tevent_req *udpsubreq;
644         NTSTATUS status;
645         int ret;
646
647         kdc_socket = talloc(kdc, struct kdc_socket);
648         NT_STATUS_HAVE_NO_MEMORY(kdc_socket);
649
650         kdc_socket->kdc = kdc;
651         kdc_socket->process = process;
652
653         ret = tsocket_address_inet_from_strings(kdc_socket, "ip",
654                                                 address, port,
655                                                 &kdc_socket->local_address);
656         if (ret != 0) {
657                 status = map_nt_error_from_unix_common(errno);
658                 return status;
659         }
660
661         if (!udp_only) {
662                 status = stream_setup_socket(kdc->task,
663                                              kdc->task->event_ctx,
664                                              kdc->task->lp_ctx,
665                                              model_ops,
666                                              &kdc_tcp_stream_ops,
667                                              "ip", address, &port,
668                                              lpcfg_socket_options(kdc->task->lp_ctx),
669                                              kdc_socket);
670                 if (!NT_STATUS_IS_OK(status)) {
671                         DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
672                                  address, port, nt_errstr(status)));
673                         talloc_free(kdc_socket);
674                         return status;
675                 }
676         }
677
678         kdc_udp_socket = talloc(kdc_socket, struct kdc_udp_socket);
679         NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket);
680
681         kdc_udp_socket->kdc_socket = kdc_socket;
682
683         ret = tdgram_inet_udp_socket(kdc_socket->local_address,
684                                      NULL,
685                                      kdc_udp_socket,
686                                      &kdc_udp_socket->dgram);
687         if (ret != 0) {
688                 status = map_nt_error_from_unix_common(errno);
689                 DEBUG(0,("Failed to bind to %s:%u UDP - %s\n",
690                          address, port, nt_errstr(status)));
691                 return status;
692         }
693
694         kdc_udp_socket->send_queue = tevent_queue_create(kdc_udp_socket,
695                                                          "kdc_udp_send_queue");
696         NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket->send_queue);
697
698         udpsubreq = tdgram_recvfrom_send(kdc_udp_socket,
699                                          kdc->task->event_ctx,
700                                          kdc_udp_socket->dgram);
701         NT_STATUS_HAVE_NO_MEMORY(udpsubreq);
702         tevent_req_set_callback(udpsubreq, kdc_udp_call_loop, kdc_udp_socket);
703
704         return NT_STATUS_OK;
705 }
706
707
708 /*
709   setup our listening sockets on the configured network interfaces
710 */
711 static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_context *lp_ctx,
712                                        struct interface *ifaces)
713 {
714         const struct model_ops *model_ops;
715         int num_interfaces;
716         TALLOC_CTX *tmp_ctx = talloc_new(kdc);
717         NTSTATUS status;
718         int i;
719         uint16_t kdc_port = lpcfg_krb5_port(lp_ctx);
720         uint16_t kpasswd_port = lpcfg_kpasswd_port(lp_ctx);
721         bool done_wildcard = false;
722
723         /* within the kdc task we want to be a single process, so
724            ask for the single process model ops and pass these to the
725            stream_setup_socket() call. */
726         model_ops = process_model_startup("single");
727         if (!model_ops) {
728                 DEBUG(0,("Can't find 'single' process model_ops\n"));
729                 return NT_STATUS_INTERNAL_ERROR;
730         }
731
732         num_interfaces = iface_list_count(ifaces);
733
734         /* if we are allowing incoming packets from any address, then
735            we need to bind to the wildcard address */
736         if (!lpcfg_bind_interfaces_only(lp_ctx)) {
737                 const char **wcard = iface_list_wildcard(kdc, lp_ctx);
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                                 NT_STATUS_NOT_OK_RETURN(status);
745                         }
746
747                         if (kpasswd_port) {
748                                 status = kdc_add_socket(kdc, model_ops,
749                                                         "kpasswd", wcard[i], kpasswd_port,
750                                                         kpasswdd_process, false);
751                                 NT_STATUS_NOT_OK_RETURN(status);
752                         }
753                 }
754                 talloc_free(wcard);
755                 done_wildcard = true;
756         }
757
758         for (i=0; i<num_interfaces; i++) {
759                 const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
760
761                 if (kdc_port) {
762                         status = kdc_add_socket(kdc, model_ops,
763                                                 "kdc", address, kdc_port,
764                                                 kdc_process, done_wildcard);
765                         NT_STATUS_NOT_OK_RETURN(status);
766                 }
767
768                 if (kpasswd_port) {
769                         status = kdc_add_socket(kdc, model_ops,
770                                                 "kpasswd", address, kpasswd_port,
771                                                 kpasswdd_process, done_wildcard);
772                         NT_STATUS_NOT_OK_RETURN(status);
773                 }
774         }
775
776         talloc_free(tmp_ctx);
777
778         return NT_STATUS_OK;
779 }
780
781 static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
782                                  struct kdc_check_generic_kerberos *r)
783 {
784         struct PAC_Validate pac_validate;
785         DATA_BLOB srv_sig;
786         struct PAC_SIGNATURE_DATA kdc_sig;
787         struct kdc_server *kdc = talloc_get_type(msg->private_data, struct kdc_server);
788         enum ndr_err_code ndr_err;
789         int ret;
790         hdb_entry_ex ent;
791         krb5_principal principal;
792
793         /* There is no reply to this request */
794         r->out.generic_reply = data_blob(NULL, 0);
795
796         ndr_err = ndr_pull_struct_blob(&r->in.generic_request, msg, &pac_validate,
797                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
798         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
799                 return NT_STATUS_INVALID_PARAMETER;
800         }
801
802         if (pac_validate.MessageType != NETLOGON_GENERIC_KRB5_PAC_VALIDATE) {
803                 /* We don't implement any other message types - such as certificate validation - yet */
804                 return NT_STATUS_INVALID_PARAMETER;
805         }
806
807         if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength)
808             || pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength
809             || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
810                 return NT_STATUS_INVALID_PARAMETER;
811         }
812
813         srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data,
814                                   pac_validate.ChecksumLength);
815
816         ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal,
817                                   lpcfg_realm(kdc->task->lp_ctx),
818                                   "krbtgt", lpcfg_realm(kdc->task->lp_ctx),
819                                   NULL);
820
821         if (ret != 0) {
822                 return NT_STATUS_NO_MEMORY;
823         }
824
825         ret = kdc->config->db[0]->hdb_fetch_kvno(kdc->smb_krb5_context->krb5_context,
826                                                  kdc->config->db[0],
827                                                  principal,
828                                                  HDB_F_GET_KRBTGT | HDB_F_DECRYPT,
829                                                  0,
830                                                  &ent);
831         
832         if (ret != 0) {
833                 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
834                 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
835
836                 return NT_STATUS_LOGON_FAILURE;
837         }
838
839         kdc_sig.type = pac_validate.SignatureType;
840         kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
841                                             pac_validate.SignatureLength);
842
843         ret = kdc_check_pac(kdc->smb_krb5_context->krb5_context, srv_sig, &kdc_sig, &ent);
844
845         hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
846         krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
847
848         if (ret != 0) {
849                 return NT_STATUS_LOGON_FAILURE;
850         }
851
852         return NT_STATUS_OK;
853 }
854
855
856 /*
857   startup the kdc task
858 */
859 static void kdc_task_init(struct task_server *task)
860 {
861         struct kdc_server *kdc;
862         NTSTATUS status;
863         krb5_error_code ret;
864         struct interface *ifaces;
865         int ldb_ret;
866
867         switch (lpcfg_server_role(task->lp_ctx)) {
868         case ROLE_STANDALONE:
869                 task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
870                 return;
871         case ROLE_DOMAIN_MEMBER:
872                 task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
873                 return;
874         case ROLE_DOMAIN_CONTROLLER:
875                 /* Yes, we want a KDC */
876                 break;
877         }
878
879         load_interface_list(task, task->lp_ctx, &ifaces);
880
881         if (iface_list_count(ifaces) == 0) {
882                 task_server_terminate(task, "kdc: no network interfaces configured", false);
883                 return;
884         }
885
886         task_server_set_title(task, "task[kdc]");
887
888         kdc = talloc_zero(task, struct kdc_server);
889         if (kdc == NULL) {
890                 task_server_terminate(task, "kdc: out of memory", true);
891                 return;
892         }
893
894         kdc->task = task;
895
896
897         /* get a samdb connection */
898         kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx,
899                                    system_session(kdc->task->lp_ctx), 0);
900         if (!kdc->samdb) {
901                 DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
902                 task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
903                 return;
904         }
905
906         ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
907         if (ldb_ret != LDB_SUCCESS) {
908                 DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
909                           ldb_errstring(kdc->samdb)));
910                 task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
911                 return;
912         }
913
914         kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5);
915
916         initialize_krb5_error_table();
917
918         ret = smb_krb5_init_context(kdc, task->event_ctx, task->lp_ctx, &kdc->smb_krb5_context);
919         if (ret) {
920                 DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
921                          error_message(ret)));
922                 task_server_terminate(task, "kdc: krb5_init_context failed", true);
923                 return;
924         }
925
926         krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);
927
928         ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
929                                   &kdc->config);
930         if(ret) {
931                 task_server_terminate(task, "kdc: failed to get KDC configuration", true);
932                 return;
933         }
934
935         kdc->config->logf = kdc->smb_krb5_context->logf;
936         kdc->config->db = talloc(kdc, struct HDB *);
937         if (!kdc->config->db) {
938                 task_server_terminate(task, "kdc: out of memory", true);
939                 return;
940         }
941         kdc->config->num_db = 1;
942
943         /*
944          * This restores the behavior before
945          * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3
946          * s4:heimdal: import lorikeet-heimdal-201107150856
947          * (commit 48936803fae4a2fb362c79365d31f420c917b85b)
948          *
949          * as_use_strongest_session_key,preauth_use_strongest_session_key
950          * and tgs_use_strongest_session_key are input to the
951          * _kdc_find_etype() function. The old bahavior is in
952          * the use_strongest_session_key=FALSE code path.
953          * (The only remaining difference in _kdc_find_etype()
954          *  is the is_preauth parameter.)
955          *
956          * The old behavior in the _kdc_get_preferred_key()
957          * function is use_strongest_server_key=TRUE.
958          */
959         kdc->config->as_use_strongest_session_key = false;
960         kdc->config->preauth_use_strongest_session_key = false;
961         kdc->config->tgs_use_strongest_session_key = false;
962         kdc->config->use_strongest_server_key = true;
963
964         /* Register hdb-samba4 hooks for use as a keytab */
965
966         kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
967         if (!kdc->base_ctx) {
968                 task_server_terminate(task, "kdc: out of memory", true);
969                 return;
970         }
971
972         kdc->base_ctx->ev_ctx = task->event_ctx;
973         kdc->base_ctx->lp_ctx = task->lp_ctx;
974
975         status = hdb_samba4_create_kdc(kdc->base_ctx,
976                                        kdc->smb_krb5_context->krb5_context,
977                                        &kdc->config->db[0]);
978         if (!NT_STATUS_IS_OK(status)) {
979                 task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
980                 return;
981         }
982
983         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
984                                    PLUGIN_TYPE_DATA, "hdb",
985                                    &hdb_samba4_interface);
986         if(ret) {
987                 task_server_terminate(task, "kdc: failed to register hdb plugin", true);
988                 return;
989         }
990
991         ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
992         if(ret) {
993                 task_server_terminate(task, "kdc: failed to register keytab plugin", true);
994                 return;
995         }
996
997         /* Register WinDC hooks */
998         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
999                                    PLUGIN_TYPE_DATA, "windc",
1000                                    &windc_plugin_table);
1001         if(ret) {
1002                 task_server_terminate(task, "kdc: failed to register windc plugin", true);
1003                 return;
1004         }
1005
1006         ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
1007
1008         if(ret) {
1009                 task_server_terminate(task, "kdc: failed to init windc plugin", true);
1010                 return;
1011         }
1012
1013         ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc->config);
1014
1015         if(ret) {
1016                 task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
1017                 return;
1018         }
1019
1020         /* start listening on the configured network interfaces */
1021         status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces);
1022         if (!NT_STATUS_IS_OK(status)) {
1023                 task_server_terminate(task, "kdc failed to setup interfaces", true);
1024                 return;
1025         }
1026
1027         status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
1028                                kdc_check_generic_kerberos, kdc);
1029         if (!NT_STATUS_IS_OK(status)) {
1030                 task_server_terminate(task, "kdc failed to setup monitoring", true);
1031                 return;
1032         }
1033
1034         irpc_add_name(task->msg_ctx, "kdc_server");
1035 }
1036
1037
1038 /* called at smbd startup - register ourselves as a server service */
1039 NTSTATUS server_service_kdc_init(void)
1040 {
1041         return register_server_service("kdc", kdc_task_init);
1042 }