/* * Find a remote realm TGS principal for an unknown host-based service * principal. */ static krb5_int32 find_referral_tgs(kdc_realm_t *kdc_active_realm, krb5_kdc_req *request, krb5_principal *krbtgt_princ) { krb5_error_code retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; char **realms = NULL, *hostname = NULL; krb5_data srealm = request->server->realm; if (!is_referral_req(kdc_active_realm, request)) goto cleanup; hostname = data2string(krb5_princ_component(kdc_context, request->server, 1)); if (hostname == NULL) { retval = ENOMEM; goto cleanup; } /* If the hostname doesn't contain a '.', it's not a FQDN. */ if (strchr(hostname, '.') == NULL) goto cleanup; retval = krb5_get_host_realm(kdc_context, hostname, &realms); if (retval) { /* no match found */ kdc_err(kdc_context, retval, "unable to find realm of host"); goto cleanup; } /* Don't return a referral to the empty realm or the service realm. */ if (realms == NULL || realms[0] == NULL || *realms[0] == '\0' || data_eq_string(srealm, realms[0])) { retval = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; goto cleanup; } retval = krb5_build_principal(kdc_context, krbtgt_princ, srealm.length, srealm.data, "krbtgt", realms[0], (char *)0); cleanup: krb5_free_host_realm(kdc_context, realms); free(hostname); return retval; }
static krb5_int32 prep_reprocess_req(krb5_kdc_req *request, krb5_principal *krbtgt_princ) { krb5_error_code retval = KRB5KRB_AP_ERR_BADMATCH; size_t len = 0; char **realms, **cpp, *temp_buf=NULL; krb5_data *comp1 = NULL, *comp2 = NULL; char *comp1_str = NULL; /* By now we know that server principal name is unknown. * If CANONICALIZE flag is set in the request * If req is not U2U authn. req * the requested server princ. has exactly two components * either * the name type is NT-SRV-HST * or name type is NT-UNKNOWN and * the 1st component is listed in conf file under host_based_services * the 1st component is not in a list in conf under "no_host_referral" * the 2d component looks like fully-qualified domain name (FQDN) * If all of these conditions are satisfied - try mapping the FQDN and * re-process the request as if client had asked for cross-realm TGT. */ if (isflagset(request->kdc_options, KDC_OPT_CANONICALIZE) && !isflagset(request->kdc_options, KDC_OPT_ENC_TKT_IN_SKEY) && krb5_princ_size(kdc_context, request->server) == 2) { comp1 = krb5_princ_component(kdc_context, request->server, 0); comp2 = krb5_princ_component(kdc_context, request->server, 1); comp1_str = calloc(1,comp1->length+1); if (!comp1_str) { retval = ENOMEM; goto cleanup; } strlcpy(comp1_str,comp1->data,comp1->length+1); if ((krb5_princ_type(kdc_context, request->server) == KRB5_NT_SRV_HST || (krb5_princ_type(kdc_context, request->server) == KRB5_NT_UNKNOWN && kdc_active_realm->realm_host_based_services != NULL && (krb5_match_config_pattern(kdc_active_realm->realm_host_based_services, comp1_str) == TRUE || krb5_match_config_pattern(kdc_active_realm->realm_host_based_services, KRB5_CONF_ASTERISK) == TRUE))) && (kdc_active_realm->realm_no_host_referral == NULL || (krb5_match_config_pattern(kdc_active_realm->realm_no_host_referral, KRB5_CONF_ASTERISK) == FALSE && krb5_match_config_pattern(kdc_active_realm->realm_no_host_referral, comp1_str) == FALSE))) { for (len=0; len < comp2->length; len++) { if (comp2->data[len] == '.') break; } if (len == comp2->length) goto cleanup; temp_buf = calloc(1, comp2->length+1); if (!temp_buf){ retval = ENOMEM; goto cleanup; } strlcpy(temp_buf, comp2->data,comp2->length+1); retval = krb5int_get_domain_realm_mapping(kdc_context, temp_buf, &realms); free(temp_buf); if (retval) { /* no match found */ kdc_err(kdc_context, retval, 0); goto cleanup; } if (realms == 0) { retval = KRB5KRB_AP_ERR_BADMATCH; goto cleanup; } if (realms[0] == 0) { free(realms); retval = KRB5KRB_AP_ERR_BADMATCH; goto cleanup; } /* Modify request. * Construct cross-realm tgt : krbtgt/REMOTE_REALM@LOCAL_REALM * and use it as a principal in this req. */ retval = krb5_build_principal(kdc_context, krbtgt_princ, (*request->server).realm.length, (*request->server).realm.data, "krbtgt", realms[0], (char *)0); for (cpp = realms; *cpp; cpp++) free(*cpp); } } cleanup: free(comp1_str); return retval; }
int main(int argc, char **argv) { krb5_error_code retval; krb5_context kcontext; verto_ctx *ctx; int errout = 0; int i; setlocale(LC_MESSAGES, ""); if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS))) { fprintf(stderr, _("%s: cannot get memory for realm list\n"), argv[0]); exit(1); } memset(kdc_realmlist, 0, (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS)); /* * A note about Kerberos contexts: This context, "kcontext", is used * for the KDC operations, i.e. setup, network connection and error * reporting. The per-realm operations use the "realm_context" * associated with each realm. */ retval = krb5int_init_context_kdc(&kcontext); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } krb5_klog_init(kcontext, "kdc", argv[0], 1); kdc_err_context = kcontext; kdc_progname = argv[0]; /* N.B.: After this point, com_err sends output to the KDC log file, and not to stderr. We use the kdc_err wrapper around com_err to ensure that the error state exists in the context known to the krb5_klog callback. */ initialize_kdc5_error_table(); /* * Scan through the argument list */ initialize_realms(kcontext, argc, argv); ctx = loop_init(VERTO_EV_TYPE_NONE); if (!ctx) { kdc_err(kcontext, ENOMEM, _("while creating main loop")); finish_realms(); return 1; } load_preauth_plugins(kcontext); load_authdata_plugins(kcontext); retval = setup_sam(); if (retval) { kdc_err(kcontext, retval, _("while initializing SAM")); finish_realms(); return 1; } /* Handle each realm's ports */ for (i=0; i<kdc_numrealms; i++) { char *cp = kdc_realmlist[i]->realm_ports; int port; while (cp && *cp) { if (*cp == ',' || isspace((int) *cp)) { cp++; continue; } port = strtol(cp, &cp, 10); if (cp == 0) break; retval = loop_add_udp_port(port); if (retval) goto net_init_error; } cp = kdc_realmlist[i]->realm_tcp_ports; while (cp && *cp) { if (*cp == ',' || isspace((int) *cp)) { cp++; continue; } port = strtol(cp, &cp, 10); if (cp == 0) break; retval = loop_add_tcp_port(port); if (retval) goto net_init_error; } } /* * Setup network listeners. Disallow network reconfig in response to * routing socket messages if we're using worker processes, since the * children won't be able to re-open the listener sockets. Hopefully our * platform has pktinfo support and doesn't need reconfigs. */ if (workers == 0) { retval = loop_setup_routing_socket(ctx, NULL, kdc_progname); if (retval) { kdc_err(kcontext, retval, _("while initializing routing socket")); finish_realms(); return 1; } retval = loop_setup_signals(ctx, NULL, reset_for_hangup); if (retval) { kdc_err(kcontext, retval, _("while initializing signal handlers")); finish_realms(); return 1; } } if ((retval = loop_setup_network(ctx, NULL, kdc_progname))) { net_init_error: kdc_err(kcontext, retval, _("while initializing network")); finish_realms(); return 1; } if (!nofork && daemon(0, 0)) { kdc_err(kcontext, errno, _("while detaching from tty")); finish_realms(); return 1; } if (pid_file != NULL) { retval = write_pid_file(pid_file); if (retval) { kdc_err(kcontext, retval, _("while creating PID file")); finish_realms(); return 1; } } if (workers > 0) { finish_realms(); retval = create_workers(ctx, workers); if (retval) { kdc_err(kcontext, errno, _("creating worker processes")); return 1; } /* We get here only in a worker child process; re-initialize realms. */ initialize_realms(kcontext, argc, argv); } krb5_klog_syslog(LOG_INFO, _("commencing operation")); if (nofork) fprintf(stderr, _("%s: starting...\n"), kdc_progname); verto_run(ctx); loop_free(ctx); krb5_klog_syslog(LOG_INFO, _("shutting down")); unload_preauth_plugins(kcontext); unload_authdata_plugins(kcontext); krb5_klog_close(kdc_context); finish_realms(); if (kdc_realmlist) free(kdc_realmlist); #ifndef NOCACHE kdc_free_lookaside(kcontext); #endif krb5_free_context(kcontext); return errout; }
/* * Initialize a realm control structure from the alternate profile or from * the specified defaults. * * After we're complete here, the essence of the realm is embodied in the * realm data and we should be all set to begin operation for that realm. */ static krb5_error_code init_realm(kdc_realm_t *rdp, char *realm, char *def_mpname, krb5_enctype def_enctype, char *def_udp_ports, char *def_tcp_ports, krb5_boolean def_manual, krb5_boolean def_restrict_anon, char **db_args, char *no_refrls, char *host_based_srvcs) { krb5_error_code kret; krb5_boolean manual; krb5_realm_params *rparams; int kdb_open_flags; krb5_kvno mkvno = IGNORE_VNO; memset(rdp, 0, sizeof(kdc_realm_t)); if (!realm) { kret = EINVAL; goto whoops; } rdp->realm_name = strdup(realm); if (rdp->realm_name == NULL) { kret = ENOMEM; goto whoops; } kret = krb5int_init_context_kdc(&rdp->realm_context); if (kret) { kdc_err(NULL, kret, _("while getting context for realm %s"), realm); goto whoops; } kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name, &rparams); if (kret) { kdc_err(rdp->realm_context, kret, _("while reading realm parameters")); goto whoops; } /* Handle profile file name */ if (rparams && rparams->realm_profile) { rdp->realm_profile = strdup(rparams->realm_profile); if (!rdp->realm_profile) { kret = ENOMEM; goto whoops; } } /* Handle master key name */ if (rparams && rparams->realm_mkey_name) rdp->realm_mpname = strdup(rparams->realm_mkey_name); else rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) : strdup(KRB5_KDB_M_NAME); if (!rdp->realm_mpname) { kret = ENOMEM; goto whoops; } /* Handle KDC ports */ if (rparams && rparams->realm_kdc_ports) rdp->realm_ports = strdup(rparams->realm_kdc_ports); else rdp->realm_ports = strdup(def_udp_ports); if (!rdp->realm_ports) { kret = ENOMEM; goto whoops; } if (rparams && rparams->realm_kdc_tcp_ports) rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports); else rdp->realm_tcp_ports = strdup(def_tcp_ports); if (!rdp->realm_tcp_ports) { kret = ENOMEM; goto whoops; } /* Handle stash file */ if (rparams && rparams->realm_stash_file) { rdp->realm_stash = strdup(rparams->realm_stash_file); if (!rdp->realm_stash) { kret = ENOMEM; goto whoops; } manual = FALSE; } else manual = def_manual; if (rparams && rparams->realm_restrict_anon_valid) rdp->realm_restrict_anon = rparams->realm_restrict_anon; else rdp->realm_restrict_anon = def_restrict_anon; /* Handle master key type */ if (rparams && rparams->realm_enctype_valid) rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype; else rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN; /* Handle reject-bad-transit flag */ if (rparams && rparams->realm_reject_bad_transit_valid) rdp->realm_reject_bad_transit = rparams->realm_reject_bad_transit; else rdp->realm_reject_bad_transit = 1; /* Handle ticket maximum life */ rdp->realm_maxlife = (rparams && rparams->realm_max_life_valid) ? rparams->realm_max_life : KRB5_KDB_MAX_LIFE; /* Handle ticket renewable maximum life */ rdp->realm_maxrlife = (rparams && rparams->realm_max_rlife_valid) ? rparams->realm_max_rlife : KRB5_KDB_MAX_RLIFE; /* Handle KDC referrals */ kret = handle_referral_params(rparams, no_refrls, host_based_srvcs, rdp); if (kret == ENOMEM) goto whoops; if (rparams) krb5_free_realm_params(rdp->realm_context, rparams); /* * We've got our parameters, now go and setup our realm context. */ /* Set the default realm of this context */ if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) { kdc_err(rdp->realm_context, kret, _("while setting default realm to %s"), realm); goto whoops; } /* first open the database before doing anything */ kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC; if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) { kdc_err(rdp->realm_context, kret, _("while initializing database for realm %s"), realm); goto whoops; } /* Assemble and parse the master key name */ if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname, rdp->realm_name, (char **) NULL, &rdp->realm_mprinc))) { kdc_err(rdp->realm_context, kret, _("while setting up master key name %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } /* * Get the master key (note, may not be the most current mkey). */ if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, rdp->realm_mkey.enctype, manual, FALSE, rdp->realm_stash, &mkvno, NULL, &rdp->realm_mkey))) { kdc_err(rdp->realm_context, kret, _("while fetching master key %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc, &rdp->realm_mkey, mkvno, &rdp->mkey_list))) { kdc_err(rdp->realm_context, kret, _("while fetching master keys list for realm %s"), realm); goto whoops; } /* Set up the keytab */ if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL, &rdp->realm_keytab))) { kdc_err(rdp->realm_context, kret, _("while resolving kdb keytab for realm %s"), realm); goto whoops; } /* Preformat the TGS name */ if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc, strlen(realm), realm, KRB5_TGS_NAME, realm, (char *) NULL))) { kdc_err(rdp->realm_context, kret, _("while building TGS name for realm %s"), realm); goto whoops; } if (!rkey_init_done) { krb5_data seed; /* * If all that worked, then initialize the random key * generators. */ seed.length = rdp->realm_mkey.length; seed.data = (char *)rdp->realm_mkey.contents; if ((kret = krb5_c_random_add_entropy(rdp->realm_context, KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed))) goto whoops; rkey_init_done = 1; } whoops: /* * If we choked, then clean up any dirt we may have dropped on the floor. */ if (kret) { finish_realm(rdp); } return(kret); }
int main(int argc, char **argv) { krb5_error_code retval; krb5_context kcontext; kdc_realm_t *realm; verto_ctx *ctx; int tcp_listen_backlog; int errout = 0; int i; setlocale(LC_ALL, ""); if (strrchr(argv[0], '/')) argv[0] = strrchr(argv[0], '/')+1; shandle.kdc_realmlist = malloc(sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS); if (shandle.kdc_realmlist == NULL) { fprintf(stderr, _("%s: cannot get memory for realm list\n"), argv[0]); exit(1); } memset(shandle.kdc_realmlist, 0, (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS)); /* * A note about Kerberos contexts: This context, "kcontext", is used * for the KDC operations, i.e. setup, network connection and error * reporting. The per-realm operations use the "realm_context" * associated with each realm. */ retval = krb5int_init_context_kdc(&kcontext); if (retval) { com_err(argv[0], retval, _("while initializing krb5")); exit(1); } krb5_klog_init(kcontext, "kdc", argv[0], 1); shandle.kdc_err_context = kcontext; kdc_progname = argv[0]; /* N.B.: After this point, com_err sends output to the KDC log file, and not to stderr. We use the kdc_err wrapper around com_err to ensure that the error state exists in the context known to the krb5_klog callback. */ initialize_kdc5_error_table(); /* * Scan through the argument list */ initialize_realms(kcontext, argc, argv, &tcp_listen_backlog); #ifndef NOCACHE retval = kdc_init_lookaside(kcontext); if (retval) { kdc_err(kcontext, retval, _("while initializing lookaside cache")); finish_realms(); return 1; } #endif ctx = loop_init(VERTO_EV_TYPE_NONE); if (!ctx) { kdc_err(kcontext, ENOMEM, _("while creating main loop")); finish_realms(); return 1; } load_preauth_plugins(&shandle, kcontext, ctx); load_authdata_plugins(kcontext); retval = setup_sam(); if (retval) { kdc_err(kcontext, retval, _("while initializing SAM")); finish_realms(); return 1; } /* Add each realm's listener addresses to the loop. */ for (i = 0; i < shandle.kdc_numrealms; i++) { realm = shandle.kdc_realmlist[i]; if (*realm->realm_listen != '\0') { retval = loop_add_udp_address(KRB5_DEFAULT_PORT, realm->realm_listen); if (retval) goto net_init_error; } if (*realm->realm_tcp_listen != '\0') { retval = loop_add_tcp_address(KRB5_DEFAULT_PORT, realm->realm_tcp_listen); if (retval) goto net_init_error; } } if (workers == 0) { retval = loop_setup_signals(ctx, &shandle, reset_for_hangup); if (retval) { kdc_err(kcontext, retval, _("while initializing signal handlers")); finish_realms(); return 1; } } if ((retval = loop_setup_network(ctx, &shandle, kdc_progname, tcp_listen_backlog))) { net_init_error: kdc_err(kcontext, retval, _("while initializing network")); finish_realms(); return 1; } if (!nofork && daemon(0, 0)) { kdc_err(kcontext, errno, _("while detaching from tty")); finish_realms(); return 1; } if (pid_file != NULL) { retval = write_pid_file(pid_file); if (retval) { kdc_err(kcontext, retval, _("while creating PID file")); finish_realms(); return 1; } } if (workers > 0) { finish_realms(); retval = create_workers(ctx, workers); if (retval) { kdc_err(kcontext, errno, _("creating worker processes")); return 1; } /* We get here only in a worker child process; re-initialize realms. */ initialize_realms(kcontext, argc, argv, NULL); } /* Initialize audit system and audit KDC startup. */ retval = load_audit_modules(kcontext); if (retval) { kdc_err(kcontext, retval, _("while loading audit plugin module(s)")); finish_realms(); return 1; } krb5_klog_syslog(LOG_INFO, _("commencing operation")); if (nofork) fprintf(stderr, _("%s: starting...\n"), kdc_progname); kau_kdc_start(kcontext, TRUE); verto_run(ctx); loop_free(ctx); kau_kdc_stop(kcontext, TRUE); krb5_klog_syslog(LOG_INFO, _("shutting down")); unload_preauth_plugins(kcontext); unload_authdata_plugins(kcontext); unload_audit_modules(kcontext); krb5_klog_close(kcontext); finish_realms(); if (shandle.kdc_realmlist) free(shandle.kdc_realmlist); #ifndef NOCACHE kdc_free_lookaside(kcontext); #endif krb5_free_context(kcontext); return errout; }
/* * Initialize a realm control structure from the alternate profile or from * the specified defaults. * * After we're complete here, the essence of the realm is embodied in the * realm data and we should be all set to begin operation for that realm. */ static krb5_error_code init_realm(kdc_realm_t * rdp, krb5_pointer aprof, char *realm, char *def_mpname, krb5_enctype def_enctype, char *def_udp_listen, char *def_tcp_listen, krb5_boolean def_manual, krb5_boolean def_restrict_anon, char **db_args, char *no_referral, char *hostbased) { krb5_error_code kret; krb5_boolean manual; int kdb_open_flags; char *svalue = NULL; const char *hierarchy[4]; krb5_kvno mkvno = IGNORE_VNO; memset(rdp, 0, sizeof(kdc_realm_t)); if (!realm) { kret = EINVAL; goto whoops; } hierarchy[0] = KRB5_CONF_REALMS; hierarchy[1] = realm; hierarchy[3] = NULL; rdp->realm_name = strdup(realm); if (rdp->realm_name == NULL) { kret = ENOMEM; goto whoops; } kret = krb5int_init_context_kdc(&rdp->realm_context); if (kret) { kdc_err(NULL, kret, _("while getting context for realm %s"), realm); goto whoops; } if (time_offset != 0) (void)krb5_set_time_offsets(rdp->realm_context, time_offset, 0); /* Handle master key name */ hierarchy[2] = KRB5_CONF_MASTER_KEY_NAME; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_mpname)) { rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) : strdup(KRB5_KDB_M_NAME); } if (!rdp->realm_mpname) { kret = ENOMEM; goto whoops; } /* Handle KDC addresses/ports */ hierarchy[2] = KRB5_CONF_KDC_LISTEN; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen)) { /* Try the old kdc_ports configuration option. */ hierarchy[2] = KRB5_CONF_KDC_PORTS; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_listen)) rdp->realm_listen = strdup(def_udp_listen); } if (!rdp->realm_listen) { kret = ENOMEM; goto whoops; } hierarchy[2] = KRB5_CONF_KDC_TCP_LISTEN; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_tcp_listen)) { /* Try the old kdc_tcp_ports configuration option. */ hierarchy[2] = KRB5_CONF_KDC_TCP_PORTS; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_tcp_listen)) rdp->realm_tcp_listen = strdup(def_tcp_listen); } if (!rdp->realm_tcp_listen) { kret = ENOMEM; goto whoops; } /* Handle stash file */ hierarchy[2] = KRB5_CONF_KEY_STASH_FILE; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &rdp->realm_stash)) manual = def_manual; else manual = FALSE; hierarchy[2] = KRB5_CONF_RESTRICT_ANONYMOUS_TO_TGT; if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &rdp->realm_restrict_anon)) rdp->realm_restrict_anon = def_restrict_anon; /* Handle master key type */ hierarchy[2] = KRB5_CONF_MASTER_KEY_TYPE; if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &svalue) || krb5_string_to_enctype(svalue, &rdp->realm_mkey.enctype)) rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN; free(svalue); svalue = NULL; /* Handle reject-bad-transit flag */ hierarchy[2] = KRB5_CONF_REJECT_BAD_TRANSIT; if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &rdp->realm_reject_bad_transit)) rdp->realm_reject_bad_transit = TRUE; /* Handle assume des-cbc-crc is supported for session keys */ hierarchy[2] = KRB5_CONF_DES_CRC_SESSION_SUPPORTED; if (krb5_aprof_get_boolean(aprof, hierarchy, TRUE, &rdp->realm_assume_des_crc_sess)) rdp->realm_assume_des_crc_sess = TRUE; /* Handle ticket maximum life */ hierarchy[2] = KRB5_CONF_MAX_LIFE; if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxlife)) rdp->realm_maxlife = KRB5_KDB_MAX_LIFE; /* Handle ticket renewable maximum life */ hierarchy[2] = KRB5_CONF_MAX_RENEWABLE_LIFE; if (krb5_aprof_get_deltat(aprof, hierarchy, TRUE, &rdp->realm_maxrlife)) rdp->realm_maxrlife = KRB5_KDB_MAX_RLIFE; /* Handle KDC referrals */ hierarchy[2] = KRB5_CONF_NO_HOST_REFERRAL; (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue); kret = combine(no_referral, svalue, &rdp->realm_no_referral); if (kret) goto whoops; free(svalue); svalue = NULL; hierarchy[2] = KRB5_CONF_HOST_BASED_SERVICES; (void)krb5_aprof_get_string_all(aprof, hierarchy, &svalue); kret = combine(hostbased, svalue, &rdp->realm_hostbased); if (kret) goto whoops; free(svalue); svalue = NULL; /* * We've got our parameters, now go and setup our realm context. */ /* Set the default realm of this context */ if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) { kdc_err(rdp->realm_context, kret, _("while setting default realm to %s"), realm); goto whoops; } /* first open the database before doing anything */ kdb_open_flags = KRB5_KDB_OPEN_RW | KRB5_KDB_SRV_TYPE_KDC; if ((kret = krb5_db_open(rdp->realm_context, db_args, kdb_open_flags))) { kdc_err(rdp->realm_context, kret, _("while initializing database for realm %s"), realm); goto whoops; } /* Assemble and parse the master key name */ if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname, rdp->realm_name, (char **) NULL, &rdp->realm_mprinc))) { kdc_err(rdp->realm_context, kret, _("while setting up master key name %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } /* * Get the master key (note, may not be the most current mkey). */ if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, rdp->realm_mkey.enctype, manual, FALSE, rdp->realm_stash, &mkvno, NULL, &rdp->realm_mkey))) { kdc_err(rdp->realm_context, kret, _("while fetching master key %s for realm %s"), rdp->realm_mpname, realm); goto whoops; } if ((kret = krb5_db_fetch_mkey_list(rdp->realm_context, rdp->realm_mprinc, &rdp->realm_mkey))) { kdc_err(rdp->realm_context, kret, _("while fetching master keys list for realm %s"), realm); goto whoops; } /* Set up the keytab */ if ((kret = krb5_ktkdb_resolve(rdp->realm_context, NULL, &rdp->realm_keytab))) { kdc_err(rdp->realm_context, kret, _("while resolving kdb keytab for realm %s"), realm); goto whoops; } /* Preformat the TGS name */ if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc, strlen(realm), realm, KRB5_TGS_NAME, realm, (char *) NULL))) { kdc_err(rdp->realm_context, kret, _("while building TGS name for realm %s"), realm); goto whoops; } if (!rkey_init_done) { krb5_data seed; /* * If all that worked, then initialize the random key * generators. */ seed.length = rdp->realm_mkey.length; seed.data = (char *)rdp->realm_mkey.contents; if ((kret = krb5_c_random_add_entropy(rdp->realm_context, KRB5_C_RANDSOURCE_TRUSTEDPARTY, &seed))) goto whoops; rkey_init_done = 1; } whoops: /* * If we choked, then clean up any dirt we may have dropped on the floor. */ if (kret) { finish_realm(rdp); } return(kret); }