2 Unix SMB/CIFS implementation.
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005-2008
7 Copyright (C) Andrew Tridgell 2005
8 Copyright (C) Stefan Metzmacher 2005
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.
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.
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/>.
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 #include "libds/common/roles.h"
40 NTSTATUS
server_service_kdc_init(void);
42 extern struct krb5plugin_windc_ftable windc_plugin_table
;
44 static NTSTATUS
kdc_proxy_unavailable_error(struct kdc_server
*kdc
,
49 krb5_data k5_error_blob
;
51 kret
= krb5_mk_error(kdc
->smb_krb5_context
->krb5_context
,
52 KRB5KDC_ERR_SVC_UNAVAILABLE
, NULL
, NULL
,
53 NULL
, NULL
, NULL
, NULL
, &k5_error_blob
);
55 DEBUG(2,(__location__
": Unable to form krb5 error reply\n"));
56 return NT_STATUS_INTERNAL_ERROR
;
59 *out
= data_blob_talloc(mem_ctx
, k5_error_blob
.data
, k5_error_blob
.length
);
60 krb5_data_free(&k5_error_blob
);
62 return NT_STATUS_NO_MEMORY
;
68 typedef enum kdc_process_ret (*kdc_process_fn_t
)(struct kdc_server
*kdc
,
72 struct tsocket_address
*peer_addr
,
73 struct tsocket_address
*my_addr
,
76 /* hold information about one kdc socket */
78 struct kdc_server
*kdc
;
79 struct tsocket_address
*local_address
;
80 kdc_process_fn_t process
;
84 struct kdc_tcp_connection
*kdc_conn
;
88 struct iovec out_iov
[2];
92 state of an open tcp connection
94 struct kdc_tcp_connection
{
95 /* stream connection we belong to */
96 struct stream_connection
*conn
;
98 /* the kdc_server the connection belongs to */
99 struct kdc_socket
*kdc_socket
;
101 struct tstream_context
*tstream
;
103 struct tevent_queue
*send_queue
;
107 static void kdc_tcp_terminate_connection(struct kdc_tcp_connection
*kdcconn
, const char *reason
)
109 stream_terminate_connection(kdcconn
->conn
, reason
);
112 static void kdc_tcp_recv(struct stream_connection
*conn
, uint16_t flags
)
114 struct kdc_tcp_connection
*kdcconn
= talloc_get_type(conn
->private_data
,
115 struct kdc_tcp_connection
);
116 /* this should never be triggered! */
117 kdc_tcp_terminate_connection(kdcconn
, "kdc_tcp_recv: called");
120 static void kdc_tcp_send(struct stream_connection
*conn
, uint16_t flags
)
122 struct kdc_tcp_connection
*kdcconn
= talloc_get_type(conn
->private_data
,
123 struct kdc_tcp_connection
);
124 /* this should never be triggered! */
125 kdc_tcp_terminate_connection(kdcconn
, "kdc_tcp_send: called");
129 Wrapper for krb5_kdc_process_krb5_request, converting to/from Samba
133 static enum kdc_process_ret
kdc_process(struct kdc_server
*kdc
,
137 struct tsocket_address
*peer_addr
,
138 struct tsocket_address
*my_addr
,
143 struct sockaddr_storage ss
;
145 krb5_data_zero(&k5_reply
);
147 krb5_kdc_update_time(NULL
);
149 ret
= tsocket_address_bsd_sockaddr(peer_addr
, (struct sockaddr
*) &ss
,
150 sizeof(struct sockaddr_storage
));
152 return KDC_PROCESS_FAILED
;
154 pa
= tsocket_address_string(peer_addr
, mem_ctx
);
156 return KDC_PROCESS_FAILED
;
159 DEBUG(10,("Received KDC packet of length %lu from %s\n",
160 (long)input
->length
- 4, pa
));
162 ret
= krb5_kdc_process_krb5_request(kdc
->smb_krb5_context
->krb5_context
,
164 input
->data
, input
->length
,
167 (struct sockaddr
*) &ss
,
170 *reply
= data_blob(NULL
, 0);
171 return KDC_PROCESS_FAILED
;
174 if (ret
== HDB_ERR_NOT_FOUND_HERE
) {
175 *reply
= data_blob(NULL
, 0);
176 return KDC_PROCESS_PROXY
;
179 if (k5_reply
.length
) {
180 *reply
= data_blob_talloc(mem_ctx
, k5_reply
.data
, k5_reply
.length
);
181 krb5_data_free(&k5_reply
);
183 *reply
= data_blob(NULL
, 0);
185 return KDC_PROCESS_OK
;
188 static void kdc_tcp_call_proxy_done(struct tevent_req
*subreq
);
189 static void kdc_tcp_call_writev_done(struct tevent_req
*subreq
);
191 static void kdc_tcp_call_loop(struct tevent_req
*subreq
)
193 struct kdc_tcp_connection
*kdc_conn
= tevent_req_callback_data(subreq
,
194 struct kdc_tcp_connection
);
195 struct kdc_tcp_call
*call
;
197 enum kdc_process_ret ret
;
199 call
= talloc(kdc_conn
, struct kdc_tcp_call
);
201 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
202 "no memory for kdc_tcp_call");
205 call
->kdc_conn
= kdc_conn
;
207 status
= tstream_read_pdu_blob_recv(subreq
,
211 if (!NT_STATUS_IS_OK(status
)) {
214 reason
= talloc_asprintf(call
, "kdc_tcp_call_loop: "
215 "tstream_read_pdu_blob_recv() - %s",
218 reason
= nt_errstr(status
);
221 kdc_tcp_terminate_connection(kdc_conn
, reason
);
225 DEBUG(10,("Received krb5 TCP packet of length %lu from %s\n",
226 (long) call
->in
.length
,
227 tsocket_address_string(kdc_conn
->conn
->remote_address
, call
)));
229 /* skip length header */
231 call
->in
.length
-= 4;
234 ret
= kdc_conn
->kdc_socket
->process(kdc_conn
->kdc_socket
->kdc
,
238 kdc_conn
->conn
->remote_address
,
239 kdc_conn
->conn
->local_address
,
241 if (ret
== KDC_PROCESS_FAILED
) {
242 kdc_tcp_terminate_connection(kdc_conn
,
243 "kdc_tcp_call_loop: process function failed");
247 if (ret
== KDC_PROCESS_PROXY
) {
250 if (!kdc_conn
->kdc_socket
->kdc
->am_rodc
) {
251 kdc_tcp_terminate_connection(kdc_conn
,
252 "kdc_tcp_call_loop: proxying requested when not RODC");
255 port
= tsocket_address_inet_port(kdc_conn
->conn
->local_address
);
257 subreq
= kdc_tcp_proxy_send(call
,
258 kdc_conn
->conn
->event
.ctx
,
259 kdc_conn
->kdc_socket
->kdc
,
262 if (subreq
== NULL
) {
263 kdc_tcp_terminate_connection(kdc_conn
,
264 "kdc_tcp_call_loop: kdc_tcp_proxy_send failed");
267 tevent_req_set_callback(subreq
, kdc_tcp_call_proxy_done
, call
);
271 /* First add the length of the out buffer */
272 RSIVAL(call
->out_hdr
, 0, call
->out
.length
);
273 call
->out_iov
[0].iov_base
= (char *) call
->out_hdr
;
274 call
->out_iov
[0].iov_len
= 4;
276 call
->out_iov
[1].iov_base
= (char *) call
->out
.data
;
277 call
->out_iov
[1].iov_len
= call
->out
.length
;
279 subreq
= tstream_writev_queue_send(call
,
280 kdc_conn
->conn
->event
.ctx
,
282 kdc_conn
->send_queue
,
284 if (subreq
== NULL
) {
285 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
286 "no memory for tstream_writev_queue_send");
289 tevent_req_set_callback(subreq
, kdc_tcp_call_writev_done
, call
);
292 * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
293 * packet_full_request_u32 provides the pdu length then.
295 subreq
= tstream_read_pdu_blob_send(kdc_conn
,
296 kdc_conn
->conn
->event
.ctx
,
298 4, /* initial_read_size */
299 packet_full_request_u32
,
301 if (subreq
== NULL
) {
302 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
303 "no memory for tstream_read_pdu_blob_send");
306 tevent_req_set_callback(subreq
, kdc_tcp_call_loop
, kdc_conn
);
309 static void kdc_tcp_call_proxy_done(struct tevent_req
*subreq
)
311 struct kdc_tcp_call
*call
= tevent_req_callback_data(subreq
,
312 struct kdc_tcp_call
);
313 struct kdc_tcp_connection
*kdc_conn
= call
->kdc_conn
;
316 status
= kdc_tcp_proxy_recv(subreq
, call
, &call
->out
);
318 if (!NT_STATUS_IS_OK(status
)) {
319 /* generate an error packet */
320 status
= kdc_proxy_unavailable_error(kdc_conn
->kdc_socket
->kdc
,
324 if (!NT_STATUS_IS_OK(status
)) {
327 reason
= talloc_asprintf(call
, "kdc_tcp_call_proxy_done: "
328 "kdc_proxy_unavailable_error - %s",
331 reason
= "kdc_tcp_call_proxy_done: kdc_proxy_unavailable_error() failed";
334 kdc_tcp_terminate_connection(call
->kdc_conn
, reason
);
338 /* First add the length of the out buffer */
339 RSIVAL(call
->out_hdr
, 0, call
->out
.length
);
340 call
->out_iov
[0].iov_base
= (char *) call
->out_hdr
;
341 call
->out_iov
[0].iov_len
= 4;
343 call
->out_iov
[1].iov_base
= (char *) call
->out
.data
;
344 call
->out_iov
[1].iov_len
= call
->out
.length
;
346 subreq
= tstream_writev_queue_send(call
,
347 kdc_conn
->conn
->event
.ctx
,
349 kdc_conn
->send_queue
,
351 if (subreq
== NULL
) {
352 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
353 "no memory for tstream_writev_queue_send");
356 tevent_req_set_callback(subreq
, kdc_tcp_call_writev_done
, call
);
359 * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
360 * packet_full_request_u32 provides the pdu length then.
362 subreq
= tstream_read_pdu_blob_send(kdc_conn
,
363 kdc_conn
->conn
->event
.ctx
,
365 4, /* initial_read_size */
366 packet_full_request_u32
,
368 if (subreq
== NULL
) {
369 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
370 "no memory for tstream_read_pdu_blob_send");
373 tevent_req_set_callback(subreq
, kdc_tcp_call_loop
, kdc_conn
);
376 static void kdc_tcp_call_writev_done(struct tevent_req
*subreq
)
378 struct kdc_tcp_call
*call
= tevent_req_callback_data(subreq
,
379 struct kdc_tcp_call
);
383 rc
= tstream_writev_queue_recv(subreq
, &sys_errno
);
388 reason
= talloc_asprintf(call
, "kdc_tcp_call_writev_done: "
389 "tstream_writev_queue_recv() - %d:%s",
390 sys_errno
, strerror(sys_errno
));
392 reason
= "kdc_tcp_call_writev_done: tstream_writev_queue_recv() failed";
395 kdc_tcp_terminate_connection(call
->kdc_conn
, reason
);
399 /* We don't care about errors */
405 called when we get a new connection
407 static void kdc_tcp_accept(struct stream_connection
*conn
)
409 struct kdc_socket
*kdc_socket
;
410 struct kdc_tcp_connection
*kdc_conn
;
411 struct tevent_req
*subreq
;
414 kdc_conn
= talloc_zero(conn
, struct kdc_tcp_connection
);
415 if (kdc_conn
== NULL
) {
416 stream_terminate_connection(conn
,
417 "kdc_tcp_accept: out of memory");
421 kdc_conn
->send_queue
= tevent_queue_create(conn
, "kdc_tcp_accept");
422 if (kdc_conn
->send_queue
== NULL
) {
423 stream_terminate_connection(conn
,
424 "kdc_tcp_accept: out of memory");
428 kdc_socket
= talloc_get_type(conn
->private_data
, struct kdc_socket
);
430 TALLOC_FREE(conn
->event
.fde
);
432 rc
= tstream_bsd_existing_socket(kdc_conn
,
433 socket_get_fd(conn
->socket
),
436 stream_terminate_connection(conn
,
437 "kdc_tcp_accept: out of memory");
441 kdc_conn
->conn
= conn
;
442 kdc_conn
->kdc_socket
= kdc_socket
;
443 conn
->private_data
= kdc_conn
;
446 * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
447 * packet_full_request_u32 provides the pdu length then.
449 subreq
= tstream_read_pdu_blob_send(kdc_conn
,
450 kdc_conn
->conn
->event
.ctx
,
452 4, /* initial_read_size */
453 packet_full_request_u32
,
455 if (subreq
== NULL
) {
456 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_accept: "
457 "no memory for tstream_read_pdu_blob_send");
460 tevent_req_set_callback(subreq
, kdc_tcp_call_loop
, kdc_conn
);
463 static const struct stream_server_ops kdc_tcp_stream_ops
= {
465 .accept_connection
= kdc_tcp_accept
,
466 .recv_handler
= kdc_tcp_recv
,
467 .send_handler
= kdc_tcp_send
470 /* hold information about one kdc/kpasswd udp socket */
471 struct kdc_udp_socket
{
472 struct kdc_socket
*kdc_socket
;
473 struct tdgram_context
*dgram
;
474 struct tevent_queue
*send_queue
;
477 struct kdc_udp_call
{
478 struct kdc_udp_socket
*sock
;
479 struct tsocket_address
*src
;
484 static void kdc_udp_call_proxy_done(struct tevent_req
*subreq
);
485 static void kdc_udp_call_sendto_done(struct tevent_req
*subreq
);
487 static void kdc_udp_call_loop(struct tevent_req
*subreq
)
489 struct kdc_udp_socket
*sock
= tevent_req_callback_data(subreq
,
490 struct kdc_udp_socket
);
491 struct kdc_udp_call
*call
;
495 enum kdc_process_ret ret
;
497 call
= talloc(sock
, struct kdc_udp_call
);
504 len
= tdgram_recvfrom_recv(subreq
, &sys_errno
,
505 call
, &buf
, &call
->src
);
513 call
->in
.length
= len
;
515 DEBUG(10,("Received krb5 UDP packet of length %lu from %s\n",
516 (long)call
->in
.length
,
517 tsocket_address_string(call
->src
, call
)));
520 ret
= sock
->kdc_socket
->process(sock
->kdc_socket
->kdc
,
525 sock
->kdc_socket
->local_address
,
527 if (ret
== KDC_PROCESS_FAILED
) {
532 if (ret
== KDC_PROCESS_PROXY
) {
535 if (!sock
->kdc_socket
->kdc
->am_rodc
) {
536 DEBUG(0,("kdc_udp_call_loop: proxying requested when not RODC"));
541 port
= tsocket_address_inet_port(sock
->kdc_socket
->local_address
);
543 subreq
= kdc_udp_proxy_send(call
,
544 sock
->kdc_socket
->kdc
->task
->event_ctx
,
545 sock
->kdc_socket
->kdc
,
548 if (subreq
== NULL
) {
552 tevent_req_set_callback(subreq
, kdc_udp_call_proxy_done
, call
);
556 subreq
= tdgram_sendto_queue_send(call
,
557 sock
->kdc_socket
->kdc
->task
->event_ctx
,
563 if (subreq
== NULL
) {
567 tevent_req_set_callback(subreq
, kdc_udp_call_sendto_done
, call
);
570 subreq
= tdgram_recvfrom_send(sock
,
571 sock
->kdc_socket
->kdc
->task
->event_ctx
,
573 if (subreq
== NULL
) {
574 task_server_terminate(sock
->kdc_socket
->kdc
->task
,
575 "no memory for tdgram_recvfrom_send",
579 tevent_req_set_callback(subreq
, kdc_udp_call_loop
, sock
);
582 static void kdc_udp_call_proxy_done(struct tevent_req
*subreq
)
584 struct kdc_udp_call
*call
=
585 tevent_req_callback_data(subreq
,
586 struct kdc_udp_call
);
589 status
= kdc_udp_proxy_recv(subreq
, call
, &call
->out
);
591 if (!NT_STATUS_IS_OK(status
)) {
592 /* generate an error packet */
593 status
= kdc_proxy_unavailable_error(call
->sock
->kdc_socket
->kdc
,
597 if (!NT_STATUS_IS_OK(status
)) {
602 subreq
= tdgram_sendto_queue_send(call
,
603 call
->sock
->kdc_socket
->kdc
->task
->event_ctx
,
605 call
->sock
->send_queue
,
609 if (subreq
== NULL
) {
614 tevent_req_set_callback(subreq
, kdc_udp_call_sendto_done
, call
);
617 static void kdc_udp_call_sendto_done(struct tevent_req
*subreq
)
619 struct kdc_udp_call
*call
= tevent_req_callback_data(subreq
,
620 struct kdc_udp_call
);
623 tdgram_sendto_queue_recv(subreq
, &sys_errno
);
625 /* We don't care about errors */
631 start listening on the given address
633 static NTSTATUS
kdc_add_socket(struct kdc_server
*kdc
,
634 const struct model_ops
*model_ops
,
638 kdc_process_fn_t process
,
641 struct kdc_socket
*kdc_socket
;
642 struct kdc_udp_socket
*kdc_udp_socket
;
643 struct tevent_req
*udpsubreq
;
647 kdc_socket
= talloc(kdc
, struct kdc_socket
);
648 NT_STATUS_HAVE_NO_MEMORY(kdc_socket
);
650 kdc_socket
->kdc
= kdc
;
651 kdc_socket
->process
= process
;
653 ret
= tsocket_address_inet_from_strings(kdc_socket
, "ip",
655 &kdc_socket
->local_address
);
657 status
= map_nt_error_from_unix_common(errno
);
662 status
= stream_setup_socket(kdc
->task
,
663 kdc
->task
->event_ctx
,
667 "ip", address
, &port
,
668 lpcfg_socket_options(kdc
->task
->lp_ctx
),
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
);
678 kdc_udp_socket
= talloc(kdc_socket
, struct kdc_udp_socket
);
679 NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket
);
681 kdc_udp_socket
->kdc_socket
= kdc_socket
;
683 ret
= tdgram_inet_udp_socket(kdc_socket
->local_address
,
686 &kdc_udp_socket
->dgram
);
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
)));
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
);
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
);
709 setup our listening sockets on the configured network interfaces
711 static NTSTATUS
kdc_startup_interfaces(struct kdc_server
*kdc
, struct loadparm_context
*lp_ctx
,
712 struct interface
*ifaces
)
714 const struct model_ops
*model_ops
;
716 TALLOC_CTX
*tmp_ctx
= talloc_new(kdc
);
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;
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");
728 DEBUG(0,("Can't find 'single' process model_ops\n"));
729 return NT_STATUS_INTERNAL_ERROR
;
732 num_interfaces
= iface_list_count(ifaces
);
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
)) {
738 char **wcard
= iface_list_wildcard(kdc
);
739 NT_STATUS_HAVE_NO_MEMORY(wcard
);
740 for (i
=0; wcard
[i
]; i
++) {
742 status
= kdc_add_socket(kdc
, model_ops
,
743 "kdc", wcard
[i
], kdc_port
,
745 if (NT_STATUS_IS_OK(status
)) {
751 status
= kdc_add_socket(kdc
, model_ops
,
752 "kpasswd", wcard
[i
], kpasswd_port
,
753 kpasswdd_process
, false);
754 if (NT_STATUS_IS_OK(status
)) {
760 if (num_binds
== 0) {
761 return NT_STATUS_INVALID_PARAMETER_MIX
;
763 done_wildcard
= true;
766 for (i
=0; i
<num_interfaces
; i
++) {
767 const char *address
= talloc_strdup(tmp_ctx
, iface_list_n_ip(ifaces
, i
));
770 status
= kdc_add_socket(kdc
, model_ops
,
771 "kdc", address
, kdc_port
,
772 kdc_process
, done_wildcard
);
773 NT_STATUS_NOT_OK_RETURN(status
);
777 status
= kdc_add_socket(kdc
, model_ops
,
778 "kpasswd", address
, kpasswd_port
,
779 kpasswdd_process
, done_wildcard
);
780 NT_STATUS_NOT_OK_RETURN(status
);
784 talloc_free(tmp_ctx
);
789 static NTSTATUS
kdc_check_generic_kerberos(struct irpc_message
*msg
,
790 struct kdc_check_generic_kerberos
*r
)
792 struct PAC_Validate pac_validate
;
794 struct PAC_SIGNATURE_DATA kdc_sig
;
795 struct kdc_server
*kdc
= talloc_get_type(msg
->private_data
, struct kdc_server
);
796 enum ndr_err_code ndr_err
;
799 krb5_principal principal
;
801 /* There is no reply to this request */
802 r
->out
.generic_reply
= data_blob(NULL
, 0);
804 ndr_err
= ndr_pull_struct_blob(&r
->in
.generic_request
, msg
, &pac_validate
,
805 (ndr_pull_flags_fn_t
)ndr_pull_PAC_Validate
);
806 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
807 return NT_STATUS_INVALID_PARAMETER
;
810 if (pac_validate
.MessageType
!= NETLOGON_GENERIC_KRB5_PAC_VALIDATE
) {
811 /* We don't implement any other message types - such as certificate validation - yet */
812 return NT_STATUS_INVALID_PARAMETER
;
815 if (pac_validate
.ChecksumAndSignature
.length
!= (pac_validate
.ChecksumLength
+ pac_validate
.SignatureLength
)
816 || pac_validate
.ChecksumAndSignature
.length
< pac_validate
.ChecksumLength
817 || pac_validate
.ChecksumAndSignature
.length
< pac_validate
.SignatureLength
) {
818 return NT_STATUS_INVALID_PARAMETER
;
821 srv_sig
= data_blob_const(pac_validate
.ChecksumAndSignature
.data
,
822 pac_validate
.ChecksumLength
);
824 ret
= krb5_make_principal(kdc
->smb_krb5_context
->krb5_context
, &principal
,
825 lpcfg_realm(kdc
->task
->lp_ctx
),
826 "krbtgt", lpcfg_realm(kdc
->task
->lp_ctx
),
830 return NT_STATUS_NO_MEMORY
;
833 ret
= kdc
->config
->db
[0]->hdb_fetch_kvno(kdc
->smb_krb5_context
->krb5_context
,
836 HDB_F_GET_KRBTGT
| HDB_F_DECRYPT
,
841 hdb_free_entry(kdc
->smb_krb5_context
->krb5_context
, &ent
);
842 krb5_free_principal(kdc
->smb_krb5_context
->krb5_context
, principal
);
844 return NT_STATUS_LOGON_FAILURE
;
847 kdc_sig
.type
= pac_validate
.SignatureType
;
848 kdc_sig
.signature
= data_blob_const(&pac_validate
.ChecksumAndSignature
.data
[pac_validate
.ChecksumLength
],
849 pac_validate
.SignatureLength
);
851 ret
= kdc_check_pac(kdc
->smb_krb5_context
->krb5_context
, srv_sig
, &kdc_sig
, &ent
);
853 hdb_free_entry(kdc
->smb_krb5_context
->krb5_context
, &ent
);
854 krb5_free_principal(kdc
->smb_krb5_context
->krb5_context
, principal
);
857 return NT_STATUS_LOGON_FAILURE
;
867 static void kdc_task_init(struct task_server
*task
)
869 struct kdc_server
*kdc
;
872 struct interface
*ifaces
;
875 switch (lpcfg_server_role(task
->lp_ctx
)) {
876 case ROLE_STANDALONE
:
877 task_server_terminate(task
, "kdc: no KDC required in standalone configuration", false);
879 case ROLE_DOMAIN_MEMBER
:
880 task_server_terminate(task
, "kdc: no KDC required in member server configuration", false);
882 case ROLE_DOMAIN_PDC
:
883 case ROLE_DOMAIN_BDC
:
884 task_server_terminate(task
, "Cannot start KDC as a 'classic Samba' DC", true);
886 case ROLE_ACTIVE_DIRECTORY_DC
:
887 /* Yes, we want a KDC */
891 load_interface_list(task
, task
->lp_ctx
, &ifaces
);
893 if (iface_list_count(ifaces
) == 0) {
894 task_server_terminate(task
, "kdc: no network interfaces configured", false);
898 task_server_set_title(task
, "task[kdc]");
900 kdc
= talloc_zero(task
, struct kdc_server
);
902 task_server_terminate(task
, "kdc: out of memory", true);
909 /* get a samdb connection */
910 kdc
->samdb
= samdb_connect(kdc
, kdc
->task
->event_ctx
, kdc
->task
->lp_ctx
,
911 system_session(kdc
->task
->lp_ctx
), 0);
913 DEBUG(1,("kdc_task_init: unable to connect to samdb\n"));
914 task_server_terminate(task
, "kdc: krb5_init_context samdb connect failed", true);
918 ldb_ret
= samdb_rodc(kdc
->samdb
, &kdc
->am_rodc
);
919 if (ldb_ret
!= LDB_SUCCESS
) {
920 DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n",
921 ldb_errstring(kdc
->samdb
)));
922 task_server_terminate(task
, "kdc: krb5_init_context samdb RODC connect failed", true);
926 kdc
->proxy_timeout
= lpcfg_parm_int(kdc
->task
->lp_ctx
, NULL
, "kdc", "proxy timeout", 5);
928 initialize_krb5_error_table();
930 ret
= smb_krb5_init_context(kdc
, task
->lp_ctx
, &kdc
->smb_krb5_context
);
932 DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
933 error_message(ret
)));
934 task_server_terminate(task
, "kdc: krb5_init_context failed", true);
938 krb5_add_et_list(kdc
->smb_krb5_context
->krb5_context
, initialize_hdb_error_table_r
);
940 ret
= krb5_kdc_get_config(kdc
->smb_krb5_context
->krb5_context
,
943 task_server_terminate(task
, "kdc: failed to get KDC configuration", true);
947 kdc
->config
->logf
= (krb5_log_facility
*)kdc
->smb_krb5_context
->pvt_log_data
;
948 kdc
->config
->db
= talloc(kdc
, struct HDB
*);
949 if (!kdc
->config
->db
) {
950 task_server_terminate(task
, "kdc: out of memory", true);
953 kdc
->config
->num_db
= 1;
956 * This restores the behavior before
957 * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3
958 * s4:heimdal: import lorikeet-heimdal-201107150856
959 * (commit 48936803fae4a2fb362c79365d31f420c917b85b)
961 * as_use_strongest_session_key,preauth_use_strongest_session_key
962 * and tgs_use_strongest_session_key are input to the
963 * _kdc_find_etype() function. The old bahavior is in
964 * the use_strongest_session_key=FALSE code path.
965 * (The only remaining difference in _kdc_find_etype()
966 * is the is_preauth parameter.)
968 * The old behavior in the _kdc_get_preferred_key()
969 * function is use_strongest_server_key=TRUE.
971 kdc
->config
->as_use_strongest_session_key
= false;
972 kdc
->config
->preauth_use_strongest_session_key
= false;
973 kdc
->config
->tgs_use_strongest_session_key
= false;
974 kdc
->config
->use_strongest_server_key
= true;
976 /* Register hdb-samba4 hooks for use as a keytab */
978 kdc
->base_ctx
= talloc_zero(kdc
, struct samba_kdc_base_context
);
979 if (!kdc
->base_ctx
) {
980 task_server_terminate(task
, "kdc: out of memory", true);
984 kdc
->base_ctx
->ev_ctx
= task
->event_ctx
;
985 kdc
->base_ctx
->lp_ctx
= task
->lp_ctx
;
987 status
= hdb_samba4_create_kdc(kdc
->base_ctx
,
988 kdc
->smb_krb5_context
->krb5_context
,
989 &kdc
->config
->db
[0]);
990 if (!NT_STATUS_IS_OK(status
)) {
991 task_server_terminate(task
, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
995 ret
= krb5_plugin_register(kdc
->smb_krb5_context
->krb5_context
,
996 PLUGIN_TYPE_DATA
, "hdb",
997 &hdb_samba4_interface
);
999 task_server_terminate(task
, "kdc: failed to register hdb plugin", true);
1003 ret
= krb5_kt_register(kdc
->smb_krb5_context
->krb5_context
, &hdb_kt_ops
);
1005 task_server_terminate(task
, "kdc: failed to register keytab plugin", true);
1009 /* Register WinDC hooks */
1010 ret
= krb5_plugin_register(kdc
->smb_krb5_context
->krb5_context
,
1011 PLUGIN_TYPE_DATA
, "windc",
1012 &windc_plugin_table
);
1014 task_server_terminate(task
, "kdc: failed to register windc plugin", true);
1018 ret
= krb5_kdc_windc_init(kdc
->smb_krb5_context
->krb5_context
);
1021 task_server_terminate(task
, "kdc: failed to init windc plugin", true);
1025 ret
= krb5_kdc_pkinit_config(kdc
->smb_krb5_context
->krb5_context
, kdc
->config
);
1028 task_server_terminate(task
, "kdc: failed to init kdc pkinit subsystem", true);
1032 /* start listening on the configured network interfaces */
1033 status
= kdc_startup_interfaces(kdc
, task
->lp_ctx
, ifaces
);
1034 if (!NT_STATUS_IS_OK(status
)) {
1035 task_server_terminate(task
, "kdc failed to setup interfaces", true);
1039 status
= IRPC_REGISTER(task
->msg_ctx
, irpc
, KDC_CHECK_GENERIC_KERBEROS
,
1040 kdc_check_generic_kerberos
, kdc
);
1041 if (!NT_STATUS_IS_OK(status
)) {
1042 task_server_terminate(task
, "kdc failed to setup monitoring", true);
1046 irpc_add_name(task
->msg_ctx
, "kdc_server");
1050 /* called at smbd startup - register ourselves as a server service */
1051 NTSTATUS
server_service_kdc_init(void)
1053 return register_server_service("kdc", kdc_task_init
);