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/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 "system/network.h" 32#include "../lib/util/dlinklist.h" 33#include "lib/messaging/irpc.h" 34#include "lib/stream/packet.h" 35#include "librpc/gen_ndr/samr.h" 36#include "librpc/gen_ndr/ndr_irpc.h" 37#include "librpc/gen_ndr/ndr_krb5pac.h" 38#include "lib/socket/netif.h" 39#include "param/param.h" 40#include "kdc/kdc.h" 41#include "librpc/gen_ndr/ndr_misc.h" 42 43 44/* Disgusting hack to get a mem_ctx and lp_ctx into the hdb plugin, when 45 * used as a keytab */ 46TALLOC_CTX *hdb_samba4_mem_ctx; 47struct tevent_context *hdb_samba4_ev_ctx; 48struct loadparm_context *hdb_samba4_lp_ctx; 49 50/* hold all the info needed to send a reply */ 51struct kdc_reply { 52 struct kdc_reply *next, *prev; 53 struct socket_address *dest; 54 DATA_BLOB packet; 55}; 56 57typedef bool (*kdc_process_fn_t)(struct kdc_server *kdc, 58 TALLOC_CTX *mem_ctx, 59 DATA_BLOB *input, 60 DATA_BLOB *reply, 61 struct socket_address *peer_addr, 62 struct socket_address *my_addr, 63 int datagram); 64 65/* hold information about one kdc socket */ 66struct kdc_socket { 67 struct socket_context *sock; 68 struct kdc_server *kdc; 69 struct tevent_fd *fde; 70 71 /* a queue of outgoing replies that have been deferred */ 72 struct kdc_reply *send_queue; 73 74 kdc_process_fn_t process; 75}; 76/* 77 state of an open tcp connection 78*/ 79struct kdc_tcp_connection { 80 /* stream connection we belong to */ 81 struct stream_connection *conn; 82 83 /* the kdc_server the connection belongs to */ 84 struct kdc_server *kdc; 85 86 struct packet_context *packet; 87 88 kdc_process_fn_t process; 89}; 90 91/* 92 handle fd send events on a KDC socket 93*/ 94static void kdc_send_handler(struct kdc_socket *kdc_socket) 95{ 96 while (kdc_socket->send_queue) { 97 struct kdc_reply *rep = kdc_socket->send_queue; 98 NTSTATUS status; 99 size_t sendlen; 100 101 status = socket_sendto(kdc_socket->sock, &rep->packet, &sendlen, 102 rep->dest); 103 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { 104 break; 105 } 106 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_BUFFER_SIZE)) { 107 /* Replace with a krb err, response to big */ 108 } 109 110 DLIST_REMOVE(kdc_socket->send_queue, rep); 111 talloc_free(rep); 112 } 113 114 if (kdc_socket->send_queue == NULL) { 115 EVENT_FD_NOT_WRITEABLE(kdc_socket->fde); 116 } 117} 118 119 120/* 121 handle fd recv events on a KDC socket 122*/ 123static void kdc_recv_handler(struct kdc_socket *kdc_socket) 124{ 125 NTSTATUS status; 126 TALLOC_CTX *tmp_ctx = talloc_new(kdc_socket); 127 DATA_BLOB blob; 128 struct kdc_reply *rep; 129 DATA_BLOB reply; 130 size_t nread, dsize; 131 struct socket_address *src; 132 struct socket_address *my_addr; 133 int ret; 134 135 status = socket_pending(kdc_socket->sock, &dsize); 136 if (!NT_STATUS_IS_OK(status)) { 137 talloc_free(tmp_ctx); 138 return; 139 } 140 141 blob = data_blob_talloc(tmp_ctx, NULL, dsize); 142 if (blob.data == NULL) { 143 /* hope this is a temporary low memory condition */ 144 talloc_free(tmp_ctx); 145 return; 146 } 147 148 status = socket_recvfrom(kdc_socket->sock, blob.data, blob.length, &nread, 149 tmp_ctx, &src); 150 if (!NT_STATUS_IS_OK(status)) { 151 talloc_free(tmp_ctx); 152 return; 153 } 154 blob.length = nread; 155 156 DEBUG(10,("Received krb5 UDP packet of length %lu from %s:%u\n", 157 (long)blob.length, src->addr, (uint16_t)src->port)); 158 159 my_addr = socket_get_my_addr(kdc_socket->sock, tmp_ctx); 160 if (!my_addr) { 161 talloc_free(tmp_ctx); 162 return; 163 } 164 165 166 /* Call krb5 */ 167 ret = kdc_socket->process(kdc_socket->kdc, 168 tmp_ctx, 169 &blob, 170 &reply, 171 src, my_addr, 172 1 /* Datagram */); 173 if (!ret) { 174 talloc_free(tmp_ctx); 175 return; 176 } 177 178 /* queue a pending reply */ 179 rep = talloc(kdc_socket, struct kdc_reply); 180 if (rep == NULL) { 181 talloc_free(tmp_ctx); 182 return; 183 } 184 rep->dest = talloc_steal(rep, src); 185 rep->packet = reply; 186 talloc_steal(rep, reply.data); 187 188 if (rep->packet.data == NULL) { 189 talloc_free(rep); 190 talloc_free(tmp_ctx); 191 return; 192 } 193 194 DLIST_ADD_END(kdc_socket->send_queue, rep, struct kdc_reply *); 195 EVENT_FD_WRITEABLE(kdc_socket->fde); 196 talloc_free(tmp_ctx); 197} 198 199/* 200 handle fd events on a KDC socket 201*/ 202static void kdc_socket_handler(struct tevent_context *ev, struct tevent_fd *fde, 203 uint16_t flags, void *private_data) 204{ 205 struct kdc_socket *kdc_socket = talloc_get_type(private_data, struct kdc_socket); 206 if (flags & EVENT_FD_WRITE) { 207 kdc_send_handler(kdc_socket); 208 } 209 if (flags & EVENT_FD_READ) { 210 kdc_recv_handler(kdc_socket); 211 } 212} 213 214static void kdc_tcp_terminate_connection(struct kdc_tcp_connection *kdcconn, const char *reason) 215{ 216 stream_terminate_connection(kdcconn->conn, reason); 217} 218 219/* 220 receive a full packet on a KDC connection 221*/ 222static NTSTATUS kdc_tcp_recv(void *private_data, DATA_BLOB blob) 223{ 224 struct kdc_tcp_connection *kdcconn = talloc_get_type(private_data, 225 struct kdc_tcp_connection); 226 NTSTATUS status = NT_STATUS_UNSUCCESSFUL; 227 TALLOC_CTX *tmp_ctx = talloc_new(kdcconn); 228 int ret; 229 DATA_BLOB input, reply; 230 struct socket_address *src_addr; 231 struct socket_address *my_addr; 232 233 talloc_steal(tmp_ctx, blob.data); 234 235 src_addr = socket_get_peer_addr(kdcconn->conn->socket, tmp_ctx); 236 if (!src_addr) { 237 talloc_free(tmp_ctx); 238 return NT_STATUS_NO_MEMORY; 239 } 240 241 my_addr = socket_get_my_addr(kdcconn->conn->socket, tmp_ctx); 242 if (!my_addr) { 243 talloc_free(tmp_ctx); 244 return NT_STATUS_NO_MEMORY; 245 } 246 247 /* Call krb5 */ 248 input = data_blob_const(blob.data + 4, blob.length - 4); 249 250 ret = kdcconn->process(kdcconn->kdc, 251 tmp_ctx, 252 &input, 253 &reply, 254 src_addr, 255 my_addr, 256 0 /* Not datagram */); 257 if (!ret) { 258 talloc_free(tmp_ctx); 259 return NT_STATUS_INTERNAL_ERROR; 260 } 261 262 /* and now encode the reply */ 263 blob = data_blob_talloc(kdcconn, NULL, reply.length + 4); 264 if (!blob.data) { 265 talloc_free(tmp_ctx); 266 return NT_STATUS_NO_MEMORY; 267 } 268 269 RSIVAL(blob.data, 0, reply.length); 270 memcpy(blob.data + 4, reply.data, reply.length); 271 272 status = packet_send(kdcconn->packet, blob); 273 if (!NT_STATUS_IS_OK(status)) { 274 talloc_free(tmp_ctx); 275 return status; 276 } 277 278 /* the call isn't needed any more */ 279 talloc_free(tmp_ctx); 280 return NT_STATUS_OK; 281} 282 283/* 284 receive some data on a KDC connection 285*/ 286static void kdc_tcp_recv_handler(struct stream_connection *conn, uint16_t flags) 287{ 288 struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data, 289 struct kdc_tcp_connection); 290 packet_recv(kdcconn->packet); 291} 292 293/* 294 called on a tcp recv error 295*/ 296static void kdc_tcp_recv_error(void *private_data, NTSTATUS status) 297{ 298 struct kdc_tcp_connection *kdcconn = talloc_get_type(private_data, 299 struct kdc_tcp_connection); 300 kdc_tcp_terminate_connection(kdcconn, nt_errstr(status)); 301} 302 303/* 304 called when we can write to a connection 305*/ 306static void kdc_tcp_send(struct stream_connection *conn, uint16_t flags) 307{ 308 struct kdc_tcp_connection *kdcconn = talloc_get_type(conn->private_data, 309 struct kdc_tcp_connection); 310 packet_queue_run(kdcconn->packet); 311} 312 313/** 314 Wrapper for krb5_kdc_process_krb5_request, converting to/from Samba 315 calling conventions 316*/ 317 318static bool kdc_process(struct kdc_server *kdc, 319 TALLOC_CTX *mem_ctx, 320 DATA_BLOB *input, 321 DATA_BLOB *reply, 322 struct socket_address *peer_addr, 323 struct socket_address *my_addr, 324 int datagram_reply) 325{ 326 int ret; 327 krb5_data k5_reply; 328 krb5_data_zero(&k5_reply); 329 330 krb5_kdc_update_time(NULL); 331 332 DEBUG(10,("Received KDC packet of length %lu from %s:%d\n", 333 (long)input->length - 4, peer_addr->addr, peer_addr->port)); 334 335 ret = krb5_kdc_process_krb5_request(kdc->smb_krb5_context->krb5_context, 336 kdc->config, 337 input->data, input->length, 338 &k5_reply, 339 peer_addr->addr, 340 peer_addr->sockaddr, 341 datagram_reply); 342 if (ret == -1) { 343 *reply = data_blob(NULL, 0); 344 return false; 345 } 346 if (k5_reply.length) { 347 *reply = data_blob_talloc(mem_ctx, k5_reply.data, k5_reply.length); 348 krb5_data_free(&k5_reply); 349 } else { 350 *reply = data_blob(NULL, 0); 351 } 352 return true; 353} 354 355/* 356 called when we get a new connection 357*/ 358static void kdc_tcp_generic_accept(struct stream_connection *conn, kdc_process_fn_t process_fn) 359{ 360 struct kdc_server *kdc = talloc_get_type(conn->private_data, struct kdc_server); 361 struct kdc_tcp_connection *kdcconn; 362 363 kdcconn = talloc_zero(conn, struct kdc_tcp_connection); 364 if (!kdcconn) { 365 stream_terminate_connection(conn, "kdc_tcp_accept: out of memory"); 366 return; 367 } 368 kdcconn->conn = conn; 369 kdcconn->kdc = kdc; 370 kdcconn->process = process_fn; 371 conn->private_data = kdcconn; 372 373 kdcconn->packet = packet_init(kdcconn); 374 if (kdcconn->packet == NULL) { 375 kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory"); 376 return; 377 } 378 packet_set_private(kdcconn->packet, kdcconn); 379 packet_set_socket(kdcconn->packet, conn->socket); 380 packet_set_callback(kdcconn->packet, kdc_tcp_recv); 381 packet_set_full_request(kdcconn->packet, packet_full_request_u32); 382 packet_set_error_handler(kdcconn->packet, kdc_tcp_recv_error); 383 packet_set_event_context(kdcconn->packet, conn->event.ctx); 384 packet_set_fde(kdcconn->packet, conn->event.fde); 385 packet_set_serialise(kdcconn->packet); 386} 387 388static void kdc_tcp_accept(struct stream_connection *conn) 389{ 390 kdc_tcp_generic_accept(conn, kdc_process); 391} 392 393static const struct stream_server_ops kdc_tcp_stream_ops = { 394 .name = "kdc_tcp", 395 .accept_connection = kdc_tcp_accept, 396 .recv_handler = kdc_tcp_recv_handler, 397 .send_handler = kdc_tcp_send 398}; 399 400static void kpasswdd_tcp_accept(struct stream_connection *conn) 401{ 402 kdc_tcp_generic_accept(conn, kpasswdd_process); 403} 404 405static const struct stream_server_ops kpasswdd_tcp_stream_ops = { 406 .name = "kpasswdd_tcp", 407 .accept_connection = kpasswdd_tcp_accept, 408 .recv_handler = kdc_tcp_recv_handler, 409 .send_handler = kdc_tcp_send 410}; 411 412/* 413 start listening on the given address 414*/ 415static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address, 416 uint16_t kdc_port, uint16_t kpasswd_port) 417{ 418 const struct model_ops *model_ops; 419 struct kdc_socket *kdc_socket; 420 struct kdc_socket *kpasswd_socket; 421 struct socket_address *kdc_address, *kpasswd_address; 422 NTSTATUS status; 423 424 kdc_socket = talloc(kdc, struct kdc_socket); 425 NT_STATUS_HAVE_NO_MEMORY(kdc_socket); 426 427 kpasswd_socket = talloc(kdc, struct kdc_socket); 428 NT_STATUS_HAVE_NO_MEMORY(kpasswd_socket); 429 430 status = socket_create("ip", SOCKET_TYPE_DGRAM, &kdc_socket->sock, 0); 431 if (!NT_STATUS_IS_OK(status)) { 432 talloc_free(kdc_socket); 433 return status; 434 } 435 436 status = socket_create("ip", SOCKET_TYPE_DGRAM, &kpasswd_socket->sock, 0); 437 if (!NT_STATUS_IS_OK(status)) { 438 talloc_free(kpasswd_socket); 439 return status; 440 } 441 442 kdc_socket->kdc = kdc; 443 kdc_socket->send_queue = NULL; 444 kdc_socket->process = kdc_process; 445 446 talloc_steal(kdc_socket, kdc_socket->sock); 447 448 kdc_socket->fde = event_add_fd(kdc->task->event_ctx, kdc, 449 socket_get_fd(kdc_socket->sock), EVENT_FD_READ, 450 kdc_socket_handler, kdc_socket); 451 452 kdc_address = socket_address_from_strings(kdc_socket, kdc_socket->sock->backend_name, 453 address, kdc_port); 454 NT_STATUS_HAVE_NO_MEMORY(kdc_address); 455 456 status = socket_listen(kdc_socket->sock, kdc_address, 0, 0); 457 if (!NT_STATUS_IS_OK(status)) { 458 DEBUG(0,("Failed to bind to %s:%d UDP for kdc - %s\n", 459 address, kdc_port, nt_errstr(status))); 460 talloc_free(kdc_socket); 461 return status; 462 } 463 464 kpasswd_socket->kdc = kdc; 465 kpasswd_socket->send_queue = NULL; 466 kpasswd_socket->process = kpasswdd_process; 467 468 talloc_steal(kpasswd_socket, kpasswd_socket->sock); 469 470 kpasswd_socket->fde = event_add_fd(kdc->task->event_ctx, kdc, 471 socket_get_fd(kpasswd_socket->sock), EVENT_FD_READ, 472 kdc_socket_handler, kpasswd_socket); 473 474 kpasswd_address = socket_address_from_strings(kpasswd_socket, kpasswd_socket->sock->backend_name, 475 address, kpasswd_port); 476 NT_STATUS_HAVE_NO_MEMORY(kpasswd_address); 477 478 status = socket_listen(kpasswd_socket->sock, kpasswd_address, 0, 0); 479 if (!NT_STATUS_IS_OK(status)) { 480 DEBUG(0,("Failed to bind to %s:%d UDP for kpasswd - %s\n", 481 address, kpasswd_port, nt_errstr(status))); 482 talloc_free(kpasswd_socket); 483 return status; 484 } 485 486 /* within the kdc task we want to be a single process, so 487 ask for the single process model ops and pass these to the 488 stream_setup_socket() call. */ 489 model_ops = process_model_startup(kdc->task->event_ctx, "single"); 490 if (!model_ops) { 491 DEBUG(0,("Can't find 'single' process model_ops\n")); 492 talloc_free(kdc_socket); 493 return NT_STATUS_INTERNAL_ERROR; 494 } 495 496 status = stream_setup_socket(kdc->task->event_ctx, 497 kdc->task->lp_ctx, 498 model_ops, 499 &kdc_tcp_stream_ops, 500 "ip", address, &kdc_port, 501 lp_socket_options(kdc->task->lp_ctx), 502 kdc); 503 if (!NT_STATUS_IS_OK(status)) { 504 DEBUG(0,("Failed to bind to %s:%u TCP - %s\n", 505 address, kdc_port, nt_errstr(status))); 506 talloc_free(kdc_socket); 507 return status; 508 } 509 510 status = stream_setup_socket(kdc->task->event_ctx, 511 kdc->task->lp_ctx, 512 model_ops, 513 &kpasswdd_tcp_stream_ops, 514 "ip", address, &kpasswd_port, 515 lp_socket_options(kdc->task->lp_ctx), 516 kdc); 517 if (!NT_STATUS_IS_OK(status)) { 518 DEBUG(0,("Failed to bind to %s:%u TCP - %s\n", 519 address, kpasswd_port, nt_errstr(status))); 520 talloc_free(kdc_socket); 521 return status; 522 } 523 524 return NT_STATUS_OK; 525} 526 527 528/* 529 setup our listening sockets on the configured network interfaces 530*/ 531static NTSTATUS kdc_startup_interfaces(struct kdc_server *kdc, struct loadparm_context *lp_ctx, 532 struct interface *ifaces) 533{ 534 int num_interfaces; 535 TALLOC_CTX *tmp_ctx = talloc_new(kdc); 536 NTSTATUS status; 537 int i; 538 539 num_interfaces = iface_count(ifaces); 540 541 for (i=0; i<num_interfaces; i++) { 542 const char *address = talloc_strdup(tmp_ctx, iface_n_ip(ifaces, i)); 543 status = kdc_add_socket(kdc, address, lp_krb5_port(lp_ctx), 544 lp_kpasswd_port(lp_ctx)); 545 NT_STATUS_NOT_OK_RETURN(status); 546 } 547 548 talloc_free(tmp_ctx); 549 550 return NT_STATUS_OK; 551} 552 553 554static NTSTATUS kdc_check_generic_kerberos(struct irpc_message *msg, 555 struct kdc_check_generic_kerberos *r) 556{ 557 struct PAC_Validate pac_validate; 558 DATA_BLOB srv_sig; 559 struct PAC_SIGNATURE_DATA kdc_sig; 560 struct kdc_server *kdc = talloc_get_type(msg->private_data, struct kdc_server); 561 enum ndr_err_code ndr_err; 562 krb5_enctype etype; 563 int ret; 564 hdb_entry_ex ent; 565 krb5_principal principal; 566 krb5_keyblock keyblock; 567 Key *key; 568 569 /* There is no reply to this request */ 570 r->out.generic_reply = data_blob(NULL, 0); 571 572 ndr_err = ndr_pull_struct_blob(&r->in.generic_request, msg, 573 lp_iconv_convenience(kdc->task->lp_ctx), 574 &pac_validate, 575 (ndr_pull_flags_fn_t)ndr_pull_PAC_Validate); 576 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { 577 return NT_STATUS_INVALID_PARAMETER; 578 } 579 580 if (pac_validate.MessageType != 3) { 581 /* We don't implement any other message types - such as certificate validation - yet */ 582 return NT_STATUS_INVALID_PARAMETER; 583 } 584 585 if (pac_validate.ChecksumAndSignature.length != (pac_validate.ChecksumLength + pac_validate.SignatureLength) 586 || pac_validate.ChecksumAndSignature.length < pac_validate.ChecksumLength 587 || pac_validate.ChecksumAndSignature.length < pac_validate.SignatureLength ) { 588 return NT_STATUS_INVALID_PARAMETER; 589 } 590 591 srv_sig = data_blob_const(pac_validate.ChecksumAndSignature.data, 592 pac_validate.ChecksumLength); 593 594 if (pac_validate.SignatureType == CKSUMTYPE_HMAC_MD5) { 595 etype = ETYPE_ARCFOUR_HMAC_MD5; 596 } else { 597 ret = krb5_cksumtype_to_enctype(kdc->smb_krb5_context->krb5_context, pac_validate.SignatureType, 598 &etype); 599 if (ret != 0) { 600 return NT_STATUS_LOGON_FAILURE; 601 } 602 } 603 604 ret = krb5_make_principal(kdc->smb_krb5_context->krb5_context, &principal, 605 lp_realm(kdc->task->lp_ctx), 606 "krbtgt", lp_realm(kdc->task->lp_ctx), 607 NULL); 608 609 if (ret != 0) { 610 return NT_STATUS_NO_MEMORY; 611 } 612 613 ret = kdc->config->db[0]->hdb_fetch(kdc->smb_krb5_context->krb5_context, 614 kdc->config->db[0], 615 principal, 616 HDB_F_GET_KRBTGT | HDB_F_DECRYPT, 617 &ent); 618 619 if (ret != 0) { 620 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent); 621 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal); 622 623 return NT_STATUS_LOGON_FAILURE; 624 } 625 626 ret = hdb_enctype2key(kdc->smb_krb5_context->krb5_context, &ent.entry, etype, &key); 627 628 if (ret != 0) { 629 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent); 630 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal); 631 return NT_STATUS_LOGON_FAILURE; 632 } 633 634 keyblock = key->key; 635 636 kdc_sig.type = pac_validate.SignatureType; 637 kdc_sig.signature = data_blob_const(&pac_validate.ChecksumAndSignature.data[pac_validate.ChecksumLength], 638 pac_validate.SignatureLength); 639 ret = check_pac_checksum(msg, srv_sig, &kdc_sig, 640 kdc->smb_krb5_context->krb5_context, &keyblock); 641 642 hdb_free_entry(kdc->smb_krb5_context->krb5_context, &ent); 643 krb5_free_principal(kdc->smb_krb5_context->krb5_context, principal); 644 645 if (ret != 0) { 646 return NT_STATUS_LOGON_FAILURE; 647 } 648 649 return NT_STATUS_OK; 650} 651 652 653/* 654 startup the kdc task 655*/ 656static void kdc_task_init(struct task_server *task) 657{ 658 struct kdc_server *kdc; 659 NTSTATUS status; 660 krb5_error_code ret; 661 struct interface *ifaces; 662 663 switch (lp_server_role(task->lp_ctx)) { 664 case ROLE_STANDALONE: 665 task_server_terminate(task, "kdc: no KDC required in standalone configuration", false); 666 return; 667 case ROLE_DOMAIN_MEMBER: 668 task_server_terminate(task, "kdc: no KDC required in member server configuration", false); 669 return; 670 case ROLE_DOMAIN_CONTROLLER: 671 /* Yes, we want a KDC */ 672 break; 673 } 674 675 load_interfaces(task, lp_interfaces(task->lp_ctx), &ifaces); 676 677 if (iface_count(ifaces) == 0) { 678 task_server_terminate(task, "kdc: no network interfaces configured", false); 679 return; 680 } 681 682 task_server_set_title(task, "task[kdc]"); 683 684 kdc = talloc(task, struct kdc_server); 685 if (kdc == NULL) { 686 task_server_terminate(task, "kdc: out of memory", true); 687 return; 688 } 689 690 kdc->task = task; 691 692 initialize_krb5_error_table(); 693 694 ret = smb_krb5_init_context(kdc, task->event_ctx, task->lp_ctx, &kdc->smb_krb5_context); 695 if (ret) { 696 DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n", 697 error_message(ret))); 698 task_server_terminate(task, "kdc: krb5_init_context failed", true); 699 return; 700 } 701 702 krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r); 703 704 ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context, 705 &kdc->config); 706 if(ret) { 707 task_server_terminate(task, "kdc: failed to get KDC configuration", true); 708 return; 709 } 710 711 kdc->config->logf = kdc->smb_krb5_context->logf; 712 kdc->config->db = talloc(kdc, struct HDB *); 713 if (!kdc->config->db) { 714 task_server_terminate(task, "kdc: out of memory", true); 715 return; 716 } 717 kdc->config->num_db = 1; 718 719 status = hdb_samba4_create_kdc(kdc, task->event_ctx, task->lp_ctx, 720 kdc->smb_krb5_context->krb5_context, 721 &kdc->config->db[0]); 722 if (!NT_STATUS_IS_OK(status)) { 723 task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true); 724 return; 725 } 726 727 /* Register hdb-samba4 hooks for use as a keytab */ 728 729 kdc->hdb_samba4_context = talloc(kdc, struct hdb_samba4_context); 730 if (!kdc->hdb_samba4_context) { 731 task_server_terminate(task, "kdc: out of memory", true); 732 return; 733 } 734 735 kdc->hdb_samba4_context->ev_ctx = task->event_ctx; 736 kdc->hdb_samba4_context->lp_ctx = task->lp_ctx; 737 738 ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 739 PLUGIN_TYPE_DATA, "hdb", 740 &hdb_samba4); 741 if(ret) { 742 task_server_terminate(task, "kdc: failed to register hdb keytab", true); 743 return; 744 } 745 746 ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops); 747 if(ret) { 748 task_server_terminate(task, "kdc: failed to register hdb keytab", true); 749 return; 750 } 751 752 /* Registar WinDC hooks */ 753 ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, 754 PLUGIN_TYPE_DATA, "windc", 755 &windc_plugin_table); 756 if(ret) { 757 task_server_terminate(task, "kdc: failed to register hdb keytab", true); 758 return; 759 } 760 761 krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context); 762 763 /* start listening on the configured network interfaces */ 764 status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces); 765 if (!NT_STATUS_IS_OK(status)) { 766 task_server_terminate(task, "kdc failed to setup interfaces", true); 767 return; 768 } 769 770 status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS, 771 kdc_check_generic_kerberos, kdc); 772 if (!NT_STATUS_IS_OK(status)) { 773 task_server_terminate(task, "nbtd failed to setup monitoring", true); 774 return; 775 } 776 777 irpc_add_name(task->msg_ctx, "kdc_server"); 778} 779 780 781/* called at smbd startup - register ourselves as a server service */ 782NTSTATUS server_service_kdc_init(void) 783{ 784 return register_server_service("kdc", kdc_task_init); 785} 786