17c478bd9Sstevel@tonic-gate /* 2*505d05c7Sgtb * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 77c478bd9Sstevel@tonic-gate 87c478bd9Sstevel@tonic-gate /* 97c478bd9Sstevel@tonic-gate * kdc/main.c 107c478bd9Sstevel@tonic-gate * 117c478bd9Sstevel@tonic-gate * Copyright 1990,2001 by the Massachusetts Institute of Technology. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 147c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 157c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 167c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 177c478bd9Sstevel@tonic-gate * 187c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 197c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 207c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 217c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 227c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 237c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 247c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 257c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 267c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 277c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 287c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 297c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 307c478bd9Sstevel@tonic-gate * or implied warranty. 317c478bd9Sstevel@tonic-gate * 327c478bd9Sstevel@tonic-gate * 337c478bd9Sstevel@tonic-gate * Main procedure body for the KDC server process. 347c478bd9Sstevel@tonic-gate */ 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <stdio.h> 377c478bd9Sstevel@tonic-gate #include <syslog.h> 387c478bd9Sstevel@tonic-gate #include <signal.h> 397c478bd9Sstevel@tonic-gate #include <errno.h> 407c478bd9Sstevel@tonic-gate #include <netdb.h> 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #include "k5-int.h" 437c478bd9Sstevel@tonic-gate #include "com_err.h" 447c478bd9Sstevel@tonic-gate #include "adm.h" 457c478bd9Sstevel@tonic-gate #include "adm_proto.h" 467c478bd9Sstevel@tonic-gate #include "kdc_util.h" 477c478bd9Sstevel@tonic-gate #include "extern.h" 487c478bd9Sstevel@tonic-gate #include "kdc5_err.h" 497c478bd9Sstevel@tonic-gate #include <libintl.h> 507c478bd9Sstevel@tonic-gate #include <locale.h> 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #ifdef HAVE_NETINET_IN_H 537c478bd9Sstevel@tonic-gate #include <netinet/in.h> 547c478bd9Sstevel@tonic-gate #endif 557c478bd9Sstevel@tonic-gate 56*505d05c7Sgtb kdc_realm_t *find_realm_data (char *, krb5_ui_4); 577c478bd9Sstevel@tonic-gate 58*505d05c7Sgtb void usage (char *); 597c478bd9Sstevel@tonic-gate 60*505d05c7Sgtb krb5_sigtype request_exit (int); 61*505d05c7Sgtb krb5_sigtype request_hup (int); 627c478bd9Sstevel@tonic-gate 63*505d05c7Sgtb void setup_signal_handlers (void); 647c478bd9Sstevel@tonic-gate 65*505d05c7Sgtb krb5_error_code setup_sam (void); 667c478bd9Sstevel@tonic-gate 67*505d05c7Sgtb void initialize_realms (krb5_context, int, char **); 687c478bd9Sstevel@tonic-gate 69*505d05c7Sgtb void finish_realms (char *); 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate static int nofork = 0; 727c478bd9Sstevel@tonic-gate static int rkey_init_done = 0; 737c478bd9Sstevel@tonic-gate 747c478bd9Sstevel@tonic-gate /* Solaris Kerberos: global here that other functions access */ 757c478bd9Sstevel@tonic-gate int max_tcp_data_connections; 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS 787c478bd9Sstevel@tonic-gate static struct sigaction s_action; 797c478bd9Sstevel@tonic-gate #endif /* POSIX_SIGNALS */ 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate #define KRB5_KDC_MAX_REALMS 32 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate /* 847c478bd9Sstevel@tonic-gate * Find the realm entry for a given realm. 857c478bd9Sstevel@tonic-gate */ 867c478bd9Sstevel@tonic-gate kdc_realm_t * 877c478bd9Sstevel@tonic-gate find_realm_data(rname, rsize) 887c478bd9Sstevel@tonic-gate char *rname; 897c478bd9Sstevel@tonic-gate krb5_ui_4 rsize; 907c478bd9Sstevel@tonic-gate { 917c478bd9Sstevel@tonic-gate int i; 927c478bd9Sstevel@tonic-gate for (i=0; i<kdc_numrealms; i++) { 937c478bd9Sstevel@tonic-gate if ((rsize == strlen(kdc_realmlist[i]->realm_name)) && 947c478bd9Sstevel@tonic-gate !strncmp(rname, kdc_realmlist[i]->realm_name, rsize)) 957c478bd9Sstevel@tonic-gate return(kdc_realmlist[i]); 967c478bd9Sstevel@tonic-gate } 977c478bd9Sstevel@tonic-gate return((kdc_realm_t *) NULL); 987c478bd9Sstevel@tonic-gate } 997c478bd9Sstevel@tonic-gate 1007c478bd9Sstevel@tonic-gate krb5_error_code 1017c478bd9Sstevel@tonic-gate setup_server_realm(sprinc) 1027c478bd9Sstevel@tonic-gate krb5_principal sprinc; 1037c478bd9Sstevel@tonic-gate { 1047c478bd9Sstevel@tonic-gate krb5_error_code kret; 1057c478bd9Sstevel@tonic-gate kdc_realm_t *newrealm; 1067c478bd9Sstevel@tonic-gate 1077c478bd9Sstevel@tonic-gate kret = 0; 1087c478bd9Sstevel@tonic-gate if (kdc_numrealms > 1) { 1097c478bd9Sstevel@tonic-gate if (!(newrealm = find_realm_data(sprinc->realm.data, 1107c478bd9Sstevel@tonic-gate (krb5_ui_4) sprinc->realm.length))) 1117c478bd9Sstevel@tonic-gate kret = ENOENT; 1127c478bd9Sstevel@tonic-gate else 1137c478bd9Sstevel@tonic-gate kdc_active_realm = newrealm; 1147c478bd9Sstevel@tonic-gate } 1157c478bd9Sstevel@tonic-gate else 1167c478bd9Sstevel@tonic-gate kdc_active_realm = kdc_realmlist[0]; 1177c478bd9Sstevel@tonic-gate return(kret); 1187c478bd9Sstevel@tonic-gate } 1197c478bd9Sstevel@tonic-gate 1207c478bd9Sstevel@tonic-gate static void 1217c478bd9Sstevel@tonic-gate finish_realm(rdp) 1227c478bd9Sstevel@tonic-gate kdc_realm_t *rdp; 1237c478bd9Sstevel@tonic-gate { 1247c478bd9Sstevel@tonic-gate if (rdp->realm_dbname) 1257c478bd9Sstevel@tonic-gate free(rdp->realm_dbname); 1267c478bd9Sstevel@tonic-gate if (rdp->realm_mpname) 1277c478bd9Sstevel@tonic-gate free(rdp->realm_mpname); 1287c478bd9Sstevel@tonic-gate if (rdp->realm_stash) 1297c478bd9Sstevel@tonic-gate free(rdp->realm_stash); 1307c478bd9Sstevel@tonic-gate if (rdp->realm_ports) 1317c478bd9Sstevel@tonic-gate free(rdp->realm_ports); 1327c478bd9Sstevel@tonic-gate if (rdp->realm_tcp_ports) 1337c478bd9Sstevel@tonic-gate free(rdp->realm_tcp_ports); 1347c478bd9Sstevel@tonic-gate if (rdp->realm_kstypes) 1357c478bd9Sstevel@tonic-gate free(rdp->realm_kstypes); 1367c478bd9Sstevel@tonic-gate if (rdp->realm_keytab) 1377c478bd9Sstevel@tonic-gate krb5_kt_close(rdp->realm_context, rdp->realm_keytab); 1387c478bd9Sstevel@tonic-gate if (rdp->realm_context) { 1397c478bd9Sstevel@tonic-gate if (rdp->realm_mprinc) 1407c478bd9Sstevel@tonic-gate krb5_free_principal(rdp->realm_context, rdp->realm_mprinc); 1417c478bd9Sstevel@tonic-gate if (rdp->realm_mkey.length && rdp->realm_mkey.contents) { 1427c478bd9Sstevel@tonic-gate memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length); 1437c478bd9Sstevel@tonic-gate free(rdp->realm_mkey.contents); 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate if (rdp->realm_tgskey.length && rdp->realm_tgskey.contents) { 1467c478bd9Sstevel@tonic-gate memset(rdp->realm_tgskey.contents, 0, rdp->realm_tgskey.length); 1477c478bd9Sstevel@tonic-gate free(rdp->realm_tgskey.contents); 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate krb5_db_fini(rdp->realm_context); 1507c478bd9Sstevel@tonic-gate if (rdp->realm_tgsprinc) 1517c478bd9Sstevel@tonic-gate krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc); 1527c478bd9Sstevel@tonic-gate krb5_free_context(rdp->realm_context); 1537c478bd9Sstevel@tonic-gate } 1547c478bd9Sstevel@tonic-gate free(rdp); 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate /* 1587c478bd9Sstevel@tonic-gate * Initialize a realm control structure from the alternate profile or from 1597c478bd9Sstevel@tonic-gate * the specified defaults. 1607c478bd9Sstevel@tonic-gate * 1617c478bd9Sstevel@tonic-gate * After we're complete here, the essence of the realm is embodied in the 1627c478bd9Sstevel@tonic-gate * realm data and we should be all set to begin operation for that realm. 1637c478bd9Sstevel@tonic-gate */ 1647c478bd9Sstevel@tonic-gate static krb5_error_code 1657c478bd9Sstevel@tonic-gate init_realm(progname, rdp, realm, def_dbname, def_mpname, 1667c478bd9Sstevel@tonic-gate def_enctype, def_udp_ports, def_tcp_ports, def_manual) 1677c478bd9Sstevel@tonic-gate char *progname; 1687c478bd9Sstevel@tonic-gate kdc_realm_t *rdp; 1697c478bd9Sstevel@tonic-gate char *realm; 1707c478bd9Sstevel@tonic-gate char *def_dbname; 1717c478bd9Sstevel@tonic-gate char *def_mpname; 1727c478bd9Sstevel@tonic-gate krb5_enctype def_enctype; 1737c478bd9Sstevel@tonic-gate char *def_udp_ports; 1747c478bd9Sstevel@tonic-gate char *def_tcp_ports; 1757c478bd9Sstevel@tonic-gate krb5_boolean def_manual; 1767c478bd9Sstevel@tonic-gate { 1777c478bd9Sstevel@tonic-gate krb5_error_code kret; 1787c478bd9Sstevel@tonic-gate krb5_boolean manual; 1797c478bd9Sstevel@tonic-gate krb5_db_entry db_entry; 1807c478bd9Sstevel@tonic-gate int num2get; 1817c478bd9Sstevel@tonic-gate krb5_boolean more; 1827c478bd9Sstevel@tonic-gate krb5_boolean db_inited; 1837c478bd9Sstevel@tonic-gate krb5_realm_params *rparams; 1847c478bd9Sstevel@tonic-gate krb5_key_data *kdata; 1857c478bd9Sstevel@tonic-gate krb5_key_salt_tuple *kslist; 1867c478bd9Sstevel@tonic-gate krb5_int32 nkslist; 1877c478bd9Sstevel@tonic-gate int i; 1887c478bd9Sstevel@tonic-gate krb5_deltat now, krb5_kdb_max_time; 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate db_inited = 0; 1917c478bd9Sstevel@tonic-gate memset((char *) rdp, 0, sizeof(kdc_realm_t)); 1927c478bd9Sstevel@tonic-gate if (!realm) { 1937c478bd9Sstevel@tonic-gate kret = EINVAL; 1947c478bd9Sstevel@tonic-gate goto whoops; 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate 1977c478bd9Sstevel@tonic-gate rdp->realm_name = realm; 1987c478bd9Sstevel@tonic-gate kret = krb5_init_context(&rdp->realm_context); 1997c478bd9Sstevel@tonic-gate if (kret) { 2007c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while getting context for realm %s"), 2017c478bd9Sstevel@tonic-gate realm); 2027c478bd9Sstevel@tonic-gate goto whoops; 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name, 2067c478bd9Sstevel@tonic-gate (char *) NULL, (char *) NULL, &rparams); 2077c478bd9Sstevel@tonic-gate if (kret) { 2087c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while reading realm parameters")); 2097c478bd9Sstevel@tonic-gate goto whoops; 2107c478bd9Sstevel@tonic-gate } 2117c478bd9Sstevel@tonic-gate 2127c478bd9Sstevel@tonic-gate /* Handle profile file name */ 2137c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_profile) 2147c478bd9Sstevel@tonic-gate rdp->realm_profile = strdup(rparams->realm_profile); 2157c478bd9Sstevel@tonic-gate 2167c478bd9Sstevel@tonic-gate /* Handle database name */ 2177c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_dbname) 2187c478bd9Sstevel@tonic-gate rdp->realm_dbname = strdup(rparams->realm_dbname); 2197c478bd9Sstevel@tonic-gate else 2207c478bd9Sstevel@tonic-gate rdp->realm_dbname = (def_dbname) ? strdup(def_dbname) : 2217c478bd9Sstevel@tonic-gate strdup(DEFAULT_KDB_FILE); 2227c478bd9Sstevel@tonic-gate 2237c478bd9Sstevel@tonic-gate /* Handle master key name */ 2247c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_mkey_name) 2257c478bd9Sstevel@tonic-gate rdp->realm_mpname = strdup(rparams->realm_mkey_name); 2267c478bd9Sstevel@tonic-gate else 2277c478bd9Sstevel@tonic-gate rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) : 2287c478bd9Sstevel@tonic-gate strdup(KRB5_KDB_M_NAME); 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate /* Handle KDC ports */ 2317c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_kdc_ports) 2327c478bd9Sstevel@tonic-gate rdp->realm_ports = strdup(rparams->realm_kdc_ports); 2337c478bd9Sstevel@tonic-gate else 2347c478bd9Sstevel@tonic-gate rdp->realm_ports = strdup(def_udp_ports); 2357c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_kdc_tcp_ports) 2367c478bd9Sstevel@tonic-gate rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports); 2377c478bd9Sstevel@tonic-gate else 2387c478bd9Sstevel@tonic-gate rdp->realm_tcp_ports = strdup(def_tcp_ports); 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate /* Handle stash file */ 2417c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_stash_file) { 2427c478bd9Sstevel@tonic-gate rdp->realm_stash = strdup(rparams->realm_stash_file); 2437c478bd9Sstevel@tonic-gate manual = FALSE; 2447c478bd9Sstevel@tonic-gate } else 2457c478bd9Sstevel@tonic-gate manual = def_manual; 2467c478bd9Sstevel@tonic-gate 2477c478bd9Sstevel@tonic-gate /* Handle master key type */ 2487c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_enctype_valid) 2497c478bd9Sstevel@tonic-gate rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype; 2507c478bd9Sstevel@tonic-gate else 2517c478bd9Sstevel@tonic-gate rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN; 2527c478bd9Sstevel@tonic-gate if ((kret = krb5_timeofday(rdp->realm_context, &now))) { 2537c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while getting timeofday")); 2547c478bd9Sstevel@tonic-gate goto whoops; 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate 2577c478bd9Sstevel@tonic-gate /* Handle ticket maximum life */ 2587c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_max_life_valid) 2597c478bd9Sstevel@tonic-gate rdp->realm_maxlife = rparams->realm_max_life; 2607c478bd9Sstevel@tonic-gate else 2617c478bd9Sstevel@tonic-gate rdp->realm_maxlife = KRB5_KDB_EXPIRATION - now - 3600; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate /* Handle ticket renewable maximum life */ 2647c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_max_rlife_valid) 2657c478bd9Sstevel@tonic-gate rdp->realm_maxrlife = rparams->realm_max_rlife; 2667c478bd9Sstevel@tonic-gate else 2677c478bd9Sstevel@tonic-gate rdp->realm_maxrlife = KRB5_KDB_EXPIRATION - now - 3600; 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate /* Handle key/salt list */ 2707c478bd9Sstevel@tonic-gate if (rparams && rparams->realm_num_keysalts) { 2717c478bd9Sstevel@tonic-gate rdp->realm_kstypes = rparams->realm_keysalts; 2727c478bd9Sstevel@tonic-gate rdp->realm_nkstypes = rparams->realm_num_keysalts; 2737c478bd9Sstevel@tonic-gate rparams->realm_keysalts = NULL; 2747c478bd9Sstevel@tonic-gate rparams->realm_num_keysalts = 0; 2757c478bd9Sstevel@tonic-gate kslist = (krb5_key_salt_tuple *) rdp->realm_kstypes; 2767c478bd9Sstevel@tonic-gate nkslist = rdp->realm_nkstypes; 2777c478bd9Sstevel@tonic-gate } else { 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * XXX Initialize default key/salt list. 2807c478bd9Sstevel@tonic-gate */ 2817c478bd9Sstevel@tonic-gate if ((kslist = (krb5_key_salt_tuple *) 2827c478bd9Sstevel@tonic-gate malloc(sizeof(krb5_key_salt_tuple)))) { 2837c478bd9Sstevel@tonic-gate kslist->ks_enctype = ENCTYPE_DES_CBC_CRC; 2847c478bd9Sstevel@tonic-gate kslist->ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; 2857c478bd9Sstevel@tonic-gate rdp->realm_kstypes = kslist; 2867c478bd9Sstevel@tonic-gate rdp->realm_nkstypes = 1; 2877c478bd9Sstevel@tonic-gate nkslist = 1; 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate else { 2907c478bd9Sstevel@tonic-gate com_err(progname, ENOMEM, 2917c478bd9Sstevel@tonic-gate gettext("while setting up key/salt list for realm %s"), 2927c478bd9Sstevel@tonic-gate realm); 2937c478bd9Sstevel@tonic-gate exit(1); 2947c478bd9Sstevel@tonic-gate } 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate if (rparams) 2987c478bd9Sstevel@tonic-gate krb5_free_realm_params(rdp->realm_context, rparams); 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate /* 3017c478bd9Sstevel@tonic-gate * We've got our parameters, now go and setup our realm context. 3027c478bd9Sstevel@tonic-gate */ 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate /* Set the default realm of this context */ 3057c478bd9Sstevel@tonic-gate if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) { 3067c478bd9Sstevel@tonic-gate com_err(progname, kret, gettext("while setting default realm to %s"), 3077c478bd9Sstevel@tonic-gate realm); 3087c478bd9Sstevel@tonic-gate goto whoops; 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate 3117c478bd9Sstevel@tonic-gate /* Assemble and parse the master key name */ 3127c478bd9Sstevel@tonic-gate if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname, 3137c478bd9Sstevel@tonic-gate rdp->realm_name, (char **) NULL, 3147c478bd9Sstevel@tonic-gate &rdp->realm_mprinc))) { 3157c478bd9Sstevel@tonic-gate com_err(progname, kret, 3167c478bd9Sstevel@tonic-gate gettext("while setting up master key name %s for realm %s"), 3177c478bd9Sstevel@tonic-gate rdp->realm_mpname, realm); 3187c478bd9Sstevel@tonic-gate goto whoops; 3197c478bd9Sstevel@tonic-gate } 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate /* 3227c478bd9Sstevel@tonic-gate * Get the master key. 3237c478bd9Sstevel@tonic-gate */ 3247c478bd9Sstevel@tonic-gate if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, 3257c478bd9Sstevel@tonic-gate rdp->realm_mkey.enctype, manual, 3267c478bd9Sstevel@tonic-gate FALSE, rdp->realm_stash, 3277c478bd9Sstevel@tonic-gate 0, &rdp->realm_mkey))) { 3287c478bd9Sstevel@tonic-gate com_err(progname, kret, 3297c478bd9Sstevel@tonic-gate gettext("while fetching master key %s for realm %s"), 3307c478bd9Sstevel@tonic-gate rdp->realm_mpname, realm); 3317c478bd9Sstevel@tonic-gate goto whoops; 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate 3347c478bd9Sstevel@tonic-gate /* Set and open the database. */ 3357c478bd9Sstevel@tonic-gate if (rdp->realm_dbname && 3367c478bd9Sstevel@tonic-gate (kret = krb5_db_set_name(rdp->realm_context, rdp->realm_dbname))) { 3377c478bd9Sstevel@tonic-gate com_err(progname, kret, 3387c478bd9Sstevel@tonic-gate gettext("while setting database name to %s for realm %s"), 3397c478bd9Sstevel@tonic-gate rdp->realm_dbname, realm); 3407c478bd9Sstevel@tonic-gate goto whoops; 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate if ((kret = krb5_db_init(rdp->realm_context))) { 3437c478bd9Sstevel@tonic-gate com_err(progname, kret, 3447c478bd9Sstevel@tonic-gate gettext("while initializing database "), 3457c478bd9Sstevel@tonic-gate gettext("for realm %s"), realm); 3467c478bd9Sstevel@tonic-gate goto whoops; 3477c478bd9Sstevel@tonic-gate } else 3487c478bd9Sstevel@tonic-gate db_inited = 1; 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate /* Verify the master key */ 3517c478bd9Sstevel@tonic-gate if ((kret = krb5_db_verify_master_key(rdp->realm_context, 3527c478bd9Sstevel@tonic-gate rdp->realm_mprinc, 3537c478bd9Sstevel@tonic-gate &rdp->realm_mkey))) { 3547c478bd9Sstevel@tonic-gate com_err(progname, kret, 3557c478bd9Sstevel@tonic-gate gettext("while verifying master key for realm %s"), 3567c478bd9Sstevel@tonic-gate realm); 3577c478bd9Sstevel@tonic-gate goto whoops; 3587c478bd9Sstevel@tonic-gate } 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate /* Fetch the master key and get its version number */ 3617c478bd9Sstevel@tonic-gate num2get = 1; 3627c478bd9Sstevel@tonic-gate kret = krb5_db_get_principal(rdp->realm_context, rdp->realm_mprinc, 3637c478bd9Sstevel@tonic-gate &db_entry, &num2get, &more); 3647c478bd9Sstevel@tonic-gate if (!kret) { 3657c478bd9Sstevel@tonic-gate if (num2get != 1) 3667c478bd9Sstevel@tonic-gate kret = KRB5_KDB_NOMASTERKEY; 3677c478bd9Sstevel@tonic-gate else { 3687c478bd9Sstevel@tonic-gate if (more) { 3697c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 3707c478bd9Sstevel@tonic-gate &db_entry, 3717c478bd9Sstevel@tonic-gate num2get); 3727c478bd9Sstevel@tonic-gate kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE; 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate if (kret) { 3777c478bd9Sstevel@tonic-gate com_err(progname, kret, 3787c478bd9Sstevel@tonic-gate gettext("while fetching master entry for realm %s"), 3797c478bd9Sstevel@tonic-gate realm); 3807c478bd9Sstevel@tonic-gate goto whoops; 3817c478bd9Sstevel@tonic-gate } 3827c478bd9Sstevel@tonic-gate 3837c478bd9Sstevel@tonic-gate /* 3847c478bd9Sstevel@tonic-gate * Get the most recent master key. Search the key list in 3857c478bd9Sstevel@tonic-gate * the order specified by the key/salt list. 3867c478bd9Sstevel@tonic-gate */ 3877c478bd9Sstevel@tonic-gate kdata = (krb5_key_data *) NULL; 3887c478bd9Sstevel@tonic-gate for (i=0; i<nkslist; i++) { 3897c478bd9Sstevel@tonic-gate if (!(kret = krb5_dbe_find_enctype(rdp->realm_context, 3907c478bd9Sstevel@tonic-gate &db_entry, 3917c478bd9Sstevel@tonic-gate kslist[i].ks_enctype, 3927c478bd9Sstevel@tonic-gate -1, 3937c478bd9Sstevel@tonic-gate -1, 3947c478bd9Sstevel@tonic-gate &kdata))) 3957c478bd9Sstevel@tonic-gate break; 3967c478bd9Sstevel@tonic-gate } 3977c478bd9Sstevel@tonic-gate if (!kdata) { 3987c478bd9Sstevel@tonic-gate com_err(progname, kret, 3997c478bd9Sstevel@tonic-gate gettext("while finding master key for realm %s"), 4007c478bd9Sstevel@tonic-gate realm); 4017c478bd9Sstevel@tonic-gate goto whoops; 4027c478bd9Sstevel@tonic-gate } 4037c478bd9Sstevel@tonic-gate rdp->realm_mkvno = kdata->key_data_kvno; 4047c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, &db_entry, num2get); 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) { 4077c478bd9Sstevel@tonic-gate com_err(progname, kret, 4087c478bd9Sstevel@tonic-gate gettext("while processing master key for realm %s"), 4097c478bd9Sstevel@tonic-gate realm); 4107c478bd9Sstevel@tonic-gate goto whoops; 4117c478bd9Sstevel@tonic-gate } 4127c478bd9Sstevel@tonic-gate 4137c478bd9Sstevel@tonic-gate /* Set up the keytab */ 4147c478bd9Sstevel@tonic-gate if ((kret = krb5_ktkdb_resolve(rdp->realm_context, 4157c478bd9Sstevel@tonic-gate NULL, 4167c478bd9Sstevel@tonic-gate &rdp->realm_keytab))) { 4177c478bd9Sstevel@tonic-gate com_err(progname, kret, 4187c478bd9Sstevel@tonic-gate gettext("while resolving kdb keytab for realm %s"), 4197c478bd9Sstevel@tonic-gate realm); 4207c478bd9Sstevel@tonic-gate goto whoops; 4217c478bd9Sstevel@tonic-gate } 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate /* Preformat the TGS name */ 4247c478bd9Sstevel@tonic-gate if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc, 4257c478bd9Sstevel@tonic-gate strlen(realm), realm, KRB5_TGS_NAME, 4267c478bd9Sstevel@tonic-gate realm, (char *) NULL))) { 4277c478bd9Sstevel@tonic-gate com_err(progname, kret, 4287c478bd9Sstevel@tonic-gate gettext("while building TGS name for realm %s"), 4297c478bd9Sstevel@tonic-gate realm); 4307c478bd9Sstevel@tonic-gate goto whoops; 4317c478bd9Sstevel@tonic-gate } 4327c478bd9Sstevel@tonic-gate 4337c478bd9Sstevel@tonic-gate /* Get the TGS database entry */ 4347c478bd9Sstevel@tonic-gate num2get = 1; 4357c478bd9Sstevel@tonic-gate if (!(kret = krb5_db_get_principal(rdp->realm_context, 4367c478bd9Sstevel@tonic-gate rdp->realm_tgsprinc, 4377c478bd9Sstevel@tonic-gate &db_entry, 4387c478bd9Sstevel@tonic-gate &num2get, 4397c478bd9Sstevel@tonic-gate &more))) { 4407c478bd9Sstevel@tonic-gate if (num2get != 1) 4417c478bd9Sstevel@tonic-gate kret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 4427c478bd9Sstevel@tonic-gate else { 4437c478bd9Sstevel@tonic-gate if (more) { 4447c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 4457c478bd9Sstevel@tonic-gate &db_entry, 4467c478bd9Sstevel@tonic-gate num2get); 4477c478bd9Sstevel@tonic-gate kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE; 4487c478bd9Sstevel@tonic-gate } 4497c478bd9Sstevel@tonic-gate } 4507c478bd9Sstevel@tonic-gate } 4517c478bd9Sstevel@tonic-gate if (kret) { 4527c478bd9Sstevel@tonic-gate com_err(progname, kret, 4537c478bd9Sstevel@tonic-gate gettext("while fetching TGS entry for realm %s"), 4547c478bd9Sstevel@tonic-gate realm); 4557c478bd9Sstevel@tonic-gate goto whoops; 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate /* 4587c478bd9Sstevel@tonic-gate * Get the most recent TGS key. Search the key list in 4597c478bd9Sstevel@tonic-gate * the order specified by the key/salt list. 4607c478bd9Sstevel@tonic-gate */ 4617c478bd9Sstevel@tonic-gate kdata = (krb5_key_data *) NULL; 4627c478bd9Sstevel@tonic-gate for (i=0; i<nkslist; i++) { 4637c478bd9Sstevel@tonic-gate if (!(kret = krb5_dbe_find_enctype(rdp->realm_context, 4647c478bd9Sstevel@tonic-gate &db_entry, 4657c478bd9Sstevel@tonic-gate kslist[i].ks_enctype, 4667c478bd9Sstevel@tonic-gate -1, 4677c478bd9Sstevel@tonic-gate -1, 4687c478bd9Sstevel@tonic-gate &kdata))) 4697c478bd9Sstevel@tonic-gate break; 4707c478bd9Sstevel@tonic-gate } 4717c478bd9Sstevel@tonic-gate if (!kdata) { 4727c478bd9Sstevel@tonic-gate com_err(progname, kret, 4737c478bd9Sstevel@tonic-gate gettext("while finding TGS key for realm %s"), 4747c478bd9Sstevel@tonic-gate realm); 4757c478bd9Sstevel@tonic-gate goto whoops; 4767c478bd9Sstevel@tonic-gate } 4777c478bd9Sstevel@tonic-gate if (!(kret = krb5_dbekd_decrypt_key_data(rdp->realm_context, 4787c478bd9Sstevel@tonic-gate &rdp->realm_mkey, 4797c478bd9Sstevel@tonic-gate kdata, 4807c478bd9Sstevel@tonic-gate &rdp->realm_tgskey, NULL))){ 4817c478bd9Sstevel@tonic-gate rdp->realm_tgskvno = kdata->key_data_kvno; 4827c478bd9Sstevel@tonic-gate } 4837c478bd9Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 4847c478bd9Sstevel@tonic-gate &db_entry, 4857c478bd9Sstevel@tonic-gate num2get); 4867c478bd9Sstevel@tonic-gate if (kret) { 4877c478bd9Sstevel@tonic-gate com_err(progname, kret, 4887c478bd9Sstevel@tonic-gate gettext("while decrypting TGS key for realm %s"), 4897c478bd9Sstevel@tonic-gate realm); 4907c478bd9Sstevel@tonic-gate goto whoops; 4917c478bd9Sstevel@tonic-gate } 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate if (!rkey_init_done) { 4947c478bd9Sstevel@tonic-gate krb5_timestamp now; 4957c478bd9Sstevel@tonic-gate krb5_data seed; 4967c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 4977c478bd9Sstevel@tonic-gate krb5_keyblock temp_key; 4987c478bd9Sstevel@tonic-gate #endif 4997c478bd9Sstevel@tonic-gate /* 5007c478bd9Sstevel@tonic-gate * If all that worked, then initialize the random key 5017c478bd9Sstevel@tonic-gate * generators. 5027c478bd9Sstevel@tonic-gate */ 5037c478bd9Sstevel@tonic-gate 5047c478bd9Sstevel@tonic-gate if ((kret = krb5_timeofday(rdp->realm_context, &now))) 5057c478bd9Sstevel@tonic-gate goto whoops; 5067c478bd9Sstevel@tonic-gate seed.length = sizeof(now); 5077c478bd9Sstevel@tonic-gate seed.data = (char *) &now; 5087c478bd9Sstevel@tonic-gate if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) 5097c478bd9Sstevel@tonic-gate goto whoops; 5107c478bd9Sstevel@tonic-gate 5117c478bd9Sstevel@tonic-gate seed.length = rdp->realm_mkey.length; 5127c478bd9Sstevel@tonic-gate seed.data = (char *)rdp->realm_mkey.contents; 5137c478bd9Sstevel@tonic-gate 5147c478bd9Sstevel@tonic-gate if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) 5157c478bd9Sstevel@tonic-gate goto whoops; 5167c478bd9Sstevel@tonic-gate 5177c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 5187c478bd9Sstevel@tonic-gate if ((kret = krb5_c_make_random_key(rdp->realm_context, 5197c478bd9Sstevel@tonic-gate ENCTYPE_DES_CBC_CRC, &temp_key))) { 5207c478bd9Sstevel@tonic-gate com_err(progname, kret, 5217c478bd9Sstevel@tonic-gate "while initializing V4 random key generator"); 5227c478bd9Sstevel@tonic-gate goto whoops; 5237c478bd9Sstevel@tonic-gate } 5247c478bd9Sstevel@tonic-gate 5257c478bd9Sstevel@tonic-gate (void) des_init_random_number_generator(temp_key.contents); 5267c478bd9Sstevel@tonic-gate krb5_free_keyblock_contents(rdp->realm_context, &temp_key); 5277c478bd9Sstevel@tonic-gate #endif 5287c478bd9Sstevel@tonic-gate rkey_init_done = 1; 5297c478bd9Sstevel@tonic-gate } 5307c478bd9Sstevel@tonic-gate whoops: 5317c478bd9Sstevel@tonic-gate /* 5327c478bd9Sstevel@tonic-gate * If we choked, then clean up any dirt we may have dropped on the floor. 5337c478bd9Sstevel@tonic-gate */ 5347c478bd9Sstevel@tonic-gate if (kret) { 5357c478bd9Sstevel@tonic-gate finish_realm(rdp); 5367c478bd9Sstevel@tonic-gate } 5377c478bd9Sstevel@tonic-gate return(kret); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate krb5_sigtype 5417c478bd9Sstevel@tonic-gate request_exit(signo) 5427c478bd9Sstevel@tonic-gate int signo; 5437c478bd9Sstevel@tonic-gate { 5447c478bd9Sstevel@tonic-gate signal_requests_exit = 1; 5457c478bd9Sstevel@tonic-gate 5467c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGTYPE 5477c478bd9Sstevel@tonic-gate return; 5487c478bd9Sstevel@tonic-gate #else 5497c478bd9Sstevel@tonic-gate return(0); 5507c478bd9Sstevel@tonic-gate #endif 5517c478bd9Sstevel@tonic-gate } 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate krb5_sigtype 5547c478bd9Sstevel@tonic-gate request_hup(signo) 5557c478bd9Sstevel@tonic-gate int signo; 5567c478bd9Sstevel@tonic-gate { 5577c478bd9Sstevel@tonic-gate signal_requests_hup = 1; 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGTYPE 5607c478bd9Sstevel@tonic-gate return; 5617c478bd9Sstevel@tonic-gate #else 5627c478bd9Sstevel@tonic-gate return(0); 5637c478bd9Sstevel@tonic-gate #endif 5647c478bd9Sstevel@tonic-gate } 5657c478bd9Sstevel@tonic-gate 5667c478bd9Sstevel@tonic-gate void 5677c478bd9Sstevel@tonic-gate setup_signal_handlers() 5687c478bd9Sstevel@tonic-gate { 5697c478bd9Sstevel@tonic-gate #ifdef POSIX_SIGNALS 5707c478bd9Sstevel@tonic-gate (void) sigemptyset(&s_action.sa_mask); 5717c478bd9Sstevel@tonic-gate s_action.sa_flags = 0; 5727c478bd9Sstevel@tonic-gate s_action.sa_handler = request_exit; 5737c478bd9Sstevel@tonic-gate (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL); 5747c478bd9Sstevel@tonic-gate (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL); 5757c478bd9Sstevel@tonic-gate s_action.sa_handler = request_hup; 5767c478bd9Sstevel@tonic-gate (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL); 5777c478bd9Sstevel@tonic-gate #else /* POSIX_SIGNALS */ 5787c478bd9Sstevel@tonic-gate signal(SIGINT, request_exit); 5797c478bd9Sstevel@tonic-gate signal(SIGTERM, request_exit); 5807c478bd9Sstevel@tonic-gate signal(SIGHUP, request_hup); 5817c478bd9Sstevel@tonic-gate #endif /* POSIX_SIGNALS */ 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate return; 5847c478bd9Sstevel@tonic-gate } 5857c478bd9Sstevel@tonic-gate 5867c478bd9Sstevel@tonic-gate krb5_error_code 5877c478bd9Sstevel@tonic-gate setup_sam() 5887c478bd9Sstevel@tonic-gate { 5897c478bd9Sstevel@tonic-gate return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key); 5907c478bd9Sstevel@tonic-gate } 5917c478bd9Sstevel@tonic-gate 5927c478bd9Sstevel@tonic-gate void 5937c478bd9Sstevel@tonic-gate usage(name) 5947c478bd9Sstevel@tonic-gate char *name; 5957c478bd9Sstevel@tonic-gate { 5967c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("usage: %s [-d dbpathname] [-r dbrealmname] [-R replaycachename ]\n\t[-m] [-k masterenctype] [-M masterkeyname] [-p port] [-n]\n"), name); 5977c478bd9Sstevel@tonic-gate return; 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate 6007c478bd9Sstevel@tonic-gate void 6017c478bd9Sstevel@tonic-gate initialize_realms(kcontext, argc, argv) 6027c478bd9Sstevel@tonic-gate krb5_context kcontext; 6037c478bd9Sstevel@tonic-gate int argc; 6047c478bd9Sstevel@tonic-gate char **argv; 6057c478bd9Sstevel@tonic-gate { 6067c478bd9Sstevel@tonic-gate int c; 6077c478bd9Sstevel@tonic-gate char *db_name = (char *) NULL; 6087c478bd9Sstevel@tonic-gate char *mkey_name = (char *) NULL; 6097c478bd9Sstevel@tonic-gate char *rcname = KDCRCACHE; 6107c478bd9Sstevel@tonic-gate char *lrealm; 6117c478bd9Sstevel@tonic-gate krb5_error_code retval; 6127c478bd9Sstevel@tonic-gate krb5_enctype menctype = ENCTYPE_UNKNOWN; 6137c478bd9Sstevel@tonic-gate kdc_realm_t *rdatap; 6147c478bd9Sstevel@tonic-gate krb5_boolean manual = FALSE; 6157c478bd9Sstevel@tonic-gate char *default_udp_ports = 0; 6167c478bd9Sstevel@tonic-gate char *default_tcp_ports = 0; 6177c478bd9Sstevel@tonic-gate krb5_pointer aprof; 6187c478bd9Sstevel@tonic-gate const char *hierarchy[3]; 6197c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 6207c478bd9Sstevel@tonic-gate char *v4mode = 0; 6217c478bd9Sstevel@tonic-gate #endif 6227c478bd9Sstevel@tonic-gate extern char *optarg; 6237c478bd9Sstevel@tonic-gate #ifdef ATHENA_DES3_KLUDGE 6247c478bd9Sstevel@tonic-gate extern struct krb5_keytypes krb5_enctypes_list[]; 6257c478bd9Sstevel@tonic-gate extern int krb5_enctypes_length; 6267c478bd9Sstevel@tonic-gate #endif 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) { 6297c478bd9Sstevel@tonic-gate hierarchy[0] = "kdcdefaults"; 6307c478bd9Sstevel@tonic-gate hierarchy[1] = "kdc_ports"; 6317c478bd9Sstevel@tonic-gate hierarchy[2] = (char *) NULL; 6327c478bd9Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports)) 6337c478bd9Sstevel@tonic-gate default_udp_ports = 0; 6347c478bd9Sstevel@tonic-gate hierarchy[1] = "kdc_tcp_ports"; 6357c478bd9Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports)) 6367c478bd9Sstevel@tonic-gate default_tcp_ports = 0; 6377c478bd9Sstevel@tonic-gate hierarchy[1] = "kdc_max_tcp_connections"; 6387c478bd9Sstevel@tonic-gate if (krb5_aprof_get_int32(aprof, hierarchy, TRUE, 6397c478bd9Sstevel@tonic-gate &max_tcp_data_connections)) { 6407c478bd9Sstevel@tonic-gate max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS; 6417c478bd9Sstevel@tonic-gate } else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) { 6427c478bd9Sstevel@tonic-gate max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS; 6437c478bd9Sstevel@tonic-gate } 6447c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 6457c478bd9Sstevel@tonic-gate hierarchy[1] = "v4_mode"; 6467c478bd9Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode)) 6477c478bd9Sstevel@tonic-gate v4mode = 0; 6487c478bd9Sstevel@tonic-gate #endif 6497c478bd9Sstevel@tonic-gate /* aprof_init can return 0 with aprof == NULL */ 6507c478bd9Sstevel@tonic-gate if (aprof) 6517c478bd9Sstevel@tonic-gate krb5_aprof_finish(aprof); 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate if (default_udp_ports == 0) 6547c478bd9Sstevel@tonic-gate default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST); 6557c478bd9Sstevel@tonic-gate if (default_tcp_ports == 0) 6567c478bd9Sstevel@tonic-gate default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST); 6577c478bd9Sstevel@tonic-gate /* 6587c478bd9Sstevel@tonic-gate * Loop through the option list. Each time we encounter a realm name, 6597c478bd9Sstevel@tonic-gate * use the previously scanned options to fill in for defaults. 6607c478bd9Sstevel@tonic-gate */ 6617c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n")) != -1) { /* SUNW */ 6627c478bd9Sstevel@tonic-gate switch(c) { 6637c478bd9Sstevel@tonic-gate case 'r': /* realm name for db */ 6647c478bd9Sstevel@tonic-gate if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) { 6657c478bd9Sstevel@tonic-gate if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) { 6667c478bd9Sstevel@tonic-gate if ((retval = init_realm(argv[0], rdatap, optarg, db_name, 6677c478bd9Sstevel@tonic-gate mkey_name, menctype, 6687c478bd9Sstevel@tonic-gate default_udp_ports, 6697c478bd9Sstevel@tonic-gate default_tcp_ports, manual))) { 6707c478bd9Sstevel@tonic-gate fprintf(stderr,gettext("%s: cannot initialize realm %s\n"), 6717c478bd9Sstevel@tonic-gate argv[0], optarg); 6727c478bd9Sstevel@tonic-gate exit(1); 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate kdc_realmlist[kdc_numrealms] = rdatap; 6757c478bd9Sstevel@tonic-gate kdc_numrealms++; 6767c478bd9Sstevel@tonic-gate } 6777c478bd9Sstevel@tonic-gate } 6787c478bd9Sstevel@tonic-gate break; 6797c478bd9Sstevel@tonic-gate case 'd': /* pathname for db */ 6807c478bd9Sstevel@tonic-gate db_name = optarg; 6817c478bd9Sstevel@tonic-gate break; 6827c478bd9Sstevel@tonic-gate case 'm': /* manual type-in of master key */ 6837c478bd9Sstevel@tonic-gate manual = TRUE; 6847c478bd9Sstevel@tonic-gate if (menctype == ENCTYPE_UNKNOWN) 6857c478bd9Sstevel@tonic-gate menctype = ENCTYPE_DES_CBC_CRC; 6867c478bd9Sstevel@tonic-gate break; 6877c478bd9Sstevel@tonic-gate case 'M': /* master key name in DB */ 6887c478bd9Sstevel@tonic-gate mkey_name = optarg; 6897c478bd9Sstevel@tonic-gate break; 6907c478bd9Sstevel@tonic-gate case 'n': 6917c478bd9Sstevel@tonic-gate nofork++; /* don't detach from terminal */ 6927c478bd9Sstevel@tonic-gate break; 6937c478bd9Sstevel@tonic-gate case 'k': /* enctype for master key */ 6947c478bd9Sstevel@tonic-gate if (krb5_string_to_enctype(optarg, &menctype)) 6957c478bd9Sstevel@tonic-gate com_err(argv[0], 0, 6967c478bd9Sstevel@tonic-gate gettext("invalid enctype %s"), optarg); 6977c478bd9Sstevel@tonic-gate break; 6987c478bd9Sstevel@tonic-gate case 'R': 6997c478bd9Sstevel@tonic-gate rcname = optarg; 7007c478bd9Sstevel@tonic-gate break; 7017c478bd9Sstevel@tonic-gate case 'p': 7027c478bd9Sstevel@tonic-gate if (default_udp_ports) 7037c478bd9Sstevel@tonic-gate free(default_udp_ports); 7047c478bd9Sstevel@tonic-gate default_udp_ports = strdup(optarg); 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate if (default_tcp_ports) 7077c478bd9Sstevel@tonic-gate free(default_tcp_ports); 7087c478bd9Sstevel@tonic-gate default_tcp_ports = strdup(optarg); 7097c478bd9Sstevel@tonic-gate 7107c478bd9Sstevel@tonic-gate break; 7117c478bd9Sstevel@tonic-gate case '4': 7127c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 7137c478bd9Sstevel@tonic-gate if (v4mode) 7147c478bd9Sstevel@tonic-gate free(v4mode); 7157c478bd9Sstevel@tonic-gate v4mode = strdup(optarg); 7167c478bd9Sstevel@tonic-gate #endif 7177c478bd9Sstevel@tonic-gate break; 7187c478bd9Sstevel@tonic-gate case '3': 7197c478bd9Sstevel@tonic-gate #ifdef ATHENA_DES3_KLUDGE 7207c478bd9Sstevel@tonic-gate if (krb5_enctypes_list[krb5_enctypes_length-1].etype 7217c478bd9Sstevel@tonic-gate != ENCTYPE_LOCAL_DES3_HMAC_SHA1) { 7227c478bd9Sstevel@tonic-gate fprintf(stderr, 7237c478bd9Sstevel@tonic-gate "internal inconsistency in enctypes_list" 7247c478bd9Sstevel@tonic-gate " while disabling\n" 7257c478bd9Sstevel@tonic-gate "des3-marc-hmac-sha1 enctype\n"); 7267c478bd9Sstevel@tonic-gate exit(1); 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate krb5_enctypes_length--; 7297c478bd9Sstevel@tonic-gate break; 7307c478bd9Sstevel@tonic-gate #endif 7317c478bd9Sstevel@tonic-gate case '?': 7327c478bd9Sstevel@tonic-gate default: 7337c478bd9Sstevel@tonic-gate usage(argv[0]); 7347c478bd9Sstevel@tonic-gate exit(1); 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate 7387c478bd9Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 7397c478bd9Sstevel@tonic-gate /* 7407c478bd9Sstevel@tonic-gate * Setup the v4 mode 7417c478bd9Sstevel@tonic-gate */ 7427c478bd9Sstevel@tonic-gate process_v4_mode(argv[0], v4mode); 7437c478bd9Sstevel@tonic-gate #endif 7447c478bd9Sstevel@tonic-gate 7457c478bd9Sstevel@tonic-gate /* 7467c478bd9Sstevel@tonic-gate * Check to see if we processed any realms. 7477c478bd9Sstevel@tonic-gate */ 7487c478bd9Sstevel@tonic-gate if (kdc_numrealms == 0) { 7497c478bd9Sstevel@tonic-gate /* no realm specified, use default realm */ 7507c478bd9Sstevel@tonic-gate if ((retval = krb5_get_default_realm(kcontext, &lrealm))) { 7517c478bd9Sstevel@tonic-gate com_err(argv[0], retval, 7527c478bd9Sstevel@tonic-gate gettext("while attempting to retrieve default realm")); 7537c478bd9Sstevel@tonic-gate exit(1); 7547c478bd9Sstevel@tonic-gate } 7557c478bd9Sstevel@tonic-gate if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) { 7567c478bd9Sstevel@tonic-gate if ((retval = init_realm(argv[0], rdatap, lrealm, db_name, 7577c478bd9Sstevel@tonic-gate mkey_name, menctype, default_udp_ports, 7587c478bd9Sstevel@tonic-gate default_tcp_ports, manual))) { 7597c478bd9Sstevel@tonic-gate fprintf(stderr, 7607c478bd9Sstevel@tonic-gate gettext("%s: cannot initialize realm %s\n"), 7617c478bd9Sstevel@tonic-gate argv[0], lrealm); 7627c478bd9Sstevel@tonic-gate exit(1); 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate kdc_realmlist[0] = rdatap; 7657c478bd9Sstevel@tonic-gate kdc_numrealms++; 7667c478bd9Sstevel@tonic-gate } 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate 7697c478bd9Sstevel@tonic-gate #ifdef USE_RCACHE 7707c478bd9Sstevel@tonic-gate /* 7717c478bd9Sstevel@tonic-gate * Now handle the replay cache. 7727c478bd9Sstevel@tonic-gate */ 7737c478bd9Sstevel@tonic-gate if ((retval = kdc_initialize_rcache(kcontext, rcname))) { 7747c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing KDC replay cache")); 7757c478bd9Sstevel@tonic-gate exit(1); 7767c478bd9Sstevel@tonic-gate } 7777c478bd9Sstevel@tonic-gate #endif 7787c478bd9Sstevel@tonic-gate 7797c478bd9Sstevel@tonic-gate /* Ensure that this is set for our first request. */ 7807c478bd9Sstevel@tonic-gate kdc_active_realm = kdc_realmlist[0]; 7817c478bd9Sstevel@tonic-gate if (default_udp_ports) 7827c478bd9Sstevel@tonic-gate free(default_udp_ports); 7837c478bd9Sstevel@tonic-gate if (default_tcp_ports) 7847c478bd9Sstevel@tonic-gate free(default_tcp_ports); 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate return; 7877c478bd9Sstevel@tonic-gate } 7887c478bd9Sstevel@tonic-gate 7897c478bd9Sstevel@tonic-gate void 7907c478bd9Sstevel@tonic-gate finish_realms(prog) 7917c478bd9Sstevel@tonic-gate char *prog; 7927c478bd9Sstevel@tonic-gate { 7937c478bd9Sstevel@tonic-gate int i; 7947c478bd9Sstevel@tonic-gate 7957c478bd9Sstevel@tonic-gate for (i = 0; i < kdc_numrealms; i++) { 7967c478bd9Sstevel@tonic-gate finish_realm(kdc_realmlist[i]); 7977c478bd9Sstevel@tonic-gate kdc_realmlist[i] = 0; 7987c478bd9Sstevel@tonic-gate } 7997c478bd9Sstevel@tonic-gate } 8007c478bd9Sstevel@tonic-gate 8017c478bd9Sstevel@tonic-gate /* 8027c478bd9Sstevel@tonic-gate outline: 8037c478bd9Sstevel@tonic-gate 8047c478bd9Sstevel@tonic-gate process args & setup 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate initialize database access (fetch master key, open DB) 8077c478bd9Sstevel@tonic-gate 8087c478bd9Sstevel@tonic-gate initialize network 8097c478bd9Sstevel@tonic-gate 8107c478bd9Sstevel@tonic-gate loop: 8117c478bd9Sstevel@tonic-gate listen for packet 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate determine packet type, dispatch to handling routine 8147c478bd9Sstevel@tonic-gate (AS or TGS (or V4?)) 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate reflect response 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate exit on signal 8197c478bd9Sstevel@tonic-gate 8207c478bd9Sstevel@tonic-gate clean up secrets, close db 8217c478bd9Sstevel@tonic-gate 8227c478bd9Sstevel@tonic-gate shut down network 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate exit 8257c478bd9Sstevel@tonic-gate */ 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate int main(argc, argv) 8287c478bd9Sstevel@tonic-gate int argc; 8297c478bd9Sstevel@tonic-gate char *argv[]; 8307c478bd9Sstevel@tonic-gate { 8317c478bd9Sstevel@tonic-gate krb5_error_code retval; 8327c478bd9Sstevel@tonic-gate krb5_context kcontext; 8337c478bd9Sstevel@tonic-gate int *port_list; 8347c478bd9Sstevel@tonic-gate int errout = 0; 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 8397c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "KRB5KDC_TEST" /* Use this only if it weren't */ 8407c478bd9Sstevel@tonic-gate #endif 8417c478bd9Sstevel@tonic-gate 8427c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 8437c478bd9Sstevel@tonic-gate 8447c478bd9Sstevel@tonic-gate if (strrchr(argv[0], '/')) 8457c478bd9Sstevel@tonic-gate argv[0] = strrchr(argv[0], '/')+1; 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) * 8487c478bd9Sstevel@tonic-gate KRB5_KDC_MAX_REALMS))) { 8497c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: cannot get memory for realm list\n"), argv[0]); 8507c478bd9Sstevel@tonic-gate exit(1); 8517c478bd9Sstevel@tonic-gate } 8527c478bd9Sstevel@tonic-gate memset((char *) kdc_realmlist, 0, 8537c478bd9Sstevel@tonic-gate (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS)); 8547c478bd9Sstevel@tonic-gate port_list = NULL; 8557c478bd9Sstevel@tonic-gate 8567c478bd9Sstevel@tonic-gate /* 8577c478bd9Sstevel@tonic-gate * A note about Kerberos contexts: This context, "kcontext", is used 8587c478bd9Sstevel@tonic-gate * for the KDC operations, i.e. setup, network connection and error 8597c478bd9Sstevel@tonic-gate * reporting. The per-realm operations use the "realm_context" 8607c478bd9Sstevel@tonic-gate * associated with each realm. 8617c478bd9Sstevel@tonic-gate */ 8627c478bd9Sstevel@tonic-gate retval = krb5_init_context(&kcontext); 8637c478bd9Sstevel@tonic-gate if (retval) { 8647c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing krb5")); 8657c478bd9Sstevel@tonic-gate exit(1); 8667c478bd9Sstevel@tonic-gate } 8677c478bd9Sstevel@tonic-gate krb5_klog_init(kcontext, "kdc", argv[0], 1); 8687c478bd9Sstevel@tonic-gate /* initialize_kdc5_error_table(); SUNWresync121 XXX */ 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate /* 8717c478bd9Sstevel@tonic-gate * Scan through the argument list 8727c478bd9Sstevel@tonic-gate */ 8737c478bd9Sstevel@tonic-gate initialize_realms(kcontext, argc, argv); 8747c478bd9Sstevel@tonic-gate 8757c478bd9Sstevel@tonic-gate setup_signal_handlers(); 8767c478bd9Sstevel@tonic-gate 8777c478bd9Sstevel@tonic-gate if (retval = setup_sam()) { 8787c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing SAM")); 8797c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 8807c478bd9Sstevel@tonic-gate return 1; 8817c478bd9Sstevel@tonic-gate } 8827c478bd9Sstevel@tonic-gate 8837c478bd9Sstevel@tonic-gate if ((retval = setup_network(argv[0]))) { 8847c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing network")); 8857c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 8867c478bd9Sstevel@tonic-gate return 1; 8877c478bd9Sstevel@tonic-gate } 8887c478bd9Sstevel@tonic-gate if (!nofork && daemon(0, 0)) { 8897c478bd9Sstevel@tonic-gate com_err(argv[0], errno, gettext("while detaching from tty")); 8907c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 8917c478bd9Sstevel@tonic-gate return 1; 8927c478bd9Sstevel@tonic-gate } 8937c478bd9Sstevel@tonic-gate if (retval = krb5_klog_syslog(LOG_INFO, "commencing operation")) { 8947c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while logging message")); 8957c478bd9Sstevel@tonic-gate errout++; 8967c478bd9Sstevel@tonic-gate }; 8977c478bd9Sstevel@tonic-gate 8987c478bd9Sstevel@tonic-gate if ((retval = listen_and_process(argv[0]))) { 8997c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while processing network requests")); 9007c478bd9Sstevel@tonic-gate errout++; 9017c478bd9Sstevel@tonic-gate } 9027c478bd9Sstevel@tonic-gate if ((retval = closedown_network(argv[0]))) { 9037c478bd9Sstevel@tonic-gate com_err(argv[0], retval, gettext("while shutting down network")); 9047c478bd9Sstevel@tonic-gate errout++; 9057c478bd9Sstevel@tonic-gate } 9067c478bd9Sstevel@tonic-gate krb5_klog_syslog(LOG_INFO, "shutting down"); 9077c478bd9Sstevel@tonic-gate krb5_klog_close(kdc_context); 9087c478bd9Sstevel@tonic-gate finish_realms(argv[0]); 9097c478bd9Sstevel@tonic-gate krb5_free_context(kcontext); 9107c478bd9Sstevel@tonic-gate return errout; 9117c478bd9Sstevel@tonic-gate } 912