int main(int argc, char **argv) { krb5_context context; int ret, optidx = 0; setprogname(argv[0]); if (getarg(args, num_args, argc, argv, &optidx)) usage(1); if (help_flag) usage(0); if (version_flag) { print_version(NULL); exit(0); } ret = krb5_init_context(&context); if (ret) krb5_errx(context, 1, "krb5_init_context"); ret = krb5_kdc_get_config(context, &config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_default_config"); kdc_openlog(context, "digest-service", config); ret = krb5_kdc_set_dbinfo(context, config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo"); #if __APPLE__ { heim_sipc mach; heim_sipc_launchd_mach_init("org.h5l.ntlm-service", ntlm_service, context, &mach); heim_sipc_timeout(60); } #endif { heim_sipc un; heim_sipc_service_unix("org.h5l.ntlm-service", ntlm_service, NULL, &un); } heim_ipc_main(); return 0; }
krb5_kdc_configuration * configure(krb5_context context, int argc, char **argv, int *optidx) { krb5_kdc_configuration *config; krb5_error_code ret; const char *p; *optidx = 0; while(getarg(args, num_args, argc, argv, optidx)) warnx("error at argument `%s'", argv[*optidx]); if(help_flag) usage (0); if (version_flag) { print_version(NULL); exit(0); } if (builtin_hdb_flag) { char *list; ret = hdb_list_builtin(context, &list); if (ret) krb5_err(context, 1, ret, "listing builtin hdb backends"); printf("builtin hdb backends: %s\n", list); free(list); exit(0); } { char **files; int aret; if (config_file == NULL) { aret = asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); if (aret == -1 || config_file == NULL) errx(1, "out of memory"); } ret = krb5_prepend_config_files_default(config_file, &files); if (ret) krb5_err(context, 1, ret, "getting configuration files"); ret = krb5_set_config_files(context, files); krb5_free_config_files(files); if(ret) krb5_err(context, 1, ret, "reading configuration files"); } ret = krb5_kdc_get_config(context, &config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_default_config"); kdc_openlog(context, "kdc", config); ret = krb5_kdc_set_dbinfo(context, config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo"); if(max_request_str) max_request_tcp = max_request_udp = parse_bytes(max_request_str, NULL); if(max_request_tcp == 0){ p = krb5_config_get_string (context, NULL, "kdc", "max-request", NULL); if(p) max_request_tcp = max_request_udp = parse_bytes(p, NULL); } if(require_preauth != -1) config->require_preauth = require_preauth; if(port_str == NULL){ p = krb5_config_get_string(context, NULL, "kdc", "ports", NULL); if (p != NULL) port_str = strdup(p); } explicit_addresses.len = 0; if (addresses_str.num_strings) { int i; for (i = 0; i < addresses_str.num_strings; ++i) add_one_address (context, addresses_str.strings[i], i == 0); free_getarg_strings (&addresses_str); } else { char **foo = krb5_config_get_strings (context, NULL, "kdc", "addresses", NULL); if (foo != NULL) { add_one_address (context, *foo++, TRUE); while (*foo) add_one_address (context, *foo++, FALSE); } } if(enable_http == -1) enable_http = krb5_config_get_bool(context, NULL, "kdc", "enable-http", NULL); if(request_log == NULL) request_log = krb5_config_get_string(context, NULL, "kdc", "kdc-request-log", NULL); if (krb5_config_get_string(context, NULL, "kdc", "enforce-transited-policy", NULL)) krb5_errx(context, 1, "enforce-transited-policy deprecated, " "use [kdc]transited-policy instead"); #ifdef SUPPORT_DETACH if(detach_from_console == -1) detach_from_console = krb5_config_get_bool_default(context, NULL, DETACH_IS_DEFAULT, "kdc", "detach", NULL); #endif /* SUPPORT_DETACH */ if(max_request_tcp == 0) max_request_tcp = 64 * 1024; if(max_request_udp == 0) max_request_udp = 64 * 1024; if (port_str == NULL) port_str = "+"; if(disable_des == -1) disable_des = krb5_config_get_bool_default(context, NULL, FALSE, "kdc", "disable-des", NULL); if(disable_des) { krb5_enctype_disable(context, ETYPE_DES_CBC_CRC); krb5_enctype_disable(context, ETYPE_DES_CBC_MD4); krb5_enctype_disable(context, ETYPE_DES_CBC_MD5); krb5_enctype_disable(context, ETYPE_DES_CBC_NONE); krb5_enctype_disable(context, ETYPE_DES_CFB64_NONE); krb5_enctype_disable(context, ETYPE_DES_PCBC_NONE); } krb5_kdc_windc_init(context); krb5_kdc_pkinit_config(context, config); return config; }
/* startup the kdc task */ static void kdc_task_init(struct task_server *task) { struct kdc_server *kdc; krb5_kdc_configuration *kdc_config = NULL; NTSTATUS status; krb5_error_code ret; struct interface *ifaces; int ldb_ret; switch (lpcfg_server_role(task->lp_ctx)) { case ROLE_STANDALONE: task_server_terminate(task, "kdc: no KDC required in standalone configuration", false); return; case ROLE_DOMAIN_MEMBER: task_server_terminate(task, "kdc: no KDC required in member server configuration", false); return; case ROLE_DOMAIN_PDC: case ROLE_DOMAIN_BDC: task_server_terminate(task, "Cannot start KDC as a 'classic Samba' DC", true); return; case ROLE_ACTIVE_DIRECTORY_DC: /* Yes, we want a KDC */ break; } load_interface_list(task, task->lp_ctx, &ifaces); if (iface_list_count(ifaces) == 0) { task_server_terminate(task, "kdc: no network interfaces configured", false); return; } task_server_set_title(task, "task[kdc]"); kdc = talloc_zero(task, struct kdc_server); if (kdc == NULL) { task_server_terminate(task, "kdc: out of memory", true); return; } kdc->task = task; /* get a samdb connection */ kdc->samdb = samdb_connect(kdc, kdc->task->event_ctx, kdc->task->lp_ctx, system_session(kdc->task->lp_ctx), NULL, 0); if (!kdc->samdb) { DEBUG(1,("kdc_task_init: unable to connect to samdb\n")); task_server_terminate(task, "kdc: krb5_init_context samdb connect failed", true); return; } ldb_ret = samdb_rodc(kdc->samdb, &kdc->am_rodc); if (ldb_ret != LDB_SUCCESS) { DEBUG(1, ("kdc_task_init: Cannot determine if we are an RODC: %s\n", ldb_errstring(kdc->samdb))); task_server_terminate(task, "kdc: krb5_init_context samdb RODC connect failed", true); return; } kdc->proxy_timeout = lpcfg_parm_int(kdc->task->lp_ctx, NULL, "kdc", "proxy timeout", 5); initialize_krb5_error_table(); ret = smb_krb5_init_context(kdc, task->lp_ctx, &kdc->smb_krb5_context); if (ret) { DEBUG(1,("kdc_task_init: krb5_init_context failed (%s)\n", error_message(ret))); task_server_terminate(task, "kdc: krb5_init_context failed", true); return; } krb5_add_et_list(kdc->smb_krb5_context->krb5_context, initialize_hdb_error_table_r); ret = krb5_kdc_get_config(kdc->smb_krb5_context->krb5_context, &kdc_config); if(ret) { task_server_terminate(task, "kdc: failed to get KDC configuration", true); return; } kdc_config->logf = (krb5_log_facility *)kdc->smb_krb5_context->pvt_log_data; kdc_config->db = talloc(kdc, struct HDB *); if (!kdc_config->db) { task_server_terminate(task, "kdc: out of memory", true); return; } kdc_config->num_db = 1; /* * This restores the behavior before * commit 255e3e18e00f717d99f3bc57c8a8895ff624f3c3 * s4:heimdal: import lorikeet-heimdal-201107150856 * (commit 48936803fae4a2fb362c79365d31f420c917b85b) * * as_use_strongest_session_key,preauth_use_strongest_session_key * and tgs_use_strongest_session_key are input to the * _kdc_find_etype() function. The old bahavior is in * the use_strongest_session_key=FALSE code path. * (The only remaining difference in _kdc_find_etype() * is the is_preauth parameter.) * * The old behavior in the _kdc_get_preferred_key() * function is use_strongest_server_key=TRUE. */ kdc_config->as_use_strongest_session_key = false; kdc_config->preauth_use_strongest_session_key = false; kdc_config->tgs_use_strongest_session_key = false; kdc_config->use_strongest_server_key = true; kdc_config->autodetect_referrals = false; /* Register hdb-samba4 hooks for use as a keytab */ kdc->base_ctx = talloc_zero(kdc, struct samba_kdc_base_context); if (!kdc->base_ctx) { task_server_terminate(task, "kdc: out of memory", true); return; } kdc->base_ctx->ev_ctx = task->event_ctx; kdc->base_ctx->lp_ctx = task->lp_ctx; kdc->base_ctx->msg_ctx = task->msg_ctx; status = hdb_samba4_create_kdc(kdc->base_ctx, kdc->smb_krb5_context->krb5_context, &kdc_config->db[0]); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "kdc: hdb_samba4_create_kdc (setup KDC database) failed", true); return; } ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, PLUGIN_TYPE_DATA, "hdb", &hdb_samba4_interface); if(ret) { task_server_terminate(task, "kdc: failed to register hdb plugin", true); return; } ret = krb5_kt_register(kdc->smb_krb5_context->krb5_context, &hdb_kt_ops); if(ret) { task_server_terminate(task, "kdc: failed to register keytab plugin", true); return; } kdc->keytab_name = talloc_asprintf(kdc, "HDB:samba4&%p", kdc->base_ctx); if (kdc->keytab_name == NULL) { task_server_terminate(task, "kdc: Failed to set keytab name", true); return; } /* Register WinDC hooks */ ret = krb5_plugin_register(kdc->smb_krb5_context->krb5_context, PLUGIN_TYPE_DATA, "windc", &windc_plugin_table); if(ret) { task_server_terminate(task, "kdc: failed to register windc plugin", true); return; } ret = krb5_kdc_windc_init(kdc->smb_krb5_context->krb5_context); if(ret) { task_server_terminate(task, "kdc: failed to init windc plugin", true); return; } ret = krb5_kdc_pkinit_config(kdc->smb_krb5_context->krb5_context, kdc_config); if(ret) { task_server_terminate(task, "kdc: failed to init kdc pkinit subsystem", true); return; } kdc->private_data = kdc_config; /* start listening on the configured network interfaces */ status = kdc_startup_interfaces(kdc, task->lp_ctx, ifaces, task->model_ops); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "kdc failed to setup interfaces", true); return; } status = IRPC_REGISTER(task->msg_ctx, irpc, KDC_CHECK_GENERIC_KERBEROS, kdc_check_generic_kerberos, kdc); if (!NT_STATUS_IS_OK(status)) { task_server_terminate(task, "kdc failed to setup monitoring", true); return; } irpc_add_name(task->msg_ctx, "kdc_server"); }
int main(int argc, char **argv) { krb5_error_code ret; krb5_context context; krb5_kdc_configuration *config; krb5_storage *sp; int fd, optidx = 0; setprogname(argv[0]); if(getarg(args, num_args, argc, argv, &optidx)) usage(1); if(help_flag) usage(0); if(version_flag){ print_version(NULL); exit(0); } ret = krb5_init_context(&context); if (ret) errx (1, "krb5_init_context failed to parse configuration file"); ret = krb5_kdc_get_config(context, &config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_default_config"); kdc_openlog(context, "kdc-replay", config); ret = krb5_kdc_set_dbinfo(context, config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo"); #ifdef PKINIT if (config->enable_pkinit) { if (config->pkinit_kdc_identity == NULL) krb5_errx(context, 1, "pkinit enabled but no identity"); if (config->pkinit_kdc_anchors == NULL) krb5_errx(context, 1, "pkinit enabled but no X509 anchors"); krb5_kdc_pk_initialize(context, config, config->pkinit_kdc_identity, config->pkinit_kdc_anchors, config->pkinit_kdc_cert_pool, config->pkinit_kdc_revoke); } #endif /* PKINIT */ if (argc != 2) errx(1, "argc != 2"); printf("kdc replay\n"); fd = open(argv[1], O_RDONLY); if (fd < 0) err(1, "open: %s", argv[1]); sp = krb5_storage_from_fd(fd); if (sp == NULL) krb5_errx(context, 1, "krb5_storage_from_fd"); while(1) { struct sockaddr_storage sa; krb5_socklen_t salen = sizeof(sa); struct timeval tv; krb5_address a; krb5_data d, r; uint32_t t, clty, tag; char astr[80]; ret = krb5_ret_uint32(sp, &t); if (ret == HEIM_ERR_EOF) break; else if (ret) krb5_errx(context, 1, "krb5_ret_uint32(version)"); if (t != 1) krb5_errx(context, 1, "version not 1"); ret = krb5_ret_uint32(sp, &t); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(time)"); ret = krb5_ret_address(sp, &a); if (ret) krb5_errx(context, 1, "krb5_ret_address"); ret = krb5_ret_data(sp, &d); if (ret) krb5_errx(context, 1, "krb5_ret_data"); ret = krb5_ret_uint32(sp, &clty); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(class|type)"); ret = krb5_ret_uint32(sp, &tag); if (ret) krb5_errx(context, 1, "krb5_ret_uint32(tag)"); ret = krb5_addr2sockaddr (context, &a, (struct sockaddr *)&sa, &salen, 88); if (ret == KRB5_PROG_ATYPE_NOSUPP) goto out; else if (ret) krb5_err(context, 1, ret, "krb5_addr2sockaddr"); ret = krb5_print_address(&a, astr, sizeof(astr), NULL); if (ret) krb5_err(context, 1, ret, "krb5_print_address"); printf("processing request from %s, %lu bytes\n", astr, (unsigned long)d.length); r.length = 0; r.data = NULL; tv.tv_sec = t; tv.tv_usec = 0; krb5_kdc_update_time(&tv); krb5_set_real_time(context, tv.tv_sec, 0); ret = krb5_kdc_process_request(context, config, d.data, d.length, &r, NULL, astr, (struct sockaddr *)&sa, 0); if (ret) krb5_err(context, 1, ret, "krb5_kdc_process_request"); if (r.length) { Der_class cl; Der_type ty; unsigned int tag2; ret = der_get_tag (r.data, r.length, &cl, &ty, &tag2, NULL); if (MAKE_TAG(cl, ty, 0) != clty) krb5_errx(context, 1, "class|type mismatch: %d != %d", (int)MAKE_TAG(cl, ty, 0), (int)clty); if (tag != tag2) krb5_errx(context, 1, "tag mismatch"); krb5_data_free(&r); } else { if (clty != 0xffffffff) krb5_errx(context, 1, "clty not invalid"); if (tag != 0xffffffff) krb5_errx(context, 1, "tag not invalid"); } out: krb5_data_free(&d); krb5_free_address(context, &a); } krb5_storage_free(sp); krb5_free_context(context); printf("done\n"); return 0; }
krb5_kdc_configuration * configure(krb5_context context, int argc, char **argv) { krb5_kdc_configuration *config; krb5_error_code ret; int optidx = 0; const char *p; while(getarg(args, num_args, argc, argv, &optidx)) warnx("error at argument `%s'", argv[optidx]); if(help_flag) usage (0); if (version_flag) { print_version(NULL); exit(0); } if (builtin_hdb_flag) { char *list; ret = hdb_list_builtin(context, &list); if (ret) krb5_err(context, 1, ret, "listing builtin hdb backends"); printf("builtin hdb backends: %s\n", list); free(list); exit(0); } argc -= optidx; argv += optidx; if (argc != 0) usage(1); { char **files; if (config_file == NULL) { asprintf(&config_file, "%s/kdc.conf", hdb_db_dir(context)); if (config_file == NULL) errx(1, "out of memory"); } ret = krb5_prepend_config_files_default(config_file, &files); if (ret) krb5_err(context, 1, ret, "getting configuration files"); ret = krb5_set_config_files(context, files); krb5_free_config_files(files); if(ret) krb5_err(context, 1, ret, "reading configuration files"); } ret = krb5_kdc_get_config(context, &config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_default_config"); kdc_openlog(context, "kdc", config); ret = krb5_kdc_set_dbinfo(context, config); if (ret) krb5_err(context, 1, ret, "krb5_kdc_set_dbinfo"); if(max_request_str) max_request_tcp = max_request_udp = parse_bytes(max_request_str, NULL); if(max_request_tcp == 0){ p = krb5_config_get_string (context, NULL, "kdc", "max-request", NULL); if(p) max_request_tcp = max_request_udp = parse_bytes(p, NULL); } if(require_preauth != -1) config->require_preauth = require_preauth; if(port_str == NULL){ p = krb5_config_get_string(context, NULL, "kdc", "ports", NULL); if (p != NULL) port_str = strdup(p); } explicit_addresses.len = 0; if (addresses_str.num_strings) { int i; for (i = 0; i < addresses_str.num_strings; ++i) add_one_address (context, addresses_str.strings[i], i == 0); free_getarg_strings (&addresses_str); } else { char **foo = krb5_config_get_strings (context, NULL, "kdc", "addresses", NULL); if (foo != NULL) { add_one_address (context, *foo++, TRUE); while (*foo) add_one_address (context, *foo++, FALSE); } } if(enable_v4 != -1) config->enable_v4 = enable_v4; if(enable_v4_cross_realm != -1) config->enable_v4_cross_realm = enable_v4_cross_realm; if(enable_524 != -1) config->enable_524 = enable_524; if(enable_http == -1) enable_http = krb5_config_get_bool(context, NULL, "kdc", "enable-http", NULL); if(request_log == NULL) request_log = krb5_config_get_string(context, NULL, "kdc", "kdc-request-log", NULL); if (krb5_config_get_string(context, NULL, "kdc", "enforce-transited-policy", NULL)) krb5_errx(context, 1, "enforce-transited-policy deprecated, " "use [kdc]transited-policy instead"); if (enable_kaserver != -1) config->enable_kaserver = enable_kaserver; #ifdef SUPPORT_DETACH if(detach_from_console == -1) detach_from_console = krb5_config_get_bool_default(context, NULL, DETACH_IS_DEFAULT, "kdc", "detach", NULL); #endif /* SUPPORT_DETACH */ if(max_request_tcp == 0) max_request_tcp = 64 * 1024; if(max_request_udp == 0) max_request_udp = 64 * 1024; if (port_str == NULL) port_str = "+"; if (v4_realm) config->v4_realm = v4_realm; if(config->v4_realm == NULL && (config->enable_kaserver || config->enable_v4)) krb5_errx(context, 1, "Kerberos 4 enabled but no realm configured"); if(disable_des == -1) disable_des = krb5_config_get_bool_default(context, NULL, FALSE, "kdc", "disable-des", NULL); if(disable_des) { krb5_enctype_disable(context, ETYPE_DES_CBC_CRC); krb5_enctype_disable(context, ETYPE_DES_CBC_MD4); krb5_enctype_disable(context, ETYPE_DES_CBC_MD5); krb5_enctype_disable(context, ETYPE_DES_CBC_NONE); krb5_enctype_disable(context, ETYPE_DES_CFB64_NONE); krb5_enctype_disable(context, ETYPE_DES_PCBC_NONE); kdc_log(context, config, 0, "DES was disabled, turned off Kerberos V4, 524 " "and kaserver"); config->enable_v4 = 0; config->enable_524 = 0; config->enable_kaserver = 0; } krb5_kdc_windc_init(context); #ifdef PKINIT #ifdef __APPLE__ config->enable_pkinit = 1; if (config->pkinit_kdc_identity == NULL) { if (config->pkinit_kdc_friendly_name == NULL) config->pkinit_kdc_friendly_name = strdup("O=System Identity,CN=com.apple.kerberos.kdc"); config->pkinit_kdc_identity = strdup("KEYCHAIN:"); } if (config->pkinit_kdc_anchors == NULL) config->pkinit_kdc_anchors = strdup("KEYCHAIN:"); #endif /* __APPLE__ */ if (config->enable_pkinit) { if (config->pkinit_kdc_identity == NULL) krb5_errx(context, 1, "pkinit enabled but no identity"); if (config->pkinit_kdc_anchors == NULL) krb5_errx(context, 1, "pkinit enabled but no X509 anchors"); krb5_kdc_pk_initialize(context, config, config->pkinit_kdc_identity, config->pkinit_kdc_anchors, config->pkinit_kdc_cert_pool, config->pkinit_kdc_revoke); } #endif /* PKINIT */ return config; }