96791442374bfe375525d1da0d1ee11e6ea8c85f
[sfrench/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
42 static NTSTATUS kdc_proxy_unavailable_error(struct kdc_server *kdc,
43                                             TALLOC_CTX *mem_ctx,
44                                             DATA_BLOB *out)
45 {
46         int kret;
47         krb5_data k5_error_blob;
48
49         kret = krb5_mk_error(kdc->smb_krb5_context->krb5_context,
50                              KRB5KDC_ERR_SVC_UNAVAILABLE, NULL, NULL,
51                              NULL, NULL, NULL, NULL, &k5_error_blob);
52         if (kret != 0) {
53                 DEBUG(2,(__location__ ": Unable to form krb5 error reply\n"));
54                 return NT_STATUS_INTERNAL_ERROR;
55         }
56
57         *out = data_blob_talloc(mem_ctx, k5_error_blob.data, k5_error_blob.length);
58         krb5_data_free(&k5_error_blob);
59         if (!out->data) {
60                 return NT_STATUS_NO_MEMORY;
61         }
62
63         return NT_STATUS_OK;
64 }
65
66 typedef enum kdc_process_ret (*kdc_process_fn_t)(struct kdc_server *kdc,
67                                                  TALLOC_CTX *mem_ctx,
68                                                  DATA_BLOB *input,
69                                                  DATA_BLOB *reply,
70                                                  struct tsocket_address *peer_addr,
71                                                  struct tsocket_address *my_addr,
72                                                  int datagram);
73
74 /* hold information about one kdc socket */
75 struct kdc_socket {
76         struct kdc_server *kdc;
77         struct tsocket_address *local_address;
78         kdc_process_fn_t process;
79 };
80
81 struct kdc_tcp_call {
82         struct kdc_tcp_connection *kdc_conn;
83         DATA_BLOB in;
84         DATA_BLOB out;
85         uint8_t out_hdr[4];
86         struct iovec out_iov[2];
87 };
88
89 /*
90   state of an open tcp connection
91 */
92 struct kdc_tcp_connection {
93         /* stream connection we belong to */
94         struct stream_connection *conn;
95
96         /* the kdc_server the connection belongs to */
97         struct kdc_socket *kdc_socket;
98
99         struct tstream_context *tstream;
100
101         struct tevent_queue *send_queue;
102 };
103
104
105 static void kdc_tcp_terminate_connection(struct kdc_tcp_connection *kdcconn, const char *reason)
106 {
107         stream_terminate_connection(kdcconn->conn, reason);
108 }
109
110 static void kdc_tcp_recv(struct stream_connection *conn, uint16_t flags)
111 {
112         struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data,
113                                                              struct kdc_tcp_connection);
114         /* this should never be triggered! */
115         kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_recv: called");
116 }
117
118 static void kdc_tcp_send(struct stream_connection *conn, uint16_t flags)
119 {
120         struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data,
121                                                              struct kdc_tcp_connection);
122         /* this should never be triggered! */
123         kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_send: called");
124 }
125
126 /**
127    Wrapper for krb5_kdc_process_krb5_request, converting to/from Samba
128    calling conventions
129 */
130
131 static enum kdc_process_ret kdc_process(struct kdc_server *kdc,
132                                         TALLOC_CTX *mem_ctx,
133                                         DATA_BLOB *input,
134                                         DATA_BLOB *reply,
135                                         struct tsocket_address *peer_addr,
136                                         struct tsocket_address *my_addr,
137                                         int datagram_reply)
138 {
139         int ret;
140         char *pa;
141         struct sockaddr_storage ss;
142         krb5_data k5_reply;
143         krb5_data_zero(&k5_reply);
144
145         krb5_kdc_update_time(NULL);
146
147         ret = tsocket_address_bsd_sockaddr(peer_addr, (struct sockaddr *) &ss,
148                                 sizeof(struct sockaddr_storage));
149         if (ret < 0) {
150                 return KDC_PROCESS_FAILED;
151         }
152         pa = tsocket_address_string(peer_addr, mem_ctx);
153         if (pa == NULL) {
154                 return KDC_PROCESS_FAILED;
155         }
156
157         DEBUG(10,("Received KDC packet of length %lu from %s\n",
158                                 (long)input->length - 4, pa));
159
160         ret = krb5_kdc_process_krb5_request(kdc->smb_krb5_context->krb5_context,
161                                             kdc->config,
162                                             input->data, input->length,
163                                             &k5_reply,
164                                             pa,
165                                             (struct sockaddr *) &ss,
166                                             datagram_reply);
167         if (ret == -1) {
168                 *reply = data_blob(NULL, 0);
169                 return KDC_PROCESS_FAILED;
170         }
171
172         if (ret == HDB_ERR_NOT_FOUND_HERE) {
173                 *reply = data_blob(NULL, 0);
174                 return KDC_PROCESS_PROXY;
175         }
176
177         if (k5_reply.length) {
178                 *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length);
179                 krb5_data_free(&k5_reply);
180         } else {
181                 *reply = data_blob(NULL, 0);
182         }
183         return KDC_PROCESS_OK;
184 }
185
186 static void kdc_tcp_call_proxy_done(struct tevent_req *subreq);
187 static void kdc_tcp_call_writev_done(struct tevent_req *subreq);
188
189 static void kdc_tcp_call_loop(struct tevent_req *subreq)
190 {
191         struct kdc_tcp_connection *kdc_conn = tevent_req_callback_data(subreq,
192                                       struct kdc_tcp_connection);
193         struct kdc_tcp_call *call;
194         NTSTATUS status;
195         enum kdc_process_ret ret;
196
197         call = talloc(kdc_conn, struct kdc_tcp_call);
198         if (call == NULL) {
199                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
200                                 "no memory for kdc_tcp_call");
201                 return;
202         }
203         call->kdc_conn = kdc_conn;
204
205         status = tstream_read_pdu_blob_recv(subreq,
206                                             call,
207                                             &call->in);
208         TALLOC_FREE(subreq);
209         if (!NT_STATUS_IS_OK(status)) {
210                 const char *reason;
211
212                 reason = talloc_asprintf(call, "kdc_tcp_call_loop: "
213                                          "tstream_read_pdu_blob_recv() - %s",
214                                          nt_errstr(status));
215                 if (!reason) {
216                         reason = nt_errstr(status);
217                 }
218
219                 kdc_tcp_terminate_connection(kdc_conn, reason);
220                 return;
221         }
222
223         DEBUG(10,("Received krb5 TCP packet of length %lu from %s\n",
224                  (long) call->in.length,
225                  tsocket_address_string(kdc_conn->conn->remote_address, call)));
226
227         /* skip length header */
228         call->in.data +=4;
229         call->in.length -= 4;
230
231         /* Call krb5 */
232         ret = kdc_conn->kdc_socket->process(kdc_conn->kdc_socket->kdc,
233                                            call,
234                                            &call->in,
235                                            &call->out,
236                                            kdc_conn->conn->remote_address,
237                                            kdc_conn->conn->local_address,
238                                            0 /* Stream */);
239         if (ret == KDC_PROCESS_FAILED) {
240                 kdc_tcp_terminate_connection(kdc_conn,
241                                 "kdc_tcp_call_loop: process function failed");
242                 return;
243         }
244
245         if (ret == KDC_PROCESS_PROXY) {
246                 uint16_t port;
247
248                 if (!kdc_conn->kdc_socket->kdc->am_rodc) {
249                         kdc_tcp_terminate_connection(kdc_conn,
250                                                      "kdc_tcp_call_loop: proxying requested when not RODC");
251                         return;
252                 }
253                 port = tsocket_address_inet_port(kdc_conn->conn->local_address);
254
255                 subreq = kdc_tcp_proxy_send(call,
256                                             kdc_conn->conn->event.ctx,
257                                             kdc_conn->kdc_socket->kdc,
258                                             port,
259                                             call->in);
260                 if (subreq == NULL) {
261                         kdc_tcp_terminate_connection(kdc_conn,
262                                 "kdc_tcp_call_loop: kdc_tcp_proxy_send failed");
263                         return;
264                 }
265                 tevent_req_set_callback(subreq, kdc_tcp_call_proxy_done, call);
266                 return;
267         }
268
269         /* First add the length of the out buffer */
270         RSIVAL(call->out_hdr, 0, call->out.length);
271         call->out_iov[0].iov_base = (char *) call->out_hdr;
272         call->out_iov[0].iov_len = 4;
273
274         call->out_iov[1].iov_base = (char *) call->out.data;
275         call->out_iov[1].iov_len = call->out.length;
276
277         subreq = tstream_writev_queue_send(call,
278                                            kdc_conn->conn->event.ctx,
279                                            kdc_conn->tstream,
280                                            kdc_conn->send_queue,
281                                            call->out_iov, 2);
282         if (subreq == NULL) {
283                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
284                                 "no memory for tstream_writev_queue_send");
285                 return;
286         }
287         tevent_req_set_callback(subreq, kdc_tcp_call_writev_done, call);
288
289         /*
290          * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
291          * packet_full_request_u32 provides the pdu length then.
292          */
293         subreq = tstream_read_pdu_blob_send(kdc_conn,
294                                             kdc_conn->conn->event.ctx,
295                                             kdc_conn->tstream,
296                                             4, /* initial_read_size */
297                                             packet_full_request_u32,
298                                             kdc_conn);
299         if (subreq == NULL) {
300                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
301                                 "no memory for tstream_read_pdu_blob_send");
302                 return;
303         }
304         tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
305 }
306
307 static void kdc_tcp_call_proxy_done(struct tevent_req *subreq)
308 {
309         struct kdc_tcp_call *call = tevent_req_callback_data(subreq,
310                         struct kdc_tcp_call);
311         struct kdc_tcp_connection *kdc_conn = call->kdc_conn;
312         NTSTATUS status;
313
314         status = kdc_tcp_proxy_recv(subreq, call, &call->out);
315         TALLOC_FREE(subreq);
316         if (!NT_STATUS_IS_OK(status)) {
317                 /* generate an error packet */
318                 status = kdc_proxy_unavailable_error(kdc_conn->kdc_socket->kdc,
319                                                      call, &call->out);
320         }
321
322         if (!NT_STATUS_IS_OK(status)) {
323                 const char *reason;
324
325                 reason = talloc_asprintf(call, "kdc_tcp_call_proxy_done: "
326                                          "kdc_proxy_unavailable_error - %s",
327                                          nt_errstr(status));
328                 if (!reason) {
329                         reason = "kdc_tcp_call_proxy_done: kdc_proxy_unavailable_error() failed";
330                 }
331
332                 kdc_tcp_terminate_connection(call->kdc_conn, reason);
333                 return;
334         }
335
336         /* First add the length of the out buffer */
337         RSIVAL(call->out_hdr, 0, call->out.length);
338         call->out_iov[0].iov_base = (char *) call->out_hdr;
339         call->out_iov[0].iov_len = 4;
340
341         call->out_iov[1].iov_base = (char *) call->out.data;
342         call->out_iov[1].iov_len = call->out.length;
343
344         subreq = tstream_writev_queue_send(call,
345                                            kdc_conn->conn->event.ctx,
346                                            kdc_conn->tstream,
347                                            kdc_conn->send_queue,
348                                            call->out_iov, 2);
349         if (subreq == NULL) {
350                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
351                                 "no memory for tstream_writev_queue_send");
352                 return;
353         }
354         tevent_req_set_callback(subreq, kdc_tcp_call_writev_done, call);
355
356         /*
357          * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
358          * packet_full_request_u32 provides the pdu length then.
359          */
360         subreq = tstream_read_pdu_blob_send(kdc_conn,
361                                             kdc_conn->conn->event.ctx,
362                                             kdc_conn->tstream,
363                                             4, /* initial_read_size */
364                                             packet_full_request_u32,
365                                             kdc_conn);
366         if (subreq == NULL) {
367                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_call_loop: "
368                                 "no memory for tstream_read_pdu_blob_send");
369                 return;
370         }
371         tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
372 }
373
374 static void kdc_tcp_call_writev_done(struct tevent_req *subreq)
375 {
376         struct kdc_tcp_call *call = tevent_req_callback_data(subreq,
377                         struct kdc_tcp_call);
378         int sys_errno;
379         int rc;
380
381         rc = tstream_writev_queue_recv(subreq, &sys_errno);
382         TALLOC_FREE(subreq);
383         if (rc == -1) {
384                 const char *reason;
385
386                 reason = talloc_asprintf(call, "kdc_tcp_call_writev_done: "
387                                          "tstream_writev_queue_recv() - %d:%s",
388                                          sys_errno, strerror(sys_errno));
389                 if (!reason) {
390                         reason = "kdc_tcp_call_writev_done: tstream_writev_queue_recv() failed";
391                 }
392
393                 kdc_tcp_terminate_connection(call->kdc_conn, reason);
394                 return;
395         }
396
397         /* We don't care about errors */
398
399         talloc_free(call);
400 }
401
402 /*
403   called when we get a new connection
404 */
405 static void kdc_tcp_accept(struct stream_connection *conn)
406 {
407         struct kdc_socket *kdc_socket;
408         struct kdc_tcp_connection *kdc_conn;
409         struct tevent_req *subreq;
410         int rc;
411
412         kdc_conn = talloc_zero(conn, struct kdc_tcp_connection);
413         if (kdc_conn == NULL) {
414                 stream_terminate_connection(conn,
415                                 "kdc_tcp_accept: out of memory");
416                 return;
417         }
418
419         kdc_conn->send_queue = tevent_queue_create(conn, "kdc_tcp_accept");
420         if (kdc_conn->send_queue == NULL) {
421                 stream_terminate_connection(conn,
422                                 "kdc_tcp_accept: out of memory");
423                 return;
424         }
425
426         kdc_socket = talloc_get_type(conn->private_data, struct kdc_socket);
427
428         TALLOC_FREE(conn->event.fde);
429
430         rc = tstream_bsd_existing_socket(kdc_conn,
431                         socket_get_fd(conn->socket),
432                         &kdc_conn->tstream);
433         if (rc < 0) {
434                 stream_terminate_connection(conn,
435                                 "kdc_tcp_accept: out of memory");
436                 return;
437         }
438
439         kdc_conn->conn = conn;
440         kdc_conn->kdc_socket = kdc_socket;
441         conn->private_data = kdc_conn;
442
443         /*
444          * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
445          * packet_full_request_u32 provides the pdu length then.
446          */
447         subreq = tstream_read_pdu_blob_send(kdc_conn,
448                                             kdc_conn->conn->event.ctx,
449                                             kdc_conn->tstream,
450                                             4, /* initial_read_size */
451                                             packet_full_request_u32,
452                                             kdc_conn);
453         if (subreq == NULL) {
454                 kdc_tcp_terminate_connection(kdc_conn, "kdc_tcp_accept: "
455                                 "no memory for tstream_read_pdu_blob_send");
456                 return;
457         }
458         tevent_req_set_callback(subreq, kdc_tcp_call_loop, kdc_conn);
459 }
460
461 static const struct stream_server_ops kdc_tcp_stream_ops = {
462         .name                   = "kdc_tcp",
463         .accept_connection      = kdc_tcp_accept,
464         .recv_handler           = kdc_tcp_recv,
465         .send_handler           = kdc_tcp_send
466 };
467
468 /* hold information about one kdc/kpasswd udp socket */
469 struct kdc_udp_socket {
470         struct kdc_socket *kdc_socket;
471         struct tdgram_context *dgram;
472         struct tevent_queue *send_queue;
473 };
474
475 struct kdc_udp_call {
476         struct kdc_udp_socket *sock;
477         struct tsocket_address *src;
478         DATA_BLOB in;
479         DATA_BLOB out;
480 };
481
482 static void kdc_udp_call_proxy_done(struct tevent_req *subreq);
483 static void kdc_udp_call_sendto_done(struct tevent_req *subreq);
484
485 static void kdc_udp_call_loop(struct tevent_req *subreq)
486 {
487         struct kdc_udp_socket *sock = tevent_req_callback_data(subreq,
488                                       struct kdc_udp_socket);
489         struct kdc_udp_call *call;
490         uint8_t *buf;
491         ssize_t len;
492         int sys_errno;
493         enum kdc_process_ret ret;
494
495         call = talloc(sock, struct kdc_udp_call);
496         if (call == NULL) {
497                 talloc_free(call);
498                 goto done;
499         }
500         call->sock = sock;
501
502         len = tdgram_recvfrom_recv(subreq, &sys_errno,
503                                    call, &buf, &call->src);
504         TALLOC_FREE(subreq);
505         if (len == -1) {
506                 talloc_free(call);
507                 goto done;
508         }
509
510         call->in.data = buf;
511         call->in.length = len;
512
513         DEBUG(10,("Received krb5 UDP packet of length %lu from %s\n",
514                  (long)call->in.length,
515                  tsocket_address_string(call->src, call)));
516
517         /* Call krb5 */
518         ret = sock->kdc_socket->process(sock->kdc_socket->kdc,
519                                        call,
520                                        &call->in,
521                                        &call->out,
522                                        call->src,
523                                        sock->kdc_socket->local_address,
524                                        1 /* Datagram */);
525         if (ret == KDC_PROCESS_FAILED) {
526                 talloc_free(call);
527                 goto done;
528         }
529
530         if (ret == KDC_PROCESS_PROXY) {
531                 uint16_t port;
532
533                 if (!sock->kdc_socket->kdc->am_rodc) {
534                         DEBUG(0,("kdc_udp_call_loop: proxying requested when not RODC"));
535                         talloc_free(call);
536                         goto done;
537                 }
538
539                 port = tsocket_address_inet_port(sock->kdc_socket->local_address);
540
541                 subreq = kdc_udp_proxy_send(call,
542                                             sock->kdc_socket->kdc->task->event_ctx,
543                                             sock->kdc_socket->kdc,
544                                             port,
545                                             call->in);
546                 if (subreq == NULL) {
547                         talloc_free(call);
548                         goto done;
549                 }
550                 tevent_req_set_callback(subreq, kdc_udp_call_proxy_done, call);
551                 goto done;
552         }
553
554         subreq = tdgram_sendto_queue_send(call,
555                                           sock->kdc_socket->kdc->task->event_ctx,
556                                           sock->dgram,
557                                           sock->send_queue,
558                                           call->out.data,
559                                           call->out.length,
560                                           call->src);
561         if (subreq == NULL) {
562                 talloc_free(call);
563                 goto done;
564         }
565         tevent_req_set_callback(subreq, kdc_udp_call_sendto_done, call);
566
567 done:
568         subreq = tdgram_recvfrom_send(sock,
569                                       sock->kdc_socket->kdc->task->event_ctx,
570                                       sock->dgram);
571         if (subreq == NULL) {
572                 task_server_terminate(sock->kdc_socket->kdc->task,
573                                       "no memory for tdgram_recvfrom_send",
574                                       true);
575                 return;
576         }
577         tevent_req_set_callback(subreq, kdc_udp_call_loop, sock);
578 }
579
580 static void kdc_udp_call_proxy_done(struct tevent_req *subreq)
581 {
582         struct kdc_udp_call *call =
583                 tevent_req_callback_data(subreq,
584                 struct kdc_udp_call);
585         NTSTATUS status;
586
587         status = kdc_udp_proxy_recv(subreq, call, &call->out);
588         TALLOC_FREE(subreq);
589         if (!NT_STATUS_IS_OK(status)) {
590                 /* generate an error packet */
591                 status = kdc_proxy_unavailable_error(call->sock->kdc_socket->kdc,
592                                                      call, &call->out);
593         }
594
595         if (!NT_STATUS_IS_OK(status)) {
596                 talloc_free(call);
597                 return;
598         }
599
600         subreq = tdgram_sendto_queue_send(call,
601                                           call->sock->kdc_socket->kdc->task->event_ctx,
602                                           call->sock->dgram,
603                                           call->sock->send_queue,
604                                           call->out.data,
605                                           call->out.length,
606                                           call->src);
607         if (subreq == NULL) {
608                 talloc_free(call);
609                 return;
610         }
611
612         tevent_req_set_callback(subreq, kdc_udp_call_sendto_done, call);
613 }
614
615 static void kdc_udp_call_sendto_done(struct tevent_req *subreq)
616 {
617         struct kdc_udp_call *call = tevent_req_callback_data(subreq,
618                                        struct kdc_udp_call);
619         ssize_t ret;
620         int sys_errno;
621
622         ret = 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                 const char **wcard = iface_list_wildcard(kdc, lp_ctx);
737                 NT_STATUS_HAVE_NO_MEMORY(wcard);
738                 for (i=0; wcard[i]; i++) {
739                         if (kdc_port) {
740                                 status = kdc_add_socket(kdc, model_ops,
741                                                         "kdc", wcard[i], kdc_port,
742                                                         kdc_process, false);
743                                 NT_STATUS_NOT_OK_RETURN(status);
744                         }
745
746                         if (kpasswd_port) {
747                                 status = kdc_add_socket(kdc, model_ops,
748                                                         "kpasswd", wcard[i], kpasswd_port,
749                                                         kpasswdd_process, false);
750                                 NT_STATUS_NOT_OK_RETURN(status);
751                         }
752                 }
753                 talloc_free(wcard);
754                 done_wildcard = true;
755         }
756
757         for (i=0; i<num_interfaces; i++) {
758                 const char *address = talloc_strdup(tmp_ctx, iface_list_n_ip(ifaces, i));
759
760                 if (kdc_port) {
761                         status = kdc_add_socket(kdc, model_ops,
762                                                 "kdc", address, kdc_port,
763                                                 kdc_process, done_wildcard);
764                         NT_STATUS_NOT_OK_RETURN(status);
765                 }
766
767                 if (kpasswd_port) {
768                         status = kdc_add_socket(kdc, model_ops,
769                                                 "kpasswd", address, kpasswd_port,
770                                                 kpasswdd_process, done_wildcard);
771                         NT_STATUS_NOT_OK_RETURN(status);
772                 }
773         }
774
775         talloc_free(tmp_ctx);
776
777         return NT_STATUS_OK;
778 }
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         krb5_enctype etype;
790         int ret;
791         hdb_entry_ex ent;
792         krb5_principal principal;
793         krb5_keyblock keyblock;
794         Key *key;
795
796         /* There is no reply to this request */
797         r->out.generic_reply = data_blob(NULL, 0);
798
799         ndr_err = ndr_pull_struct_blob(&r->in.generic_request, msg, &pac_validate,
800                                        (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate);
801         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
802                 return NT_STATUS_INVALID_PARAMETER;
803         }
804
805         if (pac_validate.MessageType != 3) {
806                 /* We don't implement any other message types - such as certificate validation - yet */
807                 return NT_STATUS_INVALID_PARAMETER;
808         }
809
810         if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength)
811             || pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength
812             || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) {
813                 return NT_STATUS_INVALID_PARAMETER;
814         }
815
816         srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data,
817                                   pac_validate.ChecksumLength);
818
819         if (pac_validate.SignatureType == CKSUMTYPE_HMAC_MD5) {
820                 etype = ETYPE_ARCFOUR_HMAC_MD5;
821         } else {
822                 ret = krb5_cksumtype_to_enctype(kdc->smb_krb5_context->krb5_context, pac_validate.SignatureType,
823                                                 &etype);
824                 if (ret != 0) {
825                         return NT_STATUS_LOGON_FAILURE;
826                 }
827         }
828
829         ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal,
830                                   lpcfg_realm(kdc->task->lp_ctx),
831                                   "krbtgt", lpcfg_realm(kdc->task->lp_ctx),
832                                   NULL);
833
834         if (ret != 0) {
835                 return NT_STATUS_NO_MEMORY;
836         }
837
838         ret = kdc->config->db[0]->hdb_fetch_kvno(kdc->smb_krb5_context->krb5_context,
839                                                  kdc->config->db[0],
840                                                  principal,
841                                                  HDB_F_GET_KRBTGT | HDB_F_DECRYPT,
842                                                  0,
843                                                  &ent);
844         
845         if (ret != 0) {
846                 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
847                 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
848
849                 return NT_STATUS_LOGON_FAILURE;
850         }
851
852         ret = hdb_enctype2key(kdc->smb_krb5_context->krb5_context, &ent.entry, etype, &key);
853
854         if (ret != 0) {
855                 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
856                 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
857                 return NT_STATUS_LOGON_FAILURE;
858         }
859
860         keyblock = key->key;
861
862         kdc_sig.type = pac_validate.SignatureType;
863         kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength],
864                                             pac_validate.SignatureLength);
865         ret = check_pac_checksum(msg, srv_sig, &kdc_sig,
866                            kdc->smb_krb5_context->krb5_context, &keyblock);
867
868         hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent);
869         krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal);
870
871         if (ret != 0) {
872                 return NT_STATUS_LOGON_FAILURE;
873         }
874
875         return NT_STATUS_OK;
876 }
877
878
879 /*
880   startup the kdc task
881 */
882 static void kdc_task_init(struct task_server *task)
883 {
884         struct kdc_server *kdc;
885         NTSTATUS status;
886         krb5_error_code ret;
887         struct interface *ifaces;
888         int ldb_ret;
889
890         switch (lpcfg_server_role(task->lp_ctx)) {
891         case ROLE_STANDALONE:
892                 task_server_terminate(task, "kdc: no KDC required in standalone configuration", false);
893                 return;
894         case ROLE_DOMAIN_MEMBER:
895                 task_server_terminate(task, "kdc: no KDC required in member server configuration", false);
896                 return;
897         case ROLE_DOMAIN_CONTROLLER:
898                 /* Yes, we want a KDC */
899                 break;
900         }
901
902         load_interface_list(task, task->lp_ctx, &ifaces);
903
904         if (iface_list_count(ifaces) == 0) {
905                 task_server_terminate(task, "kdc: no network interfaces configured", false);
906                 return;
907         }
908
909         task_server_set_title(task, "task[kdc]");
910
911         kdc = talloc_zero(task, struct kdc_server);
912         if (kdc == NULL) {
913                 task_server_terminate(task, "kdc: out of memory", true);
914                 return;
915         }
916
917         kdc->task = task;
918
919
920         /* get a samdb connection */
921         kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx,
922                                    system_session(kdc->task->lp_ctx), 0);
923         if (!kdc->samdb) {
924                 DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
925                 task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true);
926                 return;
927         }
928
929         ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc);
930         if (ldb_ret != LDB_SUCCESS) {
931                 DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
932                           ldb_errstring(kdc->samdb)));
933                 task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true);
934                 return;
935         }
936
937         kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5);
938
939         initialize_krb5_error_table();
940
941         ret = smb_krb5_init_context(kdc, task->event_ctx, task->lp_ctx, &kdc->smb_krb5_context);
942         if (ret) {
943                 DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
944                          error_message(ret)));
945                 task_server_terminate(task, "kdc: krb5_init_context failed", true);
946                 return;
947         }
948
949         krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r);
950
951         ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context,
952                                   &kdc->config);
953         if(ret) {
954                 task_server_terminate(task, "kdc: failed to get KDC configuration", true);
955                 return;
956         }
957
958         kdc->config->logf = kdc->smb_krb5_context->logf;
959         kdc->config->db = talloc(kdc, struct HDB *);
960         if (!kdc->config->db) {
961                 task_server_terminate(task, "kdc: out of memory", true);
962                 return;
963         }
964         kdc->config->num_db = 1;
965
966         /*
967          * This restores the behavior before
968          * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3
969          * s4:heimdal: import lorikeet-heimdal-201107150856
970          * (commit 48936803fae4a2fb362c79365d31f420c917b85b)
971          *
972          * as_use_strongest_session_key,preauth_use_strongest_session_key
973          * and tgs_use_strongest_session_key are input to the
974          * _kdc_find_etype() function. The old bahavior is in
975          * the use_strongest_session_key=FALSE code path.
976          * (The only remaining difference in _kdc_find_etype()
977          *  is the is_preauth parameter.)
978          *
979          * The old behavior in the _kdc_get_preferred_key()
980          * function is use_strongest_server_key=TRUE.
981          */
982         kdc->config->as_use_strongest_session_key = false;
983         kdc->config->preauth_use_strongest_session_key = false;
984         kdc->config->tgs_use_strongest_session_key = false;
985         kdc->config->use_strongest_server_key = true;
986
987         /* Register hdb-samba4 hooks for use as a keytab */
988
989         kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context);
990         if (!kdc->base_ctx) {
991                 task_server_terminate(task, "kdc: out of memory", true);
992                 return;
993         }
994
995         kdc->base_ctx->ev_ctx = task->event_ctx;
996         kdc->base_ctx->lp_ctx = task->lp_ctx;
997
998         status = hdb_samba4_create_kdc(kdc->base_ctx,
999                                        kdc->smb_krb5_context->krb5_context,
1000                                        &kdc->config->db[0]);
1001         if (!NT_STATUS_IS_OK(status)) {
1002                 task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
1003                 return;
1004         }
1005
1006         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
1007                                    PLUGIN_TYPE_DATA, "hdb",
1008                                    &hdb_samba4_interface);
1009         if(ret) {
1010                 task_server_terminate(task, "kdc: failed to register hdb plugin", true);
1011                 return;
1012         }
1013
1014         ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops);
1015         if(ret) {
1016                 task_server_terminate(task, "kdc: failed to register keytab plugin", true);
1017                 return;
1018         }
1019
1020         /* Register WinDC hooks */
1021         ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context,
1022                                    PLUGIN_TYPE_DATA, "windc",
1023                                    &windc_plugin_table);
1024         if(ret) {
1025                 task_server_terminate(task, "kdc: failed to register windc plugin", true);
1026                 return;
1027         }
1028
1029         ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context);
1030
1031         if(ret) {
1032                 task_server_terminate(task, "kdc: failed to init windc plugin", true);
1033                 return;
1034         }
1035
1036         ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc->config);
1037
1038         if(ret) {
1039                 task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true);
1040                 return;
1041         }
1042
1043         /* start listening on the configured network interfaces */
1044         status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces);
1045         if (!NT_STATUS_IS_OK(status)) {
1046                 task_server_terminate(task, "kdc failed to setup interfaces", true);
1047                 return;
1048         }
1049
1050         status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS,
1051                                kdc_check_generic_kerberos, kdc);
1052         if (!NT_STATUS_IS_OK(status)) {
1053                 task_server_terminate(task, "kdc failed to setup monitoring", true);
1054                 return;
1055         }
1056
1057         irpc_add_name(task->msg_ctx, "kdc_server");
1058 }
1059
1060
1061 /* called at smbd startup - register ourselves as a server service */
1062 NTSTATUS server_service_kdc_init(void)
1063 {
1064         return register_server_service("kdc", kdc_task_init);
1065 }