10Sstevel@tonic-gate /* 2*781Sgtb * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 30Sstevel@tonic-gate * Use is subject to license terms. 40Sstevel@tonic-gate */ 50Sstevel@tonic-gate 60Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 70Sstevel@tonic-gate 80Sstevel@tonic-gate /* 90Sstevel@tonic-gate * kdc/main.c 100Sstevel@tonic-gate * 110Sstevel@tonic-gate * Copyright 1990,2001 by the Massachusetts Institute of Technology. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * Export of this software from the United States of America may 140Sstevel@tonic-gate * require a specific license from the United States Government. 150Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 160Sstevel@tonic-gate * export to obtain such a license before exporting. 170Sstevel@tonic-gate * 180Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 190Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 200Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 210Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 220Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 230Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 240Sstevel@tonic-gate * to distribution of the software without specific, written prior 250Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 260Sstevel@tonic-gate * your software as modified software and not distribute it in such a 270Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 280Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 290Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 300Sstevel@tonic-gate * or implied warranty. 310Sstevel@tonic-gate * 320Sstevel@tonic-gate * 330Sstevel@tonic-gate * Main procedure body for the KDC server process. 340Sstevel@tonic-gate */ 350Sstevel@tonic-gate 360Sstevel@tonic-gate #include <stdio.h> 370Sstevel@tonic-gate #include <syslog.h> 380Sstevel@tonic-gate #include <signal.h> 390Sstevel@tonic-gate #include <errno.h> 400Sstevel@tonic-gate #include <netdb.h> 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include "k5-int.h" 430Sstevel@tonic-gate #include "com_err.h" 440Sstevel@tonic-gate #include "adm.h" 450Sstevel@tonic-gate #include "adm_proto.h" 460Sstevel@tonic-gate #include "kdc_util.h" 470Sstevel@tonic-gate #include "extern.h" 480Sstevel@tonic-gate #include "kdc5_err.h" 490Sstevel@tonic-gate #include <libintl.h> 500Sstevel@tonic-gate #include <locale.h> 510Sstevel@tonic-gate 520Sstevel@tonic-gate #ifdef HAVE_NETINET_IN_H 530Sstevel@tonic-gate #include <netinet/in.h> 540Sstevel@tonic-gate #endif 550Sstevel@tonic-gate 56*781Sgtb kdc_realm_t *find_realm_data (char *, krb5_ui_4); 570Sstevel@tonic-gate 58*781Sgtb void usage (char *); 590Sstevel@tonic-gate 60*781Sgtb krb5_sigtype request_exit (int); 61*781Sgtb krb5_sigtype request_hup (int); 620Sstevel@tonic-gate 63*781Sgtb void setup_signal_handlers (void); 640Sstevel@tonic-gate 65*781Sgtb krb5_error_code setup_sam (void); 660Sstevel@tonic-gate 67*781Sgtb void initialize_realms (krb5_context, int, char **); 680Sstevel@tonic-gate 69*781Sgtb void finish_realms (char *); 700Sstevel@tonic-gate 710Sstevel@tonic-gate static int nofork = 0; 720Sstevel@tonic-gate static int rkey_init_done = 0; 730Sstevel@tonic-gate 740Sstevel@tonic-gate /* Solaris Kerberos: global here that other functions access */ 750Sstevel@tonic-gate int max_tcp_data_connections; 760Sstevel@tonic-gate 770Sstevel@tonic-gate #ifdef POSIX_SIGNALS 780Sstevel@tonic-gate static struct sigaction s_action; 790Sstevel@tonic-gate #endif /* POSIX_SIGNALS */ 800Sstevel@tonic-gate 810Sstevel@tonic-gate #define KRB5_KDC_MAX_REALMS 32 820Sstevel@tonic-gate 830Sstevel@tonic-gate /* 840Sstevel@tonic-gate * Find the realm entry for a given realm. 850Sstevel@tonic-gate */ 860Sstevel@tonic-gate kdc_realm_t * 870Sstevel@tonic-gate find_realm_data(rname, rsize) 880Sstevel@tonic-gate char *rname; 890Sstevel@tonic-gate krb5_ui_4 rsize; 900Sstevel@tonic-gate { 910Sstevel@tonic-gate int i; 920Sstevel@tonic-gate for (i=0; i<kdc_numrealms; i++) { 930Sstevel@tonic-gate if ((rsize == strlen(kdc_realmlist[i]->realm_name)) && 940Sstevel@tonic-gate !strncmp(rname, kdc_realmlist[i]->realm_name, rsize)) 950Sstevel@tonic-gate return(kdc_realmlist[i]); 960Sstevel@tonic-gate } 970Sstevel@tonic-gate return((kdc_realm_t *) NULL); 980Sstevel@tonic-gate } 990Sstevel@tonic-gate 1000Sstevel@tonic-gate krb5_error_code 1010Sstevel@tonic-gate setup_server_realm(sprinc) 1020Sstevel@tonic-gate krb5_principal sprinc; 1030Sstevel@tonic-gate { 1040Sstevel@tonic-gate krb5_error_code kret; 1050Sstevel@tonic-gate kdc_realm_t *newrealm; 1060Sstevel@tonic-gate 1070Sstevel@tonic-gate kret = 0; 1080Sstevel@tonic-gate if (kdc_numrealms > 1) { 1090Sstevel@tonic-gate if (!(newrealm = find_realm_data(sprinc->realm.data, 1100Sstevel@tonic-gate (krb5_ui_4) sprinc->realm.length))) 1110Sstevel@tonic-gate kret = ENOENT; 1120Sstevel@tonic-gate else 1130Sstevel@tonic-gate kdc_active_realm = newrealm; 1140Sstevel@tonic-gate } 1150Sstevel@tonic-gate else 1160Sstevel@tonic-gate kdc_active_realm = kdc_realmlist[0]; 1170Sstevel@tonic-gate return(kret); 1180Sstevel@tonic-gate } 1190Sstevel@tonic-gate 1200Sstevel@tonic-gate static void 1210Sstevel@tonic-gate finish_realm(rdp) 1220Sstevel@tonic-gate kdc_realm_t *rdp; 1230Sstevel@tonic-gate { 1240Sstevel@tonic-gate if (rdp->realm_dbname) 1250Sstevel@tonic-gate free(rdp->realm_dbname); 1260Sstevel@tonic-gate if (rdp->realm_mpname) 1270Sstevel@tonic-gate free(rdp->realm_mpname); 1280Sstevel@tonic-gate if (rdp->realm_stash) 1290Sstevel@tonic-gate free(rdp->realm_stash); 1300Sstevel@tonic-gate if (rdp->realm_ports) 1310Sstevel@tonic-gate free(rdp->realm_ports); 1320Sstevel@tonic-gate if (rdp->realm_tcp_ports) 1330Sstevel@tonic-gate free(rdp->realm_tcp_ports); 1340Sstevel@tonic-gate if (rdp->realm_kstypes) 1350Sstevel@tonic-gate free(rdp->realm_kstypes); 1360Sstevel@tonic-gate if (rdp->realm_keytab) 1370Sstevel@tonic-gate krb5_kt_close(rdp->realm_context, rdp->realm_keytab); 1380Sstevel@tonic-gate if (rdp->realm_context) { 1390Sstevel@tonic-gate if (rdp->realm_mprinc) 1400Sstevel@tonic-gate krb5_free_principal(rdp->realm_context, rdp->realm_mprinc); 1410Sstevel@tonic-gate if (rdp->realm_mkey.length && rdp->realm_mkey.contents) { 1420Sstevel@tonic-gate memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length); 1430Sstevel@tonic-gate free(rdp->realm_mkey.contents); 1440Sstevel@tonic-gate } 1450Sstevel@tonic-gate if (rdp->realm_tgskey.length && rdp->realm_tgskey.contents) { 1460Sstevel@tonic-gate memset(rdp->realm_tgskey.contents, 0, rdp->realm_tgskey.length); 1470Sstevel@tonic-gate free(rdp->realm_tgskey.contents); 1480Sstevel@tonic-gate } 1490Sstevel@tonic-gate krb5_db_fini(rdp->realm_context); 1500Sstevel@tonic-gate if (rdp->realm_tgsprinc) 1510Sstevel@tonic-gate krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc); 1520Sstevel@tonic-gate krb5_free_context(rdp->realm_context); 1530Sstevel@tonic-gate } 1540Sstevel@tonic-gate free(rdp); 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate /* 1580Sstevel@tonic-gate * Initialize a realm control structure from the alternate profile or from 1590Sstevel@tonic-gate * the specified defaults. 1600Sstevel@tonic-gate * 1610Sstevel@tonic-gate * After we're complete here, the essence of the realm is embodied in the 1620Sstevel@tonic-gate * realm data and we should be all set to begin operation for that realm. 1630Sstevel@tonic-gate */ 1640Sstevel@tonic-gate static krb5_error_code 1650Sstevel@tonic-gate init_realm(progname, rdp, realm, def_dbname, def_mpname, 1660Sstevel@tonic-gate def_enctype, def_udp_ports, def_tcp_ports, def_manual) 1670Sstevel@tonic-gate char *progname; 1680Sstevel@tonic-gate kdc_realm_t *rdp; 1690Sstevel@tonic-gate char *realm; 1700Sstevel@tonic-gate char *def_dbname; 1710Sstevel@tonic-gate char *def_mpname; 1720Sstevel@tonic-gate krb5_enctype def_enctype; 1730Sstevel@tonic-gate char *def_udp_ports; 1740Sstevel@tonic-gate char *def_tcp_ports; 1750Sstevel@tonic-gate krb5_boolean def_manual; 1760Sstevel@tonic-gate { 1770Sstevel@tonic-gate krb5_error_code kret; 1780Sstevel@tonic-gate krb5_boolean manual; 1790Sstevel@tonic-gate krb5_db_entry db_entry; 1800Sstevel@tonic-gate int num2get; 1810Sstevel@tonic-gate krb5_boolean more; 1820Sstevel@tonic-gate krb5_boolean db_inited; 1830Sstevel@tonic-gate krb5_realm_params *rparams; 1840Sstevel@tonic-gate krb5_key_data *kdata; 1850Sstevel@tonic-gate krb5_key_salt_tuple *kslist; 1860Sstevel@tonic-gate krb5_int32 nkslist; 1870Sstevel@tonic-gate int i; 1880Sstevel@tonic-gate krb5_deltat now, krb5_kdb_max_time; 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate db_inited = 0; 1910Sstevel@tonic-gate memset((char *) rdp, 0, sizeof(kdc_realm_t)); 1920Sstevel@tonic-gate if (!realm) { 1930Sstevel@tonic-gate kret = EINVAL; 1940Sstevel@tonic-gate goto whoops; 1950Sstevel@tonic-gate } 1960Sstevel@tonic-gate 1970Sstevel@tonic-gate rdp->realm_name = realm; 1980Sstevel@tonic-gate kret = krb5_init_context(&rdp->realm_context); 1990Sstevel@tonic-gate if (kret) { 2000Sstevel@tonic-gate com_err(progname, kret, gettext("while getting context for realm %s"), 2010Sstevel@tonic-gate realm); 2020Sstevel@tonic-gate goto whoops; 2030Sstevel@tonic-gate } 2040Sstevel@tonic-gate 2050Sstevel@tonic-gate kret = krb5_read_realm_params(rdp->realm_context, rdp->realm_name, 2060Sstevel@tonic-gate (char *) NULL, (char *) NULL, &rparams); 2070Sstevel@tonic-gate if (kret) { 2080Sstevel@tonic-gate com_err(progname, kret, gettext("while reading realm parameters")); 2090Sstevel@tonic-gate goto whoops; 2100Sstevel@tonic-gate } 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate /* Handle profile file name */ 2130Sstevel@tonic-gate if (rparams && rparams->realm_profile) 2140Sstevel@tonic-gate rdp->realm_profile = strdup(rparams->realm_profile); 2150Sstevel@tonic-gate 2160Sstevel@tonic-gate /* Handle database name */ 2170Sstevel@tonic-gate if (rparams && rparams->realm_dbname) 2180Sstevel@tonic-gate rdp->realm_dbname = strdup(rparams->realm_dbname); 2190Sstevel@tonic-gate else 2200Sstevel@tonic-gate rdp->realm_dbname = (def_dbname) ? strdup(def_dbname) : 2210Sstevel@tonic-gate strdup(DEFAULT_KDB_FILE); 2220Sstevel@tonic-gate 2230Sstevel@tonic-gate /* Handle master key name */ 2240Sstevel@tonic-gate if (rparams && rparams->realm_mkey_name) 2250Sstevel@tonic-gate rdp->realm_mpname = strdup(rparams->realm_mkey_name); 2260Sstevel@tonic-gate else 2270Sstevel@tonic-gate rdp->realm_mpname = (def_mpname) ? strdup(def_mpname) : 2280Sstevel@tonic-gate strdup(KRB5_KDB_M_NAME); 2290Sstevel@tonic-gate 2300Sstevel@tonic-gate /* Handle KDC ports */ 2310Sstevel@tonic-gate if (rparams && rparams->realm_kdc_ports) 2320Sstevel@tonic-gate rdp->realm_ports = strdup(rparams->realm_kdc_ports); 2330Sstevel@tonic-gate else 2340Sstevel@tonic-gate rdp->realm_ports = strdup(def_udp_ports); 2350Sstevel@tonic-gate if (rparams && rparams->realm_kdc_tcp_ports) 2360Sstevel@tonic-gate rdp->realm_tcp_ports = strdup(rparams->realm_kdc_tcp_ports); 2370Sstevel@tonic-gate else 2380Sstevel@tonic-gate rdp->realm_tcp_ports = strdup(def_tcp_ports); 2390Sstevel@tonic-gate 2400Sstevel@tonic-gate /* Handle stash file */ 2410Sstevel@tonic-gate if (rparams && rparams->realm_stash_file) { 2420Sstevel@tonic-gate rdp->realm_stash = strdup(rparams->realm_stash_file); 2430Sstevel@tonic-gate manual = FALSE; 2440Sstevel@tonic-gate } else 2450Sstevel@tonic-gate manual = def_manual; 2460Sstevel@tonic-gate 2470Sstevel@tonic-gate /* Handle master key type */ 2480Sstevel@tonic-gate if (rparams && rparams->realm_enctype_valid) 2490Sstevel@tonic-gate rdp->realm_mkey.enctype = (krb5_enctype) rparams->realm_enctype; 2500Sstevel@tonic-gate else 2510Sstevel@tonic-gate rdp->realm_mkey.enctype = manual ? def_enctype : ENCTYPE_UNKNOWN; 2520Sstevel@tonic-gate if ((kret = krb5_timeofday(rdp->realm_context, &now))) { 2530Sstevel@tonic-gate com_err(progname, kret, gettext("while getting timeofday")); 2540Sstevel@tonic-gate goto whoops; 2550Sstevel@tonic-gate } 2560Sstevel@tonic-gate 2570Sstevel@tonic-gate /* Handle ticket maximum life */ 2580Sstevel@tonic-gate if (rparams && rparams->realm_max_life_valid) 2590Sstevel@tonic-gate rdp->realm_maxlife = rparams->realm_max_life; 2600Sstevel@tonic-gate else 2610Sstevel@tonic-gate rdp->realm_maxlife = KRB5_KDB_EXPIRATION - now - 3600; 2620Sstevel@tonic-gate 2630Sstevel@tonic-gate /* Handle ticket renewable maximum life */ 2640Sstevel@tonic-gate if (rparams && rparams->realm_max_rlife_valid) 2650Sstevel@tonic-gate rdp->realm_maxrlife = rparams->realm_max_rlife; 2660Sstevel@tonic-gate else 2670Sstevel@tonic-gate rdp->realm_maxrlife = KRB5_KDB_EXPIRATION - now - 3600; 2680Sstevel@tonic-gate 2690Sstevel@tonic-gate /* Handle key/salt list */ 2700Sstevel@tonic-gate if (rparams && rparams->realm_num_keysalts) { 2710Sstevel@tonic-gate rdp->realm_kstypes = rparams->realm_keysalts; 2720Sstevel@tonic-gate rdp->realm_nkstypes = rparams->realm_num_keysalts; 2730Sstevel@tonic-gate rparams->realm_keysalts = NULL; 2740Sstevel@tonic-gate rparams->realm_num_keysalts = 0; 2750Sstevel@tonic-gate kslist = (krb5_key_salt_tuple *) rdp->realm_kstypes; 2760Sstevel@tonic-gate nkslist = rdp->realm_nkstypes; 2770Sstevel@tonic-gate } else { 2780Sstevel@tonic-gate /* 2790Sstevel@tonic-gate * XXX Initialize default key/salt list. 2800Sstevel@tonic-gate */ 2810Sstevel@tonic-gate if ((kslist = (krb5_key_salt_tuple *) 2820Sstevel@tonic-gate malloc(sizeof(krb5_key_salt_tuple)))) { 2830Sstevel@tonic-gate kslist->ks_enctype = ENCTYPE_DES_CBC_CRC; 2840Sstevel@tonic-gate kslist->ks_salttype = KRB5_KDB_SALTTYPE_NORMAL; 2850Sstevel@tonic-gate rdp->realm_kstypes = kslist; 2860Sstevel@tonic-gate rdp->realm_nkstypes = 1; 2870Sstevel@tonic-gate nkslist = 1; 2880Sstevel@tonic-gate } 2890Sstevel@tonic-gate else { 2900Sstevel@tonic-gate com_err(progname, ENOMEM, 2910Sstevel@tonic-gate gettext("while setting up key/salt list for realm %s"), 2920Sstevel@tonic-gate realm); 2930Sstevel@tonic-gate exit(1); 2940Sstevel@tonic-gate } 2950Sstevel@tonic-gate } 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate if (rparams) 2980Sstevel@tonic-gate krb5_free_realm_params(rdp->realm_context, rparams); 2990Sstevel@tonic-gate 3000Sstevel@tonic-gate /* 3010Sstevel@tonic-gate * We've got our parameters, now go and setup our realm context. 3020Sstevel@tonic-gate */ 3030Sstevel@tonic-gate 3040Sstevel@tonic-gate /* Set the default realm of this context */ 3050Sstevel@tonic-gate if ((kret = krb5_set_default_realm(rdp->realm_context, realm))) { 3060Sstevel@tonic-gate com_err(progname, kret, gettext("while setting default realm to %s"), 3070Sstevel@tonic-gate realm); 3080Sstevel@tonic-gate goto whoops; 3090Sstevel@tonic-gate } 3100Sstevel@tonic-gate 3110Sstevel@tonic-gate /* Assemble and parse the master key name */ 3120Sstevel@tonic-gate if ((kret = krb5_db_setup_mkey_name(rdp->realm_context, rdp->realm_mpname, 3130Sstevel@tonic-gate rdp->realm_name, (char **) NULL, 3140Sstevel@tonic-gate &rdp->realm_mprinc))) { 3150Sstevel@tonic-gate com_err(progname, kret, 3160Sstevel@tonic-gate gettext("while setting up master key name %s for realm %s"), 3170Sstevel@tonic-gate rdp->realm_mpname, realm); 3180Sstevel@tonic-gate goto whoops; 3190Sstevel@tonic-gate } 3200Sstevel@tonic-gate 3210Sstevel@tonic-gate /* 3220Sstevel@tonic-gate * Get the master key. 3230Sstevel@tonic-gate */ 3240Sstevel@tonic-gate if ((kret = krb5_db_fetch_mkey(rdp->realm_context, rdp->realm_mprinc, 3250Sstevel@tonic-gate rdp->realm_mkey.enctype, manual, 3260Sstevel@tonic-gate FALSE, rdp->realm_stash, 3270Sstevel@tonic-gate 0, &rdp->realm_mkey))) { 3280Sstevel@tonic-gate com_err(progname, kret, 3290Sstevel@tonic-gate gettext("while fetching master key %s for realm %s"), 3300Sstevel@tonic-gate rdp->realm_mpname, realm); 3310Sstevel@tonic-gate goto whoops; 3320Sstevel@tonic-gate } 3330Sstevel@tonic-gate 3340Sstevel@tonic-gate /* Set and open the database. */ 3350Sstevel@tonic-gate if (rdp->realm_dbname && 3360Sstevel@tonic-gate (kret = krb5_db_set_name(rdp->realm_context, rdp->realm_dbname))) { 3370Sstevel@tonic-gate com_err(progname, kret, 3380Sstevel@tonic-gate gettext("while setting database name to %s for realm %s"), 3390Sstevel@tonic-gate rdp->realm_dbname, realm); 3400Sstevel@tonic-gate goto whoops; 3410Sstevel@tonic-gate } 3420Sstevel@tonic-gate if ((kret = krb5_db_init(rdp->realm_context))) { 3430Sstevel@tonic-gate com_err(progname, kret, 3440Sstevel@tonic-gate gettext("while initializing database "), 3450Sstevel@tonic-gate gettext("for realm %s"), realm); 3460Sstevel@tonic-gate goto whoops; 3470Sstevel@tonic-gate } else 3480Sstevel@tonic-gate db_inited = 1; 3490Sstevel@tonic-gate 3500Sstevel@tonic-gate /* Verify the master key */ 3510Sstevel@tonic-gate if ((kret = krb5_db_verify_master_key(rdp->realm_context, 3520Sstevel@tonic-gate rdp->realm_mprinc, 3530Sstevel@tonic-gate &rdp->realm_mkey))) { 3540Sstevel@tonic-gate com_err(progname, kret, 3550Sstevel@tonic-gate gettext("while verifying master key for realm %s"), 3560Sstevel@tonic-gate realm); 3570Sstevel@tonic-gate goto whoops; 3580Sstevel@tonic-gate } 3590Sstevel@tonic-gate 3600Sstevel@tonic-gate /* Fetch the master key and get its version number */ 3610Sstevel@tonic-gate num2get = 1; 3620Sstevel@tonic-gate kret = krb5_db_get_principal(rdp->realm_context, rdp->realm_mprinc, 3630Sstevel@tonic-gate &db_entry, &num2get, &more); 3640Sstevel@tonic-gate if (!kret) { 3650Sstevel@tonic-gate if (num2get != 1) 3660Sstevel@tonic-gate kret = KRB5_KDB_NOMASTERKEY; 3670Sstevel@tonic-gate else { 3680Sstevel@tonic-gate if (more) { 3690Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 3700Sstevel@tonic-gate &db_entry, 3710Sstevel@tonic-gate num2get); 3720Sstevel@tonic-gate kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE; 3730Sstevel@tonic-gate } 3740Sstevel@tonic-gate } 3750Sstevel@tonic-gate } 3760Sstevel@tonic-gate if (kret) { 3770Sstevel@tonic-gate com_err(progname, kret, 3780Sstevel@tonic-gate gettext("while fetching master entry for realm %s"), 3790Sstevel@tonic-gate realm); 3800Sstevel@tonic-gate goto whoops; 3810Sstevel@tonic-gate } 3820Sstevel@tonic-gate 3830Sstevel@tonic-gate /* 3840Sstevel@tonic-gate * Get the most recent master key. Search the key list in 3850Sstevel@tonic-gate * the order specified by the key/salt list. 3860Sstevel@tonic-gate */ 3870Sstevel@tonic-gate kdata = (krb5_key_data *) NULL; 3880Sstevel@tonic-gate for (i=0; i<nkslist; i++) { 3890Sstevel@tonic-gate if (!(kret = krb5_dbe_find_enctype(rdp->realm_context, 3900Sstevel@tonic-gate &db_entry, 3910Sstevel@tonic-gate kslist[i].ks_enctype, 3920Sstevel@tonic-gate -1, 3930Sstevel@tonic-gate -1, 3940Sstevel@tonic-gate &kdata))) 3950Sstevel@tonic-gate break; 3960Sstevel@tonic-gate } 3970Sstevel@tonic-gate if (!kdata) { 3980Sstevel@tonic-gate com_err(progname, kret, 3990Sstevel@tonic-gate gettext("while finding master key for realm %s"), 4000Sstevel@tonic-gate realm); 4010Sstevel@tonic-gate goto whoops; 4020Sstevel@tonic-gate } 4030Sstevel@tonic-gate rdp->realm_mkvno = kdata->key_data_kvno; 4040Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, &db_entry, num2get); 4050Sstevel@tonic-gate 4060Sstevel@tonic-gate if ((kret = krb5_db_set_mkey(rdp->realm_context, &rdp->realm_mkey))) { 4070Sstevel@tonic-gate com_err(progname, kret, 4080Sstevel@tonic-gate gettext("while processing master key for realm %s"), 4090Sstevel@tonic-gate realm); 4100Sstevel@tonic-gate goto whoops; 4110Sstevel@tonic-gate } 4120Sstevel@tonic-gate 4130Sstevel@tonic-gate /* Set up the keytab */ 4140Sstevel@tonic-gate if ((kret = krb5_ktkdb_resolve(rdp->realm_context, 4150Sstevel@tonic-gate NULL, 4160Sstevel@tonic-gate &rdp->realm_keytab))) { 4170Sstevel@tonic-gate com_err(progname, kret, 4180Sstevel@tonic-gate gettext("while resolving kdb keytab for realm %s"), 4190Sstevel@tonic-gate realm); 4200Sstevel@tonic-gate goto whoops; 4210Sstevel@tonic-gate } 4220Sstevel@tonic-gate 4230Sstevel@tonic-gate /* Preformat the TGS name */ 4240Sstevel@tonic-gate if ((kret = krb5_build_principal(rdp->realm_context, &rdp->realm_tgsprinc, 4250Sstevel@tonic-gate strlen(realm), realm, KRB5_TGS_NAME, 4260Sstevel@tonic-gate realm, (char *) NULL))) { 4270Sstevel@tonic-gate com_err(progname, kret, 4280Sstevel@tonic-gate gettext("while building TGS name for realm %s"), 4290Sstevel@tonic-gate realm); 4300Sstevel@tonic-gate goto whoops; 4310Sstevel@tonic-gate } 4320Sstevel@tonic-gate 4330Sstevel@tonic-gate /* Get the TGS database entry */ 4340Sstevel@tonic-gate num2get = 1; 4350Sstevel@tonic-gate if (!(kret = krb5_db_get_principal(rdp->realm_context, 4360Sstevel@tonic-gate rdp->realm_tgsprinc, 4370Sstevel@tonic-gate &db_entry, 4380Sstevel@tonic-gate &num2get, 4390Sstevel@tonic-gate &more))) { 4400Sstevel@tonic-gate if (num2get != 1) 4410Sstevel@tonic-gate kret = KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN; 4420Sstevel@tonic-gate else { 4430Sstevel@tonic-gate if (more) { 4440Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 4450Sstevel@tonic-gate &db_entry, 4460Sstevel@tonic-gate num2get); 4470Sstevel@tonic-gate kret = KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE; 4480Sstevel@tonic-gate } 4490Sstevel@tonic-gate } 4500Sstevel@tonic-gate } 4510Sstevel@tonic-gate if (kret) { 4520Sstevel@tonic-gate com_err(progname, kret, 4530Sstevel@tonic-gate gettext("while fetching TGS entry for realm %s"), 4540Sstevel@tonic-gate realm); 4550Sstevel@tonic-gate goto whoops; 4560Sstevel@tonic-gate } 4570Sstevel@tonic-gate /* 4580Sstevel@tonic-gate * Get the most recent TGS key. Search the key list in 4590Sstevel@tonic-gate * the order specified by the key/salt list. 4600Sstevel@tonic-gate */ 4610Sstevel@tonic-gate kdata = (krb5_key_data *) NULL; 4620Sstevel@tonic-gate for (i=0; i<nkslist; i++) { 4630Sstevel@tonic-gate if (!(kret = krb5_dbe_find_enctype(rdp->realm_context, 4640Sstevel@tonic-gate &db_entry, 4650Sstevel@tonic-gate kslist[i].ks_enctype, 4660Sstevel@tonic-gate -1, 4670Sstevel@tonic-gate -1, 4680Sstevel@tonic-gate &kdata))) 4690Sstevel@tonic-gate break; 4700Sstevel@tonic-gate } 4710Sstevel@tonic-gate if (!kdata) { 4720Sstevel@tonic-gate com_err(progname, kret, 4730Sstevel@tonic-gate gettext("while finding TGS key for realm %s"), 4740Sstevel@tonic-gate realm); 4750Sstevel@tonic-gate goto whoops; 4760Sstevel@tonic-gate } 4770Sstevel@tonic-gate if (!(kret = krb5_dbekd_decrypt_key_data(rdp->realm_context, 4780Sstevel@tonic-gate &rdp->realm_mkey, 4790Sstevel@tonic-gate kdata, 4800Sstevel@tonic-gate &rdp->realm_tgskey, NULL))){ 4810Sstevel@tonic-gate rdp->realm_tgskvno = kdata->key_data_kvno; 4820Sstevel@tonic-gate } 4830Sstevel@tonic-gate krb5_db_free_principal(rdp->realm_context, 4840Sstevel@tonic-gate &db_entry, 4850Sstevel@tonic-gate num2get); 4860Sstevel@tonic-gate if (kret) { 4870Sstevel@tonic-gate com_err(progname, kret, 4880Sstevel@tonic-gate gettext("while decrypting TGS key for realm %s"), 4890Sstevel@tonic-gate realm); 4900Sstevel@tonic-gate goto whoops; 4910Sstevel@tonic-gate } 4920Sstevel@tonic-gate 4930Sstevel@tonic-gate if (!rkey_init_done) { 4940Sstevel@tonic-gate krb5_timestamp now; 4950Sstevel@tonic-gate krb5_data seed; 4960Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 4970Sstevel@tonic-gate krb5_keyblock temp_key; 4980Sstevel@tonic-gate #endif 4990Sstevel@tonic-gate /* 5000Sstevel@tonic-gate * If all that worked, then initialize the random key 5010Sstevel@tonic-gate * generators. 5020Sstevel@tonic-gate */ 5030Sstevel@tonic-gate 5040Sstevel@tonic-gate if ((kret = krb5_timeofday(rdp->realm_context, &now))) 5050Sstevel@tonic-gate goto whoops; 5060Sstevel@tonic-gate seed.length = sizeof(now); 5070Sstevel@tonic-gate seed.data = (char *) &now; 5080Sstevel@tonic-gate if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) 5090Sstevel@tonic-gate goto whoops; 5100Sstevel@tonic-gate 5110Sstevel@tonic-gate seed.length = rdp->realm_mkey.length; 5120Sstevel@tonic-gate seed.data = (char *)rdp->realm_mkey.contents; 5130Sstevel@tonic-gate 5140Sstevel@tonic-gate if ((kret = krb5_c_random_seed(rdp->realm_context, &seed))) 5150Sstevel@tonic-gate goto whoops; 5160Sstevel@tonic-gate 5170Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 5180Sstevel@tonic-gate if ((kret = krb5_c_make_random_key(rdp->realm_context, 5190Sstevel@tonic-gate ENCTYPE_DES_CBC_CRC, &temp_key))) { 5200Sstevel@tonic-gate com_err(progname, kret, 5210Sstevel@tonic-gate "while initializing V4 random key generator"); 5220Sstevel@tonic-gate goto whoops; 5230Sstevel@tonic-gate } 5240Sstevel@tonic-gate 5250Sstevel@tonic-gate (void) des_init_random_number_generator(temp_key.contents); 5260Sstevel@tonic-gate krb5_free_keyblock_contents(rdp->realm_context, &temp_key); 5270Sstevel@tonic-gate #endif 5280Sstevel@tonic-gate rkey_init_done = 1; 5290Sstevel@tonic-gate } 5300Sstevel@tonic-gate whoops: 5310Sstevel@tonic-gate /* 5320Sstevel@tonic-gate * If we choked, then clean up any dirt we may have dropped on the floor. 5330Sstevel@tonic-gate */ 5340Sstevel@tonic-gate if (kret) { 5350Sstevel@tonic-gate finish_realm(rdp); 5360Sstevel@tonic-gate } 5370Sstevel@tonic-gate return(kret); 5380Sstevel@tonic-gate } 5390Sstevel@tonic-gate 5400Sstevel@tonic-gate krb5_sigtype 5410Sstevel@tonic-gate request_exit(signo) 5420Sstevel@tonic-gate int signo; 5430Sstevel@tonic-gate { 5440Sstevel@tonic-gate signal_requests_exit = 1; 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate #ifdef POSIX_SIGTYPE 5470Sstevel@tonic-gate return; 5480Sstevel@tonic-gate #else 5490Sstevel@tonic-gate return(0); 5500Sstevel@tonic-gate #endif 5510Sstevel@tonic-gate } 5520Sstevel@tonic-gate 5530Sstevel@tonic-gate krb5_sigtype 5540Sstevel@tonic-gate request_hup(signo) 5550Sstevel@tonic-gate int signo; 5560Sstevel@tonic-gate { 5570Sstevel@tonic-gate signal_requests_hup = 1; 5580Sstevel@tonic-gate 5590Sstevel@tonic-gate #ifdef POSIX_SIGTYPE 5600Sstevel@tonic-gate return; 5610Sstevel@tonic-gate #else 5620Sstevel@tonic-gate return(0); 5630Sstevel@tonic-gate #endif 5640Sstevel@tonic-gate } 5650Sstevel@tonic-gate 5660Sstevel@tonic-gate void 5670Sstevel@tonic-gate setup_signal_handlers() 5680Sstevel@tonic-gate { 5690Sstevel@tonic-gate #ifdef POSIX_SIGNALS 5700Sstevel@tonic-gate (void) sigemptyset(&s_action.sa_mask); 5710Sstevel@tonic-gate s_action.sa_flags = 0; 5720Sstevel@tonic-gate s_action.sa_handler = request_exit; 5730Sstevel@tonic-gate (void) sigaction(SIGINT, &s_action, (struct sigaction *) NULL); 5740Sstevel@tonic-gate (void) sigaction(SIGTERM, &s_action, (struct sigaction *) NULL); 5750Sstevel@tonic-gate s_action.sa_handler = request_hup; 5760Sstevel@tonic-gate (void) sigaction(SIGHUP, &s_action, (struct sigaction *) NULL); 5770Sstevel@tonic-gate #else /* POSIX_SIGNALS */ 5780Sstevel@tonic-gate signal(SIGINT, request_exit); 5790Sstevel@tonic-gate signal(SIGTERM, request_exit); 5800Sstevel@tonic-gate signal(SIGHUP, request_hup); 5810Sstevel@tonic-gate #endif /* POSIX_SIGNALS */ 5820Sstevel@tonic-gate 5830Sstevel@tonic-gate return; 5840Sstevel@tonic-gate } 5850Sstevel@tonic-gate 5860Sstevel@tonic-gate krb5_error_code 5870Sstevel@tonic-gate setup_sam() 5880Sstevel@tonic-gate { 5890Sstevel@tonic-gate return krb5_c_make_random_key(kdc_context, ENCTYPE_DES_CBC_MD5, &psr_key); 5900Sstevel@tonic-gate } 5910Sstevel@tonic-gate 5920Sstevel@tonic-gate void 5930Sstevel@tonic-gate usage(name) 5940Sstevel@tonic-gate char *name; 5950Sstevel@tonic-gate { 5960Sstevel@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); 5970Sstevel@tonic-gate return; 5980Sstevel@tonic-gate } 5990Sstevel@tonic-gate 6000Sstevel@tonic-gate void 6010Sstevel@tonic-gate initialize_realms(kcontext, argc, argv) 6020Sstevel@tonic-gate krb5_context kcontext; 6030Sstevel@tonic-gate int argc; 6040Sstevel@tonic-gate char **argv; 6050Sstevel@tonic-gate { 6060Sstevel@tonic-gate int c; 6070Sstevel@tonic-gate char *db_name = (char *) NULL; 6080Sstevel@tonic-gate char *mkey_name = (char *) NULL; 6090Sstevel@tonic-gate char *rcname = KDCRCACHE; 6100Sstevel@tonic-gate char *lrealm; 6110Sstevel@tonic-gate krb5_error_code retval; 6120Sstevel@tonic-gate krb5_enctype menctype = ENCTYPE_UNKNOWN; 6130Sstevel@tonic-gate kdc_realm_t *rdatap; 6140Sstevel@tonic-gate krb5_boolean manual = FALSE; 6150Sstevel@tonic-gate char *default_udp_ports = 0; 6160Sstevel@tonic-gate char *default_tcp_ports = 0; 6170Sstevel@tonic-gate krb5_pointer aprof; 6180Sstevel@tonic-gate const char *hierarchy[3]; 6190Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 6200Sstevel@tonic-gate char *v4mode = 0; 6210Sstevel@tonic-gate #endif 6220Sstevel@tonic-gate extern char *optarg; 6230Sstevel@tonic-gate #ifdef ATHENA_DES3_KLUDGE 6240Sstevel@tonic-gate extern struct krb5_keytypes krb5_enctypes_list[]; 6250Sstevel@tonic-gate extern int krb5_enctypes_length; 6260Sstevel@tonic-gate #endif 6270Sstevel@tonic-gate 6280Sstevel@tonic-gate if (!krb5_aprof_init(DEFAULT_KDC_PROFILE, KDC_PROFILE_ENV, &aprof)) { 6290Sstevel@tonic-gate hierarchy[0] = "kdcdefaults"; 6300Sstevel@tonic-gate hierarchy[1] = "kdc_ports"; 6310Sstevel@tonic-gate hierarchy[2] = (char *) NULL; 6320Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_udp_ports)) 6330Sstevel@tonic-gate default_udp_ports = 0; 6340Sstevel@tonic-gate hierarchy[1] = "kdc_tcp_ports"; 6350Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &default_tcp_ports)) 6360Sstevel@tonic-gate default_tcp_ports = 0; 6370Sstevel@tonic-gate hierarchy[1] = "kdc_max_tcp_connections"; 6380Sstevel@tonic-gate if (krb5_aprof_get_int32(aprof, hierarchy, TRUE, 6390Sstevel@tonic-gate &max_tcp_data_connections)) { 6400Sstevel@tonic-gate max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS; 6410Sstevel@tonic-gate } else if (max_tcp_data_connections < MIN_KDC_TCP_CONNECTIONS) { 6420Sstevel@tonic-gate max_tcp_data_connections = DEFAULT_KDC_TCP_CONNECTIONS; 6430Sstevel@tonic-gate } 6440Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 6450Sstevel@tonic-gate hierarchy[1] = "v4_mode"; 6460Sstevel@tonic-gate if (krb5_aprof_get_string(aprof, hierarchy, TRUE, &v4mode)) 6470Sstevel@tonic-gate v4mode = 0; 6480Sstevel@tonic-gate #endif 6490Sstevel@tonic-gate /* aprof_init can return 0 with aprof == NULL */ 6500Sstevel@tonic-gate if (aprof) 6510Sstevel@tonic-gate krb5_aprof_finish(aprof); 6520Sstevel@tonic-gate } 6530Sstevel@tonic-gate if (default_udp_ports == 0) 6540Sstevel@tonic-gate default_udp_ports = strdup(DEFAULT_KDC_UDP_PORTLIST); 6550Sstevel@tonic-gate if (default_tcp_ports == 0) 6560Sstevel@tonic-gate default_tcp_ports = strdup(DEFAULT_KDC_TCP_PORTLIST); 6570Sstevel@tonic-gate /* 6580Sstevel@tonic-gate * Loop through the option list. Each time we encounter a realm name, 6590Sstevel@tonic-gate * use the previously scanned options to fill in for defaults. 6600Sstevel@tonic-gate */ 6610Sstevel@tonic-gate while ((c = getopt(argc, argv, "r:d:mM:k:R:e:p:s:n")) != -1) { /* SUNW */ 6620Sstevel@tonic-gate switch(c) { 6630Sstevel@tonic-gate case 'r': /* realm name for db */ 6640Sstevel@tonic-gate if (!find_realm_data(optarg, (krb5_ui_4) strlen(optarg))) { 6650Sstevel@tonic-gate if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) { 6660Sstevel@tonic-gate if ((retval = init_realm(argv[0], rdatap, optarg, db_name, 6670Sstevel@tonic-gate mkey_name, menctype, 6680Sstevel@tonic-gate default_udp_ports, 6690Sstevel@tonic-gate default_tcp_ports, manual))) { 6700Sstevel@tonic-gate fprintf(stderr,gettext("%s: cannot initialize realm %s\n"), 6710Sstevel@tonic-gate argv[0], optarg); 6720Sstevel@tonic-gate exit(1); 6730Sstevel@tonic-gate } 6740Sstevel@tonic-gate kdc_realmlist[kdc_numrealms] = rdatap; 6750Sstevel@tonic-gate kdc_numrealms++; 6760Sstevel@tonic-gate } 6770Sstevel@tonic-gate } 6780Sstevel@tonic-gate break; 6790Sstevel@tonic-gate case 'd': /* pathname for db */ 6800Sstevel@tonic-gate db_name = optarg; 6810Sstevel@tonic-gate break; 6820Sstevel@tonic-gate case 'm': /* manual type-in of master key */ 6830Sstevel@tonic-gate manual = TRUE; 6840Sstevel@tonic-gate if (menctype == ENCTYPE_UNKNOWN) 6850Sstevel@tonic-gate menctype = ENCTYPE_DES_CBC_CRC; 6860Sstevel@tonic-gate break; 6870Sstevel@tonic-gate case 'M': /* master key name in DB */ 6880Sstevel@tonic-gate mkey_name = optarg; 6890Sstevel@tonic-gate break; 6900Sstevel@tonic-gate case 'n': 6910Sstevel@tonic-gate nofork++; /* don't detach from terminal */ 6920Sstevel@tonic-gate break; 6930Sstevel@tonic-gate case 'k': /* enctype for master key */ 6940Sstevel@tonic-gate if (krb5_string_to_enctype(optarg, &menctype)) 6950Sstevel@tonic-gate com_err(argv[0], 0, 6960Sstevel@tonic-gate gettext("invalid enctype %s"), optarg); 6970Sstevel@tonic-gate break; 6980Sstevel@tonic-gate case 'R': 6990Sstevel@tonic-gate rcname = optarg; 7000Sstevel@tonic-gate break; 7010Sstevel@tonic-gate case 'p': 7020Sstevel@tonic-gate if (default_udp_ports) 7030Sstevel@tonic-gate free(default_udp_ports); 7040Sstevel@tonic-gate default_udp_ports = strdup(optarg); 7050Sstevel@tonic-gate 7060Sstevel@tonic-gate if (default_tcp_ports) 7070Sstevel@tonic-gate free(default_tcp_ports); 7080Sstevel@tonic-gate default_tcp_ports = strdup(optarg); 7090Sstevel@tonic-gate 7100Sstevel@tonic-gate break; 7110Sstevel@tonic-gate case '4': 7120Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 7130Sstevel@tonic-gate if (v4mode) 7140Sstevel@tonic-gate free(v4mode); 7150Sstevel@tonic-gate v4mode = strdup(optarg); 7160Sstevel@tonic-gate #endif 7170Sstevel@tonic-gate break; 7180Sstevel@tonic-gate case '3': 7190Sstevel@tonic-gate #ifdef ATHENA_DES3_KLUDGE 7200Sstevel@tonic-gate if (krb5_enctypes_list[krb5_enctypes_length-1].etype 7210Sstevel@tonic-gate != ENCTYPE_LOCAL_DES3_HMAC_SHA1) { 7220Sstevel@tonic-gate fprintf(stderr, 7230Sstevel@tonic-gate "internal inconsistency in enctypes_list" 7240Sstevel@tonic-gate " while disabling\n" 7250Sstevel@tonic-gate "des3-marc-hmac-sha1 enctype\n"); 7260Sstevel@tonic-gate exit(1); 7270Sstevel@tonic-gate } 7280Sstevel@tonic-gate krb5_enctypes_length--; 7290Sstevel@tonic-gate break; 7300Sstevel@tonic-gate #endif 7310Sstevel@tonic-gate case '?': 7320Sstevel@tonic-gate default: 7330Sstevel@tonic-gate usage(argv[0]); 7340Sstevel@tonic-gate exit(1); 7350Sstevel@tonic-gate } 7360Sstevel@tonic-gate } 7370Sstevel@tonic-gate 7380Sstevel@tonic-gate #ifdef KRB5_KRB4_COMPAT 7390Sstevel@tonic-gate /* 7400Sstevel@tonic-gate * Setup the v4 mode 7410Sstevel@tonic-gate */ 7420Sstevel@tonic-gate process_v4_mode(argv[0], v4mode); 7430Sstevel@tonic-gate #endif 7440Sstevel@tonic-gate 7450Sstevel@tonic-gate /* 7460Sstevel@tonic-gate * Check to see if we processed any realms. 7470Sstevel@tonic-gate */ 7480Sstevel@tonic-gate if (kdc_numrealms == 0) { 7490Sstevel@tonic-gate /* no realm specified, use default realm */ 7500Sstevel@tonic-gate if ((retval = krb5_get_default_realm(kcontext, &lrealm))) { 7510Sstevel@tonic-gate com_err(argv[0], retval, 7520Sstevel@tonic-gate gettext("while attempting to retrieve default realm")); 7530Sstevel@tonic-gate exit(1); 7540Sstevel@tonic-gate } 7550Sstevel@tonic-gate if ((rdatap = (kdc_realm_t *) malloc(sizeof(kdc_realm_t)))) { 7560Sstevel@tonic-gate if ((retval = init_realm(argv[0], rdatap, lrealm, db_name, 7570Sstevel@tonic-gate mkey_name, menctype, default_udp_ports, 7580Sstevel@tonic-gate default_tcp_ports, manual))) { 7590Sstevel@tonic-gate fprintf(stderr, 7600Sstevel@tonic-gate gettext("%s: cannot initialize realm %s\n"), 7610Sstevel@tonic-gate argv[0], lrealm); 7620Sstevel@tonic-gate exit(1); 7630Sstevel@tonic-gate } 7640Sstevel@tonic-gate kdc_realmlist[0] = rdatap; 7650Sstevel@tonic-gate kdc_numrealms++; 7660Sstevel@tonic-gate } 7670Sstevel@tonic-gate } 7680Sstevel@tonic-gate 7690Sstevel@tonic-gate #ifdef USE_RCACHE 7700Sstevel@tonic-gate /* 7710Sstevel@tonic-gate * Now handle the replay cache. 7720Sstevel@tonic-gate */ 7730Sstevel@tonic-gate if ((retval = kdc_initialize_rcache(kcontext, rcname))) { 7740Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing KDC replay cache")); 7750Sstevel@tonic-gate exit(1); 7760Sstevel@tonic-gate } 7770Sstevel@tonic-gate #endif 7780Sstevel@tonic-gate 7790Sstevel@tonic-gate /* Ensure that this is set for our first request. */ 7800Sstevel@tonic-gate kdc_active_realm = kdc_realmlist[0]; 7810Sstevel@tonic-gate if (default_udp_ports) 7820Sstevel@tonic-gate free(default_udp_ports); 7830Sstevel@tonic-gate if (default_tcp_ports) 7840Sstevel@tonic-gate free(default_tcp_ports); 7850Sstevel@tonic-gate 7860Sstevel@tonic-gate return; 7870Sstevel@tonic-gate } 7880Sstevel@tonic-gate 7890Sstevel@tonic-gate void 7900Sstevel@tonic-gate finish_realms(prog) 7910Sstevel@tonic-gate char *prog; 7920Sstevel@tonic-gate { 7930Sstevel@tonic-gate int i; 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate for (i = 0; i < kdc_numrealms; i++) { 7960Sstevel@tonic-gate finish_realm(kdc_realmlist[i]); 7970Sstevel@tonic-gate kdc_realmlist[i] = 0; 7980Sstevel@tonic-gate } 7990Sstevel@tonic-gate } 8000Sstevel@tonic-gate 8010Sstevel@tonic-gate /* 8020Sstevel@tonic-gate outline: 8030Sstevel@tonic-gate 8040Sstevel@tonic-gate process args & setup 8050Sstevel@tonic-gate 8060Sstevel@tonic-gate initialize database access (fetch master key, open DB) 8070Sstevel@tonic-gate 8080Sstevel@tonic-gate initialize network 8090Sstevel@tonic-gate 8100Sstevel@tonic-gate loop: 8110Sstevel@tonic-gate listen for packet 8120Sstevel@tonic-gate 8130Sstevel@tonic-gate determine packet type, dispatch to handling routine 8140Sstevel@tonic-gate (AS or TGS (or V4?)) 8150Sstevel@tonic-gate 8160Sstevel@tonic-gate reflect response 8170Sstevel@tonic-gate 8180Sstevel@tonic-gate exit on signal 8190Sstevel@tonic-gate 8200Sstevel@tonic-gate clean up secrets, close db 8210Sstevel@tonic-gate 8220Sstevel@tonic-gate shut down network 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate exit 8250Sstevel@tonic-gate */ 8260Sstevel@tonic-gate 8270Sstevel@tonic-gate int main(argc, argv) 8280Sstevel@tonic-gate int argc; 8290Sstevel@tonic-gate char *argv[]; 8300Sstevel@tonic-gate { 8310Sstevel@tonic-gate krb5_error_code retval; 8320Sstevel@tonic-gate krb5_context kcontext; 8330Sstevel@tonic-gate int *port_list; 8340Sstevel@tonic-gate int errout = 0; 8350Sstevel@tonic-gate 8360Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 8370Sstevel@tonic-gate 8380Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */ 8390Sstevel@tonic-gate #define TEXT_DOMAIN "KRB5KDC_TEST" /* Use this only if it weren't */ 8400Sstevel@tonic-gate #endif 8410Sstevel@tonic-gate 8420Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 8430Sstevel@tonic-gate 8440Sstevel@tonic-gate if (strrchr(argv[0], '/')) 8450Sstevel@tonic-gate argv[0] = strrchr(argv[0], '/')+1; 8460Sstevel@tonic-gate 8470Sstevel@tonic-gate if (!(kdc_realmlist = (kdc_realm_t **) malloc(sizeof(kdc_realm_t *) * 8480Sstevel@tonic-gate KRB5_KDC_MAX_REALMS))) { 8490Sstevel@tonic-gate fprintf(stderr, gettext("%s: cannot get memory for realm list\n"), argv[0]); 8500Sstevel@tonic-gate exit(1); 8510Sstevel@tonic-gate } 8520Sstevel@tonic-gate memset((char *) kdc_realmlist, 0, 8530Sstevel@tonic-gate (size_t) (sizeof(kdc_realm_t *) * KRB5_KDC_MAX_REALMS)); 8540Sstevel@tonic-gate port_list = NULL; 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate /* 8570Sstevel@tonic-gate * A note about Kerberos contexts: This context, "kcontext", is used 8580Sstevel@tonic-gate * for the KDC operations, i.e. setup, network connection and error 8590Sstevel@tonic-gate * reporting. The per-realm operations use the "realm_context" 8600Sstevel@tonic-gate * associated with each realm. 8610Sstevel@tonic-gate */ 8620Sstevel@tonic-gate retval = krb5_init_context(&kcontext); 8630Sstevel@tonic-gate if (retval) { 8640Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing krb5")); 8650Sstevel@tonic-gate exit(1); 8660Sstevel@tonic-gate } 8670Sstevel@tonic-gate krb5_klog_init(kcontext, "kdc", argv[0], 1); 8680Sstevel@tonic-gate /* initialize_kdc5_error_table(); SUNWresync121 XXX */ 8690Sstevel@tonic-gate 8700Sstevel@tonic-gate /* 8710Sstevel@tonic-gate * Scan through the argument list 8720Sstevel@tonic-gate */ 8730Sstevel@tonic-gate initialize_realms(kcontext, argc, argv); 8740Sstevel@tonic-gate 8750Sstevel@tonic-gate setup_signal_handlers(); 8760Sstevel@tonic-gate 8770Sstevel@tonic-gate if (retval = setup_sam()) { 8780Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing SAM")); 8790Sstevel@tonic-gate finish_realms(argv[0]); 8800Sstevel@tonic-gate return 1; 8810Sstevel@tonic-gate } 8820Sstevel@tonic-gate 8830Sstevel@tonic-gate if ((retval = setup_network(argv[0]))) { 8840Sstevel@tonic-gate com_err(argv[0], retval, gettext("while initializing network")); 8850Sstevel@tonic-gate finish_realms(argv[0]); 8860Sstevel@tonic-gate return 1; 8870Sstevel@tonic-gate } 8880Sstevel@tonic-gate if (!nofork && daemon(0, 0)) { 8890Sstevel@tonic-gate com_err(argv[0], errno, gettext("while detaching from tty")); 8900Sstevel@tonic-gate finish_realms(argv[0]); 8910Sstevel@tonic-gate return 1; 8920Sstevel@tonic-gate } 8930Sstevel@tonic-gate if (retval = krb5_klog_syslog(LOG_INFO, "commencing operation")) { 8940Sstevel@tonic-gate com_err(argv[0], retval, gettext("while logging message")); 8950Sstevel@tonic-gate errout++; 8960Sstevel@tonic-gate }; 8970Sstevel@tonic-gate 8980Sstevel@tonic-gate if ((retval = listen_and_process(argv[0]))) { 8990Sstevel@tonic-gate com_err(argv[0], retval, gettext("while processing network requests")); 9000Sstevel@tonic-gate errout++; 9010Sstevel@tonic-gate } 9020Sstevel@tonic-gate if ((retval = closedown_network(argv[0]))) { 9030Sstevel@tonic-gate com_err(argv[0], retval, gettext("while shutting down network")); 9040Sstevel@tonic-gate errout++; 9050Sstevel@tonic-gate } 9060Sstevel@tonic-gate krb5_klog_syslog(LOG_INFO, "shutting down"); 9070Sstevel@tonic-gate krb5_klog_close(kdc_context); 9080Sstevel@tonic-gate finish_realms(argv[0]); 9090Sstevel@tonic-gate krb5_free_context(kcontext); 9100Sstevel@tonic-gate return errout; 9110Sstevel@tonic-gate } 912