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/service_task.h"
26 #include "smbd/service.h"
27 #include "smbd/service_stream.h"
28 #include "smbd/process_model.h"
29 #include "lib/events/events.h"
30 #include "lib/socket/socket.h"
31 #include "lib/tsocket/tsocket.h"
32 #include "libcli/util/tstream.h"
33 #include "system/network.h"
34 #include "../lib/util/dlinklist.h"
35 #include "lib/messaging/irpc.h"
36 #include "lib/stream/packet.h"
37 #include "librpc/gen_ndr/samr.h"
38 #include "librpc/gen_ndr/ndr_irpc.h"
39 #include "librpc/gen_ndr/ndr_krb5pac.h"
40 #include "lib/socket/netif.h"
41 #include "param/param.h"
43 #include "librpc/gen_ndr/ndr_misc.h"
46 extern struct krb5plugin_windc_ftable windc_plugin_table
;
47 extern struct hdb_method hdb_samba4
;
49 typedef bool (*kdc_process_fn_t
)(struct kdc_server
*kdc
,
53 struct tsocket_address
*peer_addr
,
54 struct tsocket_address
*my_addr
,
57 /* hold information about one kdc socket */
59 struct kdc_server
*kdc
;
60 struct tsocket_address
*local_address
;
61 kdc_process_fn_t process
;
65 state of an open tcp connection
67 struct kdc_tcp_connection
{
68 /* stream connection we belong to */
69 struct stream_connection
*conn
;
71 /* the kdc_server the connection belongs to */
72 struct kdc_socket
*kdc_socket
;
74 struct tstream_context
*tstream
;
76 struct tevent_queue
*send_queue
;
79 static void kdc_tcp_terminate_connection(struct kdc_tcp_connection
*kdcconn
, const char *reason
)
81 stream_terminate_connection(kdcconn
->conn
, reason
);
84 static void kdc_tcp_recv(struct stream_connection
*conn
, uint16_t flags
)
86 struct kdc_tcp_connection
*kdcconn
= talloc_get_type(conn
->private_data
,
87 struct kdc_tcp_connection
);
88 /* this should never be triggered! */
89 kdc_tcp_terminate_connection(kdcconn
, "kdc_tcp_recv: called");
92 static void kdc_tcp_send(struct stream_connection
*conn
, uint16_t flags
)
94 struct kdc_tcp_connection
*kdcconn
= talloc_get_type(conn
->private_data
,
95 struct kdc_tcp_connection
);
96 /* this should never be triggered! */
97 kdc_tcp_terminate_connection(kdcconn
, "kdc_tcp_send: called");
101 Wrapper for krb5_kdc_process_krb5_request, converting to/from Samba
105 static bool kdc_process(struct kdc_server
*kdc
,
109 struct tsocket_address
*peer_addr
,
110 struct tsocket_address
*my_addr
,
115 struct sockaddr_storage ss
;
117 krb5_data_zero(&k5_reply
);
119 krb5_kdc_update_time(NULL
);
121 ret
= tsocket_address_bsd_sockaddr(peer_addr
, (struct sockaddr
*) &ss
,
122 sizeof(struct sockaddr_storage
));
126 pa
= tsocket_address_string(peer_addr
, mem_ctx
);
131 DEBUG(10,("Received KDC packet of length %lu from %s\n",
132 (long)input
->length
- 4, pa
));
134 ret
= krb5_kdc_process_krb5_request(kdc
->smb_krb5_context
->krb5_context
,
136 input
->data
, input
->length
,
139 (struct sockaddr
*) &ss
,
142 *reply
= data_blob(NULL
, 0);
145 if (k5_reply
.length
) {
146 *reply
= data_blob_talloc(mem_ctx
, k5_reply
.data
, k5_reply
.length
);
147 krb5_data_free(&k5_reply
);
149 *reply
= data_blob(NULL
, 0);
154 struct kdc_tcp_call
{
155 struct kdc_tcp_connection
*kdc_conn
;
159 struct iovec out_iov
[2];
162 static void kdc_tcp_call_writev_done(struct tevent_req
*subreq
);
164 static void kdc_tcp_call_loop(struct tevent_req
*subreq
)
166 struct kdc_tcp_connection
*kdc_conn
= tevent_req_callback_data(subreq
,
167 struct kdc_tcp_connection
);
168 struct kdc_tcp_call
*call
;
172 call
= talloc(kdc_conn
, struct kdc_tcp_call
);
174 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
175 "no memory for kdc_tcp_call");
178 call
->kdc_conn
= kdc_conn
;
180 status
= tstream_read_pdu_blob_recv(subreq
,
184 if (!NT_STATUS_IS_OK(status
)) {
187 reason
= talloc_asprintf(call
, "kdc_tcp_call_loop: "
188 "tstream_read_pdu_blob_recv() - %s",
191 reason
= nt_errstr(status
);
194 kdc_tcp_terminate_connection(kdc_conn
, reason
);
198 DEBUG(10,("Received krb5 TCP packet of length %lu from %s\n",
199 (long) call
->in
.length
,
200 tsocket_address_string(kdc_conn
->conn
->remote_address
, call
)));
202 /* skip length header */
204 call
->in
.length
-= 4;
207 ok
= kdc_conn
->kdc_socket
->process(kdc_conn
->kdc_socket
->kdc
,
211 kdc_conn
->conn
->remote_address
,
212 kdc_conn
->conn
->local_address
,
215 kdc_tcp_terminate_connection(kdc_conn
,
216 "kdc_tcp_call_loop: process function failed");
220 /* First add the length of the out buffer */
221 RSIVAL(call
->out_hdr
, 0, call
->out
.length
);
222 call
->out_iov
[0].iov_base
= call
->out_hdr
;
223 call
->out_iov
[0].iov_len
= 4;
225 call
->out_iov
[1].iov_base
= call
->out
.data
;
226 call
->out_iov
[1].iov_len
= call
->out
.length
;
228 subreq
= tstream_writev_queue_send(call
,
229 kdc_conn
->conn
->event
.ctx
,
231 kdc_conn
->send_queue
,
233 if (subreq
== NULL
) {
234 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
235 "no memory for tstream_writev_queue_send");
238 tevent_req_set_callback(subreq
, kdc_tcp_call_writev_done
, call
);
241 * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
242 * packet_full_request_u32 provides the pdu length then.
244 subreq
= tstream_read_pdu_blob_send(kdc_conn
,
245 kdc_conn
->conn
->event
.ctx
,
247 4, /* initial_read_size */
248 packet_full_request_u32
,
250 if (subreq
== NULL
) {
251 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_call_loop: "
252 "no memory for tstream_read_pdu_blob_send");
255 tevent_req_set_callback(subreq
, kdc_tcp_call_loop
, kdc_conn
);
258 static void kdc_tcp_call_writev_done(struct tevent_req
*subreq
)
260 struct kdc_tcp_call
*call
= tevent_req_callback_data(subreq
,
261 struct kdc_tcp_call
);
265 rc
= tstream_writev_queue_recv(subreq
, &sys_errno
);
270 reason
= talloc_asprintf(call
, "kdc_tcp_call_writev_done: "
271 "tstream_writev_queue_recv() - %d:%s",
272 sys_errno
, strerror(sys_errno
));
274 reason
= "kdc_tcp_call_writev_done: tstream_writev_queue_recv() failed";
277 kdc_tcp_terminate_connection(call
->kdc_conn
, reason
);
281 /* We don't care about errors */
287 called when we get a new connection
289 static void kdc_tcp_accept(struct stream_connection
*conn
)
291 struct kdc_socket
*kdc_socket
;
292 struct kdc_tcp_connection
*kdc_conn
;
293 struct tevent_req
*subreq
;
296 kdc_conn
= talloc_zero(conn
, struct kdc_tcp_connection
);
297 if (kdc_conn
== NULL
) {
298 stream_terminate_connection(conn
,
299 "kdc_tcp_accept: out of memory");
303 kdc_conn
->send_queue
= tevent_queue_create(conn
, "kdc_tcp_accept");
304 if (kdc_conn
->send_queue
== NULL
) {
305 stream_terminate_connection(conn
,
306 "kdc_tcp_accept: out of memory");
310 kdc_socket
= talloc_get_type(conn
->private_data
, struct kdc_socket
);
312 TALLOC_FREE(conn
->event
.fde
);
314 rc
= tstream_bsd_existing_socket(kdc_conn
,
315 socket_get_fd(conn
->socket
),
318 stream_terminate_connection(conn
,
319 "kdc_tcp_accept: out of memory");
323 kdc_conn
->conn
= conn
;
324 kdc_conn
->kdc_socket
= kdc_socket
;
325 conn
->private_data
= kdc_conn
;
328 * The krb5 tcp pdu's has the length as 4 byte (initial_read_size),
329 * packet_full_request_u32 provides the pdu length then.
331 subreq
= tstream_read_pdu_blob_send(kdc_conn
,
332 kdc_conn
->conn
->event
.ctx
,
334 4, /* initial_read_size */
335 packet_full_request_u32
,
337 if (subreq
== NULL
) {
338 kdc_tcp_terminate_connection(kdc_conn
, "kdc_tcp_accept: "
339 "no memory for tstream_read_pdu_blob_send");
342 tevent_req_set_callback(subreq
, kdc_tcp_call_loop
, kdc_conn
);
345 static const struct stream_server_ops kdc_tcp_stream_ops
= {
347 .accept_connection
= kdc_tcp_accept
,
348 .recv_handler
= kdc_tcp_recv
,
349 .send_handler
= kdc_tcp_send
352 /* hold information about one kdc/kpasswd udp socket */
353 struct kdc_udp_socket
{
354 struct kdc_socket
*kdc_socket
;
355 struct tdgram_context
*dgram
;
356 struct tevent_queue
*send_queue
;
359 struct kdc_udp_call
{
360 struct tsocket_address
*src
;
365 static void kdc_udp_call_sendto_done(struct tevent_req
*subreq
);
367 static void kdc_udp_call_loop(struct tevent_req
*subreq
)
369 struct kdc_udp_socket
*sock
= tevent_req_callback_data(subreq
,
370 struct kdc_udp_socket
);
371 struct kdc_udp_call
*call
;
377 call
= talloc(sock
, struct kdc_udp_call
);
383 len
= tdgram_recvfrom_recv(subreq
, &sys_errno
,
384 call
, &buf
, &call
->src
);
392 call
->in
.length
= len
;
394 DEBUG(10,("Received krb5 UDP packet of length %lu from %s\n",
395 (long)call
->in
.length
,
396 tsocket_address_string(call
->src
, call
)));
399 ok
= sock
->kdc_socket
->process(sock
->kdc_socket
->kdc
,
404 sock
->kdc_socket
->local_address
,
411 subreq
= tdgram_sendto_queue_send(call
,
412 sock
->kdc_socket
->kdc
->task
->event_ctx
,
418 if (subreq
== NULL
) {
422 tevent_req_set_callback(subreq
, kdc_udp_call_sendto_done
, call
);
425 subreq
= tdgram_recvfrom_send(sock
,
426 sock
->kdc_socket
->kdc
->task
->event_ctx
,
428 if (subreq
== NULL
) {
429 task_server_terminate(sock
->kdc_socket
->kdc
->task
,
430 "no memory for tdgram_recvfrom_send",
434 tevent_req_set_callback(subreq
, kdc_udp_call_loop
, sock
);
437 static void kdc_udp_call_sendto_done(struct tevent_req
*subreq
)
439 struct kdc_udp_call
*call
= tevent_req_callback_data(subreq
,
440 struct kdc_udp_call
);
444 ret
= tdgram_sendto_queue_recv(subreq
, &sys_errno
);
446 /* We don't care about errors */
452 start listening on the given address
454 static NTSTATUS
kdc_add_socket(struct kdc_server
*kdc
,
455 const struct model_ops
*model_ops
,
459 kdc_process_fn_t process
)
461 struct kdc_socket
*kdc_socket
;
462 struct kdc_udp_socket
*kdc_udp_socket
;
463 struct tevent_req
*udpsubreq
;
467 kdc_socket
= talloc(kdc
, struct kdc_socket
);
468 NT_STATUS_HAVE_NO_MEMORY(kdc_socket
);
470 kdc_socket
->kdc
= kdc
;
471 kdc_socket
->process
= process
;
473 ret
= tsocket_address_inet_from_strings(kdc_socket
, "ip",
475 &kdc_socket
->local_address
);
477 status
= map_nt_error_from_unix(errno
);
481 status
= stream_setup_socket(kdc
->task
->event_ctx
,
485 "ip", address
, &port
,
486 lp_socket_options(kdc
->task
->lp_ctx
),
488 if (!NT_STATUS_IS_OK(status
)) {
489 DEBUG(0,("Failed to bind to %s:%u TCP - %s\n",
490 address
, port
, nt_errstr(status
)));
491 talloc_free(kdc_socket
);
495 kdc_udp_socket
= talloc(kdc_socket
, struct kdc_udp_socket
);
496 NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket
);
498 kdc_udp_socket
->kdc_socket
= kdc_socket
;
500 ret
= tdgram_inet_udp_socket(kdc_socket
->local_address
,
503 &kdc_udp_socket
->dgram
);
505 status
= map_nt_error_from_unix(errno
);
506 DEBUG(0,("Failed to bind to %s:%u UDP - %s\n",
507 address
, port
, nt_errstr(status
)));
511 kdc_udp_socket
->send_queue
= tevent_queue_create(kdc_udp_socket
,
512 "kdc_udp_send_queue");
513 NT_STATUS_HAVE_NO_MEMORY(kdc_udp_socket
->send_queue
);
515 udpsubreq
= tdgram_recvfrom_send(kdc_udp_socket
,
516 kdc
->task
->event_ctx
,
517 kdc_udp_socket
->dgram
);
518 NT_STATUS_HAVE_NO_MEMORY(udpsubreq
);
519 tevent_req_set_callback(udpsubreq
, kdc_udp_call_loop
, kdc_udp_socket
);
526 setup our listening sockets on the configured network interfaces
528 static NTSTATUS
kdc_startup_interfaces(struct kdc_server
*kdc
, struct loadparm_context
*lp_ctx
,
529 struct interface
*ifaces
)
531 const struct model_ops
*model_ops
;
533 TALLOC_CTX
*tmp_ctx
= talloc_new(kdc
);
537 /* within the kdc task we want to be a single process, so
538 ask for the single process model ops and pass these to the
539 stream_setup_socket() call. */
540 model_ops
= process_model_startup(kdc
->task
->event_ctx
, "single");
542 DEBUG(0,("Can't find 'single' process model_ops\n"));
543 return NT_STATUS_INTERNAL_ERROR
;
546 num_interfaces
= iface_count(ifaces
);
548 for (i
=0; i
<num_interfaces
; i
++) {
549 const char *address
= talloc_strdup(tmp_ctx
, iface_n_ip(ifaces
, i
));
550 uint16_t kdc_port
= lp_krb5_port(lp_ctx
);
551 uint16_t kpasswd_port
= lp_kpasswd_port(lp_ctx
);
554 status
= kdc_add_socket(kdc
, model_ops
,
555 "kdc", address
, kdc_port
,
557 NT_STATUS_NOT_OK_RETURN(status
);
561 status
= kdc_add_socket(kdc
, model_ops
,
562 "kpasswd", address
, kpasswd_port
,
564 NT_STATUS_NOT_OK_RETURN(status
);
568 talloc_free(tmp_ctx
);
574 static NTSTATUS
kdc_check_generic_kerberos(struct irpc_message
*msg
,
575 struct kdc_check_generic_kerberos
*r
)
577 struct PAC_Validate pac_validate
;
579 struct PAC_SIGNATURE_DATA kdc_sig
;
580 struct kdc_server
*kdc
= talloc_get_type(msg
->private_data
, struct kdc_server
);
581 enum ndr_err_code ndr_err
;
585 krb5_principal principal
;
586 krb5_keyblock keyblock
;
589 /* There is no reply to this request */
590 r
->out
.generic_reply
= data_blob(NULL
, 0);
592 ndr_err
= ndr_pull_struct_blob(&r
->in
.generic_request
, msg
,
593 lp_iconv_convenience(kdc
->task
->lp_ctx
),
595 (ndr_pull_flags_fn_t
)ndr_pull_PAC_Validate
);
596 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
597 return NT_STATUS_INVALID_PARAMETER
;
600 if (pac_validate
.MessageType
!= 3) {
601 /* We don't implement any other message types - such as certificate validation - yet */
602 return NT_STATUS_INVALID_PARAMETER
;
605 if (pac_validate
.ChecksumAndSignature
.length
!= (pac_validate
.ChecksumLength
+ pac_validate
.SignatureLength
)
606 || pac_validate
.ChecksumAndSignature
.length
< pac_validate
.ChecksumLength
607 || pac_validate
.ChecksumAndSignature
.length
< pac_validate
.SignatureLength
) {
608 return NT_STATUS_INVALID_PARAMETER
;
611 srv_sig
= data_blob_const(pac_validate
.ChecksumAndSignature
.data
,
612 pac_validate
.ChecksumLength
);
614 if (pac_validate
.SignatureType
== CKSUMTYPE_HMAC_MD5
) {
615 etype
= ETYPE_ARCFOUR_HMAC_MD5
;
617 ret
= krb5_cksumtype_to_enctype(kdc
->smb_krb5_context
->krb5_context
, pac_validate
.SignatureType
,
620 return NT_STATUS_LOGON_FAILURE
;
624 ret
= krb5_make_principal(kdc
->smb_krb5_context
->krb5_context
, &principal
,
625 lp_realm(kdc
->task
->lp_ctx
),
626 "krbtgt", lp_realm(kdc
->task
->lp_ctx
),
630 return NT_STATUS_NO_MEMORY
;
633 ret
= kdc
->config
->db
[0]->hdb_fetch(kdc
->smb_krb5_context
->krb5_context
,
636 HDB_F_GET_KRBTGT
| HDB_F_DECRYPT
,
640 hdb_free_entry(kdc
->smb_krb5_context
->krb5_context
, &ent
);
641 krb5_free_principal(kdc
->smb_krb5_context
->krb5_context
, principal
);
643 return NT_STATUS_LOGON_FAILURE
;
646 ret
= hdb_enctype2key(kdc
->smb_krb5_context
->krb5_context
, &ent
.entry
, etype
, &key
);
649 hdb_free_entry(kdc
->smb_krb5_context
->krb5_context
, &ent
);
650 krb5_free_principal(kdc
->smb_krb5_context
->krb5_context
, principal
);
651 return NT_STATUS_LOGON_FAILURE
;
656 kdc_sig
.type
= pac_validate
.SignatureType
;
657 kdc_sig
.signature
= data_blob_const(&pac_validate
.ChecksumAndSignature
.data
[pac_validate
.ChecksumLength
],
658 pac_validate
.SignatureLength
);
659 ret
= check_pac_checksum(msg
, srv_sig
, &kdc_sig
,
660 kdc
->smb_krb5_context
->krb5_context
, &keyblock
);
662 hdb_free_entry(kdc
->smb_krb5_context
->krb5_context
, &ent
);
663 krb5_free_principal(kdc
->smb_krb5_context
->krb5_context
, principal
);
666 return NT_STATUS_LOGON_FAILURE
;
676 static void kdc_task_init(struct task_server
*task
)
678 struct kdc_server
*kdc
;
681 struct interface
*ifaces
;
683 switch (lp_server_role(task
->lp_ctx
)) {
684 case ROLE_STANDALONE
:
685 task_server_terminate(task
, "kdc: no KDC required in standalone configuration", false);
687 case ROLE_DOMAIN_MEMBER
:
688 task_server_terminate(task
, "kdc: no KDC required in member server configuration", false);
690 case ROLE_DOMAIN_CONTROLLER
:
691 /* Yes, we want a KDC */
695 load_interfaces(task
, lp_interfaces(task
->lp_ctx
), &ifaces
);
697 if (iface_count(ifaces
) == 0) {
698 task_server_terminate(task
, "kdc: no network interfaces configured", false);
702 task_server_set_title(task
, "task[kdc]");
704 kdc
= talloc(task
, struct kdc_server
);
706 task_server_terminate(task
, "kdc: out of memory", true);
712 initialize_krb5_error_table();
714 ret
= smb_krb5_init_context(kdc
, task
->event_ctx
, task
->lp_ctx
, &kdc
->smb_krb5_context
);
716 DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n",
717 error_message(ret
)));
718 task_server_terminate(task
, "kdc: krb5_init_context failed", true);
722 krb5_add_et_list(kdc
->smb_krb5_context
->krb5_context
, initialize_hdb_error_table_r
);
724 ret
= krb5_kdc_get_config(kdc
->smb_krb5_context
->krb5_context
,
727 task_server_terminate(task
, "kdc: failed to get KDC configuration", true);
731 kdc
->config
->logf
= kdc
->smb_krb5_context
->logf
;
732 kdc
->config
->db
= talloc(kdc
, struct HDB
*);
733 if (!kdc
->config
->db
) {
734 task_server_terminate(task
, "kdc: out of memory", true);
737 kdc
->config
->num_db
= 1;
739 /* Register hdb-samba4 hooks for use as a keytab */
741 kdc
->base_ctx
= talloc_zero(kdc
, struct samba_kdc_base_context
);
742 if (!kdc
->base_ctx
) {
743 task_server_terminate(task
, "kdc: out of memory", true);
747 kdc
->base_ctx
->ev_ctx
= task
->event_ctx
;
748 kdc
->base_ctx
->lp_ctx
= task
->lp_ctx
;
750 status
= hdb_samba4_create_kdc(kdc
->base_ctx
,
751 kdc
->smb_krb5_context
->krb5_context
,
752 &kdc
->config
->db
[0]);
753 if (!NT_STATUS_IS_OK(status
)) {
754 task_server_terminate(task
, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true);
758 ret
= krb5_plugin_register(kdc
->smb_krb5_context
->krb5_context
,
759 PLUGIN_TYPE_DATA
, "hdb",
762 task_server_terminate(task
, "kdc: failed to register hdb plugin", true);
766 ret
= krb5_kt_register(kdc
->smb_krb5_context
->krb5_context
, &hdb_kt_ops
);
768 task_server_terminate(task
, "kdc: failed to register keytab plugin", true);
772 /* Register WinDC hooks */
773 ret
= krb5_plugin_register(kdc
->smb_krb5_context
->krb5_context
,
774 PLUGIN_TYPE_DATA
, "windc",
775 &windc_plugin_table
);
777 task_server_terminate(task
, "kdc: failed to register windc plugin", true);
781 krb5_kdc_windc_init(kdc
->smb_krb5_context
->krb5_context
);
783 /* start listening on the configured network interfaces */
784 status
= kdc_startup_interfaces(kdc
, task
->lp_ctx
, ifaces
);
785 if (!NT_STATUS_IS_OK(status
)) {
786 task_server_terminate(task
, "kdc failed to setup interfaces", true);
790 status
= IRPC_REGISTER(task
->msg_ctx
, irpc
, KDC_CHECK_GENERIC_KERBEROS
,
791 kdc_check_generic_kerberos
, kdc
);
792 if (!NT_STATUS_IS_OK(status
)) {
793 task_server_terminate(task
, "nbtd failed to setup monitoring", true);
797 irpc_add_name(task
->msg_ctx
, "kdc_server");
801 /* called at smbd startup - register ourselves as a server service */
802 NTSTATUS
server_service_kdc_init(void)
804 return register_server_service("kdc", kdc_task_init
);