libcli/util Rename common map_nt_error_from_unix to avoid duplicate symbol
[bbaumbach/samba-autobuild/.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 "dsdb/samdb/samdb.h"
36 #include "auth/session.h"
37
38 NTSTATUS server_service_kdc_init(void);
39
40 extern struct krb5plugin_windc_ftable windc_plugin_table;
41 extern struct hdb_method hdb_samba4;
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
782 static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg,
783                                  struct kdc_check_generic_kerberos *r)
784 {
785         struct PAC_Validate pac_validate;
786         DATA_BLOB srv_sig;
787         struct PAC_SIGNATURE_DATA kdc_sig;
788         struct kdc_server *kdc = talloc_get_type(msg->private_data, struct kdc_server);
789         enum ndr_err_code ndr_err;
790         krb5_enctype etype;
791         int ret;
792         hdb_entry_ex ent;
793         krb5_principal principal;
794         krb5_keyblock keyblock;
795         Key *key;
796
797         /* There is no reply to this request */
798         r->out.generic_reply = data_blob(NULL, 0);
799
800         ndr_err = ndr_pull_struct_blob(&r->in.generic_request, msg, &pac_validate,
801                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
802         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
803                 return NT_STATUS_INVALID_PARAMETER;
804         }
805
806         if (pac_validate.MessageType != 3) {
807                 /* We don't implement any other message types - such as certificate validation - yet */
808                 return NT_STATUS_INVALID_PARAMETER;
809         }
810
811         if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength)
812             || pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength
813             || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
814                 return NT_STATUS_INVALID_PARAMETER;
815         }
816
817         srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data,
818                                   pac_validate.ChecksumLength);
819
820         if (pac_validate.SignatureType == CKSUMTYPE_HMAC_MD5) {
821                 etype = ETYPE_ARCFOUR_HMAC_MD5;
822         } else {
823                 ret = krb5_cksumtype_to_enctype(kdc->smb_krb5_context->krb5_context, pac_validate.SignatureType,
824                                                 &etype);
825                 if (ret != 0) {
826                         return NT_STATUS_LOGON_FAILURE;
827                 }
828         }
829
830         ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal,
831                                   lpcfg_realm(kdc->task->lp_ctx),
832                                   "krbtgt", lpcfg_realm(kdc->task->lp_ctx),
833                                   NULL);
834
835         if (ret != 0) {
836                 return NT_STATUS_NO_MEMORY;
837         }
838
839         ret = kdc->config->db[0]->hdb_fetch_kvno(kdc->smb_krb5_context->krb5_context,
840                                                  kdc->config->db[0],
841                                                  principal,
842                                                  HDB_F_GET_KRBTGT | HDB_F_DECRYPT,
843                                                  0,
844                                                  &ent);
845         
846         if (ret != 0) {
847                 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
848                 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
849
850                 return NT_STATUS_LOGON_FAILURE;
851         }
852
853         ret = hdb_enctype2key(kdc->smb_krb5_context->krb5_context, &ent.entry, etype, &key);
854
855         if (ret != 0) {
856                 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
857                 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
858                 return NT_STATUS_LOGON_FAILURE;
859         }
860
861         keyblock = key->key;
862
863         kdc_sig.type = pac_validate.SignatureType;
864         kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
865                                             pac_validate.SignatureLength);
866         ret = check_pac_checksum(msg, srv_sig, &kdc_sig,
867                            kdc->smb_krb5_context->krb5_context, &keyblock);
868
869         hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
870         krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
871
872         if (ret != 0) {
873                 return NT_STATUS_LOGON_FAILURE;
874         }
875
876         return NT_STATUS_OK;
877 }
878
879
880 /*
881   startup the kdc task
882 */
883 static void kdc_task_init(struct task_server *task)
884 {
885         struct kdc_server *kdc;
886         NTSTATUS status;
887         krb5_error_code ret;
888         struct interface *ifaces;
889         int ldb_ret;
890
891         switch (lpcfg_server_role(task->lp_ctx)) {
892         case ROLE_STANDALONE:
893                 task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
894                 return;
895         case ROLE_DOMAIN_MEMBER:
896                 task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
897                 return;
898         case ROLE_DOMAIN_CONTROLLER:
899                 /* Yes, we want a KDC */
900                 break;
901         }
902
903         load_interface_list(task, task->lp_ctx, &ifaces);
904
905         if (iface_list_count(ifaces) == 0) {
906                 task_server_terminate(task, "kdc: no network interfaces configured", false);
907                 return;
908         }
909
910         task_server_set_title(task, "task[kdc]");
911
912         kdc = talloc_zero(task, struct kdc_server);
913         if (kdc == NULL) {
914                 task_server_terminate(task, "kdc: out of memory", true);
915                 return;
916         }
917
918         kdc->task = task;
919
920
921         /* get a samdb connection */
922         kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx,
923                                    system_session(kdc->task->lp_ctx), 0);
924         if (!kdc->samdb) {
925                 DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
926                 task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
927                 return;
928         }
929
930         ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
931         if (ldb_ret != LDB_SUCCESS) {
932                 DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
933                           ldb_errstring(kdc->samdb)));
934                 task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
935                 return;
936         }
937
938         kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5);
939
940         initialize_krb5_error_table();
941
942         ret = smb_krb5_init_context(kdc, task->event_ctx, task->lp_ctx, &kdc->smb_krb5_context);
943         if (ret) {
944                 DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
945                          error_message(ret)));
946                 task_server_terminate(task, "kdc: krb5_init_context failed", true);
947                 return;
948         }
949
950         krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);
951
952         ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
953                                   &kdc->config);
954         if(ret) {
955                 task_server_terminate(task, "kdc: failed to get KDC configuration", true);
956                 return;
957         }
958
959         kdc->config->logf = kdc->smb_krb5_context->logf;
960         kdc->config->db = talloc(kdc, struct HDB *);
961         if (!kdc->config->db) {
962                 task_server_terminate(task, "kdc: out of memory", true);
963                 return;
964         }
965         kdc->config->num_db = 1;
966
967         /* Register hdb-samba4 hooks for use as a keytab */
968
969         kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
970         if (!kdc->base_ctx) {
971                 task_server_terminate(task, "kdc: out of memory", true);
972                 return;
973         }
974
975         kdc->base_ctx->ev_ctx = task->event_ctx;
976         kdc->base_ctx->lp_ctx = task->lp_ctx;
977
978         status = hdb_samba4_create_kdc(kdc->base_ctx,
979                                        kdc->smb_krb5_context->krb5_context,
980                                        &kdc->config->db[0]);
981         if (!NT_STATUS_IS_OK(status)) {
982                 task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
983                 return;
984         }
985
986         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
987                                    PLUGIN_TYPE_DATA, "hdb",
988                                    &hdb_samba4);
989         if(ret) {
990                 task_server_terminate(task, "kdc: failed to register hdb plugin", true);
991                 return;
992         }
993
994         ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
995         if(ret) {
996                 task_server_terminate(task, "kdc: failed to register keytab plugin", true);
997                 return;
998         }
999
1000         /* Register WinDC hooks */
1001         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
1002                                    PLUGIN_TYPE_DATA, "windc",
1003                                    &windc_plugin_table);
1004         if(ret) {
1005                 task_server_terminate(task, "kdc: failed to register windc plugin", true);
1006                 return;
1007         }
1008
1009         ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
1010
1011         if(ret) {
1012                 task_server_terminate(task, "kdc: failed to init windc plugin", true);
1013                 return;
1014         }
1015
1016         ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc->config);
1017
1018         if(ret) {
1019                 task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
1020                 return;
1021         }
1022
1023         /* start listening on the configured network interfaces */
1024         status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces);
1025         if (!NT_STATUS_IS_OK(status)) {
1026                 task_server_terminate(task, "kdc failed to setup interfaces", true);
1027                 return;
1028         }
1029
1030         status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
1031                                kdc_check_generic_kerberos, kdc);
1032         if (!NT_STATUS_IS_OK(status)) {
1033                 task_server_terminate(task, "kdc failed to setup monitoring", true);
1034                 return;
1035         }
1036
1037         irpc_add_name(task->msg_ctx, "kdc_server");
1038 }
1039
1040
1041 /* called at smbd startup - register ourselves as a server service */
1042 NTSTATUS server_service_kdc_init(void)
1043 {
1044         return register_server_service("kdc", kdc_task_init);
1045 }